0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/slab.h>
0027
0028 #include "dce_abm.h"
0029 #include "dm_services.h"
0030 #include "reg_helper.h"
0031 #include "fixed31_32.h"
0032 #include "dc.h"
0033
0034 #include "atom.h"
0035
0036
0037 #define TO_DCE_ABM(abm)\
0038 container_of(abm, struct dce_abm, base)
0039
0040 #define REG(reg) \
0041 (abm_dce->regs->reg)
0042
0043 #undef FN
0044 #define FN(reg_name, field_name) \
0045 abm_dce->abm_shift->field_name, abm_dce->abm_mask->field_name
0046
0047 #define DC_LOGGER \
0048 abm->ctx->logger
0049 #define CTX \
0050 abm_dce->base.ctx
0051
0052 #define MCP_ABM_LEVEL_SET 0x65
0053 #define MCP_ABM_PIPE_SET 0x66
0054 #define MCP_BL_SET 0x67
0055
0056 #define MCP_DISABLE_ABM_IMMEDIATELY 255
0057
0058 static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id, uint32_t panel_inst)
0059 {
0060 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
0061 uint32_t rampingBoundary = 0xFFFF;
0062
0063 if (abm->dmcu_is_running == false)
0064 return true;
0065
0066 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
0067 1, 80000);
0068
0069
0070 REG_WRITE(MASTER_COMM_DATA_REG1, rampingBoundary);
0071
0072
0073 REG_UPDATE_2(MASTER_COMM_CMD_REG,
0074 MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_PIPE_SET,
0075 MASTER_COMM_CMD_REG_BYTE1, controller_id);
0076
0077
0078 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
0079
0080 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
0081 1, 80000);
0082
0083 return true;
0084 }
0085
0086 static void dmcu_set_backlight_level(
0087 struct dce_abm *abm_dce,
0088 uint32_t backlight_pwm_u16_16,
0089 uint32_t frame_ramp,
0090 uint32_t controller_id,
0091 uint32_t panel_id)
0092 {
0093 unsigned int backlight_8_bit = 0;
0094 uint32_t s2;
0095
0096 if (backlight_pwm_u16_16 & 0x10000)
0097
0098 backlight_8_bit = 0xFF;
0099 else
0100
0101 backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF;
0102
0103 dce_abm_set_pipe(&abm_dce->base, controller_id, panel_id);
0104
0105
0106 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT,
0107 0, 1, 80000);
0108
0109
0110 REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_pwm_u16_16);
0111
0112
0113 if (controller_id == 0)
0114 frame_ramp = 0;
0115 REG_WRITE(MASTER_COMM_DATA_REG1, frame_ramp);
0116
0117
0118 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_BL_SET);
0119
0120
0121 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
0122
0123
0124 s2 = REG_READ(BIOS_SCRATCH_2);
0125
0126 s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
0127 backlight_8_bit &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >>
0128 ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
0129 s2 |= (backlight_8_bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
0130
0131 REG_WRITE(BIOS_SCRATCH_2, s2);
0132
0133
0134 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT,
0135 0, 1, 80000);
0136 }
0137
0138 static void dce_abm_init(struct abm *abm, uint32_t backlight)
0139 {
0140 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
0141
0142 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
0143 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
0144 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x103);
0145 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x101);
0146 REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE, 0x101);
0147
0148 REG_SET_3(DC_ABM1_HG_MISC_CTRL, 0,
0149 ABM1_HG_NUM_OF_BINS_SEL, 0,
0150 ABM1_HG_VMAX_SEL, 1,
0151 ABM1_HG_BIN_BITWIDTH_SIZE_SEL, 0);
0152
0153 REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL, 0,
0154 ABM1_IPCSC_COEFF_SEL_R, 2,
0155 ABM1_IPCSC_COEFF_SEL_G, 4,
0156 ABM1_IPCSC_COEFF_SEL_B, 2);
0157
0158 REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL,
0159 BL1_PWM_CURRENT_ABM_LEVEL, backlight);
0160
0161 REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL,
0162 BL1_PWM_TARGET_ABM_LEVEL, backlight);
0163
0164 REG_UPDATE(BL1_PWM_USER_LEVEL,
0165 BL1_PWM_USER_LEVEL, backlight);
0166
0167 REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
0168 ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
0169 ABM1_LS_MAX_PIXEL_VALUE_THRES, 1000);
0170
0171 REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS, 0,
0172 ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, 1,
0173 ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, 1,
0174 ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1);
0175 }
0176
0177 static unsigned int dce_abm_get_current_backlight(struct abm *abm)
0178 {
0179 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
0180 unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL);
0181
0182
0183
0184
0185 return backlight;
0186 }
0187
0188 static unsigned int dce_abm_get_target_backlight(struct abm *abm)
0189 {
0190 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
0191 unsigned int backlight = REG_READ(BL1_PWM_TARGET_ABM_LEVEL);
0192
0193
0194
0195
0196 return backlight;
0197 }
0198
0199 static bool dce_abm_set_level(struct abm *abm, uint32_t level)
0200 {
0201 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
0202
0203 if (abm->dmcu_is_running == false)
0204 return true;
0205
0206 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
0207 1, 80000);
0208
0209
0210 REG_UPDATE_2(MASTER_COMM_CMD_REG,
0211 MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_LEVEL_SET,
0212 MASTER_COMM_CMD_REG_BYTE2, level);
0213
0214
0215 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
0216
0217 return true;
0218 }
0219
0220 static bool dce_abm_immediate_disable(struct abm *abm, uint32_t panel_inst)
0221 {
0222 if (abm->dmcu_is_running == false)
0223 return true;
0224
0225 dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY, panel_inst);
0226
0227 return true;
0228 }
0229
0230 static bool dce_abm_set_backlight_level_pwm(
0231 struct abm *abm,
0232 unsigned int backlight_pwm_u16_16,
0233 unsigned int frame_ramp,
0234 unsigned int controller_id,
0235 unsigned int panel_inst)
0236 {
0237 struct dce_abm *abm_dce = TO_DCE_ABM(abm);
0238
0239 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
0240 backlight_pwm_u16_16, backlight_pwm_u16_16);
0241
0242 dmcu_set_backlight_level(abm_dce,
0243 backlight_pwm_u16_16,
0244 frame_ramp,
0245 controller_id,
0246 panel_inst);
0247
0248 return true;
0249 }
0250
0251 static const struct abm_funcs dce_funcs = {
0252 .abm_init = dce_abm_init,
0253 .set_abm_level = dce_abm_set_level,
0254 .set_pipe = dce_abm_set_pipe,
0255 .set_backlight_level_pwm = dce_abm_set_backlight_level_pwm,
0256 .get_current_backlight = dce_abm_get_current_backlight,
0257 .get_target_backlight = dce_abm_get_target_backlight,
0258 .init_abm_config = NULL,
0259 .set_abm_immediate_disable = dce_abm_immediate_disable,
0260 };
0261
0262 static void dce_abm_construct(
0263 struct dce_abm *abm_dce,
0264 struct dc_context *ctx,
0265 const struct dce_abm_registers *regs,
0266 const struct dce_abm_shift *abm_shift,
0267 const struct dce_abm_mask *abm_mask)
0268 {
0269 struct abm *base = &abm_dce->base;
0270
0271 base->ctx = ctx;
0272 base->funcs = &dce_funcs;
0273 base->dmcu_is_running = false;
0274
0275 abm_dce->regs = regs;
0276 abm_dce->abm_shift = abm_shift;
0277 abm_dce->abm_mask = abm_mask;
0278 }
0279
0280 struct abm *dce_abm_create(
0281 struct dc_context *ctx,
0282 const struct dce_abm_registers *regs,
0283 const struct dce_abm_shift *abm_shift,
0284 const struct dce_abm_mask *abm_mask)
0285 {
0286 struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_ATOMIC);
0287
0288 if (abm_dce == NULL) {
0289 BREAK_TO_DEBUGGER();
0290 return NULL;
0291 }
0292
0293 dce_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask);
0294
0295 abm_dce->base.funcs = &dce_funcs;
0296
0297 return &abm_dce->base;
0298 }
0299
0300 void dce_abm_destroy(struct abm **abm)
0301 {
0302 struct dce_abm *abm_dce = TO_DCE_ABM(*abm);
0303
0304 kfree(abm_dce);
0305 *abm = NULL;
0306 }