Commit fc01d1f1 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'linux-5.9' of git://github.com/skeggsb/linux into drm-next

- Conversion of all push buffer emission to a new set of macros, with
better safety, sanity-checking, debug ability, and the use of NVIDIA's
class headers.  The headers have been trimmed to just what we use as
they're rather extensive, the full versions can be found on NVIDIA's
github[1].
- Proper push buffer space management for EVO/NVD channels.
- Fixes to firmware loading behaviour in odd situations (various
combinations of missing/incompatible FW).
- runpm reference leak fixes
- crc compile fixes without debugfs
- 2MiB system memory pages support on Pascal and newer
- misc other cleanups
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Ben Skeggs <skeggsb@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ <CACAvsv6XYgiXDK6TpvsjMo+8AkrMw7ZxmA=vKk6Gd-xuv6txBA@mail.gmail.com
parents 3afe6766 0059a908
...@@ -32,6 +32,13 @@ nouveau-y += nouveau_vga.o ...@@ -32,6 +32,13 @@ nouveau-y += nouveau_vga.o
# DRM - memory management # DRM - memory management
nouveau-y += nouveau_bo.o nouveau-y += nouveau_bo.o
nouveau-y += nouveau_bo0039.o
nouveau-y += nouveau_bo5039.o
nouveau-y += nouveau_bo74c1.o
nouveau-y += nouveau_bo85b5.o
nouveau-y += nouveau_bo9039.o
nouveau-y += nouveau_bo90b5.o
nouveau-y += nouveau_boa0b5.o
nouveau-y += nouveau_gem.o nouveau-y += nouveau_gem.o
nouveau-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_svm.o nouveau-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_svm.o
nouveau-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_dmem.o nouveau-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_dmem.o
......
...@@ -76,6 +76,14 @@ config NOUVEAU_DEBUG_MMU ...@@ -76,6 +76,14 @@ config NOUVEAU_DEBUG_MMU
help help
Say Y here if you want to enable verbose MMU debug output. Say Y here if you want to enable verbose MMU debug output.
config NOUVEAU_DEBUG_PUSH
bool "Enable additional push buffer debugging"
depends on DRM_NOUVEAU
default n
help
Say Y here if you want to enable verbose push buffer debug output
and sanity checks.
config DRM_NOUVEAU_BACKLIGHT config DRM_NOUVEAU_BACKLIGHT
bool "Support for backlight control" bool "Support for backlight control"
depends on DRM_NOUVEAU depends on DRM_NOUVEAU
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include <subdev/bios/pll.h> #include <subdev/bios/pll.h>
#include <subdev/clk.h> #include <subdev/clk.h>
#include <nvif/push006c.h>
#include <nvif/event.h> #include <nvif/event.h>
#include <nvif/cl0046.h> #include <nvif/cl0046.h>
...@@ -759,7 +761,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc) ...@@ -759,7 +761,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc)
nouveau_bo_unmap(nv_crtc->cursor.nvbo); nouveau_bo_unmap(nv_crtc->cursor.nvbo);
nouveau_bo_unpin(nv_crtc->cursor.nvbo); nouveau_bo_unpin(nv_crtc->cursor.nvbo);
nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
nvif_notify_fini(&nv_crtc->vblank); nvif_notify_dtor(&nv_crtc->vblank);
kfree(nv_crtc); kfree(nv_crtc);
} }
...@@ -1105,6 +1107,7 @@ nv04_page_flip_emit(struct nouveau_channel *chan, ...@@ -1105,6 +1107,7 @@ nv04_page_flip_emit(struct nouveau_channel *chan,
struct nouveau_fence_chan *fctx = chan->fence; struct nouveau_fence_chan *fctx = chan->fence;
struct nouveau_drm *drm = chan->drm; struct nouveau_drm *drm = chan->drm;
struct drm_device *dev = drm->dev; struct drm_device *dev = drm->dev;
struct nvif_push *push = chan->chan.push;
unsigned long flags; unsigned long flags;
int ret; int ret;
...@@ -1119,13 +1122,12 @@ nv04_page_flip_emit(struct nouveau_channel *chan, ...@@ -1119,13 +1122,12 @@ nv04_page_flip_emit(struct nouveau_channel *chan,
goto fail; goto fail;
/* Emit the pageflip */ /* Emit the pageflip */
ret = RING_SPACE(chan, 2); ret = PUSH_WAIT(push, 2);
if (ret) if (ret)
goto fail; goto fail;
BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); PUSH_NVSQ(push, NV_SW, NV_SW_PAGE_FLIP, 0x00000000);
OUT_RING (chan, 0x00000000); PUSH_KICK(push);
FIRE_RING (chan);
ret = nouveau_fence_new(chan, false, pfence); ret = nouveau_fence_new(chan, false, pfence);
if (ret) if (ret)
...@@ -1155,6 +1157,7 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, ...@@ -1155,6 +1157,7 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct nouveau_cli *cli; struct nouveau_cli *cli;
struct nouveau_fence *fence; struct nouveau_fence *fence;
struct nv04_display *dispnv04 = nv04_display(dev); struct nv04_display *dispnv04 = nv04_display(dev);
struct nvif_push *push;
int head = nouveau_crtc(crtc)->index; int head = nouveau_crtc(crtc)->index;
int ret; int ret;
...@@ -1162,6 +1165,7 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, ...@@ -1162,6 +1165,7 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
if (!chan) if (!chan)
return -ENODEV; return -ENODEV;
cli = (void *)chan->user.client; cli = (void *)chan->user.client;
push = chan->chan.push;
s = kzalloc(sizeof(*s), GFP_KERNEL); s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s) if (!s)
...@@ -1203,18 +1207,14 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, ...@@ -1203,18 +1207,14 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* Emit a page flip */ /* Emit a page flip */
if (swap_interval) { if (swap_interval) {
ret = RING_SPACE(chan, 8); ret = PUSH_WAIT(push, 8);
if (ret) if (ret)
goto fail_unreserve; goto fail_unreserve;
BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); PUSH_NVSQ(push, NV05F, 0x012c, 0);
OUT_RING (chan, 0); PUSH_NVSQ(push, NV05F, 0x0134, head);
BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); PUSH_NVSQ(push, NV05F, 0x0100, 0);
OUT_RING (chan, head); PUSH_NVSQ(push, NV05F, 0x0130, 0);
BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
OUT_RING (chan, 0);
BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
OUT_RING (chan, 0);
} }
nouveau_bo_ref(new_bo, &dispnv04->image[head]); nouveau_bo_ref(new_bo, &dispnv04->image[head]);
...@@ -1351,7 +1351,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) ...@@ -1351,7 +1351,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
nv04_cursor_init(nv_crtc); nv04_cursor_init(nv_crtc);
ret = nvif_notify_init(&disp->disp.object, nv04_crtc_vblank_handler, ret = nvif_notify_ctor(&disp->disp.object, "kmsVbl", nv04_crtc_vblank_handler,
false, NV04_DISP_NTFY_VBLANK, false, NV04_DISP_NTFY_VBLANK,
&(struct nvif_notify_head_req_v0) { &(struct nvif_notify_head_req_v0) {
.head = nv_crtc->index, .head = nv_crtc->index,
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "nouveau_connector.h" #include "nouveau_connector.h"
#include "nouveau_bo.h" #include "nouveau_bo.h"
#include "nouveau_gem.h" #include "nouveau_gem.h"
#include "nouveau_chan.h"
#include <nvif/if0004.h> #include <nvif/if0004.h>
...@@ -178,7 +179,7 @@ nv04_display_destroy(struct drm_device *dev) ...@@ -178,7 +179,7 @@ nv04_display_destroy(struct drm_device *dev)
nouveau_hw_save_vga_fonts(dev, 0); nouveau_hw_save_vga_fonts(dev, 0);
nvif_notify_fini(&disp->flip); nvif_notify_dtor(&disp->flip);
nouveau_display(dev)->priv = NULL; nouveau_display(dev)->priv = NULL;
kfree(disp); kfree(disp);
...@@ -214,8 +215,8 @@ nv04_display_create(struct drm_device *dev) ...@@ -214,8 +215,8 @@ nv04_display_create(struct drm_device *dev)
dev->driver_features &= ~DRIVER_ATOMIC; dev->driver_features &= ~DRIVER_ATOMIC;
/* Request page flip completion event. */ /* Request page flip completion event. */
if (drm->nvsw.client) { if (drm->channel) {
nvif_notify_init(&drm->nvsw, nv04_flip_complete, nvif_notify_ctor(&drm->channel->nvsw, "kmsFlip", nv04_flip_complete,
false, NV04_NVSW_NTFY_UEVENT, false, NV04_NVSW_NTFY_UEVENT,
NULL, 0, 0, &disp->flip); NULL, 0, 0, &disp->flip);
} }
......
...@@ -11,14 +11,10 @@ int base507c_acquire(struct nv50_wndw *, struct nv50_wndw_atom *, ...@@ -11,14 +11,10 @@ int base507c_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *, void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *); int base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void base507c_sema_clr(struct nv50_wndw *); int base507c_sema_clr(struct nv50_wndw *);
void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); int base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void base507c_ntfy_clr(struct nv50_wndw *); int base507c_xlut_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 base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
......
...@@ -23,91 +23,122 @@ ...@@ -23,91 +23,122 @@
#include <nvif/cl507c.h> #include <nvif/cl507c.h>
#include <nvif/event.h> #include <nvif/event.h>
#include <nvif/push507c.h>
#include <nvif/timer.h> #include <nvif/timer.h>
#include <nvhw/class/cl507c.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_fourcc.h> #include <drm/drm_fourcc.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
#include "nouveau_bo.h" #include "nouveau_bo.h"
void int
base507c_update(struct nv50_wndw *wndw, u32 *interlock) base507c_update(struct nv50_wndw *wndw, u32 *interlock)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 2))) { int ret;
evo_mthd(push, 0x0080, 1);
evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &wndw->wndw); 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) base507c_image_clr(struct nv50_wndw *wndw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 4))) { int ret;
evo_mthd(push, 0x0084, 1);
evo_data(push, 0x00000000); if ((ret = PUSH_WAIT(push, 4)))
evo_mthd(push, 0x00c0, 1); return ret;
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw); 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) base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 13))) { int ret;
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.mode << 8 | if ((ret = PUSH_WAIT(push, 13)))
asyw->image.interval << 4); return ret;
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]); PUSH_MTHD(push, NV507C, SET_PRESENT_CONTROL,
if (asyw->image.format == 0xca) { NVVAL(NV507C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
evo_mthd(push, 0x0110, 2); NVVAL(NV507C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
evo_data(push, 1);
evo_data(push, 0x6400); PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
} else {
evo_mthd(push, 0x0110, 2); if (asyw->image.format == NV507C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16) {
evo_data(push, 0); PUSH_MTHD(push, NV507C, SET_PROCESSING,
evo_data(push, 0); NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, ENABLE),
}
evo_mthd(push, 0x0800, 5); SET_CONVERSION,
evo_data(push, asyw->image.offset[0] >> 8); NVVAL(NV507C, SET_CONVERSION, GAIN, 0) |
evo_data(push, 0x00000000); NVVAL(NV507C, SET_CONVERSION, OFS, 0x64));
evo_data(push, asyw->image.h << 16 | asyw->image.w); } else {
evo_data(push, asyw->image.layout << 20 | PUSH_MTHD(push, NV507C, SET_PROCESSING,
(asyw->image.pitch[0] >> 8) << 8 | NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE));
asyw->image.blocks[0] << 8 |
asyw->image.blockh);
evo_data(push, asyw->image.kind << 16 |
asyw->image.format << 8);
evo_kick(push, &wndw->wndw);
} }
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) base507c_xlut_clr(struct nv50_wndw *wndw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 2))) { int ret;
evo_mthd(push, 0x00e0, 1);
evo_data(push, 0x00000000); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &wndw->wndw); 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) base507c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 2))) { int ret;
evo_mthd(push, 0x00e0, 1);
evo_data(push, 0x40000000); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &wndw->wndw); return ret;
}
PUSH_MTHD(push, NV507C, SET_BASE_LUT_LO,
NVDEF(NV507C, SET_BASE_LUT_LO, ENABLE, USE_CORE_LUT));
return 0;
} }
int int
...@@ -115,66 +146,77 @@ base507c_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, ...@@ -115,66 +146,77 @@ base507c_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device) struct nvif_device *device)
{ {
s64 time = nvif_msec(device, 2000ULL, s64 time = nvif_msec(device, 2000ULL,
u32 data = nouveau_bo_rd32(bo, offset / 4); if (NVBO_TD32(bo, offset, NV_DISP_BASE_NOTIFIER_1, _0, STATUS, ==, BEGUN))
if ((data & 0xc0000000) == 0x40000000)
break; break;
usleep_range(1, 2); usleep_range(1, 2);
); );
return time < 0 ? time : 0; return time < 0 ? time : 0;
} }
void int
base507c_ntfy_clr(struct nv50_wndw *wndw) base507c_ntfy_clr(struct nv50_wndw *wndw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 2))) { int ret;
evo_mthd(push, 0x00a4, 1);
evo_data(push, 0x00000000); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &wndw->wndw); 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) base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 3))) { int ret;
evo_mthd(push, 0x00a0, 2);
evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset); if ((ret = PUSH_WAIT(push, 3)))
evo_data(push, asyw->ntfy.handle); return ret;
evo_kick(push, &wndw->wndw);
} 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 void
base507c_ntfy_reset(struct nouveau_bo *bo, u32 offset) 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) base507c_sema_clr(struct nv50_wndw *wndw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 2))) { int ret;
evo_mthd(push, 0x0094, 1);
evo_data(push, 0x00000000); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &wndw->wndw); 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) base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 5))) { int ret;
evo_mthd(push, 0x0088, 4);
evo_data(push, asyw->sema.offset); if ((ret = PUSH_WAIT(push, 5)))
evo_data(push, asyw->sema.acquire); return ret;
evo_data(push, asyw->sema.release);
evo_data(push, asyw->sema.handle); PUSH_MTHD(push, NV507C, SET_SEMAPHORE_CONTROL, asyw->sema.offset,
evo_kick(push, &wndw->wndw); SET_SEMAPHORE_ACQUIRE, asyw->sema.acquire,
} SET_SEMAPHORE_RELEASE, asyw->sema.release,
SET_CONTEXT_DMA_SEMAPHORE, asyw->sema.handle);
return 0;
} }
void void
...@@ -282,8 +324,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format, ...@@ -282,8 +324,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
return ret; return ret;
} }
ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsBaseNtfy",
false, NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, wndw->notify.func, false,
NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT,
&(struct nvif_notify_uevent_req) {}, &(struct nvif_notify_uevent_req) {},
sizeof(struct nvif_notify_uevent_req), sizeof(struct nvif_notify_uevent_req),
sizeof(struct nvif_notify_uevent_rep), sizeof(struct nvif_notify_uevent_rep),
......
...@@ -21,36 +21,56 @@ ...@@ -21,36 +21,56 @@
*/ */
#include "base.h" #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) base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 13))) { int ret;
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.mode << 8 | if ((ret = PUSH_WAIT(push, 13)))
asyw->image.interval << 4); return ret;
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]); PUSH_MTHD(push, NV827C, SET_PRESENT_CONTROL,
if (asyw->image.format == 0xca) { NVVAL(NV827C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
evo_mthd(push, 0x0110, 2); NVVAL(NV827C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
evo_data(push, 1);
evo_data(push, 0x6400); PUSH_MTHD(push, NV827C, SET_CONTEXT_DMAS_ISO(0), asyw->image.handle, 1);
} else {
evo_mthd(push, 0x0110, 2); if (asyw->image.format == NV827C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16) {
evo_data(push, 0); PUSH_MTHD(push, NV827C, SET_PROCESSING,
evo_data(push, 0); NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, ENABLE),
}
evo_mthd(push, 0x0800, 5); SET_CONVERSION,
evo_data(push, asyw->image.offset[0] >> 8); NVVAL(NV827C, SET_CONVERSION, GAIN, 0) |
evo_data(push, 0x00000000); NVVAL(NV827C, SET_CONVERSION, OFS, 0x64));
evo_data(push, asyw->image.h << 16 | asyw->image.w); } else {
evo_data(push, asyw->image.layout << 20 | PUSH_MTHD(push, NV827C, SET_PROCESSING,
(asyw->image.pitch[0] >> 8) << 8 | NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE));
asyw->image.blocks[0] << 8 |
asyw->image.blockh);
evo_data(push, asyw->image.format << 8);
evo_kick(push, &wndw->wndw);
} }
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 static const struct nv50_wndw_func
......
...@@ -21,58 +21,86 @@ ...@@ -21,58 +21,86 @@
*/ */
#include "base.h" #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) base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 10))) { int ret;
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.mode << 8 | if ((ret = PUSH_WAIT(push, 10)))
asyw->image.interval << 4); return ret;
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]); PUSH_MTHD(push, NV907C, SET_PRESENT_CONTROL,
evo_mthd(push, 0x0400, 5); NVVAL(NV907C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
evo_data(push, asyw->image.offset[0] >> 8); NVDEF(NV907C, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE) |
evo_data(push, 0x00000000); NVVAL(NV907C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 24 | PUSH_MTHD(push, NV907C, SET_CONTEXT_DMAS_ISO(0), asyw->image.handle, 1);
(asyw->image.pitch[0] >> 8) << 8 |
asyw->image.blocks[0] << 8 | PUSH_MTHD(push, NV907C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8,
asyw->image.blockh); SURFACE_SET_OFFSET(0, 1), 0x00000000,
evo_data(push, asyw->image.format << 8);
evo_kick(push, &wndw->wndw); 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) base907c_xlut_clr(struct nv50_wndw *wndw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 6))) { int ret;
evo_mthd(push, 0x00e0, 1);
evo_data(push, 0x00000000); if ((ret = PUSH_WAIT(push, 6)))
evo_mthd(push, 0x00e8, 1); return ret;
evo_data(push, 0x00000000);
evo_mthd(push, 0x00fc, 1); PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO,
evo_data(push, 0x00000000); NVDEF(NV907C, SET_BASE_LUT_LO, ENABLE, DISABLE));
evo_kick(push, &wndw->wndw);
} 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) base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 6))) { int ret;
evo_mthd(push, 0x00e0, 3);
evo_data(push, asyw->xlut.i.enable << 30 | if ((ret = PUSH_WAIT(push, 6)))
asyw->xlut.i.mode << 24); return ret;
evo_data(push, asyw->xlut.i.offset >> 8);
evo_data(push, 0x40000000); PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO,
evo_mthd(push, 0x00fc, 1); NVVAL(NV907C, SET_BASE_LUT_LO, ENABLE, asyw->xlut.i.enable) |
evo_data(push, asyw->xlut.handle); NVVAL(NV907C, SET_BASE_LUT_LO, MODE, asyw->xlut.i.mode),
evo_kick(push, &wndw->wndw);
} 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 static bool
...@@ -81,8 +109,12 @@ base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) ...@@ -81,8 +109,12 @@ base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
if (size != 256 && size != 1024) if (size != 256 && size != 1024)
return false; return false;
asyw->xlut.i.mode = size == 1024 ? 4 : 7; if (size == 1024)
asyw->xlut.i.enable = 2; 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; asyw->xlut.i.load = head907d_olut_load;
return true; return true;
} }
...@@ -125,28 +157,35 @@ base907c_csc(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, ...@@ -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) base907c_csc_clr(struct nv50_wndw *wndw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 2))) { int ret;
evo_mthd(push, 0x0140, 1);
evo_data(push, 0x00000000); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &wndw->wndw); 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) base907c_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push, i; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 13))) { int ret;
evo_mthd(push, 0x0140, 12);
evo_data(push, asyw->csc.matrix[0] | 0x80000000); if ((ret = PUSH_WAIT(push, 13)))
for (i = 1; i < 12; i++) return ret;
evo_data(push, asyw->csc.matrix[i]);
evo_kick(push, &wndw->wndw); 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 const struct nv50_wndw_func
......
...@@ -15,15 +15,15 @@ int nv50_core_new(struct nouveau_drm *, struct nv50_core **); ...@@ -15,15 +15,15 @@ int nv50_core_new(struct nouveau_drm *, struct nv50_core **);
void nv50_core_del(struct nv50_core **); void nv50_core_del(struct nv50_core **);
struct nv50_core_func { struct nv50_core_func {
void (*init)(struct nv50_core *); int (*init)(struct nv50_core *);
void (*ntfy_init)(struct nouveau_bo *, u32 offset); void (*ntfy_init)(struct nouveau_bo *, u32 offset);
int (*caps_init)(struct nouveau_drm *, struct nv50_disp *); int (*caps_init)(struct nouveau_drm *, struct nv50_disp *);
int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset, int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset,
struct nvif_device *); struct nvif_device *);
void (*update)(struct nv50_core *, u32 *interlock, bool ntfy); int (*update)(struct nv50_core *, u32 *interlock, bool ntfy);
struct { struct {
void (*owner)(struct nv50_core *); int (*owner)(struct nv50_core *);
} wndw; } wndw;
const struct nv50_head_func *head; const struct nv50_head_func *head;
...@@ -31,7 +31,7 @@ struct nv50_core_func { ...@@ -31,7 +31,7 @@ struct nv50_core_func {
const struct nv50_crc_func *crc; const struct nv50_crc_func *crc;
#endif #endif
const struct nv50_outp_func { 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 *); struct nv50_head_atom *);
/* XXX: Only used by SORs and PIORs for now */ /* XXX: Only used by SORs and PIORs for now */
void (*get_caps)(struct nv50_disp *, void (*get_caps)(struct nv50_disp *,
...@@ -42,11 +42,11 @@ struct nv50_core_func { ...@@ -42,11 +42,11 @@ struct nv50_core_func {
int core507d_new(struct nouveau_drm *, s32, struct nv50_core **); int core507d_new(struct nouveau_drm *, s32, struct nv50_core **);
int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32, int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32,
struct nv50_core **); struct nv50_core **);
void core507d_init(struct nv50_core *); int core507d_init(struct nv50_core *);
void core507d_ntfy_init(struct nouveau_bo *, u32); void core507d_ntfy_init(struct nouveau_bo *, u32);
int core507d_caps_init(struct nouveau_drm *, struct nv50_disp *); int core507d_caps_init(struct nouveau_drm *, struct nv50_disp *);
int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); 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 dac507d;
extern const struct nv50_outp_func sor507d; extern const struct nv50_outp_func sor507d;
...@@ -63,8 +63,8 @@ int core917d_new(struct nouveau_drm *, s32, struct nv50_core **); ...@@ -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_new(struct nouveau_drm *, s32, struct nv50_core **);
int corec37d_caps_init(struct nouveau_drm *, struct nv50_disp *); int corec37d_caps_init(struct nouveau_drm *, struct nv50_disp *);
int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
void corec37d_update(struct nv50_core *, u32 *, bool); int corec37d_update(struct nv50_core *, u32 *, bool);
void corec37d_wndw_owner(struct nv50_core *); int corec37d_wndw_owner(struct nv50_core *);
extern const struct nv50_outp_func sorc37d; extern const struct nv50_outp_func sorc37d;
int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **); int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **);
......
...@@ -23,25 +23,36 @@ ...@@ -23,25 +23,36 @@
#include "head.h" #include "head.h"
#include <nvif/cl507d.h> #include <nvif/cl507d.h>
#include <nvif/push507c.h>
#include <nvif/timer.h> #include <nvif/timer.h>
#include <nvhw/class/cl507d.h>
#include "nouveau_bo.h" #include "nouveau_bo.h"
void int
core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy) core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
{ {
u32 *push; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 5))) { int ret;
if (ntfy) {
evo_mthd(push, 0x0084, 1); if ((ret = PUSH_WAIT(push, 5)))
evo_data(push, 0x80000000 | NV50_DISP_CORE_NTFY); return ret;
}
evo_mthd(push, 0x0080, 2); if (ntfy) {
evo_data(push, interlock[NV50_DISP_INTERLOCK_BASE] | PUSH_MTHD(push, NV507D, SET_NOTIFIER_CONTROL,
interlock[NV50_DISP_INTERLOCK_OVLY]); NVDEF(NV507D, SET_NOTIFIER_CONTROL, MODE, WRITE) |
evo_data(push, 0x00000000); NVVAL(NV507D, SET_NOTIFIER_CONTROL, OFFSET, NV50_DISP_CORE_NTFY >> 2) |
evo_kick(push, &core->chan); 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 int
...@@ -49,7 +60,7 @@ core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, ...@@ -49,7 +60,7 @@ core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device) struct nvif_device *device)
{ {
s64 time = nvif_msec(device, 2000ULL, 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; break;
usleep_range(1, 2); usleep_range(1, 2);
); );
...@@ -59,32 +70,34 @@ core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, ...@@ -59,32 +70,34 @@ core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
void void
core507d_ntfy_init(struct nouveau_bo *bo, u32 offset) 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 int
core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) 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) { if ((ret = PUSH_WAIT(push, 2)))
evo_mthd(push, 0x008c, 1); return ret;
evo_data(push, 0x0);
evo_kick(push, &disp->core->chan);
}
return 0; PUSH_MTHD(push, NV507D, GET_CAPABILITIES, 0x00000000);
return PUSH_KICK(push);
} }
void int
core507d_init(struct nv50_core *core) core507d_init(struct nv50_core *core)
{ {
u32 *push; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 2))) { int ret;
evo_mthd(push, 0x0088, 1);
evo_data(push, core->chan.sync.handle); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &core->chan); return ret;
}
PUSH_MTHD(push, NV507D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle);
return PUSH_KICK(push);
} }
static const struct nv50_core_func static const struct nv50_core_func
......
...@@ -23,56 +23,67 @@ ...@@ -23,56 +23,67 @@
#include "head.h" #include "head.h"
#include <nvif/class.h> #include <nvif/class.h>
#include <nouveau_bo.h> #include <nvif/pushc37b.h>
#include <nvif/timer.h> #include <nvif/timer.h>
void #include <nvhw/class/clc37d.h>
#include <nouveau_bo.h>
int
corec37d_wndw_owner(struct nv50_core *core) corec37d_wndw_owner(struct nv50_core *core)
{ {
struct nvif_push *push = core->chan.push;
const u32 windows = 8; /*XXX*/ const u32 windows = 8; /*XXX*/
u32 *push, i; int ret, i;
if ((push = evo_wait(&core->chan, 2 * windows))) {
for (i = 0; i < windows; i++) { if ((ret = PUSH_WAIT(push, windows * 2)))
evo_mthd(push, 0x1000 + (i * 0x080), 1); return ret;
evo_data(push, i >> 1);
} for (i = 0; i < windows; i++) {
evo_kick(push, &core->chan); 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) corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
{ {
u32 *push; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 9))) { int ret;
if (ntfy) {
evo_mthd(push, 0x020c, 1); if ((ret = PUSH_WAIT(push, 9)))
evo_data(push, 0x00001000 | NV50_DISP_CORE_NTFY); return ret;
}
if (ntfy) {
evo_mthd(push, 0x0218, 2); PUSH_MTHD(push, NVC37D, SET_NOTIFIER_CONTROL,
evo_data(push, interlock[NV50_DISP_INTERLOCK_CURS]); NVDEF(NVC37D, SET_NOTIFIER_CONTROL, MODE, WRITE) |
evo_data(push, interlock[NV50_DISP_INTERLOCK_WNDW]); NVVAL(NVC37D, SET_NOTIFIER_CONTROL, OFFSET, NV50_DISP_CORE_NTFY >> 4) |
evo_mthd(push, 0x0200, 1); NVDEF(NVC37D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE));
evo_data(push, 0x00000001);
if (ntfy) {
evo_mthd(push, 0x020c, 1);
evo_data(push, 0x00000000);
}
evo_kick(push, &core->chan);
} }
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 int
corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device) struct nvif_device *device)
{ {
u32 data;
s64 time = nvif_msec(device, 2000ULL, s64 time = nvif_msec(device, 2000ULL,
data = nouveau_bo_rd32(bo, offset / 4 + 0); if (NVBO_TD32(bo, offset, NV_DISP_NOTIFIER, _0, STATUS, ==, FINISHED))
if ((data & 0xc0000000) == 0x80000000)
break; break;
usleep_range(1, 2); usleep_range(1, 2);
); );
...@@ -82,18 +93,19 @@ corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, ...@@ -82,18 +93,19 @@ corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
void void
corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset) corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset)
{ {
nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000); NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _0,
nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000); NVDEF(NV_DISP_NOTIFIER, _0, STATUS, NOT_BEGUN));
nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000); NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _1, 0);
nouveau_bo_wr32(bo, offset / 4 + 3, 0x00000000); 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 corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
{ {
int ret; int ret;
ret = nvif_object_init(&disp->disp->object, 0, GV100_DISP_CAPS, ret = nvif_object_ctor(&disp->disp->object, "dispCaps", 0,
NULL, 0, &disp->caps); GV100_DISP_CAPS, NULL, 0, &disp->caps);
if (ret) { if (ret) {
NV_ERROR(drm, NV_ERROR(drm,
"Failed to init notifier caps region: %d\n", "Failed to init notifier caps region: %d\n",
...@@ -112,24 +124,37 @@ int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) ...@@ -112,24 +124,37 @@ int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
return 0; return 0;
} }
static void static int
corec37d_init(struct nv50_core *core) corec37d_init(struct nv50_core *core)
{ {
struct nvif_push *push = core->chan.push;
const u32 windows = 8; /*XXX*/ const u32 windows = 8; /*XXX*/
u32 *push, i; int ret, i;
if ((push = evo_wait(&core->chan, 2 + 5 * windows))) {
evo_mthd(push, 0x0208, 1); if ((ret = PUSH_WAIT(push, 2 + windows * 5)))
evo_data(push, core->chan.sync.handle); return ret;
for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1004 + (i * 0x080), 2); PUSH_MTHD(push, NVC37D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle);
evo_data(push, 0x0000001f);
evo_data(push, 0x00000000); for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1010 + (i * 0x080), 1); PUSH_MTHD(push, NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i),
evo_data(push, 0x00127fff); NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) |
} NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) |
evo_kick(push, &core->chan); NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) |
core->assign_windows = 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 static const struct nv50_core_func
......
...@@ -22,24 +22,40 @@ ...@@ -22,24 +22,40 @@
#include "core.h" #include "core.h"
#include "head.h" #include "head.h"
static void #include <nvif/pushc37b.h>
#include <nvhw/class/clc57d.h>
static int
corec57d_init(struct nv50_core *core) corec57d_init(struct nv50_core *core)
{ {
struct nvif_push *push = core->chan.push;
const u32 windows = 8; /*XXX*/ const u32 windows = 8; /*XXX*/
u32 *push, i; int ret, i;
if ((push = evo_wait(&core->chan, 2 + 5 * windows))) {
evo_mthd(push, 0x0208, 1); if ((ret = PUSH_WAIT(push, 2 + windows * 5)))
evo_data(push, core->chan.sync.handle); return ret;
for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1004 + (i * 0x080), 2); PUSH_MTHD(push, NVC57D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle);
evo_data(push, 0x0000000f);
evo_data(push, 0x00000000); for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1010 + (i * 0x080), 1); PUSH_MTHD(push, NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i),
evo_data(push, 0x00117fff); NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) |
} NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) |
evo_kick(push, &core->chan); NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) |
core->assign_windows = 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 static const struct nv50_core_func
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <nvif/cl0002.h> #include <nvif/cl0002.h>
#include <nvif/timer.h> #include <nvif/timer.h>
#include <nvhw/class/cl907d.h>
#include "nouveau_drv.h" #include "nouveau_drv.h"
#include "core.h" #include "core.h"
#include "head.h" #include "head.h"
...@@ -478,10 +480,6 @@ void nv50_crc_atomic_clr(struct nv50_head *head) ...@@ -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); 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 static inline int
nv50_crc_raster_type(enum nv50_crc_source source) nv50_crc_raster_type(enum nv50_crc_source source)
{ {
...@@ -490,11 +488,11 @@ 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_AUTO:
case NV50_CRC_SOURCE_RG: case NV50_CRC_SOURCE_RG:
case NV50_CRC_SOURCE_OUTP_ACTIVE: 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: 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: 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; return 0;
...@@ -510,11 +508,11 @@ nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu, ...@@ -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; struct nv50_core *core = nv50_disp(head->base.base.dev)->core;
int ret; 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) if (ret)
return 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), NV50_DISP_HANDLE_CRC_CTX(head, idx),
NV_DMA_IN_MEMORY, NV_DMA_IN_MEMORY,
&(struct nv_dma_v0) { &(struct nv_dma_v0) {
...@@ -531,15 +529,15 @@ nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu, ...@@ -531,15 +529,15 @@ nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu,
return 0; return 0;
fail_fini: fail_fini:
nvif_mem_fini(&ctx->mem); nvif_mem_dtor(&ctx->mem);
return ret; return ret;
} }
static inline void static inline void
nv50_crc_ctx_fini(struct nv50_crc_notifier_ctx *ctx) nv50_crc_ctx_fini(struct nv50_crc_notifier_ctx *ctx)
{ {
nvif_object_fini(&ctx->ntfy); nvif_object_dtor(&ctx->ntfy);
nvif_mem_fini(&ctx->mem); nvif_mem_dtor(&ctx->mem);
} }
int nv50_crc_set_source(struct drm_crtc *crtc, const char *source_str) int nv50_crc_set_source(struct drm_crtc *crtc, const char *source_str)
......
...@@ -50,9 +50,9 @@ struct nv50_crc_atom { ...@@ -50,9 +50,9 @@ struct nv50_crc_atom {
}; };
struct nv50_crc_func { struct nv50_crc_func {
void (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type, int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type,
struct nv50_crc_notifier_ctx *, u32 wndw); struct nv50_crc_notifier_ctx *, u32 wndw);
void (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *); int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);
u32 (*get_entry)(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); enum nv50_crc_source, int idx);
bool (*ctx_finished)(struct nv50_head *, bool (*ctx_finished)(struct nv50_head *,
...@@ -106,26 +106,27 @@ struct nv50_crc_atom {}; ...@@ -106,26 +106,27 @@ struct nv50_crc_atom {};
#define nv50_crc_set_source NULL #define nv50_crc_set_source NULL
static inline void nv50_crc_init(struct drm_device *dev) {} static inline void nv50_crc_init(struct drm_device *dev) {}
static inline int nv50_head_crc_late_register(struct nv50_head *) {} static inline int
static inline void nv50_head_crc_late_register(struct nv50_head *head) { return 0; }
nv50_crc_handle_vblank(struct nv50_head *head) { return 0; } static inline void nv50_crc_handle_vblank(struct nv50_head *head) {}
static inline int static inline int
nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *, nv50_crc_atomic_check_head(struct nv50_head *head,
struct nv50_head_atom *) {} 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_check_outp(struct nv50_atom *atom) {}
static inline void 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 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 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 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 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 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 /* IS_ENABLED(CONFIG_DEBUG_FS) */
#endif /* !__NV50_CRC_H__ */ #endif /* !__NV50_CRC_H__ */
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
#include "disp.h" #include "disp.h"
#include "head.h" #include "head.h"
#include <nvif/push507c.h>
#include <nvhw/class/cl907d.h>
#define CRC907D_MAX_ENTRIES 255 #define CRC907D_MAX_ENTRIES 255
struct crc907d_notifier { struct crc907d_notifier {
...@@ -18,68 +22,67 @@ struct crc907d_notifier { ...@@ -18,68 +22,67 @@ struct crc907d_notifier {
} entries[CRC907D_MAX_ENTRIES]; } entries[CRC907D_MAX_ENTRIES];
} __packed; } __packed;
static void static int
crc907d_set_src(struct nv50_head *head, int or, crc907d_set_src(struct nv50_head *head, int or,
enum nv50_crc_source_type source, enum nv50_crc_source_type source,
struct nv50_crc_notifier_ctx *ctx, u32 wndw) struct nv50_crc_notifier_ctx *ctx, u32 wndw)
{ {
struct drm_crtc *crtc = &head->base.base; struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; const int i = head->base.index;
const u32 hoff = head->base.index * 0x300; u32 crc_args = NVDEF(NV907D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, CORE) |
u32 *push; NVDEF(NV907D, HEAD_SET_CRC_CONTROL, EXPECT_BUFFER_COLLAPSE, FALSE) |
u32 crc_args = 0xfff00000; 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) { switch (source) {
case NV50_CRC_SOURCE_TYPE_SOR: 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; break;
case NV50_CRC_SOURCE_TYPE_PIOR: 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; break;
case NV50_CRC_SOURCE_TYPE_DAC: case NV50_CRC_SOURCE_TYPE_DAC:
crc_args |= (0x00000ff0 + or) << 8; crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, DAC(or));
break; break;
case NV50_CRC_SOURCE_TYPE_RG: 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; break;
case NV50_CRC_SOURCE_TYPE_SF: 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; break;
case NV50_CRC_SOURCE_NONE: case NV50_CRC_SOURCE_NONE:
crc_args |= 0x000fff00; crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, NONE);
break; break;
} }
push = evo_wait(core, 4); if ((ret = PUSH_WAIT(push, 4)))
if (!push) return ret;
return;
if (source) { if (source) {
evo_mthd(push, 0x0438 + hoff, 1); PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx->ntfy.handle);
evo_data(push, ctx->ntfy.handle); PUSH_MTHD(push, NV907D, HEAD_SET_CRC_CONTROL(i), crc_args);
evo_mthd(push, 0x0430 + hoff, 1);
evo_data(push, crc_args);
} else { } else {
evo_mthd(push, 0x0430 + hoff, 1); PUSH_MTHD(push, NV907D, HEAD_SET_CRC_CONTROL(i), crc_args);
evo_data(push, crc_args); PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), 0);
evo_mthd(push, 0x0438 + hoff, 1);
evo_data(push, 0);
} }
evo_kick(push, core);
return 0;
} }
static void crc907d_set_ctx(struct nv50_head *head, static int
struct nv50_crc_notifier_ctx *ctx) 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; struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
u32 *push = evo_wait(core, 2); const int i = head->base.index;
int ret;
if (!push) if ((ret = PUSH_WAIT(push, 2)))
return; return ret;
evo_mthd(push, 0x0438 + (head->base.index * 0x300), 1); PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx ? ctx->ntfy.handle : 0);
evo_data(push, ctx ? ctx->ntfy.handle : 0); return 0;
evo_kick(push, core);
} }
static u32 crc907d_get_entry(struct nv50_head *head, static u32 crc907d_get_entry(struct nv50_head *head,
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
#include "disp.h" #include "disp.h"
#include "head.h" #include "head.h"
#include <nvif/push507c.h>
#include <nvhw/class/clc37d.h>
#define CRCC37D_MAX_ENTRIES 2047 #define CRCC37D_MAX_ENTRIES 2047
struct crcc37d_notifier { struct crcc37d_notifier {
...@@ -30,62 +34,59 @@ struct crcc37d_notifier { ...@@ -30,62 +34,59 @@ struct crcc37d_notifier {
} entries[CRCC37D_MAX_ENTRIES]; } entries[CRCC37D_MAX_ENTRIES];
} __packed; } __packed;
static void static int
crcc37d_set_src(struct nv50_head *head, int or, crcc37d_set_src(struct nv50_head *head, int or,
enum nv50_crc_source_type source, enum nv50_crc_source_type source,
struct nv50_crc_notifier_ctx *ctx, u32 wndw) struct nv50_crc_notifier_ctx *ctx, u32 wndw)
{ {
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 u32 hoff = head->base.index * 0x400; const int i = head->base.index;
u32 *push; u32 crc_args = NVVAL(NVC37D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, wndw) |
u32 crc_args; 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) { switch (source) {
case NV50_CRC_SOURCE_TYPE_SOR: case NV50_CRC_SOURCE_TYPE_SOR:
crc_args = (0x00000050 + or) << 12; crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, SOR(or));
break; break;
case NV50_CRC_SOURCE_TYPE_PIOR: case NV50_CRC_SOURCE_TYPE_PIOR:
crc_args = (0x00000060 + or) << 12; crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, PIOR(or));
break; break;
case NV50_CRC_SOURCE_TYPE_SF: case NV50_CRC_SOURCE_TYPE_SF:
crc_args = 0x00000030 << 12; crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, SF);
break; break;
default: default:
crc_args = 0;
break; break;
} }
push = evo_wait(core, 4); if ((ret = PUSH_WAIT(push, 4)))
if (!push) return ret;
return;
if (source) { if (source) {
evo_mthd(push, 0x2180 + hoff, 1); PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx->ntfy.handle);
evo_data(push, ctx->ntfy.handle); PUSH_MTHD(push, NVC37D, HEAD_SET_CRC_CONTROL(i), crc_args);
evo_mthd(push, 0x2184 + hoff, 1);
evo_data(push, crc_args | wndw);
} else { } else {
evo_mthd(push, 0x2184 + hoff, 1); PUSH_MTHD(push, NVC37D, HEAD_SET_CRC_CONTROL(i), 0);
evo_data(push, 0); PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), 0);
evo_mthd(push, 0x2180 + hoff, 1);
evo_data(push, 0);
} }
evo_kick(push, core); return 0;
} }
static void crcc37d_set_ctx(struct nv50_head *head, static int
struct nv50_crc_notifier_ctx *ctx) 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; struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
u32 *push = evo_wait(core, 2); const int i = head->base.index;
int ret;
if (!push) if ((ret = PUSH_WAIT(push, 2)))
return; return ret;
evo_mthd(push, 0x2180 + (head->base.index * 0x400), 1); PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx ? ctx->ntfy.handle : 0);
evo_data(push, ctx ? ctx->ntfy.handle : 0); return 0;
evo_kick(push, core);
} }
static u32 crcc37d_get_entry(struct nv50_head *head, static u32 crcc37d_get_entry(struct nv50_head *head,
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include <nvif/cl507a.h> #include <nvif/cl507a.h>
#include <nvif/timer.h> #include <nvif/timer.h>
#include <nvhw/class/cl507a.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
...@@ -33,27 +35,37 @@ bool ...@@ -33,27 +35,37 @@ bool
curs507a_space(struct nv50_wndw *wndw) curs507a_space(struct nv50_wndw *wndw)
{ {
nvif_msec(&nouveau_drm(wndw->plane.dev)->client.device, 100, 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; return true;
); );
WARN_ON(1); WARN_ON(1);
return false; return false;
} }
static void static int
curs507a_update(struct nv50_wndw *wndw, u32 *interlock) curs507a_update(struct nv50_wndw *wndw, u32 *interlock)
{ {
if (curs507a_space(wndw)) struct nvif_object *user = &wndw->wimm.base.user;
nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000); 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) curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
if (curs507a_space(wndw)) { struct nvif_object *user = &wndw->wimm.base.user;
nvif_wr32(&wndw->wimm.base.user, 0x0084, asyw->point.y << 16 | int ret = nvif_chan_wait(&wndw->wimm, 1);
asyw->point.x); 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 const struct nv50_wimm_func
...@@ -138,8 +150,8 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, ...@@ -138,8 +150,8 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
if (*pwndw = wndw, ret) if (*pwndw = wndw, ret)
return ret; return ret;
ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, ret = nvif_object_ctor(&disp->disp->object, "kmsCurs", 0, oclass,
sizeof(args), &wndw->wimm.base.user); &args, sizeof(args), &wndw->wimm.base.user);
if (ret) { if (ret) {
NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret); NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret);
return ret; return ret;
......
...@@ -22,20 +22,29 @@ ...@@ -22,20 +22,29 @@
#include "curs.h" #include "curs.h"
#include "atom.h" #include "atom.h"
static void #include <nvhw/class/clc37a.h>
static int
cursc37a_update(struct nv50_wndw *wndw, u32 *interlock) cursc37a_update(struct nv50_wndw *wndw, u32 *interlock)
{ {
if (curs507a_space(wndw)) struct nvif_object *user = &wndw->wimm.base.user;
nvif_wr32(&wndw->wimm.base.user, 0x0200, 0x00000001); 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) cursc37a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
if (curs507a_space(wndw)) { struct nvif_object *user = &wndw->wimm.base.user;
nvif_wr32(&wndw->wimm.base.user, 0x0208, asyw->point.y << 16 | int ret = nvif_chan_wait(&wndw->wimm, 1);
asyw->point.x); 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 static const struct nv50_wimm_func
......
...@@ -21,21 +21,29 @@ ...@@ -21,21 +21,29 @@
*/ */
#include "core.h" #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, dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh) struct nv50_head_atom *asyh)
{ {
u32 *push, sync = 0; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 3))) { u32 sync = 0;
if (asyh) { int ret;
sync |= asyh->or.nvsync << 1;
sync |= asyh->or.nhsync; if (asyh) {
} sync |= NVVAL(NV507D, DAC_SET_POLARITY, HSYNC, asyh->or.nhsync);
evo_mthd(push, 0x0400 + (or * 0x080), 2); sync |= NVVAL(NV507D, DAC_SET_POLARITY, VSYNC, asyh->or.nvsync);
evo_data(push, ctrl);
evo_data(push, sync);
evo_kick(push, &core->chan);
} }
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 const struct nv50_outp_func
......
...@@ -21,16 +21,22 @@ ...@@ -21,16 +21,22 @@
*/ */
#include "core.h" #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, dac907d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh) struct nv50_head_atom *asyh)
{ {
u32 *push; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 2))) { int ret;
evo_mthd(push, 0x0180 + (or * 0x020), 1);
evo_data(push, ctrl); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &core->chan); return ret;
}
PUSH_MTHD(push, NV907D, DAC_SET_CONTROL(or), ctrl);
return 0;
} }
const struct nv50_outp_func const struct nv50_outp_func
......
This diff is collapsed.
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define __NV50_KMS_H__ #define __NV50_KMS_H__
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <nvif/mem.h> #include <nvif/mem.h>
#include <nvif/push.h>
#include "nouveau_display.h" #include "nouveau_display.h"
...@@ -61,7 +62,8 @@ struct nv50_chan { ...@@ -61,7 +62,8 @@ struct nv50_chan {
struct nv50_dmac { struct nv50_dmac {
struct nv50_chan base; struct nv50_chan base;
struct nvif_mem push; struct nvif_push _push;
struct nvif_push *push;
u32 *ptr; u32 *ptr;
struct nvif_object sync; struct nvif_object sync;
...@@ -71,6 +73,10 @@ struct nv50_dmac { ...@@ -71,6 +73,10 @@ struct nv50_dmac {
* grabbed by evo_wait (if the pushbuf reservation is successful) and * grabbed by evo_wait (if the pushbuf reservation is successful) and
* dropped again by evo_kick. */ * dropped again by evo_kick. */
struct mutex lock; struct mutex lock;
u32 cur;
u32 put;
u32 max;
}; };
struct nv50_outp_atom { struct nv50_outp_atom {
...@@ -106,18 +112,4 @@ void evo_kick(u32 *, struct nv50_dmac *); ...@@ -106,18 +112,4 @@ void evo_kick(u32 *, struct nv50_dmac *);
extern const u64 disp50xx_modifiers[]; extern const u64 disp50xx_modifiers[];
extern const u64 disp90xx_modifiers[]; extern const u64 disp90xx_modifiers[];
extern const u64 wndwc57e_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 #endif
...@@ -106,9 +106,9 @@ nv50_head_atomic_check_dither(struct nv50_head_atom *armh, ...@@ -106,9 +106,9 @@ nv50_head_atomic_check_dither(struct nv50_head_atom *armh,
} }
} }
asyh->dither.enable = mode; asyh->dither.enable = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, ENABLE);
asyh->dither.bits = mode >> 1; asyh->dither.bits = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, BITS);
asyh->dither.mode = mode >> 3; asyh->dither.mode = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, MODE);
asyh->set.dither = true; asyh->set.dither = true;
} }
...@@ -489,7 +489,7 @@ nv50_head_destroy(struct drm_crtc *crtc) ...@@ -489,7 +489,7 @@ nv50_head_destroy(struct drm_crtc *crtc)
{ {
struct nv50_head *head = nv50_head(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); nv50_lut_fini(&head->olut);
drm_crtc_cleanup(crtc); drm_crtc_cleanup(crtc);
kfree(head); kfree(head);
...@@ -598,7 +598,7 @@ nv50_head_create(struct drm_device *dev, int index) ...@@ -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, false, NV04_DISP_NTFY_VBLANK,
&(struct nvif_notify_head_req_v0) { &(struct nvif_notify_head_req_v0) {
.head = nv_crtc->index, .head = nv_crtc->index,
......
...@@ -25,74 +25,72 @@ void nv50_head_flush_clr(struct nv50_head *head, ...@@ -25,74 +25,72 @@ void nv50_head_flush_clr(struct nv50_head *head,
struct nv50_head_atom *asyh, bool flush); struct nv50_head_atom *asyh, bool flush);
struct nv50_head_func { struct nv50_head_func {
void (*view)(struct nv50_head *, struct nv50_head_atom *); int (*view)(struct nv50_head *, struct nv50_head_atom *);
void (*mode)(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)(struct nv50_head *, struct nv50_head_atom *, int);
bool olut_identity; bool olut_identity;
int olut_size; int olut_size;
void (*olut_set)(struct nv50_head *, struct nv50_head_atom *); int (*olut_set)(struct nv50_head *, struct nv50_head_atom *);
void (*olut_clr)(struct nv50_head *); int (*olut_clr)(struct nv50_head *);
void (*core_calc)(struct nv50_head *, struct nv50_head_atom *); void (*core_calc)(struct nv50_head *, struct nv50_head_atom *);
void (*core_set)(struct nv50_head *, struct nv50_head_atom *); int (*core_set)(struct nv50_head *, struct nv50_head_atom *);
void (*core_clr)(struct nv50_head *); int (*core_clr)(struct nv50_head *);
int (*curs_layout)(struct nv50_head *, struct nv50_wndw_atom *, int (*curs_layout)(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
int (*curs_format)(struct nv50_head *, struct nv50_wndw_atom *, int (*curs_format)(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
void (*curs_set)(struct nv50_head *, struct nv50_head_atom *); int (*curs_set)(struct nv50_head *, struct nv50_head_atom *);
void (*curs_clr)(struct nv50_head *); int (*curs_clr)(struct nv50_head *);
void (*base)(struct nv50_head *, struct nv50_head_atom *); int (*base)(struct nv50_head *, struct nv50_head_atom *);
void (*ovly)(struct nv50_head *, struct nv50_head_atom *); int (*ovly)(struct nv50_head *, struct nv50_head_atom *);
void (*dither)(struct nv50_head *, struct nv50_head_atom *); int (*dither)(struct nv50_head *, struct nv50_head_atom *);
void (*procamp)(struct nv50_head *, struct nv50_head_atom *); int (*procamp)(struct nv50_head *, struct nv50_head_atom *);
void (*or)(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 *); void (*static_wndw_map)(struct nv50_head *, struct nv50_head_atom *);
}; };
extern const struct nv50_head_func head507d; extern const struct nv50_head_func head507d;
void head507d_view(struct nv50_head *, struct nv50_head_atom *); int head507d_view(struct nv50_head *, struct nv50_head_atom *);
void head507d_mode(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); 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_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 *, int head507d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
int head507d_curs_format(struct nv50_head *, struct nv50_wndw_atom *, int head507d_curs_format(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
void head507d_base(struct nv50_head *, struct nv50_head_atom *); int head507d_base(struct nv50_head *, struct nv50_head_atom *);
void head507d_ovly(struct nv50_head *, struct nv50_head_atom *); int head507d_ovly(struct nv50_head *, struct nv50_head_atom *);
void head507d_dither(struct nv50_head *, struct nv50_head_atom *); int head507d_dither(struct nv50_head *, struct nv50_head_atom *);
void head507d_procamp(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 head827d;
extern const struct nv50_head_func head907d; extern const struct nv50_head_func head907d;
void head907d_view(struct nv50_head *, struct nv50_head_atom *); int head907d_view(struct nv50_head *, struct nv50_head_atom *);
void head907d_mode(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); bool head907d_olut(struct nv50_head *, struct nv50_head_atom *, int);
void head907d_olut_set(struct nv50_head *, struct nv50_head_atom *); int head907d_olut_set(struct nv50_head *, struct nv50_head_atom *);
void head907d_olut_clr(struct nv50_head *); int head907d_olut_clr(struct nv50_head *);
void head907d_core_set(struct nv50_head *, struct nv50_head_atom *); int head907d_core_set(struct nv50_head *, struct nv50_head_atom *);
void head907d_core_clr(struct nv50_head *); int head907d_core_clr(struct nv50_head *);
void head907d_curs_set(struct nv50_head *, struct nv50_head_atom *); int head907d_curs_set(struct nv50_head *, struct nv50_head_atom *);
void head907d_curs_clr(struct nv50_head *); int head907d_curs_clr(struct nv50_head *);
void head907d_ovly(struct nv50_head *, struct nv50_head_atom *); int head907d_ovly(struct nv50_head *, struct nv50_head_atom *);
void head907d_procamp(struct nv50_head *, struct nv50_head_atom *); int head907d_procamp(struct nv50_head *, struct nv50_head_atom *);
void head907d_or(struct nv50_head *, struct nv50_head_atom *); int head907d_or(struct nv50_head *, struct nv50_head_atom *);
extern const struct nv50_head_func head917d; extern const struct nv50_head_func head917d;
int head917d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *, int head917d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
extern const struct nv50_head_func headc37d; extern const struct nv50_head_func headc37d;
void headc37d_view(struct nv50_head *, struct nv50_head_atom *); int 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_curs_format(struct nv50_head *, struct nv50_wndw_atom *, int headc37d_curs_format(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
void headc37d_curs_set(struct nv50_head *, struct nv50_head_atom *); int headc37d_curs_set(struct nv50_head *, struct nv50_head_atom *);
void headc37d_curs_clr(struct nv50_head *); int headc37d_curs_clr(struct nv50_head *);
void headc37d_dither(struct nv50_head *, struct nv50_head_atom *); int headc37d_dither(struct nv50_head *, struct nv50_head_atom *);
void headc37d_static_wndw_map(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; extern const struct nv50_head_func headc57d;
......
This diff is collapsed.
...@@ -22,85 +22,128 @@ ...@@ -22,85 +22,128 @@
#include "head.h" #include "head.h"
#include "core.h" #include "core.h"
static void #include <nvif/push507c.h>
#include <nvhw/class/cl827d.h>
static int
head827d_curs_clr(struct nv50_head *head) head827d_curs_clr(struct nv50_head *head)
{ {
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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 4))) { int ret;
evo_mthd(push, 0x0880 + head->base.index * 0x400, 1);
evo_data(push, 0x05000000); if ((ret = PUSH_WAIT(push, 4)))
evo_mthd(push, 0x089c + head->base.index * 0x400, 1); return ret;
evo_data(push, 0x00000000);
evo_kick(push, core); 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) head827d_curs_set(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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 5))) { int ret;
evo_mthd(push, 0x0880 + head->base.index * 0x400, 2);
evo_data(push, 0x80000000 | asyh->curs.layout << 26 | if ((ret = PUSH_WAIT(push, 5)))
asyh->curs.format << 24); return ret;
evo_data(push, asyh->curs.offset >> 8);
evo_mthd(push, 0x089c + head->base.index * 0x400, 1); PUSH_MTHD(push, NV827D, HEAD_SET_CONTROL_CURSOR(i),
evo_data(push, asyh->curs.handle); NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) |
evo_kick(push, core); 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) head827d_core_set(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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 9))) { int ret;
evo_mthd(push, 0x0860 + head->base.index * 0x400, 1);
evo_data(push, asyh->core.offset >> 8); if ((ret = PUSH_WAIT(push, 9)))
evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); return ret;
evo_data(push, asyh->core.h << 16 | asyh->core.w);
evo_data(push, asyh->core.layout << 20 | PUSH_MTHD(push, NV827D, HEAD_SET_OFFSET(i, 0),
(asyh->core.pitch >> 8) << 8 | NVVAL(NV827D, HEAD_SET_OFFSET, ORIGIN, asyh->core.offset >> 8));
asyh->core.blocks << 8 |
asyh->core.blockh); PUSH_MTHD(push, NV827D, HEAD_SET_SIZE(i),
evo_data(push, asyh->core.format << 8); NVVAL(NV827D, HEAD_SET_SIZE, WIDTH, asyh->core.w) |
evo_data(push, asyh->core.handle); NVVAL(NV827D, HEAD_SET_SIZE, HEIGHT, asyh->core.h),
evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1);
evo_data(push, asyh->core.y << 16 | asyh->core.x); HEAD_SET_STORAGE(i),
evo_kick(push, core); 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) head827d_olut_clr(struct nv50_head *head)
{ {
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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 4))) { int ret;
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1);
evo_data(push, 0x00000000); if ((ret = PUSH_WAIT(push, 4)))
evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); return ret;
evo_data(push, 0x00000000);
evo_kick(push, core); 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) head827d_olut_set(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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 5))) { int ret;
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2);
evo_data(push, 0x80000000 | asyh->olut.mode << 30); if ((ret = PUSH_WAIT(push, 5)))
evo_data(push, asyh->olut.offset >> 8); return ret;
evo_mthd(push, 0x085c + (head->base.index * 0x400), 1);
evo_data(push, asyh->olut.handle); PUSH_MTHD(push, NV827D, HEAD_SET_BASE_LUT_LO(i),
evo_kick(push, core); 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 const struct nv50_head_func
......
This diff is collapsed.
...@@ -22,45 +22,55 @@ ...@@ -22,45 +22,55 @@
#include "head.h" #include "head.h"
#include "core.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) head917d_dither(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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 2))) { int ret;
evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1);
evo_data(push, asyh->dither.mode << 3 | if ((ret = PUSH_WAIT(push, 2)))
asyh->dither.bits << 1 | return ret;
asyh->dither.enable);
evo_kick(push, core); 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) 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 bounds = 0;
u32 *push; int ret;
if (asyh->base.cpp) { if (asyh->base.cpp) {
switch (asyh->base.cpp) { switch (asyh->base.cpp) {
case 8: bounds |= 0x00000500; break; case 8: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break;
case 4: bounds |= 0x00000300; break; case 4: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break;
case 2: bounds |= 0x00000100; break; case 2: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break;
case 1: bounds |= 0x00000000; break; case 1: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_8); break;
default: default:
WARN_ON(1); WARN_ON(1);
break; 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))) { if ((ret = PUSH_WAIT(push, 2)))
evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); return ret;
evo_data(push, bounds);
evo_kick(push, core); PUSH_MTHD(push, NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds);
} return 0;
} }
int int
...@@ -68,10 +78,10 @@ head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw, ...@@ -68,10 +78,10 @@ head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
struct nv50_head_atom *asyh) struct nv50_head_atom *asyh)
{ {
switch (asyw->state.fb->width) { switch (asyw->state.fb->width) {
case 32: asyh->curs.layout = 0; break; case 32: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W32_H32; break;
case 64: asyh->curs.layout = 1; break; case 64: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W64_H64; break;
case 128: asyh->curs.layout = 2; break; case 128: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W128_H128; break;
case 256: asyh->curs.layout = 3; break; case 256: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W256_H256; break;
default: default:
return -EINVAL; return -EINVAL;
} }
......
This diff is collapsed.
...@@ -23,83 +23,97 @@ ...@@ -23,83 +23,97 @@
#include "atom.h" #include "atom.h"
#include "core.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) 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; u8 depth;
u32 *push; int ret;
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); /*XXX: This is a dirty hack until OR depth handling is
evo_data(push, 0xfc000000 | * improved later for deep colour etc.
depth << 4 | */
asyh->or.nvsync << 3 | switch (asyh->or.depth) {
asyh->or.nhsync << 2 | case 6: depth = 5; break;
asyh->or.crc_raster); case 5: depth = 4; break;
evo_kick(push, core); 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) headc57d_procamp(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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 2))) { int ret;
evo_mthd(push, 0x2000 + (head->base.index * 0x400), 1);
#if 0 if ((ret = PUSH_WAIT(push, 2)))
evo_data(push, 0x80000000 | return ret;
asyh->procamp.sat.sin << 16 |
asyh->procamp.sat.cos << 4); //TODO:
#else PUSH_MTHD(push, NVC57D, HEAD_SET_PROCAMP(i),
evo_data(push, 0); NVDEF(NVC57D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) |
#endif NVDEF(NVC57D, HEAD_SET_PROCAMP, CHROMA_LPF, DISABLE) |
evo_kick(push, core); NVDEF(NVC57D, HEAD_SET_PROCAMP, DYNAMIC_RANGE, VESA));
} return 0;
} }
void static int
headc57d_olut_clr(struct nv50_head *head) headc57d_olut_clr(struct nv50_head *head)
{ {
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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 2))) { int ret;
evo_mthd(push, 0x2288 + (head->base.index * 0x400), 1);
evo_data(push, 0x00000000); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, core); 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) headc57d_olut_set(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;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 4))) { int ret;
evo_mthd(push, 0x2280 + (head->base.index * 0x400), 4);
evo_data(push, asyh->olut.size << 8 | if ((ret = PUSH_WAIT(push, 5)))
asyh->olut.mode << 2 | return ret;
asyh->olut.output_mode);
evo_data(push, 0xffffffff); /* FP_NORM_SCALE. */ PUSH_MTHD(push, NVC57D, HEAD_SET_OLUT_CONTROL(i),
evo_data(push, asyh->olut.handle); NVVAL(NVC57D, HEAD_SET_OLUT_CONTROL, INTERPOLATE, asyh->olut.output_mode) |
evo_data(push, asyh->olut.offset >> 8); NVDEF(NVC57D, HEAD_SET_OLUT_CONTROL, MIRROR, DISABLE) |
evo_kick(push, core); 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 static void
...@@ -161,9 +175,9 @@ headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) ...@@ -161,9 +175,9 @@ headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
if (size != 0 && size != 256 && size != 1024) if (size != 0 && size != 256 && size != 1024)
return false; 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.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) if (size == 256)
asyh->olut.load = headc57d_olut_load_8; asyh->olut.load = headc57d_olut_load_8;
else else
...@@ -171,29 +185,50 @@ headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) ...@@ -171,29 +185,50 @@ headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
return true; return true;
} }
static void static int
headc57d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) 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; struct nv50_head_mode *m = &asyh->mode;
u32 *push; const int i = head->base.index;
if ((push = evo_wait(core, 13))) { int ret;
evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5);
evo_data(push, (m->v.active << 16) | m->h.active ); if ((ret = PUSH_WAIT(push, 15)))
evo_data(push, (m->v.synce << 16) | m->h.synce ); return ret;
evo_data(push, (m->v.blanke << 16) | m->h.blanke );
evo_data(push, (m->v.blanks << 16) | m->h.blanks ); PUSH_MTHD(push, NVC57D, HEAD_SET_RASTER_SIZE(i),
evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); NVVAL(NVC57D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) |
evo_mthd(push, 0x2008 + (head->base.index * 0x400), 2); NVVAL(NVC57D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active),
evo_data(push, m->interlace);
evo_data(push, m->clock * 1000); HEAD_SET_RASTER_SYNC_END(i),
evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1); NVVAL(NVC57D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) |
evo_data(push, m->clock * 1000); NVVAL(NVC57D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce),
/*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */
evo_mthd(push, 0x2030 + (head->base.index * 0x400), 1); HEAD_SET_RASTER_BLANK_END(i),
evo_data(push, 0x00001014); NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) |
evo_kick(push, core); 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 const struct nv50_head_func
......
...@@ -60,7 +60,7 @@ nv50_lut_fini(struct nv50_lut *lut) ...@@ -60,7 +60,7 @@ nv50_lut_fini(struct nv50_lut *lut)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(lut->mem); i++) for (i = 0; i < ARRAY_SIZE(lut->mem); i++)
nvif_mem_fini(&lut->mem[i]); nvif_mem_dtor(&lut->mem[i]);
} }
int int
...@@ -70,8 +70,8 @@ nv50_lut_init(struct nv50_disp *disp, struct nvif_mmu *mmu, ...@@ -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; const u32 size = disp->disp->object.oclass < GF110_DISP ? 257 : 1025;
int i; int i;
for (i = 0; i < ARRAY_SIZE(lut->mem); i++) { for (i = 0; i < ARRAY_SIZE(lut->mem); i++) {
int ret = nvif_mem_init_map(mmu, NVIF_MEM_VRAM, size * 8, int ret = nvif_mem_ctor_map(mmu, "kmsLut", NVIF_MEM_VRAM,
&lut->mem[i]); size * 8, &lut->mem[i]);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -33,8 +33,8 @@ oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, ...@@ -33,8 +33,8 @@ oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
struct nv50_disp *disp = nv50_disp(drm->dev); struct nv50_disp *disp = nv50_disp(drm->dev);
int ret; int ret;
ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, ret = nvif_object_ctor(&disp->disp->object, "kmsOvim", 0, oclass,
sizeof(args), &wndw->wimm.base.user); &args, sizeof(args), &wndw->wimm.base.user);
if (ret) { if (ret) {
NV_ERROR(drm, "oimm%04x allocation failed: %d\n", oclass, ret); NV_ERROR(drm, "oimm%04x allocation failed: %d\n", oclass, ret);
return ret; return ret;
......
...@@ -10,11 +10,7 @@ int ovly507e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *, ...@@ -10,11 +10,7 @@ int ovly507e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
void ovly507e_release(struct nv50_wndw *, struct nv50_wndw_atom *, void ovly507e_release(struct nv50_wndw *, struct nv50_wndw_atom *,
struct nv50_head_atom *); struct nv50_head_atom *);
void ovly507e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); int ovly507e_scale_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 *);
extern const u32 ovly827e_format[]; extern const u32 ovly827e_format[];
void ovly827e_ntfy_reset(struct nouveau_bo *, u32); void ovly827e_ntfy_reset(struct nouveau_bo *, u32);
......
...@@ -28,91 +28,68 @@ ...@@ -28,91 +28,68 @@
#include <nvif/cl507e.h> #include <nvif/cl507e.h>
#include <nvif/event.h> #include <nvif/event.h>
#include <nvif/push507c.h>
void #include <nvhw/class/cl507e.h>
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);
}
}
void int
ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 4))) { int ret;
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);
}
}
void if ((ret = PUSH_WAIT(push, 4)))
ovly507e_image_clr(struct nv50_wndw *wndw) return ret;
{
u32 *push; PUSH_MTHD(push, NV507E, SET_POINT_IN,
if ((push = evo_wait(&wndw->wndw, 4))) { NVVAL(NV507E, SET_POINT_IN, X, asyw->scale.sx) |
evo_mthd(push, 0x0084, 1); NVVAL(NV507E, SET_POINT_IN, Y, asyw->scale.sy),
evo_data(push, 0x00000000);
evo_mthd(push, 0x00c0, 1); SET_SIZE_IN,
evo_data(push, 0x00000000); NVVAL(NV507E, SET_SIZE_IN, WIDTH, asyw->scale.sw) |
evo_kick(push, &wndw->wndw); 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) ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 12))) { int ret;
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);
}
}
void if ((ret = PUSH_WAIT(push, 12)))
ovly507e_ntfy_clr(struct nv50_wndw *wndw) return ret;
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x00a4, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
}
void PUSH_MTHD(push, NV507E, SET_PRESENT_CONTROL,
ovly507e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) NVDEF(NV507E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
{ NVVAL(NV507E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
u32 *push;
if ((push = evo_wait(&wndw->wndw, 3))) { PUSH_MTHD(push, NV507E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
evo_mthd(push, 0x00a0, 2);
evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset); PUSH_MTHD(push, NV507E, SET_COMPOSITION_CONTROL,
evo_data(push, asyw->ntfy.handle); NVDEF(NV507E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE));
evo_kick(push, &wndw->wndw);
} 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 void
...@@ -146,14 +123,14 @@ static const struct nv50_wndw_func ...@@ -146,14 +123,14 @@ static const struct nv50_wndw_func
ovly507e = { ovly507e = {
.acquire = ovly507e_acquire, .acquire = ovly507e_acquire,
.release = ovly507e_release, .release = ovly507e_release,
.ntfy_set = ovly507e_ntfy_set, .ntfy_set = base507c_ntfy_set,
.ntfy_clr = ovly507e_ntfy_clr, .ntfy_clr = base507c_ntfy_clr,
.ntfy_reset = base507c_ntfy_reset, .ntfy_reset = base507c_ntfy_reset,
.ntfy_wait_begun = base507c_ntfy_wait_begun, .ntfy_wait_begun = base507c_ntfy_wait_begun,
.image_set = ovly507e_image_set, .image_set = ovly507e_image_set,
.image_clr = ovly507e_image_clr, .image_clr = base507c_image_clr,
.scale_set = ovly507e_scale_set, .scale_set = ovly507e_scale_set,
.update = ovly507e_update, .update = base507c_update,
}; };
static const u32 static const u32
...@@ -192,7 +169,8 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, ...@@ -192,7 +169,8 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
return ret; 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, NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT,
&(struct nvif_notify_uevent_req) {}, &(struct nvif_notify_uevent_req) {},
sizeof(struct nvif_notify_uevent_req), sizeof(struct nvif_notify_uevent_req),
......
...@@ -24,31 +24,45 @@ ...@@ -24,31 +24,45 @@
#include <nouveau_bo.h> #include <nouveau_bo.h>
#include <nvif/push507c.h>
#include <nvif/timer.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) ovly827e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 12))) { int ret;
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.interval << 4); if ((ret = PUSH_WAIT(push, 12)))
evo_mthd(push, 0x00c0, 1); return ret;
evo_data(push, asyw->image.handle[0]);
evo_mthd(push, 0x0100, 1); PUSH_MTHD(push, NV827E, SET_PRESENT_CONTROL,
evo_data(push, 0x00000002); NVDEF(NV827E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
evo_mthd(push, 0x0800, 1); NVVAL(NV827E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
evo_data(push, asyw->image.offset[0] >> 8);
evo_mthd(push, 0x0808, 3); PUSH_MTHD(push, NV827E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 20 | PUSH_MTHD(push, NV827E, SET_COMPOSITION_CONTROL,
(asyw->image.pitch[0] >> 8) << 8 | NVDEF(NV827E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE));
asyw->image.blocks[0] << 8 |
asyw->image.blockh); PUSH_MTHD(push, NV827E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8);
evo_data(push, asyw->image.format << 8 |
asyw->image.colorspace); PUSH_MTHD(push, NV827E, SURFACE_SET_SIZE,
evo_kick(push, &wndw->wndw); 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 int
...@@ -56,8 +70,7 @@ ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, ...@@ -56,8 +70,7 @@ ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device) struct nvif_device *device)
{ {
s64 time = nvif_msec(device, 2000ULL, s64 time = nvif_msec(device, 2000ULL,
u32 data = nouveau_bo_rd32(bo, offset / 4 + 3); if (NVBO_TD32(bo, offset, NV_DISP_NOTIFICATION_1, _3, STATUS, ==, BEGUN))
if ((data & 0xffff0000) == 0xffff0000)
break; break;
usleep_range(1, 2); usleep_range(1, 2);
); );
...@@ -67,24 +80,25 @@ ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, ...@@ -67,24 +80,25 @@ ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
void void
ovly827e_ntfy_reset(struct nouveau_bo *bo, u32 offset) ovly827e_ntfy_reset(struct nouveau_bo *bo, u32 offset)
{ {
nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000); NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, TIME_STAMP_0, 0);
nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000); NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, TIME_STAMP_1, 0);
nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000); NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, _2, 0);
nouveau_bo_wr32(bo, offset / 4 + 3, 0x80000000); NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, _3,
NVDEF(NV_DISP_NOTIFICATION_1, _3, STATUS, NOT_BEGUN));
} }
static const struct nv50_wndw_func static const struct nv50_wndw_func
ovly827e = { ovly827e = {
.acquire = ovly507e_acquire, .acquire = ovly507e_acquire,
.release = ovly507e_release, .release = ovly507e_release,
.ntfy_set = ovly507e_ntfy_set, .ntfy_set = base507c_ntfy_set,
.ntfy_clr = ovly507e_ntfy_clr, .ntfy_clr = base507c_ntfy_clr,
.ntfy_reset = ovly827e_ntfy_reset, .ntfy_reset = ovly827e_ntfy_reset,
.ntfy_wait_begun = ovly827e_ntfy_wait_begun, .ntfy_wait_begun = ovly827e_ntfy_wait_begun,
.image_set = ovly827e_image_set, .image_set = ovly827e_image_set,
.image_clr = ovly507e_image_clr, .image_clr = base507c_image_clr,
.scale_set = ovly507e_scale_set, .scale_set = ovly507e_scale_set,
.update = ovly507e_update, .update = base507c_update,
}; };
const u32 const u32
......
...@@ -22,43 +22,58 @@ ...@@ -22,43 +22,58 @@
#include "ovly.h" #include "ovly.h"
#include "atom.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) ovly907e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wndw.push;
if ((push = evo_wait(&wndw->wndw, 12))) { int ret;
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.interval << 4); if ((ret = PUSH_WAIT(push, 12)))
evo_mthd(push, 0x00c0, 1); return ret;
evo_data(push, asyw->image.handle[0]);
evo_mthd(push, 0x0100, 1); PUSH_MTHD(push, NV907E, SET_PRESENT_CONTROL,
evo_data(push, 0x00000002); NVDEF(NV907E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
evo_mthd(push, 0x0400, 1); NVVAL(NV907E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
evo_data(push, asyw->image.offset[0] >> 8);
evo_mthd(push, 0x0408, 3); PUSH_MTHD(push, NV907E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 24 | PUSH_MTHD(push, NV907E, SET_COMPOSITION_CONTROL,
(asyw->image.pitch[0] >> 8) << 8 | NVDEF(NV907E, SET_COMPOSITION_CONTROL, MODE, OPAQUE));
asyw->image.blocks[0] << 8 |
asyw->image.blockh); PUSH_MTHD(push, NV907E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8);
evo_data(push, asyw->image.format << 8 |
asyw->image.colorspace); PUSH_MTHD(push, NV907E, SURFACE_SET_SIZE,
evo_kick(push, &wndw->wndw); 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 const struct nv50_wndw_func
ovly907e = { ovly907e = {
.acquire = ovly507e_acquire, .acquire = ovly507e_acquire,
.release = ovly507e_release, .release = ovly507e_release,
.ntfy_set = ovly507e_ntfy_set, .ntfy_set = base507c_ntfy_set,
.ntfy_clr = ovly507e_ntfy_clr, .ntfy_clr = base507c_ntfy_clr,
.ntfy_reset = ovly827e_ntfy_reset, .ntfy_reset = ovly827e_ntfy_reset,
.ntfy_wait_begun = ovly827e_ntfy_wait_begun, .ntfy_wait_begun = ovly827e_ntfy_wait_begun,
.image_set = ovly907e_image_set, .image_set = ovly907e_image_set,
.image_clr = ovly507e_image_clr, .image_clr = base507c_image_clr,
.scale_set = ovly507e_scale_set, .scale_set = ovly507e_scale_set,
.update = ovly507e_update, .update = base507c_update,
}; };
static const u32 static const u32
......
...@@ -21,21 +21,29 @@ ...@@ -21,21 +21,29 @@
*/ */
#include "core.h" #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, pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh) struct nv50_head_atom *asyh)
{ {
u32 *push; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 2))) { int ret;
if (asyh) {
ctrl |= asyh->or.depth << 16; if (asyh) {
ctrl |= asyh->or.nvsync << 13; ctrl |= NVVAL(NV507D, PIOR_SET_CONTROL, HSYNC_POLARITY, asyh->or.nhsync);
ctrl |= asyh->or.nhsync << 12; ctrl |= NVVAL(NV507D, PIOR_SET_CONTROL, VSYNC_POLARITY, asyh->or.nvsync);
} ctrl |= NVVAL(NV837D, PIOR_SET_CONTROL, PIXEL_DEPTH, asyh->or.depth);
evo_mthd(push, 0x0700 + (or * 0x040), 1);
evo_data(push, ctrl);
evo_kick(push, &core->chan);
} }
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507D, PIOR_SET_CONTROL(or), ctrl);
return 0;
} }
static void static void
......
...@@ -21,21 +21,29 @@ ...@@ -21,21 +21,29 @@
*/ */
#include "core.h" #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, sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh) struct nv50_head_atom *asyh)
{ {
u32 *push; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 2))) { int ret;
if (asyh) {
ctrl |= asyh->or.depth << 16; if (asyh) {
ctrl |= asyh->or.nvsync << 13; ctrl |= NVVAL(NV507D, SOR_SET_CONTROL, HSYNC_POLARITY, asyh->or.nhsync);
ctrl |= asyh->or.nhsync << 12; ctrl |= NVVAL(NV507D, SOR_SET_CONTROL, VSYNC_POLARITY, asyh->or.nvsync);
} ctrl |= NVVAL(NV837D, SOR_SET_CONTROL, PIXEL_DEPTH, asyh->or.depth);
evo_mthd(push, 0x0600 + (or * 0x40), 1);
evo_data(push, ctrl);
evo_kick(push, &core->chan);
} }
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507D, SOR_SET_CONTROL(or), ctrl);
return 0;
} }
static void static void
......
...@@ -21,28 +21,34 @@ ...@@ -21,28 +21,34 @@
*/ */
#include "core.h" #include "core.h"
#include <nouveau_bo.h>
#include <nvif/class.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, sor907d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh) struct nv50_head_atom *asyh)
{ {
u32 *push; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 2))) { int ret;
evo_mthd(push, 0x0200 + (or * 0x20), 1);
evo_data(push, ctrl); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &core->chan); return ret;
}
PUSH_MTHD(push, NV907D, SOR_SET_CONTROL(or), ctrl);
return 0;
} }
static void static void
sor907d_get_caps(struct nv50_disp *disp, struct nouveau_encoder *outp, int or) sor907d_get_caps(struct nv50_disp *disp, struct nouveau_encoder *outp, int or)
{ {
struct nouveau_bo *bo = disp->sync;
const int off = or * 2; const int off = or * 2;
u32 tmp = nouveau_bo_rd32(disp->sync, 0x000014 + off); outp->caps.dp_interlace =
NVBO_RV32(bo, off, NV907D_CORE_NOTIFIER_3, CAPABILITIES_CAP_SOR0_20, DP_INTERLACE);
outp->caps.dp_interlace = !!(tmp & 0x04000000);
} }
const struct nv50_outp_func const struct nv50_outp_func
......
...@@ -21,16 +21,22 @@ ...@@ -21,16 +21,22 @@
*/ */
#include "core.h" #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, sorc37d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh) struct nv50_head_atom *asyh)
{ {
u32 *push; struct nvif_push *push = core->chan.push;
if ((push = evo_wait(&core->chan, 2))) { int ret;
evo_mthd(push, 0x0300 + (or * 0x20), 1);
evo_data(push, ctrl); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &core->chan); return ret;
}
PUSH_MTHD(push, NVC37D, SOR_SET_CONTROL(or), ctrl);
return 0;
} }
static void static void
......
...@@ -24,30 +24,38 @@ ...@@ -24,30 +24,38 @@
#include "wndw.h" #include "wndw.h"
#include <nvif/clc37b.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) wimmc37b_update(struct nv50_wndw *wndw, u32 *interlock)
{ {
u32 *push; struct nvif_push *push = wndw->wimm.push;
if ((push = evo_wait(&wndw->wimm, 2))) { int ret;
evo_mthd(push, 0x0200, 1);
if (interlock[NV50_DISP_INTERLOCK_WNDW] & wndw->interlock.data) if ((ret = PUSH_WAIT(push, 2)))
evo_data(push, 0x00000003); return ret;
else
evo_data(push, 0x00000001); PUSH_MTHD(push, NVC37B, UPDATE, 0x00000001 |
evo_kick(push, &wndw->wimm); 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) wimmc37b_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{ {
u32 *push; struct nvif_push *push = wndw->wimm.push;
if ((push = evo_wait(&wndw->wimm, 2))) { int ret;
evo_mthd(push, 0x0208, 1);
evo_data(push, asyw->point.y << 16 | asyw->point.x); if ((ret = PUSH_WAIT(push, 2)))
evo_kick(push, &wndw->wimm); 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 static const struct nv50_wimm_func
......
...@@ -26,6 +26,10 @@ ...@@ -26,6 +26,10 @@
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/cl0002.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_atomic_helper.h>
#include <drm/drm_fourcc.h> #include <drm/drm_fourcc.h>
...@@ -35,7 +39,7 @@ ...@@ -35,7 +39,7 @@
static void static void
nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma)
{ {
nvif_object_fini(&ctxdma->object); nvif_object_dtor(&ctxdma->object);
list_del(&ctxdma->head); list_del(&ctxdma->head);
kfree(ctxdma); kfree(ctxdma);
} }
...@@ -94,8 +98,8 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb) ...@@ -94,8 +98,8 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb)
argc += sizeof(args.gf119); argc += sizeof(args.gf119);
} }
ret = nvif_object_init(wndw->ctxdma.parent, handle, NV_DMA_IN_MEMORY, ret = nvif_object_ctor(wndw->ctxdma.parent, "kmsFbCtxDma", handle,
&args, argc, &ctxdma->object); NV_DMA_IN_MEMORY, &args, argc, &ctxdma->object);
if (ret) { if (ret) {
nv50_wndw_ctxdma_del(ctxdma); nv50_wndw_ctxdma_del(ctxdma);
return ERR_PTR(ret); return ERR_PTR(ret);
...@@ -137,7 +141,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, ...@@ -137,7 +141,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
struct nv50_wndw_atom *asyw) struct nv50_wndw_atom *asyw)
{ {
if (interlock[NV50_DISP_INTERLOCK_CORE]) { 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; asyw->image.interval = 1;
} }
...@@ -201,13 +205,18 @@ static int ...@@ -201,13 +205,18 @@ static int
nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw) nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw)
{ {
switch (asyw->state.fb->format->format) { switch (asyw->state.fb->format->format) {
case DRM_FORMAT_YUYV: asyw->image.format = 0x28; break; case DRM_FORMAT_YUYV:
case DRM_FORMAT_UYVY: asyw->image.format = 0x29; break; 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: default:
WARN_ON(1); WARN_ON(1);
return -EINVAL; return -EINVAL;
} }
asyw->image.colorspace = 1;
asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_YUV_601;
return 0; return 0;
} }
...@@ -215,24 +224,41 @@ static int ...@@ -215,24 +224,41 @@ static int
nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw) nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
{ {
switch (asyw->state.fb->format->format) { switch (asyw->state.fb->format->format) {
case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break; case DRM_FORMAT_C8:
case DRM_FORMAT_XRGB8888 : asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_I8;
case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break; break;
case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break; case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_XRGB1555 : case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break; asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A8R8G8B8;
case DRM_FORMAT_XBGR2101010 : break;
case DRM_FORMAT_ABGR2101010 : asyw->image.format = 0xd1; break; case DRM_FORMAT_RGB565:
case DRM_FORMAT_XBGR8888 : asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_R5G6B5;
case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; break;
case DRM_FORMAT_XRGB2101010 : case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_ARGB2101010 : asyw->image.format = 0xdf; break; 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_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: default:
return -EINVAL; return -EINVAL;
} }
asyw->image.colorspace = 0;
asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_RGB;
return 0; return 0;
} }
...@@ -265,7 +291,7 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, ...@@ -265,7 +291,7 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
} }
if (asyw->image.kind) { 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) if (drm->client.device.info.chipset >= 0xc0)
asyw->image.blockh = tile_mode >> 4; asyw->image.blockh = tile_mode >> 4;
else else
...@@ -273,8 +299,8 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, ...@@ -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.blocks[0] = fb->pitches[0] / 64;
asyw->image.pitch[0] = 0; asyw->image.pitch[0] = 0;
} else { } else {
asyw->image.layout = 1; asyw->image.layout = NV507C_SURFACE_SET_STORAGE_MEMORY_LAYOUT_PITCH;
asyw->image.blockh = 0; asyw->image.blockh = NV507C_SURFACE_SET_STORAGE_BLOCK_HEIGHT_ONE_GOB;
asyw->image.blocks[0] = 0; asyw->image.blocks[0] = 0;
asyw->image.pitch[0] = fb->pitches[0]; asyw->image.pitch[0] = fb->pitches[0];
} }
...@@ -283,7 +309,12 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, ...@@ -283,7 +309,12 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
asyw->image.interval = 1; asyw->image.interval = 1;
else else
asyw->image.interval = 0; 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; asyw->set.image = wndw->func->image_set != NULL;
} }
...@@ -303,17 +334,17 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, ...@@ -303,17 +334,17 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
asyw->blend.k1 = asyw->state.alpha >> 8; asyw->blend.k1 = asyw->state.alpha >> 8;
switch (asyw->state.pixel_blend_mode) { switch (asyw->state.pixel_blend_mode) {
case DRM_MODE_BLEND_PREMULTI: case DRM_MODE_BLEND_PREMULTI:
asyw->blend.src_color = 2; /* K1 */ asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1;
asyw->blend.dst_color = 7; /* NEG_K1_TIMES_SRC */ asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1_TIMES_SRC;
break; break;
case DRM_MODE_BLEND_COVERAGE: case DRM_MODE_BLEND_COVERAGE:
asyw->blend.src_color = 5; /* K1_TIMES_SRC */ asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1_TIMES_SRC;
asyw->blend.dst_color = 7; /* NEG_K1_TIMES_SRC */ asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1_TIMES_SRC;
break; break;
case DRM_MODE_BLEND_PIXEL_NONE: case DRM_MODE_BLEND_PIXEL_NONE:
default: default:
asyw->blend.src_color = 2; /* K1 */ asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1;
asyw->blend.dst_color = 4; /* NEG_K1 */ asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1;
break; break;
} }
if (memcmp(&armw->blend, &asyw->blend, sizeof(asyw->blend))) if (memcmp(&armw->blend, &asyw->blend, sizeof(asyw->blend)))
...@@ -609,7 +640,7 @@ nv50_wndw_destroy(struct drm_plane *plane) ...@@ -609,7 +640,7 @@ nv50_wndw_destroy(struct drm_plane *plane)
nv50_wndw_ctxdma_del(ctxdma); nv50_wndw_ctxdma_del(ctxdma);
} }
nvif_notify_fini(&wndw->notify); nvif_notify_dtor(&wndw->notify);
nv50_dmac_destroy(&wndw->wimm); nv50_dmac_destroy(&wndw->wimm);
nv50_dmac_destroy(&wndw->wndw); nv50_dmac_destroy(&wndw->wndw);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -25,7 +25,7 @@ struct nv_pmu_args { ...@@ -25,7 +25,7 @@ struct nv_pmu_args {
#define NV_PMU_UNIT_ACR 0x0a #define NV_PMU_UNIT_ACR 0x0a
struct nv_pmu_init_msg { struct nv_pmu_init_msg {
struct nv_falcon_msg hdr; struct nvfw_falcon_msg hdr;
#define NV_PMU_INIT_MSG_INIT 0x00 #define NV_PMU_INIT_MSG_INIT 0x00
u8 msg_type; u8 msg_type;
...@@ -44,7 +44,7 @@ struct nv_pmu_init_msg { ...@@ -44,7 +44,7 @@ struct nv_pmu_init_msg {
}; };
struct nv_pmu_acr_cmd { struct nv_pmu_acr_cmd {
struct nv_falcon_cmd hdr; struct nvfw_falcon_cmd hdr;
#define NV_PMU_ACR_CMD_INIT_WPR_REGION 0x00 #define NV_PMU_ACR_CMD_INIT_WPR_REGION 0x00
#define NV_PMU_ACR_CMD_BOOTSTRAP_FALCON 0x01 #define NV_PMU_ACR_CMD_BOOTSTRAP_FALCON 0x01
#define NV_PMU_ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS 0x03 #define NV_PMU_ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS 0x03
...@@ -52,7 +52,7 @@ struct nv_pmu_acr_cmd { ...@@ -52,7 +52,7 @@ struct nv_pmu_acr_cmd {
}; };
struct nv_pmu_acr_msg { struct nv_pmu_acr_msg {
struct nv_falcon_cmd hdr; struct nvfw_falcon_cmd hdr;
u8 msg_type; u8 msg_type;
}; };
......
...@@ -13,7 +13,7 @@ struct nv_sec2_args { ...@@ -13,7 +13,7 @@ struct nv_sec2_args {
#define NV_SEC2_UNIT_ACR 0x08 #define NV_SEC2_UNIT_ACR 0x08
struct nv_sec2_init_msg { struct nv_sec2_init_msg {
struct nv_falcon_msg hdr; struct nvfw_falcon_msg hdr;
#define NV_SEC2_INIT_MSG_INIT 0x00 #define NV_SEC2_INIT_MSG_INIT 0x00
u8 msg_type; u8 msg_type;
...@@ -34,13 +34,13 @@ struct nv_sec2_init_msg { ...@@ -34,13 +34,13 @@ struct nv_sec2_init_msg {
}; };
struct nv_sec2_acr_cmd { struct nv_sec2_acr_cmd {
struct nv_falcon_cmd hdr; struct nvfw_falcon_cmd hdr;
#define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON 0x00 #define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON 0x00
u8 cmd_type; u8 cmd_type;
}; };
struct nv_sec2_acr_msg { struct nv_sec2_acr_msg {
struct nv_falcon_cmd hdr; struct nvfw_falcon_cmd hdr;
u8 msg_type; u8 msg_type;
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment