| .. | .. |
|---|
| 23 | 23 | |
|---|
| 24 | 24 | #include <nvif/cl507c.h> |
|---|
| 25 | 25 | #include <nvif/event.h> |
|---|
| 26 | +#include <nvif/push507c.h> |
|---|
| 27 | +#include <nvif/timer.h> |
|---|
| 28 | + |
|---|
| 29 | +#include <nvhw/class/cl507c.h> |
|---|
| 26 | 30 | |
|---|
| 27 | 31 | #include <drm/drm_atomic_helper.h> |
|---|
| 32 | +#include <drm/drm_fourcc.h> |
|---|
| 28 | 33 | #include <drm/drm_plane_helper.h> |
|---|
| 34 | + |
|---|
| 29 | 35 | #include "nouveau_bo.h" |
|---|
| 30 | 36 | |
|---|
| 31 | | -void |
|---|
| 37 | +int |
|---|
| 32 | 38 | base507c_update(struct nv50_wndw *wndw, u32 *interlock) |
|---|
| 33 | 39 | { |
|---|
| 34 | | - u32 *push; |
|---|
| 35 | | - if ((push = evo_wait(&wndw->wndw, 2))) { |
|---|
| 36 | | - evo_mthd(push, 0x0080, 1); |
|---|
| 37 | | - evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]); |
|---|
| 38 | | - evo_kick(push, &wndw->wndw); |
|---|
| 39 | | - } |
|---|
| 40 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 41 | + int ret; |
|---|
| 42 | + |
|---|
| 43 | + if ((ret = PUSH_WAIT(push, 2))) |
|---|
| 44 | + return ret; |
|---|
| 45 | + |
|---|
| 46 | + PUSH_MTHD(push, NV507C, UPDATE, interlock[NV50_DISP_INTERLOCK_CORE]); |
|---|
| 47 | + return PUSH_KICK(push); |
|---|
| 40 | 48 | } |
|---|
| 41 | 49 | |
|---|
| 42 | | -void |
|---|
| 50 | +int |
|---|
| 43 | 51 | base507c_image_clr(struct nv50_wndw *wndw) |
|---|
| 44 | 52 | { |
|---|
| 45 | | - u32 *push; |
|---|
| 46 | | - if ((push = evo_wait(&wndw->wndw, 4))) { |
|---|
| 47 | | - evo_mthd(push, 0x0084, 1); |
|---|
| 48 | | - evo_data(push, 0x00000000); |
|---|
| 49 | | - evo_mthd(push, 0x00c0, 1); |
|---|
| 50 | | - evo_data(push, 0x00000000); |
|---|
| 51 | | - evo_kick(push, &wndw->wndw); |
|---|
| 52 | | - } |
|---|
| 53 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 54 | + int ret; |
|---|
| 55 | + |
|---|
| 56 | + if ((ret = PUSH_WAIT(push, 4))) |
|---|
| 57 | + return ret; |
|---|
| 58 | + |
|---|
| 59 | + PUSH_MTHD(push, NV507C, SET_PRESENT_CONTROL, |
|---|
| 60 | + NVDEF(NV507C, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING) | |
|---|
| 61 | + NVVAL(NV507C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0)); |
|---|
| 62 | + |
|---|
| 63 | + PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_ISO, 0x00000000); |
|---|
| 64 | + return 0; |
|---|
| 53 | 65 | } |
|---|
| 54 | 66 | |
|---|
| 55 | | -static void |
|---|
| 67 | +static int |
|---|
| 56 | 68 | base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
|---|
| 57 | 69 | { |
|---|
| 58 | | - u32 *push; |
|---|
| 59 | | - if ((push = evo_wait(&wndw->wndw, 10))) { |
|---|
| 60 | | - evo_mthd(push, 0x0084, 1); |
|---|
| 61 | | - evo_data(push, asyw->image.mode << 8 | |
|---|
| 62 | | - asyw->image.interval << 4); |
|---|
| 63 | | - evo_mthd(push, 0x00c0, 1); |
|---|
| 64 | | - evo_data(push, asyw->image.handle[0]); |
|---|
| 65 | | - evo_mthd(push, 0x0800, 5); |
|---|
| 66 | | - evo_data(push, asyw->image.offset[0] >> 8); |
|---|
| 67 | | - evo_data(push, 0x00000000); |
|---|
| 68 | | - evo_data(push, asyw->image.h << 16 | asyw->image.w); |
|---|
| 69 | | - evo_data(push, asyw->image.layout << 20 | |
|---|
| 70 | | - (asyw->image.pitch[0] >> 8) << 8 | |
|---|
| 71 | | - asyw->image.blocks[0] << 8 | |
|---|
| 72 | | - asyw->image.blockh); |
|---|
| 73 | | - evo_data(push, asyw->image.kind << 16 | |
|---|
| 74 | | - asyw->image.format << 8); |
|---|
| 75 | | - evo_kick(push, &wndw->wndw); |
|---|
| 70 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 71 | + int ret; |
|---|
| 72 | + |
|---|
| 73 | + if ((ret = PUSH_WAIT(push, 13))) |
|---|
| 74 | + return ret; |
|---|
| 75 | + |
|---|
| 76 | + PUSH_MTHD(push, NV507C, SET_PRESENT_CONTROL, |
|---|
| 77 | + NVVAL(NV507C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | |
|---|
| 78 | + NVVAL(NV507C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval)); |
|---|
| 79 | + |
|---|
| 80 | + PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]); |
|---|
| 81 | + |
|---|
| 82 | + if (asyw->image.format == NV507C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16) { |
|---|
| 83 | + PUSH_MTHD(push, NV507C, SET_PROCESSING, |
|---|
| 84 | + NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, ENABLE), |
|---|
| 85 | + |
|---|
| 86 | + SET_CONVERSION, |
|---|
| 87 | + NVVAL(NV507C, SET_CONVERSION, GAIN, 0) | |
|---|
| 88 | + NVVAL(NV507C, SET_CONVERSION, OFS, 0x64)); |
|---|
| 89 | + } else { |
|---|
| 90 | + PUSH_MTHD(push, NV507C, SET_PROCESSING, |
|---|
| 91 | + NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE), |
|---|
| 92 | + |
|---|
| 93 | + SET_CONVERSION, |
|---|
| 94 | + NVVAL(NV507C, SET_CONVERSION, GAIN, 0) | |
|---|
| 95 | + NVVAL(NV507C, SET_CONVERSION, OFS, 0)); |
|---|
| 76 | 96 | } |
|---|
| 97 | + |
|---|
| 98 | + PUSH_MTHD(push, NV507C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8); |
|---|
| 99 | + |
|---|
| 100 | + PUSH_MTHD(push, NV507C, SURFACE_SET_SIZE(0), |
|---|
| 101 | + NVVAL(NV507C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) | |
|---|
| 102 | + NVVAL(NV507C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h), |
|---|
| 103 | + |
|---|
| 104 | + SURFACE_SET_STORAGE(0), |
|---|
| 105 | + NVVAL(NV507C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout) | |
|---|
| 106 | + NVVAL(NV507C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) | |
|---|
| 107 | + NVVAL(NV507C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) | |
|---|
| 108 | + NVVAL(NV507C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh), |
|---|
| 109 | + |
|---|
| 110 | + SURFACE_SET_PARAMS(0), |
|---|
| 111 | + NVVAL(NV507C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) | |
|---|
| 112 | + NVDEF(NV507C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) | |
|---|
| 113 | + NVDEF(NV507C, SURFACE_SET_PARAMS, GAMMA, LINEAR) | |
|---|
| 114 | + NVDEF(NV507C, SURFACE_SET_PARAMS, LAYOUT, FRM) | |
|---|
| 115 | + NVVAL(NV507C, SURFACE_SET_PARAMS, KIND, asyw->image.kind) | |
|---|
| 116 | + NVDEF(NV507C, SURFACE_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256)); |
|---|
| 117 | + return 0; |
|---|
| 77 | 118 | } |
|---|
| 78 | 119 | |
|---|
| 79 | | -void |
|---|
| 120 | +int |
|---|
| 80 | 121 | base507c_xlut_clr(struct nv50_wndw *wndw) |
|---|
| 81 | 122 | { |
|---|
| 82 | | - u32 *push; |
|---|
| 83 | | - if ((push = evo_wait(&wndw->wndw, 2))) { |
|---|
| 84 | | - evo_mthd(push, 0x00e0, 1); |
|---|
| 85 | | - evo_data(push, 0x00000000); |
|---|
| 86 | | - evo_kick(push, &wndw->wndw); |
|---|
| 87 | | - } |
|---|
| 123 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 124 | + int ret; |
|---|
| 125 | + |
|---|
| 126 | + if ((ret = PUSH_WAIT(push, 2))) |
|---|
| 127 | + return ret; |
|---|
| 128 | + |
|---|
| 129 | + PUSH_MTHD(push, NV507C, SET_BASE_LUT_LO, |
|---|
| 130 | + NVDEF(NV507C, SET_BASE_LUT_LO, ENABLE, DISABLE)); |
|---|
| 131 | + return 0; |
|---|
| 88 | 132 | } |
|---|
| 89 | 133 | |
|---|
| 90 | | -void |
|---|
| 134 | +int |
|---|
| 91 | 135 | base507c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
|---|
| 92 | 136 | { |
|---|
| 93 | | - u32 *push; |
|---|
| 94 | | - if ((push = evo_wait(&wndw->wndw, 2))) { |
|---|
| 95 | | - evo_mthd(push, 0x00e0, 1); |
|---|
| 96 | | - evo_data(push, 0x40000000); |
|---|
| 97 | | - evo_kick(push, &wndw->wndw); |
|---|
| 98 | | - } |
|---|
| 137 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 138 | + int ret; |
|---|
| 139 | + |
|---|
| 140 | + if ((ret = PUSH_WAIT(push, 2))) |
|---|
| 141 | + return ret; |
|---|
| 142 | + |
|---|
| 143 | + PUSH_MTHD(push, NV507C, SET_BASE_LUT_LO, |
|---|
| 144 | + NVDEF(NV507C, SET_BASE_LUT_LO, ENABLE, USE_CORE_LUT)); |
|---|
| 145 | + return 0; |
|---|
| 99 | 146 | } |
|---|
| 100 | 147 | |
|---|
| 101 | 148 | int |
|---|
| .. | .. |
|---|
| 103 | 150 | struct nvif_device *device) |
|---|
| 104 | 151 | { |
|---|
| 105 | 152 | s64 time = nvif_msec(device, 2000ULL, |
|---|
| 106 | | - u32 data = nouveau_bo_rd32(bo, offset / 4); |
|---|
| 107 | | - if ((data & 0xc0000000) == 0x40000000) |
|---|
| 153 | + if (NVBO_TD32(bo, offset, NV_DISP_BASE_NOTIFIER_1, _0, STATUS, ==, BEGUN)) |
|---|
| 108 | 154 | break; |
|---|
| 109 | 155 | usleep_range(1, 2); |
|---|
| 110 | 156 | ); |
|---|
| 111 | 157 | return time < 0 ? time : 0; |
|---|
| 112 | 158 | } |
|---|
| 113 | 159 | |
|---|
| 114 | | -void |
|---|
| 160 | +int |
|---|
| 115 | 161 | base507c_ntfy_clr(struct nv50_wndw *wndw) |
|---|
| 116 | 162 | { |
|---|
| 117 | | - u32 *push; |
|---|
| 118 | | - if ((push = evo_wait(&wndw->wndw, 2))) { |
|---|
| 119 | | - evo_mthd(push, 0x00a4, 1); |
|---|
| 120 | | - evo_data(push, 0x00000000); |
|---|
| 121 | | - evo_kick(push, &wndw->wndw); |
|---|
| 122 | | - } |
|---|
| 163 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 164 | + int ret; |
|---|
| 165 | + |
|---|
| 166 | + if ((ret = PUSH_WAIT(push, 2))) |
|---|
| 167 | + return ret; |
|---|
| 168 | + |
|---|
| 169 | + PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_NOTIFIER, 0x00000000); |
|---|
| 170 | + return 0; |
|---|
| 123 | 171 | } |
|---|
| 124 | 172 | |
|---|
| 125 | | -void |
|---|
| 173 | +int |
|---|
| 126 | 174 | base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
|---|
| 127 | 175 | { |
|---|
| 128 | | - u32 *push; |
|---|
| 129 | | - if ((push = evo_wait(&wndw->wndw, 3))) { |
|---|
| 130 | | - evo_mthd(push, 0x00a0, 2); |
|---|
| 131 | | - evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset); |
|---|
| 132 | | - evo_data(push, asyw->ntfy.handle); |
|---|
| 133 | | - evo_kick(push, &wndw->wndw); |
|---|
| 134 | | - } |
|---|
| 176 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 177 | + int ret; |
|---|
| 178 | + |
|---|
| 179 | + if ((ret = PUSH_WAIT(push, 3))) |
|---|
| 180 | + return ret; |
|---|
| 181 | + |
|---|
| 182 | + PUSH_MTHD(push, NV507C, SET_NOTIFIER_CONTROL, |
|---|
| 183 | + NVVAL(NV507C, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken) | |
|---|
| 184 | + NVVAL(NV507C, SET_NOTIFIER_CONTROL, OFFSET, asyw->ntfy.offset >> 2), |
|---|
| 185 | + |
|---|
| 186 | + SET_CONTEXT_DMA_NOTIFIER, asyw->ntfy.handle); |
|---|
| 187 | + return 0; |
|---|
| 135 | 188 | } |
|---|
| 136 | 189 | |
|---|
| 137 | 190 | void |
|---|
| 138 | 191 | base507c_ntfy_reset(struct nouveau_bo *bo, u32 offset) |
|---|
| 139 | 192 | { |
|---|
| 140 | | - nouveau_bo_wr32(bo, offset / 4, 0x00000000); |
|---|
| 193 | + NVBO_WR32(bo, offset, NV_DISP_BASE_NOTIFIER_1, _0, |
|---|
| 194 | + NVDEF(NV_DISP_BASE_NOTIFIER_1, _0, STATUS, NOT_BEGUN)); |
|---|
| 141 | 195 | } |
|---|
| 142 | 196 | |
|---|
| 143 | | -void |
|---|
| 197 | +int |
|---|
| 144 | 198 | base507c_sema_clr(struct nv50_wndw *wndw) |
|---|
| 145 | 199 | { |
|---|
| 146 | | - u32 *push; |
|---|
| 147 | | - if ((push = evo_wait(&wndw->wndw, 2))) { |
|---|
| 148 | | - evo_mthd(push, 0x0094, 1); |
|---|
| 149 | | - evo_data(push, 0x00000000); |
|---|
| 150 | | - evo_kick(push, &wndw->wndw); |
|---|
| 151 | | - } |
|---|
| 200 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 201 | + int ret; |
|---|
| 202 | + |
|---|
| 203 | + if ((ret = PUSH_WAIT(push, 2))) |
|---|
| 204 | + return ret; |
|---|
| 205 | + |
|---|
| 206 | + PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_SEMAPHORE, 0x00000000); |
|---|
| 207 | + return 0; |
|---|
| 152 | 208 | } |
|---|
| 153 | 209 | |
|---|
| 154 | | -void |
|---|
| 210 | +int |
|---|
| 155 | 211 | base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
|---|
| 156 | 212 | { |
|---|
| 157 | | - u32 *push; |
|---|
| 158 | | - if ((push = evo_wait(&wndw->wndw, 5))) { |
|---|
| 159 | | - evo_mthd(push, 0x0088, 4); |
|---|
| 160 | | - evo_data(push, asyw->sema.offset); |
|---|
| 161 | | - evo_data(push, asyw->sema.acquire); |
|---|
| 162 | | - evo_data(push, asyw->sema.release); |
|---|
| 163 | | - evo_data(push, asyw->sema.handle); |
|---|
| 164 | | - evo_kick(push, &wndw->wndw); |
|---|
| 165 | | - } |
|---|
| 213 | + struct nvif_push *push = wndw->wndw.push; |
|---|
| 214 | + int ret; |
|---|
| 215 | + |
|---|
| 216 | + if ((ret = PUSH_WAIT(push, 5))) |
|---|
| 217 | + return ret; |
|---|
| 218 | + |
|---|
| 219 | + PUSH_MTHD(push, NV507C, SET_SEMAPHORE_CONTROL, asyw->sema.offset, |
|---|
| 220 | + SET_SEMAPHORE_ACQUIRE, asyw->sema.acquire, |
|---|
| 221 | + SET_SEMAPHORE_RELEASE, asyw->sema.release, |
|---|
| 222 | + SET_CONTEXT_DMA_SEMAPHORE, asyw->sema.handle); |
|---|
| 223 | + return 0; |
|---|
| 166 | 224 | } |
|---|
| 167 | 225 | |
|---|
| 168 | 226 | void |
|---|
| .. | .. |
|---|
| 178 | 236 | { |
|---|
| 179 | 237 | const struct drm_framebuffer *fb = asyw->state.fb; |
|---|
| 180 | 238 | int ret; |
|---|
| 181 | | - |
|---|
| 182 | | - if (!fb->format->depth) |
|---|
| 183 | | - return -EINVAL; |
|---|
| 184 | 239 | |
|---|
| 185 | 240 | ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, |
|---|
| 186 | 241 | DRM_PLANE_HELPER_NO_SCALING, |
|---|
| .. | .. |
|---|
| 200 | 255 | asyh->base.y = asyw->state.src.y1 >> 16; |
|---|
| 201 | 256 | asyh->base.w = asyw->state.fb->width; |
|---|
| 202 | 257 | asyh->base.h = asyw->state.fb->height; |
|---|
| 258 | + |
|---|
| 259 | + /* Some newer formats, esp FP16 ones, don't have a |
|---|
| 260 | + * "depth". There's nothing that really makes sense there |
|---|
| 261 | + * either, so just set it to the implicit bit count. |
|---|
| 262 | + */ |
|---|
| 263 | + if (!asyh->base.depth) |
|---|
| 264 | + asyh->base.depth = asyh->base.cpp * 8; |
|---|
| 265 | + |
|---|
| 203 | 266 | return 0; |
|---|
| 204 | 267 | } |
|---|
| 205 | 268 | |
|---|
| .. | .. |
|---|
| 215 | 278 | DRM_FORMAT_ABGR2101010, |
|---|
| 216 | 279 | DRM_FORMAT_XBGR8888, |
|---|
| 217 | 280 | DRM_FORMAT_ABGR8888, |
|---|
| 281 | + DRM_FORMAT_XBGR16161616F, |
|---|
| 282 | + DRM_FORMAT_ABGR16161616F, |
|---|
| 218 | 283 | 0 |
|---|
| 219 | 284 | }; |
|---|
| 220 | 285 | |
|---|
| .. | .. |
|---|
| 244 | 309 | struct nv50_disp_base_channel_dma_v0 args = { |
|---|
| 245 | 310 | .head = head, |
|---|
| 246 | 311 | }; |
|---|
| 247 | | - struct nv50_disp *disp = nv50_disp(drm->dev); |
|---|
| 312 | + struct nouveau_display *disp = nouveau_display(drm->dev); |
|---|
| 313 | + struct nv50_disp *disp50 = nv50_disp(drm->dev); |
|---|
| 248 | 314 | struct nv50_wndw *wndw; |
|---|
| 249 | 315 | int ret; |
|---|
| 250 | 316 | |
|---|
| .. | .. |
|---|
| 254 | 320 | if (*pwndw = wndw, ret) |
|---|
| 255 | 321 | return ret; |
|---|
| 256 | 322 | |
|---|
| 257 | | - ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, |
|---|
| 323 | + ret = nv50_dmac_create(&drm->client.device, &disp->disp.object, |
|---|
| 258 | 324 | &oclass, head, &args, sizeof(args), |
|---|
| 259 | | - disp->sync->bo.offset, &wndw->wndw); |
|---|
| 325 | + disp50->sync->offset, &wndw->wndw); |
|---|
| 260 | 326 | if (ret) { |
|---|
| 261 | 327 | NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret); |
|---|
| 262 | 328 | return ret; |
|---|
| 263 | 329 | } |
|---|
| 264 | 330 | |
|---|
| 265 | | - ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, |
|---|
| 266 | | - false, NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, |
|---|
| 331 | + ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsBaseNtfy", |
|---|
| 332 | + wndw->notify.func, false, |
|---|
| 333 | + NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, |
|---|
| 267 | 334 | &(struct nvif_notify_uevent_req) {}, |
|---|
| 268 | 335 | sizeof(struct nvif_notify_uevent_req), |
|---|
| 269 | 336 | sizeof(struct nvif_notify_uevent_rep), |
|---|