2 * Copyright 2012-16 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <linux/slab.h>
29 #include "dm_services.h"
30 #include "reg_helper.h"
31 #include "fixed31_32.h"
37 #define TO_DCE_ABM(abm)\
38 container_of(abm, struct dce_abm, base)
44 #define FN(reg_name, field_name) \
45 abm_dce->abm_shift->field_name, abm_dce->abm_mask->field_name
52 #define MCP_ABM_LEVEL_SET 0x65
53 #define MCP_ABM_PIPE_SET 0x66
54 #define MCP_BL_SET 0x67
56 #define MCP_DISABLE_ABM_IMMEDIATELY 255
58 static bool dce_abm_set_pipe(struct abm
*abm
, uint32_t controller_id
)
60 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
61 uint32_t rampingBoundary
= 0xFFFF;
63 if (abm
->dmcu_is_running
== false)
66 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 0,
69 /* set ramping boundary */
70 REG_WRITE(MASTER_COMM_DATA_REG1
, rampingBoundary
);
72 /* setDMCUParam_Pipe */
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
);
78 REG_UPDATE(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 1);
80 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 0,
86 static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm
*abm_dce
)
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
;
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
);
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
);
102 if (bl_int_count
== 0)
105 bl_period_mask
= (1 << bl_int_count
) - 1;
106 bl_period
&= bl_period_mask
;
108 bl_pwm_mask
= bl_period_mask
<< (16 - bl_int_count
);
110 if (fractional_duty_cycle_en
== 0)
111 bl_pwm
&= bl_pwm_mask
;
115 current_backlight
= bl_pwm
<< (1 + bl_int_count
);
120 current_backlight
= div_u64(current_backlight
, bl_period
);
121 current_backlight
= (current_backlight
+ 1) >> 1;
123 current_backlight
= (uint64_t)(current_backlight
) * bl_period
;
125 round_result
= (uint32_t)(current_backlight
& 0xFFFFFFFF);
127 round_result
= (round_result
>> (bl_int_count
-1)) & 1;
129 current_backlight
>>= bl_int_count
;
130 current_backlight
+= round_result
;
132 return (uint32_t)(current_backlight
);
135 static void driver_set_backlight_level(struct dce_abm
*abm_dce
,
136 uint32_t backlight_pwm_u16_16
)
138 uint32_t backlight_16bit
;
139 uint32_t masked_pwm_period
;
141 uint64_t active_duty_cycle
;
142 uint32_t pwm_period_bitcnt
;
145 * 1. Find 16 bit backlight active duty cycle, where 0 <= backlight
146 * active duty cycle <= backlight period
149 /* 1.1 Apply bitmask for backlight period value based on value of BITCNT
151 REG_GET_2(BL_PWM_PERIOD_CNTL
,
152 BL_PWM_PERIOD_BITCNT
, &pwm_period_bitcnt
,
153 BL_PWM_PERIOD
, &masked_pwm_period
);
155 if (pwm_period_bitcnt
== 0)
158 bit_count
= pwm_period_bitcnt
;
160 /* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */
161 masked_pwm_period
= masked_pwm_period
& ((1 << bit_count
) - 1);
163 /* 1.2 Calculate integer active duty cycle required upper 16 bits
164 * contain integer component, lower 16 bits contain fractional component
165 * of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24
167 active_duty_cycle
= backlight_pwm_u16_16
* masked_pwm_period
;
169 /* 1.3 Calculate 16 bit active duty cycle from integer and fractional
170 * components shift by bitCount then mask 16 bits and add rounding bit
171 * from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0
173 backlight_16bit
= active_duty_cycle
>> bit_count
;
174 backlight_16bit
&= 0xFFFF;
175 backlight_16bit
+= (active_duty_cycle
>> (bit_count
- 1)) & 0x1;
178 * 2. Program register with updated value
181 /* 2.1 Lock group 2 backlight registers */
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);
187 // 2.2 Write new active duty cycle
188 REG_UPDATE(BL_PWM_CNTL
, BL_ACTIVE_INT_FRAC_CNT
, backlight_16bit
);
190 /* 2.3 Unlock group 2 backlight registers */
191 REG_UPDATE(BL_PWM_GRP1_REG_LOCK
,
192 BL_PWM_GRP1_REG_LOCK
, 0);
194 /* 3 Wait for pending bit to be cleared */
195 REG_WAIT(BL_PWM_GRP1_REG_LOCK
,
196 BL_PWM_GRP1_REG_UPDATE_PENDING
, 0,
200 static void dmcu_set_backlight_level(
201 struct dce_abm
*abm_dce
,
202 uint32_t backlight_pwm_u16_16
,
204 uint32_t controller_id
)
206 unsigned int backlight_8_bit
= 0;
209 if (backlight_pwm_u16_16
& 0x10000)
210 // Check for max backlight condition
211 backlight_8_bit
= 0xFF;
213 // Take MSB of fractional part since backlight is not max
214 backlight_8_bit
= (backlight_pwm_u16_16
>> 8) & 0xFF;
216 dce_abm_set_pipe(&abm_dce
->base
, controller_id
);
218 /* waitDMCUReadyForCmd */
219 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
,
222 /* setDMCUParam_BL */
223 REG_UPDATE(BL1_PWM_USER_LEVEL
, BL1_PWM_USER_LEVEL
, backlight_pwm_u16_16
);
226 if (controller_id
== 0)
228 REG_WRITE(MASTER_COMM_DATA_REG1
, frame_ramp
);
230 /* setDMCUParam_Cmd */
231 REG_UPDATE(MASTER_COMM_CMD_REG
, MASTER_COMM_CMD_REG_BYTE0
, MCP_BL_SET
);
234 REG_UPDATE(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 1);
236 /* UpdateRequestedBacklightLevel */
237 s2
= REG_READ(BIOS_SCRATCH_2
);
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
);
244 REG_WRITE(BIOS_SCRATCH_2
, s2
);
246 /* waitDMCUReadyForCmd */
247 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
,
251 static void dce_abm_init(struct abm
*abm
)
253 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
254 unsigned int backlight
= calculate_16_bit_backlight_from_pwm(abm_dce
);
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);
262 REG_SET_3(DC_ABM1_HG_MISC_CTRL
, 0,
263 ABM1_HG_NUM_OF_BINS_SEL
, 0,
265 ABM1_HG_BIN_BITWIDTH_SIZE_SEL
, 0);
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);
272 REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL
,
273 BL1_PWM_CURRENT_ABM_LEVEL
, backlight
);
275 REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL
,
276 BL1_PWM_TARGET_ABM_LEVEL
, backlight
);
278 REG_UPDATE(BL1_PWM_USER_LEVEL
,
279 BL1_PWM_USER_LEVEL
, backlight
);
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);
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);
291 static unsigned int dce_abm_get_current_backlight(struct abm
*abm
)
293 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
294 unsigned int backlight
= REG_READ(BL1_PWM_CURRENT_ABM_LEVEL
);
296 /* return backlight in hardware format which is unsigned 17 bits, with
297 * 1 bit integer and 16 bit fractional
302 static unsigned int dce_abm_get_target_backlight(struct abm
*abm
)
304 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
305 unsigned int backlight
= REG_READ(BL1_PWM_TARGET_ABM_LEVEL
);
307 /* return backlight in hardware format which is unsigned 17 bits, with
308 * 1 bit integer and 16 bit fractional
313 static bool dce_abm_set_level(struct abm
*abm
, uint32_t level
)
315 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
317 if (abm
->dmcu_is_running
== false)
320 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 0,
323 /* setDMCUParam_ABMLevel */
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
);
329 REG_UPDATE(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 1);
334 static bool dce_abm_immediate_disable(struct abm
*abm
)
336 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
338 if (abm
->dmcu_is_running
== false)
341 dce_abm_set_pipe(abm
, MCP_DISABLE_ABM_IMMEDIATELY
);
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
);
350 REG_GET(LVTMA_PWRSEQ_REF_DIV
, BL_PWM_REF_DIV
,
351 &abm
->stored_backlight_registers
.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV
);
355 static bool dce_abm_init_backlight(struct abm
*abm
)
357 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
360 /* It must not be 0, so we have to restore them
361 * Bios bug w/a - period resets to zero,
362 * restoring to cache values which is always correct
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
,
375 abm
->stored_backlight_registers
.
376 LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV
);
378 /* TODO: Note: This should not really happen since VBIOS
379 * should have initialized PWM registers on boot.
381 REG_WRITE(BL_PWM_CNTL
, 0xC000FA00);
382 REG_WRITE(BL_PWM_PERIOD_CNTL
, 0x000C0FA0);
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
);
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
);
397 /* Have driver take backlight control
398 * TakeBacklightControl(true)
400 value
= REG_READ(BIOS_SCRATCH_2
);
401 value
|= ATOM_S2_VRI_BRIGHT_ENABLE
;
402 REG_WRITE(BIOS_SCRATCH_2
, value
);
404 /* Enable the backlight output */
405 REG_UPDATE(BL_PWM_CNTL
, BL_PWM_EN
, 1);
407 /* Disable fractional pwm if configured */
408 REG_UPDATE(BL_PWM_CNTL
, BL_PWM_FRACTIONAL_EN
,
409 abm
->ctx
->dc
->config
.disable_fractional_pwm
? 0 : 1);
411 /* Unlock group 2 backlight registers */
412 REG_UPDATE(BL_PWM_GRP1_REG_LOCK
,
413 BL_PWM_GRP1_REG_LOCK
, 0);
418 static bool dce_abm_set_backlight_level_pwm(
420 unsigned int backlight_pwm_u16_16
,
421 unsigned int frame_ramp
,
422 unsigned int controller_id
,
423 bool use_smooth_brightness
)
425 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
427 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
428 backlight_pwm_u16_16
, backlight_pwm_u16_16
);
430 /* If DMCU is in reset state, DMCU is uninitialized */
431 if (use_smooth_brightness
)
432 dmcu_set_backlight_level(abm_dce
,
433 backlight_pwm_u16_16
,
437 driver_set_backlight_level(abm_dce
, backlight_pwm_u16_16
);
442 static const struct abm_funcs dce_funcs
= {
443 .abm_init
= dce_abm_init
,
444 .set_abm_level
= dce_abm_set_level
,
445 .init_backlight
= dce_abm_init_backlight
,
446 .set_pipe
= dce_abm_set_pipe
,
447 .set_backlight_level_pwm
= dce_abm_set_backlight_level_pwm
,
448 .get_current_backlight
= dce_abm_get_current_backlight
,
449 .get_target_backlight
= dce_abm_get_target_backlight
,
450 .set_abm_immediate_disable
= dce_abm_immediate_disable
453 static void dce_abm_construct(
454 struct dce_abm
*abm_dce
,
455 struct dc_context
*ctx
,
456 const struct dce_abm_registers
*regs
,
457 const struct dce_abm_shift
*abm_shift
,
458 const struct dce_abm_mask
*abm_mask
)
460 struct abm
*base
= &abm_dce
->base
;
463 base
->funcs
= &dce_funcs
;
464 base
->stored_backlight_registers
.BL_PWM_CNTL
= 0;
465 base
->stored_backlight_registers
.BL_PWM_CNTL2
= 0;
466 base
->stored_backlight_registers
.BL_PWM_PERIOD_CNTL
= 0;
467 base
->stored_backlight_registers
.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV
= 0;
468 base
->dmcu_is_running
= false;
470 abm_dce
->regs
= regs
;
471 abm_dce
->abm_shift
= abm_shift
;
472 abm_dce
->abm_mask
= abm_mask
;
475 struct abm
*dce_abm_create(
476 struct dc_context
*ctx
,
477 const struct dce_abm_registers
*regs
,
478 const struct dce_abm_shift
*abm_shift
,
479 const struct dce_abm_mask
*abm_mask
)
481 struct dce_abm
*abm_dce
= kzalloc(sizeof(*abm_dce
), GFP_KERNEL
);
483 if (abm_dce
== NULL
) {
488 dce_abm_construct(abm_dce
, ctx
, regs
, abm_shift
, abm_mask
);
490 abm_dce
->base
.funcs
= &dce_funcs
;
492 return &abm_dce
->base
;
495 void dce_abm_destroy(struct abm
**abm
)
497 struct dce_abm
*abm_dce
= TO_DCE_ABM(*abm
);