aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c12
-rw-r--r--drivers/gpu/drm/radeon/r100.c9
-rw-r--r--drivers/gpu/drm/radeon/r600.c21
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c21
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
-rw-r--r--drivers/gpu/drm/radeon/rs600.c9
10 files changed, 98 insertions, 10 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 784ba80afcb6..0d63c4436e7c 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -507,6 +507,18 @@ static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
507 return true; 507 return true;
508} 508}
509 509
510bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
511{
512 struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
513 u8 link_status[DP_LINK_STATUS_SIZE];
514
515 if (!atom_dp_get_link_status(radeon_connector, link_status))
516 return false;
517 if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count))
518 return false;
519 return true;
520}
521
510static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state) 522static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
511{ 523{
512 struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; 524 struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 2b534c528aaf..b7baf16c11d7 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -289,6 +289,7 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
289int r100_irq_process(struct radeon_device *rdev) 289int r100_irq_process(struct radeon_device *rdev)
290{ 290{
291 uint32_t status, msi_rearm; 291 uint32_t status, msi_rearm;
292 bool queue_hotplug = false;
292 293
293 status = r100_irq_ack(rdev); 294 status = r100_irq_ack(rdev);
294 if (!status) { 295 if (!status) {
@@ -310,13 +311,17 @@ int r100_irq_process(struct radeon_device *rdev)
310 drm_handle_vblank(rdev->ddev, 1); 311 drm_handle_vblank(rdev->ddev, 1);
311 } 312 }
312 if (status & RADEON_FP_DETECT_STAT) { 313 if (status & RADEON_FP_DETECT_STAT) {
313 DRM_INFO("HPD1\n"); 314 queue_hotplug = true;
315 DRM_DEBUG("HPD1\n");
314 } 316 }
315 if (status & RADEON_FP2_DETECT_STAT) { 317 if (status & RADEON_FP2_DETECT_STAT) {
316 DRM_INFO("HPD2\n"); 318 queue_hotplug = true;
319 DRM_DEBUG("HPD2\n");
317 } 320 }
318 status = r100_irq_ack(rdev); 321 status = r100_irq_ack(rdev);
319 } 322 }
323 if (queue_hotplug)
324 queue_work(rdev->wq, &rdev->hotplug_work);
320 if (rdev->msi_enabled) { 325 if (rdev->msi_enabled) {
321 switch (rdev->family) { 326 switch (rdev->family) {
322 case CHIP_RS400: 327 case CHIP_RS400:
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c11715fb29c7..250ec3fe1a16 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2674,6 +2674,7 @@ int r600_irq_process(struct radeon_device *rdev)
2674 u32 last_entry = rdev->ih.ring_size - 16; 2674 u32 last_entry = rdev->ih.ring_size - 16;
2675 u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; 2675 u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
2676 unsigned long flags; 2676 unsigned long flags;
2677 bool queue_hotplug = false;
2677 2678
2678 DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); 2679 DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
2679 2680
@@ -2745,37 +2746,43 @@ restart_ih:
2745 case 0: 2746 case 0:
2746 if (disp_int & DC_HPD1_INTERRUPT) { 2747 if (disp_int & DC_HPD1_INTERRUPT) {
2747 disp_int &= ~DC_HPD1_INTERRUPT; 2748 disp_int &= ~DC_HPD1_INTERRUPT;
2748 DRM_INFO("IH: HPD1\n"); 2749 queue_hotplug = true;
2750 DRM_DEBUG("IH: HPD1\n");
2749 } 2751 }
2750 break; 2752 break;
2751 case 1: 2753 case 1:
2752 if (disp_int & DC_HPD2_INTERRUPT) { 2754 if (disp_int & DC_HPD2_INTERRUPT) {
2753 disp_int &= ~DC_HPD2_INTERRUPT; 2755 disp_int &= ~DC_HPD2_INTERRUPT;
2754 DRM_INFO("IH: HPD2\n"); 2756 queue_hotplug = true;
2757 DRM_DEBUG("IH: HPD2\n");
2755 } 2758 }
2756 break; 2759 break;
2757 case 4: 2760 case 4:
2758 if (disp_int_cont & DC_HPD3_INTERRUPT) { 2761 if (disp_int_cont & DC_HPD3_INTERRUPT) {
2759 disp_int_cont &= ~DC_HPD3_INTERRUPT; 2762 disp_int_cont &= ~DC_HPD3_INTERRUPT;
2760 DRM_INFO("IH: HPD3\n"); 2763 queue_hotplug = true;
2764 DRM_DEBUG("IH: HPD3\n");
2761 } 2765 }
2762 break; 2766 break;
2763 case 5: 2767 case 5:
2764 if (disp_int_cont & DC_HPD4_INTERRUPT) { 2768 if (disp_int_cont & DC_HPD4_INTERRUPT) {
2765 disp_int_cont &= ~DC_HPD4_INTERRUPT; 2769 disp_int_cont &= ~DC_HPD4_INTERRUPT;
2766 DRM_INFO("IH: HPD4\n"); 2770 queue_hotplug = true;
2771 DRM_DEBUG("IH: HPD4\n");
2767 } 2772 }
2768 break; 2773 break;
2769 case 10: 2774 case 10:
2770 if (disp_int_cont2 & DC_HPD5_INTERRUPT) { 2775 if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
2771 disp_int_cont &= ~DC_HPD5_INTERRUPT; 2776 disp_int_cont &= ~DC_HPD5_INTERRUPT;
2772 DRM_INFO("IH: HPD5\n"); 2777 queue_hotplug = true;
2778 DRM_DEBUG("IH: HPD5\n");
2773 } 2779 }
2774 break; 2780 break;
2775 case 12: 2781 case 12:
2776 if (disp_int_cont2 & DC_HPD6_INTERRUPT) { 2782 if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
2777 disp_int_cont &= ~DC_HPD6_INTERRUPT; 2783 disp_int_cont &= ~DC_HPD6_INTERRUPT;
2778 DRM_INFO("IH: HPD6\n"); 2784 queue_hotplug = true;
2785 DRM_DEBUG("IH: HPD6\n");
2779 } 2786 }
2780 break; 2787 break;
2781 default: 2788 default:
@@ -2807,6 +2814,8 @@ restart_ih:
2807 wptr = r600_get_ih_wptr(rdev); 2814 wptr = r600_get_ih_wptr(rdev);
2808 if (wptr != rdev->ih.wptr) 2815 if (wptr != rdev->ih.wptr)
2809 goto restart_ih; 2816 goto restart_ih;
2817 if (queue_hotplug)
2818 queue_work(rdev->wq, &rdev->hotplug_work);
2810 rdev->ih.rptr = rptr; 2819 rdev->ih.rptr = rptr;
2811 WREG32(IH_RB_RPTR, rdev->ih.rptr); 2820 WREG32(IH_RB_RPTR, rdev->ih.rptr);
2812 spin_unlock_irqrestore(&rdev->ih.lock, flags); 2821 spin_unlock_irqrestore(&rdev->ih.lock, flags);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 29c6e0af3755..a15cf9ceb9a7 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -809,6 +809,8 @@ struct radeon_device {
809 struct r600_blit r600_blit; 809 struct r600_blit r600_blit;
810 int msi_enabled; /* msi enabled */ 810 int msi_enabled; /* msi enabled */
811 struct r600_ih ih; /* r6/700 interrupt ring */ 811 struct r600_ih ih; /* r6/700 interrupt ring */
812 struct workqueue_struct *wq;
813 struct work_struct hotplug_work;
812}; 814};
813 815
814int radeon_device_init(struct radeon_device *rdev, 816int radeon_device_init(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 7328d1528a85..cfa2ebb259fe 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -40,6 +40,26 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
40 struct drm_encoder *encoder, 40 struct drm_encoder *encoder,
41 bool connected); 41 bool connected);
42 42
43void radeon_connector_hotplug(struct drm_connector *connector)
44{
45 struct drm_device *dev = connector->dev;
46 struct radeon_device *rdev = dev->dev_private;
47 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
48
49 if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
50 radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
51
52 if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
53 if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
54 if (radeon_dp_needs_link_train(radeon_connector)) {
55 if (connector->encoder)
56 dp_link_train(connector->encoder, connector);
57 }
58 }
59 }
60
61}
62
43static void radeon_property_change_mode(struct drm_encoder *encoder) 63static void radeon_property_change_mode(struct drm_encoder *encoder)
44{ 64{
45 struct drm_crtc *crtc = encoder->crtc; 65 struct drm_crtc *crtc = encoder->crtc;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 60ee6a8b4f7f..7e55647f118e 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -570,6 +570,11 @@ int radeon_device_init(struct radeon_device *rdev,
570 rwlock_init(&rdev->fence_drv.lock); 570 rwlock_init(&rdev->fence_drv.lock);
571 INIT_LIST_HEAD(&rdev->gem.objects); 571 INIT_LIST_HEAD(&rdev->gem.objects);
572 572
573 /* setup workqueue */
574 rdev->wq = create_workqueue("radeon");
575 if (rdev->wq == NULL)
576 return -ENOMEM;
577
573 /* Set asic functions */ 578 /* Set asic functions */
574 r = radeon_asic_init(rdev); 579 r = radeon_asic_init(rdev);
575 if (r) { 580 if (r) {
@@ -643,6 +648,7 @@ void radeon_device_fini(struct radeon_device *rdev)
643 DRM_INFO("radeon: finishing device.\n"); 648 DRM_INFO("radeon: finishing device.\n");
644 rdev->shutdown = true; 649 rdev->shutdown = true;
645 radeon_fini(rdev); 650 radeon_fini(rdev);
651 destroy_workqueue(rdev->wq);
646 vga_client_register(rdev->pdev, NULL, NULL, NULL); 652 vga_client_register(rdev->pdev, NULL, NULL, NULL);
647 iounmap(rdev->rmmio); 653 iounmap(rdev->rmmio);
648 rdev->rmmio = NULL; 654 rdev->rmmio = NULL;
@@ -689,6 +695,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
689 radeon_save_bios_scratch_regs(rdev); 695 radeon_save_bios_scratch_regs(rdev);
690 696
691 radeon_suspend(rdev); 697 radeon_suspend(rdev);
698 radeon_hpd_fini(rdev);
692 /* evict remaining vram memory */ 699 /* evict remaining vram memory */
693 radeon_bo_evict_vram(rdev); 700 radeon_bo_evict_vram(rdev);
694 701
@@ -723,6 +730,8 @@ int radeon_resume_kms(struct drm_device *dev)
723 fb_set_suspend(rdev->fbdev_info, 0); 730 fb_set_suspend(rdev->fbdev_info, 0);
724 release_console_sem(); 731 release_console_sem();
725 732
733 /* reset hpd state */
734 radeon_hpd_init(rdev);
726 /* blat the mode back in */ 735 /* blat the mode back in */
727 drm_helper_resume_force_mode(dev); 736 drm_helper_resume_force_mode(dev);
728 return 0; 737 return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index d4f4fb1c54c7..c115f2e442eb 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -741,6 +741,8 @@ int radeon_modeset_init(struct radeon_device *rdev)
741 if (!ret) { 741 if (!ret) {
742 return ret; 742 return ret;
743 } 743 }
744 /* initialize hpd */
745 radeon_hpd_init(rdev);
744 drm_helper_initial_config(rdev->ddev); 746 drm_helper_initial_config(rdev->ddev);
745 return 0; 747 return 0;
746} 748}
@@ -748,6 +750,7 @@ int radeon_modeset_init(struct radeon_device *rdev)
748void radeon_modeset_fini(struct radeon_device *rdev) 750void radeon_modeset_fini(struct radeon_device *rdev)
749{ 751{
750 if (rdev->mode_info.mode_config_initialized) { 752 if (rdev->mode_info.mode_config_initialized) {
753 radeon_hpd_fini(rdev);
751 drm_mode_config_cleanup(rdev->ddev); 754 drm_mode_config_cleanup(rdev->ddev);
752 rdev->mode_info.mode_config_initialized = false; 755 rdev->mode_info.mode_config_initialized = false;
753 } 756 }
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 26789970c5cf..9223296fe37b 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -39,11 +39,32 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS)
39 return radeon_irq_process(rdev); 39 return radeon_irq_process(rdev);
40} 40}
41 41
42/*
43 * Handle hotplug events outside the interrupt handler proper.
44 */
45static void radeon_hotplug_work_func(struct work_struct *work)
46{
47 struct radeon_device *rdev = container_of(work, struct radeon_device,
48 hotplug_work);
49 struct drm_device *dev = rdev->ddev;
50 struct drm_mode_config *mode_config = &dev->mode_config;
51 struct drm_connector *connector;
52
53 if (mode_config->num_connector) {
54 list_for_each_entry(connector, &mode_config->connector_list, head)
55 radeon_connector_hotplug(connector);
56 }
57 /* Just fire off a uevent and let userspace tell us what to do */
58 drm_sysfs_hotplug_event(dev);
59}
60
42void radeon_driver_irq_preinstall_kms(struct drm_device *dev) 61void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
43{ 62{
44 struct radeon_device *rdev = dev->dev_private; 63 struct radeon_device *rdev = dev->dev_private;
45 unsigned i; 64 unsigned i;
46 65
66 INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
67
47 /* Disable *all* interrupts */ 68 /* Disable *all* interrupts */
48 rdev->irq.sw_int = false; 69 rdev->irq.sw_int = false;
49 for (i = 0; i < 2; i++) { 70 for (i = 0; i < 2; i++) {
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 61b90343f794..15ec7ca18a95 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -392,6 +392,8 @@ struct radeon_framebuffer {
392 struct drm_gem_object *obj; 392 struct drm_gem_object *obj;
393}; 393};
394 394
395extern void radeon_connector_hotplug(struct drm_connector *connector);
396extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
395extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, 397extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
396 struct drm_display_mode *mode); 398 struct drm_display_mode *mode);
397extern void radeon_dp_set_link_config(struct drm_connector *connector, 399extern void radeon_dp_set_link_config(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 6364ba1d4153..fd5ab01f6ad1 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -388,6 +388,7 @@ int rs600_irq_process(struct radeon_device *rdev)
388{ 388{
389 uint32_t status, msi_rearm; 389 uint32_t status, msi_rearm;
390 uint32_t r500_disp_int; 390 uint32_t r500_disp_int;
391 bool queue_hotplug = false;
391 392
392 status = rs600_irq_ack(rdev, &r500_disp_int); 393 status = rs600_irq_ack(rdev, &r500_disp_int);
393 if (!status && !r500_disp_int) { 394 if (!status && !r500_disp_int) {
@@ -403,13 +404,17 @@ int rs600_irq_process(struct radeon_device *rdev)
403 if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) 404 if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int))
404 drm_handle_vblank(rdev->ddev, 1); 405 drm_handle_vblank(rdev->ddev, 1);
405 if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { 406 if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) {
406 DRM_INFO("HPD1\n"); 407 queue_hotplug = true;
408 DRM_DEBUG("HPD1\n");
407 } 409 }
408 if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) { 410 if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) {
409 DRM_INFO("HPD2\n"); 411 queue_hotplug = true;
412 DRM_DEBUG("HPD2\n");
410 } 413 }
411 status = rs600_irq_ack(rdev, &r500_disp_int); 414 status = rs600_irq_ack(rdev, &r500_disp_int);
412 } 415 }
416 if (queue_hotplug)
417 queue_work(rdev->wq, &rdev->hotplug_work);
413 if (rdev->msi_enabled) { 418 if (rdev->msi_enabled) {
414 switch (rdev->family) { 419 switch (rdev->family) {
415 case CHIP_RS600: 420 case CHIP_RS600: