diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2014-11-07 13:58:11 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-11-12 11:56:44 -0500 |
commit | 90b2fee35cb9c143f049091ff7ea87500c5c7c46 (patch) | |
tree | 2534a071e41d4bc628ff580a363e6774ed6a5e73 | |
parent | 4e21518c3d635ad8cad7c07198bb3f592b25395c (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.c | 94 |
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 | ||
4102 | static 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 | |||
4102 | static int ci_initialize_mc_reg_table(struct radeon_device *rdev) | 4192 | static 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; |