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);
83 static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm
*abm_dce
)
85 uint64_t current_backlight
;
86 uint32_t round_result
;
87 uint32_t pwm_period_cntl
, bl_period
, bl_int_count
;
88 uint32_t bl_pwm_cntl
, bl_pwm
, fractional_duty_cycle_en
;
89 uint32_t bl_period_mask
, bl_pwm_mask
;
91 pwm_period_cntl
= REG_READ(BL_PWM_PERIOD_CNTL
);
92 REG_GET(BL_PWM_PERIOD_CNTL
, BL_PWM_PERIOD
, &bl_period
);
93 REG_GET(BL_PWM_PERIOD_CNTL
, BL_PWM_PERIOD_BITCNT
, &bl_int_count
);
95 bl_pwm_cntl
= REG_READ(BL_PWM_CNTL
);
96 REG_GET(BL_PWM_CNTL
, BL_ACTIVE_INT_FRAC_CNT
, (uint32_t *)(&bl_pwm
));
97 REG_GET(BL_PWM_CNTL
, BL_PWM_FRACTIONAL_EN
, &fractional_duty_cycle_en
);
99 if (bl_int_count
== 0)
102 bl_period_mask
= (1 << bl_int_count
) - 1;
103 bl_period
&= bl_period_mask
;
105 bl_pwm_mask
= bl_period_mask
<< (16 - bl_int_count
);
107 if (fractional_duty_cycle_en
== 0)
108 bl_pwm
&= bl_pwm_mask
;
112 current_backlight
= bl_pwm
<< (1 + bl_int_count
);
117 current_backlight
= div_u64(current_backlight
, bl_period
);
118 current_backlight
= (current_backlight
+ 1) >> 1;
120 current_backlight
= (uint64_t)(current_backlight
) * bl_period
;
122 round_result
= (uint32_t)(current_backlight
& 0xFFFFFFFF);
124 round_result
= (round_result
>> (bl_int_count
-1)) & 1;
126 current_backlight
>>= bl_int_count
;
127 current_backlight
+= round_result
;
129 return (uint32_t)(current_backlight
);
132 static void driver_set_backlight_level(struct dce_abm
*abm_dce
,
133 uint32_t backlight_pwm_u16_16
)
135 uint32_t backlight_16bit
;
136 uint32_t masked_pwm_period
;
138 uint64_t active_duty_cycle
;
139 uint32_t pwm_period_bitcnt
;
142 * 1. Find 16 bit backlight active duty cycle, where 0 <= backlight
143 * active duty cycle <= backlight period
146 /* 1.1 Apply bitmask for backlight period value based on value of BITCNT
148 REG_GET_2(BL_PWM_PERIOD_CNTL
,
149 BL_PWM_PERIOD_BITCNT
, &pwm_period_bitcnt
,
150 BL_PWM_PERIOD
, &masked_pwm_period
);
152 if (pwm_period_bitcnt
== 0)
155 bit_count
= pwm_period_bitcnt
;
157 /* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */
158 masked_pwm_period
= masked_pwm_period
& ((1 << bit_count
) - 1);
160 /* 1.2 Calculate integer active duty cycle required upper 16 bits
161 * contain integer component, lower 16 bits contain fractional component
162 * of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24
164 active_duty_cycle
= backlight_pwm_u16_16
* masked_pwm_period
;
166 /* 1.3 Calculate 16 bit active duty cycle from integer and fractional
167 * components shift by bitCount then mask 16 bits and add rounding bit
168 * from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0
170 backlight_16bit
= active_duty_cycle
>> bit_count
;
171 backlight_16bit
&= 0xFFFF;
172 backlight_16bit
+= (active_duty_cycle
>> (bit_count
- 1)) & 0x1;
175 * 2. Program register with updated value
178 /* 2.1 Lock group 2 backlight registers */
180 REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK
,
181 BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN
, 1,
182 BL_PWM_GRP1_REG_LOCK
, 1);
184 // 2.2 Write new active duty cycle
185 REG_UPDATE(BL_PWM_CNTL
, BL_ACTIVE_INT_FRAC_CNT
, backlight_16bit
);
187 /* 2.3 Unlock group 2 backlight registers */
188 REG_UPDATE(BL_PWM_GRP1_REG_LOCK
,
189 BL_PWM_GRP1_REG_LOCK
, 0);
191 /* 3 Wait for pending bit to be cleared */
192 REG_WAIT(BL_PWM_GRP1_REG_LOCK
,
193 BL_PWM_GRP1_REG_UPDATE_PENDING
, 0,
197 static void dmcu_set_backlight_level(
198 struct dce_abm
*abm_dce
,
199 uint32_t backlight_pwm_u16_16
,
201 uint32_t controller_id
)
203 unsigned int backlight_8_bit
= 0;
206 if (backlight_pwm_u16_16
& 0x10000)
207 // Check for max backlight condition
208 backlight_8_bit
= 0xFF;
210 // Take MSB of fractional part since backlight is not max
211 backlight_8_bit
= (backlight_pwm_u16_16
>> 8) & 0xFF;
213 dce_abm_set_pipe(&abm_dce
->base
, controller_id
);
215 /* waitDMCUReadyForCmd */
216 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
,
219 /* setDMCUParam_BL */
220 REG_UPDATE(BL1_PWM_USER_LEVEL
, BL1_PWM_USER_LEVEL
, backlight_pwm_u16_16
);
223 if (controller_id
== 0)
225 REG_WRITE(MASTER_COMM_DATA_REG1
, frame_ramp
);
227 /* setDMCUParam_Cmd */
228 REG_UPDATE(MASTER_COMM_CMD_REG
, MASTER_COMM_CMD_REG_BYTE0
, MCP_BL_SET
);
231 REG_UPDATE(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 1);
233 /* UpdateRequestedBacklightLevel */
234 s2
= REG_READ(BIOS_SCRATCH_2
);
236 s2
&= ~ATOM_S2_CURRENT_BL_LEVEL_MASK
;
237 backlight_8_bit
&= (ATOM_S2_CURRENT_BL_LEVEL_MASK
>>
238 ATOM_S2_CURRENT_BL_LEVEL_SHIFT
);
239 s2
|= (backlight_8_bit
<< ATOM_S2_CURRENT_BL_LEVEL_SHIFT
);
241 REG_WRITE(BIOS_SCRATCH_2
, s2
);
244 static void dce_abm_init(struct abm
*abm
)
246 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
247 unsigned int backlight
= calculate_16_bit_backlight_from_pwm(abm_dce
);
249 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE
, 0x103);
250 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE
, 0x101);
251 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE
, 0x103);
252 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE
, 0x101);
253 REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE
, 0x101);
255 REG_SET_3(DC_ABM1_HG_MISC_CTRL
, 0,
256 ABM1_HG_NUM_OF_BINS_SEL
, 0,
258 ABM1_HG_BIN_BITWIDTH_SIZE_SEL
, 0);
260 REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL
, 0,
261 ABM1_IPCSC_COEFF_SEL_R
, 2,
262 ABM1_IPCSC_COEFF_SEL_G
, 4,
263 ABM1_IPCSC_COEFF_SEL_B
, 2);
265 REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL
,
266 BL1_PWM_CURRENT_ABM_LEVEL
, backlight
);
268 REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL
,
269 BL1_PWM_TARGET_ABM_LEVEL
, backlight
);
271 REG_UPDATE(BL1_PWM_USER_LEVEL
,
272 BL1_PWM_USER_LEVEL
, backlight
);
274 REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES
,
275 ABM1_LS_MIN_PIXEL_VALUE_THRES
, 0,
276 ABM1_LS_MAX_PIXEL_VALUE_THRES
, 1000);
278 REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS
, 0,
279 ABM1_HG_REG_READ_MISSED_FRAME_CLEAR
, 1,
280 ABM1_LS_REG_READ_MISSED_FRAME_CLEAR
, 1,
281 ABM1_BL_REG_READ_MISSED_FRAME_CLEAR
, 1);
284 static unsigned int dce_abm_get_current_backlight(struct abm
*abm
)
286 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
287 unsigned int backlight
= REG_READ(BL1_PWM_CURRENT_ABM_LEVEL
);
289 /* return backlight in hardware format which is unsigned 17 bits, with
290 * 1 bit integer and 16 bit fractional
295 static unsigned int dce_abm_get_target_backlight(struct abm
*abm
)
297 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
298 unsigned int backlight
= REG_READ(BL1_PWM_TARGET_ABM_LEVEL
);
300 /* return backlight in hardware format which is unsigned 17 bits, with
301 * 1 bit integer and 16 bit fractional
306 static bool dce_abm_set_level(struct abm
*abm
, uint32_t level
)
308 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
310 if (abm
->dmcu_is_running
== false)
313 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 0,
316 /* setDMCUParam_ABMLevel */
317 REG_UPDATE_2(MASTER_COMM_CMD_REG
,
318 MASTER_COMM_CMD_REG_BYTE0
, MCP_ABM_LEVEL_SET
,
319 MASTER_COMM_CMD_REG_BYTE2
, level
);
322 REG_UPDATE(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 1);
327 static bool dce_abm_immediate_disable(struct abm
*abm
)
329 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
331 if (abm
->dmcu_is_running
== false)
334 dce_abm_set_pipe(abm
, MCP_DISABLE_ABM_IMMEDIATELY
);
336 abm
->stored_backlight_registers
.BL_PWM_CNTL
=
337 REG_READ(BL_PWM_CNTL
);
338 abm
->stored_backlight_registers
.BL_PWM_CNTL2
=
339 REG_READ(BL_PWM_CNTL2
);
340 abm
->stored_backlight_registers
.BL_PWM_PERIOD_CNTL
=
341 REG_READ(BL_PWM_PERIOD_CNTL
);
343 REG_GET(LVTMA_PWRSEQ_REF_DIV
, BL_PWM_REF_DIV
,
344 &abm
->stored_backlight_registers
.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV
);
348 static bool dce_abm_init_backlight(struct abm
*abm
)
350 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
353 /* It must not be 0, so we have to restore them
354 * Bios bug w/a - period resets to zero,
355 * restoring to cache values which is always correct
357 REG_GET(BL_PWM_CNTL
, BL_ACTIVE_INT_FRAC_CNT
, &value
);
358 if (value
== 0 || value
== 1) {
359 if (abm
->stored_backlight_registers
.BL_PWM_CNTL
!= 0) {
360 REG_WRITE(BL_PWM_CNTL
,
361 abm
->stored_backlight_registers
.BL_PWM_CNTL
);
362 REG_WRITE(BL_PWM_CNTL2
,
363 abm
->stored_backlight_registers
.BL_PWM_CNTL2
);
364 REG_WRITE(BL_PWM_PERIOD_CNTL
,
365 abm
->stored_backlight_registers
.BL_PWM_PERIOD_CNTL
);
366 REG_UPDATE(LVTMA_PWRSEQ_REF_DIV
,
368 abm
->stored_backlight_registers
.
369 LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV
);
371 /* TODO: Note: This should not really happen since VBIOS
372 * should have initialized PWM registers on boot.
374 REG_WRITE(BL_PWM_CNTL
, 0xC000FA00);
375 REG_WRITE(BL_PWM_PERIOD_CNTL
, 0x000C0FA0);
378 abm
->stored_backlight_registers
.BL_PWM_CNTL
=
379 REG_READ(BL_PWM_CNTL
);
380 abm
->stored_backlight_registers
.BL_PWM_CNTL2
=
381 REG_READ(BL_PWM_CNTL2
);
382 abm
->stored_backlight_registers
.BL_PWM_PERIOD_CNTL
=
383 REG_READ(BL_PWM_PERIOD_CNTL
);
385 REG_GET(LVTMA_PWRSEQ_REF_DIV
, BL_PWM_REF_DIV
,
386 &abm
->stored_backlight_registers
.
387 LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV
);
390 /* Have driver take backlight control
391 * TakeBacklightControl(true)
393 value
= REG_READ(BIOS_SCRATCH_2
);
394 value
|= ATOM_S2_VRI_BRIGHT_ENABLE
;
395 REG_WRITE(BIOS_SCRATCH_2
, value
);
397 /* Enable the backlight output */
398 REG_UPDATE(BL_PWM_CNTL
, BL_PWM_EN
, 1);
400 /* Unlock group 2 backlight registers */
401 REG_UPDATE(BL_PWM_GRP1_REG_LOCK
,
402 BL_PWM_GRP1_REG_LOCK
, 0);
407 static bool dce_abm_set_backlight_level_pwm(
409 unsigned int backlight_pwm_u16_16
,
410 unsigned int frame_ramp
,
411 unsigned int controller_id
,
412 bool use_smooth_brightness
)
414 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
416 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
417 backlight_pwm_u16_16
, backlight_pwm_u16_16
);
419 /* If DMCU is in reset state, DMCU is uninitialized */
420 if (use_smooth_brightness
)
421 dmcu_set_backlight_level(abm_dce
,
422 backlight_pwm_u16_16
,
426 driver_set_backlight_level(abm_dce
, backlight_pwm_u16_16
);
431 static const struct abm_funcs dce_funcs
= {
432 .abm_init
= dce_abm_init
,
433 .set_abm_level
= dce_abm_set_level
,
434 .init_backlight
= dce_abm_init_backlight
,
435 .set_pipe
= dce_abm_set_pipe
,
436 .set_backlight_level_pwm
= dce_abm_set_backlight_level_pwm
,
437 .get_current_backlight
= dce_abm_get_current_backlight
,
438 .get_target_backlight
= dce_abm_get_target_backlight
,
439 .set_abm_immediate_disable
= dce_abm_immediate_disable
442 static void dce_abm_construct(
443 struct dce_abm
*abm_dce
,
444 struct dc_context
*ctx
,
445 const struct dce_abm_registers
*regs
,
446 const struct dce_abm_shift
*abm_shift
,
447 const struct dce_abm_mask
*abm_mask
)
449 struct abm
*base
= &abm_dce
->base
;
452 base
->funcs
= &dce_funcs
;
453 base
->stored_backlight_registers
.BL_PWM_CNTL
= 0;
454 base
->stored_backlight_registers
.BL_PWM_CNTL2
= 0;
455 base
->stored_backlight_registers
.BL_PWM_PERIOD_CNTL
= 0;
456 base
->stored_backlight_registers
.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV
= 0;
457 base
->dmcu_is_running
= false;
459 abm_dce
->regs
= regs
;
460 abm_dce
->abm_shift
= abm_shift
;
461 abm_dce
->abm_mask
= abm_mask
;
464 struct abm
*dce_abm_create(
465 struct dc_context
*ctx
,
466 const struct dce_abm_registers
*regs
,
467 const struct dce_abm_shift
*abm_shift
,
468 const struct dce_abm_mask
*abm_mask
)
470 struct dce_abm
*abm_dce
= kzalloc(sizeof(*abm_dce
), GFP_KERNEL
);
472 if (abm_dce
== NULL
) {
477 dce_abm_construct(abm_dce
, ctx
, regs
, abm_shift
, abm_mask
);
479 abm_dce
->base
.funcs
= &dce_funcs
;
481 return &abm_dce
->base
;
484 void dce_abm_destroy(struct abm
**abm
)
486 struct dce_abm
*abm_dce
= TO_DCE_ABM(*abm
);
488 if (abm_dce
->base
.dmcu_is_running
== true)
489 abm_dce
->base
.funcs
->set_abm_immediate_disable(*abm
);