]> code.ossystems Code Review - openembedded-core.git/blob
79f068f422488c7fd4d7249453661989a6e81461
[openembedded-core.git] /
1 commit 75fed4ae8454aa975c274b2585ec2287dd15773d
2 Author: Keith Packard <keithp@keithp.com>
3 Date:   Wed Jul 30 13:03:43 2008 -0700
4
5     i915: Initialize hardware status page at device load when possible.
6     
7     Some chips were unstable with repeated setup/teardown of the hardware status
8     page.
9     
10     Signed-off-by: Eric Anholt <eric@anholt.net>
11     Signed-off-by: Dave Airlie <airlied@redhat.com>
12
13 diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
14 index 4c72a01..b3c4ac9 100644
15 --- a/drivers/gpu/drm/i915/i915_dma.c
16 +++ b/drivers/gpu/drm/i915/i915_dma.c
17 @@ -71,6 +71,52 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
18         return -EBUSY;
19  }
20  
21 +/**
22 + * Sets up the hardware status page for devices that need a physical address
23 + * in the register.
24 + */
25 +int i915_init_phys_hws(struct drm_device *dev)
26 +{
27 +       drm_i915_private_t *dev_priv = dev->dev_private;
28 +       /* Program Hardware Status Page */
29 +       dev_priv->status_page_dmah =
30 +               drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
31 +
32 +       if (!dev_priv->status_page_dmah) {
33 +               DRM_ERROR("Can not allocate hardware status page\n");
34 +               return -ENOMEM;
35 +       }
36 +       dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
37 +       dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
38 +
39 +       memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
40 +
41 +       I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
42 +       DRM_DEBUG("Enabled hardware status page\n");
43 +       return 0;
44 +}
45 +
46 +/**
47 + * Frees the hardware status page, whether it's a physical address or a virtual
48 + * address set up by the X Server.
49 + */
50 +void i915_free_hws(struct drm_device *dev)
51 +{
52 +       drm_i915_private_t *dev_priv = dev->dev_private;
53 +       if (dev_priv->status_page_dmah) {
54 +               drm_pci_free(dev, dev_priv->status_page_dmah);
55 +               dev_priv->status_page_dmah = NULL;
56 +       }
57 +
58 +       if (dev_priv->status_gfx_addr) {
59 +               dev_priv->status_gfx_addr = 0;
60 +               drm_core_ioremapfree(&dev_priv->hws_map, dev);
61 +       }
62 +
63 +       /* Need to rewrite hardware status page */
64 +       I915_WRITE(HWS_PGA, 0x1ffff000);
65 +}
66 +
67  void i915_kernel_lost_context(struct drm_device * dev)
68  {
69         drm_i915_private_t *dev_priv = dev->dev_private;
70 @@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_device * dev)
71                 dev_priv->ring.map.size = 0;
72         }
73  
74 -       if (dev_priv->status_page_dmah) {
75 -               drm_pci_free(dev, dev_priv->status_page_dmah);
76 -               dev_priv->status_page_dmah = NULL;
77 -               /* Need to rewrite hardware status page */
78 -               I915_WRITE(HWS_PGA, 0x1ffff000);
79 -       }
80 -
81 -       if (dev_priv->status_gfx_addr) {
82 -               dev_priv->status_gfx_addr = 0;
83 -               drm_core_ioremapfree(&dev_priv->hws_map, dev);
84 -               I915_WRITE(HWS_PGA, 0x1ffff000);
85 -       }
86 +       /* Clear the HWS virtual address at teardown */
87 +       if (I915_NEED_GFX_HWS(dev))
88 +               i915_free_hws(dev);
89  
90         return 0;
91  }
92 @@ -165,23 +202,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
93          */
94         dev_priv->allow_batchbuffer = 1;
95  
96 -       /* Program Hardware Status Page */
97 -       if (!I915_NEED_GFX_HWS(dev)) {
98 -               dev_priv->status_page_dmah =
99 -                       drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
100 -
101 -               if (!dev_priv->status_page_dmah) {
102 -                       i915_dma_cleanup(dev);
103 -                       DRM_ERROR("Can not allocate hardware status page\n");
104 -                       return -ENOMEM;
105 -               }
106 -               dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
107 -               dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
108 -
109 -               memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
110 -               I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
111 -       }
112 -       DRM_DEBUG("Enabled hardware status page\n");
113         return 0;
114  }
115  
116 @@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
117                          _DRM_KERNEL | _DRM_DRIVER,
118                          &dev_priv->mmio_map);
119  
120 +       /* Init HWS */
121 +       if (!I915_NEED_GFX_HWS(dev)) {
122 +               ret = i915_init_phys_hws(dev);
123 +               if (ret != 0)
124 +                       return ret;
125 +       }
126  
127         /* On the 945G/GM, the chipset reports the MSI capability on the
128          * integrated graphics even though the support isn't actually there
129 @@ -796,6 +822,8 @@ int i915_driver_unload(struct drm_device *dev)
130         if (dev->pdev->msi_enabled)
131                 pci_disable_msi(dev->pdev);
132  
133 +       i915_free_hws(dev);
134 +
135         if (dev_priv->mmio_map)
136                 drm_rmmap(dev, dev_priv->mmio_map);
137