Line data Source code
1 : /* Copyright 2018 Advanced Micro Devices, Inc.
2 : *
3 : * Permission is hereby granted, free of charge, to any person obtaining a
4 : * copy of this software and associated documentation files (the "Software"),
5 : * to deal in the Software without restriction, including without limitation
6 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 : * and/or sell copies of the Software, and to permit persons to whom the
8 : * Software is furnished to do so, subject to the following conditions:
9 : *
10 : * The above copyright notice and this permission notice shall be included in
11 : * all copies or substantial portions of the Software.
12 : *
13 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 : * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 : * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 : * OTHER DEALINGS IN THE SOFTWARE.
20 : *
21 : * Authors: AMD
22 : *
23 : */
24 :
25 : #include "power_helpers.h"
26 : #include "dc/inc/hw/dmcu.h"
27 : #include "dc/inc/hw/abm.h"
28 : #include "dc.h"
29 : #include "core_types.h"
30 : #include "dmub_cmd.h"
31 :
32 : #define DIV_ROUNDUP(a, b) (((a)+((b)/2))/(b))
33 : #define bswap16_based_on_endian(big_endian, value) \
34 : (big_endian) ? cpu_to_be16(value) : cpu_to_le16(value)
35 :
36 : /* Possible Min Reduction config from least aggressive to most aggressive
37 : * 0 1 2 3 4 5 6 7 8 9 10 11 12
38 : * 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 %
39 : */
40 : static const unsigned char min_reduction_table[13] = {
41 : 0xff, 0xfa, 0xf0, 0xf0, 0xd9, 0xcd, 0xc0, 0xb1, 0x99, 0x93, 0x80, 0x82, 0x66};
42 :
43 : /* Possible Max Reduction configs from least aggressive to most aggressive
44 : * 0 1 2 3 4 5 6 7 8 9 10 11 12
45 : * 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 %
46 : */
47 : static const unsigned char max_reduction_table[13] = {
48 : 0xf5, 0xe5, 0xd9, 0xcd, 0xb1, 0xa5, 0xa5, 0x80, 0x65, 0x4d, 0x4d, 0x4d, 0x32};
49 :
50 : /* Possible ABM 2.2 Min Reduction configs from least aggressive to most aggressive
51 : * 0 1 2 3 4 5 6 7 8 9 10 11 12
52 : * 100 100 100 100 100 100 100 100 100 92.2 83.1 75.3 75.3 %
53 : */
54 : static const unsigned char min_reduction_table_v_2_2[13] = {
55 : 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xd4, 0xc0, 0xc0};
56 :
57 : /* Possible ABM 2.2 Max Reduction configs from least aggressive to most aggressive
58 : * 0 1 2 3 4 5 6 7 8 9 10 11 12
59 : * 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 %
60 : */
61 : static const unsigned char max_reduction_table_v_2_2[13] = {
62 : 0xf5, 0xe5, 0xbf, 0xb1, 0xa5, 0x85, 0x7c, 0x65, 0x4d, 0x40, 0x32, 0x20, 0x20};
63 :
64 : /* Predefined ABM configuration sets. We may have different configuration sets
65 : * in order to satisfy different power/quality requirements.
66 : */
67 : static const unsigned char abm_config[abm_defines_max_config][abm_defines_max_level] = {
68 : /* ABM Level 1, ABM Level 2, ABM Level 3, ABM Level 4 */
69 : { 2, 5, 7, 8 }, /* Default - Medium aggressiveness */
70 : { 2, 5, 8, 11 }, /* Alt #1 - Increased aggressiveness */
71 : { 0, 2, 4, 8 }, /* Alt #2 - Minimal aggressiveness */
72 : { 3, 6, 10, 12 }, /* Alt #3 - Super aggressiveness */
73 : };
74 :
75 : struct abm_parameters {
76 : unsigned char min_reduction;
77 : unsigned char max_reduction;
78 : unsigned char bright_pos_gain;
79 : unsigned char dark_pos_gain;
80 : unsigned char brightness_gain;
81 : unsigned char contrast_factor;
82 : unsigned char deviation_gain;
83 : unsigned char min_knee;
84 : unsigned char max_knee;
85 : unsigned short blRampReduction;
86 : unsigned short blRampStart;
87 : };
88 :
89 : static const struct abm_parameters abm_settings_config0[abm_defines_max_level] = {
90 : // min_red max_red bright_pos dark_pos bright_gain contrast dev min_knee max_knee blRed blStart
91 : {0xff, 0xbf, 0x20, 0x00, 0xff, 0x99, 0xb3, 0x40, 0xe0, 0xf777, 0xcccc},
92 : {0xde, 0x85, 0x20, 0x00, 0xe0, 0x90, 0xa8, 0x40, 0xc8, 0xf777, 0xcccc},
93 : {0xb0, 0x50, 0x20, 0x00, 0xc0, 0x88, 0x78, 0x70, 0xa0, 0xeeee, 0x9999},
94 : {0x82, 0x40, 0x20, 0x00, 0x00, 0xb8, 0xb3, 0x70, 0x70, 0xe333, 0xb333},
95 : };
96 :
97 : static const struct abm_parameters abm_settings_config1[abm_defines_max_level] = {
98 : // min_red max_red bright_pos dark_pos bright_gain contrast dev min_knee max_knee blRed blStart
99 : {0xf0, 0xd9, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
100 : {0xcd, 0xa5, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
101 : {0x99, 0x65, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
102 : {0x82, 0x4d, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
103 : };
104 :
105 : static const struct abm_parameters * const abm_settings[] = {
106 : abm_settings_config0,
107 : abm_settings_config1,
108 : };
109 :
110 : #define NUM_AMBI_LEVEL 5
111 : #define NUM_AGGR_LEVEL 4
112 : #define NUM_POWER_FN_SEGS 8
113 : #define NUM_BL_CURVE_SEGS 16
114 : #define IRAM_SIZE 256
115 :
116 : #define IRAM_RESERVE_AREA_START_V2 0xF0 // reserve 0xF0~0xF6 are write by DMCU only
117 : #define IRAM_RESERVE_AREA_END_V2 0xF6 // reserve 0xF0~0xF6 are write by DMCU only
118 :
119 : #define IRAM_RESERVE_AREA_START_V2_2 0xF0 // reserve 0xF0~0xFF are write by DMCU only
120 : #define IRAM_RESERVE_AREA_END_V2_2 0xFF // reserve 0xF0~0xFF are write by DMCU only
121 :
122 : #pragma pack(push, 1)
123 : /* NOTE: iRAM is 256B in size */
124 : struct iram_table_v_2 {
125 : /* flags */
126 : uint16_t min_abm_backlight; /* 0x00 U16 */
127 :
128 : /* parameters for ABM2.0 algorithm */
129 : uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x02 U0.8 */
130 : uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x16 U0.8 */
131 : uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x2a U2.6 */
132 : uint8_t bright_neg_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x3e U2.6 */
133 : uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x52 U2.6 */
134 : uint8_t dark_neg_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x66 U2.6 */
135 : uint8_t iir_curve[NUM_AMBI_LEVEL]; /* 0x7a U0.8 */
136 : uint8_t deviation_gain; /* 0x7f U0.8 */
137 :
138 : /* parameters for crgb conversion */
139 : uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; /* 0x80 U3.13 */
140 : uint16_t crgb_offset[NUM_POWER_FN_SEGS]; /* 0x90 U1.15 */
141 : uint16_t crgb_slope[NUM_POWER_FN_SEGS]; /* 0xa0 U4.12 */
142 :
143 : /* parameters for custom curve */
144 : /* thresholds for brightness --> backlight */
145 : uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; /* 0xb0 U16.0 */
146 : /* offsets for brightness --> backlight */
147 : uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; /* 0xd0 U16.0 */
148 :
149 : /* For reading PSR State directly from IRAM */
150 : uint8_t psr_state; /* 0xf0 */
151 : uint8_t dmcu_mcp_interface_version; /* 0xf1 */
152 : uint8_t dmcu_abm_feature_version; /* 0xf2 */
153 : uint8_t dmcu_psr_feature_version; /* 0xf3 */
154 : uint16_t dmcu_version; /* 0xf4 */
155 : uint8_t dmcu_state; /* 0xf6 */
156 :
157 : uint16_t blRampReduction; /* 0xf7 */
158 : uint16_t blRampStart; /* 0xf9 */
159 : uint8_t dummy5; /* 0xfb */
160 : uint8_t dummy6; /* 0xfc */
161 : uint8_t dummy7; /* 0xfd */
162 : uint8_t dummy8; /* 0xfe */
163 : uint8_t dummy9; /* 0xff */
164 : };
165 :
166 : struct iram_table_v_2_2 {
167 : /* flags */
168 : uint16_t flags; /* 0x00 U16 */
169 :
170 : /* parameters for ABM2.2 algorithm */
171 : uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x02 U0.8 */
172 : uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x16 U0.8 */
173 : uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x2a U2.6 */
174 : uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x3e U2.6 */
175 : uint8_t hybrid_factor[NUM_AGGR_LEVEL]; /* 0x52 U0.8 */
176 : uint8_t contrast_factor[NUM_AGGR_LEVEL]; /* 0x56 U0.8 */
177 : uint8_t deviation_gain[NUM_AGGR_LEVEL]; /* 0x5a U0.8 */
178 : uint8_t iir_curve[NUM_AMBI_LEVEL]; /* 0x5e U0.8 */
179 : uint8_t min_knee[NUM_AGGR_LEVEL]; /* 0x63 U0.8 */
180 : uint8_t max_knee[NUM_AGGR_LEVEL]; /* 0x67 U0.8 */
181 : uint16_t min_abm_backlight; /* 0x6b U16 */
182 : uint8_t pad[19]; /* 0x6d U0.8 */
183 :
184 : /* parameters for crgb conversion */
185 : uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; /* 0x80 U3.13 */
186 : uint16_t crgb_offset[NUM_POWER_FN_SEGS]; /* 0x90 U1.15 */
187 : uint16_t crgb_slope[NUM_POWER_FN_SEGS]; /* 0xa0 U4.12 */
188 :
189 : /* parameters for custom curve */
190 : /* thresholds for brightness --> backlight */
191 : uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; /* 0xb0 U16.0 */
192 : /* offsets for brightness --> backlight */
193 : uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; /* 0xd0 U16.0 */
194 :
195 : /* For reading PSR State directly from IRAM */
196 : uint8_t psr_state; /* 0xf0 */
197 : uint8_t dmcu_mcp_interface_version; /* 0xf1 */
198 : uint8_t dmcu_abm_feature_version; /* 0xf2 */
199 : uint8_t dmcu_psr_feature_version; /* 0xf3 */
200 : uint16_t dmcu_version; /* 0xf4 */
201 : uint8_t dmcu_state; /* 0xf6 */
202 :
203 : uint8_t dummy1; /* 0xf7 */
204 : uint8_t dummy2; /* 0xf8 */
205 : uint8_t dummy3; /* 0xf9 */
206 : uint8_t dummy4; /* 0xfa */
207 : uint8_t dummy5; /* 0xfb */
208 : uint8_t dummy6; /* 0xfc */
209 : uint8_t dummy7; /* 0xfd */
210 : uint8_t dummy8; /* 0xfe */
211 : uint8_t dummy9; /* 0xff */
212 : };
213 : #pragma pack(pop)
214 :
215 0 : static void fill_backlight_transform_table(struct dmcu_iram_parameters params,
216 : struct iram_table_v_2 *table)
217 : {
218 : unsigned int i;
219 0 : unsigned int num_entries = NUM_BL_CURVE_SEGS;
220 : unsigned int lut_index;
221 :
222 0 : table->backlight_thresholds[0] = 0;
223 0 : table->backlight_offsets[0] = params.backlight_lut_array[0];
224 0 : table->backlight_thresholds[num_entries-1] = 0xFFFF;
225 0 : table->backlight_offsets[num_entries-1] =
226 0 : params.backlight_lut_array[params.backlight_lut_array_size - 1];
227 :
228 : /* Setup all brightness levels between 0% and 100% exclusive
229 : * Fills brightness-to-backlight transform table. Backlight custom curve
230 : * describes transform from brightness to backlight. It will be defined
231 : * as set of thresholds and set of offsets, together, implying
232 : * extrapolation of custom curve into 16 uniformly spanned linear
233 : * segments. Each threshold/offset represented by 16 bit entry in
234 : * format U4.10.
235 : */
236 0 : for (i = 1; i+1 < num_entries; i++) {
237 0 : lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1);
238 0 : ASSERT(lut_index < params.backlight_lut_array_size);
239 :
240 0 : table->backlight_thresholds[i] =
241 0 : cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries));
242 0 : table->backlight_offsets[i] =
243 0 : cpu_to_be16(params.backlight_lut_array[lut_index]);
244 : }
245 0 : }
246 :
247 0 : static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters params,
248 : struct iram_table_v_2_2 *table, bool big_endian)
249 : {
250 : unsigned int i;
251 0 : unsigned int num_entries = NUM_BL_CURVE_SEGS;
252 : unsigned int lut_index;
253 :
254 0 : table->backlight_thresholds[0] = 0;
255 0 : table->backlight_offsets[0] = params.backlight_lut_array[0];
256 0 : table->backlight_thresholds[num_entries-1] = 0xFFFF;
257 0 : table->backlight_offsets[num_entries-1] =
258 0 : params.backlight_lut_array[params.backlight_lut_array_size - 1];
259 :
260 : /* Setup all brightness levels between 0% and 100% exclusive
261 : * Fills brightness-to-backlight transform table. Backlight custom curve
262 : * describes transform from brightness to backlight. It will be defined
263 : * as set of thresholds and set of offsets, together, implying
264 : * extrapolation of custom curve into 16 uniformly spanned linear
265 : * segments. Each threshold/offset represented by 16 bit entry in
266 : * format U4.10.
267 : */
268 0 : for (i = 1; i+1 < num_entries; i++) {
269 0 : lut_index = DIV_ROUNDUP((i * params.backlight_lut_array_size), num_entries);
270 0 : ASSERT(lut_index < params.backlight_lut_array_size);
271 :
272 0 : table->backlight_thresholds[i] = (big_endian) ?
273 0 : cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)) :
274 0 : cpu_to_le16(DIV_ROUNDUP((i * 65536), num_entries));
275 0 : table->backlight_offsets[i] = (big_endian) ?
276 0 : cpu_to_be16(params.backlight_lut_array[lut_index]) :
277 0 : cpu_to_le16(params.backlight_lut_array[lut_index]);
278 : }
279 0 : }
280 :
281 0 : static void fill_iram_v_2(struct iram_table_v_2 *ram_table, struct dmcu_iram_parameters params)
282 : {
283 0 : unsigned int set = params.set;
284 :
285 0 : ram_table->min_abm_backlight =
286 0 : cpu_to_be16(params.min_abm_backlight);
287 0 : ram_table->deviation_gain = 0xb3;
288 :
289 0 : ram_table->blRampReduction =
290 0 : cpu_to_be16(params.backlight_ramping_reduction);
291 0 : ram_table->blRampStart =
292 0 : cpu_to_be16(params.backlight_ramping_start);
293 :
294 0 : ram_table->min_reduction[0][0] = min_reduction_table[abm_config[set][0]];
295 0 : ram_table->min_reduction[1][0] = min_reduction_table[abm_config[set][0]];
296 0 : ram_table->min_reduction[2][0] = min_reduction_table[abm_config[set][0]];
297 0 : ram_table->min_reduction[3][0] = min_reduction_table[abm_config[set][0]];
298 0 : ram_table->min_reduction[4][0] = min_reduction_table[abm_config[set][0]];
299 0 : ram_table->max_reduction[0][0] = max_reduction_table[abm_config[set][0]];
300 0 : ram_table->max_reduction[1][0] = max_reduction_table[abm_config[set][0]];
301 0 : ram_table->max_reduction[2][0] = max_reduction_table[abm_config[set][0]];
302 0 : ram_table->max_reduction[3][0] = max_reduction_table[abm_config[set][0]];
303 0 : ram_table->max_reduction[4][0] = max_reduction_table[abm_config[set][0]];
304 :
305 0 : ram_table->min_reduction[0][1] = min_reduction_table[abm_config[set][1]];
306 0 : ram_table->min_reduction[1][1] = min_reduction_table[abm_config[set][1]];
307 0 : ram_table->min_reduction[2][1] = min_reduction_table[abm_config[set][1]];
308 0 : ram_table->min_reduction[3][1] = min_reduction_table[abm_config[set][1]];
309 0 : ram_table->min_reduction[4][1] = min_reduction_table[abm_config[set][1]];
310 0 : ram_table->max_reduction[0][1] = max_reduction_table[abm_config[set][1]];
311 0 : ram_table->max_reduction[1][1] = max_reduction_table[abm_config[set][1]];
312 0 : ram_table->max_reduction[2][1] = max_reduction_table[abm_config[set][1]];
313 0 : ram_table->max_reduction[3][1] = max_reduction_table[abm_config[set][1]];
314 0 : ram_table->max_reduction[4][1] = max_reduction_table[abm_config[set][1]];
315 :
316 0 : ram_table->min_reduction[0][2] = min_reduction_table[abm_config[set][2]];
317 0 : ram_table->min_reduction[1][2] = min_reduction_table[abm_config[set][2]];
318 0 : ram_table->min_reduction[2][2] = min_reduction_table[abm_config[set][2]];
319 0 : ram_table->min_reduction[3][2] = min_reduction_table[abm_config[set][2]];
320 0 : ram_table->min_reduction[4][2] = min_reduction_table[abm_config[set][2]];
321 0 : ram_table->max_reduction[0][2] = max_reduction_table[abm_config[set][2]];
322 0 : ram_table->max_reduction[1][2] = max_reduction_table[abm_config[set][2]];
323 0 : ram_table->max_reduction[2][2] = max_reduction_table[abm_config[set][2]];
324 0 : ram_table->max_reduction[3][2] = max_reduction_table[abm_config[set][2]];
325 0 : ram_table->max_reduction[4][2] = max_reduction_table[abm_config[set][2]];
326 :
327 0 : ram_table->min_reduction[0][3] = min_reduction_table[abm_config[set][3]];
328 0 : ram_table->min_reduction[1][3] = min_reduction_table[abm_config[set][3]];
329 0 : ram_table->min_reduction[2][3] = min_reduction_table[abm_config[set][3]];
330 0 : ram_table->min_reduction[3][3] = min_reduction_table[abm_config[set][3]];
331 0 : ram_table->min_reduction[4][3] = min_reduction_table[abm_config[set][3]];
332 0 : ram_table->max_reduction[0][3] = max_reduction_table[abm_config[set][3]];
333 0 : ram_table->max_reduction[1][3] = max_reduction_table[abm_config[set][3]];
334 0 : ram_table->max_reduction[2][3] = max_reduction_table[abm_config[set][3]];
335 0 : ram_table->max_reduction[3][3] = max_reduction_table[abm_config[set][3]];
336 0 : ram_table->max_reduction[4][3] = max_reduction_table[abm_config[set][3]];
337 :
338 0 : ram_table->bright_pos_gain[0][0] = 0x20;
339 0 : ram_table->bright_pos_gain[0][1] = 0x20;
340 0 : ram_table->bright_pos_gain[0][2] = 0x20;
341 0 : ram_table->bright_pos_gain[0][3] = 0x20;
342 0 : ram_table->bright_pos_gain[1][0] = 0x20;
343 0 : ram_table->bright_pos_gain[1][1] = 0x20;
344 0 : ram_table->bright_pos_gain[1][2] = 0x20;
345 0 : ram_table->bright_pos_gain[1][3] = 0x20;
346 0 : ram_table->bright_pos_gain[2][0] = 0x20;
347 0 : ram_table->bright_pos_gain[2][1] = 0x20;
348 0 : ram_table->bright_pos_gain[2][2] = 0x20;
349 0 : ram_table->bright_pos_gain[2][3] = 0x20;
350 0 : ram_table->bright_pos_gain[3][0] = 0x20;
351 0 : ram_table->bright_pos_gain[3][1] = 0x20;
352 0 : ram_table->bright_pos_gain[3][2] = 0x20;
353 0 : ram_table->bright_pos_gain[3][3] = 0x20;
354 0 : ram_table->bright_pos_gain[4][0] = 0x20;
355 0 : ram_table->bright_pos_gain[4][1] = 0x20;
356 0 : ram_table->bright_pos_gain[4][2] = 0x20;
357 0 : ram_table->bright_pos_gain[4][3] = 0x20;
358 0 : ram_table->bright_neg_gain[0][0] = 0x00;
359 0 : ram_table->bright_neg_gain[0][1] = 0x00;
360 0 : ram_table->bright_neg_gain[0][2] = 0x00;
361 0 : ram_table->bright_neg_gain[0][3] = 0x00;
362 0 : ram_table->bright_neg_gain[1][0] = 0x00;
363 0 : ram_table->bright_neg_gain[1][1] = 0x00;
364 0 : ram_table->bright_neg_gain[1][2] = 0x00;
365 0 : ram_table->bright_neg_gain[1][3] = 0x00;
366 0 : ram_table->bright_neg_gain[2][0] = 0x00;
367 0 : ram_table->bright_neg_gain[2][1] = 0x00;
368 0 : ram_table->bright_neg_gain[2][2] = 0x00;
369 0 : ram_table->bright_neg_gain[2][3] = 0x00;
370 0 : ram_table->bright_neg_gain[3][0] = 0x00;
371 0 : ram_table->bright_neg_gain[3][1] = 0x00;
372 0 : ram_table->bright_neg_gain[3][2] = 0x00;
373 0 : ram_table->bright_neg_gain[3][3] = 0x00;
374 0 : ram_table->bright_neg_gain[4][0] = 0x00;
375 0 : ram_table->bright_neg_gain[4][1] = 0x00;
376 0 : ram_table->bright_neg_gain[4][2] = 0x00;
377 0 : ram_table->bright_neg_gain[4][3] = 0x00;
378 0 : ram_table->dark_pos_gain[0][0] = 0x00;
379 0 : ram_table->dark_pos_gain[0][1] = 0x00;
380 0 : ram_table->dark_pos_gain[0][2] = 0x00;
381 0 : ram_table->dark_pos_gain[0][3] = 0x00;
382 0 : ram_table->dark_pos_gain[1][0] = 0x00;
383 0 : ram_table->dark_pos_gain[1][1] = 0x00;
384 0 : ram_table->dark_pos_gain[1][2] = 0x00;
385 0 : ram_table->dark_pos_gain[1][3] = 0x00;
386 0 : ram_table->dark_pos_gain[2][0] = 0x00;
387 0 : ram_table->dark_pos_gain[2][1] = 0x00;
388 0 : ram_table->dark_pos_gain[2][2] = 0x00;
389 0 : ram_table->dark_pos_gain[2][3] = 0x00;
390 0 : ram_table->dark_pos_gain[3][0] = 0x00;
391 0 : ram_table->dark_pos_gain[3][1] = 0x00;
392 0 : ram_table->dark_pos_gain[3][2] = 0x00;
393 0 : ram_table->dark_pos_gain[3][3] = 0x00;
394 0 : ram_table->dark_pos_gain[4][0] = 0x00;
395 0 : ram_table->dark_pos_gain[4][1] = 0x00;
396 0 : ram_table->dark_pos_gain[4][2] = 0x00;
397 0 : ram_table->dark_pos_gain[4][3] = 0x00;
398 0 : ram_table->dark_neg_gain[0][0] = 0x00;
399 0 : ram_table->dark_neg_gain[0][1] = 0x00;
400 0 : ram_table->dark_neg_gain[0][2] = 0x00;
401 0 : ram_table->dark_neg_gain[0][3] = 0x00;
402 0 : ram_table->dark_neg_gain[1][0] = 0x00;
403 0 : ram_table->dark_neg_gain[1][1] = 0x00;
404 0 : ram_table->dark_neg_gain[1][2] = 0x00;
405 0 : ram_table->dark_neg_gain[1][3] = 0x00;
406 0 : ram_table->dark_neg_gain[2][0] = 0x00;
407 0 : ram_table->dark_neg_gain[2][1] = 0x00;
408 0 : ram_table->dark_neg_gain[2][2] = 0x00;
409 0 : ram_table->dark_neg_gain[2][3] = 0x00;
410 0 : ram_table->dark_neg_gain[3][0] = 0x00;
411 0 : ram_table->dark_neg_gain[3][1] = 0x00;
412 0 : ram_table->dark_neg_gain[3][2] = 0x00;
413 0 : ram_table->dark_neg_gain[3][3] = 0x00;
414 0 : ram_table->dark_neg_gain[4][0] = 0x00;
415 0 : ram_table->dark_neg_gain[4][1] = 0x00;
416 0 : ram_table->dark_neg_gain[4][2] = 0x00;
417 0 : ram_table->dark_neg_gain[4][3] = 0x00;
418 :
419 0 : ram_table->iir_curve[0] = 0x65;
420 0 : ram_table->iir_curve[1] = 0x65;
421 0 : ram_table->iir_curve[2] = 0x65;
422 0 : ram_table->iir_curve[3] = 0x65;
423 0 : ram_table->iir_curve[4] = 0x65;
424 :
425 : //Gamma 2.4
426 0 : ram_table->crgb_thresh[0] = cpu_to_be16(0x13b6);
427 0 : ram_table->crgb_thresh[1] = cpu_to_be16(0x1648);
428 0 : ram_table->crgb_thresh[2] = cpu_to_be16(0x18e3);
429 0 : ram_table->crgb_thresh[3] = cpu_to_be16(0x1b41);
430 0 : ram_table->crgb_thresh[4] = cpu_to_be16(0x1d46);
431 0 : ram_table->crgb_thresh[5] = cpu_to_be16(0x1f21);
432 0 : ram_table->crgb_thresh[6] = cpu_to_be16(0x2167);
433 0 : ram_table->crgb_thresh[7] = cpu_to_be16(0x2384);
434 0 : ram_table->crgb_offset[0] = cpu_to_be16(0x2999);
435 0 : ram_table->crgb_offset[1] = cpu_to_be16(0x3999);
436 0 : ram_table->crgb_offset[2] = cpu_to_be16(0x4666);
437 0 : ram_table->crgb_offset[3] = cpu_to_be16(0x5999);
438 0 : ram_table->crgb_offset[4] = cpu_to_be16(0x6333);
439 0 : ram_table->crgb_offset[5] = cpu_to_be16(0x7800);
440 0 : ram_table->crgb_offset[6] = cpu_to_be16(0x8c00);
441 0 : ram_table->crgb_offset[7] = cpu_to_be16(0xa000);
442 0 : ram_table->crgb_slope[0] = cpu_to_be16(0x3147);
443 0 : ram_table->crgb_slope[1] = cpu_to_be16(0x2978);
444 0 : ram_table->crgb_slope[2] = cpu_to_be16(0x23a2);
445 0 : ram_table->crgb_slope[3] = cpu_to_be16(0x1f55);
446 0 : ram_table->crgb_slope[4] = cpu_to_be16(0x1c63);
447 0 : ram_table->crgb_slope[5] = cpu_to_be16(0x1a0f);
448 0 : ram_table->crgb_slope[6] = cpu_to_be16(0x178d);
449 0 : ram_table->crgb_slope[7] = cpu_to_be16(0x15ab);
450 :
451 0 : fill_backlight_transform_table(
452 : params, ram_table);
453 0 : }
454 :
455 0 : static void fill_iram_v_2_2(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params)
456 : {
457 0 : unsigned int set = params.set;
458 :
459 0 : ram_table->flags = 0x0;
460 :
461 0 : ram_table->min_abm_backlight =
462 0 : cpu_to_be16(params.min_abm_backlight);
463 :
464 0 : ram_table->deviation_gain[0] = 0xb3;
465 0 : ram_table->deviation_gain[1] = 0xa8;
466 0 : ram_table->deviation_gain[2] = 0x98;
467 0 : ram_table->deviation_gain[3] = 0x68;
468 :
469 0 : ram_table->min_reduction[0][0] = min_reduction_table_v_2_2[abm_config[set][0]];
470 0 : ram_table->min_reduction[1][0] = min_reduction_table_v_2_2[abm_config[set][0]];
471 0 : ram_table->min_reduction[2][0] = min_reduction_table_v_2_2[abm_config[set][0]];
472 0 : ram_table->min_reduction[3][0] = min_reduction_table_v_2_2[abm_config[set][0]];
473 0 : ram_table->min_reduction[4][0] = min_reduction_table_v_2_2[abm_config[set][0]];
474 0 : ram_table->max_reduction[0][0] = max_reduction_table_v_2_2[abm_config[set][0]];
475 0 : ram_table->max_reduction[1][0] = max_reduction_table_v_2_2[abm_config[set][0]];
476 0 : ram_table->max_reduction[2][0] = max_reduction_table_v_2_2[abm_config[set][0]];
477 0 : ram_table->max_reduction[3][0] = max_reduction_table_v_2_2[abm_config[set][0]];
478 0 : ram_table->max_reduction[4][0] = max_reduction_table_v_2_2[abm_config[set][0]];
479 :
480 0 : ram_table->min_reduction[0][1] = min_reduction_table_v_2_2[abm_config[set][1]];
481 0 : ram_table->min_reduction[1][1] = min_reduction_table_v_2_2[abm_config[set][1]];
482 0 : ram_table->min_reduction[2][1] = min_reduction_table_v_2_2[abm_config[set][1]];
483 0 : ram_table->min_reduction[3][1] = min_reduction_table_v_2_2[abm_config[set][1]];
484 0 : ram_table->min_reduction[4][1] = min_reduction_table_v_2_2[abm_config[set][1]];
485 0 : ram_table->max_reduction[0][1] = max_reduction_table_v_2_2[abm_config[set][1]];
486 0 : ram_table->max_reduction[1][1] = max_reduction_table_v_2_2[abm_config[set][1]];
487 0 : ram_table->max_reduction[2][1] = max_reduction_table_v_2_2[abm_config[set][1]];
488 0 : ram_table->max_reduction[3][1] = max_reduction_table_v_2_2[abm_config[set][1]];
489 0 : ram_table->max_reduction[4][1] = max_reduction_table_v_2_2[abm_config[set][1]];
490 :
491 0 : ram_table->min_reduction[0][2] = min_reduction_table_v_2_2[abm_config[set][2]];
492 0 : ram_table->min_reduction[1][2] = min_reduction_table_v_2_2[abm_config[set][2]];
493 0 : ram_table->min_reduction[2][2] = min_reduction_table_v_2_2[abm_config[set][2]];
494 0 : ram_table->min_reduction[3][2] = min_reduction_table_v_2_2[abm_config[set][2]];
495 0 : ram_table->min_reduction[4][2] = min_reduction_table_v_2_2[abm_config[set][2]];
496 0 : ram_table->max_reduction[0][2] = max_reduction_table_v_2_2[abm_config[set][2]];
497 0 : ram_table->max_reduction[1][2] = max_reduction_table_v_2_2[abm_config[set][2]];
498 0 : ram_table->max_reduction[2][2] = max_reduction_table_v_2_2[abm_config[set][2]];
499 0 : ram_table->max_reduction[3][2] = max_reduction_table_v_2_2[abm_config[set][2]];
500 0 : ram_table->max_reduction[4][2] = max_reduction_table_v_2_2[abm_config[set][2]];
501 :
502 0 : ram_table->min_reduction[0][3] = min_reduction_table_v_2_2[abm_config[set][3]];
503 0 : ram_table->min_reduction[1][3] = min_reduction_table_v_2_2[abm_config[set][3]];
504 0 : ram_table->min_reduction[2][3] = min_reduction_table_v_2_2[abm_config[set][3]];
505 0 : ram_table->min_reduction[3][3] = min_reduction_table_v_2_2[abm_config[set][3]];
506 0 : ram_table->min_reduction[4][3] = min_reduction_table_v_2_2[abm_config[set][3]];
507 0 : ram_table->max_reduction[0][3] = max_reduction_table_v_2_2[abm_config[set][3]];
508 0 : ram_table->max_reduction[1][3] = max_reduction_table_v_2_2[abm_config[set][3]];
509 0 : ram_table->max_reduction[2][3] = max_reduction_table_v_2_2[abm_config[set][3]];
510 0 : ram_table->max_reduction[3][3] = max_reduction_table_v_2_2[abm_config[set][3]];
511 0 : ram_table->max_reduction[4][3] = max_reduction_table_v_2_2[abm_config[set][3]];
512 :
513 0 : ram_table->bright_pos_gain[0][0] = 0x20;
514 0 : ram_table->bright_pos_gain[0][1] = 0x20;
515 0 : ram_table->bright_pos_gain[0][2] = 0x20;
516 0 : ram_table->bright_pos_gain[0][3] = 0x20;
517 0 : ram_table->bright_pos_gain[1][0] = 0x20;
518 0 : ram_table->bright_pos_gain[1][1] = 0x20;
519 0 : ram_table->bright_pos_gain[1][2] = 0x20;
520 0 : ram_table->bright_pos_gain[1][3] = 0x20;
521 0 : ram_table->bright_pos_gain[2][0] = 0x20;
522 0 : ram_table->bright_pos_gain[2][1] = 0x20;
523 0 : ram_table->bright_pos_gain[2][2] = 0x20;
524 0 : ram_table->bright_pos_gain[2][3] = 0x20;
525 0 : ram_table->bright_pos_gain[3][0] = 0x20;
526 0 : ram_table->bright_pos_gain[3][1] = 0x20;
527 0 : ram_table->bright_pos_gain[3][2] = 0x20;
528 0 : ram_table->bright_pos_gain[3][3] = 0x20;
529 0 : ram_table->bright_pos_gain[4][0] = 0x20;
530 0 : ram_table->bright_pos_gain[4][1] = 0x20;
531 0 : ram_table->bright_pos_gain[4][2] = 0x20;
532 0 : ram_table->bright_pos_gain[4][3] = 0x20;
533 :
534 0 : ram_table->dark_pos_gain[0][0] = 0x00;
535 0 : ram_table->dark_pos_gain[0][1] = 0x00;
536 0 : ram_table->dark_pos_gain[0][2] = 0x00;
537 0 : ram_table->dark_pos_gain[0][3] = 0x00;
538 0 : ram_table->dark_pos_gain[1][0] = 0x00;
539 0 : ram_table->dark_pos_gain[1][1] = 0x00;
540 0 : ram_table->dark_pos_gain[1][2] = 0x00;
541 0 : ram_table->dark_pos_gain[1][3] = 0x00;
542 0 : ram_table->dark_pos_gain[2][0] = 0x00;
543 0 : ram_table->dark_pos_gain[2][1] = 0x00;
544 0 : ram_table->dark_pos_gain[2][2] = 0x00;
545 0 : ram_table->dark_pos_gain[2][3] = 0x00;
546 0 : ram_table->dark_pos_gain[3][0] = 0x00;
547 0 : ram_table->dark_pos_gain[3][1] = 0x00;
548 0 : ram_table->dark_pos_gain[3][2] = 0x00;
549 0 : ram_table->dark_pos_gain[3][3] = 0x00;
550 0 : ram_table->dark_pos_gain[4][0] = 0x00;
551 0 : ram_table->dark_pos_gain[4][1] = 0x00;
552 0 : ram_table->dark_pos_gain[4][2] = 0x00;
553 0 : ram_table->dark_pos_gain[4][3] = 0x00;
554 :
555 0 : ram_table->hybrid_factor[0] = 0xff;
556 0 : ram_table->hybrid_factor[1] = 0xff;
557 0 : ram_table->hybrid_factor[2] = 0xff;
558 0 : ram_table->hybrid_factor[3] = 0xc0;
559 :
560 0 : ram_table->contrast_factor[0] = 0x99;
561 0 : ram_table->contrast_factor[1] = 0x99;
562 0 : ram_table->contrast_factor[2] = 0x90;
563 0 : ram_table->contrast_factor[3] = 0x80;
564 :
565 0 : ram_table->iir_curve[0] = 0x65;
566 0 : ram_table->iir_curve[1] = 0x65;
567 0 : ram_table->iir_curve[2] = 0x65;
568 0 : ram_table->iir_curve[3] = 0x65;
569 0 : ram_table->iir_curve[4] = 0x65;
570 :
571 : //Gamma 2.2
572 0 : ram_table->crgb_thresh[0] = cpu_to_be16(0x127c);
573 0 : ram_table->crgb_thresh[1] = cpu_to_be16(0x151b);
574 0 : ram_table->crgb_thresh[2] = cpu_to_be16(0x17d5);
575 0 : ram_table->crgb_thresh[3] = cpu_to_be16(0x1a56);
576 0 : ram_table->crgb_thresh[4] = cpu_to_be16(0x1c83);
577 0 : ram_table->crgb_thresh[5] = cpu_to_be16(0x1e72);
578 0 : ram_table->crgb_thresh[6] = cpu_to_be16(0x20f0);
579 0 : ram_table->crgb_thresh[7] = cpu_to_be16(0x232b);
580 0 : ram_table->crgb_offset[0] = cpu_to_be16(0x2999);
581 0 : ram_table->crgb_offset[1] = cpu_to_be16(0x3999);
582 0 : ram_table->crgb_offset[2] = cpu_to_be16(0x4666);
583 0 : ram_table->crgb_offset[3] = cpu_to_be16(0x5999);
584 0 : ram_table->crgb_offset[4] = cpu_to_be16(0x6333);
585 0 : ram_table->crgb_offset[5] = cpu_to_be16(0x7800);
586 0 : ram_table->crgb_offset[6] = cpu_to_be16(0x8c00);
587 0 : ram_table->crgb_offset[7] = cpu_to_be16(0xa000);
588 0 : ram_table->crgb_slope[0] = cpu_to_be16(0x3609);
589 0 : ram_table->crgb_slope[1] = cpu_to_be16(0x2dfa);
590 0 : ram_table->crgb_slope[2] = cpu_to_be16(0x27ea);
591 0 : ram_table->crgb_slope[3] = cpu_to_be16(0x235d);
592 0 : ram_table->crgb_slope[4] = cpu_to_be16(0x2042);
593 0 : ram_table->crgb_slope[5] = cpu_to_be16(0x1dc3);
594 0 : ram_table->crgb_slope[6] = cpu_to_be16(0x1b1a);
595 0 : ram_table->crgb_slope[7] = cpu_to_be16(0x1910);
596 :
597 0 : fill_backlight_transform_table_v_2_2(
598 : params, ram_table, true);
599 0 : }
600 :
601 0 : static void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params, bool big_endian)
602 : {
603 : unsigned int i, j;
604 0 : unsigned int set = params.set;
605 :
606 0 : ram_table->flags = 0x0;
607 0 : ram_table->min_abm_backlight = (big_endian) ?
608 0 : cpu_to_be16(params.min_abm_backlight) :
609 : cpu_to_le16(params.min_abm_backlight);
610 :
611 0 : for (i = 0; i < NUM_AGGR_LEVEL; i++) {
612 0 : ram_table->hybrid_factor[i] = abm_settings[set][i].brightness_gain;
613 0 : ram_table->contrast_factor[i] = abm_settings[set][i].contrast_factor;
614 0 : ram_table->deviation_gain[i] = abm_settings[set][i].deviation_gain;
615 0 : ram_table->min_knee[i] = abm_settings[set][i].min_knee;
616 0 : ram_table->max_knee[i] = abm_settings[set][i].max_knee;
617 :
618 0 : for (j = 0; j < NUM_AMBI_LEVEL; j++) {
619 0 : ram_table->min_reduction[j][i] = abm_settings[set][i].min_reduction;
620 0 : ram_table->max_reduction[j][i] = abm_settings[set][i].max_reduction;
621 0 : ram_table->bright_pos_gain[j][i] = abm_settings[set][i].bright_pos_gain;
622 0 : ram_table->dark_pos_gain[j][i] = abm_settings[set][i].dark_pos_gain;
623 : }
624 : }
625 :
626 0 : ram_table->iir_curve[0] = 0x65;
627 0 : ram_table->iir_curve[1] = 0x65;
628 0 : ram_table->iir_curve[2] = 0x65;
629 0 : ram_table->iir_curve[3] = 0x65;
630 0 : ram_table->iir_curve[4] = 0x65;
631 :
632 : //Gamma 2.2
633 0 : ram_table->crgb_thresh[0] = bswap16_based_on_endian(big_endian, 0x127c);
634 0 : ram_table->crgb_thresh[1] = bswap16_based_on_endian(big_endian, 0x151b);
635 0 : ram_table->crgb_thresh[2] = bswap16_based_on_endian(big_endian, 0x17d5);
636 0 : ram_table->crgb_thresh[3] = bswap16_based_on_endian(big_endian, 0x1a56);
637 0 : ram_table->crgb_thresh[4] = bswap16_based_on_endian(big_endian, 0x1c83);
638 0 : ram_table->crgb_thresh[5] = bswap16_based_on_endian(big_endian, 0x1e72);
639 0 : ram_table->crgb_thresh[6] = bswap16_based_on_endian(big_endian, 0x20f0);
640 0 : ram_table->crgb_thresh[7] = bswap16_based_on_endian(big_endian, 0x232b);
641 0 : ram_table->crgb_offset[0] = bswap16_based_on_endian(big_endian, 0x2999);
642 0 : ram_table->crgb_offset[1] = bswap16_based_on_endian(big_endian, 0x3999);
643 0 : ram_table->crgb_offset[2] = bswap16_based_on_endian(big_endian, 0x4666);
644 0 : ram_table->crgb_offset[3] = bswap16_based_on_endian(big_endian, 0x5999);
645 0 : ram_table->crgb_offset[4] = bswap16_based_on_endian(big_endian, 0x6333);
646 0 : ram_table->crgb_offset[5] = bswap16_based_on_endian(big_endian, 0x7800);
647 0 : ram_table->crgb_offset[6] = bswap16_based_on_endian(big_endian, 0x8c00);
648 0 : ram_table->crgb_offset[7] = bswap16_based_on_endian(big_endian, 0xa000);
649 0 : ram_table->crgb_slope[0] = bswap16_based_on_endian(big_endian, 0x3609);
650 0 : ram_table->crgb_slope[1] = bswap16_based_on_endian(big_endian, 0x2dfa);
651 0 : ram_table->crgb_slope[2] = bswap16_based_on_endian(big_endian, 0x27ea);
652 0 : ram_table->crgb_slope[3] = bswap16_based_on_endian(big_endian, 0x235d);
653 0 : ram_table->crgb_slope[4] = bswap16_based_on_endian(big_endian, 0x2042);
654 0 : ram_table->crgb_slope[5] = bswap16_based_on_endian(big_endian, 0x1dc3);
655 0 : ram_table->crgb_slope[6] = bswap16_based_on_endian(big_endian, 0x1b1a);
656 0 : ram_table->crgb_slope[7] = bswap16_based_on_endian(big_endian, 0x1910);
657 :
658 0 : fill_backlight_transform_table_v_2_2(
659 : params, ram_table, big_endian);
660 0 : }
661 :
662 0 : bool dmub_init_abm_config(struct resource_pool *res_pool,
663 : struct dmcu_iram_parameters params,
664 : unsigned int inst)
665 : {
666 : struct iram_table_v_2_2 ram_table;
667 : struct abm_config_table config;
668 0 : unsigned int set = params.set;
669 0 : bool result = false;
670 0 : uint32_t i, j = 0;
671 :
672 : #if defined(CONFIG_DRM_AMD_DC_DCN)
673 0 : if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL)
674 : return false;
675 : #else
676 : if (res_pool->abm == NULL)
677 : return false;
678 : #endif
679 :
680 0 : memset(&ram_table, 0, sizeof(ram_table));
681 0 : memset(&config, 0, sizeof(config));
682 :
683 0 : fill_iram_v_2_3(&ram_table, params, false);
684 :
685 : // We must copy to structure that is aligned to 32-bit
686 0 : for (i = 0; i < NUM_POWER_FN_SEGS; i++) {
687 0 : config.crgb_thresh[i] = ram_table.crgb_thresh[i];
688 0 : config.crgb_offset[i] = ram_table.crgb_offset[i];
689 0 : config.crgb_slope[i] = ram_table.crgb_slope[i];
690 : }
691 :
692 0 : for (i = 0; i < NUM_BL_CURVE_SEGS; i++) {
693 0 : config.backlight_thresholds[i] = ram_table.backlight_thresholds[i];
694 0 : config.backlight_offsets[i] = ram_table.backlight_offsets[i];
695 : }
696 :
697 0 : for (i = 0; i < NUM_AMBI_LEVEL; i++)
698 0 : config.iir_curve[i] = ram_table.iir_curve[i];
699 :
700 0 : for (i = 0; i < NUM_AMBI_LEVEL; i++) {
701 0 : for (j = 0; j < NUM_AGGR_LEVEL; j++) {
702 0 : config.min_reduction[i][j] = ram_table.min_reduction[i][j];
703 0 : config.max_reduction[i][j] = ram_table.max_reduction[i][j];
704 0 : config.bright_pos_gain[i][j] = ram_table.bright_pos_gain[i][j];
705 0 : config.dark_pos_gain[i][j] = ram_table.dark_pos_gain[i][j];
706 : }
707 : }
708 :
709 0 : for (i = 0; i < NUM_AGGR_LEVEL; i++) {
710 0 : config.hybrid_factor[i] = ram_table.hybrid_factor[i];
711 0 : config.contrast_factor[i] = ram_table.contrast_factor[i];
712 0 : config.deviation_gain[i] = ram_table.deviation_gain[i];
713 0 : config.min_knee[i] = ram_table.min_knee[i];
714 0 : config.max_knee[i] = ram_table.max_knee[i];
715 : }
716 :
717 0 : if (params.backlight_ramping_override) {
718 0 : for (i = 0; i < NUM_AGGR_LEVEL; i++) {
719 0 : config.blRampReduction[i] = params.backlight_ramping_reduction;
720 0 : config.blRampStart[i] = params.backlight_ramping_start;
721 : }
722 : } else {
723 0 : for (i = 0; i < NUM_AGGR_LEVEL; i++) {
724 0 : config.blRampReduction[i] = abm_settings[set][i].blRampReduction;
725 0 : config.blRampStart[i] = abm_settings[set][i].blRampStart;
726 : }
727 : }
728 :
729 0 : config.min_abm_backlight = ram_table.min_abm_backlight;
730 :
731 : #if defined(CONFIG_DRM_AMD_DC_DCN)
732 0 : if (res_pool->multiple_abms[inst]) {
733 0 : result = res_pool->multiple_abms[inst]->funcs->init_abm_config(
734 : res_pool->multiple_abms[inst], (char *)(&config), sizeof(struct abm_config_table), inst);
735 : } else
736 : #endif
737 0 : result = res_pool->abm->funcs->init_abm_config(
738 : res_pool->abm, (char *)(&config), sizeof(struct abm_config_table), 0);
739 :
740 : return result;
741 : }
742 :
743 0 : bool dmcu_load_iram(struct dmcu *dmcu,
744 : struct dmcu_iram_parameters params)
745 : {
746 : unsigned char ram_table[IRAM_SIZE];
747 0 : bool result = false;
748 :
749 0 : if (dmcu == NULL)
750 : return false;
751 :
752 0 : if (dmcu && !dmcu->funcs->is_dmcu_initialized(dmcu))
753 : return true;
754 :
755 0 : memset(&ram_table, 0, sizeof(ram_table));
756 :
757 0 : if (dmcu->dmcu_version.abm_version == 0x24) {
758 0 : fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true);
759 0 : result = dmcu->funcs->load_iram(
760 : dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
761 0 : } else if (dmcu->dmcu_version.abm_version == 0x23) {
762 0 : fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true);
763 :
764 0 : result = dmcu->funcs->load_iram(
765 : dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
766 0 : } else if (dmcu->dmcu_version.abm_version == 0x22) {
767 0 : fill_iram_v_2_2((struct iram_table_v_2_2 *)ram_table, params);
768 :
769 0 : result = dmcu->funcs->load_iram(
770 : dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
771 : } else {
772 0 : fill_iram_v_2((struct iram_table_v_2 *)ram_table, params);
773 :
774 0 : result = dmcu->funcs->load_iram(
775 : dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2);
776 :
777 0 : if (result)
778 0 : result = dmcu->funcs->load_iram(
779 : dmcu, IRAM_RESERVE_AREA_END_V2 + 1,
780 : (char *)(&ram_table) + IRAM_RESERVE_AREA_END_V2 + 1,
781 : sizeof(ram_table) - IRAM_RESERVE_AREA_END_V2 - 1);
782 : }
783 :
784 : return result;
785 : }
786 :
787 : /*
788 : * is_psr_su_specific_panel() - check if sink is AMD vendor-specific PSR-SU
789 : * supported eDP device.
790 : *
791 : * @link: dc link pointer
792 : *
793 : * Return: true if AMDGPU vendor specific PSR-SU eDP panel
794 : */
795 0 : bool is_psr_su_specific_panel(struct dc_link *link)
796 : {
797 0 : bool isPSRSUSupported = false;
798 0 : struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
799 :
800 0 : if (dpcd_caps->edp_rev >= DP_EDP_14) {
801 0 : if (dpcd_caps->psr_info.psr_version >= DP_PSR2_WITH_Y_COORD_ET_SUPPORTED)
802 0 : isPSRSUSupported = true;
803 : /*
804 : * Some panels will report PSR capabilities over additional DPCD bits.
805 : * Such panels are approved despite reporting only PSR v3, as long as
806 : * the additional bits are reported.
807 : */
808 0 : if (dpcd_caps->sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) {
809 : /*
810 : * This is the temporary workaround to disable PSRSU when system turned on
811 : * DSC function on the sepcific sink.
812 : */
813 0 : if (dpcd_caps->psr_info.psr_version < DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)
814 : isPSRSUSupported = false;
815 0 : else if (dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
816 0 : ((dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x08) ||
817 : (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x07)))
818 : isPSRSUSupported = false;
819 0 : else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1)
820 0 : isPSRSUSupported = true;
821 : }
822 : }
823 :
824 0 : return isPSRSUSupported;
825 : }
826 :
827 : /**
828 : * mod_power_calc_psr_configs() - calculate/update generic psr configuration fields.
829 : * @psr_config: [output], psr configuration structure to be updated
830 : * @link: [input] dc link pointer
831 : * @stream: [input] dc stream state pointer
832 : *
833 : * calculate and update the psr configuration fields that are not DM specific, i.e. such
834 : * fields which are based on DPCD caps or timing information. To setup PSR in DMUB FW,
835 : * this helper is assumed to be called before the call of the DC helper dc_link_setup_psr().
836 : *
837 : * PSR config fields to be updated within the helper:
838 : * - psr_rfb_setup_time
839 : * - psr_sdp_transmit_line_num_deadline
840 : * - line_time_in_us
841 : * - su_y_granularity
842 : * - su_granularity_required
843 : * - psr_frame_capture_indication_req
844 : * - psr_exit_link_training_required
845 : *
846 : * PSR config fields that are DM specific and NOT updated within the helper:
847 : * - allow_smu_optimizations
848 : * - allow_multi_disp_optimizations
849 : */
850 0 : void mod_power_calc_psr_configs(struct psr_config *psr_config,
851 : struct dc_link *link,
852 : const struct dc_stream_state *stream)
853 : {
854 0 : unsigned int num_vblank_lines = 0;
855 0 : unsigned int vblank_time_in_us = 0;
856 0 : unsigned int sdp_tx_deadline_in_us = 0;
857 0 : unsigned int line_time_in_us = 0;
858 0 : struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
859 0 : const int psr_setup_time_step_in_us = 55; /* refer to eDP spec DPCD 0x071h */
860 :
861 : /* timing parameters */
862 0 : num_vblank_lines = stream->timing.v_total -
863 0 : stream->timing.v_addressable -
864 0 : stream->timing.v_border_top -
865 0 : stream->timing.v_border_bottom;
866 :
867 0 : vblank_time_in_us = (stream->timing.h_total * num_vblank_lines * 1000) / (stream->timing.pix_clk_100hz / 10);
868 :
869 0 : line_time_in_us = ((stream->timing.h_total * 1000) / (stream->timing.pix_clk_100hz / 10)) + 1;
870 :
871 : /**
872 : * psr configuration fields
873 : *
874 : * as per eDP 1.5 pg. 377 of 459, DPCD 0x071h bits [3:1], psr setup time bits interpreted as below
875 : * 000b <--> 330 us (default)
876 : * 001b <--> 275 us
877 : * 010b <--> 220 us
878 : * 011b <--> 165 us
879 : * 100b <--> 110 us
880 : * 101b <--> 055 us
881 : * 110b <--> 000 us
882 : */
883 0 : psr_config->psr_rfb_setup_time =
884 0 : (6 - dpcd_caps->psr_info.psr_dpcd_caps.bits.PSR_SETUP_TIME) * psr_setup_time_step_in_us;
885 :
886 0 : if (psr_config->psr_rfb_setup_time > vblank_time_in_us) {
887 0 : link->psr_settings.psr_frame_capture_indication_req = true;
888 0 : link->psr_settings.psr_sdp_transmit_line_num_deadline = num_vblank_lines;
889 : } else {
890 0 : sdp_tx_deadline_in_us = vblank_time_in_us - psr_config->psr_rfb_setup_time;
891 :
892 : /* Set the last possible line SDP may be transmitted without violating the RFB setup time */
893 0 : link->psr_settings.psr_frame_capture_indication_req = false;
894 0 : link->psr_settings.psr_sdp_transmit_line_num_deadline = sdp_tx_deadline_in_us / line_time_in_us;
895 : }
896 :
897 0 : psr_config->psr_sdp_transmit_line_num_deadline = link->psr_settings.psr_sdp_transmit_line_num_deadline;
898 0 : psr_config->line_time_in_us = line_time_in_us;
899 0 : psr_config->su_y_granularity = dpcd_caps->psr_info.psr2_su_y_granularity_cap;
900 0 : psr_config->su_granularity_required = dpcd_caps->psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED;
901 0 : psr_config->psr_frame_capture_indication_req = link->psr_settings.psr_frame_capture_indication_req;
902 0 : psr_config->psr_exit_link_training_required =
903 0 : !link->dpcd_caps.psr_info.psr_dpcd_caps.bits.LINK_TRAINING_ON_EXIT_NOT_REQUIRED;
904 0 : }
905 :
906 0 : bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_state *stream)
907 : {
908 0 : return context && context->stream_count == 1 && dc_is_embedded_signal(stream->signal);
909 : }
|