1193 lines · c
1/*2 * Copyright 2012-16 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "core_types.h"27#include "link_encoder.h"28#include "dce_dmcu.h"29#include "dm_services.h"30#include "reg_helper.h"31#include "fixed31_32.h"32#include "dc.h"33 34#define TO_DCE_DMCU(dmcu)\35 container_of(dmcu, struct dce_dmcu, base)36 37#define REG(reg) \38 (dmcu_dce->regs->reg)39 40#undef FN41#define FN(reg_name, field_name) \42 dmcu_dce->dmcu_shift->field_name, dmcu_dce->dmcu_mask->field_name43 44#define CTX \45 dmcu_dce->base.ctx46 47/* PSR related commands */48#define PSR_ENABLE 0x2049#define PSR_EXIT 0x2150#define PSR_SET 0x2351#define PSR_SET_WAITLOOP 0x3152#define MCP_INIT_DMCU 0x8853#define MCP_INIT_IRAM 0x8954#define MCP_SYNC_PHY_LOCK 0x9055#define MCP_SYNC_PHY_UNLOCK 0x9156#define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */57#define CRC_WIN_NOTIFY 0x9258#define CRC_STOP_UPDATE 0x9359#define MCP_SEND_EDID_CEA 0xA060#define EDID_CEA_CMD_ACK 161#define EDID_CEA_CMD_NACK 262#define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L63 64// PSP FW version65#define mmMP0_SMN_C2PMSG_58 0x1607A66 67//Register access policy version68#define mmMP0_SMN_C2PMSG_91 0x1609B69 70static const uint32_t abm_gain_stepsize = 0x0060;71 72static bool dce_dmcu_init(struct dmcu *dmcu)73{74 // Do nothing75 return true;76}77 78static bool dce_dmcu_load_iram(struct dmcu *dmcu,79 unsigned int start_offset,80 const char *src,81 unsigned int bytes)82{83 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);84 unsigned int count = 0;85 86 /* Enable write access to IRAM */87 REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,88 IRAM_HOST_ACCESS_EN, 1,89 IRAM_WR_ADDR_AUTO_INC, 1);90 91 REG_WAIT(DCI_MEM_PWR_STATUS, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10);92 93 REG_WRITE(DMCU_IRAM_WR_CTRL, start_offset);94 95 for (count = 0; count < bytes; count++)96 REG_WRITE(DMCU_IRAM_WR_DATA, src[count]);97 98 /* Disable write access to IRAM to allow dynamic sleep state */99 REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,100 IRAM_HOST_ACCESS_EN, 0,101 IRAM_WR_ADDR_AUTO_INC, 0);102 103 return true;104}105 106static void dce_get_dmcu_psr_state(struct dmcu *dmcu, enum dc_psr_state *state)107{108 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);109 110 uint32_t psr_state_offset = 0xf0;111 112 /* Enable write access to IRAM */113 REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 1);114 115 REG_WAIT(DCI_MEM_PWR_STATUS, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10);116 117 /* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */118 REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);119 120 /* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/121 *state = (enum dc_psr_state)REG_READ(DMCU_IRAM_RD_DATA);122 123 /* Disable write access to IRAM after finished using IRAM124 * in order to allow dynamic sleep state125 */126 REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 0);127}128 129static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)130{131 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);132 unsigned int dmcu_max_retry_on_wait_reg_ready = 801;133 unsigned int dmcu_wait_reg_ready_interval = 100;134 135 unsigned int retryCount;136 enum dc_psr_state state = PSR_STATE0;137 138 /* waitDMCUReadyForCmd */139 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,140 dmcu_wait_reg_ready_interval,141 dmcu_max_retry_on_wait_reg_ready);142 143 /* setDMCUParam_Cmd */144 if (enable)145 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,146 PSR_ENABLE);147 else148 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,149 PSR_EXIT);150 151 /* notifyDMCUMsg */152 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);153 if (wait == true) {154 for (retryCount = 0; retryCount <= 100; retryCount++) {155 dce_get_dmcu_psr_state(dmcu, &state);156 if (enable) {157 if (state != PSR_STATE0)158 break;159 } else {160 if (state == PSR_STATE0)161 break;162 }163 udelay(10);164 }165 }166}167 168static bool dce_dmcu_setup_psr(struct dmcu *dmcu,169 struct dc_link *link,170 struct psr_context *psr_context)171{172 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);173 174 unsigned int dmcu_max_retry_on_wait_reg_ready = 801;175 unsigned int dmcu_wait_reg_ready_interval = 100;176 177 union dce_dmcu_psr_config_data_reg1 masterCmdData1;178 union dce_dmcu_psr_config_data_reg2 masterCmdData2;179 union dce_dmcu_psr_config_data_reg3 masterCmdData3;180 181 link->link_enc->funcs->psr_program_dp_dphy_fast_training(link->link_enc,182 psr_context->psrExitLinkTrainingRequired);183 184 /* Enable static screen interrupts for PSR supported display */185 /* Disable the interrupt coming from other displays. */186 REG_UPDATE_4(DMCU_INTERRUPT_TO_UC_EN_MASK,187 STATIC_SCREEN1_INT_TO_UC_EN, 0,188 STATIC_SCREEN2_INT_TO_UC_EN, 0,189 STATIC_SCREEN3_INT_TO_UC_EN, 0,190 STATIC_SCREEN4_INT_TO_UC_EN, 0);191 192 switch (psr_context->controllerId) {193 /* Driver uses case 1 for unconfigured */194 case 1:195 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,196 STATIC_SCREEN1_INT_TO_UC_EN, 1);197 break;198 case 2:199 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,200 STATIC_SCREEN2_INT_TO_UC_EN, 1);201 break;202 case 3:203 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,204 STATIC_SCREEN3_INT_TO_UC_EN, 1);205 break;206 case 4:207 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,208 STATIC_SCREEN4_INT_TO_UC_EN, 1);209 break;210 case 5:211 /* CZ/NL only has 4 CRTC!!212 * really valid.213 * There is no interrupt enable mask for these instances.214 */215 break;216 case 6:217 /* CZ/NL only has 4 CRTC!!218 * These are here because they are defined in HW regspec,219 * but not really valid. There is no interrupt enable mask220 * for these instances.221 */222 break;223 default:224 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,225 STATIC_SCREEN1_INT_TO_UC_EN, 1);226 break;227 }228 229 link->link_enc->funcs->psr_program_secondary_packet(link->link_enc,230 psr_context->sdpTransmitLineNumDeadline);231 232 /* waitDMCUReadyForCmd */233 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,234 dmcu_wait_reg_ready_interval,235 dmcu_max_retry_on_wait_reg_ready);236 237 /* setDMCUParam_PSRHostConfigData */238 masterCmdData1.u32All = 0;239 masterCmdData1.bits.timehyst_frames = psr_context->timehyst_frames;240 masterCmdData1.bits.hyst_lines = psr_context->hyst_lines;241 masterCmdData1.bits.rfb_update_auto_en =242 psr_context->rfb_update_auto_en;243 masterCmdData1.bits.dp_port_num = psr_context->transmitterId;244 masterCmdData1.bits.dcp_sel = psr_context->controllerId;245 masterCmdData1.bits.phy_type = psr_context->phyType;246 masterCmdData1.bits.frame_cap_ind =247 psr_context->psrFrameCaptureIndicationReq;248 masterCmdData1.bits.aux_chan = psr_context->channel;249 masterCmdData1.bits.aux_repeat = psr_context->aux_repeats;250 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1),251 masterCmdData1.u32All);252 253 masterCmdData2.u32All = 0;254 masterCmdData2.bits.dig_fe = psr_context->engineId;255 masterCmdData2.bits.dig_be = psr_context->transmitterId;256 masterCmdData2.bits.skip_wait_for_pll_lock =257 psr_context->skipPsrWaitForPllLock;258 masterCmdData2.bits.frame_delay = psr_context->frame_delay;259 masterCmdData2.bits.smu_phy_id = psr_context->smuPhyId;260 masterCmdData2.bits.num_of_controllers =261 psr_context->numberOfControllers;262 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG2),263 masterCmdData2.u32All);264 265 masterCmdData3.u32All = 0;266 masterCmdData3.bits.psr_level = psr_context->psr_level.u32all;267 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG3),268 masterCmdData3.u32All);269 270 /* setDMCUParam_Cmd */271 REG_UPDATE(MASTER_COMM_CMD_REG,272 MASTER_COMM_CMD_REG_BYTE0, PSR_SET);273 274 /* notifyDMCUMsg */275 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);276 277 return true;278}279 280static bool dce_is_dmcu_initialized(struct dmcu *dmcu)281{282 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);283 unsigned int dmcu_uc_reset;284 285 /* microcontroller is not running */286 REG_GET(DMCU_STATUS, UC_IN_RESET, &dmcu_uc_reset);287 288 /* DMCU is not running */289 if (dmcu_uc_reset)290 return false;291 292 return true;293}294 295static void dce_psr_wait_loop(296 struct dmcu *dmcu,297 unsigned int wait_loop_number)298{299 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);300 union dce_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1;301 302 if (dmcu->cached_wait_loop_number == wait_loop_number)303 return;304 305 /* DMCU is not running */306 if (!dce_is_dmcu_initialized(dmcu))307 return;308 309 /* waitDMCUReadyForCmd */310 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);311 312 masterCmdData1.u32 = 0;313 masterCmdData1.bits.wait_loop = wait_loop_number;314 dmcu->cached_wait_loop_number = wait_loop_number;315 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32);316 317 /* setDMCUParam_Cmd */318 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP);319 320 /* notifyDMCUMsg */321 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);322}323 324static void dce_get_psr_wait_loop(325 struct dmcu *dmcu, unsigned int *psr_wait_loop_number)326{327 *psr_wait_loop_number = dmcu->cached_wait_loop_number;328 return;329}330 331static void dcn10_get_dmcu_version(struct dmcu *dmcu)332{333 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);334 uint32_t dmcu_version_offset = 0xf1;335 336 /* Enable write access to IRAM */337 REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,338 IRAM_HOST_ACCESS_EN, 1,339 IRAM_RD_ADDR_AUTO_INC, 1);340 341 REG_WAIT(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10);342 343 /* Write address to IRAM_RD_ADDR and read from DATA register */344 REG_WRITE(DMCU_IRAM_RD_CTRL, dmcu_version_offset);345 dmcu->dmcu_version.interface_version = REG_READ(DMCU_IRAM_RD_DATA);346 dmcu->dmcu_version.abm_version = REG_READ(DMCU_IRAM_RD_DATA);347 dmcu->dmcu_version.psr_version = REG_READ(DMCU_IRAM_RD_DATA);348 dmcu->dmcu_version.build_version = ((REG_READ(DMCU_IRAM_RD_DATA) << 8) |349 REG_READ(DMCU_IRAM_RD_DATA));350 351 /* Disable write access to IRAM to allow dynamic sleep state */352 REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,353 IRAM_HOST_ACCESS_EN, 0,354 IRAM_RD_ADDR_AUTO_INC, 0);355}356 357static void dcn10_dmcu_enable_fractional_pwm(struct dmcu *dmcu,358 uint32_t fractional_pwm)359{360 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);361 362 /* Wait until microcontroller is ready to process interrupt */363 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);364 365 /* Set PWM fractional enable/disable */366 REG_WRITE(MASTER_COMM_DATA_REG1, fractional_pwm);367 368 /* Set command to enable or disable fractional PWM microcontroller */369 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,370 MCP_BL_SET_PWM_FRAC);371 372 /* Notify microcontroller of new command */373 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);374 375 /* Ensure command has been executed before continuing */376 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);377}378 379static bool dcn10_dmcu_init(struct dmcu *dmcu)380{381 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);382 const struct dc_config *config = &dmcu->ctx->dc->config;383 bool status = false;384 struct dc_context *ctx = dmcu->ctx;385 unsigned int i;386 // 5 4 3 2 1 0387 // F E D C B A - bit 0 is A, bit 5 is F388 unsigned int tx_interrupt_mask = 0;389 390 PERF_TRACE();391 /* Definition of DC_DMCU_SCRATCH392 * 0 : firmare not loaded393 * 1 : PSP load DMCU FW but not initialized394 * 2 : Firmware already initialized395 */396 dmcu->dmcu_state = REG_READ(DC_DMCU_SCRATCH);397 398 for (i = 0; i < ctx->dc->link_count; i++) {399 if (ctx->dc->links[i]->link_enc->features.flags.bits.DP_IS_USB_C) {400 if (ctx->dc->links[i]->link_enc->transmitter >= TRANSMITTER_UNIPHY_A &&401 ctx->dc->links[i]->link_enc->transmitter <= TRANSMITTER_UNIPHY_F) {402 tx_interrupt_mask |= 1 << ctx->dc->links[i]->link_enc->transmitter;403 }404 }405 }406 407 switch (dmcu->dmcu_state) {408 case DMCU_UNLOADED:409 status = false;410 break;411 case DMCU_LOADED_UNINITIALIZED:412 /* Wait until microcontroller is ready to process interrupt */413 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);414 415 /* Set initialized ramping boundary value */416 REG_WRITE(MASTER_COMM_DATA_REG1, 0xFFFF);417 418 /* Set backlight ramping stepsize */419 REG_WRITE(MASTER_COMM_DATA_REG2, abm_gain_stepsize);420 421 REG_WRITE(MASTER_COMM_DATA_REG3, tx_interrupt_mask);422 423 /* Set command to initialize microcontroller */424 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,425 MCP_INIT_DMCU);426 427 /* Notify microcontroller of new command */428 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);429 430 /* Ensure command has been executed before continuing */431 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);432 433 // Check state is initialized434 dmcu->dmcu_state = REG_READ(DC_DMCU_SCRATCH);435 436 // If microcontroller is not in running state, fail437 if (dmcu->dmcu_state == DMCU_RUNNING) {438 /* Retrieve and cache the DMCU firmware version. */439 dcn10_get_dmcu_version(dmcu);440 441 /* Initialize DMCU to use fractional PWM or not */442 dcn10_dmcu_enable_fractional_pwm(dmcu,443 (config->disable_fractional_pwm == false) ? 1 : 0);444 status = true;445 } else {446 status = false;447 }448 449 break;450 case DMCU_RUNNING:451 status = true;452 break;453 default:454 status = false;455 break;456 }457 458 PERF_TRACE();459 return status;460}461 462static bool dcn21_dmcu_init(struct dmcu *dmcu)463{464 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);465 uint32_t dmcub_psp_version = REG_READ(DMCUB_SCRATCH15);466 467 if (dmcu->auto_load_dmcu && dmcub_psp_version == 0) {468 return false;469 }470 471 return dcn10_dmcu_init(dmcu);472}473 474static bool dcn10_dmcu_load_iram(struct dmcu *dmcu,475 unsigned int start_offset,476 const char *src,477 unsigned int bytes)478{479 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);480 unsigned int count = 0;481 482 /* If microcontroller is not running, do nothing */483 if (dmcu->dmcu_state != DMCU_RUNNING)484 return false;485 486 /* Enable write access to IRAM */487 REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,488 IRAM_HOST_ACCESS_EN, 1,489 IRAM_WR_ADDR_AUTO_INC, 1);490 491 REG_WAIT(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10);492 493 REG_WRITE(DMCU_IRAM_WR_CTRL, start_offset);494 495 for (count = 0; count < bytes; count++)496 REG_WRITE(DMCU_IRAM_WR_DATA, src[count]);497 498 /* Disable write access to IRAM to allow dynamic sleep state */499 REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,500 IRAM_HOST_ACCESS_EN, 0,501 IRAM_WR_ADDR_AUTO_INC, 0);502 503 /* Wait until microcontroller is ready to process interrupt */504 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);505 506 /* Set command to signal IRAM is loaded and to initialize IRAM */507 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,508 MCP_INIT_IRAM);509 510 /* Notify microcontroller of new command */511 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);512 513 /* Ensure command has been executed before continuing */514 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);515 516 return true;517}518 519static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, enum dc_psr_state *state)520{521 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);522 523 uint32_t psr_state_offset = 0xf0;524 525 /* If microcontroller is not running, do nothing */526 if (dmcu->dmcu_state != DMCU_RUNNING)527 return;528 529 /* Enable write access to IRAM */530 REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 1);531 532 REG_WAIT(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10);533 534 /* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */535 REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);536 537 /* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/538 *state = (enum dc_psr_state)REG_READ(DMCU_IRAM_RD_DATA);539 540 /* Disable write access to IRAM after finished using IRAM541 * in order to allow dynamic sleep state542 */543 REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 0);544}545 546static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)547{548 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);549 unsigned int dmcu_max_retry_on_wait_reg_ready = 801;550 unsigned int dmcu_wait_reg_ready_interval = 100;551 552 unsigned int retryCount;553 enum dc_psr_state state = PSR_STATE0;554 555 /* If microcontroller is not running, do nothing */556 if (dmcu->dmcu_state != DMCU_RUNNING)557 return;558 559 /* waitDMCUReadyForCmd */560 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,561 dmcu_wait_reg_ready_interval,562 dmcu_max_retry_on_wait_reg_ready);563 564 /* setDMCUParam_Cmd */565 if (enable)566 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,567 PSR_ENABLE);568 else569 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,570 PSR_EXIT);571 572 /* notifyDMCUMsg */573 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);574 575 /* Below loops 1000 x 500us = 500 ms.576 * Exit PSR may need to wait 1-2 frames to power up. Timeout after at577 * least a few frames. Should never hit the max retry assert below.578 */579 if (wait == true) {580 for (retryCount = 0; retryCount <= 1000; retryCount++) {581 dcn10_get_dmcu_psr_state(dmcu, &state);582 if (enable) {583 if (state != PSR_STATE0)584 break;585 } else {586 if (state == PSR_STATE0)587 break;588 }589 /* must *not* be fsleep - this can be called from high irq levels */590 udelay(500);591 }592 593 /* assert if max retry hit */594 if (retryCount >= 1000)595 ASSERT(0);596 }597}598 599static bool dcn10_dmcu_setup_psr(struct dmcu *dmcu,600 struct dc_link *link,601 struct psr_context *psr_context)602{603 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);604 605 unsigned int dmcu_max_retry_on_wait_reg_ready = 801;606 unsigned int dmcu_wait_reg_ready_interval = 100;607 608 union dce_dmcu_psr_config_data_reg1 masterCmdData1;609 union dce_dmcu_psr_config_data_reg2 masterCmdData2;610 union dce_dmcu_psr_config_data_reg3 masterCmdData3;611 612 /* If microcontroller is not running, do nothing */613 if (dmcu->dmcu_state != DMCU_RUNNING)614 return false;615 616 link->link_enc->funcs->psr_program_dp_dphy_fast_training(link->link_enc,617 psr_context->psrExitLinkTrainingRequired);618 619 /* Enable static screen interrupts for PSR supported display */620 /* Disable the interrupt coming from other displays. */621 REG_UPDATE_4(DMCU_INTERRUPT_TO_UC_EN_MASK,622 STATIC_SCREEN1_INT_TO_UC_EN, 0,623 STATIC_SCREEN2_INT_TO_UC_EN, 0,624 STATIC_SCREEN3_INT_TO_UC_EN, 0,625 STATIC_SCREEN4_INT_TO_UC_EN, 0);626 627 switch (psr_context->controllerId) {628 /* Driver uses case 1 for unconfigured */629 case 1:630 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,631 STATIC_SCREEN1_INT_TO_UC_EN, 1);632 break;633 case 2:634 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,635 STATIC_SCREEN2_INT_TO_UC_EN, 1);636 break;637 case 3:638 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,639 STATIC_SCREEN3_INT_TO_UC_EN, 1);640 break;641 case 4:642 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,643 STATIC_SCREEN4_INT_TO_UC_EN, 1);644 break;645 case 5:646 /* CZ/NL only has 4 CRTC!!647 * really valid.648 * There is no interrupt enable mask for these instances.649 */650 break;651 case 6:652 /* CZ/NL only has 4 CRTC!!653 * These are here because they are defined in HW regspec,654 * but not really valid. There is no interrupt enable mask655 * for these instances.656 */657 break;658 default:659 REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,660 STATIC_SCREEN1_INT_TO_UC_EN, 1);661 break;662 }663 664 link->link_enc->funcs->psr_program_secondary_packet(link->link_enc,665 psr_context->sdpTransmitLineNumDeadline);666 667 if (psr_context->allow_smu_optimizations)668 REG_UPDATE(SMU_INTERRUPT_CONTROL, DC_SMU_INT_ENABLE, 1);669 670 /* waitDMCUReadyForCmd */671 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,672 dmcu_wait_reg_ready_interval,673 dmcu_max_retry_on_wait_reg_ready);674 675 /* setDMCUParam_PSRHostConfigData */676 masterCmdData1.u32All = 0;677 masterCmdData1.bits.timehyst_frames = psr_context->timehyst_frames;678 masterCmdData1.bits.hyst_lines = psr_context->hyst_lines;679 masterCmdData1.bits.rfb_update_auto_en =680 psr_context->rfb_update_auto_en;681 masterCmdData1.bits.dp_port_num = psr_context->transmitterId;682 masterCmdData1.bits.dcp_sel = psr_context->controllerId;683 masterCmdData1.bits.phy_type = psr_context->phyType;684 masterCmdData1.bits.frame_cap_ind =685 psr_context->psrFrameCaptureIndicationReq;686 masterCmdData1.bits.aux_chan = psr_context->channel;687 masterCmdData1.bits.aux_repeat = psr_context->aux_repeats;688 masterCmdData1.bits.allow_smu_optimizations = psr_context->allow_smu_optimizations;689 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1),690 masterCmdData1.u32All);691 692 masterCmdData2.u32All = 0;693 masterCmdData2.bits.dig_fe = psr_context->engineId;694 masterCmdData2.bits.dig_be = psr_context->transmitterId;695 masterCmdData2.bits.skip_wait_for_pll_lock =696 psr_context->skipPsrWaitForPllLock;697 masterCmdData2.bits.frame_delay = psr_context->frame_delay;698 masterCmdData2.bits.smu_phy_id = psr_context->smuPhyId;699 masterCmdData2.bits.num_of_controllers =700 psr_context->numberOfControllers;701 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG2),702 masterCmdData2.u32All);703 704 masterCmdData3.u32All = 0;705 masterCmdData3.bits.psr_level = psr_context->psr_level.u32all;706 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG3),707 masterCmdData3.u32All);708 709 710 /* setDMCUParam_Cmd */711 REG_UPDATE(MASTER_COMM_CMD_REG,712 MASTER_COMM_CMD_REG_BYTE0, PSR_SET);713 714 /* notifyDMCUMsg */715 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);716 717 /* waitDMCUReadyForCmd */718 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);719 720 return true;721}722 723static void dcn10_psr_wait_loop(724 struct dmcu *dmcu,725 unsigned int wait_loop_number)726{727 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);728 union dce_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1;729 730 /* If microcontroller is not running, do nothing */731 if (dmcu->dmcu_state != DMCU_RUNNING)732 return;733 734 if (wait_loop_number != 0) {735 /* waitDMCUReadyForCmd */736 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);737 738 masterCmdData1.u32 = 0;739 masterCmdData1.bits.wait_loop = wait_loop_number;740 dmcu->cached_wait_loop_number = wait_loop_number;741 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32);742 743 /* setDMCUParam_Cmd */744 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP);745 746 /* notifyDMCUMsg */747 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);748 }749}750 751static void dcn10_get_psr_wait_loop(752 struct dmcu *dmcu, unsigned int *psr_wait_loop_number)753{754 *psr_wait_loop_number = dmcu->cached_wait_loop_number;755 return;756}757 758static bool dcn10_is_dmcu_initialized(struct dmcu *dmcu)759{760 /* microcontroller is not running */761 if (dmcu->dmcu_state != DMCU_RUNNING)762 return false;763 return true;764}765 766 767 768static bool dcn20_lock_phy(struct dmcu *dmcu)769{770 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);771 772 /* If microcontroller is not running, do nothing */773 if (dmcu->dmcu_state != DMCU_RUNNING)774 return false;775 776 /* waitDMCUReadyForCmd */777 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);778 779 /* setDMCUParam_Cmd */780 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_SYNC_PHY_LOCK);781 782 /* notifyDMCUMsg */783 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);784 785 /* waitDMCUReadyForCmd */786 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);787 788 return true;789}790 791static bool dcn20_unlock_phy(struct dmcu *dmcu)792{793 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);794 795 /* If microcontroller is not running, do nothing */796 if (dmcu->dmcu_state != DMCU_RUNNING)797 return false;798 799 /* waitDMCUReadyForCmd */800 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);801 802 /* setDMCUParam_Cmd */803 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_SYNC_PHY_UNLOCK);804 805 /* notifyDMCUMsg */806 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);807 808 /* waitDMCUReadyForCmd */809 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);810 811 return true;812}813 814static bool dcn10_send_edid_cea(struct dmcu *dmcu,815 int offset,816 int total_length,817 uint8_t *data,818 int length)819{820 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);821 uint32_t header, data1, data2;822 823 /* If microcontroller is not running, do nothing */824 if (dmcu->dmcu_state != DMCU_RUNNING)825 return false;826 827 if (length > 8 || length <= 0)828 return false;829 830 header = ((uint32_t)offset & 0xFFFF) << 16 | (total_length & 0xFFFF);831 data1 = (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) |832 (((uint32_t)data[2]) << 8) | ((uint32_t)data[3]);833 data2 = (((uint32_t)data[4]) << 24) | (((uint32_t)data[5]) << 16) |834 (((uint32_t)data[6]) << 8) | ((uint32_t)data[7]);835 836 /* waitDMCUReadyForCmd */837 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);838 839 /* setDMCUParam_Cmd */840 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_SEND_EDID_CEA);841 842 REG_WRITE(MASTER_COMM_DATA_REG1, header);843 REG_WRITE(MASTER_COMM_DATA_REG2, data1);844 REG_WRITE(MASTER_COMM_DATA_REG3, data2);845 846 /* notifyDMCUMsg */847 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);848 849 /* waitDMCUReadyForCmd */850 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);851 852 return true;853}854 855static bool dcn10_get_scp_results(struct dmcu *dmcu,856 uint32_t *cmd,857 uint32_t *data1,858 uint32_t *data2,859 uint32_t *data3)860{861 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);862 863 /* If microcontroller is not running, do nothing */864 if (dmcu->dmcu_state != DMCU_RUNNING)865 return false;866 867 *cmd = REG_READ(SLAVE_COMM_CMD_REG);868 *data1 = REG_READ(SLAVE_COMM_DATA_REG1);869 *data2 = REG_READ(SLAVE_COMM_DATA_REG2);870 *data3 = REG_READ(SLAVE_COMM_DATA_REG3);871 872 /* clear SCP interrupt */873 REG_UPDATE(SLAVE_COMM_CNTL_REG, SLAVE_COMM_INTERRUPT, 0);874 875 return true;876}877 878static bool dcn10_recv_amd_vsdb(struct dmcu *dmcu,879 int *version,880 int *min_frame_rate,881 int *max_frame_rate)882{883 uint32_t data[4];884 int cmd, ack, len;885 886 if (!dcn10_get_scp_results(dmcu, &data[0], &data[1], &data[2], &data[3]))887 return false;888 889 cmd = data[0] & 0x3FF;890 len = (data[0] >> 10) & 0x3F;891 ack = data[1];892 893 if (cmd != MCP_SEND_EDID_CEA || ack != EDID_CEA_CMD_ACK || len != 12)894 return false;895 896 if ((data[2] & 0xFF)) {897 *version = (data[2] >> 8) & 0xFF;898 *min_frame_rate = (data[3] >> 16) & 0xFFFF;899 *max_frame_rate = data[3] & 0xFFFF;900 return true;901 }902 903 return false;904}905 906static bool dcn10_recv_edid_cea_ack(struct dmcu *dmcu, int *offset)907{908 uint32_t data[4];909 int cmd, ack;910 911 if (!dcn10_get_scp_results(dmcu,912 &data[0], &data[1], &data[2], &data[3]))913 return false;914 915 cmd = data[0] & 0x3FF;916 ack = data[1];917 918 if (cmd != MCP_SEND_EDID_CEA)919 return false;920 921 if (ack == EDID_CEA_CMD_ACK)922 return true;923 924 *offset = data[2]; /* nack */925 return false;926}927 928 929#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)930static void dcn10_forward_crc_window(struct dmcu *dmcu,931 struct rect *rect,932 struct otg_phy_mux *mux_mapping)933{934 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);935 unsigned int dmcu_max_retry_on_wait_reg_ready = 801;936 unsigned int dmcu_wait_reg_ready_interval = 100;937 unsigned int crc_start = 0, crc_end = 0, otg_phy_mux = 0;938 int x_start, y_start, x_end, y_end;939 940 /* If microcontroller is not running, do nothing */941 if (dmcu->dmcu_state != DMCU_RUNNING)942 return;943 944 if (!rect)945 return;946 947 /* waitDMCUReadyForCmd */948 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,949 dmcu_wait_reg_ready_interval,950 dmcu_max_retry_on_wait_reg_ready);951 952 x_start = rect->x;953 y_start = rect->y;954 x_end = x_start + rect->width;955 y_end = y_start + rect->height;956 957 /* build up nitification data */958 crc_start = (((unsigned int) x_start) << 16) | y_start;959 crc_end = (((unsigned int) x_end) << 16) | y_end;960 otg_phy_mux =961 (((unsigned int) mux_mapping->otg_output_num) << 16) | mux_mapping->phy_output_num;962 963 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1),964 crc_start);965 966 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG2),967 crc_end);968 969 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG3),970 otg_phy_mux);971 972 /* setDMCUParam_Cmd */973 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,974 CRC_WIN_NOTIFY);975 976 /* notifyDMCUMsg */977 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);978}979 980static void dcn10_stop_crc_win_update(struct dmcu *dmcu,981 struct otg_phy_mux *mux_mapping)982{983 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);984 unsigned int dmcu_max_retry_on_wait_reg_ready = 801;985 unsigned int dmcu_wait_reg_ready_interval = 100;986 unsigned int otg_phy_mux = 0;987 988 /* If microcontroller is not running, do nothing */989 if (dmcu->dmcu_state != DMCU_RUNNING)990 return;991 992 /* waitDMCUReadyForCmd */993 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,994 dmcu_wait_reg_ready_interval,995 dmcu_max_retry_on_wait_reg_ready);996 997 /* build up nitification data */998 otg_phy_mux =999 (((unsigned int) mux_mapping->otg_output_num) << 16) | mux_mapping->phy_output_num;1000 1001 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1),1002 otg_phy_mux);1003 1004 /* setDMCUParam_Cmd */1005 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,1006 CRC_STOP_UPDATE);1007 1008 /* notifyDMCUMsg */1009 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);1010}1011#endif1012 1013static const struct dmcu_funcs dce_funcs = {1014 .dmcu_init = dce_dmcu_init,1015 .load_iram = dce_dmcu_load_iram,1016 .set_psr_enable = dce_dmcu_set_psr_enable,1017 .setup_psr = dce_dmcu_setup_psr,1018 .get_psr_state = dce_get_dmcu_psr_state,1019 .set_psr_wait_loop = dce_psr_wait_loop,1020 .get_psr_wait_loop = dce_get_psr_wait_loop,1021 .is_dmcu_initialized = dce_is_dmcu_initialized1022};1023 1024static const struct dmcu_funcs dcn10_funcs = {1025 .dmcu_init = dcn10_dmcu_init,1026 .load_iram = dcn10_dmcu_load_iram,1027 .set_psr_enable = dcn10_dmcu_set_psr_enable,1028 .setup_psr = dcn10_dmcu_setup_psr,1029 .get_psr_state = dcn10_get_dmcu_psr_state,1030 .set_psr_wait_loop = dcn10_psr_wait_loop,1031 .get_psr_wait_loop = dcn10_get_psr_wait_loop,1032 .send_edid_cea = dcn10_send_edid_cea,1033 .recv_amd_vsdb = dcn10_recv_amd_vsdb,1034 .recv_edid_cea_ack = dcn10_recv_edid_cea_ack,1035#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)1036 .forward_crc_window = dcn10_forward_crc_window,1037 .stop_crc_win_update = dcn10_stop_crc_win_update,1038#endif1039 .is_dmcu_initialized = dcn10_is_dmcu_initialized1040};1041 1042static const struct dmcu_funcs dcn20_funcs = {1043 .dmcu_init = dcn10_dmcu_init,1044 .load_iram = dcn10_dmcu_load_iram,1045 .set_psr_enable = dcn10_dmcu_set_psr_enable,1046 .setup_psr = dcn10_dmcu_setup_psr,1047 .get_psr_state = dcn10_get_dmcu_psr_state,1048 .set_psr_wait_loop = dcn10_psr_wait_loop,1049 .get_psr_wait_loop = dcn10_get_psr_wait_loop,1050 .is_dmcu_initialized = dcn10_is_dmcu_initialized,1051 .lock_phy = dcn20_lock_phy,1052 .unlock_phy = dcn20_unlock_phy1053};1054 1055static const struct dmcu_funcs dcn21_funcs = {1056 .dmcu_init = dcn21_dmcu_init,1057 .load_iram = dcn10_dmcu_load_iram,1058 .set_psr_enable = dcn10_dmcu_set_psr_enable,1059 .setup_psr = dcn10_dmcu_setup_psr,1060 .get_psr_state = dcn10_get_dmcu_psr_state,1061 .set_psr_wait_loop = dcn10_psr_wait_loop,1062 .get_psr_wait_loop = dcn10_get_psr_wait_loop,1063 .is_dmcu_initialized = dcn10_is_dmcu_initialized,1064 .lock_phy = dcn20_lock_phy,1065 .unlock_phy = dcn20_unlock_phy1066};1067 1068static void dce_dmcu_construct(1069 struct dce_dmcu *dmcu_dce,1070 struct dc_context *ctx,1071 const struct dce_dmcu_registers *regs,1072 const struct dce_dmcu_shift *dmcu_shift,1073 const struct dce_dmcu_mask *dmcu_mask)1074{1075 struct dmcu *base = &dmcu_dce->base;1076 1077 base->ctx = ctx;1078 base->funcs = &dce_funcs;1079 base->cached_wait_loop_number = 0;1080 1081 dmcu_dce->regs = regs;1082 dmcu_dce->dmcu_shift = dmcu_shift;1083 dmcu_dce->dmcu_mask = dmcu_mask;1084}1085 1086static void dcn21_dmcu_construct(1087 struct dce_dmcu *dmcu_dce,1088 struct dc_context *ctx,1089 const struct dce_dmcu_registers *regs,1090 const struct dce_dmcu_shift *dmcu_shift,1091 const struct dce_dmcu_mask *dmcu_mask)1092{1093 uint32_t psp_version = 0;1094 1095 dce_dmcu_construct(dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);1096 1097 psp_version = dm_read_reg(ctx, mmMP0_SMN_C2PMSG_58);1098 dmcu_dce->base.auto_load_dmcu = ((psp_version & 0x00FF00FF) > 0x00110029);1099 dmcu_dce->base.psp_version = psp_version;1100}1101 1102struct dmcu *dce_dmcu_create(1103 struct dc_context *ctx,1104 const struct dce_dmcu_registers *regs,1105 const struct dce_dmcu_shift *dmcu_shift,1106 const struct dce_dmcu_mask *dmcu_mask)1107{1108 struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL);1109 1110 if (dmcu_dce == NULL) {1111 BREAK_TO_DEBUGGER();1112 return NULL;1113 }1114 1115 dce_dmcu_construct(1116 dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);1117 1118 dmcu_dce->base.funcs = &dce_funcs;1119 1120 return &dmcu_dce->base;1121}1122 1123struct dmcu *dcn10_dmcu_create(1124 struct dc_context *ctx,1125 const struct dce_dmcu_registers *regs,1126 const struct dce_dmcu_shift *dmcu_shift,1127 const struct dce_dmcu_mask *dmcu_mask)1128{1129 struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);1130 1131 if (dmcu_dce == NULL) {1132 BREAK_TO_DEBUGGER();1133 return NULL;1134 }1135 1136 dce_dmcu_construct(1137 dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);1138 1139 dmcu_dce->base.funcs = &dcn10_funcs;1140 1141 return &dmcu_dce->base;1142}1143 1144struct dmcu *dcn20_dmcu_create(1145 struct dc_context *ctx,1146 const struct dce_dmcu_registers *regs,1147 const struct dce_dmcu_shift *dmcu_shift,1148 const struct dce_dmcu_mask *dmcu_mask)1149{1150 struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);1151 1152 if (dmcu_dce == NULL) {1153 BREAK_TO_DEBUGGER();1154 return NULL;1155 }1156 1157 dce_dmcu_construct(1158 dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);1159 1160 dmcu_dce->base.funcs = &dcn20_funcs;1161 1162 return &dmcu_dce->base;1163}1164 1165struct dmcu *dcn21_dmcu_create(1166 struct dc_context *ctx,1167 const struct dce_dmcu_registers *regs,1168 const struct dce_dmcu_shift *dmcu_shift,1169 const struct dce_dmcu_mask *dmcu_mask)1170{1171 struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);1172 1173 if (dmcu_dce == NULL) {1174 BREAK_TO_DEBUGGER();1175 return NULL;1176 }1177 1178 dcn21_dmcu_construct(1179 dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);1180 1181 dmcu_dce->base.funcs = &dcn21_funcs;1182 1183 return &dmcu_dce->base;1184}1185 1186void dce_dmcu_destroy(struct dmcu **dmcu)1187{1188 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(*dmcu);1189 1190 kfree(dmcu_dce);1191 *dmcu = NULL;1192}1193