Commit 6d86951a authored by Ben Skeggs's avatar Ben Skeggs

drm/nvc0: initial support for tiled buffer objects

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent ddbaf79a
...@@ -120,9 +120,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, ...@@ -120,9 +120,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
align >>= PAGE_SHIFT; align >>= PAGE_SHIFT;
if (!nvbo->no_vm && dev_priv->chan_vm) { if (!nvbo->no_vm && dev_priv->chan_vm) {
if (dev_priv->card_type == NV_C0)
page_shift = 12;
ret = nouveau_vm_get(dev_priv->chan_vm, size, page_shift, ret = nouveau_vm_get(dev_priv->chan_vm, size, page_shift,
NV_MEM_ACCESS_RW, &nvbo->vma); NV_MEM_ACCESS_RW, &nvbo->vma);
if (ret) { if (ret) {
......
...@@ -77,7 +77,8 @@ enum { ...@@ -77,7 +77,8 @@ enum {
/* G80+ display objects */ /* G80+ display objects */
NvEvoVRAM = 0x01000000, NvEvoVRAM = 0x01000000,
NvEvoFB16 = 0x01000001, NvEvoFB16 = 0x01000001,
NvEvoFB32 = 0x01000002 NvEvoFB32 = 0x01000002,
NvEvoVRAM_LP = 0x01000003
}; };
#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 #define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039
......
...@@ -115,15 +115,16 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) ...@@ -115,15 +115,16 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
OUT_RING(evo, 0); OUT_RING(evo, 0);
BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1); BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
if (dev_priv->chipset != 0x50) if (dev_priv->chipset != 0x50)
if (nv_crtc->fb.tile_flags == 0x7a00) if (nv_crtc->fb.tile_flags == 0x7a00 ||
nv_crtc->fb.tile_flags == 0xfe00)
OUT_RING(evo, NvEvoFB32); OUT_RING(evo, NvEvoFB32);
else else
if (nv_crtc->fb.tile_flags == 0x7000) if (nv_crtc->fb.tile_flags == 0x7000)
OUT_RING(evo, NvEvoFB16); OUT_RING(evo, NvEvoFB16);
else else
OUT_RING(evo, NvEvoVRAM); OUT_RING(evo, NvEvoVRAM_LP);
else else
OUT_RING(evo, NvEvoVRAM); OUT_RING(evo, NvEvoVRAM_LP);
} }
nv_crtc->fb.blanked = blanked; nv_crtc->fb.blanked = blanked;
...@@ -555,13 +556,14 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, ...@@ -555,13 +556,14 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
return ret; return ret;
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
if (nv_crtc->fb.tile_flags == 0x7a00) if (nv_crtc->fb.tile_flags == 0x7a00 ||
nv_crtc->fb.tile_flags == 0xfe00)
OUT_RING(evo, NvEvoFB32); OUT_RING(evo, NvEvoFB32);
else else
if (nv_crtc->fb.tile_flags == 0x7000) if (nv_crtc->fb.tile_flags == 0x7000)
OUT_RING(evo, NvEvoFB16); OUT_RING(evo, NvEvoFB16);
else else
OUT_RING(evo, NvEvoVRAM); OUT_RING(evo, NvEvoVRAM_LP);
} }
ret = RING_SPACE(evo, 12); ret = RING_SPACE(evo, 12);
...@@ -575,8 +577,10 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, ...@@ -575,8 +577,10 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
if (!nv_crtc->fb.tile_flags) { if (!nv_crtc->fb.tile_flags) {
OUT_RING(evo, drm_fb->pitch | (1 << 20)); OUT_RING(evo, drm_fb->pitch | (1 << 20));
} else { } else {
OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | u32 tile_mode = fb->nvbo->tile_mode;
fb->nvbo->tile_mode); if (dev_priv->card_type >= NV_C0)
tile_mode >>= 4;
OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode);
} }
if (dev_priv->chipset == 0x50) if (dev_priv->chipset == 0x50)
OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format); OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
......
...@@ -53,7 +53,8 @@ nv50_evo_channel_del(struct nouveau_channel **pevo) ...@@ -53,7 +53,8 @@ nv50_evo_channel_del(struct nouveau_channel **pevo)
int int
nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name, nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name,
u32 tile_flags, u32 magic_flags, u32 offset, u32 limit) u32 tile_flags, u32 magic_flags, u32 offset, u32 limit,
u32 flags5)
{ {
struct drm_nouveau_private *dev_priv = evo->dev->dev_private; struct drm_nouveau_private *dev_priv = evo->dev->dev_private;
struct drm_device *dev = evo->dev; struct drm_device *dev = evo->dev;
...@@ -70,10 +71,7 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name, ...@@ -70,10 +71,7 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name,
nv_wo32(obj, 8, offset); nv_wo32(obj, 8, offset);
nv_wo32(obj, 12, 0x00000000); nv_wo32(obj, 12, 0x00000000);
nv_wo32(obj, 16, 0x00000000); nv_wo32(obj, 16, 0x00000000);
if (dev_priv->card_type < NV_C0) nv_wo32(obj, 20, flags5);
nv_wo32(obj, 20, 0x00010000);
else
nv_wo32(obj, 20, 0x00020000);
dev_priv->engine.instmem.flush(dev); dev_priv->engine.instmem.flush(dev);
ret = nouveau_ramht_insert(evo, name, obj); ret = nouveau_ramht_insert(evo, name, obj);
...@@ -264,9 +262,31 @@ nv50_evo_create(struct drm_device *dev) ...@@ -264,9 +262,31 @@ nv50_evo_create(struct drm_device *dev)
} }
/* create some default objects for the scanout memtypes we support */ /* create some default objects for the scanout memtypes we support */
if (dev_priv->card_type >= NV_C0) {
ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0xfe, 0x19,
0, 0xffffffff, 0x00000000);
if (ret) {
nv50_evo_channel_del(&dev_priv->evo);
return ret;
}
ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19,
0, dev_priv->vram_size, 0x00020000);
if (ret) {
nv50_evo_channel_del(&dev_priv->evo);
return ret;
}
ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19,
0, dev_priv->vram_size, 0x00000000);
if (ret) {
nv50_evo_channel_del(&dev_priv->evo);
return ret;
}
} else
if (dev_priv->chipset != 0x50) { if (dev_priv->chipset != 0x50) {
ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19, ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19,
0, 0xffffffff); 0, 0xffffffff, 0x00010000);
if (ret) { if (ret) {
nv50_evo_channel_del(&dev_priv->evo); nv50_evo_channel_del(&dev_priv->evo);
return ret; return ret;
...@@ -274,20 +294,27 @@ nv50_evo_create(struct drm_device *dev) ...@@ -274,20 +294,27 @@ nv50_evo_create(struct drm_device *dev)
ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0x7a, 0x19, ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0x7a, 0x19,
0, 0xffffffff); 0, 0xffffffff, 0x00010000);
if (ret) { if (ret) {
nv50_evo_channel_del(&dev_priv->evo); nv50_evo_channel_del(&dev_priv->evo);
return ret; return ret;
} }
}
ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19, ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19,
0, dev_priv->vram_size); 0, dev_priv->vram_size, 0x00010000);
if (ret) { if (ret) {
nv50_evo_channel_del(&dev_priv->evo); nv50_evo_channel_del(&dev_priv->evo);
return ret; return ret;
} }
ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19,
0, dev_priv->vram_size, 0x00010000);
if (ret) {
nv50_evo_channel_del(&dev_priv->evo);
return ret;
}
}
return 0; return 0;
} }
......
...@@ -29,8 +29,16 @@ ...@@ -29,8 +29,16 @@
bool bool
nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags) nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
{ {
if (likely(!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))) switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) {
case 0x0000:
case 0xfe00:
case 0xdb00:
case 0x1100:
return true; return true;
default:
break;
}
return false; return false;
} }
......
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