aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2014-11-07 13:58:11 -0500
committerAlex Deucher <alexander.deucher@amd.com>2014-11-12 11:56:44 -0500
commit90b2fee35cb9c143f049091ff7ea87500c5c7c46 (patch)
tree2534a071e41d4bc628ff580a363e6774ed6a5e73
parent4e21518c3d635ad8cad7c07198bb3f592b25395c (diff)
drm/radeon: fix dpm mc init for certain hawaii boards
Needs special overrides for certain vram configurations. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index befa84c4a6ae..d9071aefc5f5 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -4099,6 +4099,96 @@ static int ci_copy_vbios_mc_reg_table(const struct atom_mc_reg_table *table,
4099 return 0; 4099 return 0;
4100} 4100}
4101 4101
4102static int ci_register_patching_mc_seq(struct radeon_device *rdev,
4103 struct ci_mc_reg_table *table)
4104{
4105 u8 i, k;
4106 u32 tmp;
4107 bool patch;
4108
4109 tmp = RREG32(MC_SEQ_MISC0);
4110 patch = ((tmp & 0x0000f00) == 0x300) ? true : false;
4111
4112 if (patch &&
4113 ((rdev->pdev->device == 0x67B0) ||
4114 (rdev->pdev->device == 0x67B1))) {
4115 for (i = 0; i < table->last; i++) {
4116 if (table->last >= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
4117 return -EINVAL;
4118 switch(table->mc_reg_address[i].s1 >> 2) {
4119 case MC_SEQ_MISC1:
4120 for (k = 0; k < table->num_entries; k++) {
4121 if ((table->mc_reg_table_entry[k].mclk_max == 125000) ||
4122 (table->mc_reg_table_entry[k].mclk_max == 137500))
4123 table->mc_reg_table_entry[k].mc_data[i] =
4124 (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFFFFF8) |
4125 0x00000007;
4126 }
4127 break;
4128 case MC_SEQ_WR_CTL_D0:
4129 for (k = 0; k < table->num_entries; k++) {
4130 if ((table->mc_reg_table_entry[k].mclk_max == 125000) ||
4131 (table->mc_reg_table_entry[k].mclk_max == 137500))
4132 table->mc_reg_table_entry[k].mc_data[i] =
4133 (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFF0F00) |
4134 0x0000D0DD;
4135 }
4136 break;
4137 case MC_SEQ_WR_CTL_D1:
4138 for (k = 0; k < table->num_entries; k++) {
4139 if ((table->mc_reg_table_entry[k].mclk_max == 125000) ||
4140 (table->mc_reg_table_entry[k].mclk_max == 137500))
4141 table->mc_reg_table_entry[k].mc_data[i] =
4142 (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFF0F00) |
4143 0x0000D0DD;
4144 }
4145 break;
4146 case MC_SEQ_WR_CTL_2:
4147 for (k = 0; k < table->num_entries; k++) {
4148 if ((table->mc_reg_table_entry[k].mclk_max == 125000) ||
4149 (table->mc_reg_table_entry[k].mclk_max == 137500))
4150 table->mc_reg_table_entry[k].mc_data[i] = 0;
4151 }
4152 break;
4153 case MC_SEQ_CAS_TIMING:
4154 for (k = 0; k < table->num_entries; k++) {
4155 if (table->mc_reg_table_entry[k].mclk_max == 125000)
4156 table->mc_reg_table_entry[k].mc_data[i] =
4157 (table->mc_reg_table_entry[k].mc_data[i] & 0xFFE0FE0F) |
4158 0x000C0140;
4159 else if (table->mc_reg_table_entry[k].mclk_max == 137500)
4160 table->mc_reg_table_entry[k].mc_data[i] =
4161 (table->mc_reg_table_entry[k].mc_data[i] & 0xFFE0FE0F) |
4162 0x000C0150;
4163 }
4164 break;
4165 case MC_SEQ_MISC_TIMING:
4166 for (k = 0; k < table->num_entries; k++) {
4167 if (table->mc_reg_table_entry[k].mclk_max == 125000)
4168 table->mc_reg_table_entry[k].mc_data[i] =
4169 (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFFFFE0) |
4170 0x00000030;
4171 else if (table->mc_reg_table_entry[k].mclk_max == 137500)
4172 table->mc_reg_table_entry[k].mc_data[i] =
4173 (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFFFFE0) |
4174 0x00000035;
4175 }
4176 break;
4177 default:
4178 break;
4179 }
4180 }
4181
4182 WREG32(MC_SEQ_IO_DEBUG_INDEX, 3);
4183 tmp = RREG32(MC_SEQ_IO_DEBUG_DATA);
4184 tmp = (tmp & 0xFFF8FFFF) | (1 << 16);
4185 WREG32(MC_SEQ_IO_DEBUG_INDEX, 3);
4186 WREG32(MC_SEQ_IO_DEBUG_DATA, tmp);
4187 }
4188
4189 return 0;
4190}
4191
4102static int ci_initialize_mc_reg_table(struct radeon_device *rdev) 4192static int ci_initialize_mc_reg_table(struct radeon_device *rdev)
4103{ 4193{
4104 struct ci_power_info *pi = ci_get_pi(rdev); 4194 struct ci_power_info *pi = ci_get_pi(rdev);
@@ -4142,6 +4232,10 @@ static int ci_initialize_mc_reg_table(struct radeon_device *rdev)
4142 4232
4143 ci_set_s0_mc_reg_index(ci_table); 4233 ci_set_s0_mc_reg_index(ci_table);
4144 4234
4235 ret = ci_register_patching_mc_seq(rdev, ci_table);
4236 if (ret)
4237 goto init_mc_done;
4238
4145 ret = ci_set_mc_special_registers(rdev, ci_table); 4239 ret = ci_set_mc_special_registers(rdev, ci_table);
4146 if (ret) 4240 if (ret)
4147 goto init_mc_done; 4241 goto init_mc_done;