diff options
46 files changed, 1837 insertions, 971 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index ea283894a12a..308c104ccdbd 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -110,7 +110,6 @@ config DRM_RADEON | |||
110 | select HWMON | 110 | select HWMON |
111 | select BACKLIGHT_CLASS_DEVICE | 111 | select BACKLIGHT_CLASS_DEVICE |
112 | select INTERVAL_TREE | 112 | select INTERVAL_TREE |
113 | select MMU_NOTIFIER | ||
114 | help | 113 | help |
115 | Choose this option if you have an ATI Radeon graphics card. There | 114 | Choose this option if you have an ATI Radeon graphics card. There |
116 | are both PCI and AGP versions. You don't need to choose this to | 115 | are both PCI and AGP versions. You don't need to choose this to |
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index c58cfd3c3917..4605633e253b 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -80,8 +80,10 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
80 | r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ | 80 | r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ |
81 | rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ | 81 | rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ |
82 | trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ | 82 | trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ |
83 | ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o \ | 83 | ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o \ |
84 | radeon_sync.o | 84 | radeon_sync.o radeon_audio.o |
85 | |||
86 | radeon-$(CONFIG_MMU_NOTIFIER) += radeon_mn.o | ||
85 | 87 | ||
86 | # add async DMA block | 88 | # add async DMA block |
87 | radeon-y += \ | 89 | radeon-y += \ |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index b8cd7975f797..7c9df1eac065 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <drm/drm_crtc_helper.h> | 27 | #include <drm/drm_crtc_helper.h> |
28 | #include <drm/radeon_drm.h> | 28 | #include <drm/radeon_drm.h> |
29 | #include "radeon.h" | 29 | #include "radeon.h" |
30 | #include "radeon_audio.h" | ||
30 | #include "atom.h" | 31 | #include "atom.h" |
31 | #include <linux/backlight.h> | 32 | #include <linux/backlight.h> |
32 | 33 | ||
@@ -664,6 +665,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
664 | int | 665 | int |
665 | atombios_get_encoder_mode(struct drm_encoder *encoder) | 666 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
666 | { | 667 | { |
668 | struct drm_device *dev = encoder->dev; | ||
669 | struct radeon_device *rdev = dev->dev_private; | ||
667 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 670 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
668 | struct drm_connector *connector; | 671 | struct drm_connector *connector; |
669 | struct radeon_connector *radeon_connector; | 672 | struct radeon_connector *radeon_connector; |
@@ -728,6 +731,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
728 | dig_connector = radeon_connector->con_priv; | 731 | dig_connector = radeon_connector->con_priv; |
729 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 732 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
730 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { | 733 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { |
734 | if (radeon_audio != 0 && ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev)) | ||
735 | return ATOM_ENCODER_MODE_DP_AUDIO; | ||
731 | return ATOM_ENCODER_MODE_DP; | 736 | return ATOM_ENCODER_MODE_DP; |
732 | } else if (radeon_audio != 0) { | 737 | } else if (radeon_audio != 0) { |
733 | if (radeon_connector->audio == RADEON_AUDIO_ENABLE) | 738 | if (radeon_connector->audio == RADEON_AUDIO_ENABLE) |
@@ -742,6 +747,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
742 | } | 747 | } |
743 | break; | 748 | break; |
744 | case DRM_MODE_CONNECTOR_eDP: | 749 | case DRM_MODE_CONNECTOR_eDP: |
750 | if (radeon_audio != 0 && ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev)) | ||
751 | return ATOM_ENCODER_MODE_DP_AUDIO; | ||
745 | return ATOM_ENCODER_MODE_DP; | 752 | return ATOM_ENCODER_MODE_DP; |
746 | case DRM_MODE_CONNECTOR_DVIA: | 753 | case DRM_MODE_CONNECTOR_DVIA: |
747 | case DRM_MODE_CONNECTOR_VGA: | 754 | case DRM_MODE_CONNECTOR_VGA: |
@@ -1615,6 +1622,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1615 | struct radeon_connector *radeon_connector = NULL; | 1622 | struct radeon_connector *radeon_connector = NULL; |
1616 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; | 1623 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; |
1617 | bool travis_quirk = false; | 1624 | bool travis_quirk = false; |
1625 | int encoder_mode; | ||
1618 | 1626 | ||
1619 | if (connector) { | 1627 | if (connector) { |
1620 | radeon_connector = to_radeon_connector(connector); | 1628 | radeon_connector = to_radeon_connector(connector); |
@@ -1710,6 +1718,11 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1710 | } | 1718 | } |
1711 | break; | 1719 | break; |
1712 | } | 1720 | } |
1721 | |||
1722 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
1723 | if (radeon_audio != 0 && | ||
1724 | (encoder_mode == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(encoder_mode))) | ||
1725 | radeon_audio_dpms(encoder, mode); | ||
1713 | } | 1726 | } |
1714 | 1727 | ||
1715 | static void | 1728 | static void |
@@ -2123,6 +2136,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
2123 | struct drm_device *dev = encoder->dev; | 2136 | struct drm_device *dev = encoder->dev; |
2124 | struct radeon_device *rdev = dev->dev_private; | 2137 | struct radeon_device *rdev = dev->dev_private; |
2125 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 2138 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
2139 | int encoder_mode; | ||
2126 | 2140 | ||
2127 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 2141 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
2128 | 2142 | ||
@@ -2149,6 +2163,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
2149 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: | 2163 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: |
2150 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 2164 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
2151 | /* handled in dpms */ | 2165 | /* handled in dpms */ |
2166 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
2167 | if (radeon_audio != 0 && | ||
2168 | (encoder_mode == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(encoder_mode))) | ||
2169 | radeon_audio_mode_set(encoder, adjusted_mode); | ||
2152 | break; | 2170 | break; |
2153 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 2171 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
2154 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 2172 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
@@ -2170,13 +2188,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
2170 | } | 2188 | } |
2171 | 2189 | ||
2172 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 2190 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
2173 | |||
2174 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | ||
2175 | if (rdev->asic->display.hdmi_enable) | ||
2176 | radeon_hdmi_enable(rdev, encoder, true); | ||
2177 | if (rdev->asic->display.hdmi_setmode) | ||
2178 | radeon_hdmi_setmode(rdev, encoder, adjusted_mode); | ||
2179 | } | ||
2180 | } | 2191 | } |
2181 | 2192 | ||
2182 | static bool | 2193 | static bool |
@@ -2442,10 +2453,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | |||
2442 | 2453 | ||
2443 | disable_done: | 2454 | disable_done: |
2444 | if (radeon_encoder_is_digital(encoder)) { | 2455 | if (radeon_encoder_is_digital(encoder)) { |
2445 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | ||
2446 | if (rdev->asic->display.hdmi_enable) | ||
2447 | radeon_hdmi_enable(rdev, encoder, false); | ||
2448 | } | ||
2449 | dig = radeon_encoder->enc_priv; | 2456 | dig = radeon_encoder->enc_priv; |
2450 | dig->dig_encoder = -1; | 2457 | dig->dig_encoder = -1; |
2451 | } | 2458 | } |
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 0b2929de9f41..db08f17be76b 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
@@ -2277,6 +2277,7 @@ static void btc_update_requested_ps(struct radeon_device *rdev, | |||
2277 | eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps; | 2277 | eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps; |
2278 | } | 2278 | } |
2279 | 2279 | ||
2280 | #if 0 | ||
2280 | void btc_dpm_reset_asic(struct radeon_device *rdev) | 2281 | void btc_dpm_reset_asic(struct radeon_device *rdev) |
2281 | { | 2282 | { |
2282 | rv770_restrict_performance_levels_before_switch(rdev); | 2283 | rv770_restrict_performance_levels_before_switch(rdev); |
@@ -2284,6 +2285,7 @@ void btc_dpm_reset_asic(struct radeon_device *rdev) | |||
2284 | btc_set_boot_state_timing(rdev); | 2285 | btc_set_boot_state_timing(rdev); |
2285 | rv770_set_boot_state(rdev); | 2286 | rv770_set_boot_state(rdev); |
2286 | } | 2287 | } |
2288 | #endif | ||
2287 | 2289 | ||
2288 | int btc_dpm_pre_set_power_state(struct radeon_device *rdev) | 2290 | int btc_dpm_pre_set_power_state(struct radeon_device *rdev) |
2289 | { | 2291 | { |
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index f373a81ba3d5..bcd2f1fe803f 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c | |||
@@ -187,6 +187,9 @@ static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate); | |||
187 | static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev, | 187 | static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev, |
188 | PPSMC_Msg msg, u32 parameter); | 188 | PPSMC_Msg msg, u32 parameter); |
189 | 189 | ||
190 | static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev); | ||
191 | static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev); | ||
192 | |||
190 | static struct ci_power_info *ci_get_pi(struct radeon_device *rdev) | 193 | static struct ci_power_info *ci_get_pi(struct radeon_device *rdev) |
191 | { | 194 | { |
192 | struct ci_power_info *pi = rdev->pm.dpm.priv; | 195 | struct ci_power_info *pi = rdev->pm.dpm.priv; |
@@ -1043,22 +1046,24 @@ static int ci_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) | |||
1043 | return -EINVAL; | 1046 | return -EINVAL; |
1044 | } | 1047 | } |
1045 | 1048 | ||
1049 | pi->fan_is_controlled_by_smc = true; | ||
1046 | return 0; | 1050 | return 0; |
1047 | } | 1051 | } |
1048 | 1052 | ||
1049 | #if 0 | ||
1050 | static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) | 1053 | static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) |
1051 | { | 1054 | { |
1052 | PPSMC_Result ret; | 1055 | PPSMC_Result ret; |
1056 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
1053 | 1057 | ||
1054 | ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl); | 1058 | ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl); |
1055 | if (ret == PPSMC_Result_OK) | 1059 | if (ret == PPSMC_Result_OK) { |
1060 | pi->fan_is_controlled_by_smc = false; | ||
1056 | return 0; | 1061 | return 0; |
1057 | else | 1062 | } else |
1058 | return -EINVAL; | 1063 | return -EINVAL; |
1059 | } | 1064 | } |
1060 | 1065 | ||
1061 | static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, | 1066 | int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, |
1062 | u32 *speed) | 1067 | u32 *speed) |
1063 | { | 1068 | { |
1064 | u32 duty, duty100; | 1069 | u32 duty, duty100; |
@@ -1083,21 +1088,22 @@ static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, | |||
1083 | return 0; | 1088 | return 0; |
1084 | } | 1089 | } |
1085 | 1090 | ||
1086 | static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | 1091 | int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, |
1087 | u32 speed) | 1092 | u32 speed) |
1088 | { | 1093 | { |
1089 | u32 tmp; | 1094 | u32 tmp; |
1090 | u32 duty, duty100; | 1095 | u32 duty, duty100; |
1091 | u64 tmp64; | 1096 | u64 tmp64; |
1097 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
1092 | 1098 | ||
1093 | if (rdev->pm.no_fan) | 1099 | if (rdev->pm.no_fan) |
1094 | return -ENOENT; | 1100 | return -ENOENT; |
1095 | 1101 | ||
1096 | if (speed > 100) | 1102 | if (pi->fan_is_controlled_by_smc) |
1097 | return -EINVAL; | 1103 | return -EINVAL; |
1098 | 1104 | ||
1099 | if (rdev->pm.dpm.fan.ucode_fan_control) | 1105 | if (speed > 100) |
1100 | ci_fan_ctrl_stop_smc_fan_control(rdev); | 1106 | return -EINVAL; |
1101 | 1107 | ||
1102 | duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; | 1108 | duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; |
1103 | 1109 | ||
@@ -1112,11 +1118,38 @@ static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | |||
1112 | tmp |= FDO_STATIC_DUTY(duty); | 1118 | tmp |= FDO_STATIC_DUTY(duty); |
1113 | WREG32_SMC(CG_FDO_CTRL0, tmp); | 1119 | WREG32_SMC(CG_FDO_CTRL0, tmp); |
1114 | 1120 | ||
1115 | ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | ||
1116 | |||
1117 | return 0; | 1121 | return 0; |
1118 | } | 1122 | } |
1119 | 1123 | ||
1124 | void ci_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode) | ||
1125 | { | ||
1126 | if (mode) { | ||
1127 | /* stop auto-manage */ | ||
1128 | if (rdev->pm.dpm.fan.ucode_fan_control) | ||
1129 | ci_fan_ctrl_stop_smc_fan_control(rdev); | ||
1130 | ci_fan_ctrl_set_static_mode(rdev, mode); | ||
1131 | } else { | ||
1132 | /* restart auto-manage */ | ||
1133 | if (rdev->pm.dpm.fan.ucode_fan_control) | ||
1134 | ci_thermal_start_smc_fan_control(rdev); | ||
1135 | else | ||
1136 | ci_fan_ctrl_set_default_mode(rdev); | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | u32 ci_fan_ctrl_get_mode(struct radeon_device *rdev) | ||
1141 | { | ||
1142 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
1143 | u32 tmp; | ||
1144 | |||
1145 | if (pi->fan_is_controlled_by_smc) | ||
1146 | return 0; | ||
1147 | |||
1148 | tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; | ||
1149 | return (tmp >> FDO_PWM_MODE_SHIFT); | ||
1150 | } | ||
1151 | |||
1152 | #if 0 | ||
1120 | static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, | 1153 | static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, |
1121 | u32 *speed) | 1154 | u32 *speed) |
1122 | { | 1155 | { |
@@ -1698,10 +1731,12 @@ static int ci_set_overdrive_target_tdp(struct radeon_device *rdev, | |||
1698 | return 0; | 1731 | return 0; |
1699 | } | 1732 | } |
1700 | 1733 | ||
1734 | #if 0 | ||
1701 | static int ci_set_boot_state(struct radeon_device *rdev) | 1735 | static int ci_set_boot_state(struct radeon_device *rdev) |
1702 | { | 1736 | { |
1703 | return ci_enable_sclk_mclk_dpm(rdev, false); | 1737 | return ci_enable_sclk_mclk_dpm(rdev, false); |
1704 | } | 1738 | } |
1739 | #endif | ||
1705 | 1740 | ||
1706 | static u32 ci_get_average_sclk_freq(struct radeon_device *rdev) | 1741 | static u32 ci_get_average_sclk_freq(struct radeon_device *rdev) |
1707 | { | 1742 | { |
@@ -5343,10 +5378,12 @@ int ci_dpm_set_power_state(struct radeon_device *rdev) | |||
5343 | return 0; | 5378 | return 0; |
5344 | } | 5379 | } |
5345 | 5380 | ||
5381 | #if 0 | ||
5346 | void ci_dpm_reset_asic(struct radeon_device *rdev) | 5382 | void ci_dpm_reset_asic(struct radeon_device *rdev) |
5347 | { | 5383 | { |
5348 | ci_set_boot_state(rdev); | 5384 | ci_set_boot_state(rdev); |
5349 | } | 5385 | } |
5386 | #endif | ||
5350 | 5387 | ||
5351 | void ci_dpm_display_configuration_changed(struct radeon_device *rdev) | 5388 | void ci_dpm_display_configuration_changed(struct radeon_device *rdev) |
5352 | { | 5389 | { |
diff --git a/drivers/gpu/drm/radeon/ci_dpm.h b/drivers/gpu/drm/radeon/ci_dpm.h index 84e3d3bcf9f3..723220ffbea2 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.h +++ b/drivers/gpu/drm/radeon/ci_dpm.h | |||
@@ -291,6 +291,7 @@ struct ci_power_info { | |||
291 | struct ci_ps requested_ps; | 291 | struct ci_ps requested_ps; |
292 | /* fan control */ | 292 | /* fan control */ |
293 | bool fan_ctrl_is_in_default_mode; | 293 | bool fan_ctrl_is_in_default_mode; |
294 | bool fan_is_controlled_by_smc; | ||
294 | u32 t_min; | 295 | u32 t_min; |
295 | u32 fan_ctrl_default_mode; | 296 | u32 fan_ctrl_default_mode; |
296 | }; | 297 | }; |
diff --git a/drivers/gpu/drm/radeon/ci_smc.c b/drivers/gpu/drm/radeon/ci_smc.c index e78bcad7a43e..35c6f648ba04 100644 --- a/drivers/gpu/drm/radeon/ci_smc.c +++ b/drivers/gpu/drm/radeon/ci_smc.c | |||
@@ -184,6 +184,7 @@ PPSMC_Result ci_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg) | |||
184 | return (PPSMC_Result)tmp; | 184 | return (PPSMC_Result)tmp; |
185 | } | 185 | } |
186 | 186 | ||
187 | #if 0 | ||
187 | PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev) | 188 | PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev) |
188 | { | 189 | { |
189 | u32 tmp; | 190 | u32 tmp; |
@@ -201,6 +202,7 @@ PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev) | |||
201 | 202 | ||
202 | return PPSMC_Result_OK; | 203 | return PPSMC_Result_OK; |
203 | } | 204 | } |
205 | #endif | ||
204 | 206 | ||
205 | int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit) | 207 | int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit) |
206 | { | 208 | { |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index ed336fbfab7c..de77c27d8106 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "drmP.h" | 27 | #include "drmP.h" |
28 | #include "radeon.h" | 28 | #include "radeon.h" |
29 | #include "radeon_asic.h" | 29 | #include "radeon_asic.h" |
30 | #include "radeon_audio.h" | ||
30 | #include "cikd.h" | 31 | #include "cikd.h" |
31 | #include "atom.h" | 32 | #include "atom.h" |
32 | #include "cik_blit_shaders.h" | 33 | #include "cik_blit_shaders.h" |
@@ -8517,7 +8518,7 @@ static int cik_startup(struct radeon_device *rdev) | |||
8517 | return r; | 8518 | return r; |
8518 | } | 8519 | } |
8519 | 8520 | ||
8520 | r = dce6_audio_init(rdev); | 8521 | r = radeon_audio_init(rdev); |
8521 | if (r) | 8522 | if (r) |
8522 | return r; | 8523 | return r; |
8523 | 8524 | ||
@@ -8575,7 +8576,7 @@ int cik_suspend(struct radeon_device *rdev) | |||
8575 | { | 8576 | { |
8576 | radeon_kfd_suspend(rdev); | 8577 | radeon_kfd_suspend(rdev); |
8577 | radeon_pm_suspend(rdev); | 8578 | radeon_pm_suspend(rdev); |
8578 | dce6_audio_fini(rdev); | 8579 | radeon_audio_fini(rdev); |
8579 | radeon_vm_manager_fini(rdev); | 8580 | radeon_vm_manager_fini(rdev); |
8580 | cik_cp_enable(rdev, false); | 8581 | cik_cp_enable(rdev, false); |
8581 | cik_sdma_enable(rdev, false); | 8582 | cik_sdma_enable(rdev, false); |
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 9aad0327e4d1..ca058589ddef 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c | |||
@@ -2005,11 +2005,13 @@ int cypress_dpm_set_power_state(struct radeon_device *rdev) | |||
2005 | return 0; | 2005 | return 0; |
2006 | } | 2006 | } |
2007 | 2007 | ||
2008 | #if 0 | ||
2008 | void cypress_dpm_reset_asic(struct radeon_device *rdev) | 2009 | void cypress_dpm_reset_asic(struct radeon_device *rdev) |
2009 | { | 2010 | { |
2010 | rv770_restrict_performance_levels_before_switch(rdev); | 2011 | rv770_restrict_performance_levels_before_switch(rdev); |
2011 | rv770_set_boot_state(rdev); | 2012 | rv770_set_boot_state(rdev); |
2012 | } | 2013 | } |
2014 | #endif | ||
2013 | 2015 | ||
2014 | void cypress_dpm_display_configuration_changed(struct radeon_device *rdev) | 2016 | void cypress_dpm_display_configuration_changed(struct radeon_device *rdev) |
2015 | { | 2017 | { |
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index bafdf92a5732..f04205170b8a 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c | |||
@@ -24,37 +24,17 @@ | |||
24 | #include <drm/drmP.h> | 24 | #include <drm/drmP.h> |
25 | #include "radeon.h" | 25 | #include "radeon.h" |
26 | #include "radeon_asic.h" | 26 | #include "radeon_asic.h" |
27 | #include "radeon_audio.h" | ||
27 | #include "r600d.h" | 28 | #include "r600d.h" |
28 | 29 | ||
29 | static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | 30 | void dce3_2_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, |
31 | u8 *sadb, int sad_count) | ||
30 | { | 32 | { |
31 | struct radeon_device *rdev = encoder->dev->dev_private; | 33 | struct radeon_device *rdev = encoder->dev->dev_private; |
32 | struct drm_connector *connector; | ||
33 | struct radeon_connector *radeon_connector = NULL; | ||
34 | u32 tmp; | 34 | u32 tmp; |
35 | u8 *sadb = NULL; | ||
36 | int sad_count; | ||
37 | |||
38 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
39 | if (connector->encoder == encoder) { | ||
40 | radeon_connector = to_radeon_connector(connector); | ||
41 | break; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | if (!radeon_connector) { | ||
46 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
47 | return; | ||
48 | } | ||
49 | |||
50 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); | ||
51 | if (sad_count < 0) { | ||
52 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | ||
53 | sad_count = 0; | ||
54 | } | ||
55 | 35 | ||
56 | /* program the speaker allocation */ | 36 | /* program the speaker allocation */ |
57 | tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); | 37 | tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); |
58 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); | 38 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); |
59 | /* set HDMI mode */ | 39 | /* set HDMI mode */ |
60 | tmp |= HDMI_CONNECTION; | 40 | tmp |= HDMI_CONNECTION; |
@@ -62,19 +42,32 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
62 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | 42 | tmp |= SPEAKER_ALLOCATION(sadb[0]); |
63 | else | 43 | else |
64 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | 44 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ |
65 | WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); | 45 | WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); |
66 | |||
67 | kfree(sadb); | ||
68 | } | 46 | } |
69 | 47 | ||
70 | static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) | 48 | void dce3_2_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, |
49 | u8 *sadb, int sad_count) | ||
71 | { | 50 | { |
72 | struct radeon_device *rdev = encoder->dev->dev_private; | 51 | struct radeon_device *rdev = encoder->dev->dev_private; |
73 | struct drm_connector *connector; | 52 | u32 tmp; |
74 | struct radeon_connector *radeon_connector = NULL; | 53 | |
75 | struct cea_sad *sads; | 54 | /* program the speaker allocation */ |
76 | int i, sad_count; | 55 | tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); |
56 | tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); | ||
57 | /* set DP mode */ | ||
58 | tmp |= DP_CONNECTION; | ||
59 | if (sad_count) | ||
60 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | ||
61 | else | ||
62 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | ||
63 | WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); | ||
64 | } | ||
77 | 65 | ||
66 | void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder, | ||
67 | struct cea_sad *sads, int sad_count) | ||
68 | { | ||
69 | int i; | ||
70 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
78 | static const u16 eld_reg_to_type[][2] = { | 71 | static const u16 eld_reg_to_type[][2] = { |
79 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, | 72 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, |
80 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, | 73 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, |
@@ -90,25 +83,6 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
90 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, | 83 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, |
91 | }; | 84 | }; |
92 | 85 | ||
93 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
94 | if (connector->encoder == encoder) { | ||
95 | radeon_connector = to_radeon_connector(connector); | ||
96 | break; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | if (!radeon_connector) { | ||
101 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
102 | return; | ||
103 | } | ||
104 | |||
105 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); | ||
106 | if (sad_count <= 0) { | ||
107 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); | ||
108 | return; | ||
109 | } | ||
110 | BUG_ON(!sads); | ||
111 | |||
112 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { | 86 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
113 | u32 value = 0; | 87 | u32 value = 0; |
114 | u8 stereo_freqs = 0; | 88 | u8 stereo_freqs = 0; |
@@ -135,110 +109,124 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
135 | 109 | ||
136 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); | 110 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); |
137 | 111 | ||
138 | WREG32(eld_reg_to_type[i][0], value); | 112 | WREG32_ENDPOINT(0, eld_reg_to_type[i][0], value); |
139 | } | 113 | } |
140 | |||
141 | kfree(sads); | ||
142 | } | 114 | } |
143 | 115 | ||
144 | /* | 116 | void dce3_2_audio_set_dto(struct radeon_device *rdev, |
145 | * update the info frames with the data from the current display mode | 117 | struct radeon_crtc *crtc, unsigned int clock) |
146 | */ | ||
147 | void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) | ||
148 | { | 118 | { |
149 | struct drm_device *dev = encoder->dev; | 119 | struct radeon_encoder *radeon_encoder; |
150 | struct radeon_device *rdev = dev->dev_private; | 120 | struct radeon_encoder_atom_dig *dig; |
151 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 121 | unsigned int max_ratio = clock / 24000; |
152 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 122 | u32 dto_phase; |
153 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; | 123 | u32 wallclock_ratio; |
154 | struct hdmi_avi_infoframe frame; | 124 | u32 dto_cntl; |
155 | uint32_t offset; | 125 | |
156 | ssize_t err; | 126 | if (!crtc) |
157 | |||
158 | if (!dig || !dig->afmt) | ||
159 | return; | ||
160 | |||
161 | /* Silent, r600_hdmi_enable will raise WARN for us */ | ||
162 | if (!dig->afmt->enabled) | ||
163 | return; | 127 | return; |
164 | offset = dig->afmt->offset; | ||
165 | |||
166 | /* disable audio prior to setting up hw */ | ||
167 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
168 | r600_audio_enable(rdev, dig->afmt->pin, 0); | ||
169 | 128 | ||
170 | r600_audio_set_dto(encoder, mode->clock); | 129 | radeon_encoder = to_radeon_encoder(crtc->encoder); |
130 | dig = radeon_encoder->enc_priv; | ||
171 | 131 | ||
172 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, | 132 | if (!dig) |
173 | HDMI0_NULL_SEND); /* send null packets when required */ | 133 | return; |
174 | |||
175 | WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000); | ||
176 | 134 | ||
177 | if (ASIC_IS_DCE32(rdev)) { | 135 | if (max_ratio >= 8) { |
178 | WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, | 136 | dto_phase = 192 * 1000; |
179 | HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ | 137 | wallclock_ratio = 3; |
180 | HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ | 138 | } else if (max_ratio >= 4) { |
181 | WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, | 139 | dto_phase = 96 * 1000; |
182 | AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */ | 140 | wallclock_ratio = 2; |
183 | AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ | 141 | } else if (max_ratio >= 2) { |
142 | dto_phase = 48 * 1000; | ||
143 | wallclock_ratio = 1; | ||
184 | } else { | 144 | } else { |
185 | WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, | 145 | dto_phase = 24 * 1000; |
186 | HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ | 146 | wallclock_ratio = 0; |
187 | HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ | ||
188 | HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ | ||
189 | HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ | ||
190 | } | 147 | } |
191 | 148 | ||
192 | if (ASIC_IS_DCE32(rdev)) { | 149 | /* Express [24MHz / target pixel clock] as an exact rational |
193 | dce3_2_afmt_write_speaker_allocation(encoder); | 150 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
194 | dce3_2_afmt_write_sad_regs(encoder); | 151 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
152 | */ | ||
153 | if (dig->dig_encoder == 0) { | ||
154 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
155 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
156 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
157 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | ||
158 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock); | ||
159 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
160 | } else { | ||
161 | dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
162 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
163 | WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); | ||
164 | WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); | ||
165 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock); | ||
166 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ | ||
195 | } | 167 | } |
168 | } | ||
169 | |||
170 | void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, | ||
171 | const struct radeon_hdmi_acr *acr) | ||
172 | { | ||
173 | struct drm_device *dev = encoder->dev; | ||
174 | struct radeon_device *rdev = dev->dev_private; | ||
196 | 175 | ||
197 | WREG32(HDMI0_ACR_PACKET_CONTROL + offset, | 176 | WREG32(HDMI0_ACR_PACKET_CONTROL + offset, |
198 | HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */ | 177 | HDMI0_ACR_SOURCE | /* select SW CTS value */ |
199 | HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ | 178 | HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ |
200 | 179 | ||
201 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, | 180 | WREG32_P(HDMI0_ACR_32_0 + offset, |
202 | HDMI0_NULL_SEND | /* send null packets when required */ | 181 | HDMI0_ACR_CTS_32(acr->cts_32khz), |
203 | HDMI0_GC_SEND | /* send general control packets */ | 182 | ~HDMI0_ACR_CTS_32_MASK); |
204 | HDMI0_GC_CONT); /* send general control packets every frame */ | 183 | WREG32_P(HDMI0_ACR_32_1 + offset, |
205 | 184 | HDMI0_ACR_N_32(acr->n_32khz), | |
206 | /* TODO: HDMI0_AUDIO_INFO_UPDATE */ | 185 | ~HDMI0_ACR_N_32_MASK); |
207 | WREG32(HDMI0_INFOFRAME_CONTROL0 + offset, | 186 | |
208 | HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ | 187 | WREG32_P(HDMI0_ACR_44_0 + offset, |
209 | HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */ | 188 | HDMI0_ACR_CTS_44(acr->cts_44_1khz), |
210 | HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ | 189 | ~HDMI0_ACR_CTS_44_MASK); |
211 | HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */ | 190 | WREG32_P(HDMI0_ACR_44_1 + offset, |
212 | 191 | HDMI0_ACR_N_44(acr->n_44_1khz), | |
213 | WREG32(HDMI0_INFOFRAME_CONTROL1 + offset, | 192 | ~HDMI0_ACR_N_44_MASK); |
214 | HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */ | 193 | |
215 | HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ | 194 | WREG32_P(HDMI0_ACR_48_0 + offset, |
216 | 195 | HDMI0_ACR_CTS_48(acr->cts_48khz), | |
217 | WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ | 196 | ~HDMI0_ACR_CTS_48_MASK); |
218 | 197 | WREG32_P(HDMI0_ACR_48_1 + offset, | |
219 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); | 198 | HDMI0_ACR_N_48(acr->n_48khz), |
220 | if (err < 0) { | 199 | ~HDMI0_ACR_N_48_MASK); |
221 | DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); | 200 | } |
222 | return; | ||
223 | } | ||
224 | 201 | ||
225 | err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); | 202 | void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset) |
226 | if (err < 0) { | 203 | { |
227 | DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); | 204 | struct drm_device *dev = encoder->dev; |
228 | return; | 205 | struct radeon_device *rdev = dev->dev_private; |
229 | } | ||
230 | 206 | ||
231 | r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); | 207 | WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, |
232 | r600_hdmi_update_ACR(encoder, mode->clock); | 208 | HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ |
209 | HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ | ||
233 | 210 | ||
234 | /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ | 211 | WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, |
235 | WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); | 212 | AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */ |
236 | WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); | 213 | AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ |
237 | WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001); | ||
238 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); | ||
239 | 214 | ||
240 | r600_hdmi_audio_workaround(encoder); | 215 | WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, |
216 | HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ | ||
217 | HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */ | ||
241 | 218 | ||
242 | /* enable audio after to setting up hw */ | 219 | WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, |
243 | r600_audio_enable(rdev, dig->afmt->pin, 0xf); | 220 | HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ |
221 | } | ||
222 | |||
223 | void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) | ||
224 | { | ||
225 | struct drm_device *dev = encoder->dev; | ||
226 | struct radeon_device *rdev = dev->dev_private; | ||
227 | |||
228 | if (mute) | ||
229 | WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE); | ||
230 | else | ||
231 | WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE); | ||
244 | } | 232 | } |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index f312edf4d50e..192c80389151 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -23,9 +23,10 @@ | |||
23 | #include <linux/hdmi.h> | 23 | #include <linux/hdmi.h> |
24 | #include <drm/drmP.h> | 24 | #include <drm/drmP.h> |
25 | #include "radeon.h" | 25 | #include "radeon.h" |
26 | #include "radeon_audio.h" | ||
26 | #include "sid.h" | 27 | #include "sid.h" |
27 | 28 | ||
28 | static u32 dce6_endpoint_rreg(struct radeon_device *rdev, | 29 | u32 dce6_endpoint_rreg(struct radeon_device *rdev, |
29 | u32 block_offset, u32 reg) | 30 | u32 block_offset, u32 reg) |
30 | { | 31 | { |
31 | unsigned long flags; | 32 | unsigned long flags; |
@@ -39,7 +40,7 @@ static u32 dce6_endpoint_rreg(struct radeon_device *rdev, | |||
39 | return r; | 40 | return r; |
40 | } | 41 | } |
41 | 42 | ||
42 | static void dce6_endpoint_wreg(struct radeon_device *rdev, | 43 | void dce6_endpoint_wreg(struct radeon_device *rdev, |
43 | u32 block_offset, u32 reg, u32 v) | 44 | u32 block_offset, u32 reg, u32 v) |
44 | { | 45 | { |
45 | unsigned long flags; | 46 | unsigned long flags; |
@@ -54,10 +55,6 @@ static void dce6_endpoint_wreg(struct radeon_device *rdev, | |||
54 | spin_unlock_irqrestore(&rdev->end_idx_lock, flags); | 55 | spin_unlock_irqrestore(&rdev->end_idx_lock, flags); |
55 | } | 56 | } |
56 | 57 | ||
57 | #define RREG32_ENDPOINT(block, reg) dce6_endpoint_rreg(rdev, (block), (reg)) | ||
58 | #define WREG32_ENDPOINT(block, reg, v) dce6_endpoint_wreg(rdev, (block), (reg), (v)) | ||
59 | |||
60 | |||
61 | static void dce6_afmt_get_connected_pins(struct radeon_device *rdev) | 58 | static void dce6_afmt_get_connected_pins(struct radeon_device *rdev) |
62 | { | 59 | { |
63 | int i; | 60 | int i; |
@@ -105,13 +102,11 @@ void dce6_afmt_select_pin(struct drm_encoder *encoder) | |||
105 | } | 102 | } |
106 | 103 | ||
107 | void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | 104 | void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, |
108 | struct drm_display_mode *mode) | 105 | struct drm_connector *connector, struct drm_display_mode *mode) |
109 | { | 106 | { |
110 | struct radeon_device *rdev = encoder->dev->dev_private; | 107 | struct radeon_device *rdev = encoder->dev->dev_private; |
111 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 108 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
112 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 109 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
113 | struct drm_connector *connector; | ||
114 | struct radeon_connector *radeon_connector = NULL; | ||
115 | u32 tmp = 0, offset; | 110 | u32 tmp = 0, offset; |
116 | 111 | ||
117 | if (!dig || !dig->afmt || !dig->afmt->pin) | 112 | if (!dig || !dig->afmt || !dig->afmt->pin) |
@@ -119,18 +114,6 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | |||
119 | 114 | ||
120 | offset = dig->afmt->pin->offset; | 115 | offset = dig->afmt->pin->offset; |
121 | 116 | ||
122 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
123 | if (connector->encoder == encoder) { | ||
124 | radeon_connector = to_radeon_connector(connector); | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | if (!radeon_connector) { | ||
130 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
131 | return; | ||
132 | } | ||
133 | |||
134 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { | 117 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { |
135 | if (connector->latency_present[1]) | 118 | if (connector->latency_present[1]) |
136 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | | 119 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | |
@@ -147,40 +130,19 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | |||
147 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); | 130 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); |
148 | } | 131 | } |
149 | 132 | ||
150 | void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | 133 | void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, |
134 | u8 *sadb, int sad_count) | ||
151 | { | 135 | { |
152 | struct radeon_device *rdev = encoder->dev->dev_private; | 136 | struct radeon_device *rdev = encoder->dev->dev_private; |
153 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 137 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
154 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 138 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
155 | struct drm_connector *connector; | ||
156 | struct radeon_connector *radeon_connector = NULL; | ||
157 | u32 offset, tmp; | 139 | u32 offset, tmp; |
158 | u8 *sadb = NULL; | ||
159 | int sad_count; | ||
160 | 140 | ||
161 | if (!dig || !dig->afmt || !dig->afmt->pin) | 141 | if (!dig || !dig->afmt || !dig->afmt->pin) |
162 | return; | 142 | return; |
163 | 143 | ||
164 | offset = dig->afmt->pin->offset; | 144 | offset = dig->afmt->pin->offset; |
165 | 145 | ||
166 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
167 | if (connector->encoder == encoder) { | ||
168 | radeon_connector = to_radeon_connector(connector); | ||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | if (!radeon_connector) { | ||
174 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); | ||
179 | if (sad_count < 0) { | ||
180 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | ||
181 | sad_count = 0; | ||
182 | } | ||
183 | |||
184 | /* program the speaker allocation */ | 146 | /* program the speaker allocation */ |
185 | tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); | 147 | tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); |
186 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); | 148 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); |
@@ -191,21 +153,41 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
191 | else | 153 | else |
192 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | 154 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ |
193 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); | 155 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); |
194 | |||
195 | kfree(sadb); | ||
196 | } | 156 | } |
197 | 157 | ||
198 | void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | 158 | void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, |
159 | u8 *sadb, int sad_count) | ||
199 | { | 160 | { |
200 | struct radeon_device *rdev = encoder->dev->dev_private; | 161 | struct radeon_device *rdev = encoder->dev->dev_private; |
201 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 162 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
202 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 163 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
203 | u32 offset; | 164 | u32 offset, tmp; |
204 | struct drm_connector *connector; | 165 | |
205 | struct radeon_connector *radeon_connector = NULL; | 166 | if (!dig || !dig->afmt || !dig->afmt->pin) |
206 | struct cea_sad *sads; | 167 | return; |
207 | int i, sad_count; | ||
208 | 168 | ||
169 | offset = dig->afmt->pin->offset; | ||
170 | |||
171 | /* program the speaker allocation */ | ||
172 | tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); | ||
173 | tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); | ||
174 | /* set DP mode */ | ||
175 | tmp |= DP_CONNECTION; | ||
176 | if (sad_count) | ||
177 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | ||
178 | else | ||
179 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | ||
180 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); | ||
181 | } | ||
182 | |||
183 | void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, | ||
184 | struct cea_sad *sads, int sad_count) | ||
185 | { | ||
186 | u32 offset; | ||
187 | int i; | ||
188 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
189 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
190 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
209 | static const u16 eld_reg_to_type[][2] = { | 191 | static const u16 eld_reg_to_type[][2] = { |
210 | { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, | 192 | { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, |
211 | { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, | 193 | { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, |
@@ -226,25 +208,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
226 | 208 | ||
227 | offset = dig->afmt->pin->offset; | 209 | offset = dig->afmt->pin->offset; |
228 | 210 | ||
229 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
230 | if (connector->encoder == encoder) { | ||
231 | radeon_connector = to_radeon_connector(connector); | ||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | if (!radeon_connector) { | ||
237 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
238 | return; | ||
239 | } | ||
240 | |||
241 | sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); | ||
242 | if (sad_count <= 0) { | ||
243 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); | ||
244 | return; | ||
245 | } | ||
246 | BUG_ON(!sads); | ||
247 | |||
248 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { | 211 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
249 | u32 value = 0; | 212 | u32 value = 0; |
250 | u8 stereo_freqs = 0; | 213 | u8 stereo_freqs = 0; |
@@ -273,13 +236,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
273 | 236 | ||
274 | WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); | 237 | WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); |
275 | } | 238 | } |
276 | |||
277 | kfree(sads); | ||
278 | } | ||
279 | |||
280 | static int dce6_audio_chipset_supported(struct radeon_device *rdev) | ||
281 | { | ||
282 | return !ASIC_IS_NODCE(rdev); | ||
283 | } | 239 | } |
284 | 240 | ||
285 | void dce6_audio_enable(struct radeon_device *rdev, | 241 | void dce6_audio_enable(struct radeon_device *rdev, |
@@ -293,64 +249,76 @@ void dce6_audio_enable(struct radeon_device *rdev, | |||
293 | enable_mask ? AUDIO_ENABLED : 0); | 249 | enable_mask ? AUDIO_ENABLED : 0); |
294 | } | 250 | } |
295 | 251 | ||
296 | static const u32 pin_offsets[7] = | 252 | void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, |
297 | { | 253 | struct radeon_crtc *crtc, unsigned int clock) |
298 | (0x5e00 - 0x5e00), | ||
299 | (0x5e18 - 0x5e00), | ||
300 | (0x5e30 - 0x5e00), | ||
301 | (0x5e48 - 0x5e00), | ||
302 | (0x5e60 - 0x5e00), | ||
303 | (0x5e78 - 0x5e00), | ||
304 | (0x5e90 - 0x5e00), | ||
305 | }; | ||
306 | |||
307 | int dce6_audio_init(struct radeon_device *rdev) | ||
308 | { | 254 | { |
309 | int i; | 255 | /* Two dtos; generally use dto0 for HDMI */ |
256 | u32 value = 0; | ||
310 | 257 | ||
311 | if (!radeon_audio || !dce6_audio_chipset_supported(rdev)) | 258 | if (crtc) |
312 | return 0; | 259 | value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); |
313 | 260 | ||
314 | rdev->audio.enabled = true; | 261 | WREG32(DCCG_AUDIO_DTO_SOURCE, value); |
315 | 262 | ||
316 | if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */ | 263 | /* Express [24MHz / target pixel clock] as an exact rational |
317 | rdev->audio.num_pins = 7; | 264 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
318 | else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */ | 265 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
319 | rdev->audio.num_pins = 3; | 266 | */ |
320 | else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */ | 267 | WREG32(DCCG_AUDIO_DTO0_PHASE, 24000); |
321 | rdev->audio.num_pins = 7; | 268 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock); |
322 | else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */ | 269 | } |
323 | rdev->audio.num_pins = 6; | ||
324 | else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */ | ||
325 | rdev->audio.num_pins = 2; | ||
326 | else /* SI: 6 streams, 6 endpoints */ | ||
327 | rdev->audio.num_pins = 6; | ||
328 | 270 | ||
329 | for (i = 0; i < rdev->audio.num_pins; i++) { | 271 | void dce6_dp_audio_set_dto(struct radeon_device *rdev, |
330 | rdev->audio.pin[i].channels = -1; | 272 | struct radeon_crtc *crtc, unsigned int clock) |
331 | rdev->audio.pin[i].rate = -1; | 273 | { |
332 | rdev->audio.pin[i].bits_per_sample = -1; | 274 | /* Two dtos; generally use dto1 for DP */ |
333 | rdev->audio.pin[i].status_bits = 0; | 275 | u32 value = 0; |
334 | rdev->audio.pin[i].category_code = 0; | 276 | value |= DCCG_AUDIO_DTO_SEL; |
335 | rdev->audio.pin[i].connected = false; | 277 | |
336 | rdev->audio.pin[i].offset = pin_offsets[i]; | 278 | if (crtc) |
337 | rdev->audio.pin[i].id = i; | 279 | value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); |
338 | /* disable audio. it will be set up later */ | 280 | |
339 | dce6_audio_enable(rdev, &rdev->audio.pin[i], false); | 281 | WREG32(DCCG_AUDIO_DTO_SOURCE, value); |
340 | } | ||
341 | 282 | ||
342 | return 0; | 283 | /* Express [24MHz / target pixel clock] as an exact rational |
284 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | ||
285 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | ||
286 | */ | ||
287 | WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); | ||
288 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock); | ||
343 | } | 289 | } |
344 | 290 | ||
345 | void dce6_audio_fini(struct radeon_device *rdev) | 291 | void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable) |
346 | { | 292 | { |
347 | int i; | 293 | struct drm_device *dev = encoder->dev; |
294 | struct radeon_device *rdev = dev->dev_private; | ||
295 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
296 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
297 | uint32_t offset; | ||
348 | 298 | ||
349 | if (!rdev->audio.enabled) | 299 | if (!dig || !dig->afmt) |
350 | return; | 300 | return; |
351 | 301 | ||
352 | for (i = 0; i < rdev->audio.num_pins; i++) | 302 | offset = dig->afmt->offset; |
353 | dce6_audio_enable(rdev, &rdev->audio.pin[i], false); | 303 | |
304 | if (enable) { | ||
305 | if (dig->afmt->enabled) | ||
306 | return; | ||
307 | |||
308 | WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); | ||
309 | WREG32(EVERGREEN_DP_SEC_CNTL + offset, | ||
310 | EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ | ||
311 | EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ | ||
312 | EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */ | ||
313 | EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ | ||
314 | radeon_audio_enable(rdev, dig->afmt->pin, true); | ||
315 | } else { | ||
316 | if (!dig->afmt->enabled) | ||
317 | return; | ||
318 | |||
319 | WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0); | ||
320 | radeon_audio_enable(rdev, dig->afmt->pin, false); | ||
321 | } | ||
354 | 322 | ||
355 | rdev->audio.enabled = false; | 323 | dig->afmt->enabled = enable; |
356 | } | 324 | } |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 85995b4e3338..78600f534c80 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <drm/drmP.h> | 26 | #include <drm/drmP.h> |
27 | #include "radeon.h" | 27 | #include "radeon.h" |
28 | #include "radeon_asic.h" | 28 | #include "radeon_asic.h" |
29 | #include "radeon_audio.h" | ||
29 | #include <drm/radeon_drm.h> | 30 | #include <drm/radeon_drm.h> |
30 | #include "evergreend.h" | 31 | #include "evergreend.h" |
31 | #include "atom.h" | 32 | #include "atom.h" |
@@ -5286,7 +5287,7 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
5286 | return r; | 5287 | return r; |
5287 | } | 5288 | } |
5288 | 5289 | ||
5289 | r = r600_audio_init(rdev); | 5290 | r = radeon_audio_init(rdev); |
5290 | if (r) { | 5291 | if (r) { |
5291 | DRM_ERROR("radeon: audio init failed\n"); | 5292 | DRM_ERROR("radeon: audio init failed\n"); |
5292 | return r; | 5293 | return r; |
@@ -5332,7 +5333,7 @@ int evergreen_resume(struct radeon_device *rdev) | |||
5332 | int evergreen_suspend(struct radeon_device *rdev) | 5333 | int evergreen_suspend(struct radeon_device *rdev) |
5333 | { | 5334 | { |
5334 | radeon_pm_suspend(rdev); | 5335 | radeon_pm_suspend(rdev); |
5335 | r600_audio_fini(rdev); | 5336 | radeon_audio_fini(rdev); |
5336 | uvd_v1_0_fini(rdev); | 5337 | uvd_v1_0_fini(rdev); |
5337 | radeon_uvd_suspend(rdev); | 5338 | radeon_uvd_suspend(rdev); |
5338 | r700_cp_stop(rdev); | 5339 | r700_cp_stop(rdev); |
@@ -5482,7 +5483,7 @@ int evergreen_init(struct radeon_device *rdev) | |||
5482 | void evergreen_fini(struct radeon_device *rdev) | 5483 | void evergreen_fini(struct radeon_device *rdev) |
5483 | { | 5484 | { |
5484 | radeon_pm_fini(rdev); | 5485 | radeon_pm_fini(rdev); |
5485 | r600_audio_fini(rdev); | 5486 | radeon_audio_fini(rdev); |
5486 | r700_cp_fini(rdev); | 5487 | r700_cp_fini(rdev); |
5487 | r600_dma_fini(rdev); | 5488 | r600_dma_fini(rdev); |
5488 | r600_irq_fini(rdev); | 5489 | r600_irq_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 924b1b7ab455..c9e0fbbf76a3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -83,6 +83,7 @@ struct evergreen_cs_track { | |||
83 | u32 htile_offset; | 83 | u32 htile_offset; |
84 | u32 htile_surface; | 84 | u32 htile_surface; |
85 | struct radeon_bo *htile_bo; | 85 | struct radeon_bo *htile_bo; |
86 | unsigned long indirect_draw_buffer_size; | ||
86 | }; | 87 | }; |
87 | 88 | ||
88 | static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) | 89 | static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) |
@@ -1896,6 +1897,14 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
1896 | } | 1897 | } |
1897 | break; | 1898 | break; |
1898 | } | 1899 | } |
1900 | case PACKET3_INDEX_BUFFER_SIZE: | ||
1901 | { | ||
1902 | if (pkt->count != 0) { | ||
1903 | DRM_ERROR("bad INDEX_BUFFER_SIZE\n"); | ||
1904 | return -EINVAL; | ||
1905 | } | ||
1906 | break; | ||
1907 | } | ||
1899 | case PACKET3_DRAW_INDEX: | 1908 | case PACKET3_DRAW_INDEX: |
1900 | { | 1909 | { |
1901 | uint64_t offset; | 1910 | uint64_t offset; |
@@ -2006,6 +2015,67 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2006 | return r; | 2015 | return r; |
2007 | } | 2016 | } |
2008 | break; | 2017 | break; |
2018 | case PACKET3_SET_BASE: | ||
2019 | { | ||
2020 | /* | ||
2021 | DW 1 HEADER Header of the packet. Shader_Type in bit 1 of the Header will correspond to the shader type of the Load, see Type-3 Packet. | ||
2022 | 2 BASE_INDEX Bits [3:0] BASE_INDEX - Base Index specifies which base address is specified in the last two DWs. | ||
2023 | 0001: DX11 Draw_Index_Indirect Patch Table Base: Base address for Draw_Index_Indirect data. | ||
2024 | 3 ADDRESS_LO Bits [31:3] - Lower bits of QWORD-Aligned Address. Bits [2:0] - Reserved | ||
2025 | 4 ADDRESS_HI Bits [31:8] - Reserved. Bits [7:0] - Upper bits of Address [47:32] | ||
2026 | */ | ||
2027 | if (pkt->count != 2) { | ||
2028 | DRM_ERROR("bad SET_BASE\n"); | ||
2029 | return -EINVAL; | ||
2030 | } | ||
2031 | |||
2032 | /* currently only supporting setting indirect draw buffer base address */ | ||
2033 | if (idx_value != 1) { | ||
2034 | DRM_ERROR("bad SET_BASE\n"); | ||
2035 | return -EINVAL; | ||
2036 | } | ||
2037 | |||
2038 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); | ||
2039 | if (r) { | ||
2040 | DRM_ERROR("bad SET_BASE\n"); | ||
2041 | return -EINVAL; | ||
2042 | } | ||
2043 | |||
2044 | track->indirect_draw_buffer_size = radeon_bo_size(reloc->robj); | ||
2045 | |||
2046 | ib[idx+1] = reloc->gpu_offset; | ||
2047 | ib[idx+2] = upper_32_bits(reloc->gpu_offset) & 0xff; | ||
2048 | |||
2049 | break; | ||
2050 | } | ||
2051 | case PACKET3_DRAW_INDIRECT: | ||
2052 | case PACKET3_DRAW_INDEX_INDIRECT: | ||
2053 | { | ||
2054 | u64 size = pkt->opcode == PACKET3_DRAW_INDIRECT ? 16 : 20; | ||
2055 | |||
2056 | /* | ||
2057 | DW 1 HEADER | ||
2058 | 2 DATA_OFFSET Bits [31:0] + byte aligned offset where the required data structure starts. Bits 1:0 are zero | ||
2059 | 3 DRAW_INITIATOR Draw Initiator Register. Written to the VGT_DRAW_INITIATOR register for the assigned context | ||
2060 | */ | ||
2061 | if (pkt->count != 1) { | ||
2062 | DRM_ERROR("bad DRAW_INDIRECT\n"); | ||
2063 | return -EINVAL; | ||
2064 | } | ||
2065 | |||
2066 | if (idx_value + size > track->indirect_draw_buffer_size) { | ||
2067 | dev_warn(p->dev, "DRAW_INDIRECT buffer too small %u + %llu > %lu\n", | ||
2068 | idx_value, size, track->indirect_draw_buffer_size); | ||
2069 | return -EINVAL; | ||
2070 | } | ||
2071 | |||
2072 | r = evergreen_cs_track_check(p); | ||
2073 | if (r) { | ||
2074 | dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); | ||
2075 | return r; | ||
2076 | } | ||
2077 | break; | ||
2078 | } | ||
2009 | case PACKET3_DISPATCH_DIRECT: | 2079 | case PACKET3_DISPATCH_DIRECT: |
2010 | if (pkt->count != 3) { | 2080 | if (pkt->count != 3) { |
2011 | DRM_ERROR("bad DISPATCH_DIRECT\n"); | 2081 | DRM_ERROR("bad DISPATCH_DIRECT\n"); |
@@ -3243,7 +3313,13 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev, | |||
3243 | 3313 | ||
3244 | switch (pkt->opcode) { | 3314 | switch (pkt->opcode) { |
3245 | case PACKET3_NOP: | 3315 | case PACKET3_NOP: |
3316 | break; | ||
3246 | case PACKET3_SET_BASE: | 3317 | case PACKET3_SET_BASE: |
3318 | if (idx_value != 1) { | ||
3319 | DRM_ERROR("bad SET_BASE"); | ||
3320 | return -EINVAL; | ||
3321 | } | ||
3322 | break; | ||
3247 | case PACKET3_CLEAR_STATE: | 3323 | case PACKET3_CLEAR_STATE: |
3248 | case PACKET3_INDEX_BUFFER_SIZE: | 3324 | case PACKET3_INDEX_BUFFER_SIZE: |
3249 | case PACKET3_DISPATCH_DIRECT: | 3325 | case PACKET3_DISPATCH_DIRECT: |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 53abd9b17a50..1d9aebc79595 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -29,17 +29,12 @@ | |||
29 | #include <drm/radeon_drm.h> | 29 | #include <drm/radeon_drm.h> |
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "radeon_asic.h" | 31 | #include "radeon_asic.h" |
32 | #include "radeon_audio.h" | ||
32 | #include "evergreend.h" | 33 | #include "evergreend.h" |
33 | #include "atom.h" | 34 | #include "atom.h" |
34 | 35 | ||
35 | extern void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder); | ||
36 | extern void dce6_afmt_write_sad_regs(struct drm_encoder *encoder); | ||
37 | extern void dce6_afmt_select_pin(struct drm_encoder *encoder); | ||
38 | extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | ||
39 | struct drm_display_mode *mode); | ||
40 | |||
41 | /* enable the audio stream */ | 36 | /* enable the audio stream */ |
42 | static void dce4_audio_enable(struct radeon_device *rdev, | 37 | void dce4_audio_enable(struct radeon_device *rdev, |
43 | struct r600_audio_pin *pin, | 38 | struct r600_audio_pin *pin, |
44 | u8 enable_mask) | 39 | u8 enable_mask) |
45 | { | 40 | { |
@@ -69,48 +64,42 @@ static void dce4_audio_enable(struct radeon_device *rdev, | |||
69 | WREG32(AZ_HOT_PLUG_CONTROL, tmp); | 64 | WREG32(AZ_HOT_PLUG_CONTROL, tmp); |
70 | } | 65 | } |
71 | 66 | ||
72 | /* | 67 | void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset, |
73 | * update the N and CTS parameters for a given pixel clock rate | 68 | const struct radeon_hdmi_acr *acr) |
74 | */ | ||
75 | static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) | ||
76 | { | 69 | { |
77 | struct drm_device *dev = encoder->dev; | 70 | struct drm_device *dev = encoder->dev; |
78 | struct radeon_device *rdev = dev->dev_private; | 71 | struct radeon_device *rdev = dev->dev_private; |
79 | struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); | 72 | int bpc = 8; |
80 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
81 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
82 | uint32_t offset = dig->afmt->offset; | ||
83 | 73 | ||
84 | WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr.cts_32khz)); | 74 | if (encoder->crtc) { |
85 | WREG32(HDMI_ACR_32_1 + offset, acr.n_32khz); | 75 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
76 | bpc = radeon_crtc->bpc; | ||
77 | } | ||
86 | 78 | ||
87 | WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr.cts_44_1khz)); | 79 | if (bpc > 8) |
88 | WREG32(HDMI_ACR_44_1 + offset, acr.n_44_1khz); | 80 | WREG32(HDMI_ACR_PACKET_CONTROL + offset, |
81 | HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ | ||
82 | else | ||
83 | WREG32(HDMI_ACR_PACKET_CONTROL + offset, | ||
84 | HDMI_ACR_SOURCE | /* select SW CTS value */ | ||
85 | HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ | ||
86 | |||
87 | WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr->cts_32khz)); | ||
88 | WREG32(HDMI_ACR_32_1 + offset, acr->n_32khz); | ||
89 | 89 | ||
90 | WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr.cts_48khz)); | 90 | WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr->cts_44_1khz)); |
91 | WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); | 91 | WREG32(HDMI_ACR_44_1 + offset, acr->n_44_1khz); |
92 | |||
93 | WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr->cts_48khz)); | ||
94 | WREG32(HDMI_ACR_48_1 + offset, acr->n_48khz); | ||
92 | } | 95 | } |
93 | 96 | ||
94 | static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, | 97 | void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, |
95 | struct drm_display_mode *mode) | 98 | struct drm_connector *connector, struct drm_display_mode *mode) |
96 | { | 99 | { |
97 | struct radeon_device *rdev = encoder->dev->dev_private; | 100 | struct radeon_device *rdev = encoder->dev->dev_private; |
98 | struct drm_connector *connector; | ||
99 | struct radeon_connector *radeon_connector = NULL; | ||
100 | u32 tmp = 0; | 101 | u32 tmp = 0; |
101 | 102 | ||
102 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
103 | if (connector->encoder == encoder) { | ||
104 | radeon_connector = to_radeon_connector(connector); | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | if (!radeon_connector) { | ||
110 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { | 103 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { |
115 | if (connector->latency_present[1]) | 104 | if (connector->latency_present[1]) |
116 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | | 105 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | |
@@ -124,38 +113,17 @@ static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, | |||
124 | else | 113 | else |
125 | tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); | 114 | tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); |
126 | } | 115 | } |
127 | WREG32(AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp); | 116 | WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp); |
128 | } | 117 | } |
129 | 118 | ||
130 | static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | 119 | void dce4_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, |
120 | u8 *sadb, int sad_count) | ||
131 | { | 121 | { |
132 | struct radeon_device *rdev = encoder->dev->dev_private; | 122 | struct radeon_device *rdev = encoder->dev->dev_private; |
133 | struct drm_connector *connector; | ||
134 | struct radeon_connector *radeon_connector = NULL; | ||
135 | u32 tmp; | 123 | u32 tmp; |
136 | u8 *sadb = NULL; | ||
137 | int sad_count; | ||
138 | |||
139 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
140 | if (connector->encoder == encoder) { | ||
141 | radeon_connector = to_radeon_connector(connector); | ||
142 | break; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | if (!radeon_connector) { | ||
147 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
148 | return; | ||
149 | } | ||
150 | |||
151 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); | ||
152 | if (sad_count < 0) { | ||
153 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | ||
154 | sad_count = 0; | ||
155 | } | ||
156 | 124 | ||
157 | /* program the speaker allocation */ | 125 | /* program the speaker allocation */ |
158 | tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); | 126 | tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); |
159 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); | 127 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); |
160 | /* set HDMI mode */ | 128 | /* set HDMI mode */ |
161 | tmp |= HDMI_CONNECTION; | 129 | tmp |= HDMI_CONNECTION; |
@@ -163,19 +131,32 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
163 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | 131 | tmp |= SPEAKER_ALLOCATION(sadb[0]); |
164 | else | 132 | else |
165 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | 133 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ |
166 | WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); | 134 | WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); |
167 | |||
168 | kfree(sadb); | ||
169 | } | 135 | } |
170 | 136 | ||
171 | static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) | 137 | void dce4_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, |
138 | u8 *sadb, int sad_count) | ||
172 | { | 139 | { |
173 | struct radeon_device *rdev = encoder->dev->dev_private; | 140 | struct radeon_device *rdev = encoder->dev->dev_private; |
174 | struct drm_connector *connector; | 141 | u32 tmp; |
175 | struct radeon_connector *radeon_connector = NULL; | ||
176 | struct cea_sad *sads; | ||
177 | int i, sad_count; | ||
178 | 142 | ||
143 | /* program the speaker allocation */ | ||
144 | tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); | ||
145 | tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); | ||
146 | /* set DP mode */ | ||
147 | tmp |= DP_CONNECTION; | ||
148 | if (sad_count) | ||
149 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | ||
150 | else | ||
151 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | ||
152 | WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); | ||
153 | } | ||
154 | |||
155 | void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder, | ||
156 | struct cea_sad *sads, int sad_count) | ||
157 | { | ||
158 | int i; | ||
159 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
179 | static const u16 eld_reg_to_type[][2] = { | 160 | static const u16 eld_reg_to_type[][2] = { |
180 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, | 161 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, |
181 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, | 162 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, |
@@ -191,25 +172,6 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) | |||
191 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, | 172 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, |
192 | }; | 173 | }; |
193 | 174 | ||
194 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
195 | if (connector->encoder == encoder) { | ||
196 | radeon_connector = to_radeon_connector(connector); | ||
197 | break; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | if (!radeon_connector) { | ||
202 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); | ||
207 | if (sad_count <= 0) { | ||
208 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); | ||
209 | return; | ||
210 | } | ||
211 | BUG_ON(!sads); | ||
212 | |||
213 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { | 175 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
214 | u32 value = 0; | 176 | u32 value = 0; |
215 | u8 stereo_freqs = 0; | 177 | u8 stereo_freqs = 0; |
@@ -236,25 +198,17 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) | |||
236 | 198 | ||
237 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); | 199 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); |
238 | 200 | ||
239 | WREG32(eld_reg_to_type[i][0], value); | 201 | WREG32_ENDPOINT(0, eld_reg_to_type[i][0], value); |
240 | } | 202 | } |
241 | |||
242 | kfree(sads); | ||
243 | } | 203 | } |
244 | 204 | ||
245 | /* | 205 | /* |
246 | * build a HDMI Video Info Frame | 206 | * build a AVI Info Frame |
247 | */ | 207 | */ |
248 | static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder, | 208 | void evergreen_set_avi_packet(struct radeon_device *rdev, u32 offset, |
249 | void *buffer, size_t size) | 209 | unsigned char *buffer, size_t size) |
250 | { | 210 | { |
251 | struct drm_device *dev = encoder->dev; | ||
252 | struct radeon_device *rdev = dev->dev_private; | ||
253 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
254 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
255 | uint32_t offset = dig->afmt->offset; | ||
256 | uint8_t *frame = buffer + 3; | 211 | uint8_t *frame = buffer + 3; |
257 | uint8_t *header = buffer; | ||
258 | 212 | ||
259 | WREG32(AFMT_AVI_INFO0 + offset, | 213 | WREG32(AFMT_AVI_INFO0 + offset, |
260 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); | 214 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); |
@@ -263,104 +217,103 @@ static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder, | |||
263 | WREG32(AFMT_AVI_INFO2 + offset, | 217 | WREG32(AFMT_AVI_INFO2 + offset, |
264 | frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); | 218 | frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); |
265 | WREG32(AFMT_AVI_INFO3 + offset, | 219 | WREG32(AFMT_AVI_INFO3 + offset, |
266 | frame[0xC] | (frame[0xD] << 8) | (header[1] << 24)); | 220 | frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24)); |
221 | |||
222 | WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset, | ||
223 | HDMI_AVI_INFO_SEND | /* enable AVI info frames */ | ||
224 | HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */ | ||
225 | |||
226 | WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset, | ||
227 | HDMI_AVI_INFO_LINE(2), /* anything other than 0 */ | ||
228 | ~HDMI_AVI_INFO_LINE_MASK); | ||
267 | } | 229 | } |
268 | 230 | ||
269 | static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) | 231 | void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, |
232 | struct radeon_crtc *crtc, unsigned int clock) | ||
270 | { | 233 | { |
271 | struct drm_device *dev = encoder->dev; | 234 | unsigned int max_ratio = clock / 24000; |
272 | struct radeon_device *rdev = dev->dev_private; | ||
273 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
274 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
275 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
276 | u32 base_rate = 24000; | ||
277 | u32 max_ratio = clock / base_rate; | ||
278 | u32 dto_phase; | 235 | u32 dto_phase; |
279 | u32 dto_modulo = clock; | ||
280 | u32 wallclock_ratio; | 236 | u32 wallclock_ratio; |
281 | u32 dto_cntl; | 237 | u32 value; |
282 | 238 | ||
283 | if (!dig || !dig->afmt) | 239 | if (max_ratio >= 8) { |
284 | return; | 240 | dto_phase = 192 * 1000; |
285 | 241 | wallclock_ratio = 3; | |
286 | if (ASIC_IS_DCE6(rdev)) { | 242 | } else if (max_ratio >= 4) { |
287 | dto_phase = 24 * 1000; | 243 | dto_phase = 96 * 1000; |
244 | wallclock_ratio = 2; | ||
245 | } else if (max_ratio >= 2) { | ||
246 | dto_phase = 48 * 1000; | ||
247 | wallclock_ratio = 1; | ||
288 | } else { | 248 | } else { |
289 | if (max_ratio >= 8) { | 249 | dto_phase = 24 * 1000; |
290 | dto_phase = 192 * 1000; | 250 | wallclock_ratio = 0; |
291 | wallclock_ratio = 3; | ||
292 | } else if (max_ratio >= 4) { | ||
293 | dto_phase = 96 * 1000; | ||
294 | wallclock_ratio = 2; | ||
295 | } else if (max_ratio >= 2) { | ||
296 | dto_phase = 48 * 1000; | ||
297 | wallclock_ratio = 1; | ||
298 | } else { | ||
299 | dto_phase = 24 * 1000; | ||
300 | wallclock_ratio = 0; | ||
301 | } | ||
302 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
303 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
304 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
305 | } | 251 | } |
306 | 252 | ||
307 | /* XXX two dtos; generally use dto0 for hdmi */ | 253 | value = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; |
254 | value |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
255 | value &= ~DCCG_AUDIO_DTO1_USE_512FBR_DTO; | ||
256 | WREG32(DCCG_AUDIO_DTO0_CNTL, value); | ||
257 | |||
258 | /* Two dtos; generally use dto0 for HDMI */ | ||
259 | value = 0; | ||
260 | |||
261 | if (crtc) | ||
262 | value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); | ||
263 | |||
264 | WREG32(DCCG_AUDIO_DTO_SOURCE, value); | ||
265 | |||
308 | /* Express [24MHz / target pixel clock] as an exact rational | 266 | /* Express [24MHz / target pixel clock] as an exact rational |
309 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 267 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
310 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | 268 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
311 | */ | 269 | */ |
312 | WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); | ||
313 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | 270 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); |
314 | WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); | 271 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock); |
315 | } | 272 | } |
316 | 273 | ||
317 | 274 | void dce4_dp_audio_set_dto(struct radeon_device *rdev, | |
318 | /* | 275 | struct radeon_crtc *crtc, unsigned int clock) |
319 | * update the info frames with the data from the current display mode | ||
320 | */ | ||
321 | void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) | ||
322 | { | 276 | { |
323 | struct drm_device *dev = encoder->dev; | 277 | u32 value; |
324 | struct radeon_device *rdev = dev->dev_private; | ||
325 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
326 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
327 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
328 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; | ||
329 | struct hdmi_avi_infoframe frame; | ||
330 | uint32_t offset; | ||
331 | ssize_t err; | ||
332 | uint32_t val; | ||
333 | int bpc = 8; | ||
334 | 278 | ||
335 | if (!dig || !dig->afmt) | 279 | value = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; |
336 | return; | 280 | value |= DCCG_AUDIO_DTO1_USE_512FBR_DTO; |
281 | WREG32(DCCG_AUDIO_DTO1_CNTL, value); | ||
337 | 282 | ||
338 | /* Silent, r600_hdmi_enable will raise WARN for us */ | 283 | /* Two dtos; generally use dto1 for DP */ |
339 | if (!dig->afmt->enabled) | 284 | value = 0; |
340 | return; | 285 | value |= DCCG_AUDIO_DTO_SEL; |
341 | offset = dig->afmt->offset; | ||
342 | 286 | ||
343 | /* hdmi deep color mode general control packets setup, if bpc > 8 */ | 287 | if (crtc) |
344 | if (encoder->crtc) { | 288 | value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); |
345 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
346 | bpc = radeon_crtc->bpc; | ||
347 | } | ||
348 | 289 | ||
349 | /* disable audio prior to setting up hw */ | 290 | WREG32(DCCG_AUDIO_DTO_SOURCE, value); |
350 | if (ASIC_IS_DCE6(rdev)) { | 291 | |
351 | dig->afmt->pin = dce6_audio_get_pin(rdev); | 292 | /* Express [24MHz / target pixel clock] as an exact rational |
352 | dce6_audio_enable(rdev, dig->afmt->pin, 0); | 293 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
353 | } else { | 294 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
354 | dig->afmt->pin = r600_audio_get_pin(rdev); | 295 | */ |
355 | dce4_audio_enable(rdev, dig->afmt->pin, 0); | 296 | WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); |
356 | } | 297 | WREG32(DCCG_AUDIO_DTO1_MODULE, rdev->clock.max_pixel_clock * 10); |
298 | } | ||
357 | 299 | ||
358 | evergreen_audio_set_dto(encoder, mode->clock); | 300 | void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset) |
301 | { | ||
302 | struct drm_device *dev = encoder->dev; | ||
303 | struct radeon_device *rdev = dev->dev_private; | ||
359 | 304 | ||
360 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, | 305 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, |
361 | HDMI_NULL_SEND); /* send null packets when required */ | 306 | HDMI_NULL_SEND | /* send null packets when required */ |
307 | HDMI_GC_SEND | /* send general control packets */ | ||
308 | HDMI_GC_CONT); /* send general control packets every frame */ | ||
309 | } | ||
362 | 310 | ||
363 | WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000); | 311 | void dce4_hdmi_set_color_depth(struct drm_encoder *encoder, u32 offset, int bpc) |
312 | { | ||
313 | struct drm_device *dev = encoder->dev; | ||
314 | struct radeon_device *rdev = dev->dev_private; | ||
315 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
316 | uint32_t val; | ||
364 | 317 | ||
365 | val = RREG32(HDMI_CONTROL + offset); | 318 | val = RREG32(HDMI_CONTROL + offset); |
366 | val &= ~HDMI_DEEP_COLOR_ENABLE; | 319 | val &= ~HDMI_DEEP_COLOR_ENABLE; |
@@ -390,113 +343,59 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
390 | } | 343 | } |
391 | 344 | ||
392 | WREG32(HDMI_CONTROL + offset, val); | 345 | WREG32(HDMI_CONTROL + offset, val); |
346 | } | ||
393 | 347 | ||
394 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, | 348 | void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset) |
395 | HDMI_NULL_SEND | /* send null packets when required */ | 349 | { |
396 | HDMI_GC_SEND | /* send general control packets */ | 350 | struct drm_device *dev = encoder->dev; |
397 | HDMI_GC_CONT); /* send general control packets every frame */ | 351 | struct radeon_device *rdev = dev->dev_private; |
398 | 352 | ||
399 | WREG32(HDMI_INFOFRAME_CONTROL0 + offset, | 353 | WREG32(HDMI_INFOFRAME_CONTROL0 + offset, |
400 | HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ | 354 | HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ |
401 | HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */ | 355 | HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */ |
402 | 356 | ||
403 | WREG32(AFMT_INFOFRAME_CONTROL0 + offset, | 357 | WREG32(AFMT_INFOFRAME_CONTROL0 + offset, |
404 | AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ | 358 | AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ |
405 | 359 | ||
406 | WREG32(HDMI_INFOFRAME_CONTROL1 + offset, | 360 | WREG32(HDMI_INFOFRAME_CONTROL1 + offset, |
407 | HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */ | 361 | HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */ |
408 | |||
409 | WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */ | ||
410 | 362 | ||
411 | WREG32(HDMI_AUDIO_PACKET_CONTROL + offset, | 363 | WREG32(HDMI_AUDIO_PACKET_CONTROL + offset, |
412 | HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */ | 364 | HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */ |
413 | HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ | 365 | HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ |
414 | |||
415 | WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, | ||
416 | AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ | ||
417 | |||
418 | /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */ | ||
419 | |||
420 | if (bpc > 8) | ||
421 | WREG32(HDMI_ACR_PACKET_CONTROL + offset, | ||
422 | HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ | ||
423 | else | ||
424 | WREG32(HDMI_ACR_PACKET_CONTROL + offset, | ||
425 | HDMI_ACR_SOURCE | /* select SW CTS value */ | ||
426 | HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ | ||
427 | |||
428 | evergreen_hdmi_update_ACR(encoder, mode->clock); | ||
429 | 366 | ||
430 | WREG32(AFMT_60958_0 + offset, | 367 | WREG32(AFMT_60958_0 + offset, |
431 | AFMT_60958_CS_CHANNEL_NUMBER_L(1)); | 368 | AFMT_60958_CS_CHANNEL_NUMBER_L(1)); |
432 | 369 | ||
433 | WREG32(AFMT_60958_1 + offset, | 370 | WREG32(AFMT_60958_1 + offset, |
434 | AFMT_60958_CS_CHANNEL_NUMBER_R(2)); | 371 | AFMT_60958_CS_CHANNEL_NUMBER_R(2)); |
435 | 372 | ||
436 | WREG32(AFMT_60958_2 + offset, | 373 | WREG32(AFMT_60958_2 + offset, |
437 | AFMT_60958_CS_CHANNEL_NUMBER_2(3) | | 374 | AFMT_60958_CS_CHANNEL_NUMBER_2(3) | |
438 | AFMT_60958_CS_CHANNEL_NUMBER_3(4) | | 375 | AFMT_60958_CS_CHANNEL_NUMBER_3(4) | |
439 | AFMT_60958_CS_CHANNEL_NUMBER_4(5) | | 376 | AFMT_60958_CS_CHANNEL_NUMBER_4(5) | |
440 | AFMT_60958_CS_CHANNEL_NUMBER_5(6) | | 377 | AFMT_60958_CS_CHANNEL_NUMBER_5(6) | |
441 | AFMT_60958_CS_CHANNEL_NUMBER_6(7) | | 378 | AFMT_60958_CS_CHANNEL_NUMBER_6(7) | |
442 | AFMT_60958_CS_CHANNEL_NUMBER_7(8)); | 379 | AFMT_60958_CS_CHANNEL_NUMBER_7(8)); |
443 | |||
444 | if (ASIC_IS_DCE6(rdev)) { | ||
445 | dce6_afmt_write_speaker_allocation(encoder); | ||
446 | } else { | ||
447 | dce4_afmt_write_speaker_allocation(encoder); | ||
448 | } | ||
449 | 380 | ||
450 | WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset, | 381 | WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset, |
451 | AFMT_AUDIO_CHANNEL_ENABLE(0xff)); | 382 | AFMT_AUDIO_CHANNEL_ENABLE(0xff)); |
452 | |||
453 | /* fglrx sets 0x40 in 0x5f80 here */ | ||
454 | |||
455 | if (ASIC_IS_DCE6(rdev)) { | ||
456 | dce6_afmt_select_pin(encoder); | ||
457 | dce6_afmt_write_sad_regs(encoder); | ||
458 | dce6_afmt_write_latency_fields(encoder, mode); | ||
459 | } else { | ||
460 | evergreen_hdmi_write_sad_regs(encoder); | ||
461 | dce4_afmt_write_latency_fields(encoder, mode); | ||
462 | } | ||
463 | |||
464 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); | ||
465 | if (err < 0) { | ||
466 | DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); | ||
467 | return; | ||
468 | } | ||
469 | |||
470 | err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); | ||
471 | if (err < 0) { | ||
472 | DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); | ||
473 | return; | ||
474 | } | ||
475 | |||
476 | evergreen_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); | ||
477 | |||
478 | WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset, | ||
479 | HDMI_AVI_INFO_SEND | /* enable AVI info frames */ | ||
480 | HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */ | ||
481 | 383 | ||
482 | WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset, | 384 | /* allow 60958 channel status and send audio packets fields to be updated */ |
483 | HDMI_AVI_INFO_LINE(2), /* anything other than 0 */ | 385 | WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, |
484 | ~HDMI_AVI_INFO_LINE_MASK); | 386 | AFMT_AUDIO_SAMPLE_SEND | AFMT_RESET_FIFO_WHEN_AUDIO_DIS | AFMT_60958_CS_UPDATE); |
387 | } | ||
485 | 388 | ||
486 | WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + offset, | ||
487 | AFMT_AUDIO_SAMPLE_SEND); /* send audio packets */ | ||
488 | 389 | ||
489 | /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ | 390 | void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) |
490 | WREG32(AFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF); | 391 | { |
491 | WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); | 392 | struct drm_device *dev = encoder->dev; |
492 | WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001); | 393 | struct radeon_device *rdev = dev->dev_private; |
493 | WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); | ||
494 | 394 | ||
495 | /* enable audio after to setting up hw */ | 395 | if (mute) |
496 | if (ASIC_IS_DCE6(rdev)) | 396 | WREG32_OR(HDMI_GC + offset, HDMI_GC_AVMUTE); |
497 | dce6_audio_enable(rdev, dig->afmt->pin, 1); | ||
498 | else | 397 | else |
499 | dce4_audio_enable(rdev, dig->afmt->pin, 0xf); | 398 | WREG32_AND(HDMI_GC + offset, ~HDMI_GC_AVMUTE); |
500 | } | 399 | } |
501 | 400 | ||
502 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | 401 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) |
@@ -516,10 +415,7 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
516 | return; | 415 | return; |
517 | 416 | ||
518 | if (!enable && dig->afmt->pin) { | 417 | if (!enable && dig->afmt->pin) { |
519 | if (ASIC_IS_DCE6(rdev)) | 418 | radeon_audio_enable(rdev, dig->afmt->pin, 0); |
520 | dce6_audio_enable(rdev, dig->afmt->pin, 0); | ||
521 | else | ||
522 | dce4_audio_enable(rdev, dig->afmt->pin, 0); | ||
523 | dig->afmt->pin = NULL; | 419 | dig->afmt->pin = NULL; |
524 | } | 420 | } |
525 | 421 | ||
@@ -528,3 +424,57 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
528 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", | 424 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
529 | enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id); | 425 | enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id); |
530 | } | 426 | } |
427 | |||
428 | void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable) | ||
429 | { | ||
430 | struct drm_device *dev = encoder->dev; | ||
431 | struct radeon_device *rdev = dev->dev_private; | ||
432 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
433 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
434 | uint32_t offset; | ||
435 | |||
436 | if (!dig || !dig->afmt) | ||
437 | return; | ||
438 | |||
439 | offset = dig->afmt->offset; | ||
440 | |||
441 | if (enable) { | ||
442 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
443 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
444 | struct radeon_connector_atom_dig *dig_connector; | ||
445 | uint32_t val; | ||
446 | |||
447 | if (dig->afmt->enabled) | ||
448 | return; | ||
449 | |||
450 | WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); | ||
451 | |||
452 | if (radeon_connector->con_priv) { | ||
453 | dig_connector = radeon_connector->con_priv; | ||
454 | val = RREG32(EVERGREEN_DP_SEC_AUD_N + offset); | ||
455 | val &= ~EVERGREEN_DP_SEC_N_BASE_MULTIPLE(0xf); | ||
456 | |||
457 | if (dig_connector->dp_clock == 162000) | ||
458 | val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(3); | ||
459 | else | ||
460 | val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(5); | ||
461 | |||
462 | WREG32(EVERGREEN_DP_SEC_AUD_N + offset, val); | ||
463 | } | ||
464 | |||
465 | WREG32(EVERGREEN_DP_SEC_CNTL + offset, | ||
466 | EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ | ||
467 | EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ | ||
468 | EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */ | ||
469 | EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ | ||
470 | radeon_audio_enable(rdev, dig->afmt->pin, 0xf); | ||
471 | } else { | ||
472 | if (!dig->afmt->enabled) | ||
473 | return; | ||
474 | |||
475 | WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0); | ||
476 | radeon_audio_enable(rdev, dig->afmt->pin, 0); | ||
477 | } | ||
478 | |||
479 | dig->afmt->enabled = enable; | ||
480 | } | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 23bff590fb6e..aa939dfed3a3 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
@@ -251,4 +251,19 @@ | |||
251 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ | 251 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ |
252 | #define EVERGREEN_HDMI_BASE 0x7030 | 252 | #define EVERGREEN_HDMI_BASE 0x7030 |
253 | 253 | ||
254 | /* Display Port block */ | ||
255 | #define EVERGREEN_DP_SEC_CNTL 0x7280 | ||
256 | # define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) | ||
257 | # define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) | ||
258 | # define EVERGREEN_DP_SEC_ATP_ENABLE (1 << 8) | ||
259 | # define EVERGREEN_DP_SEC_AIP_ENABLE (1 << 12) | ||
260 | # define EVERGREEN_DP_SEC_GSP_ENABLE (1 << 20) | ||
261 | # define EVERGREEN_DP_SEC_AVI_ENABLE (1 << 24) | ||
262 | # define EVERGREEN_DP_SEC_MPG_ENABLE (1 << 28) | ||
263 | #define EVERGREEN_DP_SEC_TIMESTAMP 0x72a4 | ||
264 | # define EVERGREEN_DP_SEC_TIMESTAMP_MODE(x) (((x) & 0x3) << 0) | ||
265 | #define EVERGREEN_DP_SEC_AUD_N 0x7294 | ||
266 | # define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) | ||
267 | # define EVERGREEN_DP_SEC_SS_EN (1 << 28) | ||
268 | |||
254 | #endif | 269 | #endif |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index b066d6711b8d..ee83d2a88750 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -509,6 +509,7 @@ | |||
509 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 | 509 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 |
510 | #define DCCG_AUDIO_DTO1_LOAD 0x05c8 | 510 | #define DCCG_AUDIO_DTO1_LOAD 0x05c8 |
511 | #define DCCG_AUDIO_DTO1_CNTL 0x05cc | 511 | #define DCCG_AUDIO_DTO1_CNTL 0x05cc |
512 | # define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3) | ||
512 | 513 | ||
513 | /* DCE 4.0 AFMT */ | 514 | /* DCE 4.0 AFMT */ |
514 | #define HDMI_CONTROL 0x7030 | 515 | #define HDMI_CONTROL 0x7030 |
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index e3e9c10cfba9..c5eb286517a8 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -1925,6 +1925,7 @@ void kv_dpm_setup_asic(struct radeon_device *rdev) | |||
1925 | kv_init_sclk_t(rdev); | 1925 | kv_init_sclk_t(rdev); |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | #if 0 | ||
1928 | void kv_dpm_reset_asic(struct radeon_device *rdev) | 1929 | void kv_dpm_reset_asic(struct radeon_device *rdev) |
1929 | { | 1930 | { |
1930 | struct kv_power_info *pi = kv_get_pi(rdev); | 1931 | struct kv_power_info *pi = kv_get_pi(rdev); |
@@ -1945,6 +1946,7 @@ void kv_dpm_reset_asic(struct radeon_device *rdev) | |||
1945 | kv_set_enabled_level(rdev, pi->graphics_boot_level); | 1946 | kv_set_enabled_level(rdev, pi->graphics_boot_level); |
1946 | } | 1947 | } |
1947 | } | 1948 | } |
1949 | #endif | ||
1948 | 1950 | ||
1949 | //XXX use sumo_dpm_display_configuration_changed | 1951 | //XXX use sumo_dpm_display_configuration_changed |
1950 | 1952 | ||
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index aea48c89b241..24242a7f0ac3 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <drm/drmP.h> | 27 | #include <drm/drmP.h> |
28 | #include "radeon.h" | 28 | #include "radeon.h" |
29 | #include "radeon_asic.h" | 29 | #include "radeon_asic.h" |
30 | #include "radeon_audio.h" | ||
30 | #include <drm/radeon_drm.h> | 31 | #include <drm/radeon_drm.h> |
31 | #include "nid.h" | 32 | #include "nid.h" |
32 | #include "atom.h" | 33 | #include "atom.h" |
@@ -2097,15 +2098,9 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2097 | return r; | 2098 | return r; |
2098 | } | 2099 | } |
2099 | 2100 | ||
2100 | if (ASIC_IS_DCE6(rdev)) { | 2101 | r = radeon_audio_init(rdev); |
2101 | r = dce6_audio_init(rdev); | 2102 | if (r) |
2102 | if (r) | 2103 | return r; |
2103 | return r; | ||
2104 | } else { | ||
2105 | r = r600_audio_init(rdev); | ||
2106 | if (r) | ||
2107 | return r; | ||
2108 | } | ||
2109 | 2104 | ||
2110 | return 0; | 2105 | return 0; |
2111 | } | 2106 | } |
@@ -2140,10 +2135,7 @@ int cayman_resume(struct radeon_device *rdev) | |||
2140 | int cayman_suspend(struct radeon_device *rdev) | 2135 | int cayman_suspend(struct radeon_device *rdev) |
2141 | { | 2136 | { |
2142 | radeon_pm_suspend(rdev); | 2137 | radeon_pm_suspend(rdev); |
2143 | if (ASIC_IS_DCE6(rdev)) | 2138 | radeon_audio_fini(rdev); |
2144 | dce6_audio_fini(rdev); | ||
2145 | else | ||
2146 | r600_audio_fini(rdev); | ||
2147 | radeon_vm_manager_fini(rdev); | 2139 | radeon_vm_manager_fini(rdev); |
2148 | cayman_cp_enable(rdev, false); | 2140 | cayman_cp_enable(rdev, false); |
2149 | cayman_dma_stop(rdev); | 2141 | cayman_dma_stop(rdev); |
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 6d2f16cf2c1c..7bc9f8d9804a 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c | |||
@@ -3862,11 +3862,13 @@ void ni_dpm_post_set_power_state(struct radeon_device *rdev) | |||
3862 | ni_update_current_ps(rdev, new_ps); | 3862 | ni_update_current_ps(rdev, new_ps); |
3863 | } | 3863 | } |
3864 | 3864 | ||
3865 | #if 0 | ||
3865 | void ni_dpm_reset_asic(struct radeon_device *rdev) | 3866 | void ni_dpm_reset_asic(struct radeon_device *rdev) |
3866 | { | 3867 | { |
3867 | ni_restrict_performance_levels_before_switch(rdev); | 3868 | ni_restrict_performance_levels_before_switch(rdev); |
3868 | rv770_set_boot_state(rdev); | 3869 | rv770_set_boot_state(rdev); |
3869 | } | 3870 | } |
3871 | #endif | ||
3870 | 3872 | ||
3871 | union power_info { | 3873 | union power_info { |
3872 | struct _ATOM_POWERPLAY_INFO info; | 3874 | struct _ATOM_POWERPLAY_INFO info; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index ef5d6066fa5b..07a71a2488c9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <drm/radeon_drm.h> | 33 | #include <drm/radeon_drm.h> |
34 | #include "radeon.h" | 34 | #include "radeon.h" |
35 | #include "radeon_asic.h" | 35 | #include "radeon_asic.h" |
36 | #include "radeon_audio.h" | ||
36 | #include "radeon_mode.h" | 37 | #include "radeon_mode.h" |
37 | #include "r600d.h" | 38 | #include "r600d.h" |
38 | #include "atom.h" | 39 | #include "atom.h" |
@@ -3054,7 +3055,7 @@ static int r600_startup(struct radeon_device *rdev) | |||
3054 | return r; | 3055 | return r; |
3055 | } | 3056 | } |
3056 | 3057 | ||
3057 | r = r600_audio_init(rdev); | 3058 | r = radeon_audio_init(rdev); |
3058 | if (r) { | 3059 | if (r) { |
3059 | DRM_ERROR("radeon: audio init failed\n"); | 3060 | DRM_ERROR("radeon: audio init failed\n"); |
3060 | return r; | 3061 | return r; |
@@ -3105,7 +3106,7 @@ int r600_resume(struct radeon_device *rdev) | |||
3105 | int r600_suspend(struct radeon_device *rdev) | 3106 | int r600_suspend(struct radeon_device *rdev) |
3106 | { | 3107 | { |
3107 | radeon_pm_suspend(rdev); | 3108 | radeon_pm_suspend(rdev); |
3108 | r600_audio_fini(rdev); | 3109 | radeon_audio_fini(rdev); |
3109 | r600_cp_stop(rdev); | 3110 | r600_cp_stop(rdev); |
3110 | if (rdev->has_uvd) { | 3111 | if (rdev->has_uvd) { |
3111 | uvd_v1_0_fini(rdev); | 3112 | uvd_v1_0_fini(rdev); |
@@ -3224,7 +3225,7 @@ int r600_init(struct radeon_device *rdev) | |||
3224 | void r600_fini(struct radeon_device *rdev) | 3225 | void r600_fini(struct radeon_device *rdev) |
3225 | { | 3226 | { |
3226 | radeon_pm_fini(rdev); | 3227 | radeon_pm_fini(rdev); |
3227 | r600_audio_fini(rdev); | 3228 | radeon_audio_fini(rdev); |
3228 | r600_cp_fini(rdev); | 3229 | r600_cp_fini(rdev); |
3229 | r600_irq_fini(rdev); | 3230 | r600_irq_fini(rdev); |
3230 | if (rdev->has_uvd) { | 3231 | if (rdev->has_uvd) { |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index b90dc0eb08e6..62c91ed669ce 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <drm/radeon_drm.h> | 29 | #include <drm/radeon_drm.h> |
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "radeon_asic.h" | 31 | #include "radeon_asic.h" |
32 | #include "radeon_audio.h" | ||
32 | #include "r600d.h" | 33 | #include "r600d.h" |
33 | #include "atom.h" | 34 | #include "atom.h" |
34 | 35 | ||
@@ -55,30 +56,6 @@ enum r600_hdmi_iec_status_bits { | |||
55 | AUDIO_STATUS_LEVEL = 0x80 | 56 | AUDIO_STATUS_LEVEL = 0x80 |
56 | }; | 57 | }; |
57 | 58 | ||
58 | static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { | ||
59 | /* 32kHz 44.1kHz 48kHz */ | ||
60 | /* Clock N CTS N CTS N CTS */ | ||
61 | { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ | ||
62 | { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ | ||
63 | { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ | ||
64 | { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ | ||
65 | { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ | ||
66 | { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ | ||
67 | { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ | ||
68 | { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ | ||
69 | { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ | ||
70 | { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ | ||
71 | }; | ||
72 | |||
73 | |||
74 | /* | ||
75 | * check if the chipset is supported | ||
76 | */ | ||
77 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | ||
78 | { | ||
79 | return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); | ||
80 | } | ||
81 | |||
82 | static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) | 59 | static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) |
83 | { | 60 | { |
84 | struct r600_audio_pin status; | 61 | struct r600_audio_pin status; |
@@ -191,155 +168,56 @@ void r600_audio_enable(struct radeon_device *rdev, | |||
191 | WREG32(AZ_HOT_PLUG_CONTROL, tmp); | 168 | WREG32(AZ_HOT_PLUG_CONTROL, tmp); |
192 | } | 169 | } |
193 | 170 | ||
194 | /* | ||
195 | * initialize the audio vars | ||
196 | */ | ||
197 | int r600_audio_init(struct radeon_device *rdev) | ||
198 | { | ||
199 | if (!radeon_audio || !r600_audio_chipset_supported(rdev)) | ||
200 | return 0; | ||
201 | |||
202 | rdev->audio.enabled = true; | ||
203 | |||
204 | rdev->audio.num_pins = 1; | ||
205 | rdev->audio.pin[0].channels = -1; | ||
206 | rdev->audio.pin[0].rate = -1; | ||
207 | rdev->audio.pin[0].bits_per_sample = -1; | ||
208 | rdev->audio.pin[0].status_bits = 0; | ||
209 | rdev->audio.pin[0].category_code = 0; | ||
210 | rdev->audio.pin[0].id = 0; | ||
211 | /* disable audio. it will be set up later */ | ||
212 | r600_audio_enable(rdev, &rdev->audio.pin[0], 0); | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * release the audio timer | ||
219 | * TODO: How to do this correctly on SMP systems? | ||
220 | */ | ||
221 | void r600_audio_fini(struct radeon_device *rdev) | ||
222 | { | ||
223 | if (!rdev->audio.enabled) | ||
224 | return; | ||
225 | |||
226 | r600_audio_enable(rdev, &rdev->audio.pin[0], 0); | ||
227 | |||
228 | rdev->audio.enabled = false; | ||
229 | } | ||
230 | |||
231 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev) | 171 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev) |
232 | { | 172 | { |
233 | /* only one pin on 6xx-NI */ | 173 | /* only one pin on 6xx-NI */ |
234 | return &rdev->audio.pin[0]; | 174 | return &rdev->audio.pin[0]; |
235 | } | 175 | } |
236 | 176 | ||
237 | /* | 177 | void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset, |
238 | * calculate CTS and N values if they are not found in the table | 178 | const struct radeon_hdmi_acr *acr) |
239 | */ | ||
240 | static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) | ||
241 | { | ||
242 | int n, cts; | ||
243 | unsigned long div, mul; | ||
244 | |||
245 | /* Safe, but overly large values */ | ||
246 | n = 128 * freq; | ||
247 | cts = clock * 1000; | ||
248 | |||
249 | /* Smallest valid fraction */ | ||
250 | div = gcd(n, cts); | ||
251 | |||
252 | n /= div; | ||
253 | cts /= div; | ||
254 | |||
255 | /* | ||
256 | * The optimal N is 128*freq/1000. Calculate the closest larger | ||
257 | * value that doesn't truncate any bits. | ||
258 | */ | ||
259 | mul = ((128*freq/1000) + (n-1))/n; | ||
260 | |||
261 | n *= mul; | ||
262 | cts *= mul; | ||
263 | |||
264 | /* Check that we are in spec (not always possible) */ | ||
265 | if (n < (128*freq/1500)) | ||
266 | printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n"); | ||
267 | if (n > (128*freq/300)) | ||
268 | printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n"); | ||
269 | |||
270 | *N = n; | ||
271 | *CTS = cts; | ||
272 | |||
273 | DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", | ||
274 | *N, *CTS, freq); | ||
275 | } | ||
276 | |||
277 | struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) | ||
278 | { | ||
279 | struct radeon_hdmi_acr res; | ||
280 | u8 i; | ||
281 | |||
282 | /* Precalculated values for common clocks */ | ||
283 | for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) { | ||
284 | if (r600_hdmi_predefined_acr[i].clock == clock) | ||
285 | return r600_hdmi_predefined_acr[i]; | ||
286 | } | ||
287 | |||
288 | /* And odd clocks get manually calculated */ | ||
289 | r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); | ||
290 | r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); | ||
291 | r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); | ||
292 | |||
293 | return res; | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * update the N and CTS parameters for a given pixel clock rate | ||
298 | */ | ||
299 | void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) | ||
300 | { | 179 | { |
301 | struct drm_device *dev = encoder->dev; | 180 | struct drm_device *dev = encoder->dev; |
302 | struct radeon_device *rdev = dev->dev_private; | 181 | struct radeon_device *rdev = dev->dev_private; |
303 | struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); | 182 | |
304 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 183 | /* DCE 3.0 uses register that's normally for CRC_CONTROL */ |
305 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 184 | uint32_t acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL : |
306 | uint32_t offset = dig->afmt->offset; | 185 | HDMI0_ACR_PACKET_CONTROL; |
186 | WREG32_P(acr_ctl + offset, | ||
187 | HDMI0_ACR_SOURCE | /* select SW CTS value */ | ||
188 | HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */ | ||
189 | ~(HDMI0_ACR_SOURCE | | ||
190 | HDMI0_ACR_AUTO_SEND)); | ||
307 | 191 | ||
308 | WREG32_P(HDMI0_ACR_32_0 + offset, | 192 | WREG32_P(HDMI0_ACR_32_0 + offset, |
309 | HDMI0_ACR_CTS_32(acr.cts_32khz), | 193 | HDMI0_ACR_CTS_32(acr->cts_32khz), |
310 | ~HDMI0_ACR_CTS_32_MASK); | 194 | ~HDMI0_ACR_CTS_32_MASK); |
311 | WREG32_P(HDMI0_ACR_32_1 + offset, | 195 | WREG32_P(HDMI0_ACR_32_1 + offset, |
312 | HDMI0_ACR_N_32(acr.n_32khz), | 196 | HDMI0_ACR_N_32(acr->n_32khz), |
313 | ~HDMI0_ACR_N_32_MASK); | 197 | ~HDMI0_ACR_N_32_MASK); |
314 | 198 | ||
315 | WREG32_P(HDMI0_ACR_44_0 + offset, | 199 | WREG32_P(HDMI0_ACR_44_0 + offset, |
316 | HDMI0_ACR_CTS_44(acr.cts_44_1khz), | 200 | HDMI0_ACR_CTS_44(acr->cts_44_1khz), |
317 | ~HDMI0_ACR_CTS_44_MASK); | 201 | ~HDMI0_ACR_CTS_44_MASK); |
318 | WREG32_P(HDMI0_ACR_44_1 + offset, | 202 | WREG32_P(HDMI0_ACR_44_1 + offset, |
319 | HDMI0_ACR_N_44(acr.n_44_1khz), | 203 | HDMI0_ACR_N_44(acr->n_44_1khz), |
320 | ~HDMI0_ACR_N_44_MASK); | 204 | ~HDMI0_ACR_N_44_MASK); |
321 | 205 | ||
322 | WREG32_P(HDMI0_ACR_48_0 + offset, | 206 | WREG32_P(HDMI0_ACR_48_0 + offset, |
323 | HDMI0_ACR_CTS_48(acr.cts_48khz), | 207 | HDMI0_ACR_CTS_48(acr->cts_48khz), |
324 | ~HDMI0_ACR_CTS_48_MASK); | 208 | ~HDMI0_ACR_CTS_48_MASK); |
325 | WREG32_P(HDMI0_ACR_48_1 + offset, | 209 | WREG32_P(HDMI0_ACR_48_1 + offset, |
326 | HDMI0_ACR_N_48(acr.n_48khz), | 210 | HDMI0_ACR_N_48(acr->n_48khz), |
327 | ~HDMI0_ACR_N_48_MASK); | 211 | ~HDMI0_ACR_N_48_MASK); |
328 | } | 212 | } |
329 | 213 | ||
330 | /* | 214 | /* |
331 | * build a HDMI Video Info Frame | 215 | * build a HDMI Video Info Frame |
332 | */ | 216 | */ |
333 | void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, | 217 | void r600_set_avi_packet(struct radeon_device *rdev, u32 offset, |
334 | size_t size) | 218 | unsigned char *buffer, size_t size) |
335 | { | 219 | { |
336 | struct drm_device *dev = encoder->dev; | ||
337 | struct radeon_device *rdev = dev->dev_private; | ||
338 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
339 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
340 | uint32_t offset = dig->afmt->offset; | ||
341 | uint8_t *frame = buffer + 3; | 220 | uint8_t *frame = buffer + 3; |
342 | uint8_t *header = buffer; | ||
343 | 221 | ||
344 | WREG32(HDMI0_AVI_INFO0 + offset, | 222 | WREG32(HDMI0_AVI_INFO0 + offset, |
345 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); | 223 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); |
@@ -348,7 +226,14 @@ void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, | |||
348 | WREG32(HDMI0_AVI_INFO2 + offset, | 226 | WREG32(HDMI0_AVI_INFO2 + offset, |
349 | frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); | 227 | frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); |
350 | WREG32(HDMI0_AVI_INFO3 + offset, | 228 | WREG32(HDMI0_AVI_INFO3 + offset, |
351 | frame[0xC] | (frame[0xD] << 8) | (header[1] << 24)); | 229 | frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24)); |
230 | |||
231 | WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, | ||
232 | HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ | ||
233 | HDMI0_AVI_INFO_CONT); /* send AVI info frames every frame/field */ | ||
234 | |||
235 | WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, | ||
236 | HDMI0_AVI_INFO_LINE(2)); /* anything other than 0 */ | ||
352 | } | 237 | } |
353 | 238 | ||
354 | /* | 239 | /* |
@@ -425,188 +310,94 @@ void r600_hdmi_audio_workaround(struct drm_encoder *encoder) | |||
425 | value, ~HDMI0_AUDIO_TEST_EN); | 310 | value, ~HDMI0_AUDIO_TEST_EN); |
426 | } | 311 | } |
427 | 312 | ||
428 | void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | 313 | void r600_hdmi_audio_set_dto(struct radeon_device *rdev, |
314 | struct radeon_crtc *crtc, unsigned int clock) | ||
429 | { | 315 | { |
430 | struct drm_device *dev = encoder->dev; | 316 | struct radeon_encoder *radeon_encoder; |
431 | struct radeon_device *rdev = dev->dev_private; | 317 | struct radeon_encoder_atom_dig *dig; |
432 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
433 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
434 | u32 base_rate = 24000; | ||
435 | u32 max_ratio = clock / base_rate; | ||
436 | u32 dto_phase; | ||
437 | u32 dto_modulo = clock; | ||
438 | u32 wallclock_ratio; | ||
439 | u32 dto_cntl; | ||
440 | 318 | ||
441 | if (!dig || !dig->afmt) | 319 | if (!crtc) |
442 | return; | 320 | return; |
443 | 321 | ||
444 | if (max_ratio >= 8) { | 322 | radeon_encoder = to_radeon_encoder(crtc->encoder); |
445 | dto_phase = 192 * 1000; | 323 | dig = radeon_encoder->enc_priv; |
446 | wallclock_ratio = 3; | ||
447 | } else if (max_ratio >= 4) { | ||
448 | dto_phase = 96 * 1000; | ||
449 | wallclock_ratio = 2; | ||
450 | } else if (max_ratio >= 2) { | ||
451 | dto_phase = 48 * 1000; | ||
452 | wallclock_ratio = 1; | ||
453 | } else { | ||
454 | dto_phase = 24 * 1000; | ||
455 | wallclock_ratio = 0; | ||
456 | } | ||
457 | 324 | ||
458 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. | 325 | if (!dig) |
459 | * doesn't matter which one you use. Just use the first one. | 326 | return; |
460 | */ | 327 | |
461 | /* XXX two dtos; generally use dto0 for hdmi */ | 328 | if (dig->dig_encoder == 0) { |
462 | /* Express [24MHz / target pixel clock] as an exact rational | 329 | WREG32(DCCG_AUDIO_DTO0_PHASE, 24000 * 100); |
463 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 330 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); |
464 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | 331 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ |
465 | */ | ||
466 | if (ASIC_IS_DCE32(rdev)) { | ||
467 | if (dig->dig_encoder == 0) { | ||
468 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
469 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
470 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
471 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | ||
472 | WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); | ||
473 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
474 | } else { | ||
475 | dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
476 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
477 | WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); | ||
478 | WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); | ||
479 | WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo); | ||
480 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ | ||
481 | } | ||
482 | } else { | 332 | } else { |
483 | /* according to the reg specs, this should DCE3.2 only, but in | 333 | WREG32(DCCG_AUDIO_DTO1_PHASE, 24000 * 100); |
484 | * practice it seems to cover DCE2.0/3.0/3.1 as well. | 334 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); |
485 | */ | 335 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ |
486 | if (dig->dig_encoder == 0) { | ||
487 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); | ||
488 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); | ||
489 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
490 | } else { | ||
491 | WREG32(DCCG_AUDIO_DTO1_PHASE, base_rate * 100); | ||
492 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); | ||
493 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ | ||
494 | } | ||
495 | } | 336 | } |
496 | } | 337 | } |
497 | 338 | ||
498 | /* | 339 | void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset) |
499 | * update the info frames with the data from the current display mode | ||
500 | */ | ||
501 | void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) | ||
502 | { | 340 | { |
503 | struct drm_device *dev = encoder->dev; | 341 | struct drm_device *dev = encoder->dev; |
504 | struct radeon_device *rdev = dev->dev_private; | 342 | struct radeon_device *rdev = dev->dev_private; |
505 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
506 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
507 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; | ||
508 | struct hdmi_avi_infoframe frame; | ||
509 | uint32_t offset; | ||
510 | uint32_t acr_ctl; | ||
511 | ssize_t err; | ||
512 | |||
513 | if (!dig || !dig->afmt) | ||
514 | return; | ||
515 | |||
516 | /* Silent, r600_hdmi_enable will raise WARN for us */ | ||
517 | if (!dig->afmt->enabled) | ||
518 | return; | ||
519 | offset = dig->afmt->offset; | ||
520 | 343 | ||
521 | /* disable audio prior to setting up hw */ | 344 | WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset, |
522 | dig->afmt->pin = r600_audio_get_pin(rdev); | 345 | HDMI0_NULL_SEND | /* send null packets when required */ |
523 | r600_audio_enable(rdev, dig->afmt->pin, 0xf); | 346 | HDMI0_GC_SEND | /* send general control packets */ |
347 | HDMI0_GC_CONT); /* send general control packets every frame */ | ||
348 | } | ||
524 | 349 | ||
525 | r600_audio_set_dto(encoder, mode->clock); | 350 | void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset) |
351 | { | ||
352 | struct drm_device *dev = encoder->dev; | ||
353 | struct radeon_device *rdev = dev->dev_private; | ||
526 | 354 | ||
527 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, | 355 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, |
528 | HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ | 356 | HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ |
529 | HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ | 357 | HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ |
530 | HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ | 358 | HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ |
531 | HDMI0_60958_CS_UPDATE, /* allow 60958 channel status fields to be updated */ | 359 | HDMI0_60958_CS_UPDATE, /* allow 60958 channel status fields to be updated */ |
532 | ~(HDMI0_AUDIO_SAMPLE_SEND | | 360 | ~(HDMI0_AUDIO_SAMPLE_SEND | |
533 | HDMI0_AUDIO_DELAY_EN_MASK | | 361 | HDMI0_AUDIO_DELAY_EN_MASK | |
534 | HDMI0_AUDIO_PACKETS_PER_LINE_MASK | | 362 | HDMI0_AUDIO_PACKETS_PER_LINE_MASK | |
535 | HDMI0_60958_CS_UPDATE)); | 363 | HDMI0_60958_CS_UPDATE)); |
536 | |||
537 | /* DCE 3.0 uses register that's normally for CRC_CONTROL */ | ||
538 | acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL : | ||
539 | HDMI0_ACR_PACKET_CONTROL; | ||
540 | WREG32_P(acr_ctl + offset, | ||
541 | HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */ | ||
542 | HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */ | ||
543 | ~(HDMI0_ACR_SOURCE | | ||
544 | HDMI0_ACR_AUTO_SEND)); | ||
545 | |||
546 | WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset, | ||
547 | HDMI0_NULL_SEND | /* send null packets when required */ | ||
548 | HDMI0_GC_SEND | /* send general control packets */ | ||
549 | HDMI0_GC_CONT); /* send general control packets every frame */ | ||
550 | 364 | ||
551 | WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, | 365 | WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, |
552 | HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ | 366 | HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ |
553 | HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */ | 367 | HDMI0_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ |
554 | HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ | ||
555 | HDMI0_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ | ||
556 | 368 | ||
557 | WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset, | 369 | WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset, |
558 | HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */ | 370 | HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */ |
559 | HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */ | 371 | ~HDMI0_AUDIO_INFO_LINE_MASK); |
560 | ~(HDMI0_AVI_INFO_LINE_MASK | | ||
561 | HDMI0_AUDIO_INFO_LINE_MASK)); | ||
562 | |||
563 | WREG32_AND(HDMI0_GC + offset, | ||
564 | ~HDMI0_GC_AVMUTE); /* unset HDMI0_GC_AVMUTE */ | ||
565 | |||
566 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); | ||
567 | if (err < 0) { | ||
568 | DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); | ||
569 | return; | ||
570 | } | ||
571 | |||
572 | err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); | ||
573 | if (err < 0) { | ||
574 | DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); | ||
575 | return; | ||
576 | } | ||
577 | |||
578 | r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); | ||
579 | |||
580 | /* fglrx duplicates INFOFRAME_CONTROL0 & INFOFRAME_CONTROL1 ops here */ | ||
581 | 372 | ||
582 | WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset, | 373 | WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset, |
583 | ~(HDMI0_GENERIC0_SEND | | 374 | ~(HDMI0_GENERIC0_SEND | |
584 | HDMI0_GENERIC0_CONT | | 375 | HDMI0_GENERIC0_CONT | |
585 | HDMI0_GENERIC0_UPDATE | | 376 | HDMI0_GENERIC0_UPDATE | |
586 | HDMI0_GENERIC1_SEND | | 377 | HDMI0_GENERIC1_SEND | |
587 | HDMI0_GENERIC1_CONT | | 378 | HDMI0_GENERIC1_CONT | |
588 | HDMI0_GENERIC0_LINE_MASK | | 379 | HDMI0_GENERIC0_LINE_MASK | |
589 | HDMI0_GENERIC1_LINE_MASK)); | 380 | HDMI0_GENERIC1_LINE_MASK)); |
590 | |||
591 | r600_hdmi_update_ACR(encoder, mode->clock); | ||
592 | 381 | ||
593 | WREG32_P(HDMI0_60958_0 + offset, | 382 | WREG32_P(HDMI0_60958_0 + offset, |
594 | HDMI0_60958_CS_CHANNEL_NUMBER_L(1), | 383 | HDMI0_60958_CS_CHANNEL_NUMBER_L(1), |
595 | ~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK | | 384 | ~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK | |
596 | HDMI0_60958_CS_CLOCK_ACCURACY_MASK)); | 385 | HDMI0_60958_CS_CLOCK_ACCURACY_MASK)); |
597 | 386 | ||
598 | WREG32_P(HDMI0_60958_1 + offset, | 387 | WREG32_P(HDMI0_60958_1 + offset, |
599 | HDMI0_60958_CS_CHANNEL_NUMBER_R(2), | 388 | HDMI0_60958_CS_CHANNEL_NUMBER_R(2), |
600 | ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK); | 389 | ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK); |
390 | } | ||
601 | 391 | ||
602 | /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ | 392 | void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute) |
603 | WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); | 393 | { |
604 | WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); | 394 | struct drm_device *dev = encoder->dev; |
605 | WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001); | 395 | struct radeon_device *rdev = dev->dev_private; |
606 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); | ||
607 | 396 | ||
608 | /* enable audio after to setting up hw */ | 397 | if (mute) |
609 | r600_audio_enable(rdev, dig->afmt->pin, 0xf); | 398 | WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE); |
399 | else | ||
400 | WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE); | ||
610 | } | 401 | } |
611 | 402 | ||
612 | /** | 403 | /** |
@@ -692,7 +483,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
692 | return; | 483 | return; |
693 | 484 | ||
694 | if (!enable && dig->afmt->pin) { | 485 | if (!enable && dig->afmt->pin) { |
695 | r600_audio_enable(rdev, dig->afmt->pin, 0); | 486 | radeon_audio_enable(rdev, dig->afmt->pin, 0); |
696 | dig->afmt->pin = NULL; | 487 | dig->afmt->pin = NULL; |
697 | } | 488 | } |
698 | 489 | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 54529b837afa..93e407b7e7a7 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1757,6 +1757,9 @@ struct r600_audio { | |||
1757 | bool enabled; | 1757 | bool enabled; |
1758 | struct r600_audio_pin pin[RADEON_MAX_AFMT_BLOCKS]; | 1758 | struct r600_audio_pin pin[RADEON_MAX_AFMT_BLOCKS]; |
1759 | int num_pins; | 1759 | int num_pins; |
1760 | struct radeon_audio_funcs *hdmi_funcs; | ||
1761 | struct radeon_audio_funcs *dp_funcs; | ||
1762 | struct radeon_audio_basic_funcs *funcs; | ||
1760 | }; | 1763 | }; |
1761 | 1764 | ||
1762 | /* | 1765 | /* |
@@ -1777,8 +1780,16 @@ void radeon_test_syncing(struct radeon_device *rdev); | |||
1777 | /* | 1780 | /* |
1778 | * MMU Notifier | 1781 | * MMU Notifier |
1779 | */ | 1782 | */ |
1783 | #if defined(CONFIG_MMU_NOTIFIER) | ||
1780 | int radeon_mn_register(struct radeon_bo *bo, unsigned long addr); | 1784 | int radeon_mn_register(struct radeon_bo *bo, unsigned long addr); |
1781 | void radeon_mn_unregister(struct radeon_bo *bo); | 1785 | void radeon_mn_unregister(struct radeon_bo *bo); |
1786 | #else | ||
1787 | static inline int radeon_mn_register(struct radeon_bo *bo, unsigned long addr) | ||
1788 | { | ||
1789 | return -ENODEV; | ||
1790 | } | ||
1791 | static inline void radeon_mn_unregister(struct radeon_bo *bo) {} | ||
1792 | #endif | ||
1782 | 1793 | ||
1783 | /* | 1794 | /* |
1784 | * Debugfs | 1795 | * Debugfs |
@@ -1967,6 +1978,10 @@ struct radeon_asic { | |||
1967 | bool (*vblank_too_short)(struct radeon_device *rdev); | 1978 | bool (*vblank_too_short)(struct radeon_device *rdev); |
1968 | void (*powergate_uvd)(struct radeon_device *rdev, bool gate); | 1979 | void (*powergate_uvd)(struct radeon_device *rdev, bool gate); |
1969 | void (*enable_bapm)(struct radeon_device *rdev, bool enable); | 1980 | void (*enable_bapm)(struct radeon_device *rdev, bool enable); |
1981 | void (*fan_ctrl_set_mode)(struct radeon_device *rdev, u32 mode); | ||
1982 | u32 (*fan_ctrl_get_mode)(struct radeon_device *rdev); | ||
1983 | int (*set_fan_speed_percent)(struct radeon_device *rdev, u32 speed); | ||
1984 | int (*get_fan_speed_percent)(struct radeon_device *rdev, u32 *speed); | ||
1970 | } dpm; | 1985 | } dpm; |
1971 | /* pageflipping */ | 1986 | /* pageflipping */ |
1972 | struct { | 1987 | struct { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 121aff6a3b41..f811ee14a237 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -638,8 +638,6 @@ static struct radeon_asic rs600_asic = { | |||
638 | .wait_for_vblank = &avivo_wait_for_vblank, | 638 | .wait_for_vblank = &avivo_wait_for_vblank, |
639 | .set_backlight_level = &atombios_set_backlight_level, | 639 | .set_backlight_level = &atombios_set_backlight_level, |
640 | .get_backlight_level = &atombios_get_backlight_level, | 640 | .get_backlight_level = &atombios_get_backlight_level, |
641 | .hdmi_enable = &r600_hdmi_enable, | ||
642 | .hdmi_setmode = &r600_hdmi_setmode, | ||
643 | }, | 641 | }, |
644 | .copy = { | 642 | .copy = { |
645 | .blit = &r100_copy_blit, | 643 | .blit = &r100_copy_blit, |
@@ -706,8 +704,6 @@ static struct radeon_asic rs690_asic = { | |||
706 | .wait_for_vblank = &avivo_wait_for_vblank, | 704 | .wait_for_vblank = &avivo_wait_for_vblank, |
707 | .set_backlight_level = &atombios_set_backlight_level, | 705 | .set_backlight_level = &atombios_set_backlight_level, |
708 | .get_backlight_level = &atombios_get_backlight_level, | 706 | .get_backlight_level = &atombios_get_backlight_level, |
709 | .hdmi_enable = &r600_hdmi_enable, | ||
710 | .hdmi_setmode = &r600_hdmi_setmode, | ||
711 | }, | 707 | }, |
712 | .copy = { | 708 | .copy = { |
713 | .blit = &r100_copy_blit, | 709 | .blit = &r100_copy_blit, |
@@ -935,8 +931,6 @@ static struct radeon_asic r600_asic = { | |||
935 | .wait_for_vblank = &avivo_wait_for_vblank, | 931 | .wait_for_vblank = &avivo_wait_for_vblank, |
936 | .set_backlight_level = &atombios_set_backlight_level, | 932 | .set_backlight_level = &atombios_set_backlight_level, |
937 | .get_backlight_level = &atombios_get_backlight_level, | 933 | .get_backlight_level = &atombios_get_backlight_level, |
938 | .hdmi_enable = &r600_hdmi_enable, | ||
939 | .hdmi_setmode = &r600_hdmi_setmode, | ||
940 | }, | 934 | }, |
941 | .copy = { | 935 | .copy = { |
942 | .blit = &r600_copy_cpdma, | 936 | .blit = &r600_copy_cpdma, |
@@ -1021,8 +1015,6 @@ static struct radeon_asic rv6xx_asic = { | |||
1021 | .wait_for_vblank = &avivo_wait_for_vblank, | 1015 | .wait_for_vblank = &avivo_wait_for_vblank, |
1022 | .set_backlight_level = &atombios_set_backlight_level, | 1016 | .set_backlight_level = &atombios_set_backlight_level, |
1023 | .get_backlight_level = &atombios_get_backlight_level, | 1017 | .get_backlight_level = &atombios_get_backlight_level, |
1024 | .hdmi_enable = &r600_hdmi_enable, | ||
1025 | .hdmi_setmode = &r600_hdmi_setmode, | ||
1026 | }, | 1018 | }, |
1027 | .copy = { | 1019 | .copy = { |
1028 | .blit = &r600_copy_cpdma, | 1020 | .blit = &r600_copy_cpdma, |
@@ -1112,8 +1104,6 @@ static struct radeon_asic rs780_asic = { | |||
1112 | .wait_for_vblank = &avivo_wait_for_vblank, | 1104 | .wait_for_vblank = &avivo_wait_for_vblank, |
1113 | .set_backlight_level = &atombios_set_backlight_level, | 1105 | .set_backlight_level = &atombios_set_backlight_level, |
1114 | .get_backlight_level = &atombios_get_backlight_level, | 1106 | .get_backlight_level = &atombios_get_backlight_level, |
1115 | .hdmi_enable = &r600_hdmi_enable, | ||
1116 | .hdmi_setmode = &r600_hdmi_setmode, | ||
1117 | }, | 1107 | }, |
1118 | .copy = { | 1108 | .copy = { |
1119 | .blit = &r600_copy_cpdma, | 1109 | .blit = &r600_copy_cpdma, |
@@ -1216,8 +1206,6 @@ static struct radeon_asic rv770_asic = { | |||
1216 | .wait_for_vblank = &avivo_wait_for_vblank, | 1206 | .wait_for_vblank = &avivo_wait_for_vblank, |
1217 | .set_backlight_level = &atombios_set_backlight_level, | 1207 | .set_backlight_level = &atombios_set_backlight_level, |
1218 | .get_backlight_level = &atombios_get_backlight_level, | 1208 | .get_backlight_level = &atombios_get_backlight_level, |
1219 | .hdmi_enable = &r600_hdmi_enable, | ||
1220 | .hdmi_setmode = &dce3_1_hdmi_setmode, | ||
1221 | }, | 1209 | }, |
1222 | .copy = { | 1210 | .copy = { |
1223 | .blit = &r600_copy_cpdma, | 1211 | .blit = &r600_copy_cpdma, |
@@ -1334,8 +1322,6 @@ static struct radeon_asic evergreen_asic = { | |||
1334 | .wait_for_vblank = &dce4_wait_for_vblank, | 1322 | .wait_for_vblank = &dce4_wait_for_vblank, |
1335 | .set_backlight_level = &atombios_set_backlight_level, | 1323 | .set_backlight_level = &atombios_set_backlight_level, |
1336 | .get_backlight_level = &atombios_get_backlight_level, | 1324 | .get_backlight_level = &atombios_get_backlight_level, |
1337 | .hdmi_enable = &evergreen_hdmi_enable, | ||
1338 | .hdmi_setmode = &evergreen_hdmi_setmode, | ||
1339 | }, | 1325 | }, |
1340 | .copy = { | 1326 | .copy = { |
1341 | .blit = &r600_copy_cpdma, | 1327 | .blit = &r600_copy_cpdma, |
@@ -1426,8 +1412,6 @@ static struct radeon_asic sumo_asic = { | |||
1426 | .wait_for_vblank = &dce4_wait_for_vblank, | 1412 | .wait_for_vblank = &dce4_wait_for_vblank, |
1427 | .set_backlight_level = &atombios_set_backlight_level, | 1413 | .set_backlight_level = &atombios_set_backlight_level, |
1428 | .get_backlight_level = &atombios_get_backlight_level, | 1414 | .get_backlight_level = &atombios_get_backlight_level, |
1429 | .hdmi_enable = &evergreen_hdmi_enable, | ||
1430 | .hdmi_setmode = &evergreen_hdmi_setmode, | ||
1431 | }, | 1415 | }, |
1432 | .copy = { | 1416 | .copy = { |
1433 | .blit = &r600_copy_cpdma, | 1417 | .blit = &r600_copy_cpdma, |
@@ -1517,8 +1501,6 @@ static struct radeon_asic btc_asic = { | |||
1517 | .wait_for_vblank = &dce4_wait_for_vblank, | 1501 | .wait_for_vblank = &dce4_wait_for_vblank, |
1518 | .set_backlight_level = &atombios_set_backlight_level, | 1502 | .set_backlight_level = &atombios_set_backlight_level, |
1519 | .get_backlight_level = &atombios_get_backlight_level, | 1503 | .get_backlight_level = &atombios_get_backlight_level, |
1520 | .hdmi_enable = &evergreen_hdmi_enable, | ||
1521 | .hdmi_setmode = &evergreen_hdmi_setmode, | ||
1522 | }, | 1504 | }, |
1523 | .copy = { | 1505 | .copy = { |
1524 | .blit = &r600_copy_cpdma, | 1506 | .blit = &r600_copy_cpdma, |
@@ -1663,8 +1645,6 @@ static struct radeon_asic cayman_asic = { | |||
1663 | .wait_for_vblank = &dce4_wait_for_vblank, | 1645 | .wait_for_vblank = &dce4_wait_for_vblank, |
1664 | .set_backlight_level = &atombios_set_backlight_level, | 1646 | .set_backlight_level = &atombios_set_backlight_level, |
1665 | .get_backlight_level = &atombios_get_backlight_level, | 1647 | .get_backlight_level = &atombios_get_backlight_level, |
1666 | .hdmi_enable = &evergreen_hdmi_enable, | ||
1667 | .hdmi_setmode = &evergreen_hdmi_setmode, | ||
1668 | }, | 1648 | }, |
1669 | .copy = { | 1649 | .copy = { |
1670 | .blit = &r600_copy_cpdma, | 1650 | .blit = &r600_copy_cpdma, |
@@ -1766,8 +1746,6 @@ static struct radeon_asic trinity_asic = { | |||
1766 | .wait_for_vblank = &dce4_wait_for_vblank, | 1746 | .wait_for_vblank = &dce4_wait_for_vblank, |
1767 | .set_backlight_level = &atombios_set_backlight_level, | 1747 | .set_backlight_level = &atombios_set_backlight_level, |
1768 | .get_backlight_level = &atombios_get_backlight_level, | 1748 | .get_backlight_level = &atombios_get_backlight_level, |
1769 | .hdmi_enable = &evergreen_hdmi_enable, | ||
1770 | .hdmi_setmode = &evergreen_hdmi_setmode, | ||
1771 | }, | 1749 | }, |
1772 | .copy = { | 1750 | .copy = { |
1773 | .blit = &r600_copy_cpdma, | 1751 | .blit = &r600_copy_cpdma, |
@@ -1899,8 +1877,6 @@ static struct radeon_asic si_asic = { | |||
1899 | .wait_for_vblank = &dce4_wait_for_vblank, | 1877 | .wait_for_vblank = &dce4_wait_for_vblank, |
1900 | .set_backlight_level = &atombios_set_backlight_level, | 1878 | .set_backlight_level = &atombios_set_backlight_level, |
1901 | .get_backlight_level = &atombios_get_backlight_level, | 1879 | .get_backlight_level = &atombios_get_backlight_level, |
1902 | .hdmi_enable = &evergreen_hdmi_enable, | ||
1903 | .hdmi_setmode = &evergreen_hdmi_setmode, | ||
1904 | }, | 1880 | }, |
1905 | .copy = { | 1881 | .copy = { |
1906 | .blit = &r600_copy_cpdma, | 1882 | .blit = &r600_copy_cpdma, |
@@ -1953,6 +1929,10 @@ static struct radeon_asic si_asic = { | |||
1953 | .debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level, | 1929 | .debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level, |
1954 | .force_performance_level = &si_dpm_force_performance_level, | 1930 | .force_performance_level = &si_dpm_force_performance_level, |
1955 | .vblank_too_short = &ni_dpm_vblank_too_short, | 1931 | .vblank_too_short = &ni_dpm_vblank_too_short, |
1932 | .fan_ctrl_set_mode = &si_fan_ctrl_set_mode, | ||
1933 | .fan_ctrl_get_mode = &si_fan_ctrl_get_mode, | ||
1934 | .get_fan_speed_percent = &si_fan_ctrl_get_fan_speed_percent, | ||
1935 | .set_fan_speed_percent = &si_fan_ctrl_set_fan_speed_percent, | ||
1956 | }, | 1936 | }, |
1957 | .pflip = { | 1937 | .pflip = { |
1958 | .page_flip = &evergreen_page_flip, | 1938 | .page_flip = &evergreen_page_flip, |
@@ -2062,8 +2042,6 @@ static struct radeon_asic ci_asic = { | |||
2062 | .wait_for_vblank = &dce4_wait_for_vblank, | 2042 | .wait_for_vblank = &dce4_wait_for_vblank, |
2063 | .set_backlight_level = &atombios_set_backlight_level, | 2043 | .set_backlight_level = &atombios_set_backlight_level, |
2064 | .get_backlight_level = &atombios_get_backlight_level, | 2044 | .get_backlight_level = &atombios_get_backlight_level, |
2065 | .hdmi_enable = &evergreen_hdmi_enable, | ||
2066 | .hdmi_setmode = &evergreen_hdmi_setmode, | ||
2067 | }, | 2045 | }, |
2068 | .copy = { | 2046 | .copy = { |
2069 | .blit = &cik_copy_cpdma, | 2047 | .blit = &cik_copy_cpdma, |
@@ -2118,6 +2096,10 @@ static struct radeon_asic ci_asic = { | |||
2118 | .force_performance_level = &ci_dpm_force_performance_level, | 2096 | .force_performance_level = &ci_dpm_force_performance_level, |
2119 | .vblank_too_short = &ci_dpm_vblank_too_short, | 2097 | .vblank_too_short = &ci_dpm_vblank_too_short, |
2120 | .powergate_uvd = &ci_dpm_powergate_uvd, | 2098 | .powergate_uvd = &ci_dpm_powergate_uvd, |
2099 | .fan_ctrl_set_mode = &ci_fan_ctrl_set_mode, | ||
2100 | .fan_ctrl_get_mode = &ci_fan_ctrl_get_mode, | ||
2101 | .get_fan_speed_percent = &ci_fan_ctrl_get_fan_speed_percent, | ||
2102 | .set_fan_speed_percent = &ci_fan_ctrl_set_fan_speed_percent, | ||
2121 | }, | 2103 | }, |
2122 | .pflip = { | 2104 | .pflip = { |
2123 | .page_flip = &evergreen_page_flip, | 2105 | .page_flip = &evergreen_page_flip, |
@@ -2169,8 +2151,6 @@ static struct radeon_asic kv_asic = { | |||
2169 | .wait_for_vblank = &dce4_wait_for_vblank, | 2151 | .wait_for_vblank = &dce4_wait_for_vblank, |
2170 | .set_backlight_level = &atombios_set_backlight_level, | 2152 | .set_backlight_level = &atombios_set_backlight_level, |
2171 | .get_backlight_level = &atombios_get_backlight_level, | 2153 | .get_backlight_level = &atombios_get_backlight_level, |
2172 | .hdmi_enable = &evergreen_hdmi_enable, | ||
2173 | .hdmi_setmode = &evergreen_hdmi_setmode, | ||
2174 | }, | 2154 | }, |
2175 | .copy = { | 2155 | .copy = { |
2176 | .blit = &cik_copy_cpdma, | 2156 | .blit = &cik_copy_cpdma, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 2a45d548d5ec..4045a320a424 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -390,7 +390,6 @@ void r600_irq_suspend(struct radeon_device *rdev); | |||
390 | void r600_disable_interrupts(struct radeon_device *rdev); | 390 | void r600_disable_interrupts(struct radeon_device *rdev); |
391 | void r600_rlc_stop(struct radeon_device *rdev); | 391 | void r600_rlc_stop(struct radeon_device *rdev); |
392 | /* r600 audio */ | 392 | /* r600 audio */ |
393 | int r600_audio_init(struct radeon_device *rdev); | ||
394 | void r600_audio_fini(struct radeon_device *rdev); | 393 | void r600_audio_fini(struct radeon_device *rdev); |
395 | void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock); | 394 | void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock); |
396 | void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, | 395 | void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, |
@@ -399,8 +398,6 @@ void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock); | |||
399 | void r600_hdmi_audio_workaround(struct drm_encoder *encoder); | 398 | void r600_hdmi_audio_workaround(struct drm_encoder *encoder); |
400 | int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); | 399 | int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); |
401 | void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); | 400 | void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); |
402 | void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); | ||
403 | void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); | ||
404 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 401 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
405 | u32 r600_get_xclk(struct radeon_device *rdev); | 402 | u32 r600_get_xclk(struct radeon_device *rdev); |
406 | uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev); | 403 | uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev); |
@@ -469,8 +466,6 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, | |||
469 | u32 rv770_get_xclk(struct radeon_device *rdev); | 466 | u32 rv770_get_xclk(struct radeon_device *rdev); |
470 | int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); | 467 | int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); |
471 | int rv770_get_temp(struct radeon_device *rdev); | 468 | int rv770_get_temp(struct radeon_device *rdev); |
472 | /* hdmi */ | ||
473 | void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); | ||
474 | /* rv7xx pm */ | 469 | /* rv7xx pm */ |
475 | int rv770_dpm_init(struct radeon_device *rdev); | 470 | int rv770_dpm_init(struct radeon_device *rdev); |
476 | int rv770_dpm_enable(struct radeon_device *rdev); | 471 | int rv770_dpm_enable(struct radeon_device *rdev); |
@@ -540,8 +535,6 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, | |||
540 | uint64_t src_offset, uint64_t dst_offset, | 535 | uint64_t src_offset, uint64_t dst_offset, |
541 | unsigned num_gpu_pages, | 536 | unsigned num_gpu_pages, |
542 | struct reservation_object *resv); | 537 | struct reservation_object *resv); |
543 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); | ||
544 | void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); | ||
545 | int evergreen_get_temp(struct radeon_device *rdev); | 538 | int evergreen_get_temp(struct radeon_device *rdev); |
546 | int sumo_get_temp(struct radeon_device *rdev); | 539 | int sumo_get_temp(struct radeon_device *rdev); |
547 | int tn_get_temp(struct radeon_device *rdev); | 540 | int tn_get_temp(struct radeon_device *rdev); |
@@ -680,7 +673,6 @@ void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable); | |||
680 | 673 | ||
681 | /* DCE6 - SI */ | 674 | /* DCE6 - SI */ |
682 | void dce6_bandwidth_update(struct radeon_device *rdev); | 675 | void dce6_bandwidth_update(struct radeon_device *rdev); |
683 | int dce6_audio_init(struct radeon_device *rdev); | ||
684 | void dce6_audio_fini(struct radeon_device *rdev); | 676 | void dce6_audio_fini(struct radeon_device *rdev); |
685 | 677 | ||
686 | /* | 678 | /* |
@@ -744,6 +736,12 @@ void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | |||
744 | struct seq_file *m); | 736 | struct seq_file *m); |
745 | int si_dpm_force_performance_level(struct radeon_device *rdev, | 737 | int si_dpm_force_performance_level(struct radeon_device *rdev, |
746 | enum radeon_dpm_forced_level level); | 738 | enum radeon_dpm_forced_level level); |
739 | int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, | ||
740 | u32 *speed); | ||
741 | int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | ||
742 | u32 speed); | ||
743 | u32 si_fan_ctrl_get_mode(struct radeon_device *rdev); | ||
744 | void si_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode); | ||
747 | 745 | ||
748 | /* DCE8 - CIK */ | 746 | /* DCE8 - CIK */ |
749 | void dce8_bandwidth_update(struct radeon_device *rdev); | 747 | void dce8_bandwidth_update(struct radeon_device *rdev); |
@@ -861,6 +859,13 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev, | |||
861 | bool ci_dpm_vblank_too_short(struct radeon_device *rdev); | 859 | bool ci_dpm_vblank_too_short(struct radeon_device *rdev); |
862 | void ci_dpm_powergate_uvd(struct radeon_device *rdev, bool gate); | 860 | void ci_dpm_powergate_uvd(struct radeon_device *rdev, bool gate); |
863 | 861 | ||
862 | int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, | ||
863 | u32 *speed); | ||
864 | int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | ||
865 | u32 speed); | ||
866 | u32 ci_fan_ctrl_get_mode(struct radeon_device *rdev); | ||
867 | void ci_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode); | ||
868 | |||
864 | int kv_dpm_init(struct radeon_device *rdev); | 869 | int kv_dpm_init(struct radeon_device *rdev); |
865 | int kv_dpm_enable(struct radeon_device *rdev); | 870 | int kv_dpm_enable(struct radeon_device *rdev); |
866 | int kv_dpm_late_enable(struct radeon_device *rdev); | 871 | int kv_dpm_late_enable(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c new file mode 100644 index 000000000000..a3ceef6d9632 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_audio.c | |||
@@ -0,0 +1,766 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Slava Grigorev <slava.grigorev@amd.com> | ||
23 | */ | ||
24 | |||
25 | #include <linux/gcd.h> | ||
26 | #include <drm/drmP.h> | ||
27 | #include <drm/drm_crtc.h> | ||
28 | #include "radeon.h" | ||
29 | #include "atom.h" | ||
30 | #include "radeon_audio.h" | ||
31 | |||
32 | void r600_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, | ||
33 | u8 enable_mask); | ||
34 | void dce4_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, | ||
35 | u8 enable_mask); | ||
36 | void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, | ||
37 | u8 enable_mask); | ||
38 | u32 dce6_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg); | ||
39 | void dce6_endpoint_wreg(struct radeon_device *rdev, | ||
40 | u32 offset, u32 reg, u32 v); | ||
41 | void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder, | ||
42 | struct cea_sad *sads, int sad_count); | ||
43 | void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder, | ||
44 | struct cea_sad *sads, int sad_count); | ||
45 | void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, | ||
46 | struct cea_sad *sads, int sad_count); | ||
47 | void dce3_2_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, | ||
48 | u8 *sadb, int sad_count); | ||
49 | void dce3_2_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, | ||
50 | u8 *sadb, int sad_count); | ||
51 | void dce4_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, | ||
52 | u8 *sadb, int sad_count); | ||
53 | void dce4_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, | ||
54 | u8 *sadb, int sad_count); | ||
55 | void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, | ||
56 | u8 *sadb, int sad_count); | ||
57 | void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, | ||
58 | u8 *sadb, int sad_count); | ||
59 | void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, | ||
60 | struct drm_connector *connector, struct drm_display_mode *mode); | ||
61 | void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | ||
62 | struct drm_connector *connector, struct drm_display_mode *mode); | ||
63 | struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); | ||
64 | struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); | ||
65 | void dce6_afmt_select_pin(struct drm_encoder *encoder); | ||
66 | void r600_hdmi_audio_set_dto(struct radeon_device *rdev, | ||
67 | struct radeon_crtc *crtc, unsigned int clock); | ||
68 | void dce3_2_audio_set_dto(struct radeon_device *rdev, | ||
69 | struct radeon_crtc *crtc, unsigned int clock); | ||
70 | void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, | ||
71 | struct radeon_crtc *crtc, unsigned int clock); | ||
72 | void dce4_dp_audio_set_dto(struct radeon_device *rdev, | ||
73 | struct radeon_crtc *crtc, unsigned int clock); | ||
74 | void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, | ||
75 | struct radeon_crtc *crtc, unsigned int clock); | ||
76 | void dce6_dp_audio_set_dto(struct radeon_device *rdev, | ||
77 | struct radeon_crtc *crtc, unsigned int clock); | ||
78 | void r600_set_avi_packet(struct radeon_device *rdev, u32 offset, | ||
79 | unsigned char *buffer, size_t size); | ||
80 | void evergreen_set_avi_packet(struct radeon_device *rdev, u32 offset, | ||
81 | unsigned char *buffer, size_t size); | ||
82 | void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset, | ||
83 | const struct radeon_hdmi_acr *acr); | ||
84 | void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, | ||
85 | const struct radeon_hdmi_acr *acr); | ||
86 | void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset, | ||
87 | const struct radeon_hdmi_acr *acr); | ||
88 | void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset); | ||
89 | void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset); | ||
90 | void dce4_hdmi_set_color_depth(struct drm_encoder *encoder, | ||
91 | u32 offset, int bpc); | ||
92 | void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset); | ||
93 | void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset); | ||
94 | void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset); | ||
95 | void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); | ||
96 | void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); | ||
97 | void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); | ||
98 | static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, | ||
99 | struct drm_display_mode *mode); | ||
100 | static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, | ||
101 | struct drm_display_mode *mode); | ||
102 | void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); | ||
103 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); | ||
104 | void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable); | ||
105 | void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable); | ||
106 | |||
107 | static const u32 pin_offsets[7] = | ||
108 | { | ||
109 | (0x5e00 - 0x5e00), | ||
110 | (0x5e18 - 0x5e00), | ||
111 | (0x5e30 - 0x5e00), | ||
112 | (0x5e48 - 0x5e00), | ||
113 | (0x5e60 - 0x5e00), | ||
114 | (0x5e78 - 0x5e00), | ||
115 | (0x5e90 - 0x5e00), | ||
116 | }; | ||
117 | |||
118 | static u32 radeon_audio_rreg(struct radeon_device *rdev, u32 offset, u32 reg) | ||
119 | { | ||
120 | return RREG32(reg); | ||
121 | } | ||
122 | |||
123 | static void radeon_audio_wreg(struct radeon_device *rdev, u32 offset, | ||
124 | u32 reg, u32 v) | ||
125 | { | ||
126 | WREG32(reg, v); | ||
127 | } | ||
128 | |||
129 | static struct radeon_audio_basic_funcs r600_funcs = { | ||
130 | .endpoint_rreg = radeon_audio_rreg, | ||
131 | .endpoint_wreg = radeon_audio_wreg, | ||
132 | .enable = r600_audio_enable, | ||
133 | }; | ||
134 | |||
135 | static struct radeon_audio_basic_funcs dce32_funcs = { | ||
136 | .endpoint_rreg = radeon_audio_rreg, | ||
137 | .endpoint_wreg = radeon_audio_wreg, | ||
138 | .enable = r600_audio_enable, | ||
139 | }; | ||
140 | |||
141 | static struct radeon_audio_basic_funcs dce4_funcs = { | ||
142 | .endpoint_rreg = radeon_audio_rreg, | ||
143 | .endpoint_wreg = radeon_audio_wreg, | ||
144 | .enable = dce4_audio_enable, | ||
145 | }; | ||
146 | |||
147 | static struct radeon_audio_basic_funcs dce6_funcs = { | ||
148 | .endpoint_rreg = dce6_endpoint_rreg, | ||
149 | .endpoint_wreg = dce6_endpoint_wreg, | ||
150 | .enable = dce6_audio_enable, | ||
151 | }; | ||
152 | |||
153 | static struct radeon_audio_funcs r600_hdmi_funcs = { | ||
154 | .get_pin = r600_audio_get_pin, | ||
155 | .set_dto = r600_hdmi_audio_set_dto, | ||
156 | .update_acr = r600_hdmi_update_acr, | ||
157 | .set_vbi_packet = r600_set_vbi_packet, | ||
158 | .set_avi_packet = r600_set_avi_packet, | ||
159 | .set_audio_packet = r600_set_audio_packet, | ||
160 | .set_mute = r600_set_mute, | ||
161 | .mode_set = radeon_audio_hdmi_mode_set, | ||
162 | .dpms = r600_hdmi_enable, | ||
163 | }; | ||
164 | |||
165 | static struct radeon_audio_funcs dce32_hdmi_funcs = { | ||
166 | .get_pin = r600_audio_get_pin, | ||
167 | .write_sad_regs = dce3_2_afmt_write_sad_regs, | ||
168 | .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, | ||
169 | .set_dto = dce3_2_audio_set_dto, | ||
170 | .update_acr = dce3_2_hdmi_update_acr, | ||
171 | .set_vbi_packet = r600_set_vbi_packet, | ||
172 | .set_avi_packet = r600_set_avi_packet, | ||
173 | .set_audio_packet = dce3_2_set_audio_packet, | ||
174 | .set_mute = dce3_2_set_mute, | ||
175 | .mode_set = radeon_audio_hdmi_mode_set, | ||
176 | .dpms = r600_hdmi_enable, | ||
177 | }; | ||
178 | |||
179 | static struct radeon_audio_funcs dce32_dp_funcs = { | ||
180 | .get_pin = r600_audio_get_pin, | ||
181 | .write_sad_regs = dce3_2_afmt_write_sad_regs, | ||
182 | .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, | ||
183 | .set_dto = dce3_2_audio_set_dto, | ||
184 | .set_avi_packet = r600_set_avi_packet, | ||
185 | .set_audio_packet = dce3_2_set_audio_packet, | ||
186 | }; | ||
187 | |||
188 | static struct radeon_audio_funcs dce4_hdmi_funcs = { | ||
189 | .get_pin = r600_audio_get_pin, | ||
190 | .write_sad_regs = evergreen_hdmi_write_sad_regs, | ||
191 | .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, | ||
192 | .write_latency_fields = dce4_afmt_write_latency_fields, | ||
193 | .set_dto = dce4_hdmi_audio_set_dto, | ||
194 | .update_acr = evergreen_hdmi_update_acr, | ||
195 | .set_vbi_packet = dce4_set_vbi_packet, | ||
196 | .set_color_depth = dce4_hdmi_set_color_depth, | ||
197 | .set_avi_packet = evergreen_set_avi_packet, | ||
198 | .set_audio_packet = dce4_set_audio_packet, | ||
199 | .set_mute = dce4_set_mute, | ||
200 | .mode_set = radeon_audio_hdmi_mode_set, | ||
201 | .dpms = evergreen_hdmi_enable, | ||
202 | }; | ||
203 | |||
204 | static struct radeon_audio_funcs dce4_dp_funcs = { | ||
205 | .get_pin = r600_audio_get_pin, | ||
206 | .write_sad_regs = evergreen_hdmi_write_sad_regs, | ||
207 | .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation, | ||
208 | .write_latency_fields = dce4_afmt_write_latency_fields, | ||
209 | .set_dto = dce4_dp_audio_set_dto, | ||
210 | .set_avi_packet = evergreen_set_avi_packet, | ||
211 | .set_audio_packet = dce4_set_audio_packet, | ||
212 | .mode_set = radeon_audio_dp_mode_set, | ||
213 | .dpms = evergreen_enable_dp_audio_packets, | ||
214 | }; | ||
215 | |||
216 | static struct radeon_audio_funcs dce6_hdmi_funcs = { | ||
217 | .select_pin = dce6_afmt_select_pin, | ||
218 | .get_pin = dce6_audio_get_pin, | ||
219 | .write_sad_regs = dce6_afmt_write_sad_regs, | ||
220 | .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, | ||
221 | .write_latency_fields = dce6_afmt_write_latency_fields, | ||
222 | .set_dto = dce6_hdmi_audio_set_dto, | ||
223 | .update_acr = evergreen_hdmi_update_acr, | ||
224 | .set_vbi_packet = dce4_set_vbi_packet, | ||
225 | .set_color_depth = dce4_hdmi_set_color_depth, | ||
226 | .set_avi_packet = evergreen_set_avi_packet, | ||
227 | .set_audio_packet = dce4_set_audio_packet, | ||
228 | .set_mute = dce4_set_mute, | ||
229 | .mode_set = radeon_audio_hdmi_mode_set, | ||
230 | .dpms = evergreen_hdmi_enable, | ||
231 | }; | ||
232 | |||
233 | static struct radeon_audio_funcs dce6_dp_funcs = { | ||
234 | .select_pin = dce6_afmt_select_pin, | ||
235 | .get_pin = dce6_audio_get_pin, | ||
236 | .write_sad_regs = dce6_afmt_write_sad_regs, | ||
237 | .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, | ||
238 | .write_latency_fields = dce6_afmt_write_latency_fields, | ||
239 | .set_dto = dce6_dp_audio_set_dto, | ||
240 | .set_avi_packet = evergreen_set_avi_packet, | ||
241 | .set_audio_packet = dce4_set_audio_packet, | ||
242 | .mode_set = radeon_audio_dp_mode_set, | ||
243 | .dpms = dce6_enable_dp_audio_packets, | ||
244 | }; | ||
245 | |||
246 | static void radeon_audio_interface_init(struct radeon_device *rdev) | ||
247 | { | ||
248 | if (ASIC_IS_DCE6(rdev)) { | ||
249 | rdev->audio.funcs = &dce6_funcs; | ||
250 | rdev->audio.hdmi_funcs = &dce6_hdmi_funcs; | ||
251 | rdev->audio.dp_funcs = &dce6_dp_funcs; | ||
252 | } else if (ASIC_IS_DCE4(rdev)) { | ||
253 | rdev->audio.funcs = &dce4_funcs; | ||
254 | rdev->audio.hdmi_funcs = &dce4_hdmi_funcs; | ||
255 | rdev->audio.dp_funcs = &dce4_dp_funcs; | ||
256 | } else if (ASIC_IS_DCE32(rdev)) { | ||
257 | rdev->audio.funcs = &dce32_funcs; | ||
258 | rdev->audio.hdmi_funcs = &dce32_hdmi_funcs; | ||
259 | rdev->audio.dp_funcs = &dce32_dp_funcs; | ||
260 | } else { | ||
261 | rdev->audio.funcs = &r600_funcs; | ||
262 | rdev->audio.hdmi_funcs = &r600_hdmi_funcs; | ||
263 | rdev->audio.dp_funcs = 0; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static int radeon_audio_chipset_supported(struct radeon_device *rdev) | ||
268 | { | ||
269 | return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); | ||
270 | } | ||
271 | |||
272 | int radeon_audio_init(struct radeon_device *rdev) | ||
273 | { | ||
274 | int i; | ||
275 | |||
276 | if (!radeon_audio || !radeon_audio_chipset_supported(rdev)) | ||
277 | return 0; | ||
278 | |||
279 | rdev->audio.enabled = true; | ||
280 | |||
281 | if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */ | ||
282 | rdev->audio.num_pins = 3; | ||
283 | else if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */ | ||
284 | rdev->audio.num_pins = 7; | ||
285 | else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */ | ||
286 | rdev->audio.num_pins = 7; | ||
287 | else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */ | ||
288 | rdev->audio.num_pins = 2; | ||
289 | else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */ | ||
290 | rdev->audio.num_pins = 6; | ||
291 | else if (ASIC_IS_DCE6(rdev)) /* SI: 6 streams, 6 endpoints */ | ||
292 | rdev->audio.num_pins = 6; | ||
293 | else | ||
294 | rdev->audio.num_pins = 1; | ||
295 | |||
296 | for (i = 0; i < rdev->audio.num_pins; i++) { | ||
297 | rdev->audio.pin[i].channels = -1; | ||
298 | rdev->audio.pin[i].rate = -1; | ||
299 | rdev->audio.pin[i].bits_per_sample = -1; | ||
300 | rdev->audio.pin[i].status_bits = 0; | ||
301 | rdev->audio.pin[i].category_code = 0; | ||
302 | rdev->audio.pin[i].connected = false; | ||
303 | rdev->audio.pin[i].offset = pin_offsets[i]; | ||
304 | rdev->audio.pin[i].id = i; | ||
305 | } | ||
306 | |||
307 | radeon_audio_interface_init(rdev); | ||
308 | |||
309 | /* disable audio. it will be set up later */ | ||
310 | for (i = 0; i < rdev->audio.num_pins; i++) | ||
311 | radeon_audio_enable(rdev, &rdev->audio.pin[i], false); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg) | ||
317 | { | ||
318 | if (rdev->audio.funcs->endpoint_rreg) | ||
319 | return rdev->audio.funcs->endpoint_rreg(rdev, offset, reg); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, | ||
325 | u32 reg, u32 v) | ||
326 | { | ||
327 | if (rdev->audio.funcs->endpoint_wreg) | ||
328 | rdev->audio.funcs->endpoint_wreg(rdev, offset, reg, v); | ||
329 | } | ||
330 | |||
331 | static void radeon_audio_write_sad_regs(struct drm_encoder *encoder) | ||
332 | { | ||
333 | struct radeon_encoder *radeon_encoder; | ||
334 | struct drm_connector *connector; | ||
335 | struct radeon_connector *radeon_connector = NULL; | ||
336 | struct cea_sad *sads; | ||
337 | int sad_count; | ||
338 | |||
339 | list_for_each_entry(connector, | ||
340 | &encoder->dev->mode_config.connector_list, head) { | ||
341 | if (connector->encoder == encoder) { | ||
342 | radeon_connector = to_radeon_connector(connector); | ||
343 | break; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | if (!radeon_connector) { | ||
348 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
349 | return; | ||
350 | } | ||
351 | |||
352 | sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); | ||
353 | if (sad_count <= 0) { | ||
354 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); | ||
355 | return; | ||
356 | } | ||
357 | BUG_ON(!sads); | ||
358 | |||
359 | radeon_encoder = to_radeon_encoder(encoder); | ||
360 | |||
361 | if (radeon_encoder->audio && radeon_encoder->audio->write_sad_regs) | ||
362 | radeon_encoder->audio->write_sad_regs(encoder, sads, sad_count); | ||
363 | |||
364 | kfree(sads); | ||
365 | } | ||
366 | |||
367 | static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) | ||
368 | { | ||
369 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
370 | struct drm_connector *connector; | ||
371 | struct radeon_connector *radeon_connector = NULL; | ||
372 | u8 *sadb = NULL; | ||
373 | int sad_count; | ||
374 | |||
375 | list_for_each_entry(connector, | ||
376 | &encoder->dev->mode_config.connector_list, head) { | ||
377 | if (connector->encoder == encoder) { | ||
378 | radeon_connector = to_radeon_connector(connector); | ||
379 | break; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | if (!radeon_connector) { | ||
384 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
385 | return; | ||
386 | } | ||
387 | |||
388 | sad_count = drm_edid_to_speaker_allocation( | ||
389 | radeon_connector_edid(connector), &sadb); | ||
390 | if (sad_count < 0) { | ||
391 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", | ||
392 | sad_count); | ||
393 | sad_count = 0; | ||
394 | } | ||
395 | |||
396 | if (radeon_encoder->audio && radeon_encoder->audio->write_speaker_allocation) | ||
397 | radeon_encoder->audio->write_speaker_allocation(encoder, sadb, sad_count); | ||
398 | |||
399 | kfree(sadb); | ||
400 | } | ||
401 | |||
402 | static void radeon_audio_write_latency_fields(struct drm_encoder *encoder, | ||
403 | struct drm_display_mode *mode) | ||
404 | { | ||
405 | struct radeon_encoder *radeon_encoder; | ||
406 | struct drm_connector *connector; | ||
407 | struct radeon_connector *radeon_connector = 0; | ||
408 | |||
409 | list_for_each_entry(connector, | ||
410 | &encoder->dev->mode_config.connector_list, head) { | ||
411 | if (connector->encoder == encoder) { | ||
412 | radeon_connector = to_radeon_connector(connector); | ||
413 | break; | ||
414 | } | ||
415 | } | ||
416 | |||
417 | if (!radeon_connector) { | ||
418 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
419 | return; | ||
420 | } | ||
421 | |||
422 | radeon_encoder = to_radeon_encoder(encoder); | ||
423 | |||
424 | if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields) | ||
425 | radeon_encoder->audio->write_latency_fields(encoder, connector, mode); | ||
426 | } | ||
427 | |||
428 | struct r600_audio_pin* radeon_audio_get_pin(struct drm_encoder *encoder) | ||
429 | { | ||
430 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
431 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
432 | |||
433 | if (radeon_encoder->audio && radeon_encoder->audio->get_pin) | ||
434 | return radeon_encoder->audio->get_pin(rdev); | ||
435 | |||
436 | return NULL; | ||
437 | } | ||
438 | |||
439 | static void radeon_audio_select_pin(struct drm_encoder *encoder) | ||
440 | { | ||
441 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
442 | |||
443 | if (radeon_encoder->audio && radeon_encoder->audio->select_pin) | ||
444 | radeon_encoder->audio->select_pin(encoder); | ||
445 | } | ||
446 | |||
447 | void radeon_audio_enable(struct radeon_device *rdev, | ||
448 | struct r600_audio_pin *pin, u8 enable_mask) | ||
449 | { | ||
450 | if (rdev->audio.funcs->enable) | ||
451 | rdev->audio.funcs->enable(rdev, pin, enable_mask); | ||
452 | } | ||
453 | |||
454 | void radeon_audio_detect(struct drm_connector *connector, | ||
455 | enum drm_connector_status status) | ||
456 | { | ||
457 | struct radeon_device *rdev; | ||
458 | struct radeon_encoder *radeon_encoder; | ||
459 | struct radeon_encoder_atom_dig *dig; | ||
460 | |||
461 | if (!connector || !connector->encoder) | ||
462 | return; | ||
463 | |||
464 | rdev = connector->encoder->dev->dev_private; | ||
465 | radeon_encoder = to_radeon_encoder(connector->encoder); | ||
466 | dig = radeon_encoder->enc_priv; | ||
467 | |||
468 | if (status == connector_status_connected) { | ||
469 | struct radeon_connector *radeon_connector; | ||
470 | int sink_type; | ||
471 | |||
472 | if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { | ||
473 | radeon_encoder->audio = NULL; | ||
474 | return; | ||
475 | } | ||
476 | |||
477 | radeon_connector = to_radeon_connector(connector); | ||
478 | sink_type = radeon_dp_getsinktype(radeon_connector); | ||
479 | |||
480 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort && | ||
481 | sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) | ||
482 | radeon_encoder->audio = rdev->audio.dp_funcs; | ||
483 | else | ||
484 | radeon_encoder->audio = rdev->audio.hdmi_funcs; | ||
485 | |||
486 | radeon_audio_write_speaker_allocation(connector->encoder); | ||
487 | radeon_audio_write_sad_regs(connector->encoder); | ||
488 | if (connector->encoder->crtc) | ||
489 | radeon_audio_write_latency_fields(connector->encoder, | ||
490 | &connector->encoder->crtc->mode); | ||
491 | radeon_audio_enable(rdev, dig->afmt->pin, 0xf); | ||
492 | } else { | ||
493 | radeon_audio_enable(rdev, dig->afmt->pin, 0); | ||
494 | } | ||
495 | } | ||
496 | |||
497 | void radeon_audio_fini(struct radeon_device *rdev) | ||
498 | { | ||
499 | int i; | ||
500 | |||
501 | if (!rdev->audio.enabled) | ||
502 | return; | ||
503 | |||
504 | for (i = 0; i < rdev->audio.num_pins; i++) | ||
505 | radeon_audio_enable(rdev, &rdev->audio.pin[i], false); | ||
506 | |||
507 | rdev->audio.enabled = false; | ||
508 | } | ||
509 | |||
510 | static void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock) | ||
511 | { | ||
512 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
513 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
514 | struct radeon_crtc *crtc = to_radeon_crtc(encoder->crtc); | ||
515 | |||
516 | if (radeon_encoder->audio && radeon_encoder->audio->set_dto) | ||
517 | radeon_encoder->audio->set_dto(rdev, crtc, clock); | ||
518 | } | ||
519 | |||
520 | static int radeon_audio_set_avi_packet(struct drm_encoder *encoder, | ||
521 | struct drm_display_mode *mode) | ||
522 | { | ||
523 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
524 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
525 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
526 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; | ||
527 | struct hdmi_avi_infoframe frame; | ||
528 | int err; | ||
529 | |||
530 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); | ||
531 | if (err < 0) { | ||
532 | DRM_ERROR("failed to setup AVI infoframe: %d\n", err); | ||
533 | return err; | ||
534 | } | ||
535 | |||
536 | err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); | ||
537 | if (err < 0) { | ||
538 | DRM_ERROR("failed to pack AVI infoframe: %d\n", err); | ||
539 | return err; | ||
540 | } | ||
541 | |||
542 | if (dig && dig->afmt && | ||
543 | radeon_encoder->audio && radeon_encoder->audio->set_avi_packet) | ||
544 | radeon_encoder->audio->set_avi_packet(rdev, dig->afmt->offset, | ||
545 | buffer, sizeof(buffer)); | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | /* | ||
551 | * calculate CTS and N values if they are not found in the table | ||
552 | */ | ||
553 | static void radeon_audio_calc_cts(unsigned int clock, int *CTS, int *N, int freq) | ||
554 | { | ||
555 | int n, cts; | ||
556 | unsigned long div, mul; | ||
557 | |||
558 | /* Safe, but overly large values */ | ||
559 | n = 128 * freq; | ||
560 | cts = clock * 1000; | ||
561 | |||
562 | /* Smallest valid fraction */ | ||
563 | div = gcd(n, cts); | ||
564 | |||
565 | n /= div; | ||
566 | cts /= div; | ||
567 | |||
568 | /* | ||
569 | * The optimal N is 128*freq/1000. Calculate the closest larger | ||
570 | * value that doesn't truncate any bits. | ||
571 | */ | ||
572 | mul = ((128*freq/1000) + (n-1))/n; | ||
573 | |||
574 | n *= mul; | ||
575 | cts *= mul; | ||
576 | |||
577 | /* Check that we are in spec (not always possible) */ | ||
578 | if (n < (128*freq/1500)) | ||
579 | printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n"); | ||
580 | if (n > (128*freq/300)) | ||
581 | printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n"); | ||
582 | |||
583 | *N = n; | ||
584 | *CTS = cts; | ||
585 | |||
586 | DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", | ||
587 | *N, *CTS, freq); | ||
588 | } | ||
589 | |||
590 | static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock) | ||
591 | { | ||
592 | static struct radeon_hdmi_acr res; | ||
593 | u8 i; | ||
594 | |||
595 | static const struct radeon_hdmi_acr hdmi_predefined_acr[] = { | ||
596 | /* 32kHz 44.1kHz 48kHz */ | ||
597 | /* Clock N CTS N CTS N CTS */ | ||
598 | { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ | ||
599 | { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ | ||
600 | { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ | ||
601 | { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ | ||
602 | { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ | ||
603 | { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ | ||
604 | { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ | ||
605 | { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ | ||
606 | { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ | ||
607 | { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ | ||
608 | }; | ||
609 | |||
610 | /* Precalculated values for common clocks */ | ||
611 | for (i = 0; i < ARRAY_SIZE(hdmi_predefined_acr); i++) | ||
612 | if (hdmi_predefined_acr[i].clock == clock) | ||
613 | return &hdmi_predefined_acr[i]; | ||
614 | |||
615 | /* And odd clocks get manually calculated */ | ||
616 | radeon_audio_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); | ||
617 | radeon_audio_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); | ||
618 | radeon_audio_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); | ||
619 | |||
620 | return &res; | ||
621 | } | ||
622 | |||
623 | /* | ||
624 | * update the N and CTS parameters for a given pixel clock rate | ||
625 | */ | ||
626 | static void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock) | ||
627 | { | ||
628 | const struct radeon_hdmi_acr *acr = radeon_audio_acr(clock); | ||
629 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
630 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
631 | |||
632 | if (!dig || !dig->afmt) | ||
633 | return; | ||
634 | |||
635 | if (radeon_encoder->audio && radeon_encoder->audio->update_acr) | ||
636 | radeon_encoder->audio->update_acr(encoder, dig->afmt->offset, acr); | ||
637 | } | ||
638 | |||
639 | static void radeon_audio_set_vbi_packet(struct drm_encoder *encoder) | ||
640 | { | ||
641 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
642 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
643 | |||
644 | if (!dig || !dig->afmt) | ||
645 | return; | ||
646 | |||
647 | if (radeon_encoder->audio && radeon_encoder->audio->set_vbi_packet) | ||
648 | radeon_encoder->audio->set_vbi_packet(encoder, dig->afmt->offset); | ||
649 | } | ||
650 | |||
651 | static void radeon_hdmi_set_color_depth(struct drm_encoder *encoder) | ||
652 | { | ||
653 | int bpc = 8; | ||
654 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
655 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
656 | |||
657 | if (!dig || !dig->afmt) | ||
658 | return; | ||
659 | |||
660 | if (encoder->crtc) { | ||
661 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
662 | bpc = radeon_crtc->bpc; | ||
663 | } | ||
664 | |||
665 | if (radeon_encoder->audio && radeon_encoder->audio->set_color_depth) | ||
666 | radeon_encoder->audio->set_color_depth(encoder, dig->afmt->offset, bpc); | ||
667 | } | ||
668 | |||
669 | static void radeon_audio_set_audio_packet(struct drm_encoder *encoder) | ||
670 | { | ||
671 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
672 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
673 | |||
674 | if (!dig || !dig->afmt) | ||
675 | return; | ||
676 | |||
677 | if (radeon_encoder->audio && radeon_encoder->audio->set_audio_packet) | ||
678 | radeon_encoder->audio->set_audio_packet(encoder, dig->afmt->offset); | ||
679 | } | ||
680 | |||
681 | static void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute) | ||
682 | { | ||
683 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
684 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
685 | |||
686 | if (!dig || !dig->afmt) | ||
687 | return; | ||
688 | |||
689 | if (radeon_encoder->audio && radeon_encoder->audio->set_mute) | ||
690 | radeon_encoder->audio->set_mute(encoder, dig->afmt->offset, mute); | ||
691 | } | ||
692 | |||
693 | /* | ||
694 | * update the info frames with the data from the current display mode | ||
695 | */ | ||
696 | static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, | ||
697 | struct drm_display_mode *mode) | ||
698 | { | ||
699 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
700 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
701 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
702 | |||
703 | if (!dig || !dig->afmt) | ||
704 | return; | ||
705 | |||
706 | /* disable audio prior to setting up hw */ | ||
707 | dig->afmt->pin = radeon_audio_get_pin(encoder); | ||
708 | radeon_audio_enable(rdev, dig->afmt->pin, 0); | ||
709 | |||
710 | radeon_audio_set_dto(encoder, mode->clock); | ||
711 | radeon_audio_set_vbi_packet(encoder); | ||
712 | radeon_hdmi_set_color_depth(encoder); | ||
713 | radeon_audio_set_mute(encoder, false); | ||
714 | radeon_audio_update_acr(encoder, mode->clock); | ||
715 | radeon_audio_set_audio_packet(encoder); | ||
716 | radeon_audio_select_pin(encoder); | ||
717 | |||
718 | if (radeon_audio_set_avi_packet(encoder, mode) < 0) | ||
719 | return; | ||
720 | |||
721 | /* enable audio after to setting up hw */ | ||
722 | radeon_audio_enable(rdev, dig->afmt->pin, 0xf); | ||
723 | } | ||
724 | |||
725 | static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, | ||
726 | struct drm_display_mode *mode) | ||
727 | { | ||
728 | struct drm_device *dev = encoder->dev; | ||
729 | struct radeon_device *rdev = dev->dev_private; | ||
730 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
731 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
732 | |||
733 | if (!dig || !dig->afmt) | ||
734 | return; | ||
735 | |||
736 | /* disable audio prior to setting up hw */ | ||
737 | dig->afmt->pin = radeon_audio_get_pin(encoder); | ||
738 | radeon_audio_enable(rdev, dig->afmt->pin, 0); | ||
739 | |||
740 | radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10); | ||
741 | radeon_audio_set_audio_packet(encoder); | ||
742 | radeon_audio_select_pin(encoder); | ||
743 | |||
744 | if (radeon_audio_set_avi_packet(encoder, mode) < 0) | ||
745 | return; | ||
746 | |||
747 | /* enable audio after to setting up hw */ | ||
748 | radeon_audio_enable(rdev, dig->afmt->pin, 0xf); | ||
749 | } | ||
750 | |||
751 | void radeon_audio_mode_set(struct drm_encoder *encoder, | ||
752 | struct drm_display_mode *mode) | ||
753 | { | ||
754 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
755 | |||
756 | if (radeon_encoder->audio && radeon_encoder->audio->mode_set) | ||
757 | radeon_encoder->audio->mode_set(encoder, mode); | ||
758 | } | ||
759 | |||
760 | void radeon_audio_dpms(struct drm_encoder *encoder, int mode) | ||
761 | { | ||
762 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
763 | |||
764 | if (radeon_encoder->audio && radeon_encoder->audio->dpms) | ||
765 | radeon_encoder->audio->dpms(encoder, mode == DRM_MODE_DPMS_ON); | ||
766 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h new file mode 100644 index 000000000000..c92d059ab204 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_audio.h | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Slava Grigorev <slava.grigorev@amd.com> | ||
23 | */ | ||
24 | |||
25 | #ifndef __RADEON_AUDIO_H__ | ||
26 | #define __RADEON_AUDIO_H__ | ||
27 | |||
28 | #include <linux/types.h> | ||
29 | |||
30 | #define RREG32_ENDPOINT(block, reg) \ | ||
31 | radeon_audio_endpoint_rreg(rdev, (block), (reg)) | ||
32 | #define WREG32_ENDPOINT(block, reg, v) \ | ||
33 | radeon_audio_endpoint_wreg(rdev, (block), (reg), (v)) | ||
34 | |||
35 | struct radeon_audio_basic_funcs | ||
36 | { | ||
37 | u32 (*endpoint_rreg)(struct radeon_device *rdev, u32 offset, u32 reg); | ||
38 | void (*endpoint_wreg)(struct radeon_device *rdev, | ||
39 | u32 offset, u32 reg, u32 v); | ||
40 | void (*enable)(struct radeon_device *rdev, | ||
41 | struct r600_audio_pin *pin, u8 enable_mask); | ||
42 | }; | ||
43 | |||
44 | struct radeon_audio_funcs | ||
45 | { | ||
46 | void (*select_pin)(struct drm_encoder *encoder); | ||
47 | struct r600_audio_pin* (*get_pin)(struct radeon_device *rdev); | ||
48 | void (*write_latency_fields)(struct drm_encoder *encoder, | ||
49 | struct drm_connector *connector, struct drm_display_mode *mode); | ||
50 | void (*write_sad_regs)(struct drm_encoder *encoder, | ||
51 | struct cea_sad *sads, int sad_count); | ||
52 | void (*write_speaker_allocation)(struct drm_encoder *encoder, | ||
53 | u8 *sadb, int sad_count); | ||
54 | void (*set_dto)(struct radeon_device *rdev, | ||
55 | struct radeon_crtc *crtc, unsigned int clock); | ||
56 | void (*update_acr)(struct drm_encoder *encoder, long offset, | ||
57 | const struct radeon_hdmi_acr *acr); | ||
58 | void (*set_vbi_packet)(struct drm_encoder *encoder, u32 offset); | ||
59 | void (*set_color_depth)(struct drm_encoder *encoder, u32 offset, int bpc); | ||
60 | void (*set_avi_packet)(struct radeon_device *rdev, u32 offset, | ||
61 | unsigned char *buffer, size_t size); | ||
62 | void (*set_audio_packet)(struct drm_encoder *encoder, u32 offset); | ||
63 | void (*set_mute)(struct drm_encoder *encoder, u32 offset, bool mute); | ||
64 | void (*mode_set)(struct drm_encoder *encoder, | ||
65 | struct drm_display_mode *mode); | ||
66 | void (*dpms)(struct drm_encoder *encoder, bool mode); | ||
67 | }; | ||
68 | |||
69 | int radeon_audio_init(struct radeon_device *rdev); | ||
70 | void radeon_audio_detect(struct drm_connector *connector, | ||
71 | enum drm_connector_status status); | ||
72 | u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, | ||
73 | u32 offset, u32 reg); | ||
74 | void radeon_audio_endpoint_wreg(struct radeon_device *rdev, | ||
75 | u32 offset, u32 reg, u32 v); | ||
76 | struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder); | ||
77 | void radeon_audio_enable(struct radeon_device *rdev, | ||
78 | struct r600_audio_pin *pin, u8 enable_mask); | ||
79 | void radeon_audio_fini(struct radeon_device *rdev); | ||
80 | void radeon_audio_mode_set(struct drm_encoder *encoder, | ||
81 | struct drm_display_mode *mode); | ||
82 | void radeon_audio_dpms(struct drm_encoder *encoder, int mode); | ||
83 | |||
84 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 26baa9c05f6c..27def67cb6be 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <drm/drm_fb_helper.h> | 29 | #include <drm/drm_fb_helper.h> |
30 | #include <drm/radeon_drm.h> | 30 | #include <drm/radeon_drm.h> |
31 | #include "radeon.h" | 31 | #include "radeon.h" |
32 | #include "radeon_audio.h" | ||
32 | #include "atom.h" | 33 | #include "atom.h" |
33 | 34 | ||
34 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
@@ -1332,6 +1333,9 @@ out: | |||
1332 | /* updated in get modes as well since we need to know if it's analog or digital */ | 1333 | /* updated in get modes as well since we need to know if it's analog or digital */ |
1333 | radeon_connector_update_scratch_regs(connector, ret); | 1334 | radeon_connector_update_scratch_regs(connector, ret); |
1334 | 1335 | ||
1336 | if (radeon_audio != 0) | ||
1337 | radeon_audio_detect(connector, ret); | ||
1338 | |||
1335 | exit: | 1339 | exit: |
1336 | pm_runtime_mark_last_busy(connector->dev->dev); | 1340 | pm_runtime_mark_last_busy(connector->dev->dev); |
1337 | pm_runtime_put_autosuspend(connector->dev->dev); | 1341 | pm_runtime_put_autosuspend(connector->dev->dev); |
@@ -1654,6 +1658,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1654 | } | 1658 | } |
1655 | 1659 | ||
1656 | radeon_connector_update_scratch_regs(connector, ret); | 1660 | radeon_connector_update_scratch_regs(connector, ret); |
1661 | |||
1662 | if (radeon_audio != 0) | ||
1663 | radeon_audio_detect(connector, ret); | ||
1664 | |||
1657 | out: | 1665 | out: |
1658 | pm_runtime_mark_last_busy(connector->dev->dev); | 1666 | pm_runtime_mark_last_busy(connector->dev->dev); |
1659 | pm_runtime_put_autosuspend(connector->dev->dev); | 1667 | pm_runtime_put_autosuspend(connector->dev->dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4f50fb0e3d93..5d684beb48d3 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -88,9 +88,10 @@ | |||
88 | * 2.39.0 - Add INFO query for number of active CUs | 88 | * 2.39.0 - Add INFO query for number of active CUs |
89 | * 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting | 89 | * 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting |
90 | * CS to GPU on >= r600 | 90 | * CS to GPU on >= r600 |
91 | * 2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing support | ||
91 | */ | 92 | */ |
92 | #define KMS_DRIVER_MAJOR 2 | 93 | #define KMS_DRIVER_MAJOR 2 |
93 | #define KMS_DRIVER_MINOR 40 | 94 | #define KMS_DRIVER_MINOR 41 |
94 | #define KMS_DRIVER_PATCHLEVEL 0 | 95 | #define KMS_DRIVER_PATCHLEVEL 0 |
95 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 96 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
96 | int radeon_driver_unload_kms(struct drm_device *dev); | 97 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 3000bc4c136b..ea276ff6d174 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -428,16 +428,6 @@ void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state) | |||
428 | fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state); | 428 | fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state); |
429 | } | 429 | } |
430 | 430 | ||
431 | int radeon_fbdev_total_size(struct radeon_device *rdev) | ||
432 | { | ||
433 | struct radeon_bo *robj; | ||
434 | int size = 0; | ||
435 | |||
436 | robj = gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj); | ||
437 | size += radeon_bo_size(robj); | ||
438 | return size; | ||
439 | } | ||
440 | |||
441 | bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) | 431 | bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) |
442 | { | 432 | { |
443 | if (robj == gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj)) | 433 | if (robj == gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj)) |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index add622008407..9590bcd321c0 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -1048,11 +1048,6 @@ struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev, | |||
1048 | return NULL; | 1048 | return NULL; |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) | ||
1052 | { | ||
1053 | return NULL; | ||
1054 | } | ||
1055 | |||
1056 | void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, | 1051 | void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, |
1057 | u8 slave_addr, | 1052 | u8 slave_addr, |
1058 | u8 addr, | 1053 | u8 addr, |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 390db897f322..920a8be8abad 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -449,6 +449,7 @@ struct radeon_encoder { | |||
449 | int audio_polling_active; | 449 | int audio_polling_active; |
450 | bool is_ext_encoder; | 450 | bool is_ext_encoder; |
451 | u16 caps; | 451 | u16 caps; |
452 | struct radeon_audio_funcs *audio; | ||
452 | }; | 453 | }; |
453 | 454 | ||
454 | struct radeon_connector_atom_dig { | 455 | struct radeon_connector_atom_dig { |
@@ -745,8 +746,6 @@ extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connec | |||
745 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); | 746 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); |
746 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux); | 747 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux); |
747 | 748 | ||
748 | extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); | ||
749 | |||
750 | extern bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, | 749 | extern bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, |
751 | struct radeon_atom_ss *ss, | 750 | struct radeon_atom_ss *ss, |
752 | int id); | 751 | int id); |
@@ -925,7 +924,6 @@ void dce8_program_fmt(struct drm_encoder *encoder); | |||
925 | int radeon_fbdev_init(struct radeon_device *rdev); | 924 | int radeon_fbdev_init(struct radeon_device *rdev); |
926 | void radeon_fbdev_fini(struct radeon_device *rdev); | 925 | void radeon_fbdev_fini(struct radeon_device *rdev); |
927 | void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state); | 926 | void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state); |
928 | int radeon_fbdev_total_size(struct radeon_device *rdev); | ||
929 | bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); | 927 | bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); |
930 | 928 | ||
931 | void radeon_fb_output_poll_changed(struct radeon_device *rdev); | 929 | void radeon_fb_output_poll_changed(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 86fc56434b28..1d955776f4d0 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -576,12 +576,6 @@ int radeon_bo_list_validate(struct radeon_device *rdev, | |||
576 | return 0; | 576 | return 0; |
577 | } | 577 | } |
578 | 578 | ||
579 | int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | ||
580 | struct vm_area_struct *vma) | ||
581 | { | ||
582 | return ttm_fbdev_mmap(vma, &bo->tbo); | ||
583 | } | ||
584 | |||
585 | int radeon_bo_get_surface_reg(struct radeon_bo *bo) | 579 | int radeon_bo_get_surface_reg(struct radeon_bo *bo) |
586 | { | 580 | { |
587 | struct radeon_device *rdev = bo->rdev; | 581 | struct radeon_device *rdev = bo->rdev; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 3b0b377f76cb..d8d295ee7c12 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -143,8 +143,6 @@ extern void radeon_bo_fini(struct radeon_device *rdev); | |||
143 | extern int radeon_bo_list_validate(struct radeon_device *rdev, | 143 | extern int radeon_bo_list_validate(struct radeon_device *rdev, |
144 | struct ww_acquire_ctx *ticket, | 144 | struct ww_acquire_ctx *ticket, |
145 | struct list_head *head, int ring); | 145 | struct list_head *head, int ring); |
146 | extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | ||
147 | struct vm_area_struct *vma); | ||
148 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, | 146 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, |
149 | u32 tiling_flags, u32 pitch); | 147 | u32 tiling_flags, u32 pitch); |
150 | extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo, | 148 | extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo, |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f7da8fe96a66..91e1bd246cad 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "radeon.h" | 24 | #include "radeon.h" |
25 | #include "avivod.h" | 25 | #include "avivod.h" |
26 | #include "atom.h" | 26 | #include "atom.h" |
27 | #include "r600_dpm.h" | ||
27 | #include <linux/power_supply.h> | 28 | #include <linux/power_supply.h> |
28 | #include <linux/hwmon.h> | 29 | #include <linux/hwmon.h> |
29 | #include <linux/hwmon-sysfs.h> | 30 | #include <linux/hwmon-sysfs.h> |
@@ -554,6 +555,96 @@ fail: | |||
554 | return count; | 555 | return count; |
555 | } | 556 | } |
556 | 557 | ||
558 | static ssize_t radeon_hwmon_get_pwm1_enable(struct device *dev, | ||
559 | struct device_attribute *attr, | ||
560 | char *buf) | ||
561 | { | ||
562 | struct radeon_device *rdev = dev_get_drvdata(dev); | ||
563 | u32 pwm_mode = 0; | ||
564 | |||
565 | if (rdev->asic->dpm.fan_ctrl_get_mode) | ||
566 | pwm_mode = rdev->asic->dpm.fan_ctrl_get_mode(rdev); | ||
567 | |||
568 | /* never 0 (full-speed), fuse or smc-controlled always */ | ||
569 | return sprintf(buf, "%i\n", pwm_mode == FDO_PWM_MODE_STATIC ? 1 : 2); | ||
570 | } | ||
571 | |||
572 | static ssize_t radeon_hwmon_set_pwm1_enable(struct device *dev, | ||
573 | struct device_attribute *attr, | ||
574 | const char *buf, | ||
575 | size_t count) | ||
576 | { | ||
577 | struct radeon_device *rdev = dev_get_drvdata(dev); | ||
578 | int err; | ||
579 | int value; | ||
580 | |||
581 | if(!rdev->asic->dpm.fan_ctrl_set_mode) | ||
582 | return -EINVAL; | ||
583 | |||
584 | err = kstrtoint(buf, 10, &value); | ||
585 | if (err) | ||
586 | return err; | ||
587 | |||
588 | switch(value) { | ||
589 | case 1: /* manual, percent-based */ | ||
590 | rdev->asic->dpm.fan_ctrl_set_mode(rdev, FDO_PWM_MODE_STATIC); | ||
591 | break; | ||
592 | default: /* disable */ | ||
593 | rdev->asic->dpm.fan_ctrl_set_mode(rdev, 0); | ||
594 | break; | ||
595 | } | ||
596 | |||
597 | return count; | ||
598 | } | ||
599 | |||
600 | static ssize_t radeon_hwmon_get_pwm1_min(struct device *dev, | ||
601 | struct device_attribute *attr, | ||
602 | char *buf) | ||
603 | { | ||
604 | return sprintf(buf, "%i\n", 0); | ||
605 | } | ||
606 | |||
607 | static ssize_t radeon_hwmon_get_pwm1_max(struct device *dev, | ||
608 | struct device_attribute *attr, | ||
609 | char *buf) | ||
610 | { | ||
611 | return sprintf(buf, "%i\n", 100); /* pwm uses percent-based fan-control */ | ||
612 | } | ||
613 | |||
614 | static ssize_t radeon_hwmon_set_pwm1(struct device *dev, | ||
615 | struct device_attribute *attr, | ||
616 | const char *buf, size_t count) | ||
617 | { | ||
618 | struct radeon_device *rdev = dev_get_drvdata(dev); | ||
619 | int err; | ||
620 | u32 value; | ||
621 | |||
622 | err = kstrtou32(buf, 10, &value); | ||
623 | if (err) | ||
624 | return err; | ||
625 | |||
626 | err = rdev->asic->dpm.set_fan_speed_percent(rdev, value); | ||
627 | if (err) | ||
628 | return err; | ||
629 | |||
630 | return count; | ||
631 | } | ||
632 | |||
633 | static ssize_t radeon_hwmon_get_pwm1(struct device *dev, | ||
634 | struct device_attribute *attr, | ||
635 | char *buf) | ||
636 | { | ||
637 | struct radeon_device *rdev = dev_get_drvdata(dev); | ||
638 | int err; | ||
639 | u32 speed; | ||
640 | |||
641 | err = rdev->asic->dpm.get_fan_speed_percent(rdev, &speed); | ||
642 | if (err) | ||
643 | return err; | ||
644 | |||
645 | return sprintf(buf, "%i\n", speed); | ||
646 | } | ||
647 | |||
557 | static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); | 648 | static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); |
558 | static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); | 649 | static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); |
559 | static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, radeon_get_dpm_state, radeon_set_dpm_state); | 650 | static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, radeon_get_dpm_state, radeon_set_dpm_state); |
@@ -601,11 +692,20 @@ static ssize_t radeon_hwmon_show_temp_thresh(struct device *dev, | |||
601 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0); | 692 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0); |
602 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 0); | 693 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 0); |
603 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 1); | 694 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 1); |
695 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, radeon_hwmon_get_pwm1, radeon_hwmon_set_pwm1, 0); | ||
696 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, radeon_hwmon_get_pwm1_enable, radeon_hwmon_set_pwm1_enable, 0); | ||
697 | static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO, radeon_hwmon_get_pwm1_min, NULL, 0); | ||
698 | static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO, radeon_hwmon_get_pwm1_max, NULL, 0); | ||
699 | |||
604 | 700 | ||
605 | static struct attribute *hwmon_attributes[] = { | 701 | static struct attribute *hwmon_attributes[] = { |
606 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 702 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
607 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | 703 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
608 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | 704 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, |
705 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
706 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
707 | &sensor_dev_attr_pwm1_min.dev_attr.attr, | ||
708 | &sensor_dev_attr_pwm1_max.dev_attr.attr, | ||
609 | NULL | 709 | NULL |
610 | }; | 710 | }; |
611 | 711 | ||
@@ -614,6 +714,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, | |||
614 | { | 714 | { |
615 | struct device *dev = container_of(kobj, struct device, kobj); | 715 | struct device *dev = container_of(kobj, struct device, kobj); |
616 | struct radeon_device *rdev = dev_get_drvdata(dev); | 716 | struct radeon_device *rdev = dev_get_drvdata(dev); |
717 | umode_t effective_mode = attr->mode; | ||
617 | 718 | ||
618 | /* Skip limit attributes if DPM is not enabled */ | 719 | /* Skip limit attributes if DPM is not enabled */ |
619 | if (rdev->pm.pm_method != PM_METHOD_DPM && | 720 | if (rdev->pm.pm_method != PM_METHOD_DPM && |
@@ -621,7 +722,35 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, | |||
621 | attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr)) | 722 | attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr)) |
622 | return 0; | 723 | return 0; |
623 | 724 | ||
624 | return attr->mode; | 725 | /* Skip fan attributes if fan is not present */ |
726 | if (rdev->pm.no_fan && | ||
727 | (attr == &sensor_dev_attr_pwm1.dev_attr.attr || | ||
728 | attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr || | ||
729 | attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || | ||
730 | attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) | ||
731 | return 0; | ||
732 | |||
733 | /* mask fan attributes if we have no bindings for this asic to expose */ | ||
734 | if ((!rdev->asic->dpm.get_fan_speed_percent && | ||
735 | attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't query fan */ | ||
736 | (!rdev->asic->dpm.fan_ctrl_get_mode && | ||
737 | attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't query state */ | ||
738 | effective_mode &= ~S_IRUGO; | ||
739 | |||
740 | if ((!rdev->asic->dpm.set_fan_speed_percent && | ||
741 | attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't manage fan */ | ||
742 | (!rdev->asic->dpm.fan_ctrl_set_mode && | ||
743 | attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't manage state */ | ||
744 | effective_mode &= ~S_IWUSR; | ||
745 | |||
746 | /* hide max/min values if we can't both query and manage the fan */ | ||
747 | if ((!rdev->asic->dpm.set_fan_speed_percent && | ||
748 | !rdev->asic->dpm.get_fan_speed_percent) && | ||
749 | (attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || | ||
750 | attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) | ||
751 | return 0; | ||
752 | |||
753 | return effective_mode; | ||
625 | } | 754 | } |
626 | 755 | ||
627 | static const struct attribute_group hwmon_attrgroup = { | 756 | static const struct attribute_group hwmon_attrgroup = { |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 9acb1c3c005b..68f154a451c0 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <drm/drmP.h> | 38 | #include <drm/drmP.h> |
39 | #include "radeon.h" | 39 | #include "radeon.h" |
40 | #include "radeon_asic.h" | 40 | #include "radeon_asic.h" |
41 | #include "radeon_audio.h" | ||
41 | #include "atom.h" | 42 | #include "atom.h" |
42 | #include "rs600d.h" | 43 | #include "rs600d.h" |
43 | 44 | ||
@@ -1012,7 +1013,7 @@ static int rs600_startup(struct radeon_device *rdev) | |||
1012 | return r; | 1013 | return r; |
1013 | } | 1014 | } |
1014 | 1015 | ||
1015 | r = r600_audio_init(rdev); | 1016 | r = radeon_audio_init(rdev); |
1016 | if (r) { | 1017 | if (r) { |
1017 | dev_err(rdev->dev, "failed initializing audio\n"); | 1018 | dev_err(rdev->dev, "failed initializing audio\n"); |
1018 | return r; | 1019 | return r; |
@@ -1053,7 +1054,7 @@ int rs600_resume(struct radeon_device *rdev) | |||
1053 | int rs600_suspend(struct radeon_device *rdev) | 1054 | int rs600_suspend(struct radeon_device *rdev) |
1054 | { | 1055 | { |
1055 | radeon_pm_suspend(rdev); | 1056 | radeon_pm_suspend(rdev); |
1056 | r600_audio_fini(rdev); | 1057 | radeon_audio_fini(rdev); |
1057 | r100_cp_disable(rdev); | 1058 | r100_cp_disable(rdev); |
1058 | radeon_wb_disable(rdev); | 1059 | radeon_wb_disable(rdev); |
1059 | rs600_irq_disable(rdev); | 1060 | rs600_irq_disable(rdev); |
@@ -1064,7 +1065,7 @@ int rs600_suspend(struct radeon_device *rdev) | |||
1064 | void rs600_fini(struct radeon_device *rdev) | 1065 | void rs600_fini(struct radeon_device *rdev) |
1065 | { | 1066 | { |
1066 | radeon_pm_fini(rdev); | 1067 | radeon_pm_fini(rdev); |
1067 | r600_audio_fini(rdev); | 1068 | radeon_audio_fini(rdev); |
1068 | r100_cp_fini(rdev); | 1069 | r100_cp_fini(rdev); |
1069 | radeon_wb_fini(rdev); | 1070 | radeon_wb_fini(rdev); |
1070 | radeon_ib_pool_fini(rdev); | 1071 | radeon_ib_pool_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 0a2d36e81108..516ca27cfa12 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <drm/drmP.h> | 28 | #include <drm/drmP.h> |
29 | #include "radeon.h" | 29 | #include "radeon.h" |
30 | #include "radeon_asic.h" | 30 | #include "radeon_asic.h" |
31 | #include "radeon_audio.h" | ||
31 | #include "atom.h" | 32 | #include "atom.h" |
32 | #include "rs690d.h" | 33 | #include "rs690d.h" |
33 | 34 | ||
@@ -729,7 +730,7 @@ static int rs690_startup(struct radeon_device *rdev) | |||
729 | return r; | 730 | return r; |
730 | } | 731 | } |
731 | 732 | ||
732 | r = r600_audio_init(rdev); | 733 | r = radeon_audio_init(rdev); |
733 | if (r) { | 734 | if (r) { |
734 | dev_err(rdev->dev, "failed initializing audio\n"); | 735 | dev_err(rdev->dev, "failed initializing audio\n"); |
735 | return r; | 736 | return r; |
@@ -770,7 +771,7 @@ int rs690_resume(struct radeon_device *rdev) | |||
770 | int rs690_suspend(struct radeon_device *rdev) | 771 | int rs690_suspend(struct radeon_device *rdev) |
771 | { | 772 | { |
772 | radeon_pm_suspend(rdev); | 773 | radeon_pm_suspend(rdev); |
773 | r600_audio_fini(rdev); | 774 | radeon_audio_fini(rdev); |
774 | r100_cp_disable(rdev); | 775 | r100_cp_disable(rdev); |
775 | radeon_wb_disable(rdev); | 776 | radeon_wb_disable(rdev); |
776 | rs600_irq_disable(rdev); | 777 | rs600_irq_disable(rdev); |
@@ -781,7 +782,7 @@ int rs690_suspend(struct radeon_device *rdev) | |||
781 | void rs690_fini(struct radeon_device *rdev) | 782 | void rs690_fini(struct radeon_device *rdev) |
782 | { | 783 | { |
783 | radeon_pm_fini(rdev); | 784 | radeon_pm_fini(rdev); |
784 | r600_audio_fini(rdev); | 785 | radeon_audio_fini(rdev); |
785 | r100_cp_fini(rdev); | 786 | r100_cp_fini(rdev); |
786 | radeon_wb_fini(rdev); | 787 | radeon_wb_fini(rdev); |
787 | radeon_ib_pool_fini(rdev); | 788 | radeon_ib_pool_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 372016e266d0..01ee96acb398 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <drm/drmP.h> | 30 | #include <drm/drmP.h> |
31 | #include "radeon.h" | 31 | #include "radeon.h" |
32 | #include "radeon_asic.h" | 32 | #include "radeon_asic.h" |
33 | #include "radeon_audio.h" | ||
33 | #include <drm/radeon_drm.h> | 34 | #include <drm/radeon_drm.h> |
34 | #include "rv770d.h" | 35 | #include "rv770d.h" |
35 | #include "atom.h" | 36 | #include "atom.h" |
@@ -1788,7 +1789,7 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1788 | return r; | 1789 | return r; |
1789 | } | 1790 | } |
1790 | 1791 | ||
1791 | r = r600_audio_init(rdev); | 1792 | r = radeon_audio_init(rdev); |
1792 | if (r) { | 1793 | if (r) { |
1793 | DRM_ERROR("radeon: audio init failed\n"); | 1794 | DRM_ERROR("radeon: audio init failed\n"); |
1794 | return r; | 1795 | return r; |
@@ -1829,7 +1830,7 @@ int rv770_resume(struct radeon_device *rdev) | |||
1829 | int rv770_suspend(struct radeon_device *rdev) | 1830 | int rv770_suspend(struct radeon_device *rdev) |
1830 | { | 1831 | { |
1831 | radeon_pm_suspend(rdev); | 1832 | radeon_pm_suspend(rdev); |
1832 | r600_audio_fini(rdev); | 1833 | radeon_audio_fini(rdev); |
1833 | uvd_v1_0_fini(rdev); | 1834 | uvd_v1_0_fini(rdev); |
1834 | radeon_uvd_suspend(rdev); | 1835 | radeon_uvd_suspend(rdev); |
1835 | r700_cp_stop(rdev); | 1836 | r700_cp_stop(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 755a8f96fe46..306732641b23 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -231,6 +231,7 @@ u8 rv770_get_seq_value(struct radeon_device *rdev, | |||
231 | MC_CG_SEQ_DRAMCONF_S0 : MC_CG_SEQ_DRAMCONF_S1; | 231 | MC_CG_SEQ_DRAMCONF_S0 : MC_CG_SEQ_DRAMCONF_S1; |
232 | } | 232 | } |
233 | 233 | ||
234 | #if 0 | ||
234 | int rv770_read_smc_soft_register(struct radeon_device *rdev, | 235 | int rv770_read_smc_soft_register(struct radeon_device *rdev, |
235 | u16 reg_offset, u32 *value) | 236 | u16 reg_offset, u32 *value) |
236 | { | 237 | { |
@@ -240,6 +241,7 @@ int rv770_read_smc_soft_register(struct radeon_device *rdev, | |||
240 | pi->soft_regs_start + reg_offset, | 241 | pi->soft_regs_start + reg_offset, |
241 | value, pi->sram_end); | 242 | value, pi->sram_end); |
242 | } | 243 | } |
244 | #endif | ||
243 | 245 | ||
244 | int rv770_write_smc_soft_register(struct radeon_device *rdev, | 246 | int rv770_write_smc_soft_register(struct radeon_device *rdev, |
245 | u16 reg_offset, u32 value) | 247 | u16 reg_offset, u32 value) |
@@ -2075,6 +2077,7 @@ int rv770_dpm_set_power_state(struct radeon_device *rdev) | |||
2075 | return 0; | 2077 | return 0; |
2076 | } | 2078 | } |
2077 | 2079 | ||
2080 | #if 0 | ||
2078 | void rv770_dpm_reset_asic(struct radeon_device *rdev) | 2081 | void rv770_dpm_reset_asic(struct radeon_device *rdev) |
2079 | { | 2082 | { |
2080 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | 2083 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
@@ -2087,6 +2090,7 @@ void rv770_dpm_reset_asic(struct radeon_device *rdev) | |||
2087 | if (pi->dcodt) | 2090 | if (pi->dcodt) |
2088 | rv770_program_dcodt_after_state_switch(rdev, boot_ps, boot_ps); | 2091 | rv770_program_dcodt_after_state_switch(rdev, boot_ps, boot_ps); |
2089 | } | 2092 | } |
2093 | #endif | ||
2090 | 2094 | ||
2091 | void rv770_dpm_setup_asic(struct radeon_device *rdev) | 2095 | void rv770_dpm_setup_asic(struct radeon_device *rdev) |
2092 | { | 2096 | { |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h b/drivers/gpu/drm/radeon/rv770_dpm.h index f776634840c9..d12beab7f3e6 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.h +++ b/drivers/gpu/drm/radeon/rv770_dpm.h | |||
@@ -278,8 +278,6 @@ void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, | |||
278 | void rv770_get_engine_memory_ss(struct radeon_device *rdev); | 278 | void rv770_get_engine_memory_ss(struct radeon_device *rdev); |
279 | 279 | ||
280 | /* smc */ | 280 | /* smc */ |
281 | int rv770_read_smc_soft_register(struct radeon_device *rdev, | ||
282 | u16 reg_offset, u32 *value); | ||
283 | int rv770_write_smc_soft_register(struct radeon_device *rdev, | 281 | int rv770_write_smc_soft_register(struct radeon_device *rdev, |
284 | u16 reg_offset, u32 value); | 282 | u16 reg_offset, u32 value); |
285 | 283 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 5d89b874a1a2..73107fe9e46f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <drm/drmP.h> | 27 | #include <drm/drmP.h> |
28 | #include "radeon.h" | 28 | #include "radeon.h" |
29 | #include "radeon_asic.h" | 29 | #include "radeon_asic.h" |
30 | #include "radeon_audio.h" | ||
30 | #include <drm/radeon_drm.h> | 31 | #include <drm/radeon_drm.h> |
31 | #include "sid.h" | 32 | #include "sid.h" |
32 | #include "atom.h" | 33 | #include "atom.h" |
@@ -6869,7 +6870,7 @@ static int si_startup(struct radeon_device *rdev) | |||
6869 | return r; | 6870 | return r; |
6870 | } | 6871 | } |
6871 | 6872 | ||
6872 | r = dce6_audio_init(rdev); | 6873 | r = radeon_audio_init(rdev); |
6873 | if (r) | 6874 | if (r) |
6874 | return r; | 6875 | return r; |
6875 | 6876 | ||
@@ -6908,7 +6909,7 @@ int si_resume(struct radeon_device *rdev) | |||
6908 | int si_suspend(struct radeon_device *rdev) | 6909 | int si_suspend(struct radeon_device *rdev) |
6909 | { | 6910 | { |
6910 | radeon_pm_suspend(rdev); | 6911 | radeon_pm_suspend(rdev); |
6911 | dce6_audio_fini(rdev); | 6912 | radeon_audio_fini(rdev); |
6912 | radeon_vm_manager_fini(rdev); | 6913 | radeon_vm_manager_fini(rdev); |
6913 | si_cp_enable(rdev, false); | 6914 | si_cp_enable(rdev, false); |
6914 | cayman_dma_stop(rdev); | 6915 | cayman_dma_stop(rdev); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index eff8a6444956..7be11651b7e6 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -1756,6 +1756,9 @@ static int si_calculate_sclk_params(struct radeon_device *rdev, | |||
1756 | u32 engine_clock, | 1756 | u32 engine_clock, |
1757 | SISLANDS_SMC_SCLK_VALUE *sclk); | 1757 | SISLANDS_SMC_SCLK_VALUE *sclk); |
1758 | 1758 | ||
1759 | static void si_thermal_start_smc_fan_control(struct radeon_device *rdev); | ||
1760 | static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev); | ||
1761 | |||
1759 | static struct si_power_info *si_get_pi(struct radeon_device *rdev) | 1762 | static struct si_power_info *si_get_pi(struct radeon_device *rdev) |
1760 | { | 1763 | { |
1761 | struct si_power_info *pi = rdev->pm.dpm.priv; | 1764 | struct si_power_info *pi = rdev->pm.dpm.priv; |
@@ -3359,11 +3362,13 @@ int si_dpm_force_performance_level(struct radeon_device *rdev, | |||
3359 | return 0; | 3362 | return 0; |
3360 | } | 3363 | } |
3361 | 3364 | ||
3365 | #if 0 | ||
3362 | static int si_set_boot_state(struct radeon_device *rdev) | 3366 | static int si_set_boot_state(struct radeon_device *rdev) |
3363 | { | 3367 | { |
3364 | return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ? | 3368 | return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ? |
3365 | 0 : -EINVAL; | 3369 | 0 : -EINVAL; |
3366 | } | 3370 | } |
3371 | #endif | ||
3367 | 3372 | ||
3368 | static int si_set_sw_state(struct radeon_device *rdev) | 3373 | static int si_set_sw_state(struct radeon_device *rdev) |
3369 | { | 3374 | { |
@@ -5973,6 +5978,10 @@ static int si_thermal_setup_fan_table(struct radeon_device *rdev) | |||
5973 | slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); | 5978 | slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); |
5974 | slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); | 5979 | slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); |
5975 | 5980 | ||
5981 | fan_table.temp_min = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100); | ||
5982 | fan_table.temp_med = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100); | ||
5983 | fan_table.temp_max = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100); | ||
5984 | |||
5976 | fan_table.slope1 = cpu_to_be16(slope1); | 5985 | fan_table.slope1 = cpu_to_be16(slope1); |
5977 | fan_table.slope2 = cpu_to_be16(slope2); | 5986 | fan_table.slope2 = cpu_to_be16(slope2); |
5978 | 5987 | ||
@@ -6012,29 +6021,35 @@ static int si_thermal_setup_fan_table(struct radeon_device *rdev) | |||
6012 | 6021 | ||
6013 | static int si_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) | 6022 | static int si_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) |
6014 | { | 6023 | { |
6024 | struct si_power_info *si_pi = si_get_pi(rdev); | ||
6015 | PPSMC_Result ret; | 6025 | PPSMC_Result ret; |
6016 | 6026 | ||
6017 | ret = si_send_msg_to_smc(rdev, PPSMC_StartFanControl); | 6027 | ret = si_send_msg_to_smc(rdev, PPSMC_StartFanControl); |
6018 | if (ret == PPSMC_Result_OK) | 6028 | if (ret == PPSMC_Result_OK) { |
6029 | si_pi->fan_is_controlled_by_smc = true; | ||
6019 | return 0; | 6030 | return 0; |
6020 | else | 6031 | } else { |
6021 | return -EINVAL; | 6032 | return -EINVAL; |
6033 | } | ||
6022 | } | 6034 | } |
6023 | 6035 | ||
6024 | static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) | 6036 | static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) |
6025 | { | 6037 | { |
6038 | struct si_power_info *si_pi = si_get_pi(rdev); | ||
6026 | PPSMC_Result ret; | 6039 | PPSMC_Result ret; |
6027 | 6040 | ||
6028 | ret = si_send_msg_to_smc(rdev, PPSMC_StopFanControl); | 6041 | ret = si_send_msg_to_smc(rdev, PPSMC_StopFanControl); |
6029 | if (ret == PPSMC_Result_OK) | 6042 | |
6043 | if (ret == PPSMC_Result_OK) { | ||
6044 | si_pi->fan_is_controlled_by_smc = false; | ||
6030 | return 0; | 6045 | return 0; |
6031 | else | 6046 | } else { |
6032 | return -EINVAL; | 6047 | return -EINVAL; |
6048 | } | ||
6033 | } | 6049 | } |
6034 | 6050 | ||
6035 | #if 0 | 6051 | int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, |
6036 | static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, | 6052 | u32 *speed) |
6037 | u32 *speed) | ||
6038 | { | 6053 | { |
6039 | u32 duty, duty100; | 6054 | u32 duty, duty100; |
6040 | u64 tmp64; | 6055 | u64 tmp64; |
@@ -6058,9 +6073,10 @@ static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, | |||
6058 | return 0; | 6073 | return 0; |
6059 | } | 6074 | } |
6060 | 6075 | ||
6061 | static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | 6076 | int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, |
6062 | u32 speed) | 6077 | u32 speed) |
6063 | { | 6078 | { |
6079 | struct si_power_info *si_pi = si_get_pi(rdev); | ||
6064 | u32 tmp; | 6080 | u32 tmp; |
6065 | u32 duty, duty100; | 6081 | u32 duty, duty100; |
6066 | u64 tmp64; | 6082 | u64 tmp64; |
@@ -6068,11 +6084,11 @@ static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | |||
6068 | if (rdev->pm.no_fan) | 6084 | if (rdev->pm.no_fan) |
6069 | return -ENOENT; | 6085 | return -ENOENT; |
6070 | 6086 | ||
6071 | if (speed > 100) | 6087 | if (si_pi->fan_is_controlled_by_smc) |
6072 | return -EINVAL; | 6088 | return -EINVAL; |
6073 | 6089 | ||
6074 | if (rdev->pm.dpm.fan.ucode_fan_control) | 6090 | if (speed > 100) |
6075 | si_fan_ctrl_stop_smc_fan_control(rdev); | 6091 | return -EINVAL; |
6076 | 6092 | ||
6077 | duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; | 6093 | duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; |
6078 | 6094 | ||
@@ -6087,11 +6103,38 @@ static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | |||
6087 | tmp |= FDO_STATIC_DUTY(duty); | 6103 | tmp |= FDO_STATIC_DUTY(duty); |
6088 | WREG32(CG_FDO_CTRL0, tmp); | 6104 | WREG32(CG_FDO_CTRL0, tmp); |
6089 | 6105 | ||
6090 | si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | ||
6091 | |||
6092 | return 0; | 6106 | return 0; |
6093 | } | 6107 | } |
6094 | 6108 | ||
6109 | void si_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode) | ||
6110 | { | ||
6111 | if (mode) { | ||
6112 | /* stop auto-manage */ | ||
6113 | if (rdev->pm.dpm.fan.ucode_fan_control) | ||
6114 | si_fan_ctrl_stop_smc_fan_control(rdev); | ||
6115 | si_fan_ctrl_set_static_mode(rdev, mode); | ||
6116 | } else { | ||
6117 | /* restart auto-manage */ | ||
6118 | if (rdev->pm.dpm.fan.ucode_fan_control) | ||
6119 | si_thermal_start_smc_fan_control(rdev); | ||
6120 | else | ||
6121 | si_fan_ctrl_set_default_mode(rdev); | ||
6122 | } | ||
6123 | } | ||
6124 | |||
6125 | u32 si_fan_ctrl_get_mode(struct radeon_device *rdev) | ||
6126 | { | ||
6127 | struct si_power_info *si_pi = si_get_pi(rdev); | ||
6128 | u32 tmp; | ||
6129 | |||
6130 | if (si_pi->fan_is_controlled_by_smc) | ||
6131 | return 0; | ||
6132 | |||
6133 | tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; | ||
6134 | return (tmp >> FDO_PWM_MODE_SHIFT); | ||
6135 | } | ||
6136 | |||
6137 | #if 0 | ||
6095 | static int si_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, | 6138 | static int si_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, |
6096 | u32 *speed) | 6139 | u32 *speed) |
6097 | { | 6140 | { |
@@ -6538,13 +6581,14 @@ void si_dpm_post_set_power_state(struct radeon_device *rdev) | |||
6538 | ni_update_current_ps(rdev, new_ps); | 6581 | ni_update_current_ps(rdev, new_ps); |
6539 | } | 6582 | } |
6540 | 6583 | ||
6541 | 6584 | #if 0 | |
6542 | void si_dpm_reset_asic(struct radeon_device *rdev) | 6585 | void si_dpm_reset_asic(struct radeon_device *rdev) |
6543 | { | 6586 | { |
6544 | si_restrict_performance_levels_before_switch(rdev); | 6587 | si_restrict_performance_levels_before_switch(rdev); |
6545 | si_disable_ulv(rdev); | 6588 | si_disable_ulv(rdev); |
6546 | si_set_boot_state(rdev); | 6589 | si_set_boot_state(rdev); |
6547 | } | 6590 | } |
6591 | #endif | ||
6548 | 6592 | ||
6549 | void si_dpm_display_configuration_changed(struct radeon_device *rdev) | 6593 | void si_dpm_display_configuration_changed(struct radeon_device *rdev) |
6550 | { | 6594 | { |
@@ -6912,7 +6956,6 @@ int si_dpm_init(struct radeon_device *rdev) | |||
6912 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | 6956 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; |
6913 | 6957 | ||
6914 | si_pi->fan_ctrl_is_in_default_mode = true; | 6958 | si_pi->fan_ctrl_is_in_default_mode = true; |
6915 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
6916 | 6959 | ||
6917 | return 0; | 6960 | return 0; |
6918 | } | 6961 | } |
diff --git a/drivers/gpu/drm/radeon/si_dpm.h b/drivers/gpu/drm/radeon/si_dpm.h index d16bb1b5f10f..1032a68be792 100644 --- a/drivers/gpu/drm/radeon/si_dpm.h +++ b/drivers/gpu/drm/radeon/si_dpm.h | |||
@@ -202,6 +202,7 @@ struct si_power_info { | |||
202 | bool fan_ctrl_is_in_default_mode; | 202 | bool fan_ctrl_is_in_default_mode; |
203 | u32 t_min; | 203 | u32 t_min; |
204 | u32 fan_ctrl_default_mode; | 204 | u32 fan_ctrl_default_mode; |
205 | bool fan_is_controlled_by_smc; | ||
205 | }; | 206 | }; |
206 | 207 | ||
207 | #define SISLANDS_INITIAL_STATE_ARB_INDEX 0 | 208 | #define SISLANDS_INITIAL_STATE_ARB_INDEX 0 |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 84999242c747..cbd91d226f3c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -901,6 +901,16 @@ | |||
901 | /* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */ | 901 | /* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */ |
902 | #define CRTC_STATUS_FRAME_COUNT 0x6e98 | 902 | #define CRTC_STATUS_FRAME_COUNT 0x6e98 |
903 | 903 | ||
904 | /* Audio clocks */ | ||
905 | #define DCCG_AUDIO_DTO_SOURCE 0x05ac | ||
906 | # define DCCG_AUDIO_DTO0_SOURCE_SEL(x) ((x) << 0) /* crtc0 - crtc5 */ | ||
907 | # define DCCG_AUDIO_DTO_SEL (1 << 4) /* 0=dto0 1=dto1 */ | ||
908 | |||
909 | #define DCCG_AUDIO_DTO0_PHASE 0x05b0 | ||
910 | #define DCCG_AUDIO_DTO0_MODULE 0x05b4 | ||
911 | #define DCCG_AUDIO_DTO1_PHASE 0x05b8 | ||
912 | #define DCCG_AUDIO_DTO1_MODULE 0x05bc | ||
913 | |||
904 | #define AFMT_AUDIO_SRC_CONTROL 0x713c | 914 | #define AFMT_AUDIO_SRC_CONTROL 0x713c |
905 | #define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0) | 915 | #define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0) |
906 | /* AFMT_AUDIO_SRC_SELECT | 916 | /* AFMT_AUDIO_SRC_SELECT |
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index 1f8a8833e1be..25fd4ced36c8 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c | |||
@@ -1338,6 +1338,7 @@ void sumo_dpm_post_set_power_state(struct radeon_device *rdev) | |||
1338 | sumo_update_current_ps(rdev, new_ps); | 1338 | sumo_update_current_ps(rdev, new_ps); |
1339 | } | 1339 | } |
1340 | 1340 | ||
1341 | #if 0 | ||
1341 | void sumo_dpm_reset_asic(struct radeon_device *rdev) | 1342 | void sumo_dpm_reset_asic(struct radeon_device *rdev) |
1342 | { | 1343 | { |
1343 | sumo_program_bootup_state(rdev); | 1344 | sumo_program_bootup_state(rdev); |
@@ -1349,6 +1350,7 @@ void sumo_dpm_reset_asic(struct radeon_device *rdev) | |||
1349 | sumo_set_forced_mode_enabled(rdev); | 1350 | sumo_set_forced_mode_enabled(rdev); |
1350 | sumo_set_forced_mode_disabled(rdev); | 1351 | sumo_set_forced_mode_disabled(rdev); |
1351 | } | 1352 | } |
1353 | #endif | ||
1352 | 1354 | ||
1353 | void sumo_dpm_setup_asic(struct radeon_device *rdev) | 1355 | void sumo_dpm_setup_asic(struct radeon_device *rdev) |
1354 | { | 1356 | { |
@@ -1537,6 +1539,7 @@ u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev, | |||
1537 | return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit; | 1539 | return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit; |
1538 | } | 1540 | } |
1539 | 1541 | ||
1542 | #if 0 | ||
1540 | u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev, | 1543 | u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev, |
1541 | struct sumo_vid_mapping_table *vid_mapping_table, | 1544 | struct sumo_vid_mapping_table *vid_mapping_table, |
1542 | u32 vid_7bit) | 1545 | u32 vid_7bit) |
@@ -1550,6 +1553,7 @@ u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev, | |||
1550 | 1553 | ||
1551 | return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_2bit; | 1554 | return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_2bit; |
1552 | } | 1555 | } |
1556 | #endif | ||
1553 | 1557 | ||
1554 | static u16 sumo_convert_voltage_index_to_value(struct radeon_device *rdev, | 1558 | static u16 sumo_convert_voltage_index_to_value(struct radeon_device *rdev, |
1555 | u32 vid_2bit) | 1559 | u32 vid_2bit) |
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.h b/drivers/gpu/drm/radeon/sumo_dpm.h index db1ea32a907b..07dda299c784 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.h +++ b/drivers/gpu/drm/radeon/sumo_dpm.h | |||
@@ -202,9 +202,6 @@ void sumo_construct_vid_mapping_table(struct radeon_device *rdev, | |||
202 | u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev, | 202 | u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev, |
203 | struct sumo_vid_mapping_table *vid_mapping_table, | 203 | struct sumo_vid_mapping_table *vid_mapping_table, |
204 | u32 vid_2bit); | 204 | u32 vid_2bit); |
205 | u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev, | ||
206 | struct sumo_vid_mapping_table *vid_mapping_table, | ||
207 | u32 vid_7bit); | ||
208 | u32 sumo_get_sleep_divider_from_id(u32 id); | 205 | u32 sumo_get_sleep_divider_from_id(u32 id); |
209 | u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev, | 206 | u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev, |
210 | u32 sclk, | 207 | u32 sclk, |
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index b4ec5c4e7969..38dacb7a3689 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c | |||
@@ -1269,6 +1269,7 @@ void trinity_dpm_setup_asic(struct radeon_device *rdev) | |||
1269 | trinity_release_mutex(rdev); | 1269 | trinity_release_mutex(rdev); |
1270 | } | 1270 | } |
1271 | 1271 | ||
1272 | #if 0 | ||
1272 | void trinity_dpm_reset_asic(struct radeon_device *rdev) | 1273 | void trinity_dpm_reset_asic(struct radeon_device *rdev) |
1273 | { | 1274 | { |
1274 | struct trinity_power_info *pi = trinity_get_pi(rdev); | 1275 | struct trinity_power_info *pi = trinity_get_pi(rdev); |
@@ -1284,6 +1285,7 @@ void trinity_dpm_reset_asic(struct radeon_device *rdev) | |||
1284 | } | 1285 | } |
1285 | trinity_release_mutex(rdev); | 1286 | trinity_release_mutex(rdev); |
1286 | } | 1287 | } |
1288 | #endif | ||
1287 | 1289 | ||
1288 | static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev, | 1290 | static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev, |
1289 | u32 vid_2bit) | 1291 | u32 vid_2bit) |