This source file includes following definitions.
- dce_abm_set_pipe
- calculate_16_bit_backlight_from_pwm
- driver_set_backlight_level
- dmcu_set_backlight_level
- dce_abm_init
- dce_abm_get_current_backlight
- dce_abm_get_target_backlight
- dce_abm_set_level
- dce_abm_immediate_disable
- dce_abm_init_backlight
- dce_abm_set_backlight_level_pwm
- dce_abm_construct
- dce_abm_create
- dce_abm_destroy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <linux/slab.h>
27
28 #include "dce_abm.h"
29 #include "dm_services.h"
30 #include "reg_helper.h"
31 #include "fixed31_32.h"
32 #include "dc.h"
33
34 #include "atom.h"
35
36
37 #define TO_DCE_ABM(abm)\
38 container_of(abm, struct dce_abm, base)
39
40 #define REG(reg) \
41 (abm_dce->regs->reg)
42
43 #undef FN
44 #define FN(reg_name, field_name) \
45 abm_dce->abm_shift->field_name, abm_dce->abm_mask->field_name
46
47 #define DC_LOGGER \
48 abm->ctx->logger
49 #define CTX \
50 abm_dce->base.ctx
51
52 #define MCP_ABM_LEVEL_SET 0x65
53 #define MCP_ABM_PIPE_SET 0x66
54 #define MCP_BL_SET 0x67
55
56 #define MCP_DISABLE_ABM_IMMEDIATELY 255
57
58 static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id)
59 {
60 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
61 uint32_t rampingBoundary = 0xFFFF;
62
63 if (abm->dmcu_is_running == false)
64 return true;
65
66 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
67 1, 80000);
68
69
70 REG_WRITE(MASTER_COMM_DATA_REG1, rampingBoundary);
71
72
73 REG_UPDATE_2(MASTER_COMM_CMD_REG,
74 MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_PIPE_SET,
75 MASTER_COMM_CMD_REG_BYTE1, controller_id);
76
77
78 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
79
80 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
81 1, 80000);
82
83 return true;
84 }
85
86 static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *abm_dce)
87 {
88 uint64_t current_backlight;
89 uint32_t round_result;
90 uint32_t pwm_period_cntl, bl_period, bl_int_count;
91 uint32_t bl_pwm_cntl, bl_pwm, fractional_duty_cycle_en;
92 uint32_t bl_period_mask, bl_pwm_mask;
93
94 pwm_period_cntl = REG_READ(BL_PWM_PERIOD_CNTL);
95 REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period);
96 REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count);
97
98 bl_pwm_cntl = REG_READ(BL_PWM_CNTL);
99 REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, (uint32_t *)(&bl_pwm));
100 REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en);
101
102 if (bl_int_count == 0)
103 bl_int_count = 16;
104
105 bl_period_mask = (1 << bl_int_count) - 1;
106 bl_period &= bl_period_mask;
107
108 bl_pwm_mask = bl_period_mask << (16 - bl_int_count);
109
110 if (fractional_duty_cycle_en == 0)
111 bl_pwm &= bl_pwm_mask;
112 else
113 bl_pwm &= 0xFFFF;
114
115 current_backlight = bl_pwm << (1 + bl_int_count);
116
117 if (bl_period == 0)
118 bl_period = 0xFFFF;
119
120 current_backlight = div_u64(current_backlight, bl_period);
121 current_backlight = (current_backlight + 1) >> 1;
122
123 current_backlight = (uint64_t)(current_backlight) * bl_period;
124
125 round_result = (uint32_t)(current_backlight & 0xFFFFFFFF);
126
127 round_result = (round_result >> (bl_int_count-1)) & 1;
128
129 current_backlight >>= bl_int_count;
130 current_backlight += round_result;
131
132 return (uint32_t)(current_backlight);
133 }
134
135 static void driver_set_backlight_level(struct dce_abm *abm_dce,
136 uint32_t backlight_pwm_u16_16)
137 {
138 uint32_t backlight_16bit;
139 uint32_t masked_pwm_period;
140 uint8_t bit_count;
141 uint64_t active_duty_cycle;
142 uint32_t pwm_period_bitcnt;
143
144
145
146
147
148
149
150
151 REG_GET_2(BL_PWM_PERIOD_CNTL,
152 BL_PWM_PERIOD_BITCNT, &pwm_period_bitcnt,
153 BL_PWM_PERIOD, &masked_pwm_period);
154
155 if (pwm_period_bitcnt == 0)
156 bit_count = 16;
157 else
158 bit_count = pwm_period_bitcnt;
159
160
161 masked_pwm_period = masked_pwm_period & ((1 << bit_count) - 1);
162
163
164
165
166
167 active_duty_cycle = backlight_pwm_u16_16 * masked_pwm_period;
168
169
170
171
172
173 backlight_16bit = active_duty_cycle >> bit_count;
174 backlight_16bit &= 0xFFFF;
175 backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1;
176
177
178
179
180
181
182
183 REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK,
184 BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, 1,
185 BL_PWM_GRP1_REG_LOCK, 1);
186
187
188 REG_UPDATE(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, backlight_16bit);
189
190
191 REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
192 BL_PWM_GRP1_REG_LOCK, 0);
193
194
195 REG_WAIT(BL_PWM_GRP1_REG_LOCK,
196 BL_PWM_GRP1_REG_UPDATE_PENDING, 0,
197 1, 10000);
198 }
199
200 static void dmcu_set_backlight_level(
201 struct dce_abm *abm_dce,
202 uint32_t backlight_pwm_u16_16,
203 uint32_t frame_ramp,
204 uint32_t controller_id)
205 {
206 unsigned int backlight_8_bit = 0;
207 uint32_t s2;
208
209 if (backlight_pwm_u16_16 & 0x10000)
210
211 backlight_8_bit = 0xFF;
212 else
213
214 backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF;
215
216 dce_abm_set_pipe(&abm_dce->base, controller_id);
217
218
219 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT,
220 0, 1, 80000);
221
222
223 REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_pwm_u16_16);
224
225
226 if (controller_id == 0)
227 frame_ramp = 0;
228 REG_WRITE(MASTER_COMM_DATA_REG1, frame_ramp);
229
230
231 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_BL_SET);
232
233
234 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
235
236
237 s2 = REG_READ(BIOS_SCRATCH_2);
238
239 s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
240 backlight_8_bit &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >>
241 ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
242 s2 |= (backlight_8_bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
243
244 REG_WRITE(BIOS_SCRATCH_2, s2);
245
246
247 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT,
248 0, 1, 80000);
249 }
250
251 static void dce_abm_init(struct abm *abm)
252 {
253 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
254 unsigned int backlight = calculate_16_bit_backlight_from_pwm(abm_dce);
255
256 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
257 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
258 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x103);
259 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x101);
260 REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE, 0x101);
261
262 REG_SET_3(DC_ABM1_HG_MISC_CTRL, 0,
263 ABM1_HG_NUM_OF_BINS_SEL, 0,
264 ABM1_HG_VMAX_SEL, 1,
265 ABM1_HG_BIN_BITWIDTH_SIZE_SEL, 0);
266
267 REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL, 0,
268 ABM1_IPCSC_COEFF_SEL_R, 2,
269 ABM1_IPCSC_COEFF_SEL_G, 4,
270 ABM1_IPCSC_COEFF_SEL_B, 2);
271
272 REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL,
273 BL1_PWM_CURRENT_ABM_LEVEL, backlight);
274
275 REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL,
276 BL1_PWM_TARGET_ABM_LEVEL, backlight);
277
278 REG_UPDATE(BL1_PWM_USER_LEVEL,
279 BL1_PWM_USER_LEVEL, backlight);
280
281 REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
282 ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
283 ABM1_LS_MAX_PIXEL_VALUE_THRES, 1000);
284
285 REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS, 0,
286 ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, 1,
287 ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, 1,
288 ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1);
289 }
290
291 static unsigned int dce_abm_get_current_backlight(struct abm *abm)
292 {
293 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
294 unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL);
295
296
297
298
299 return backlight;
300 }
301
302 static unsigned int dce_abm_get_target_backlight(struct abm *abm)
303 {
304 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
305 unsigned int backlight = REG_READ(BL1_PWM_TARGET_ABM_LEVEL);
306
307
308
309
310 return backlight;
311 }
312
313 static bool dce_abm_set_level(struct abm *abm, uint32_t level)
314 {
315 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
316
317 if (abm->dmcu_is_running == false)
318 return true;
319
320 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
321 1, 80000);
322
323
324 REG_UPDATE_2(MASTER_COMM_CMD_REG,
325 MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_LEVEL_SET,
326 MASTER_COMM_CMD_REG_BYTE2, level);
327
328
329 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
330
331 return true;
332 }
333
334 static bool dce_abm_immediate_disable(struct abm *abm)
335 {
336 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
337
338 if (abm->dmcu_is_running == false)
339 return true;
340
341 dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY);
342
343 abm->stored_backlight_registers.BL_PWM_CNTL =
344 REG_READ(BL_PWM_CNTL);
345 abm->stored_backlight_registers.BL_PWM_CNTL2 =
346 REG_READ(BL_PWM_CNTL2);
347 abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
348 REG_READ(BL_PWM_PERIOD_CNTL);
349
350 REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
351 &abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
352 return true;
353 }
354
355 static bool dce_abm_init_backlight(struct abm *abm)
356 {
357 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
358 uint32_t value;
359
360
361
362
363
364 REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
365 if (value == 0 || value == 1) {
366 if (abm->stored_backlight_registers.BL_PWM_CNTL != 0) {
367 REG_WRITE(BL_PWM_CNTL,
368 abm->stored_backlight_registers.BL_PWM_CNTL);
369 REG_WRITE(BL_PWM_CNTL2,
370 abm->stored_backlight_registers.BL_PWM_CNTL2);
371 REG_WRITE(BL_PWM_PERIOD_CNTL,
372 abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
373 REG_UPDATE(LVTMA_PWRSEQ_REF_DIV,
374 BL_PWM_REF_DIV,
375 abm->stored_backlight_registers.
376 LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
377 } else {
378
379
380
381 REG_WRITE(BL_PWM_CNTL, 0xC000FA00);
382 REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
383 }
384 } else {
385 abm->stored_backlight_registers.BL_PWM_CNTL =
386 REG_READ(BL_PWM_CNTL);
387 abm->stored_backlight_registers.BL_PWM_CNTL2 =
388 REG_READ(BL_PWM_CNTL2);
389 abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
390 REG_READ(BL_PWM_PERIOD_CNTL);
391
392 REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
393 &abm->stored_backlight_registers.
394 LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
395 }
396
397
398
399
400 value = REG_READ(BIOS_SCRATCH_2);
401 value |= ATOM_S2_VRI_BRIGHT_ENABLE;
402 REG_WRITE(BIOS_SCRATCH_2, value);
403
404
405 REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
406
407
408 REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
409 BL_PWM_GRP1_REG_LOCK, 0);
410
411 return true;
412 }
413
414 static bool dce_abm_set_backlight_level_pwm(
415 struct abm *abm,
416 unsigned int backlight_pwm_u16_16,
417 unsigned int frame_ramp,
418 unsigned int controller_id,
419 bool use_smooth_brightness)
420 {
421 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
422
423 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
424 backlight_pwm_u16_16, backlight_pwm_u16_16);
425
426
427 if (use_smooth_brightness)
428 dmcu_set_backlight_level(abm_dce,
429 backlight_pwm_u16_16,
430 frame_ramp,
431 controller_id);
432 else
433 driver_set_backlight_level(abm_dce, backlight_pwm_u16_16);
434
435 return true;
436 }
437
438 static const struct abm_funcs dce_funcs = {
439 .abm_init = dce_abm_init,
440 .set_abm_level = dce_abm_set_level,
441 .init_backlight = dce_abm_init_backlight,
442 .set_pipe = dce_abm_set_pipe,
443 .set_backlight_level_pwm = dce_abm_set_backlight_level_pwm,
444 .get_current_backlight = dce_abm_get_current_backlight,
445 .get_target_backlight = dce_abm_get_target_backlight,
446 .set_abm_immediate_disable = dce_abm_immediate_disable
447 };
448
449 static void dce_abm_construct(
450 struct dce_abm *abm_dce,
451 struct dc_context *ctx,
452 const struct dce_abm_registers *regs,
453 const struct dce_abm_shift *abm_shift,
454 const struct dce_abm_mask *abm_mask)
455 {
456 struct abm *base = &abm_dce->base;
457
458 base->ctx = ctx;
459 base->funcs = &dce_funcs;
460 base->stored_backlight_registers.BL_PWM_CNTL = 0;
461 base->stored_backlight_registers.BL_PWM_CNTL2 = 0;
462 base->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 0;
463 base->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV = 0;
464 base->dmcu_is_running = false;
465
466 abm_dce->regs = regs;
467 abm_dce->abm_shift = abm_shift;
468 abm_dce->abm_mask = abm_mask;
469 }
470
471 struct abm *dce_abm_create(
472 struct dc_context *ctx,
473 const struct dce_abm_registers *regs,
474 const struct dce_abm_shift *abm_shift,
475 const struct dce_abm_mask *abm_mask)
476 {
477 struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL);
478
479 if (abm_dce == NULL) {
480 BREAK_TO_DEBUGGER();
481 return NULL;
482 }
483
484 dce_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask);
485
486 abm_dce->base.funcs = &dce_funcs;
487
488 return &abm_dce->base;
489 }
490
491 void dce_abm_destroy(struct abm **abm)
492 {
493 struct dce_abm *abm_dce = TO_DCE_ABM(*abm);
494
495 if (abm_dce->base.dmcu_is_running == true)
496 abm_dce->base.funcs->set_abm_immediate_disable(*abm);
497
498 kfree(abm_dce);
499 *abm = NULL;
500 }