1 /* 2 * Copyright 2012-16 Advanced Micro Devices, Inc. 3 * 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: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 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. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include "dce_abm.h" 27 #include "dm_services.h" 28 #include "reg_helper.h" 29 #include "fixed31_32.h" 30 #include "dc.h" 31 32 #include "atom.h" 33 34 35 #define TO_DCE_ABM(abm)\ 36 container_of(abm, struct dce_abm, base) 37 38 #define REG(reg) \ 39 (abm_dce->regs->reg) 40 41 #undef FN 42 #define FN(reg_name, field_name) \ 43 abm_dce->abm_shift->field_name, abm_dce->abm_mask->field_name 44 45 #define DC_LOGGER \ 46 abm->ctx->logger 47 #define CTX \ 48 abm_dce->base.ctx 49 50 #define MCP_ABM_LEVEL_SET 0x65 51 #define MCP_ABM_PIPE_SET 0x66 52 #define MCP_BL_SET 0x67 53 54 #define MCP_DISABLE_ABM_IMMEDIATELY 255 55 56 static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id) 57 { 58 struct dce_abm *abm_dce = TO_DCE_ABM(abm); 59 uint32_t rampingBoundary = 0xFFFF; 60 61 if (abm->dmcu_is_running == false) 62 return true; 63 64 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 65 1, 80000); 66 67 /* set ramping boundary */ 68 REG_WRITE(MASTER_COMM_DATA_REG1, rampingBoundary); 69 70 /* setDMCUParam_Pipe */ 71 REG_UPDATE_2(MASTER_COMM_CMD_REG, 72 MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_PIPE_SET, 73 MASTER_COMM_CMD_REG_BYTE1, controller_id); 74 75 /* notifyDMCUMsg */ 76 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); 77 78 return true; 79 } 80 81 static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *abm_dce) 82 { 83 uint64_t current_backlight; 84 uint32_t round_result; 85 uint32_t pwm_period_cntl, bl_period, bl_int_count; 86 uint32_t bl_pwm_cntl, bl_pwm, fractional_duty_cycle_en; 87 uint32_t bl_period_mask, bl_pwm_mask; 88 89 pwm_period_cntl = REG_READ(BL_PWM_PERIOD_CNTL); 90 REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period); 91 REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count); 92 93 bl_pwm_cntl = REG_READ(BL_PWM_CNTL); 94 REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, (uint32_t *)(&bl_pwm)); 95 REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en); 96 97 if (bl_int_count == 0) 98 bl_int_count = 16; 99 100 bl_period_mask = (1 << bl_int_count) - 1; 101 bl_period &= bl_period_mask; 102 103 bl_pwm_mask = bl_period_mask << (16 - bl_int_count); 104 105 if (fractional_duty_cycle_en == 0) 106 bl_pwm &= bl_pwm_mask; 107 else 108 bl_pwm &= 0xFFFF; 109 110 current_backlight = bl_pwm << (1 + bl_int_count); 111 112 if (bl_period == 0) 113 bl_period = 0xFFFF; 114 115 current_backlight = div_u64(current_backlight, bl_period); 116 current_backlight = (current_backlight + 1) >> 1; 117 118 current_backlight = (uint64_t)(current_backlight) * bl_period; 119 120 round_result = (uint32_t)(current_backlight & 0xFFFFFFFF); 121 122 round_result = (round_result >> (bl_int_count-1)) & 1; 123 124 current_backlight >>= bl_int_count; 125 current_backlight += round_result; 126 127 return (uint32_t)(current_backlight); 128 } 129 130 static void driver_set_backlight_level(struct dce_abm *abm_dce, 131 uint32_t backlight_pwm_u16_16) 132 { 133 uint32_t backlight_16bit; 134 uint32_t masked_pwm_period; 135 uint8_t bit_count; 136 uint64_t active_duty_cycle; 137 uint32_t pwm_period_bitcnt; 138 139 /* 140 * 1. Find 16 bit backlight active duty cycle, where 0 <= backlight 141 * active duty cycle <= backlight period 142 */ 143 144 /* 1.1 Apply bitmask for backlight period value based on value of BITCNT 145 */ 146 REG_GET_2(BL_PWM_PERIOD_CNTL, 147 BL_PWM_PERIOD_BITCNT, &pwm_period_bitcnt, 148 BL_PWM_PERIOD, &masked_pwm_period); 149 150 if (pwm_period_bitcnt == 0) 151 bit_count = 16; 152 else 153 bit_count = pwm_period_bitcnt; 154 155 /* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */ 156 masked_pwm_period = masked_pwm_period & ((1 << bit_count) - 1); 157 158 /* 1.2 Calculate integer active duty cycle required upper 16 bits 159 * contain integer component, lower 16 bits contain fractional component 160 * of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24 161 */ 162 active_duty_cycle = backlight_pwm_u16_16 * masked_pwm_period; 163 164 /* 1.3 Calculate 16 bit active duty cycle from integer and fractional 165 * components shift by bitCount then mask 16 bits and add rounding bit 166 * from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0 167 */ 168 backlight_16bit = active_duty_cycle >> bit_count; 169 backlight_16bit &= 0xFFFF; 170 backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1; 171 172 /* 173 * 2. Program register with updated value 174 */ 175 176 /* 2.1 Lock group 2 backlight registers */ 177 178 REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK, 179 BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, 1, 180 BL_PWM_GRP1_REG_LOCK, 1); 181 182 // 2.2 Write new active duty cycle 183 REG_UPDATE(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, backlight_16bit); 184 185 /* 2.3 Unlock group 2 backlight registers */ 186 REG_UPDATE(BL_PWM_GRP1_REG_LOCK, 187 BL_PWM_GRP1_REG_LOCK, 0); 188 189 /* 3 Wait for pending bit to be cleared */ 190 REG_WAIT(BL_PWM_GRP1_REG_LOCK, 191 BL_PWM_GRP1_REG_UPDATE_PENDING, 0, 192 1, 10000); 193 } 194 195 static void dmcu_set_backlight_level( 196 struct dce_abm *abm_dce, 197 uint32_t backlight_pwm_u16_16, 198 uint32_t frame_ramp, 199 uint32_t controller_id) 200 { 201 unsigned int backlight_8_bit = 0; 202 uint32_t s2; 203 204 if (backlight_pwm_u16_16 & 0x10000) 205 // Check for max backlight condition 206 backlight_8_bit = 0xFF; 207 else 208 // Take MSB of fractional part since backlight is not max 209 backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; 210 211 dce_abm_set_pipe(&abm_dce->base, controller_id); 212 213 /* waitDMCUReadyForCmd */ 214 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 215 0, 1, 80000); 216 217 /* setDMCUParam_BL */ 218 REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_pwm_u16_16); 219 220 /* write ramp */ 221 if (controller_id == 0) 222 frame_ramp = 0; 223 REG_WRITE(MASTER_COMM_DATA_REG1, frame_ramp); 224 225 /* setDMCUParam_Cmd */ 226 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_BL_SET); 227 228 /* notifyDMCUMsg */ 229 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); 230 231 /* UpdateRequestedBacklightLevel */ 232 s2 = REG_READ(BIOS_SCRATCH_2); 233 234 s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK; 235 backlight_8_bit &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >> 236 ATOM_S2_CURRENT_BL_LEVEL_SHIFT); 237 s2 |= (backlight_8_bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT); 238 239 REG_WRITE(BIOS_SCRATCH_2, s2); 240 } 241 242 static void dce_abm_init(struct abm *abm) 243 { 244 struct dce_abm *abm_dce = TO_DCE_ABM(abm); 245 unsigned int backlight = calculate_16_bit_backlight_from_pwm(abm_dce); 246 247 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103); 248 REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101); 249 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x103); 250 REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x101); 251 REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE, 0x101); 252 253 REG_SET_3(DC_ABM1_HG_MISC_CTRL, 0, 254 ABM1_HG_NUM_OF_BINS_SEL, 0, 255 ABM1_HG_VMAX_SEL, 1, 256 ABM1_HG_BIN_BITWIDTH_SIZE_SEL, 0); 257 258 REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL, 0, 259 ABM1_IPCSC_COEFF_SEL_R, 2, 260 ABM1_IPCSC_COEFF_SEL_G, 4, 261 ABM1_IPCSC_COEFF_SEL_B, 2); 262 263 REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL, 264 BL1_PWM_CURRENT_ABM_LEVEL, backlight); 265 266 REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL, 267 BL1_PWM_TARGET_ABM_LEVEL, backlight); 268 269 REG_UPDATE(BL1_PWM_USER_LEVEL, 270 BL1_PWM_USER_LEVEL, backlight); 271 272 REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, 273 ABM1_LS_MIN_PIXEL_VALUE_THRES, 0, 274 ABM1_LS_MAX_PIXEL_VALUE_THRES, 1000); 275 276 REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS, 0, 277 ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, 1, 278 ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, 1, 279 ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1); 280 } 281 282 static unsigned int dce_abm_get_current_backlight(struct abm *abm) 283 { 284 struct dce_abm *abm_dce = TO_DCE_ABM(abm); 285 unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL); 286 287 /* return backlight in hardware format which is unsigned 17 bits, with 288 * 1 bit integer and 16 bit fractional 289 */ 290 return backlight; 291 } 292 293 static unsigned int dce_abm_get_target_backlight(struct abm *abm) 294 { 295 struct dce_abm *abm_dce = TO_DCE_ABM(abm); 296 unsigned int backlight = REG_READ(BL1_PWM_TARGET_ABM_LEVEL); 297 298 /* return backlight in hardware format which is unsigned 17 bits, with 299 * 1 bit integer and 16 bit fractional 300 */ 301 return backlight; 302 } 303 304 static bool dce_abm_set_level(struct abm *abm, uint32_t level) 305 { 306 struct dce_abm *abm_dce = TO_DCE_ABM(abm); 307 308 if (abm->dmcu_is_running == false) 309 return true; 310 311 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 312 1, 80000); 313 314 /* setDMCUParam_ABMLevel */ 315 REG_UPDATE_2(MASTER_COMM_CMD_REG, 316 MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_LEVEL_SET, 317 MASTER_COMM_CMD_REG_BYTE2, level); 318 319 /* notifyDMCUMsg */ 320 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); 321 322 return true; 323 } 324 325 static bool dce_abm_immediate_disable(struct abm *abm) 326 { 327 struct dce_abm *abm_dce = TO_DCE_ABM(abm); 328 329 if (abm->dmcu_is_running == false) 330 return true; 331 332 dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY); 333 334 abm->stored_backlight_registers.BL_PWM_CNTL = 335 REG_READ(BL_PWM_CNTL); 336 abm->stored_backlight_registers.BL_PWM_CNTL2 = 337 REG_READ(BL_PWM_CNTL2); 338 abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 339 REG_READ(BL_PWM_PERIOD_CNTL); 340 341 REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV, 342 &abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV); 343 return true; 344 } 345 346 static bool dce_abm_init_backlight(struct abm *abm) 347 { 348 struct dce_abm *abm_dce = TO_DCE_ABM(abm); 349 uint32_t value; 350 351 /* It must not be 0, so we have to restore them 352 * Bios bug w/a - period resets to zero, 353 * restoring to cache values which is always correct 354 */ 355 REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value); 356 if (value == 0 || value == 1) { 357 if (abm->stored_backlight_registers.BL_PWM_CNTL != 0) { 358 REG_WRITE(BL_PWM_CNTL, 359 abm->stored_backlight_registers.BL_PWM_CNTL); 360 REG_WRITE(BL_PWM_CNTL2, 361 abm->stored_backlight_registers.BL_PWM_CNTL2); 362 REG_WRITE(BL_PWM_PERIOD_CNTL, 363 abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL); 364 REG_UPDATE(LVTMA_PWRSEQ_REF_DIV, 365 BL_PWM_REF_DIV, 366 abm->stored_backlight_registers. 367 LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV); 368 } else { 369 /* TODO: Note: This should not really happen since VBIOS 370 * should have initialized PWM registers on boot. 371 */ 372 REG_WRITE(BL_PWM_CNTL, 0xC000FA00); 373 REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0); 374 } 375 } else { 376 abm->stored_backlight_registers.BL_PWM_CNTL = 377 REG_READ(BL_PWM_CNTL); 378 abm->stored_backlight_registers.BL_PWM_CNTL2 = 379 REG_READ(BL_PWM_CNTL2); 380 abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 381 REG_READ(BL_PWM_PERIOD_CNTL); 382 383 REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV, 384 &abm->stored_backlight_registers. 385 LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV); 386 } 387 388 /* Have driver take backlight control 389 * TakeBacklightControl(true) 390 */ 391 value = REG_READ(BIOS_SCRATCH_2); 392 value |= ATOM_S2_VRI_BRIGHT_ENABLE; 393 REG_WRITE(BIOS_SCRATCH_2, value); 394 395 /* Enable the backlight output */ 396 REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1); 397 398 /* Unlock group 2 backlight registers */ 399 REG_UPDATE(BL_PWM_GRP1_REG_LOCK, 400 BL_PWM_GRP1_REG_LOCK, 0); 401 402 return true; 403 } 404 405 static bool dce_abm_set_backlight_level_pwm( 406 struct abm *abm, 407 unsigned int backlight_pwm_u16_16, 408 unsigned int frame_ramp, 409 unsigned int controller_id, 410 bool use_smooth_brightness) 411 { 412 struct dce_abm *abm_dce = TO_DCE_ABM(abm); 413 414 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", 415 backlight_pwm_u16_16, backlight_pwm_u16_16); 416 417 /* If DMCU is in reset state, DMCU is uninitialized */ 418 if (use_smooth_brightness) 419 dmcu_set_backlight_level(abm_dce, 420 backlight_pwm_u16_16, 421 frame_ramp, 422 controller_id); 423 else 424 driver_set_backlight_level(abm_dce, backlight_pwm_u16_16); 425 426 return true; 427 } 428 429 static const struct abm_funcs dce_funcs = { 430 .abm_init = dce_abm_init, 431 .set_abm_level = dce_abm_set_level, 432 .init_backlight = dce_abm_init_backlight, 433 .set_pipe = dce_abm_set_pipe, 434 .set_backlight_level_pwm = dce_abm_set_backlight_level_pwm, 435 .get_current_backlight = dce_abm_get_current_backlight, 436 .get_target_backlight = dce_abm_get_target_backlight, 437 .set_abm_immediate_disable = dce_abm_immediate_disable 438 }; 439 440 static void dce_abm_construct( 441 struct dce_abm *abm_dce, 442 struct dc_context *ctx, 443 const struct dce_abm_registers *regs, 444 const struct dce_abm_shift *abm_shift, 445 const struct dce_abm_mask *abm_mask) 446 { 447 struct abm *base = &abm_dce->base; 448 449 base->ctx = ctx; 450 base->funcs = &dce_funcs; 451 base->stored_backlight_registers.BL_PWM_CNTL = 0; 452 base->stored_backlight_registers.BL_PWM_CNTL2 = 0; 453 base->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 0; 454 base->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV = 0; 455 base->dmcu_is_running = false; 456 457 abm_dce->regs = regs; 458 abm_dce->abm_shift = abm_shift; 459 abm_dce->abm_mask = abm_mask; 460 } 461 462 struct abm *dce_abm_create( 463 struct dc_context *ctx, 464 const struct dce_abm_registers *regs, 465 const struct dce_abm_shift *abm_shift, 466 const struct dce_abm_mask *abm_mask) 467 { 468 struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL); 469 470 if (abm_dce == NULL) { 471 BREAK_TO_DEBUGGER(); 472 return NULL; 473 } 474 475 dce_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask); 476 477 abm_dce->base.funcs = &dce_funcs; 478 479 return &abm_dce->base; 480 } 481 482 void dce_abm_destroy(struct abm **abm) 483 { 484 struct dce_abm *abm_dce = TO_DCE_ABM(*abm); 485 486 if (abm_dce->base.dmcu_is_running == true) 487 abm_dce->base.funcs->set_abm_immediate_disable(*abm); 488 489 kfree(abm_dce); 490 *abm = NULL; 491 } 492