11590700dSBen Skeggs /* 21590700dSBen Skeggs * Copyright 2018 Red Hat Inc. 31590700dSBen Skeggs * 41590700dSBen Skeggs * Permission is hereby granted, free of charge, to any person obtaining a 51590700dSBen Skeggs * copy of this software and associated documentation files (the "Software"), 61590700dSBen Skeggs * to deal in the Software without restriction, including without limitation 71590700dSBen Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense, 81590700dSBen Skeggs * and/or sell copies of the Software, and to permit persons to whom the 91590700dSBen Skeggs * Software is furnished to do so, subject to the following conditions: 101590700dSBen Skeggs * 111590700dSBen Skeggs * The above copyright notice and this permission notice shall be included in 121590700dSBen Skeggs * all copies or substantial portions of the Software. 131590700dSBen Skeggs * 141590700dSBen Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 151590700dSBen Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 161590700dSBen Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 171590700dSBen Skeggs * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 181590700dSBen Skeggs * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 191590700dSBen Skeggs * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 201590700dSBen Skeggs * OTHER DEALINGS IN THE SOFTWARE. 211590700dSBen Skeggs */ 221590700dSBen Skeggs #include "core.h" 231590700dSBen Skeggs #include "head.h" 241590700dSBen Skeggs 251590700dSBen Skeggs #include <nvif/cl507d.h> 265e691222SBen Skeggs #include <nvif/push507c.h> 27ed3d1489SBen Skeggs #include <nvif/timer.h> 281590700dSBen Skeggs 29b11d8ca1SBen Skeggs #include <nvhw/class/cl507d.h> 30b11d8ca1SBen Skeggs 311590700dSBen Skeggs #include "nouveau_bo.h" 321590700dSBen Skeggs 33203f6eafSBen Skeggs int 3453e0a3e7SBen Skeggs core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy) 3509e1b78aSBen Skeggs { 36203f6eafSBen Skeggs struct nvif_push *push = core->chan.push; 37203f6eafSBen Skeggs int ret; 38203f6eafSBen Skeggs 39203f6eafSBen Skeggs if ((ret = PUSH_WAIT(push, 5))) 40203f6eafSBen Skeggs return ret; 41203f6eafSBen Skeggs 42203f6eafSBen Skeggs if (ntfy) 43203f6eafSBen Skeggs PUSH_NVSQ(push, NV507D, 0x0084, 0x80000000 | NV50_DISP_CORE_NTFY); 44203f6eafSBen Skeggs 45203f6eafSBen Skeggs PUSH_NVSQ(push, NV507D, 0x0080, interlock[NV50_DISP_INTERLOCK_BASE] | 46203f6eafSBen Skeggs interlock[NV50_DISP_INTERLOCK_OVLY], 47203f6eafSBen Skeggs 0x0084, 0x00000000); 48203f6eafSBen Skeggs return PUSH_KICK(push); 4909e1b78aSBen Skeggs } 5009e1b78aSBen Skeggs 5109e1b78aSBen Skeggs int 5209e1b78aSBen Skeggs core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, 5309e1b78aSBen Skeggs struct nvif_device *device) 5409e1b78aSBen Skeggs { 5509e1b78aSBen Skeggs s64 time = nvif_msec(device, 2000ULL, 564daef27cSBen Skeggs if (NVBO_TD32(bo, offset, NV_DISP_CORE_NOTIFIER_1, COMPLETION_0, DONE, ==, TRUE)) 5709e1b78aSBen Skeggs break; 5809e1b78aSBen Skeggs usleep_range(1, 2); 5909e1b78aSBen Skeggs ); 6009e1b78aSBen Skeggs return time < 0 ? time : 0; 6109e1b78aSBen Skeggs } 6209e1b78aSBen Skeggs 6309e1b78aSBen Skeggs void 6409e1b78aSBen Skeggs core507d_ntfy_init(struct nouveau_bo *bo, u32 offset) 6509e1b78aSBen Skeggs { 6638a323b0SBen Skeggs NVBO_WR32(bo, offset, NV_DISP_CORE_NOTIFIER_1, COMPLETION_0, 6738a323b0SBen Skeggs NVDEF(NV_DISP_CORE_NOTIFIER_1, COMPLETION_0, DONE, FALSE)); 6809e1b78aSBen Skeggs } 6909e1b78aSBen Skeggs 704a2cb418SLyude Paul int 714a2cb418SLyude Paul core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) 724a2cb418SLyude Paul { 733c43c362SBen Skeggs struct nvif_push *push = disp->core->chan.push; 743c43c362SBen Skeggs int ret; 754a2cb418SLyude Paul 763c43c362SBen Skeggs if ((ret = PUSH_WAIT(push, 2))) 773c43c362SBen Skeggs return ret; 784a2cb418SLyude Paul 79d8b24526SBen Skeggs PUSH_MTHD(push, NV507D, GET_CAPABILITIES, 0x00000000); 803c43c362SBen Skeggs return PUSH_KICK(push); 814a2cb418SLyude Paul } 824a2cb418SLyude Paul 835e691222SBen Skeggs int 8409e1b78aSBen Skeggs core507d_init(struct nv50_core *core) 8509e1b78aSBen Skeggs { 865e691222SBen Skeggs struct nvif_push *push = core->chan.push; 875e691222SBen Skeggs int ret; 885e691222SBen Skeggs 895e691222SBen Skeggs if ((ret = PUSH_WAIT(push, 2))) 905e691222SBen Skeggs return ret; 915e691222SBen Skeggs 92b11d8ca1SBen Skeggs PUSH_MTHD(push, NV507D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle); 935e691222SBen Skeggs return PUSH_KICK(push); 9409e1b78aSBen Skeggs } 9509e1b78aSBen Skeggs 961590700dSBen Skeggs static const struct nv50_core_func 971590700dSBen Skeggs core507d = { 9809e1b78aSBen Skeggs .init = core507d_init, 9909e1b78aSBen Skeggs .ntfy_init = core507d_ntfy_init, 1004a2cb418SLyude Paul .caps_init = core507d_caps_init, 10109e1b78aSBen Skeggs .ntfy_wait_done = core507d_ntfy_wait_done, 10209e1b78aSBen Skeggs .update = core507d_update, 1031590700dSBen Skeggs .head = &head507d, 1041590700dSBen Skeggs .dac = &dac507d, 1051590700dSBen Skeggs .sor = &sor507d, 1061590700dSBen Skeggs .pior = &pior507d, 1071590700dSBen Skeggs }; 1081590700dSBen Skeggs 10909e1b78aSBen Skeggs int 1101590700dSBen Skeggs core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm, 1111590700dSBen Skeggs s32 oclass, struct nv50_core **pcore) 1121590700dSBen Skeggs { 1131590700dSBen Skeggs struct nv50_disp_core_channel_dma_v0 args = {}; 1141590700dSBen Skeggs struct nv50_disp *disp = nv50_disp(drm->dev); 1151590700dSBen Skeggs struct nv50_core *core; 1161590700dSBen Skeggs int ret; 1171590700dSBen Skeggs 1181590700dSBen Skeggs if (!(core = *pcore = kzalloc(sizeof(*core), GFP_KERNEL))) 1191590700dSBen Skeggs return -ENOMEM; 1201590700dSBen Skeggs core->func = func; 1211590700dSBen Skeggs 1221590700dSBen Skeggs ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, 1231590700dSBen Skeggs &oclass, 0, &args, sizeof(args), 1240dc9b286SNirmoy Das disp->sync->offset, &core->chan); 1251590700dSBen Skeggs if (ret) { 1261590700dSBen Skeggs NV_ERROR(drm, "core%04x allocation failed: %d\n", oclass, ret); 1271590700dSBen Skeggs return ret; 1281590700dSBen Skeggs } 1291590700dSBen Skeggs 1301590700dSBen Skeggs return 0; 1311590700dSBen Skeggs } 1321590700dSBen Skeggs 1331590700dSBen Skeggs int 1341590700dSBen Skeggs core507d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) 1351590700dSBen Skeggs { 1361590700dSBen Skeggs return core507d_new_(&core507d, drm, oclass, pcore); 1371590700dSBen Skeggs } 138