diff options
author | Thomas Hellstrom <thomas@tungstengraphics.com> | 2006-08-08 07:34:46 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2006-09-21 15:32:31 -0400 |
commit | 7981bf7d494a6c4d45e22c54b0da887e5a67e705 (patch) | |
tree | 2cf27c4def2875d2463050056def16736189f5f3 /drivers/char | |
parent | 8d153f7107ff2c5d6e32053ae377c961187ab6b9 (diff) |
drm: SiS 315 Awareness.
Add support for the SiS 315 to the DRM.
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/drm/drm_pciids.h | 1 | ||||
-rw-r--r-- | drivers/char/drm/sis_drv.c | 1 | ||||
-rw-r--r-- | drivers/char/drm/sis_drv.h | 12 | ||||
-rw-r--r-- | drivers/char/drm/sis_mm.c | 71 |
4 files changed, 84 insertions, 1 deletions
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index bf9bdc50c1e3..8c16cde91133 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 93880e449201..3d5b3218b6ff 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 330a2c4eade2..2b8d6f6ed7c0 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 | ||
42 | enum 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 | |||
44 | typedef struct drm_sis_private { | 53 | typedef 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 | ||
64 | extern int sis_idle(drm_device_t *dev); | ||
55 | extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp); | 65 | extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp); |
56 | extern void sis_lastclose(drm_device_t *dev); | 66 | extern 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 0eb1dca232b7..3041c5b42d56 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 | ||
229 | static 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 | |||
245 | int 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 | |||
229 | void sis_lastclose(struct drm_device *dev) | 299 | void 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 | ||