diff options
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_combios.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 8 |
6 files changed, 56 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 3cd3234ba0a..10e41af6b02 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -957,7 +957,11 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
957 | /* adjust pixel clock as needed */ | 957 | /* adjust pixel clock as needed */ |
958 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); | 958 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); |
959 | 959 | ||
960 | if (ASIC_IS_AVIVO(rdev)) | 960 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
961 | /* TV seems to prefer the legacy algo on some boards */ | ||
962 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | ||
963 | &ref_div, &post_div); | ||
964 | else if (ASIC_IS_AVIVO(rdev)) | ||
961 | radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 965 | radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
962 | &ref_div, &post_div); | 966 | &ref_div, &post_div); |
963 | else | 967 | else |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index cf7c8d5b4ec..cf602e2d071 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -448,7 +448,7 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, | |||
448 | 448 | ||
449 | bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) | 449 | bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) |
450 | { | 450 | { |
451 | int edid_info; | 451 | int edid_info, size; |
452 | struct edid *edid; | 452 | struct edid *edid; |
453 | unsigned char *raw; | 453 | unsigned char *raw; |
454 | edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE); | 454 | edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE); |
@@ -456,11 +456,12 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) | |||
456 | return false; | 456 | return false; |
457 | 457 | ||
458 | raw = rdev->bios + edid_info; | 458 | raw = rdev->bios + edid_info; |
459 | edid = kmalloc(EDID_LENGTH * (raw[0x7e] + 1), GFP_KERNEL); | 459 | size = EDID_LENGTH * (raw[0x7e] + 1); |
460 | edid = kmalloc(size, GFP_KERNEL); | ||
460 | if (edid == NULL) | 461 | if (edid == NULL) |
461 | return false; | 462 | return false; |
462 | 463 | ||
463 | memcpy((unsigned char *)edid, raw, EDID_LENGTH * (raw[0x7e] + 1)); | 464 | memcpy((unsigned char *)edid, raw, size); |
464 | 465 | ||
465 | if (!drm_edid_is_valid(edid)) { | 466 | if (!drm_edid_is_valid(edid)) { |
466 | kfree(edid); | 467 | kfree(edid); |
@@ -468,6 +469,7 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) | |||
468 | } | 469 | } |
469 | 470 | ||
470 | rdev->mode_info.bios_hardcoded_edid = edid; | 471 | rdev->mode_info.bios_hardcoded_edid = edid; |
472 | rdev->mode_info.bios_hardcoded_edid_size = size; | ||
471 | return true; | 473 | return true; |
472 | } | 474 | } |
473 | 475 | ||
@@ -475,8 +477,17 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) | |||
475 | struct edid * | 477 | struct edid * |
476 | radeon_bios_get_hardcoded_edid(struct radeon_device *rdev) | 478 | radeon_bios_get_hardcoded_edid(struct radeon_device *rdev) |
477 | { | 479 | { |
478 | if (rdev->mode_info.bios_hardcoded_edid) | 480 | struct edid *edid; |
479 | return rdev->mode_info.bios_hardcoded_edid; | 481 | |
482 | if (rdev->mode_info.bios_hardcoded_edid) { | ||
483 | edid = kmalloc(rdev->mode_info.bios_hardcoded_edid_size, GFP_KERNEL); | ||
484 | if (edid) { | ||
485 | memcpy((unsigned char *)edid, | ||
486 | (unsigned char *)rdev->mode_info.bios_hardcoded_edid, | ||
487 | rdev->mode_info.bios_hardcoded_edid_size); | ||
488 | return edid; | ||
489 | } | ||
490 | } | ||
480 | return NULL; | 491 | return NULL; |
481 | } | 492 | } |
482 | 493 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 28c7961cd19..2ef6d513506 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -633,6 +633,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector, | |||
633 | static enum drm_connector_status | 633 | static enum drm_connector_status |
634 | radeon_vga_detect(struct drm_connector *connector, bool force) | 634 | radeon_vga_detect(struct drm_connector *connector, bool force) |
635 | { | 635 | { |
636 | struct drm_device *dev = connector->dev; | ||
637 | struct radeon_device *rdev = dev->dev_private; | ||
636 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 638 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
637 | struct drm_encoder *encoder; | 639 | struct drm_encoder *encoder; |
638 | struct drm_encoder_helper_funcs *encoder_funcs; | 640 | struct drm_encoder_helper_funcs *encoder_funcs; |
@@ -683,6 +685,17 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
683 | 685 | ||
684 | if (ret == connector_status_connected) | 686 | if (ret == connector_status_connected) |
685 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); | 687 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); |
688 | |||
689 | /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the | ||
690 | * vbios to deal with KVMs. If we have one and are not able to detect a monitor | ||
691 | * by other means, assume the CRT is connected and use that EDID. | ||
692 | */ | ||
693 | if ((!rdev->is_atom_bios) && | ||
694 | (ret == connector_status_disconnected) && | ||
695 | rdev->mode_info.bios_hardcoded_edid_size) { | ||
696 | ret = connector_status_connected; | ||
697 | } | ||
698 | |||
686 | radeon_connector_update_scratch_regs(connector, ret); | 699 | radeon_connector_update_scratch_regs(connector, ret); |
687 | return ret; | 700 | return ret; |
688 | } | 701 | } |
@@ -794,6 +807,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector) | |||
794 | static enum drm_connector_status | 807 | static enum drm_connector_status |
795 | radeon_dvi_detect(struct drm_connector *connector, bool force) | 808 | radeon_dvi_detect(struct drm_connector *connector, bool force) |
796 | { | 809 | { |
810 | struct drm_device *dev = connector->dev; | ||
811 | struct radeon_device *rdev = dev->dev_private; | ||
797 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 812 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
798 | struct drm_encoder *encoder = NULL; | 813 | struct drm_encoder *encoder = NULL; |
799 | struct drm_encoder_helper_funcs *encoder_funcs; | 814 | struct drm_encoder_helper_funcs *encoder_funcs; |
@@ -833,8 +848,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
833 | * you don't really know what's connected to which port as both are digital. | 848 | * you don't really know what's connected to which port as both are digital. |
834 | */ | 849 | */ |
835 | if (radeon_connector->shared_ddc && (ret == connector_status_connected)) { | 850 | if (radeon_connector->shared_ddc && (ret == connector_status_connected)) { |
836 | struct drm_device *dev = connector->dev; | ||
837 | struct radeon_device *rdev = dev->dev_private; | ||
838 | struct drm_connector *list_connector; | 851 | struct drm_connector *list_connector; |
839 | struct radeon_connector *list_radeon_connector; | 852 | struct radeon_connector *list_radeon_connector; |
840 | list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) { | 853 | list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) { |
@@ -899,6 +912,19 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
899 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); | 912 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); |
900 | } | 913 | } |
901 | 914 | ||
915 | /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the | ||
916 | * vbios to deal with KVMs. If we have one and are not able to detect a monitor | ||
917 | * by other means, assume the DFP is connected and use that EDID. In most | ||
918 | * cases the DVI port is actually a virtual KVM port connected to the service | ||
919 | * processor. | ||
920 | */ | ||
921 | if ((!rdev->is_atom_bios) && | ||
922 | (ret == connector_status_disconnected) && | ||
923 | rdev->mode_info.bios_hardcoded_edid_size) { | ||
924 | radeon_connector->use_digital = true; | ||
925 | ret = connector_status_connected; | ||
926 | } | ||
927 | |||
902 | out: | 928 | out: |
903 | /* updated in get modes as well since we need to know if it's analog or digital */ | 929 | /* updated in get modes as well since we need to know if it's analog or digital */ |
904 | radeon_connector_update_scratch_regs(connector, ret); | 930 | radeon_connector_update_scratch_regs(connector, ret); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 66c9af1b3d9..41a5d48e657 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -889,7 +889,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
889 | } | 889 | } |
890 | 890 | ||
891 | if (rdev->flags & RADEON_IS_MOBILITY) { | 891 | if (rdev->flags & RADEON_IS_MOBILITY) { |
892 | /* A temporal workaround for the occational blanking on certain laptop panels. | 892 | /* A temporal workaround for the occasional blanking on certain laptop panels. |
893 | This appears to related to the PLL divider registers (fail to lock?). | 893 | This appears to related to the PLL divider registers (fail to lock?). |
894 | It occurs even when all dividers are the same with their old settings. | 894 | It occurs even when all dividers are the same with their old settings. |
895 | In this case we really don't need to fiddle with PLL registers. | 895 | In this case we really don't need to fiddle with PLL registers. |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index e4582814bb7..9c57538231d 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -239,6 +239,7 @@ struct radeon_mode_info { | |||
239 | struct drm_property *underscan_vborder_property; | 239 | struct drm_property *underscan_vborder_property; |
240 | /* hardcoded DFP edid from BIOS */ | 240 | /* hardcoded DFP edid from BIOS */ |
241 | struct edid *bios_hardcoded_edid; | 241 | struct edid *bios_hardcoded_edid; |
242 | int bios_hardcoded_edid_size; | ||
242 | 243 | ||
243 | /* pointer to fbdev info structure */ | 244 | /* pointer to fbdev info structure */ |
244 | struct radeon_fbdev *rfbdev; | 245 | struct radeon_fbdev *rfbdev; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 2aed03bde4b..08de669e025 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -365,12 +365,14 @@ static ssize_t radeon_set_pm_profile(struct device *dev, | |||
365 | else if (strncmp("high", buf, strlen("high")) == 0) | 365 | else if (strncmp("high", buf, strlen("high")) == 0) |
366 | rdev->pm.profile = PM_PROFILE_HIGH; | 366 | rdev->pm.profile = PM_PROFILE_HIGH; |
367 | else { | 367 | else { |
368 | DRM_ERROR("invalid power profile!\n"); | 368 | count = -EINVAL; |
369 | goto fail; | 369 | goto fail; |
370 | } | 370 | } |
371 | radeon_pm_update_profile(rdev); | 371 | radeon_pm_update_profile(rdev); |
372 | radeon_pm_set_clocks(rdev); | 372 | radeon_pm_set_clocks(rdev); |
373 | } | 373 | } else |
374 | count = -EINVAL; | ||
375 | |||
374 | fail: | 376 | fail: |
375 | mutex_unlock(&rdev->pm.mutex); | 377 | mutex_unlock(&rdev->pm.mutex); |
376 | 378 | ||
@@ -413,7 +415,7 @@ static ssize_t radeon_set_pm_method(struct device *dev, | |||
413 | mutex_unlock(&rdev->pm.mutex); | 415 | mutex_unlock(&rdev->pm.mutex); |
414 | cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); | 416 | cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); |
415 | } else { | 417 | } else { |
416 | DRM_ERROR("invalid power method!\n"); | 418 | count = -EINVAL; |
417 | goto fail; | 419 | goto fail; |
418 | } | 420 | } |
419 | radeon_pm_compute_clocks(rdev); | 421 | radeon_pm_compute_clocks(rdev); |