diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv50')
41 files changed, 2461 insertions, 1649 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.h b/drivers/gpu/drm/nouveau/dispnv50/base.h index e7f14f230f35..085bd3aeb40b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base.h +++ b/drivers/gpu/drm/nouveau/dispnv50/base.h @@ -11,14 +11,10 @@ int base507c_acquire(struct nv50_wndw *, struct nv50_wndw_atom *, struct nv50_head_atom *); void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *, struct nv50_head_atom *); -void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *); -void base507c_sema_clr(struct nv50_wndw *); -void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); -void base507c_ntfy_clr(struct nv50_wndw *); -void base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *); -void base507c_xlut_clr(struct nv50_wndw *); -void base507c_image_clr(struct nv50_wndw *); -void base507c_update(struct nv50_wndw *, u32 *); +int base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *); +int base507c_sema_clr(struct nv50_wndw *); +int base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *); +int base507c_xlut_clr(struct nv50_wndw *); int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index ba20a7722900..302d4e6fc52f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -23,91 +23,122 @@ #include <nvif/cl507c.h> #include <nvif/event.h> +#include <nvif/push507c.h> #include <nvif/timer.h> +#include <nvhw/class/cl507c.h> + #include <drm/drm_atomic_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_plane_helper.h> #include "nouveau_bo.h" -void +int base507c_update(struct nv50_wndw *wndw, u32 *interlock) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x0080, 1); - evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507C, UPDATE, interlock[NV50_DISP_INTERLOCK_CORE]); + return PUSH_KICK(push); } -void +int base507c_image_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 4))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x00c0, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NV507C, SET_PRESENT_CONTROL, + NVDEF(NV507C, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING) | + NVVAL(NV507C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0)); + + PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_ISO, 0x00000000); + return 0; } -static void +static int base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 13))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, asyw->image.mode << 8 | - asyw->image.interval << 4); - evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle[0]); - if (asyw->image.format == 0xca) { - evo_mthd(push, 0x0110, 2); - evo_data(push, 1); - evo_data(push, 0x6400); - } else { - evo_mthd(push, 0x0110, 2); - evo_data(push, 0); - evo_data(push, 0); - } - evo_mthd(push, 0x0800, 5); - evo_data(push, asyw->image.offset[0] >> 8); - evo_data(push, 0x00000000); - evo_data(push, asyw->image.h << 16 | asyw->image.w); - evo_data(push, asyw->image.layout << 20 | - (asyw->image.pitch[0] >> 8) << 8 | - asyw->image.blocks[0] << 8 | - asyw->image.blockh); - evo_data(push, asyw->image.kind << 16 | - asyw->image.format << 8); - evo_kick(push, &wndw->wndw); + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 13))) + return ret; + + PUSH_MTHD(push, NV507C, SET_PRESENT_CONTROL, + NVVAL(NV507C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | + NVVAL(NV507C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval)); + + PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]); + + if (asyw->image.format == NV507C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16) { + PUSH_MTHD(push, NV507C, SET_PROCESSING, + NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, ENABLE), + + SET_CONVERSION, + NVVAL(NV507C, SET_CONVERSION, GAIN, 0) | + NVVAL(NV507C, SET_CONVERSION, OFS, 0x64)); + } else { + PUSH_MTHD(push, NV507C, SET_PROCESSING, + NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE)); } + + PUSH_MTHD(push, NV507C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8); + + PUSH_MTHD(push, NV507C, SURFACE_SET_SIZE(0), + NVVAL(NV507C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NV507C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h), + + SURFACE_SET_STORAGE(0), + NVVAL(NV507C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout) | + NVVAL(NV507C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) | + NVVAL(NV507C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NV507C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh), + + SURFACE_SET_PARAMS(0), + NVVAL(NV507C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) | + NVDEF(NV507C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) | + NVDEF(NV507C, SURFACE_SET_PARAMS, GAMMA, LINEAR) | + NVDEF(NV507C, SURFACE_SET_PARAMS, LAYOUT, FRM) | + NVVAL(NV507C, SURFACE_SET_PARAMS, KIND, asyw->image.kind) | + NVDEF(NV507C, SURFACE_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256)); + return 0; } -void +int base507c_xlut_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x00e0, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507C, SET_BASE_LUT_LO, + NVDEF(NV507C, SET_BASE_LUT_LO, ENABLE, DISABLE)); + return 0; } -void +int base507c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x00e0, 1); - evo_data(push, 0x40000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507C, SET_BASE_LUT_LO, + NVDEF(NV507C, SET_BASE_LUT_LO, ENABLE, USE_CORE_LUT)); + return 0; } int @@ -115,66 +146,77 @@ base507c_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, struct nvif_device *device) { s64 time = nvif_msec(device, 2000ULL, - u32 data = nouveau_bo_rd32(bo, offset / 4); - if ((data & 0xc0000000) == 0x40000000) + if (NVBO_TD32(bo, offset, NV_DISP_BASE_NOTIFIER_1, _0, STATUS, ==, BEGUN)) break; usleep_range(1, 2); ); return time < 0 ? time : 0; } -void +int base507c_ntfy_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x00a4, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_NOTIFIER, 0x00000000); + return 0; } -void +int base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 3))) { - evo_mthd(push, 0x00a0, 2); - evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset); - evo_data(push, asyw->ntfy.handle); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 3))) + return ret; + + PUSH_MTHD(push, NV507C, SET_NOTIFIER_CONTROL, + NVVAL(NV507C, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken) | + NVVAL(NV507C, SET_NOTIFIER_CONTROL, OFFSET, asyw->ntfy.offset >> 2), + + SET_CONTEXT_DMA_NOTIFIER, asyw->ntfy.handle); + return 0; } void base507c_ntfy_reset(struct nouveau_bo *bo, u32 offset) { - nouveau_bo_wr32(bo, offset / 4, 0x00000000); + NVBO_WR32(bo, offset, NV_DISP_BASE_NOTIFIER_1, _0, + NVDEF(NV_DISP_BASE_NOTIFIER_1, _0, STATUS, NOT_BEGUN)); } -void +int base507c_sema_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x0094, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_SEMAPHORE, 0x00000000); + return 0; } -void +int base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 5))) { - evo_mthd(push, 0x0088, 4); - evo_data(push, asyw->sema.offset); - evo_data(push, asyw->sema.acquire); - evo_data(push, asyw->sema.release); - evo_data(push, asyw->sema.handle); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + PUSH_MTHD(push, NV507C, SET_SEMAPHORE_CONTROL, asyw->sema.offset, + SET_SEMAPHORE_ACQUIRE, asyw->sema.acquire, + SET_SEMAPHORE_RELEASE, asyw->sema.release, + SET_CONTEXT_DMA_SEMAPHORE, asyw->sema.handle); + return 0; } void @@ -282,8 +324,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format, return ret; } - ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, - false, NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, + ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsBaseNtfy", + wndw->notify.func, false, + NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, &(struct nvif_notify_uevent_req) {}, sizeof(struct nvif_notify_uevent_req), sizeof(struct nvif_notify_uevent_rep), diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c index f4c05949dd62..18d34096f125 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base827c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c @@ -21,36 +21,56 @@ */ #include "base.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl827c.h> + +static int base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 13))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, asyw->image.mode << 8 | - asyw->image.interval << 4); - evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle[0]); - if (asyw->image.format == 0xca) { - evo_mthd(push, 0x0110, 2); - evo_data(push, 1); - evo_data(push, 0x6400); - } else { - evo_mthd(push, 0x0110, 2); - evo_data(push, 0); - evo_data(push, 0); - } - evo_mthd(push, 0x0800, 5); - evo_data(push, asyw->image.offset[0] >> 8); - evo_data(push, 0x00000000); - evo_data(push, asyw->image.h << 16 | asyw->image.w); - evo_data(push, asyw->image.layout << 20 | - (asyw->image.pitch[0] >> 8) << 8 | - asyw->image.blocks[0] << 8 | - asyw->image.blockh); - evo_data(push, asyw->image.format << 8); - evo_kick(push, &wndw->wndw); + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 13))) + return ret; + + PUSH_MTHD(push, NV827C, SET_PRESENT_CONTROL, + NVVAL(NV827C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | + NVVAL(NV827C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval)); + + PUSH_MTHD(push, NV827C, SET_CONTEXT_DMAS_ISO(0), asyw->image.handle, 1); + + if (asyw->image.format == NV827C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16) { + PUSH_MTHD(push, NV827C, SET_PROCESSING, + NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, ENABLE), + + SET_CONVERSION, + NVVAL(NV827C, SET_CONVERSION, GAIN, 0) | + NVVAL(NV827C, SET_CONVERSION, OFS, 0x64)); + } else { + PUSH_MTHD(push, NV827C, SET_PROCESSING, + NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE)); } + + PUSH_MTHD(push, NV827C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8, + SURFACE_SET_OFFSET(0, 1), 0x00000000, + + SURFACE_SET_SIZE(0), + NVVAL(NV827C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NV827C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h), + + SURFACE_SET_STORAGE(0), + NVVAL(NV827C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) | + NVVAL(NV827C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) | + NVVAL(NV827C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NV827C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout), + + SURFACE_SET_PARAMS(0), + NVVAL(NV827C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) | + NVDEF(NV827C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) | + NVDEF(NV827C, SURFACE_SET_PARAMS, GAMMA, LINEAR) | + NVDEF(NV827C, SURFACE_SET_PARAMS, LAYOUT, FRM)); + return 0; } static const struct nv50_wndw_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c index 224a34c340fe..5396e3707cc4 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c @@ -21,58 +21,86 @@ */ #include "base.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl907c.h> + +static int base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 10))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, asyw->image.mode << 8 | - asyw->image.interval << 4); - evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle[0]); - evo_mthd(push, 0x0400, 5); - evo_data(push, asyw->image.offset[0] >> 8); - evo_data(push, 0x00000000); - evo_data(push, asyw->image.h << 16 | asyw->image.w); - evo_data(push, asyw->image.layout << 24 | - (asyw->image.pitch[0] >> 8) << 8 | - asyw->image.blocks[0] << 8 | - asyw->image.blockh); - evo_data(push, asyw->image.format << 8); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 10))) + return ret; + + PUSH_MTHD(push, NV907C, SET_PRESENT_CONTROL, + NVVAL(NV907C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | + NVDEF(NV907C, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE) | + NVVAL(NV907C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval)); + + PUSH_MTHD(push, NV907C, SET_CONTEXT_DMAS_ISO(0), asyw->image.handle, 1); + + PUSH_MTHD(push, NV907C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8, + SURFACE_SET_OFFSET(0, 1), 0x00000000, + + SURFACE_SET_SIZE(0), + NVVAL(NV907C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NV907C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h), + + SURFACE_SET_STORAGE(0), + NVVAL(NV907C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) | + NVVAL(NV907C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) | + NVVAL(NV907C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NV907C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout), + + SURFACE_SET_PARAMS(0), + NVVAL(NV907C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) | + NVDEF(NV907C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) | + NVDEF(NV907C, SURFACE_SET_PARAMS, GAMMA, LINEAR) | + NVDEF(NV907C, SURFACE_SET_PARAMS, LAYOUT, FRM)); + return 0; } -static void +static int base907c_xlut_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 6))) { - evo_mthd(push, 0x00e0, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x00e8, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x00fc, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 6))) + return ret; + + PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO, + NVDEF(NV907C, SET_BASE_LUT_LO, ENABLE, DISABLE)); + + PUSH_MTHD(push, NV907C, SET_OUTPUT_LUT_LO, + NVDEF(NV907C, SET_OUTPUT_LUT_LO, ENABLE, DISABLE)); + + PUSH_MTHD(push, NV907C, SET_CONTEXT_DMA_LUT, 0x00000000); + return 0; } -static void +static int base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 6))) { - evo_mthd(push, 0x00e0, 3); - evo_data(push, asyw->xlut.i.enable << 30 | - asyw->xlut.i.mode << 24); - evo_data(push, asyw->xlut.i.offset >> 8); - evo_data(push, 0x40000000); - evo_mthd(push, 0x00fc, 1); - evo_data(push, asyw->xlut.handle); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 6))) + return ret; + + PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO, + NVVAL(NV907C, SET_BASE_LUT_LO, ENABLE, asyw->xlut.i.enable) | + NVVAL(NV907C, SET_BASE_LUT_LO, MODE, asyw->xlut.i.mode), + + SET_BASE_LUT_HI, asyw->xlut.i.offset >> 8, + + SET_OUTPUT_LUT_LO, + NVDEF(NV907C, SET_OUTPUT_LUT_LO, ENABLE, USE_CORE_LUT)); + + PUSH_MTHD(push, NV907C, SET_CONTEXT_DMA_LUT, asyw->xlut.handle); + return 0; } static bool @@ -81,8 +109,12 @@ base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) if (size != 256 && size != 1024) return false; - asyw->xlut.i.mode = size == 1024 ? 4 : 7; - asyw->xlut.i.enable = 2; + if (size == 1024) + asyw->xlut.i.mode = NV907C_SET_BASE_LUT_LO_MODE_INTERPOLATE_1025_UNITY_RANGE; + else + asyw->xlut.i.mode = NV907C_SET_BASE_LUT_LO_MODE_INTERPOLATE_257_UNITY_RANGE; + + asyw->xlut.i.enable = NV907C_SET_BASE_LUT_LO_ENABLE_ENABLE; asyw->xlut.i.load = head907d_olut_load; return true; } @@ -125,28 +157,35 @@ base907c_csc(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, } } -static void +static int base907c_csc_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x0140, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV907C, SET_CSC_RED2RED, + NVDEF(NV907C, SET_CSC_RED2RED, OWNER, CORE)); + return 0; } -static void +static int base907c_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push, i; - if ((push = evo_wait(&wndw->wndw, 13))) { - evo_mthd(push, 0x0140, 12); - evo_data(push, asyw->csc.matrix[0] | 0x80000000); - for (i = 1; i < 12; i++) - evo_data(push, asyw->csc.matrix[i]); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 13))) + return ret; + + PUSH_MTHD(push, NV907C, SET_CSC_RED2RED, + NVDEF(NV907C, SET_CSC_RED2RED, OWNER, BASE) | + NVVAL(NV907C, SET_CSC_RED2RED, COEFF, asyw->csc.matrix[0]), + + SET_CSC_GRN2RED, &asyw->csc.matrix[1], 11); + return 0; } const struct nv50_wndw_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h b/drivers/gpu/drm/nouveau/dispnv50/core.h index e021cb340569..498622c0c670 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.h +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h @@ -15,15 +15,15 @@ int nv50_core_new(struct nouveau_drm *, struct nv50_core **); void nv50_core_del(struct nv50_core **); struct nv50_core_func { - void (*init)(struct nv50_core *); + int (*init)(struct nv50_core *); void (*ntfy_init)(struct nouveau_bo *, u32 offset); int (*caps_init)(struct nouveau_drm *, struct nv50_disp *); int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset, struct nvif_device *); - void (*update)(struct nv50_core *, u32 *interlock, bool ntfy); + int (*update)(struct nv50_core *, u32 *interlock, bool ntfy); struct { - void (*owner)(struct nv50_core *); + int (*owner)(struct nv50_core *); } wndw; const struct nv50_head_func *head; @@ -31,7 +31,7 @@ struct nv50_core_func { const struct nv50_crc_func *crc; #endif const struct nv50_outp_func { - void (*ctrl)(struct nv50_core *, int or, u32 ctrl, + int (*ctrl)(struct nv50_core *, int or, u32 ctrl, struct nv50_head_atom *); /* XXX: Only used by SORs and PIORs for now */ void (*get_caps)(struct nv50_disp *, @@ -42,11 +42,11 @@ struct nv50_core_func { int core507d_new(struct nouveau_drm *, s32, struct nv50_core **); int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32, struct nv50_core **); -void core507d_init(struct nv50_core *); +int core507d_init(struct nv50_core *); void core507d_ntfy_init(struct nouveau_bo *, u32); int core507d_caps_init(struct nouveau_drm *, struct nv50_disp *); int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); -void core507d_update(struct nv50_core *, u32 *, bool); +int core507d_update(struct nv50_core *, u32 *, bool); extern const struct nv50_outp_func dac507d; extern const struct nv50_outp_func sor507d; @@ -63,8 +63,8 @@ int core917d_new(struct nouveau_drm *, s32, struct nv50_core **); int corec37d_new(struct nouveau_drm *, s32, struct nv50_core **); int corec37d_caps_init(struct nouveau_drm *, struct nv50_disp *); int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); -void corec37d_update(struct nv50_core *, u32 *, bool); -void corec37d_wndw_owner(struct nv50_core *); +int corec37d_update(struct nv50_core *, u32 *, bool); +int corec37d_wndw_owner(struct nv50_core *); extern const struct nv50_outp_func sorc37d; int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **); diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c index 1d66f694b945..ad1f09a143aa 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c @@ -23,25 +23,36 @@ #include "head.h" #include <nvif/cl507d.h> +#include <nvif/push507c.h> #include <nvif/timer.h> +#include <nvhw/class/cl507d.h> + #include "nouveau_bo.h" -void +int core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy) { - u32 *push; - if ((push = evo_wait(&core->chan, 5))) { - if (ntfy) { - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x80000000 | NV50_DISP_CORE_NTFY); - } - evo_mthd(push, 0x0080, 2); - evo_data(push, interlock[NV50_DISP_INTERLOCK_BASE] | - interlock[NV50_DISP_INTERLOCK_OVLY]); - evo_data(push, 0x00000000); - evo_kick(push, &core->chan); + struct nvif_push *push = core->chan.push; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + if (ntfy) { + PUSH_MTHD(push, NV507D, SET_NOTIFIER_CONTROL, + NVDEF(NV507D, SET_NOTIFIER_CONTROL, MODE, WRITE) | + NVVAL(NV507D, SET_NOTIFIER_CONTROL, OFFSET, NV50_DISP_CORE_NTFY >> 2) | + NVDEF(NV507D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE)); } + + PUSH_MTHD(push, NV507D, UPDATE, interlock[NV50_DISP_INTERLOCK_BASE] | + interlock[NV50_DISP_INTERLOCK_OVLY] | + NVDEF(NV507D, UPDATE, NOT_DRIVER_FRIENDLY, FALSE) | + NVDEF(NV507D, UPDATE, NOT_DRIVER_UNFRIENDLY, FALSE) | + NVDEF(NV507D, UPDATE, INHIBIT_INTERRUPTS, FALSE)); + + return PUSH_KICK(push); } int @@ -49,7 +60,7 @@ core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, struct nvif_device *device) { s64 time = nvif_msec(device, 2000ULL, - if (nouveau_bo_rd32(bo, offset / 4)) + if (NVBO_TD32(bo, offset, NV_DISP_CORE_NOTIFIER_1, COMPLETION_0, DONE, ==, TRUE)) break; usleep_range(1, 2); ); @@ -59,32 +70,34 @@ core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, void core507d_ntfy_init(struct nouveau_bo *bo, u32 offset) { - nouveau_bo_wr32(bo, offset / 4, 0x00000000); + NVBO_WR32(bo, offset, NV_DISP_CORE_NOTIFIER_1, COMPLETION_0, + NVDEF(NV_DISP_CORE_NOTIFIER_1, COMPLETION_0, DONE, FALSE)); } int core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) { - u32 *push = evo_wait(&disp->core->chan, 2); + struct nvif_push *push = disp->core->chan.push; + int ret; - if (push) { - evo_mthd(push, 0x008c, 1); - evo_data(push, 0x0); - evo_kick(push, &disp->core->chan); - } + if ((ret = PUSH_WAIT(push, 2))) + return ret; - return 0; + PUSH_MTHD(push, NV507D, GET_CAPABILITIES, 0x00000000); + return PUSH_KICK(push); } -void +int core507d_init(struct nv50_core *core) { - u32 *push; - if ((push = evo_wait(&core->chan, 2))) { - evo_mthd(push, 0x0088, 1); - evo_data(push, core->chan.sync.handle); - evo_kick(push, &core->chan); - } + struct nvif_push *push = core->chan.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle); + return PUSH_KICK(push); } static const struct nv50_core_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/corec37d.c b/drivers/gpu/drm/nouveau/dispnv50/corec37d.c index ec83189a1d48..9035d3ab062c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/corec37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/corec37d.c @@ -23,56 +23,67 @@ #include "head.h" #include <nvif/class.h> -#include <nouveau_bo.h> - +#include <nvif/pushc37b.h> #include <nvif/timer.h> -void +#include <nvhw/class/clc37d.h> + +#include <nouveau_bo.h> + +int corec37d_wndw_owner(struct nv50_core *core) { + struct nvif_push *push = core->chan.push; const u32 windows = 8; /*XXX*/ - u32 *push, i; - if ((push = evo_wait(&core->chan, 2 * windows))) { - for (i = 0; i < windows; i++) { - evo_mthd(push, 0x1000 + (i * 0x080), 1); - evo_data(push, i >> 1); - } - evo_kick(push, &core->chan); + int ret, i; + + if ((ret = PUSH_WAIT(push, windows * 2))) + return ret; + + for (i = 0; i < windows; i++) { + PUSH_MTHD(push, NVC37D, WINDOW_SET_CONTROL(i), + NVDEF(NVC37D, WINDOW_SET_CONTROL, OWNER, HEAD(i >> 1))); } + + return 0; } -void +int corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy) { - u32 *push; - if ((push = evo_wait(&core->chan, 9))) { - if (ntfy) { - evo_mthd(push, 0x020c, 1); - evo_data(push, 0x00001000 | NV50_DISP_CORE_NTFY); - } - - evo_mthd(push, 0x0218, 2); - evo_data(push, interlock[NV50_DISP_INTERLOCK_CURS]); - evo_data(push, interlock[NV50_DISP_INTERLOCK_WNDW]); - evo_mthd(push, 0x0200, 1); - evo_data(push, 0x00000001); - - if (ntfy) { - evo_mthd(push, 0x020c, 1); - evo_data(push, 0x00000000); - } - evo_kick(push, &core->chan); + struct nvif_push *push = core->chan.push; + int ret; + + if ((ret = PUSH_WAIT(push, 9))) + return ret; + + if (ntfy) { + PUSH_MTHD(push, NVC37D, SET_NOTIFIER_CONTROL, + NVDEF(NVC37D, SET_NOTIFIER_CONTROL, MODE, WRITE) | + NVVAL(NVC37D, SET_NOTIFIER_CONTROL, OFFSET, NV50_DISP_CORE_NTFY >> 4) | + NVDEF(NVC37D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE)); } + + PUSH_MTHD(push, NVC37D, SET_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_CURS], + SET_WINDOW_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_WNDW]); + PUSH_MTHD(push, NVC37D, UPDATE, 0x00000001 | + NVDEF(NVC37D, UPDATE, SPECIAL_HANDLING, NONE) | + NVDEF(NVC37D, UPDATE, INHIBIT_INTERRUPTS, FALSE)); + + if (ntfy) { + PUSH_MTHD(push, NVC37D, SET_NOTIFIER_CONTROL, + NVDEF(NVC37D, SET_NOTIFIER_CONTROL, NOTIFY, DISABLE)); + } + + return PUSH_KICK(push); } int corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, struct nvif_device *device) { - u32 data; s64 time = nvif_msec(device, 2000ULL, - data = nouveau_bo_rd32(bo, offset / 4 + 0); - if ((data & 0xc0000000) == 0x80000000) + if (NVBO_TD32(bo, offset, NV_DISP_NOTIFIER, _0, STATUS, ==, FINISHED)) break; usleep_range(1, 2); ); @@ -82,18 +93,19 @@ corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, void corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset) { - nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000); - nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000); - nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000); - nouveau_bo_wr32(bo, offset / 4 + 3, 0x00000000); + NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _0, + NVDEF(NV_DISP_NOTIFIER, _0, STATUS, NOT_BEGUN)); + NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _1, 0); + NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _2, 0); + NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _3, 0); } int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) { int ret; - ret = nvif_object_init(&disp->disp->object, 0, GV100_DISP_CAPS, - NULL, 0, &disp->caps); + ret = nvif_object_ctor(&disp->disp->object, "dispCaps", 0, + GV100_DISP_CAPS, NULL, 0, &disp->caps); if (ret) { NV_ERROR(drm, "Failed to init notifier caps region: %d\n", @@ -112,24 +124,37 @@ int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) return 0; } -static void +static int corec37d_init(struct nv50_core *core) { + struct nvif_push *push = core->chan.push; const u32 windows = 8; /*XXX*/ - u32 *push, i; - if ((push = evo_wait(&core->chan, 2 + 5 * windows))) { - evo_mthd(push, 0x0208, 1); - evo_data(push, core->chan.sync.handle); - for (i = 0; i < windows; i++) { - evo_mthd(push, 0x1004 + (i * 0x080), 2); - evo_data(push, 0x0000001f); - evo_data(push, 0x00000000); - evo_mthd(push, 0x1010 + (i * 0x080), 1); - evo_data(push, 0x00127fff); - } - evo_kick(push, &core->chan); - core->assign_windows = true; + int ret, i; + + if ((ret = PUSH_WAIT(push, 2 + windows * 5))) + return ret; + + PUSH_MTHD(push, NVC37D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle); + + for (i = 0; i < windows; i++) { + PUSH_MTHD(push, NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i), + NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) | + NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) | + NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) | + NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED8BPP, TRUE) | + NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, YUV_PACKED422, TRUE), + + WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS(i), 0x00000000); + + PUSH_MTHD(push, NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS(i), + NVVAL(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, MAX_PIXELS_FETCHED_PER_LINE, 0x7fff) | + NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_LUT, USAGE_1025) | + NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_SCALER_TAPS, TAPS_2) | + NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, UPSCALING_ALLOWED, FALSE)); } + + core->assign_windows = true; + return PUSH_KICK(push); } static const struct nv50_core_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/corec57d.c b/drivers/gpu/drm/nouveau/dispnv50/corec57d.c index e1c11eba0ce1..75876546eac1 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/corec57d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/corec57d.c @@ -22,24 +22,40 @@ #include "core.h" #include "head.h" -static void +#include <nvif/pushc37b.h> + +#include <nvhw/class/clc57d.h> + +static int corec57d_init(struct nv50_core *core) { + struct nvif_push *push = core->chan.push; const u32 windows = 8; /*XXX*/ - u32 *push, i; - if ((push = evo_wait(&core->chan, 2 + 5 * windows))) { - evo_mthd(push, 0x0208, 1); - evo_data(push, core->chan.sync.handle); - for (i = 0; i < windows; i++) { - evo_mthd(push, 0x1004 + (i * 0x080), 2); - evo_data(push, 0x0000000f); - evo_data(push, 0x00000000); - evo_mthd(push, 0x1010 + (i * 0x080), 1); - evo_data(push, 0x00117fff); - } - evo_kick(push, &core->chan); - core->assign_windows = true; + int ret, i; + + if ((ret = PUSH_WAIT(push, 2 + windows * 5))) + return ret; + + PUSH_MTHD(push, NVC57D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle); + + for (i = 0; i < windows; i++) { + PUSH_MTHD(push, NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i), + NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) | + NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) | + NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) | + NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED8BPP, TRUE), + + WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS(i), 0x00000000); + + PUSH_MTHD(push, NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS(i), + NVVAL(NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS, MAX_PIXELS_FETCHED_PER_LINE, 0x7fff) | + NVDEF(NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS, ILUT_ALLOWED, TRUE) | + NVDEF(NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_SCALER_TAPS, TAPS_2) | + NVDEF(NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS, UPSCALING_ALLOWED, FALSE)); } + + core->assign_windows = true; + return PUSH_KICK(push); } static const struct nv50_core_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.c b/drivers/gpu/drm/nouveau/dispnv50/crc.c index f17fb6d56757..b8c31b697797 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/crc.c +++ b/drivers/gpu/drm/nouveau/dispnv50/crc.c @@ -9,6 +9,8 @@ #include <nvif/cl0002.h> #include <nvif/timer.h> +#include <nvhw/class/cl907d.h> + #include "nouveau_drv.h" #include "core.h" #include "head.h" @@ -478,10 +480,6 @@ void nv50_crc_atomic_clr(struct nv50_head *head) func->set_src(head, 0, NV50_CRC_SOURCE_TYPE_NONE, NULL, 0); } -#define NV50_CRC_RASTER_ACTIVE 0 -#define NV50_CRC_RASTER_COMPLETE 1 -#define NV50_CRC_RASTER_INACTIVE 2 - static inline int nv50_crc_raster_type(enum nv50_crc_source source) { @@ -490,11 +488,11 @@ nv50_crc_raster_type(enum nv50_crc_source source) case NV50_CRC_SOURCE_AUTO: case NV50_CRC_SOURCE_RG: case NV50_CRC_SOURCE_OUTP_ACTIVE: - return NV50_CRC_RASTER_ACTIVE; + return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_ACTIVE_RASTER; case NV50_CRC_SOURCE_OUTP_COMPLETE: - return NV50_CRC_RASTER_COMPLETE; + return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_COMPLETE_RASTER; case NV50_CRC_SOURCE_OUTP_INACTIVE: - return NV50_CRC_RASTER_INACTIVE; + return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_NON_ACTIVE_RASTER; } return 0; @@ -510,11 +508,11 @@ nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu, struct nv50_core *core = nv50_disp(head->base.base.dev)->core; int ret; - ret = nvif_mem_init_map(mmu, NVIF_MEM_VRAM, len, &ctx->mem); + ret = nvif_mem_ctor_map(mmu, "kmsCrcNtfy", NVIF_MEM_VRAM, len, &ctx->mem); if (ret) return ret; - ret = nvif_object_init(&core->chan.base.user, + ret = nvif_object_ctor(&core->chan.base.user, "kmsCrcNtfyCtxDma", NV50_DISP_HANDLE_CRC_CTX(head, idx), NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { @@ -531,15 +529,15 @@ nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu, return 0; fail_fini: - nvif_mem_fini(&ctx->mem); + nvif_mem_dtor(&ctx->mem); return ret; } static inline void nv50_crc_ctx_fini(struct nv50_crc_notifier_ctx *ctx) { - nvif_object_fini(&ctx->ntfy); - nvif_mem_fini(&ctx->mem); + nvif_object_dtor(&ctx->ntfy); + nvif_mem_dtor(&ctx->mem); } int nv50_crc_set_source(struct drm_crtc *crtc, const char *source_str) diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.h b/drivers/gpu/drm/nouveau/dispnv50/crc.h index 4bc59e779315..4fce871b04c8 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/crc.h +++ b/drivers/gpu/drm/nouveau/dispnv50/crc.h @@ -50,9 +50,9 @@ struct nv50_crc_atom { }; struct nv50_crc_func { - void (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type, - struct nv50_crc_notifier_ctx *, u32 wndw); - void (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *); + int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type, + struct nv50_crc_notifier_ctx *, u32 wndw); + int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *); u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *, enum nv50_crc_source, int idx); bool (*ctx_finished)(struct nv50_head *, @@ -106,26 +106,27 @@ struct nv50_crc_atom {}; #define nv50_crc_set_source NULL static inline void nv50_crc_init(struct drm_device *dev) {} -static inline int nv50_head_crc_late_register(struct nv50_head *) {} -static inline void -nv50_crc_handle_vblank(struct nv50_head *head) { return 0; } +static inline int +nv50_head_crc_late_register(struct nv50_head *head) { return 0; } +static inline void nv50_crc_handle_vblank(struct nv50_head *head) {} static inline int -nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *, - struct nv50_head_atom *) {} +nv50_crc_atomic_check_head(struct nv50_head *head, + struct nv50_head_atom *asyh, + struct nv50_head_atom *armh) { return 0; } static inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {} static inline void -nv50_crc_atomic_stop_reporting(struct drm_atomic_state *) {} +nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {} static inline void -nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *) {} +nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {} static inline void -nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *) {} +nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {} static inline void -nv50_crc_atomic_start_reporting(struct drm_atomic_state *) {} +nv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {} static inline void -nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *) {} +nv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {} static inline void -nv50_crc_atomic_clr(struct nv50_head *) {} +nv50_crc_atomic_clr(struct nv50_head *head) {} #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ #endif /* !__NV50_CRC_H__ */ diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc907d.c b/drivers/gpu/drm/nouveau/dispnv50/crc907d.c index 92e907de7645..0fb0fdb9f119 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/crc907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/crc907d.c @@ -6,6 +6,10 @@ #include "disp.h" #include "head.h" +#include <nvif/push507c.h> + +#include <nvhw/class/cl907d.h> + #define CRC907D_MAX_ENTRIES 255 struct crc907d_notifier { @@ -18,68 +22,67 @@ struct crc907d_notifier { } entries[CRC907D_MAX_ENTRIES]; } __packed; -static void +static int crc907d_set_src(struct nv50_head *head, int or, enum nv50_crc_source_type source, struct nv50_crc_notifier_ctx *ctx, u32 wndw) { - struct drm_crtc *crtc = &head->base.base; - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - const u32 hoff = head->base.index * 0x300; - u32 *push; - u32 crc_args = 0xfff00000; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + u32 crc_args = NVDEF(NV907D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, CORE) | + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, EXPECT_BUFFER_COLLAPSE, FALSE) | + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, TIMESTAMP_MODE, FALSE) | + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, SECONDARY_OUTPUT, NONE) | + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, CRC_DURING_SNOOZE, DISABLE); + int ret; switch (source) { case NV50_CRC_SOURCE_TYPE_SOR: - crc_args |= (0x00000f0f + or * 16) << 8; + crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, SOR(or)); break; case NV50_CRC_SOURCE_TYPE_PIOR: - crc_args |= (0x000000ff + or * 256) << 8; + crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, PIOR(or)); break; case NV50_CRC_SOURCE_TYPE_DAC: - crc_args |= (0x00000ff0 + or) << 8; + crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, DAC(or)); break; case NV50_CRC_SOURCE_TYPE_RG: - crc_args |= (0x00000ff8 + drm_crtc_index(crtc)) << 8; + crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, RG(i)); break; case NV50_CRC_SOURCE_TYPE_SF: - crc_args |= (0x00000f8f + drm_crtc_index(crtc) * 16) << 8; + crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, SF(i)); break; case NV50_CRC_SOURCE_NONE: - crc_args |= 0x000fff00; + crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, NONE); break; } - push = evo_wait(core, 4); - if (!push) - return; + if ((ret = PUSH_WAIT(push, 4))) + return ret; if (source) { - evo_mthd(push, 0x0438 + hoff, 1); - evo_data(push, ctx->ntfy.handle); - evo_mthd(push, 0x0430 + hoff, 1); - evo_data(push, crc_args); + PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx->ntfy.handle); + PUSH_MTHD(push, NV907D, HEAD_SET_CRC_CONTROL(i), crc_args); } else { - evo_mthd(push, 0x0430 + hoff, 1); - evo_data(push, crc_args); - evo_mthd(push, 0x0438 + hoff, 1); - evo_data(push, 0); + PUSH_MTHD(push, NV907D, HEAD_SET_CRC_CONTROL(i), crc_args); + PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), 0); } - evo_kick(push, core); + + return 0; } -static void crc907d_set_ctx(struct nv50_head *head, - struct nv50_crc_notifier_ctx *ctx) +static int +crc907d_set_ctx(struct nv50_head *head, struct nv50_crc_notifier_ctx *ctx) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push = evo_wait(core, 2); + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; - if (!push) - return; + if ((ret = PUSH_WAIT(push, 2))) + return ret; - evo_mthd(push, 0x0438 + (head->base.index * 0x300), 1); - evo_data(push, ctx ? ctx->ntfy.handle : 0); - evo_kick(push, core); + PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx ? ctx->ntfy.handle : 0); + return 0; } static u32 crc907d_get_entry(struct nv50_head *head, diff --git a/drivers/gpu/drm/nouveau/dispnv50/crcc37d.c b/drivers/gpu/drm/nouveau/dispnv50/crcc37d.c index 940cefd5517d..9afe9a87bde0 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/crcc37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/crcc37d.c @@ -6,6 +6,10 @@ #include "disp.h" #include "head.h" +#include <nvif/push507c.h> + +#include <nvhw/class/clc37d.h> + #define CRCC37D_MAX_ENTRIES 2047 struct crcc37d_notifier { @@ -30,62 +34,59 @@ struct crcc37d_notifier { } entries[CRCC37D_MAX_ENTRIES]; } __packed; -static void +static int crcc37d_set_src(struct nv50_head *head, int or, enum nv50_crc_source_type source, struct nv50_crc_notifier_ctx *ctx, u32 wndw) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - const u32 hoff = head->base.index * 0x400; - u32 *push; - u32 crc_args; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + u32 crc_args = NVVAL(NVC37D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, wndw) | + NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, EXPECT_BUFFER_COLLAPSE, FALSE) | + NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, SECONDARY_CRC, NONE) | + NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, CRC_DURING_SNOOZE, DISABLE); + int ret; switch (source) { case NV50_CRC_SOURCE_TYPE_SOR: - crc_args = (0x00000050 + or) << 12; + crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, SOR(or)); break; case NV50_CRC_SOURCE_TYPE_PIOR: - crc_args = (0x00000060 + or) << 12; + crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, PIOR(or)); break; case NV50_CRC_SOURCE_TYPE_SF: - crc_args = 0x00000030 << 12; + crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, SF); break; default: - crc_args = 0; break; } - push = evo_wait(core, 4); - if (!push) - return; + if ((ret = PUSH_WAIT(push, 4))) + return ret; if (source) { - evo_mthd(push, 0x2180 + hoff, 1); - evo_data(push, ctx->ntfy.handle); - evo_mthd(push, 0x2184 + hoff, 1); - evo_data(push, crc_args | wndw); + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx->ntfy.handle); + PUSH_MTHD(push, NVC37D, HEAD_SET_CRC_CONTROL(i), crc_args); } else { - evo_mthd(push, 0x2184 + hoff, 1); - evo_data(push, 0); - evo_mthd(push, 0x2180 + hoff, 1); - evo_data(push, 0); + PUSH_MTHD(push, NVC37D, HEAD_SET_CRC_CONTROL(i), 0); + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), 0); } - evo_kick(push, core); + return 0; } -static void crcc37d_set_ctx(struct nv50_head *head, - struct nv50_crc_notifier_ctx *ctx) +static int +crcc37d_set_ctx(struct nv50_head *head, struct nv50_crc_notifier_ctx *ctx) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push = evo_wait(core, 2); + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; - if (!push) - return; + if ((ret = PUSH_WAIT(push, 2))) + return ret; - evo_mthd(push, 0x2180 + (head->base.index * 0x400), 1); - evo_data(push, ctx ? ctx->ntfy.handle : 0); - evo_kick(push, core); + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx ? ctx->ntfy.handle : 0); + return 0; } static u32 crcc37d_get_entry(struct nv50_head *head, diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index 658a200ab616..54fbd6fe751d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -26,6 +26,8 @@ #include <nvif/cl507a.h> #include <nvif/timer.h> +#include <nvhw/class/cl507a.h> + #include <drm/drm_atomic_helper.h> #include <drm/drm_plane_helper.h> @@ -33,27 +35,37 @@ bool curs507a_space(struct nv50_wndw *wndw) { nvif_msec(&nouveau_drm(wndw->plane.dev)->client.device, 100, - if (nvif_rd32(&wndw->wimm.base.user, 0x0008) >= 4) + if (NVIF_TV32(&wndw->wimm.base.user, NV507A, FREE, COUNT, >=, 4)) return true; ); + WARN_ON(1); return false; } -static void +static int curs507a_update(struct nv50_wndw *wndw, u32 *interlock) { - if (curs507a_space(wndw)) - nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000); + struct nvif_object *user = &wndw->wimm.base.user; + int ret = nvif_chan_wait(&wndw->wimm, 1); + if (ret == 0) { + NVIF_WR32(user, NV507A, UPDATE, + NVDEF(NV507A, UPDATE, INTERLOCK_WITH_CORE, DISABLE)); + } + return ret; } -static void +static int curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - if (curs507a_space(wndw)) { - nvif_wr32(&wndw->wimm.base.user, 0x0084, asyw->point.y << 16 | - asyw->point.x); + struct nvif_object *user = &wndw->wimm.base.user; + int ret = nvif_chan_wait(&wndw->wimm, 1); + if (ret == 0) { + NVIF_WR32(user, NV507A, SET_CURSOR_HOT_SPOT_POINT_OUT, + NVVAL(NV507A, SET_CURSOR_HOT_SPOT_POINT_OUT, X, asyw->point.x) | + NVVAL(NV507A, SET_CURSOR_HOT_SPOT_POINT_OUT, Y, asyw->point.y)); } + return ret; } const struct nv50_wimm_func @@ -138,8 +150,8 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, if (*pwndw = wndw, ret) return ret; - ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, - sizeof(args), &wndw->wimm.base.user); + ret = nvif_object_ctor(&disp->disp->object, "kmsCurs", 0, oclass, + &args, sizeof(args), &wndw->wimm.base.user); if (ret) { NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret); return ret; diff --git a/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c b/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c index 96dff4f09f57..e39d08698c63 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c @@ -22,20 +22,29 @@ #include "curs.h" #include "atom.h" -static void +#include <nvhw/class/clc37a.h> + +static int cursc37a_update(struct nv50_wndw *wndw, u32 *interlock) { - if (curs507a_space(wndw)) - nvif_wr32(&wndw->wimm.base.user, 0x0200, 0x00000001); + struct nvif_object *user = &wndw->wimm.base.user; + int ret = nvif_chan_wait(&wndw->wimm, 1); + if (ret == 0) + NVIF_WR32(user, NVC37A, UPDATE, 0x00000001); + return ret; } -static void +static int cursc37a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - if (curs507a_space(wndw)) { - nvif_wr32(&wndw->wimm.base.user, 0x0208, asyw->point.y << 16 | - asyw->point.x); + struct nvif_object *user = &wndw->wimm.base.user; + int ret = nvif_chan_wait(&wndw->wimm, 1); + if (ret == 0) { + NVIF_WR32(user, NVC37A, SET_CURSOR_HOT_SPOT_POINT_OUT(0), + NVVAL(NVC37A, SET_CURSOR_HOT_SPOT_POINT_OUT, X, asyw->point.x) | + NVVAL(NVC37A, SET_CURSOR_HOT_SPOT_POINT_OUT, Y, asyw->point.y)); } + return ret; } static const struct nv50_wimm_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/dac507d.c b/drivers/gpu/drm/nouveau/dispnv50/dac507d.c index 2a10ef7d30a8..09de78d96679 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/dac507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/dac507d.c @@ -21,21 +21,29 @@ */ #include "core.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl507d.h> + +static int dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { - u32 *push, sync = 0; - if ((push = evo_wait(&core->chan, 3))) { - if (asyh) { - sync |= asyh->or.nvsync << 1; - sync |= asyh->or.nhsync; - } - evo_mthd(push, 0x0400 + (or * 0x080), 2); - evo_data(push, ctrl); - evo_data(push, sync); - evo_kick(push, &core->chan); + struct nvif_push *push = core->chan.push; + u32 sync = 0; + int ret; + + if (asyh) { + sync |= NVVAL(NV507D, DAC_SET_POLARITY, HSYNC, asyh->or.nhsync); + sync |= NVVAL(NV507D, DAC_SET_POLARITY, VSYNC, asyh->or.nvsync); } + + if ((ret = PUSH_WAIT(push, 3))) + return ret; + + PUSH_MTHD(push, NV507D, DAC_SET_CONTROL(or), ctrl, + DAC_SET_POLARITY(or), sync); + return 0; } const struct nv50_outp_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/dac907d.c b/drivers/gpu/drm/nouveau/dispnv50/dac907d.c index 11e87fa53fac..95efa625b691 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/dac907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/dac907d.c @@ -21,16 +21,22 @@ */ #include "core.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl907d.h> + +static int dac907d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { - u32 *push; - if ((push = evo_wait(&core->chan, 2))) { - evo_mthd(push, 0x0180 + (or * 0x020), 1); - evo_data(push, ctrl); - evo_kick(push, &core->chan); - } + struct nvif_push *push = core->chan.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV907D, DAC_SET_CONTROL(or), ctrl); + return 0; } const struct nv50_outp_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index cd71b9876c8a..e7874877da85 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -41,6 +41,8 @@ #include <drm/drm_scdc_helper.h> #include <drm/drm_vblank.h> +#include <nvif/push507c.h> + #include <nvif/class.h> #include <nvif/cl0002.h> #include <nvif/cl5070.h> @@ -48,6 +50,13 @@ #include <nvif/event.h> #include <nvif/timer.h> +#include <nvhw/class/cl507c.h> +#include <nvhw/class/cl507d.h> +#include <nvhw/class/cl837d.h> +#include <nvhw/class/cl887d.h> +#include <nvhw/class/cl907d.h> +#include <nvhw/class/cl917d.h> + #include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_gem.h" @@ -79,8 +88,9 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp, while (oclass[0]) { for (i = 0; i < n; i++) { if (sclass[i].oclass == oclass[0]) { - ret = nvif_object_init(disp, 0, oclass[0], - data, size, &chan->user); + ret = nvif_object_ctor(disp, "kmsChan", 0, + oclass[0], data, size, + &chan->user); if (ret == 0) nvif_object_map(&chan->user, NULL, 0); nvif_object_sclass_put(&sclass); @@ -97,7 +107,7 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp, static void nv50_chan_destroy(struct nv50_chan *chan) { - nvif_object_fini(&chan->user); + nvif_object_dtor(&chan->user); } /****************************************************************************** @@ -107,12 +117,106 @@ nv50_chan_destroy(struct nv50_chan *chan) void nv50_dmac_destroy(struct nv50_dmac *dmac) { - nvif_object_fini(&dmac->vram); - nvif_object_fini(&dmac->sync); + nvif_object_dtor(&dmac->vram); + nvif_object_dtor(&dmac->sync); nv50_chan_destroy(&dmac->base); - nvif_mem_fini(&dmac->push); + nvif_mem_dtor(&dmac->_push.mem); +} + +static void +nv50_dmac_kick(struct nvif_push *push) +{ + struct nv50_dmac *dmac = container_of(push, typeof(*dmac), _push); + + dmac->cur = push->cur - (u32 *)dmac->_push.mem.object.map.ptr; + if (dmac->put != dmac->cur) { + /* Push buffer fetches are not coherent with BAR1, we need to ensure + * writes have been flushed right through to VRAM before writing PUT. + */ + if (dmac->push->mem.type & NVIF_MEM_VRAM) { + struct nvif_device *device = dmac->base.device; + nvif_wr32(&device->object, 0x070000, 0x00000001); + nvif_msec(device, 2000, + if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002)) + break; + ); + } + + NVIF_WV32(&dmac->base.user, NV507C, PUT, PTR, dmac->cur); + dmac->put = dmac->cur; + } + + push->bgn = push->cur; +} + +static int +nv50_dmac_free(struct nv50_dmac *dmac) +{ + u32 get = NVIF_RV32(&dmac->base.user, NV507C, GET, PTR); + if (get > dmac->cur) /* NVIDIA stay 5 away from GET, do the same. */ + return get - dmac->cur - 5; + return dmac->max - dmac->cur; +} + +static int +nv50_dmac_wind(struct nv50_dmac *dmac) +{ + /* Wait for GET to depart from the beginning of the push buffer to + * prevent writing PUT == GET, which would be ignored by HW. + */ + u32 get = NVIF_RV32(&dmac->base.user, NV507C, GET, PTR); + if (get == 0) { + /* Corner-case, HW idle, but non-committed work pending. */ + if (dmac->put == 0) + nv50_dmac_kick(dmac->push); + + if (nvif_msec(dmac->base.device, 2000, + if (NVIF_TV32(&dmac->base.user, NV507C, GET, PTR, >, 0)) + break; + ) < 0) + return -ETIMEDOUT; + } + + PUSH_RSVD(dmac->push, PUSH_JUMP(dmac->push, 0)); + dmac->cur = 0; + return 0; +} + +static int +nv50_dmac_wait(struct nvif_push *push, u32 size) +{ + struct nv50_dmac *dmac = container_of(push, typeof(*dmac), _push); + int free; + + if (WARN_ON(size > dmac->max)) + return -EINVAL; + + dmac->cur = push->cur - (u32 *)dmac->_push.mem.object.map.ptr; + if (dmac->cur + size >= dmac->max) { + int ret = nv50_dmac_wind(dmac); + if (ret) + return ret; + + push->cur = dmac->_push.mem.object.map.ptr; + push->cur = push->cur + dmac->cur; + nv50_dmac_kick(push); + } + + if (nvif_msec(dmac->base.device, 2000, + if ((free = nv50_dmac_free(dmac)) >= size) + break; + ) < 0) { + WARN_ON(1); + return -ETIMEDOUT; + } + + push->bgn = dmac->_push.mem.object.map.ptr; + push->bgn = push->bgn + dmac->cur; + push->cur = push->bgn; + push->end = push->cur + free; + return 0; } int @@ -139,13 +243,21 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, if (device->info.family == NV_DEVICE_INFO_V0_PASCAL) type |= NVIF_MEM_VRAM; - ret = nvif_mem_init_map(&cli->mmu, type, 0x1000, &dmac->push); + ret = nvif_mem_ctor_map(&cli->mmu, "kmsChanPush", type, 0x1000, + &dmac->_push.mem); if (ret) return ret; - dmac->ptr = dmac->push.object.map.ptr; + dmac->ptr = dmac->_push.mem.object.map.ptr; + dmac->_push.wait = nv50_dmac_wait; + dmac->_push.kick = nv50_dmac_kick; + dmac->push = &dmac->_push; + dmac->push->bgn = dmac->_push.mem.object.map.ptr; + dmac->push->cur = dmac->push->bgn; + dmac->push->end = dmac->push->bgn; + dmac->max = 0x1000/4 - 1; - args->pushbuf = nvif_handle(&dmac->push.object); + args->pushbuf = nvif_handle(&dmac->_push.mem.object); ret = nv50_chan_create(device, disp, oclass, head, data, size, &dmac->base); @@ -155,7 +267,7 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, if (!syncbuf) return 0; - ret = nvif_object_init(&dmac->base.user, NV50_DISP_HANDLE_SYNCBUF, + ret = nvif_object_ctor(&dmac->base.user, "kmsSyncCtxDma", NV50_DISP_HANDLE_SYNCBUF, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, @@ -167,7 +279,7 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, if (ret) return ret; - ret = nvif_object_init(&dmac->base.user, NV50_DISP_HANDLE_VRAM, + ret = nvif_object_ctor(&dmac->base.user, "kmsVramCtxDma", NV50_DISP_HANDLE_VRAM, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, @@ -183,64 +295,6 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, } /****************************************************************************** - * EVO channel helpers - *****************************************************************************/ -static void -evo_flush(struct nv50_dmac *dmac) -{ - /* Push buffer fetches are not coherent with BAR1, we need to ensure - * writes have been flushed right through to VRAM before writing PUT. - */ - if (dmac->push.type & NVIF_MEM_VRAM) { - struct nvif_device *device = dmac->base.device; - nvif_wr32(&device->object, 0x070000, 0x00000001); - nvif_msec(device, 2000, - if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002)) - break; - ); - } -} - -u32 * -evo_wait(struct nv50_dmac *evoc, int nr) -{ - struct nv50_dmac *dmac = evoc; - struct nvif_device *device = dmac->base.device; - u32 put = nvif_rd32(&dmac->base.user, 0x0000) / 4; - - mutex_lock(&dmac->lock); - if (put + nr >= (PAGE_SIZE / 4) - 8) { - dmac->ptr[put] = 0x20000000; - evo_flush(dmac); - - nvif_wr32(&dmac->base.user, 0x0000, 0x00000000); - if (nvif_msec(device, 2000, - if (!nvif_rd32(&dmac->base.user, 0x0004)) - break; - ) < 0) { - mutex_unlock(&dmac->lock); - pr_err("nouveau: evo channel stalled\n"); - return NULL; - } - - put = 0; - } - - return dmac->ptr + put; -} - -void -evo_kick(u32 *push, struct nv50_dmac *evoc) -{ - struct nv50_dmac *dmac = evoc; - - evo_flush(dmac); - - nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2); - mutex_unlock(&dmac->lock); -} - -/****************************************************************************** * Output path helpers *****************************************************************************/ static void @@ -365,8 +419,9 @@ nv50_dac_disable(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nv50_core *core = nv50_disp(encoder->dev)->core; + const u32 ctrl = NVDEF(NV507D, DAC_SET_CONTROL, OWNER, NONE); if (nv_encoder->crtc) - core->func->dac->ctrl(core, nv_encoder->or, 0x00000000, NULL); + core->func->dac->ctrl(core, nv_encoder->or, ctrl, NULL); nv_encoder->crtc = NULL; nv50_outp_release(nv_encoder); } @@ -378,10 +433,23 @@ nv50_dac_enable(struct drm_encoder *encoder) struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nv50_head_atom *asyh = nv50_head_atom(nv_crtc->base.state); struct nv50_core *core = nv50_disp(encoder->dev)->core; + u32 ctrl = 0; + + switch (nv_crtc->index) { + case 0: ctrl |= NVDEF(NV507D, DAC_SET_CONTROL, OWNER, HEAD0); break; + case 1: ctrl |= NVDEF(NV507D, DAC_SET_CONTROL, OWNER, HEAD1); break; + case 2: ctrl |= NVDEF(NV907D, DAC_SET_CONTROL, OWNER_MASK, HEAD2); break; + case 3: ctrl |= NVDEF(NV907D, DAC_SET_CONTROL, OWNER_MASK, HEAD3); break; + default: + WARN_ON(1); + break; + } + + ctrl |= NVDEF(NV507D, DAC_SET_CONTROL, PROTOCOL, RGB_CRT); nv50_outp_acquire(nv_encoder, false); - core->func->dac->ctrl(core, nv_encoder->or, 1 << nv_crtc->index, asyh); + core->func->dac->ctrl(core, nv_encoder->or, ctrl, asyh); asyh->or.depth = 0; nv_encoder->crtc = encoder->crtc; @@ -586,6 +654,9 @@ nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) (0x0100 << nv_crtc->index), }; + if (!nv_encoder->audio) + return; + nv_encoder->audio = false; nvif_mthd(&disp->disp->object, 0, &args, sizeof(args)); @@ -928,10 +999,10 @@ static u8 nv50_dp_bpc_to_depth(unsigned int bpc) { switch (bpc) { - case 6: return 0x2; - case 8: return 0x5; - case 10: /* fall-through */ - default: return 0x6; + case 6: return NV837D_SOR_SET_CONTROL_PIXEL_DEPTH_BPP_18_444; + case 8: return NV837D_SOR_SET_CONTROL_PIXEL_DEPTH_BPP_24_444; + case 10: + default: return NV837D_SOR_SET_CONTROL_PIXEL_DEPTH_BPP_30_444; } } @@ -970,9 +1041,9 @@ nv50_msto_enable(struct drm_encoder *encoder) nv50_outp_acquire(mstm->outp, false /*XXX: MST audio.*/); if (mstm->outp->link & 1) - proto = 0x8; + proto = NV917D_SOR_SET_CONTROL_PROTOCOL_DP_A; else - proto = 0x9; + proto = NV917D_SOR_SET_CONTROL_PROTOCOL_DP_B; mstm->outp->update(mstm->outp, head->base.index, armh, proto, nv50_dp_bpc_to_depth(armh->or.bpc)); @@ -1501,10 +1572,10 @@ nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head, if (!asyh) { nv_encoder->ctrl &= ~BIT(head); - if (!(nv_encoder->ctrl & 0x0000000f)) + if (NVDEF_TEST(nv_encoder->ctrl, NV507D, SOR_SET_CONTROL, OWNER, ==, NONE)) nv_encoder->ctrl = 0; } else { - nv_encoder->ctrl |= proto << 8; + nv_encoder->ctrl |= NVVAL(NV507D, SOR_SET_CONTROL, PROTOCOL, proto); nv_encoder->ctrl |= BIT(head); asyh->or.depth = depth; } @@ -1562,8 +1633,8 @@ nv50_sor_enable(struct drm_encoder *encoder) struct nouveau_connector *nv_connector; struct nvbios *bios = &drm->vbios; bool hda = false; - u8 proto = 0xf; - u8 depth = 0x0; + u8 proto = NV507D_SOR_SET_CONTROL_PROTOCOL_CUSTOM; + u8 depth = NV837D_SOR_SET_CONTROL_PIXEL_DEPTH_DEFAULT; nv_connector = nouveau_encoder_connector_get(nv_encoder); nv_encoder->crtc = encoder->crtc; @@ -1577,7 +1648,7 @@ nv50_sor_enable(struct drm_encoder *encoder) switch (nv_encoder->dcb->type) { case DCB_OUTPUT_TMDS: if (nv_encoder->link & 1) { - proto = 0x1; + proto = NV507D_SOR_SET_CONTROL_PROTOCOL_SINGLE_TMDS_A; /* Only enable dual-link if: * - Need to (i.e. rate > 165MHz) * - DCB says we can @@ -1587,15 +1658,15 @@ nv50_sor_enable(struct drm_encoder *encoder) if (mode->clock >= 165000 && nv_encoder->dcb->duallink_possible && !drm_detect_hdmi_monitor(nv_connector->edid)) - proto |= 0x4; + proto = NV507D_SOR_SET_CONTROL_PROTOCOL_DUAL_TMDS; } else { - proto = 0x2; + proto = NV507D_SOR_SET_CONTROL_PROTOCOL_SINGLE_TMDS_B; } nv50_hdmi_enable(&nv_encoder->base.base, mode); break; case DCB_OUTPUT_LVDS: - proto = 0x0; + proto = NV507D_SOR_SET_CONTROL_PROTOCOL_LVDS_CUSTOM; if (bios->fp_no_ddc) { if (bios->fp.dual_link) @@ -1629,9 +1700,9 @@ nv50_sor_enable(struct drm_encoder *encoder) depth = nv50_dp_bpc_to_depth(asyh->or.bpc); if (nv_encoder->link & 1) - proto = 0x8; + proto = NV887D_SOR_SET_CONTROL_PROTOCOL_DP_A; else - proto = 0x9; + proto = NV887D_SOR_SET_CONTROL_PROTOCOL_DP_B; nv50_audio_enable(encoder, mode); break; @@ -1766,8 +1837,9 @@ nv50_pior_disable(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nv50_core *core = nv50_disp(encoder->dev)->core; + const u32 ctrl = NVDEF(NV507D, PIOR_SET_CONTROL, OWNER, NONE); if (nv_encoder->crtc) - core->func->pior->ctrl(core, nv_encoder->or, 0x00000000, NULL); + core->func->pior->ctrl(core, nv_encoder->or, ctrl, NULL); nv_encoder->crtc = NULL; nv50_outp_release(nv_encoder); } @@ -1779,29 +1851,36 @@ nv50_pior_enable(struct drm_encoder *encoder) struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nv50_head_atom *asyh = nv50_head_atom(nv_crtc->base.state); struct nv50_core *core = nv50_disp(encoder->dev)->core; - u8 owner = 1 << nv_crtc->index; - u8 proto; + u32 ctrl = 0; + + switch (nv_crtc->index) { + case 0: ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, OWNER, HEAD0); break; + case 1: ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, OWNER, HEAD1); break; + default: + WARN_ON(1); + break; + } nv50_outp_acquire(nv_encoder, false); switch (asyh->or.bpc) { - case 10: asyh->or.depth = 0x6; break; - case 8: asyh->or.depth = 0x5; break; - case 6: asyh->or.depth = 0x2; break; - default: asyh->or.depth = 0x0; break; + case 10: asyh->or.depth = NV837D_PIOR_SET_CONTROL_PIXEL_DEPTH_BPP_30_444; break; + case 8: asyh->or.depth = NV837D_PIOR_SET_CONTROL_PIXEL_DEPTH_BPP_24_444; break; + case 6: asyh->or.depth = NV837D_PIOR_SET_CONTROL_PIXEL_DEPTH_BPP_18_444; break; + default: asyh->or.depth = NV837D_PIOR_SET_CONTROL_PIXEL_DEPTH_DEFAULT; break; } switch (nv_encoder->dcb->type) { case DCB_OUTPUT_TMDS: case DCB_OUTPUT_DP: - proto = 0x0; + ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, PROTOCOL, EXT_TMDS_ENC); break; default: BUG(); break; } - core->func->pior->ctrl(core, nv_encoder->or, (proto << 8) | owner, asyh); + core->func->pior->ctrl(core, nv_encoder->or, ctrl, asyh); nv_encoder->crtc = encoder->crtc; } @@ -2078,7 +2157,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) */ if (core->assign_windows) { core->func->wndw.owner(core); - core->func->update(core, interlock, false); + nv50_disp_atomic_commit_core(state, interlock); core->assign_windows = false; interlock[NV50_DISP_INTERLOCK_CORE] = 0; } @@ -2168,8 +2247,10 @@ nv50_disp_atomic_commit(struct drm_device *dev, int ret, i; ret = pm_runtime_get_sync(dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(dev->dev); return ret; + } ret = drm_atomic_helper_setup_commit(state, nonblock); if (ret) @@ -2460,7 +2541,7 @@ nv50_display_destroy(struct drm_device *dev) nv50_audio_component_fini(nouveau_drm(dev)); nvif_object_unmap(&disp->caps); - nvif_object_fini(&disp->caps); + nvif_object_dtor(&disp->caps); nv50_core_del(&disp->core); nouveau_bo_unmap(disp->sync); @@ -2532,7 +2613,7 @@ nv50_display_create(struct drm_device *dev) if (disp->disp->object.oclass >= TU102_DISP) nouveau_display(dev)->format_modifiers = wndwc57e_modifiers; else - if (disp->disp->object.oclass >= GF110_DISP) + if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI) nouveau_display(dev)->format_modifiers = disp90xx_modifiers; else nouveau_display(dev)->format_modifiers = disp50xx_modifiers; diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h index 1968c6921f9e..92bddc083617 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -2,6 +2,7 @@ #define __NV50_KMS_H__ #include <linux/workqueue.h> #include <nvif/mem.h> +#include <nvif/push.h> #include "nouveau_display.h" @@ -61,7 +62,8 @@ struct nv50_chan { struct nv50_dmac { struct nv50_chan base; - struct nvif_mem push; + struct nvif_push _push; + struct nvif_push *push; u32 *ptr; struct nvif_object sync; @@ -71,6 +73,10 @@ struct nv50_dmac { * grabbed by evo_wait (if the pushbuf reservation is successful) and * dropped again by evo_kick. */ struct mutex lock; + + u32 cur; + u32 put; + u32 max; }; struct nv50_outp_atom { @@ -106,18 +112,4 @@ void evo_kick(u32 *, struct nv50_dmac *); extern const u64 disp50xx_modifiers[]; extern const u64 disp90xx_modifiers[]; extern const u64 wndwc57e_modifiers[]; - -#define evo_mthd(p, m, s) do { \ - const u32 _m = (m), _s = (s); \ - if (drm_debug_enabled(DRM_UT_KMS)) \ - pr_err("%04x %d %s\n", _m, _s, __func__); \ - *((p)++) = ((_s << 18) | _m); \ -} while(0) - -#define evo_data(p, d) do { \ - const u32 _d = (d); \ - if (drm_debug_enabled(DRM_UT_KMS)) \ - pr_err("\t%08x\n", _d); \ - *((p)++) = _d; \ -} while(0) #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 9a10ec267d1f..841edfaf5b9d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -106,9 +106,9 @@ nv50_head_atomic_check_dither(struct nv50_head_atom *armh, } } - asyh->dither.enable = mode; - asyh->dither.bits = mode >> 1; - asyh->dither.mode = mode >> 3; + asyh->dither.enable = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, ENABLE); + asyh->dither.bits = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, BITS); + asyh->dither.mode = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, MODE); asyh->set.dither = true; } @@ -489,7 +489,7 @@ nv50_head_destroy(struct drm_crtc *crtc) { struct nv50_head *head = nv50_head(crtc); - nvif_notify_fini(&head->base.vblank); + nvif_notify_dtor(&head->base.vblank); nv50_lut_fini(&head->olut); drm_crtc_cleanup(crtc); kfree(head); @@ -598,7 +598,7 @@ nv50_head_create(struct drm_device *dev, int index) } } - ret = nvif_notify_init(&disp->disp->object, nv50_head_vblank_handler, + ret = nvif_notify_ctor(&disp->disp->object, "kmsVbl", nv50_head_vblank_handler, false, NV04_DISP_NTFY_VBLANK, &(struct nvif_notify_head_req_v0) { .head = nv_crtc->index, diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.h b/drivers/gpu/drm/nouveau/dispnv50/head.h index 30501ad1824e..dae841dc05fd 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.h +++ b/drivers/gpu/drm/nouveau/dispnv50/head.h @@ -25,74 +25,72 @@ void nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool flush); struct nv50_head_func { - void (*view)(struct nv50_head *, struct nv50_head_atom *); - void (*mode)(struct nv50_head *, struct nv50_head_atom *); + int (*view)(struct nv50_head *, struct nv50_head_atom *); + int (*mode)(struct nv50_head *, struct nv50_head_atom *); bool (*olut)(struct nv50_head *, struct nv50_head_atom *, int); bool olut_identity; int olut_size; - void (*olut_set)(struct nv50_head *, struct nv50_head_atom *); - void (*olut_clr)(struct nv50_head *); + int (*olut_set)(struct nv50_head *, struct nv50_head_atom *); + int (*olut_clr)(struct nv50_head *); void (*core_calc)(struct nv50_head *, struct nv50_head_atom *); - void (*core_set)(struct nv50_head *, struct nv50_head_atom *); - void (*core_clr)(struct nv50_head *); + int (*core_set)(struct nv50_head *, struct nv50_head_atom *); + int (*core_clr)(struct nv50_head *); int (*curs_layout)(struct nv50_head *, struct nv50_wndw_atom *, struct nv50_head_atom *); int (*curs_format)(struct nv50_head *, struct nv50_wndw_atom *, struct nv50_head_atom *); - void (*curs_set)(struct nv50_head *, struct nv50_head_atom *); - void (*curs_clr)(struct nv50_head *); - void (*base)(struct nv50_head *, struct nv50_head_atom *); - void (*ovly)(struct nv50_head *, struct nv50_head_atom *); - void (*dither)(struct nv50_head *, struct nv50_head_atom *); - void (*procamp)(struct nv50_head *, struct nv50_head_atom *); - void (*or)(struct nv50_head *, struct nv50_head_atom *); + int (*curs_set)(struct nv50_head *, struct nv50_head_atom *); + int (*curs_clr)(struct nv50_head *); + int (*base)(struct nv50_head *, struct nv50_head_atom *); + int (*ovly)(struct nv50_head *, struct nv50_head_atom *); + int (*dither)(struct nv50_head *, struct nv50_head_atom *); + int (*procamp)(struct nv50_head *, struct nv50_head_atom *); + int (*or)(struct nv50_head *, struct nv50_head_atom *); void (*static_wndw_map)(struct nv50_head *, struct nv50_head_atom *); }; extern const struct nv50_head_func head507d; -void head507d_view(struct nv50_head *, struct nv50_head_atom *); -void head507d_mode(struct nv50_head *, struct nv50_head_atom *); +int head507d_view(struct nv50_head *, struct nv50_head_atom *); +int head507d_mode(struct nv50_head *, struct nv50_head_atom *); bool head507d_olut(struct nv50_head *, struct nv50_head_atom *, int); void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *); -void head507d_core_clr(struct nv50_head *); +int head507d_core_clr(struct nv50_head *); int head507d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *, struct nv50_head_atom *); int head507d_curs_format(struct nv50_head *, struct nv50_wndw_atom *, struct nv50_head_atom *); -void head507d_base(struct nv50_head *, struct nv50_head_atom *); -void head507d_ovly(struct nv50_head *, struct nv50_head_atom *); -void head507d_dither(struct nv50_head *, struct nv50_head_atom *); -void head507d_procamp(struct nv50_head *, struct nv50_head_atom *); +int head507d_base(struct nv50_head *, struct nv50_head_atom *); +int head507d_ovly(struct nv50_head *, struct nv50_head_atom *); +int head507d_dither(struct nv50_head *, struct nv50_head_atom *); +int head507d_procamp(struct nv50_head *, struct nv50_head_atom *); extern const struct nv50_head_func head827d; extern const struct nv50_head_func head907d; -void head907d_view(struct nv50_head *, struct nv50_head_atom *); -void head907d_mode(struct nv50_head *, struct nv50_head_atom *); +int head907d_view(struct nv50_head *, struct nv50_head_atom *); +int head907d_mode(struct nv50_head *, struct nv50_head_atom *); bool head907d_olut(struct nv50_head *, struct nv50_head_atom *, int); -void head907d_olut_set(struct nv50_head *, struct nv50_head_atom *); -void head907d_olut_clr(struct nv50_head *); -void head907d_core_set(struct nv50_head *, struct nv50_head_atom *); -void head907d_core_clr(struct nv50_head *); -void head907d_curs_set(struct nv50_head *, struct nv50_head_atom *); -void head907d_curs_clr(struct nv50_head *); -void head907d_ovly(struct nv50_head *, struct nv50_head_atom *); -void head907d_procamp(struct nv50_head *, struct nv50_head_atom *); -void head907d_or(struct nv50_head *, struct nv50_head_atom *); +int head907d_olut_set(struct nv50_head *, struct nv50_head_atom *); +int head907d_olut_clr(struct nv50_head *); +int head907d_core_set(struct nv50_head *, struct nv50_head_atom *); +int head907d_core_clr(struct nv50_head *); +int head907d_curs_set(struct nv50_head *, struct nv50_head_atom *); +int head907d_curs_clr(struct nv50_head *); +int head907d_ovly(struct nv50_head *, struct nv50_head_atom *); +int head907d_procamp(struct nv50_head *, struct nv50_head_atom *); +int head907d_or(struct nv50_head *, struct nv50_head_atom *); extern const struct nv50_head_func head917d; int head917d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *, struct nv50_head_atom *); extern const struct nv50_head_func headc37d; -void headc37d_view(struct nv50_head *, struct nv50_head_atom *); -void headc37d_core_set(struct nv50_head *, struct nv50_head_atom *); -void headc37d_core_clr(struct nv50_head *); +int headc37d_view(struct nv50_head *, struct nv50_head_atom *); int headc37d_curs_format(struct nv50_head *, struct nv50_wndw_atom *, struct nv50_head_atom *); -void headc37d_curs_set(struct nv50_head *, struct nv50_head_atom *); -void headc37d_curs_clr(struct nv50_head *); -void headc37d_dither(struct nv50_head *, struct nv50_head_atom *); +int headc37d_curs_set(struct nv50_head *, struct nv50_head_atom *); +int headc37d_curs_clr(struct nv50_head *); +int headc37d_dither(struct nv50_head *, struct nv50_head_atom *); void headc37d_static_wndw_map(struct nv50_head *, struct nv50_head_atom *); extern const struct nv50_head_func headc57d; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head507d.c b/drivers/gpu/drm/nouveau/dispnv50/head507d.c index 66ccf36b56a2..0edd4e520c8e 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head507d.c @@ -22,111 +22,141 @@ #include "head.h" #include "core.h" -void +#include <nvif/push507c.h> + +#include <nvhw/class/cl507d.h> + +int head507d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x08a8 + (head->base.index * 0x400), 1); - evo_data(push, asyh->procamp.sat.sin << 20 | - asyh->procamp.sat.cos << 8); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_PROCAMP(i), + NVDEF(NV507D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) | + NVDEF(NV507D, HEAD_SET_PROCAMP, CHROMA_LPF, AUTO) | + NVVAL(NV507D, HEAD_SET_PROCAMP, SAT_COS, asyh->procamp.sat.cos) | + NVVAL(NV507D, HEAD_SET_PROCAMP, SAT_SINE, asyh->procamp.sat.sin) | + NVDEF(NV507D, HEAD_SET_PROCAMP, TRANSITION, HARD)); + return 0; } -void +int head507d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x08a0 + (head->base.index * 0x0400), 1); - evo_data(push, asyh->dither.mode << 3 | - asyh->dither.bits << 1 | - asyh->dither.enable); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_DITHER_CONTROL(i), + NVVAL(NV507D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) | + NVVAL(NV507D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) | + NVVAL(NV507D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) | + NVVAL(NV507D, HEAD_SET_DITHER_CONTROL, PHASE, 0)); + return 0; } -void +int head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; u32 bounds = 0; - u32 *push; + int ret; if (asyh->ovly.cpp) { switch (asyh->ovly.cpp) { - case 4: bounds |= 0x00000300; break; - case 2: bounds |= 0x00000100; break; + case 4: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break; + case 2: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break; default: WARN_ON(1); break; } - bounds |= 0x00000001; + bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE); } else { - bounds |= 0x00000100; + bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); } - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x0904 + head->base.index * 0x400, 1); - evo_data(push, bounds); - evo_kick(push, core); - } + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds); + return 0; } -void +int head507d_base(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; u32 bounds = 0; - u32 *push; + int ret; if (asyh->base.cpp) { switch (asyh->base.cpp) { - case 8: bounds |= 0x00000500; break; - case 4: bounds |= 0x00000300; break; - case 2: bounds |= 0x00000100; break; - case 1: bounds |= 0x00000000; break; + case 8: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break; + case 4: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break; + case 2: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break; + case 1: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_8); break; default: WARN_ON(1); break; } - bounds |= 0x00000001; + bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE); } - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x0900 + head->base.index * 0x400, 1); - evo_data(push, bounds); - evo_kick(push, core); - } + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds); + return 0; } -static void +static int head507d_curs_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); - evo_data(push, 0x05000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) | + NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8) | + NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, SIZE, W64_H64)); + return 0; } -static void +static int head507d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 3))) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); - evo_data(push, 0x80000000 | asyh->curs.layout << 26 | - asyh->curs.format << 24); - evo_data(push, asyh->curs.offset >> 8); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 3))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) | + NVVAL(NV507D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) | + NVVAL(NV507D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) | + NVVAL(NV507D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) | + NVVAL(NV507D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) | + NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND) | + NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, SUB_OWNER, NONE), + + HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8); + return 0; } int @@ -134,7 +164,7 @@ head507d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { switch (asyw->image.format) { - case 0xcf: asyh->curs.format = 1; break; + case 0xcf: asyh->curs.format = NV507D_HEAD_SET_CONTROL_CURSOR_FORMAT_A8R8G8B8; break; default: WARN_ON(1); return -EINVAL; @@ -147,54 +177,70 @@ head507d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { switch (asyw->image.w) { - case 32: asyh->curs.layout = 0; break; - case 64: asyh->curs.layout = 1; break; + case 32: asyh->curs.layout = NV507D_HEAD_SET_CONTROL_CURSOR_SIZE_W32_H32; break; + case 64: asyh->curs.layout = NV507D_HEAD_SET_CONTROL_CURSOR_SIZE_W64_H64; break; default: return -EINVAL; } return 0; } -void +int head507d_core_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x0874 + head->base.index * 0x400, 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_CONTEXT_DMA_ISO(i), 0x00000000); + return 0; } -static void +static int head507d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 9))) { - evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); - evo_data(push, asyh->core.h << 16 | asyh->core.w); - evo_data(push, asyh->core.layout << 20 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.blocks << 8 | - asyh->core.blockh); - evo_data(push, asyh->core.kind << 16 | - asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); - evo_data(push, asyh->core.y << 16 | asyh->core.x); - evo_kick(push, core); - - /* EVO will complain with INVALID_STATE if we have an - * active cursor and (re)specify HeadSetContextDmaIso - * without also updating HeadSetOffsetCursor. - */ - asyh->set.curs = asyh->curs.visible; - asyh->set.olut = asyh->olut.handle != 0; - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 9))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_OFFSET(i, 0), + NVVAL(NV507D, HEAD_SET_OFFSET, ORIGIN, asyh->core.offset >> 8)); + + PUSH_MTHD(push, NV507D, HEAD_SET_SIZE(i), + NVVAL(NV507D, HEAD_SET_SIZE, WIDTH, asyh->core.w) | + NVVAL(NV507D, HEAD_SET_SIZE, HEIGHT, asyh->core.h), + + HEAD_SET_STORAGE(i), + NVVAL(NV507D, HEAD_SET_STORAGE, BLOCK_HEIGHT, asyh->core.blockh) | + NVVAL(NV507D, HEAD_SET_STORAGE, PITCH, asyh->core.pitch >> 8) | + NVVAL(NV507D, HEAD_SET_STORAGE, PITCH, asyh->core.blocks) | + NVVAL(NV507D, HEAD_SET_STORAGE, MEMORY_LAYOUT, asyh->core.layout), + + HEAD_SET_PARAMS(i), + NVVAL(NV507D, HEAD_SET_PARAMS, FORMAT, asyh->core.format) | + NVVAL(NV507D, HEAD_SET_PARAMS, KIND, asyh->core.kind) | + NVDEF(NV507D, HEAD_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256), + + HEAD_SET_CONTEXT_DMA_ISO(i), + NVVAL(NV507D, HEAD_SET_CONTEXT_DMA_ISO, HANDLE, asyh->core.handle)); + + PUSH_MTHD(push, NV507D, HEAD_SET_VIEWPORT_POINT_IN(i, 0), + NVVAL(NV507D, HEAD_SET_VIEWPORT_POINT_IN, X, asyh->core.x) | + NVVAL(NV507D, HEAD_SET_VIEWPORT_POINT_IN, Y, asyh->core.y)); + + /* EVO will complain with INVALID_STATE if we have an + * active cursor and (re)specify HeadSetContextDmaIso + * without also updating HeadSetOffsetCursor. + */ + asyh->set.curs = asyh->curs.visible; + asyh->set.olut = asyh->olut.handle != 0; + return 0; } void @@ -221,37 +267,47 @@ head507d_core_calc(struct nv50_head *head, struct nv50_head_atom *asyh) } asyh->core.handle = disp->core->chan.vram.handle; asyh->core.offset = 0; - asyh->core.format = 0xcf; - asyh->core.kind = 0; - asyh->core.layout = 1; - asyh->core.blockh = 0; + asyh->core.format = NV507D_HEAD_SET_PARAMS_FORMAT_A8R8G8B8; + asyh->core.kind = NV507D_HEAD_SET_PARAMS_KIND_KIND_PITCH; + asyh->core.layout = NV507D_HEAD_SET_STORAGE_MEMORY_LAYOUT_PITCH; + asyh->core.blockh = NV507D_HEAD_SET_STORAGE_BLOCK_HEIGHT_ONE_GOB; asyh->core.blocks = 0; asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4; } -static void +static int head507d_olut_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_BASE_LUT_LO(i), + NVDEF(NV507D, HEAD_SET_BASE_LUT_LO, ENABLE, DISABLE)); + return 0; } -static void +static int head507d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 3))) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); - evo_data(push, 0x80000000 | asyh->olut.mode << 30); - evo_data(push, asyh->olut.offset >> 8); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 3))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_BASE_LUT_LO(i), + NVDEF(NV507D, HEAD_SET_BASE_LUT_LO, ENABLE, ENABLE) | + NVVAL(NV507D, HEAD_SET_BASE_LUT_LO, MODE, asyh->olut.mode) | + NVVAL(NV507D, HEAD_SET_BASE_LUT_LO, ORIGIN, 0), + + HEAD_SET_BASE_LUT_HI(i), + NVVAL(NV507D, HEAD_SET_BASE_LUT_HI, ORIGIN, asyh->olut.offset >> 8)); + return 0; } static void @@ -278,53 +334,97 @@ head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) return false; if (asyh->base.cpp == 1) - asyh->olut.mode = 0; + asyh->olut.mode = NV507D_HEAD_SET_BASE_LUT_LO_MODE_LORES; else - asyh->olut.mode = 1; + asyh->olut.mode = NV507D_HEAD_SET_BASE_LUT_LO_MODE_HIRES; asyh->olut.load = head507d_olut_load; return true; } -void +int head507d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; struct nv50_head_mode *m = &asyh->mode; - u32 *push; - if ((push = evo_wait(core, 13))) { - evo_mthd(push, 0x0804 + (head->base.index * 0x400), 2); - evo_data(push, 0x00800000 | m->clock); - evo_data(push, m->interlace ? 0x00000002 : 0x00000000); - evo_mthd(push, 0x0810 + (head->base.index * 0x400), 7); - evo_data(push, 0x00000000); - evo_data(push, m->v.active << 16 | m->h.active ); - evo_data(push, m->v.synce << 16 | m->h.synce ); - evo_data(push, m->v.blanke << 16 | m->h.blanke ); - evo_data(push, m->v.blanks << 16 | m->h.blanks ); - evo_data(push, m->v.blank2e << 16 | m->v.blank2s); - evo_data(push, asyh->mode.v.blankus); - evo_mthd(push, 0x082c + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 13))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_PIXEL_CLOCK(i), + NVVAL(NV507D, HEAD_SET_PIXEL_CLOCK, FREQUENCY, m->clock) | + NVDEF(NV507D, HEAD_SET_PIXEL_CLOCK, MODE, CLK_CUSTOM) | + NVDEF(NV507D, HEAD_SET_PIXEL_CLOCK, ADJ1000DIV1001, FALSE) | + NVDEF(NV507D, HEAD_SET_PIXEL_CLOCK, NOT_DRIVER, FALSE), + + HEAD_SET_CONTROL(i), + NVVAL(NV507D, HEAD_SET_CONTROL, STRUCTURE, m->interlace)); + + PUSH_MTHD(push, NV507D, HEAD_SET_OVERSCAN_COLOR(i), + NVVAL(NV507D, HEAD_SET_OVERSCAN_COLOR, RED, 0) | + NVVAL(NV507D, HEAD_SET_OVERSCAN_COLOR, GRN, 0) | + NVVAL(NV507D, HEAD_SET_OVERSCAN_COLOR, BLU, 0), + + HEAD_SET_RASTER_SIZE(i), + NVVAL(NV507D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) | + NVVAL(NV507D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active), + + HEAD_SET_RASTER_SYNC_END(i), + NVVAL(NV507D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) | + NVVAL(NV507D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce), + + HEAD_SET_RASTER_BLANK_END(i), + NVVAL(NV507D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) | + NVVAL(NV507D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke), + + HEAD_SET_RASTER_BLANK_START(i), + NVVAL(NV507D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) | + NVVAL(NV507D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks), + + HEAD_SET_RASTER_VERT_BLANK2(i), + NVVAL(NV507D, HEAD_SET_RASTER_VERT_BLANK2, YSTART, m->v.blank2s) | + NVVAL(NV507D, HEAD_SET_RASTER_VERT_BLANK2, YEND, m->v.blank2e), + + HEAD_SET_RASTER_VERT_BLANK_DMI(i), + NVVAL(NV507D, HEAD_SET_RASTER_VERT_BLANK_DMI, DURATION, m->v.blankus)); + + PUSH_MTHD(push, NV507D, HEAD_SET_DEFAULT_BASE_COLOR(i), + NVVAL(NV507D, HEAD_SET_DEFAULT_BASE_COLOR, RED, 0) | + NVVAL(NV507D, HEAD_SET_DEFAULT_BASE_COLOR, GREEN, 0) | + NVVAL(NV507D, HEAD_SET_DEFAULT_BASE_COLOR, BLUE, 0)); + return 0; } -void +int head507d_view(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 7))) { - evo_mthd(push, 0x08a4 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x08c8 + (head->base.index * 0x400), 1); - evo_data(push, asyh->view.iH << 16 | asyh->view.iW); - evo_mthd(push, 0x08d8 + (head->base.index * 0x400), 2); - evo_data(push, asyh->view.oH << 16 | asyh->view.oW); - evo_data(push, asyh->view.oH << 16 | asyh->view.oW); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 7))) + return ret; + + PUSH_MTHD(push, NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER(i), + NVDEF(NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER, VERTICAL_TAPS, TAPS_1) | + NVDEF(NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER, HORIZONTAL_TAPS, TAPS_1) | + NVVAL(NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER, HRESPONSE_BIAS, 0) | + NVVAL(NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER, VRESPONSE_BIAS, 0)); + + PUSH_MTHD(push, NV507D, HEAD_SET_VIEWPORT_SIZE_IN(i), + NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_IN, WIDTH, asyh->view.iW) | + NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_IN, HEIGHT, asyh->view.iH)); + + PUSH_MTHD(push, NV507D, HEAD_SET_VIEWPORT_SIZE_OUT(i), + NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_OUT, WIDTH, asyh->view.oW) | + NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_OUT, HEIGHT, asyh->view.oH), + + HEAD_SET_VIEWPORT_SIZE_OUT_MIN(i), + NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, WIDTH, asyh->view.oW) | + NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, HEIGHT, asyh->view.oH)); + return 0; } const struct nv50_head_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/head827d.c b/drivers/gpu/drm/nouveau/dispnv50/head827d.c index 11877119eea4..194d1771c481 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head827d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head827d.c @@ -22,85 +22,128 @@ #include "head.h" #include "core.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl827d.h> + +static int head827d_curs_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); - evo_data(push, 0x05000000); - evo_mthd(push, 0x089c + head->base.index * 0x400, 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NV827D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) | + NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8) | + NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, SIZE, W64_H64)); + + PUSH_MTHD(push, NV827D, HEAD_SET_CONTEXT_DMA_CURSOR(i), 0x00000000); + return 0; } -static void +static int head827d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 5))) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); - evo_data(push, 0x80000000 | asyh->curs.layout << 26 | - asyh->curs.format << 24); - evo_data(push, asyh->curs.offset >> 8); - evo_mthd(push, 0x089c + head->base.index * 0x400, 1); - evo_data(push, asyh->curs.handle); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + PUSH_MTHD(push, NV827D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) | + NVVAL(NV827D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) | + NVVAL(NV827D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) | + NVVAL(NV827D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) | + NVVAL(NV827D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) | + NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND) | + NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, SUB_OWNER, NONE), + + HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8); + + PUSH_MTHD(push, NV827D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle); + return 0; } -static void +static int head827d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 9))) { - evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); - evo_data(push, asyh->core.h << 16 | asyh->core.w); - evo_data(push, asyh->core.layout << 20 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.blocks << 8 | - asyh->core.blockh); - evo_data(push, asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); - evo_data(push, asyh->core.y << 16 | asyh->core.x); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 9))) + return ret; + + PUSH_MTHD(push, NV827D, HEAD_SET_OFFSET(i, 0), + NVVAL(NV827D, HEAD_SET_OFFSET, ORIGIN, asyh->core.offset >> 8)); + + PUSH_MTHD(push, NV827D, HEAD_SET_SIZE(i), + NVVAL(NV827D, HEAD_SET_SIZE, WIDTH, asyh->core.w) | + NVVAL(NV827D, HEAD_SET_SIZE, HEIGHT, asyh->core.h), + + HEAD_SET_STORAGE(i), + NVVAL(NV827D, HEAD_SET_STORAGE, BLOCK_HEIGHT, asyh->core.blockh) | + NVVAL(NV827D, HEAD_SET_STORAGE, PITCH, asyh->core.pitch >> 8) | + NVVAL(NV827D, HEAD_SET_STORAGE, PITCH, asyh->core.blocks) | + NVVAL(NV827D, HEAD_SET_STORAGE, MEMORY_LAYOUT, asyh->core.layout), + + HEAD_SET_PARAMS(i), + NVVAL(NV827D, HEAD_SET_PARAMS, FORMAT, asyh->core.format) | + NVDEF(NV827D, HEAD_SET_PARAMS, SUPER_SAMPLE, X1_AA) | + NVDEF(NV827D, HEAD_SET_PARAMS, GAMMA, LINEAR), + + HEAD_SET_CONTEXT_DMAS_ISO(i, 0), + NVVAL(NV827D, HEAD_SET_CONTEXT_DMAS_ISO, HANDLE, asyh->core.handle)); + + PUSH_MTHD(push, NV827D, HEAD_SET_VIEWPORT_POINT_IN(i, 0), + NVVAL(NV827D, HEAD_SET_VIEWPORT_POINT_IN, X, asyh->core.x) | + NVVAL(NV827D, HEAD_SET_VIEWPORT_POINT_IN, Y, asyh->core.y)); + return 0; } -static void +static int head827d_olut_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NV827D, HEAD_SET_BASE_LUT_LO(i), + NVDEF(NV827D, HEAD_SET_BASE_LUT_LO, ENABLE, DISABLE)); + + PUSH_MTHD(push, NV827D, HEAD_SET_CONTEXT_DMA_LUT(i), 0x00000000); + return 0; } -static void +static int head827d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 5))) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); - evo_data(push, 0x80000000 | asyh->olut.mode << 30); - evo_data(push, asyh->olut.offset >> 8); - evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); - evo_data(push, asyh->olut.handle); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + PUSH_MTHD(push, NV827D, HEAD_SET_BASE_LUT_LO(i), + NVDEF(NV827D, HEAD_SET_BASE_LUT_LO, ENABLE, ENABLE) | + NVVAL(NV827D, HEAD_SET_BASE_LUT_LO, MODE, asyh->olut.mode) | + NVVAL(NV827D, HEAD_SET_BASE_LUT_LO, ORIGIN, 0), + + HEAD_SET_BASE_LUT_HI(i), + NVVAL(NV827D, HEAD_SET_BASE_LUT_HI, ORIGIN, asyh->olut.offset >> 8)); + + PUSH_MTHD(push, NV827D, HEAD_SET_CONTEXT_DMA_LUT(i), asyh->olut.handle); + return 0; } const struct nv50_head_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/head907d.c b/drivers/gpu/drm/nouveau/dispnv50/head907d.c index 63a0b45d96d6..8f860e9c5224 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head907d.c @@ -29,196 +29,257 @@ #include "core.h" #include "crc.h" -void +#include <nvif/push507c.h> + +#include <nvhw/class/cl907d.h> + +int head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 3))) { - evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2); - evo_data(push, asyh->or.depth << 6 | - asyh->or.nvsync << 4 | - asyh->or.nhsync << 3 | - asyh->or.crc_raster); - evo_data(push, 0x31ec6000 | head->base.index << 25 | - asyh->mode.interlace); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 3))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE(i), + NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, CRC_MODE, asyh->or.crc_raster) | + NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, HSYNC_POLARITY, asyh->or.nhsync) | + NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, VSYNC_POLARITY, asyh->or.nvsync) | + NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, PIXEL_DEPTH, asyh->or.depth), + + HEAD_SET_CONTROL(i), 0x31ec6000 | head->base.index << 25 | + NVVAL(NV907D, HEAD_SET_CONTROL, STRUCTURE, asyh->mode.interlace)); + return 0; } -void +int head907d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x0498 + (head->base.index * 0x300), 1); - evo_data(push, asyh->procamp.sat.sin << 20 | - asyh->procamp.sat.cos << 8); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_PROCAMP(i), + NVDEF(NV907D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) | + NVDEF(NV907D, HEAD_SET_PROCAMP, CHROMA_LPF, AUTO) | + NVVAL(NV907D, HEAD_SET_PROCAMP, SAT_COS, asyh->procamp.sat.cos) | + NVVAL(NV907D, HEAD_SET_PROCAMP, SAT_SINE, asyh->procamp.sat.sin) | + NVDEF(NV907D, HEAD_SET_PROCAMP, DYNAMIC_RANGE, VESA) | + NVDEF(NV907D, HEAD_SET_PROCAMP, RANGE_COMPRESSION, DISABLE)); + return 0; } -static void +static int head907d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x0490 + (head->base.index * 0x0300), 1); - evo_data(push, asyh->dither.mode << 3 | - asyh->dither.bits << 1 | - asyh->dither.enable); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_DITHER_CONTROL(i), + NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) | + NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) | + NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) | + NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, PHASE, 0)); + return 0; } -void +int head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; u32 bounds = 0; - u32 *push; + int ret; if (asyh->ovly.cpp) { switch (asyh->ovly.cpp) { - case 8: bounds |= 0x00000500; break; - case 4: bounds |= 0x00000300; break; - case 2: bounds |= 0x00000100; break; + case 8: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break; + case 4: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break; + case 2: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break; default: WARN_ON(1); break; } - bounds |= 0x00000001; + bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, USABLE, TRUE); } else { - bounds |= 0x00000100; + bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); } - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x04d4 + head->base.index * 0x300, 1); - evo_data(push, bounds); - evo_kick(push, core); - } + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS(i), bounds); + return 0; } -static void +static int head907d_base(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; u32 bounds = 0; - u32 *push; + int ret; if (asyh->base.cpp) { switch (asyh->base.cpp) { - case 8: bounds |= 0x00000500; break; - case 4: bounds |= 0x00000300; break; - case 2: bounds |= 0x00000100; break; - case 1: bounds |= 0x00000000; break; + case 8: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break; + case 4: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break; + case 2: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break; + case 1: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_8); break; default: WARN_ON(1); break; } - bounds |= 0x00000001; + bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE); } - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); - evo_data(push, bounds); - evo_kick(push, core); - } + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds); + return 0; } -void +int head907d_curs_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x0480 + head->base.index * 0x300, 1); - evo_data(push, 0x05000000); - evo_mthd(push, 0x048c + head->base.index * 0x300, 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) | + NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8) | + NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, SIZE, W64_H64)); + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CURSOR(i), 0x00000000); + return 0; } -void +int head907d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 5))) { - evo_mthd(push, 0x0480 + head->base.index * 0x300, 2); - evo_data(push, 0x80000000 | asyh->curs.layout << 26 | - asyh->curs.format << 24); - evo_data(push, asyh->curs.offset >> 8); - evo_mthd(push, 0x048c + head->base.index * 0x300, 1); - evo_data(push, asyh->curs.handle); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) | + NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) | + NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) | + NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) | + NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) | + NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND), + + HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8); + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle); + return 0; } -void +int head907d_core_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x0474 + head->base.index * 0x300, 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMAS_ISO(i), 0x00000000); + return 0; } -void +int head907d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 9))) { - evo_mthd(push, 0x0460 + head->base.index * 0x300, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0468 + head->base.index * 0x300, 4); - evo_data(push, asyh->core.h << 16 | asyh->core.w); - evo_data(push, asyh->core.layout << 24 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.blocks << 8 | - asyh->core.blockh); - evo_data(push, asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1); - evo_data(push, asyh->core.y << 16 | asyh->core.x); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 9))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_OFFSET(i), + NVVAL(NV907D, HEAD_SET_OFFSET, ORIGIN, asyh->core.offset >> 8)); + + PUSH_MTHD(push, NV907D, HEAD_SET_SIZE(i), + NVVAL(NV907D, HEAD_SET_SIZE, WIDTH, asyh->core.w) | + NVVAL(NV907D, HEAD_SET_SIZE, HEIGHT, asyh->core.h), + + HEAD_SET_STORAGE(i), + NVVAL(NV907D, HEAD_SET_STORAGE, BLOCK_HEIGHT, asyh->core.blockh) | + NVVAL(NV907D, HEAD_SET_STORAGE, PITCH, asyh->core.pitch >> 8) | + NVVAL(NV907D, HEAD_SET_STORAGE, PITCH, asyh->core.blocks) | + NVVAL(NV907D, HEAD_SET_STORAGE, MEMORY_LAYOUT, asyh->core.layout), + + HEAD_SET_PARAMS(i), + NVVAL(NV907D, HEAD_SET_PARAMS, FORMAT, asyh->core.format) | + NVDEF(NV907D, HEAD_SET_PARAMS, SUPER_SAMPLE, X1_AA) | + NVDEF(NV907D, HEAD_SET_PARAMS, GAMMA, LINEAR), + + HEAD_SET_CONTEXT_DMAS_ISO(i), + NVVAL(NV907D, HEAD_SET_CONTEXT_DMAS_ISO, HANDLE, asyh->core.handle)); + + PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_POINT_IN(i), + NVVAL(NV907D, HEAD_SET_VIEWPORT_POINT_IN, X, asyh->core.x) | + NVVAL(NV907D, HEAD_SET_VIEWPORT_POINT_IN, Y, asyh->core.y)); + return 0; } -void +int head907d_olut_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x0448 + (head->base.index * 0x300), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_OUTPUT_LUT_LO(i), + NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, ENABLE, DISABLE)); + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_LUT(i), 0x00000000); + return 0; } -void +int head907d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 5))) { - evo_mthd(push, 0x0448 + (head->base.index * 0x300), 2); - evo_data(push, 0x80000000 | asyh->olut.mode << 24); - evo_data(push, asyh->olut.offset >> 8); - evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); - evo_data(push, asyh->olut.handle); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_OUTPUT_LUT_LO(i), + NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, ENABLE, ENABLE) | + NVVAL(NV907D, HEAD_SET_OUTPUT_LUT_LO, MODE, asyh->olut.mode) | + NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, NEVER_YIELD_TO_BASE, DISABLE), + + HEAD_SET_OUTPUT_LUT_HI(i), + NVVAL(NV907D, HEAD_SET_OUTPUT_LUT_HI, ORIGIN, asyh->olut.offset >> 8)); + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_LUT(i), asyh->olut.handle); + return 0; } void @@ -244,52 +305,110 @@ head907d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) if (size != 256 && size != 1024) return false; - asyh->olut.mode = size == 1024 ? 4 : 7; + if (size == 1024) + asyh->olut.mode = NV907D_HEAD_SET_OUTPUT_LUT_LO_MODE_INTERPOLATE_1025_UNITY_RANGE; + else + asyh->olut.mode = NV907D_HEAD_SET_OUTPUT_LUT_LO_MODE_INTERPOLATE_257_UNITY_RANGE; + asyh->olut.load = head907d_olut_load; return true; } -void +int head907d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; struct nv50_head_mode *m = &asyh->mode; - u32 *push; - if ((push = evo_wait(core, 14))) { - evo_mthd(push, 0x0410 + (head->base.index * 0x300), 6); - evo_data(push, 0x00000000); - evo_data(push, m->v.active << 16 | m->h.active ); - evo_data(push, m->v.synce << 16 | m->h.synce ); - evo_data(push, m->v.blanke << 16 | m->h.blanke ); - evo_data(push, m->v.blanks << 16 | m->h.blanks ); - evo_data(push, m->v.blank2e << 16 | m->v.blank2s); - evo_mthd(push, 0x042c + (head->base.index * 0x300), 2); - evo_data(push, 0x00000000); /* ??? */ - evo_data(push, 0xffffff00); - evo_mthd(push, 0x0450 + (head->base.index * 0x300), 3); - evo_data(push, m->clock * 1000); - evo_data(push, 0x00200000); /* ??? */ - evo_data(push, m->clock * 1000); - evo_kick(push, core); - } + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 14))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_OVERSCAN_COLOR(i), + NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, RED, 0) | + NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, GRN, 0) | + NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, BLU, 0), + + HEAD_SET_RASTER_SIZE(i), + NVVAL(NV907D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) | + NVVAL(NV907D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active), + + HEAD_SET_RASTER_SYNC_END(i), + NVVAL(NV907D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) | + NVVAL(NV907D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce), + + HEAD_SET_RASTER_BLANK_END(i), + NVVAL(NV907D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) | + NVVAL(NV907D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke), + + HEAD_SET_RASTER_BLANK_START(i), + NVVAL(NV907D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) | + NVVAL(NV907D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks), + + HEAD_SET_RASTER_VERT_BLANK2(i), + NVVAL(NV907D, HEAD_SET_RASTER_VERT_BLANK2, YSTART, m->v.blank2s) | + NVVAL(NV907D, HEAD_SET_RASTER_VERT_BLANK2, YEND, m->v.blank2e)); + + PUSH_MTHD(push, NV907D, HEAD_SET_DEFAULT_BASE_COLOR(i), + NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, RED, 0) | + NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, GREEN, 0) | + NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, BLUE, 0), + + HEAD_SET_CRC_CONTROL(i), + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, CORE) | + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, EXPECT_BUFFER_COLLAPSE, FALSE) | + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, TIMESTAMP_MODE, FALSE) | + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, NONE) | + NVDEF(NV907D, HEAD_SET_CRC_CONTROL, SECONDARY_OUTPUT, NONE)); + + PUSH_MTHD(push, NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY(i), + NVVAL(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, m->clock * 1000) | + NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, ADJ1000DIV1001, FALSE), + + HEAD_SET_PIXEL_CLOCK_CONFIGURATION(i), + NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, MODE, CLK_CUSTOM) | + NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, NOT_DRIVER, FALSE) | + NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, ENABLE_HOPPING, FALSE), + + HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i), + NVVAL(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, m->clock * 1000) | + NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, ADJ1000DIV1001, FALSE)); + return 0; } -void +int head907d_view(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 8))) { - evo_mthd(push, 0x0494 + (head->base.index * 0x300), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x04b8 + (head->base.index * 0x300), 1); - evo_data(push, asyh->view.iH << 16 | asyh->view.iW); - evo_mthd(push, 0x04c0 + (head->base.index * 0x300), 3); - evo_data(push, asyh->view.oH << 16 | asyh->view.oW); - evo_data(push, asyh->view.oH << 16 | asyh->view.oW); - evo_data(push, asyh->view.oH << 16 | asyh->view.oW); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 8))) + return ret; + + PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER(i), + NVDEF(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, VERTICAL_TAPS, TAPS_1) | + NVDEF(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, HORIZONTAL_TAPS, TAPS_1) | + NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, HRESPONSE_BIAS, 0) | + NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, VRESPONSE_BIAS, 0)); + + PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_SIZE_IN(i), + NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_IN, WIDTH, asyh->view.iW) | + NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_IN, HEIGHT, asyh->view.iH)); + + PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_SIZE_OUT(i), + NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT, WIDTH, asyh->view.oW) | + NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT, HEIGHT, asyh->view.oH), + + HEAD_SET_VIEWPORT_SIZE_OUT_MIN(i), + NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, WIDTH, asyh->view.oW) | + NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, HEIGHT, asyh->view.oH), + + HEAD_SET_VIEWPORT_SIZE_OUT_MAX(i), + NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MAX, WIDTH, asyh->view.oW) | + NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MAX, HEIGHT, asyh->view.oH)); + return 0; } const struct nv50_head_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/head917d.c b/drivers/gpu/drm/nouveau/dispnv50/head917d.c index 76958cedd51f..a5d827403660 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head917d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head917d.c @@ -22,45 +22,55 @@ #include "head.h" #include "core.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl917d.h> + +static int head917d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1); - evo_data(push, asyh->dither.mode << 3 | - asyh->dither.bits << 1 | - asyh->dither.enable); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV917D, HEAD_SET_DITHER_CONTROL(i), + NVVAL(NV917D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) | + NVVAL(NV917D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) | + NVVAL(NV917D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) | + NVVAL(NV917D, HEAD_SET_DITHER_CONTROL, PHASE, 0)); + return 0; } -static void +static int head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; u32 bounds = 0; - u32 *push; + int ret; if (asyh->base.cpp) { switch (asyh->base.cpp) { - case 8: bounds |= 0x00000500; break; - case 4: bounds |= 0x00000300; break; - case 2: bounds |= 0x00000100; break; - case 1: bounds |= 0x00000000; break; + case 8: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break; + case 4: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break; + case 2: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break; + case 1: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_8); break; default: WARN_ON(1); break; } - bounds |= 0x00020001; + bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE); + bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, BASE_LUT, USAGE_1025); } - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); - evo_data(push, bounds); - evo_kick(push, core); - } + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds); + return 0; } int @@ -68,10 +78,10 @@ head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { switch (asyw->state.fb->width) { - case 32: asyh->curs.layout = 0; break; - case 64: asyh->curs.layout = 1; break; - case 128: asyh->curs.layout = 2; break; - case 256: asyh->curs.layout = 3; break; + case 32: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W32_H32; break; + case 64: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W64_H64; break; + case 128: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W128_H128; break; + case 256: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W256_H256; break; default: return -EINVAL; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/headc37d.c b/drivers/gpu/drm/nouveau/dispnv50/headc37d.c index 35fcdf8825b5..63adfeba50e5 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/headc37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/headc37d.c @@ -23,96 +23,131 @@ #include "atom.h" #include "core.h" -static void +#include <nvif/pushc37b.h> + +#include <nvhw/class/clc37d.h> + +static int headc37d_or(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; u8 depth; - u32 *push; - - if ((push = evo_wait(core, 2))) { - /*XXX: This is a dirty hack until OR depth handling is - * improved later for deep colour etc. - */ - switch (asyh->or.depth) { - case 6: depth = 5; break; - case 5: depth = 4; break; - case 2: depth = 1; break; - case 0: depth = 4; break; - default: - depth = asyh->or.depth; - WARN_ON(1); - break; - } - - evo_mthd(push, 0x2004 + (head->base.index * 0x400), 1); - evo_data(push, depth << 4 | - asyh->or.nvsync << 3 | - asyh->or.nhsync << 2 | - asyh->or.crc_raster); - evo_kick(push, core); + int ret; + + /*XXX: This is a dirty hack until OR depth handling is + * improved later for deep colour etc. + */ + switch (asyh->or.depth) { + case 6: depth = 5; break; + case 5: depth = 4; break; + case 2: depth = 1; break; + case 0: depth = 4; break; + default: + depth = asyh->or.depth; + WARN_ON(1); + break; } + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTROL_OUTPUT_RESOURCE(i), + NVVAL(NVC37D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, CRC_MODE, asyh->or.crc_raster) | + NVVAL(NVC37D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, HSYNC_POLARITY, asyh->or.nhsync) | + NVVAL(NVC37D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, VSYNC_POLARITY, asyh->or.nvsync) | + NVVAL(NVC37D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, PIXEL_DEPTH, depth) | + NVDEF(NVC37D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, COLOR_SPACE_OVERRIDE, DISABLE)); + return 0; } -static void +static int headc37d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x2000 + (head->base.index * 0x400), 1); - evo_data(push, 0x80000000 | - asyh->procamp.sat.sin << 16 | - asyh->procamp.sat.cos << 4); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_PROCAMP(i), + NVDEF(NVC37D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) | + NVDEF(NVC37D, HEAD_SET_PROCAMP, CHROMA_LPF, DISABLE) | + NVVAL(NVC37D, HEAD_SET_PROCAMP, SAT_COS, asyh->procamp.sat.cos) | + NVVAL(NVC37D, HEAD_SET_PROCAMP, SAT_SINE, asyh->procamp.sat.sin) | + NVDEF(NVC37D, HEAD_SET_PROCAMP, DYNAMIC_RANGE, VESA) | + NVDEF(NVC37D, HEAD_SET_PROCAMP, RANGE_COMPRESSION, DISABLE) | + NVDEF(NVC37D, HEAD_SET_PROCAMP, BLACK_LEVEL, GRAPHICS)); + return 0; } -void +int headc37d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x2018 + (head->base.index * 0x0400), 1); - evo_data(push, asyh->dither.mode << 8 | - asyh->dither.bits << 4 | - asyh->dither.enable); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_DITHER_CONTROL(i), + NVVAL(NVC37D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) | + NVVAL(NVC37D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) | + NVDEF(NVC37D, HEAD_SET_DITHER_CONTROL, OFFSET_ENABLE, DISABLE) | + NVVAL(NVC37D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) | + NVVAL(NVC37D, HEAD_SET_DITHER_CONTROL, PHASE, 0)); + return 0; } -void +int headc37d_curs_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x209c + head->base.index * 0x400, 1); - evo_data(push, 0x000000cf); - evo_mthd(push, 0x2088 + head->base.index * 0x400, 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NVC37D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) | + NVDEF(NVC37D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8)); + + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CURSOR(i, 0), 0x00000000); + return 0; } -void +int headc37d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 7))) { - evo_mthd(push, 0x209c + head->base.index * 0x400, 2); - evo_data(push, 0x80000000 | - asyh->curs.layout << 8 | - asyh->curs.format << 0); - evo_data(push, 0x000072ff); - evo_mthd(push, 0x2088 + head->base.index * 0x400, 1); - evo_data(push, asyh->curs.handle); - evo_mthd(push, 0x2090 + head->base.index * 0x400, 1); - evo_data(push, asyh->curs.offset >> 8); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 7))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NVC37D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) | + NVVAL(NVC37D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) | + NVVAL(NVC37D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) | + NVVAL(NVC37D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) | + NVVAL(NVC37D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) | + NVDEF(NVC37D, HEAD_SET_CONTROL_CURSOR, DE_GAMMA, NONE), + + HEAD_SET_CONTROL_CURSOR_COMPOSITION(i), + NVVAL(NVC37D, HEAD_SET_CONTROL_CURSOR_COMPOSITION, K1, 0xff) | + NVDEF(NVC37D, HEAD_SET_CONTROL_CURSOR_COMPOSITION, CURSOR_COLOR_FACTOR_SELECT, + K1) | + NVDEF(NVC37D, HEAD_SET_CONTROL_CURSOR_COMPOSITION, VIEWPORT_COLOR_FACTOR_SELECT, + NEG_K1_TIMES_SRC) | + NVDEF(NVC37D, HEAD_SET_CONTROL_CURSOR_COMPOSITION, MODE, BLEND)); + + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CURSOR(i, 0), asyh->curs.handle); + PUSH_MTHD(push, NVC37D, HEAD_SET_OFFSET_CURSOR(i, 0), asyh->curs.offset >> 8); + return 0; } int @@ -123,32 +158,38 @@ headc37d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw, return 0; } -static void +static int headc37d_olut_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x20ac + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_OUTPUT_LUT(i), 0x00000000); + return 0; } -static void +static int headc37d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x20a4 + (head->base.index * 0x400), 3); - evo_data(push, asyh->olut.output_mode << 8 | - asyh->olut.range << 4 | - asyh->olut.size); - evo_data(push, asyh->olut.offset >> 8); - evo_data(push, asyh->olut.handle); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_CONTROL_OUTPUT_LUT(i), + NVVAL(NVC37D, HEAD_SET_CONTROL_OUTPUT_LUT, SIZE, asyh->olut.size) | + NVVAL(NVC37D, HEAD_SET_CONTROL_OUTPUT_LUT, RANGE, asyh->olut.range) | + NVVAL(NVC37D, HEAD_SET_CONTROL_OUTPUT_LUT, OUTPUT_MODE, asyh->olut.output_mode), + + HEAD_SET_OFFSET_OUTPUT_LUT(i), asyh->olut.offset >> 8, + HEAD_SET_CONTEXT_DMA_OUTPUT_LUT(i), asyh->olut.handle); + return 0; } static bool @@ -157,51 +198,77 @@ headc37d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) if (size != 256 && size != 1024) return false; - asyh->olut.mode = 2; - asyh->olut.size = size == 1024 ? 2 : 0; - asyh->olut.range = 0; - asyh->olut.output_mode = 1; + asyh->olut.size = size == 1024 ? NVC37D_HEAD_SET_CONTROL_OUTPUT_LUT_SIZE_SIZE_1025 : + NVC37D_HEAD_SET_CONTROL_OUTPUT_LUT_SIZE_SIZE_257; + asyh->olut.range = NVC37D_HEAD_SET_CONTROL_OUTPUT_LUT_RANGE_UNITY; + asyh->olut.output_mode = NVC37D_HEAD_SET_CONTROL_OUTPUT_LUT_OUTPUT_MODE_INTERPOLATE; asyh->olut.load = head907d_olut_load; return true; } -static void +static int headc37d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; struct nv50_head_mode *m = &asyh->mode; - u32 *push; - if ((push = evo_wait(core, 13))) { - evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5); - evo_data(push, (m->v.active << 16) | m->h.active ); - evo_data(push, (m->v.synce << 16) | m->h.synce ); - evo_data(push, (m->v.blanke << 16) | m->h.blanke ); - evo_data(push, (m->v.blanks << 16) | m->h.blanks ); - evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_mthd(push, 0x2008 + (head->base.index * 0x400), 2); - evo_data(push, m->interlace); - evo_data(push, m->clock * 1000); - evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1); - evo_data(push, m->clock * 1000); - /*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */ - evo_mthd(push, 0x2030 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000124); - evo_kick(push, core); - } + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 15))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_RASTER_SIZE(i), + NVVAL(NVC37D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) | + NVVAL(NVC37D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active), + + HEAD_SET_RASTER_SYNC_END(i), + NVVAL(NVC37D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) | + NVVAL(NVC37D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce), + + HEAD_SET_RASTER_BLANK_END(i), + NVVAL(NVC37D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) | + NVVAL(NVC37D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke), + + HEAD_SET_RASTER_BLANK_START(i), + NVVAL(NVC37D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) | + NVVAL(NVC37D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks)); + + //XXX: + PUSH_NVSQ(push, NVC37D, 0x2074 + (i * 0x400), m->v.blank2e << 16 | m->v.blank2s); + PUSH_NVSQ(push, NVC37D, 0x2008 + (i * 0x400), m->interlace); + + PUSH_MTHD(push, NVC37D, HEAD_SET_PIXEL_CLOCK_FREQUENCY(i), + NVVAL(NVC37D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, m->clock * 1000)); + + PUSH_MTHD(push, NVC37D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i), + NVVAL(NVC37D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, m->clock * 1000)); + + /*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */ + PUSH_MTHD(push, NVC37D, HEAD_SET_HEAD_USAGE_BOUNDS(i), + NVDEF(NVC37D, HEAD_SET_HEAD_USAGE_BOUNDS, CURSOR, USAGE_W256_H256) | + NVDEF(NVC37D, HEAD_SET_HEAD_USAGE_BOUNDS, OUTPUT_LUT, USAGE_1025) | + NVDEF(NVC37D, HEAD_SET_HEAD_USAGE_BOUNDS, UPSCALING_ALLOWED, TRUE)); + return 0; } -void +int headc37d_view(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x204c + (head->base.index * 0x400), 1); - evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); - evo_mthd(push, 0x2058 + (head->base.index * 0x400), 1); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NVC37D, HEAD_SET_VIEWPORT_SIZE_IN(i), + NVVAL(NVC37D, HEAD_SET_VIEWPORT_SIZE_IN, WIDTH, asyh->view.iW) | + NVVAL(NVC37D, HEAD_SET_VIEWPORT_SIZE_IN, HEIGHT, asyh->view.iH)); + + PUSH_MTHD(push, NVC37D, HEAD_SET_VIEWPORT_SIZE_OUT(i), + NVVAL(NVC37D, HEAD_SET_VIEWPORT_SIZE_OUT, WIDTH, asyh->view.oW) | + NVVAL(NVC37D, HEAD_SET_VIEWPORT_SIZE_OUT, HEIGHT, asyh->view.oH)); + return 0; } void diff --git a/drivers/gpu/drm/nouveau/dispnv50/headc57d.c b/drivers/gpu/drm/nouveau/dispnv50/headc57d.c index c7d04dd935fd..fd51527b56b8 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/headc57d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/headc57d.c @@ -23,83 +23,97 @@ #include "atom.h" #include "core.h" -static void +#include <nvif/pushc37b.h> + +#include <nvhw/class/clc57d.h> + +static int headc57d_or(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; u8 depth; - u32 *push; - - if ((push = evo_wait(core, 2))) { - /*XXX: This is a dirty hack until OR depth handling is - * improved later for deep colour etc. - */ - switch (asyh->or.depth) { - case 6: depth = 5; break; - case 5: depth = 4; break; - case 2: depth = 1; break; - case 0: depth = 4; break; - default: - depth = asyh->or.depth; - WARN_ON(1); - break; - } + int ret; - evo_mthd(push, 0x2004 + (head->base.index * 0x400), 1); - evo_data(push, 0xfc000000 | - depth << 4 | - asyh->or.nvsync << 3 | - asyh->or.nhsync << 2 | - asyh->or.crc_raster); - evo_kick(push, core); + /*XXX: This is a dirty hack until OR depth handling is + * improved later for deep colour etc. + */ + switch (asyh->or.depth) { + case 6: depth = 5; break; + case 5: depth = 4; break; + case 2: depth = 1; break; + case 0: depth = 4; break; + default: + depth = asyh->or.depth; + WARN_ON(1); + break; } + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE(i), + NVVAL(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, CRC_MODE, asyh->or.crc_raster) | + NVVAL(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, HSYNC_POLARITY, asyh->or.nhsync) | + NVVAL(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, VSYNC_POLARITY, asyh->or.nvsync) | + NVVAL(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, PIXEL_DEPTH, depth) | + NVDEF(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, COLOR_SPACE_OVERRIDE, DISABLE) | + NVDEF(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, EXT_PACKET_WIN, NONE)); + return 0; } -static void +static int headc57d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x2000 + (head->base.index * 0x400), 1); -#if 0 - evo_data(push, 0x80000000 | - asyh->procamp.sat.sin << 16 | - asyh->procamp.sat.cos << 4); -#else - evo_data(push, 0); -#endif - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + //TODO: + PUSH_MTHD(push, NVC57D, HEAD_SET_PROCAMP(i), + NVDEF(NVC57D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) | + NVDEF(NVC57D, HEAD_SET_PROCAMP, CHROMA_LPF, DISABLE) | + NVDEF(NVC57D, HEAD_SET_PROCAMP, DYNAMIC_RANGE, VESA)); + return 0; } -void +static int headc57d_olut_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - evo_mthd(push, 0x2288 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC57D, HEAD_SET_CONTEXT_DMA_OLUT(i), 0x00000000); + return 0; } -void +static int headc57d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x2280 + (head->base.index * 0x400), 4); - evo_data(push, asyh->olut.size << 8 | - asyh->olut.mode << 2 | - asyh->olut.output_mode); - evo_data(push, 0xffffffff); /* FP_NORM_SCALE. */ - evo_data(push, asyh->olut.handle); - evo_data(push, asyh->olut.offset >> 8); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + PUSH_MTHD(push, NVC57D, HEAD_SET_OLUT_CONTROL(i), + NVVAL(NVC57D, HEAD_SET_OLUT_CONTROL, INTERPOLATE, asyh->olut.output_mode) | + NVDEF(NVC57D, HEAD_SET_OLUT_CONTROL, MIRROR, DISABLE) | + NVVAL(NVC57D, HEAD_SET_OLUT_CONTROL, MODE, asyh->olut.mode) | + NVVAL(NVC57D, HEAD_SET_OLUT_CONTROL, SIZE, asyh->olut.size), + + HEAD_SET_OLUT_FP_NORM_SCALE(i), 0xffffffff, + HEAD_SET_CONTEXT_DMA_OLUT(i), asyh->olut.handle, + HEAD_SET_OFFSET_OLUT(i), asyh->olut.offset >> 8); + return 0; } static void @@ -161,9 +175,9 @@ headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) if (size != 0 && size != 256 && size != 1024) return false; - asyh->olut.mode = 2; /* DIRECT10 */ + asyh->olut.mode = NVC57D_HEAD_SET_OLUT_CONTROL_MODE_DIRECT10; asyh->olut.size = 4 /* VSS header. */ + 1024 + 1 /* Entries. */; - asyh->olut.output_mode = 1; /* INTERPOLATE_ENABLE. */ + asyh->olut.output_mode = NVC57D_HEAD_SET_OLUT_CONTROL_INTERPOLATE_ENABLE; if (size == 256) asyh->olut.load = headc57d_olut_load_8; else @@ -171,29 +185,50 @@ headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) return true; } -static void +static int headc57d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; struct nv50_head_mode *m = &asyh->mode; - u32 *push; - if ((push = evo_wait(core, 13))) { - evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5); - evo_data(push, (m->v.active << 16) | m->h.active ); - evo_data(push, (m->v.synce << 16) | m->h.synce ); - evo_data(push, (m->v.blanke << 16) | m->h.blanke ); - evo_data(push, (m->v.blanks << 16) | m->h.blanks ); - evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_mthd(push, 0x2008 + (head->base.index * 0x400), 2); - evo_data(push, m->interlace); - evo_data(push, m->clock * 1000); - evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1); - evo_data(push, m->clock * 1000); - /*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */ - evo_mthd(push, 0x2030 + (head->base.index * 0x400), 1); - evo_data(push, 0x00001014); - evo_kick(push, core); - } + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 15))) + return ret; + + PUSH_MTHD(push, NVC57D, HEAD_SET_RASTER_SIZE(i), + NVVAL(NVC57D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) | + NVVAL(NVC57D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active), + + HEAD_SET_RASTER_SYNC_END(i), + NVVAL(NVC57D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) | + NVVAL(NVC57D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce), + + HEAD_SET_RASTER_BLANK_END(i), + NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) | + NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke), + + HEAD_SET_RASTER_BLANK_START(i), + NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) | + NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks)); + + //XXX: + PUSH_NVSQ(push, NVC57D, 0x2074 + (i * 0x400), m->v.blank2e << 16 | m->v.blank2s); + PUSH_NVSQ(push, NVC57D, 0x2008 + (i * 0x400), m->interlace); + + PUSH_MTHD(push, NVC57D, HEAD_SET_PIXEL_CLOCK_FREQUENCY(i), + NVVAL(NVC57D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, m->clock * 1000)); + + PUSH_MTHD(push, NVC57D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i), + NVVAL(NVC57D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, m->clock * 1000)); + + /*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */ + PUSH_MTHD(push, NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS(i), + NVDEF(NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS, CURSOR, USAGE_W256_H256) | + NVDEF(NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS, OLUT_ALLOWED, TRUE) | + NVDEF(NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS, OUTPUT_SCALER_TAPS, TAPS_2) | + NVDEF(NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS, UPSCALING_ALLOWED, TRUE)); + return 0; } const struct nv50_head_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/lut.c b/drivers/gpu/drm/nouveau/dispnv50/lut.c index 4e95ca5604ab..6b2ad1e6eab9 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/lut.c +++ b/drivers/gpu/drm/nouveau/dispnv50/lut.c @@ -60,7 +60,7 @@ nv50_lut_fini(struct nv50_lut *lut) { int i; for (i = 0; i < ARRAY_SIZE(lut->mem); i++) - nvif_mem_fini(&lut->mem[i]); + nvif_mem_dtor(&lut->mem[i]); } int @@ -70,8 +70,8 @@ nv50_lut_init(struct nv50_disp *disp, struct nvif_mmu *mmu, const u32 size = disp->disp->object.oclass < GF110_DISP ? 257 : 1025; int i; for (i = 0; i < ARRAY_SIZE(lut->mem); i++) { - int ret = nvif_mem_init_map(mmu, NVIF_MEM_VRAM, size * 8, - &lut->mem[i]); + int ret = nvif_mem_ctor_map(mmu, "kmsLut", NVIF_MEM_VRAM, + size * 8, &lut->mem[i]); if (ret) return ret; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c b/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c index 2ee404b3e19f..a6c3a9b95bdb 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c +++ b/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c @@ -33,8 +33,8 @@ oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, struct nv50_disp *disp = nv50_disp(drm->dev); int ret; - ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, - sizeof(args), &wndw->wimm.base.user); + ret = nvif_object_ctor(&disp->disp->object, "kmsOvim", 0, oclass, + &args, sizeof(args), &wndw->wimm.base.user); if (ret) { NV_ERROR(drm, "oimm%04x allocation failed: %d\n", oclass, ret); return ret; diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.h b/drivers/gpu/drm/nouveau/dispnv50/ovly.h index 4869d52d1786..6ae1fbe12ca7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly.h +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.h @@ -10,11 +10,7 @@ int ovly507e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *, struct nv50_head_atom *); void ovly507e_release(struct nv50_wndw *, struct nv50_wndw_atom *, struct nv50_head_atom *); -void ovly507e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); -void ovly507e_ntfy_clr(struct nv50_wndw *); -void ovly507e_image_clr(struct nv50_wndw *); -void ovly507e_scale_set(struct nv50_wndw *, struct nv50_wndw_atom *); -void ovly507e_update(struct nv50_wndw *, u32 *); +int ovly507e_scale_set(struct nv50_wndw *, struct nv50_wndw_atom *); extern const u32 ovly827e_format[]; void ovly827e_ntfy_reset(struct nouveau_bo *, u32); diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c index 4cce1078140a..afd6c7271de1 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c @@ -28,91 +28,68 @@ #include <nvif/cl507e.h> #include <nvif/event.h> +#include <nvif/push507c.h> -void -ovly507e_update(struct nv50_wndw *wndw, u32 *interlock) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x0080, 1); - evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]); - evo_kick(push, &wndw->wndw); - } -} +#include <nvhw/class/cl507e.h> -void +int ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 4))) { - evo_mthd(push, 0x00e0, 3); - evo_data(push, asyw->scale.sy << 16 | asyw->scale.sx); - evo_data(push, asyw->scale.sh << 16 | asyw->scale.sw); - evo_data(push, asyw->scale.dw); - evo_kick(push, &wndw->wndw); - } -} + struct nvif_push *push = wndw->wndw.push; + int ret; -void -ovly507e_image_clr(struct nv50_wndw *wndw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 4))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x00c0, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NV507E, SET_POINT_IN, + NVVAL(NV507E, SET_POINT_IN, X, asyw->scale.sx) | + NVVAL(NV507E, SET_POINT_IN, Y, asyw->scale.sy), + + SET_SIZE_IN, + NVVAL(NV507E, SET_SIZE_IN, WIDTH, asyw->scale.sw) | + NVVAL(NV507E, SET_SIZE_IN, HEIGHT, asyw->scale.sh), + + SET_SIZE_OUT, + NVVAL(NV507E, SET_SIZE_OUT, WIDTH, asyw->scale.dw)); + return 0; } -static void +static int ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 12))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, asyw->image.interval << 4); - evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle[0]); - evo_mthd(push, 0x0100, 1); - evo_data(push, 0x00000002); - evo_mthd(push, 0x0800, 1); - evo_data(push, asyw->image.offset[0] >> 8); - evo_mthd(push, 0x0808, 3); - evo_data(push, asyw->image.h << 16 | asyw->image.w); - evo_data(push, asyw->image.layout << 20 | - (asyw->image.pitch[0] >> 8) << 8 | - asyw->image.blocks[0] << 8 | - asyw->image.blockh); - evo_data(push, asyw->image.kind << 16 | - asyw->image.format << 8 | - asyw->image.colorspace); - evo_kick(push, &wndw->wndw); - } -} + struct nvif_push *push = wndw->wndw.push; + int ret; -void -ovly507e_ntfy_clr(struct nv50_wndw *wndw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x00a4, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } -} + if ((ret = PUSH_WAIT(push, 12))) + return ret; -void -ovly507e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 3))) { - evo_mthd(push, 0x00a0, 2); - evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset); - evo_data(push, asyw->ntfy.handle); - evo_kick(push, &wndw->wndw); - } + PUSH_MTHD(push, NV507E, SET_PRESENT_CONTROL, + NVDEF(NV507E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) | + NVVAL(NV507E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval)); + + PUSH_MTHD(push, NV507E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]); + + PUSH_MTHD(push, NV507E, SET_COMPOSITION_CONTROL, + NVDEF(NV507E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE)); + + PUSH_MTHD(push, NV507E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8); + + PUSH_MTHD(push, NV507E, SURFACE_SET_SIZE, + NVVAL(NV507E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NV507E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h), + + SURFACE_SET_STORAGE, + NVVAL(NV507E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) | + NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) | + NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NV507E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout), + + SURFACE_SET_PARAMS, + NVVAL(NV507E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) | + NVVAL(NV507E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace) | + NVVAL(NV507E, SURFACE_SET_PARAMS, KIND, asyw->image.kind) | + NVDEF(NV507E, SURFACE_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256)); + return 0; } void @@ -146,14 +123,14 @@ static const struct nv50_wndw_func ovly507e = { .acquire = ovly507e_acquire, .release = ovly507e_release, - .ntfy_set = ovly507e_ntfy_set, - .ntfy_clr = ovly507e_ntfy_clr, + .ntfy_set = base507c_ntfy_set, + .ntfy_clr = base507c_ntfy_clr, .ntfy_reset = base507c_ntfy_reset, .ntfy_wait_begun = base507c_ntfy_wait_begun, .image_set = ovly507e_image_set, - .image_clr = ovly507e_image_clr, + .image_clr = base507c_image_clr, .scale_set = ovly507e_scale_set, - .update = ovly507e_update, + .update = base507c_update, }; static const u32 @@ -192,7 +169,8 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, return ret; } - ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, false, + ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsOvlyNtfy", + wndw->notify.func, false, NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT, &(struct nvif_notify_uevent_req) {}, sizeof(struct nvif_notify_uevent_req), diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c index 4f7ce57f2036..02dc02d9260f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c @@ -24,31 +24,45 @@ #include <nouveau_bo.h> +#include <nvif/push507c.h> #include <nvif/timer.h> -static void +#include <nvhw/class/cl827e.h> + +static int ovly827e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 12))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, asyw->image.interval << 4); - evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle[0]); - evo_mthd(push, 0x0100, 1); - evo_data(push, 0x00000002); - evo_mthd(push, 0x0800, 1); - evo_data(push, asyw->image.offset[0] >> 8); - evo_mthd(push, 0x0808, 3); - evo_data(push, asyw->image.h << 16 | asyw->image.w); - evo_data(push, asyw->image.layout << 20 | - (asyw->image.pitch[0] >> 8) << 8 | - asyw->image.blocks[0] << 8 | - asyw->image.blockh); - evo_data(push, asyw->image.format << 8 | - asyw->image.colorspace); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 12))) + return ret; + + PUSH_MTHD(push, NV827E, SET_PRESENT_CONTROL, + NVDEF(NV827E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) | + NVVAL(NV827E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval)); + + PUSH_MTHD(push, NV827E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]); + + PUSH_MTHD(push, NV827E, SET_COMPOSITION_CONTROL, + NVDEF(NV827E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE)); + + PUSH_MTHD(push, NV827E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8); + + PUSH_MTHD(push, NV827E, SURFACE_SET_SIZE, + NVVAL(NV827E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NV827E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h), + + SURFACE_SET_STORAGE, + NVVAL(NV827E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) | + NVVAL(NV827E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) | + NVVAL(NV827E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NV827E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout), + + SURFACE_SET_PARAMS, + NVVAL(NV827E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) | + NVVAL(NV827E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace)); + return 0; } int @@ -56,8 +70,7 @@ ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, struct nvif_device *device) { s64 time = nvif_msec(device, 2000ULL, - u32 data = nouveau_bo_rd32(bo, offset / 4 + 3); - if ((data & 0xffff0000) == 0xffff0000) + if (NVBO_TD32(bo, offset, NV_DISP_NOTIFICATION_1, _3, STATUS, ==, BEGUN)) break; usleep_range(1, 2); ); @@ -67,24 +80,25 @@ ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, void ovly827e_ntfy_reset(struct nouveau_bo *bo, u32 offset) { - nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000); - nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000); - nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000); - nouveau_bo_wr32(bo, offset / 4 + 3, 0x80000000); + NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, TIME_STAMP_0, 0); + NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, TIME_STAMP_1, 0); + NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, _2, 0); + NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, _3, + NVDEF(NV_DISP_NOTIFICATION_1, _3, STATUS, NOT_BEGUN)); } static const struct nv50_wndw_func ovly827e = { .acquire = ovly507e_acquire, .release = ovly507e_release, - .ntfy_set = ovly507e_ntfy_set, - .ntfy_clr = ovly507e_ntfy_clr, + .ntfy_set = base507c_ntfy_set, + .ntfy_clr = base507c_ntfy_clr, .ntfy_reset = ovly827e_ntfy_reset, .ntfy_wait_begun = ovly827e_ntfy_wait_begun, .image_set = ovly827e_image_set, - .image_clr = ovly507e_image_clr, + .image_clr = base507c_image_clr, .scale_set = ovly507e_scale_set, - .update = ovly507e_update, + .update = base507c_update, }; const u32 diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c index 9efe5e9d5ce4..645130d18a99 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c @@ -22,43 +22,58 @@ #include "ovly.h" #include "atom.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl907e.h> + +static int ovly907e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 12))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, asyw->image.interval << 4); - evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle[0]); - evo_mthd(push, 0x0100, 1); - evo_data(push, 0x00000002); - evo_mthd(push, 0x0400, 1); - evo_data(push, asyw->image.offset[0] >> 8); - evo_mthd(push, 0x0408, 3); - evo_data(push, asyw->image.h << 16 | asyw->image.w); - evo_data(push, asyw->image.layout << 24 | - (asyw->image.pitch[0] >> 8) << 8 | - asyw->image.blocks[0] << 8 | - asyw->image.blockh); - evo_data(push, asyw->image.format << 8 | - asyw->image.colorspace); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 12))) + return ret; + + PUSH_MTHD(push, NV907E, SET_PRESENT_CONTROL, + NVDEF(NV907E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) | + NVVAL(NV907E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval)); + + PUSH_MTHD(push, NV907E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]); + + PUSH_MTHD(push, NV907E, SET_COMPOSITION_CONTROL, + NVDEF(NV907E, SET_COMPOSITION_CONTROL, MODE, OPAQUE)); + + PUSH_MTHD(push, NV907E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8); + + PUSH_MTHD(push, NV907E, SURFACE_SET_SIZE, + NVVAL(NV907E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NV907E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h), + + SURFACE_SET_STORAGE, + NVVAL(NV907E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) | + NVVAL(NV907E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) | + NVVAL(NV907E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NV907E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout), + + SURFACE_SET_PARAMS, + NVVAL(NV907E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) | + NVVAL(NV907E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace)); + return 0; } const struct nv50_wndw_func ovly907e = { .acquire = ovly507e_acquire, .release = ovly507e_release, - .ntfy_set = ovly507e_ntfy_set, - .ntfy_clr = ovly507e_ntfy_clr, + .ntfy_set = base507c_ntfy_set, + .ntfy_clr = base507c_ntfy_clr, .ntfy_reset = ovly827e_ntfy_reset, .ntfy_wait_begun = ovly827e_ntfy_wait_begun, .image_set = ovly907e_image_set, - .image_clr = ovly507e_image_clr, + .image_clr = base507c_image_clr, .scale_set = ovly507e_scale_set, - .update = ovly507e_update, + .update = base507c_update, }; static const u32 diff --git a/drivers/gpu/drm/nouveau/dispnv50/pior507d.c b/drivers/gpu/drm/nouveau/dispnv50/pior507d.c index 45d8ce7d2c28..17d230256bdd 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/pior507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/pior507d.c @@ -21,21 +21,29 @@ */ #include "core.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl507d.h> +#include <nvhw/class/cl837d.h> + +static int pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { - u32 *push; - if ((push = evo_wait(&core->chan, 2))) { - if (asyh) { - ctrl |= asyh->or.depth << 16; - ctrl |= asyh->or.nvsync << 13; - ctrl |= asyh->or.nhsync << 12; - } - evo_mthd(push, 0x0700 + (or * 0x040), 1); - evo_data(push, ctrl); - evo_kick(push, &core->chan); + struct nvif_push *push = core->chan.push; + int ret; + + if (asyh) { + ctrl |= NVVAL(NV507D, PIOR_SET_CONTROL, HSYNC_POLARITY, asyh->or.nhsync); + ctrl |= NVVAL(NV507D, PIOR_SET_CONTROL, VSYNC_POLARITY, asyh->or.nvsync); + ctrl |= NVVAL(NV837D, PIOR_SET_CONTROL, PIXEL_DEPTH, asyh->or.depth); } + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, PIOR_SET_CONTROL(or), ctrl); + return 0; } static void diff --git a/drivers/gpu/drm/nouveau/dispnv50/sor507d.c b/drivers/gpu/drm/nouveau/dispnv50/sor507d.c index 9a59fa7da00d..ca73d7710885 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/sor507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/sor507d.c @@ -21,21 +21,29 @@ */ #include "core.h" -static void +#include <nvif/push507c.h> + +#include <nvhw/class/cl507d.h> +#include <nvhw/class/cl837d.h> + +static int sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { - u32 *push; - if ((push = evo_wait(&core->chan, 2))) { - if (asyh) { - ctrl |= asyh->or.depth << 16; - ctrl |= asyh->or.nvsync << 13; - ctrl |= asyh->or.nhsync << 12; - } - evo_mthd(push, 0x0600 + (or * 0x40), 1); - evo_data(push, ctrl); - evo_kick(push, &core->chan); + struct nvif_push *push = core->chan.push; + int ret; + + if (asyh) { + ctrl |= NVVAL(NV507D, SOR_SET_CONTROL, HSYNC_POLARITY, asyh->or.nhsync); + ctrl |= NVVAL(NV507D, SOR_SET_CONTROL, VSYNC_POLARITY, asyh->or.nvsync); + ctrl |= NVVAL(NV837D, SOR_SET_CONTROL, PIXEL_DEPTH, asyh->or.depth); } + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV507D, SOR_SET_CONTROL(or), ctrl); + return 0; } static void diff --git a/drivers/gpu/drm/nouveau/dispnv50/sor907d.c b/drivers/gpu/drm/nouveau/dispnv50/sor907d.c index 9577ccf1c809..c86cd8fa61d6 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/sor907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/sor907d.c @@ -21,28 +21,34 @@ */ #include "core.h" -#include <nouveau_bo.h> #include <nvif/class.h> +#include <nvif/push507c.h> -static void +#include <nvhw/class/cl907d.h> + +#include <nouveau_bo.h> + +static int sor907d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { - u32 *push; - if ((push = evo_wait(&core->chan, 2))) { - evo_mthd(push, 0x0200 + (or * 0x20), 1); - evo_data(push, ctrl); - evo_kick(push, &core->chan); - } + struct nvif_push *push = core->chan.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NV907D, SOR_SET_CONTROL(or), ctrl); + return 0; } static void sor907d_get_caps(struct nv50_disp *disp, struct nouveau_encoder *outp, int or) { + struct nouveau_bo *bo = disp->sync; const int off = or * 2; - u32 tmp = nouveau_bo_rd32(disp->sync, 0x000014 + off); - - outp->caps.dp_interlace = !!(tmp & 0x04000000); + outp->caps.dp_interlace = + NVBO_RV32(bo, off, NV907D_CORE_NOTIFIER_3, CAPABILITIES_CAP_SOR0_20, DP_INTERLACE); } const struct nv50_outp_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c b/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c index c86ca955fdcd..9eaef34816da 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c @@ -21,16 +21,22 @@ */ #include "core.h" -static void +#include <nvif/pushc37b.h> + +#include <nvhw/class/clc37d.h> + +static int sorc37d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { - u32 *push; - if ((push = evo_wait(&core->chan, 2))) { - evo_mthd(push, 0x0300 + (or * 0x20), 1); - evo_data(push, ctrl); - evo_kick(push, &core->chan); - } + struct nvif_push *push = core->chan.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37D, SOR_SET_CONTROL(or), ctrl); + return 0; } static void diff --git a/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c b/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c index f7dbd965e4e7..685b70871324 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c @@ -24,30 +24,38 @@ #include "wndw.h" #include <nvif/clc37b.h> +#include <nvif/pushc37b.h> -static void +#include <nvhw/class/clc37b.h> + +static int wimmc37b_update(struct nv50_wndw *wndw, u32 *interlock) { - u32 *push; - if ((push = evo_wait(&wndw->wimm, 2))) { - evo_mthd(push, 0x0200, 1); - if (interlock[NV50_DISP_INTERLOCK_WNDW] & wndw->interlock.data) - evo_data(push, 0x00000003); - else - evo_data(push, 0x00000001); - evo_kick(push, &wndw->wimm); - } + struct nvif_push *push = wndw->wimm.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37B, UPDATE, 0x00000001 | + NVVAL(NVC37B, UPDATE, INTERLOCK_WITH_WINDOW, + !!(interlock[NV50_DISP_INTERLOCK_WNDW] & wndw->interlock.data))); + return PUSH_KICK(push); } -static void +static int wimmc37b_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wimm, 2))) { - evo_mthd(push, 0x0208, 1); - evo_data(push, asyw->point.y << 16 | asyw->point.x); - evo_kick(push, &wndw->wimm); - } + struct nvif_push *push = wndw->wimm.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37B, SET_POINT_OUT(0), + NVVAL(NVC37B, SET_POINT_OUT, X, asyw->point.x) | + NVVAL(NVC37B, SET_POINT_OUT, Y, asyw->point.y)); + return 0; } static const struct nv50_wimm_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 293ccfdba17e..447ecc9fec42 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -26,6 +26,10 @@ #include <nvif/class.h> #include <nvif/cl0002.h> +#include <nvhw/class/cl507c.h> +#include <nvhw/class/cl507e.h> +#include <nvhw/class/clc37e.h> + #include <drm/drm_atomic_helper.h> #include <drm/drm_fourcc.h> @@ -35,7 +39,7 @@ static void nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) { - nvif_object_fini(&ctxdma->object); + nvif_object_dtor(&ctxdma->object); list_del(&ctxdma->head); kfree(ctxdma); } @@ -94,8 +98,8 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb) argc += sizeof(args.gf119); } - ret = nvif_object_init(wndw->ctxdma.parent, handle, NV_DMA_IN_MEMORY, - &args, argc, &ctxdma->object); + ret = nvif_object_ctor(wndw->ctxdma.parent, "kmsFbCtxDma", handle, + NV_DMA_IN_MEMORY, &args, argc, &ctxdma->object); if (ret) { nv50_wndw_ctxdma_del(ctxdma); return ERR_PTR(ret); @@ -137,7 +141,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, struct nv50_wndw_atom *asyw) { if (interlock[NV50_DISP_INTERLOCK_CORE]) { - asyw->image.mode = 0; + asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_NON_TEARING; asyw->image.interval = 1; } @@ -201,13 +205,18 @@ static int nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw) { switch (asyw->state.fb->format->format) { - case DRM_FORMAT_YUYV: asyw->image.format = 0x28; break; - case DRM_FORMAT_UYVY: asyw->image.format = 0x29; break; + case DRM_FORMAT_YUYV: + asyw->image.format = NV507E_SURFACE_SET_PARAMS_FORMAT_VE8YO8UE8YE8; + break; + case DRM_FORMAT_UYVY: + asyw->image.format = NV507E_SURFACE_SET_PARAMS_FORMAT_YO8VE8YE8UE8; + break; default: WARN_ON(1); return -EINVAL; } - asyw->image.colorspace = 1; + + asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_YUV_601; return 0; } @@ -215,24 +224,41 @@ static int nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw) { switch (asyw->state.fb->format->format) { - case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break; - case DRM_FORMAT_XRGB8888 : - case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break; - case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break; - case DRM_FORMAT_XRGB1555 : - case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break; - case DRM_FORMAT_XBGR2101010 : - case DRM_FORMAT_ABGR2101010 : asyw->image.format = 0xd1; break; - case DRM_FORMAT_XBGR8888 : - case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; - case DRM_FORMAT_XRGB2101010 : - case DRM_FORMAT_ARGB2101010 : asyw->image.format = 0xdf; break; + case DRM_FORMAT_C8: + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_I8; + break; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A8R8G8B8; + break; + case DRM_FORMAT_RGB565: + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_R5G6B5; + break; + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_ARGB1555: + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A1R5G5B5; + break; + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A2B10G10R10; + break; + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A8B8G8R8; + break; + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: + asyw->image.format = NVC37E_SET_PARAMS_FORMAT_A2R10G10B10; + break; case DRM_FORMAT_XBGR16161616F: - case DRM_FORMAT_ABGR16161616F: asyw->image.format = 0xca; break; + case DRM_FORMAT_ABGR16161616F: + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16; + break; default: return -EINVAL; } - asyw->image.colorspace = 0; + + asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_RGB; return 0; } @@ -265,7 +291,7 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, } if (asyw->image.kind) { - asyw->image.layout = 0; + asyw->image.layout = NV507C_SURFACE_SET_STORAGE_MEMORY_LAYOUT_BLOCKLINEAR; if (drm->client.device.info.chipset >= 0xc0) asyw->image.blockh = tile_mode >> 4; else @@ -273,8 +299,8 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, asyw->image.blocks[0] = fb->pitches[0] / 64; asyw->image.pitch[0] = 0; } else { - asyw->image.layout = 1; - asyw->image.blockh = 0; + asyw->image.layout = NV507C_SURFACE_SET_STORAGE_MEMORY_LAYOUT_PITCH; + asyw->image.blockh = NV507C_SURFACE_SET_STORAGE_BLOCK_HEIGHT_ONE_GOB; asyw->image.blocks[0] = 0; asyw->image.pitch[0] = fb->pitches[0]; } @@ -283,7 +309,12 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, asyw->image.interval = 1; else asyw->image.interval = 0; - asyw->image.mode = asyw->image.interval ? 0 : 1; + + if (asyw->image.interval) + asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_NON_TEARING; + else + asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_IMMEDIATE; + asyw->set.image = wndw->func->image_set != NULL; } @@ -303,17 +334,17 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, asyw->blend.k1 = asyw->state.alpha >> 8; switch (asyw->state.pixel_blend_mode) { case DRM_MODE_BLEND_PREMULTI: - asyw->blend.src_color = 2; /* K1 */ - asyw->blend.dst_color = 7; /* NEG_K1_TIMES_SRC */ + asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1; + asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1_TIMES_SRC; break; case DRM_MODE_BLEND_COVERAGE: - asyw->blend.src_color = 5; /* K1_TIMES_SRC */ - asyw->blend.dst_color = 7; /* NEG_K1_TIMES_SRC */ + asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1_TIMES_SRC; + asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1_TIMES_SRC; break; case DRM_MODE_BLEND_PIXEL_NONE: default: - asyw->blend.src_color = 2; /* K1 */ - asyw->blend.dst_color = 4; /* NEG_K1 */ + asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1; + asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1; break; } if (memcmp(&armw->blend, &asyw->blend, sizeof(asyw->blend))) @@ -609,7 +640,7 @@ nv50_wndw_destroy(struct drm_plane *plane) nv50_wndw_ctxdma_del(ctxdma); } - nvif_notify_fini(&wndw->notify); + nvif_notify_dtor(&wndw->notify); nv50_dmac_destroy(&wndw->wimm); nv50_dmac_destroy(&wndw->wndw); diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index a7412b9d3a98..3278e2880034 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -57,48 +57,59 @@ struct nv50_wndw_func { void (*prepare)(struct nv50_wndw *, struct nv50_head_atom *asyh, struct nv50_wndw_atom *asyw); - void (*sema_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*sema_clr)(struct nv50_wndw *); + int (*sema_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*sema_clr)(struct nv50_wndw *); void (*ntfy_reset)(struct nouveau_bo *, u32 offset); - void (*ntfy_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*ntfy_clr)(struct nv50_wndw *); + int (*ntfy_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*ntfy_clr)(struct nv50_wndw *); int (*ntfy_wait_begun)(struct nouveau_bo *, u32 offset, struct nvif_device *); bool (*ilut)(struct nv50_wndw *, struct nv50_wndw_atom *, int); void (*csc)(struct nv50_wndw *, struct nv50_wndw_atom *, const struct drm_color_ctm *); - void (*csc_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*csc_clr)(struct nv50_wndw *); + int (*csc_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*csc_clr)(struct nv50_wndw *); bool ilut_identity; int ilut_size; bool olut_core; - void (*xlut_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*xlut_clr)(struct nv50_wndw *); - void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*image_clr)(struct nv50_wndw *); - void (*scale_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*blend_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - - void (*update)(struct nv50_wndw *, u32 *interlock); + int (*xlut_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*xlut_clr)(struct nv50_wndw *); + int (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*image_clr)(struct nv50_wndw *); + int (*scale_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*blend_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + + int (*update)(struct nv50_wndw *, u32 *interlock); }; extern const struct drm_plane_funcs nv50_wndw; void base507c_ntfy_reset(struct nouveau_bo *, u32); +int base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); +int base507c_ntfy_clr(struct nv50_wndw *); int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *); +int base507c_image_clr(struct nv50_wndw *); +int base507c_update(struct nv50_wndw *, u32 *); void base907c_csc(struct nv50_wndw *, struct nv50_wndw_atom *, const struct drm_color_ctm *); struct nv50_wimm_func { - void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*update)(struct nv50_wndw *, u32 *interlock); + int (*update)(struct nv50_wndw *, u32 *interlock); }; extern const struct nv50_wimm_func curs507a; bool curs507a_space(struct nv50_wndw *); +static inline __must_check int +nvif_chan_wait(struct nv50_dmac *dmac, u32 size) +{ + struct nv50_wndw *wndw = container_of(dmac, typeof(*wndw), wimm); + return curs507a_space(wndw) ? 0 : -ETIMEDOUT; +} + int wndwc37e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, struct nv50_wndw **); int wndwc37e_new_(const struct nv50_wndw_func *, struct nouveau_drm *, @@ -108,13 +119,13 @@ int wndwc37e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *, struct nv50_head_atom *); void wndwc37e_release(struct nv50_wndw *, struct nv50_wndw_atom *, struct nv50_head_atom *); -void wndwc37e_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *); -void wndwc37e_sema_clr(struct nv50_wndw *); -void wndwc37e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); -void wndwc37e_ntfy_clr(struct nv50_wndw *); -void wndwc37e_image_clr(struct nv50_wndw *); -void wndwc37e_blend_set(struct nv50_wndw *, struct nv50_wndw_atom *); -void wndwc37e_update(struct nv50_wndw *, u32 *); +int wndwc37e_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *); +int wndwc37e_sema_clr(struct nv50_wndw *); +int wndwc37e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); +int wndwc37e_ntfy_clr(struct nv50_wndw *); +int wndwc37e_image_clr(struct nv50_wndw *); +int wndwc37e_blend_set(struct nv50_wndw *, struct nv50_wndw_atom *); +int wndwc37e_update(struct nv50_wndw *, u32 *); int wndwc57e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, struct nv50_wndw **); diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c index bb84e4d54a33..57df997c5ff3 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c @@ -27,48 +27,59 @@ #include <nouveau_bo.h> #include <nvif/clc37e.h> +#include <nvif/pushc37b.h> -static void +#include <nvhw/class/clc37e.h> + +static int wndwc37e_csc_clr(struct nv50_wndw *wndw) { + return 0; } -static void +static int wndwc37e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push, i; - if ((push = evo_wait(&wndw->wndw, 13))) { - evo_mthd(push, 0x02bc, 12); - for (i = 0; i < 12; i++) - evo_data(push, asyw->csc.matrix[i]); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 13))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_CSC_RED2RED, asyw->csc.matrix, 12); + return 0; } -static void +static int wndwc37e_ilut_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x02b8, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_INPUT_LUT, 0x00000000); + return 0; } -static void +static int wndwc37e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 4))) { - evo_mthd(push, 0x02b0, 3); - evo_data(push, asyw->xlut.i.output_mode << 8 | - asyw->xlut.i.range << 4 | - asyw->xlut.i.size); - evo_data(push, asyw->xlut.i.offset >> 8); - evo_data(push, asyw->xlut.handle); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_CONTROL_INPUT_LUT, + NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, OUTPUT_MODE, asyw->xlut.i.output_mode) | + NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, RANGE, asyw->xlut.i.range) | + NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, SIZE, asyw->xlut.i.size), + + SET_OFFSET_INPUT_LUT, asyw->xlut.i.offset >> 8, + SET_CONTEXT_DMA_INPUT_LUT, asyw->xlut.handle); + return 0; } static bool @@ -77,144 +88,206 @@ wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) if (size != 256 && size != 1024) return false; - asyw->xlut.i.mode = 2; - asyw->xlut.i.size = size == 1024 ? 2 : 0; - asyw->xlut.i.range = 0; - asyw->xlut.i.output_mode = 1; + asyw->xlut.i.size = size == 1024 ? NVC37E_SET_CONTROL_INPUT_LUT_SIZE_SIZE_1025 : + NVC37E_SET_CONTROL_INPUT_LUT_SIZE_SIZE_257; + asyw->xlut.i.range = NVC37E_SET_CONTROL_INPUT_LUT_RANGE_UNITY; + asyw->xlut.i.output_mode = NVC37E_SET_CONTROL_INPUT_LUT_OUTPUT_MODE_INTERPOLATE; asyw->xlut.i.load = head907d_olut_load; return true; } -void +int wndwc37e_blend_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 8))) { - evo_mthd(push, 0x02ec, 7); - evo_data(push, asyw->blend.depth << 4); - evo_data(push, asyw->blend.k1); - evo_data(push, asyw->blend.dst_color << 12 | - asyw->blend.dst_color << 8 | - asyw->blend.src_color << 4 | - asyw->blend.src_color); - evo_data(push, 0xffff0000); - evo_data(push, 0xffff0000); - evo_data(push, 0xffff0000); - evo_data(push, 0xffff0000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 8))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_COMPOSITION_CONTROL, + NVDEF(NVC37E, SET_COMPOSITION_CONTROL, COLOR_KEY_SELECT, DISABLE) | + NVVAL(NVC37E, SET_COMPOSITION_CONTROL, DEPTH, asyw->blend.depth), + + SET_COMPOSITION_CONSTANT_ALPHA, + NVVAL(NVC37E, SET_COMPOSITION_CONSTANT_ALPHA, K1, asyw->blend.k1) | + NVVAL(NVC37E, SET_COMPOSITION_CONSTANT_ALPHA, K2, 0), + + SET_COMPOSITION_FACTOR_SELECT, + NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, SRC_COLOR_FACTOR_MATCH_SELECT, + asyw->blend.src_color) | + NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, SRC_COLOR_FACTOR_NO_MATCH_SELECT, + asyw->blend.src_color) | + NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, DST_COLOR_FACTOR_MATCH_SELECT, + asyw->blend.dst_color) | + NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, DST_COLOR_FACTOR_NO_MATCH_SELECT, + asyw->blend.dst_color), + + SET_KEY_ALPHA, + NVVAL(NVC37E, SET_KEY_ALPHA, MIN, 0x0000) | + NVVAL(NVC37E, SET_KEY_ALPHA, MAX, 0xffff), + + SET_KEY_RED_CR, + NVVAL(NVC37E, SET_KEY_RED_CR, MIN, 0x0000) | + NVVAL(NVC37E, SET_KEY_RED_CR, MAX, 0xffff), + + SET_KEY_GREEN_Y, + NVVAL(NVC37E, SET_KEY_GREEN_Y, MIN, 0x0000) | + NVVAL(NVC37E, SET_KEY_GREEN_Y, MAX, 0xffff), + + SET_KEY_BLUE_CB, + NVVAL(NVC37E, SET_KEY_BLUE_CB, MIN, 0x0000) | + NVVAL(NVC37E, SET_KEY_BLUE_CB, MAX, 0xffff)); + return 0; } -void +int wndwc37e_image_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 4))) { - evo_mthd(push, 0x0308, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x0240, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_PRESENT_CONTROL, + NVVAL(NVC37E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0) | + NVDEF(NVC37E, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING)); + + PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_ISO(0), 0x00000000); + return 0; } -static void +static int wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - - if (!(push = evo_wait(&wndw->wndw, 17))) - return; - - evo_mthd(push, 0x0308, 1); - evo_data(push, asyw->image.mode << 4 | asyw->image.interval); - evo_mthd(push, 0x0224, 4); - evo_data(push, asyw->image.h << 16 | asyw->image.w); - evo_data(push, asyw->image.layout << 4 | asyw->image.blockh); - evo_data(push, asyw->csc.valid << 17 | - asyw->image.colorspace << 8 | - asyw->image.format); - evo_data(push, asyw->image.blocks[0] | (asyw->image.pitch[0] >> 6)); - evo_mthd(push, 0x0240, 1); - evo_data(push, asyw->image.handle[0]); - evo_mthd(push, 0x0260, 1); - evo_data(push, asyw->image.offset[0] >> 8); - evo_mthd(push, 0x0290, 1); - evo_data(push, (asyw->state.src_y >> 16) << 16 | - (asyw->state.src_x >> 16)); - evo_mthd(push, 0x0298, 1); - evo_data(push, (asyw->state.src_h >> 16) << 16 | - (asyw->state.src_w >> 16)); - evo_mthd(push, 0x02a4, 1); - evo_data(push, asyw->state.crtc_h << 16 | - asyw->state.crtc_w); - evo_kick(push, &wndw->wndw); + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 17))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_PRESENT_CONTROL, + NVVAL(NVC37E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) | + NVVAL(NVC37E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | + NVDEF(NVC37E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE)); + + PUSH_MTHD(push, NVC37E, SET_SIZE, + NVVAL(NVC37E, SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NVC37E, SET_SIZE, HEIGHT, asyw->image.h), + + SET_STORAGE, + NVVAL(NVC37E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) | + NVVAL(NVC37E, SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout), + + SET_PARAMS, + NVVAL(NVC37E, SET_PARAMS, FORMAT, asyw->image.format) | + NVVAL(NVC37E, SET_PARAMS, COLOR_SPACE, asyw->image.colorspace) | + NVDEF(NVC37E, SET_PARAMS, INPUT_RANGE, BYPASS) | + NVDEF(NVC37E, SET_PARAMS, UNDERREPLICATE, DISABLE) | + NVDEF(NVC37E, SET_PARAMS, DE_GAMMA, NONE) | + NVVAL(NVC37E, SET_PARAMS, CSC, asyw->csc.valid) | + NVDEF(NVC37E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) | + NVDEF(NVC37E, SET_PARAMS, SWAP_UV, DISABLE), + + SET_PLANAR_STORAGE(0), + NVVAL(NVC37E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NVC37E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6)); + + PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_ISO(0), asyw->image.handle, 1); + PUSH_MTHD(push, NVC37E, SET_OFFSET(0), asyw->image.offset[0] >> 8); + + PUSH_MTHD(push, NVC37E, SET_POINT_IN(0), + NVVAL(NVC37E, SET_POINT_IN, X, asyw->state.src_x >> 16) | + NVVAL(NVC37E, SET_POINT_IN, Y, asyw->state.src_y >> 16)); + + PUSH_MTHD(push, NVC37E, SET_SIZE_IN, + NVVAL(NVC37E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) | + NVVAL(NVC37E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16)); + + PUSH_MTHD(push, NVC37E, SET_SIZE_OUT, + NVVAL(NVC37E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) | + NVVAL(NVC37E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h)); + return 0; } -void +int wndwc37e_ntfy_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x021c, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_NOTIFIER, 0x00000000); + return 0; } -void +int wndwc37e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 3))) { - evo_mthd(push, 0x021c, 2); - evo_data(push, asyw->ntfy.handle); - evo_data(push, asyw->ntfy.offset | asyw->ntfy.awaken); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 3))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_NOTIFIER, asyw->ntfy.handle, + + SET_NOTIFIER_CONTROL, + NVVAL(NVC37E, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken) | + NVVAL(NVC37E, SET_NOTIFIER_CONTROL, OFFSET, asyw->ntfy.offset >> 4)); + return 0; } -void +int wndwc37e_sema_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x0218, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_SEMAPHORE, 0x00000000); + return 0; } -void +int wndwc37e_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 5))) { - evo_mthd(push, 0x020c, 4); - evo_data(push, asyw->sema.offset); - evo_data(push, asyw->sema.acquire); - evo_data(push, asyw->sema.release); - evo_data(push, asyw->sema.handle); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_SEMAPHORE_CONTROL, asyw->sema.offset, + SET_SEMAPHORE_ACQUIRE, asyw->sema.acquire, + SET_SEMAPHORE_RELEASE, asyw->sema.release, + SET_CONTEXT_DMA_SEMAPHORE, asyw->sema.handle); + return 0; } -void +int wndwc37e_update(struct nv50_wndw *wndw, u32 *interlock) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 5))) { - evo_mthd(push, 0x0370, 2); - evo_data(push, interlock[NV50_DISP_INTERLOCK_CURS] << 1 | - interlock[NV50_DISP_INTERLOCK_CORE]); - evo_data(push, interlock[NV50_DISP_INTERLOCK_WNDW]); - evo_mthd(push, 0x0200, 1); - if (interlock[NV50_DISP_INTERLOCK_WIMM] & wndw->interlock.data) - evo_data(push, 0x00001001); - else - evo_data(push, 0x00000001); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 5))) + return ret; + + PUSH_MTHD(push, NVC37E, SET_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_CURS] << 1 | + interlock[NV50_DISP_INTERLOCK_CORE], + SET_WINDOW_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_WNDW]); + + PUSH_MTHD(push, NVC37E, UPDATE, 0x00000001 | + NVVAL(NVC37E, UPDATE, INTERLOCK_WITH_WIN_IMM, + !!(interlock[NV50_DISP_INTERLOCK_WIMM] & wndw->interlock.data))); + + return PUSH_KICK(push); } void diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c index 1d64741595ba..429be0bb0222 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c @@ -27,97 +27,120 @@ #include <nouveau_bo.h> #include <nvif/clc37e.h> +#include <nvif/pushc37b.h> -static void +#include <nvhw/class/clc57e.h> + +static int wndwc57e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - - if (!(push = evo_wait(&wndw->wndw, 17))) - return; - - evo_mthd(push, 0x0308, 1); - evo_data(push, asyw->image.mode << 4 | asyw->image.interval); - evo_mthd(push, 0x0224, 4); - evo_data(push, asyw->image.h << 16 | asyw->image.w); - evo_data(push, asyw->image.layout << 4 | asyw->image.blockh); - evo_data(push, asyw->image.colorspace << 8 | - asyw->image.format); - evo_data(push, asyw->image.blocks[0] | (asyw->image.pitch[0] >> 6)); - evo_mthd(push, 0x0240, 1); - evo_data(push, asyw->image.handle[0]); - evo_mthd(push, 0x0260, 1); - evo_data(push, asyw->image.offset[0] >> 8); - evo_mthd(push, 0x0290, 1); - evo_data(push, (asyw->state.src_y >> 16) << 16 | - (asyw->state.src_x >> 16)); - evo_mthd(push, 0x0298, 1); - evo_data(push, (asyw->state.src_h >> 16) << 16 | - (asyw->state.src_w >> 16)); - evo_mthd(push, 0x02a4, 1); - evo_data(push, asyw->state.crtc_h << 16 | - asyw->state.crtc_w); - evo_kick(push, &wndw->wndw); + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 17))) + return ret; + + PUSH_MTHD(push, NVC57E, SET_PRESENT_CONTROL, + NVVAL(NVC57E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) | + NVVAL(NVC57E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | + NVDEF(NVC57E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE)); + + PUSH_MTHD(push, NVC57E, SET_SIZE, + NVVAL(NVC57E, SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NVC57E, SET_SIZE, HEIGHT, asyw->image.h), + + SET_STORAGE, + NVVAL(NVC57E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) | + NVVAL(NVC57E, SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout), + + SET_PARAMS, + NVVAL(NVC57E, SET_PARAMS, FORMAT, asyw->image.format) | + NVDEF(NVC57E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) | + NVDEF(NVC57E, SET_PARAMS, SWAP_UV, DISABLE) | + NVDEF(NVC57E, SET_PARAMS, FMT_ROUNDING_MODE, ROUND_TO_NEAREST), + + SET_PLANAR_STORAGE(0), + NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6)); + + PUSH_MTHD(push, NVC57E, SET_CONTEXT_DMA_ISO(0), asyw->image.handle, 1); + PUSH_MTHD(push, NVC57E, SET_OFFSET(0), asyw->image.offset[0] >> 8); + + PUSH_MTHD(push, NVC57E, SET_POINT_IN(0), + NVVAL(NVC57E, SET_POINT_IN, X, asyw->state.src_x >> 16) | + NVVAL(NVC57E, SET_POINT_IN, Y, asyw->state.src_y >> 16)); + + PUSH_MTHD(push, NVC57E, SET_SIZE_IN, + NVVAL(NVC57E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) | + NVVAL(NVC57E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16)); + + PUSH_MTHD(push, NVC57E, SET_SIZE_OUT, + NVVAL(NVC57E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) | + NVVAL(NVC57E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h)); + return 0; } -static void +static int wndwc57e_csc_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 13))) { - evo_mthd(push, 0x0400, 12); - evo_data(push, 0x00010000); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_data(push, 0x00010000); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_data(push, 0x00010000); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + const u32 identity[12] = { + 0x00010000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00010000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00010000, 0x00000000, + }; + int ret; + + if ((ret = PUSH_WAIT(push, 1 + ARRAY_SIZE(identity)))) + return ret; + + PUSH_MTHD(push, NVC57E, SET_FMT_COEFFICIENT_C00, identity, ARRAY_SIZE(identity)); + return 0; } -static void +static int wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push, i; - if ((push = evo_wait(&wndw->wndw, 13))) { - evo_mthd(push, 0x0400, 12); - for (i = 0; i < 12; i++) - evo_data(push, asyw->csc.matrix[i]); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 13))) + return ret; + + PUSH_MTHD(push, NVC57E, SET_FMT_COEFFICIENT_C00, asyw->csc.matrix, 12); + return 0; } -static void +static int wndwc57e_ilut_clr(struct nv50_wndw *wndw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x0444, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_MTHD(push, NVC57E, SET_CONTEXT_DMA_ILUT, 0x00000000); + return 0; } -static void +static int wndwc57e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wndw, 4))) { - evo_mthd(push, 0x0440, 3); - evo_data(push, asyw->xlut.i.size << 8 | - asyw->xlut.i.mode << 2 | - asyw->xlut.i.output_mode); - evo_data(push, asyw->xlut.handle); - evo_data(push, asyw->xlut.i.offset >> 8); - evo_kick(push, &wndw->wndw); - } + struct nvif_push *push = wndw->wndw.push; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_MTHD(push, NVC57E, SET_ILUT_CONTROL, + NVVAL(NVC57E, SET_ILUT_CONTROL, SIZE, asyw->xlut.i.size) | + NVVAL(NVC57E, SET_ILUT_CONTROL, MODE, asyw->xlut.i.mode) | + NVVAL(NVC57E, SET_ILUT_CONTROL, INTERPOLATE, asyw->xlut.i.output_mode), + + SET_CONTEXT_DMA_ILUT, asyw->xlut.handle, + SET_OFFSET_ILUT, asyw->xlut.i.offset >> 8); + return 0; } static u16 @@ -162,13 +185,13 @@ wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) if (size = size ? size : 1024, size != 256 && size != 1024) return false; - if (size == 256) { - asyw->xlut.i.mode = 1; /* DIRECT8. */ - } else { - asyw->xlut.i.mode = 2; /* DIRECT10. */ - } + if (size == 256) + asyw->xlut.i.mode = NVC57E_SET_ILUT_CONTROL_MODE_DIRECT8; + else + asyw->xlut.i.mode = NVC57E_SET_ILUT_CONTROL_MODE_DIRECT10; + asyw->xlut.i.size = 4 /* VSS header. */ + size + 1 /* Entries. */; - asyw->xlut.i.output_mode = 0; /* INTERPOLATE_DISABLE. */ + asyw->xlut.i.output_mode = NVC57E_SET_ILUT_CONTROL_INTERPOLATE_DISABLE; asyw->xlut.i.load = wndwc57e_ilut_load; return true; } |