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
, uint32_t panel_inst
)
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 void dmcu_set_backlight_level(
87 struct dce_abm
*abm_dce
,
88 uint32_t backlight_pwm_u16_16
,
90 uint32_t controller_id
,
93 unsigned int backlight_8_bit
= 0;
96 if (backlight_pwm_u16_16
& 0x10000)
97 // Check for max backlight condition
98 backlight_8_bit
= 0xFF;
100 // Take MSB of fractional part since backlight is not max
101 backlight_8_bit
= (backlight_pwm_u16_16
>> 8) & 0xFF;
103 dce_abm_set_pipe(&abm_dce
->base
, controller_id
, panel_id
);
105 /* waitDMCUReadyForCmd */
106 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
,
109 /* setDMCUParam_BL */
110 REG_UPDATE(BL1_PWM_USER_LEVEL
, BL1_PWM_USER_LEVEL
, backlight_pwm_u16_16
);
113 if (controller_id
== 0)
115 REG_WRITE(MASTER_COMM_DATA_REG1
, frame_ramp
);
117 /* setDMCUParam_Cmd */
118 REG_UPDATE(MASTER_COMM_CMD_REG
, MASTER_COMM_CMD_REG_BYTE0
, MCP_BL_SET
);
121 REG_UPDATE(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 1);
123 /* UpdateRequestedBacklightLevel */
124 s2
= REG_READ(BIOS_SCRATCH_2
);
126 s2
&= ~ATOM_S2_CURRENT_BL_LEVEL_MASK
;
127 backlight_8_bit
&= (ATOM_S2_CURRENT_BL_LEVEL_MASK
>>
128 ATOM_S2_CURRENT_BL_LEVEL_SHIFT
);
129 s2
|= (backlight_8_bit
<< ATOM_S2_CURRENT_BL_LEVEL_SHIFT
);
131 REG_WRITE(BIOS_SCRATCH_2
, s2
);
133 /* waitDMCUReadyForCmd */
134 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
,
138 static void dce_abm_init(struct abm
*abm
, uint32_t backlight
)
140 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
142 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE
, 0x103);
143 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE
, 0x101);
144 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE
, 0x103);
145 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE
, 0x101);
146 REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE
, 0x101);
148 REG_SET_3(DC_ABM1_HG_MISC_CTRL
, 0,
149 ABM1_HG_NUM_OF_BINS_SEL
, 0,
151 ABM1_HG_BIN_BITWIDTH_SIZE_SEL
, 0);
153 REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL
, 0,
154 ABM1_IPCSC_COEFF_SEL_R
, 2,
155 ABM1_IPCSC_COEFF_SEL_G
, 4,
156 ABM1_IPCSC_COEFF_SEL_B
, 2);
158 REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL
,
159 BL1_PWM_CURRENT_ABM_LEVEL
, backlight
);
161 REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL
,
162 BL1_PWM_TARGET_ABM_LEVEL
, backlight
);
164 REG_UPDATE(BL1_PWM_USER_LEVEL
,
165 BL1_PWM_USER_LEVEL
, backlight
);
167 REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES
,
168 ABM1_LS_MIN_PIXEL_VALUE_THRES
, 0,
169 ABM1_LS_MAX_PIXEL_VALUE_THRES
, 1000);
171 REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS
, 0,
172 ABM1_HG_REG_READ_MISSED_FRAME_CLEAR
, 1,
173 ABM1_LS_REG_READ_MISSED_FRAME_CLEAR
, 1,
174 ABM1_BL_REG_READ_MISSED_FRAME_CLEAR
, 1);
177 static unsigned int dce_abm_get_current_backlight(struct abm
*abm
)
179 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
180 unsigned int backlight
= REG_READ(BL1_PWM_CURRENT_ABM_LEVEL
);
182 /* return backlight in hardware format which is unsigned 17 bits, with
183 * 1 bit integer and 16 bit fractional
188 static unsigned int dce_abm_get_target_backlight(struct abm
*abm
)
190 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
191 unsigned int backlight
= REG_READ(BL1_PWM_TARGET_ABM_LEVEL
);
193 /* return backlight in hardware format which is unsigned 17 bits, with
194 * 1 bit integer and 16 bit fractional
199 static bool dce_abm_set_level(struct abm
*abm
, uint32_t level
)
201 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
203 if (abm
->dmcu_is_running
== false)
206 REG_WAIT(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 0,
209 /* setDMCUParam_ABMLevel */
210 REG_UPDATE_2(MASTER_COMM_CMD_REG
,
211 MASTER_COMM_CMD_REG_BYTE0
, MCP_ABM_LEVEL_SET
,
212 MASTER_COMM_CMD_REG_BYTE2
, level
);
215 REG_UPDATE(MASTER_COMM_CNTL_REG
, MASTER_COMM_INTERRUPT
, 1);
220 static bool dce_abm_immediate_disable(struct abm
*abm
, uint32_t panel_inst
)
222 if (abm
->dmcu_is_running
== false)
225 dce_abm_set_pipe(abm
, MCP_DISABLE_ABM_IMMEDIATELY
, panel_inst
);
230 static bool dce_abm_set_backlight_level_pwm(
232 unsigned int backlight_pwm_u16_16
,
233 unsigned int frame_ramp
,
234 unsigned int controller_id
,
235 unsigned int panel_inst
)
237 struct dce_abm
*abm_dce
= TO_DCE_ABM(abm
);
239 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
240 backlight_pwm_u16_16
, backlight_pwm_u16_16
);
242 dmcu_set_backlight_level(abm_dce
,
243 backlight_pwm_u16_16
,
251 static const struct abm_funcs dce_funcs
= {
252 .abm_init
= dce_abm_init
,
253 .set_abm_level
= dce_abm_set_level
,
254 .set_pipe
= dce_abm_set_pipe
,
255 .set_backlight_level_pwm
= dce_abm_set_backlight_level_pwm
,
256 .get_current_backlight
= dce_abm_get_current_backlight
,
257 .get_target_backlight
= dce_abm_get_target_backlight
,
258 .init_abm_config
= NULL
,
259 .set_abm_immediate_disable
= dce_abm_immediate_disable
,
262 static void dce_abm_construct(
263 struct dce_abm
*abm_dce
,
264 struct dc_context
*ctx
,
265 const struct dce_abm_registers
*regs
,
266 const struct dce_abm_shift
*abm_shift
,
267 const struct dce_abm_mask
*abm_mask
)
269 struct abm
*base
= &abm_dce
->base
;
272 base
->funcs
= &dce_funcs
;
273 base
->dmcu_is_running
= false;
275 abm_dce
->regs
= regs
;
276 abm_dce
->abm_shift
= abm_shift
;
277 abm_dce
->abm_mask
= abm_mask
;
280 struct abm
*dce_abm_create(
281 struct dc_context
*ctx
,
282 const struct dce_abm_registers
*regs
,
283 const struct dce_abm_shift
*abm_shift
,
284 const struct dce_abm_mask
*abm_mask
)
286 struct dce_abm
*abm_dce
= kzalloc(sizeof(*abm_dce
), GFP_KERNEL
);
288 if (abm_dce
== NULL
) {
293 dce_abm_construct(abm_dce
, ctx
, regs
, abm_shift
, abm_mask
);
295 abm_dce
->base
.funcs
= &dce_funcs
;
297 return &abm_dce
->base
;
300 void dce_abm_destroy(struct abm
**abm
)
302 struct dce_abm
*abm_dce
= TO_DCE_ABM(*abm
);