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
# DRM - memory management
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-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_svm.o
nouveau-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_dmem.o
......
......@@ -76,6 +76,14 @@ config NOUVEAU_DEBUG_MMU
help
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
bool "Support for backlight control"
depends on DRM_NOUVEAU
......
......@@ -44,6 +44,8 @@
#include <subdev/bios/pll.h>
#include <subdev/clk.h>
#include <nvif/push006c.h>
#include <nvif/event.h>
#include <nvif/cl0046.h>
......@@ -759,7 +761,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc)
nouveau_bo_unmap(nv_crtc->cursor.nvbo);
nouveau_bo_unpin(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);
}
......@@ -1105,6 +1107,7 @@ nv04_page_flip_emit(struct nouveau_channel *chan,
struct nouveau_fence_chan *fctx = chan->fence;
struct nouveau_drm *drm = chan->drm;
struct drm_device *dev = drm->dev;
struct nvif_push *push = chan->chan.push;
unsigned long flags;
int ret;
......@@ -1119,13 +1122,12 @@ nv04_page_flip_emit(struct nouveau_channel *chan,
goto fail;
/* Emit the pageflip */
ret = RING_SPACE(chan, 2);
ret = PUSH_WAIT(push, 2);
if (ret)
goto fail;
BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
OUT_RING (chan, 0x00000000);
FIRE_RING (chan);
PUSH_NVSQ(push, NV_SW, NV_SW_PAGE_FLIP, 0x00000000);
PUSH_KICK(push);
ret = nouveau_fence_new(chan, false, pfence);
if (ret)
......@@ -1155,6 +1157,7 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct nouveau_cli *cli;
struct nouveau_fence *fence;
struct nv04_display *dispnv04 = nv04_display(dev);
struct nvif_push *push;
int head = nouveau_crtc(crtc)->index;
int ret;
......@@ -1162,6 +1165,7 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
if (!chan)
return -ENODEV;
cli = (void *)chan->user.client;
push = chan->chan.push;
s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
......@@ -1203,18 +1207,14 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* Emit a page flip */
if (swap_interval) {
ret = RING_SPACE(chan, 8);
ret = PUSH_WAIT(push, 8);
if (ret)
goto fail_unreserve;
BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1);
OUT_RING (chan, 0);
BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1);
OUT_RING (chan, head);
BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
OUT_RING (chan, 0);
BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
OUT_RING (chan, 0);
PUSH_NVSQ(push, NV05F, 0x012c, 0);
PUSH_NVSQ(push, NV05F, 0x0134, head);
PUSH_NVSQ(push, NV05F, 0x0100, 0);
PUSH_NVSQ(push, NV05F, 0x0130, 0);
}
nouveau_bo_ref(new_bo, &dispnv04->image[head]);
......@@ -1351,7 +1351,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
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,
&(struct nvif_notify_head_req_v0) {
.head = nv_crtc->index,
......
......@@ -31,6 +31,7 @@
#include "nouveau_connector.h"
#include "nouveau_bo.h"
#include "nouveau_gem.h"
#include "nouveau_chan.h"
#include <nvif/if0004.h>
......@@ -178,7 +179,7 @@ nv04_display_destroy(struct drm_device *dev)
nouveau_hw_save_vga_fonts(dev, 0);
nvif_notify_fini(&disp->flip);
nvif_notify_dtor(&disp->flip);
nouveau_display(dev)->priv = NULL;
kfree(disp);
......@@ -214,8 +215,8 @@ nv04_display_create(struct drm_device *dev)
dev->driver_features &= ~DRIVER_ATOMIC;
/* Request page flip completion event. */
if (drm->nvsw.client) {
nvif_notify_init(&drm->nvsw, nv04_flip_complete,
if (drm->channel) {
nvif_notify_ctor(&drm->channel->nvsw, "kmsFlip", nv04_flip_complete,
false, NV04_NVSW_NTFY_UEVENT,
NULL, 0, 0, &disp->flip);
}
......
......@@ -11,14 +11,10 @@ int base507c_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void base507c_sema_clr(struct nv50_wndw *);
void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void base507c_ntfy_clr(struct nv50_wndw *);
void base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void base507c_xlut_clr(struct nv50_wndw *);
void base507c_image_clr(struct nv50_wndw *);
void base507c_update(struct nv50_wndw *, u32 *);
int base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
int base507c_sema_clr(struct nv50_wndw *);
int base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *);
int base507c_xlut_clr(struct nv50_wndw *);
int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
......
......@@ -23,91 +23,122 @@
#include <nvif/cl507c.h>
#include <nvif/event.h>
#include <nvif/push507c.h>
#include <nvif/timer.h>
#include <nvhw/class/cl507c.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_plane_helper.h>
#include "nouveau_bo.h"
void
int
base507c_update(struct nv50_wndw *wndw, u32 *interlock)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x0080, 1);
evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507C, UPDATE, interlock[NV50_DISP_INTERLOCK_CORE]);
return PUSH_KICK(push);
}
void
int
base507c_image_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 4))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, 0x00000000);
evo_mthd(push, 0x00c0, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 4)))
return ret;
PUSH_MTHD(push, NV507C, SET_PRESENT_CONTROL,
NVDEF(NV507C, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING) |
NVVAL(NV507C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0));
PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_ISO, 0x00000000);
return 0;
}
static void
static int
base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 13))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.mode << 8 |
asyw->image.interval << 4);
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]);
if (asyw->image.format == 0xca) {
evo_mthd(push, 0x0110, 2);
evo_data(push, 1);
evo_data(push, 0x6400);
} else {
evo_mthd(push, 0x0110, 2);
evo_data(push, 0);
evo_data(push, 0);
}
evo_mthd(push, 0x0800, 5);
evo_data(push, asyw->image.offset[0] >> 8);
evo_data(push, 0x00000000);
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 20 |
(asyw->image.pitch[0] >> 8) << 8 |
asyw->image.blocks[0] << 8 |
asyw->image.blockh);
evo_data(push, asyw->image.kind << 16 |
asyw->image.format << 8);
evo_kick(push, &wndw->wndw);
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 13)))
return ret;
PUSH_MTHD(push, NV507C, SET_PRESENT_CONTROL,
NVVAL(NV507C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
NVVAL(NV507C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
if (asyw->image.format == NV507C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16) {
PUSH_MTHD(push, NV507C, SET_PROCESSING,
NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, ENABLE),
SET_CONVERSION,
NVVAL(NV507C, SET_CONVERSION, GAIN, 0) |
NVVAL(NV507C, SET_CONVERSION, OFS, 0x64));
} else {
PUSH_MTHD(push, NV507C, SET_PROCESSING,
NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE));
}
PUSH_MTHD(push, NV507C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8);
PUSH_MTHD(push, NV507C, SURFACE_SET_SIZE(0),
NVVAL(NV507C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
NVVAL(NV507C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
SURFACE_SET_STORAGE(0),
NVVAL(NV507C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout) |
NVVAL(NV507C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) |
NVVAL(NV507C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
NVVAL(NV507C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh),
SURFACE_SET_PARAMS(0),
NVVAL(NV507C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
NVDEF(NV507C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) |
NVDEF(NV507C, SURFACE_SET_PARAMS, GAMMA, LINEAR) |
NVDEF(NV507C, SURFACE_SET_PARAMS, LAYOUT, FRM) |
NVVAL(NV507C, SURFACE_SET_PARAMS, KIND, asyw->image.kind) |
NVDEF(NV507C, SURFACE_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256));
return 0;
}
void
int
base507c_xlut_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x00e0, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507C, SET_BASE_LUT_LO,
NVDEF(NV507C, SET_BASE_LUT_LO, ENABLE, DISABLE));
return 0;
}
void
int
base507c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x00e0, 1);
evo_data(push, 0x40000000);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507C, SET_BASE_LUT_LO,
NVDEF(NV507C, SET_BASE_LUT_LO, ENABLE, USE_CORE_LUT));
return 0;
}
int
......@@ -115,66 +146,77 @@ base507c_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device)
{
s64 time = nvif_msec(device, 2000ULL,
u32 data = nouveau_bo_rd32(bo, offset / 4);
if ((data & 0xc0000000) == 0x40000000)
if (NVBO_TD32(bo, offset, NV_DISP_BASE_NOTIFIER_1, _0, STATUS, ==, BEGUN))
break;
usleep_range(1, 2);
);
return time < 0 ? time : 0;
}
void
int
base507c_ntfy_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x00a4, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_NOTIFIER, 0x00000000);
return 0;
}
void
int
base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 3))) {
evo_mthd(push, 0x00a0, 2);
evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset);
evo_data(push, asyw->ntfy.handle);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 3)))
return ret;
PUSH_MTHD(push, NV507C, SET_NOTIFIER_CONTROL,
NVVAL(NV507C, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken) |
NVVAL(NV507C, SET_NOTIFIER_CONTROL, OFFSET, asyw->ntfy.offset >> 2),
SET_CONTEXT_DMA_NOTIFIER, asyw->ntfy.handle);
return 0;
}
void
base507c_ntfy_reset(struct nouveau_bo *bo, u32 offset)
{
nouveau_bo_wr32(bo, offset / 4, 0x00000000);
NVBO_WR32(bo, offset, NV_DISP_BASE_NOTIFIER_1, _0,
NVDEF(NV_DISP_BASE_NOTIFIER_1, _0, STATUS, NOT_BEGUN));
}
void
int
base507c_sema_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x0094, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507C, SET_CONTEXT_DMA_SEMAPHORE, 0x00000000);
return 0;
}
void
int
base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 5))) {
evo_mthd(push, 0x0088, 4);
evo_data(push, asyw->sema.offset);
evo_data(push, asyw->sema.acquire);
evo_data(push, asyw->sema.release);
evo_data(push, asyw->sema.handle);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 5)))
return ret;
PUSH_MTHD(push, NV507C, SET_SEMAPHORE_CONTROL, asyw->sema.offset,
SET_SEMAPHORE_ACQUIRE, asyw->sema.acquire,
SET_SEMAPHORE_RELEASE, asyw->sema.release,
SET_CONTEXT_DMA_SEMAPHORE, asyw->sema.handle);
return 0;
}
void
......@@ -282,8 +324,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
return ret;
}
ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func,
false, NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT,
ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsBaseNtfy",
wndw->notify.func, false,
NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT,
&(struct nvif_notify_uevent_req) {},
sizeof(struct nvif_notify_uevent_req),
sizeof(struct nvif_notify_uevent_rep),
......
......@@ -21,36 +21,56 @@
*/
#include "base.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl827c.h>
static int
base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 13))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.mode << 8 |
asyw->image.interval << 4);
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]);
if (asyw->image.format == 0xca) {
evo_mthd(push, 0x0110, 2);
evo_data(push, 1);
evo_data(push, 0x6400);
} else {
evo_mthd(push, 0x0110, 2);
evo_data(push, 0);
evo_data(push, 0);
}
evo_mthd(push, 0x0800, 5);
evo_data(push, asyw->image.offset[0] >> 8);
evo_data(push, 0x00000000);
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 20 |
(asyw->image.pitch[0] >> 8) << 8 |
asyw->image.blocks[0] << 8 |
asyw->image.blockh);
evo_data(push, asyw->image.format << 8);
evo_kick(push, &wndw->wndw);
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 13)))
return ret;
PUSH_MTHD(push, NV827C, SET_PRESENT_CONTROL,
NVVAL(NV827C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
NVVAL(NV827C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
PUSH_MTHD(push, NV827C, SET_CONTEXT_DMAS_ISO(0), asyw->image.handle, 1);
if (asyw->image.format == NV827C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16) {
PUSH_MTHD(push, NV827C, SET_PROCESSING,
NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, ENABLE),
SET_CONVERSION,
NVVAL(NV827C, SET_CONVERSION, GAIN, 0) |
NVVAL(NV827C, SET_CONVERSION, OFS, 0x64));
} else {
PUSH_MTHD(push, NV827C, SET_PROCESSING,
NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE));
}
PUSH_MTHD(push, NV827C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8,
SURFACE_SET_OFFSET(0, 1), 0x00000000,
SURFACE_SET_SIZE(0),
NVVAL(NV827C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
NVVAL(NV827C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
SURFACE_SET_STORAGE(0),
NVVAL(NV827C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
NVVAL(NV827C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) |
NVVAL(NV827C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
NVVAL(NV827C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
SURFACE_SET_PARAMS(0),
NVVAL(NV827C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
NVDEF(NV827C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) |
NVDEF(NV827C, SURFACE_SET_PARAMS, GAMMA, LINEAR) |
NVDEF(NV827C, SURFACE_SET_PARAMS, LAYOUT, FRM));
return 0;
}
static const struct nv50_wndw_func
......
......@@ -21,58 +21,86 @@
*/
#include "base.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl907c.h>
static int
base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 10))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.mode << 8 |
asyw->image.interval << 4);
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]);
evo_mthd(push, 0x0400, 5);
evo_data(push, asyw->image.offset[0] >> 8);
evo_data(push, 0x00000000);
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 24 |
(asyw->image.pitch[0] >> 8) << 8 |
asyw->image.blocks[0] << 8 |
asyw->image.blockh);
evo_data(push, asyw->image.format << 8);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 10)))
return ret;
PUSH_MTHD(push, NV907C, SET_PRESENT_CONTROL,
NVVAL(NV907C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
NVDEF(NV907C, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE) |
NVVAL(NV907C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
PUSH_MTHD(push, NV907C, SET_CONTEXT_DMAS_ISO(0), asyw->image.handle, 1);
PUSH_MTHD(push, NV907C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8,
SURFACE_SET_OFFSET(0, 1), 0x00000000,
SURFACE_SET_SIZE(0),
NVVAL(NV907C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
NVVAL(NV907C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
SURFACE_SET_STORAGE(0),
NVVAL(NV907C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
NVVAL(NV907C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) |
NVVAL(NV907C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
NVVAL(NV907C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
SURFACE_SET_PARAMS(0),
NVVAL(NV907C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
NVDEF(NV907C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) |
NVDEF(NV907C, SURFACE_SET_PARAMS, GAMMA, LINEAR) |
NVDEF(NV907C, SURFACE_SET_PARAMS, LAYOUT, FRM));
return 0;
}
static void
static int
base907c_xlut_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 6))) {
evo_mthd(push, 0x00e0, 1);
evo_data(push, 0x00000000);
evo_mthd(push, 0x00e8, 1);
evo_data(push, 0x00000000);
evo_mthd(push, 0x00fc, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 6)))
return ret;
PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO,
NVDEF(NV907C, SET_BASE_LUT_LO, ENABLE, DISABLE));
PUSH_MTHD(push, NV907C, SET_OUTPUT_LUT_LO,
NVDEF(NV907C, SET_OUTPUT_LUT_LO, ENABLE, DISABLE));
PUSH_MTHD(push, NV907C, SET_CONTEXT_DMA_LUT, 0x00000000);
return 0;
}
static void
static int
base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 6))) {
evo_mthd(push, 0x00e0, 3);
evo_data(push, asyw->xlut.i.enable << 30 |
asyw->xlut.i.mode << 24);
evo_data(push, asyw->xlut.i.offset >> 8);
evo_data(push, 0x40000000);
evo_mthd(push, 0x00fc, 1);
evo_data(push, asyw->xlut.handle);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 6)))
return ret;
PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO,
NVVAL(NV907C, SET_BASE_LUT_LO, ENABLE, asyw->xlut.i.enable) |
NVVAL(NV907C, SET_BASE_LUT_LO, MODE, asyw->xlut.i.mode),
SET_BASE_LUT_HI, asyw->xlut.i.offset >> 8,
SET_OUTPUT_LUT_LO,
NVDEF(NV907C, SET_OUTPUT_LUT_LO, ENABLE, USE_CORE_LUT));
PUSH_MTHD(push, NV907C, SET_CONTEXT_DMA_LUT, asyw->xlut.handle);
return 0;
}
static bool
......@@ -81,8 +109,12 @@ base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
if (size != 256 && size != 1024)
return false;
asyw->xlut.i.mode = size == 1024 ? 4 : 7;
asyw->xlut.i.enable = 2;
if (size == 1024)
asyw->xlut.i.mode = NV907C_SET_BASE_LUT_LO_MODE_INTERPOLATE_1025_UNITY_RANGE;
else
asyw->xlut.i.mode = NV907C_SET_BASE_LUT_LO_MODE_INTERPOLATE_257_UNITY_RANGE;
asyw->xlut.i.enable = NV907C_SET_BASE_LUT_LO_ENABLE_ENABLE;
asyw->xlut.i.load = head907d_olut_load;
return true;
}
......@@ -125,28 +157,35 @@ base907c_csc(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
}
}
static void
static int
base907c_csc_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x0140, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV907C, SET_CSC_RED2RED,
NVDEF(NV907C, SET_CSC_RED2RED, OWNER, CORE));
return 0;
}
static void
static int
base907c_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push, i;
if ((push = evo_wait(&wndw->wndw, 13))) {
evo_mthd(push, 0x0140, 12);
evo_data(push, asyw->csc.matrix[0] | 0x80000000);
for (i = 1; i < 12; i++)
evo_data(push, asyw->csc.matrix[i]);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 13)))
return ret;
PUSH_MTHD(push, NV907C, SET_CSC_RED2RED,
NVDEF(NV907C, SET_CSC_RED2RED, OWNER, BASE) |
NVVAL(NV907C, SET_CSC_RED2RED, COEFF, asyw->csc.matrix[0]),
SET_CSC_GRN2RED, &asyw->csc.matrix[1], 11);
return 0;
}
const struct nv50_wndw_func
......
......@@ -15,15 +15,15 @@ int nv50_core_new(struct nouveau_drm *, struct nv50_core **);
void nv50_core_del(struct nv50_core **);
struct nv50_core_func {
void (*init)(struct nv50_core *);
int (*init)(struct nv50_core *);
void (*ntfy_init)(struct nouveau_bo *, u32 offset);
int (*caps_init)(struct nouveau_drm *, struct nv50_disp *);
int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset,
struct nvif_device *);
void (*update)(struct nv50_core *, u32 *interlock, bool ntfy);
int (*update)(struct nv50_core *, u32 *interlock, bool ntfy);
struct {
void (*owner)(struct nv50_core *);
int (*owner)(struct nv50_core *);
} wndw;
const struct nv50_head_func *head;
......@@ -31,7 +31,7 @@ struct nv50_core_func {
const struct nv50_crc_func *crc;
#endif
const struct nv50_outp_func {
void (*ctrl)(struct nv50_core *, int or, u32 ctrl,
int (*ctrl)(struct nv50_core *, int or, u32 ctrl,
struct nv50_head_atom *);
/* XXX: Only used by SORs and PIORs for now */
void (*get_caps)(struct nv50_disp *,
......@@ -42,11 +42,11 @@ struct nv50_core_func {
int core507d_new(struct nouveau_drm *, s32, struct nv50_core **);
int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32,
struct nv50_core **);
void core507d_init(struct nv50_core *);
int core507d_init(struct nv50_core *);
void core507d_ntfy_init(struct nouveau_bo *, u32);
int core507d_caps_init(struct nouveau_drm *, struct nv50_disp *);
int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
void core507d_update(struct nv50_core *, u32 *, bool);
int core507d_update(struct nv50_core *, u32 *, bool);
extern const struct nv50_outp_func dac507d;
extern const struct nv50_outp_func sor507d;
......@@ -63,8 +63,8 @@ int core917d_new(struct nouveau_drm *, s32, struct nv50_core **);
int corec37d_new(struct nouveau_drm *, s32, struct nv50_core **);
int corec37d_caps_init(struct nouveau_drm *, struct nv50_disp *);
int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
void corec37d_update(struct nv50_core *, u32 *, bool);
void corec37d_wndw_owner(struct nv50_core *);
int corec37d_update(struct nv50_core *, u32 *, bool);
int corec37d_wndw_owner(struct nv50_core *);
extern const struct nv50_outp_func sorc37d;
int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **);
......
......@@ -23,25 +23,36 @@
#include "head.h"
#include <nvif/cl507d.h>
#include <nvif/push507c.h>
#include <nvif/timer.h>
#include <nvhw/class/cl507d.h>
#include "nouveau_bo.h"
void
int
core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
{
u32 *push;
if ((push = evo_wait(&core->chan, 5))) {
if (ntfy) {
evo_mthd(push, 0x0084, 1);
evo_data(push, 0x80000000 | NV50_DISP_CORE_NTFY);
}
evo_mthd(push, 0x0080, 2);
evo_data(push, interlock[NV50_DISP_INTERLOCK_BASE] |
interlock[NV50_DISP_INTERLOCK_OVLY]);
evo_data(push, 0x00000000);
evo_kick(push, &core->chan);
struct nvif_push *push = core->chan.push;
int ret;
if ((ret = PUSH_WAIT(push, 5)))
return ret;
if (ntfy) {
PUSH_MTHD(push, NV507D, SET_NOTIFIER_CONTROL,
NVDEF(NV507D, SET_NOTIFIER_CONTROL, MODE, WRITE) |
NVVAL(NV507D, SET_NOTIFIER_CONTROL, OFFSET, NV50_DISP_CORE_NTFY >> 2) |
NVDEF(NV507D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE));
}
PUSH_MTHD(push, NV507D, UPDATE, interlock[NV50_DISP_INTERLOCK_BASE] |
interlock[NV50_DISP_INTERLOCK_OVLY] |
NVDEF(NV507D, UPDATE, NOT_DRIVER_FRIENDLY, FALSE) |
NVDEF(NV507D, UPDATE, NOT_DRIVER_UNFRIENDLY, FALSE) |
NVDEF(NV507D, UPDATE, INHIBIT_INTERRUPTS, FALSE));
return PUSH_KICK(push);
}
int
......@@ -49,7 +60,7 @@ core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device)
{
s64 time = nvif_msec(device, 2000ULL,
if (nouveau_bo_rd32(bo, offset / 4))
if (NVBO_TD32(bo, offset, NV_DISP_CORE_NOTIFIER_1, COMPLETION_0, DONE, ==, TRUE))
break;
usleep_range(1, 2);
);
......@@ -59,32 +70,34 @@ core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
void
core507d_ntfy_init(struct nouveau_bo *bo, u32 offset)
{
nouveau_bo_wr32(bo, offset / 4, 0x00000000);
NVBO_WR32(bo, offset, NV_DISP_CORE_NOTIFIER_1, COMPLETION_0,
NVDEF(NV_DISP_CORE_NOTIFIER_1, COMPLETION_0, DONE, FALSE));
}
int
core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
{
u32 *push = evo_wait(&disp->core->chan, 2);
struct nvif_push *push = disp->core->chan.push;
int ret;
if (push) {
evo_mthd(push, 0x008c, 1);
evo_data(push, 0x0);
evo_kick(push, &disp->core->chan);
}
if ((ret = PUSH_WAIT(push, 2)))
return ret;
return 0;
PUSH_MTHD(push, NV507D, GET_CAPABILITIES, 0x00000000);
return PUSH_KICK(push);
}
void
int
core507d_init(struct nv50_core *core)
{
u32 *push;
if ((push = evo_wait(&core->chan, 2))) {
evo_mthd(push, 0x0088, 1);
evo_data(push, core->chan.sync.handle);
evo_kick(push, &core->chan);
}
struct nvif_push *push = core->chan.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle);
return PUSH_KICK(push);
}
static const struct nv50_core_func
......
......@@ -23,56 +23,67 @@
#include "head.h"
#include <nvif/class.h>
#include <nouveau_bo.h>
#include <nvif/pushc37b.h>
#include <nvif/timer.h>
void
#include <nvhw/class/clc37d.h>
#include <nouveau_bo.h>
int
corec37d_wndw_owner(struct nv50_core *core)
{
struct nvif_push *push = core->chan.push;
const u32 windows = 8; /*XXX*/
u32 *push, i;
if ((push = evo_wait(&core->chan, 2 * windows))) {
for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1000 + (i * 0x080), 1);
evo_data(push, i >> 1);
}
evo_kick(push, &core->chan);
int ret, i;
if ((ret = PUSH_WAIT(push, windows * 2)))
return ret;
for (i = 0; i < windows; i++) {
PUSH_MTHD(push, NVC37D, WINDOW_SET_CONTROL(i),
NVDEF(NVC37D, WINDOW_SET_CONTROL, OWNER, HEAD(i >> 1)));
}
return 0;
}
void
int
corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
{
u32 *push;
if ((push = evo_wait(&core->chan, 9))) {
if (ntfy) {
evo_mthd(push, 0x020c, 1);
evo_data(push, 0x00001000 | NV50_DISP_CORE_NTFY);
}
evo_mthd(push, 0x0218, 2);
evo_data(push, interlock[NV50_DISP_INTERLOCK_CURS]);
evo_data(push, interlock[NV50_DISP_INTERLOCK_WNDW]);
evo_mthd(push, 0x0200, 1);
evo_data(push, 0x00000001);
if (ntfy) {
evo_mthd(push, 0x020c, 1);
evo_data(push, 0x00000000);
}
evo_kick(push, &core->chan);
struct nvif_push *push = core->chan.push;
int ret;
if ((ret = PUSH_WAIT(push, 9)))
return ret;
if (ntfy) {
PUSH_MTHD(push, NVC37D, SET_NOTIFIER_CONTROL,
NVDEF(NVC37D, SET_NOTIFIER_CONTROL, MODE, WRITE) |
NVVAL(NVC37D, SET_NOTIFIER_CONTROL, OFFSET, NV50_DISP_CORE_NTFY >> 4) |
NVDEF(NVC37D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE));
}
PUSH_MTHD(push, NVC37D, SET_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_CURS],
SET_WINDOW_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_WNDW]);
PUSH_MTHD(push, NVC37D, UPDATE, 0x00000001 |
NVDEF(NVC37D, UPDATE, SPECIAL_HANDLING, NONE) |
NVDEF(NVC37D, UPDATE, INHIBIT_INTERRUPTS, FALSE));
if (ntfy) {
PUSH_MTHD(push, NVC37D, SET_NOTIFIER_CONTROL,
NVDEF(NVC37D, SET_NOTIFIER_CONTROL, NOTIFY, DISABLE));
}
return PUSH_KICK(push);
}
int
corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device)
{
u32 data;
s64 time = nvif_msec(device, 2000ULL,
data = nouveau_bo_rd32(bo, offset / 4 + 0);
if ((data & 0xc0000000) == 0x80000000)
if (NVBO_TD32(bo, offset, NV_DISP_NOTIFIER, _0, STATUS, ==, FINISHED))
break;
usleep_range(1, 2);
);
......@@ -82,18 +93,19 @@ corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
void
corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset)
{
nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000);
nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000);
nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000);
nouveau_bo_wr32(bo, offset / 4 + 3, 0x00000000);
NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _0,
NVDEF(NV_DISP_NOTIFIER, _0, STATUS, NOT_BEGUN));
NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _1, 0);
NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _2, 0);
NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _3, 0);
}
int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
{
int ret;
ret = nvif_object_init(&disp->disp->object, 0, GV100_DISP_CAPS,
NULL, 0, &disp->caps);
ret = nvif_object_ctor(&disp->disp->object, "dispCaps", 0,
GV100_DISP_CAPS, NULL, 0, &disp->caps);
if (ret) {
NV_ERROR(drm,
"Failed to init notifier caps region: %d\n",
......@@ -112,24 +124,37 @@ int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
return 0;
}
static void
static int
corec37d_init(struct nv50_core *core)
{
struct nvif_push *push = core->chan.push;
const u32 windows = 8; /*XXX*/
u32 *push, i;
if ((push = evo_wait(&core->chan, 2 + 5 * windows))) {
evo_mthd(push, 0x0208, 1);
evo_data(push, core->chan.sync.handle);
for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1004 + (i * 0x080), 2);
evo_data(push, 0x0000001f);
evo_data(push, 0x00000000);
evo_mthd(push, 0x1010 + (i * 0x080), 1);
evo_data(push, 0x00127fff);
}
evo_kick(push, &core->chan);
core->assign_windows = true;
int ret, i;
if ((ret = PUSH_WAIT(push, 2 + windows * 5)))
return ret;
PUSH_MTHD(push, NVC37D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle);
for (i = 0; i < windows; i++) {
PUSH_MTHD(push, NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i),
NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) |
NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) |
NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) |
NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED8BPP, TRUE) |
NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, YUV_PACKED422, TRUE),
WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS(i), 0x00000000);
PUSH_MTHD(push, NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS(i),
NVVAL(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, MAX_PIXELS_FETCHED_PER_LINE, 0x7fff) |
NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_LUT, USAGE_1025) |
NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_SCALER_TAPS, TAPS_2) |
NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, UPSCALING_ALLOWED, FALSE));
}
core->assign_windows = true;
return PUSH_KICK(push);
}
static const struct nv50_core_func
......
......@@ -22,24 +22,40 @@
#include "core.h"
#include "head.h"
static void
#include <nvif/pushc37b.h>
#include <nvhw/class/clc57d.h>
static int
corec57d_init(struct nv50_core *core)
{
struct nvif_push *push = core->chan.push;
const u32 windows = 8; /*XXX*/
u32 *push, i;
if ((push = evo_wait(&core->chan, 2 + 5 * windows))) {
evo_mthd(push, 0x0208, 1);
evo_data(push, core->chan.sync.handle);
for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1004 + (i * 0x080), 2);
evo_data(push, 0x0000000f);
evo_data(push, 0x00000000);
evo_mthd(push, 0x1010 + (i * 0x080), 1);
evo_data(push, 0x00117fff);
}
evo_kick(push, &core->chan);
core->assign_windows = true;
int ret, i;
if ((ret = PUSH_WAIT(push, 2 + windows * 5)))
return ret;
PUSH_MTHD(push, NVC57D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle);
for (i = 0; i < windows; i++) {
PUSH_MTHD(push, NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i),
NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) |
NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) |
NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) |
NVDEF(NVC57D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED8BPP, TRUE),
WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS(i), 0x00000000);
PUSH_MTHD(push, NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS(i),
NVVAL(NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS, MAX_PIXELS_FETCHED_PER_LINE, 0x7fff) |
NVDEF(NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS, ILUT_ALLOWED, TRUE) |
NVDEF(NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_SCALER_TAPS, TAPS_2) |
NVDEF(NVC57D, WINDOW_SET_WINDOW_USAGE_BOUNDS, UPSCALING_ALLOWED, FALSE));
}
core->assign_windows = true;
return PUSH_KICK(push);
}
static const struct nv50_core_func
......
......@@ -9,6 +9,8 @@
#include <nvif/cl0002.h>
#include <nvif/timer.h>
#include <nvhw/class/cl907d.h>
#include "nouveau_drv.h"
#include "core.h"
#include "head.h"
......@@ -478,10 +480,6 @@ void nv50_crc_atomic_clr(struct nv50_head *head)
func->set_src(head, 0, NV50_CRC_SOURCE_TYPE_NONE, NULL, 0);
}
#define NV50_CRC_RASTER_ACTIVE 0
#define NV50_CRC_RASTER_COMPLETE 1
#define NV50_CRC_RASTER_INACTIVE 2
static inline int
nv50_crc_raster_type(enum nv50_crc_source source)
{
......@@ -490,11 +488,11 @@ nv50_crc_raster_type(enum nv50_crc_source source)
case NV50_CRC_SOURCE_AUTO:
case NV50_CRC_SOURCE_RG:
case NV50_CRC_SOURCE_OUTP_ACTIVE:
return NV50_CRC_RASTER_ACTIVE;
return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_ACTIVE_RASTER;
case NV50_CRC_SOURCE_OUTP_COMPLETE:
return NV50_CRC_RASTER_COMPLETE;
return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_COMPLETE_RASTER;
case NV50_CRC_SOURCE_OUTP_INACTIVE:
return NV50_CRC_RASTER_INACTIVE;
return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_NON_ACTIVE_RASTER;
}
return 0;
......@@ -510,11 +508,11 @@ nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu,
struct nv50_core *core = nv50_disp(head->base.base.dev)->core;
int ret;
ret = nvif_mem_init_map(mmu, NVIF_MEM_VRAM, len, &ctx->mem);
ret = nvif_mem_ctor_map(mmu, "kmsCrcNtfy", NVIF_MEM_VRAM, len, &ctx->mem);
if (ret)
return ret;
ret = nvif_object_init(&core->chan.base.user,
ret = nvif_object_ctor(&core->chan.base.user, "kmsCrcNtfyCtxDma",
NV50_DISP_HANDLE_CRC_CTX(head, idx),
NV_DMA_IN_MEMORY,
&(struct nv_dma_v0) {
......@@ -531,15 +529,15 @@ nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu,
return 0;
fail_fini:
nvif_mem_fini(&ctx->mem);
nvif_mem_dtor(&ctx->mem);
return ret;
}
static inline void
nv50_crc_ctx_fini(struct nv50_crc_notifier_ctx *ctx)
{
nvif_object_fini(&ctx->ntfy);
nvif_mem_fini(&ctx->mem);
nvif_object_dtor(&ctx->ntfy);
nvif_mem_dtor(&ctx->mem);
}
int nv50_crc_set_source(struct drm_crtc *crtc, const char *source_str)
......
......@@ -50,9 +50,9 @@ struct nv50_crc_atom {
};
struct nv50_crc_func {
void (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type,
struct nv50_crc_notifier_ctx *, u32 wndw);
void (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);
int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type,
struct nv50_crc_notifier_ctx *, u32 wndw);
int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);
u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *,
enum nv50_crc_source, int idx);
bool (*ctx_finished)(struct nv50_head *,
......@@ -106,26 +106,27 @@ struct nv50_crc_atom {};
#define nv50_crc_set_source NULL
static inline void nv50_crc_init(struct drm_device *dev) {}
static inline int nv50_head_crc_late_register(struct nv50_head *) {}
static inline void
nv50_crc_handle_vblank(struct nv50_head *head) { return 0; }
static inline int
nv50_head_crc_late_register(struct nv50_head *head) { return 0; }
static inline void nv50_crc_handle_vblank(struct nv50_head *head) {}
static inline int
nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *,
struct nv50_head_atom *) {}
nv50_crc_atomic_check_head(struct nv50_head *head,
struct nv50_head_atom *asyh,
struct nv50_head_atom *armh) { return 0; }
static inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {}
static inline void
nv50_crc_atomic_stop_reporting(struct drm_atomic_state *) {}
nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {}
static inline void
nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *) {}
nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {}
static inline void
nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *) {}
nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {}
static inline void
nv50_crc_atomic_start_reporting(struct drm_atomic_state *) {}
nv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {}
static inline void
nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *) {}
nv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {}
static inline void
nv50_crc_atomic_clr(struct nv50_head *) {}
nv50_crc_atomic_clr(struct nv50_head *head) {}
#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
#endif /* !__NV50_CRC_H__ */
......@@ -6,6 +6,10 @@
#include "disp.h"
#include "head.h"
#include <nvif/push507c.h>
#include <nvhw/class/cl907d.h>
#define CRC907D_MAX_ENTRIES 255
struct crc907d_notifier {
......@@ -18,68 +22,67 @@ struct crc907d_notifier {
} entries[CRC907D_MAX_ENTRIES];
} __packed;
static void
static int
crc907d_set_src(struct nv50_head *head, int or,
enum nv50_crc_source_type source,
struct nv50_crc_notifier_ctx *ctx, u32 wndw)
{
struct drm_crtc *crtc = &head->base.base;
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
const u32 hoff = head->base.index * 0x300;
u32 *push;
u32 crc_args = 0xfff00000;
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
u32 crc_args = NVDEF(NV907D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, CORE) |
NVDEF(NV907D, HEAD_SET_CRC_CONTROL, EXPECT_BUFFER_COLLAPSE, FALSE) |
NVDEF(NV907D, HEAD_SET_CRC_CONTROL, TIMESTAMP_MODE, FALSE) |
NVDEF(NV907D, HEAD_SET_CRC_CONTROL, SECONDARY_OUTPUT, NONE) |
NVDEF(NV907D, HEAD_SET_CRC_CONTROL, CRC_DURING_SNOOZE, DISABLE);
int ret;
switch (source) {
case NV50_CRC_SOURCE_TYPE_SOR:
crc_args |= (0x00000f0f + or * 16) << 8;
crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, SOR(or));
break;
case NV50_CRC_SOURCE_TYPE_PIOR:
crc_args |= (0x000000ff + or * 256) << 8;
crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, PIOR(or));
break;
case NV50_CRC_SOURCE_TYPE_DAC:
crc_args |= (0x00000ff0 + or) << 8;
crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, DAC(or));
break;
case NV50_CRC_SOURCE_TYPE_RG:
crc_args |= (0x00000ff8 + drm_crtc_index(crtc)) << 8;
crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, RG(i));
break;
case NV50_CRC_SOURCE_TYPE_SF:
crc_args |= (0x00000f8f + drm_crtc_index(crtc) * 16) << 8;
crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, SF(i));
break;
case NV50_CRC_SOURCE_NONE:
crc_args |= 0x000fff00;
crc_args |= NVDEF(NV907D, HEAD_SET_CRC_CONTROL, PRIMARY_OUTPUT, NONE);
break;
}
push = evo_wait(core, 4);
if (!push)
return;
if ((ret = PUSH_WAIT(push, 4)))
return ret;
if (source) {
evo_mthd(push, 0x0438 + hoff, 1);
evo_data(push, ctx->ntfy.handle);
evo_mthd(push, 0x0430 + hoff, 1);
evo_data(push, crc_args);
PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx->ntfy.handle);
PUSH_MTHD(push, NV907D, HEAD_SET_CRC_CONTROL(i), crc_args);
} else {
evo_mthd(push, 0x0430 + hoff, 1);
evo_data(push, crc_args);
evo_mthd(push, 0x0438 + hoff, 1);
evo_data(push, 0);
PUSH_MTHD(push, NV907D, HEAD_SET_CRC_CONTROL(i), crc_args);
PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), 0);
}
evo_kick(push, core);
return 0;
}
static void crc907d_set_ctx(struct nv50_head *head,
struct nv50_crc_notifier_ctx *ctx)
static int
crc907d_set_ctx(struct nv50_head *head, struct nv50_crc_notifier_ctx *ctx)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push = evo_wait(core, 2);
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if (!push)
return;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
evo_mthd(push, 0x0438 + (head->base.index * 0x300), 1);
evo_data(push, ctx ? ctx->ntfy.handle : 0);
evo_kick(push, core);
PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx ? ctx->ntfy.handle : 0);
return 0;
}
static u32 crc907d_get_entry(struct nv50_head *head,
......
......@@ -6,6 +6,10 @@
#include "disp.h"
#include "head.h"
#include <nvif/push507c.h>
#include <nvhw/class/clc37d.h>
#define CRCC37D_MAX_ENTRIES 2047
struct crcc37d_notifier {
......@@ -30,62 +34,59 @@ struct crcc37d_notifier {
} entries[CRCC37D_MAX_ENTRIES];
} __packed;
static void
static int
crcc37d_set_src(struct nv50_head *head, int or,
enum nv50_crc_source_type source,
struct nv50_crc_notifier_ctx *ctx, u32 wndw)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
const u32 hoff = head->base.index * 0x400;
u32 *push;
u32 crc_args;
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
u32 crc_args = NVVAL(NVC37D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, wndw) |
NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, EXPECT_BUFFER_COLLAPSE, FALSE) |
NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, SECONDARY_CRC, NONE) |
NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, CRC_DURING_SNOOZE, DISABLE);
int ret;
switch (source) {
case NV50_CRC_SOURCE_TYPE_SOR:
crc_args = (0x00000050 + or) << 12;
crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, SOR(or));
break;
case NV50_CRC_SOURCE_TYPE_PIOR:
crc_args = (0x00000060 + or) << 12;
crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, PIOR(or));
break;
case NV50_CRC_SOURCE_TYPE_SF:
crc_args = 0x00000030 << 12;
crc_args |= NVDEF(NVC37D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, SF);
break;
default:
crc_args = 0;
break;
}
push = evo_wait(core, 4);
if (!push)
return;
if ((ret = PUSH_WAIT(push, 4)))
return ret;
if (source) {
evo_mthd(push, 0x2180 + hoff, 1);
evo_data(push, ctx->ntfy.handle);
evo_mthd(push, 0x2184 + hoff, 1);
evo_data(push, crc_args | wndw);
PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx->ntfy.handle);
PUSH_MTHD(push, NVC37D, HEAD_SET_CRC_CONTROL(i), crc_args);
} else {
evo_mthd(push, 0x2184 + hoff, 1);
evo_data(push, 0);
evo_mthd(push, 0x2180 + hoff, 1);
evo_data(push, 0);
PUSH_MTHD(push, NVC37D, HEAD_SET_CRC_CONTROL(i), 0);
PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), 0);
}
evo_kick(push, core);
return 0;
}
static void crcc37d_set_ctx(struct nv50_head *head,
struct nv50_crc_notifier_ctx *ctx)
static int
crcc37d_set_ctx(struct nv50_head *head, struct nv50_crc_notifier_ctx *ctx)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push = evo_wait(core, 2);
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if (!push)
return;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
evo_mthd(push, 0x2180 + (head->base.index * 0x400), 1);
evo_data(push, ctx ? ctx->ntfy.handle : 0);
evo_kick(push, core);
PUSH_MTHD(push, NVC37D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx ? ctx->ntfy.handle : 0);
return 0;
}
static u32 crcc37d_get_entry(struct nv50_head *head,
......
......@@ -26,6 +26,8 @@
#include <nvif/cl507a.h>
#include <nvif/timer.h>
#include <nvhw/class/cl507a.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_plane_helper.h>
......@@ -33,27 +35,37 @@ bool
curs507a_space(struct nv50_wndw *wndw)
{
nvif_msec(&nouveau_drm(wndw->plane.dev)->client.device, 100,
if (nvif_rd32(&wndw->wimm.base.user, 0x0008) >= 4)
if (NVIF_TV32(&wndw->wimm.base.user, NV507A, FREE, COUNT, >=, 4))
return true;
);
WARN_ON(1);
return false;
}
static void
static int
curs507a_update(struct nv50_wndw *wndw, u32 *interlock)
{
if (curs507a_space(wndw))
nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000);
struct nvif_object *user = &wndw->wimm.base.user;
int ret = nvif_chan_wait(&wndw->wimm, 1);
if (ret == 0) {
NVIF_WR32(user, NV507A, UPDATE,
NVDEF(NV507A, UPDATE, INTERLOCK_WITH_CORE, DISABLE));
}
return ret;
}
static void
static int
curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
if (curs507a_space(wndw)) {
nvif_wr32(&wndw->wimm.base.user, 0x0084, asyw->point.y << 16 |
asyw->point.x);
struct nvif_object *user = &wndw->wimm.base.user;
int ret = nvif_chan_wait(&wndw->wimm, 1);
if (ret == 0) {
NVIF_WR32(user, NV507A, SET_CURSOR_HOT_SPOT_POINT_OUT,
NVVAL(NV507A, SET_CURSOR_HOT_SPOT_POINT_OUT, X, asyw->point.x) |
NVVAL(NV507A, SET_CURSOR_HOT_SPOT_POINT_OUT, Y, asyw->point.y));
}
return ret;
}
const struct nv50_wimm_func
......@@ -138,8 +150,8 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
if (*pwndw = wndw, ret)
return ret;
ret = nvif_object_init(&disp->disp->object, 0, oclass, &args,
sizeof(args), &wndw->wimm.base.user);
ret = nvif_object_ctor(&disp->disp->object, "kmsCurs", 0, oclass,
&args, sizeof(args), &wndw->wimm.base.user);
if (ret) {
NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret);
return ret;
......
......@@ -22,20 +22,29 @@
#include "curs.h"
#include "atom.h"
static void
#include <nvhw/class/clc37a.h>
static int
cursc37a_update(struct nv50_wndw *wndw, u32 *interlock)
{
if (curs507a_space(wndw))
nvif_wr32(&wndw->wimm.base.user, 0x0200, 0x00000001);
struct nvif_object *user = &wndw->wimm.base.user;
int ret = nvif_chan_wait(&wndw->wimm, 1);
if (ret == 0)
NVIF_WR32(user, NVC37A, UPDATE, 0x00000001);
return ret;
}
static void
static int
cursc37a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
if (curs507a_space(wndw)) {
nvif_wr32(&wndw->wimm.base.user, 0x0208, asyw->point.y << 16 |
asyw->point.x);
struct nvif_object *user = &wndw->wimm.base.user;
int ret = nvif_chan_wait(&wndw->wimm, 1);
if (ret == 0) {
NVIF_WR32(user, NVC37A, SET_CURSOR_HOT_SPOT_POINT_OUT(0),
NVVAL(NVC37A, SET_CURSOR_HOT_SPOT_POINT_OUT, X, asyw->point.x) |
NVVAL(NVC37A, SET_CURSOR_HOT_SPOT_POINT_OUT, Y, asyw->point.y));
}
return ret;
}
static const struct nv50_wimm_func
......
......@@ -21,21 +21,29 @@
*/
#include "core.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl507d.h>
static int
dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh)
{
u32 *push, sync = 0;
if ((push = evo_wait(&core->chan, 3))) {
if (asyh) {
sync |= asyh->or.nvsync << 1;
sync |= asyh->or.nhsync;
}
evo_mthd(push, 0x0400 + (or * 0x080), 2);
evo_data(push, ctrl);
evo_data(push, sync);
evo_kick(push, &core->chan);
struct nvif_push *push = core->chan.push;
u32 sync = 0;
int ret;
if (asyh) {
sync |= NVVAL(NV507D, DAC_SET_POLARITY, HSYNC, asyh->or.nhsync);
sync |= NVVAL(NV507D, DAC_SET_POLARITY, VSYNC, asyh->or.nvsync);
}
if ((ret = PUSH_WAIT(push, 3)))
return ret;
PUSH_MTHD(push, NV507D, DAC_SET_CONTROL(or), ctrl,
DAC_SET_POLARITY(or), sync);
return 0;
}
const struct nv50_outp_func
......
......@@ -21,16 +21,22 @@
*/
#include "core.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl907d.h>
static int
dac907d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh)
{
u32 *push;
if ((push = evo_wait(&core->chan, 2))) {
evo_mthd(push, 0x0180 + (or * 0x020), 1);
evo_data(push, ctrl);
evo_kick(push, &core->chan);
}
struct nvif_push *push = core->chan.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV907D, DAC_SET_CONTROL(or), ctrl);
return 0;
}
const struct nv50_outp_func
......
This diff is collapsed.
......@@ -2,6 +2,7 @@
#define __NV50_KMS_H__
#include <linux/workqueue.h>
#include <nvif/mem.h>
#include <nvif/push.h>
#include "nouveau_display.h"
......@@ -61,7 +62,8 @@ struct nv50_chan {
struct nv50_dmac {
struct nv50_chan base;
struct nvif_mem push;
struct nvif_push _push;
struct nvif_push *push;
u32 *ptr;
struct nvif_object sync;
......@@ -71,6 +73,10 @@ struct nv50_dmac {
* grabbed by evo_wait (if the pushbuf reservation is successful) and
* dropped again by evo_kick. */
struct mutex lock;
u32 cur;
u32 put;
u32 max;
};
struct nv50_outp_atom {
......@@ -106,18 +112,4 @@ void evo_kick(u32 *, struct nv50_dmac *);
extern const u64 disp50xx_modifiers[];
extern const u64 disp90xx_modifiers[];
extern const u64 wndwc57e_modifiers[];
#define evo_mthd(p, m, s) do { \
const u32 _m = (m), _s = (s); \
if (drm_debug_enabled(DRM_UT_KMS)) \
pr_err("%04x %d %s\n", _m, _s, __func__); \
*((p)++) = ((_s << 18) | _m); \
} while(0)
#define evo_data(p, d) do { \
const u32 _d = (d); \
if (drm_debug_enabled(DRM_UT_KMS)) \
pr_err("\t%08x\n", _d); \
*((p)++) = _d; \
} while(0)
#endif
......@@ -106,9 +106,9 @@ nv50_head_atomic_check_dither(struct nv50_head_atom *armh,
}
}
asyh->dither.enable = mode;
asyh->dither.bits = mode >> 1;
asyh->dither.mode = mode >> 3;
asyh->dither.enable = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, ENABLE);
asyh->dither.bits = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, BITS);
asyh->dither.mode = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, MODE);
asyh->set.dither = true;
}
......@@ -489,7 +489,7 @@ nv50_head_destroy(struct drm_crtc *crtc)
{
struct nv50_head *head = nv50_head(crtc);
nvif_notify_fini(&head->base.vblank);
nvif_notify_dtor(&head->base.vblank);
nv50_lut_fini(&head->olut);
drm_crtc_cleanup(crtc);
kfree(head);
......@@ -598,7 +598,7 @@ nv50_head_create(struct drm_device *dev, int index)
}
}
ret = nvif_notify_init(&disp->disp->object, nv50_head_vblank_handler,
ret = nvif_notify_ctor(&disp->disp->object, "kmsVbl", nv50_head_vblank_handler,
false, NV04_DISP_NTFY_VBLANK,
&(struct nvif_notify_head_req_v0) {
.head = nv_crtc->index,
......
......@@ -25,74 +25,72 @@ void nv50_head_flush_clr(struct nv50_head *head,
struct nv50_head_atom *asyh, bool flush);
struct nv50_head_func {
void (*view)(struct nv50_head *, struct nv50_head_atom *);
void (*mode)(struct nv50_head *, struct nv50_head_atom *);
int (*view)(struct nv50_head *, struct nv50_head_atom *);
int (*mode)(struct nv50_head *, struct nv50_head_atom *);
bool (*olut)(struct nv50_head *, struct nv50_head_atom *, int);
bool olut_identity;
int olut_size;
void (*olut_set)(struct nv50_head *, struct nv50_head_atom *);
void (*olut_clr)(struct nv50_head *);
int (*olut_set)(struct nv50_head *, struct nv50_head_atom *);
int (*olut_clr)(struct nv50_head *);
void (*core_calc)(struct nv50_head *, struct nv50_head_atom *);
void (*core_set)(struct nv50_head *, struct nv50_head_atom *);
void (*core_clr)(struct nv50_head *);
int (*core_set)(struct nv50_head *, struct nv50_head_atom *);
int (*core_clr)(struct nv50_head *);
int (*curs_layout)(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
int (*curs_format)(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
void (*curs_set)(struct nv50_head *, struct nv50_head_atom *);
void (*curs_clr)(struct nv50_head *);
void (*base)(struct nv50_head *, struct nv50_head_atom *);
void (*ovly)(struct nv50_head *, struct nv50_head_atom *);
void (*dither)(struct nv50_head *, struct nv50_head_atom *);
void (*procamp)(struct nv50_head *, struct nv50_head_atom *);
void (*or)(struct nv50_head *, struct nv50_head_atom *);
int (*curs_set)(struct nv50_head *, struct nv50_head_atom *);
int (*curs_clr)(struct nv50_head *);
int (*base)(struct nv50_head *, struct nv50_head_atom *);
int (*ovly)(struct nv50_head *, struct nv50_head_atom *);
int (*dither)(struct nv50_head *, struct nv50_head_atom *);
int (*procamp)(struct nv50_head *, struct nv50_head_atom *);
int (*or)(struct nv50_head *, struct nv50_head_atom *);
void (*static_wndw_map)(struct nv50_head *, struct nv50_head_atom *);
};
extern const struct nv50_head_func head507d;
void head507d_view(struct nv50_head *, struct nv50_head_atom *);
void head507d_mode(struct nv50_head *, struct nv50_head_atom *);
int head507d_view(struct nv50_head *, struct nv50_head_atom *);
int head507d_mode(struct nv50_head *, struct nv50_head_atom *);
bool head507d_olut(struct nv50_head *, struct nv50_head_atom *, int);
void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *);
void head507d_core_clr(struct nv50_head *);
int head507d_core_clr(struct nv50_head *);
int head507d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
int head507d_curs_format(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
void head507d_base(struct nv50_head *, struct nv50_head_atom *);
void head507d_ovly(struct nv50_head *, struct nv50_head_atom *);
void head507d_dither(struct nv50_head *, struct nv50_head_atom *);
void head507d_procamp(struct nv50_head *, struct nv50_head_atom *);
int head507d_base(struct nv50_head *, struct nv50_head_atom *);
int head507d_ovly(struct nv50_head *, struct nv50_head_atom *);
int head507d_dither(struct nv50_head *, struct nv50_head_atom *);
int head507d_procamp(struct nv50_head *, struct nv50_head_atom *);
extern const struct nv50_head_func head827d;
extern const struct nv50_head_func head907d;
void head907d_view(struct nv50_head *, struct nv50_head_atom *);
void head907d_mode(struct nv50_head *, struct nv50_head_atom *);
int head907d_view(struct nv50_head *, struct nv50_head_atom *);
int head907d_mode(struct nv50_head *, struct nv50_head_atom *);
bool head907d_olut(struct nv50_head *, struct nv50_head_atom *, int);
void head907d_olut_set(struct nv50_head *, struct nv50_head_atom *);
void head907d_olut_clr(struct nv50_head *);
void head907d_core_set(struct nv50_head *, struct nv50_head_atom *);
void head907d_core_clr(struct nv50_head *);
void head907d_curs_set(struct nv50_head *, struct nv50_head_atom *);
void head907d_curs_clr(struct nv50_head *);
void head907d_ovly(struct nv50_head *, struct nv50_head_atom *);
void head907d_procamp(struct nv50_head *, struct nv50_head_atom *);
void head907d_or(struct nv50_head *, struct nv50_head_atom *);
int head907d_olut_set(struct nv50_head *, struct nv50_head_atom *);
int head907d_olut_clr(struct nv50_head *);
int head907d_core_set(struct nv50_head *, struct nv50_head_atom *);
int head907d_core_clr(struct nv50_head *);
int head907d_curs_set(struct nv50_head *, struct nv50_head_atom *);
int head907d_curs_clr(struct nv50_head *);
int head907d_ovly(struct nv50_head *, struct nv50_head_atom *);
int head907d_procamp(struct nv50_head *, struct nv50_head_atom *);
int head907d_or(struct nv50_head *, struct nv50_head_atom *);
extern const struct nv50_head_func head917d;
int head917d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
extern const struct nv50_head_func headc37d;
void headc37d_view(struct nv50_head *, struct nv50_head_atom *);
void headc37d_core_set(struct nv50_head *, struct nv50_head_atom *);
void headc37d_core_clr(struct nv50_head *);
int headc37d_view(struct nv50_head *, struct nv50_head_atom *);
int headc37d_curs_format(struct nv50_head *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
void headc37d_curs_set(struct nv50_head *, struct nv50_head_atom *);
void headc37d_curs_clr(struct nv50_head *);
void headc37d_dither(struct nv50_head *, struct nv50_head_atom *);
int headc37d_curs_set(struct nv50_head *, struct nv50_head_atom *);
int headc37d_curs_clr(struct nv50_head *);
int headc37d_dither(struct nv50_head *, struct nv50_head_atom *);
void headc37d_static_wndw_map(struct nv50_head *, struct nv50_head_atom *);
extern const struct nv50_head_func headc57d;
......
This diff is collapsed.
......@@ -22,85 +22,128 @@
#include "head.h"
#include "core.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl827d.h>
static int
head827d_curs_clr(struct nv50_head *head)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 4))) {
evo_mthd(push, 0x0880 + head->base.index * 0x400, 1);
evo_data(push, 0x05000000);
evo_mthd(push, 0x089c + head->base.index * 0x400, 1);
evo_data(push, 0x00000000);
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 4)))
return ret;
PUSH_MTHD(push, NV827D, HEAD_SET_CONTROL_CURSOR(i),
NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) |
NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8) |
NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, SIZE, W64_H64));
PUSH_MTHD(push, NV827D, HEAD_SET_CONTEXT_DMA_CURSOR(i), 0x00000000);
return 0;
}
static void
static int
head827d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 5))) {
evo_mthd(push, 0x0880 + head->base.index * 0x400, 2);
evo_data(push, 0x80000000 | asyh->curs.layout << 26 |
asyh->curs.format << 24);
evo_data(push, asyh->curs.offset >> 8);
evo_mthd(push, 0x089c + head->base.index * 0x400, 1);
evo_data(push, asyh->curs.handle);
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 5)))
return ret;
PUSH_MTHD(push, NV827D, HEAD_SET_CONTROL_CURSOR(i),
NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) |
NVVAL(NV827D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) |
NVVAL(NV827D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) |
NVVAL(NV827D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) |
NVVAL(NV827D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) |
NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND) |
NVDEF(NV827D, HEAD_SET_CONTROL_CURSOR, SUB_OWNER, NONE),
HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8);
PUSH_MTHD(push, NV827D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle);
return 0;
}
static void
static int
head827d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 9))) {
evo_mthd(push, 0x0860 + head->base.index * 0x400, 1);
evo_data(push, asyh->core.offset >> 8);
evo_mthd(push, 0x0868 + head->base.index * 0x400, 4);
evo_data(push, asyh->core.h << 16 | asyh->core.w);
evo_data(push, asyh->core.layout << 20 |
(asyh->core.pitch >> 8) << 8 |
asyh->core.blocks << 8 |
asyh->core.blockh);
evo_data(push, asyh->core.format << 8);
evo_data(push, asyh->core.handle);
evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1);
evo_data(push, asyh->core.y << 16 | asyh->core.x);
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 9)))
return ret;
PUSH_MTHD(push, NV827D, HEAD_SET_OFFSET(i, 0),
NVVAL(NV827D, HEAD_SET_OFFSET, ORIGIN, asyh->core.offset >> 8));
PUSH_MTHD(push, NV827D, HEAD_SET_SIZE(i),
NVVAL(NV827D, HEAD_SET_SIZE, WIDTH, asyh->core.w) |
NVVAL(NV827D, HEAD_SET_SIZE, HEIGHT, asyh->core.h),
HEAD_SET_STORAGE(i),
NVVAL(NV827D, HEAD_SET_STORAGE, BLOCK_HEIGHT, asyh->core.blockh) |
NVVAL(NV827D, HEAD_SET_STORAGE, PITCH, asyh->core.pitch >> 8) |
NVVAL(NV827D, HEAD_SET_STORAGE, PITCH, asyh->core.blocks) |
NVVAL(NV827D, HEAD_SET_STORAGE, MEMORY_LAYOUT, asyh->core.layout),
HEAD_SET_PARAMS(i),
NVVAL(NV827D, HEAD_SET_PARAMS, FORMAT, asyh->core.format) |
NVDEF(NV827D, HEAD_SET_PARAMS, SUPER_SAMPLE, X1_AA) |
NVDEF(NV827D, HEAD_SET_PARAMS, GAMMA, LINEAR),
HEAD_SET_CONTEXT_DMAS_ISO(i, 0),
NVVAL(NV827D, HEAD_SET_CONTEXT_DMAS_ISO, HANDLE, asyh->core.handle));
PUSH_MTHD(push, NV827D, HEAD_SET_VIEWPORT_POINT_IN(i, 0),
NVVAL(NV827D, HEAD_SET_VIEWPORT_POINT_IN, X, asyh->core.x) |
NVVAL(NV827D, HEAD_SET_VIEWPORT_POINT_IN, Y, asyh->core.y));
return 0;
}
static void
static int
head827d_olut_clr(struct nv50_head *head)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 4))) {
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1);
evo_data(push, 0x00000000);
evo_mthd(push, 0x085c + (head->base.index * 0x400), 1);
evo_data(push, 0x00000000);
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 4)))
return ret;
PUSH_MTHD(push, NV827D, HEAD_SET_BASE_LUT_LO(i),
NVDEF(NV827D, HEAD_SET_BASE_LUT_LO, ENABLE, DISABLE));
PUSH_MTHD(push, NV827D, HEAD_SET_CONTEXT_DMA_LUT(i), 0x00000000);
return 0;
}
static void
static int
head827d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 5))) {
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2);
evo_data(push, 0x80000000 | asyh->olut.mode << 30);
evo_data(push, asyh->olut.offset >> 8);
evo_mthd(push, 0x085c + (head->base.index * 0x400), 1);
evo_data(push, asyh->olut.handle);
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 5)))
return ret;
PUSH_MTHD(push, NV827D, HEAD_SET_BASE_LUT_LO(i),
NVDEF(NV827D, HEAD_SET_BASE_LUT_LO, ENABLE, ENABLE) |
NVVAL(NV827D, HEAD_SET_BASE_LUT_LO, MODE, asyh->olut.mode) |
NVVAL(NV827D, HEAD_SET_BASE_LUT_LO, ORIGIN, 0),
HEAD_SET_BASE_LUT_HI(i),
NVVAL(NV827D, HEAD_SET_BASE_LUT_HI, ORIGIN, asyh->olut.offset >> 8));
PUSH_MTHD(push, NV827D, HEAD_SET_CONTEXT_DMA_LUT(i), asyh->olut.handle);
return 0;
}
const struct nv50_head_func
......
This diff is collapsed.
......@@ -22,45 +22,55 @@
#include "head.h"
#include "core.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl917d.h>
static int
head917d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 2))) {
evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1);
evo_data(push, asyh->dither.mode << 3 |
asyh->dither.bits << 1 |
asyh->dither.enable);
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV917D, HEAD_SET_DITHER_CONTROL(i),
NVVAL(NV917D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) |
NVVAL(NV917D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) |
NVVAL(NV917D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) |
NVVAL(NV917D, HEAD_SET_DITHER_CONTROL, PHASE, 0));
return 0;
}
static void
static int
head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
u32 bounds = 0;
u32 *push;
int ret;
if (asyh->base.cpp) {
switch (asyh->base.cpp) {
case 8: bounds |= 0x00000500; break;
case 4: bounds |= 0x00000300; break;
case 2: bounds |= 0x00000100; break;
case 1: bounds |= 0x00000000; break;
case 8: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break;
case 4: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break;
case 2: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break;
case 1: bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_8); break;
default:
WARN_ON(1);
break;
}
bounds |= 0x00020001;
bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE);
bounds |= NVDEF(NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, BASE_LUT, USAGE_1025);
}
if ((push = evo_wait(core, 2))) {
evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1);
evo_data(push, bounds);
evo_kick(push, core);
}
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV917D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds);
return 0;
}
int
......@@ -68,10 +78,10 @@ head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
struct nv50_head_atom *asyh)
{
switch (asyw->state.fb->width) {
case 32: asyh->curs.layout = 0; break;
case 64: asyh->curs.layout = 1; break;
case 128: asyh->curs.layout = 2; break;
case 256: asyh->curs.layout = 3; break;
case 32: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W32_H32; break;
case 64: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W64_H64; break;
case 128: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W128_H128; break;
case 256: asyh->curs.layout = NV917D_HEAD_SET_CONTROL_CURSOR_SIZE_W256_H256; break;
default:
return -EINVAL;
}
......
This diff is collapsed.
......@@ -23,83 +23,97 @@
#include "atom.h"
#include "core.h"
static void
#include <nvif/pushc37b.h>
#include <nvhw/class/clc57d.h>
static int
headc57d_or(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
u8 depth;
u32 *push;
if ((push = evo_wait(core, 2))) {
/*XXX: This is a dirty hack until OR depth handling is
* improved later for deep colour etc.
*/
switch (asyh->or.depth) {
case 6: depth = 5; break;
case 5: depth = 4; break;
case 2: depth = 1; break;
case 0: depth = 4; break;
default:
depth = asyh->or.depth;
WARN_ON(1);
break;
}
int ret;
evo_mthd(push, 0x2004 + (head->base.index * 0x400), 1);
evo_data(push, 0xfc000000 |
depth << 4 |
asyh->or.nvsync << 3 |
asyh->or.nhsync << 2 |
asyh->or.crc_raster);
evo_kick(push, core);
/*XXX: This is a dirty hack until OR depth handling is
* improved later for deep colour etc.
*/
switch (asyh->or.depth) {
case 6: depth = 5; break;
case 5: depth = 4; break;
case 2: depth = 1; break;
case 0: depth = 4; break;
default:
depth = asyh->or.depth;
WARN_ON(1);
break;
}
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE(i),
NVVAL(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, CRC_MODE, asyh->or.crc_raster) |
NVVAL(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, HSYNC_POLARITY, asyh->or.nhsync) |
NVVAL(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, VSYNC_POLARITY, asyh->or.nvsync) |
NVVAL(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, PIXEL_DEPTH, depth) |
NVDEF(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, COLOR_SPACE_OVERRIDE, DISABLE) |
NVDEF(NVC57D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, EXT_PACKET_WIN, NONE));
return 0;
}
static void
static int
headc57d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 2))) {
evo_mthd(push, 0x2000 + (head->base.index * 0x400), 1);
#if 0
evo_data(push, 0x80000000 |
asyh->procamp.sat.sin << 16 |
asyh->procamp.sat.cos << 4);
#else
evo_data(push, 0);
#endif
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
//TODO:
PUSH_MTHD(push, NVC57D, HEAD_SET_PROCAMP(i),
NVDEF(NVC57D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) |
NVDEF(NVC57D, HEAD_SET_PROCAMP, CHROMA_LPF, DISABLE) |
NVDEF(NVC57D, HEAD_SET_PROCAMP, DYNAMIC_RANGE, VESA));
return 0;
}
void
static int
headc57d_olut_clr(struct nv50_head *head)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 2))) {
evo_mthd(push, 0x2288 + (head->base.index * 0x400), 1);
evo_data(push, 0x00000000);
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NVC57D, HEAD_SET_CONTEXT_DMA_OLUT(i), 0x00000000);
return 0;
}
void
static int
headc57d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
u32 *push;
if ((push = evo_wait(core, 4))) {
evo_mthd(push, 0x2280 + (head->base.index * 0x400), 4);
evo_data(push, asyh->olut.size << 8 |
asyh->olut.mode << 2 |
asyh->olut.output_mode);
evo_data(push, 0xffffffff); /* FP_NORM_SCALE. */
evo_data(push, asyh->olut.handle);
evo_data(push, asyh->olut.offset >> 8);
evo_kick(push, core);
}
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 5)))
return ret;
PUSH_MTHD(push, NVC57D, HEAD_SET_OLUT_CONTROL(i),
NVVAL(NVC57D, HEAD_SET_OLUT_CONTROL, INTERPOLATE, asyh->olut.output_mode) |
NVDEF(NVC57D, HEAD_SET_OLUT_CONTROL, MIRROR, DISABLE) |
NVVAL(NVC57D, HEAD_SET_OLUT_CONTROL, MODE, asyh->olut.mode) |
NVVAL(NVC57D, HEAD_SET_OLUT_CONTROL, SIZE, asyh->olut.size),
HEAD_SET_OLUT_FP_NORM_SCALE(i), 0xffffffff,
HEAD_SET_CONTEXT_DMA_OLUT(i), asyh->olut.handle,
HEAD_SET_OFFSET_OLUT(i), asyh->olut.offset >> 8);
return 0;
}
static void
......@@ -161,9 +175,9 @@ headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
if (size != 0 && size != 256 && size != 1024)
return false;
asyh->olut.mode = 2; /* DIRECT10 */
asyh->olut.mode = NVC57D_HEAD_SET_OLUT_CONTROL_MODE_DIRECT10;
asyh->olut.size = 4 /* VSS header. */ + 1024 + 1 /* Entries. */;
asyh->olut.output_mode = 1; /* INTERPOLATE_ENABLE. */
asyh->olut.output_mode = NVC57D_HEAD_SET_OLUT_CONTROL_INTERPOLATE_ENABLE;
if (size == 256)
asyh->olut.load = headc57d_olut_load_8;
else
......@@ -171,29 +185,50 @@ headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
return true;
}
static void
static int
headc57d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
{
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
struct nv50_head_mode *m = &asyh->mode;
u32 *push;
if ((push = evo_wait(core, 13))) {
evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5);
evo_data(push, (m->v.active << 16) | m->h.active );
evo_data(push, (m->v.synce << 16) | m->h.synce );
evo_data(push, (m->v.blanke << 16) | m->h.blanke );
evo_data(push, (m->v.blanks << 16) | m->h.blanks );
evo_data(push, (m->v.blank2e << 16) | m->v.blank2s);
evo_mthd(push, 0x2008 + (head->base.index * 0x400), 2);
evo_data(push, m->interlace);
evo_data(push, m->clock * 1000);
evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1);
evo_data(push, m->clock * 1000);
/*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */
evo_mthd(push, 0x2030 + (head->base.index * 0x400), 1);
evo_data(push, 0x00001014);
evo_kick(push, core);
}
const int i = head->base.index;
int ret;
if ((ret = PUSH_WAIT(push, 15)))
return ret;
PUSH_MTHD(push, NVC57D, HEAD_SET_RASTER_SIZE(i),
NVVAL(NVC57D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) |
NVVAL(NVC57D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active),
HEAD_SET_RASTER_SYNC_END(i),
NVVAL(NVC57D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) |
NVVAL(NVC57D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce),
HEAD_SET_RASTER_BLANK_END(i),
NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) |
NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke),
HEAD_SET_RASTER_BLANK_START(i),
NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) |
NVVAL(NVC57D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks));
//XXX:
PUSH_NVSQ(push, NVC57D, 0x2074 + (i * 0x400), m->v.blank2e << 16 | m->v.blank2s);
PUSH_NVSQ(push, NVC57D, 0x2008 + (i * 0x400), m->interlace);
PUSH_MTHD(push, NVC57D, HEAD_SET_PIXEL_CLOCK_FREQUENCY(i),
NVVAL(NVC57D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, m->clock * 1000));
PUSH_MTHD(push, NVC57D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i),
NVVAL(NVC57D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, m->clock * 1000));
/*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */
PUSH_MTHD(push, NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS(i),
NVDEF(NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS, CURSOR, USAGE_W256_H256) |
NVDEF(NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS, OLUT_ALLOWED, TRUE) |
NVDEF(NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS, OUTPUT_SCALER_TAPS, TAPS_2) |
NVDEF(NVC57D, HEAD_SET_HEAD_USAGE_BOUNDS, UPSCALING_ALLOWED, TRUE));
return 0;
}
const struct nv50_head_func
......
......@@ -60,7 +60,7 @@ nv50_lut_fini(struct nv50_lut *lut)
{
int i;
for (i = 0; i < ARRAY_SIZE(lut->mem); i++)
nvif_mem_fini(&lut->mem[i]);
nvif_mem_dtor(&lut->mem[i]);
}
int
......@@ -70,8 +70,8 @@ nv50_lut_init(struct nv50_disp *disp, struct nvif_mmu *mmu,
const u32 size = disp->disp->object.oclass < GF110_DISP ? 257 : 1025;
int i;
for (i = 0; i < ARRAY_SIZE(lut->mem); i++) {
int ret = nvif_mem_init_map(mmu, NVIF_MEM_VRAM, size * 8,
&lut->mem[i]);
int ret = nvif_mem_ctor_map(mmu, "kmsLut", NVIF_MEM_VRAM,
size * 8, &lut->mem[i]);
if (ret)
return ret;
}
......
......@@ -33,8 +33,8 @@ oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
struct nv50_disp *disp = nv50_disp(drm->dev);
int ret;
ret = nvif_object_init(&disp->disp->object, 0, oclass, &args,
sizeof(args), &wndw->wimm.base.user);
ret = nvif_object_ctor(&disp->disp->object, "kmsOvim", 0, oclass,
&args, sizeof(args), &wndw->wimm.base.user);
if (ret) {
NV_ERROR(drm, "oimm%04x allocation failed: %d\n", oclass, ret);
return ret;
......
......@@ -10,11 +10,7 @@ int ovly507e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
void ovly507e_release(struct nv50_wndw *, struct nv50_wndw_atom *,
struct nv50_head_atom *);
void ovly507e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void ovly507e_ntfy_clr(struct nv50_wndw *);
void ovly507e_image_clr(struct nv50_wndw *);
void ovly507e_scale_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void ovly507e_update(struct nv50_wndw *, u32 *);
int ovly507e_scale_set(struct nv50_wndw *, struct nv50_wndw_atom *);
extern const u32 ovly827e_format[];
void ovly827e_ntfy_reset(struct nouveau_bo *, u32);
......
......@@ -28,91 +28,68 @@
#include <nvif/cl507e.h>
#include <nvif/event.h>
#include <nvif/push507c.h>
void
ovly507e_update(struct nv50_wndw *wndw, u32 *interlock)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x0080, 1);
evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]);
evo_kick(push, &wndw->wndw);
}
}
#include <nvhw/class/cl507e.h>
void
int
ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 4))) {
evo_mthd(push, 0x00e0, 3);
evo_data(push, asyw->scale.sy << 16 | asyw->scale.sx);
evo_data(push, asyw->scale.sh << 16 | asyw->scale.sw);
evo_data(push, asyw->scale.dw);
evo_kick(push, &wndw->wndw);
}
}
struct nvif_push *push = wndw->wndw.push;
int ret;
void
ovly507e_image_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 4))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, 0x00000000);
evo_mthd(push, 0x00c0, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
if ((ret = PUSH_WAIT(push, 4)))
return ret;
PUSH_MTHD(push, NV507E, SET_POINT_IN,
NVVAL(NV507E, SET_POINT_IN, X, asyw->scale.sx) |
NVVAL(NV507E, SET_POINT_IN, Y, asyw->scale.sy),
SET_SIZE_IN,
NVVAL(NV507E, SET_SIZE_IN, WIDTH, asyw->scale.sw) |
NVVAL(NV507E, SET_SIZE_IN, HEIGHT, asyw->scale.sh),
SET_SIZE_OUT,
NVVAL(NV507E, SET_SIZE_OUT, WIDTH, asyw->scale.dw));
return 0;
}
static void
static int
ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 12))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.interval << 4);
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]);
evo_mthd(push, 0x0100, 1);
evo_data(push, 0x00000002);
evo_mthd(push, 0x0800, 1);
evo_data(push, asyw->image.offset[0] >> 8);
evo_mthd(push, 0x0808, 3);
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 20 |
(asyw->image.pitch[0] >> 8) << 8 |
asyw->image.blocks[0] << 8 |
asyw->image.blockh);
evo_data(push, asyw->image.kind << 16 |
asyw->image.format << 8 |
asyw->image.colorspace);
evo_kick(push, &wndw->wndw);
}
}
struct nvif_push *push = wndw->wndw.push;
int ret;
void
ovly507e_ntfy_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x00a4, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
}
if ((ret = PUSH_WAIT(push, 12)))
return ret;
void
ovly507e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 3))) {
evo_mthd(push, 0x00a0, 2);
evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset);
evo_data(push, asyw->ntfy.handle);
evo_kick(push, &wndw->wndw);
}
PUSH_MTHD(push, NV507E, SET_PRESENT_CONTROL,
NVDEF(NV507E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
NVVAL(NV507E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
PUSH_MTHD(push, NV507E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
PUSH_MTHD(push, NV507E, SET_COMPOSITION_CONTROL,
NVDEF(NV507E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE));
PUSH_MTHD(push, NV507E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8);
PUSH_MTHD(push, NV507E, SURFACE_SET_SIZE,
NVVAL(NV507E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
NVVAL(NV507E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
SURFACE_SET_STORAGE,
NVVAL(NV507E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) |
NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
NVVAL(NV507E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
SURFACE_SET_PARAMS,
NVVAL(NV507E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
NVVAL(NV507E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace) |
NVVAL(NV507E, SURFACE_SET_PARAMS, KIND, asyw->image.kind) |
NVDEF(NV507E, SURFACE_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256));
return 0;
}
void
......@@ -146,14 +123,14 @@ static const struct nv50_wndw_func
ovly507e = {
.acquire = ovly507e_acquire,
.release = ovly507e_release,
.ntfy_set = ovly507e_ntfy_set,
.ntfy_clr = ovly507e_ntfy_clr,
.ntfy_set = base507c_ntfy_set,
.ntfy_clr = base507c_ntfy_clr,
.ntfy_reset = base507c_ntfy_reset,
.ntfy_wait_begun = base507c_ntfy_wait_begun,
.image_set = ovly507e_image_set,
.image_clr = ovly507e_image_clr,
.image_clr = base507c_image_clr,
.scale_set = ovly507e_scale_set,
.update = ovly507e_update,
.update = base507c_update,
};
static const u32
......@@ -192,7 +169,8 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
return ret;
}
ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, false,
ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsOvlyNtfy",
wndw->notify.func, false,
NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT,
&(struct nvif_notify_uevent_req) {},
sizeof(struct nvif_notify_uevent_req),
......
......@@ -24,31 +24,45 @@
#include <nouveau_bo.h>
#include <nvif/push507c.h>
#include <nvif/timer.h>
static void
#include <nvhw/class/cl827e.h>
static int
ovly827e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 12))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.interval << 4);
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]);
evo_mthd(push, 0x0100, 1);
evo_data(push, 0x00000002);
evo_mthd(push, 0x0800, 1);
evo_data(push, asyw->image.offset[0] >> 8);
evo_mthd(push, 0x0808, 3);
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 20 |
(asyw->image.pitch[0] >> 8) << 8 |
asyw->image.blocks[0] << 8 |
asyw->image.blockh);
evo_data(push, asyw->image.format << 8 |
asyw->image.colorspace);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 12)))
return ret;
PUSH_MTHD(push, NV827E, SET_PRESENT_CONTROL,
NVDEF(NV827E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
NVVAL(NV827E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
PUSH_MTHD(push, NV827E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
PUSH_MTHD(push, NV827E, SET_COMPOSITION_CONTROL,
NVDEF(NV827E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE));
PUSH_MTHD(push, NV827E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8);
PUSH_MTHD(push, NV827E, SURFACE_SET_SIZE,
NVVAL(NV827E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
NVVAL(NV827E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
SURFACE_SET_STORAGE,
NVVAL(NV827E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
NVVAL(NV827E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) |
NVVAL(NV827E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
NVVAL(NV827E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
SURFACE_SET_PARAMS,
NVVAL(NV827E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
NVVAL(NV827E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace));
return 0;
}
int
......@@ -56,8 +70,7 @@ ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
struct nvif_device *device)
{
s64 time = nvif_msec(device, 2000ULL,
u32 data = nouveau_bo_rd32(bo, offset / 4 + 3);
if ((data & 0xffff0000) == 0xffff0000)
if (NVBO_TD32(bo, offset, NV_DISP_NOTIFICATION_1, _3, STATUS, ==, BEGUN))
break;
usleep_range(1, 2);
);
......@@ -67,24 +80,25 @@ ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
void
ovly827e_ntfy_reset(struct nouveau_bo *bo, u32 offset)
{
nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000);
nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000);
nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000);
nouveau_bo_wr32(bo, offset / 4 + 3, 0x80000000);
NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, TIME_STAMP_0, 0);
NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, TIME_STAMP_1, 0);
NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, _2, 0);
NVBO_WR32(bo, offset, NV_DISP_NOTIFICATION_1, _3,
NVDEF(NV_DISP_NOTIFICATION_1, _3, STATUS, NOT_BEGUN));
}
static const struct nv50_wndw_func
ovly827e = {
.acquire = ovly507e_acquire,
.release = ovly507e_release,
.ntfy_set = ovly507e_ntfy_set,
.ntfy_clr = ovly507e_ntfy_clr,
.ntfy_set = base507c_ntfy_set,
.ntfy_clr = base507c_ntfy_clr,
.ntfy_reset = ovly827e_ntfy_reset,
.ntfy_wait_begun = ovly827e_ntfy_wait_begun,
.image_set = ovly827e_image_set,
.image_clr = ovly507e_image_clr,
.image_clr = base507c_image_clr,
.scale_set = ovly507e_scale_set,
.update = ovly507e_update,
.update = base507c_update,
};
const u32
......
......@@ -22,43 +22,58 @@
#include "ovly.h"
#include "atom.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl907e.h>
static int
ovly907e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 12))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.interval << 4);
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle[0]);
evo_mthd(push, 0x0100, 1);
evo_data(push, 0x00000002);
evo_mthd(push, 0x0400, 1);
evo_data(push, asyw->image.offset[0] >> 8);
evo_mthd(push, 0x0408, 3);
evo_data(push, asyw->image.h << 16 | asyw->image.w);
evo_data(push, asyw->image.layout << 24 |
(asyw->image.pitch[0] >> 8) << 8 |
asyw->image.blocks[0] << 8 |
asyw->image.blockh);
evo_data(push, asyw->image.format << 8 |
asyw->image.colorspace);
evo_kick(push, &wndw->wndw);
}
struct nvif_push *push = wndw->wndw.push;
int ret;
if ((ret = PUSH_WAIT(push, 12)))
return ret;
PUSH_MTHD(push, NV907E, SET_PRESENT_CONTROL,
NVDEF(NV907E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
NVVAL(NV907E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
PUSH_MTHD(push, NV907E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
PUSH_MTHD(push, NV907E, SET_COMPOSITION_CONTROL,
NVDEF(NV907E, SET_COMPOSITION_CONTROL, MODE, OPAQUE));
PUSH_MTHD(push, NV907E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8);
PUSH_MTHD(push, NV907E, SURFACE_SET_SIZE,
NVVAL(NV907E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
NVVAL(NV907E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
SURFACE_SET_STORAGE,
NVVAL(NV907E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
NVVAL(NV907E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) |
NVVAL(NV907E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
NVVAL(NV907E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
SURFACE_SET_PARAMS,
NVVAL(NV907E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
NVVAL(NV907E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace));
return 0;
}
const struct nv50_wndw_func
ovly907e = {
.acquire = ovly507e_acquire,
.release = ovly507e_release,
.ntfy_set = ovly507e_ntfy_set,
.ntfy_clr = ovly507e_ntfy_clr,
.ntfy_set = base507c_ntfy_set,
.ntfy_clr = base507c_ntfy_clr,
.ntfy_reset = ovly827e_ntfy_reset,
.ntfy_wait_begun = ovly827e_ntfy_wait_begun,
.image_set = ovly907e_image_set,
.image_clr = ovly507e_image_clr,
.image_clr = base507c_image_clr,
.scale_set = ovly507e_scale_set,
.update = ovly507e_update,
.update = base507c_update,
};
static const u32
......
......@@ -21,21 +21,29 @@
*/
#include "core.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl507d.h>
#include <nvhw/class/cl837d.h>
static int
pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh)
{
u32 *push;
if ((push = evo_wait(&core->chan, 2))) {
if (asyh) {
ctrl |= asyh->or.depth << 16;
ctrl |= asyh->or.nvsync << 13;
ctrl |= asyh->or.nhsync << 12;
}
evo_mthd(push, 0x0700 + (or * 0x040), 1);
evo_data(push, ctrl);
evo_kick(push, &core->chan);
struct nvif_push *push = core->chan.push;
int ret;
if (asyh) {
ctrl |= NVVAL(NV507D, PIOR_SET_CONTROL, HSYNC_POLARITY, asyh->or.nhsync);
ctrl |= NVVAL(NV507D, PIOR_SET_CONTROL, VSYNC_POLARITY, asyh->or.nvsync);
ctrl |= NVVAL(NV837D, PIOR_SET_CONTROL, PIXEL_DEPTH, asyh->or.depth);
}
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507D, PIOR_SET_CONTROL(or), ctrl);
return 0;
}
static void
......
......@@ -21,21 +21,29 @@
*/
#include "core.h"
static void
#include <nvif/push507c.h>
#include <nvhw/class/cl507d.h>
#include <nvhw/class/cl837d.h>
static int
sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh)
{
u32 *push;
if ((push = evo_wait(&core->chan, 2))) {
if (asyh) {
ctrl |= asyh->or.depth << 16;
ctrl |= asyh->or.nvsync << 13;
ctrl |= asyh->or.nhsync << 12;
}
evo_mthd(push, 0x0600 + (or * 0x40), 1);
evo_data(push, ctrl);
evo_kick(push, &core->chan);
struct nvif_push *push = core->chan.push;
int ret;
if (asyh) {
ctrl |= NVVAL(NV507D, SOR_SET_CONTROL, HSYNC_POLARITY, asyh->or.nhsync);
ctrl |= NVVAL(NV507D, SOR_SET_CONTROL, VSYNC_POLARITY, asyh->or.nvsync);
ctrl |= NVVAL(NV837D, SOR_SET_CONTROL, PIXEL_DEPTH, asyh->or.depth);
}
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV507D, SOR_SET_CONTROL(or), ctrl);
return 0;
}
static void
......
......@@ -21,28 +21,34 @@
*/
#include "core.h"
#include <nouveau_bo.h>
#include <nvif/class.h>
#include <nvif/push507c.h>
static void
#include <nvhw/class/cl907d.h>
#include <nouveau_bo.h>
static int
sor907d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh)
{
u32 *push;
if ((push = evo_wait(&core->chan, 2))) {
evo_mthd(push, 0x0200 + (or * 0x20), 1);
evo_data(push, ctrl);
evo_kick(push, &core->chan);
}
struct nvif_push *push = core->chan.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NV907D, SOR_SET_CONTROL(or), ctrl);
return 0;
}
static void
sor907d_get_caps(struct nv50_disp *disp, struct nouveau_encoder *outp, int or)
{
struct nouveau_bo *bo = disp->sync;
const int off = or * 2;
u32 tmp = nouveau_bo_rd32(disp->sync, 0x000014 + off);
outp->caps.dp_interlace = !!(tmp & 0x04000000);
outp->caps.dp_interlace =
NVBO_RV32(bo, off, NV907D_CORE_NOTIFIER_3, CAPABILITIES_CAP_SOR0_20, DP_INTERLACE);
}
const struct nv50_outp_func
......
......@@ -21,16 +21,22 @@
*/
#include "core.h"
static void
#include <nvif/pushc37b.h>
#include <nvhw/class/clc37d.h>
static int
sorc37d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh)
{
u32 *push;
if ((push = evo_wait(&core->chan, 2))) {
evo_mthd(push, 0x0300 + (or * 0x20), 1);
evo_data(push, ctrl);
evo_kick(push, &core->chan);
}
struct nvif_push *push = core->chan.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NVC37D, SOR_SET_CONTROL(or), ctrl);
return 0;
}
static void
......
......@@ -24,30 +24,38 @@
#include "wndw.h"
#include <nvif/clc37b.h>
#include <nvif/pushc37b.h>
static void
#include <nvhw/class/clc37b.h>
static int
wimmc37b_update(struct nv50_wndw *wndw, u32 *interlock)
{
u32 *push;
if ((push = evo_wait(&wndw->wimm, 2))) {
evo_mthd(push, 0x0200, 1);
if (interlock[NV50_DISP_INTERLOCK_WNDW] & wndw->interlock.data)
evo_data(push, 0x00000003);
else
evo_data(push, 0x00000001);
evo_kick(push, &wndw->wimm);
}
struct nvif_push *push = wndw->wimm.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NVC37B, UPDATE, 0x00000001 |
NVVAL(NVC37B, UPDATE, INTERLOCK_WITH_WINDOW,
!!(interlock[NV50_DISP_INTERLOCK_WNDW] & wndw->interlock.data)));
return PUSH_KICK(push);
}
static void
static int
wimmc37b_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wimm, 2))) {
evo_mthd(push, 0x0208, 1);
evo_data(push, asyw->point.y << 16 | asyw->point.x);
evo_kick(push, &wndw->wimm);
}
struct nvif_push *push = wndw->wimm.push;
int ret;
if ((ret = PUSH_WAIT(push, 2)))
return ret;
PUSH_MTHD(push, NVC37B, SET_POINT_OUT(0),
NVVAL(NVC37B, SET_POINT_OUT, X, asyw->point.x) |
NVVAL(NVC37B, SET_POINT_OUT, Y, asyw->point.y));
return 0;
}
static const struct nv50_wimm_func
......
......@@ -26,6 +26,10 @@
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvhw/class/cl507c.h>
#include <nvhw/class/cl507e.h>
#include <nvhw/class/clc37e.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_fourcc.h>
......@@ -35,7 +39,7 @@
static void
nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma)
{
nvif_object_fini(&ctxdma->object);
nvif_object_dtor(&ctxdma->object);
list_del(&ctxdma->head);
kfree(ctxdma);
}
......@@ -94,8 +98,8 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb)
argc += sizeof(args.gf119);
}
ret = nvif_object_init(wndw->ctxdma.parent, handle, NV_DMA_IN_MEMORY,
&args, argc, &ctxdma->object);
ret = nvif_object_ctor(wndw->ctxdma.parent, "kmsFbCtxDma", handle,
NV_DMA_IN_MEMORY, &args, argc, &ctxdma->object);
if (ret) {
nv50_wndw_ctxdma_del(ctxdma);
return ERR_PTR(ret);
......@@ -137,7 +141,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
struct nv50_wndw_atom *asyw)
{
if (interlock[NV50_DISP_INTERLOCK_CORE]) {
asyw->image.mode = 0;
asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_NON_TEARING;
asyw->image.interval = 1;
}
......@@ -201,13 +205,18 @@ static int
nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw)
{
switch (asyw->state.fb->format->format) {
case DRM_FORMAT_YUYV: asyw->image.format = 0x28; break;
case DRM_FORMAT_UYVY: asyw->image.format = 0x29; break;
case DRM_FORMAT_YUYV:
asyw->image.format = NV507E_SURFACE_SET_PARAMS_FORMAT_VE8YO8UE8YE8;
break;
case DRM_FORMAT_UYVY:
asyw->image.format = NV507E_SURFACE_SET_PARAMS_FORMAT_YO8VE8YE8UE8;
break;
default:
WARN_ON(1);
return -EINVAL;
}
asyw->image.colorspace = 1;
asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_YUV_601;
return 0;
}
......@@ -215,24 +224,41 @@ static int
nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
{
switch (asyw->state.fb->format->format) {
case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break;
case DRM_FORMAT_XRGB8888 :
case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break;
case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break;
case DRM_FORMAT_XRGB1555 :
case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break;
case DRM_FORMAT_XBGR2101010 :
case DRM_FORMAT_ABGR2101010 : asyw->image.format = 0xd1; break;
case DRM_FORMAT_XBGR8888 :
case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break;
case DRM_FORMAT_XRGB2101010 :
case DRM_FORMAT_ARGB2101010 : asyw->image.format = 0xdf; break;
case DRM_FORMAT_C8:
asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_I8;
break;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A8R8G8B8;
break;
case DRM_FORMAT_RGB565:
asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_R5G6B5;
break;
case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_ARGB1555:
asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A1R5G5B5;
break;
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ABGR2101010:
asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A2B10G10R10;
break;
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ABGR8888:
asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A8B8G8R8;
break;
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_ARGB2101010:
asyw->image.format = NVC37E_SET_PARAMS_FORMAT_A2R10G10B10;
break;
case DRM_FORMAT_XBGR16161616F:
case DRM_FORMAT_ABGR16161616F: asyw->image.format = 0xca; break;
case DRM_FORMAT_ABGR16161616F:
asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16;
break;
default:
return -EINVAL;
}
asyw->image.colorspace = 0;
asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_RGB;
return 0;
}
......@@ -265,7 +291,7 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
}
if (asyw->image.kind) {
asyw->image.layout = 0;
asyw->image.layout = NV507C_SURFACE_SET_STORAGE_MEMORY_LAYOUT_BLOCKLINEAR;
if (drm->client.device.info.chipset >= 0xc0)
asyw->image.blockh = tile_mode >> 4;
else
......@@ -273,8 +299,8 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
asyw->image.blocks[0] = fb->pitches[0] / 64;
asyw->image.pitch[0] = 0;
} else {
asyw->image.layout = 1;
asyw->image.blockh = 0;
asyw->image.layout = NV507C_SURFACE_SET_STORAGE_MEMORY_LAYOUT_PITCH;
asyw->image.blockh = NV507C_SURFACE_SET_STORAGE_BLOCK_HEIGHT_ONE_GOB;
asyw->image.blocks[0] = 0;
asyw->image.pitch[0] = fb->pitches[0];
}
......@@ -283,7 +309,12 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
asyw->image.interval = 1;
else
asyw->image.interval = 0;
asyw->image.mode = asyw->image.interval ? 0 : 1;
if (asyw->image.interval)
asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_NON_TEARING;
else
asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_IMMEDIATE;
asyw->set.image = wndw->func->image_set != NULL;
}
......@@ -303,17 +334,17 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
asyw->blend.k1 = asyw->state.alpha >> 8;
switch (asyw->state.pixel_blend_mode) {
case DRM_MODE_BLEND_PREMULTI:
asyw->blend.src_color = 2; /* K1 */
asyw->blend.dst_color = 7; /* NEG_K1_TIMES_SRC */
asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1;
asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1_TIMES_SRC;
break;
case DRM_MODE_BLEND_COVERAGE:
asyw->blend.src_color = 5; /* K1_TIMES_SRC */
asyw->blend.dst_color = 7; /* NEG_K1_TIMES_SRC */
asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1_TIMES_SRC;
asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1_TIMES_SRC;
break;
case DRM_MODE_BLEND_PIXEL_NONE:
default:
asyw->blend.src_color = 2; /* K1 */
asyw->blend.dst_color = 4; /* NEG_K1 */
asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1;
asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1;
break;
}
if (memcmp(&armw->blend, &asyw->blend, sizeof(asyw->blend)))
......@@ -609,7 +640,7 @@ nv50_wndw_destroy(struct drm_plane *plane)
nv50_wndw_ctxdma_del(ctxdma);
}
nvif_notify_fini(&wndw->notify);
nvif_notify_dtor(&wndw->notify);
nv50_dmac_destroy(&wndw->wimm);
nv50_dmac_destroy(&wndw->wndw);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -25,7 +25,7 @@ struct nv_pmu_args {
#define NV_PMU_UNIT_ACR 0x0a
struct nv_pmu_init_msg {
struct nv_falcon_msg hdr;
struct nvfw_falcon_msg hdr;
#define NV_PMU_INIT_MSG_INIT 0x00
u8 msg_type;
......@@ -44,7 +44,7 @@ struct nv_pmu_init_msg {
};
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_BOOTSTRAP_FALCON 0x01
#define NV_PMU_ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS 0x03
......@@ -52,7 +52,7 @@ struct nv_pmu_acr_cmd {
};
struct nv_pmu_acr_msg {
struct nv_falcon_cmd hdr;
struct nvfw_falcon_cmd hdr;
u8 msg_type;
};
......
......@@ -13,7 +13,7 @@ struct nv_sec2_args {
#define NV_SEC2_UNIT_ACR 0x08
struct nv_sec2_init_msg {
struct nv_falcon_msg hdr;
struct nvfw_falcon_msg hdr;
#define NV_SEC2_INIT_MSG_INIT 0x00
u8 msg_type;
......@@ -34,13 +34,13 @@ struct nv_sec2_init_msg {
};
struct nv_sec2_acr_cmd {
struct nv_falcon_cmd hdr;
struct nvfw_falcon_cmd hdr;
#define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON 0x00
u8 cmd_type;
};
struct nv_sec2_acr_msg {
struct nv_falcon_cmd hdr;
struct nvfw_falcon_cmd hdr;
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