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/drm/sis_mm.c | |
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/drm/sis_mm.c')
-rw-r--r-- | drivers/char/drm/sis_mm.c | 71 |
1 files changed, 71 insertions, 0 deletions
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 | ||