577 lines · c
1/*2 * Copyright 2022 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 "../dmub_srv.h"27#include "dc_types.h"28#include "dmub_reg.h"29#include "dmub_dcn35.h"30#include "dc/dc_types.h"31 32#include "dcn/dcn_3_5_0_offset.h"33#include "dcn/dcn_3_5_0_sh_mask.h"34 35#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg]36#define CTX dmub37#define REGS dmub->regs_dcn3538#define REG_OFFSET_EXP(reg_name) BASE(reg##reg_name##_BASE_IDX) + reg##reg_name39 40void dmub_srv_dcn35_regs_init(struct dmub_srv *dmub, struct dc_context *ctx) {41 struct dmub_srv_dcn35_regs *regs = dmub->regs_dcn35;42#define REG_STRUCT regs43 44#define DMUB_SR(reg) REG_STRUCT->offset.reg = REG_OFFSET_EXP(reg);45 DMUB_DCN35_REGS()46 DMCUB_INTERNAL_REGS()47#undef DMUB_SR48 49#define DMUB_SF(reg, field) REG_STRUCT->mask.reg##__##field = FD_MASK(reg, field);50 DMUB_DCN35_FIELDS()51#undef DMUB_SF52 53#define DMUB_SF(reg, field) REG_STRUCT->shift.reg##__##field = FD_SHIFT(reg, field);54 DMUB_DCN35_FIELDS()55#undef DMUB_SF56#undef REG_STRUCT57}58 59static void dmub_dcn35_get_fb_base_offset(struct dmub_srv *dmub,60 uint64_t *fb_base,61 uint64_t *fb_offset)62{63 uint32_t tmp;64 65 /*66 if (dmub->fb_base || dmub->fb_offset) {67 *fb_base = dmub->fb_base;68 *fb_offset = dmub->fb_offset;69 return;70 }71 */72 73 REG_GET(DCN_VM_FB_LOCATION_BASE, FB_BASE, &tmp);74 *fb_base = (uint64_t)tmp << 24;75 76 REG_GET(DCN_VM_FB_OFFSET, FB_OFFSET, &tmp);77 *fb_offset = (uint64_t)tmp << 24;78}79 80static inline void dmub_dcn35_translate_addr(const union dmub_addr *addr_in,81 uint64_t fb_base,82 uint64_t fb_offset,83 union dmub_addr *addr_out)84{85 addr_out->quad_part = addr_in->quad_part - fb_base + fb_offset;86}87 88void dmub_dcn35_reset(struct dmub_srv *dmub)89{90 union dmub_gpint_data_register cmd;91 const uint32_t timeout = 100;92 uint32_t in_reset, is_enabled, scratch, i, pwait_mode;93 94 REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset);95 96 if (in_reset == 0) {97 cmd.bits.status = 1;98 cmd.bits.command_code = DMUB_GPINT__STOP_FW;99 cmd.bits.param = 0;100 101 dmub->hw_funcs.set_gpint(dmub, cmd);102 103 /**104 * Timeout covers both the ACK and the wait105 * for remaining work to finish.106 */107 108 for (i = 0; i < timeout; ++i) {109 if (dmub->hw_funcs.is_gpint_acked(dmub, cmd))110 break;111 112 udelay(1);113 }114 115 for (i = 0; i < timeout; ++i) {116 scratch = dmub->hw_funcs.get_gpint_response(dmub);117 if (scratch == DMUB_GPINT__STOP_FW_RESPONSE)118 break;119 120 udelay(1);121 }122 123 for (i = 0; i < timeout; ++i) {124 REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode);125 if (pwait_mode & (1 << 0))126 break;127 128 udelay(1);129 }130 /* Force reset in case we timed out, DMCUB is likely hung. */131 }132 133 REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enabled);134 135 if (is_enabled) {136 REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);137 REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1);138 REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0);139 }140 141 REG_WRITE(DMCUB_INBOX1_RPTR, 0);142 REG_WRITE(DMCUB_INBOX1_WPTR, 0);143 REG_WRITE(DMCUB_OUTBOX1_RPTR, 0);144 REG_WRITE(DMCUB_OUTBOX1_WPTR, 0);145 REG_WRITE(DMCUB_OUTBOX0_RPTR, 0);146 REG_WRITE(DMCUB_OUTBOX0_WPTR, 0);147 REG_WRITE(DMCUB_SCRATCH0, 0);148 149 /* Clear the GPINT command manually so we don't send anything during boot. */150 cmd.all = 0;151 dmub->hw_funcs.set_gpint(dmub, cmd);152}153 154void dmub_dcn35_reset_release(struct dmub_srv *dmub)155{156 REG_WRITE(DMCUB_SCRATCH15, dmub->psp_version & 0x001100FF);157 158 REG_UPDATE_3(DMU_CLK_CNTL,159 LONO_DISPCLK_GATE_DISABLE, 1,160 LONO_SOCCLK_GATE_DISABLE, 1,161 LONO_DMCUBCLK_GATE_DISABLE, 1);162 163 REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1);164 udelay(1);165 REG_UPDATE_2(DMCUB_CNTL, DMCUB_ENABLE, 1, DMCUB_TRACEPORT_EN, 1);166 REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);167 udelay(1);168 REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 0);169 REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 0);170}171 172void dmub_dcn35_backdoor_load(struct dmub_srv *dmub,173 const struct dmub_window *cw0,174 const struct dmub_window *cw1)175{176 union dmub_addr offset;177 uint64_t fb_base, fb_offset;178 179 dmub_dcn35_get_fb_base_offset(dmub, &fb_base, &fb_offset);180 181 dmub_dcn35_translate_addr(&cw0->offset, fb_base, fb_offset, &offset);182 183 REG_WRITE(DMCUB_REGION3_CW0_OFFSET, offset.u.low_part);184 REG_WRITE(DMCUB_REGION3_CW0_OFFSET_HIGH, offset.u.high_part);185 REG_WRITE(DMCUB_REGION3_CW0_BASE_ADDRESS, cw0->region.base);186 REG_SET_2(DMCUB_REGION3_CW0_TOP_ADDRESS, 0,187 DMCUB_REGION3_CW0_TOP_ADDRESS, cw0->region.top,188 DMCUB_REGION3_CW0_ENABLE, 1);189 190 dmub_dcn35_translate_addr(&cw1->offset, fb_base, fb_offset, &offset);191 192 REG_WRITE(DMCUB_REGION3_CW1_OFFSET, offset.u.low_part);193 REG_WRITE(DMCUB_REGION3_CW1_OFFSET_HIGH, offset.u.high_part);194 REG_WRITE(DMCUB_REGION3_CW1_BASE_ADDRESS, cw1->region.base);195 REG_SET_2(DMCUB_REGION3_CW1_TOP_ADDRESS, 0,196 DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top,197 DMCUB_REGION3_CW1_ENABLE, 1);198 199 /* TODO: Do we need to set DMCUB_MEM_UNIT_ID? */200 REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0);201}202 203void dmub_dcn35_backdoor_load_zfb_mode(struct dmub_srv *dmub,204 const struct dmub_window *cw0,205 const struct dmub_window *cw1)206{207 union dmub_addr offset;208 209 REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1);210 offset = cw0->offset;211 REG_WRITE(DMCUB_REGION3_CW0_OFFSET, offset.u.low_part);212 REG_WRITE(DMCUB_REGION3_CW0_OFFSET_HIGH, offset.u.high_part);213 REG_WRITE(DMCUB_REGION3_CW0_BASE_ADDRESS, cw0->region.base);214 REG_SET_2(DMCUB_REGION3_CW0_TOP_ADDRESS, 0,215 DMCUB_REGION3_CW0_TOP_ADDRESS, cw0->region.top,216 DMCUB_REGION3_CW0_ENABLE, 1);217 offset = cw1->offset;218 REG_WRITE(DMCUB_REGION3_CW1_OFFSET, offset.u.low_part);219 REG_WRITE(DMCUB_REGION3_CW1_OFFSET_HIGH, offset.u.high_part);220 REG_WRITE(DMCUB_REGION3_CW1_BASE_ADDRESS, cw1->region.base);221 REG_SET_2(DMCUB_REGION3_CW1_TOP_ADDRESS, 0,222 DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top,223 DMCUB_REGION3_CW1_ENABLE, 1);224 REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID,225 0x20);226}227void dmub_dcn35_setup_windows(struct dmub_srv *dmub,228 const struct dmub_window *cw2,229 const struct dmub_window *cw3,230 const struct dmub_window *cw4,231 const struct dmub_window *cw5,232 const struct dmub_window *cw6,233 const struct dmub_window *region6)234{235 union dmub_addr offset;236 237 offset = cw3->offset;238 239 REG_WRITE(DMCUB_REGION3_CW3_OFFSET, offset.u.low_part);240 REG_WRITE(DMCUB_REGION3_CW3_OFFSET_HIGH, offset.u.high_part);241 REG_WRITE(DMCUB_REGION3_CW3_BASE_ADDRESS, cw3->region.base);242 REG_SET_2(DMCUB_REGION3_CW3_TOP_ADDRESS, 0,243 DMCUB_REGION3_CW3_TOP_ADDRESS, cw3->region.top,244 DMCUB_REGION3_CW3_ENABLE, 1);245 246 offset = cw4->offset;247 248 REG_WRITE(DMCUB_REGION3_CW4_OFFSET, offset.u.low_part);249 REG_WRITE(DMCUB_REGION3_CW4_OFFSET_HIGH, offset.u.high_part);250 REG_WRITE(DMCUB_REGION3_CW4_BASE_ADDRESS, cw4->region.base);251 REG_SET_2(DMCUB_REGION3_CW4_TOP_ADDRESS, 0,252 DMCUB_REGION3_CW4_TOP_ADDRESS, cw4->region.top,253 DMCUB_REGION3_CW4_ENABLE, 1);254 255 offset = cw5->offset;256 257 REG_WRITE(DMCUB_REGION3_CW5_OFFSET, offset.u.low_part);258 REG_WRITE(DMCUB_REGION3_CW5_OFFSET_HIGH, offset.u.high_part);259 REG_WRITE(DMCUB_REGION3_CW5_BASE_ADDRESS, cw5->region.base);260 REG_SET_2(DMCUB_REGION3_CW5_TOP_ADDRESS, 0,261 DMCUB_REGION3_CW5_TOP_ADDRESS, cw5->region.top,262 DMCUB_REGION3_CW5_ENABLE, 1);263 264 REG_WRITE(DMCUB_REGION5_OFFSET, offset.u.low_part);265 REG_WRITE(DMCUB_REGION5_OFFSET_HIGH, offset.u.high_part);266 REG_SET_2(DMCUB_REGION5_TOP_ADDRESS, 0,267 DMCUB_REGION5_TOP_ADDRESS,268 cw5->region.top - cw5->region.base - 1,269 DMCUB_REGION5_ENABLE, 1);270 271 offset = cw6->offset;272 273 REG_WRITE(DMCUB_REGION3_CW6_OFFSET, offset.u.low_part);274 REG_WRITE(DMCUB_REGION3_CW6_OFFSET_HIGH, offset.u.high_part);275 REG_WRITE(DMCUB_REGION3_CW6_BASE_ADDRESS, cw6->region.base);276 REG_SET_2(DMCUB_REGION3_CW6_TOP_ADDRESS, 0,277 DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top,278 DMCUB_REGION3_CW6_ENABLE, 1);279 280 offset = region6->offset;281 282 REG_WRITE(DMCUB_REGION6_OFFSET, offset.u.low_part);283 REG_WRITE(DMCUB_REGION6_OFFSET_HIGH, offset.u.high_part);284 REG_SET_2(DMCUB_REGION6_TOP_ADDRESS, 0,285 DMCUB_REGION6_TOP_ADDRESS,286 region6->region.top - region6->region.base - 1,287 DMCUB_REGION6_ENABLE, 1);288}289 290void dmub_dcn35_setup_mailbox(struct dmub_srv *dmub,291 const struct dmub_region *inbox1)292{293 REG_WRITE(DMCUB_INBOX1_BASE_ADDRESS, inbox1->base);294 REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);295}296 297uint32_t dmub_dcn35_get_inbox1_wptr(struct dmub_srv *dmub)298{299 return REG_READ(DMCUB_INBOX1_WPTR);300}301 302uint32_t dmub_dcn35_get_inbox1_rptr(struct dmub_srv *dmub)303{304 return REG_READ(DMCUB_INBOX1_RPTR);305}306 307void dmub_dcn35_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset)308{309 REG_WRITE(DMCUB_INBOX1_WPTR, wptr_offset);310}311 312void dmub_dcn35_setup_out_mailbox(struct dmub_srv *dmub,313 const struct dmub_region *outbox1)314{315 REG_WRITE(DMCUB_OUTBOX1_BASE_ADDRESS, outbox1->base);316 REG_WRITE(DMCUB_OUTBOX1_SIZE, outbox1->top - outbox1->base);317}318 319uint32_t dmub_dcn35_get_outbox1_wptr(struct dmub_srv *dmub)320{321 /**322 * outbox1 wptr register is accessed without locks (dal & dc)323 * and to be called only by dmub_srv_stat_get_notification()324 */325 return REG_READ(DMCUB_OUTBOX1_WPTR);326}327 328void dmub_dcn35_set_outbox1_rptr(struct dmub_srv *dmub, uint32_t rptr_offset)329{330 /**331 * outbox1 rptr register is accessed without locks (dal & dc)332 * and to be called only by dmub_srv_stat_get_notification()333 */334 REG_WRITE(DMCUB_OUTBOX1_RPTR, rptr_offset);335}336 337bool dmub_dcn35_is_hw_init(struct dmub_srv *dmub)338{339 union dmub_fw_boot_status status;340 uint32_t is_enable;341 342 status.all = REG_READ(DMCUB_SCRATCH0);343 REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enable);344 345 return is_enable != 0 && status.bits.dal_fw;346}347 348bool dmub_dcn35_is_supported(struct dmub_srv *dmub)349{350 uint32_t supported = 0;351 352 REG_GET(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE, &supported);353 354 return supported;355}356 357void dmub_dcn35_set_gpint(struct dmub_srv *dmub,358 union dmub_gpint_data_register reg)359{360 REG_WRITE(DMCUB_GPINT_DATAIN1, reg.all);361}362 363bool dmub_dcn35_is_gpint_acked(struct dmub_srv *dmub,364 union dmub_gpint_data_register reg)365{366 union dmub_gpint_data_register test;367 368 reg.bits.status = 0;369 test.all = REG_READ(DMCUB_GPINT_DATAIN1);370 371 return test.all == reg.all;372}373 374uint32_t dmub_dcn35_get_gpint_response(struct dmub_srv *dmub)375{376 return REG_READ(DMCUB_SCRATCH7);377}378 379uint32_t dmub_dcn35_get_gpint_dataout(struct dmub_srv *dmub)380{381 uint32_t dataout = REG_READ(DMCUB_GPINT_DATAOUT);382 383 REG_UPDATE(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN, 0);384 385 REG_WRITE(DMCUB_GPINT_DATAOUT, 0);386 REG_UPDATE(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK, 1);387 REG_UPDATE(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK, 0);388 389 REG_UPDATE(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN, 1);390 391 return dataout;392}393 394union dmub_fw_boot_status dmub_dcn35_get_fw_boot_status(struct dmub_srv *dmub)395{396 union dmub_fw_boot_status status;397 398 status.all = REG_READ(DMCUB_SCRATCH0);399 return status;400}401 402union dmub_fw_boot_options dmub_dcn35_get_fw_boot_option(struct dmub_srv *dmub)403{404 union dmub_fw_boot_options option;405 406 option.all = REG_READ(DMCUB_SCRATCH14);407 return option;408}409 410void dmub_dcn35_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmub_srv_hw_params *params)411{412 union dmub_fw_boot_options boot_options = {0};413 union dmub_fw_boot_options cur_boot_options = {0};414 415 cur_boot_options = dmub_dcn35_get_fw_boot_option(dmub);416 417 boot_options.bits.z10_disable = params->disable_z10;418 boot_options.bits.dpia_supported = params->dpia_supported;419 boot_options.bits.enable_dpia = cur_boot_options.bits.enable_dpia && !params->disable_dpia;420 boot_options.bits.usb4_cm_version = params->usb4_cm_version;421 boot_options.bits.dpia_hpd_int_enable_supported = params->dpia_hpd_int_enable_supported;422 boot_options.bits.power_optimization = params->power_optimization;423 boot_options.bits.disable_clk_ds = params->disallow_dispclk_dppclk_ds;424 boot_options.bits.disable_clk_gate = params->disable_clock_gate;425 boot_options.bits.ips_disable = params->disable_ips;426 boot_options.bits.ips_sequential_ono = params->ips_sequential_ono;427 boot_options.bits.disable_sldo_opt = params->disable_sldo_opt;428 boot_options.bits.enable_non_transparent_setconfig = params->enable_non_transparent_setconfig;429 430 REG_WRITE(DMCUB_SCRATCH14, boot_options.all);431}432 433void dmub_dcn35_skip_dmub_panel_power_sequence(struct dmub_srv *dmub, bool skip)434{435 union dmub_fw_boot_options boot_options;436 boot_options.all = REG_READ(DMCUB_SCRATCH14);437 boot_options.bits.skip_phy_init_panel_sequence = skip;438 REG_WRITE(DMCUB_SCRATCH14, boot_options.all);439}440 441void dmub_dcn35_setup_outbox0(struct dmub_srv *dmub,442 const struct dmub_region *outbox0)443{444 REG_WRITE(DMCUB_OUTBOX0_BASE_ADDRESS, outbox0->base);445 446 REG_WRITE(DMCUB_OUTBOX0_SIZE, outbox0->top - outbox0->base);447}448 449uint32_t dmub_dcn35_get_outbox0_wptr(struct dmub_srv *dmub)450{451 return REG_READ(DMCUB_OUTBOX0_WPTR);452}453 454void dmub_dcn35_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset)455{456 REG_WRITE(DMCUB_OUTBOX0_RPTR, rptr_offset);457}458 459uint32_t dmub_dcn35_get_current_time(struct dmub_srv *dmub)460{461 return REG_READ(DMCUB_TIMER_CURRENT);462}463 464void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data)465{466 uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset;467 uint32_t is_traceport_enabled, is_cw6_enabled;468 469 if (!dmub || !diag_data)470 return;471 472 memset(diag_data, 0, sizeof(*diag_data));473 474 diag_data->dmcub_version = dmub->fw_version;475 476 diag_data->scratch[0] = REG_READ(DMCUB_SCRATCH0);477 diag_data->scratch[1] = REG_READ(DMCUB_SCRATCH1);478 diag_data->scratch[2] = REG_READ(DMCUB_SCRATCH2);479 diag_data->scratch[3] = REG_READ(DMCUB_SCRATCH3);480 diag_data->scratch[4] = REG_READ(DMCUB_SCRATCH4);481 diag_data->scratch[5] = REG_READ(DMCUB_SCRATCH5);482 diag_data->scratch[6] = REG_READ(DMCUB_SCRATCH6);483 diag_data->scratch[7] = REG_READ(DMCUB_SCRATCH7);484 diag_data->scratch[8] = REG_READ(DMCUB_SCRATCH8);485 diag_data->scratch[9] = REG_READ(DMCUB_SCRATCH9);486 diag_data->scratch[10] = REG_READ(DMCUB_SCRATCH10);487 diag_data->scratch[11] = REG_READ(DMCUB_SCRATCH11);488 diag_data->scratch[12] = REG_READ(DMCUB_SCRATCH12);489 diag_data->scratch[13] = REG_READ(DMCUB_SCRATCH13);490 diag_data->scratch[14] = REG_READ(DMCUB_SCRATCH14);491 diag_data->scratch[15] = REG_READ(DMCUB_SCRATCH15);492 diag_data->scratch[16] = REG_READ(DMCUB_SCRATCH16);493 494 diag_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR);495 diag_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR);496 diag_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR);497 498 diag_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR);499 diag_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR);500 diag_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE);501 502 diag_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR);503 diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR);504 diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE);505 506 diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR);507 diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR);508 diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE);509 510 REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled);511 diag_data->is_dmcub_enabled = is_dmub_enabled;512 513 REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset);514 diag_data->is_dmcub_soft_reset = is_soft_reset;515 516 REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset);517 diag_data->is_dmcub_secure_reset = is_sec_reset;518 519 REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled);520 diag_data->is_traceport_en = is_traceport_enabled;521 522 REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled);523 diag_data->is_cw6_enabled = is_cw6_enabled;524 525 diag_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0);526 diag_data->timeout_info = dmub->debug;527}528void dmub_dcn35_configure_dmub_in_system_memory(struct dmub_srv *dmub)529{530 /* DMCUB_REGION3_TMR_AXI_SPACE values:531 * 0b011 (0x3) - FB physical address532 * 0b100 (0x4) - GPU virtual address533 *534 * Default value is 0x3 (FB Physical address for TMR). When programming535 * DMUB to be in system memory, change to 0x4. The system memory allocated536 * is accessible by both GPU and CPU, so we use GPU virtual address.537 */538 REG_WRITE(DMCUB_REGION3_TMR_AXI_SPACE, 0x4);539}540 541bool dmub_dcn35_should_detect(struct dmub_srv *dmub)542{543 uint32_t fw_boot_status = REG_READ(DMCUB_SCRATCH0);544 bool should_detect = (fw_boot_status & DMUB_FW_BOOT_STATUS_BIT_DETECTION_REQUIRED) != 0;545 return should_detect;546}547 548void dmub_dcn35_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data)549{550 REG_WRITE(DMCUB_INBOX0_WPTR, data.inbox0_cmd_common.all);551}552 553void dmub_dcn35_clear_inbox0_ack_register(struct dmub_srv *dmub)554{555 REG_WRITE(DMCUB_SCRATCH17, 0);556}557 558uint32_t dmub_dcn35_read_inbox0_ack_register(struct dmub_srv *dmub)559{560 return REG_READ(DMCUB_SCRATCH17);561}562 563bool dmub_dcn35_is_hw_powered_up(struct dmub_srv *dmub)564{565 union dmub_fw_boot_status status;566 uint32_t is_enable;567 568 REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enable);569 if (is_enable == 0)570 return false;571 572 status.all = REG_READ(DMCUB_SCRATCH0);573 574 return (status.bits.dal_fw && status.bits.hw_power_init_done && status.bits.mailbox_rdy) ||575 (!status.bits.dal_fw && status.bits.mailbox_rdy);576}577