Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: fix incorrect CM/TF programming sequence in dwb

[How]
the programming sequeune was for old asic.
the correct programming sequeunce should be similar to the one
used in mpc. the fix is copied from the mpc programming sequeunce.

Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Anson Jacob <Anson.Jacob@amd.com>
Signed-off-by: Roy Chan <roy.chan@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Roy Chan and committed by
Alex Deucher
781e1e23 4fd771ea

+64 -26
+64 -26
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
··· 49 49 static void dwb3_get_reg_field_ogam(struct dcn30_dwbc *dwbc30, 50 50 struct dcn3_xfer_func_reg *reg) 51 51 { 52 + reg->shifts.field_region_start_base = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION_START_BASE_B; 53 + reg->masks.field_region_start_base = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION_START_BASE_B; 54 + reg->shifts.field_offset = dwbc30->dwbc_shift->DWB_OGAM_RAMA_OFFSET_B; 55 + reg->masks.field_offset = dwbc30->dwbc_mask->DWB_OGAM_RAMA_OFFSET_B; 56 + 52 57 reg->shifts.exp_region0_lut_offset = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION0_LUT_OFFSET; 53 58 reg->masks.exp_region0_lut_offset = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION0_LUT_OFFSET; 54 59 reg->shifts.exp_region0_num_segments = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; ··· 71 66 reg->masks.field_region_end_base = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION_END_BASE_B; 72 67 reg->shifts.field_region_linear_slope = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION_START_SLOPE_B; 73 68 reg->masks.field_region_linear_slope = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION_START_SLOPE_B; 74 - reg->masks.field_offset = dwbc30->dwbc_mask->DWB_OGAM_RAMA_OFFSET_B; 75 - reg->shifts.field_offset = dwbc30->dwbc_shift->DWB_OGAM_RAMA_OFFSET_B; 76 69 reg->shifts.exp_region_start = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION_START_B; 77 70 reg->masks.exp_region_start = dwbc30->dwbc_mask->DWB_OGAM_RAMA_EXP_REGION_START_B; 78 71 reg->shifts.exp_resion_start_segment = dwbc30->dwbc_shift->DWB_OGAM_RAMA_EXP_REGION_START_SEGMENT_B; ··· 150 147 uint32_t state_mode; 151 148 uint32_t ram_select; 152 149 153 - REG_GET(DWB_OGAM_CONTROL, 154 - DWB_OGAM_MODE, &state_mode); 155 - REG_GET(DWB_OGAM_CONTROL, 156 - DWB_OGAM_SELECT, &ram_select); 150 + REG_GET_2(DWB_OGAM_CONTROL, 151 + DWB_OGAM_MODE_CURRENT, &state_mode, 152 + DWB_OGAM_SELECT_CURRENT, &ram_select); 157 153 158 154 if (state_mode == 0) { 159 155 mode = LUT_BYPASS; 160 156 } else if (state_mode == 2) { 161 157 if (ram_select == 0) 162 158 mode = LUT_RAM_A; 163 - else 159 + else if (ram_select == 1) 164 160 mode = LUT_RAM_B; 161 + else 162 + mode = LUT_BYPASS; 165 163 } else { 166 164 // Reserved value 167 165 mode = LUT_BYPASS; ··· 176 172 struct dcn30_dwbc *dwbc30, 177 173 bool is_ram_a) 178 174 { 179 - REG_UPDATE(DWB_OGAM_LUT_CONTROL, 180 - DWB_OGAM_LUT_READ_COLOR_SEL, 7); 181 - REG_UPDATE(DWB_OGAM_CONTROL, 182 - DWB_OGAM_SELECT, is_ram_a == true ? 0 : 1); 175 + REG_UPDATE_2(DWB_OGAM_LUT_CONTROL, 176 + DWB_OGAM_LUT_WRITE_COLOR_MASK, 7, 177 + DWB_OGAM_LUT_HOST_SEL, (is_ram_a == true) ? 0 : 1); 178 + 183 179 REG_SET(DWB_OGAM_LUT_INDEX, 0, DWB_OGAM_LUT_INDEX, 0); 184 180 } 185 181 ··· 189 185 { 190 186 uint32_t i; 191 187 192 - // triple base implementation 193 - for (i = 0; i < num/2; i++) { 194 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+0].red_reg); 195 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+0].green_reg); 196 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+0].blue_reg); 197 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+1].red_reg); 198 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+1].green_reg); 199 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+1].blue_reg); 200 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+2].red_reg); 201 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+2].green_reg); 202 - REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[2*i+2].blue_reg); 188 + uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg; 189 + uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg; 190 + uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg; 191 + 192 + if (is_rgb_equal(rgb, num)) { 193 + for (i = 0 ; i < num; i++) 194 + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[i].red_reg); 195 + 196 + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, last_base_value_red); 197 + 198 + } else { 199 + 200 + REG_UPDATE(DWB_OGAM_LUT_CONTROL, 201 + DWB_OGAM_LUT_WRITE_COLOR_MASK, 4); 202 + 203 + for (i = 0 ; i < num; i++) 204 + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[i].red_reg); 205 + 206 + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, last_base_value_red); 207 + 208 + REG_SET(DWB_OGAM_LUT_INDEX, 0, DWB_OGAM_LUT_INDEX, 0); 209 + 210 + REG_UPDATE(DWB_OGAM_LUT_CONTROL, 211 + DWB_OGAM_LUT_WRITE_COLOR_MASK, 2); 212 + 213 + for (i = 0 ; i < num; i++) 214 + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[i].green_reg); 215 + 216 + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, last_base_value_green); 217 + 218 + REG_SET(DWB_OGAM_LUT_INDEX, 0, DWB_OGAM_LUT_INDEX, 0); 219 + 220 + REG_UPDATE(DWB_OGAM_LUT_CONTROL, 221 + DWB_OGAM_LUT_WRITE_COLOR_MASK, 1); 222 + 223 + for (i = 0 ; i < num; i++) 224 + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, rgb[i].blue_reg); 225 + 226 + REG_SET(DWB_OGAM_LUT_DATA, 0, DWB_OGAM_LUT_DATA, last_base_value_blue); 203 227 } 204 228 } 205 229 ··· 242 210 REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_MODE, 0); 243 211 return false; 244 212 } 213 + 214 + REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_MODE, 2); 245 215 246 216 current_mode = dwb3_get_ogam_current(dwbc30); 247 217 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) ··· 261 227 dwb3_program_ogam_pwl( 262 228 dwbc30, params->rgb_resulted, params->hw_points_num); 263 229 264 - REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_MODE, 2); 265 - REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_SELECT, next_mode == LUT_RAM_A ? 0 : 1); 230 + REG_UPDATE(DWB_OGAM_CONTROL, DWB_OGAM_SELECT, next_mode == LUT_RAM_A ? 0 : 1); 266 231 267 232 return true; 268 233 } ··· 304 271 305 272 struct color_matrices_reg gam_regs; 306 273 307 - REG_UPDATE(DWB_GAMUT_REMAP_COEF_FORMAT, DWB_GAMUT_REMAP_COEF_FORMAT, coef_format); 308 - 309 274 if (regval == NULL || select == CM_GAMUT_REMAP_MODE_BYPASS) { 310 275 REG_SET(DWB_GAMUT_REMAP_MODE, 0, 311 276 DWB_GAMUT_REMAP_MODE, 0); 312 277 return; 313 278 } 279 + 280 + REG_UPDATE(DWB_GAMUT_REMAP_COEF_FORMAT, DWB_GAMUT_REMAP_COEF_FORMAT, coef_format); 281 + 282 + gam_regs.shifts.csc_c11 = dwbc30->dwbc_shift->DWB_GAMUT_REMAPA_C11; 283 + gam_regs.masks.csc_c11 = dwbc30->dwbc_mask->DWB_GAMUT_REMAPA_C11; 284 + gam_regs.shifts.csc_c12 = dwbc30->dwbc_shift->DWB_GAMUT_REMAPA_C12; 285 + gam_regs.masks.csc_c12 = dwbc30->dwbc_mask->DWB_GAMUT_REMAPA_C12; 314 286 315 287 switch (select) { 316 288 case CM_GAMUT_REMAP_MODE_RAMA_COEFF: