aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/drm/drm_pciids.h1
-rw-r--r--drivers/char/drm/sis_drv.c1
-rw-r--r--drivers/char/drm/sis_drv.h12
-rw-r--r--drivers/char/drm/sis_mm.c71
4 files changed, 84 insertions, 1 deletions
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index bf9bdc50c1e..8c16cde9113 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -209,6 +209,7 @@
209 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 209 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
210 {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 210 {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
211 {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 211 {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
212 {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
212 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 213 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
213 {0, 0, 0} 214 {0, 0, 0}
214 215
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
index 93880e44920..3d5b3218b6f 100644
--- a/drivers/char/drm/sis_drv.c
+++ b/drivers/char/drm/sis_drv.c
@@ -69,6 +69,7 @@ static struct drm_driver driver = {
69 .load = sis_driver_load, 69 .load = sis_driver_load,
70 .unload = sis_driver_unload, 70 .unload = sis_driver_unload,
71 .context_dtor = NULL, 71 .context_dtor = NULL,
72 .dma_quiescent = sis_idle,
72 .reclaim_buffers = NULL, 73 .reclaim_buffers = NULL,
73 .reclaim_buffers_locked = sis_reclaim_buffers_locked, 74 .reclaim_buffers_locked = sis_reclaim_buffers_locked,
74 .lastclose = sis_lastclose, 75 .lastclose = sis_lastclose,
diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
index 330a2c4eade..2b8d6f6ed7c 100644
--- a/drivers/char/drm/sis_drv.h
+++ b/drivers/char/drm/sis_drv.h
@@ -34,13 +34,22 @@
34#define DRIVER_AUTHOR "SIS, Tungsten Graphics" 34#define DRIVER_AUTHOR "SIS, Tungsten Graphics"
35#define DRIVER_NAME "sis" 35#define DRIVER_NAME "sis"
36#define DRIVER_DESC "SIS 300/630/540" 36#define DRIVER_DESC "SIS 300/630/540"
37#define DRIVER_DATE "20060529" 37#define DRIVER_DATE "20060704"
38#define DRIVER_MAJOR 1 38#define DRIVER_MAJOR 1
39#define DRIVER_MINOR 2 39#define DRIVER_MINOR 2
40#define DRIVER_PATCHLEVEL 1 40#define DRIVER_PATCHLEVEL 1
41 41
42enum sis_family {
43 SIS_OTHER = 0,
44 SIS_CHIP_315 = 1,
45};
46
42#include "drm_sman.h" 47#include "drm_sman.h"
43 48
49#define SIS_BASE (dev_priv->mmio)
50#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg);
51#define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val);
52
44typedef struct drm_sis_private { 53typedef struct drm_sis_private {
45 drm_local_map_t *mmio; 54 drm_local_map_t *mmio;
46 unsigned int idle_fault; 55 unsigned int idle_fault;
@@ -52,6 +61,7 @@ typedef struct drm_sis_private {
52 unsigned long agp_offset; 61 unsigned long agp_offset;
53} drm_sis_private_t; 62} drm_sis_private_t;
54 63
64extern int sis_idle(drm_device_t *dev);
55extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp); 65extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp);
56extern void sis_lastclose(drm_device_t *dev); 66extern void sis_lastclose(drm_device_t *dev);
57 67
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index 0eb1dca232b..3041c5b42d5 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -226,6 +226,76 @@ static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
226 return sis_drm_alloc(dev, priv, data, AGP_TYPE); 226 return sis_drm_alloc(dev, priv, data, AGP_TYPE);
227} 227}
228 228
229static drm_local_map_t *sis_reg_init(drm_device_t *dev)
230{
231 drm_map_list_t *entry;
232 drm_local_map_t *map;
233
234 list_for_each_entry(entry, &dev->maplist->head, head) {
235 map = entry->map;
236 if (!map)
237 continue;
238 if (map->type == _DRM_REGISTERS) {
239 return map;
240 }
241 }
242 return NULL;
243}
244
245int sis_idle(drm_device_t *dev)
246{
247 drm_sis_private_t *dev_priv = dev->dev_private;
248 uint32_t idle_reg;
249 unsigned long end;
250 int i;
251
252 if (dev_priv->idle_fault)
253 return 0;
254
255 if (dev_priv->mmio == NULL) {
256 dev_priv->mmio = sis_reg_init(dev);
257 if (dev_priv->mmio == NULL) {
258 DRM_ERROR("Could not find register map.\n");
259 return 0;
260 }
261 }
262
263 /*
264 * Implement a device switch here if needed
265 */
266
267 if (dev_priv->chipset != SIS_CHIP_315)
268 return 0;
269
270 /*
271 * Timeout after 3 seconds. We cannot use DRM_WAIT_ON here
272 * because its polling frequency is too low.
273 */
274
275 end = jiffies + (DRM_HZ * 3);
276
277 for (i=0; i<4; ++i) {
278 do {
279 idle_reg = SIS_READ(0x85cc);
280 } while ( !time_after_eq(jiffies, end) &&
281 ((idle_reg & 0x80000000) != 0x80000000));
282 }
283
284 if (time_after_eq(jiffies, end)) {
285 DRM_ERROR("Graphics engine idle timeout. "
286 "Disabling idle check\n");
287 dev_priv->idle_fault = TRUE;
288 }
289
290 /*
291 * The caller never sees an error code. It gets trapped
292 * in libdrm.
293 */
294
295 return 0;
296}
297
298
229void sis_lastclose(struct drm_device *dev) 299void sis_lastclose(struct drm_device *dev)
230{ 300{
231 drm_sis_private_t *dev_priv = dev->dev_private; 301 drm_sis_private_t *dev_priv = dev->dev_private;
@@ -237,6 +307,7 @@ void sis_lastclose(struct drm_device *dev)
237 drm_sman_cleanup(&dev_priv->sman); 307 drm_sman_cleanup(&dev_priv->sman);
238 dev_priv->vram_initialized = FALSE; 308 dev_priv->vram_initialized = FALSE;
239 dev_priv->agp_initialized = FALSE; 309 dev_priv->agp_initialized = FALSE;
310 dev_priv->mmio = NULL;
240 mutex_unlock(&dev->struct_mutex); 311 mutex_unlock(&dev->struct_mutex);
241} 312}
242 313