0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include "power_helpers.h"
0026 #include "dc/inc/hw/dmcu.h"
0027 #include "dc/inc/hw/abm.h"
0028 #include "dc.h"
0029 #include "core_types.h"
0030 #include "dmub_cmd.h"
0031
0032 #define DIV_ROUNDUP(a, b) (((a)+((b)/2))/(b))
0033 #define bswap16_based_on_endian(big_endian, value) \
0034 (big_endian) ? cpu_to_be16(value) : cpu_to_le16(value)
0035
0036
0037
0038
0039
0040 static const unsigned char min_reduction_table[13] = {
0041 0xff, 0xfa, 0xf0, 0xf0, 0xd9, 0xcd, 0xc0, 0xb1, 0x99, 0x93, 0x80, 0x82, 0x66};
0042
0043
0044
0045
0046
0047 static const unsigned char max_reduction_table[13] = {
0048 0xf5, 0xe5, 0xd9, 0xcd, 0xb1, 0xa5, 0xa5, 0x80, 0x65, 0x4d, 0x4d, 0x4d, 0x32};
0049
0050
0051
0052
0053
0054 static const unsigned char min_reduction_table_v_2_2[13] = {
0055 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xd4, 0xc0, 0xc0};
0056
0057
0058
0059
0060
0061 static const unsigned char max_reduction_table_v_2_2[13] = {
0062 0xf5, 0xe5, 0xbf, 0xb1, 0xa5, 0x85, 0x7c, 0x65, 0x4d, 0x40, 0x32, 0x20, 0x20};
0063
0064
0065
0066
0067 static const unsigned char abm_config[abm_defines_max_config][abm_defines_max_level] = {
0068
0069 { 2, 5, 7, 8 },
0070 { 2, 5, 8, 11 },
0071 { 0, 2, 4, 8 },
0072 { 3, 6, 10, 12 },
0073 };
0074
0075 struct abm_parameters {
0076 unsigned char min_reduction;
0077 unsigned char max_reduction;
0078 unsigned char bright_pos_gain;
0079 unsigned char dark_pos_gain;
0080 unsigned char brightness_gain;
0081 unsigned char contrast_factor;
0082 unsigned char deviation_gain;
0083 unsigned char min_knee;
0084 unsigned char max_knee;
0085 unsigned short blRampReduction;
0086 unsigned short blRampStart;
0087 };
0088
0089 static const struct abm_parameters abm_settings_config0[abm_defines_max_level] = {
0090
0091 {0xff, 0xbf, 0x20, 0x00, 0xff, 0x99, 0xb3, 0x40, 0xe0, 0xf777, 0xcccc},
0092 {0xde, 0x85, 0x20, 0x00, 0xe0, 0x90, 0xa8, 0x40, 0xc8, 0xf777, 0xcccc},
0093 {0xb0, 0x50, 0x20, 0x00, 0xc0, 0x88, 0x78, 0x70, 0xa0, 0xeeee, 0x9999},
0094 {0x82, 0x40, 0x20, 0x00, 0x00, 0xb8, 0xb3, 0x70, 0x70, 0xe333, 0xb333},
0095 };
0096
0097 static const struct abm_parameters abm_settings_config1[abm_defines_max_level] = {
0098
0099 {0xf0, 0xd9, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
0100 {0xcd, 0xa5, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
0101 {0x99, 0x65, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
0102 {0x82, 0x4d, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
0103 };
0104
0105 static const struct abm_parameters * const abm_settings[] = {
0106 abm_settings_config0,
0107 abm_settings_config1,
0108 };
0109
0110 #define NUM_AMBI_LEVEL 5
0111 #define NUM_AGGR_LEVEL 4
0112 #define NUM_POWER_FN_SEGS 8
0113 #define NUM_BL_CURVE_SEGS 16
0114 #define IRAM_SIZE 256
0115
0116 #define IRAM_RESERVE_AREA_START_V2 0xF0
0117 #define IRAM_RESERVE_AREA_END_V2 0xF6
0118
0119 #define IRAM_RESERVE_AREA_START_V2_2 0xF0
0120 #define IRAM_RESERVE_AREA_END_V2_2 0xFF
0121
0122 #pragma pack(push, 1)
0123
0124 struct iram_table_v_2 {
0125
0126 uint16_t min_abm_backlight;
0127
0128
0129 uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0130 uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0131 uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0132 uint8_t bright_neg_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0133 uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0134 uint8_t dark_neg_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0135 uint8_t iir_curve[NUM_AMBI_LEVEL];
0136 uint8_t deviation_gain;
0137
0138
0139 uint16_t crgb_thresh[NUM_POWER_FN_SEGS];
0140 uint16_t crgb_offset[NUM_POWER_FN_SEGS];
0141 uint16_t crgb_slope[NUM_POWER_FN_SEGS];
0142
0143
0144
0145 uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS];
0146
0147 uint16_t backlight_offsets[NUM_BL_CURVE_SEGS];
0148
0149
0150 uint8_t psr_state;
0151 uint8_t dmcu_mcp_interface_version;
0152 uint8_t dmcu_abm_feature_version;
0153 uint8_t dmcu_psr_feature_version;
0154 uint16_t dmcu_version;
0155 uint8_t dmcu_state;
0156
0157 uint16_t blRampReduction;
0158 uint16_t blRampStart;
0159 uint8_t dummy5;
0160 uint8_t dummy6;
0161 uint8_t dummy7;
0162 uint8_t dummy8;
0163 uint8_t dummy9;
0164 };
0165
0166 struct iram_table_v_2_2 {
0167
0168 uint16_t flags;
0169
0170
0171 uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0172 uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0173 uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0174 uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];
0175 uint8_t hybrid_factor[NUM_AGGR_LEVEL];
0176 uint8_t contrast_factor[NUM_AGGR_LEVEL];
0177 uint8_t deviation_gain[NUM_AGGR_LEVEL];
0178 uint8_t iir_curve[NUM_AMBI_LEVEL];
0179 uint8_t min_knee[NUM_AGGR_LEVEL];
0180 uint8_t max_knee[NUM_AGGR_LEVEL];
0181 uint16_t min_abm_backlight;
0182 uint8_t pad[19];
0183
0184
0185 uint16_t crgb_thresh[NUM_POWER_FN_SEGS];
0186 uint16_t crgb_offset[NUM_POWER_FN_SEGS];
0187 uint16_t crgb_slope[NUM_POWER_FN_SEGS];
0188
0189
0190
0191 uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS];
0192
0193 uint16_t backlight_offsets[NUM_BL_CURVE_SEGS];
0194
0195
0196 uint8_t psr_state;
0197 uint8_t dmcu_mcp_interface_version;
0198 uint8_t dmcu_abm_feature_version;
0199 uint8_t dmcu_psr_feature_version;
0200 uint16_t dmcu_version;
0201 uint8_t dmcu_state;
0202
0203 uint8_t dummy1;
0204 uint8_t dummy2;
0205 uint8_t dummy3;
0206 uint8_t dummy4;
0207 uint8_t dummy5;
0208 uint8_t dummy6;
0209 uint8_t dummy7;
0210 uint8_t dummy8;
0211 uint8_t dummy9;
0212 };
0213 #pragma pack(pop)
0214
0215 static void fill_backlight_transform_table(struct dmcu_iram_parameters params,
0216 struct iram_table_v_2 *table)
0217 {
0218 unsigned int i;
0219 unsigned int num_entries = NUM_BL_CURVE_SEGS;
0220 unsigned int lut_index;
0221
0222 table->backlight_thresholds[0] = 0;
0223 table->backlight_offsets[0] = params.backlight_lut_array[0];
0224 table->backlight_thresholds[num_entries-1] = 0xFFFF;
0225 table->backlight_offsets[num_entries-1] =
0226 params.backlight_lut_array[params.backlight_lut_array_size - 1];
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236 for (i = 1; i+1 < num_entries; i++) {
0237 lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1);
0238 ASSERT(lut_index < params.backlight_lut_array_size);
0239
0240 table->backlight_thresholds[i] =
0241 cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries));
0242 table->backlight_offsets[i] =
0243 cpu_to_be16(params.backlight_lut_array[lut_index]);
0244 }
0245 }
0246
0247 static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters params,
0248 struct iram_table_v_2_2 *table, bool big_endian)
0249 {
0250 unsigned int i;
0251 unsigned int num_entries = NUM_BL_CURVE_SEGS;
0252 unsigned int lut_index;
0253
0254 table->backlight_thresholds[0] = 0;
0255 table->backlight_offsets[0] = params.backlight_lut_array[0];
0256 table->backlight_thresholds[num_entries-1] = 0xFFFF;
0257 table->backlight_offsets[num_entries-1] =
0258 params.backlight_lut_array[params.backlight_lut_array_size - 1];
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 for (i = 1; i+1 < num_entries; i++) {
0269 lut_index = DIV_ROUNDUP((i * params.backlight_lut_array_size), num_entries);
0270 ASSERT(lut_index < params.backlight_lut_array_size);
0271
0272 table->backlight_thresholds[i] = (big_endian) ?
0273 cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)) :
0274 cpu_to_le16(DIV_ROUNDUP((i * 65536), num_entries));
0275 table->backlight_offsets[i] = (big_endian) ?
0276 cpu_to_be16(params.backlight_lut_array[lut_index]) :
0277 cpu_to_le16(params.backlight_lut_array[lut_index]);
0278 }
0279 }
0280
0281 static void fill_iram_v_2(struct iram_table_v_2 *ram_table, struct dmcu_iram_parameters params)
0282 {
0283 unsigned int set = params.set;
0284
0285 ram_table->min_abm_backlight =
0286 cpu_to_be16(params.min_abm_backlight);
0287 ram_table->deviation_gain = 0xb3;
0288
0289 ram_table->blRampReduction =
0290 cpu_to_be16(params.backlight_ramping_reduction);
0291 ram_table->blRampStart =
0292 cpu_to_be16(params.backlight_ramping_start);
0293
0294 ram_table->min_reduction[0][0] = min_reduction_table[abm_config[set][0]];
0295 ram_table->min_reduction[1][0] = min_reduction_table[abm_config[set][0]];
0296 ram_table->min_reduction[2][0] = min_reduction_table[abm_config[set][0]];
0297 ram_table->min_reduction[3][0] = min_reduction_table[abm_config[set][0]];
0298 ram_table->min_reduction[4][0] = min_reduction_table[abm_config[set][0]];
0299 ram_table->max_reduction[0][0] = max_reduction_table[abm_config[set][0]];
0300 ram_table->max_reduction[1][0] = max_reduction_table[abm_config[set][0]];
0301 ram_table->max_reduction[2][0] = max_reduction_table[abm_config[set][0]];
0302 ram_table->max_reduction[3][0] = max_reduction_table[abm_config[set][0]];
0303 ram_table->max_reduction[4][0] = max_reduction_table[abm_config[set][0]];
0304
0305 ram_table->min_reduction[0][1] = min_reduction_table[abm_config[set][1]];
0306 ram_table->min_reduction[1][1] = min_reduction_table[abm_config[set][1]];
0307 ram_table->min_reduction[2][1] = min_reduction_table[abm_config[set][1]];
0308 ram_table->min_reduction[3][1] = min_reduction_table[abm_config[set][1]];
0309 ram_table->min_reduction[4][1] = min_reduction_table[abm_config[set][1]];
0310 ram_table->max_reduction[0][1] = max_reduction_table[abm_config[set][1]];
0311 ram_table->max_reduction[1][1] = max_reduction_table[abm_config[set][1]];
0312 ram_table->max_reduction[2][1] = max_reduction_table[abm_config[set][1]];
0313 ram_table->max_reduction[3][1] = max_reduction_table[abm_config[set][1]];
0314 ram_table->max_reduction[4][1] = max_reduction_table[abm_config[set][1]];
0315
0316 ram_table->min_reduction[0][2] = min_reduction_table[abm_config[set][2]];
0317 ram_table->min_reduction[1][2] = min_reduction_table[abm_config[set][2]];
0318 ram_table->min_reduction[2][2] = min_reduction_table[abm_config[set][2]];
0319 ram_table->min_reduction[3][2] = min_reduction_table[abm_config[set][2]];
0320 ram_table->min_reduction[4][2] = min_reduction_table[abm_config[set][2]];
0321 ram_table->max_reduction[0][2] = max_reduction_table[abm_config[set][2]];
0322 ram_table->max_reduction[1][2] = max_reduction_table[abm_config[set][2]];
0323 ram_table->max_reduction[2][2] = max_reduction_table[abm_config[set][2]];
0324 ram_table->max_reduction[3][2] = max_reduction_table[abm_config[set][2]];
0325 ram_table->max_reduction[4][2] = max_reduction_table[abm_config[set][2]];
0326
0327 ram_table->min_reduction[0][3] = min_reduction_table[abm_config[set][3]];
0328 ram_table->min_reduction[1][3] = min_reduction_table[abm_config[set][3]];
0329 ram_table->min_reduction[2][3] = min_reduction_table[abm_config[set][3]];
0330 ram_table->min_reduction[3][3] = min_reduction_table[abm_config[set][3]];
0331 ram_table->min_reduction[4][3] = min_reduction_table[abm_config[set][3]];
0332 ram_table->max_reduction[0][3] = max_reduction_table[abm_config[set][3]];
0333 ram_table->max_reduction[1][3] = max_reduction_table[abm_config[set][3]];
0334 ram_table->max_reduction[2][3] = max_reduction_table[abm_config[set][3]];
0335 ram_table->max_reduction[3][3] = max_reduction_table[abm_config[set][3]];
0336 ram_table->max_reduction[4][3] = max_reduction_table[abm_config[set][3]];
0337
0338 ram_table->bright_pos_gain[0][0] = 0x20;
0339 ram_table->bright_pos_gain[0][1] = 0x20;
0340 ram_table->bright_pos_gain[0][2] = 0x20;
0341 ram_table->bright_pos_gain[0][3] = 0x20;
0342 ram_table->bright_pos_gain[1][0] = 0x20;
0343 ram_table->bright_pos_gain[1][1] = 0x20;
0344 ram_table->bright_pos_gain[1][2] = 0x20;
0345 ram_table->bright_pos_gain[1][3] = 0x20;
0346 ram_table->bright_pos_gain[2][0] = 0x20;
0347 ram_table->bright_pos_gain[2][1] = 0x20;
0348 ram_table->bright_pos_gain[2][2] = 0x20;
0349 ram_table->bright_pos_gain[2][3] = 0x20;
0350 ram_table->bright_pos_gain[3][0] = 0x20;
0351 ram_table->bright_pos_gain[3][1] = 0x20;
0352 ram_table->bright_pos_gain[3][2] = 0x20;
0353 ram_table->bright_pos_gain[3][3] = 0x20;
0354 ram_table->bright_pos_gain[4][0] = 0x20;
0355 ram_table->bright_pos_gain[4][1] = 0x20;
0356 ram_table->bright_pos_gain[4][2] = 0x20;
0357 ram_table->bright_pos_gain[4][3] = 0x20;
0358 ram_table->bright_neg_gain[0][0] = 0x00;
0359 ram_table->bright_neg_gain[0][1] = 0x00;
0360 ram_table->bright_neg_gain[0][2] = 0x00;
0361 ram_table->bright_neg_gain[0][3] = 0x00;
0362 ram_table->bright_neg_gain[1][0] = 0x00;
0363 ram_table->bright_neg_gain[1][1] = 0x00;
0364 ram_table->bright_neg_gain[1][2] = 0x00;
0365 ram_table->bright_neg_gain[1][3] = 0x00;
0366 ram_table->bright_neg_gain[2][0] = 0x00;
0367 ram_table->bright_neg_gain[2][1] = 0x00;
0368 ram_table->bright_neg_gain[2][2] = 0x00;
0369 ram_table->bright_neg_gain[2][3] = 0x00;
0370 ram_table->bright_neg_gain[3][0] = 0x00;
0371 ram_table->bright_neg_gain[3][1] = 0x00;
0372 ram_table->bright_neg_gain[3][2] = 0x00;
0373 ram_table->bright_neg_gain[3][3] = 0x00;
0374 ram_table->bright_neg_gain[4][0] = 0x00;
0375 ram_table->bright_neg_gain[4][1] = 0x00;
0376 ram_table->bright_neg_gain[4][2] = 0x00;
0377 ram_table->bright_neg_gain[4][3] = 0x00;
0378 ram_table->dark_pos_gain[0][0] = 0x00;
0379 ram_table->dark_pos_gain[0][1] = 0x00;
0380 ram_table->dark_pos_gain[0][2] = 0x00;
0381 ram_table->dark_pos_gain[0][3] = 0x00;
0382 ram_table->dark_pos_gain[1][0] = 0x00;
0383 ram_table->dark_pos_gain[1][1] = 0x00;
0384 ram_table->dark_pos_gain[1][2] = 0x00;
0385 ram_table->dark_pos_gain[1][3] = 0x00;
0386 ram_table->dark_pos_gain[2][0] = 0x00;
0387 ram_table->dark_pos_gain[2][1] = 0x00;
0388 ram_table->dark_pos_gain[2][2] = 0x00;
0389 ram_table->dark_pos_gain[2][3] = 0x00;
0390 ram_table->dark_pos_gain[3][0] = 0x00;
0391 ram_table->dark_pos_gain[3][1] = 0x00;
0392 ram_table->dark_pos_gain[3][2] = 0x00;
0393 ram_table->dark_pos_gain[3][3] = 0x00;
0394 ram_table->dark_pos_gain[4][0] = 0x00;
0395 ram_table->dark_pos_gain[4][1] = 0x00;
0396 ram_table->dark_pos_gain[4][2] = 0x00;
0397 ram_table->dark_pos_gain[4][3] = 0x00;
0398 ram_table->dark_neg_gain[0][0] = 0x00;
0399 ram_table->dark_neg_gain[0][1] = 0x00;
0400 ram_table->dark_neg_gain[0][2] = 0x00;
0401 ram_table->dark_neg_gain[0][3] = 0x00;
0402 ram_table->dark_neg_gain[1][0] = 0x00;
0403 ram_table->dark_neg_gain[1][1] = 0x00;
0404 ram_table->dark_neg_gain[1][2] = 0x00;
0405 ram_table->dark_neg_gain[1][3] = 0x00;
0406 ram_table->dark_neg_gain[2][0] = 0x00;
0407 ram_table->dark_neg_gain[2][1] = 0x00;
0408 ram_table->dark_neg_gain[2][2] = 0x00;
0409 ram_table->dark_neg_gain[2][3] = 0x00;
0410 ram_table->dark_neg_gain[3][0] = 0x00;
0411 ram_table->dark_neg_gain[3][1] = 0x00;
0412 ram_table->dark_neg_gain[3][2] = 0x00;
0413 ram_table->dark_neg_gain[3][3] = 0x00;
0414 ram_table->dark_neg_gain[4][0] = 0x00;
0415 ram_table->dark_neg_gain[4][1] = 0x00;
0416 ram_table->dark_neg_gain[4][2] = 0x00;
0417 ram_table->dark_neg_gain[4][3] = 0x00;
0418
0419 ram_table->iir_curve[0] = 0x65;
0420 ram_table->iir_curve[1] = 0x65;
0421 ram_table->iir_curve[2] = 0x65;
0422 ram_table->iir_curve[3] = 0x65;
0423 ram_table->iir_curve[4] = 0x65;
0424
0425
0426 ram_table->crgb_thresh[0] = cpu_to_be16(0x13b6);
0427 ram_table->crgb_thresh[1] = cpu_to_be16(0x1648);
0428 ram_table->crgb_thresh[2] = cpu_to_be16(0x18e3);
0429 ram_table->crgb_thresh[3] = cpu_to_be16(0x1b41);
0430 ram_table->crgb_thresh[4] = cpu_to_be16(0x1d46);
0431 ram_table->crgb_thresh[5] = cpu_to_be16(0x1f21);
0432 ram_table->crgb_thresh[6] = cpu_to_be16(0x2167);
0433 ram_table->crgb_thresh[7] = cpu_to_be16(0x2384);
0434 ram_table->crgb_offset[0] = cpu_to_be16(0x2999);
0435 ram_table->crgb_offset[1] = cpu_to_be16(0x3999);
0436 ram_table->crgb_offset[2] = cpu_to_be16(0x4666);
0437 ram_table->crgb_offset[3] = cpu_to_be16(0x5999);
0438 ram_table->crgb_offset[4] = cpu_to_be16(0x6333);
0439 ram_table->crgb_offset[5] = cpu_to_be16(0x7800);
0440 ram_table->crgb_offset[6] = cpu_to_be16(0x8c00);
0441 ram_table->crgb_offset[7] = cpu_to_be16(0xa000);
0442 ram_table->crgb_slope[0] = cpu_to_be16(0x3147);
0443 ram_table->crgb_slope[1] = cpu_to_be16(0x2978);
0444 ram_table->crgb_slope[2] = cpu_to_be16(0x23a2);
0445 ram_table->crgb_slope[3] = cpu_to_be16(0x1f55);
0446 ram_table->crgb_slope[4] = cpu_to_be16(0x1c63);
0447 ram_table->crgb_slope[5] = cpu_to_be16(0x1a0f);
0448 ram_table->crgb_slope[6] = cpu_to_be16(0x178d);
0449 ram_table->crgb_slope[7] = cpu_to_be16(0x15ab);
0450
0451 fill_backlight_transform_table(
0452 params, ram_table);
0453 }
0454
0455 static void fill_iram_v_2_2(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params)
0456 {
0457 unsigned int set = params.set;
0458
0459 ram_table->flags = 0x0;
0460
0461 ram_table->min_abm_backlight =
0462 cpu_to_be16(params.min_abm_backlight);
0463
0464 ram_table->deviation_gain[0] = 0xb3;
0465 ram_table->deviation_gain[1] = 0xa8;
0466 ram_table->deviation_gain[2] = 0x98;
0467 ram_table->deviation_gain[3] = 0x68;
0468
0469 ram_table->min_reduction[0][0] = min_reduction_table_v_2_2[abm_config[set][0]];
0470 ram_table->min_reduction[1][0] = min_reduction_table_v_2_2[abm_config[set][0]];
0471 ram_table->min_reduction[2][0] = min_reduction_table_v_2_2[abm_config[set][0]];
0472 ram_table->min_reduction[3][0] = min_reduction_table_v_2_2[abm_config[set][0]];
0473 ram_table->min_reduction[4][0] = min_reduction_table_v_2_2[abm_config[set][0]];
0474 ram_table->max_reduction[0][0] = max_reduction_table_v_2_2[abm_config[set][0]];
0475 ram_table->max_reduction[1][0] = max_reduction_table_v_2_2[abm_config[set][0]];
0476 ram_table->max_reduction[2][0] = max_reduction_table_v_2_2[abm_config[set][0]];
0477 ram_table->max_reduction[3][0] = max_reduction_table_v_2_2[abm_config[set][0]];
0478 ram_table->max_reduction[4][0] = max_reduction_table_v_2_2[abm_config[set][0]];
0479
0480 ram_table->min_reduction[0][1] = min_reduction_table_v_2_2[abm_config[set][1]];
0481 ram_table->min_reduction[1][1] = min_reduction_table_v_2_2[abm_config[set][1]];
0482 ram_table->min_reduction[2][1] = min_reduction_table_v_2_2[abm_config[set][1]];
0483 ram_table->min_reduction[3][1] = min_reduction_table_v_2_2[abm_config[set][1]];
0484 ram_table->min_reduction[4][1] = min_reduction_table_v_2_2[abm_config[set][1]];
0485 ram_table->max_reduction[0][1] = max_reduction_table_v_2_2[abm_config[set][1]];
0486 ram_table->max_reduction[1][1] = max_reduction_table_v_2_2[abm_config[set][1]];
0487 ram_table->max_reduction[2][1] = max_reduction_table_v_2_2[abm_config[set][1]];
0488 ram_table->max_reduction[3][1] = max_reduction_table_v_2_2[abm_config[set][1]];
0489 ram_table->max_reduction[4][1] = max_reduction_table_v_2_2[abm_config[set][1]];
0490
0491 ram_table->min_reduction[0][2] = min_reduction_table_v_2_2[abm_config[set][2]];
0492 ram_table->min_reduction[1][2] = min_reduction_table_v_2_2[abm_config[set][2]];
0493 ram_table->min_reduction[2][2] = min_reduction_table_v_2_2[abm_config[set][2]];
0494 ram_table->min_reduction[3][2] = min_reduction_table_v_2_2[abm_config[set][2]];
0495 ram_table->min_reduction[4][2] = min_reduction_table_v_2_2[abm_config[set][2]];
0496 ram_table->max_reduction[0][2] = max_reduction_table_v_2_2[abm_config[set][2]];
0497 ram_table->max_reduction[1][2] = max_reduction_table_v_2_2[abm_config[set][2]];
0498 ram_table->max_reduction[2][2] = max_reduction_table_v_2_2[abm_config[set][2]];
0499 ram_table->max_reduction[3][2] = max_reduction_table_v_2_2[abm_config[set][2]];
0500 ram_table->max_reduction[4][2] = max_reduction_table_v_2_2[abm_config[set][2]];
0501
0502 ram_table->min_reduction[0][3] = min_reduction_table_v_2_2[abm_config[set][3]];
0503 ram_table->min_reduction[1][3] = min_reduction_table_v_2_2[abm_config[set][3]];
0504 ram_table->min_reduction[2][3] = min_reduction_table_v_2_2[abm_config[set][3]];
0505 ram_table->min_reduction[3][3] = min_reduction_table_v_2_2[abm_config[set][3]];
0506 ram_table->min_reduction[4][3] = min_reduction_table_v_2_2[abm_config[set][3]];
0507 ram_table->max_reduction[0][3] = max_reduction_table_v_2_2[abm_config[set][3]];
0508 ram_table->max_reduction[1][3] = max_reduction_table_v_2_2[abm_config[set][3]];
0509 ram_table->max_reduction[2][3] = max_reduction_table_v_2_2[abm_config[set][3]];
0510 ram_table->max_reduction[3][3] = max_reduction_table_v_2_2[abm_config[set][3]];
0511 ram_table->max_reduction[4][3] = max_reduction_table_v_2_2[abm_config[set][3]];
0512
0513 ram_table->bright_pos_gain[0][0] = 0x20;
0514 ram_table->bright_pos_gain[0][1] = 0x20;
0515 ram_table->bright_pos_gain[0][2] = 0x20;
0516 ram_table->bright_pos_gain[0][3] = 0x20;
0517 ram_table->bright_pos_gain[1][0] = 0x20;
0518 ram_table->bright_pos_gain[1][1] = 0x20;
0519 ram_table->bright_pos_gain[1][2] = 0x20;
0520 ram_table->bright_pos_gain[1][3] = 0x20;
0521 ram_table->bright_pos_gain[2][0] = 0x20;
0522 ram_table->bright_pos_gain[2][1] = 0x20;
0523 ram_table->bright_pos_gain[2][2] = 0x20;
0524 ram_table->bright_pos_gain[2][3] = 0x20;
0525 ram_table->bright_pos_gain[3][0] = 0x20;
0526 ram_table->bright_pos_gain[3][1] = 0x20;
0527 ram_table->bright_pos_gain[3][2] = 0x20;
0528 ram_table->bright_pos_gain[3][3] = 0x20;
0529 ram_table->bright_pos_gain[4][0] = 0x20;
0530 ram_table->bright_pos_gain[4][1] = 0x20;
0531 ram_table->bright_pos_gain[4][2] = 0x20;
0532 ram_table->bright_pos_gain[4][3] = 0x20;
0533
0534 ram_table->dark_pos_gain[0][0] = 0x00;
0535 ram_table->dark_pos_gain[0][1] = 0x00;
0536 ram_table->dark_pos_gain[0][2] = 0x00;
0537 ram_table->dark_pos_gain[0][3] = 0x00;
0538 ram_table->dark_pos_gain[1][0] = 0x00;
0539 ram_table->dark_pos_gain[1][1] = 0x00;
0540 ram_table->dark_pos_gain[1][2] = 0x00;
0541 ram_table->dark_pos_gain[1][3] = 0x00;
0542 ram_table->dark_pos_gain[2][0] = 0x00;
0543 ram_table->dark_pos_gain[2][1] = 0x00;
0544 ram_table->dark_pos_gain[2][2] = 0x00;
0545 ram_table->dark_pos_gain[2][3] = 0x00;
0546 ram_table->dark_pos_gain[3][0] = 0x00;
0547 ram_table->dark_pos_gain[3][1] = 0x00;
0548 ram_table->dark_pos_gain[3][2] = 0x00;
0549 ram_table->dark_pos_gain[3][3] = 0x00;
0550 ram_table->dark_pos_gain[4][0] = 0x00;
0551 ram_table->dark_pos_gain[4][1] = 0x00;
0552 ram_table->dark_pos_gain[4][2] = 0x00;
0553 ram_table->dark_pos_gain[4][3] = 0x00;
0554
0555 ram_table->hybrid_factor[0] = 0xff;
0556 ram_table->hybrid_factor[1] = 0xff;
0557 ram_table->hybrid_factor[2] = 0xff;
0558 ram_table->hybrid_factor[3] = 0xc0;
0559
0560 ram_table->contrast_factor[0] = 0x99;
0561 ram_table->contrast_factor[1] = 0x99;
0562 ram_table->contrast_factor[2] = 0x90;
0563 ram_table->contrast_factor[3] = 0x80;
0564
0565 ram_table->iir_curve[0] = 0x65;
0566 ram_table->iir_curve[1] = 0x65;
0567 ram_table->iir_curve[2] = 0x65;
0568 ram_table->iir_curve[3] = 0x65;
0569 ram_table->iir_curve[4] = 0x65;
0570
0571
0572 ram_table->crgb_thresh[0] = cpu_to_be16(0x127c);
0573 ram_table->crgb_thresh[1] = cpu_to_be16(0x151b);
0574 ram_table->crgb_thresh[2] = cpu_to_be16(0x17d5);
0575 ram_table->crgb_thresh[3] = cpu_to_be16(0x1a56);
0576 ram_table->crgb_thresh[4] = cpu_to_be16(0x1c83);
0577 ram_table->crgb_thresh[5] = cpu_to_be16(0x1e72);
0578 ram_table->crgb_thresh[6] = cpu_to_be16(0x20f0);
0579 ram_table->crgb_thresh[7] = cpu_to_be16(0x232b);
0580 ram_table->crgb_offset[0] = cpu_to_be16(0x2999);
0581 ram_table->crgb_offset[1] = cpu_to_be16(0x3999);
0582 ram_table->crgb_offset[2] = cpu_to_be16(0x4666);
0583 ram_table->crgb_offset[3] = cpu_to_be16(0x5999);
0584 ram_table->crgb_offset[4] = cpu_to_be16(0x6333);
0585 ram_table->crgb_offset[5] = cpu_to_be16(0x7800);
0586 ram_table->crgb_offset[6] = cpu_to_be16(0x8c00);
0587 ram_table->crgb_offset[7] = cpu_to_be16(0xa000);
0588 ram_table->crgb_slope[0] = cpu_to_be16(0x3609);
0589 ram_table->crgb_slope[1] = cpu_to_be16(0x2dfa);
0590 ram_table->crgb_slope[2] = cpu_to_be16(0x27ea);
0591 ram_table->crgb_slope[3] = cpu_to_be16(0x235d);
0592 ram_table->crgb_slope[4] = cpu_to_be16(0x2042);
0593 ram_table->crgb_slope[5] = cpu_to_be16(0x1dc3);
0594 ram_table->crgb_slope[6] = cpu_to_be16(0x1b1a);
0595 ram_table->crgb_slope[7] = cpu_to_be16(0x1910);
0596
0597 fill_backlight_transform_table_v_2_2(
0598 params, ram_table, true);
0599 }
0600
0601 static void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params, bool big_endian)
0602 {
0603 unsigned int i, j;
0604 unsigned int set = params.set;
0605
0606 ram_table->flags = 0x0;
0607 ram_table->min_abm_backlight = (big_endian) ?
0608 cpu_to_be16(params.min_abm_backlight) :
0609 cpu_to_le16(params.min_abm_backlight);
0610
0611 for (i = 0; i < NUM_AGGR_LEVEL; i++) {
0612 ram_table->hybrid_factor[i] = abm_settings[set][i].brightness_gain;
0613 ram_table->contrast_factor[i] = abm_settings[set][i].contrast_factor;
0614 ram_table->deviation_gain[i] = abm_settings[set][i].deviation_gain;
0615 ram_table->min_knee[i] = abm_settings[set][i].min_knee;
0616 ram_table->max_knee[i] = abm_settings[set][i].max_knee;
0617
0618 for (j = 0; j < NUM_AMBI_LEVEL; j++) {
0619 ram_table->min_reduction[j][i] = abm_settings[set][i].min_reduction;
0620 ram_table->max_reduction[j][i] = abm_settings[set][i].max_reduction;
0621 ram_table->bright_pos_gain[j][i] = abm_settings[set][i].bright_pos_gain;
0622 ram_table->dark_pos_gain[j][i] = abm_settings[set][i].dark_pos_gain;
0623 }
0624 }
0625
0626 ram_table->iir_curve[0] = 0x65;
0627 ram_table->iir_curve[1] = 0x65;
0628 ram_table->iir_curve[2] = 0x65;
0629 ram_table->iir_curve[3] = 0x65;
0630 ram_table->iir_curve[4] = 0x65;
0631
0632
0633 ram_table->crgb_thresh[0] = bswap16_based_on_endian(big_endian, 0x127c);
0634 ram_table->crgb_thresh[1] = bswap16_based_on_endian(big_endian, 0x151b);
0635 ram_table->crgb_thresh[2] = bswap16_based_on_endian(big_endian, 0x17d5);
0636 ram_table->crgb_thresh[3] = bswap16_based_on_endian(big_endian, 0x1a56);
0637 ram_table->crgb_thresh[4] = bswap16_based_on_endian(big_endian, 0x1c83);
0638 ram_table->crgb_thresh[5] = bswap16_based_on_endian(big_endian, 0x1e72);
0639 ram_table->crgb_thresh[6] = bswap16_based_on_endian(big_endian, 0x20f0);
0640 ram_table->crgb_thresh[7] = bswap16_based_on_endian(big_endian, 0x232b);
0641 ram_table->crgb_offset[0] = bswap16_based_on_endian(big_endian, 0x2999);
0642 ram_table->crgb_offset[1] = bswap16_based_on_endian(big_endian, 0x3999);
0643 ram_table->crgb_offset[2] = bswap16_based_on_endian(big_endian, 0x4666);
0644 ram_table->crgb_offset[3] = bswap16_based_on_endian(big_endian, 0x5999);
0645 ram_table->crgb_offset[4] = bswap16_based_on_endian(big_endian, 0x6333);
0646 ram_table->crgb_offset[5] = bswap16_based_on_endian(big_endian, 0x7800);
0647 ram_table->crgb_offset[6] = bswap16_based_on_endian(big_endian, 0x8c00);
0648 ram_table->crgb_offset[7] = bswap16_based_on_endian(big_endian, 0xa000);
0649 ram_table->crgb_slope[0] = bswap16_based_on_endian(big_endian, 0x3609);
0650 ram_table->crgb_slope[1] = bswap16_based_on_endian(big_endian, 0x2dfa);
0651 ram_table->crgb_slope[2] = bswap16_based_on_endian(big_endian, 0x27ea);
0652 ram_table->crgb_slope[3] = bswap16_based_on_endian(big_endian, 0x235d);
0653 ram_table->crgb_slope[4] = bswap16_based_on_endian(big_endian, 0x2042);
0654 ram_table->crgb_slope[5] = bswap16_based_on_endian(big_endian, 0x1dc3);
0655 ram_table->crgb_slope[6] = bswap16_based_on_endian(big_endian, 0x1b1a);
0656 ram_table->crgb_slope[7] = bswap16_based_on_endian(big_endian, 0x1910);
0657
0658 fill_backlight_transform_table_v_2_2(
0659 params, ram_table, big_endian);
0660 }
0661
0662 bool dmub_init_abm_config(struct resource_pool *res_pool,
0663 struct dmcu_iram_parameters params,
0664 unsigned int inst)
0665 {
0666 struct iram_table_v_2_2 ram_table;
0667 struct abm_config_table config;
0668 unsigned int set = params.set;
0669 bool result = false;
0670 uint32_t i, j = 0;
0671
0672 #if defined(CONFIG_DRM_AMD_DC_DCN)
0673 if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL)
0674 return false;
0675 #else
0676 if (res_pool->abm == NULL)
0677 return false;
0678 #endif
0679
0680 memset(&ram_table, 0, sizeof(ram_table));
0681 memset(&config, 0, sizeof(config));
0682
0683 fill_iram_v_2_3(&ram_table, params, false);
0684
0685
0686 for (i = 0; i < NUM_POWER_FN_SEGS; i++) {
0687 config.crgb_thresh[i] = ram_table.crgb_thresh[i];
0688 config.crgb_offset[i] = ram_table.crgb_offset[i];
0689 config.crgb_slope[i] = ram_table.crgb_slope[i];
0690 }
0691
0692 for (i = 0; i < NUM_BL_CURVE_SEGS; i++) {
0693 config.backlight_thresholds[i] = ram_table.backlight_thresholds[i];
0694 config.backlight_offsets[i] = ram_table.backlight_offsets[i];
0695 }
0696
0697 for (i = 0; i < NUM_AMBI_LEVEL; i++)
0698 config.iir_curve[i] = ram_table.iir_curve[i];
0699
0700 for (i = 0; i < NUM_AMBI_LEVEL; i++) {
0701 for (j = 0; j < NUM_AGGR_LEVEL; j++) {
0702 config.min_reduction[i][j] = ram_table.min_reduction[i][j];
0703 config.max_reduction[i][j] = ram_table.max_reduction[i][j];
0704 config.bright_pos_gain[i][j] = ram_table.bright_pos_gain[i][j];
0705 config.dark_pos_gain[i][j] = ram_table.dark_pos_gain[i][j];
0706 }
0707 }
0708
0709 for (i = 0; i < NUM_AGGR_LEVEL; i++) {
0710 config.hybrid_factor[i] = ram_table.hybrid_factor[i];
0711 config.contrast_factor[i] = ram_table.contrast_factor[i];
0712 config.deviation_gain[i] = ram_table.deviation_gain[i];
0713 config.min_knee[i] = ram_table.min_knee[i];
0714 config.max_knee[i] = ram_table.max_knee[i];
0715 }
0716
0717 if (params.backlight_ramping_override) {
0718 for (i = 0; i < NUM_AGGR_LEVEL; i++) {
0719 config.blRampReduction[i] = params.backlight_ramping_reduction;
0720 config.blRampStart[i] = params.backlight_ramping_start;
0721 }
0722 } else {
0723 for (i = 0; i < NUM_AGGR_LEVEL; i++) {
0724 config.blRampReduction[i] = abm_settings[set][i].blRampReduction;
0725 config.blRampStart[i] = abm_settings[set][i].blRampStart;
0726 }
0727 }
0728
0729 config.min_abm_backlight = ram_table.min_abm_backlight;
0730
0731 #if defined(CONFIG_DRM_AMD_DC_DCN)
0732 if (res_pool->multiple_abms[inst]) {
0733 result = res_pool->multiple_abms[inst]->funcs->init_abm_config(
0734 res_pool->multiple_abms[inst], (char *)(&config), sizeof(struct abm_config_table), inst);
0735 } else
0736 #endif
0737 result = res_pool->abm->funcs->init_abm_config(
0738 res_pool->abm, (char *)(&config), sizeof(struct abm_config_table), 0);
0739
0740 return result;
0741 }
0742
0743 bool dmcu_load_iram(struct dmcu *dmcu,
0744 struct dmcu_iram_parameters params)
0745 {
0746 unsigned char ram_table[IRAM_SIZE];
0747 bool result = false;
0748
0749 if (dmcu == NULL)
0750 return false;
0751
0752 if (dmcu && !dmcu->funcs->is_dmcu_initialized(dmcu))
0753 return true;
0754
0755 memset(&ram_table, 0, sizeof(ram_table));
0756
0757 if (dmcu->dmcu_version.abm_version == 0x24) {
0758 fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true);
0759 result = dmcu->funcs->load_iram(
0760 dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
0761 } else if (dmcu->dmcu_version.abm_version == 0x23) {
0762 fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true);
0763
0764 result = dmcu->funcs->load_iram(
0765 dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
0766 } else if (dmcu->dmcu_version.abm_version == 0x22) {
0767 fill_iram_v_2_2((struct iram_table_v_2_2 *)ram_table, params);
0768
0769 result = dmcu->funcs->load_iram(
0770 dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
0771 } else {
0772 fill_iram_v_2((struct iram_table_v_2 *)ram_table, params);
0773
0774 result = dmcu->funcs->load_iram(
0775 dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2);
0776
0777 if (result)
0778 result = dmcu->funcs->load_iram(
0779 dmcu, IRAM_RESERVE_AREA_END_V2 + 1,
0780 (char *)(&ram_table) + IRAM_RESERVE_AREA_END_V2 + 1,
0781 sizeof(ram_table) - IRAM_RESERVE_AREA_END_V2 - 1);
0782 }
0783
0784 return result;
0785 }
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795 bool is_psr_su_specific_panel(struct dc_link *link)
0796 {
0797 bool isPSRSUSupported = false;
0798 struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
0799
0800 if (dpcd_caps->edp_rev >= DP_EDP_14) {
0801 if (dpcd_caps->psr_info.psr_version >= DP_PSR2_WITH_Y_COORD_ET_SUPPORTED)
0802 isPSRSUSupported = true;
0803
0804
0805
0806
0807
0808 if (dpcd_caps->sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) {
0809
0810
0811
0812
0813 if (dpcd_caps->psr_info.psr_version < DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)
0814 isPSRSUSupported = false;
0815 else if (dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
0816 ((dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x08) ||
0817 (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x07)))
0818 isPSRSUSupported = false;
0819 else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1)
0820 isPSRSUSupported = true;
0821 }
0822 }
0823
0824 return isPSRSUSupported;
0825 }
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850 void mod_power_calc_psr_configs(struct psr_config *psr_config,
0851 struct dc_link *link,
0852 const struct dc_stream_state *stream)
0853 {
0854 unsigned int num_vblank_lines = 0;
0855 unsigned int vblank_time_in_us = 0;
0856 unsigned int sdp_tx_deadline_in_us = 0;
0857 unsigned int line_time_in_us = 0;
0858 struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
0859 const int psr_setup_time_step_in_us = 55;
0860
0861
0862 num_vblank_lines = stream->timing.v_total -
0863 stream->timing.v_addressable -
0864 stream->timing.v_border_top -
0865 stream->timing.v_border_bottom;
0866
0867 vblank_time_in_us = (stream->timing.h_total * num_vblank_lines * 1000) / (stream->timing.pix_clk_100hz / 10);
0868
0869 line_time_in_us = ((stream->timing.h_total * 1000) / (stream->timing.pix_clk_100hz / 10)) + 1;
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882
0883 psr_config->psr_rfb_setup_time =
0884 (6 - dpcd_caps->psr_info.psr_dpcd_caps.bits.PSR_SETUP_TIME) * psr_setup_time_step_in_us;
0885
0886 if (psr_config->psr_rfb_setup_time > vblank_time_in_us) {
0887 link->psr_settings.psr_frame_capture_indication_req = true;
0888 link->psr_settings.psr_sdp_transmit_line_num_deadline = num_vblank_lines;
0889 } else {
0890 sdp_tx_deadline_in_us = vblank_time_in_us - psr_config->psr_rfb_setup_time;
0891
0892
0893 link->psr_settings.psr_frame_capture_indication_req = false;
0894 link->psr_settings.psr_sdp_transmit_line_num_deadline = sdp_tx_deadline_in_us / line_time_in_us;
0895 }
0896
0897 psr_config->psr_sdp_transmit_line_num_deadline = link->psr_settings.psr_sdp_transmit_line_num_deadline;
0898 psr_config->line_time_in_us = line_time_in_us;
0899 psr_config->su_y_granularity = dpcd_caps->psr_info.psr2_su_y_granularity_cap;
0900 psr_config->su_granularity_required = dpcd_caps->psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED;
0901 psr_config->psr_frame_capture_indication_req = link->psr_settings.psr_frame_capture_indication_req;
0902 psr_config->psr_exit_link_training_required =
0903 !link->dpcd_caps.psr_info.psr_dpcd_caps.bits.LINK_TRAINING_ON_EXIT_NOT_REQUIRED;
0904 }
0905
0906 bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_state *stream)
0907 {
0908 return context && context->stream_count == 1 && dc_is_embedded_signal(stream->signal);
0909 }