aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c1
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c2
-rw-r--r--drivers/gpu/drm/radeon/r600_dpm.c35
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c84
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c51
7 files changed, 120 insertions, 68 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 15936524f226..bc0119fb6c12 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -209,6 +209,7 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
209{ 209{
210 int ret; 210 int ret;
211 211
212 radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
212 radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; 213 radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
213 radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer; 214 radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer;
214 ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux); 215 ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux);
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index 89b4afa5041c..f7e46cf682af 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -597,7 +597,7 @@ int cik_sdma_ring_test(struct radeon_device *rdev,
597 tmp = 0xCAFEDEAD; 597 tmp = 0xCAFEDEAD;
598 writel(tmp, ptr); 598 writel(tmp, ptr);
599 599
600 r = radeon_ring_lock(rdev, ring, 4); 600 r = radeon_ring_lock(rdev, ring, 5);
601 if (r) { 601 if (r) {
602 DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r); 602 DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r);
603 return r; 603 return r;
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c
index cbf7e3269f84..9c61b74ef441 100644
--- a/drivers/gpu/drm/radeon/r600_dpm.c
+++ b/drivers/gpu/drm/radeon/r600_dpm.c
@@ -158,16 +158,18 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
158 u32 line_time_us, vblank_lines; 158 u32 line_time_us, vblank_lines;
159 u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ 159 u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
160 160
161 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 161 if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
162 radeon_crtc = to_radeon_crtc(crtc); 162 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
163 if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { 163 radeon_crtc = to_radeon_crtc(crtc);
164 line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / 164 if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
165 radeon_crtc->hw_mode.clock; 165 line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
166 vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - 166 radeon_crtc->hw_mode.clock;
167 radeon_crtc->hw_mode.crtc_vdisplay + 167 vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
168 (radeon_crtc->v_border * 2); 168 radeon_crtc->hw_mode.crtc_vdisplay +
169 vblank_time_us = vblank_lines * line_time_us; 169 (radeon_crtc->v_border * 2);
170 break; 170 vblank_time_us = vblank_lines * line_time_us;
171 break;
172 }
171 } 173 }
172 } 174 }
173 175
@@ -181,14 +183,15 @@ u32 r600_dpm_get_vrefresh(struct radeon_device *rdev)
181 struct radeon_crtc *radeon_crtc; 183 struct radeon_crtc *radeon_crtc;
182 u32 vrefresh = 0; 184 u32 vrefresh = 0;
183 185
184 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 186 if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
185 radeon_crtc = to_radeon_crtc(crtc); 187 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
186 if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { 188 radeon_crtc = to_radeon_crtc(crtc);
187 vrefresh = radeon_crtc->hw_mode.vrefresh; 189 if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
188 break; 190 vrefresh = radeon_crtc->hw_mode.vrefresh;
191 break;
192 }
189 } 193 }
190 } 194 }
191
192 return vrefresh; 195 return vrefresh;
193} 196}
194 197
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index dedea72f48c4..a9fb0d016d38 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -528,6 +528,13 @@ static bool radeon_atpx_detect(void)
528 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true); 528 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
529 } 529 }
530 530
531 /* some newer PX laptops mark the dGPU as a non-VGA display device */
532 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
533 vga_count++;
534
535 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
536 }
537
531 if (has_atpx && vga_count == 2) { 538 if (has_atpx && vga_count == 2) {
532 acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer); 539 acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
533 printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", 540 printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 2f7cbb901fb1..8d99d5ee8014 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -840,6 +840,38 @@ static void avivo_reduce_ratio(unsigned *nom, unsigned *den,
840} 840}
841 841
842/** 842/**
843 * avivo_get_fb_ref_div - feedback and ref divider calculation
844 *
845 * @nom: nominator
846 * @den: denominator
847 * @post_div: post divider
848 * @fb_div_max: feedback divider maximum
849 * @ref_div_max: reference divider maximum
850 * @fb_div: resulting feedback divider
851 * @ref_div: resulting reference divider
852 *
853 * Calculate feedback and reference divider for a given post divider. Makes
854 * sure we stay within the limits.
855 */
856static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div,
857 unsigned fb_div_max, unsigned ref_div_max,
858 unsigned *fb_div, unsigned *ref_div)
859{
860 /* limit reference * post divider to a maximum */
861 ref_div_max = min(210 / post_div, ref_div_max);
862
863 /* get matching reference and feedback divider */
864 *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);
865 *fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den);
866
867 /* limit fb divider to its maximum */
868 if (*fb_div > fb_div_max) {
869 *ref_div = DIV_ROUND_CLOSEST(*ref_div * fb_div_max, *fb_div);
870 *fb_div = fb_div_max;
871 }
872}
873
874/**
843 * radeon_compute_pll_avivo - compute PLL paramaters 875 * radeon_compute_pll_avivo - compute PLL paramaters
844 * 876 *
845 * @pll: information about the PLL 877 * @pll: information about the PLL
@@ -860,6 +892,9 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
860 u32 *ref_div_p, 892 u32 *ref_div_p,
861 u32 *post_div_p) 893 u32 *post_div_p)
862{ 894{
895 unsigned target_clock = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ?
896 freq : freq / 10;
897
863 unsigned fb_div_min, fb_div_max, fb_div; 898 unsigned fb_div_min, fb_div_max, fb_div;
864 unsigned post_div_min, post_div_max, post_div; 899 unsigned post_div_min, post_div_max, post_div;
865 unsigned ref_div_min, ref_div_max, ref_div; 900 unsigned ref_div_min, ref_div_max, ref_div;
@@ -880,14 +915,18 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
880 ref_div_min = pll->reference_div; 915 ref_div_min = pll->reference_div;
881 else 916 else
882 ref_div_min = pll->min_ref_div; 917 ref_div_min = pll->min_ref_div;
883 ref_div_max = pll->max_ref_div; 918
919 if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV &&
920 pll->flags & RADEON_PLL_USE_REF_DIV)
921 ref_div_max = pll->reference_div;
922 else
923 ref_div_max = pll->max_ref_div;
884 924
885 /* determine allowed post divider range */ 925 /* determine allowed post divider range */
886 if (pll->flags & RADEON_PLL_USE_POST_DIV) { 926 if (pll->flags & RADEON_PLL_USE_POST_DIV) {
887 post_div_min = pll->post_div; 927 post_div_min = pll->post_div;
888 post_div_max = pll->post_div; 928 post_div_max = pll->post_div;
889 } else { 929 } else {
890 unsigned target_clock = freq / 10;
891 unsigned vco_min, vco_max; 930 unsigned vco_min, vco_max;
892 931
893 if (pll->flags & RADEON_PLL_IS_LCD) { 932 if (pll->flags & RADEON_PLL_IS_LCD) {
@@ -898,6 +937,11 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
898 vco_max = pll->pll_out_max; 937 vco_max = pll->pll_out_max;
899 } 938 }
900 939
940 if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
941 vco_min *= 10;
942 vco_max *= 10;
943 }
944
901 post_div_min = vco_min / target_clock; 945 post_div_min = vco_min / target_clock;
902 if ((target_clock * post_div_min) < vco_min) 946 if ((target_clock * post_div_min) < vco_min)
903 ++post_div_min; 947 ++post_div_min;
@@ -912,7 +956,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
912 } 956 }
913 957
914 /* represent the searched ratio as fractional number */ 958 /* represent the searched ratio as fractional number */
915 nom = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ? freq : freq / 10; 959 nom = target_clock;
916 den = pll->reference_freq; 960 den = pll->reference_freq;
917 961
918 /* reduce the numbers to a simpler ratio */ 962 /* reduce the numbers to a simpler ratio */
@@ -926,7 +970,12 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
926 diff_best = ~0; 970 diff_best = ~0;
927 971
928 for (post_div = post_div_min; post_div <= post_div_max; ++post_div) { 972 for (post_div = post_div_min; post_div <= post_div_max; ++post_div) {
929 unsigned diff = abs(den - den / post_div * post_div); 973 unsigned diff;
974 avivo_get_fb_ref_div(nom, den, post_div, fb_div_max,
975 ref_div_max, &fb_div, &ref_div);
976 diff = abs(target_clock - (pll->reference_freq * fb_div) /
977 (ref_div * post_div));
978
930 if (diff < diff_best || (diff == diff_best && 979 if (diff < diff_best || (diff == diff_best &&
931 !(pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP))) { 980 !(pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP))) {
932 981
@@ -936,28 +985,9 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
936 } 985 }
937 post_div = post_div_best; 986 post_div = post_div_best;
938 987
939 /* limit reference * post divider to a maximum */ 988 /* get the feedback and reference divider for the optimal value */
940 ref_div_max = min(210 / post_div, ref_div_max); 989 avivo_get_fb_ref_div(nom, den, post_div, fb_div_max, ref_div_max,
941 990 &fb_div, &ref_div);
942 /* get matching reference and feedback divider */
943 ref_div = max(DIV_ROUND_CLOSEST(den, post_div), 1u);
944 fb_div = DIV_ROUND_CLOSEST(nom * ref_div * post_div, den);
945
946 /* we're almost done, but reference and feedback
947 divider might be to large now */
948
949 nom = fb_div;
950 den = ref_div;
951
952 if (fb_div > fb_div_max) {
953 ref_div = DIV_ROUND_CLOSEST(den * fb_div_max, nom);
954 fb_div = fb_div_max;
955 }
956
957 if (ref_div > ref_div_max) {
958 ref_div = ref_div_max;
959 fb_div = DIV_ROUND_CLOSEST(nom * ref_div_max, den);
960 }
961 991
962 /* reduce the numbers to a simpler ratio once more */ 992 /* reduce the numbers to a simpler ratio once more */
963 /* this also makes sure that the reference divider is large enough */ 993 /* this also makes sure that the reference divider is large enough */
@@ -979,7 +1009,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
979 *post_div_p = post_div; 1009 *post_div_p = post_div;
980 1010
981 DRM_DEBUG_KMS("%d - %d, pll dividers - fb: %d.%d ref: %d, post %d\n", 1011 DRM_DEBUG_KMS("%d - %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
982 freq, *dot_clock_p, *fb_div_p, *frac_fb_div_p, 1012 freq, *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p,
983 ref_div, post_div); 1013 ref_div, post_div);
984} 1014}
985 1015
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index fb3d13f693dd..0cc47f12d995 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -107,11 +107,9 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
107 flags |= RADEON_IS_PCI; 107 flags |= RADEON_IS_PCI;
108 } 108 }
109 109
110 if (radeon_runtime_pm == 1) 110 if ((radeon_runtime_pm != 0) &&
111 flags |= RADEON_IS_PX; 111 radeon_has_atpx() &&
112 else if ((radeon_runtime_pm == -1) && 112 ((flags & RADEON_IS_IGP) == 0))
113 radeon_has_atpx() &&
114 ((flags & RADEON_IS_IGP) == 0))
115 flags |= RADEON_IS_PX; 113 flags |= RADEON_IS_PX;
116 114
117 /* radeon_device_init should report only fatal error 115 /* radeon_device_init should report only fatal error
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index ee738a524639..6fac8efe8340 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -603,7 +603,6 @@ static const struct attribute_group *hwmon_groups[] = {
603static int radeon_hwmon_init(struct radeon_device *rdev) 603static int radeon_hwmon_init(struct radeon_device *rdev)
604{ 604{
605 int err = 0; 605 int err = 0;
606 struct device *hwmon_dev;
607 606
608 switch (rdev->pm.int_thermal_type) { 607 switch (rdev->pm.int_thermal_type) {
609 case THERMAL_TYPE_RV6XX: 608 case THERMAL_TYPE_RV6XX:
@@ -616,11 +615,11 @@ static int radeon_hwmon_init(struct radeon_device *rdev)
616 case THERMAL_TYPE_KV: 615 case THERMAL_TYPE_KV:
617 if (rdev->asic->pm.get_temperature == NULL) 616 if (rdev->asic->pm.get_temperature == NULL)
618 return err; 617 return err;
619 hwmon_dev = hwmon_device_register_with_groups(rdev->dev, 618 rdev->pm.int_hwmon_dev = hwmon_device_register_with_groups(rdev->dev,
620 "radeon", rdev, 619 "radeon", rdev,
621 hwmon_groups); 620 hwmon_groups);
622 if (IS_ERR(hwmon_dev)) { 621 if (IS_ERR(rdev->pm.int_hwmon_dev)) {
623 err = PTR_ERR(hwmon_dev); 622 err = PTR_ERR(rdev->pm.int_hwmon_dev);
624 dev_err(rdev->dev, 623 dev_err(rdev->dev,
625 "Unable to register hwmon device: %d\n", err); 624 "Unable to register hwmon device: %d\n", err);
626 } 625 }
@@ -632,6 +631,12 @@ static int radeon_hwmon_init(struct radeon_device *rdev)
632 return err; 631 return err;
633} 632}
634 633
634static void radeon_hwmon_fini(struct radeon_device *rdev)
635{
636 if (rdev->pm.int_hwmon_dev)
637 hwmon_device_unregister(rdev->pm.int_hwmon_dev);
638}
639
635static void radeon_dpm_thermal_work_handler(struct work_struct *work) 640static void radeon_dpm_thermal_work_handler(struct work_struct *work)
636{ 641{
637 struct radeon_device *rdev = 642 struct radeon_device *rdev =
@@ -1257,6 +1262,7 @@ int radeon_pm_init(struct radeon_device *rdev)
1257 case CHIP_RV670: 1262 case CHIP_RV670:
1258 case CHIP_RS780: 1263 case CHIP_RS780:
1259 case CHIP_RS880: 1264 case CHIP_RS880:
1265 case CHIP_RV770:
1260 case CHIP_BARTS: 1266 case CHIP_BARTS:
1261 case CHIP_TURKS: 1267 case CHIP_TURKS:
1262 case CHIP_CAICOS: 1268 case CHIP_CAICOS:
@@ -1273,7 +1279,6 @@ int radeon_pm_init(struct radeon_device *rdev)
1273 else 1279 else
1274 rdev->pm.pm_method = PM_METHOD_PROFILE; 1280 rdev->pm.pm_method = PM_METHOD_PROFILE;
1275 break; 1281 break;
1276 case CHIP_RV770:
1277 case CHIP_RV730: 1282 case CHIP_RV730:
1278 case CHIP_RV710: 1283 case CHIP_RV710:
1279 case CHIP_RV740: 1284 case CHIP_RV740:
@@ -1353,6 +1358,8 @@ static void radeon_pm_fini_old(struct radeon_device *rdev)
1353 device_remove_file(rdev->dev, &dev_attr_power_method); 1358 device_remove_file(rdev->dev, &dev_attr_power_method);
1354 } 1359 }
1355 1360
1361 radeon_hwmon_fini(rdev);
1362
1356 if (rdev->pm.power_state) 1363 if (rdev->pm.power_state)
1357 kfree(rdev->pm.power_state); 1364 kfree(rdev->pm.power_state);
1358} 1365}
@@ -1372,6 +1379,8 @@ static void radeon_pm_fini_dpm(struct radeon_device *rdev)
1372 } 1379 }
1373 radeon_dpm_fini(rdev); 1380 radeon_dpm_fini(rdev);
1374 1381
1382 radeon_hwmon_fini(rdev);
1383
1375 if (rdev->pm.power_state) 1384 if (rdev->pm.power_state)
1376 kfree(rdev->pm.power_state); 1385 kfree(rdev->pm.power_state);
1377} 1386}
@@ -1397,12 +1406,14 @@ static void radeon_pm_compute_clocks_old(struct radeon_device *rdev)
1397 1406
1398 rdev->pm.active_crtcs = 0; 1407 rdev->pm.active_crtcs = 0;
1399 rdev->pm.active_crtc_count = 0; 1408 rdev->pm.active_crtc_count = 0;
1400 list_for_each_entry(crtc, 1409 if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
1401 &ddev->mode_config.crtc_list, head) { 1410 list_for_each_entry(crtc,
1402 radeon_crtc = to_radeon_crtc(crtc); 1411 &ddev->mode_config.crtc_list, head) {
1403 if (radeon_crtc->enabled) { 1412 radeon_crtc = to_radeon_crtc(crtc);
1404 rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); 1413 if (radeon_crtc->enabled) {
1405 rdev->pm.active_crtc_count++; 1414 rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
1415 rdev->pm.active_crtc_count++;
1416 }
1406 } 1417 }
1407 } 1418 }
1408 1419
@@ -1469,12 +1480,14 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
1469 /* update active crtc counts */ 1480 /* update active crtc counts */
1470 rdev->pm.dpm.new_active_crtcs = 0; 1481 rdev->pm.dpm.new_active_crtcs = 0;
1471 rdev->pm.dpm.new_active_crtc_count = 0; 1482 rdev->pm.dpm.new_active_crtc_count = 0;
1472 list_for_each_entry(crtc, 1483 if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
1473 &ddev->mode_config.crtc_list, head) { 1484 list_for_each_entry(crtc,
1474 radeon_crtc = to_radeon_crtc(crtc); 1485 &ddev->mode_config.crtc_list, head) {
1475 if (crtc->enabled) { 1486 radeon_crtc = to_radeon_crtc(crtc);
1476 rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); 1487 if (crtc->enabled) {
1477 rdev->pm.dpm.new_active_crtc_count++; 1488 rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id);
1489 rdev->pm.dpm.new_active_crtc_count++;
1490 }
1478 } 1491 }
1479 } 1492 }
1480 1493