diff options
Diffstat (limited to 'drivers/gpu')
51 files changed, 2006 insertions, 924 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8fab7890a363..2f631c75f704 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -258,31 +258,6 @@ void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) | |||
258 | EXPORT_SYMBOL(drm_mode_object_find); | 258 | EXPORT_SYMBOL(drm_mode_object_find); |
259 | 259 | ||
260 | /** | 260 | /** |
261 | * drm_crtc_from_fb - find the CRTC structure associated with an fb | ||
262 | * @dev: DRM device | ||
263 | * @fb: framebuffer in question | ||
264 | * | ||
265 | * LOCKING: | ||
266 | * Caller must hold mode_config lock. | ||
267 | * | ||
268 | * Find CRTC in the mode_config structure that matches @fb. | ||
269 | * | ||
270 | * RETURNS: | ||
271 | * Pointer to the CRTC or NULL if it wasn't found. | ||
272 | */ | ||
273 | struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev, | ||
274 | struct drm_framebuffer *fb) | ||
275 | { | ||
276 | struct drm_crtc *crtc; | ||
277 | |||
278 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
279 | if (crtc->fb == fb) | ||
280 | return crtc; | ||
281 | } | ||
282 | return NULL; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * drm_framebuffer_init - initialize a framebuffer | 261 | * drm_framebuffer_init - initialize a framebuffer |
287 | * @dev: DRM device | 262 | * @dev: DRM device |
288 | * | 263 | * |
@@ -328,11 +303,20 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb) | |||
328 | { | 303 | { |
329 | struct drm_device *dev = fb->dev; | 304 | struct drm_device *dev = fb->dev; |
330 | struct drm_crtc *crtc; | 305 | struct drm_crtc *crtc; |
306 | struct drm_mode_set set; | ||
307 | int ret; | ||
331 | 308 | ||
332 | /* remove from any CRTC */ | 309 | /* remove from any CRTC */ |
333 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 310 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
334 | if (crtc->fb == fb) | 311 | if (crtc->fb == fb) { |
335 | crtc->fb = NULL; | 312 | /* should turn off the crtc */ |
313 | memset(&set, 0, sizeof(struct drm_mode_set)); | ||
314 | set.crtc = crtc; | ||
315 | set.fb = NULL; | ||
316 | ret = crtc->funcs->set_config(&set); | ||
317 | if (ret) | ||
318 | DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); | ||
319 | } | ||
336 | } | 320 | } |
337 | 321 | ||
338 | drm_mode_object_put(dev, &fb->base); | 322 | drm_mode_object_put(dev, &fb->base); |
@@ -1461,7 +1445,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
1461 | goto out; | 1445 | goto out; |
1462 | } | 1446 | } |
1463 | 1447 | ||
1464 | if (crtc_req->count_connectors > 0 && !mode && !fb) { | 1448 | if (crtc_req->count_connectors > 0 && (!mode || !fb)) { |
1465 | DRM_DEBUG("Count connectors is %d but no mode or fb set\n", | 1449 | DRM_DEBUG("Count connectors is %d but no mode or fb set\n", |
1466 | crtc_req->count_connectors); | 1450 | crtc_req->count_connectors); |
1467 | ret = -EINVAL; | 1451 | ret = -EINVAL; |
@@ -1511,7 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
1511 | set.mode = mode; | 1495 | set.mode = mode; |
1512 | set.connectors = connector_set; | 1496 | set.connectors = connector_set; |
1513 | set.num_connectors = crtc_req->count_connectors; | 1497 | set.num_connectors = crtc_req->count_connectors; |
1514 | set.fb =fb; | 1498 | set.fb = fb; |
1515 | ret = crtc->funcs->set_config(&set); | 1499 | ret = crtc->funcs->set_config(&set); |
1516 | 1500 | ||
1517 | out: | 1501 | out: |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 3da9cfa31848..6aaa2cb23365 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -706,8 +706,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
706 | struct drm_encoder **save_encoders, *new_encoder; | 706 | struct drm_encoder **save_encoders, *new_encoder; |
707 | struct drm_framebuffer *old_fb = NULL; | 707 | struct drm_framebuffer *old_fb = NULL; |
708 | bool save_enabled; | 708 | bool save_enabled; |
709 | bool mode_changed = false; | 709 | bool mode_changed = false; /* if true do a full mode set */ |
710 | bool fb_changed = false; | 710 | bool fb_changed = false; /* if true and !mode_changed just do a flip */ |
711 | struct drm_connector *connector; | 711 | struct drm_connector *connector; |
712 | int count = 0, ro, fail = 0; | 712 | int count = 0, ro, fail = 0; |
713 | struct drm_crtc_helper_funcs *crtc_funcs; | 713 | struct drm_crtc_helper_funcs *crtc_funcs; |
@@ -758,6 +758,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
758 | if (set->crtc->fb == NULL) { | 758 | if (set->crtc->fb == NULL) { |
759 | DRM_DEBUG("crtc has no fb, full mode set\n"); | 759 | DRM_DEBUG("crtc has no fb, full mode set\n"); |
760 | mode_changed = true; | 760 | mode_changed = true; |
761 | } else if (set->fb == NULL) { | ||
762 | mode_changed = true; | ||
761 | } else if ((set->fb->bits_per_pixel != | 763 | } else if ((set->fb->bits_per_pixel != |
762 | set->crtc->fb->bits_per_pixel) || | 764 | set->crtc->fb->bits_per_pixel) || |
763 | set->fb->depth != set->crtc->fb->depth) | 765 | set->fb->depth != set->crtc->fb->depth) |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 80cc6d06d61b..7f2728bbc16c 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -502,12 +502,40 @@ static int add_detailed_info(struct drm_connector *connector, | |||
502 | struct detailed_non_pixel *data = &timing->data.other_data; | 502 | struct detailed_non_pixel *data = &timing->data.other_data; |
503 | struct drm_display_mode *newmode; | 503 | struct drm_display_mode *newmode; |
504 | 504 | ||
505 | /* EDID up to and including 1.2 may put monitor info here */ | 505 | /* X server check is version 1.1 or higher */ |
506 | if (edid->version == 1 && edid->revision < 3) | 506 | if (edid->version == 1 && edid->revision >= 1 && |
507 | continue; | 507 | !timing->pixel_clock) { |
508 | 508 | /* Other timing or info */ | |
509 | /* Detailed mode timing */ | 509 | switch (data->type) { |
510 | if (timing->pixel_clock) { | 510 | case EDID_DETAIL_MONITOR_SERIAL: |
511 | break; | ||
512 | case EDID_DETAIL_MONITOR_STRING: | ||
513 | break; | ||
514 | case EDID_DETAIL_MONITOR_RANGE: | ||
515 | /* Get monitor range data */ | ||
516 | break; | ||
517 | case EDID_DETAIL_MONITOR_NAME: | ||
518 | break; | ||
519 | case EDID_DETAIL_MONITOR_CPDATA: | ||
520 | break; | ||
521 | case EDID_DETAIL_STD_MODES: | ||
522 | /* Five modes per detailed section */ | ||
523 | for (j = 0; j < 5; i++) { | ||
524 | struct std_timing *std; | ||
525 | struct drm_display_mode *newmode; | ||
526 | |||
527 | std = &data->data.timings[j]; | ||
528 | newmode = drm_mode_std(dev, std); | ||
529 | if (newmode) { | ||
530 | drm_mode_probed_add(connector, newmode); | ||
531 | modes++; | ||
532 | } | ||
533 | } | ||
534 | break; | ||
535 | default: | ||
536 | break; | ||
537 | } | ||
538 | } else { | ||
511 | newmode = drm_mode_detailed(dev, edid, timing, quirks); | 539 | newmode = drm_mode_detailed(dev, edid, timing, quirks); |
512 | if (!newmode) | 540 | if (!newmode) |
513 | continue; | 541 | continue; |
@@ -518,38 +546,6 @@ static int add_detailed_info(struct drm_connector *connector, | |||
518 | drm_mode_probed_add(connector, newmode); | 546 | drm_mode_probed_add(connector, newmode); |
519 | 547 | ||
520 | modes++; | 548 | modes++; |
521 | continue; | ||
522 | } | ||
523 | |||
524 | /* Other timing or info */ | ||
525 | switch (data->type) { | ||
526 | case EDID_DETAIL_MONITOR_SERIAL: | ||
527 | break; | ||
528 | case EDID_DETAIL_MONITOR_STRING: | ||
529 | break; | ||
530 | case EDID_DETAIL_MONITOR_RANGE: | ||
531 | /* Get monitor range data */ | ||
532 | break; | ||
533 | case EDID_DETAIL_MONITOR_NAME: | ||
534 | break; | ||
535 | case EDID_DETAIL_MONITOR_CPDATA: | ||
536 | break; | ||
537 | case EDID_DETAIL_STD_MODES: | ||
538 | /* Five modes per detailed section */ | ||
539 | for (j = 0; j < 5; i++) { | ||
540 | struct std_timing *std; | ||
541 | struct drm_display_mode *newmode; | ||
542 | |||
543 | std = &data->data.timings[j]; | ||
544 | newmode = drm_mode_std(dev, std); | ||
545 | if (newmode) { | ||
546 | drm_mode_probed_add(connector, newmode); | ||
547 | modes++; | ||
548 | } | ||
549 | } | ||
550 | break; | ||
551 | default: | ||
552 | break; | ||
553 | } | 549 | } |
554 | } | 550 | } |
555 | 551 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index b4a3dbcebe9b..f85aaf21e783 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -566,7 +566,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
566 | 566 | ||
567 | ret = drm_vblank_get(dev, crtc); | 567 | ret = drm_vblank_get(dev, crtc); |
568 | if (ret) { | 568 | if (ret) { |
569 | DRM_ERROR("failed to acquire vblank counter, %d\n", ret); | 569 | DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); |
570 | return ret; | 570 | return ret; |
571 | } | 571 | } |
572 | seq = drm_vblank_count(dev, crtc); | 572 | seq = drm_vblank_count(dev, crtc); |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 54f492a488a9..7914097b09c6 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -566,6 +566,8 @@ void drm_mode_connector_list_update(struct drm_connector *connector) | |||
566 | found_it = 1; | 566 | found_it = 1; |
567 | /* if equal delete the probed mode */ | 567 | /* if equal delete the probed mode */ |
568 | mode->status = pmode->status; | 568 | mode->status = pmode->status; |
569 | /* Merge type bits together */ | ||
570 | mode->type |= pmode->type; | ||
569 | list_del(&pmode->head); | 571 | list_del(&pmode->head); |
570 | drm_mode_destroy(connector->dev, pmode); | 572 | drm_mode_destroy(connector->dev, pmode); |
571 | break; | 573 | break; |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 85ec31b3ff00..f7a615b80c70 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -22,44 +22,50 @@ | |||
22 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) | 22 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) |
23 | #define to_drm_connector(d) container_of(d, struct drm_connector, kdev) | 23 | #define to_drm_connector(d) container_of(d, struct drm_connector, kdev) |
24 | 24 | ||
25 | static struct device_type drm_sysfs_device_minor = { | ||
26 | .name = "drm_minor" | ||
27 | }; | ||
28 | |||
25 | /** | 29 | /** |
26 | * drm_sysfs_suspend - DRM class suspend hook | 30 | * drm_class_suspend - DRM class suspend hook |
27 | * @dev: Linux device to suspend | 31 | * @dev: Linux device to suspend |
28 | * @state: power state to enter | 32 | * @state: power state to enter |
29 | * | 33 | * |
30 | * Just figures out what the actual struct drm_device associated with | 34 | * Just figures out what the actual struct drm_device associated with |
31 | * @dev is and calls its suspend hook, if present. | 35 | * @dev is and calls its suspend hook, if present. |
32 | */ | 36 | */ |
33 | static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | 37 | static int drm_class_suspend(struct device *dev, pm_message_t state) |
34 | { | 38 | { |
35 | struct drm_minor *drm_minor = to_drm_minor(dev); | 39 | if (dev->type == &drm_sysfs_device_minor) { |
36 | struct drm_device *drm_dev = drm_minor->dev; | 40 | struct drm_minor *drm_minor = to_drm_minor(dev); |
37 | 41 | struct drm_device *drm_dev = drm_minor->dev; | |
38 | if (drm_minor->type == DRM_MINOR_LEGACY && | 42 | |
39 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && | 43 | if (drm_minor->type == DRM_MINOR_LEGACY && |
40 | drm_dev->driver->suspend) | 44 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && |
41 | return drm_dev->driver->suspend(drm_dev, state); | 45 | drm_dev->driver->suspend) |
42 | 46 | return drm_dev->driver->suspend(drm_dev, state); | |
47 | } | ||
43 | return 0; | 48 | return 0; |
44 | } | 49 | } |
45 | 50 | ||
46 | /** | 51 | /** |
47 | * drm_sysfs_resume - DRM class resume hook | 52 | * drm_class_resume - DRM class resume hook |
48 | * @dev: Linux device to resume | 53 | * @dev: Linux device to resume |
49 | * | 54 | * |
50 | * Just figures out what the actual struct drm_device associated with | 55 | * Just figures out what the actual struct drm_device associated with |
51 | * @dev is and calls its resume hook, if present. | 56 | * @dev is and calls its resume hook, if present. |
52 | */ | 57 | */ |
53 | static int drm_sysfs_resume(struct device *dev) | 58 | static int drm_class_resume(struct device *dev) |
54 | { | 59 | { |
55 | struct drm_minor *drm_minor = to_drm_minor(dev); | 60 | if (dev->type == &drm_sysfs_device_minor) { |
56 | struct drm_device *drm_dev = drm_minor->dev; | 61 | struct drm_minor *drm_minor = to_drm_minor(dev); |
57 | 62 | struct drm_device *drm_dev = drm_minor->dev; | |
58 | if (drm_minor->type == DRM_MINOR_LEGACY && | 63 | |
59 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && | 64 | if (drm_minor->type == DRM_MINOR_LEGACY && |
60 | drm_dev->driver->resume) | 65 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && |
61 | return drm_dev->driver->resume(drm_dev); | 66 | drm_dev->driver->resume) |
62 | 67 | return drm_dev->driver->resume(drm_dev); | |
68 | } | ||
63 | return 0; | 69 | return 0; |
64 | } | 70 | } |
65 | 71 | ||
@@ -99,8 +105,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name) | |||
99 | goto err_out; | 105 | goto err_out; |
100 | } | 106 | } |
101 | 107 | ||
102 | class->suspend = drm_sysfs_suspend; | 108 | class->suspend = drm_class_suspend; |
103 | class->resume = drm_sysfs_resume; | 109 | class->resume = drm_class_resume; |
104 | 110 | ||
105 | err = class_create_file(class, &class_attr_version); | 111 | err = class_create_file(class, &class_attr_version); |
106 | if (err) | 112 | if (err) |
@@ -480,6 +486,7 @@ int drm_sysfs_device_add(struct drm_minor *minor) | |||
480 | minor->kdev.class = drm_class; | 486 | minor->kdev.class = drm_class; |
481 | minor->kdev.release = drm_sysfs_device_release; | 487 | minor->kdev.release = drm_sysfs_device_release; |
482 | minor->kdev.devt = minor->device; | 488 | minor->kdev.devt = minor->device; |
489 | minor->kdev.type = &drm_sysfs_device_minor; | ||
483 | if (minor->type == DRM_MINOR_CONTROL) | 490 | if (minor->type == DRM_MINOR_CONTROL) |
484 | minor_str = "controlD%d"; | 491 | minor_str = "controlD%d"; |
485 | else if (minor->type == DRM_MINOR_RENDER) | 492 | else if (minor->type == DRM_MINOR_RENDER) |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 8c4783180bf6..50d1f782768c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1186,6 +1186,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1186 | if (ret) | 1186 | if (ret) |
1187 | goto out_iomapfree; | 1187 | goto out_iomapfree; |
1188 | 1188 | ||
1189 | dev_priv->wq = create_workqueue("i915"); | ||
1190 | if (dev_priv->wq == NULL) { | ||
1191 | DRM_ERROR("Failed to create our workqueue.\n"); | ||
1192 | ret = -ENOMEM; | ||
1193 | goto out_iomapfree; | ||
1194 | } | ||
1195 | |||
1189 | /* enable GEM by default */ | 1196 | /* enable GEM by default */ |
1190 | dev_priv->has_gem = 1; | 1197 | dev_priv->has_gem = 1; |
1191 | 1198 | ||
@@ -1211,7 +1218,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1211 | if (!I915_NEED_GFX_HWS(dev)) { | 1218 | if (!I915_NEED_GFX_HWS(dev)) { |
1212 | ret = i915_init_phys_hws(dev); | 1219 | ret = i915_init_phys_hws(dev); |
1213 | if (ret != 0) | 1220 | if (ret != 0) |
1214 | goto out_iomapfree; | 1221 | goto out_workqueue_free; |
1215 | } | 1222 | } |
1216 | 1223 | ||
1217 | i915_get_mem_freq(dev); | 1224 | i915_get_mem_freq(dev); |
@@ -1245,7 +1252,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1245 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); | 1252 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); |
1246 | if (ret < 0) { | 1253 | if (ret < 0) { |
1247 | DRM_ERROR("failed to init modeset\n"); | 1254 | DRM_ERROR("failed to init modeset\n"); |
1248 | goto out_rmmap; | 1255 | goto out_workqueue_free; |
1249 | } | 1256 | } |
1250 | } | 1257 | } |
1251 | 1258 | ||
@@ -1256,6 +1263,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1256 | 1263 | ||
1257 | return 0; | 1264 | return 0; |
1258 | 1265 | ||
1266 | out_workqueue_free: | ||
1267 | destroy_workqueue(dev_priv->wq); | ||
1259 | out_iomapfree: | 1268 | out_iomapfree: |
1260 | io_mapping_free(dev_priv->mm.gtt_mapping); | 1269 | io_mapping_free(dev_priv->mm.gtt_mapping); |
1261 | out_rmmap: | 1270 | out_rmmap: |
@@ -1269,6 +1278,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
1269 | { | 1278 | { |
1270 | struct drm_i915_private *dev_priv = dev->dev_private; | 1279 | struct drm_i915_private *dev_priv = dev->dev_private; |
1271 | 1280 | ||
1281 | destroy_workqueue(dev_priv->wq); | ||
1282 | |||
1272 | io_mapping_free(dev_priv->mm.gtt_mapping); | 1283 | io_mapping_free(dev_priv->mm.gtt_mapping); |
1273 | if (dev_priv->mm.gtt_mtrr >= 0) { | 1284 | if (dev_priv->mm.gtt_mtrr >= 0) { |
1274 | mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, | 1285 | mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d08752875885..5b4f87e55621 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -219,8 +219,10 @@ typedef struct drm_i915_private { | |||
219 | unsigned int lvds_vbt:1; | 219 | unsigned int lvds_vbt:1; |
220 | unsigned int int_crt_support:1; | 220 | unsigned int int_crt_support:1; |
221 | unsigned int lvds_use_ssc:1; | 221 | unsigned int lvds_use_ssc:1; |
222 | unsigned int edp_support:1; | ||
222 | int lvds_ssc_freq; | 223 | int lvds_ssc_freq; |
223 | 224 | ||
225 | int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ | ||
224 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 226 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ |
225 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 227 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
226 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 228 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
@@ -229,6 +231,8 @@ typedef struct drm_i915_private { | |||
229 | 231 | ||
230 | spinlock_t error_lock; | 232 | spinlock_t error_lock; |
231 | struct drm_i915_error_state *first_error; | 233 | struct drm_i915_error_state *first_error; |
234 | struct work_struct error_work; | ||
235 | struct workqueue_struct *wq; | ||
232 | 236 | ||
233 | /* Register state */ | 237 | /* Register state */ |
234 | u8 saveLBB; | 238 | u8 saveLBB; |
@@ -381,6 +385,9 @@ typedef struct drm_i915_private { | |||
381 | */ | 385 | */ |
382 | struct list_head inactive_list; | 386 | struct list_head inactive_list; |
383 | 387 | ||
388 | /** LRU list of objects with fence regs on them. */ | ||
389 | struct list_head fence_list; | ||
390 | |||
384 | /** | 391 | /** |
385 | * List of breadcrumbs associated with GPU requests currently | 392 | * List of breadcrumbs associated with GPU requests currently |
386 | * outstanding. | 393 | * outstanding. |
@@ -448,6 +455,9 @@ struct drm_i915_gem_object { | |||
448 | /** This object's place on the active/flushing/inactive lists */ | 455 | /** This object's place on the active/flushing/inactive lists */ |
449 | struct list_head list; | 456 | struct list_head list; |
450 | 457 | ||
458 | /** This object's place on the fenced object LRU */ | ||
459 | struct list_head fence_list; | ||
460 | |||
451 | /** | 461 | /** |
452 | * This is set if the object is on the active or flushing lists | 462 | * This is set if the object is on the active or flushing lists |
453 | * (has pending rendering), and is not set if it's on inactive (ready | 463 | * (has pending rendering), and is not set if it's on inactive (ready |
@@ -888,6 +898,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
888 | IS_I915GM(dev))) | 898 | IS_I915GM(dev))) |
889 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 899 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
890 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 900 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
901 | #define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev)) | ||
891 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) | 902 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) |
892 | /* dsparb controlled by hw only */ | 903 | /* dsparb controlled by hw only */ |
893 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 904 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5bf420378b6d..0c07a755b3a3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -978,6 +978,7 @@ int | |||
978 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | 978 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, |
979 | struct drm_file *file_priv) | 979 | struct drm_file *file_priv) |
980 | { | 980 | { |
981 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
981 | struct drm_i915_gem_set_domain *args = data; | 982 | struct drm_i915_gem_set_domain *args = data; |
982 | struct drm_gem_object *obj; | 983 | struct drm_gem_object *obj; |
983 | uint32_t read_domains = args->read_domains; | 984 | uint32_t read_domains = args->read_domains; |
@@ -1010,8 +1011,18 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1010 | obj, obj->size, read_domains, write_domain); | 1011 | obj, obj->size, read_domains, write_domain); |
1011 | #endif | 1012 | #endif |
1012 | if (read_domains & I915_GEM_DOMAIN_GTT) { | 1013 | if (read_domains & I915_GEM_DOMAIN_GTT) { |
1014 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1015 | |||
1013 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); | 1016 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); |
1014 | 1017 | ||
1018 | /* Update the LRU on the fence for the CPU access that's | ||
1019 | * about to occur. | ||
1020 | */ | ||
1021 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | ||
1022 | list_move_tail(&obj_priv->fence_list, | ||
1023 | &dev_priv->mm.fence_list); | ||
1024 | } | ||
1025 | |||
1015 | /* Silently promote "you're not bound, there was nothing to do" | 1026 | /* Silently promote "you're not bound, there was nothing to do" |
1016 | * to success, since the client was just asking us to | 1027 | * to success, since the client was just asking us to |
1017 | * make sure everything was done. | 1028 | * make sure everything was done. |
@@ -1155,8 +1166,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1155 | } | 1166 | } |
1156 | 1167 | ||
1157 | /* Need a new fence register? */ | 1168 | /* Need a new fence register? */ |
1158 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && | 1169 | if (obj_priv->tiling_mode != I915_TILING_NONE) { |
1159 | obj_priv->tiling_mode != I915_TILING_NONE) { | ||
1160 | ret = i915_gem_object_get_fence_reg(obj); | 1170 | ret = i915_gem_object_get_fence_reg(obj); |
1161 | if (ret) { | 1171 | if (ret) { |
1162 | mutex_unlock(&dev->struct_mutex); | 1172 | mutex_unlock(&dev->struct_mutex); |
@@ -1570,7 +1580,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1570 | } | 1580 | } |
1571 | 1581 | ||
1572 | if (was_empty && !dev_priv->mm.suspended) | 1582 | if (was_empty && !dev_priv->mm.suspended) |
1573 | schedule_delayed_work(&dev_priv->mm.retire_work, HZ); | 1583 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); |
1574 | return seqno; | 1584 | return seqno; |
1575 | } | 1585 | } |
1576 | 1586 | ||
@@ -1719,7 +1729,7 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1719 | i915_gem_retire_requests(dev); | 1729 | i915_gem_retire_requests(dev); |
1720 | if (!dev_priv->mm.suspended && | 1730 | if (!dev_priv->mm.suspended && |
1721 | !list_empty(&dev_priv->mm.request_list)) | 1731 | !list_empty(&dev_priv->mm.request_list)) |
1722 | schedule_delayed_work(&dev_priv->mm.retire_work, HZ); | 1732 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); |
1723 | mutex_unlock(&dev->struct_mutex); | 1733 | mutex_unlock(&dev->struct_mutex); |
1724 | } | 1734 | } |
1725 | 1735 | ||
@@ -2208,6 +2218,12 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2208 | struct drm_i915_gem_object *old_obj_priv = NULL; | 2218 | struct drm_i915_gem_object *old_obj_priv = NULL; |
2209 | int i, ret, avail; | 2219 | int i, ret, avail; |
2210 | 2220 | ||
2221 | /* Just update our place in the LRU if our fence is getting used. */ | ||
2222 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | ||
2223 | list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | ||
2224 | return 0; | ||
2225 | } | ||
2226 | |||
2211 | switch (obj_priv->tiling_mode) { | 2227 | switch (obj_priv->tiling_mode) { |
2212 | case I915_TILING_NONE: | 2228 | case I915_TILING_NONE: |
2213 | WARN(1, "allocating a fence for non-tiled object?\n"); | 2229 | WARN(1, "allocating a fence for non-tiled object?\n"); |
@@ -2229,7 +2245,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2229 | } | 2245 | } |
2230 | 2246 | ||
2231 | /* First try to find a free reg */ | 2247 | /* First try to find a free reg */ |
2232 | try_again: | ||
2233 | avail = 0; | 2248 | avail = 0; |
2234 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { | 2249 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { |
2235 | reg = &dev_priv->fence_regs[i]; | 2250 | reg = &dev_priv->fence_regs[i]; |
@@ -2243,52 +2258,41 @@ try_again: | |||
2243 | 2258 | ||
2244 | /* None available, try to steal one or wait for a user to finish */ | 2259 | /* None available, try to steal one or wait for a user to finish */ |
2245 | if (i == dev_priv->num_fence_regs) { | 2260 | if (i == dev_priv->num_fence_regs) { |
2246 | uint32_t seqno = dev_priv->mm.next_gem_seqno; | 2261 | struct drm_gem_object *old_obj = NULL; |
2247 | 2262 | ||
2248 | if (avail == 0) | 2263 | if (avail == 0) |
2249 | return -ENOSPC; | 2264 | return -ENOSPC; |
2250 | 2265 | ||
2251 | for (i = dev_priv->fence_reg_start; | 2266 | list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list, |
2252 | i < dev_priv->num_fence_regs; i++) { | 2267 | fence_list) { |
2253 | uint32_t this_seqno; | 2268 | old_obj = old_obj_priv->obj; |
2254 | 2269 | ||
2255 | reg = &dev_priv->fence_regs[i]; | 2270 | reg = &dev_priv->fence_regs[old_obj_priv->fence_reg]; |
2256 | old_obj_priv = reg->obj->driver_private; | ||
2257 | 2271 | ||
2258 | if (old_obj_priv->pin_count) | 2272 | if (old_obj_priv->pin_count) |
2259 | continue; | 2273 | continue; |
2260 | 2274 | ||
2275 | /* Take a reference, as otherwise the wait_rendering | ||
2276 | * below may cause the object to get freed out from | ||
2277 | * under us. | ||
2278 | */ | ||
2279 | drm_gem_object_reference(old_obj); | ||
2280 | |||
2261 | /* i915 uses fences for GPU access to tiled buffers */ | 2281 | /* i915 uses fences for GPU access to tiled buffers */ |
2262 | if (IS_I965G(dev) || !old_obj_priv->active) | 2282 | if (IS_I965G(dev) || !old_obj_priv->active) |
2263 | break; | 2283 | break; |
2264 | 2284 | ||
2265 | /* find the seqno of the first available fence */ | 2285 | /* This brings the object to the head of the LRU if it |
2266 | this_seqno = old_obj_priv->last_rendering_seqno; | 2286 | * had been written to. The only way this should |
2267 | if (this_seqno != 0 && | 2287 | * result in us waiting longer than the expected |
2268 | reg->obj->write_domain == 0 && | 2288 | * optimal amount of time is if there was a |
2269 | i915_seqno_passed(seqno, this_seqno)) | 2289 | * fence-using buffer later that was read-only. |
2270 | seqno = this_seqno; | 2290 | */ |
2271 | } | 2291 | i915_gem_object_flush_gpu_write_domain(old_obj); |
2272 | 2292 | ret = i915_gem_object_wait_rendering(old_obj); | |
2273 | /* | 2293 | if (ret != 0) |
2274 | * Now things get ugly... we have to wait for one of the | ||
2275 | * objects to finish before trying again. | ||
2276 | */ | ||
2277 | if (i == dev_priv->num_fence_regs) { | ||
2278 | if (seqno == dev_priv->mm.next_gem_seqno) { | ||
2279 | i915_gem_flush(dev, | ||
2280 | I915_GEM_GPU_DOMAINS, | ||
2281 | I915_GEM_GPU_DOMAINS); | ||
2282 | seqno = i915_add_request(dev, NULL, | ||
2283 | I915_GEM_GPU_DOMAINS); | ||
2284 | if (seqno == 0) | ||
2285 | return -ENOMEM; | ||
2286 | } | ||
2287 | |||
2288 | ret = i915_wait_request(dev, seqno); | ||
2289 | if (ret) | ||
2290 | return ret; | 2294 | return ret; |
2291 | goto try_again; | 2295 | break; |
2292 | } | 2296 | } |
2293 | 2297 | ||
2294 | /* | 2298 | /* |
@@ -2296,10 +2300,15 @@ try_again: | |||
2296 | * for this object next time we need it. | 2300 | * for this object next time we need it. |
2297 | */ | 2301 | */ |
2298 | i915_gem_release_mmap(reg->obj); | 2302 | i915_gem_release_mmap(reg->obj); |
2303 | i = old_obj_priv->fence_reg; | ||
2299 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2304 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2305 | list_del_init(&old_obj_priv->fence_list); | ||
2306 | drm_gem_object_unreference(old_obj); | ||
2300 | } | 2307 | } |
2301 | 2308 | ||
2302 | obj_priv->fence_reg = i; | 2309 | obj_priv->fence_reg = i; |
2310 | list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | ||
2311 | |||
2303 | reg->obj = obj; | 2312 | reg->obj = obj; |
2304 | 2313 | ||
2305 | if (IS_I965G(dev)) | 2314 | if (IS_I965G(dev)) |
@@ -2342,6 +2351,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2342 | 2351 | ||
2343 | dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; | 2352 | dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; |
2344 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2353 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2354 | list_del_init(&obj_priv->fence_list); | ||
2345 | } | 2355 | } |
2346 | 2356 | ||
2347 | /** | 2357 | /** |
@@ -3595,9 +3605,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
3595 | * Pre-965 chips need a fence register set up in order to | 3605 | * Pre-965 chips need a fence register set up in order to |
3596 | * properly handle tiled surfaces. | 3606 | * properly handle tiled surfaces. |
3597 | */ | 3607 | */ |
3598 | if (!IS_I965G(dev) && | 3608 | if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) { |
3599 | obj_priv->fence_reg == I915_FENCE_REG_NONE && | ||
3600 | obj_priv->tiling_mode != I915_TILING_NONE) { | ||
3601 | ret = i915_gem_object_get_fence_reg(obj); | 3609 | ret = i915_gem_object_get_fence_reg(obj); |
3602 | if (ret != 0) { | 3610 | if (ret != 0) { |
3603 | if (ret != -EBUSY && ret != -ERESTARTSYS) | 3611 | if (ret != -EBUSY && ret != -ERESTARTSYS) |
@@ -3806,6 +3814,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
3806 | obj_priv->obj = obj; | 3814 | obj_priv->obj = obj; |
3807 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 3815 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
3808 | INIT_LIST_HEAD(&obj_priv->list); | 3816 | INIT_LIST_HEAD(&obj_priv->list); |
3817 | INIT_LIST_HEAD(&obj_priv->fence_list); | ||
3809 | 3818 | ||
3810 | return 0; | 3819 | return 0; |
3811 | } | 3820 | } |
@@ -4253,6 +4262,7 @@ i915_gem_load(struct drm_device *dev) | |||
4253 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); | 4262 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); |
4254 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4263 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
4255 | INIT_LIST_HEAD(&dev_priv->mm.request_list); | 4264 | INIT_LIST_HEAD(&dev_priv->mm.request_list); |
4265 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | ||
4256 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 4266 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
4257 | i915_gem_retire_work_handler); | 4267 | i915_gem_retire_work_handler); |
4258 | dev_priv->mm.next_gem_seqno = 1; | 4268 | dev_priv->mm.next_gem_seqno = 1; |
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c index 9a44bfcb8139..cb3b97405fbf 100644 --- a/drivers/gpu/drm/i915/i915_gem_debugfs.c +++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c | |||
@@ -343,6 +343,8 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
343 | 343 | ||
344 | error = dev_priv->first_error; | 344 | error = dev_priv->first_error; |
345 | 345 | ||
346 | seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, | ||
347 | error->time.tv_usec); | ||
346 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | 348 | seq_printf(m, "EIR: 0x%08x\n", error->eir); |
347 | seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); | 349 | seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
348 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); | 350 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7ba23a69a0c0..7ebc84c2881e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -190,7 +190,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
190 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; | 190 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; |
191 | 191 | ||
192 | if (!i915_pipe_enabled(dev, pipe)) { | 192 | if (!i915_pipe_enabled(dev, pipe)) { |
193 | DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); | 193 | DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); |
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
@@ -219,7 +219,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | |||
219 | int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; | 219 | int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; |
220 | 220 | ||
221 | if (!i915_pipe_enabled(dev, pipe)) { | 221 | if (!i915_pipe_enabled(dev, pipe)) { |
222 | DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); | 222 | DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); |
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
@@ -290,6 +290,35 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
290 | return ret; | 290 | return ret; |
291 | } | 291 | } |
292 | 292 | ||
293 | /** | ||
294 | * i915_error_work_func - do process context error handling work | ||
295 | * @work: work struct | ||
296 | * | ||
297 | * Fire an error uevent so userspace can see that a hang or error | ||
298 | * was detected. | ||
299 | */ | ||
300 | static void i915_error_work_func(struct work_struct *work) | ||
301 | { | ||
302 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | ||
303 | error_work); | ||
304 | struct drm_device *dev = dev_priv->dev; | ||
305 | char *event_string = "ERROR=1"; | ||
306 | char *envp[] = { event_string, NULL }; | ||
307 | |||
308 | DRM_DEBUG("generating error event\n"); | ||
309 | |||
310 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * i915_capture_error_state - capture an error record for later analysis | ||
315 | * @dev: drm device | ||
316 | * | ||
317 | * Should be called when an error is detected (either a hang or an error | ||
318 | * interrupt) to capture error state from the time of the error. Fills | ||
319 | * out a structure which becomes available in debugfs for user level tools | ||
320 | * to pick up. | ||
321 | */ | ||
293 | static void i915_capture_error_state(struct drm_device *dev) | 322 | static void i915_capture_error_state(struct drm_device *dev) |
294 | { | 323 | { |
295 | struct drm_i915_private *dev_priv = dev->dev_private; | 324 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -325,12 +354,137 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
325 | error->acthd = I915_READ(ACTHD_I965); | 354 | error->acthd = I915_READ(ACTHD_I965); |
326 | } | 355 | } |
327 | 356 | ||
357 | do_gettimeofday(&error->time); | ||
358 | |||
328 | dev_priv->first_error = error; | 359 | dev_priv->first_error = error; |
329 | 360 | ||
330 | out: | 361 | out: |
331 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | 362 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); |
332 | } | 363 | } |
333 | 364 | ||
365 | /** | ||
366 | * i915_handle_error - handle an error interrupt | ||
367 | * @dev: drm device | ||
368 | * | ||
369 | * Do some basic checking of regsiter state at error interrupt time and | ||
370 | * dump it to the syslog. Also call i915_capture_error_state() to make | ||
371 | * sure we get a record and make it available in debugfs. Fire a uevent | ||
372 | * so userspace knows something bad happened (should trigger collection | ||
373 | * of a ring dump etc.). | ||
374 | */ | ||
375 | static void i915_handle_error(struct drm_device *dev) | ||
376 | { | ||
377 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
378 | u32 eir = I915_READ(EIR); | ||
379 | u32 pipea_stats = I915_READ(PIPEASTAT); | ||
380 | u32 pipeb_stats = I915_READ(PIPEBSTAT); | ||
381 | |||
382 | i915_capture_error_state(dev); | ||
383 | |||
384 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", | ||
385 | eir); | ||
386 | |||
387 | if (IS_G4X(dev)) { | ||
388 | if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) { | ||
389 | u32 ipeir = I915_READ(IPEIR_I965); | ||
390 | |||
391 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
392 | I915_READ(IPEIR_I965)); | ||
393 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
394 | I915_READ(IPEHR_I965)); | ||
395 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
396 | I915_READ(INSTDONE_I965)); | ||
397 | printk(KERN_ERR " INSTPS: 0x%08x\n", | ||
398 | I915_READ(INSTPS)); | ||
399 | printk(KERN_ERR " INSTDONE1: 0x%08x\n", | ||
400 | I915_READ(INSTDONE1)); | ||
401 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
402 | I915_READ(ACTHD_I965)); | ||
403 | I915_WRITE(IPEIR_I965, ipeir); | ||
404 | (void)I915_READ(IPEIR_I965); | ||
405 | } | ||
406 | if (eir & GM45_ERROR_PAGE_TABLE) { | ||
407 | u32 pgtbl_err = I915_READ(PGTBL_ER); | ||
408 | printk(KERN_ERR "page table error\n"); | ||
409 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | ||
410 | pgtbl_err); | ||
411 | I915_WRITE(PGTBL_ER, pgtbl_err); | ||
412 | (void)I915_READ(PGTBL_ER); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | if (IS_I9XX(dev)) { | ||
417 | if (eir & I915_ERROR_PAGE_TABLE) { | ||
418 | u32 pgtbl_err = I915_READ(PGTBL_ER); | ||
419 | printk(KERN_ERR "page table error\n"); | ||
420 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | ||
421 | pgtbl_err); | ||
422 | I915_WRITE(PGTBL_ER, pgtbl_err); | ||
423 | (void)I915_READ(PGTBL_ER); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | if (eir & I915_ERROR_MEMORY_REFRESH) { | ||
428 | printk(KERN_ERR "memory refresh error\n"); | ||
429 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", | ||
430 | pipea_stats); | ||
431 | printk(KERN_ERR "PIPEBSTAT: 0x%08x\n", | ||
432 | pipeb_stats); | ||
433 | /* pipestat has already been acked */ | ||
434 | } | ||
435 | if (eir & I915_ERROR_INSTRUCTION) { | ||
436 | printk(KERN_ERR "instruction error\n"); | ||
437 | printk(KERN_ERR " INSTPM: 0x%08x\n", | ||
438 | I915_READ(INSTPM)); | ||
439 | if (!IS_I965G(dev)) { | ||
440 | u32 ipeir = I915_READ(IPEIR); | ||
441 | |||
442 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
443 | I915_READ(IPEIR)); | ||
444 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
445 | I915_READ(IPEHR)); | ||
446 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
447 | I915_READ(INSTDONE)); | ||
448 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
449 | I915_READ(ACTHD)); | ||
450 | I915_WRITE(IPEIR, ipeir); | ||
451 | (void)I915_READ(IPEIR); | ||
452 | } else { | ||
453 | u32 ipeir = I915_READ(IPEIR_I965); | ||
454 | |||
455 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
456 | I915_READ(IPEIR_I965)); | ||
457 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
458 | I915_READ(IPEHR_I965)); | ||
459 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
460 | I915_READ(INSTDONE_I965)); | ||
461 | printk(KERN_ERR " INSTPS: 0x%08x\n", | ||
462 | I915_READ(INSTPS)); | ||
463 | printk(KERN_ERR " INSTDONE1: 0x%08x\n", | ||
464 | I915_READ(INSTDONE1)); | ||
465 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
466 | I915_READ(ACTHD_I965)); | ||
467 | I915_WRITE(IPEIR_I965, ipeir); | ||
468 | (void)I915_READ(IPEIR_I965); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | I915_WRITE(EIR, eir); | ||
473 | (void)I915_READ(EIR); | ||
474 | eir = I915_READ(EIR); | ||
475 | if (eir) { | ||
476 | /* | ||
477 | * some errors might have become stuck, | ||
478 | * mask them. | ||
479 | */ | ||
480 | DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir); | ||
481 | I915_WRITE(EMR, I915_READ(EMR) | eir); | ||
482 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); | ||
483 | } | ||
484 | |||
485 | queue_work(dev_priv->wq, &dev_priv->error_work); | ||
486 | } | ||
487 | |||
334 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 488 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
335 | { | 489 | { |
336 | struct drm_device *dev = (struct drm_device *) arg; | 490 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -372,6 +526,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
372 | pipea_stats = I915_READ(PIPEASTAT); | 526 | pipea_stats = I915_READ(PIPEASTAT); |
373 | pipeb_stats = I915_READ(PIPEBSTAT); | 527 | pipeb_stats = I915_READ(PIPEBSTAT); |
374 | 528 | ||
529 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | ||
530 | i915_handle_error(dev); | ||
531 | |||
375 | /* | 532 | /* |
376 | * Clear the PIPE(A|B)STAT regs before the IIR | 533 | * Clear the PIPE(A|B)STAT regs before the IIR |
377 | */ | 534 | */ |
@@ -403,86 +560,13 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
403 | DRM_DEBUG("hotplug event received, stat 0x%08x\n", | 560 | DRM_DEBUG("hotplug event received, stat 0x%08x\n", |
404 | hotplug_status); | 561 | hotplug_status); |
405 | if (hotplug_status & dev_priv->hotplug_supported_mask) | 562 | if (hotplug_status & dev_priv->hotplug_supported_mask) |
406 | schedule_work(&dev_priv->hotplug_work); | 563 | queue_work(dev_priv->wq, |
564 | &dev_priv->hotplug_work); | ||
407 | 565 | ||
408 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); | 566 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
409 | I915_READ(PORT_HOTPLUG_STAT); | 567 | I915_READ(PORT_HOTPLUG_STAT); |
410 | } | 568 | } |
411 | 569 | ||
412 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) { | ||
413 | u32 eir = I915_READ(EIR); | ||
414 | |||
415 | i915_capture_error_state(dev); | ||
416 | |||
417 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", | ||
418 | eir); | ||
419 | if (eir & I915_ERROR_PAGE_TABLE) { | ||
420 | u32 pgtbl_err = I915_READ(PGTBL_ER); | ||
421 | printk(KERN_ERR "page table error\n"); | ||
422 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | ||
423 | pgtbl_err); | ||
424 | I915_WRITE(PGTBL_ER, pgtbl_err); | ||
425 | (void)I915_READ(PGTBL_ER); | ||
426 | } | ||
427 | if (eir & I915_ERROR_MEMORY_REFRESH) { | ||
428 | printk(KERN_ERR "memory refresh error\n"); | ||
429 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", | ||
430 | pipea_stats); | ||
431 | printk(KERN_ERR "PIPEBSTAT: 0x%08x\n", | ||
432 | pipeb_stats); | ||
433 | /* pipestat has already been acked */ | ||
434 | } | ||
435 | if (eir & I915_ERROR_INSTRUCTION) { | ||
436 | printk(KERN_ERR "instruction error\n"); | ||
437 | printk(KERN_ERR " INSTPM: 0x%08x\n", | ||
438 | I915_READ(INSTPM)); | ||
439 | if (!IS_I965G(dev)) { | ||
440 | u32 ipeir = I915_READ(IPEIR); | ||
441 | |||
442 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
443 | I915_READ(IPEIR)); | ||
444 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
445 | I915_READ(IPEHR)); | ||
446 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
447 | I915_READ(INSTDONE)); | ||
448 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
449 | I915_READ(ACTHD)); | ||
450 | I915_WRITE(IPEIR, ipeir); | ||
451 | (void)I915_READ(IPEIR); | ||
452 | } else { | ||
453 | u32 ipeir = I915_READ(IPEIR_I965); | ||
454 | |||
455 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
456 | I915_READ(IPEIR_I965)); | ||
457 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
458 | I915_READ(IPEHR_I965)); | ||
459 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
460 | I915_READ(INSTDONE_I965)); | ||
461 | printk(KERN_ERR " INSTPS: 0x%08x\n", | ||
462 | I915_READ(INSTPS)); | ||
463 | printk(KERN_ERR " INSTDONE1: 0x%08x\n", | ||
464 | I915_READ(INSTDONE1)); | ||
465 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
466 | I915_READ(ACTHD_I965)); | ||
467 | I915_WRITE(IPEIR_I965, ipeir); | ||
468 | (void)I915_READ(IPEIR_I965); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | I915_WRITE(EIR, eir); | ||
473 | (void)I915_READ(EIR); | ||
474 | eir = I915_READ(EIR); | ||
475 | if (eir) { | ||
476 | /* | ||
477 | * some errors might have become stuck, | ||
478 | * mask them. | ||
479 | */ | ||
480 | DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir); | ||
481 | I915_WRITE(EMR, I915_READ(EMR) | eir); | ||
482 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); | ||
483 | } | ||
484 | } | ||
485 | |||
486 | I915_WRITE(IIR, iir); | 570 | I915_WRITE(IIR, iir); |
487 | new_iir = I915_READ(IIR); /* Flush posted writes */ | 571 | new_iir = I915_READ(IIR); /* Flush posted writes */ |
488 | 572 | ||
@@ -830,6 +914,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
830 | atomic_set(&dev_priv->irq_received, 0); | 914 | atomic_set(&dev_priv->irq_received, 0); |
831 | 915 | ||
832 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); | 916 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); |
917 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); | ||
833 | 918 | ||
834 | if (IS_IGDNG(dev)) { | 919 | if (IS_IGDNG(dev)) { |
835 | igdng_irq_preinstall(dev); | 920 | igdng_irq_preinstall(dev); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6c0858484094..2955083aa471 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1395,6 +1395,7 @@ | |||
1395 | #define TV_V_CHROMA_42 0x684a8 | 1395 | #define TV_V_CHROMA_42 0x684a8 |
1396 | 1396 | ||
1397 | /* Display Port */ | 1397 | /* Display Port */ |
1398 | #define DP_A 0x64000 /* eDP */ | ||
1398 | #define DP_B 0x64100 | 1399 | #define DP_B 0x64100 |
1399 | #define DP_C 0x64200 | 1400 | #define DP_C 0x64200 |
1400 | #define DP_D 0x64300 | 1401 | #define DP_D 0x64300 |
@@ -1437,13 +1438,22 @@ | |||
1437 | /* Mystic DPCD version 1.1 special mode */ | 1438 | /* Mystic DPCD version 1.1 special mode */ |
1438 | #define DP_ENHANCED_FRAMING (1 << 18) | 1439 | #define DP_ENHANCED_FRAMING (1 << 18) |
1439 | 1440 | ||
1441 | /* eDP */ | ||
1442 | #define DP_PLL_FREQ_270MHZ (0 << 16) | ||
1443 | #define DP_PLL_FREQ_160MHZ (1 << 16) | ||
1444 | #define DP_PLL_FREQ_MASK (3 << 16) | ||
1445 | |||
1440 | /** locked once port is enabled */ | 1446 | /** locked once port is enabled */ |
1441 | #define DP_PORT_REVERSAL (1 << 15) | 1447 | #define DP_PORT_REVERSAL (1 << 15) |
1442 | 1448 | ||
1449 | /* eDP */ | ||
1450 | #define DP_PLL_ENABLE (1 << 14) | ||
1451 | |||
1443 | /** sends the clock on lane 15 of the PEG for debug */ | 1452 | /** sends the clock on lane 15 of the PEG for debug */ |
1444 | #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) | 1453 | #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) |
1445 | 1454 | ||
1446 | #define DP_SCRAMBLING_DISABLE (1 << 12) | 1455 | #define DP_SCRAMBLING_DISABLE (1 << 12) |
1456 | #define DP_SCRAMBLING_DISABLE_IGDNG (1 << 7) | ||
1447 | 1457 | ||
1448 | /** limit RGB values to avoid confusing TVs */ | 1458 | /** limit RGB values to avoid confusing TVs */ |
1449 | #define DP_COLOR_RANGE_16_235 (1 << 8) | 1459 | #define DP_COLOR_RANGE_16_235 (1 << 8) |
@@ -1463,6 +1473,13 @@ | |||
1463 | * is 20 bytes in each direction, hence the 5 fixed | 1473 | * is 20 bytes in each direction, hence the 5 fixed |
1464 | * data registers | 1474 | * data registers |
1465 | */ | 1475 | */ |
1476 | #define DPA_AUX_CH_CTL 0x64010 | ||
1477 | #define DPA_AUX_CH_DATA1 0x64014 | ||
1478 | #define DPA_AUX_CH_DATA2 0x64018 | ||
1479 | #define DPA_AUX_CH_DATA3 0x6401c | ||
1480 | #define DPA_AUX_CH_DATA4 0x64020 | ||
1481 | #define DPA_AUX_CH_DATA5 0x64024 | ||
1482 | |||
1466 | #define DPB_AUX_CH_CTL 0x64110 | 1483 | #define DPB_AUX_CH_CTL 0x64110 |
1467 | #define DPB_AUX_CH_DATA1 0x64114 | 1484 | #define DPB_AUX_CH_DATA1 0x64114 |
1468 | #define DPB_AUX_CH_DATA2 0x64118 | 1485 | #define DPB_AUX_CH_DATA2 0x64118 |
@@ -1618,7 +1635,7 @@ | |||
1618 | #define I830_FIFO_LINE_SIZE 32 | 1635 | #define I830_FIFO_LINE_SIZE 32 |
1619 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ | 1636 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ |
1620 | #define I915_FIFO_SIZE 95 | 1637 | #define I915_FIFO_SIZE 95 |
1621 | #define I855GM_FIFO_SIZE 255 | 1638 | #define I855GM_FIFO_SIZE 127 /* In cachelines */ |
1622 | #define I830_FIFO_SIZE 95 | 1639 | #define I830_FIFO_SIZE 95 |
1623 | #define I915_MAX_WM 0x3f | 1640 | #define I915_MAX_WM 0x3f |
1624 | 1641 | ||
@@ -1848,6 +1865,8 @@ | |||
1848 | #define PFA_CTL_1 0x68080 | 1865 | #define PFA_CTL_1 0x68080 |
1849 | #define PFB_CTL_1 0x68880 | 1866 | #define PFB_CTL_1 0x68880 |
1850 | #define PF_ENABLE (1<<31) | 1867 | #define PF_ENABLE (1<<31) |
1868 | #define PFA_WIN_SZ 0x68074 | ||
1869 | #define PFB_WIN_SZ 0x68874 | ||
1851 | 1870 | ||
1852 | /* legacy palette */ | 1871 | /* legacy palette */ |
1853 | #define LGC_PALETTE_A 0x4a000 | 1872 | #define LGC_PALETTE_A 0x4a000 |
@@ -2208,4 +2227,28 @@ | |||
2208 | #define PCH_PP_OFF_DELAYS 0xc720c | 2227 | #define PCH_PP_OFF_DELAYS 0xc720c |
2209 | #define PCH_PP_DIVISOR 0xc7210 | 2228 | #define PCH_PP_DIVISOR 0xc7210 |
2210 | 2229 | ||
2230 | #define PCH_DP_B 0xe4100 | ||
2231 | #define PCH_DPB_AUX_CH_CTL 0xe4110 | ||
2232 | #define PCH_DPB_AUX_CH_DATA1 0xe4114 | ||
2233 | #define PCH_DPB_AUX_CH_DATA2 0xe4118 | ||
2234 | #define PCH_DPB_AUX_CH_DATA3 0xe411c | ||
2235 | #define PCH_DPB_AUX_CH_DATA4 0xe4120 | ||
2236 | #define PCH_DPB_AUX_CH_DATA5 0xe4124 | ||
2237 | |||
2238 | #define PCH_DP_C 0xe4200 | ||
2239 | #define PCH_DPC_AUX_CH_CTL 0xe4210 | ||
2240 | #define PCH_DPC_AUX_CH_DATA1 0xe4214 | ||
2241 | #define PCH_DPC_AUX_CH_DATA2 0xe4218 | ||
2242 | #define PCH_DPC_AUX_CH_DATA3 0xe421c | ||
2243 | #define PCH_DPC_AUX_CH_DATA4 0xe4220 | ||
2244 | #define PCH_DPC_AUX_CH_DATA5 0xe4224 | ||
2245 | |||
2246 | #define PCH_DP_D 0xe4300 | ||
2247 | #define PCH_DPD_AUX_CH_CTL 0xe4310 | ||
2248 | #define PCH_DPD_AUX_CH_DATA1 0xe4314 | ||
2249 | #define PCH_DPD_AUX_CH_DATA2 0xe4318 | ||
2250 | #define PCH_DPD_AUX_CH_DATA3 0xe431c | ||
2251 | #define PCH_DPD_AUX_CH_DATA4 0xe4320 | ||
2252 | #define PCH_DPD_AUX_CH_DATA5 0xe4324 | ||
2253 | |||
2211 | #endif /* _I915_REG_H_ */ | 2254 | #endif /* _I915_REG_H_ */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 9e1d16e5c3ea..1d04e1904ac6 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -598,7 +598,7 @@ int i915_restore_state(struct drm_device *dev) | |||
598 | 598 | ||
599 | for (i = 0; i < 16; i++) { | 599 | for (i = 0; i < 16; i++) { |
600 | I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); | 600 | I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); |
601 | I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); | 601 | I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i]); |
602 | } | 602 | } |
603 | for (i = 0; i < 3; i++) | 603 | for (i = 0; i < 3; i++) |
604 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | 604 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 7cc447191028..f806fcc54e09 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id) | |||
59 | return NULL; | 59 | return NULL; |
60 | } | 60 | } |
61 | 61 | ||
62 | static u16 | ||
63 | get_blocksize(void *p) | ||
64 | { | ||
65 | u16 *block_ptr, block_size; | ||
66 | |||
67 | block_ptr = (u16 *)((char *)p - 2); | ||
68 | block_size = *block_ptr; | ||
69 | return block_size; | ||
70 | } | ||
71 | |||
62 | static void | 72 | static void |
63 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | 73 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, |
64 | struct lvds_dvo_timing *dvo_timing) | 74 | struct lvds_dvo_timing *dvo_timing) |
@@ -97,14 +107,13 @@ static void | |||
97 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, | 107 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, |
98 | struct bdb_header *bdb) | 108 | struct bdb_header *bdb) |
99 | { | 109 | { |
100 | struct drm_device *dev = dev_priv->dev; | ||
101 | struct bdb_lvds_options *lvds_options; | 110 | struct bdb_lvds_options *lvds_options; |
102 | struct bdb_lvds_lfp_data *lvds_lfp_data; | 111 | struct bdb_lvds_lfp_data *lvds_lfp_data; |
103 | struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; | 112 | struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; |
104 | struct bdb_lvds_lfp_data_entry *entry; | 113 | struct bdb_lvds_lfp_data_entry *entry; |
105 | struct lvds_dvo_timing *dvo_timing; | 114 | struct lvds_dvo_timing *dvo_timing; |
106 | struct drm_display_mode *panel_fixed_mode; | 115 | struct drm_display_mode *panel_fixed_mode; |
107 | int lfp_data_size; | 116 | int lfp_data_size, dvo_timing_offset; |
108 | 117 | ||
109 | /* Defaults if we can't find VBT info */ | 118 | /* Defaults if we can't find VBT info */ |
110 | dev_priv->lvds_dither = 0; | 119 | dev_priv->lvds_dither = 0; |
@@ -133,14 +142,16 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
133 | entry = (struct bdb_lvds_lfp_data_entry *) | 142 | entry = (struct bdb_lvds_lfp_data_entry *) |
134 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * | 143 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * |
135 | lvds_options->panel_type)); | 144 | lvds_options->panel_type)); |
145 | dvo_timing_offset = lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset - | ||
146 | lvds_lfp_data_ptrs->ptr[0].fp_timing_offset; | ||
136 | 147 | ||
137 | /* On IGDNG mobile, LVDS data block removes panel fitting registers. | 148 | /* |
138 | So dec 2 dword from dvo_timing offset */ | 149 | * the size of fp_timing varies on the different platform. |
139 | if (IS_IGDNG(dev)) | 150 | * So calculate the DVO timing relative offset in LVDS data |
140 | dvo_timing = (struct lvds_dvo_timing *) | 151 | * entry to get the DVO timing entry |
141 | ((u8 *)&entry->dvo_timing - 8); | 152 | */ |
142 | else | 153 | dvo_timing = (struct lvds_dvo_timing *) |
143 | dvo_timing = &entry->dvo_timing; | 154 | ((unsigned char *)entry + dvo_timing_offset); |
144 | 155 | ||
145 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); | 156 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
146 | 157 | ||
@@ -214,6 +225,41 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
214 | } | 225 | } |
215 | 226 | ||
216 | static void | 227 | static void |
228 | parse_general_definitions(struct drm_i915_private *dev_priv, | ||
229 | struct bdb_header *bdb) | ||
230 | { | ||
231 | struct bdb_general_definitions *general; | ||
232 | const int crt_bus_map_table[] = { | ||
233 | GPIOB, | ||
234 | GPIOA, | ||
235 | GPIOC, | ||
236 | GPIOD, | ||
237 | GPIOE, | ||
238 | GPIOF, | ||
239 | }; | ||
240 | |||
241 | /* Set sensible defaults in case we can't find the general block | ||
242 | or it is the wrong chipset */ | ||
243 | dev_priv->crt_ddc_bus = -1; | ||
244 | |||
245 | general = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
246 | if (general) { | ||
247 | u16 block_size = get_blocksize(general); | ||
248 | if (block_size >= sizeof(*general)) { | ||
249 | int bus_pin = general->crt_ddc_gmbus_pin; | ||
250 | DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin); | ||
251 | if ((bus_pin >= 1) && (bus_pin <= 6)) { | ||
252 | dev_priv->crt_ddc_bus = | ||
253 | crt_bus_map_table[bus_pin-1]; | ||
254 | } | ||
255 | } else { | ||
256 | DRM_DEBUG("BDB_GD too small (%d). Invalid.\n", | ||
257 | block_size); | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static void | ||
217 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | 263 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, |
218 | struct bdb_header *bdb) | 264 | struct bdb_header *bdb) |
219 | { | 265 | { |
@@ -221,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
221 | struct bdb_general_definitions *p_defs; | 267 | struct bdb_general_definitions *p_defs; |
222 | struct child_device_config *p_child; | 268 | struct child_device_config *p_child; |
223 | int i, child_device_num, count; | 269 | int i, child_device_num, count; |
224 | u16 block_size, *block_ptr; | 270 | u16 block_size; |
225 | 271 | ||
226 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 272 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
227 | if (!p_defs) { | 273 | if (!p_defs) { |
@@ -239,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
239 | return; | 285 | return; |
240 | } | 286 | } |
241 | /* get the block size of general definitions */ | 287 | /* get the block size of general definitions */ |
242 | block_ptr = (u16 *)((char *)p_defs - 2); | 288 | block_size = get_blocksize(p_defs); |
243 | block_size = *block_ptr; | ||
244 | /* get the number of child device */ | 289 | /* get the number of child device */ |
245 | child_device_num = (block_size - sizeof(*p_defs)) / | 290 | child_device_num = (block_size - sizeof(*p_defs)) / |
246 | sizeof(*p_child); | 291 | sizeof(*p_child); |
@@ -295,6 +340,25 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
295 | } | 340 | } |
296 | return; | 341 | return; |
297 | } | 342 | } |
343 | |||
344 | static void | ||
345 | parse_driver_features(struct drm_i915_private *dev_priv, | ||
346 | struct bdb_header *bdb) | ||
347 | { | ||
348 | struct drm_device *dev = dev_priv->dev; | ||
349 | struct bdb_driver_features *driver; | ||
350 | |||
351 | /* set default for chips without eDP */ | ||
352 | if (!SUPPORTS_EDP(dev)) { | ||
353 | dev_priv->edp_support = 0; | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | driver = find_section(bdb, BDB_DRIVER_FEATURES); | ||
358 | if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP) | ||
359 | dev_priv->edp_support = 1; | ||
360 | } | ||
361 | |||
298 | /** | 362 | /** |
299 | * intel_init_bios - initialize VBIOS settings & find VBT | 363 | * intel_init_bios - initialize VBIOS settings & find VBT |
300 | * @dev: DRM device | 364 | * @dev: DRM device |
@@ -342,9 +406,12 @@ intel_init_bios(struct drm_device *dev) | |||
342 | 406 | ||
343 | /* Grab useful general definitions */ | 407 | /* Grab useful general definitions */ |
344 | parse_general_features(dev_priv, bdb); | 408 | parse_general_features(dev_priv, bdb); |
409 | parse_general_definitions(dev_priv, bdb); | ||
345 | parse_lfp_panel_data(dev_priv, bdb); | 410 | parse_lfp_panel_data(dev_priv, bdb); |
346 | parse_sdvo_panel_data(dev_priv, bdb); | 411 | parse_sdvo_panel_data(dev_priv, bdb); |
347 | parse_sdvo_device_mapping(dev_priv, bdb); | 412 | parse_sdvo_device_mapping(dev_priv, bdb); |
413 | parse_driver_features(dev_priv, bdb); | ||
414 | |||
348 | pci_unmap_rom(pdev, bios); | 415 | pci_unmap_rom(pdev, bios); |
349 | 416 | ||
350 | return 0; | 417 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index fe72e1c225d8..0f8e5f69ac7a 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -381,6 +381,51 @@ struct bdb_sdvo_lvds_options { | |||
381 | } __attribute__((packed)); | 381 | } __attribute__((packed)); |
382 | 382 | ||
383 | 383 | ||
384 | #define BDB_DRIVER_FEATURE_NO_LVDS 0 | ||
385 | #define BDB_DRIVER_FEATURE_INT_LVDS 1 | ||
386 | #define BDB_DRIVER_FEATURE_SDVO_LVDS 2 | ||
387 | #define BDB_DRIVER_FEATURE_EDP 3 | ||
388 | |||
389 | struct bdb_driver_features { | ||
390 | u8 boot_dev_algorithm:1; | ||
391 | u8 block_display_switch:1; | ||
392 | u8 allow_display_switch:1; | ||
393 | u8 hotplug_dvo:1; | ||
394 | u8 dual_view_zoom:1; | ||
395 | u8 int15h_hook:1; | ||
396 | u8 sprite_in_clone:1; | ||
397 | u8 primary_lfp_id:1; | ||
398 | |||
399 | u16 boot_mode_x; | ||
400 | u16 boot_mode_y; | ||
401 | u8 boot_mode_bpp; | ||
402 | u8 boot_mode_refresh; | ||
403 | |||
404 | u16 enable_lfp_primary:1; | ||
405 | u16 selective_mode_pruning:1; | ||
406 | u16 dual_frequency:1; | ||
407 | u16 render_clock_freq:1; /* 0: high freq; 1: low freq */ | ||
408 | u16 nt_clone_support:1; | ||
409 | u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */ | ||
410 | u16 sprite_display_assign:1; /* 0: secondary; 1: primary */ | ||
411 | u16 cui_aspect_scaling:1; | ||
412 | u16 preserve_aspect_ratio:1; | ||
413 | u16 sdvo_device_power_down:1; | ||
414 | u16 crt_hotplug:1; | ||
415 | u16 lvds_config:2; | ||
416 | u16 tv_hotplug:1; | ||
417 | u16 hdmi_config:2; | ||
418 | |||
419 | u8 static_display:1; | ||
420 | u8 reserved2:7; | ||
421 | u16 legacy_crt_max_x; | ||
422 | u16 legacy_crt_max_y; | ||
423 | u8 legacy_crt_max_refresh; | ||
424 | |||
425 | u8 hdmi_termination; | ||
426 | u8 custom_vbt_version; | ||
427 | } __attribute__((packed)); | ||
428 | |||
384 | bool intel_init_bios(struct drm_device *dev); | 429 | bool intel_init_bios(struct drm_device *dev); |
385 | 430 | ||
386 | /* | 431 | /* |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index d6a1a6e5539a..590f81c8f594 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -156,6 +156,9 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector) | |||
156 | 156 | ||
157 | temp = adpa = I915_READ(PCH_ADPA); | 157 | temp = adpa = I915_READ(PCH_ADPA); |
158 | 158 | ||
159 | adpa &= ~ADPA_DAC_ENABLE; | ||
160 | I915_WRITE(PCH_ADPA, adpa); | ||
161 | |||
159 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 162 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; |
160 | 163 | ||
161 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 164 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | |
@@ -169,13 +172,14 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector) | |||
169 | DRM_DEBUG("pch crt adpa 0x%x", adpa); | 172 | DRM_DEBUG("pch crt adpa 0x%x", adpa); |
170 | I915_WRITE(PCH_ADPA, adpa); | 173 | I915_WRITE(PCH_ADPA, adpa); |
171 | 174 | ||
172 | /* This might not be needed as not specified in spec...*/ | 175 | while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) |
173 | udelay(1000); | 176 | ; |
174 | 177 | ||
175 | /* Check the status to see if both blue and green are on now */ | 178 | /* Check the status to see if both blue and green are on now */ |
176 | adpa = I915_READ(PCH_ADPA); | 179 | adpa = I915_READ(PCH_ADPA); |
177 | if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) == | 180 | adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK; |
178 | ADPA_CRT_HOTPLUG_MONITOR_COLOR) | 181 | if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) || |
182 | (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO)) | ||
179 | ret = true; | 183 | ret = true; |
180 | else | 184 | else |
181 | ret = false; | 185 | ret = false; |
@@ -504,6 +508,7 @@ void intel_crt_init(struct drm_device *dev) | |||
504 | { | 508 | { |
505 | struct drm_connector *connector; | 509 | struct drm_connector *connector; |
506 | struct intel_output *intel_output; | 510 | struct intel_output *intel_output; |
511 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
507 | u32 i2c_reg; | 512 | u32 i2c_reg; |
508 | 513 | ||
509 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); | 514 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); |
@@ -523,8 +528,12 @@ void intel_crt_init(struct drm_device *dev) | |||
523 | /* Set up the DDC bus. */ | 528 | /* Set up the DDC bus. */ |
524 | if (IS_IGDNG(dev)) | 529 | if (IS_IGDNG(dev)) |
525 | i2c_reg = PCH_GPIOA; | 530 | i2c_reg = PCH_GPIOA; |
526 | else | 531 | else { |
527 | i2c_reg = GPIOA; | 532 | i2c_reg = GPIOA; |
533 | /* Use VBT information for CRT DDC if available */ | ||
534 | if (dev_priv->crt_ddc_bus != -1) | ||
535 | i2c_reg = dev_priv->crt_ddc_bus; | ||
536 | } | ||
528 | intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); | 537 | intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); |
529 | if (!intel_output->ddc_bus) { | 538 | if (!intel_output->ddc_bus) { |
530 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " | 539 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " |
@@ -533,6 +542,10 @@ void intel_crt_init(struct drm_device *dev) | |||
533 | } | 542 | } |
534 | 543 | ||
535 | intel_output->type = INTEL_OUTPUT_ANALOG; | 544 | intel_output->type = INTEL_OUTPUT_ANALOG; |
545 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
546 | (1 << INTEL_ANALOG_CLONE_BIT) | | ||
547 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
548 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
536 | connector->interlace_allowed = 0; | 549 | connector->interlace_allowed = 0; |
537 | connector->doublescan_allowed = 0; | 550 | connector->doublescan_allowed = 0; |
538 | 551 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 508838ee31e0..3fadb5358858 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
35 | #include "drm_crtc_helper.h" | 35 | #include "drm_crtc_helper.h" |
36 | 36 | ||
37 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) | ||
38 | |||
37 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 39 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
38 | static void intel_update_watermarks(struct drm_device *dev); | 40 | static void intel_update_watermarks(struct drm_device *dev); |
39 | 41 | ||
@@ -88,7 +90,7 @@ struct intel_limit { | |||
88 | #define I8XX_P2_SLOW 4 | 90 | #define I8XX_P2_SLOW 4 |
89 | #define I8XX_P2_FAST 2 | 91 | #define I8XX_P2_FAST 2 |
90 | #define I8XX_P2_LVDS_SLOW 14 | 92 | #define I8XX_P2_LVDS_SLOW 14 |
91 | #define I8XX_P2_LVDS_FAST 14 /* No fast option */ | 93 | #define I8XX_P2_LVDS_FAST 7 |
92 | #define I8XX_P2_SLOW_LIMIT 165000 | 94 | #define I8XX_P2_SLOW_LIMIT 165000 |
93 | 95 | ||
94 | #define I9XX_DOT_MIN 20000 | 96 | #define I9XX_DOT_MIN 20000 |
@@ -268,6 +270,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
268 | static bool | 270 | static bool |
269 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, | 271 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
270 | int target, int refclk, intel_clock_t *best_clock); | 272 | int target, int refclk, intel_clock_t *best_clock); |
273 | static bool | ||
274 | intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc, | ||
275 | int target, int refclk, intel_clock_t *best_clock); | ||
271 | 276 | ||
272 | static const intel_limit_t intel_limits_i8xx_dvo = { | 277 | static const intel_limit_t intel_limits_i8xx_dvo = { |
273 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 278 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
@@ -598,6 +603,23 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | |||
598 | return false; | 603 | return false; |
599 | } | 604 | } |
600 | 605 | ||
606 | struct drm_connector * | ||
607 | intel_pipe_get_output (struct drm_crtc *crtc) | ||
608 | { | ||
609 | struct drm_device *dev = crtc->dev; | ||
610 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
611 | struct drm_connector *l_entry, *ret = NULL; | ||
612 | |||
613 | list_for_each_entry(l_entry, &mode_config->connector_list, head) { | ||
614 | if (l_entry->encoder && | ||
615 | l_entry->encoder->crtc == crtc) { | ||
616 | ret = l_entry; | ||
617 | break; | ||
618 | } | ||
619 | } | ||
620 | return ret; | ||
621 | } | ||
622 | |||
601 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) | 623 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) |
602 | /** | 624 | /** |
603 | * Returns whether the given set of divisors are valid for a given refclk with | 625 | * Returns whether the given set of divisors are valid for a given refclk with |
@@ -644,8 +666,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
644 | intel_clock_t clock; | 666 | intel_clock_t clock; |
645 | int err = target; | 667 | int err = target; |
646 | 668 | ||
647 | if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | 669 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
648 | (I915_READ(LVDS) & LVDS_PORT_EN) != 0) { | 670 | (I915_READ(LVDS)) != 0) { |
649 | /* | 671 | /* |
650 | * For LVDS, if the panel is on, just rely on its current | 672 | * For LVDS, if the panel is on, just rely on its current |
651 | * settings for dual-channel. We haven't figured out how to | 673 | * settings for dual-channel. We haven't figured out how to |
@@ -752,6 +774,30 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
752 | } | 774 | } |
753 | 775 | ||
754 | static bool | 776 | static bool |
777 | intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
778 | int target, int refclk, intel_clock_t *best_clock) | ||
779 | { | ||
780 | struct drm_device *dev = crtc->dev; | ||
781 | intel_clock_t clock; | ||
782 | if (target < 200000) { | ||
783 | clock.n = 1; | ||
784 | clock.p1 = 2; | ||
785 | clock.p2 = 10; | ||
786 | clock.m1 = 12; | ||
787 | clock.m2 = 9; | ||
788 | } else { | ||
789 | clock.n = 2; | ||
790 | clock.p1 = 1; | ||
791 | clock.p2 = 10; | ||
792 | clock.m1 = 14; | ||
793 | clock.m2 = 8; | ||
794 | } | ||
795 | intel_clock(dev, refclk, &clock); | ||
796 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | ||
797 | return true; | ||
798 | } | ||
799 | |||
800 | static bool | ||
755 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 801 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
756 | int target, int refclk, intel_clock_t *best_clock) | 802 | int target, int refclk, intel_clock_t *best_clock) |
757 | { | 803 | { |
@@ -763,6 +809,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
763 | int err_most = 47; | 809 | int err_most = 47; |
764 | found = false; | 810 | found = false; |
765 | 811 | ||
812 | /* eDP has only 2 clock choice, no n/m/p setting */ | ||
813 | if (HAS_eDP) | ||
814 | return true; | ||
815 | |||
816 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) | ||
817 | return intel_find_pll_igdng_dp(limit, crtc, target, | ||
818 | refclk, best_clock); | ||
819 | |||
766 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 820 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
767 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | 821 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
768 | LVDS_CLKB_POWER_UP) | 822 | LVDS_CLKB_POWER_UP) |
@@ -998,6 +1052,90 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
998 | return 0; | 1052 | return 0; |
999 | } | 1053 | } |
1000 | 1054 | ||
1055 | /* Disable the VGA plane that we never use */ | ||
1056 | static void i915_disable_vga (struct drm_device *dev) | ||
1057 | { | ||
1058 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1059 | u8 sr1; | ||
1060 | u32 vga_reg; | ||
1061 | |||
1062 | if (IS_IGDNG(dev)) | ||
1063 | vga_reg = CPU_VGACNTRL; | ||
1064 | else | ||
1065 | vga_reg = VGACNTRL; | ||
1066 | |||
1067 | if (I915_READ(vga_reg) & VGA_DISP_DISABLE) | ||
1068 | return; | ||
1069 | |||
1070 | I915_WRITE8(VGA_SR_INDEX, 1); | ||
1071 | sr1 = I915_READ8(VGA_SR_DATA); | ||
1072 | I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5)); | ||
1073 | udelay(100); | ||
1074 | |||
1075 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
1076 | } | ||
1077 | |||
1078 | static void igdng_disable_pll_edp (struct drm_crtc *crtc) | ||
1079 | { | ||
1080 | struct drm_device *dev = crtc->dev; | ||
1081 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1082 | u32 dpa_ctl; | ||
1083 | |||
1084 | DRM_DEBUG("\n"); | ||
1085 | dpa_ctl = I915_READ(DP_A); | ||
1086 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
1087 | I915_WRITE(DP_A, dpa_ctl); | ||
1088 | } | ||
1089 | |||
1090 | static void igdng_enable_pll_edp (struct drm_crtc *crtc) | ||
1091 | { | ||
1092 | struct drm_device *dev = crtc->dev; | ||
1093 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1094 | u32 dpa_ctl; | ||
1095 | |||
1096 | dpa_ctl = I915_READ(DP_A); | ||
1097 | dpa_ctl |= DP_PLL_ENABLE; | ||
1098 | I915_WRITE(DP_A, dpa_ctl); | ||
1099 | udelay(200); | ||
1100 | } | ||
1101 | |||
1102 | |||
1103 | static void igdng_set_pll_edp (struct drm_crtc *crtc, int clock) | ||
1104 | { | ||
1105 | struct drm_device *dev = crtc->dev; | ||
1106 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1107 | u32 dpa_ctl; | ||
1108 | |||
1109 | DRM_DEBUG("eDP PLL enable for clock %d\n", clock); | ||
1110 | dpa_ctl = I915_READ(DP_A); | ||
1111 | dpa_ctl &= ~DP_PLL_FREQ_MASK; | ||
1112 | |||
1113 | if (clock < 200000) { | ||
1114 | u32 temp; | ||
1115 | dpa_ctl |= DP_PLL_FREQ_160MHZ; | ||
1116 | /* workaround for 160Mhz: | ||
1117 | 1) program 0x4600c bits 15:0 = 0x8124 | ||
1118 | 2) program 0x46010 bit 0 = 1 | ||
1119 | 3) program 0x46034 bit 24 = 1 | ||
1120 | 4) program 0x64000 bit 14 = 1 | ||
1121 | */ | ||
1122 | temp = I915_READ(0x4600c); | ||
1123 | temp &= 0xffff0000; | ||
1124 | I915_WRITE(0x4600c, temp | 0x8124); | ||
1125 | |||
1126 | temp = I915_READ(0x46010); | ||
1127 | I915_WRITE(0x46010, temp | 1); | ||
1128 | |||
1129 | temp = I915_READ(0x46034); | ||
1130 | I915_WRITE(0x46034, temp | (1 << 24)); | ||
1131 | } else { | ||
1132 | dpa_ctl |= DP_PLL_FREQ_270MHZ; | ||
1133 | } | ||
1134 | I915_WRITE(DP_A, dpa_ctl); | ||
1135 | |||
1136 | udelay(500); | ||
1137 | } | ||
1138 | |||
1001 | static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | 1139 | static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) |
1002 | { | 1140 | { |
1003 | struct drm_device *dev = crtc->dev; | 1141 | struct drm_device *dev = crtc->dev; |
@@ -1015,6 +1153,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1015 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | 1153 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; |
1016 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; | 1154 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; |
1017 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; | 1155 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; |
1156 | int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; | ||
1018 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; | 1157 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; |
1019 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; | 1158 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; |
1020 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; | 1159 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; |
@@ -1028,7 +1167,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1028 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; | 1167 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; |
1029 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1168 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
1030 | u32 temp; | 1169 | u32 temp; |
1031 | int tries = 5, j; | 1170 | int tries = 5, j, n; |
1032 | 1171 | ||
1033 | /* XXX: When our outputs are all unaware of DPMS modes other than off | 1172 | /* XXX: When our outputs are all unaware of DPMS modes other than off |
1034 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | 1173 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. |
@@ -1038,27 +1177,32 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1038 | case DRM_MODE_DPMS_STANDBY: | 1177 | case DRM_MODE_DPMS_STANDBY: |
1039 | case DRM_MODE_DPMS_SUSPEND: | 1178 | case DRM_MODE_DPMS_SUSPEND: |
1040 | DRM_DEBUG("crtc %d dpms on\n", pipe); | 1179 | DRM_DEBUG("crtc %d dpms on\n", pipe); |
1041 | /* enable PCH DPLL */ | 1180 | if (HAS_eDP) { |
1042 | temp = I915_READ(pch_dpll_reg); | 1181 | /* enable eDP PLL */ |
1043 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 1182 | igdng_enable_pll_edp(crtc); |
1044 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); | 1183 | } else { |
1045 | I915_READ(pch_dpll_reg); | 1184 | /* enable PCH DPLL */ |
1046 | } | 1185 | temp = I915_READ(pch_dpll_reg); |
1047 | 1186 | if ((temp & DPLL_VCO_ENABLE) == 0) { | |
1048 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1187 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); |
1049 | temp = I915_READ(fdi_rx_reg); | 1188 | I915_READ(pch_dpll_reg); |
1050 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | | 1189 | } |
1051 | FDI_SEL_PCDCLK | | ||
1052 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ | ||
1053 | I915_READ(fdi_rx_reg); | ||
1054 | udelay(200); | ||
1055 | 1190 | ||
1056 | /* Enable CPU FDI TX PLL, always on for IGDNG */ | 1191 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1057 | temp = I915_READ(fdi_tx_reg); | 1192 | temp = I915_READ(fdi_rx_reg); |
1058 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | 1193 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | |
1059 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | 1194 | FDI_SEL_PCDCLK | |
1060 | I915_READ(fdi_tx_reg); | 1195 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ |
1061 | udelay(100); | 1196 | I915_READ(fdi_rx_reg); |
1197 | udelay(200); | ||
1198 | |||
1199 | /* Enable CPU FDI TX PLL, always on for IGDNG */ | ||
1200 | temp = I915_READ(fdi_tx_reg); | ||
1201 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | ||
1202 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | ||
1203 | I915_READ(fdi_tx_reg); | ||
1204 | udelay(100); | ||
1205 | } | ||
1062 | } | 1206 | } |
1063 | 1207 | ||
1064 | /* Enable CPU pipe */ | 1208 | /* Enable CPU pipe */ |
@@ -1077,122 +1221,126 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1077 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 1221 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); |
1078 | } | 1222 | } |
1079 | 1223 | ||
1080 | /* enable CPU FDI TX and PCH FDI RX */ | 1224 | if (!HAS_eDP) { |
1081 | temp = I915_READ(fdi_tx_reg); | 1225 | /* enable CPU FDI TX and PCH FDI RX */ |
1082 | temp |= FDI_TX_ENABLE; | 1226 | temp = I915_READ(fdi_tx_reg); |
1083 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ | 1227 | temp |= FDI_TX_ENABLE; |
1084 | temp &= ~FDI_LINK_TRAIN_NONE; | 1228 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ |
1085 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1229 | temp &= ~FDI_LINK_TRAIN_NONE; |
1086 | I915_WRITE(fdi_tx_reg, temp); | 1230 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1087 | I915_READ(fdi_tx_reg); | 1231 | I915_WRITE(fdi_tx_reg, temp); |
1232 | I915_READ(fdi_tx_reg); | ||
1088 | 1233 | ||
1089 | temp = I915_READ(fdi_rx_reg); | 1234 | temp = I915_READ(fdi_rx_reg); |
1090 | temp &= ~FDI_LINK_TRAIN_NONE; | 1235 | temp &= ~FDI_LINK_TRAIN_NONE; |
1091 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1236 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1092 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | 1237 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); |
1093 | I915_READ(fdi_rx_reg); | 1238 | I915_READ(fdi_rx_reg); |
1094 | 1239 | ||
1095 | udelay(150); | 1240 | udelay(150); |
1096 | 1241 | ||
1097 | /* Train FDI. */ | 1242 | /* Train FDI. */ |
1098 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit | 1243 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit |
1099 | for train result */ | 1244 | for train result */ |
1100 | temp = I915_READ(fdi_rx_imr_reg); | 1245 | temp = I915_READ(fdi_rx_imr_reg); |
1101 | temp &= ~FDI_RX_SYMBOL_LOCK; | 1246 | temp &= ~FDI_RX_SYMBOL_LOCK; |
1102 | temp &= ~FDI_RX_BIT_LOCK; | 1247 | temp &= ~FDI_RX_BIT_LOCK; |
1103 | I915_WRITE(fdi_rx_imr_reg, temp); | 1248 | I915_WRITE(fdi_rx_imr_reg, temp); |
1104 | I915_READ(fdi_rx_imr_reg); | 1249 | I915_READ(fdi_rx_imr_reg); |
1105 | udelay(150); | 1250 | udelay(150); |
1106 | 1251 | ||
1107 | temp = I915_READ(fdi_rx_iir_reg); | 1252 | temp = I915_READ(fdi_rx_iir_reg); |
1108 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1253 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1109 | 1254 | ||
1110 | if ((temp & FDI_RX_BIT_LOCK) == 0) { | 1255 | if ((temp & FDI_RX_BIT_LOCK) == 0) { |
1111 | for (j = 0; j < tries; j++) { | 1256 | for (j = 0; j < tries; j++) { |
1112 | temp = I915_READ(fdi_rx_iir_reg); | 1257 | temp = I915_READ(fdi_rx_iir_reg); |
1113 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1258 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1114 | if (temp & FDI_RX_BIT_LOCK) | 1259 | if (temp & FDI_RX_BIT_LOCK) |
1115 | break; | 1260 | break; |
1116 | udelay(200); | 1261 | udelay(200); |
1117 | } | 1262 | } |
1118 | if (j != tries) | 1263 | if (j != tries) |
1264 | I915_WRITE(fdi_rx_iir_reg, | ||
1265 | temp | FDI_RX_BIT_LOCK); | ||
1266 | else | ||
1267 | DRM_DEBUG("train 1 fail\n"); | ||
1268 | } else { | ||
1119 | I915_WRITE(fdi_rx_iir_reg, | 1269 | I915_WRITE(fdi_rx_iir_reg, |
1120 | temp | FDI_RX_BIT_LOCK); | 1270 | temp | FDI_RX_BIT_LOCK); |
1121 | else | 1271 | DRM_DEBUG("train 1 ok 2!\n"); |
1122 | DRM_DEBUG("train 1 fail\n"); | 1272 | } |
1123 | } else { | 1273 | temp = I915_READ(fdi_tx_reg); |
1124 | I915_WRITE(fdi_rx_iir_reg, | 1274 | temp &= ~FDI_LINK_TRAIN_NONE; |
1125 | temp | FDI_RX_BIT_LOCK); | 1275 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1126 | DRM_DEBUG("train 1 ok 2!\n"); | 1276 | I915_WRITE(fdi_tx_reg, temp); |
1127 | } | 1277 | |
1128 | temp = I915_READ(fdi_tx_reg); | 1278 | temp = I915_READ(fdi_rx_reg); |
1129 | temp &= ~FDI_LINK_TRAIN_NONE; | 1279 | temp &= ~FDI_LINK_TRAIN_NONE; |
1130 | temp |= FDI_LINK_TRAIN_PATTERN_2; | 1280 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1131 | I915_WRITE(fdi_tx_reg, temp); | 1281 | I915_WRITE(fdi_rx_reg, temp); |
1132 | |||
1133 | temp = I915_READ(fdi_rx_reg); | ||
1134 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1135 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1136 | I915_WRITE(fdi_rx_reg, temp); | ||
1137 | 1282 | ||
1138 | udelay(150); | 1283 | udelay(150); |
1139 | 1284 | ||
1140 | temp = I915_READ(fdi_rx_iir_reg); | 1285 | temp = I915_READ(fdi_rx_iir_reg); |
1141 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1286 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1142 | 1287 | ||
1143 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { | 1288 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { |
1144 | for (j = 0; j < tries; j++) { | 1289 | for (j = 0; j < tries; j++) { |
1145 | temp = I915_READ(fdi_rx_iir_reg); | 1290 | temp = I915_READ(fdi_rx_iir_reg); |
1146 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1291 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1147 | if (temp & FDI_RX_SYMBOL_LOCK) | 1292 | if (temp & FDI_RX_SYMBOL_LOCK) |
1148 | break; | 1293 | break; |
1149 | udelay(200); | 1294 | udelay(200); |
1150 | } | 1295 | } |
1151 | if (j != tries) { | 1296 | if (j != tries) { |
1297 | I915_WRITE(fdi_rx_iir_reg, | ||
1298 | temp | FDI_RX_SYMBOL_LOCK); | ||
1299 | DRM_DEBUG("train 2 ok 1!\n"); | ||
1300 | } else | ||
1301 | DRM_DEBUG("train 2 fail\n"); | ||
1302 | } else { | ||
1152 | I915_WRITE(fdi_rx_iir_reg, | 1303 | I915_WRITE(fdi_rx_iir_reg, |
1153 | temp | FDI_RX_SYMBOL_LOCK); | 1304 | temp | FDI_RX_SYMBOL_LOCK); |
1154 | DRM_DEBUG("train 2 ok 1!\n"); | 1305 | DRM_DEBUG("train 2 ok 2!\n"); |
1155 | } else | 1306 | } |
1156 | DRM_DEBUG("train 2 fail\n"); | 1307 | DRM_DEBUG("train done\n"); |
1157 | } else { | ||
1158 | I915_WRITE(fdi_rx_iir_reg, temp | FDI_RX_SYMBOL_LOCK); | ||
1159 | DRM_DEBUG("train 2 ok 2!\n"); | ||
1160 | } | ||
1161 | DRM_DEBUG("train done\n"); | ||
1162 | 1308 | ||
1163 | /* set transcoder timing */ | 1309 | /* set transcoder timing */ |
1164 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); | 1310 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); |
1165 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); | 1311 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); |
1166 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); | 1312 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); |
1167 | 1313 | ||
1168 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); | 1314 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); |
1169 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); | 1315 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); |
1170 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); | 1316 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); |
1171 | 1317 | ||
1172 | /* enable PCH transcoder */ | 1318 | /* enable PCH transcoder */ |
1173 | temp = I915_READ(transconf_reg); | 1319 | temp = I915_READ(transconf_reg); |
1174 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 1320 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
1175 | I915_READ(transconf_reg); | 1321 | I915_READ(transconf_reg); |
1176 | 1322 | ||
1177 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 1323 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) |
1178 | ; | 1324 | ; |
1179 | 1325 | ||
1180 | /* enable normal */ | 1326 | /* enable normal */ |
1181 | 1327 | ||
1182 | temp = I915_READ(fdi_tx_reg); | 1328 | temp = I915_READ(fdi_tx_reg); |
1183 | temp &= ~FDI_LINK_TRAIN_NONE; | 1329 | temp &= ~FDI_LINK_TRAIN_NONE; |
1184 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | | 1330 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | |
1185 | FDI_TX_ENHANCE_FRAME_ENABLE); | 1331 | FDI_TX_ENHANCE_FRAME_ENABLE); |
1186 | I915_READ(fdi_tx_reg); | 1332 | I915_READ(fdi_tx_reg); |
1187 | 1333 | ||
1188 | temp = I915_READ(fdi_rx_reg); | 1334 | temp = I915_READ(fdi_rx_reg); |
1189 | temp &= ~FDI_LINK_TRAIN_NONE; | 1335 | temp &= ~FDI_LINK_TRAIN_NONE; |
1190 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | | 1336 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | |
1191 | FDI_RX_ENHANCE_FRAME_ENABLE); | 1337 | FDI_RX_ENHANCE_FRAME_ENABLE); |
1192 | I915_READ(fdi_rx_reg); | 1338 | I915_READ(fdi_rx_reg); |
1193 | 1339 | ||
1194 | /* wait one idle pattern time */ | 1340 | /* wait one idle pattern time */ |
1195 | udelay(100); | 1341 | udelay(100); |
1342 | |||
1343 | } | ||
1196 | 1344 | ||
1197 | intel_crtc_load_lut(crtc); | 1345 | intel_crtc_load_lut(crtc); |
1198 | 1346 | ||
@@ -1200,8 +1348,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1200 | case DRM_MODE_DPMS_OFF: | 1348 | case DRM_MODE_DPMS_OFF: |
1201 | DRM_DEBUG("crtc %d dpms off\n", pipe); | 1349 | DRM_DEBUG("crtc %d dpms off\n", pipe); |
1202 | 1350 | ||
1203 | /* Disable the VGA plane that we never use */ | 1351 | i915_disable_vga(dev); |
1204 | I915_WRITE(CPU_VGACNTRL, VGA_DISP_DISABLE); | ||
1205 | 1352 | ||
1206 | /* Disable display plane */ | 1353 | /* Disable display plane */ |
1207 | temp = I915_READ(dspcntr_reg); | 1354 | temp = I915_READ(dspcntr_reg); |
@@ -1217,17 +1364,23 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1217 | if ((temp & PIPEACONF_ENABLE) != 0) { | 1364 | if ((temp & PIPEACONF_ENABLE) != 0) { |
1218 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 1365 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); |
1219 | I915_READ(pipeconf_reg); | 1366 | I915_READ(pipeconf_reg); |
1367 | n = 0; | ||
1220 | /* wait for cpu pipe off, pipe state */ | 1368 | /* wait for cpu pipe off, pipe state */ |
1221 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) | 1369 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { |
1222 | ; | 1370 | n++; |
1371 | if (n < 60) { | ||
1372 | udelay(500); | ||
1373 | continue; | ||
1374 | } else { | ||
1375 | DRM_DEBUG("pipe %d off delay\n", pipe); | ||
1376 | break; | ||
1377 | } | ||
1378 | } | ||
1223 | } else | 1379 | } else |
1224 | DRM_DEBUG("crtc %d is disabled\n", pipe); | 1380 | DRM_DEBUG("crtc %d is disabled\n", pipe); |
1225 | 1381 | ||
1226 | /* IGDNG-A : disable cpu panel fitter ? */ | 1382 | if (HAS_eDP) { |
1227 | temp = I915_READ(pf_ctl_reg); | 1383 | igdng_disable_pll_edp(crtc); |
1228 | if ((temp & PF_ENABLE) != 0) { | ||
1229 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
1230 | I915_READ(pf_ctl_reg); | ||
1231 | } | 1384 | } |
1232 | 1385 | ||
1233 | /* disable CPU FDI tx and PCH FDI rx */ | 1386 | /* disable CPU FDI tx and PCH FDI rx */ |
@@ -1239,6 +1392,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1239 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); | 1392 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); |
1240 | I915_READ(fdi_rx_reg); | 1393 | I915_READ(fdi_rx_reg); |
1241 | 1394 | ||
1395 | udelay(100); | ||
1396 | |||
1242 | /* still set train pattern 1 */ | 1397 | /* still set train pattern 1 */ |
1243 | temp = I915_READ(fdi_tx_reg); | 1398 | temp = I915_READ(fdi_tx_reg); |
1244 | temp &= ~FDI_LINK_TRAIN_NONE; | 1399 | temp &= ~FDI_LINK_TRAIN_NONE; |
@@ -1250,14 +1405,25 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1250 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1405 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1251 | I915_WRITE(fdi_rx_reg, temp); | 1406 | I915_WRITE(fdi_rx_reg, temp); |
1252 | 1407 | ||
1408 | udelay(100); | ||
1409 | |||
1253 | /* disable PCH transcoder */ | 1410 | /* disable PCH transcoder */ |
1254 | temp = I915_READ(transconf_reg); | 1411 | temp = I915_READ(transconf_reg); |
1255 | if ((temp & TRANS_ENABLE) != 0) { | 1412 | if ((temp & TRANS_ENABLE) != 0) { |
1256 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 1413 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); |
1257 | I915_READ(transconf_reg); | 1414 | I915_READ(transconf_reg); |
1415 | n = 0; | ||
1258 | /* wait for PCH transcoder off, transcoder state */ | 1416 | /* wait for PCH transcoder off, transcoder state */ |
1259 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) | 1417 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { |
1260 | ; | 1418 | n++; |
1419 | if (n < 60) { | ||
1420 | udelay(500); | ||
1421 | continue; | ||
1422 | } else { | ||
1423 | DRM_DEBUG("transcoder %d off delay\n", pipe); | ||
1424 | break; | ||
1425 | } | ||
1426 | } | ||
1261 | } | 1427 | } |
1262 | 1428 | ||
1263 | /* disable PCH DPLL */ | 1429 | /* disable PCH DPLL */ |
@@ -1275,6 +1441,22 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1275 | I915_READ(fdi_rx_reg); | 1441 | I915_READ(fdi_rx_reg); |
1276 | } | 1442 | } |
1277 | 1443 | ||
1444 | /* Disable CPU FDI TX PLL */ | ||
1445 | temp = I915_READ(fdi_tx_reg); | ||
1446 | if ((temp & FDI_TX_PLL_ENABLE) != 0) { | ||
1447 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE); | ||
1448 | I915_READ(fdi_tx_reg); | ||
1449 | udelay(100); | ||
1450 | } | ||
1451 | |||
1452 | /* Disable PF */ | ||
1453 | temp = I915_READ(pf_ctl_reg); | ||
1454 | if ((temp & PF_ENABLE) != 0) { | ||
1455 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
1456 | I915_READ(pf_ctl_reg); | ||
1457 | } | ||
1458 | I915_WRITE(pf_win_size, 0); | ||
1459 | |||
1278 | /* Wait for the clocks to turn off. */ | 1460 | /* Wait for the clocks to turn off. */ |
1279 | udelay(150); | 1461 | udelay(150); |
1280 | break; | 1462 | break; |
@@ -1342,7 +1524,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1342 | //intel_crtc_dpms_video(crtc, FALSE); TODO | 1524 | //intel_crtc_dpms_video(crtc, FALSE); TODO |
1343 | 1525 | ||
1344 | /* Disable the VGA plane that we never use */ | 1526 | /* Disable the VGA plane that we never use */ |
1345 | I915_WRITE(VGACNTRL, VGA_DISP_DISABLE); | 1527 | i915_disable_vga(dev); |
1346 | 1528 | ||
1347 | /* Disable display plane */ | 1529 | /* Disable display plane */ |
1348 | temp = I915_READ(dspcntr_reg); | 1530 | temp = I915_READ(dspcntr_reg); |
@@ -1623,48 +1805,72 @@ static struct intel_watermark_params igd_cursor_hplloff_wm = { | |||
1623 | IGD_FIFO_LINE_SIZE | 1805 | IGD_FIFO_LINE_SIZE |
1624 | }; | 1806 | }; |
1625 | static struct intel_watermark_params i945_wm_info = { | 1807 | static struct intel_watermark_params i945_wm_info = { |
1626 | I915_FIFO_LINE_SIZE, | 1808 | I945_FIFO_SIZE, |
1627 | I915_MAX_WM, | 1809 | I915_MAX_WM, |
1628 | 1, | 1810 | 1, |
1629 | 0, | 1811 | 2, |
1630 | IGD_FIFO_LINE_SIZE | 1812 | I915_FIFO_LINE_SIZE |
1631 | }; | 1813 | }; |
1632 | static struct intel_watermark_params i915_wm_info = { | 1814 | static struct intel_watermark_params i915_wm_info = { |
1633 | I945_FIFO_SIZE, | 1815 | I915_FIFO_SIZE, |
1634 | I915_MAX_WM, | 1816 | I915_MAX_WM, |
1635 | 1, | 1817 | 1, |
1636 | 0, | 1818 | 2, |
1637 | I915_FIFO_LINE_SIZE | 1819 | I915_FIFO_LINE_SIZE |
1638 | }; | 1820 | }; |
1639 | static struct intel_watermark_params i855_wm_info = { | 1821 | static struct intel_watermark_params i855_wm_info = { |
1640 | I855GM_FIFO_SIZE, | 1822 | I855GM_FIFO_SIZE, |
1641 | I915_MAX_WM, | 1823 | I915_MAX_WM, |
1642 | 1, | 1824 | 1, |
1643 | 0, | 1825 | 2, |
1644 | I830_FIFO_LINE_SIZE | 1826 | I830_FIFO_LINE_SIZE |
1645 | }; | 1827 | }; |
1646 | static struct intel_watermark_params i830_wm_info = { | 1828 | static struct intel_watermark_params i830_wm_info = { |
1647 | I830_FIFO_SIZE, | 1829 | I830_FIFO_SIZE, |
1648 | I915_MAX_WM, | 1830 | I915_MAX_WM, |
1649 | 1, | 1831 | 1, |
1650 | 0, | 1832 | 2, |
1651 | I830_FIFO_LINE_SIZE | 1833 | I830_FIFO_LINE_SIZE |
1652 | }; | 1834 | }; |
1653 | 1835 | ||
1836 | /** | ||
1837 | * intel_calculate_wm - calculate watermark level | ||
1838 | * @clock_in_khz: pixel clock | ||
1839 | * @wm: chip FIFO params | ||
1840 | * @pixel_size: display pixel size | ||
1841 | * @latency_ns: memory latency for the platform | ||
1842 | * | ||
1843 | * Calculate the watermark level (the level at which the display plane will | ||
1844 | * start fetching from memory again). Each chip has a different display | ||
1845 | * FIFO size and allocation, so the caller needs to figure that out and pass | ||
1846 | * in the correct intel_watermark_params structure. | ||
1847 | * | ||
1848 | * As the pixel clock runs, the FIFO will be drained at a rate that depends | ||
1849 | * on the pixel size. When it reaches the watermark level, it'll start | ||
1850 | * fetching FIFO line sized based chunks from memory until the FIFO fills | ||
1851 | * past the watermark point. If the FIFO drains completely, a FIFO underrun | ||
1852 | * will occur, and a display engine hang could result. | ||
1853 | */ | ||
1654 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | 1854 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, |
1655 | struct intel_watermark_params *wm, | 1855 | struct intel_watermark_params *wm, |
1656 | int pixel_size, | 1856 | int pixel_size, |
1657 | unsigned long latency_ns) | 1857 | unsigned long latency_ns) |
1658 | { | 1858 | { |
1659 | unsigned long bytes_required, wm_size; | 1859 | long entries_required, wm_size; |
1660 | 1860 | ||
1661 | bytes_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; | 1861 | entries_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; |
1662 | bytes_required /= wm->cacheline_size; | 1862 | entries_required /= wm->cacheline_size; |
1663 | wm_size = wm->fifo_size - bytes_required - wm->guard_size; | ||
1664 | 1863 | ||
1665 | if (wm_size > wm->max_wm) | 1864 | DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required); |
1865 | |||
1866 | wm_size = wm->fifo_size - (entries_required + wm->guard_size); | ||
1867 | |||
1868 | DRM_DEBUG("FIFO watermark level: %d\n", wm_size); | ||
1869 | |||
1870 | /* Don't promote wm_size to unsigned... */ | ||
1871 | if (wm_size > (long)wm->max_wm) | ||
1666 | wm_size = wm->max_wm; | 1872 | wm_size = wm->max_wm; |
1667 | if (wm_size == 0) | 1873 | if (wm_size <= 0) |
1668 | wm_size = wm->default_wm; | 1874 | wm_size = wm->default_wm; |
1669 | return wm_size; | 1875 | return wm_size; |
1670 | } | 1876 | } |
@@ -1799,8 +2005,40 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, | |||
1799 | return; | 2005 | return; |
1800 | } | 2006 | } |
1801 | 2007 | ||
1802 | const static int latency_ns = 5000; /* default for non-igd platforms */ | 2008 | const static int latency_ns = 3000; /* default for non-igd platforms */ |
1803 | 2009 | ||
2010 | static int intel_get_fifo_size(struct drm_device *dev, int plane) | ||
2011 | { | ||
2012 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2013 | uint32_t dsparb = I915_READ(DSPARB); | ||
2014 | int size; | ||
2015 | |||
2016 | if (IS_I9XX(dev)) { | ||
2017 | if (plane == 0) | ||
2018 | size = dsparb & 0x7f; | ||
2019 | else | ||
2020 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - | ||
2021 | (dsparb & 0x7f); | ||
2022 | } else if (IS_I85X(dev)) { | ||
2023 | if (plane == 0) | ||
2024 | size = dsparb & 0x1ff; | ||
2025 | else | ||
2026 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - | ||
2027 | (dsparb & 0x1ff); | ||
2028 | size >>= 1; /* Convert to cachelines */ | ||
2029 | } else if (IS_845G(dev)) { | ||
2030 | size = dsparb & 0x7f; | ||
2031 | size >>= 2; /* Convert to cachelines */ | ||
2032 | } else { | ||
2033 | size = dsparb & 0x7f; | ||
2034 | size >>= 1; /* Convert to cachelines */ | ||
2035 | } | ||
2036 | |||
2037 | DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", | ||
2038 | size); | ||
2039 | |||
2040 | return size; | ||
2041 | } | ||
1804 | 2042 | ||
1805 | static void i965_update_wm(struct drm_device *dev) | 2043 | static void i965_update_wm(struct drm_device *dev) |
1806 | { | 2044 | { |
@@ -1817,101 +2055,89 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
1817 | int planeb_clock, int sr_hdisplay, int pixel_size) | 2055 | int planeb_clock, int sr_hdisplay, int pixel_size) |
1818 | { | 2056 | { |
1819 | struct drm_i915_private *dev_priv = dev->dev_private; | 2057 | struct drm_i915_private *dev_priv = dev->dev_private; |
1820 | uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; | 2058 | uint32_t fwater_lo; |
1821 | uint32_t fwater_hi = I915_READ(FW_BLC2) & LM_FIFO_WATERMARK; | 2059 | uint32_t fwater_hi; |
1822 | int bsize, asize, cwm, bwm = 1, awm = 1, srwm = 1; | 2060 | int total_size, cacheline_size, cwm, srwm = 1; |
1823 | uint32_t dsparb = I915_READ(DSPARB); | 2061 | int planea_wm, planeb_wm; |
1824 | int planea_entries, planeb_entries; | 2062 | struct intel_watermark_params planea_params, planeb_params; |
1825 | struct intel_watermark_params *wm_params; | ||
1826 | unsigned long line_time_us; | 2063 | unsigned long line_time_us; |
1827 | int sr_clock, sr_entries = 0; | 2064 | int sr_clock, sr_entries = 0; |
1828 | 2065 | ||
2066 | /* Create copies of the base settings for each pipe */ | ||
1829 | if (IS_I965GM(dev) || IS_I945GM(dev)) | 2067 | if (IS_I965GM(dev) || IS_I945GM(dev)) |
1830 | wm_params = &i945_wm_info; | 2068 | planea_params = planeb_params = i945_wm_info; |
1831 | else if (IS_I9XX(dev)) | 2069 | else if (IS_I9XX(dev)) |
1832 | wm_params = &i915_wm_info; | 2070 | planea_params = planeb_params = i915_wm_info; |
1833 | else | 2071 | else |
1834 | wm_params = &i855_wm_info; | 2072 | planea_params = planeb_params = i855_wm_info; |
1835 | 2073 | ||
1836 | planea_entries = intel_calculate_wm(planea_clock, wm_params, | 2074 | /* Grab a couple of global values before we overwrite them */ |
1837 | pixel_size, latency_ns); | 2075 | total_size = planea_params.fifo_size; |
1838 | planeb_entries = intel_calculate_wm(planeb_clock, wm_params, | 2076 | cacheline_size = planea_params.cacheline_size; |
1839 | pixel_size, latency_ns); | ||
1840 | 2077 | ||
1841 | DRM_DEBUG("FIFO entries - A: %d, B: %d\n", planea_entries, | 2078 | /* Update per-plane FIFO sizes */ |
1842 | planeb_entries); | 2079 | planea_params.fifo_size = intel_get_fifo_size(dev, 0); |
2080 | planeb_params.fifo_size = intel_get_fifo_size(dev, 1); | ||
1843 | 2081 | ||
1844 | if (IS_I9XX(dev)) { | 2082 | planea_wm = intel_calculate_wm(planea_clock, &planea_params, |
1845 | asize = dsparb & 0x7f; | 2083 | pixel_size, latency_ns); |
1846 | bsize = (dsparb >> DSPARB_CSTART_SHIFT) & 0x7f; | 2084 | planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params, |
1847 | } else { | 2085 | pixel_size, latency_ns); |
1848 | asize = dsparb & 0x1ff; | 2086 | DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); |
1849 | bsize = (dsparb >> DSPARB_BEND_SHIFT) & 0x1ff; | ||
1850 | } | ||
1851 | DRM_DEBUG("FIFO size - A: %d, B: %d\n", asize, bsize); | ||
1852 | |||
1853 | /* Two extra entries for padding */ | ||
1854 | awm = asize - (planea_entries + 2); | ||
1855 | bwm = bsize - (planeb_entries + 2); | ||
1856 | |||
1857 | /* Sanity check against potentially bad FIFO allocations */ | ||
1858 | if (awm <= 0) { | ||
1859 | /* pipe is on but has too few FIFO entries */ | ||
1860 | if (planea_entries != 0) | ||
1861 | DRM_DEBUG("plane A needs more FIFO entries\n"); | ||
1862 | awm = 1; | ||
1863 | } | ||
1864 | if (bwm <= 0) { | ||
1865 | if (planeb_entries != 0) | ||
1866 | DRM_DEBUG("plane B needs more FIFO entries\n"); | ||
1867 | bwm = 1; | ||
1868 | } | ||
1869 | 2087 | ||
1870 | /* | 2088 | /* |
1871 | * Overlay gets an aggressive default since video jitter is bad. | 2089 | * Overlay gets an aggressive default since video jitter is bad. |
1872 | */ | 2090 | */ |
1873 | cwm = 2; | 2091 | cwm = 2; |
1874 | 2092 | ||
1875 | /* Calc sr entries for one pipe configs */ | 2093 | /* Calc sr entries for one plane configs */ |
1876 | if (!planea_clock || !planeb_clock) { | 2094 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { |
2095 | /* self-refresh has much higher latency */ | ||
2096 | const static int sr_latency_ns = 6000; | ||
2097 | |||
1877 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 2098 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
1878 | line_time_us = (sr_hdisplay * 1000) / sr_clock; | 2099 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); |
1879 | sr_entries = (((latency_ns / line_time_us) + 1) * pixel_size * | 2100 | |
1880 | sr_hdisplay) / 1000; | 2101 | /* Use ns/us then divide to preserve precision */ |
1881 | sr_entries = roundup(sr_entries / wm_params->cacheline_size, 1); | 2102 | sr_entries = (((sr_latency_ns / line_time_us) + 1) * |
1882 | if (sr_entries < wm_params->fifo_size) | 2103 | pixel_size * sr_hdisplay) / 1000; |
1883 | srwm = wm_params->fifo_size - sr_entries; | 2104 | sr_entries = roundup(sr_entries / cacheline_size, 1); |
2105 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | ||
2106 | srwm = total_size - sr_entries; | ||
2107 | if (srwm < 0) | ||
2108 | srwm = 1; | ||
2109 | if (IS_I9XX(dev)) | ||
2110 | I915_WRITE(FW_BLC_SELF, (srwm & 0x3f)); | ||
1884 | } | 2111 | } |
1885 | 2112 | ||
1886 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | 2113 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
1887 | awm, bwm, cwm, srwm); | 2114 | planea_wm, planeb_wm, cwm, srwm); |
1888 | 2115 | ||
1889 | fwater_lo = fwater_lo | ((bwm & 0x3f) << 16) | (awm & 0x3f); | 2116 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); |
1890 | fwater_hi = fwater_hi | (cwm & 0x1f); | 2117 | fwater_hi = (cwm & 0x1f); |
2118 | |||
2119 | /* Set request length to 8 cachelines per fetch */ | ||
2120 | fwater_lo = fwater_lo | (1 << 24) | (1 << 8); | ||
2121 | fwater_hi = fwater_hi | (1 << 8); | ||
1891 | 2122 | ||
1892 | I915_WRITE(FW_BLC, fwater_lo); | 2123 | I915_WRITE(FW_BLC, fwater_lo); |
1893 | I915_WRITE(FW_BLC2, fwater_hi); | 2124 | I915_WRITE(FW_BLC2, fwater_hi); |
1894 | if (IS_I9XX(dev)) | ||
1895 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); | ||
1896 | } | 2125 | } |
1897 | 2126 | ||
1898 | static void i830_update_wm(struct drm_device *dev, int planea_clock, | 2127 | static void i830_update_wm(struct drm_device *dev, int planea_clock, |
1899 | int pixel_size) | 2128 | int pixel_size) |
1900 | { | 2129 | { |
1901 | struct drm_i915_private *dev_priv = dev->dev_private; | 2130 | struct drm_i915_private *dev_priv = dev->dev_private; |
1902 | uint32_t dsparb = I915_READ(DSPARB); | 2131 | uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; |
1903 | uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; | 2132 | int planea_wm; |
1904 | unsigned int asize, awm; | ||
1905 | int planea_entries; | ||
1906 | |||
1907 | planea_entries = intel_calculate_wm(planea_clock, &i830_wm_info, | ||
1908 | pixel_size, latency_ns); | ||
1909 | 2133 | ||
1910 | asize = dsparb & 0x7f; | 2134 | i830_wm_info.fifo_size = intel_get_fifo_size(dev, 0); |
1911 | 2135 | ||
1912 | awm = asize - planea_entries; | 2136 | planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info, |
2137 | pixel_size, latency_ns); | ||
2138 | fwater_lo |= (3<<8) | planea_wm; | ||
1913 | 2139 | ||
1914 | fwater_lo = fwater_lo | awm; | 2140 | DRM_DEBUG("Setting FIFO watermarks - A: %d\n", planea_wm); |
1915 | 2141 | ||
1916 | I915_WRITE(FW_BLC, fwater_lo); | 2142 | I915_WRITE(FW_BLC, fwater_lo); |
1917 | } | 2143 | } |
@@ -1984,7 +2210,7 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
1984 | if (enabled <= 0) | 2210 | if (enabled <= 0) |
1985 | return; | 2211 | return; |
1986 | 2212 | ||
1987 | /* Single pipe configs can enable self refresh */ | 2213 | /* Single plane configs can enable self refresh */ |
1988 | if (enabled == 1 && IS_IGD(dev)) | 2214 | if (enabled == 1 && IS_IGD(dev)) |
1989 | igd_enable_cxsr(dev, sr_clock, pixel_size); | 2215 | igd_enable_cxsr(dev, sr_clock, pixel_size); |
1990 | else if (IS_IGD(dev)) | 2216 | else if (IS_IGD(dev)) |
@@ -2028,6 +2254,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2028 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; | 2254 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; |
2029 | bool ok, is_sdvo = false, is_dvo = false; | 2255 | bool ok, is_sdvo = false, is_dvo = false; |
2030 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 2256 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
2257 | bool is_edp = false; | ||
2031 | struct drm_mode_config *mode_config = &dev->mode_config; | 2258 | struct drm_mode_config *mode_config = &dev->mode_config; |
2032 | struct drm_connector *connector; | 2259 | struct drm_connector *connector; |
2033 | const intel_limit_t *limit; | 2260 | const intel_limit_t *limit; |
@@ -2043,6 +2270,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2043 | int lvds_reg = LVDS; | 2270 | int lvds_reg = LVDS; |
2044 | u32 temp; | 2271 | u32 temp; |
2045 | int sdvo_pixel_multiply; | 2272 | int sdvo_pixel_multiply; |
2273 | int target_clock; | ||
2046 | 2274 | ||
2047 | drm_vblank_pre_modeset(dev, pipe); | 2275 | drm_vblank_pre_modeset(dev, pipe); |
2048 | 2276 | ||
@@ -2074,6 +2302,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2074 | case INTEL_OUTPUT_DISPLAYPORT: | 2302 | case INTEL_OUTPUT_DISPLAYPORT: |
2075 | is_dp = true; | 2303 | is_dp = true; |
2076 | break; | 2304 | break; |
2305 | case INTEL_OUTPUT_EDP: | ||
2306 | is_edp = true; | ||
2307 | break; | ||
2077 | } | 2308 | } |
2078 | 2309 | ||
2079 | num_outputs++; | 2310 | num_outputs++; |
@@ -2125,11 +2356,29 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2125 | } | 2356 | } |
2126 | 2357 | ||
2127 | /* FDI link */ | 2358 | /* FDI link */ |
2128 | if (IS_IGDNG(dev)) | 2359 | if (IS_IGDNG(dev)) { |
2129 | igdng_compute_m_n(3, 4, /* lane num 4 */ | 2360 | int lane, link_bw; |
2130 | adjusted_mode->clock, | 2361 | /* eDP doesn't require FDI link, so just set DP M/N |
2131 | 270000, /* lane clock */ | 2362 | according to current link config */ |
2132 | &m_n); | 2363 | if (is_edp) { |
2364 | struct drm_connector *edp; | ||
2365 | target_clock = mode->clock; | ||
2366 | edp = intel_pipe_get_output(crtc); | ||
2367 | intel_edp_link_config(to_intel_output(edp), | ||
2368 | &lane, &link_bw); | ||
2369 | } else { | ||
2370 | /* DP over FDI requires target mode clock | ||
2371 | instead of link clock */ | ||
2372 | if (is_dp) | ||
2373 | target_clock = mode->clock; | ||
2374 | else | ||
2375 | target_clock = adjusted_mode->clock; | ||
2376 | lane = 4; | ||
2377 | link_bw = 270000; | ||
2378 | } | ||
2379 | igdng_compute_m_n(3, lane, target_clock, | ||
2380 | link_bw, &m_n); | ||
2381 | } | ||
2133 | 2382 | ||
2134 | if (IS_IGD(dev)) | 2383 | if (IS_IGD(dev)) |
2135 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; | 2384 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; |
@@ -2147,7 +2396,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2147 | if (is_sdvo) { | 2396 | if (is_sdvo) { |
2148 | dpll |= DPLL_DVO_HIGH_SPEED; | 2397 | dpll |= DPLL_DVO_HIGH_SPEED; |
2149 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | 2398 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; |
2150 | if (IS_I945G(dev) || IS_I945GM(dev)) | 2399 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
2151 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; | 2400 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; |
2152 | else if (IS_IGDNG(dev)) | 2401 | else if (IS_IGDNG(dev)) |
2153 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | 2402 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
@@ -2250,29 +2499,15 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2250 | dpll_reg = pch_dpll_reg; | 2499 | dpll_reg = pch_dpll_reg; |
2251 | } | 2500 | } |
2252 | 2501 | ||
2253 | if (dpll & DPLL_VCO_ENABLE) { | 2502 | if (is_edp) { |
2503 | igdng_disable_pll_edp(crtc); | ||
2504 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
2254 | I915_WRITE(fp_reg, fp); | 2505 | I915_WRITE(fp_reg, fp); |
2255 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 2506 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
2256 | I915_READ(dpll_reg); | 2507 | I915_READ(dpll_reg); |
2257 | udelay(150); | 2508 | udelay(150); |
2258 | } | 2509 | } |
2259 | 2510 | ||
2260 | if (IS_IGDNG(dev)) { | ||
2261 | /* enable PCH clock reference source */ | ||
2262 | /* XXX need to change the setting for other outputs */ | ||
2263 | u32 temp; | ||
2264 | temp = I915_READ(PCH_DREF_CONTROL); | ||
2265 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | ||
2266 | temp |= DREF_NONSPREAD_CK505_ENABLE; | ||
2267 | temp &= ~DREF_SSC_SOURCE_MASK; | ||
2268 | temp |= DREF_SSC_SOURCE_ENABLE; | ||
2269 | temp &= ~DREF_SSC1_ENABLE; | ||
2270 | /* if no eDP, disable source output to CPU */ | ||
2271 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | ||
2272 | temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; | ||
2273 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
2274 | } | ||
2275 | |||
2276 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 2511 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
2277 | * This is an exception to the general rule that mode_set doesn't turn | 2512 | * This is an exception to the general rule that mode_set doesn't turn |
2278 | * things on. | 2513 | * things on. |
@@ -2304,23 +2539,25 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2304 | if (is_dp) | 2539 | if (is_dp) |
2305 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | 2540 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
2306 | 2541 | ||
2307 | I915_WRITE(fp_reg, fp); | 2542 | if (!is_edp) { |
2308 | I915_WRITE(dpll_reg, dpll); | 2543 | I915_WRITE(fp_reg, fp); |
2309 | I915_READ(dpll_reg); | ||
2310 | /* Wait for the clocks to stabilize. */ | ||
2311 | udelay(150); | ||
2312 | |||
2313 | if (IS_I965G(dev) && !IS_IGDNG(dev)) { | ||
2314 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
2315 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | ||
2316 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | ||
2317 | } else { | ||
2318 | /* write it again -- the BIOS does, after all */ | ||
2319 | I915_WRITE(dpll_reg, dpll); | 2544 | I915_WRITE(dpll_reg, dpll); |
2545 | I915_READ(dpll_reg); | ||
2546 | /* Wait for the clocks to stabilize. */ | ||
2547 | udelay(150); | ||
2548 | |||
2549 | if (IS_I965G(dev) && !IS_IGDNG(dev)) { | ||
2550 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
2551 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | ||
2552 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | ||
2553 | } else { | ||
2554 | /* write it again -- the BIOS does, after all */ | ||
2555 | I915_WRITE(dpll_reg, dpll); | ||
2556 | } | ||
2557 | I915_READ(dpll_reg); | ||
2558 | /* Wait for the clocks to stabilize. */ | ||
2559 | udelay(150); | ||
2320 | } | 2560 | } |
2321 | I915_READ(dpll_reg); | ||
2322 | /* Wait for the clocks to stabilize. */ | ||
2323 | udelay(150); | ||
2324 | 2561 | ||
2325 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 2562 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
2326 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 2563 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
@@ -2350,10 +2587,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2350 | I915_WRITE(link_m1_reg, m_n.link_m); | 2587 | I915_WRITE(link_m1_reg, m_n.link_m); |
2351 | I915_WRITE(link_n1_reg, m_n.link_n); | 2588 | I915_WRITE(link_n1_reg, m_n.link_n); |
2352 | 2589 | ||
2353 | /* enable FDI RX PLL too */ | 2590 | if (is_edp) { |
2354 | temp = I915_READ(fdi_rx_reg); | 2591 | igdng_set_pll_edp(crtc, adjusted_mode->clock); |
2355 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | 2592 | } else { |
2356 | udelay(200); | 2593 | /* enable FDI RX PLL too */ |
2594 | temp = I915_READ(fdi_rx_reg); | ||
2595 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | ||
2596 | udelay(200); | ||
2597 | } | ||
2357 | } | 2598 | } |
2358 | 2599 | ||
2359 | I915_WRITE(pipeconf_reg, pipeconf); | 2600 | I915_WRITE(pipeconf_reg, pipeconf); |
@@ -2929,7 +3170,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) | |||
2929 | 3170 | ||
2930 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 3171 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
2931 | struct intel_output *intel_output = to_intel_output(connector); | 3172 | struct intel_output *intel_output = to_intel_output(connector); |
2932 | if (type_mask & (1 << intel_output->type)) | 3173 | if (type_mask & intel_output->clone_mask) |
2933 | index_mask |= (1 << entry); | 3174 | index_mask |= (1 << entry); |
2934 | entry++; | 3175 | entry++; |
2935 | } | 3176 | } |
@@ -2951,12 +3192,17 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2951 | if (IS_IGDNG(dev)) { | 3192 | if (IS_IGDNG(dev)) { |
2952 | int found; | 3193 | int found; |
2953 | 3194 | ||
3195 | if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) | ||
3196 | intel_dp_init(dev, DP_A); | ||
3197 | |||
2954 | if (I915_READ(HDMIB) & PORT_DETECTED) { | 3198 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
2955 | /* check SDVOB */ | 3199 | /* check SDVOB */ |
2956 | /* found = intel_sdvo_init(dev, HDMIB); */ | 3200 | /* found = intel_sdvo_init(dev, HDMIB); */ |
2957 | found = 0; | 3201 | found = 0; |
2958 | if (!found) | 3202 | if (!found) |
2959 | intel_hdmi_init(dev, HDMIB); | 3203 | intel_hdmi_init(dev, HDMIB); |
3204 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) | ||
3205 | intel_dp_init(dev, PCH_DP_B); | ||
2960 | } | 3206 | } |
2961 | 3207 | ||
2962 | if (I915_READ(HDMIC) & PORT_DETECTED) | 3208 | if (I915_READ(HDMIC) & PORT_DETECTED) |
@@ -2965,31 +3211,37 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2965 | if (I915_READ(HDMID) & PORT_DETECTED) | 3211 | if (I915_READ(HDMID) & PORT_DETECTED) |
2966 | intel_hdmi_init(dev, HDMID); | 3212 | intel_hdmi_init(dev, HDMID); |
2967 | 3213 | ||
3214 | if (I915_READ(PCH_DP_C) & DP_DETECTED) | ||
3215 | intel_dp_init(dev, PCH_DP_C); | ||
3216 | |||
3217 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | ||
3218 | intel_dp_init(dev, PCH_DP_D); | ||
3219 | |||
2968 | } else if (IS_I9XX(dev)) { | 3220 | } else if (IS_I9XX(dev)) { |
2969 | int found; | 3221 | bool found = false; |
2970 | u32 reg; | ||
2971 | 3222 | ||
2972 | if (I915_READ(SDVOB) & SDVO_DETECTED) { | 3223 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
2973 | found = intel_sdvo_init(dev, SDVOB); | 3224 | found = intel_sdvo_init(dev, SDVOB); |
2974 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 3225 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) |
2975 | intel_hdmi_init(dev, SDVOB); | 3226 | intel_hdmi_init(dev, SDVOB); |
3227 | |||
2976 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | 3228 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) |
2977 | intel_dp_init(dev, DP_B); | 3229 | intel_dp_init(dev, DP_B); |
2978 | } | 3230 | } |
2979 | 3231 | ||
2980 | /* Before G4X SDVOC doesn't have its own detect register */ | 3232 | /* Before G4X SDVOC doesn't have its own detect register */ |
2981 | if (IS_G4X(dev)) | ||
2982 | reg = SDVOC; | ||
2983 | else | ||
2984 | reg = SDVOB; | ||
2985 | 3233 | ||
2986 | if (I915_READ(reg) & SDVO_DETECTED) { | 3234 | if (I915_READ(SDVOB) & SDVO_DETECTED) |
2987 | found = intel_sdvo_init(dev, SDVOC); | 3235 | found = intel_sdvo_init(dev, SDVOC); |
2988 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 3236 | |
3237 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { | ||
3238 | |||
3239 | if (SUPPORTS_INTEGRATED_HDMI(dev)) | ||
2989 | intel_hdmi_init(dev, SDVOC); | 3240 | intel_hdmi_init(dev, SDVOC); |
2990 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | 3241 | if (SUPPORTS_INTEGRATED_DP(dev)) |
2991 | intel_dp_init(dev, DP_C); | 3242 | intel_dp_init(dev, DP_C); |
2992 | } | 3243 | } |
3244 | |||
2993 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) | 3245 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) |
2994 | intel_dp_init(dev, DP_D); | 3246 | intel_dp_init(dev, DP_D); |
2995 | } else | 3247 | } else |
@@ -3001,47 +3253,10 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3001 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 3253 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
3002 | struct intel_output *intel_output = to_intel_output(connector); | 3254 | struct intel_output *intel_output = to_intel_output(connector); |
3003 | struct drm_encoder *encoder = &intel_output->enc; | 3255 | struct drm_encoder *encoder = &intel_output->enc; |
3004 | int crtc_mask = 0, clone_mask = 0; | ||
3005 | 3256 | ||
3006 | /* valid crtcs */ | 3257 | encoder->possible_crtcs = intel_output->crtc_mask; |
3007 | switch(intel_output->type) { | 3258 | encoder->possible_clones = intel_connector_clones(dev, |
3008 | case INTEL_OUTPUT_HDMI: | 3259 | intel_output->clone_mask); |
3009 | crtc_mask = ((1 << 0)| | ||
3010 | (1 << 1)); | ||
3011 | clone_mask = ((1 << INTEL_OUTPUT_HDMI)); | ||
3012 | break; | ||
3013 | case INTEL_OUTPUT_DVO: | ||
3014 | case INTEL_OUTPUT_SDVO: | ||
3015 | crtc_mask = ((1 << 0)| | ||
3016 | (1 << 1)); | ||
3017 | clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | | ||
3018 | (1 << INTEL_OUTPUT_DVO) | | ||
3019 | (1 << INTEL_OUTPUT_SDVO)); | ||
3020 | break; | ||
3021 | case INTEL_OUTPUT_ANALOG: | ||
3022 | crtc_mask = ((1 << 0)| | ||
3023 | (1 << 1)); | ||
3024 | clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | | ||
3025 | (1 << INTEL_OUTPUT_DVO) | | ||
3026 | (1 << INTEL_OUTPUT_SDVO)); | ||
3027 | break; | ||
3028 | case INTEL_OUTPUT_LVDS: | ||
3029 | crtc_mask = (1 << 1); | ||
3030 | clone_mask = (1 << INTEL_OUTPUT_LVDS); | ||
3031 | break; | ||
3032 | case INTEL_OUTPUT_TVOUT: | ||
3033 | crtc_mask = ((1 << 0) | | ||
3034 | (1 << 1)); | ||
3035 | clone_mask = (1 << INTEL_OUTPUT_TVOUT); | ||
3036 | break; | ||
3037 | case INTEL_OUTPUT_DISPLAYPORT: | ||
3038 | crtc_mask = ((1 << 0) | | ||
3039 | (1 << 1)); | ||
3040 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); | ||
3041 | break; | ||
3042 | } | ||
3043 | encoder->possible_crtcs = crtc_mask; | ||
3044 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); | ||
3045 | } | 3260 | } |
3046 | } | 3261 | } |
3047 | 3262 | ||
@@ -3148,6 +3363,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
3148 | if (IS_I965G(dev)) { | 3363 | if (IS_I965G(dev)) { |
3149 | dev->mode_config.max_width = 8192; | 3364 | dev->mode_config.max_width = 8192; |
3150 | dev->mode_config.max_height = 8192; | 3365 | dev->mode_config.max_height = 8192; |
3366 | } else if (IS_I9XX(dev)) { | ||
3367 | dev->mode_config.max_width = 4096; | ||
3368 | dev->mode_config.max_height = 4096; | ||
3151 | } else { | 3369 | } else { |
3152 | dev->mode_config.max_width = 2048; | 3370 | dev->mode_config.max_width = 2048; |
3153 | dev->mode_config.max_height = 2048; | 3371 | dev->mode_config.max_height = 2048; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6770ae88370d..f2afc4af4bc9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -40,6 +40,8 @@ | |||
40 | 40 | ||
41 | #define DP_LINK_CONFIGURATION_SIZE 9 | 41 | #define DP_LINK_CONFIGURATION_SIZE 9 |
42 | 42 | ||
43 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | ||
44 | |||
43 | struct intel_dp_priv { | 45 | struct intel_dp_priv { |
44 | uint32_t output_reg; | 46 | uint32_t output_reg; |
45 | uint32_t DP; | 47 | uint32_t DP; |
@@ -63,6 +65,19 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | |||
63 | static void | 65 | static void |
64 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); | 66 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); |
65 | 67 | ||
68 | void | ||
69 | intel_edp_link_config (struct intel_output *intel_output, | ||
70 | int *lane_num, int *link_bw) | ||
71 | { | ||
72 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
73 | |||
74 | *lane_num = dp_priv->lane_count; | ||
75 | if (dp_priv->link_bw == DP_LINK_BW_1_62) | ||
76 | *link_bw = 162000; | ||
77 | else if (dp_priv->link_bw == DP_LINK_BW_2_7) | ||
78 | *link_bw = 270000; | ||
79 | } | ||
80 | |||
66 | static int | 81 | static int |
67 | intel_dp_max_lane_count(struct intel_output *intel_output) | 82 | intel_dp_max_lane_count(struct intel_output *intel_output) |
68 | { | 83 | { |
@@ -206,7 +221,13 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
206 | * and would like to run at 2MHz. So, take the | 221 | * and would like to run at 2MHz. So, take the |
207 | * hrawclk value and divide by 2 and use that | 222 | * hrawclk value and divide by 2 and use that |
208 | */ | 223 | */ |
209 | aux_clock_divider = intel_hrawclk(dev) / 2; | 224 | if (IS_eDP(intel_output)) |
225 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ | ||
226 | else if (IS_IGDNG(dev)) | ||
227 | aux_clock_divider = 62; /* IGDNG: input clock fixed at 125Mhz */ | ||
228 | else | ||
229 | aux_clock_divider = intel_hrawclk(dev) / 2; | ||
230 | |||
210 | /* Must try at least 3 times according to DP spec */ | 231 | /* Must try at least 3 times according to DP spec */ |
211 | for (try = 0; try < 5; try++) { | 232 | for (try = 0; try < 5; try++) { |
212 | /* Load the send data into the aux channel data registers */ | 233 | /* Load the send data into the aux channel data registers */ |
@@ -236,7 +257,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
236 | } | 257 | } |
237 | 258 | ||
238 | /* Clear done status and any errors */ | 259 | /* Clear done status and any errors */ |
239 | I915_WRITE(ch_ctl, (ctl | | 260 | I915_WRITE(ch_ctl, (status | |
240 | DP_AUX_CH_CTL_DONE | | 261 | DP_AUX_CH_CTL_DONE | |
241 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | 262 | DP_AUX_CH_CTL_TIME_OUT_ERROR | |
242 | DP_AUX_CH_CTL_RECEIVE_ERROR)); | 263 | DP_AUX_CH_CTL_RECEIVE_ERROR)); |
@@ -295,7 +316,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output, | |||
295 | return -1; | 316 | return -1; |
296 | msg[0] = AUX_NATIVE_WRITE << 4; | 317 | msg[0] = AUX_NATIVE_WRITE << 4; |
297 | msg[1] = address >> 8; | 318 | msg[1] = address >> 8; |
298 | msg[2] = address; | 319 | msg[2] = address & 0xff; |
299 | msg[3] = send_bytes - 1; | 320 | msg[3] = send_bytes - 1; |
300 | memcpy(&msg[4], send, send_bytes); | 321 | memcpy(&msg[4], send, send_bytes); |
301 | msg_bytes = send_bytes + 4; | 322 | msg_bytes = send_bytes + 4; |
@@ -387,8 +408,8 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name) | |||
387 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); | 408 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); |
388 | dp_priv->adapter.owner = THIS_MODULE; | 409 | dp_priv->adapter.owner = THIS_MODULE; |
389 | dp_priv->adapter.class = I2C_CLASS_DDC; | 410 | dp_priv->adapter.class = I2C_CLASS_DDC; |
390 | strncpy (dp_priv->adapter.name, name, sizeof dp_priv->adapter.name - 1); | 411 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); |
391 | dp_priv->adapter.name[sizeof dp_priv->adapter.name - 1] = '\0'; | 412 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; |
392 | dp_priv->adapter.algo_data = &dp_priv->algo; | 413 | dp_priv->adapter.algo_data = &dp_priv->algo; |
393 | dp_priv->adapter.dev.parent = &intel_output->base.kdev; | 414 | dp_priv->adapter.dev.parent = &intel_output->base.kdev; |
394 | 415 | ||
@@ -493,22 +514,40 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
493 | intel_dp_compute_m_n(3, lane_count, | 514 | intel_dp_compute_m_n(3, lane_count, |
494 | mode->clock, adjusted_mode->clock, &m_n); | 515 | mode->clock, adjusted_mode->clock, &m_n); |
495 | 516 | ||
496 | if (intel_crtc->pipe == 0) { | 517 | if (IS_IGDNG(dev)) { |
497 | I915_WRITE(PIPEA_GMCH_DATA_M, | 518 | if (intel_crtc->pipe == 0) { |
498 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | 519 | I915_WRITE(TRANSA_DATA_M1, |
499 | m_n.gmch_m); | 520 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | |
500 | I915_WRITE(PIPEA_GMCH_DATA_N, | 521 | m_n.gmch_m); |
501 | m_n.gmch_n); | 522 | I915_WRITE(TRANSA_DATA_N1, m_n.gmch_n); |
502 | I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m); | 523 | I915_WRITE(TRANSA_DP_LINK_M1, m_n.link_m); |
503 | I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n); | 524 | I915_WRITE(TRANSA_DP_LINK_N1, m_n.link_n); |
525 | } else { | ||
526 | I915_WRITE(TRANSB_DATA_M1, | ||
527 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
528 | m_n.gmch_m); | ||
529 | I915_WRITE(TRANSB_DATA_N1, m_n.gmch_n); | ||
530 | I915_WRITE(TRANSB_DP_LINK_M1, m_n.link_m); | ||
531 | I915_WRITE(TRANSB_DP_LINK_N1, m_n.link_n); | ||
532 | } | ||
504 | } else { | 533 | } else { |
505 | I915_WRITE(PIPEB_GMCH_DATA_M, | 534 | if (intel_crtc->pipe == 0) { |
506 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | 535 | I915_WRITE(PIPEA_GMCH_DATA_M, |
507 | m_n.gmch_m); | 536 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | |
508 | I915_WRITE(PIPEB_GMCH_DATA_N, | 537 | m_n.gmch_m); |
509 | m_n.gmch_n); | 538 | I915_WRITE(PIPEA_GMCH_DATA_N, |
510 | I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m); | 539 | m_n.gmch_n); |
511 | I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); | 540 | I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m); |
541 | I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n); | ||
542 | } else { | ||
543 | I915_WRITE(PIPEB_GMCH_DATA_M, | ||
544 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
545 | m_n.gmch_m); | ||
546 | I915_WRITE(PIPEB_GMCH_DATA_N, | ||
547 | m_n.gmch_n); | ||
548 | I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m); | ||
549 | I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); | ||
550 | } | ||
512 | } | 551 | } |
513 | } | 552 | } |
514 | 553 | ||
@@ -556,8 +595,38 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
556 | 595 | ||
557 | if (intel_crtc->pipe == 1) | 596 | if (intel_crtc->pipe == 1) |
558 | dp_priv->DP |= DP_PIPEB_SELECT; | 597 | dp_priv->DP |= DP_PIPEB_SELECT; |
598 | |||
599 | if (IS_eDP(intel_output)) { | ||
600 | /* don't miss out required setting for eDP */ | ||
601 | dp_priv->DP |= DP_PLL_ENABLE; | ||
602 | if (adjusted_mode->clock < 200000) | ||
603 | dp_priv->DP |= DP_PLL_FREQ_160MHZ; | ||
604 | else | ||
605 | dp_priv->DP |= DP_PLL_FREQ_270MHZ; | ||
606 | } | ||
559 | } | 607 | } |
560 | 608 | ||
609 | static void igdng_edp_backlight_on (struct drm_device *dev) | ||
610 | { | ||
611 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
612 | u32 pp; | ||
613 | |||
614 | DRM_DEBUG("\n"); | ||
615 | pp = I915_READ(PCH_PP_CONTROL); | ||
616 | pp |= EDP_BLC_ENABLE; | ||
617 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
618 | } | ||
619 | |||
620 | static void igdng_edp_backlight_off (struct drm_device *dev) | ||
621 | { | ||
622 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
623 | u32 pp; | ||
624 | |||
625 | DRM_DEBUG("\n"); | ||
626 | pp = I915_READ(PCH_PP_CONTROL); | ||
627 | pp &= ~EDP_BLC_ENABLE; | ||
628 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
629 | } | ||
561 | 630 | ||
562 | static void | 631 | static void |
563 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 632 | intel_dp_dpms(struct drm_encoder *encoder, int mode) |
@@ -569,11 +638,17 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
569 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 638 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); |
570 | 639 | ||
571 | if (mode != DRM_MODE_DPMS_ON) { | 640 | if (mode != DRM_MODE_DPMS_ON) { |
572 | if (dp_reg & DP_PORT_EN) | 641 | if (dp_reg & DP_PORT_EN) { |
573 | intel_dp_link_down(intel_output, dp_priv->DP); | 642 | intel_dp_link_down(intel_output, dp_priv->DP); |
643 | if (IS_eDP(intel_output)) | ||
644 | igdng_edp_backlight_off(dev); | ||
645 | } | ||
574 | } else { | 646 | } else { |
575 | if (!(dp_reg & DP_PORT_EN)) | 647 | if (!(dp_reg & DP_PORT_EN)) { |
576 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | 648 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); |
649 | if (IS_eDP(intel_output)) | ||
650 | igdng_edp_backlight_on(dev); | ||
651 | } | ||
577 | } | 652 | } |
578 | dp_priv->dpms_mode = mode; | 653 | dp_priv->dpms_mode = mode; |
579 | } | 654 | } |
@@ -935,6 +1010,23 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) | |||
935 | struct drm_i915_private *dev_priv = dev->dev_private; | 1010 | struct drm_i915_private *dev_priv = dev->dev_private; |
936 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1011 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; |
937 | 1012 | ||
1013 | DRM_DEBUG("\n"); | ||
1014 | |||
1015 | if (IS_eDP(intel_output)) { | ||
1016 | DP &= ~DP_PLL_ENABLE; | ||
1017 | I915_WRITE(dp_priv->output_reg, DP); | ||
1018 | POSTING_READ(dp_priv->output_reg); | ||
1019 | udelay(100); | ||
1020 | } | ||
1021 | |||
1022 | DP &= ~DP_LINK_TRAIN_MASK; | ||
1023 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | ||
1024 | POSTING_READ(dp_priv->output_reg); | ||
1025 | |||
1026 | udelay(17000); | ||
1027 | |||
1028 | if (IS_eDP(intel_output)) | ||
1029 | DP |= DP_LINK_TRAIN_OFF; | ||
938 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | 1030 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); |
939 | POSTING_READ(dp_priv->output_reg); | 1031 | POSTING_READ(dp_priv->output_reg); |
940 | } | 1032 | } |
@@ -978,6 +1070,24 @@ intel_dp_check_link_status(struct intel_output *intel_output) | |||
978 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | 1070 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); |
979 | } | 1071 | } |
980 | 1072 | ||
1073 | static enum drm_connector_status | ||
1074 | igdng_dp_detect(struct drm_connector *connector) | ||
1075 | { | ||
1076 | struct intel_output *intel_output = to_intel_output(connector); | ||
1077 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
1078 | enum drm_connector_status status; | ||
1079 | |||
1080 | status = connector_status_disconnected; | ||
1081 | if (intel_dp_aux_native_read(intel_output, | ||
1082 | 0x000, dp_priv->dpcd, | ||
1083 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | ||
1084 | { | ||
1085 | if (dp_priv->dpcd[0] != 0) | ||
1086 | status = connector_status_connected; | ||
1087 | } | ||
1088 | return status; | ||
1089 | } | ||
1090 | |||
981 | /** | 1091 | /** |
982 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. | 1092 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. |
983 | * | 1093 | * |
@@ -996,6 +1106,9 @@ intel_dp_detect(struct drm_connector *connector) | |||
996 | 1106 | ||
997 | dp_priv->has_audio = false; | 1107 | dp_priv->has_audio = false; |
998 | 1108 | ||
1109 | if (IS_IGDNG(dev)) | ||
1110 | return igdng_dp_detect(connector); | ||
1111 | |||
999 | temp = I915_READ(PORT_HOTPLUG_EN); | 1112 | temp = I915_READ(PORT_HOTPLUG_EN); |
1000 | 1113 | ||
1001 | I915_WRITE(PORT_HOTPLUG_EN, | 1114 | I915_WRITE(PORT_HOTPLUG_EN, |
@@ -1039,11 +1152,27 @@ intel_dp_detect(struct drm_connector *connector) | |||
1039 | static int intel_dp_get_modes(struct drm_connector *connector) | 1152 | static int intel_dp_get_modes(struct drm_connector *connector) |
1040 | { | 1153 | { |
1041 | struct intel_output *intel_output = to_intel_output(connector); | 1154 | struct intel_output *intel_output = to_intel_output(connector); |
1155 | struct drm_device *dev = intel_output->base.dev; | ||
1156 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1157 | int ret; | ||
1042 | 1158 | ||
1043 | /* We should parse the EDID data and find out if it has an audio sink | 1159 | /* We should parse the EDID data and find out if it has an audio sink |
1044 | */ | 1160 | */ |
1045 | 1161 | ||
1046 | return intel_ddc_get_modes(intel_output); | 1162 | ret = intel_ddc_get_modes(intel_output); |
1163 | if (ret) | ||
1164 | return ret; | ||
1165 | |||
1166 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | ||
1167 | if (IS_eDP(intel_output)) { | ||
1168 | if (dev_priv->panel_fixed_mode != NULL) { | ||
1169 | struct drm_display_mode *mode; | ||
1170 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | ||
1171 | drm_mode_probed_add(connector, mode); | ||
1172 | return 1; | ||
1173 | } | ||
1174 | } | ||
1175 | return 0; | ||
1047 | } | 1176 | } |
1048 | 1177 | ||
1049 | static void | 1178 | static void |
@@ -1106,6 +1235,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1106 | struct drm_connector *connector; | 1235 | struct drm_connector *connector; |
1107 | struct intel_output *intel_output; | 1236 | struct intel_output *intel_output; |
1108 | struct intel_dp_priv *dp_priv; | 1237 | struct intel_dp_priv *dp_priv; |
1238 | const char *name = NULL; | ||
1109 | 1239 | ||
1110 | intel_output = kcalloc(sizeof(struct intel_output) + | 1240 | intel_output = kcalloc(sizeof(struct intel_output) + |
1111 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1241 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); |
@@ -1119,8 +1249,23 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1119 | DRM_MODE_CONNECTOR_DisplayPort); | 1249 | DRM_MODE_CONNECTOR_DisplayPort); |
1120 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); | 1250 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); |
1121 | 1251 | ||
1122 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | 1252 | if (output_reg == DP_A) |
1123 | 1253 | intel_output->type = INTEL_OUTPUT_EDP; | |
1254 | else | ||
1255 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | ||
1256 | |||
1257 | if (output_reg == DP_B) | ||
1258 | intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); | ||
1259 | else if (output_reg == DP_C) | ||
1260 | intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); | ||
1261 | else if (output_reg == DP_D) | ||
1262 | intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | ||
1263 | |||
1264 | if (IS_eDP(intel_output)) { | ||
1265 | intel_output->crtc_mask = (1 << 1); | ||
1266 | intel_output->clone_mask = (1 << INTEL_OUTPUT_EDP); | ||
1267 | } else | ||
1268 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
1124 | connector->interlace_allowed = true; | 1269 | connector->interlace_allowed = true; |
1125 | connector->doublescan_allowed = 0; | 1270 | connector->doublescan_allowed = 0; |
1126 | 1271 | ||
@@ -1139,12 +1284,41 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1139 | drm_sysfs_connector_add(connector); | 1284 | drm_sysfs_connector_add(connector); |
1140 | 1285 | ||
1141 | /* Set up the DDC bus. */ | 1286 | /* Set up the DDC bus. */ |
1142 | intel_dp_i2c_init(intel_output, | 1287 | switch (output_reg) { |
1143 | (output_reg == DP_B) ? "DPDDC-B" : | 1288 | case DP_A: |
1144 | (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D"); | 1289 | name = "DPDDC-A"; |
1290 | break; | ||
1291 | case DP_B: | ||
1292 | case PCH_DP_B: | ||
1293 | name = "DPDDC-B"; | ||
1294 | break; | ||
1295 | case DP_C: | ||
1296 | case PCH_DP_C: | ||
1297 | name = "DPDDC-C"; | ||
1298 | break; | ||
1299 | case DP_D: | ||
1300 | case PCH_DP_D: | ||
1301 | name = "DPDDC-D"; | ||
1302 | break; | ||
1303 | } | ||
1304 | |||
1305 | intel_dp_i2c_init(intel_output, name); | ||
1306 | |||
1145 | intel_output->ddc_bus = &dp_priv->adapter; | 1307 | intel_output->ddc_bus = &dp_priv->adapter; |
1146 | intel_output->hot_plug = intel_dp_hot_plug; | 1308 | intel_output->hot_plug = intel_dp_hot_plug; |
1147 | 1309 | ||
1310 | if (output_reg == DP_A) { | ||
1311 | /* initialize panel mode from VBT if available for eDP */ | ||
1312 | if (dev_priv->lfp_lvds_vbt_mode) { | ||
1313 | dev_priv->panel_fixed_mode = | ||
1314 | drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); | ||
1315 | if (dev_priv->panel_fixed_mode) { | ||
1316 | dev_priv->panel_fixed_mode->type |= | ||
1317 | DRM_MODE_TYPE_PREFERRED; | ||
1318 | } | ||
1319 | } | ||
1320 | } | ||
1321 | |||
1148 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written | 1322 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written |
1149 | * 0xd. Failure to do so will result in spurious interrupts being | 1323 | * 0xd. Failure to do so will result in spurious interrupts being |
1150 | * generated on the port when a cable is not attached. | 1324 | * generated on the port when a cable is not attached. |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 004541c935a8..25aa6facc12d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -55,6 +55,25 @@ | |||
55 | #define INTEL_OUTPUT_TVOUT 5 | 55 | #define INTEL_OUTPUT_TVOUT 5 |
56 | #define INTEL_OUTPUT_HDMI 6 | 56 | #define INTEL_OUTPUT_HDMI 6 |
57 | #define INTEL_OUTPUT_DISPLAYPORT 7 | 57 | #define INTEL_OUTPUT_DISPLAYPORT 7 |
58 | #define INTEL_OUTPUT_EDP 8 | ||
59 | |||
60 | /* Intel Pipe Clone Bit */ | ||
61 | #define INTEL_HDMIB_CLONE_BIT 1 | ||
62 | #define INTEL_HDMIC_CLONE_BIT 2 | ||
63 | #define INTEL_HDMID_CLONE_BIT 3 | ||
64 | #define INTEL_HDMIE_CLONE_BIT 4 | ||
65 | #define INTEL_HDMIF_CLONE_BIT 5 | ||
66 | #define INTEL_SDVO_NON_TV_CLONE_BIT 6 | ||
67 | #define INTEL_SDVO_TV_CLONE_BIT 7 | ||
68 | #define INTEL_SDVO_LVDS_CLONE_BIT 8 | ||
69 | #define INTEL_ANALOG_CLONE_BIT 9 | ||
70 | #define INTEL_TV_CLONE_BIT 10 | ||
71 | #define INTEL_DP_B_CLONE_BIT 11 | ||
72 | #define INTEL_DP_C_CLONE_BIT 12 | ||
73 | #define INTEL_DP_D_CLONE_BIT 13 | ||
74 | #define INTEL_LVDS_CLONE_BIT 14 | ||
75 | #define INTEL_DVO_TMDS_CLONE_BIT 15 | ||
76 | #define INTEL_DVO_LVDS_CLONE_BIT 16 | ||
58 | 77 | ||
59 | #define INTEL_DVO_CHIP_NONE 0 | 78 | #define INTEL_DVO_CHIP_NONE 0 |
60 | #define INTEL_DVO_CHIP_LVDS 1 | 79 | #define INTEL_DVO_CHIP_LVDS 1 |
@@ -85,6 +104,8 @@ struct intel_output { | |||
85 | bool needs_tv_clock; | 104 | bool needs_tv_clock; |
86 | void *dev_priv; | 105 | void *dev_priv; |
87 | void (*hot_plug)(struct intel_output *); | 106 | void (*hot_plug)(struct intel_output *); |
107 | int crtc_mask; | ||
108 | int clone_mask; | ||
88 | }; | 109 | }; |
89 | 110 | ||
90 | struct intel_crtc { | 111 | struct intel_crtc { |
@@ -121,6 +142,8 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg); | |||
121 | void | 142 | void |
122 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | 143 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
123 | struct drm_display_mode *adjusted_mode); | 144 | struct drm_display_mode *adjusted_mode); |
145 | extern void intel_edp_link_config (struct intel_output *, int *, int *); | ||
146 | |||
124 | 147 | ||
125 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 148 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
126 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 149 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 13bff20930e8..a4d2606de778 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev) | |||
435 | continue; | 435 | continue; |
436 | 436 | ||
437 | intel_output->type = INTEL_OUTPUT_DVO; | 437 | intel_output->type = INTEL_OUTPUT_DVO; |
438 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
438 | switch (dvo->type) { | 439 | switch (dvo->type) { |
439 | case INTEL_DVO_CHIP_TMDS: | 440 | case INTEL_DVO_CHIP_TMDS: |
441 | intel_output->clone_mask = | ||
442 | (1 << INTEL_DVO_TMDS_CLONE_BIT) | | ||
443 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
440 | drm_connector_init(dev, connector, | 444 | drm_connector_init(dev, connector, |
441 | &intel_dvo_connector_funcs, | 445 | &intel_dvo_connector_funcs, |
442 | DRM_MODE_CONNECTOR_DVII); | 446 | DRM_MODE_CONNECTOR_DVII); |
443 | encoder_type = DRM_MODE_ENCODER_TMDS; | 447 | encoder_type = DRM_MODE_ENCODER_TMDS; |
444 | break; | 448 | break; |
445 | case INTEL_DVO_CHIP_LVDS: | 449 | case INTEL_DVO_CHIP_LVDS: |
450 | intel_output->clone_mask = | ||
451 | (1 << INTEL_DVO_LVDS_CLONE_BIT); | ||
446 | drm_connector_init(dev, connector, | 452 | drm_connector_init(dev, connector, |
447 | &intel_dvo_connector_funcs, | 453 | &intel_dvo_connector_funcs, |
448 | DRM_MODE_CONNECTOR_LVDS); | 454 | DRM_MODE_CONNECTOR_LVDS); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 9e30daae37dc..fa304e136010 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -130,16 +130,17 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
130 | } | 130 | } |
131 | 131 | ||
132 | static enum drm_connector_status | 132 | static enum drm_connector_status |
133 | intel_hdmi_edid_detect(struct drm_connector *connector) | 133 | intel_hdmi_detect(struct drm_connector *connector) |
134 | { | 134 | { |
135 | struct intel_output *intel_output = to_intel_output(connector); | 135 | struct intel_output *intel_output = to_intel_output(connector); |
136 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 136 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; |
137 | struct edid *edid = NULL; | 137 | struct edid *edid = NULL; |
138 | enum drm_connector_status status = connector_status_disconnected; | 138 | enum drm_connector_status status = connector_status_disconnected; |
139 | 139 | ||
140 | hdmi_priv->has_hdmi_sink = false; | ||
140 | edid = drm_get_edid(&intel_output->base, | 141 | edid = drm_get_edid(&intel_output->base, |
141 | intel_output->ddc_bus); | 142 | intel_output->ddc_bus); |
142 | hdmi_priv->has_hdmi_sink = false; | 143 | |
143 | if (edid) { | 144 | if (edid) { |
144 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 145 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
145 | status = connector_status_connected; | 146 | status = connector_status_connected; |
@@ -148,65 +149,8 @@ intel_hdmi_edid_detect(struct drm_connector *connector) | |||
148 | intel_output->base.display_info.raw_edid = NULL; | 149 | intel_output->base.display_info.raw_edid = NULL; |
149 | kfree(edid); | 150 | kfree(edid); |
150 | } | 151 | } |
151 | return status; | ||
152 | } | ||
153 | |||
154 | static enum drm_connector_status | ||
155 | igdng_hdmi_detect(struct drm_connector *connector) | ||
156 | { | ||
157 | struct intel_output *intel_output = to_intel_output(connector); | ||
158 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | ||
159 | |||
160 | /* FIXME hotplug detect */ | ||
161 | 152 | ||
162 | hdmi_priv->has_hdmi_sink = false; | 153 | return status; |
163 | return intel_hdmi_edid_detect(connector); | ||
164 | } | ||
165 | |||
166 | static enum drm_connector_status | ||
167 | intel_hdmi_detect(struct drm_connector *connector) | ||
168 | { | ||
169 | struct drm_device *dev = connector->dev; | ||
170 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
171 | struct intel_output *intel_output = to_intel_output(connector); | ||
172 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | ||
173 | u32 temp, bit; | ||
174 | |||
175 | if (IS_IGDNG(dev)) | ||
176 | return igdng_hdmi_detect(connector); | ||
177 | |||
178 | temp = I915_READ(PORT_HOTPLUG_EN); | ||
179 | |||
180 | switch (hdmi_priv->sdvox_reg) { | ||
181 | case SDVOB: | ||
182 | temp |= HDMIB_HOTPLUG_INT_EN; | ||
183 | break; | ||
184 | case SDVOC: | ||
185 | temp |= HDMIC_HOTPLUG_INT_EN; | ||
186 | break; | ||
187 | default: | ||
188 | return connector_status_unknown; | ||
189 | } | ||
190 | |||
191 | I915_WRITE(PORT_HOTPLUG_EN, temp); | ||
192 | |||
193 | POSTING_READ(PORT_HOTPLUG_EN); | ||
194 | |||
195 | switch (hdmi_priv->sdvox_reg) { | ||
196 | case SDVOB: | ||
197 | bit = HDMIB_HOTPLUG_INT_STATUS; | ||
198 | break; | ||
199 | case SDVOC: | ||
200 | bit = HDMIC_HOTPLUG_INT_STATUS; | ||
201 | break; | ||
202 | default: | ||
203 | return connector_status_unknown; | ||
204 | } | ||
205 | |||
206 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) | ||
207 | return intel_hdmi_edid_detect(connector); | ||
208 | else | ||
209 | return connector_status_disconnected; | ||
210 | } | 154 | } |
211 | 155 | ||
212 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 156 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
@@ -286,22 +230,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
286 | 230 | ||
287 | connector->interlace_allowed = 0; | 231 | connector->interlace_allowed = 0; |
288 | connector->doublescan_allowed = 0; | 232 | connector->doublescan_allowed = 0; |
233 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
289 | 234 | ||
290 | /* Set up the DDC bus. */ | 235 | /* Set up the DDC bus. */ |
291 | if (sdvox_reg == SDVOB) | 236 | if (sdvox_reg == SDVOB) { |
237 | intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); | ||
292 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); | 238 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); |
293 | else if (sdvox_reg == SDVOC) | 239 | } else if (sdvox_reg == SDVOC) { |
240 | intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); | ||
294 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); | 241 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); |
295 | else if (sdvox_reg == HDMIB) | 242 | } else if (sdvox_reg == HDMIB) { |
243 | intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); | ||
296 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, | 244 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, |
297 | "HDMIB"); | 245 | "HDMIB"); |
298 | else if (sdvox_reg == HDMIC) | 246 | } else if (sdvox_reg == HDMIC) { |
247 | intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); | ||
299 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, | 248 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, |
300 | "HDMIC"); | 249 | "HDMIC"); |
301 | else if (sdvox_reg == HDMID) | 250 | } else if (sdvox_reg == HDMID) { |
251 | intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); | ||
302 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, | 252 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, |
303 | "HDMID"); | 253 | "HDMID"); |
304 | 254 | } | |
305 | if (!intel_output->ddc_bus) | 255 | if (!intel_output->ddc_bus) |
306 | goto err_connector; | 256 | goto err_connector; |
307 | 257 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 9ab38efffecf..8df02ef89261 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
780 | }, | 780 | }, |
781 | { | 781 | { |
782 | .callback = intel_no_lvds_dmi_callback, | 782 | .callback = intel_no_lvds_dmi_callback, |
783 | .ident = "AOpen Mini PC MP915", | ||
784 | .matches = { | ||
785 | DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), | ||
786 | DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"), | ||
787 | }, | ||
788 | }, | ||
789 | { | ||
790 | .callback = intel_no_lvds_dmi_callback, | ||
783 | .ident = "Aopen i945GTt-VFA", | 791 | .ident = "Aopen i945GTt-VFA", |
784 | .matches = { | 792 | .matches = { |
785 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), | 793 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), |
@@ -884,6 +892,10 @@ void intel_lvds_init(struct drm_device *dev) | |||
884 | if (IS_IGDNG(dev)) { | 892 | if (IS_IGDNG(dev)) { |
885 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 893 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
886 | return; | 894 | return; |
895 | if (dev_priv->edp_support) { | ||
896 | DRM_DEBUG("disable LVDS for eDP support\n"); | ||
897 | return; | ||
898 | } | ||
887 | gpio = PCH_GPIOC; | 899 | gpio = PCH_GPIOC; |
888 | } | 900 | } |
889 | 901 | ||
@@ -904,6 +916,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
904 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 916 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
905 | intel_output->type = INTEL_OUTPUT_LVDS; | 917 | intel_output->type = INTEL_OUTPUT_LVDS; |
906 | 918 | ||
919 | intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | ||
920 | intel_output->crtc_mask = (1 << 1); | ||
907 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); | 921 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); |
908 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); | 922 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); |
909 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 923 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 4f0c30948bc4..d3b74ba62b4a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "drm.h" | 31 | #include "drm.h" |
32 | #include "drm_crtc.h" | 32 | #include "drm_crtc.h" |
33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
34 | #include "drm_edid.h" | ||
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
36 | #include "intel_sdvo_regs.h" | 37 | #include "intel_sdvo_regs.h" |
@@ -55,6 +56,12 @@ struct intel_sdvo_priv { | |||
55 | /* Pixel clock limitations reported by the SDVO device, in kHz */ | 56 | /* Pixel clock limitations reported by the SDVO device, in kHz */ |
56 | int pixel_clock_min, pixel_clock_max; | 57 | int pixel_clock_min, pixel_clock_max; |
57 | 58 | ||
59 | /* | ||
60 | * For multiple function SDVO device, | ||
61 | * this is for current attached outputs. | ||
62 | */ | ||
63 | uint16_t attached_output; | ||
64 | |||
58 | /** | 65 | /** |
59 | * This is set if we're going to treat the device as TV-out. | 66 | * This is set if we're going to treat the device as TV-out. |
60 | * | 67 | * |
@@ -114,6 +121,9 @@ struct intel_sdvo_priv { | |||
114 | u32 save_SDVOX; | 121 | u32 save_SDVOX; |
115 | }; | 122 | }; |
116 | 123 | ||
124 | static bool | ||
125 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags); | ||
126 | |||
117 | /** | 127 | /** |
118 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 128 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
119 | * SDVOB and SDVOC to work around apparent hardware issues (according to | 129 | * SDVOB and SDVOC to work around apparent hardware issues (according to |
@@ -1435,41 +1445,96 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | |||
1435 | intel_sdvo_read_response(intel_output, &response, 2); | 1445 | intel_sdvo_read_response(intel_output, &response, 2); |
1436 | } | 1446 | } |
1437 | 1447 | ||
1438 | static void | 1448 | static bool |
1439 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | 1449 | intel_sdvo_multifunc_encoder(struct intel_output *intel_output) |
1450 | { | ||
1451 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1452 | int caps = 0; | ||
1453 | |||
1454 | if (sdvo_priv->caps.output_flags & | ||
1455 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | ||
1456 | caps++; | ||
1457 | if (sdvo_priv->caps.output_flags & | ||
1458 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | ||
1459 | caps++; | ||
1460 | if (sdvo_priv->caps.output_flags & | ||
1461 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) | ||
1462 | caps++; | ||
1463 | if (sdvo_priv->caps.output_flags & | ||
1464 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | ||
1465 | caps++; | ||
1466 | if (sdvo_priv->caps.output_flags & | ||
1467 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) | ||
1468 | caps++; | ||
1469 | |||
1470 | if (sdvo_priv->caps.output_flags & | ||
1471 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) | ||
1472 | caps++; | ||
1473 | |||
1474 | if (sdvo_priv->caps.output_flags & | ||
1475 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) | ||
1476 | caps++; | ||
1477 | |||
1478 | return (caps > 1); | ||
1479 | } | ||
1480 | |||
1481 | enum drm_connector_status | ||
1482 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | ||
1440 | { | 1483 | { |
1441 | struct intel_output *intel_output = to_intel_output(connector); | 1484 | struct intel_output *intel_output = to_intel_output(connector); |
1442 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1485 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1486 | enum drm_connector_status status = connector_status_connected; | ||
1443 | struct edid *edid = NULL; | 1487 | struct edid *edid = NULL; |
1444 | 1488 | ||
1445 | edid = drm_get_edid(&intel_output->base, | 1489 | edid = drm_get_edid(&intel_output->base, |
1446 | intel_output->ddc_bus); | 1490 | intel_output->ddc_bus); |
1447 | if (edid != NULL) { | 1491 | if (edid != NULL) { |
1448 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1492 | /* Don't report the output as connected if it's a DVI-I |
1493 | * connector with a non-digital EDID coming out. | ||
1494 | */ | ||
1495 | if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1496 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
1497 | sdvo_priv->is_hdmi = | ||
1498 | drm_detect_hdmi_monitor(edid); | ||
1499 | else | ||
1500 | status = connector_status_disconnected; | ||
1501 | } | ||
1502 | |||
1449 | kfree(edid); | 1503 | kfree(edid); |
1450 | intel_output->base.display_info.raw_edid = NULL; | 1504 | intel_output->base.display_info.raw_edid = NULL; |
1451 | } | 1505 | |
1506 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | ||
1507 | status = connector_status_disconnected; | ||
1508 | |||
1509 | return status; | ||
1452 | } | 1510 | } |
1453 | 1511 | ||
1454 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1512 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
1455 | { | 1513 | { |
1456 | u8 response[2]; | 1514 | uint16_t response; |
1457 | u8 status; | 1515 | u8 status; |
1458 | struct intel_output *intel_output = to_intel_output(connector); | 1516 | struct intel_output *intel_output = to_intel_output(connector); |
1517 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1459 | 1518 | ||
1460 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1519 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); |
1461 | status = intel_sdvo_read_response(intel_output, &response, 2); | 1520 | status = intel_sdvo_read_response(intel_output, &response, 2); |
1462 | 1521 | ||
1463 | DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); | 1522 | DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8); |
1464 | 1523 | ||
1465 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1524 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1466 | return connector_status_unknown; | 1525 | return connector_status_unknown; |
1467 | 1526 | ||
1468 | if ((response[0] != 0) || (response[1] != 0)) { | 1527 | if (response == 0) |
1469 | intel_sdvo_hdmi_sink_detect(connector); | ||
1470 | return connector_status_connected; | ||
1471 | } else | ||
1472 | return connector_status_disconnected; | 1528 | return connector_status_disconnected; |
1529 | |||
1530 | if (intel_sdvo_multifunc_encoder(intel_output) && | ||
1531 | sdvo_priv->attached_output != response) { | ||
1532 | if (sdvo_priv->controlled_output != response && | ||
1533 | intel_sdvo_output_setup(intel_output, response) != true) | ||
1534 | return connector_status_unknown; | ||
1535 | sdvo_priv->attached_output = response; | ||
1536 | } | ||
1537 | return intel_sdvo_hdmi_sink_detect(connector, response); | ||
1473 | } | 1538 | } |
1474 | 1539 | ||
1475 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1540 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
@@ -1866,16 +1931,112 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) | |||
1866 | return 0x72; | 1931 | return 0x72; |
1867 | } | 1932 | } |
1868 | 1933 | ||
1934 | static bool | ||
1935 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | ||
1936 | { | ||
1937 | struct drm_connector *connector = &intel_output->base; | ||
1938 | struct drm_encoder *encoder = &intel_output->enc; | ||
1939 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1940 | bool ret = true, registered = false; | ||
1941 | |||
1942 | sdvo_priv->is_tv = false; | ||
1943 | intel_output->needs_tv_clock = false; | ||
1944 | sdvo_priv->is_lvds = false; | ||
1945 | |||
1946 | if (device_is_registered(&connector->kdev)) { | ||
1947 | drm_sysfs_connector_remove(connector); | ||
1948 | registered = true; | ||
1949 | } | ||
1950 | |||
1951 | if (flags & | ||
1952 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1953 | if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) | ||
1954 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; | ||
1955 | else | ||
1956 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | ||
1957 | |||
1958 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | ||
1959 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | ||
1960 | |||
1961 | if (intel_sdvo_get_supp_encode(intel_output, | ||
1962 | &sdvo_priv->encode) && | ||
1963 | intel_sdvo_get_digital_encoding_mode(intel_output) && | ||
1964 | sdvo_priv->is_hdmi) { | ||
1965 | /* enable hdmi encoding mode if supported */ | ||
1966 | intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); | ||
1967 | intel_sdvo_set_colorimetry(intel_output, | ||
1968 | SDVO_COLORIMETRY_RGB256); | ||
1969 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
1970 | intel_output->clone_mask = | ||
1971 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
1972 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1973 | } | ||
1974 | } else if (flags & SDVO_OUTPUT_SVID0) { | ||
1975 | |||
1976 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | ||
1977 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
1978 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
1979 | sdvo_priv->is_tv = true; | ||
1980 | intel_output->needs_tv_clock = true; | ||
1981 | intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
1982 | } else if (flags & SDVO_OUTPUT_RGB0) { | ||
1983 | |||
1984 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | ||
1985 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
1986 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1987 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
1988 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1989 | } else if (flags & SDVO_OUTPUT_RGB1) { | ||
1990 | |||
1991 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | ||
1992 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
1993 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1994 | } else if (flags & SDVO_OUTPUT_LVDS0) { | ||
1995 | |||
1996 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | ||
1997 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1998 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1999 | sdvo_priv->is_lvds = true; | ||
2000 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2001 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2002 | } else if (flags & SDVO_OUTPUT_LVDS1) { | ||
2003 | |||
2004 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | ||
2005 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
2006 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
2007 | sdvo_priv->is_lvds = true; | ||
2008 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2009 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2010 | } else { | ||
2011 | |||
2012 | unsigned char bytes[2]; | ||
2013 | |||
2014 | sdvo_priv->controlled_output = 0; | ||
2015 | memcpy(bytes, &sdvo_priv->caps.output_flags, 2); | ||
2016 | DRM_DEBUG_KMS(I915_SDVO, | ||
2017 | "%s: Unknown SDVO output type (0x%02x%02x)\n", | ||
2018 | SDVO_NAME(sdvo_priv), | ||
2019 | bytes[0], bytes[1]); | ||
2020 | ret = false; | ||
2021 | } | ||
2022 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
2023 | |||
2024 | if (ret && registered) | ||
2025 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | ||
2026 | |||
2027 | |||
2028 | return ret; | ||
2029 | |||
2030 | } | ||
2031 | |||
1869 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 2032 | bool intel_sdvo_init(struct drm_device *dev, int output_device) |
1870 | { | 2033 | { |
1871 | struct drm_connector *connector; | 2034 | struct drm_connector *connector; |
1872 | struct intel_output *intel_output; | 2035 | struct intel_output *intel_output; |
1873 | struct intel_sdvo_priv *sdvo_priv; | 2036 | struct intel_sdvo_priv *sdvo_priv; |
1874 | 2037 | ||
1875 | int connector_type; | ||
1876 | u8 ch[0x40]; | 2038 | u8 ch[0x40]; |
1877 | int i; | 2039 | int i; |
1878 | int encoder_type; | ||
1879 | 2040 | ||
1880 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2041 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
1881 | if (!intel_output) { | 2042 | if (!intel_output) { |
@@ -1925,88 +2086,28 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1925 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; | 2086 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
1926 | 2087 | ||
1927 | /* In defaut case sdvo lvds is false */ | 2088 | /* In defaut case sdvo lvds is false */ |
1928 | sdvo_priv->is_lvds = false; | ||
1929 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); | 2089 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); |
1930 | 2090 | ||
1931 | if (sdvo_priv->caps.output_flags & | 2091 | if (intel_sdvo_output_setup(intel_output, |
1932 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | 2092 | sdvo_priv->caps.output_flags) != true) { |
1933 | if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) | 2093 | DRM_DEBUG("SDVO output failed to setup on SDVO%c\n", |
1934 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; | 2094 | output_device == SDVOB ? 'B' : 'C'); |
1935 | else | ||
1936 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | ||
1937 | |||
1938 | encoder_type = DRM_MODE_ENCODER_TMDS; | ||
1939 | connector_type = DRM_MODE_CONNECTOR_DVID; | ||
1940 | |||
1941 | if (intel_sdvo_get_supp_encode(intel_output, | ||
1942 | &sdvo_priv->encode) && | ||
1943 | intel_sdvo_get_digital_encoding_mode(intel_output) && | ||
1944 | sdvo_priv->is_hdmi) { | ||
1945 | /* enable hdmi encoding mode if supported */ | ||
1946 | intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); | ||
1947 | intel_sdvo_set_colorimetry(intel_output, | ||
1948 | SDVO_COLORIMETRY_RGB256); | ||
1949 | connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
1950 | } | ||
1951 | } | ||
1952 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0) | ||
1953 | { | ||
1954 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | ||
1955 | encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
1956 | connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
1957 | sdvo_priv->is_tv = true; | ||
1958 | intel_output->needs_tv_clock = true; | ||
1959 | } | ||
1960 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) | ||
1961 | { | ||
1962 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | ||
1963 | encoder_type = DRM_MODE_ENCODER_DAC; | ||
1964 | connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1965 | } | ||
1966 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) | ||
1967 | { | ||
1968 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | ||
1969 | encoder_type = DRM_MODE_ENCODER_DAC; | ||
1970 | connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1971 | } | ||
1972 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0) | ||
1973 | { | ||
1974 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | ||
1975 | encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1976 | connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1977 | sdvo_priv->is_lvds = true; | ||
1978 | } | ||
1979 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1) | ||
1980 | { | ||
1981 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | ||
1982 | encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1983 | connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1984 | sdvo_priv->is_lvds = true; | ||
1985 | } | ||
1986 | else | ||
1987 | { | ||
1988 | unsigned char bytes[2]; | ||
1989 | |||
1990 | sdvo_priv->controlled_output = 0; | ||
1991 | memcpy (bytes, &sdvo_priv->caps.output_flags, 2); | ||
1992 | DRM_DEBUG_KMS(I915_SDVO, | ||
1993 | "%s: Unknown SDVO output type (0x%02x%02x)\n", | ||
1994 | SDVO_NAME(sdvo_priv), | ||
1995 | bytes[0], bytes[1]); | ||
1996 | encoder_type = DRM_MODE_ENCODER_NONE; | ||
1997 | connector_type = DRM_MODE_CONNECTOR_Unknown; | ||
1998 | goto err_i2c; | 2095 | goto err_i2c; |
1999 | } | 2096 | } |
2000 | 2097 | ||
2098 | |||
2001 | connector = &intel_output->base; | 2099 | connector = &intel_output->base; |
2002 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, | 2100 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, |
2003 | connector_type); | 2101 | connector->connector_type); |
2102 | |||
2004 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); | 2103 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); |
2005 | connector->interlace_allowed = 0; | 2104 | connector->interlace_allowed = 0; |
2006 | connector->doublescan_allowed = 0; | 2105 | connector->doublescan_allowed = 0; |
2007 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 2106 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
2008 | 2107 | ||
2009 | drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type); | 2108 | drm_encoder_init(dev, &intel_output->enc, |
2109 | &intel_sdvo_enc_funcs, intel_output->enc.encoder_type); | ||
2110 | |||
2010 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); | 2111 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); |
2011 | 2112 | ||
2012 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 2113 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index a43c98e3f077..2fbe13a0de81 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1490,6 +1490,27 @@ static struct input_res { | |||
1490 | {"1920x1080", 1920, 1080}, | 1490 | {"1920x1080", 1920, 1080}, |
1491 | }; | 1491 | }; |
1492 | 1492 | ||
1493 | /* | ||
1494 | * Chose preferred mode according to line number of TV format | ||
1495 | */ | ||
1496 | static void | ||
1497 | intel_tv_chose_preferred_modes(struct drm_connector *connector, | ||
1498 | struct drm_display_mode *mode_ptr) | ||
1499 | { | ||
1500 | struct intel_output *intel_output = to_intel_output(connector); | ||
1501 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | ||
1502 | |||
1503 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | ||
1504 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | ||
1505 | else if (tv_mode->nbr_end > 480) { | ||
1506 | if (tv_mode->progressive == true && tv_mode->nbr_end < 720) { | ||
1507 | if (mode_ptr->vdisplay == 720) | ||
1508 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | ||
1509 | } else if (mode_ptr->vdisplay == 1080) | ||
1510 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1493 | /** | 1514 | /** |
1494 | * Stub get_modes function. | 1515 | * Stub get_modes function. |
1495 | * | 1516 | * |
@@ -1544,6 +1565,7 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
1544 | mode_ptr->clock = (int) tmp; | 1565 | mode_ptr->clock = (int) tmp; |
1545 | 1566 | ||
1546 | mode_ptr->type = DRM_MODE_TYPE_DRIVER; | 1567 | mode_ptr->type = DRM_MODE_TYPE_DRIVER; |
1568 | intel_tv_chose_preferred_modes(connector, mode_ptr); | ||
1547 | drm_mode_probed_add(connector, mode_ptr); | 1569 | drm_mode_probed_add(connector, mode_ptr); |
1548 | count++; | 1570 | count++; |
1549 | } | 1571 | } |
@@ -1696,6 +1718,7 @@ intel_tv_init(struct drm_device *dev) | |||
1696 | if (!intel_output) { | 1718 | if (!intel_output) { |
1697 | return; | 1719 | return; |
1698 | } | 1720 | } |
1721 | |||
1699 | connector = &intel_output->base; | 1722 | connector = &intel_output->base; |
1700 | 1723 | ||
1701 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1724 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
@@ -1707,6 +1730,7 @@ intel_tv_init(struct drm_device *dev) | |||
1707 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 1730 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
1708 | tv_priv = (struct intel_tv_priv *)(intel_output + 1); | 1731 | tv_priv = (struct intel_tv_priv *)(intel_output + 1); |
1709 | intel_output->type = INTEL_OUTPUT_TVOUT; | 1732 | intel_output->type = INTEL_OUTPUT_TVOUT; |
1733 | intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); | ||
1710 | intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1734 | intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
1711 | intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1735 | intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1712 | intel_output->dev_priv = tv_priv; | 1736 | intel_output->dev_priv = tv_priv; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 05a44896dffb..68e728e8be4d 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -254,6 +254,72 @@ void r100_mc_fini(struct radeon_device *rdev) | |||
254 | 254 | ||
255 | 255 | ||
256 | /* | 256 | /* |
257 | * Interrupts | ||
258 | */ | ||
259 | int r100_irq_set(struct radeon_device *rdev) | ||
260 | { | ||
261 | uint32_t tmp = 0; | ||
262 | |||
263 | if (rdev->irq.sw_int) { | ||
264 | tmp |= RADEON_SW_INT_ENABLE; | ||
265 | } | ||
266 | if (rdev->irq.crtc_vblank_int[0]) { | ||
267 | tmp |= RADEON_CRTC_VBLANK_MASK; | ||
268 | } | ||
269 | if (rdev->irq.crtc_vblank_int[1]) { | ||
270 | tmp |= RADEON_CRTC2_VBLANK_MASK; | ||
271 | } | ||
272 | WREG32(RADEON_GEN_INT_CNTL, tmp); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | ||
277 | { | ||
278 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | ||
279 | uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | | ||
280 | RADEON_CRTC2_VBLANK_STAT; | ||
281 | |||
282 | if (irqs) { | ||
283 | WREG32(RADEON_GEN_INT_STATUS, irqs); | ||
284 | } | ||
285 | return irqs & irq_mask; | ||
286 | } | ||
287 | |||
288 | int r100_irq_process(struct radeon_device *rdev) | ||
289 | { | ||
290 | uint32_t status; | ||
291 | |||
292 | status = r100_irq_ack(rdev); | ||
293 | if (!status) { | ||
294 | return IRQ_NONE; | ||
295 | } | ||
296 | while (status) { | ||
297 | /* SW interrupt */ | ||
298 | if (status & RADEON_SW_INT_TEST) { | ||
299 | radeon_fence_process(rdev); | ||
300 | } | ||
301 | /* Vertical blank interrupts */ | ||
302 | if (status & RADEON_CRTC_VBLANK_STAT) { | ||
303 | drm_handle_vblank(rdev->ddev, 0); | ||
304 | } | ||
305 | if (status & RADEON_CRTC2_VBLANK_STAT) { | ||
306 | drm_handle_vblank(rdev->ddev, 1); | ||
307 | } | ||
308 | status = r100_irq_ack(rdev); | ||
309 | } | ||
310 | return IRQ_HANDLED; | ||
311 | } | ||
312 | |||
313 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) | ||
314 | { | ||
315 | if (crtc == 0) | ||
316 | return RREG32(RADEON_CRTC_CRNT_FRAME); | ||
317 | else | ||
318 | return RREG32(RADEON_CRTC2_CRNT_FRAME); | ||
319 | } | ||
320 | |||
321 | |||
322 | /* | ||
257 | * Fence emission | 323 | * Fence emission |
258 | */ | 324 | */ |
259 | void r100_fence_ring_emit(struct radeon_device *rdev, | 325 | void r100_fence_ring_emit(struct radeon_device *rdev, |
@@ -722,13 +788,14 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p, | |||
722 | unsigned idx) | 788 | unsigned idx) |
723 | { | 789 | { |
724 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; | 790 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; |
725 | uint32_t header = ib_chunk->kdata[idx]; | 791 | uint32_t header; |
726 | 792 | ||
727 | if (idx >= ib_chunk->length_dw) { | 793 | if (idx >= ib_chunk->length_dw) { |
728 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", | 794 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", |
729 | idx, ib_chunk->length_dw); | 795 | idx, ib_chunk->length_dw); |
730 | return -EINVAL; | 796 | return -EINVAL; |
731 | } | 797 | } |
798 | header = ib_chunk->kdata[idx]; | ||
732 | pkt->idx = idx; | 799 | pkt->idx = idx; |
733 | pkt->type = CP_PACKET_GET_TYPE(header); | 800 | pkt->type = CP_PACKET_GET_TYPE(header); |
734 | pkt->count = CP_PACKET_GET_COUNT(header); | 801 | pkt->count = CP_PACKET_GET_COUNT(header); |
@@ -1024,6 +1091,16 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1024 | tmp |= tile_flags; | 1091 | tmp |= tile_flags; |
1025 | ib[idx] = tmp; | 1092 | ib[idx] = tmp; |
1026 | break; | 1093 | break; |
1094 | case RADEON_RB3D_ZPASS_ADDR: | ||
1095 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1096 | if (r) { | ||
1097 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
1098 | idx, reg); | ||
1099 | r100_cs_dump_packet(p, pkt); | ||
1100 | return r; | ||
1101 | } | ||
1102 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | ||
1103 | break; | ||
1027 | default: | 1104 | default: |
1028 | /* FIXME: we don't want to allow anyothers packet */ | 1105 | /* FIXME: we don't want to allow anyothers packet */ |
1029 | break; | 1106 | break; |
@@ -1555,26 +1632,6 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
1555 | r100_pll_errata_after_data(rdev); | 1632 | r100_pll_errata_after_data(rdev); |
1556 | } | 1633 | } |
1557 | 1634 | ||
1558 | uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) | ||
1559 | { | ||
1560 | if (reg < 0x10000) | ||
1561 | return readl(((void __iomem *)rdev->rmmio) + reg); | ||
1562 | else { | ||
1563 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | ||
1564 | return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | ||
1565 | } | ||
1566 | } | ||
1567 | |||
1568 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
1569 | { | ||
1570 | if (reg < 0x10000) | ||
1571 | writel(v, ((void __iomem *)rdev->rmmio) + reg); | ||
1572 | else { | ||
1573 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | ||
1574 | writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | int r100_init(struct radeon_device *rdev) | 1635 | int r100_init(struct radeon_device *rdev) |
1579 | { | 1636 | { |
1580 | return 0; | 1637 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 9c8d41534a5d..053f4ec397f7 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -83,8 +83,8 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
83 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB); | 83 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB); |
84 | (void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); | 84 | (void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); |
85 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); | 85 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); |
86 | mb(); | ||
87 | } | 86 | } |
87 | mb(); | ||
88 | } | 88 | } |
89 | 89 | ||
90 | int rv370_pcie_gart_enable(struct radeon_device *rdev) | 90 | int rv370_pcie_gart_enable(struct radeon_device *rdev) |
@@ -448,6 +448,7 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
448 | /* rv350,rv370,rv380 */ | 448 | /* rv350,rv370,rv380 */ |
449 | rdev->num_gb_pipes = 1; | 449 | rdev->num_gb_pipes = 1; |
450 | } | 450 | } |
451 | rdev->num_z_pipes = 1; | ||
451 | gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); | 452 | gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); |
452 | switch (rdev->num_gb_pipes) { | 453 | switch (rdev->num_gb_pipes) { |
453 | case 2: | 454 | case 2: |
@@ -486,7 +487,8 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
486 | printk(KERN_WARNING "Failed to wait MC idle while " | 487 | printk(KERN_WARNING "Failed to wait MC idle while " |
487 | "programming pipes. Bad things might happen.\n"); | 488 | "programming pipes. Bad things might happen.\n"); |
488 | } | 489 | } |
489 | DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes); | 490 | DRM_INFO("radeon: %d quad pipes, %d Z pipes initialized.\n", |
491 | rdev->num_gb_pipes, rdev->num_z_pipes); | ||
490 | } | 492 | } |
491 | 493 | ||
492 | int r300_ga_reset(struct radeon_device *rdev) | 494 | int r300_ga_reset(struct radeon_device *rdev) |
@@ -593,27 +595,6 @@ void r300_vram_info(struct radeon_device *rdev) | |||
593 | 595 | ||
594 | 596 | ||
595 | /* | 597 | /* |
596 | * Indirect registers accessor | ||
597 | */ | ||
598 | uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg) | ||
599 | { | ||
600 | uint32_t r; | ||
601 | |||
602 | WREG8(RADEON_PCIE_INDEX, ((reg) & 0xff)); | ||
603 | (void)RREG32(RADEON_PCIE_INDEX); | ||
604 | r = RREG32(RADEON_PCIE_DATA); | ||
605 | return r; | ||
606 | } | ||
607 | |||
608 | void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
609 | { | ||
610 | WREG8(RADEON_PCIE_INDEX, ((reg) & 0xff)); | ||
611 | (void)RREG32(RADEON_PCIE_INDEX); | ||
612 | WREG32(RADEON_PCIE_DATA, (v)); | ||
613 | (void)RREG32(RADEON_PCIE_DATA); | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * PCIE Lanes | 598 | * PCIE Lanes |
618 | */ | 599 | */ |
619 | 600 | ||
@@ -1403,6 +1384,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
1403 | tmp = (ib_chunk->kdata[idx] >> 22) & 0xF; | 1384 | tmp = (ib_chunk->kdata[idx] >> 22) & 0xF; |
1404 | track->textures[i].txdepth = tmp; | 1385 | track->textures[i].txdepth = tmp; |
1405 | break; | 1386 | break; |
1387 | case R300_ZB_ZPASS_ADDR: | ||
1388 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1389 | if (r) { | ||
1390 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
1391 | idx, reg); | ||
1392 | r100_cs_dump_packet(p, pkt); | ||
1393 | return r; | ||
1394 | } | ||
1395 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | ||
1396 | break; | ||
1397 | case 0x4be8: | ||
1398 | /* valid register only on RV530 */ | ||
1399 | if (p->rdev->family == CHIP_RV530) | ||
1400 | break; | ||
1401 | /* fallthrough do not move */ | ||
1406 | default: | 1402 | default: |
1407 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | 1403 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
1408 | reg, idx); | 1404 | reg, idx); |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index dea497a979f2..97426a6f370f 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -165,7 +165,18 @@ void r420_pipes_init(struct radeon_device *rdev) | |||
165 | printk(KERN_WARNING "Failed to wait GUI idle while " | 165 | printk(KERN_WARNING "Failed to wait GUI idle while " |
166 | "programming pipes. Bad things might happen.\n"); | 166 | "programming pipes. Bad things might happen.\n"); |
167 | } | 167 | } |
168 | DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes); | 168 | |
169 | if (rdev->family == CHIP_RV530) { | ||
170 | tmp = RREG32(RV530_GB_PIPE_SELECT2); | ||
171 | if ((tmp & 3) == 3) | ||
172 | rdev->num_z_pipes = 2; | ||
173 | else | ||
174 | rdev->num_z_pipes = 1; | ||
175 | } else | ||
176 | rdev->num_z_pipes = 1; | ||
177 | |||
178 | DRM_INFO("radeon: %d quad pipes, %d z pipes initialized.\n", | ||
179 | rdev->num_gb_pipes, rdev->num_z_pipes); | ||
169 | } | 180 | } |
170 | 181 | ||
171 | void r420_gpu_init(struct radeon_device *rdev) | 182 | void r420_gpu_init(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 036691b38cb7..e1d5e0331e19 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
@@ -350,6 +350,7 @@ | |||
350 | #define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 | 350 | #define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 |
351 | #define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 | 351 | #define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 |
352 | #define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c | 352 | #define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c |
353 | #define AVIVO_D1CRTC_FRAME_COUNT 0x60a4 | ||
353 | #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 | 354 | #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 |
354 | 355 | ||
355 | /* master controls */ | 356 | /* master controls */ |
@@ -438,14 +439,15 @@ | |||
438 | # define AVIVO_DC_LB_DISP1_END_ADR_SHIFT 4 | 439 | # define AVIVO_DC_LB_DISP1_END_ADR_SHIFT 4 |
439 | # define AVIVO_DC_LB_DISP1_END_ADR_MASK 0x7ff | 440 | # define AVIVO_DC_LB_DISP1_END_ADR_MASK 0x7ff |
440 | 441 | ||
441 | #define R500_DxMODE_INT_MASK 0x6540 | ||
442 | #define R500_D1MODE_INT_MASK (1<<0) | ||
443 | #define R500_D2MODE_INT_MASK (1<<8) | ||
444 | |||
445 | #define AVIVO_D1MODE_DATA_FORMAT 0x6528 | 442 | #define AVIVO_D1MODE_DATA_FORMAT 0x6528 |
446 | # define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) | 443 | # define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) |
447 | #define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C | 444 | #define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C |
445 | #define AVIVO_D1MODE_VBLANK_STATUS 0x6534 | ||
446 | # define AVIVO_VBLANK_ACK (1 << 4) | ||
448 | #define AVIVO_D1MODE_VLINE_START_END 0x6538 | 447 | #define AVIVO_D1MODE_VLINE_START_END 0x6538 |
448 | #define AVIVO_DxMODE_INT_MASK 0x6540 | ||
449 | # define AVIVO_D1MODE_INT_MASK (1 << 0) | ||
450 | # define AVIVO_D2MODE_INT_MASK (1 << 8) | ||
449 | #define AVIVO_D1MODE_VIEWPORT_START 0x6580 | 451 | #define AVIVO_D1MODE_VIEWPORT_START 0x6580 |
450 | #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 | 452 | #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 |
451 | #define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 | 453 | #define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 |
@@ -475,6 +477,7 @@ | |||
475 | #define AVIVO_D2CRTC_BLANK_CONTROL 0x6884 | 477 | #define AVIVO_D2CRTC_BLANK_CONTROL 0x6884 |
476 | #define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888 | 478 | #define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888 |
477 | #define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c | 479 | #define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c |
480 | #define AVIVO_D2CRTC_FRAME_COUNT 0x68a4 | ||
478 | #define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4 | 481 | #define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4 |
479 | 482 | ||
480 | #define AVIVO_D2GRPH_ENABLE 0x6900 | 483 | #define AVIVO_D2GRPH_ENABLE 0x6900 |
@@ -497,6 +500,7 @@ | |||
497 | #define AVIVO_D2CUR_SIZE 0x6c10 | 500 | #define AVIVO_D2CUR_SIZE 0x6c10 |
498 | #define AVIVO_D2CUR_POSITION 0x6c14 | 501 | #define AVIVO_D2CUR_POSITION 0x6c14 |
499 | 502 | ||
503 | #define AVIVO_D2MODE_VBLANK_STATUS 0x6d34 | ||
500 | #define AVIVO_D2MODE_VLINE_START_END 0x6d38 | 504 | #define AVIVO_D2MODE_VLINE_START_END 0x6d38 |
501 | #define AVIVO_D2MODE_VIEWPORT_START 0x6d80 | 505 | #define AVIVO_D2MODE_VIEWPORT_START 0x6d80 |
502 | #define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 | 506 | #define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 |
@@ -748,4 +752,8 @@ | |||
748 | # define AVIVO_I2C_EN (1 << 0) | 752 | # define AVIVO_I2C_EN (1 << 0) |
749 | # define AVIVO_I2C_RESET (1 << 8) | 753 | # define AVIVO_I2C_RESET (1 << 8) |
750 | 754 | ||
755 | #define AVIVO_DISP_INTERRUPT_STATUS 0x7edc | ||
756 | # define AVIVO_D1_VBLANK_INTERRUPT (1 << 4) | ||
757 | # define AVIVO_D2_VBLANK_INTERRUPT (1 << 5) | ||
758 | |||
751 | #endif | 759 | #endif |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 09fb0b6ec7dd..ebd6b0f7bdff 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -177,7 +177,6 @@ void r520_gpu_init(struct radeon_device *rdev) | |||
177 | */ | 177 | */ |
178 | /* workaround for RV530 */ | 178 | /* workaround for RV530 */ |
179 | if (rdev->family == CHIP_RV530) { | 179 | if (rdev->family == CHIP_RV530) { |
180 | WREG32(0x4124, 1); | ||
181 | WREG32(0x4128, 0xFF); | 180 | WREG32(0x4128, 0xFF); |
182 | } | 181 | } |
183 | r420_pipes_init(rdev); | 182 | r420_pipes_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 146f3570af8e..20f17908b036 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
@@ -384,8 +384,9 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) | |||
384 | DRM_INFO("Loading RV670 PFP Microcode\n"); | 384 | DRM_INFO("Loading RV670 PFP Microcode\n"); |
385 | for (i = 0; i < PFP_UCODE_SIZE; i++) | 385 | for (i = 0; i < PFP_UCODE_SIZE; i++) |
386 | RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); | 386 | RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); |
387 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { | 387 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || |
388 | DRM_INFO("Loading RS780 CP Microcode\n"); | 388 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { |
389 | DRM_INFO("Loading RS780/RS880 CP Microcode\n"); | ||
389 | for (i = 0; i < PM4_UCODE_SIZE; i++) { | 390 | for (i = 0; i < PM4_UCODE_SIZE; i++) { |
390 | RADEON_WRITE(R600_CP_ME_RAM_DATA, | 391 | RADEON_WRITE(R600_CP_ME_RAM_DATA, |
391 | RS780_cp_microcode[i][0]); | 392 | RS780_cp_microcode[i][0]); |
@@ -396,7 +397,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) | |||
396 | } | 397 | } |
397 | 398 | ||
398 | RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); | 399 | RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); |
399 | DRM_INFO("Loading RS780 PFP Microcode\n"); | 400 | DRM_INFO("Loading RS780/RS880 PFP Microcode\n"); |
400 | for (i = 0; i < PFP_UCODE_SIZE; i++) | 401 | for (i = 0; i < PFP_UCODE_SIZE; i++) |
401 | RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]); | 402 | RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]); |
402 | } | 403 | } |
@@ -783,6 +784,7 @@ static void r600_gfx_init(struct drm_device *dev, | |||
783 | break; | 784 | break; |
784 | case CHIP_RV610: | 785 | case CHIP_RV610: |
785 | case CHIP_RS780: | 786 | case CHIP_RS780: |
787 | case CHIP_RS880: | ||
786 | case CHIP_RV620: | 788 | case CHIP_RV620: |
787 | dev_priv->r600_max_pipes = 1; | 789 | dev_priv->r600_max_pipes = 1; |
788 | dev_priv->r600_max_tile_pipes = 1; | 790 | dev_priv->r600_max_tile_pipes = 1; |
@@ -917,7 +919,8 @@ static void r600_gfx_init(struct drm_device *dev, | |||
917 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || | 919 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || |
918 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || | 920 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || |
919 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || | 921 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || |
920 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) | 922 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || |
923 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) | ||
921 | RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); | 924 | RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); |
922 | else | 925 | else |
923 | RADEON_WRITE(R600_DB_DEBUG, 0); | 926 | RADEON_WRITE(R600_DB_DEBUG, 0); |
@@ -935,7 +938,8 @@ static void r600_gfx_init(struct drm_device *dev, | |||
935 | sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); | 938 | sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); |
936 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || | 939 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || |
937 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || | 940 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || |
938 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { | 941 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || |
942 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { | ||
939 | sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | | 943 | sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | |
940 | R600_FETCH_FIFO_HIWATER(0xa) | | 944 | R600_FETCH_FIFO_HIWATER(0xa) | |
941 | R600_DONE_FIFO_HIWATER(0xe0) | | 945 | R600_DONE_FIFO_HIWATER(0xe0) | |
@@ -978,7 +982,8 @@ static void r600_gfx_init(struct drm_device *dev, | |||
978 | R600_NUM_ES_STACK_ENTRIES(0)); | 982 | R600_NUM_ES_STACK_ENTRIES(0)); |
979 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || | 983 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || |
980 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || | 984 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || |
981 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { | 985 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || |
986 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { | ||
982 | /* no vertex cache */ | 987 | /* no vertex cache */ |
983 | sq_config &= ~R600_VC_ENABLE; | 988 | sq_config &= ~R600_VC_ENABLE; |
984 | 989 | ||
@@ -1035,7 +1040,8 @@ static void r600_gfx_init(struct drm_device *dev, | |||
1035 | 1040 | ||
1036 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || | 1041 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || |
1037 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || | 1042 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || |
1038 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) | 1043 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || |
1044 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) | ||
1039 | RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); | 1045 | RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); |
1040 | else | 1046 | else |
1041 | RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); | 1047 | RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); |
@@ -1078,6 +1084,7 @@ static void r600_gfx_init(struct drm_device *dev, | |||
1078 | break; | 1084 | break; |
1079 | case CHIP_RV610: | 1085 | case CHIP_RV610: |
1080 | case CHIP_RS780: | 1086 | case CHIP_RS780: |
1087 | case CHIP_RS880: | ||
1081 | case CHIP_RV620: | 1088 | case CHIP_RV620: |
1082 | gs_prim_buffer_depth = 32; | 1089 | gs_prim_buffer_depth = 32; |
1083 | break; | 1090 | break; |
@@ -1123,6 +1130,7 @@ static void r600_gfx_init(struct drm_device *dev, | |||
1123 | switch (dev_priv->flags & RADEON_FAMILY_MASK) { | 1130 | switch (dev_priv->flags & RADEON_FAMILY_MASK) { |
1124 | case CHIP_RV610: | 1131 | case CHIP_RV610: |
1125 | case CHIP_RS780: | 1132 | case CHIP_RS780: |
1133 | case CHIP_RS880: | ||
1126 | case CHIP_RV620: | 1134 | case CHIP_RV620: |
1127 | tc_cntl = R600_TC_L2_SIZE(8); | 1135 | tc_cntl = R600_TC_L2_SIZE(8); |
1128 | break; | 1136 | break; |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b1d945b8ed6c..b519fb2fecbb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -242,6 +242,7 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | |||
242 | uint64_t *gpu_addr); | 242 | uint64_t *gpu_addr); |
243 | void radeon_object_unpin(struct radeon_object *robj); | 243 | void radeon_object_unpin(struct radeon_object *robj); |
244 | int radeon_object_wait(struct radeon_object *robj); | 244 | int radeon_object_wait(struct radeon_object *robj); |
245 | int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement); | ||
245 | int radeon_object_evict_vram(struct radeon_device *rdev); | 246 | int radeon_object_evict_vram(struct radeon_device *rdev); |
246 | int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset); | 247 | int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset); |
247 | void radeon_object_force_delete(struct radeon_device *rdev); | 248 | void radeon_object_force_delete(struct radeon_device *rdev); |
@@ -574,6 +575,7 @@ struct radeon_asic { | |||
574 | void (*ring_start)(struct radeon_device *rdev); | 575 | void (*ring_start)(struct radeon_device *rdev); |
575 | int (*irq_set)(struct radeon_device *rdev); | 576 | int (*irq_set)(struct radeon_device *rdev); |
576 | int (*irq_process)(struct radeon_device *rdev); | 577 | int (*irq_process)(struct radeon_device *rdev); |
578 | u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); | ||
577 | void (*fence_ring_emit)(struct radeon_device *rdev, struct radeon_fence *fence); | 579 | void (*fence_ring_emit)(struct radeon_device *rdev, struct radeon_fence *fence); |
578 | int (*cs_parse)(struct radeon_cs_parser *p); | 580 | int (*cs_parse)(struct radeon_cs_parser *p); |
579 | int (*copy_blit)(struct radeon_device *rdev, | 581 | int (*copy_blit)(struct radeon_device *rdev, |
@@ -653,6 +655,7 @@ struct radeon_device { | |||
653 | int usec_timeout; | 655 | int usec_timeout; |
654 | enum radeon_pll_errata pll_errata; | 656 | enum radeon_pll_errata pll_errata; |
655 | int num_gb_pipes; | 657 | int num_gb_pipes; |
658 | int num_z_pipes; | ||
656 | int disp_priority; | 659 | int disp_priority; |
657 | /* BIOS */ | 660 | /* BIOS */ |
658 | uint8_t *bios; | 661 | uint8_t *bios; |
@@ -666,14 +669,11 @@ struct radeon_device { | |||
666 | resource_size_t rmmio_base; | 669 | resource_size_t rmmio_base; |
667 | resource_size_t rmmio_size; | 670 | resource_size_t rmmio_size; |
668 | void *rmmio; | 671 | void *rmmio; |
669 | radeon_rreg_t mm_rreg; | ||
670 | radeon_wreg_t mm_wreg; | ||
671 | radeon_rreg_t mc_rreg; | 672 | radeon_rreg_t mc_rreg; |
672 | radeon_wreg_t mc_wreg; | 673 | radeon_wreg_t mc_wreg; |
673 | radeon_rreg_t pll_rreg; | 674 | radeon_rreg_t pll_rreg; |
674 | radeon_wreg_t pll_wreg; | 675 | radeon_wreg_t pll_wreg; |
675 | radeon_rreg_t pcie_rreg; | 676 | uint32_t pcie_reg_mask; |
676 | radeon_wreg_t pcie_wreg; | ||
677 | radeon_rreg_t pciep_rreg; | 677 | radeon_rreg_t pciep_rreg; |
678 | radeon_wreg_t pciep_wreg; | 678 | radeon_wreg_t pciep_wreg; |
679 | struct radeon_clock clock; | 679 | struct radeon_clock clock; |
@@ -705,22 +705,42 @@ int radeon_device_init(struct radeon_device *rdev, | |||
705 | void radeon_device_fini(struct radeon_device *rdev); | 705 | void radeon_device_fini(struct radeon_device *rdev); |
706 | int radeon_gpu_wait_for_idle(struct radeon_device *rdev); | 706 | int radeon_gpu_wait_for_idle(struct radeon_device *rdev); |
707 | 707 | ||
708 | static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) | ||
709 | { | ||
710 | if (reg < 0x10000) | ||
711 | return readl(((void __iomem *)rdev->rmmio) + reg); | ||
712 | else { | ||
713 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | ||
714 | return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | ||
715 | } | ||
716 | } | ||
717 | |||
718 | static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
719 | { | ||
720 | if (reg < 0x10000) | ||
721 | writel(v, ((void __iomem *)rdev->rmmio) + reg); | ||
722 | else { | ||
723 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | ||
724 | writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | ||
725 | } | ||
726 | } | ||
727 | |||
708 | 728 | ||
709 | /* | 729 | /* |
710 | * Registers read & write functions. | 730 | * Registers read & write functions. |
711 | */ | 731 | */ |
712 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) | 732 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) |
713 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) | 733 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) |
714 | #define RREG32(reg) rdev->mm_rreg(rdev, (reg)) | 734 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) |
715 | #define WREG32(reg, v) rdev->mm_wreg(rdev, (reg), (v)) | 735 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) |
716 | #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) | 736 | #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) |
717 | #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) | 737 | #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) |
718 | #define RREG32_PLL(reg) rdev->pll_rreg(rdev, (reg)) | 738 | #define RREG32_PLL(reg) rdev->pll_rreg(rdev, (reg)) |
719 | #define WREG32_PLL(reg, v) rdev->pll_wreg(rdev, (reg), (v)) | 739 | #define WREG32_PLL(reg, v) rdev->pll_wreg(rdev, (reg), (v)) |
720 | #define RREG32_MC(reg) rdev->mc_rreg(rdev, (reg)) | 740 | #define RREG32_MC(reg) rdev->mc_rreg(rdev, (reg)) |
721 | #define WREG32_MC(reg, v) rdev->mc_wreg(rdev, (reg), (v)) | 741 | #define WREG32_MC(reg, v) rdev->mc_wreg(rdev, (reg), (v)) |
722 | #define RREG32_PCIE(reg) rdev->pcie_rreg(rdev, (reg)) | 742 | #define RREG32_PCIE(reg) rv370_pcie_rreg(rdev, (reg)) |
723 | #define WREG32_PCIE(reg, v) rdev->pcie_wreg(rdev, (reg), (v)) | 743 | #define WREG32_PCIE(reg, v) rv370_pcie_wreg(rdev, (reg), (v)) |
724 | #define WREG32_P(reg, val, mask) \ | 744 | #define WREG32_P(reg, val, mask) \ |
725 | do { \ | 745 | do { \ |
726 | uint32_t tmp_ = RREG32(reg); \ | 746 | uint32_t tmp_ = RREG32(reg); \ |
@@ -736,6 +756,24 @@ int radeon_gpu_wait_for_idle(struct radeon_device *rdev); | |||
736 | WREG32_PLL(reg, tmp_); \ | 756 | WREG32_PLL(reg, tmp_); \ |
737 | } while (0) | 757 | } while (0) |
738 | 758 | ||
759 | /* | ||
760 | * Indirect registers accessor | ||
761 | */ | ||
762 | static inline uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg) | ||
763 | { | ||
764 | uint32_t r; | ||
765 | |||
766 | WREG32(RADEON_PCIE_INDEX, ((reg) & rdev->pcie_reg_mask)); | ||
767 | r = RREG32(RADEON_PCIE_DATA); | ||
768 | return r; | ||
769 | } | ||
770 | |||
771 | static inline void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
772 | { | ||
773 | WREG32(RADEON_PCIE_INDEX, ((reg) & rdev->pcie_reg_mask)); | ||
774 | WREG32(RADEON_PCIE_DATA, (v)); | ||
775 | } | ||
776 | |||
739 | void r100_pll_errata_after_index(struct radeon_device *rdev); | 777 | void r100_pll_errata_after_index(struct radeon_device *rdev); |
740 | 778 | ||
741 | 779 | ||
@@ -862,6 +900,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
862 | #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) | 900 | #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) |
863 | #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) | 901 | #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) |
864 | #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) | 902 | #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) |
903 | #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) | ||
865 | #define radeon_fence_ring_emit(rdev, fence) (rdev)->asic->fence_ring_emit((rdev), (fence)) | 904 | #define radeon_fence_ring_emit(rdev, fence) (rdev)->asic->fence_ring_emit((rdev), (fence)) |
866 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) | 905 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) |
867 | #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) | 906 | #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 9a75876e0c3b..7ca6c13569b5 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -49,6 +49,7 @@ void r100_vram_info(struct radeon_device *rdev); | |||
49 | int r100_gpu_reset(struct radeon_device *rdev); | 49 | int r100_gpu_reset(struct radeon_device *rdev); |
50 | int r100_mc_init(struct radeon_device *rdev); | 50 | int r100_mc_init(struct radeon_device *rdev); |
51 | void r100_mc_fini(struct radeon_device *rdev); | 51 | void r100_mc_fini(struct radeon_device *rdev); |
52 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); | ||
52 | int r100_wb_init(struct radeon_device *rdev); | 53 | int r100_wb_init(struct radeon_device *rdev); |
53 | void r100_wb_fini(struct radeon_device *rdev); | 54 | void r100_wb_fini(struct radeon_device *rdev); |
54 | int r100_gart_enable(struct radeon_device *rdev); | 55 | int r100_gart_enable(struct radeon_device *rdev); |
@@ -96,6 +97,7 @@ static struct radeon_asic r100_asic = { | |||
96 | .ring_start = &r100_ring_start, | 97 | .ring_start = &r100_ring_start, |
97 | .irq_set = &r100_irq_set, | 98 | .irq_set = &r100_irq_set, |
98 | .irq_process = &r100_irq_process, | 99 | .irq_process = &r100_irq_process, |
100 | .get_vblank_counter = &r100_get_vblank_counter, | ||
99 | .fence_ring_emit = &r100_fence_ring_emit, | 101 | .fence_ring_emit = &r100_fence_ring_emit, |
100 | .cs_parse = &r100_cs_parse, | 102 | .cs_parse = &r100_cs_parse, |
101 | .copy_blit = &r100_copy_blit, | 103 | .copy_blit = &r100_copy_blit, |
@@ -156,6 +158,7 @@ static struct radeon_asic r300_asic = { | |||
156 | .ring_start = &r300_ring_start, | 158 | .ring_start = &r300_ring_start, |
157 | .irq_set = &r100_irq_set, | 159 | .irq_set = &r100_irq_set, |
158 | .irq_process = &r100_irq_process, | 160 | .irq_process = &r100_irq_process, |
161 | .get_vblank_counter = &r100_get_vblank_counter, | ||
159 | .fence_ring_emit = &r300_fence_ring_emit, | 162 | .fence_ring_emit = &r300_fence_ring_emit, |
160 | .cs_parse = &r300_cs_parse, | 163 | .cs_parse = &r300_cs_parse, |
161 | .copy_blit = &r100_copy_blit, | 164 | .copy_blit = &r100_copy_blit, |
@@ -196,6 +199,7 @@ static struct radeon_asic r420_asic = { | |||
196 | .ring_start = &r300_ring_start, | 199 | .ring_start = &r300_ring_start, |
197 | .irq_set = &r100_irq_set, | 200 | .irq_set = &r100_irq_set, |
198 | .irq_process = &r100_irq_process, | 201 | .irq_process = &r100_irq_process, |
202 | .get_vblank_counter = &r100_get_vblank_counter, | ||
199 | .fence_ring_emit = &r300_fence_ring_emit, | 203 | .fence_ring_emit = &r300_fence_ring_emit, |
200 | .cs_parse = &r300_cs_parse, | 204 | .cs_parse = &r300_cs_parse, |
201 | .copy_blit = &r100_copy_blit, | 205 | .copy_blit = &r100_copy_blit, |
@@ -243,6 +247,7 @@ static struct radeon_asic rs400_asic = { | |||
243 | .ring_start = &r300_ring_start, | 247 | .ring_start = &r300_ring_start, |
244 | .irq_set = &r100_irq_set, | 248 | .irq_set = &r100_irq_set, |
245 | .irq_process = &r100_irq_process, | 249 | .irq_process = &r100_irq_process, |
250 | .get_vblank_counter = &r100_get_vblank_counter, | ||
246 | .fence_ring_emit = &r300_fence_ring_emit, | 251 | .fence_ring_emit = &r300_fence_ring_emit, |
247 | .cs_parse = &r300_cs_parse, | 252 | .cs_parse = &r300_cs_parse, |
248 | .copy_blit = &r100_copy_blit, | 253 | .copy_blit = &r100_copy_blit, |
@@ -266,6 +271,8 @@ void rs600_vram_info(struct radeon_device *rdev); | |||
266 | int rs600_mc_init(struct radeon_device *rdev); | 271 | int rs600_mc_init(struct radeon_device *rdev); |
267 | void rs600_mc_fini(struct radeon_device *rdev); | 272 | void rs600_mc_fini(struct radeon_device *rdev); |
268 | int rs600_irq_set(struct radeon_device *rdev); | 273 | int rs600_irq_set(struct radeon_device *rdev); |
274 | int rs600_irq_process(struct radeon_device *rdev); | ||
275 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); | ||
269 | int rs600_gart_enable(struct radeon_device *rdev); | 276 | int rs600_gart_enable(struct radeon_device *rdev); |
270 | void rs600_gart_disable(struct radeon_device *rdev); | 277 | void rs600_gart_disable(struct radeon_device *rdev); |
271 | void rs600_gart_tlb_flush(struct radeon_device *rdev); | 278 | void rs600_gart_tlb_flush(struct radeon_device *rdev); |
@@ -291,7 +298,8 @@ static struct radeon_asic rs600_asic = { | |||
291 | .cp_disable = &r100_cp_disable, | 298 | .cp_disable = &r100_cp_disable, |
292 | .ring_start = &r300_ring_start, | 299 | .ring_start = &r300_ring_start, |
293 | .irq_set = &rs600_irq_set, | 300 | .irq_set = &rs600_irq_set, |
294 | .irq_process = &r100_irq_process, | 301 | .irq_process = &rs600_irq_process, |
302 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
295 | .fence_ring_emit = &r300_fence_ring_emit, | 303 | .fence_ring_emit = &r300_fence_ring_emit, |
296 | .cs_parse = &r300_cs_parse, | 304 | .cs_parse = &r300_cs_parse, |
297 | .copy_blit = &r100_copy_blit, | 305 | .copy_blit = &r100_copy_blit, |
@@ -308,6 +316,7 @@ static struct radeon_asic rs600_asic = { | |||
308 | /* | 316 | /* |
309 | * rs690,rs740 | 317 | * rs690,rs740 |
310 | */ | 318 | */ |
319 | int rs690_init(struct radeon_device *rdev); | ||
311 | void rs690_errata(struct radeon_device *rdev); | 320 | void rs690_errata(struct radeon_device *rdev); |
312 | void rs690_vram_info(struct radeon_device *rdev); | 321 | void rs690_vram_info(struct radeon_device *rdev); |
313 | int rs690_mc_init(struct radeon_device *rdev); | 322 | int rs690_mc_init(struct radeon_device *rdev); |
@@ -316,7 +325,7 @@ uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); | |||
316 | void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 325 | void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
317 | void rs690_bandwidth_update(struct radeon_device *rdev); | 326 | void rs690_bandwidth_update(struct radeon_device *rdev); |
318 | static struct radeon_asic rs690_asic = { | 327 | static struct radeon_asic rs690_asic = { |
319 | .init = &r300_init, | 328 | .init = &rs690_init, |
320 | .errata = &rs690_errata, | 329 | .errata = &rs690_errata, |
321 | .vram_info = &rs690_vram_info, | 330 | .vram_info = &rs690_vram_info, |
322 | .gpu_reset = &r300_gpu_reset, | 331 | .gpu_reset = &r300_gpu_reset, |
@@ -333,7 +342,8 @@ static struct radeon_asic rs690_asic = { | |||
333 | .cp_disable = &r100_cp_disable, | 342 | .cp_disable = &r100_cp_disable, |
334 | .ring_start = &r300_ring_start, | 343 | .ring_start = &r300_ring_start, |
335 | .irq_set = &rs600_irq_set, | 344 | .irq_set = &rs600_irq_set, |
336 | .irq_process = &r100_irq_process, | 345 | .irq_process = &rs600_irq_process, |
346 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
337 | .fence_ring_emit = &r300_fence_ring_emit, | 347 | .fence_ring_emit = &r300_fence_ring_emit, |
338 | .cs_parse = &r300_cs_parse, | 348 | .cs_parse = &r300_cs_parse, |
339 | .copy_blit = &r100_copy_blit, | 349 | .copy_blit = &r100_copy_blit, |
@@ -381,8 +391,9 @@ static struct radeon_asic rv515_asic = { | |||
381 | .cp_fini = &r100_cp_fini, | 391 | .cp_fini = &r100_cp_fini, |
382 | .cp_disable = &r100_cp_disable, | 392 | .cp_disable = &r100_cp_disable, |
383 | .ring_start = &rv515_ring_start, | 393 | .ring_start = &rv515_ring_start, |
384 | .irq_set = &r100_irq_set, | 394 | .irq_set = &rs600_irq_set, |
385 | .irq_process = &r100_irq_process, | 395 | .irq_process = &rs600_irq_process, |
396 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
386 | .fence_ring_emit = &r300_fence_ring_emit, | 397 | .fence_ring_emit = &r300_fence_ring_emit, |
387 | .cs_parse = &r300_cs_parse, | 398 | .cs_parse = &r300_cs_parse, |
388 | .copy_blit = &r100_copy_blit, | 399 | .copy_blit = &r100_copy_blit, |
@@ -423,8 +434,9 @@ static struct radeon_asic r520_asic = { | |||
423 | .cp_fini = &r100_cp_fini, | 434 | .cp_fini = &r100_cp_fini, |
424 | .cp_disable = &r100_cp_disable, | 435 | .cp_disable = &r100_cp_disable, |
425 | .ring_start = &rv515_ring_start, | 436 | .ring_start = &rv515_ring_start, |
426 | .irq_set = &r100_irq_set, | 437 | .irq_set = &rs600_irq_set, |
427 | .irq_process = &r100_irq_process, | 438 | .irq_process = &rs600_irq_process, |
439 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
428 | .fence_ring_emit = &r300_fence_ring_emit, | 440 | .fence_ring_emit = &r300_fence_ring_emit, |
429 | .cs_parse = &r300_cs_parse, | 441 | .cs_parse = &r300_cs_parse, |
430 | .copy_blit = &r100_copy_blit, | 442 | .copy_blit = &r100_copy_blit, |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index afc4db280b94..2a027e00762a 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -685,23 +685,15 @@ static const uint32_t default_tvdac_adj[CHIP_LAST] = { | |||
685 | 0x00780000, /* rs480 */ | 685 | 0x00780000, /* rs480 */ |
686 | }; | 686 | }; |
687 | 687 | ||
688 | static struct radeon_encoder_tv_dac | 688 | static void radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev, |
689 | *radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev) | 689 | struct radeon_encoder_tv_dac *tv_dac) |
690 | { | 690 | { |
691 | struct radeon_encoder_tv_dac *tv_dac = NULL; | ||
692 | |||
693 | tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); | ||
694 | |||
695 | if (!tv_dac) | ||
696 | return NULL; | ||
697 | |||
698 | tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family]; | 691 | tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family]; |
699 | if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250)) | 692 | if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250)) |
700 | tv_dac->ps2_tvdac_adj = 0x00880000; | 693 | tv_dac->ps2_tvdac_adj = 0x00880000; |
701 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; | 694 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; |
702 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; | 695 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; |
703 | 696 | return; | |
704 | return tv_dac; | ||
705 | } | 697 | } |
706 | 698 | ||
707 | struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | 699 | struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct |
@@ -713,19 +705,18 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
713 | uint16_t dac_info; | 705 | uint16_t dac_info; |
714 | uint8_t rev, bg, dac; | 706 | uint8_t rev, bg, dac; |
715 | struct radeon_encoder_tv_dac *tv_dac = NULL; | 707 | struct radeon_encoder_tv_dac *tv_dac = NULL; |
708 | int found = 0; | ||
709 | |||
710 | tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); | ||
711 | if (!tv_dac) | ||
712 | return NULL; | ||
716 | 713 | ||
717 | if (rdev->bios == NULL) | 714 | if (rdev->bios == NULL) |
718 | return radeon_legacy_get_tv_dac_info_from_table(rdev); | 715 | goto out; |
719 | 716 | ||
720 | /* first check TV table */ | 717 | /* first check TV table */ |
721 | dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); | 718 | dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); |
722 | if (dac_info) { | 719 | if (dac_info) { |
723 | tv_dac = | ||
724 | kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); | ||
725 | |||
726 | if (!tv_dac) | ||
727 | return NULL; | ||
728 | |||
729 | rev = RBIOS8(dac_info + 0x3); | 720 | rev = RBIOS8(dac_info + 0x3); |
730 | if (rev > 4) { | 721 | if (rev > 4) { |
731 | bg = RBIOS8(dac_info + 0xc) & 0xf; | 722 | bg = RBIOS8(dac_info + 0xc) & 0xf; |
@@ -739,6 +730,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
739 | bg = RBIOS8(dac_info + 0x10) & 0xf; | 730 | bg = RBIOS8(dac_info + 0x10) & 0xf; |
740 | dac = RBIOS8(dac_info + 0x11) & 0xf; | 731 | dac = RBIOS8(dac_info + 0x11) & 0xf; |
741 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 732 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
733 | found = 1; | ||
742 | } else if (rev > 1) { | 734 | } else if (rev > 1) { |
743 | bg = RBIOS8(dac_info + 0xc) & 0xf; | 735 | bg = RBIOS8(dac_info + 0xc) & 0xf; |
744 | dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; | 736 | dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; |
@@ -751,22 +743,15 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
751 | bg = RBIOS8(dac_info + 0xe) & 0xf; | 743 | bg = RBIOS8(dac_info + 0xe) & 0xf; |
752 | dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf; | 744 | dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf; |
753 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 745 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
746 | found = 1; | ||
754 | } | 747 | } |
755 | |||
756 | tv_dac->tv_std = radeon_combios_get_tv_info(encoder); | 748 | tv_dac->tv_std = radeon_combios_get_tv_info(encoder); |
757 | 749 | } | |
758 | } else { | 750 | if (!found) { |
759 | /* then check CRT table */ | 751 | /* then check CRT table */ |
760 | dac_info = | 752 | dac_info = |
761 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); | 753 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
762 | if (dac_info) { | 754 | if (dac_info) { |
763 | tv_dac = | ||
764 | kzalloc(sizeof(struct radeon_encoder_tv_dac), | ||
765 | GFP_KERNEL); | ||
766 | |||
767 | if (!tv_dac) | ||
768 | return NULL; | ||
769 | |||
770 | rev = RBIOS8(dac_info) & 0x3; | 755 | rev = RBIOS8(dac_info) & 0x3; |
771 | if (rev < 2) { | 756 | if (rev < 2) { |
772 | bg = RBIOS8(dac_info + 0x3) & 0xf; | 757 | bg = RBIOS8(dac_info + 0x3) & 0xf; |
@@ -775,6 +760,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
775 | (bg << 16) | (dac << 20); | 760 | (bg << 16) | (dac << 20); |
776 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; | 761 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; |
777 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; | 762 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; |
763 | found = 1; | ||
778 | } else { | 764 | } else { |
779 | bg = RBIOS8(dac_info + 0x4) & 0xf; | 765 | bg = RBIOS8(dac_info + 0x4) & 0xf; |
780 | dac = RBIOS8(dac_info + 0x5) & 0xf; | 766 | dac = RBIOS8(dac_info + 0x5) & 0xf; |
@@ -782,13 +768,17 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
782 | (bg << 16) | (dac << 20); | 768 | (bg << 16) | (dac << 20); |
783 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; | 769 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; |
784 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; | 770 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; |
771 | found = 1; | ||
785 | } | 772 | } |
786 | } else { | 773 | } else { |
787 | DRM_INFO("No TV DAC info found in BIOS\n"); | 774 | DRM_INFO("No TV DAC info found in BIOS\n"); |
788 | return radeon_legacy_get_tv_dac_info_from_table(rdev); | ||
789 | } | 775 | } |
790 | } | 776 | } |
791 | 777 | ||
778 | out: | ||
779 | if (!found) /* fallback to defaults */ | ||
780 | radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac); | ||
781 | |||
792 | return tv_dac; | 782 | return tv_dac; |
793 | } | 783 | } |
794 | 784 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index d8356827ef17..7a52c461145c 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -406,6 +406,15 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) | |||
406 | { | 406 | { |
407 | uint32_t gb_tile_config, gb_pipe_sel = 0; | 407 | uint32_t gb_tile_config, gb_pipe_sel = 0; |
408 | 408 | ||
409 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { | ||
410 | uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2); | ||
411 | if ((z_pipe_sel & 3) == 3) | ||
412 | dev_priv->num_z_pipes = 2; | ||
413 | else | ||
414 | dev_priv->num_z_pipes = 1; | ||
415 | } else | ||
416 | dev_priv->num_z_pipes = 1; | ||
417 | |||
409 | /* RS4xx/RS6xx/R4xx/R5xx */ | 418 | /* RS4xx/RS6xx/R4xx/R5xx */ |
410 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { | 419 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { |
411 | gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); | 420 | gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index a162ade74b7f..7693f7c67bd3 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -152,7 +152,9 @@ int radeon_mc_setup(struct radeon_device *rdev) | |||
152 | } | 152 | } |
153 | } else { | 153 | } else { |
154 | rdev->mc.vram_location = 0; | 154 | rdev->mc.vram_location = 0; |
155 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | 155 | tmp = rdev->mc.mc_vram_size; |
156 | tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1); | ||
157 | rdev->mc.gtt_location = tmp; | ||
156 | } | 158 | } |
157 | DRM_INFO("radeon: VRAM %uM\n", rdev->mc.real_vram_size >> 20); | 159 | DRM_INFO("radeon: VRAM %uM\n", rdev->mc.real_vram_size >> 20); |
158 | DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n", | 160 | DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n", |
@@ -223,25 +225,18 @@ void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
223 | 225 | ||
224 | void radeon_register_accessor_init(struct radeon_device *rdev) | 226 | void radeon_register_accessor_init(struct radeon_device *rdev) |
225 | { | 227 | { |
226 | rdev->mm_rreg = &r100_mm_rreg; | ||
227 | rdev->mm_wreg = &r100_mm_wreg; | ||
228 | rdev->mc_rreg = &radeon_invalid_rreg; | 228 | rdev->mc_rreg = &radeon_invalid_rreg; |
229 | rdev->mc_wreg = &radeon_invalid_wreg; | 229 | rdev->mc_wreg = &radeon_invalid_wreg; |
230 | rdev->pll_rreg = &radeon_invalid_rreg; | 230 | rdev->pll_rreg = &radeon_invalid_rreg; |
231 | rdev->pll_wreg = &radeon_invalid_wreg; | 231 | rdev->pll_wreg = &radeon_invalid_wreg; |
232 | rdev->pcie_rreg = &radeon_invalid_rreg; | ||
233 | rdev->pcie_wreg = &radeon_invalid_wreg; | ||
234 | rdev->pciep_rreg = &radeon_invalid_rreg; | 232 | rdev->pciep_rreg = &radeon_invalid_rreg; |
235 | rdev->pciep_wreg = &radeon_invalid_wreg; | 233 | rdev->pciep_wreg = &radeon_invalid_wreg; |
236 | 234 | ||
237 | /* Don't change order as we are overridding accessor. */ | 235 | /* Don't change order as we are overridding accessor. */ |
238 | if (rdev->family < CHIP_RV515) { | 236 | if (rdev->family < CHIP_RV515) { |
239 | rdev->pcie_rreg = &rv370_pcie_rreg; | 237 | rdev->pcie_reg_mask = 0xff; |
240 | rdev->pcie_wreg = &rv370_pcie_wreg; | 238 | } else { |
241 | } | 239 | rdev->pcie_reg_mask = 0x7ff; |
242 | if (rdev->family >= CHIP_RV515) { | ||
243 | rdev->pcie_rreg = &rv515_pcie_rreg; | ||
244 | rdev->pcie_wreg = &rv515_pcie_wreg; | ||
245 | } | 240 | } |
246 | /* FIXME: not sure here */ | 241 | /* FIXME: not sure here */ |
247 | if (rdev->family <= CHIP_R580) { | 242 | if (rdev->family <= CHIP_R580) { |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 3cfcee17dc56..0bd5879a4957 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -318,6 +318,14 @@ static int __init radeon_init(void) | |||
318 | driver = &driver_old; | 318 | driver = &driver_old; |
319 | driver->num_ioctls = radeon_max_ioctl; | 319 | driver->num_ioctls = radeon_max_ioctl; |
320 | #if defined(CONFIG_DRM_RADEON_KMS) | 320 | #if defined(CONFIG_DRM_RADEON_KMS) |
321 | #ifdef CONFIG_VGA_CONSOLE | ||
322 | if (vgacon_text_force() && radeon_modeset == -1) { | ||
323 | DRM_INFO("VGACON disable radeon kernel modesetting.\n"); | ||
324 | driver = &driver_old; | ||
325 | driver->driver_features &= ~DRIVER_MODESET; | ||
326 | radeon_modeset = 0; | ||
327 | } | ||
328 | #endif | ||
321 | /* if enabled by default */ | 329 | /* if enabled by default */ |
322 | if (radeon_modeset == -1) { | 330 | if (radeon_modeset == -1) { |
323 | DRM_INFO("radeon default to kernel modesetting.\n"); | 331 | DRM_INFO("radeon default to kernel modesetting.\n"); |
@@ -329,17 +337,8 @@ static int __init radeon_init(void) | |||
329 | driver->driver_features |= DRIVER_MODESET; | 337 | driver->driver_features |= DRIVER_MODESET; |
330 | driver->num_ioctls = radeon_max_kms_ioctl; | 338 | driver->num_ioctls = radeon_max_kms_ioctl; |
331 | } | 339 | } |
332 | |||
333 | /* if the vga console setting is enabled still | 340 | /* if the vga console setting is enabled still |
334 | * let modprobe override it */ | 341 | * let modprobe override it */ |
335 | #ifdef CONFIG_VGA_CONSOLE | ||
336 | if (vgacon_text_force() && radeon_modeset == -1) { | ||
337 | DRM_INFO("VGACON disable radeon kernel modesetting.\n"); | ||
338 | driver = &driver_old; | ||
339 | driver->driver_features &= ~DRIVER_MODESET; | ||
340 | radeon_modeset = 0; | ||
341 | } | ||
342 | #endif | ||
343 | #endif | 342 | #endif |
344 | return drm_init(driver); | 343 | return drm_init(driver); |
345 | } | 344 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 127d0456f628..6fa32dac4e97 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -100,9 +100,10 @@ | |||
100 | * 1.28- Add support for VBL on CRTC2 | 100 | * 1.28- Add support for VBL on CRTC2 |
101 | * 1.29- R500 3D cmd buffer support | 101 | * 1.29- R500 3D cmd buffer support |
102 | * 1.30- Add support for occlusion queries | 102 | * 1.30- Add support for occlusion queries |
103 | * 1.31- Add support for num Z pipes from GET_PARAM | ||
103 | */ | 104 | */ |
104 | #define DRIVER_MAJOR 1 | 105 | #define DRIVER_MAJOR 1 |
105 | #define DRIVER_MINOR 30 | 106 | #define DRIVER_MINOR 31 |
106 | #define DRIVER_PATCHLEVEL 0 | 107 | #define DRIVER_PATCHLEVEL 0 |
107 | 108 | ||
108 | /* | 109 | /* |
@@ -143,6 +144,7 @@ enum radeon_family { | |||
143 | CHIP_RV635, | 144 | CHIP_RV635, |
144 | CHIP_RV670, | 145 | CHIP_RV670, |
145 | CHIP_RS780, | 146 | CHIP_RS780, |
147 | CHIP_RS880, | ||
146 | CHIP_RV770, | 148 | CHIP_RV770, |
147 | CHIP_RV730, | 149 | CHIP_RV730, |
148 | CHIP_RV710, | 150 | CHIP_RV710, |
@@ -328,6 +330,7 @@ typedef struct drm_radeon_private { | |||
328 | resource_size_t fb_aper_offset; | 330 | resource_size_t fb_aper_offset; |
329 | 331 | ||
330 | int num_gb_pipes; | 332 | int num_gb_pipes; |
333 | int num_z_pipes; | ||
331 | int track_flush; | 334 | int track_flush; |
332 | drm_local_map_t *mmio; | 335 | drm_local_map_t *mmio; |
333 | 336 | ||
@@ -688,6 +691,7 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga | |||
688 | 691 | ||
689 | /* pipe config regs */ | 692 | /* pipe config regs */ |
690 | #define R400_GB_PIPE_SELECT 0x402c | 693 | #define R400_GB_PIPE_SELECT 0x402c |
694 | #define RV530_GB_PIPE_SELECT2 0x4124 | ||
691 | #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ | 695 | #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ |
692 | #define R300_GB_TILE_CONFIG 0x4018 | 696 | #define R300_GB_TILE_CONFIG 0x4018 |
693 | # define R300_ENABLE_TILING (1 << 0) | 697 | # define R300_ENABLE_TILING (1 << 0) |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 3206c0ad7b6c..ec383edf5f38 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -574,6 +574,8 @@ int radeonfb_create(struct radeon_device *rdev, | |||
574 | goto out_unref; | 574 | goto out_unref; |
575 | } | 575 | } |
576 | 576 | ||
577 | memset_io(fbptr, 0, aligned_size); | ||
578 | |||
577 | strcpy(info->fix.id, "radeondrmfb"); | 579 | strcpy(info->fix.id, "radeondrmfb"); |
578 | info->fix.type = FB_TYPE_PACKED_PIXELS; | 580 | info->fix.type = FB_TYPE_PACKED_PIXELS; |
579 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 581 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index cded5180c752..d880edf254db 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -262,8 +262,34 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
262 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | 262 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, |
263 | struct drm_file *filp) | 263 | struct drm_file *filp) |
264 | { | 264 | { |
265 | /* FIXME: implement */ | 265 | struct drm_radeon_gem_busy *args = data; |
266 | return 0; | 266 | struct drm_gem_object *gobj; |
267 | struct radeon_object *robj; | ||
268 | int r; | ||
269 | uint32_t cur_placement; | ||
270 | |||
271 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | ||
272 | if (gobj == NULL) { | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | robj = gobj->driver_private; | ||
276 | r = radeon_object_busy_domain(robj, &cur_placement); | ||
277 | switch (cur_placement) { | ||
278 | case TTM_PL_VRAM: | ||
279 | args->domain = RADEON_GEM_DOMAIN_VRAM; | ||
280 | break; | ||
281 | case TTM_PL_TT: | ||
282 | args->domain = RADEON_GEM_DOMAIN_GTT; | ||
283 | break; | ||
284 | case TTM_PL_SYSTEM: | ||
285 | args->domain = RADEON_GEM_DOMAIN_CPU; | ||
286 | default: | ||
287 | break; | ||
288 | } | ||
289 | mutex_lock(&dev->struct_mutex); | ||
290 | drm_gem_object_unreference(gobj); | ||
291 | mutex_unlock(&dev->struct_mutex); | ||
292 | return r; | ||
267 | } | 293 | } |
268 | 294 | ||
269 | int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | 295 | int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 491d569deb0e..9805e4b6ca1b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -32,60 +32,6 @@ | |||
32 | #include "radeon.h" | 32 | #include "radeon.h" |
33 | #include "atom.h" | 33 | #include "atom.h" |
34 | 34 | ||
35 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | ||
36 | { | ||
37 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | ||
38 | uint32_t irq_mask = RADEON_SW_INT_TEST; | ||
39 | |||
40 | if (irqs) { | ||
41 | WREG32(RADEON_GEN_INT_STATUS, irqs); | ||
42 | } | ||
43 | return irqs & irq_mask; | ||
44 | } | ||
45 | |||
46 | int r100_irq_set(struct radeon_device *rdev) | ||
47 | { | ||
48 | uint32_t tmp = 0; | ||
49 | |||
50 | if (rdev->irq.sw_int) { | ||
51 | tmp |= RADEON_SW_INT_ENABLE; | ||
52 | } | ||
53 | /* Todo go through CRTC and enable vblank int or not */ | ||
54 | WREG32(RADEON_GEN_INT_CNTL, tmp); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | int r100_irq_process(struct radeon_device *rdev) | ||
59 | { | ||
60 | uint32_t status; | ||
61 | |||
62 | status = r100_irq_ack(rdev); | ||
63 | if (!status) { | ||
64 | return IRQ_NONE; | ||
65 | } | ||
66 | while (status) { | ||
67 | /* SW interrupt */ | ||
68 | if (status & RADEON_SW_INT_TEST) { | ||
69 | radeon_fence_process(rdev); | ||
70 | } | ||
71 | status = r100_irq_ack(rdev); | ||
72 | } | ||
73 | return IRQ_HANDLED; | ||
74 | } | ||
75 | |||
76 | int rs600_irq_set(struct radeon_device *rdev) | ||
77 | { | ||
78 | uint32_t tmp = 0; | ||
79 | |||
80 | if (rdev->irq.sw_int) { | ||
81 | tmp |= RADEON_SW_INT_ENABLE; | ||
82 | } | ||
83 | WREG32(RADEON_GEN_INT_CNTL, tmp); | ||
84 | /* Todo go through CRTC and enable vblank int or not */ | ||
85 | WREG32(R500_DxMODE_INT_MASK, 0); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | 35 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) |
90 | { | 36 | { |
91 | struct drm_device *dev = (struct drm_device *) arg; | 37 | struct drm_device *dev = (struct drm_device *) arg; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 937a2f1cdb46..dce09ada32bc 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -58,6 +58,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
58 | if (r) { | 58 | if (r) { |
59 | DRM_ERROR("Failed to initialize radeon, disabling IOCTL\n"); | 59 | DRM_ERROR("Failed to initialize radeon, disabling IOCTL\n"); |
60 | radeon_device_fini(rdev); | 60 | radeon_device_fini(rdev); |
61 | kfree(rdev); | ||
62 | dev->dev_private = NULL; | ||
61 | return r; | 63 | return r; |
62 | } | 64 | } |
63 | return 0; | 65 | return 0; |
@@ -93,6 +95,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
93 | case RADEON_INFO_NUM_GB_PIPES: | 95 | case RADEON_INFO_NUM_GB_PIPES: |
94 | value = rdev->num_gb_pipes; | 96 | value = rdev->num_gb_pipes; |
95 | break; | 97 | break; |
98 | case RADEON_INFO_NUM_Z_PIPES: | ||
99 | value = rdev->num_z_pipes; | ||
100 | break; | ||
96 | default: | 101 | default: |
97 | DRM_DEBUG("Invalid request %d\n", info->request); | 102 | DRM_DEBUG("Invalid request %d\n", info->request); |
98 | return -EINVAL; | 103 | return -EINVAL; |
@@ -139,19 +144,42 @@ void radeon_driver_preclose_kms(struct drm_device *dev, | |||
139 | */ | 144 | */ |
140 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) | 145 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) |
141 | { | 146 | { |
142 | /* FIXME: implement */ | 147 | struct radeon_device *rdev = dev->dev_private; |
143 | return 0; | 148 | |
149 | if (crtc < 0 || crtc > 1) { | ||
150 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | |||
154 | return radeon_get_vblank_counter(rdev, crtc); | ||
144 | } | 155 | } |
145 | 156 | ||
146 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) | 157 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) |
147 | { | 158 | { |
148 | /* FIXME: implement */ | 159 | struct radeon_device *rdev = dev->dev_private; |
149 | return 0; | 160 | |
161 | if (crtc < 0 || crtc > 1) { | ||
162 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
163 | return -EINVAL; | ||
164 | } | ||
165 | |||
166 | rdev->irq.crtc_vblank_int[crtc] = true; | ||
167 | |||
168 | return radeon_irq_set(rdev); | ||
150 | } | 169 | } |
151 | 170 | ||
152 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) | 171 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) |
153 | { | 172 | { |
154 | /* FIXME: implement */ | 173 | struct radeon_device *rdev = dev->dev_private; |
174 | |||
175 | if (crtc < 0 || crtc > 1) { | ||
176 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | rdev->irq.crtc_vblank_int[crtc] = false; | ||
181 | |||
182 | radeon_irq_set(rdev); | ||
155 | } | 183 | } |
156 | 184 | ||
157 | 185 | ||
@@ -293,5 +321,6 @@ struct drm_ioctl_desc radeon_ioctls_kms[] = { | |||
293 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH), | 321 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH), |
294 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH), | 322 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH), |
295 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH), | 323 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH), |
324 | DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH), | ||
296 | }; | 325 | }; |
297 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); | 326 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 7d06dc98a42a..0da72f18fd3a 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -310,10 +310,13 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
310 | RADEON_CRTC_DISP_REQ_EN_B)); | 310 | RADEON_CRTC_DISP_REQ_EN_B)); |
311 | WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); | 311 | WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); |
312 | } | 312 | } |
313 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); | ||
314 | radeon_crtc_load_lut(crtc); | ||
313 | break; | 315 | break; |
314 | case DRM_MODE_DPMS_STANDBY: | 316 | case DRM_MODE_DPMS_STANDBY: |
315 | case DRM_MODE_DPMS_SUSPEND: | 317 | case DRM_MODE_DPMS_SUSPEND: |
316 | case DRM_MODE_DPMS_OFF: | 318 | case DRM_MODE_DPMS_OFF: |
319 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); | ||
317 | if (radeon_crtc->crtc_id) | 320 | if (radeon_crtc->crtc_id) |
318 | WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); | 321 | WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); |
319 | else { | 322 | else { |
@@ -323,10 +326,6 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
323 | } | 326 | } |
324 | break; | 327 | break; |
325 | } | 328 | } |
326 | |||
327 | if (mode != DRM_MODE_DPMS_OFF) { | ||
328 | radeon_crtc_load_lut(crtc); | ||
329 | } | ||
330 | } | 329 | } |
331 | 330 | ||
332 | /* properly set crtc bpp when using atombios */ | 331 | /* properly set crtc bpp when using atombios */ |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 34d0f58eb944..9322675ef6d0 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -1066,6 +1066,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1066 | 1066 | ||
1067 | switch (radeon_encoder->encoder_id) { | 1067 | switch (radeon_encoder->encoder_id) { |
1068 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | 1068 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: |
1069 | encoder->possible_crtcs = 0x1; | ||
1069 | drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); | 1070 | drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); |
1070 | drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); | 1071 | drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); |
1071 | if (rdev->is_atom_bios) | 1072 | if (rdev->is_atom_bios) |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index dd9ac2fed6d6..b85fb83d7ae8 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -106,7 +106,7 @@ static inline uint32_t radeon_object_flags_from_domain(uint32_t domain) | |||
106 | flags |= TTM_PL_FLAG_VRAM | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; | 106 | flags |= TTM_PL_FLAG_VRAM | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; |
107 | } | 107 | } |
108 | if (domain & RADEON_GEM_DOMAIN_GTT) { | 108 | if (domain & RADEON_GEM_DOMAIN_GTT) { |
109 | flags |= TTM_PL_FLAG_TT | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; | 109 | flags |= TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; |
110 | } | 110 | } |
111 | if (domain & RADEON_GEM_DOMAIN_CPU) { | 111 | if (domain & RADEON_GEM_DOMAIN_CPU) { |
112 | flags |= TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING; | 112 | flags |= TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING; |
@@ -316,6 +316,25 @@ int radeon_object_wait(struct radeon_object *robj) | |||
316 | return r; | 316 | return r; |
317 | } | 317 | } |
318 | 318 | ||
319 | int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement) | ||
320 | { | ||
321 | int r = 0; | ||
322 | |||
323 | r = radeon_object_reserve(robj, true); | ||
324 | if (unlikely(r != 0)) { | ||
325 | DRM_ERROR("radeon: failed to reserve object for waiting.\n"); | ||
326 | return r; | ||
327 | } | ||
328 | spin_lock(&robj->tobj.lock); | ||
329 | *cur_placement = robj->tobj.mem.mem_type; | ||
330 | if (robj->tobj.sync_obj) { | ||
331 | r = ttm_bo_wait(&robj->tobj, true, true, true); | ||
332 | } | ||
333 | spin_unlock(&robj->tobj.lock); | ||
334 | radeon_object_unreserve(robj); | ||
335 | return r; | ||
336 | } | ||
337 | |||
319 | int radeon_object_evict_vram(struct radeon_device *rdev) | 338 | int radeon_object_evict_vram(struct radeon_device *rdev) |
320 | { | 339 | { |
321 | if (rdev->flags & RADEON_IS_IGP) { | 340 | if (rdev->flags & RADEON_IS_IGP) { |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index e1b618574461..4df43f62c678 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -982,12 +982,15 @@ | |||
982 | # define RS400_TMDS2_PLLRST (1 << 1) | 982 | # define RS400_TMDS2_PLLRST (1 << 1) |
983 | 983 | ||
984 | #define RADEON_GEN_INT_CNTL 0x0040 | 984 | #define RADEON_GEN_INT_CNTL 0x0040 |
985 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | ||
986 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | ||
985 | # define RADEON_SW_INT_ENABLE (1 << 25) | 987 | # define RADEON_SW_INT_ENABLE (1 << 25) |
986 | #define RADEON_GEN_INT_STATUS 0x0044 | 988 | #define RADEON_GEN_INT_STATUS 0x0044 |
987 | # define RADEON_VSYNC_INT_AK (1 << 2) | 989 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) |
988 | # define RADEON_VSYNC_INT (1 << 2) | 990 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) |
989 | # define RADEON_VSYNC2_INT_AK (1 << 6) | 991 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) |
990 | # define RADEON_VSYNC2_INT (1 << 6) | 992 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) |
993 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) | ||
991 | # define RADEON_SW_INT_FIRE (1 << 26) | 994 | # define RADEON_SW_INT_FIRE (1 << 26) |
992 | # define RADEON_SW_INT_TEST (1 << 25) | 995 | # define RADEON_SW_INT_TEST (1 << 25) |
993 | # define RADEON_SW_INT_TEST_ACK (1 << 25) | 996 | # define RADEON_SW_INT_TEST_ACK (1 << 25) |
@@ -2334,6 +2337,9 @@ | |||
2334 | # define RADEON_RE_WIDTH_SHIFT 0 | 2337 | # define RADEON_RE_WIDTH_SHIFT 0 |
2335 | # define RADEON_RE_HEIGHT_SHIFT 16 | 2338 | # define RADEON_RE_HEIGHT_SHIFT 16 |
2336 | 2339 | ||
2340 | #define RADEON_RB3D_ZPASS_DATA 0x3290 | ||
2341 | #define RADEON_RB3D_ZPASS_ADDR 0x3294 | ||
2342 | |||
2337 | #define RADEON_SE_CNTL 0x1c4c | 2343 | #define RADEON_SE_CNTL 0x1c4c |
2338 | # define RADEON_FFACE_CULL_CW (0 << 0) | 2344 | # define RADEON_FFACE_CULL_CW (0 << 0) |
2339 | # define RADEON_FFACE_CULL_CCW (1 << 0) | 2345 | # define RADEON_FFACE_CULL_CCW (1 << 0) |
@@ -3568,4 +3574,6 @@ | |||
3568 | #define RADEON_SCRATCH_REG4 0x15f0 | 3574 | #define RADEON_SCRATCH_REG4 0x15f0 |
3569 | #define RADEON_SCRATCH_REG5 0x15f4 | 3575 | #define RADEON_SCRATCH_REG5 0x15f4 |
3570 | 3576 | ||
3577 | #define RV530_GB_PIPE_SELECT2 0x4124 | ||
3578 | |||
3571 | #endif | 3579 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 46645f3e0328..2882f40d5ec5 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -3081,6 +3081,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil | |||
3081 | case RADEON_PARAM_NUM_GB_PIPES: | 3081 | case RADEON_PARAM_NUM_GB_PIPES: |
3082 | value = dev_priv->num_gb_pipes; | 3082 | value = dev_priv->num_gb_pipes; |
3083 | break; | 3083 | break; |
3084 | case RADEON_PARAM_NUM_Z_PIPES: | ||
3085 | value = dev_priv->num_z_pipes; | ||
3086 | break; | ||
3084 | default: | 3087 | default: |
3085 | DRM_DEBUG("Invalid parameter %d\n", param->param); | 3088 | DRM_DEBUG("Invalid parameter %d\n", param->param); |
3086 | return -EINVAL; | 3089 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index bbea6dee4a94..7e8ce983a908 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -240,6 +240,88 @@ void rs600_mc_fini(struct radeon_device *rdev) | |||
240 | 240 | ||
241 | 241 | ||
242 | /* | 242 | /* |
243 | * Interrupts | ||
244 | */ | ||
245 | int rs600_irq_set(struct radeon_device *rdev) | ||
246 | { | ||
247 | uint32_t tmp = 0; | ||
248 | uint32_t mode_int = 0; | ||
249 | |||
250 | if (rdev->irq.sw_int) { | ||
251 | tmp |= RADEON_SW_INT_ENABLE; | ||
252 | } | ||
253 | if (rdev->irq.crtc_vblank_int[0]) { | ||
254 | tmp |= AVIVO_DISPLAY_INT_STATUS; | ||
255 | mode_int |= AVIVO_D1MODE_INT_MASK; | ||
256 | } | ||
257 | if (rdev->irq.crtc_vblank_int[1]) { | ||
258 | tmp |= AVIVO_DISPLAY_INT_STATUS; | ||
259 | mode_int |= AVIVO_D2MODE_INT_MASK; | ||
260 | } | ||
261 | WREG32(RADEON_GEN_INT_CNTL, tmp); | ||
262 | WREG32(AVIVO_DxMODE_INT_MASK, mode_int); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) | ||
267 | { | ||
268 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | ||
269 | uint32_t irq_mask = RADEON_SW_INT_TEST; | ||
270 | |||
271 | if (irqs & AVIVO_DISPLAY_INT_STATUS) { | ||
272 | *r500_disp_int = RREG32(AVIVO_DISP_INTERRUPT_STATUS); | ||
273 | if (*r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) { | ||
274 | WREG32(AVIVO_D1MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK); | ||
275 | } | ||
276 | if (*r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) { | ||
277 | WREG32(AVIVO_D2MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK); | ||
278 | } | ||
279 | } else { | ||
280 | *r500_disp_int = 0; | ||
281 | } | ||
282 | |||
283 | if (irqs) { | ||
284 | WREG32(RADEON_GEN_INT_STATUS, irqs); | ||
285 | } | ||
286 | return irqs & irq_mask; | ||
287 | } | ||
288 | |||
289 | int rs600_irq_process(struct radeon_device *rdev) | ||
290 | { | ||
291 | uint32_t status; | ||
292 | uint32_t r500_disp_int; | ||
293 | |||
294 | status = rs600_irq_ack(rdev, &r500_disp_int); | ||
295 | if (!status && !r500_disp_int) { | ||
296 | return IRQ_NONE; | ||
297 | } | ||
298 | while (status || r500_disp_int) { | ||
299 | /* SW interrupt */ | ||
300 | if (status & RADEON_SW_INT_TEST) { | ||
301 | radeon_fence_process(rdev); | ||
302 | } | ||
303 | /* Vertical blank interrupts */ | ||
304 | if (r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) { | ||
305 | drm_handle_vblank(rdev->ddev, 0); | ||
306 | } | ||
307 | if (r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) { | ||
308 | drm_handle_vblank(rdev->ddev, 1); | ||
309 | } | ||
310 | status = rs600_irq_ack(rdev, &r500_disp_int); | ||
311 | } | ||
312 | return IRQ_HANDLED; | ||
313 | } | ||
314 | |||
315 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc) | ||
316 | { | ||
317 | if (crtc == 0) | ||
318 | return RREG32(AVIVO_D1CRTC_FRAME_COUNT); | ||
319 | else | ||
320 | return RREG32(AVIVO_D2CRTC_FRAME_COUNT); | ||
321 | } | ||
322 | |||
323 | |||
324 | /* | ||
243 | * Global GPU functions | 325 | * Global GPU functions |
244 | */ | 326 | */ |
245 | void rs600_disable_vga(struct radeon_device *rdev) | 327 | void rs600_disable_vga(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 839595b00728..bc6b7c5339bc 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -652,3 +652,68 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
652 | WREG32(RS690_MC_DATA, v); | 652 | WREG32(RS690_MC_DATA, v); |
653 | WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); | 653 | WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); |
654 | } | 654 | } |
655 | |||
656 | static const unsigned rs690_reg_safe_bm[219] = { | ||
657 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
658 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
659 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
660 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
661 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
662 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
663 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
664 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
665 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
666 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
667 | 0x17FF1FFF,0xFFFFFFFC,0xFFFFFFFF,0xFF30FFBF, | ||
668 | 0xFFFFFFF8,0xC3E6FFFF,0xFFFFF6DF,0xFFFFFFFF, | ||
669 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
670 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
671 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFF03F, | ||
672 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
673 | 0xFFFFFFFF,0xFFFFEFCE,0xF00EBFFF,0x007C0000, | ||
674 | 0xF0000078,0xFF000009,0xFFFFFFFF,0xFFFFFFFF, | ||
675 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
676 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
677 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
678 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
679 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
680 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
681 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
682 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
683 | 0xFFFFF7FF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
684 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
685 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
686 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
687 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
688 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
689 | 0xFFFFFC78,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF, | ||
690 | 0x38FF8F50,0xFFF88082,0xF000000C,0xFAE009FF, | ||
691 | 0x0000FFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000, | ||
692 | 0x00000000,0x0000C100,0x00000000,0x00000000, | ||
693 | 0x00000000,0x00000000,0x00000000,0x00000000, | ||
694 | 0x00000000,0xFFFF0000,0xFFFFFFFF,0xFF80FFFF, | ||
695 | 0x00000000,0x00000000,0x00000000,0x00000000, | ||
696 | 0x0003FC01,0xFFFFFFF8,0xFE800B19,0xFFFFFFFF, | ||
697 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
698 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
699 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
700 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
701 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
702 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
703 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
704 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
705 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
706 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
707 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
708 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
709 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
710 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
711 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
712 | }; | ||
713 | |||
714 | int rs690_init(struct radeon_device *rdev) | ||
715 | { | ||
716 | rdev->config.r300.reg_safe_bm = rs690_reg_safe_bm; | ||
717 | rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs690_reg_safe_bm); | ||
718 | return 0; | ||
719 | } | ||
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 551e608702e4..31a7f668ae5a 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -370,6 +370,7 @@ void rv515_vram_info(struct radeon_device *rdev) | |||
370 | 370 | ||
371 | rv515_vram_get_type(rdev); | 371 | rv515_vram_get_type(rdev); |
372 | 372 | ||
373 | r100_vram_init_sizes(rdev); | ||
373 | /* FIXME: we should enforce default clock in case GPU is not in | 374 | /* FIXME: we should enforce default clock in case GPU is not in |
374 | * default setup | 375 | * default setup |
375 | */ | 376 | */ |
@@ -399,25 +400,6 @@ void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
399 | WREG32(MC_IND_INDEX, 0); | 400 | WREG32(MC_IND_INDEX, 0); |
400 | } | 401 | } |
401 | 402 | ||
402 | uint32_t rv515_pcie_rreg(struct radeon_device *rdev, uint32_t reg) | ||
403 | { | ||
404 | uint32_t r; | ||
405 | |||
406 | WREG32(PCIE_INDEX, ((reg) & 0x7ff)); | ||
407 | (void)RREG32(PCIE_INDEX); | ||
408 | r = RREG32(PCIE_DATA); | ||
409 | return r; | ||
410 | } | ||
411 | |||
412 | void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
413 | { | ||
414 | WREG32(PCIE_INDEX, ((reg) & 0x7ff)); | ||
415 | (void)RREG32(PCIE_INDEX); | ||
416 | WREG32(PCIE_DATA, (v)); | ||
417 | (void)RREG32(PCIE_DATA); | ||
418 | } | ||
419 | |||
420 | |||
421 | /* | 403 | /* |
422 | * Debugfs info | 404 | * Debugfs info |
423 | */ | 405 | */ |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 6538d4236989..c2b0d710d10f 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -1182,13 +1182,14 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, | |||
1182 | 1182 | ||
1183 | int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type) | 1183 | int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type) |
1184 | { | 1184 | { |
1185 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; | 1185 | struct ttm_mem_type_manager *man; |
1186 | int ret = -EINVAL; | 1186 | int ret = -EINVAL; |
1187 | 1187 | ||
1188 | if (mem_type >= TTM_NUM_MEM_TYPES) { | 1188 | if (mem_type >= TTM_NUM_MEM_TYPES) { |
1189 | printk(KERN_ERR TTM_PFX "Illegal memory type %d\n", mem_type); | 1189 | printk(KERN_ERR TTM_PFX "Illegal memory type %d\n", mem_type); |
1190 | return ret; | 1190 | return ret; |
1191 | } | 1191 | } |
1192 | man = &bdev->man[mem_type]; | ||
1192 | 1193 | ||
1193 | if (!man->has_type) { | 1194 | if (!man->has_type) { |
1194 | printk(KERN_ERR TTM_PFX "Trying to take down uninitialized " | 1195 | printk(KERN_ERR TTM_PFX "Trying to take down uninitialized " |
@@ -1575,6 +1576,10 @@ int ttm_bo_wait(struct ttm_buffer_object *bo, | |||
1575 | driver->sync_obj_unref(&sync_obj); | 1576 | driver->sync_obj_unref(&sync_obj); |
1576 | driver->sync_obj_unref(&tmp_obj); | 1577 | driver->sync_obj_unref(&tmp_obj); |
1577 | spin_lock(&bo->lock); | 1578 | spin_lock(&bo->lock); |
1579 | } else { | ||
1580 | spin_unlock(&bo->lock); | ||
1581 | driver->sync_obj_unref(&sync_obj); | ||
1582 | spin_lock(&bo->lock); | ||
1578 | } | 1583 | } |
1579 | } | 1584 | } |
1580 | return 0; | 1585 | return 0; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index ce2e6f38ea01..ad4ada07c6cf 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -150,7 +150,7 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, | |||
150 | #ifdef CONFIG_X86 | 150 | #ifdef CONFIG_X86 |
151 | dst = kmap_atomic_prot(d, KM_USER0, prot); | 151 | dst = kmap_atomic_prot(d, KM_USER0, prot); |
152 | #else | 152 | #else |
153 | if (prot != PAGE_KERNEL) | 153 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) |
154 | dst = vmap(&d, 1, 0, prot); | 154 | dst = vmap(&d, 1, 0, prot); |
155 | else | 155 | else |
156 | dst = kmap(d); | 156 | dst = kmap(d); |
@@ -163,7 +163,7 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, | |||
163 | #ifdef CONFIG_X86 | 163 | #ifdef CONFIG_X86 |
164 | kunmap_atomic(dst, KM_USER0); | 164 | kunmap_atomic(dst, KM_USER0); |
165 | #else | 165 | #else |
166 | if (prot != PAGE_KERNEL) | 166 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) |
167 | vunmap(dst); | 167 | vunmap(dst); |
168 | else | 168 | else |
169 | kunmap(d); | 169 | kunmap(d); |
@@ -186,7 +186,7 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, | |||
186 | #ifdef CONFIG_X86 | 186 | #ifdef CONFIG_X86 |
187 | src = kmap_atomic_prot(s, KM_USER0, prot); | 187 | src = kmap_atomic_prot(s, KM_USER0, prot); |
188 | #else | 188 | #else |
189 | if (prot != PAGE_KERNEL) | 189 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) |
190 | src = vmap(&s, 1, 0, prot); | 190 | src = vmap(&s, 1, 0, prot); |
191 | else | 191 | else |
192 | src = kmap(s); | 192 | src = kmap(s); |
@@ -199,7 +199,7 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, | |||
199 | #ifdef CONFIG_X86 | 199 | #ifdef CONFIG_X86 |
200 | kunmap_atomic(src, KM_USER0); | 200 | kunmap_atomic(src, KM_USER0); |
201 | #else | 201 | #else |
202 | if (prot != PAGE_KERNEL) | 202 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) |
203 | vunmap(src); | 203 | vunmap(src); |
204 | else | 204 | else |
205 | kunmap(s); | 205 | kunmap(s); |