aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_fb.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-02-13 18:57:35 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-02-24 15:46:07 -0500
commit8f7286f8e4e80f7b868ba3d117ae900f0d207cbe (patch)
tree018804469b7bce4033b4156442c904512282fab2 /drivers/gpu/drm/nouveau/nv50_fb.c
parent26c0c9e33a2eb44b345d22d5928d5c8b7b261226 (diff)
drm/nv50: support for compression
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_fb.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fb.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c
index 50290dea0ac4..ed411d88451d 100644
--- a/drivers/gpu/drm/nouveau/nv50_fb.c
+++ b/drivers/gpu/drm/nouveau/nv50_fb.c
@@ -8,31 +8,61 @@ struct nv50_fb_priv {
8 dma_addr_t r100c08; 8 dma_addr_t r100c08;
9}; 9};
10 10
11static void
12nv50_fb_destroy(struct drm_device *dev)
13{
14 struct drm_nouveau_private *dev_priv = dev->dev_private;
15 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
16 struct nv50_fb_priv *priv = pfb->priv;
17
18 if (drm_mm_initialized(&pfb->tag_heap))
19 drm_mm_takedown(&pfb->tag_heap);
20
21 if (priv->r100c08_page) {
22 pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE,
23 PCI_DMA_BIDIRECTIONAL);
24 __free_page(priv->r100c08_page);
25 }
26
27 kfree(priv);
28 pfb->priv = NULL;
29}
30
11static int 31static int
12nv50_fb_create(struct drm_device *dev) 32nv50_fb_create(struct drm_device *dev)
13{ 33{
14 struct drm_nouveau_private *dev_priv = dev->dev_private; 34 struct drm_nouveau_private *dev_priv = dev->dev_private;
35 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
15 struct nv50_fb_priv *priv; 36 struct nv50_fb_priv *priv;
37 u32 tagmem;
38 int ret;
16 39
17 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 40 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
18 if (!priv) 41 if (!priv)
19 return -ENOMEM; 42 return -ENOMEM;
43 pfb->priv = priv;
20 44
21 priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO); 45 priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
22 if (!priv->r100c08_page) { 46 if (!priv->r100c08_page) {
23 kfree(priv); 47 nv50_fb_destroy(dev);
24 return -ENOMEM; 48 return -ENOMEM;
25 } 49 }
26 50
27 priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0, 51 priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0,
28 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 52 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
29 if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) { 53 if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) {
30 __free_page(priv->r100c08_page); 54 nv50_fb_destroy(dev);
31 kfree(priv);
32 return -EFAULT; 55 return -EFAULT;
33 } 56 }
34 57
35 dev_priv->engine.fb.priv = priv; 58 tagmem = nv_rd32(dev, 0x100320);
59 NV_DEBUG(dev, "%d tags available\n", tagmem);
60 ret = drm_mm_init(&pfb->tag_heap, 0, tagmem);
61 if (ret) {
62 nv50_fb_destroy(dev);
63 return ret;
64 }
65
36 return 0; 66 return 0;
37} 67}
38 68
@@ -81,18 +111,7 @@ nv50_fb_init(struct drm_device *dev)
81void 111void
82nv50_fb_takedown(struct drm_device *dev) 112nv50_fb_takedown(struct drm_device *dev)
83{ 113{
84 struct drm_nouveau_private *dev_priv = dev->dev_private; 114 nv50_fb_destroy(dev);
85 struct nv50_fb_priv *priv;
86
87 priv = dev_priv->engine.fb.priv;
88 if (!priv)
89 return;
90 dev_priv->engine.fb.priv = NULL;
91
92 pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE,
93 PCI_DMA_BIDIRECTIONAL);
94 __free_page(priv->r100c08_page);
95 kfree(priv);
96} 115}
97 116
98void 117void