From: Ben Skeggs Date: Thu, 8 Nov 2012 23:22:31 +0000 (+1000) Subject: drm/nv50/disp: allocate display from driver core X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=2d0aca211994241c36f2bcfff7141e708f66b005;p=linux-beck.git drm/nv50/disp: allocate display from driver core EVO channels still handled "manually", this won't be ported here, and will instead be held off until nv50_display/nvd0_display are merged. Signed-off-by: Ben Skeggs --- diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 9c849e5347dd..04755561d8bd 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -36,6 +36,8 @@ #include "nouveau_fence.h" #include +#include + #include static void nv50_display_bh(unsigned long); @@ -120,43 +122,6 @@ nv50_display_init(struct drm_device *dev) struct nouveau_device *device = nouveau_dev(dev); struct nouveau_channel *evo; int ret, i; - u32 val; - - nv_wr32(device, 0x00610184, nv_rd32(device, 0x00614004)); - - /* - * I think the 0x006101XX range is some kind of main control area - * that enables things. - */ - /* CRTC? */ - for (i = 0; i < 2; i++) { - val = nv_rd32(device, 0x00616100 + (i * 0x800)); - nv_wr32(device, 0x00610190 + (i * 0x10), val); - val = nv_rd32(device, 0x00616104 + (i * 0x800)); - nv_wr32(device, 0x00610194 + (i * 0x10), val); - val = nv_rd32(device, 0x00616108 + (i * 0x800)); - nv_wr32(device, 0x00610198 + (i * 0x10), val); - val = nv_rd32(device, 0x0061610c + (i * 0x800)); - nv_wr32(device, 0x0061019c + (i * 0x10), val); - } - - /* DAC */ - for (i = 0; i < 3; i++) { - val = nv_rd32(device, 0x0061a000 + (i * 0x800)); - nv_wr32(device, 0x006101d0 + (i * 0x04), val); - } - - /* SOR */ - for (i = 0; i < nv50_sor_nr(dev); i++) { - val = nv_rd32(device, 0x0061c000 + (i * 0x800)); - nv_wr32(device, 0x006101e0 + (i * 0x04), val); - } - - /* EXT */ - for (i = 0; i < 3; i++) { - val = nv_rd32(device, 0x0061e000 + (i * 0x800)); - nv_wr32(device, 0x006101f0 + (i * 0x04), val); - } for (i = 0; i < 3; i++) { nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 | @@ -164,20 +129,6 @@ nv50_display_init(struct drm_device *dev) nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001); } - /* The precise purpose is unknown, i suspect it has something to do - * with text mode. - */ - if (nv_rd32(device, NV50_PDISPLAY_INTR_1) & 0x100) { - nv_wr32(device, NV50_PDISPLAY_INTR_1, 0x100); - nv_wr32(device, 0x006194e8, nv_rd32(device, 0x006194e8) & ~1); - if (!nv_wait(device, 0x006194e8, 2, 0)) { - NV_ERROR(drm, "timeout: (0x6194e8 & 2) != 0\n"); - NV_ERROR(drm, "0x6194e8 = 0x%08x\n", - nv_rd32(device, 0x6194e8)); - return -EBUSY; - } - } - for (i = 0; i < 2; i++) { nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000); if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), @@ -201,22 +152,11 @@ nv50_display_init(struct drm_device *dev) } } - nv_wr32(device, NV50_PDISPLAY_PIO_CTRL, 0x00000000); - nv_mask(device, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000); - nv_wr32(device, NV50_PDISPLAY_INTR_EN_0, 0x00000000); - nv_mask(device, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000); - nv_wr32(device, NV50_PDISPLAY_INTR_EN_1, - NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 | - NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 | - NV50_PDISPLAY_INTR_EN_1_CLK_UNK40); - ret = nv50_evo_init(dev); if (ret) return ret; evo = nv50_display(dev)->master; - nv_wr32(device, NV50_PDISPLAY_OBJECTS, (nv50_display(dev)->ramin->addr >> 8) | 9); - ret = RING_SPACE(evo, 3); if (ret) return ret; @@ -289,14 +229,18 @@ nv50_display_fini(struct drm_device *dev) nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_STATE(i))); } } - - /* disable interrupts. */ - nv_wr32(device, NV50_PDISPLAY_INTR_EN_1, 0x00000000); } int nv50_display_create(struct drm_device *dev) { + static const u16 oclass[] = { + NVA3_DISP_CLASS, + NV94_DISP_CLASS, + NVA0_DISP_CLASS, + NV84_DISP_CLASS, + NV50_DISP_CLASS, + }; struct nouveau_drm *drm = nouveau_drm(dev); struct dcb_table *dcb = &drm->vbios.dcb; struct drm_connector *connector, *ct; @@ -312,6 +256,17 @@ nv50_display_create(struct drm_device *dev) nouveau_display(dev)->init = nv50_display_init; nouveau_display(dev)->fini = nv50_display_fini; + /* attempt to allocate a supported evo display class */ + ret = -ENODEV; + for (i = 0; ret && i < ARRAY_SIZE(oclass); i++) { + ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, + 0xd1500000, oclass[i], NULL, 0, + &priv->core); + } + + if (ret) + return ret; + /* Create CRTC objects */ for (i = 0; i < 2; i++) { ret = nv50_crtc_create(dev, i); diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 40aa6737adeb..13363110d57f 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -44,6 +44,7 @@ struct nv50_display_crtc { struct nv50_display { struct nouveau_channel *master; + struct nouveau_object *core; struct nouveau_gpuobj *ramin; u32 dmao; u32 hash; diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c index 48d08d865318..2fd043ec0fb3 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.c +++ b/drivers/gpu/drm/nouveau/nv50_evo.c @@ -245,7 +245,6 @@ nv50_evo_destroy(struct drm_device *dev) nv50_evo_channel_del(&disp->crtc[i].sync); } nv50_evo_channel_del(&disp->master); - nouveau_gpuobj_ref(NULL, &disp->ramin); } int @@ -261,13 +260,7 @@ nv50_evo_create(struct drm_device *dev) * use this also as there's no per-channel support on the * hardware */ - ret = nouveau_gpuobj_new(drm->device, NULL, 32768, 65536, - NVOBJ_FLAG_ZERO_ALLOC, &disp->ramin); - if (ret) { - NV_ERROR(drm, "Error allocating EVO channel memory: %d\n", ret); - goto err; - } - + disp->ramin = nv_gpuobj(disp->core->parent); disp->hash = 0x0000; disp->dmao = 0x1000;