1c349dbc7Sjsg /* Copyright 2018 Advanced Micro Devices, Inc. 2c349dbc7Sjsg * 3c349dbc7Sjsg * Permission is hereby granted, free of charge, to any person obtaining a 4c349dbc7Sjsg * copy of this software and associated documentation files (the "Software"), 5c349dbc7Sjsg * to deal in the Software without restriction, including without limitation 6c349dbc7Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 7c349dbc7Sjsg * and/or sell copies of the Software, and to permit persons to whom the 8c349dbc7Sjsg * Software is furnished to do so, subject to the following conditions: 9c349dbc7Sjsg * 10c349dbc7Sjsg * The above copyright notice and this permission notice shall be included in 11c349dbc7Sjsg * all copies or substantial portions of the Software. 12c349dbc7Sjsg * 13c349dbc7Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14c349dbc7Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15c349dbc7Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16c349dbc7Sjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 17c349dbc7Sjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18c349dbc7Sjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19c349dbc7Sjsg * OTHER DEALINGS IN THE SOFTWARE. 20c349dbc7Sjsg * 21c349dbc7Sjsg * Authors: AMD 22c349dbc7Sjsg * 23c349dbc7Sjsg */ 24c349dbc7Sjsg 25c349dbc7Sjsg #include "power_helpers.h" 26c349dbc7Sjsg #include "dc/inc/hw/dmcu.h" 27ad8b1aafSjsg #include "dc/inc/hw/abm.h" 28ad8b1aafSjsg #include "dc.h" 29ad8b1aafSjsg #include "core_types.h" 30ad8b1aafSjsg #include "dmub_cmd.h" 31c349dbc7Sjsg 32c349dbc7Sjsg #define DIV_ROUNDUP(a, b) (((a)+((b)/2))/(b)) 33ad8b1aafSjsg #define bswap16_based_on_endian(big_endian, value) \ 34ad8b1aafSjsg (big_endian) ? cpu_to_be16(value) : cpu_to_le16(value) 35c349dbc7Sjsg 36c349dbc7Sjsg /* Possible Min Reduction config from least aggressive to most aggressive 37c349dbc7Sjsg * 0 1 2 3 4 5 6 7 8 9 10 11 12 38c349dbc7Sjsg * 100 98.0 94.1 94.1 85.1 80.3 75.3 69.4 60.0 57.6 50.2 49.8 40.0 % 39c349dbc7Sjsg */ 40c349dbc7Sjsg static const unsigned char min_reduction_table[13] = { 41c349dbc7Sjsg 0xff, 0xfa, 0xf0, 0xf0, 0xd9, 0xcd, 0xc0, 0xb1, 0x99, 0x93, 0x80, 0x82, 0x66}; 42c349dbc7Sjsg 43c349dbc7Sjsg /* Possible Max Reduction configs from least aggressive to most aggressive 44c349dbc7Sjsg * 0 1 2 3 4 5 6 7 8 9 10 11 12 45c349dbc7Sjsg * 96.1 89.8 85.1 80.3 69.4 64.7 64.7 50.2 39.6 30.2 30.2 30.2 19.6 % 46c349dbc7Sjsg */ 47c349dbc7Sjsg static const unsigned char max_reduction_table[13] = { 48c349dbc7Sjsg 0xf5, 0xe5, 0xd9, 0xcd, 0xb1, 0xa5, 0xa5, 0x80, 0x65, 0x4d, 0x4d, 0x4d, 0x32}; 49c349dbc7Sjsg 50c349dbc7Sjsg /* Possible ABM 2.2 Min Reduction configs from least aggressive to most aggressive 51c349dbc7Sjsg * 0 1 2 3 4 5 6 7 8 9 10 11 12 52c349dbc7Sjsg * 100 100 100 100 100 100 100 100 100 92.2 83.1 75.3 75.3 % 53c349dbc7Sjsg */ 54c349dbc7Sjsg static const unsigned char min_reduction_table_v_2_2[13] = { 55c349dbc7Sjsg 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xd4, 0xc0, 0xc0}; 56c349dbc7Sjsg 57c349dbc7Sjsg /* Possible ABM 2.2 Max Reduction configs from least aggressive to most aggressive 58c349dbc7Sjsg * 0 1 2 3 4 5 6 7 8 9 10 11 12 59c349dbc7Sjsg * 96.1 89.8 74.9 69.4 64.7 52.2 48.6 39.6 30.2 25.1 19.6 12.5 12.5 % 60c349dbc7Sjsg */ 61c349dbc7Sjsg static const unsigned char max_reduction_table_v_2_2[13] = { 62c349dbc7Sjsg 0xf5, 0xe5, 0xbf, 0xb1, 0xa5, 0x85, 0x7c, 0x65, 0x4d, 0x40, 0x32, 0x20, 0x20}; 63c349dbc7Sjsg 64c349dbc7Sjsg /* Predefined ABM configuration sets. We may have different configuration sets 65c349dbc7Sjsg * in order to satisfy different power/quality requirements. 66c349dbc7Sjsg */ 67c349dbc7Sjsg static const unsigned char abm_config[abm_defines_max_config][abm_defines_max_level] = { 68c349dbc7Sjsg /* ABM Level 1, ABM Level 2, ABM Level 3, ABM Level 4 */ 69c349dbc7Sjsg { 2, 5, 7, 8 }, /* Default - Medium aggressiveness */ 70c349dbc7Sjsg { 2, 5, 8, 11 }, /* Alt #1 - Increased aggressiveness */ 71c349dbc7Sjsg { 0, 2, 4, 8 }, /* Alt #2 - Minimal aggressiveness */ 72c349dbc7Sjsg { 3, 6, 10, 12 }, /* Alt #3 - Super aggressiveness */ 73c349dbc7Sjsg }; 74c349dbc7Sjsg 75c349dbc7Sjsg struct abm_parameters { 76c349dbc7Sjsg unsigned char min_reduction; 77c349dbc7Sjsg unsigned char max_reduction; 78c349dbc7Sjsg unsigned char bright_pos_gain; 79c349dbc7Sjsg unsigned char dark_pos_gain; 80c349dbc7Sjsg unsigned char brightness_gain; 81c349dbc7Sjsg unsigned char contrast_factor; 82c349dbc7Sjsg unsigned char deviation_gain; 83c349dbc7Sjsg unsigned char min_knee; 84c349dbc7Sjsg unsigned char max_knee; 855ca02815Sjsg unsigned short blRampReduction; 865ca02815Sjsg unsigned short blRampStart; 87c349dbc7Sjsg }; 88c349dbc7Sjsg 89c349dbc7Sjsg static const struct abm_parameters abm_settings_config0[abm_defines_max_level] = { 905ca02815Sjsg // min_red max_red bright_pos dark_pos bright_gain contrast dev min_knee max_knee blRed blStart 915ca02815Sjsg {0xff, 0xbf, 0x20, 0x00, 0xff, 0x99, 0xb3, 0x40, 0xe0, 0xf777, 0xcccc}, 925ca02815Sjsg {0xde, 0x85, 0x20, 0x00, 0xe0, 0x90, 0xa8, 0x40, 0xc8, 0xf777, 0xcccc}, 935ca02815Sjsg {0xb0, 0x50, 0x20, 0x00, 0xc0, 0x88, 0x78, 0x70, 0xa0, 0xeeee, 0x9999}, 945ca02815Sjsg {0x82, 0x40, 0x20, 0x00, 0x00, 0xb8, 0xb3, 0x70, 0x70, 0xe333, 0xb333}, 95c349dbc7Sjsg }; 96c349dbc7Sjsg 97c349dbc7Sjsg static const struct abm_parameters abm_settings_config1[abm_defines_max_level] = { 985ca02815Sjsg // min_red max_red bright_pos dark_pos bright_gain contrast dev min_knee max_knee blRed blStart 995ca02815Sjsg {0xf0, 0xd9, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc}, 1005ca02815Sjsg {0xcd, 0xa5, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc}, 1015ca02815Sjsg {0x99, 0x65, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc}, 1025ca02815Sjsg {0x82, 0x4d, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc}, 103c349dbc7Sjsg }; 104c349dbc7Sjsg 105f005ef32Sjsg static const struct abm_parameters abm_settings_config2[abm_defines_max_level] = { 106f005ef32Sjsg // min_red max_red bright_pos dark_pos bright_gain contrast dev min_knee max_knee blRed blStart 107f005ef32Sjsg {0xf0, 0xbf, 0x20, 0x00, 0x88, 0x99, 0xb3, 0x40, 0xe0, 0x0000, 0xcccc}, 108f005ef32Sjsg {0xd8, 0x85, 0x20, 0x00, 0x70, 0x90, 0xa8, 0x40, 0xc8, 0x0700, 0xb333}, 109f005ef32Sjsg {0xb8, 0x58, 0x20, 0x00, 0x64, 0x88, 0x78, 0x70, 0xa0, 0x7000, 0x9999}, 110f005ef32Sjsg {0x82, 0x40, 0x20, 0x00, 0x00, 0xb8, 0xb3, 0x70, 0x70, 0xc333, 0xb333}, 111f005ef32Sjsg }; 112f005ef32Sjsg 113c349dbc7Sjsg static const struct abm_parameters * const abm_settings[] = { 114c349dbc7Sjsg abm_settings_config0, 115c349dbc7Sjsg abm_settings_config1, 116f005ef32Sjsg abm_settings_config2, 117f005ef32Sjsg }; 118f005ef32Sjsg 119f005ef32Sjsg static const struct dm_bl_data_point custom_backlight_curve0[] = { 120f005ef32Sjsg {2, 14}, {4, 16}, {6, 18}, {8, 21}, {10, 23}, {12, 26}, {14, 29}, {16, 32}, {18, 35}, 121f005ef32Sjsg {20, 38}, {22, 41}, {24, 44}, {26, 48}, {28, 52}, {30, 55}, {32, 59}, {34, 62}, 122f005ef32Sjsg {36, 67}, {38, 71}, {40, 75}, {42, 80}, {44, 84}, {46, 88}, {48, 93}, {50, 98}, 123f005ef32Sjsg {52, 103}, {54, 108}, {56, 113}, {58, 118}, {60, 123}, {62, 129}, {64, 135}, {66, 140}, 124f005ef32Sjsg {68, 146}, {70, 152}, {72, 158}, {74, 164}, {76, 171}, {78, 177}, {80, 183}, {82, 190}, 125f005ef32Sjsg {84, 197}, {86, 204}, {88, 211}, {90, 218}, {92, 225}, {94, 232}, {96, 240}, {98, 247}}; 126f005ef32Sjsg 127f005ef32Sjsg struct custom_backlight_profile { 128f005ef32Sjsg uint8_t ac_level_percentage; 129f005ef32Sjsg uint8_t dc_level_percentage; 130f005ef32Sjsg uint8_t min_input_signal; 131f005ef32Sjsg uint8_t max_input_signal; 132f005ef32Sjsg uint8_t num_data_points; 133f005ef32Sjsg const struct dm_bl_data_point *data_points; 134f005ef32Sjsg }; 135f005ef32Sjsg 136f005ef32Sjsg static const struct custom_backlight_profile custom_backlight_profiles[] = { 137f005ef32Sjsg {100, 32, 12, 255, ARRAY_SIZE(custom_backlight_curve0), custom_backlight_curve0}, 138c349dbc7Sjsg }; 139c349dbc7Sjsg 140c349dbc7Sjsg #define NUM_AMBI_LEVEL 5 141c349dbc7Sjsg #define NUM_AGGR_LEVEL 4 142c349dbc7Sjsg #define NUM_POWER_FN_SEGS 8 143c349dbc7Sjsg #define NUM_BL_CURVE_SEGS 16 144c349dbc7Sjsg #define IRAM_SIZE 256 145c349dbc7Sjsg 146c349dbc7Sjsg #define IRAM_RESERVE_AREA_START_V2 0xF0 // reserve 0xF0~0xF6 are write by DMCU only 147c349dbc7Sjsg #define IRAM_RESERVE_AREA_END_V2 0xF6 // reserve 0xF0~0xF6 are write by DMCU only 148c349dbc7Sjsg 149c349dbc7Sjsg #define IRAM_RESERVE_AREA_START_V2_2 0xF0 // reserve 0xF0~0xFF are write by DMCU only 150c349dbc7Sjsg #define IRAM_RESERVE_AREA_END_V2_2 0xFF // reserve 0xF0~0xFF are write by DMCU only 151c349dbc7Sjsg 152c349dbc7Sjsg #pragma pack(push, 1) 153c349dbc7Sjsg /* NOTE: iRAM is 256B in size */ 154c349dbc7Sjsg struct iram_table_v_2 { 155c349dbc7Sjsg /* flags */ 156c349dbc7Sjsg uint16_t min_abm_backlight; /* 0x00 U16 */ 157c349dbc7Sjsg 158c349dbc7Sjsg /* parameters for ABM2.0 algorithm */ 159c349dbc7Sjsg uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x02 U0.8 */ 160c349dbc7Sjsg uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x16 U0.8 */ 161c349dbc7Sjsg uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x2a U2.6 */ 162c349dbc7Sjsg uint8_t bright_neg_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x3e U2.6 */ 163c349dbc7Sjsg uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x52 U2.6 */ 164c349dbc7Sjsg uint8_t dark_neg_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x66 U2.6 */ 165c349dbc7Sjsg uint8_t iir_curve[NUM_AMBI_LEVEL]; /* 0x7a U0.8 */ 166c349dbc7Sjsg uint8_t deviation_gain; /* 0x7f U0.8 */ 167c349dbc7Sjsg 168c349dbc7Sjsg /* parameters for crgb conversion */ 169c349dbc7Sjsg uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; /* 0x80 U3.13 */ 170c349dbc7Sjsg uint16_t crgb_offset[NUM_POWER_FN_SEGS]; /* 0x90 U1.15 */ 171c349dbc7Sjsg uint16_t crgb_slope[NUM_POWER_FN_SEGS]; /* 0xa0 U4.12 */ 172c349dbc7Sjsg 173c349dbc7Sjsg /* parameters for custom curve */ 174c349dbc7Sjsg /* thresholds for brightness --> backlight */ 175c349dbc7Sjsg uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; /* 0xb0 U16.0 */ 176c349dbc7Sjsg /* offsets for brightness --> backlight */ 177c349dbc7Sjsg uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; /* 0xd0 U16.0 */ 178c349dbc7Sjsg 179c349dbc7Sjsg /* For reading PSR State directly from IRAM */ 180c349dbc7Sjsg uint8_t psr_state; /* 0xf0 */ 181c349dbc7Sjsg uint8_t dmcu_mcp_interface_version; /* 0xf1 */ 182c349dbc7Sjsg uint8_t dmcu_abm_feature_version; /* 0xf2 */ 183c349dbc7Sjsg uint8_t dmcu_psr_feature_version; /* 0xf3 */ 184c349dbc7Sjsg uint16_t dmcu_version; /* 0xf4 */ 185c349dbc7Sjsg uint8_t dmcu_state; /* 0xf6 */ 186c349dbc7Sjsg 187c349dbc7Sjsg uint16_t blRampReduction; /* 0xf7 */ 188c349dbc7Sjsg uint16_t blRampStart; /* 0xf9 */ 189c349dbc7Sjsg uint8_t dummy5; /* 0xfb */ 190c349dbc7Sjsg uint8_t dummy6; /* 0xfc */ 191c349dbc7Sjsg uint8_t dummy7; /* 0xfd */ 192c349dbc7Sjsg uint8_t dummy8; /* 0xfe */ 193c349dbc7Sjsg uint8_t dummy9; /* 0xff */ 194c349dbc7Sjsg }; 195c349dbc7Sjsg 196c349dbc7Sjsg struct iram_table_v_2_2 { 197c349dbc7Sjsg /* flags */ 198c349dbc7Sjsg uint16_t flags; /* 0x00 U16 */ 199c349dbc7Sjsg 200c349dbc7Sjsg /* parameters for ABM2.2 algorithm */ 201c349dbc7Sjsg uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x02 U0.8 */ 202c349dbc7Sjsg uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x16 U0.8 */ 203c349dbc7Sjsg uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x2a U2.6 */ 204c349dbc7Sjsg uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x3e U2.6 */ 205c349dbc7Sjsg uint8_t hybrid_factor[NUM_AGGR_LEVEL]; /* 0x52 U0.8 */ 206c349dbc7Sjsg uint8_t contrast_factor[NUM_AGGR_LEVEL]; /* 0x56 U0.8 */ 207c349dbc7Sjsg uint8_t deviation_gain[NUM_AGGR_LEVEL]; /* 0x5a U0.8 */ 208c349dbc7Sjsg uint8_t iir_curve[NUM_AMBI_LEVEL]; /* 0x5e U0.8 */ 209c349dbc7Sjsg uint8_t min_knee[NUM_AGGR_LEVEL]; /* 0x63 U0.8 */ 210c349dbc7Sjsg uint8_t max_knee[NUM_AGGR_LEVEL]; /* 0x67 U0.8 */ 211c349dbc7Sjsg uint16_t min_abm_backlight; /* 0x6b U16 */ 212c349dbc7Sjsg uint8_t pad[19]; /* 0x6d U0.8 */ 213c349dbc7Sjsg 214c349dbc7Sjsg /* parameters for crgb conversion */ 215c349dbc7Sjsg uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; /* 0x80 U3.13 */ 216c349dbc7Sjsg uint16_t crgb_offset[NUM_POWER_FN_SEGS]; /* 0x90 U1.15 */ 217c349dbc7Sjsg uint16_t crgb_slope[NUM_POWER_FN_SEGS]; /* 0xa0 U4.12 */ 218c349dbc7Sjsg 219c349dbc7Sjsg /* parameters for custom curve */ 220c349dbc7Sjsg /* thresholds for brightness --> backlight */ 221c349dbc7Sjsg uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; /* 0xb0 U16.0 */ 222c349dbc7Sjsg /* offsets for brightness --> backlight */ 223c349dbc7Sjsg uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; /* 0xd0 U16.0 */ 224c349dbc7Sjsg 225c349dbc7Sjsg /* For reading PSR State directly from IRAM */ 226c349dbc7Sjsg uint8_t psr_state; /* 0xf0 */ 227c349dbc7Sjsg uint8_t dmcu_mcp_interface_version; /* 0xf1 */ 228c349dbc7Sjsg uint8_t dmcu_abm_feature_version; /* 0xf2 */ 229c349dbc7Sjsg uint8_t dmcu_psr_feature_version; /* 0xf3 */ 230c349dbc7Sjsg uint16_t dmcu_version; /* 0xf4 */ 231c349dbc7Sjsg uint8_t dmcu_state; /* 0xf6 */ 232c349dbc7Sjsg 233c349dbc7Sjsg uint8_t dummy1; /* 0xf7 */ 234c349dbc7Sjsg uint8_t dummy2; /* 0xf8 */ 235c349dbc7Sjsg uint8_t dummy3; /* 0xf9 */ 236c349dbc7Sjsg uint8_t dummy4; /* 0xfa */ 237c349dbc7Sjsg uint8_t dummy5; /* 0xfb */ 238c349dbc7Sjsg uint8_t dummy6; /* 0xfc */ 239c349dbc7Sjsg uint8_t dummy7; /* 0xfd */ 240c349dbc7Sjsg uint8_t dummy8; /* 0xfe */ 241c349dbc7Sjsg uint8_t dummy9; /* 0xff */ 242c349dbc7Sjsg }; 243c349dbc7Sjsg #pragma pack(pop) 244c349dbc7Sjsg 245c349dbc7Sjsg static void fill_backlight_transform_table(struct dmcu_iram_parameters params, 246c349dbc7Sjsg struct iram_table_v_2 *table) 247c349dbc7Sjsg { 248c349dbc7Sjsg unsigned int i; 249c349dbc7Sjsg unsigned int num_entries = NUM_BL_CURVE_SEGS; 250c349dbc7Sjsg unsigned int lut_index; 251c349dbc7Sjsg 252c349dbc7Sjsg table->backlight_thresholds[0] = 0; 253c349dbc7Sjsg table->backlight_offsets[0] = params.backlight_lut_array[0]; 254c349dbc7Sjsg table->backlight_thresholds[num_entries-1] = 0xFFFF; 255c349dbc7Sjsg table->backlight_offsets[num_entries-1] = 256c349dbc7Sjsg params.backlight_lut_array[params.backlight_lut_array_size - 1]; 257c349dbc7Sjsg 258c349dbc7Sjsg /* Setup all brightness levels between 0% and 100% exclusive 259c349dbc7Sjsg * Fills brightness-to-backlight transform table. Backlight custom curve 260c349dbc7Sjsg * describes transform from brightness to backlight. It will be defined 261c349dbc7Sjsg * as set of thresholds and set of offsets, together, implying 262c349dbc7Sjsg * extrapolation of custom curve into 16 uniformly spanned linear 263c349dbc7Sjsg * segments. Each threshold/offset represented by 16 bit entry in 264c349dbc7Sjsg * format U4.10. 265c349dbc7Sjsg */ 266c349dbc7Sjsg for (i = 1; i+1 < num_entries; i++) { 267c349dbc7Sjsg lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1); 268c349dbc7Sjsg ASSERT(lut_index < params.backlight_lut_array_size); 269c349dbc7Sjsg 270c349dbc7Sjsg table->backlight_thresholds[i] = 271c349dbc7Sjsg cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)); 272c349dbc7Sjsg table->backlight_offsets[i] = 273c349dbc7Sjsg cpu_to_be16(params.backlight_lut_array[lut_index]); 274c349dbc7Sjsg } 275c349dbc7Sjsg } 276c349dbc7Sjsg 277c349dbc7Sjsg static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters params, 278ad8b1aafSjsg struct iram_table_v_2_2 *table, bool big_endian) 279c349dbc7Sjsg { 280c349dbc7Sjsg unsigned int i; 281c349dbc7Sjsg unsigned int num_entries = NUM_BL_CURVE_SEGS; 282c349dbc7Sjsg unsigned int lut_index; 283c349dbc7Sjsg 284c349dbc7Sjsg table->backlight_thresholds[0] = 0; 285c349dbc7Sjsg table->backlight_offsets[0] = params.backlight_lut_array[0]; 286c349dbc7Sjsg table->backlight_thresholds[num_entries-1] = 0xFFFF; 287c349dbc7Sjsg table->backlight_offsets[num_entries-1] = 288c349dbc7Sjsg params.backlight_lut_array[params.backlight_lut_array_size - 1]; 289c349dbc7Sjsg 290c349dbc7Sjsg /* Setup all brightness levels between 0% and 100% exclusive 291c349dbc7Sjsg * Fills brightness-to-backlight transform table. Backlight custom curve 292c349dbc7Sjsg * describes transform from brightness to backlight. It will be defined 293c349dbc7Sjsg * as set of thresholds and set of offsets, together, implying 294c349dbc7Sjsg * extrapolation of custom curve into 16 uniformly spanned linear 295c349dbc7Sjsg * segments. Each threshold/offset represented by 16 bit entry in 296c349dbc7Sjsg * format U4.10. 297c349dbc7Sjsg */ 298c349dbc7Sjsg for (i = 1; i+1 < num_entries; i++) { 2995ca02815Sjsg lut_index = DIV_ROUNDUP((i * params.backlight_lut_array_size), num_entries); 300c349dbc7Sjsg ASSERT(lut_index < params.backlight_lut_array_size); 301c349dbc7Sjsg 302ad8b1aafSjsg table->backlight_thresholds[i] = (big_endian) ? 303ad8b1aafSjsg cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)) : 304ad8b1aafSjsg cpu_to_le16(DIV_ROUNDUP((i * 65536), num_entries)); 305ad8b1aafSjsg table->backlight_offsets[i] = (big_endian) ? 306ad8b1aafSjsg cpu_to_be16(params.backlight_lut_array[lut_index]) : 307ad8b1aafSjsg cpu_to_le16(params.backlight_lut_array[lut_index]); 308c349dbc7Sjsg } 309c349dbc7Sjsg } 310c349dbc7Sjsg 3115ca02815Sjsg static void fill_iram_v_2(struct iram_table_v_2 *ram_table, struct dmcu_iram_parameters params) 312c349dbc7Sjsg { 313c349dbc7Sjsg unsigned int set = params.set; 314c349dbc7Sjsg 315c349dbc7Sjsg ram_table->min_abm_backlight = 316c349dbc7Sjsg cpu_to_be16(params.min_abm_backlight); 317c349dbc7Sjsg ram_table->deviation_gain = 0xb3; 318c349dbc7Sjsg 319c349dbc7Sjsg ram_table->blRampReduction = 320c349dbc7Sjsg cpu_to_be16(params.backlight_ramping_reduction); 321c349dbc7Sjsg ram_table->blRampStart = 322c349dbc7Sjsg cpu_to_be16(params.backlight_ramping_start); 323c349dbc7Sjsg 324c349dbc7Sjsg ram_table->min_reduction[0][0] = min_reduction_table[abm_config[set][0]]; 325c349dbc7Sjsg ram_table->min_reduction[1][0] = min_reduction_table[abm_config[set][0]]; 326c349dbc7Sjsg ram_table->min_reduction[2][0] = min_reduction_table[abm_config[set][0]]; 327c349dbc7Sjsg ram_table->min_reduction[3][0] = min_reduction_table[abm_config[set][0]]; 328c349dbc7Sjsg ram_table->min_reduction[4][0] = min_reduction_table[abm_config[set][0]]; 329c349dbc7Sjsg ram_table->max_reduction[0][0] = max_reduction_table[abm_config[set][0]]; 330c349dbc7Sjsg ram_table->max_reduction[1][0] = max_reduction_table[abm_config[set][0]]; 331c349dbc7Sjsg ram_table->max_reduction[2][0] = max_reduction_table[abm_config[set][0]]; 332c349dbc7Sjsg ram_table->max_reduction[3][0] = max_reduction_table[abm_config[set][0]]; 333c349dbc7Sjsg ram_table->max_reduction[4][0] = max_reduction_table[abm_config[set][0]]; 334c349dbc7Sjsg 335c349dbc7Sjsg ram_table->min_reduction[0][1] = min_reduction_table[abm_config[set][1]]; 336c349dbc7Sjsg ram_table->min_reduction[1][1] = min_reduction_table[abm_config[set][1]]; 337c349dbc7Sjsg ram_table->min_reduction[2][1] = min_reduction_table[abm_config[set][1]]; 338c349dbc7Sjsg ram_table->min_reduction[3][1] = min_reduction_table[abm_config[set][1]]; 339c349dbc7Sjsg ram_table->min_reduction[4][1] = min_reduction_table[abm_config[set][1]]; 340c349dbc7Sjsg ram_table->max_reduction[0][1] = max_reduction_table[abm_config[set][1]]; 341c349dbc7Sjsg ram_table->max_reduction[1][1] = max_reduction_table[abm_config[set][1]]; 342c349dbc7Sjsg ram_table->max_reduction[2][1] = max_reduction_table[abm_config[set][1]]; 343c349dbc7Sjsg ram_table->max_reduction[3][1] = max_reduction_table[abm_config[set][1]]; 344c349dbc7Sjsg ram_table->max_reduction[4][1] = max_reduction_table[abm_config[set][1]]; 345c349dbc7Sjsg 346c349dbc7Sjsg ram_table->min_reduction[0][2] = min_reduction_table[abm_config[set][2]]; 347c349dbc7Sjsg ram_table->min_reduction[1][2] = min_reduction_table[abm_config[set][2]]; 348c349dbc7Sjsg ram_table->min_reduction[2][2] = min_reduction_table[abm_config[set][2]]; 349c349dbc7Sjsg ram_table->min_reduction[3][2] = min_reduction_table[abm_config[set][2]]; 350c349dbc7Sjsg ram_table->min_reduction[4][2] = min_reduction_table[abm_config[set][2]]; 351c349dbc7Sjsg ram_table->max_reduction[0][2] = max_reduction_table[abm_config[set][2]]; 352c349dbc7Sjsg ram_table->max_reduction[1][2] = max_reduction_table[abm_config[set][2]]; 353c349dbc7Sjsg ram_table->max_reduction[2][2] = max_reduction_table[abm_config[set][2]]; 354c349dbc7Sjsg ram_table->max_reduction[3][2] = max_reduction_table[abm_config[set][2]]; 355c349dbc7Sjsg ram_table->max_reduction[4][2] = max_reduction_table[abm_config[set][2]]; 356c349dbc7Sjsg 357c349dbc7Sjsg ram_table->min_reduction[0][3] = min_reduction_table[abm_config[set][3]]; 358c349dbc7Sjsg ram_table->min_reduction[1][3] = min_reduction_table[abm_config[set][3]]; 359c349dbc7Sjsg ram_table->min_reduction[2][3] = min_reduction_table[abm_config[set][3]]; 360c349dbc7Sjsg ram_table->min_reduction[3][3] = min_reduction_table[abm_config[set][3]]; 361c349dbc7Sjsg ram_table->min_reduction[4][3] = min_reduction_table[abm_config[set][3]]; 362c349dbc7Sjsg ram_table->max_reduction[0][3] = max_reduction_table[abm_config[set][3]]; 363c349dbc7Sjsg ram_table->max_reduction[1][3] = max_reduction_table[abm_config[set][3]]; 364c349dbc7Sjsg ram_table->max_reduction[2][3] = max_reduction_table[abm_config[set][3]]; 365c349dbc7Sjsg ram_table->max_reduction[3][3] = max_reduction_table[abm_config[set][3]]; 366c349dbc7Sjsg ram_table->max_reduction[4][3] = max_reduction_table[abm_config[set][3]]; 367c349dbc7Sjsg 368c349dbc7Sjsg ram_table->bright_pos_gain[0][0] = 0x20; 369c349dbc7Sjsg ram_table->bright_pos_gain[0][1] = 0x20; 370c349dbc7Sjsg ram_table->bright_pos_gain[0][2] = 0x20; 371c349dbc7Sjsg ram_table->bright_pos_gain[0][3] = 0x20; 372c349dbc7Sjsg ram_table->bright_pos_gain[1][0] = 0x20; 373c349dbc7Sjsg ram_table->bright_pos_gain[1][1] = 0x20; 374c349dbc7Sjsg ram_table->bright_pos_gain[1][2] = 0x20; 375c349dbc7Sjsg ram_table->bright_pos_gain[1][3] = 0x20; 376c349dbc7Sjsg ram_table->bright_pos_gain[2][0] = 0x20; 377c349dbc7Sjsg ram_table->bright_pos_gain[2][1] = 0x20; 378c349dbc7Sjsg ram_table->bright_pos_gain[2][2] = 0x20; 379c349dbc7Sjsg ram_table->bright_pos_gain[2][3] = 0x20; 380c349dbc7Sjsg ram_table->bright_pos_gain[3][0] = 0x20; 381c349dbc7Sjsg ram_table->bright_pos_gain[3][1] = 0x20; 382c349dbc7Sjsg ram_table->bright_pos_gain[3][2] = 0x20; 383c349dbc7Sjsg ram_table->bright_pos_gain[3][3] = 0x20; 384c349dbc7Sjsg ram_table->bright_pos_gain[4][0] = 0x20; 385c349dbc7Sjsg ram_table->bright_pos_gain[4][1] = 0x20; 386c349dbc7Sjsg ram_table->bright_pos_gain[4][2] = 0x20; 387c349dbc7Sjsg ram_table->bright_pos_gain[4][3] = 0x20; 388ad8b1aafSjsg ram_table->bright_neg_gain[0][0] = 0x00; 389c349dbc7Sjsg ram_table->bright_neg_gain[0][1] = 0x00; 390c349dbc7Sjsg ram_table->bright_neg_gain[0][2] = 0x00; 391c349dbc7Sjsg ram_table->bright_neg_gain[0][3] = 0x00; 392c349dbc7Sjsg ram_table->bright_neg_gain[1][0] = 0x00; 393c349dbc7Sjsg ram_table->bright_neg_gain[1][1] = 0x00; 394c349dbc7Sjsg ram_table->bright_neg_gain[1][2] = 0x00; 395c349dbc7Sjsg ram_table->bright_neg_gain[1][3] = 0x00; 396c349dbc7Sjsg ram_table->bright_neg_gain[2][0] = 0x00; 397c349dbc7Sjsg ram_table->bright_neg_gain[2][1] = 0x00; 398c349dbc7Sjsg ram_table->bright_neg_gain[2][2] = 0x00; 399c349dbc7Sjsg ram_table->bright_neg_gain[2][3] = 0x00; 400c349dbc7Sjsg ram_table->bright_neg_gain[3][0] = 0x00; 401c349dbc7Sjsg ram_table->bright_neg_gain[3][1] = 0x00; 402c349dbc7Sjsg ram_table->bright_neg_gain[3][2] = 0x00; 403c349dbc7Sjsg ram_table->bright_neg_gain[3][3] = 0x00; 404c349dbc7Sjsg ram_table->bright_neg_gain[4][0] = 0x00; 405c349dbc7Sjsg ram_table->bright_neg_gain[4][1] = 0x00; 406c349dbc7Sjsg ram_table->bright_neg_gain[4][2] = 0x00; 407c349dbc7Sjsg ram_table->bright_neg_gain[4][3] = 0x00; 408c349dbc7Sjsg ram_table->dark_pos_gain[0][0] = 0x00; 409c349dbc7Sjsg ram_table->dark_pos_gain[0][1] = 0x00; 410c349dbc7Sjsg ram_table->dark_pos_gain[0][2] = 0x00; 411c349dbc7Sjsg ram_table->dark_pos_gain[0][3] = 0x00; 412c349dbc7Sjsg ram_table->dark_pos_gain[1][0] = 0x00; 413c349dbc7Sjsg ram_table->dark_pos_gain[1][1] = 0x00; 414c349dbc7Sjsg ram_table->dark_pos_gain[1][2] = 0x00; 415c349dbc7Sjsg ram_table->dark_pos_gain[1][3] = 0x00; 416c349dbc7Sjsg ram_table->dark_pos_gain[2][0] = 0x00; 417c349dbc7Sjsg ram_table->dark_pos_gain[2][1] = 0x00; 418c349dbc7Sjsg ram_table->dark_pos_gain[2][2] = 0x00; 419c349dbc7Sjsg ram_table->dark_pos_gain[2][3] = 0x00; 420c349dbc7Sjsg ram_table->dark_pos_gain[3][0] = 0x00; 421c349dbc7Sjsg ram_table->dark_pos_gain[3][1] = 0x00; 422c349dbc7Sjsg ram_table->dark_pos_gain[3][2] = 0x00; 423c349dbc7Sjsg ram_table->dark_pos_gain[3][3] = 0x00; 424c349dbc7Sjsg ram_table->dark_pos_gain[4][0] = 0x00; 425c349dbc7Sjsg ram_table->dark_pos_gain[4][1] = 0x00; 426c349dbc7Sjsg ram_table->dark_pos_gain[4][2] = 0x00; 427c349dbc7Sjsg ram_table->dark_pos_gain[4][3] = 0x00; 428c349dbc7Sjsg ram_table->dark_neg_gain[0][0] = 0x00; 429c349dbc7Sjsg ram_table->dark_neg_gain[0][1] = 0x00; 430c349dbc7Sjsg ram_table->dark_neg_gain[0][2] = 0x00; 431c349dbc7Sjsg ram_table->dark_neg_gain[0][3] = 0x00; 432c349dbc7Sjsg ram_table->dark_neg_gain[1][0] = 0x00; 433c349dbc7Sjsg ram_table->dark_neg_gain[1][1] = 0x00; 434c349dbc7Sjsg ram_table->dark_neg_gain[1][2] = 0x00; 435c349dbc7Sjsg ram_table->dark_neg_gain[1][3] = 0x00; 436c349dbc7Sjsg ram_table->dark_neg_gain[2][0] = 0x00; 437c349dbc7Sjsg ram_table->dark_neg_gain[2][1] = 0x00; 438c349dbc7Sjsg ram_table->dark_neg_gain[2][2] = 0x00; 439c349dbc7Sjsg ram_table->dark_neg_gain[2][3] = 0x00; 440c349dbc7Sjsg ram_table->dark_neg_gain[3][0] = 0x00; 441c349dbc7Sjsg ram_table->dark_neg_gain[3][1] = 0x00; 442c349dbc7Sjsg ram_table->dark_neg_gain[3][2] = 0x00; 443c349dbc7Sjsg ram_table->dark_neg_gain[3][3] = 0x00; 444c349dbc7Sjsg ram_table->dark_neg_gain[4][0] = 0x00; 445c349dbc7Sjsg ram_table->dark_neg_gain[4][1] = 0x00; 446c349dbc7Sjsg ram_table->dark_neg_gain[4][2] = 0x00; 447c349dbc7Sjsg ram_table->dark_neg_gain[4][3] = 0x00; 448c349dbc7Sjsg 449c349dbc7Sjsg ram_table->iir_curve[0] = 0x65; 450c349dbc7Sjsg ram_table->iir_curve[1] = 0x65; 451c349dbc7Sjsg ram_table->iir_curve[2] = 0x65; 452c349dbc7Sjsg ram_table->iir_curve[3] = 0x65; 453c349dbc7Sjsg ram_table->iir_curve[4] = 0x65; 454c349dbc7Sjsg 455c349dbc7Sjsg //Gamma 2.4 456c349dbc7Sjsg ram_table->crgb_thresh[0] = cpu_to_be16(0x13b6); 457c349dbc7Sjsg ram_table->crgb_thresh[1] = cpu_to_be16(0x1648); 458c349dbc7Sjsg ram_table->crgb_thresh[2] = cpu_to_be16(0x18e3); 459c349dbc7Sjsg ram_table->crgb_thresh[3] = cpu_to_be16(0x1b41); 460c349dbc7Sjsg ram_table->crgb_thresh[4] = cpu_to_be16(0x1d46); 461c349dbc7Sjsg ram_table->crgb_thresh[5] = cpu_to_be16(0x1f21); 462c349dbc7Sjsg ram_table->crgb_thresh[6] = cpu_to_be16(0x2167); 463c349dbc7Sjsg ram_table->crgb_thresh[7] = cpu_to_be16(0x2384); 464c349dbc7Sjsg ram_table->crgb_offset[0] = cpu_to_be16(0x2999); 465c349dbc7Sjsg ram_table->crgb_offset[1] = cpu_to_be16(0x3999); 466c349dbc7Sjsg ram_table->crgb_offset[2] = cpu_to_be16(0x4666); 467c349dbc7Sjsg ram_table->crgb_offset[3] = cpu_to_be16(0x5999); 468c349dbc7Sjsg ram_table->crgb_offset[4] = cpu_to_be16(0x6333); 469c349dbc7Sjsg ram_table->crgb_offset[5] = cpu_to_be16(0x7800); 470c349dbc7Sjsg ram_table->crgb_offset[6] = cpu_to_be16(0x8c00); 471c349dbc7Sjsg ram_table->crgb_offset[7] = cpu_to_be16(0xa000); 472c349dbc7Sjsg ram_table->crgb_slope[0] = cpu_to_be16(0x3147); 473c349dbc7Sjsg ram_table->crgb_slope[1] = cpu_to_be16(0x2978); 474c349dbc7Sjsg ram_table->crgb_slope[2] = cpu_to_be16(0x23a2); 475c349dbc7Sjsg ram_table->crgb_slope[3] = cpu_to_be16(0x1f55); 476c349dbc7Sjsg ram_table->crgb_slope[4] = cpu_to_be16(0x1c63); 477c349dbc7Sjsg ram_table->crgb_slope[5] = cpu_to_be16(0x1a0f); 478c349dbc7Sjsg ram_table->crgb_slope[6] = cpu_to_be16(0x178d); 479c349dbc7Sjsg ram_table->crgb_slope[7] = cpu_to_be16(0x15ab); 480c349dbc7Sjsg 481c349dbc7Sjsg fill_backlight_transform_table( 482c349dbc7Sjsg params, ram_table); 483c349dbc7Sjsg } 484c349dbc7Sjsg 4855ca02815Sjsg static void fill_iram_v_2_2(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params) 486c349dbc7Sjsg { 487c349dbc7Sjsg unsigned int set = params.set; 488c349dbc7Sjsg 489c349dbc7Sjsg ram_table->flags = 0x0; 490c349dbc7Sjsg 491c349dbc7Sjsg ram_table->min_abm_backlight = 492c349dbc7Sjsg cpu_to_be16(params.min_abm_backlight); 493c349dbc7Sjsg 494c349dbc7Sjsg ram_table->deviation_gain[0] = 0xb3; 495c349dbc7Sjsg ram_table->deviation_gain[1] = 0xa8; 496c349dbc7Sjsg ram_table->deviation_gain[2] = 0x98; 497c349dbc7Sjsg ram_table->deviation_gain[3] = 0x68; 498c349dbc7Sjsg 499c349dbc7Sjsg ram_table->min_reduction[0][0] = min_reduction_table_v_2_2[abm_config[set][0]]; 500c349dbc7Sjsg ram_table->min_reduction[1][0] = min_reduction_table_v_2_2[abm_config[set][0]]; 501c349dbc7Sjsg ram_table->min_reduction[2][0] = min_reduction_table_v_2_2[abm_config[set][0]]; 502c349dbc7Sjsg ram_table->min_reduction[3][0] = min_reduction_table_v_2_2[abm_config[set][0]]; 503c349dbc7Sjsg ram_table->min_reduction[4][0] = min_reduction_table_v_2_2[abm_config[set][0]]; 504c349dbc7Sjsg ram_table->max_reduction[0][0] = max_reduction_table_v_2_2[abm_config[set][0]]; 505c349dbc7Sjsg ram_table->max_reduction[1][0] = max_reduction_table_v_2_2[abm_config[set][0]]; 506c349dbc7Sjsg ram_table->max_reduction[2][0] = max_reduction_table_v_2_2[abm_config[set][0]]; 507c349dbc7Sjsg ram_table->max_reduction[3][0] = max_reduction_table_v_2_2[abm_config[set][0]]; 508c349dbc7Sjsg ram_table->max_reduction[4][0] = max_reduction_table_v_2_2[abm_config[set][0]]; 509c349dbc7Sjsg 510c349dbc7Sjsg ram_table->min_reduction[0][1] = min_reduction_table_v_2_2[abm_config[set][1]]; 511c349dbc7Sjsg ram_table->min_reduction[1][1] = min_reduction_table_v_2_2[abm_config[set][1]]; 512c349dbc7Sjsg ram_table->min_reduction[2][1] = min_reduction_table_v_2_2[abm_config[set][1]]; 513c349dbc7Sjsg ram_table->min_reduction[3][1] = min_reduction_table_v_2_2[abm_config[set][1]]; 514c349dbc7Sjsg ram_table->min_reduction[4][1] = min_reduction_table_v_2_2[abm_config[set][1]]; 515c349dbc7Sjsg ram_table->max_reduction[0][1] = max_reduction_table_v_2_2[abm_config[set][1]]; 516c349dbc7Sjsg ram_table->max_reduction[1][1] = max_reduction_table_v_2_2[abm_config[set][1]]; 517c349dbc7Sjsg ram_table->max_reduction[2][1] = max_reduction_table_v_2_2[abm_config[set][1]]; 518c349dbc7Sjsg ram_table->max_reduction[3][1] = max_reduction_table_v_2_2[abm_config[set][1]]; 519c349dbc7Sjsg ram_table->max_reduction[4][1] = max_reduction_table_v_2_2[abm_config[set][1]]; 520c349dbc7Sjsg 521c349dbc7Sjsg ram_table->min_reduction[0][2] = min_reduction_table_v_2_2[abm_config[set][2]]; 522c349dbc7Sjsg ram_table->min_reduction[1][2] = min_reduction_table_v_2_2[abm_config[set][2]]; 523c349dbc7Sjsg ram_table->min_reduction[2][2] = min_reduction_table_v_2_2[abm_config[set][2]]; 524c349dbc7Sjsg ram_table->min_reduction[3][2] = min_reduction_table_v_2_2[abm_config[set][2]]; 525c349dbc7Sjsg ram_table->min_reduction[4][2] = min_reduction_table_v_2_2[abm_config[set][2]]; 526c349dbc7Sjsg ram_table->max_reduction[0][2] = max_reduction_table_v_2_2[abm_config[set][2]]; 527c349dbc7Sjsg ram_table->max_reduction[1][2] = max_reduction_table_v_2_2[abm_config[set][2]]; 528c349dbc7Sjsg ram_table->max_reduction[2][2] = max_reduction_table_v_2_2[abm_config[set][2]]; 529c349dbc7Sjsg ram_table->max_reduction[3][2] = max_reduction_table_v_2_2[abm_config[set][2]]; 530c349dbc7Sjsg ram_table->max_reduction[4][2] = max_reduction_table_v_2_2[abm_config[set][2]]; 531c349dbc7Sjsg 532c349dbc7Sjsg ram_table->min_reduction[0][3] = min_reduction_table_v_2_2[abm_config[set][3]]; 533c349dbc7Sjsg ram_table->min_reduction[1][3] = min_reduction_table_v_2_2[abm_config[set][3]]; 534c349dbc7Sjsg ram_table->min_reduction[2][3] = min_reduction_table_v_2_2[abm_config[set][3]]; 535c349dbc7Sjsg ram_table->min_reduction[3][3] = min_reduction_table_v_2_2[abm_config[set][3]]; 536c349dbc7Sjsg ram_table->min_reduction[4][3] = min_reduction_table_v_2_2[abm_config[set][3]]; 537c349dbc7Sjsg ram_table->max_reduction[0][3] = max_reduction_table_v_2_2[abm_config[set][3]]; 538c349dbc7Sjsg ram_table->max_reduction[1][3] = max_reduction_table_v_2_2[abm_config[set][3]]; 539c349dbc7Sjsg ram_table->max_reduction[2][3] = max_reduction_table_v_2_2[abm_config[set][3]]; 540c349dbc7Sjsg ram_table->max_reduction[3][3] = max_reduction_table_v_2_2[abm_config[set][3]]; 541c349dbc7Sjsg ram_table->max_reduction[4][3] = max_reduction_table_v_2_2[abm_config[set][3]]; 542c349dbc7Sjsg 543c349dbc7Sjsg ram_table->bright_pos_gain[0][0] = 0x20; 544c349dbc7Sjsg ram_table->bright_pos_gain[0][1] = 0x20; 545c349dbc7Sjsg ram_table->bright_pos_gain[0][2] = 0x20; 546c349dbc7Sjsg ram_table->bright_pos_gain[0][3] = 0x20; 547c349dbc7Sjsg ram_table->bright_pos_gain[1][0] = 0x20; 548c349dbc7Sjsg ram_table->bright_pos_gain[1][1] = 0x20; 549c349dbc7Sjsg ram_table->bright_pos_gain[1][2] = 0x20; 550c349dbc7Sjsg ram_table->bright_pos_gain[1][3] = 0x20; 551c349dbc7Sjsg ram_table->bright_pos_gain[2][0] = 0x20; 552c349dbc7Sjsg ram_table->bright_pos_gain[2][1] = 0x20; 553c349dbc7Sjsg ram_table->bright_pos_gain[2][2] = 0x20; 554c349dbc7Sjsg ram_table->bright_pos_gain[2][3] = 0x20; 555c349dbc7Sjsg ram_table->bright_pos_gain[3][0] = 0x20; 556c349dbc7Sjsg ram_table->bright_pos_gain[3][1] = 0x20; 557c349dbc7Sjsg ram_table->bright_pos_gain[3][2] = 0x20; 558c349dbc7Sjsg ram_table->bright_pos_gain[3][3] = 0x20; 559c349dbc7Sjsg ram_table->bright_pos_gain[4][0] = 0x20; 560c349dbc7Sjsg ram_table->bright_pos_gain[4][1] = 0x20; 561c349dbc7Sjsg ram_table->bright_pos_gain[4][2] = 0x20; 562c349dbc7Sjsg ram_table->bright_pos_gain[4][3] = 0x20; 563c349dbc7Sjsg 564c349dbc7Sjsg ram_table->dark_pos_gain[0][0] = 0x00; 565c349dbc7Sjsg ram_table->dark_pos_gain[0][1] = 0x00; 566c349dbc7Sjsg ram_table->dark_pos_gain[0][2] = 0x00; 567c349dbc7Sjsg ram_table->dark_pos_gain[0][3] = 0x00; 568c349dbc7Sjsg ram_table->dark_pos_gain[1][0] = 0x00; 569c349dbc7Sjsg ram_table->dark_pos_gain[1][1] = 0x00; 570c349dbc7Sjsg ram_table->dark_pos_gain[1][2] = 0x00; 571c349dbc7Sjsg ram_table->dark_pos_gain[1][3] = 0x00; 572c349dbc7Sjsg ram_table->dark_pos_gain[2][0] = 0x00; 573c349dbc7Sjsg ram_table->dark_pos_gain[2][1] = 0x00; 574c349dbc7Sjsg ram_table->dark_pos_gain[2][2] = 0x00; 575c349dbc7Sjsg ram_table->dark_pos_gain[2][3] = 0x00; 576c349dbc7Sjsg ram_table->dark_pos_gain[3][0] = 0x00; 577c349dbc7Sjsg ram_table->dark_pos_gain[3][1] = 0x00; 578c349dbc7Sjsg ram_table->dark_pos_gain[3][2] = 0x00; 579c349dbc7Sjsg ram_table->dark_pos_gain[3][3] = 0x00; 580c349dbc7Sjsg ram_table->dark_pos_gain[4][0] = 0x00; 581c349dbc7Sjsg ram_table->dark_pos_gain[4][1] = 0x00; 582c349dbc7Sjsg ram_table->dark_pos_gain[4][2] = 0x00; 583c349dbc7Sjsg ram_table->dark_pos_gain[4][3] = 0x00; 584c349dbc7Sjsg 585c349dbc7Sjsg ram_table->hybrid_factor[0] = 0xff; 586c349dbc7Sjsg ram_table->hybrid_factor[1] = 0xff; 587c349dbc7Sjsg ram_table->hybrid_factor[2] = 0xff; 588c349dbc7Sjsg ram_table->hybrid_factor[3] = 0xc0; 589c349dbc7Sjsg 590c349dbc7Sjsg ram_table->contrast_factor[0] = 0x99; 591c349dbc7Sjsg ram_table->contrast_factor[1] = 0x99; 592c349dbc7Sjsg ram_table->contrast_factor[2] = 0x90; 593c349dbc7Sjsg ram_table->contrast_factor[3] = 0x80; 594c349dbc7Sjsg 595c349dbc7Sjsg ram_table->iir_curve[0] = 0x65; 596c349dbc7Sjsg ram_table->iir_curve[1] = 0x65; 597c349dbc7Sjsg ram_table->iir_curve[2] = 0x65; 598c349dbc7Sjsg ram_table->iir_curve[3] = 0x65; 599c349dbc7Sjsg ram_table->iir_curve[4] = 0x65; 600c349dbc7Sjsg 601c349dbc7Sjsg //Gamma 2.2 602c349dbc7Sjsg ram_table->crgb_thresh[0] = cpu_to_be16(0x127c); 603c349dbc7Sjsg ram_table->crgb_thresh[1] = cpu_to_be16(0x151b); 604c349dbc7Sjsg ram_table->crgb_thresh[2] = cpu_to_be16(0x17d5); 605c349dbc7Sjsg ram_table->crgb_thresh[3] = cpu_to_be16(0x1a56); 606c349dbc7Sjsg ram_table->crgb_thresh[4] = cpu_to_be16(0x1c83); 607c349dbc7Sjsg ram_table->crgb_thresh[5] = cpu_to_be16(0x1e72); 608c349dbc7Sjsg ram_table->crgb_thresh[6] = cpu_to_be16(0x20f0); 609c349dbc7Sjsg ram_table->crgb_thresh[7] = cpu_to_be16(0x232b); 610c349dbc7Sjsg ram_table->crgb_offset[0] = cpu_to_be16(0x2999); 611c349dbc7Sjsg ram_table->crgb_offset[1] = cpu_to_be16(0x3999); 612c349dbc7Sjsg ram_table->crgb_offset[2] = cpu_to_be16(0x4666); 613c349dbc7Sjsg ram_table->crgb_offset[3] = cpu_to_be16(0x5999); 614c349dbc7Sjsg ram_table->crgb_offset[4] = cpu_to_be16(0x6333); 615c349dbc7Sjsg ram_table->crgb_offset[5] = cpu_to_be16(0x7800); 616c349dbc7Sjsg ram_table->crgb_offset[6] = cpu_to_be16(0x8c00); 617c349dbc7Sjsg ram_table->crgb_offset[7] = cpu_to_be16(0xa000); 618c349dbc7Sjsg ram_table->crgb_slope[0] = cpu_to_be16(0x3609); 619c349dbc7Sjsg ram_table->crgb_slope[1] = cpu_to_be16(0x2dfa); 620c349dbc7Sjsg ram_table->crgb_slope[2] = cpu_to_be16(0x27ea); 621c349dbc7Sjsg ram_table->crgb_slope[3] = cpu_to_be16(0x235d); 622c349dbc7Sjsg ram_table->crgb_slope[4] = cpu_to_be16(0x2042); 623c349dbc7Sjsg ram_table->crgb_slope[5] = cpu_to_be16(0x1dc3); 624c349dbc7Sjsg ram_table->crgb_slope[6] = cpu_to_be16(0x1b1a); 625c349dbc7Sjsg ram_table->crgb_slope[7] = cpu_to_be16(0x1910); 626c349dbc7Sjsg 627c349dbc7Sjsg fill_backlight_transform_table_v_2_2( 628ad8b1aafSjsg params, ram_table, true); 629c349dbc7Sjsg } 630c349dbc7Sjsg 6315ca02815Sjsg static void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params, bool big_endian) 632c349dbc7Sjsg { 633c349dbc7Sjsg unsigned int i, j; 634c349dbc7Sjsg unsigned int set = params.set; 635c349dbc7Sjsg 636c349dbc7Sjsg ram_table->flags = 0x0; 637ad8b1aafSjsg ram_table->min_abm_backlight = (big_endian) ? 638ad8b1aafSjsg cpu_to_be16(params.min_abm_backlight) : 639ad8b1aafSjsg cpu_to_le16(params.min_abm_backlight); 640c349dbc7Sjsg 641c349dbc7Sjsg for (i = 0; i < NUM_AGGR_LEVEL; i++) { 642c349dbc7Sjsg ram_table->hybrid_factor[i] = abm_settings[set][i].brightness_gain; 643c349dbc7Sjsg ram_table->contrast_factor[i] = abm_settings[set][i].contrast_factor; 644c349dbc7Sjsg ram_table->deviation_gain[i] = abm_settings[set][i].deviation_gain; 645c349dbc7Sjsg ram_table->min_knee[i] = abm_settings[set][i].min_knee; 646c349dbc7Sjsg ram_table->max_knee[i] = abm_settings[set][i].max_knee; 647c349dbc7Sjsg 648c349dbc7Sjsg for (j = 0; j < NUM_AMBI_LEVEL; j++) { 649c349dbc7Sjsg ram_table->min_reduction[j][i] = abm_settings[set][i].min_reduction; 650c349dbc7Sjsg ram_table->max_reduction[j][i] = abm_settings[set][i].max_reduction; 651c349dbc7Sjsg ram_table->bright_pos_gain[j][i] = abm_settings[set][i].bright_pos_gain; 652c349dbc7Sjsg ram_table->dark_pos_gain[j][i] = abm_settings[set][i].dark_pos_gain; 653c349dbc7Sjsg } 654c349dbc7Sjsg } 655c349dbc7Sjsg 656c349dbc7Sjsg ram_table->iir_curve[0] = 0x65; 657c349dbc7Sjsg ram_table->iir_curve[1] = 0x65; 658c349dbc7Sjsg ram_table->iir_curve[2] = 0x65; 659c349dbc7Sjsg ram_table->iir_curve[3] = 0x65; 660c349dbc7Sjsg ram_table->iir_curve[4] = 0x65; 661c349dbc7Sjsg 662c349dbc7Sjsg //Gamma 2.2 663ad8b1aafSjsg ram_table->crgb_thresh[0] = bswap16_based_on_endian(big_endian, 0x127c); 664ad8b1aafSjsg ram_table->crgb_thresh[1] = bswap16_based_on_endian(big_endian, 0x151b); 665ad8b1aafSjsg ram_table->crgb_thresh[2] = bswap16_based_on_endian(big_endian, 0x17d5); 666ad8b1aafSjsg ram_table->crgb_thresh[3] = bswap16_based_on_endian(big_endian, 0x1a56); 667ad8b1aafSjsg ram_table->crgb_thresh[4] = bswap16_based_on_endian(big_endian, 0x1c83); 668ad8b1aafSjsg ram_table->crgb_thresh[5] = bswap16_based_on_endian(big_endian, 0x1e72); 669ad8b1aafSjsg ram_table->crgb_thresh[6] = bswap16_based_on_endian(big_endian, 0x20f0); 670ad8b1aafSjsg ram_table->crgb_thresh[7] = bswap16_based_on_endian(big_endian, 0x232b); 671ad8b1aafSjsg ram_table->crgb_offset[0] = bswap16_based_on_endian(big_endian, 0x2999); 672ad8b1aafSjsg ram_table->crgb_offset[1] = bswap16_based_on_endian(big_endian, 0x3999); 673ad8b1aafSjsg ram_table->crgb_offset[2] = bswap16_based_on_endian(big_endian, 0x4666); 674ad8b1aafSjsg ram_table->crgb_offset[3] = bswap16_based_on_endian(big_endian, 0x5999); 675ad8b1aafSjsg ram_table->crgb_offset[4] = bswap16_based_on_endian(big_endian, 0x6333); 676ad8b1aafSjsg ram_table->crgb_offset[5] = bswap16_based_on_endian(big_endian, 0x7800); 677ad8b1aafSjsg ram_table->crgb_offset[6] = bswap16_based_on_endian(big_endian, 0x8c00); 678ad8b1aafSjsg ram_table->crgb_offset[7] = bswap16_based_on_endian(big_endian, 0xa000); 679ad8b1aafSjsg ram_table->crgb_slope[0] = bswap16_based_on_endian(big_endian, 0x3609); 680ad8b1aafSjsg ram_table->crgb_slope[1] = bswap16_based_on_endian(big_endian, 0x2dfa); 681ad8b1aafSjsg ram_table->crgb_slope[2] = bswap16_based_on_endian(big_endian, 0x27ea); 682ad8b1aafSjsg ram_table->crgb_slope[3] = bswap16_based_on_endian(big_endian, 0x235d); 683ad8b1aafSjsg ram_table->crgb_slope[4] = bswap16_based_on_endian(big_endian, 0x2042); 684ad8b1aafSjsg ram_table->crgb_slope[5] = bswap16_based_on_endian(big_endian, 0x1dc3); 685ad8b1aafSjsg ram_table->crgb_slope[6] = bswap16_based_on_endian(big_endian, 0x1b1a); 686ad8b1aafSjsg ram_table->crgb_slope[7] = bswap16_based_on_endian(big_endian, 0x1910); 687c349dbc7Sjsg 688c349dbc7Sjsg fill_backlight_transform_table_v_2_2( 689ad8b1aafSjsg params, ram_table, big_endian); 690ad8b1aafSjsg } 691ad8b1aafSjsg 692ad8b1aafSjsg bool dmub_init_abm_config(struct resource_pool *res_pool, 6935ca02815Sjsg struct dmcu_iram_parameters params, 6945ca02815Sjsg unsigned int inst) 695ad8b1aafSjsg { 696ad8b1aafSjsg struct iram_table_v_2_2 ram_table; 697ad8b1aafSjsg struct abm_config_table config; 6985ca02815Sjsg unsigned int set = params.set; 699ad8b1aafSjsg bool result = false; 700ad8b1aafSjsg uint32_t i, j = 0; 701ad8b1aafSjsg 7025ca02815Sjsg if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL) 703ad8b1aafSjsg return false; 704ad8b1aafSjsg 705ad8b1aafSjsg memset(&ram_table, 0, sizeof(ram_table)); 706ad8b1aafSjsg memset(&config, 0, sizeof(config)); 707ad8b1aafSjsg 708ad8b1aafSjsg fill_iram_v_2_3(&ram_table, params, false); 709ad8b1aafSjsg 710ad8b1aafSjsg // We must copy to structure that is aligned to 32-bit 711ad8b1aafSjsg for (i = 0; i < NUM_POWER_FN_SEGS; i++) { 712ad8b1aafSjsg config.crgb_thresh[i] = ram_table.crgb_thresh[i]; 713ad8b1aafSjsg config.crgb_offset[i] = ram_table.crgb_offset[i]; 714ad8b1aafSjsg config.crgb_slope[i] = ram_table.crgb_slope[i]; 715ad8b1aafSjsg } 716ad8b1aafSjsg 717ad8b1aafSjsg for (i = 0; i < NUM_BL_CURVE_SEGS; i++) { 718ad8b1aafSjsg config.backlight_thresholds[i] = ram_table.backlight_thresholds[i]; 719ad8b1aafSjsg config.backlight_offsets[i] = ram_table.backlight_offsets[i]; 720ad8b1aafSjsg } 721ad8b1aafSjsg 722ad8b1aafSjsg for (i = 0; i < NUM_AMBI_LEVEL; i++) 723ad8b1aafSjsg config.iir_curve[i] = ram_table.iir_curve[i]; 724ad8b1aafSjsg 725ad8b1aafSjsg for (i = 0; i < NUM_AMBI_LEVEL; i++) { 726ad8b1aafSjsg for (j = 0; j < NUM_AGGR_LEVEL; j++) { 727ad8b1aafSjsg config.min_reduction[i][j] = ram_table.min_reduction[i][j]; 728ad8b1aafSjsg config.max_reduction[i][j] = ram_table.max_reduction[i][j]; 729ad8b1aafSjsg config.bright_pos_gain[i][j] = ram_table.bright_pos_gain[i][j]; 730ad8b1aafSjsg config.dark_pos_gain[i][j] = ram_table.dark_pos_gain[i][j]; 731ad8b1aafSjsg } 732ad8b1aafSjsg } 733ad8b1aafSjsg 734ad8b1aafSjsg for (i = 0; i < NUM_AGGR_LEVEL; i++) { 735ad8b1aafSjsg config.hybrid_factor[i] = ram_table.hybrid_factor[i]; 736ad8b1aafSjsg config.contrast_factor[i] = ram_table.contrast_factor[i]; 737ad8b1aafSjsg config.deviation_gain[i] = ram_table.deviation_gain[i]; 738ad8b1aafSjsg config.min_knee[i] = ram_table.min_knee[i]; 739ad8b1aafSjsg config.max_knee[i] = ram_table.max_knee[i]; 740ad8b1aafSjsg } 741ad8b1aafSjsg 7425ca02815Sjsg if (params.backlight_ramping_override) { 7435ca02815Sjsg for (i = 0; i < NUM_AGGR_LEVEL; i++) { 7445ca02815Sjsg config.blRampReduction[i] = params.backlight_ramping_reduction; 7455ca02815Sjsg config.blRampStart[i] = params.backlight_ramping_start; 7465ca02815Sjsg } 7475ca02815Sjsg } else { 7485ca02815Sjsg for (i = 0; i < NUM_AGGR_LEVEL; i++) { 7495ca02815Sjsg config.blRampReduction[i] = abm_settings[set][i].blRampReduction; 7505ca02815Sjsg config.blRampStart[i] = abm_settings[set][i].blRampStart; 7515ca02815Sjsg } 7525ca02815Sjsg } 7535ca02815Sjsg 754ad8b1aafSjsg config.min_abm_backlight = ram_table.min_abm_backlight; 755ad8b1aafSjsg 7565ca02815Sjsg if (res_pool->multiple_abms[inst]) { 7575ca02815Sjsg result = res_pool->multiple_abms[inst]->funcs->init_abm_config( 7585ca02815Sjsg res_pool->multiple_abms[inst], (char *)(&config), sizeof(struct abm_config_table), inst); 759ad8b1aafSjsg } else 760ad8b1aafSjsg result = res_pool->abm->funcs->init_abm_config( 7615ca02815Sjsg res_pool->abm, (char *)(&config), sizeof(struct abm_config_table), 0); 762ad8b1aafSjsg 763ad8b1aafSjsg return result; 764c349dbc7Sjsg } 765c349dbc7Sjsg 766c349dbc7Sjsg bool dmcu_load_iram(struct dmcu *dmcu, 767c349dbc7Sjsg struct dmcu_iram_parameters params) 768c349dbc7Sjsg { 769c349dbc7Sjsg unsigned char ram_table[IRAM_SIZE]; 770c349dbc7Sjsg bool result = false; 771c349dbc7Sjsg 772c349dbc7Sjsg if (dmcu == NULL) 773c349dbc7Sjsg return false; 774c349dbc7Sjsg 775ad8b1aafSjsg if (dmcu && !dmcu->funcs->is_dmcu_initialized(dmcu)) 776c349dbc7Sjsg return true; 777c349dbc7Sjsg 778c349dbc7Sjsg memset(&ram_table, 0, sizeof(ram_table)); 779c349dbc7Sjsg 780c349dbc7Sjsg if (dmcu->dmcu_version.abm_version == 0x24) { 781ad8b1aafSjsg fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true); 782f005ef32Sjsg result = dmcu->funcs->load_iram(dmcu, 0, (char *)(&ram_table), 783f005ef32Sjsg IRAM_RESERVE_AREA_START_V2_2); 784c349dbc7Sjsg } else if (dmcu->dmcu_version.abm_version == 0x23) { 785ad8b1aafSjsg fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true); 786c349dbc7Sjsg 787c349dbc7Sjsg result = dmcu->funcs->load_iram( 788c349dbc7Sjsg dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2); 789c349dbc7Sjsg } else if (dmcu->dmcu_version.abm_version == 0x22) { 790c349dbc7Sjsg fill_iram_v_2_2((struct iram_table_v_2_2 *)ram_table, params); 791c349dbc7Sjsg 792c349dbc7Sjsg result = dmcu->funcs->load_iram( 793c349dbc7Sjsg dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2); 794c349dbc7Sjsg } else { 795c349dbc7Sjsg fill_iram_v_2((struct iram_table_v_2 *)ram_table, params); 796c349dbc7Sjsg 797c349dbc7Sjsg result = dmcu->funcs->load_iram( 798c349dbc7Sjsg dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2); 799c349dbc7Sjsg 800c349dbc7Sjsg if (result) 801c349dbc7Sjsg result = dmcu->funcs->load_iram( 802c349dbc7Sjsg dmcu, IRAM_RESERVE_AREA_END_V2 + 1, 803c349dbc7Sjsg (char *)(&ram_table) + IRAM_RESERVE_AREA_END_V2 + 1, 804c349dbc7Sjsg sizeof(ram_table) - IRAM_RESERVE_AREA_END_V2 - 1); 805c349dbc7Sjsg } 806c349dbc7Sjsg 807c349dbc7Sjsg return result; 808c349dbc7Sjsg } 809c349dbc7Sjsg 8101bb76ff1Sjsg /* 8111bb76ff1Sjsg * is_psr_su_specific_panel() - check if sink is AMD vendor-specific PSR-SU 8121bb76ff1Sjsg * supported eDP device. 8131bb76ff1Sjsg * 8141bb76ff1Sjsg * @link: dc link pointer 8151bb76ff1Sjsg * 8161bb76ff1Sjsg * Return: true if AMDGPU vendor specific PSR-SU eDP panel 8171bb76ff1Sjsg */ 8181bb76ff1Sjsg bool is_psr_su_specific_panel(struct dc_link *link) 8191bb76ff1Sjsg { 8201bb76ff1Sjsg bool isPSRSUSupported = false; 8211bb76ff1Sjsg struct dpcd_caps *dpcd_caps = &link->dpcd_caps; 8221bb76ff1Sjsg 8231bb76ff1Sjsg if (dpcd_caps->edp_rev >= DP_EDP_14) { 8241bb76ff1Sjsg if (dpcd_caps->psr_info.psr_version >= DP_PSR2_WITH_Y_COORD_ET_SUPPORTED) 8251bb76ff1Sjsg isPSRSUSupported = true; 8261bb76ff1Sjsg /* 8271bb76ff1Sjsg * Some panels will report PSR capabilities over additional DPCD bits. 8281bb76ff1Sjsg * Such panels are approved despite reporting only PSR v3, as long as 8291bb76ff1Sjsg * the additional bits are reported. 8301bb76ff1Sjsg */ 8311bb76ff1Sjsg if (dpcd_caps->sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) { 8321bb76ff1Sjsg /* 8331bb76ff1Sjsg * This is the temporary workaround to disable PSRSU when system turned on 8341bb76ff1Sjsg * DSC function on the sepcific sink. 8351bb76ff1Sjsg */ 8361bb76ff1Sjsg if (dpcd_caps->psr_info.psr_version < DP_PSR2_WITH_Y_COORD_IS_SUPPORTED) 8371bb76ff1Sjsg isPSRSUSupported = false; 8381bb76ff1Sjsg else if (dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT && 8391bb76ff1Sjsg ((dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x08) || 8401bb76ff1Sjsg (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x07))) 8411bb76ff1Sjsg isPSRSUSupported = false; 842b5a87694Sjsg else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03) 843b5a87694Sjsg isPSRSUSupported = false; 844*c2596b38Sjsg else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x01) 845*c2596b38Sjsg isPSRSUSupported = false; 8461bb76ff1Sjsg else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1) 8471bb76ff1Sjsg isPSRSUSupported = true; 8481bb76ff1Sjsg } 8491bb76ff1Sjsg } 8501bb76ff1Sjsg 8511bb76ff1Sjsg return isPSRSUSupported; 8521bb76ff1Sjsg } 8531bb76ff1Sjsg 8541bb76ff1Sjsg /** 8551bb76ff1Sjsg * mod_power_calc_psr_configs() - calculate/update generic psr configuration fields. 8561bb76ff1Sjsg * @psr_config: [output], psr configuration structure to be updated 8571bb76ff1Sjsg * @link: [input] dc link pointer 8581bb76ff1Sjsg * @stream: [input] dc stream state pointer 8591bb76ff1Sjsg * 8601bb76ff1Sjsg * calculate and update the psr configuration fields that are not DM specific, i.e. such 8611bb76ff1Sjsg * fields which are based on DPCD caps or timing information. To setup PSR in DMUB FW, 8621bb76ff1Sjsg * this helper is assumed to be called before the call of the DC helper dc_link_setup_psr(). 8631bb76ff1Sjsg * 8641bb76ff1Sjsg * PSR config fields to be updated within the helper: 8651bb76ff1Sjsg * - psr_rfb_setup_time 8661bb76ff1Sjsg * - psr_sdp_transmit_line_num_deadline 8671bb76ff1Sjsg * - line_time_in_us 8681bb76ff1Sjsg * - su_y_granularity 8691bb76ff1Sjsg * - su_granularity_required 8701bb76ff1Sjsg * - psr_frame_capture_indication_req 8711bb76ff1Sjsg * - psr_exit_link_training_required 8721bb76ff1Sjsg * 8731bb76ff1Sjsg * PSR config fields that are DM specific and NOT updated within the helper: 8741bb76ff1Sjsg * - allow_smu_optimizations 8751bb76ff1Sjsg * - allow_multi_disp_optimizations 8761bb76ff1Sjsg */ 8771bb76ff1Sjsg void mod_power_calc_psr_configs(struct psr_config *psr_config, 8781bb76ff1Sjsg struct dc_link *link, 8791bb76ff1Sjsg const struct dc_stream_state *stream) 8801bb76ff1Sjsg { 8811bb76ff1Sjsg unsigned int num_vblank_lines = 0; 8821bb76ff1Sjsg unsigned int vblank_time_in_us = 0; 8831bb76ff1Sjsg unsigned int sdp_tx_deadline_in_us = 0; 8841bb76ff1Sjsg unsigned int line_time_in_us = 0; 8851bb76ff1Sjsg struct dpcd_caps *dpcd_caps = &link->dpcd_caps; 8861bb76ff1Sjsg const int psr_setup_time_step_in_us = 55; /* refer to eDP spec DPCD 0x071h */ 8871bb76ff1Sjsg 8881bb76ff1Sjsg /* timing parameters */ 8891bb76ff1Sjsg num_vblank_lines = stream->timing.v_total - 8901bb76ff1Sjsg stream->timing.v_addressable - 8911bb76ff1Sjsg stream->timing.v_border_top - 8921bb76ff1Sjsg stream->timing.v_border_bottom; 8931bb76ff1Sjsg 8941bb76ff1Sjsg vblank_time_in_us = (stream->timing.h_total * num_vblank_lines * 1000) / (stream->timing.pix_clk_100hz / 10); 8951bb76ff1Sjsg 8961bb76ff1Sjsg line_time_in_us = ((stream->timing.h_total * 1000) / (stream->timing.pix_clk_100hz / 10)) + 1; 8971bb76ff1Sjsg 8981bb76ff1Sjsg /** 8991bb76ff1Sjsg * psr configuration fields 9001bb76ff1Sjsg * 9011bb76ff1Sjsg * as per eDP 1.5 pg. 377 of 459, DPCD 0x071h bits [3:1], psr setup time bits interpreted as below 9021bb76ff1Sjsg * 000b <--> 330 us (default) 9031bb76ff1Sjsg * 001b <--> 275 us 9041bb76ff1Sjsg * 010b <--> 220 us 9051bb76ff1Sjsg * 011b <--> 165 us 9061bb76ff1Sjsg * 100b <--> 110 us 9071bb76ff1Sjsg * 101b <--> 055 us 9081bb76ff1Sjsg * 110b <--> 000 us 9091bb76ff1Sjsg */ 9101bb76ff1Sjsg psr_config->psr_rfb_setup_time = 9111bb76ff1Sjsg (6 - dpcd_caps->psr_info.psr_dpcd_caps.bits.PSR_SETUP_TIME) * psr_setup_time_step_in_us; 9121bb76ff1Sjsg 9131bb76ff1Sjsg if (psr_config->psr_rfb_setup_time > vblank_time_in_us) { 9141bb76ff1Sjsg link->psr_settings.psr_frame_capture_indication_req = true; 9151bb76ff1Sjsg link->psr_settings.psr_sdp_transmit_line_num_deadline = num_vblank_lines; 9161bb76ff1Sjsg } else { 9171bb76ff1Sjsg sdp_tx_deadline_in_us = vblank_time_in_us - psr_config->psr_rfb_setup_time; 9181bb76ff1Sjsg 9191bb76ff1Sjsg /* Set the last possible line SDP may be transmitted without violating the RFB setup time */ 9201bb76ff1Sjsg link->psr_settings.psr_frame_capture_indication_req = false; 9211bb76ff1Sjsg link->psr_settings.psr_sdp_transmit_line_num_deadline = sdp_tx_deadline_in_us / line_time_in_us; 9221bb76ff1Sjsg } 9231bb76ff1Sjsg 9241bb76ff1Sjsg psr_config->psr_sdp_transmit_line_num_deadline = link->psr_settings.psr_sdp_transmit_line_num_deadline; 9251bb76ff1Sjsg psr_config->line_time_in_us = line_time_in_us; 9261bb76ff1Sjsg psr_config->su_y_granularity = dpcd_caps->psr_info.psr2_su_y_granularity_cap; 9271bb76ff1Sjsg psr_config->su_granularity_required = dpcd_caps->psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED; 9281bb76ff1Sjsg psr_config->psr_frame_capture_indication_req = link->psr_settings.psr_frame_capture_indication_req; 9291bb76ff1Sjsg psr_config->psr_exit_link_training_required = 9301bb76ff1Sjsg !link->dpcd_caps.psr_info.psr_dpcd_caps.bits.LINK_TRAINING_ON_EXIT_NOT_REQUIRED; 9311bb76ff1Sjsg } 9321bb76ff1Sjsg 933f005ef32Sjsg void init_replay_config(struct dc_link *link, struct replay_config *pr_config) 934f005ef32Sjsg { 935f005ef32Sjsg link->replay_settings.config = *pr_config; 936f005ef32Sjsg } 937f005ef32Sjsg 9381bb76ff1Sjsg bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_state *stream) 9391bb76ff1Sjsg { 9401bb76ff1Sjsg return context && context->stream_count == 1 && dc_is_embedded_signal(stream->signal); 9411bb76ff1Sjsg } 9429cb0f46aSjsg 943f005ef32Sjsg bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, 9449cb0f46aSjsg struct dc_stream_state *stream, 9459cb0f46aSjsg struct psr_config *config) 9469cb0f46aSjsg { 9479cb0f46aSjsg uint16_t pic_height; 948f005ef32Sjsg uint16_t slice_height; 9499cb0f46aSjsg 950f005ef32Sjsg config->dsc_slice_height = 0; 9519cb0f46aSjsg if ((link->connector_signal & SIGNAL_TYPE_EDP) && 9529cb0f46aSjsg (!dc->caps.edp_dsc_support || 9539cb0f46aSjsg link->panel_config.dsc.disable_dsc_edp || 9549cb0f46aSjsg !link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT || 9559cb0f46aSjsg !stream->timing.dsc_cfg.num_slices_v)) 9569cb0f46aSjsg return true; 9579cb0f46aSjsg 9589cb0f46aSjsg pic_height = stream->timing.v_addressable + 9599cb0f46aSjsg stream->timing.v_border_top + stream->timing.v_border_bottom; 9607db262eaSjsg 9617db262eaSjsg if (stream->timing.dsc_cfg.num_slices_v == 0) 9627db262eaSjsg return false; 9637db262eaSjsg 9649cb0f46aSjsg slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v; 965f005ef32Sjsg config->dsc_slice_height = slice_height; 9669cb0f46aSjsg 9679cb0f46aSjsg if (slice_height) { 9689cb0f46aSjsg if (config->su_y_granularity && 9699cb0f46aSjsg (slice_height % config->su_y_granularity)) { 9709cb0f46aSjsg ASSERT(0); 9719cb0f46aSjsg return false; 9729cb0f46aSjsg } 9739cb0f46aSjsg } 9749cb0f46aSjsg 9759cb0f46aSjsg return true; 9769cb0f46aSjsg } 977f005ef32Sjsg 978f005ef32Sjsg bool fill_custom_backlight_caps(unsigned int config_no, struct dm_acpi_atif_backlight_caps *caps) 979f005ef32Sjsg { 980f005ef32Sjsg unsigned int data_points_size; 981f005ef32Sjsg 982f005ef32Sjsg if (config_no >= ARRAY_SIZE(custom_backlight_profiles)) 983f005ef32Sjsg return false; 984f005ef32Sjsg 985f005ef32Sjsg data_points_size = custom_backlight_profiles[config_no].num_data_points 986f005ef32Sjsg * sizeof(custom_backlight_profiles[config_no].data_points[0]); 987f005ef32Sjsg 988f005ef32Sjsg caps->size = sizeof(struct dm_acpi_atif_backlight_caps) - sizeof(caps->data_points) + data_points_size; 989f005ef32Sjsg caps->flags = 0; 990f005ef32Sjsg caps->error_code = 0; 991f005ef32Sjsg caps->ac_level_percentage = custom_backlight_profiles[config_no].ac_level_percentage; 992f005ef32Sjsg caps->dc_level_percentage = custom_backlight_profiles[config_no].dc_level_percentage; 993f005ef32Sjsg caps->min_input_signal = custom_backlight_profiles[config_no].min_input_signal; 994f005ef32Sjsg caps->max_input_signal = custom_backlight_profiles[config_no].max_input_signal; 995f005ef32Sjsg caps->num_data_points = custom_backlight_profiles[config_no].num_data_points; 996f005ef32Sjsg memcpy(caps->data_points, custom_backlight_profiles[config_no].data_points, data_points_size); 997f005ef32Sjsg return true; 998f005ef32Sjsg } 999