1*7f7d7ea1SAurabindo Pillai // SPDX-License-Identifier: MIT 2*7f7d7ea1SAurabindo Pillai 3*7f7d7ea1SAurabindo Pillai /* Copyright 2025 Advanced Micro Devices, Inc. */ 4*7f7d7ea1SAurabindo Pillai 5*7f7d7ea1SAurabindo Pillai #include "../dmub_srv.h" 6*7f7d7ea1SAurabindo Pillai #include "dmub_reg.h" 7*7f7d7ea1SAurabindo Pillai #include "dmub_dcn60.h" 8*7f7d7ea1SAurabindo Pillai 9*7f7d7ea1SAurabindo Pillai #include "dcn/dcn_6_0_0_offset.h" 10*7f7d7ea1SAurabindo Pillai #include "dcn/dcn_6_0_0_sh_mask.h" 11*7f7d7ea1SAurabindo Pillai #include "mmhub/mmhub_5_0_1_offset.h" 12*7f7d7ea1SAurabindo Pillai #include "mmhub/mmhub_5_0_1_sh_mask.h" 13*7f7d7ea1SAurabindo Pillai 14*7f7d7ea1SAurabindo Pillai #define DCN_BASE__INST0_SEG2 0x000034C0 15*7f7d7ea1SAurabindo Pillai #define MMHUB_BASE__INST0_SEG1 0x0001A000 16*7f7d7ea1SAurabindo Pillai 17*7f7d7ea1SAurabindo Pillai #define BASE_INNER(seg) DCN_BASE__INST0_SEG##seg 18*7f7d7ea1SAurabindo Pillai #define CTX dmub 19*7f7d7ea1SAurabindo Pillai #define REGS dmub->regs_dcn60 20*7f7d7ea1SAurabindo Pillai #define REG_OFFSET_EXP(reg_name) (BASE(reg##reg_name##_BASE_IDX) + reg##reg_name) 21*7f7d7ea1SAurabindo Pillai #define EXT_REG_READ(addr) dmub->funcs.reg_read(dmub->user_ctx, addr); 22*7f7d7ea1SAurabindo Pillai #define DAGB0_WRCLI_OSD_PENDING 0x1A083 23*7f7d7ea1SAurabindo Pillai 24*7f7d7ea1SAurabindo Pillai #define MMHUB_BASE_INNER(seg) MMHUB_BASE__INST0_SEG##seg 25*7f7d7ea1SAurabindo Pillai #define MMHUB_BASE(seg) MMHUB_BASE_INNER(seg) 26*7f7d7ea1SAurabindo Pillai #define MMHUB_REG_OFFSET(reg_name) (MMHUB_BASE(reg##reg_name##_BASE_IDX) + reg##reg_name) 27*7f7d7ea1SAurabindo Pillai 28*7f7d7ea1SAurabindo Pillai const struct dmub_srv_dcn60_regs dmub_srv_dcn60_regs = { 29*7f7d7ea1SAurabindo Pillai #define DMUB_SR(reg) .reg = REG_OFFSET_EXP(reg), 30*7f7d7ea1SAurabindo Pillai #define MMHUB_SR(reg) .reg = MMHUB_REG_OFFSET(reg), 31*7f7d7ea1SAurabindo Pillai .offset = { 32*7f7d7ea1SAurabindo Pillai DMUB_DCN60_REGS() 33*7f7d7ea1SAurabindo Pillai DMCUB_INTERNAL_REGS() 34*7f7d7ea1SAurabindo Pillai DCN60_EXTERNAL_MMHUB_REGS() 35*7f7d7ea1SAurabindo Pillai }, 36*7f7d7ea1SAurabindo Pillai #undef MMHUB_SR 37*7f7d7ea1SAurabindo Pillai #undef DMUB_SR 38*7f7d7ea1SAurabindo Pillai 39*7f7d7ea1SAurabindo Pillai #define DMUB_SF(reg, field) .reg##__##field = FD_MASK(reg, field), 40*7f7d7ea1SAurabindo Pillai .mask = { 41*7f7d7ea1SAurabindo Pillai DMUB_DCN60_FIELDS() 42*7f7d7ea1SAurabindo Pillai DCN60_EXTERNAL_MMHUB_FIELDS() 43*7f7d7ea1SAurabindo Pillai }, 44*7f7d7ea1SAurabindo Pillai #undef DMUB_SF 45*7f7d7ea1SAurabindo Pillai 46*7f7d7ea1SAurabindo Pillai #define DMUB_SF(reg, field) .reg##__##field = FD_SHIFT(reg, field), 47*7f7d7ea1SAurabindo Pillai .shift = { 48*7f7d7ea1SAurabindo Pillai DMUB_DCN60_FIELDS() 49*7f7d7ea1SAurabindo Pillai DCN60_EXTERNAL_MMHUB_FIELDS() 50*7f7d7ea1SAurabindo Pillai }, 51*7f7d7ea1SAurabindo Pillai #undef DMUB_SF 52*7f7d7ea1SAurabindo Pillai }; 53*7f7d7ea1SAurabindo Pillai 54*7f7d7ea1SAurabindo Pillai static void dmub_dcn60_get_fb_base_offset(struct dmub_srv *dmub, 55*7f7d7ea1SAurabindo Pillai uint64_t *fb_base, 56*7f7d7ea1SAurabindo Pillai uint64_t *fb_offset) 57*7f7d7ea1SAurabindo Pillai { 58*7f7d7ea1SAurabindo Pillai uint32_t tmp_fb_base, tmp_fb_offset; 59*7f7d7ea1SAurabindo Pillai 60*7f7d7ea1SAurabindo Pillai /* 61*7f7d7ea1SAurabindo Pillai * Favor override values from DM. 62*7f7d7ea1SAurabindo Pillai * This can handle multi device systems with shared memory space. 63*7f7d7ea1SAurabindo Pillai */ 64*7f7d7ea1SAurabindo Pillai if (dmub->soc_fb_info.fb_base || dmub->soc_fb_info.fb_offset) { 65*7f7d7ea1SAurabindo Pillai *fb_base = dmub->soc_fb_info.fb_base; 66*7f7d7ea1SAurabindo Pillai *fb_offset = dmub->soc_fb_info.fb_offset; 67*7f7d7ea1SAurabindo Pillai return; 68*7f7d7ea1SAurabindo Pillai } 69*7f7d7ea1SAurabindo Pillai 70*7f7d7ea1SAurabindo Pillai /* 71*7f7d7ea1SAurabindo Pillai * For DCN only environments prefer DCN local registers first. 72*7f7d7ea1SAurabindo Pillai * These should be a copy of the MMHUB registers below for single device systems. 73*7f7d7ea1SAurabindo Pillai */ 74*7f7d7ea1SAurabindo Pillai REG_GET(DCN_VM_FB_LOCATION_BASE, FB_BASE, &tmp_fb_base); 75*7f7d7ea1SAurabindo Pillai REG_GET(DCN_VM_FB_OFFSET, FB_OFFSET, &tmp_fb_offset); 76*7f7d7ea1SAurabindo Pillai 77*7f7d7ea1SAurabindo Pillai if (!dmub->no_ext_reg_access && tmp_fb_base == 0 && tmp_fb_offset == 0) { 78*7f7d7ea1SAurabindo Pillai /* 79*7f7d7ea1SAurabindo Pillai * Memory translation is handled by MMHUB for DMU. 80*7f7d7ea1SAurabindo Pillai * Use these as a fallback if DCN is not configured. 81*7f7d7ea1SAurabindo Pillai */ 82*7f7d7ea1SAurabindo Pillai REG_GET(MMMC_VM_FB_LOCATION_BASE, FB_BASE, &tmp_fb_base); 83*7f7d7ea1SAurabindo Pillai REG_GET(MMMC_VM_FB_OFFSET, FB_OFFSET, &tmp_fb_offset); 84*7f7d7ea1SAurabindo Pillai } 85*7f7d7ea1SAurabindo Pillai 86*7f7d7ea1SAurabindo Pillai *fb_base = (uint64_t)tmp_fb_base << 24; 87*7f7d7ea1SAurabindo Pillai *fb_offset = (uint64_t)tmp_fb_offset << 24; 88*7f7d7ea1SAurabindo Pillai } 89*7f7d7ea1SAurabindo Pillai 90*7f7d7ea1SAurabindo Pillai static inline void dmub_dcn60_translate_addr(const union dmub_addr *addr_in, 91*7f7d7ea1SAurabindo Pillai uint64_t fb_base, 92*7f7d7ea1SAurabindo Pillai uint64_t fb_offset, 93*7f7d7ea1SAurabindo Pillai union dmub_addr *addr_out) 94*7f7d7ea1SAurabindo Pillai { 95*7f7d7ea1SAurabindo Pillai addr_out->quad_part = addr_in->quad_part - fb_base + fb_offset; 96*7f7d7ea1SAurabindo Pillai } 97*7f7d7ea1SAurabindo Pillai 98*7f7d7ea1SAurabindo Pillai void dmub_dcn60_reset(struct dmub_srv *dmub) 99*7f7d7ea1SAurabindo Pillai { 100*7f7d7ea1SAurabindo Pillai union dmub_gpint_data_register cmd; 101*7f7d7ea1SAurabindo Pillai const uint32_t timeout_us = 1 * 1000 * 1000; //1s 102*7f7d7ea1SAurabindo Pillai const uint32_t poll_delay_us = 1; //1us 103*7f7d7ea1SAurabindo Pillai uint32_t i = 0; 104*7f7d7ea1SAurabindo Pillai uint32_t enabled, in_reset, scratch, pwait_mode, outstanding_req;; 105*7f7d7ea1SAurabindo Pillai 106*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_CNTL, 107*7f7d7ea1SAurabindo Pillai DMCUB_ENABLE, &enabled); 108*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_CNTL2, 109*7f7d7ea1SAurabindo Pillai DMCUB_SOFT_RESET, &in_reset); 110*7f7d7ea1SAurabindo Pillai 111*7f7d7ea1SAurabindo Pillai if (enabled && in_reset == 0) { 112*7f7d7ea1SAurabindo Pillai cmd.bits.status = 1; 113*7f7d7ea1SAurabindo Pillai cmd.bits.command_code = DMUB_GPINT__STOP_FW; 114*7f7d7ea1SAurabindo Pillai cmd.bits.param = 0; 115*7f7d7ea1SAurabindo Pillai 116*7f7d7ea1SAurabindo Pillai dmub->hw_funcs.set_gpint(dmub, cmd); 117*7f7d7ea1SAurabindo Pillai 118*7f7d7ea1SAurabindo Pillai for (; i < timeout_us; i++) { 119*7f7d7ea1SAurabindo Pillai scratch = REG_READ(DMCUB_SCRATCH7); 120*7f7d7ea1SAurabindo Pillai if (scratch == DMUB_GPINT__STOP_FW_RESPONSE) 121*7f7d7ea1SAurabindo Pillai break; 122*7f7d7ea1SAurabindo Pillai 123*7f7d7ea1SAurabindo Pillai udelay(poll_delay_us); 124*7f7d7ea1SAurabindo Pillai } 125*7f7d7ea1SAurabindo Pillai 126*7f7d7ea1SAurabindo Pillai for (; i < timeout_us; i++) { 127*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode); 128*7f7d7ea1SAurabindo Pillai if (pwait_mode & (1 << 0)) 129*7f7d7ea1SAurabindo Pillai break; 130*7f7d7ea1SAurabindo Pillai 131*7f7d7ea1SAurabindo Pillai udelay(poll_delay_us); 132*7f7d7ea1SAurabindo Pillai } 133*7f7d7ea1SAurabindo Pillai 134*7f7d7ea1SAurabindo Pillai if (!dmub->no_ext_reg_access) { 135*7f7d7ea1SAurabindo Pillai for (; i < timeout_us; i++) { 136*7f7d7ea1SAurabindo Pillai outstanding_req = EXT_REG_READ(DAGB0_WRCLI_OSD_PENDING); 137*7f7d7ea1SAurabindo Pillai if (!(outstanding_req & 0x10)) 138*7f7d7ea1SAurabindo Pillai break; 139*7f7d7ea1SAurabindo Pillai 140*7f7d7ea1SAurabindo Pillai udelay(poll_delay_us); 141*7f7d7ea1SAurabindo Pillai } 142*7f7d7ea1SAurabindo Pillai } 143*7f7d7ea1SAurabindo Pillai } 144*7f7d7ea1SAurabindo Pillai 145*7f7d7ea1SAurabindo Pillai if (enabled) { 146*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1); 147*7f7d7ea1SAurabindo Pillai udelay(1); 148*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); 149*7f7d7ea1SAurabindo Pillai } 150*7f7d7ea1SAurabindo Pillai 151*7f7d7ea1SAurabindo Pillai if (i >= timeout_us) { 152*7f7d7ea1SAurabindo Pillai /* timeout should never occur */ 153*7f7d7ea1SAurabindo Pillai BREAK_TO_DEBUGGER(); 154*7f7d7ea1SAurabindo Pillai } 155*7f7d7ea1SAurabindo Pillai 156*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_REGION3_CW2_TOP_ADDRESS, DMCUB_REGION3_CW2_ENABLE, 0); 157*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_REGION3_CW3_TOP_ADDRESS, DMCUB_REGION3_CW3_ENABLE, 0); 158*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_REGION3_CW4_TOP_ADDRESS, DMCUB_REGION3_CW4_ENABLE, 0); 159*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_REGION3_CW5_TOP_ADDRESS, DMCUB_REGION3_CW5_ENABLE, 0); 160*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, 0); 161*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_REGION3_CW7_TOP_ADDRESS, DMCUB_REGION3_CW7_ENABLE, 0); 162*7f7d7ea1SAurabindo Pillai 163*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_INBOX1_RPTR, 0); 164*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_INBOX1_WPTR, 0); 165*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); 166*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX1_WPTR, 0); 167*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX0_RPTR, 0); 168*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX0_WPTR, 0); 169*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_SCRATCH0, 0); 170*7f7d7ea1SAurabindo Pillai 171*7f7d7ea1SAurabindo Pillai /* Clear the GPINT command manually so we don't reset again. */ 172*7f7d7ea1SAurabindo Pillai cmd.all = 0; 173*7f7d7ea1SAurabindo Pillai dmub->hw_funcs.set_gpint(dmub, cmd); 174*7f7d7ea1SAurabindo Pillai } 175*7f7d7ea1SAurabindo Pillai 176*7f7d7ea1SAurabindo Pillai void dmub_dcn60_reset_release(struct dmub_srv *dmub) 177*7f7d7ea1SAurabindo Pillai { 178*7f7d7ea1SAurabindo Pillai REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 0); 179*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_SCRATCH15, dmub->psp_version & 0x001100FF); 180*7f7d7ea1SAurabindo Pillai REG_UPDATE_2(DMCUB_CNTL, DMCUB_ENABLE, 1, DMCUB_TRACEPORT_EN, 1); 181*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 0); 182*7f7d7ea1SAurabindo Pillai } 183*7f7d7ea1SAurabindo Pillai 184*7f7d7ea1SAurabindo Pillai void dmub_dcn60_backdoor_load(struct dmub_srv *dmub, 185*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw0, 186*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw1) 187*7f7d7ea1SAurabindo Pillai { 188*7f7d7ea1SAurabindo Pillai union dmub_addr offset; 189*7f7d7ea1SAurabindo Pillai uint64_t fb_base, fb_offset; 190*7f7d7ea1SAurabindo Pillai 191*7f7d7ea1SAurabindo Pillai dmub_dcn60_get_fb_base_offset(dmub, &fb_base, &fb_offset); 192*7f7d7ea1SAurabindo Pillai 193*7f7d7ea1SAurabindo Pillai /* reset and disable DMCUB and MMHUBBUB DMUIF */ 194*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1); 195*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); 196*7f7d7ea1SAurabindo Pillai 197*7f7d7ea1SAurabindo Pillai dmub_dcn60_translate_addr(&cw0->offset, fb_base, fb_offset, &offset); 198*7f7d7ea1SAurabindo Pillai 199*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW0_OFFSET, offset.u.low_part); 200*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW0_OFFSET_HIGH, offset.u.high_part); 201*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW0_BASE_ADDRESS, cw0->region.base); 202*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION3_CW0_TOP_ADDRESS, 0, 203*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW0_TOP_ADDRESS, cw0->region.top, 204*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW0_ENABLE, 1); 205*7f7d7ea1SAurabindo Pillai 206*7f7d7ea1SAurabindo Pillai dmub_dcn60_translate_addr(&cw1->offset, fb_base, fb_offset, &offset); 207*7f7d7ea1SAurabindo Pillai 208*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW1_OFFSET, offset.u.low_part); 209*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW1_OFFSET_HIGH, offset.u.high_part); 210*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW1_BASE_ADDRESS, cw1->region.base); 211*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION3_CW1_TOP_ADDRESS, 0, 212*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top, 213*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW1_ENABLE, 1); 214*7f7d7ea1SAurabindo Pillai 215*7f7d7ea1SAurabindo Pillai /* release DMCUB reset only to prevent premature execution */ 216*7f7d7ea1SAurabindo Pillai REG_UPDATE_3(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, 217*7f7d7ea1SAurabindo Pillai DMCUB_MEM_SEC_LVL, 0x2, 218*7f7d7ea1SAurabindo Pillai DMCUB_MEM_UNIT_ID, 0x20); 219*7f7d7ea1SAurabindo Pillai } 220*7f7d7ea1SAurabindo Pillai 221*7f7d7ea1SAurabindo Pillai void dmub_dcn60_backdoor_load_zfb_mode(struct dmub_srv *dmub, 222*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw0, 223*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw1) 224*7f7d7ea1SAurabindo Pillai { 225*7f7d7ea1SAurabindo Pillai union dmub_addr offset; 226*7f7d7ea1SAurabindo Pillai 227*7f7d7ea1SAurabindo Pillai /* reset and disable DMCUB and MMHUBBUB DMUIF */ 228*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1); 229*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); 230*7f7d7ea1SAurabindo Pillai 231*7f7d7ea1SAurabindo Pillai offset = cw0->offset; 232*7f7d7ea1SAurabindo Pillai 233*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW0_OFFSET, offset.u.low_part); 234*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW0_OFFSET_HIGH, offset.u.high_part); 235*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW0_BASE_ADDRESS, cw0->region.base); 236*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION3_CW0_TOP_ADDRESS, 0, 237*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW0_TOP_ADDRESS, cw0->region.top, 238*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW0_ENABLE, 1); 239*7f7d7ea1SAurabindo Pillai 240*7f7d7ea1SAurabindo Pillai offset = cw1->offset; 241*7f7d7ea1SAurabindo Pillai 242*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW1_OFFSET, offset.u.low_part); 243*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW1_OFFSET_HIGH, offset.u.high_part); 244*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW1_BASE_ADDRESS, cw1->region.base); 245*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION3_CW1_TOP_ADDRESS, 0, 246*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top, 247*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW1_ENABLE, 1); 248*7f7d7ea1SAurabindo Pillai 249*7f7d7ea1SAurabindo Pillai /* release DMCUB reset only to prevent premature execution */ 250*7f7d7ea1SAurabindo Pillai REG_UPDATE_3(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, 251*7f7d7ea1SAurabindo Pillai DMCUB_MEM_SEC_LVL, 0x2, 252*7f7d7ea1SAurabindo Pillai DMCUB_MEM_UNIT_ID, 0x20); 253*7f7d7ea1SAurabindo Pillai } 254*7f7d7ea1SAurabindo Pillai 255*7f7d7ea1SAurabindo Pillai void dmub_dcn60_setup_windows(struct dmub_srv *dmub, 256*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw2, 257*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw3, 258*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw4, 259*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw5, 260*7f7d7ea1SAurabindo Pillai const struct dmub_window *cw6, 261*7f7d7ea1SAurabindo Pillai const struct dmub_window *region6) 262*7f7d7ea1SAurabindo Pillai { 263*7f7d7ea1SAurabindo Pillai (void)cw2; 264*7f7d7ea1SAurabindo Pillai union dmub_addr offset; 265*7f7d7ea1SAurabindo Pillai 266*7f7d7ea1SAurabindo Pillai offset = cw3->offset; 267*7f7d7ea1SAurabindo Pillai 268*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW3_OFFSET, offset.u.low_part); 269*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW3_OFFSET_HIGH, offset.u.high_part); 270*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW3_BASE_ADDRESS, cw3->region.base); 271*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION3_CW3_TOP_ADDRESS, 0, 272*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW3_TOP_ADDRESS, cw3->region.top, 273*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW3_ENABLE, 1); 274*7f7d7ea1SAurabindo Pillai 275*7f7d7ea1SAurabindo Pillai offset = cw4->offset; 276*7f7d7ea1SAurabindo Pillai 277*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW4_OFFSET, offset.u.low_part); 278*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW4_OFFSET_HIGH, offset.u.high_part); 279*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW4_BASE_ADDRESS, cw4->region.base); 280*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION3_CW4_TOP_ADDRESS, 0, 281*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW4_TOP_ADDRESS, cw4->region.top, 282*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW4_ENABLE, 1); 283*7f7d7ea1SAurabindo Pillai 284*7f7d7ea1SAurabindo Pillai offset = cw5->offset; 285*7f7d7ea1SAurabindo Pillai 286*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW5_OFFSET, offset.u.low_part); 287*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW5_OFFSET_HIGH, offset.u.high_part); 288*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW5_BASE_ADDRESS, cw5->region.base); 289*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION3_CW5_TOP_ADDRESS, 0, 290*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW5_TOP_ADDRESS, cw5->region.top, 291*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW5_ENABLE, 1); 292*7f7d7ea1SAurabindo Pillai 293*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION5_OFFSET, offset.u.low_part); 294*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION5_OFFSET_HIGH, offset.u.high_part); 295*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION5_TOP_ADDRESS, 0, 296*7f7d7ea1SAurabindo Pillai DMCUB_REGION5_TOP_ADDRESS, 297*7f7d7ea1SAurabindo Pillai cw5->region.top - cw5->region.base - 1, 298*7f7d7ea1SAurabindo Pillai DMCUB_REGION5_ENABLE, 1); 299*7f7d7ea1SAurabindo Pillai 300*7f7d7ea1SAurabindo Pillai offset = cw6->offset; 301*7f7d7ea1SAurabindo Pillai 302*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW6_OFFSET, offset.u.low_part); 303*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW6_OFFSET_HIGH, offset.u.high_part); 304*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_CW6_BASE_ADDRESS, cw6->region.base); 305*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION3_CW6_TOP_ADDRESS, 0, 306*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top, 307*7f7d7ea1SAurabindo Pillai DMCUB_REGION3_CW6_ENABLE, 1); 308*7f7d7ea1SAurabindo Pillai 309*7f7d7ea1SAurabindo Pillai offset = region6->offset; 310*7f7d7ea1SAurabindo Pillai 311*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION6_OFFSET, offset.u.low_part); 312*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION6_OFFSET_HIGH, offset.u.high_part); 313*7f7d7ea1SAurabindo Pillai REG_SET_2(DMCUB_REGION6_TOP_ADDRESS, 0, 314*7f7d7ea1SAurabindo Pillai DMCUB_REGION6_TOP_ADDRESS, 315*7f7d7ea1SAurabindo Pillai region6->region.top - region6->region.base - 1, 316*7f7d7ea1SAurabindo Pillai DMCUB_REGION6_ENABLE, 1); 317*7f7d7ea1SAurabindo Pillai } 318*7f7d7ea1SAurabindo Pillai 319*7f7d7ea1SAurabindo Pillai void dmub_dcn60_setup_mailbox(struct dmub_srv *dmub, 320*7f7d7ea1SAurabindo Pillai const struct dmub_region *inbox1) 321*7f7d7ea1SAurabindo Pillai { 322*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_INBOX1_BASE_ADDRESS, inbox1->base); 323*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base); 324*7f7d7ea1SAurabindo Pillai } 325*7f7d7ea1SAurabindo Pillai 326*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_get_inbox1_wptr(struct dmub_srv *dmub) 327*7f7d7ea1SAurabindo Pillai { 328*7f7d7ea1SAurabindo Pillai return REG_READ(DMCUB_INBOX1_WPTR); 329*7f7d7ea1SAurabindo Pillai } 330*7f7d7ea1SAurabindo Pillai 331*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_get_inbox1_rptr(struct dmub_srv *dmub) 332*7f7d7ea1SAurabindo Pillai { 333*7f7d7ea1SAurabindo Pillai return REG_READ(DMCUB_INBOX1_RPTR); 334*7f7d7ea1SAurabindo Pillai } 335*7f7d7ea1SAurabindo Pillai 336*7f7d7ea1SAurabindo Pillai void dmub_dcn60_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset) 337*7f7d7ea1SAurabindo Pillai { 338*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_INBOX1_WPTR, wptr_offset); 339*7f7d7ea1SAurabindo Pillai } 340*7f7d7ea1SAurabindo Pillai 341*7f7d7ea1SAurabindo Pillai void dmub_dcn60_setup_out_mailbox(struct dmub_srv *dmub, 342*7f7d7ea1SAurabindo Pillai const struct dmub_region *outbox1) 343*7f7d7ea1SAurabindo Pillai { 344*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX1_BASE_ADDRESS, outbox1->base); 345*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX1_SIZE, outbox1->top - outbox1->base); 346*7f7d7ea1SAurabindo Pillai } 347*7f7d7ea1SAurabindo Pillai 348*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_get_outbox1_wptr(struct dmub_srv *dmub) 349*7f7d7ea1SAurabindo Pillai { 350*7f7d7ea1SAurabindo Pillai /** 351*7f7d7ea1SAurabindo Pillai * outbox1 wptr register is accessed without locks (dal & dc) 352*7f7d7ea1SAurabindo Pillai * and to be called only by dmub_srv_stat_get_notification() 353*7f7d7ea1SAurabindo Pillai */ 354*7f7d7ea1SAurabindo Pillai return REG_READ(DMCUB_OUTBOX1_WPTR); 355*7f7d7ea1SAurabindo Pillai } 356*7f7d7ea1SAurabindo Pillai 357*7f7d7ea1SAurabindo Pillai void dmub_dcn60_set_outbox1_rptr(struct dmub_srv *dmub, uint32_t rptr_offset) 358*7f7d7ea1SAurabindo Pillai { 359*7f7d7ea1SAurabindo Pillai /** 360*7f7d7ea1SAurabindo Pillai * outbox1 rptr register is accessed without locks (dal & dc) 361*7f7d7ea1SAurabindo Pillai * and to be called only by dmub_srv_stat_get_notification() 362*7f7d7ea1SAurabindo Pillai */ 363*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX1_RPTR, rptr_offset); 364*7f7d7ea1SAurabindo Pillai } 365*7f7d7ea1SAurabindo Pillai 366*7f7d7ea1SAurabindo Pillai bool dmub_dcn60_is_hw_init(struct dmub_srv *dmub) 367*7f7d7ea1SAurabindo Pillai { 368*7f7d7ea1SAurabindo Pillai union dmub_fw_boot_status status; 369*7f7d7ea1SAurabindo Pillai uint32_t is_hw_init; 370*7f7d7ea1SAurabindo Pillai 371*7f7d7ea1SAurabindo Pillai status.all = REG_READ(DMCUB_SCRATCH0); 372*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_hw_init); 373*7f7d7ea1SAurabindo Pillai 374*7f7d7ea1SAurabindo Pillai return is_hw_init != 0 && status.bits.dal_fw; 375*7f7d7ea1SAurabindo Pillai } 376*7f7d7ea1SAurabindo Pillai 377*7f7d7ea1SAurabindo Pillai bool dmub_dcn60_is_supported(struct dmub_srv *dmub) 378*7f7d7ea1SAurabindo Pillai { 379*7f7d7ea1SAurabindo Pillai (void)dmub; 380*7f7d7ea1SAurabindo Pillai // TODO: CC_DC_PIPE_DIS::DC_DMCUB_ENABLE no longer exists 381*7f7d7ea1SAurabindo Pillai //REG_GET(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE, &supported); 382*7f7d7ea1SAurabindo Pillai return 1; 383*7f7d7ea1SAurabindo Pillai } 384*7f7d7ea1SAurabindo Pillai 385*7f7d7ea1SAurabindo Pillai void dmub_dcn60_set_gpint(struct dmub_srv *dmub, 386*7f7d7ea1SAurabindo Pillai union dmub_gpint_data_register reg) 387*7f7d7ea1SAurabindo Pillai { 388*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_GPINT_DATAIN1, reg.all); 389*7f7d7ea1SAurabindo Pillai } 390*7f7d7ea1SAurabindo Pillai 391*7f7d7ea1SAurabindo Pillai bool dmub_dcn60_is_gpint_acked(struct dmub_srv *dmub, 392*7f7d7ea1SAurabindo Pillai union dmub_gpint_data_register reg) 393*7f7d7ea1SAurabindo Pillai { 394*7f7d7ea1SAurabindo Pillai union dmub_gpint_data_register test; 395*7f7d7ea1SAurabindo Pillai 396*7f7d7ea1SAurabindo Pillai reg.bits.status = 0; 397*7f7d7ea1SAurabindo Pillai test.all = REG_READ(DMCUB_GPINT_DATAIN1); 398*7f7d7ea1SAurabindo Pillai 399*7f7d7ea1SAurabindo Pillai return test.all == reg.all; 400*7f7d7ea1SAurabindo Pillai } 401*7f7d7ea1SAurabindo Pillai 402*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_get_gpint_response(struct dmub_srv *dmub) 403*7f7d7ea1SAurabindo Pillai { 404*7f7d7ea1SAurabindo Pillai return REG_READ(DMCUB_SCRATCH7); 405*7f7d7ea1SAurabindo Pillai } 406*7f7d7ea1SAurabindo Pillai 407*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_get_gpint_dataout(struct dmub_srv *dmub) 408*7f7d7ea1SAurabindo Pillai { 409*7f7d7ea1SAurabindo Pillai uint32_t dataout = REG_READ(DMCUB_GPINT_DATAOUT); 410*7f7d7ea1SAurabindo Pillai 411*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN, 0); 412*7f7d7ea1SAurabindo Pillai 413*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_GPINT_DATAOUT, 0); 414*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK, 1); 415*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK, 0); 416*7f7d7ea1SAurabindo Pillai 417*7f7d7ea1SAurabindo Pillai REG_UPDATE(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN, 1); 418*7f7d7ea1SAurabindo Pillai 419*7f7d7ea1SAurabindo Pillai return dataout; 420*7f7d7ea1SAurabindo Pillai } 421*7f7d7ea1SAurabindo Pillai 422*7f7d7ea1SAurabindo Pillai union dmub_fw_boot_status dmub_dcn60_get_fw_boot_status(struct dmub_srv *dmub) 423*7f7d7ea1SAurabindo Pillai { 424*7f7d7ea1SAurabindo Pillai union dmub_fw_boot_status status; 425*7f7d7ea1SAurabindo Pillai 426*7f7d7ea1SAurabindo Pillai status.all = REG_READ(DMCUB_SCRATCH0); 427*7f7d7ea1SAurabindo Pillai return status; 428*7f7d7ea1SAurabindo Pillai } 429*7f7d7ea1SAurabindo Pillai 430*7f7d7ea1SAurabindo Pillai void dmub_dcn60_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmub_srv_hw_params *params) 431*7f7d7ea1SAurabindo Pillai { 432*7f7d7ea1SAurabindo Pillai union dmub_fw_boot_options boot_options = {0}; 433*7f7d7ea1SAurabindo Pillai 434*7f7d7ea1SAurabindo Pillai boot_options.bits.z10_disable = params->disable_z10; 435*7f7d7ea1SAurabindo Pillai 436*7f7d7ea1SAurabindo Pillai boot_options.bits.skip_phy_access = params->disallow_phy_access; 437*7f7d7ea1SAurabindo Pillai 438*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_SCRATCH14, boot_options.all); 439*7f7d7ea1SAurabindo Pillai } 440*7f7d7ea1SAurabindo Pillai 441*7f7d7ea1SAurabindo Pillai void dmub_dcn60_skip_dmub_panel_power_sequence(struct dmub_srv *dmub, bool skip) 442*7f7d7ea1SAurabindo Pillai { 443*7f7d7ea1SAurabindo Pillai union dmub_fw_boot_options boot_options; 444*7f7d7ea1SAurabindo Pillai boot_options.all = REG_READ(DMCUB_SCRATCH14); 445*7f7d7ea1SAurabindo Pillai boot_options.bits.skip_phy_init_panel_sequence = skip; 446*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_SCRATCH14, boot_options.all); 447*7f7d7ea1SAurabindo Pillai } 448*7f7d7ea1SAurabindo Pillai 449*7f7d7ea1SAurabindo Pillai void dmub_dcn60_setup_outbox0(struct dmub_srv *dmub, 450*7f7d7ea1SAurabindo Pillai const struct dmub_region *outbox0) 451*7f7d7ea1SAurabindo Pillai { 452*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX0_BASE_ADDRESS, outbox0->base); 453*7f7d7ea1SAurabindo Pillai 454*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX0_SIZE, outbox0->top - outbox0->base); 455*7f7d7ea1SAurabindo Pillai } 456*7f7d7ea1SAurabindo Pillai 457*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_get_outbox0_wptr(struct dmub_srv *dmub) 458*7f7d7ea1SAurabindo Pillai { 459*7f7d7ea1SAurabindo Pillai return REG_READ(DMCUB_OUTBOX0_WPTR); 460*7f7d7ea1SAurabindo Pillai } 461*7f7d7ea1SAurabindo Pillai 462*7f7d7ea1SAurabindo Pillai void dmub_dcn60_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset) 463*7f7d7ea1SAurabindo Pillai { 464*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_OUTBOX0_RPTR, rptr_offset); 465*7f7d7ea1SAurabindo Pillai } 466*7f7d7ea1SAurabindo Pillai 467*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_get_current_time(struct dmub_srv *dmub) 468*7f7d7ea1SAurabindo Pillai { 469*7f7d7ea1SAurabindo Pillai return REG_READ(DMCUB_TIMER_CURRENT); 470*7f7d7ea1SAurabindo Pillai } 471*7f7d7ea1SAurabindo Pillai 472*7f7d7ea1SAurabindo Pillai void dmub_dcn60_get_diagnostic_data(struct dmub_srv *dmub) 473*7f7d7ea1SAurabindo Pillai { 474*7f7d7ea1SAurabindo Pillai uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset, is_pwait; 475*7f7d7ea1SAurabindo Pillai uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled; 476*7f7d7ea1SAurabindo Pillai struct dmub_timeout_info timeout = {0}; 477*7f7d7ea1SAurabindo Pillai 478*7f7d7ea1SAurabindo Pillai if (!dmub) 479*7f7d7ea1SAurabindo Pillai return; 480*7f7d7ea1SAurabindo Pillai 481*7f7d7ea1SAurabindo Pillai /* timeout data filled externally, cache before resetting memory */ 482*7f7d7ea1SAurabindo Pillai timeout = dmub->debug.timeout_info; 483*7f7d7ea1SAurabindo Pillai memset(&dmub->debug, 0, sizeof(dmub->debug)); 484*7f7d7ea1SAurabindo Pillai dmub->debug.timeout_info = timeout; 485*7f7d7ea1SAurabindo Pillai 486*7f7d7ea1SAurabindo Pillai dmub->debug.dmcub_version = dmub->fw_version; 487*7f7d7ea1SAurabindo Pillai 488*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[0] = REG_READ(DMCUB_SCRATCH0); 489*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[1] = REG_READ(DMCUB_SCRATCH1); 490*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[2] = REG_READ(DMCUB_SCRATCH2); 491*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[3] = REG_READ(DMCUB_SCRATCH3); 492*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[4] = REG_READ(DMCUB_SCRATCH4); 493*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[5] = REG_READ(DMCUB_SCRATCH5); 494*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[6] = REG_READ(DMCUB_SCRATCH6); 495*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[7] = REG_READ(DMCUB_SCRATCH7); 496*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[8] = REG_READ(DMCUB_SCRATCH8); 497*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[9] = REG_READ(DMCUB_SCRATCH9); 498*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[10] = REG_READ(DMCUB_SCRATCH10); 499*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[11] = REG_READ(DMCUB_SCRATCH11); 500*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[12] = REG_READ(DMCUB_SCRATCH12); 501*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[13] = REG_READ(DMCUB_SCRATCH13); 502*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[14] = REG_READ(DMCUB_SCRATCH14); 503*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[15] = REG_READ(DMCUB_SCRATCH15); 504*7f7d7ea1SAurabindo Pillai dmub->debug.scratch[16] = REG_READ(DMCUB_SCRATCH16); 505*7f7d7ea1SAurabindo Pillai 506*7f7d7ea1SAurabindo Pillai dmub->debug.undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); 507*7f7d7ea1SAurabindo Pillai dmub->debug.inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); 508*7f7d7ea1SAurabindo Pillai dmub->debug.data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); 509*7f7d7ea1SAurabindo Pillai 510*7f7d7ea1SAurabindo Pillai dmub->debug.inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); 511*7f7d7ea1SAurabindo Pillai dmub->debug.inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); 512*7f7d7ea1SAurabindo Pillai dmub->debug.inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); 513*7f7d7ea1SAurabindo Pillai 514*7f7d7ea1SAurabindo Pillai dmub->debug.inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); 515*7f7d7ea1SAurabindo Pillai dmub->debug.inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); 516*7f7d7ea1SAurabindo Pillai dmub->debug.inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); 517*7f7d7ea1SAurabindo Pillai 518*7f7d7ea1SAurabindo Pillai dmub->debug.outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); 519*7f7d7ea1SAurabindo Pillai dmub->debug.outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); 520*7f7d7ea1SAurabindo Pillai dmub->debug.outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); 521*7f7d7ea1SAurabindo Pillai 522*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); 523*7f7d7ea1SAurabindo Pillai ASSERT(is_dmub_enabled <= 0xFF); 524*7f7d7ea1SAurabindo Pillai dmub->debug.is_dmcub_enabled = (uint8_t)is_dmub_enabled; 525*7f7d7ea1SAurabindo Pillai 526*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait); 527*7f7d7ea1SAurabindo Pillai ASSERT(is_pwait <= 0xFF); 528*7f7d7ea1SAurabindo Pillai dmub->debug.is_pwait = (uint8_t)is_pwait; 529*7f7d7ea1SAurabindo Pillai 530*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); 531*7f7d7ea1SAurabindo Pillai ASSERT(is_soft_reset <= 0xFF); 532*7f7d7ea1SAurabindo Pillai dmub->debug.is_dmcub_soft_reset = (uint8_t)is_soft_reset; 533*7f7d7ea1SAurabindo Pillai 534*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset); 535*7f7d7ea1SAurabindo Pillai ASSERT(is_sec_reset <= 0xFF); 536*7f7d7ea1SAurabindo Pillai dmub->debug.is_dmcub_secure_reset = (uint8_t)is_sec_reset; 537*7f7d7ea1SAurabindo Pillai 538*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); 539*7f7d7ea1SAurabindo Pillai ASSERT(is_traceport_enabled <= 0xFF); 540*7f7d7ea1SAurabindo Pillai dmub->debug.is_traceport_en = (uint8_t)is_traceport_enabled; 541*7f7d7ea1SAurabindo Pillai 542*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); 543*7f7d7ea1SAurabindo Pillai ASSERT(is_cw0_enabled <= 0xFF); 544*7f7d7ea1SAurabindo Pillai dmub->debug.is_cw0_enabled = (uint8_t)is_cw0_enabled; 545*7f7d7ea1SAurabindo Pillai 546*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); 547*7f7d7ea1SAurabindo Pillai ASSERT(is_cw6_enabled <= 0xFF); 548*7f7d7ea1SAurabindo Pillai dmub->debug.is_cw6_enabled = (uint8_t)is_cw6_enabled; 549*7f7d7ea1SAurabindo Pillai 550*7f7d7ea1SAurabindo Pillai dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); 551*7f7d7ea1SAurabindo Pillai } 552*7f7d7ea1SAurabindo Pillai void dmub_dcn60_configure_dmub_in_system_memory(struct dmub_srv *dmub) 553*7f7d7ea1SAurabindo Pillai { 554*7f7d7ea1SAurabindo Pillai /* DMCUB_REGION3_TMR_AXI_SPACE values: 555*7f7d7ea1SAurabindo Pillai * 0b011 (0x3) - FB physical address 556*7f7d7ea1SAurabindo Pillai * 0b100 (0x4) - GPU virtual address 557*7f7d7ea1SAurabindo Pillai * 558*7f7d7ea1SAurabindo Pillai * Default value is 0x3 (FB Physical address for TMR). When programming 559*7f7d7ea1SAurabindo Pillai * DMUB to be in system memory, change to 0x4. The system memory allocated 560*7f7d7ea1SAurabindo Pillai * is accessible by both GPU and CPU, so we use GPU virtual address. 561*7f7d7ea1SAurabindo Pillai */ 562*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REGION3_TMR_AXI_SPACE, 0x4); 563*7f7d7ea1SAurabindo Pillai } 564*7f7d7ea1SAurabindo Pillai 565*7f7d7ea1SAurabindo Pillai void dmub_dcn60_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data) 566*7f7d7ea1SAurabindo Pillai { 567*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_INBOX0_WPTR, data.inbox0_cmd_common.all); 568*7f7d7ea1SAurabindo Pillai } 569*7f7d7ea1SAurabindo Pillai 570*7f7d7ea1SAurabindo Pillai void dmub_dcn60_clear_inbox0_ack_register(struct dmub_srv *dmub) 571*7f7d7ea1SAurabindo Pillai { 572*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_SCRATCH17, 0); 573*7f7d7ea1SAurabindo Pillai } 574*7f7d7ea1SAurabindo Pillai 575*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_read_inbox0_ack_register(struct dmub_srv *dmub) 576*7f7d7ea1SAurabindo Pillai { 577*7f7d7ea1SAurabindo Pillai return REG_READ(DMCUB_SCRATCH17); 578*7f7d7ea1SAurabindo Pillai } 579*7f7d7ea1SAurabindo Pillai 580*7f7d7ea1SAurabindo Pillai void dmub_dcn60_send_reg_inbox0_cmd_msg(struct dmub_srv *dmub, 581*7f7d7ea1SAurabindo Pillai union dmub_rb_cmd *cmd) 582*7f7d7ea1SAurabindo Pillai { 583*7f7d7ea1SAurabindo Pillai uint32_t *dwords = (uint32_t *)cmd; 584*7f7d7ea1SAurabindo Pillai uint32_t payload_size_bytes = cmd->cmd_common.header.payload_bytes; 585*7f7d7ea1SAurabindo Pillai uint32_t msg_index; 586*7f7d7ea1SAurabindo Pillai static_assert(sizeof(*cmd) == 64, "DMUB command size mismatch"); 587*7f7d7ea1SAurabindo Pillai 588*7f7d7ea1SAurabindo Pillai /* read remaining data based on payload size */ 589*7f7d7ea1SAurabindo Pillai for (msg_index = 0; msg_index < 15; msg_index++) { 590*7f7d7ea1SAurabindo Pillai if (payload_size_bytes <= msg_index * 4) { 591*7f7d7ea1SAurabindo Pillai break; 592*7f7d7ea1SAurabindo Pillai } 593*7f7d7ea1SAurabindo Pillai 594*7f7d7ea1SAurabindo Pillai switch (msg_index) { 595*7f7d7ea1SAurabindo Pillai case 0: 596*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG0, dwords[msg_index + 1]); 597*7f7d7ea1SAurabindo Pillai break; 598*7f7d7ea1SAurabindo Pillai case 1: 599*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG1, dwords[msg_index + 1]); 600*7f7d7ea1SAurabindo Pillai break; 601*7f7d7ea1SAurabindo Pillai case 2: 602*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG2, dwords[msg_index + 1]); 603*7f7d7ea1SAurabindo Pillai break; 604*7f7d7ea1SAurabindo Pillai case 3: 605*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG3, dwords[msg_index + 1]); 606*7f7d7ea1SAurabindo Pillai break; 607*7f7d7ea1SAurabindo Pillai case 4: 608*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG4, dwords[msg_index + 1]); 609*7f7d7ea1SAurabindo Pillai break; 610*7f7d7ea1SAurabindo Pillai case 5: 611*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG5, dwords[msg_index + 1]); 612*7f7d7ea1SAurabindo Pillai break; 613*7f7d7ea1SAurabindo Pillai case 6: 614*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG6, dwords[msg_index + 1]); 615*7f7d7ea1SAurabindo Pillai break; 616*7f7d7ea1SAurabindo Pillai case 7: 617*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG7, dwords[msg_index + 1]); 618*7f7d7ea1SAurabindo Pillai break; 619*7f7d7ea1SAurabindo Pillai case 8: 620*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG8, dwords[msg_index + 1]); 621*7f7d7ea1SAurabindo Pillai break; 622*7f7d7ea1SAurabindo Pillai case 9: 623*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG9, dwords[msg_index + 1]); 624*7f7d7ea1SAurabindo Pillai break; 625*7f7d7ea1SAurabindo Pillai case 10: 626*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG10, dwords[msg_index + 1]); 627*7f7d7ea1SAurabindo Pillai break; 628*7f7d7ea1SAurabindo Pillai case 11: 629*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG11, dwords[msg_index + 1]); 630*7f7d7ea1SAurabindo Pillai break; 631*7f7d7ea1SAurabindo Pillai case 12: 632*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG12, dwords[msg_index + 1]); 633*7f7d7ea1SAurabindo Pillai break; 634*7f7d7ea1SAurabindo Pillai case 13: 635*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG13, dwords[msg_index + 1]); 636*7f7d7ea1SAurabindo Pillai break; 637*7f7d7ea1SAurabindo Pillai case 14: 638*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_MSG14, dwords[msg_index + 1]); 639*7f7d7ea1SAurabindo Pillai break; 640*7f7d7ea1SAurabindo Pillai } 641*7f7d7ea1SAurabindo Pillai } 642*7f7d7ea1SAurabindo Pillai 643*7f7d7ea1SAurabindo Pillai /* writing to INBOX RDY register will trigger DMUB REG INBOX0 RDY 644*7f7d7ea1SAurabindo Pillai * interrupt. 645*7f7d7ea1SAurabindo Pillai */ 646*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_INBOX0_RDY, dwords[0]); 647*7f7d7ea1SAurabindo Pillai } 648*7f7d7ea1SAurabindo Pillai 649*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_read_reg_inbox0_rsp_int_status(struct dmub_srv *dmub) 650*7f7d7ea1SAurabindo Pillai { 651*7f7d7ea1SAurabindo Pillai uint32_t status; 652*7f7d7ea1SAurabindo Pillai 653*7f7d7ea1SAurabindo Pillai REG_GET(HOST_INTERRUPT_CSR, HOST_REG_INBOX0_RSP_INT_STAT, &status); 654*7f7d7ea1SAurabindo Pillai return status; 655*7f7d7ea1SAurabindo Pillai } 656*7f7d7ea1SAurabindo Pillai 657*7f7d7ea1SAurabindo Pillai void dmub_dcn60_read_reg_inbox0_cmd_rsp(struct dmub_srv *dmub, 658*7f7d7ea1SAurabindo Pillai union dmub_rb_cmd *cmd) 659*7f7d7ea1SAurabindo Pillai { 660*7f7d7ea1SAurabindo Pillai uint32_t *dwords = (uint32_t *)cmd; 661*7f7d7ea1SAurabindo Pillai 662*7f7d7ea1SAurabindo Pillai static_assert(sizeof(*cmd) == 64, "DMUB command size mismatch"); 663*7f7d7ea1SAurabindo Pillai 664*7f7d7ea1SAurabindo Pillai dwords[0] = REG_READ(DMCUB_REG_INBOX0_RSP); 665*7f7d7ea1SAurabindo Pillai dwords[1] = REG_READ(DMCUB_REG_INBOX0_MSG0); 666*7f7d7ea1SAurabindo Pillai dwords[2] = REG_READ(DMCUB_REG_INBOX0_MSG1); 667*7f7d7ea1SAurabindo Pillai dwords[3] = REG_READ(DMCUB_REG_INBOX0_MSG2); 668*7f7d7ea1SAurabindo Pillai dwords[4] = REG_READ(DMCUB_REG_INBOX0_MSG3); 669*7f7d7ea1SAurabindo Pillai dwords[5] = REG_READ(DMCUB_REG_INBOX0_MSG4); 670*7f7d7ea1SAurabindo Pillai dwords[6] = REG_READ(DMCUB_REG_INBOX0_MSG5); 671*7f7d7ea1SAurabindo Pillai dwords[7] = REG_READ(DMCUB_REG_INBOX0_MSG6); 672*7f7d7ea1SAurabindo Pillai dwords[8] = REG_READ(DMCUB_REG_INBOX0_MSG7); 673*7f7d7ea1SAurabindo Pillai dwords[9] = REG_READ(DMCUB_REG_INBOX0_MSG8); 674*7f7d7ea1SAurabindo Pillai dwords[10] = REG_READ(DMCUB_REG_INBOX0_MSG9); 675*7f7d7ea1SAurabindo Pillai dwords[11] = REG_READ(DMCUB_REG_INBOX0_MSG10); 676*7f7d7ea1SAurabindo Pillai dwords[12] = REG_READ(DMCUB_REG_INBOX0_MSG11); 677*7f7d7ea1SAurabindo Pillai dwords[13] = REG_READ(DMCUB_REG_INBOX0_MSG12); 678*7f7d7ea1SAurabindo Pillai dwords[14] = REG_READ(DMCUB_REG_INBOX0_MSG13); 679*7f7d7ea1SAurabindo Pillai dwords[15] = REG_READ(DMCUB_REG_INBOX0_MSG14); 680*7f7d7ea1SAurabindo Pillai } 681*7f7d7ea1SAurabindo Pillai 682*7f7d7ea1SAurabindo Pillai void dmub_dcn60_write_reg_inbox0_rsp_int_ack(struct dmub_srv *dmub) 683*7f7d7ea1SAurabindo Pillai { 684*7f7d7ea1SAurabindo Pillai REG_UPDATE(HOST_INTERRUPT_CSR, HOST_REG_INBOX0_RSP_INT_ACK, 1); 685*7f7d7ea1SAurabindo Pillai } 686*7f7d7ea1SAurabindo Pillai 687*7f7d7ea1SAurabindo Pillai void dmub_dcn60_clear_reg_inbox0_rsp_int_ack(struct dmub_srv *dmub) 688*7f7d7ea1SAurabindo Pillai { 689*7f7d7ea1SAurabindo Pillai REG_UPDATE(HOST_INTERRUPT_CSR, HOST_REG_INBOX0_RSP_INT_ACK, 0); 690*7f7d7ea1SAurabindo Pillai } 691*7f7d7ea1SAurabindo Pillai 692*7f7d7ea1SAurabindo Pillai void dmub_dcn60_enable_reg_inbox0_rsp_int(struct dmub_srv *dmub, bool enable) 693*7f7d7ea1SAurabindo Pillai { 694*7f7d7ea1SAurabindo Pillai REG_UPDATE(HOST_INTERRUPT_CSR, HOST_REG_INBOX0_RSP_INT_EN, enable ? 1:0); 695*7f7d7ea1SAurabindo Pillai } 696*7f7d7ea1SAurabindo Pillai 697*7f7d7ea1SAurabindo Pillai void dmub_dcn60_write_reg_outbox0_rdy_int_ack(struct dmub_srv *dmub) 698*7f7d7ea1SAurabindo Pillai { 699*7f7d7ea1SAurabindo Pillai REG_UPDATE(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_ACK, 1); 700*7f7d7ea1SAurabindo Pillai REG_UPDATE(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_ACK, 0); 701*7f7d7ea1SAurabindo Pillai } 702*7f7d7ea1SAurabindo Pillai 703*7f7d7ea1SAurabindo Pillai void dmub_dcn60_read_reg_outbox0_msg(struct dmub_srv *dmub, uint32_t *msg) 704*7f7d7ea1SAurabindo Pillai { 705*7f7d7ea1SAurabindo Pillai *msg = REG_READ(DMCUB_REG_OUTBOX0_MSG0); 706*7f7d7ea1SAurabindo Pillai } 707*7f7d7ea1SAurabindo Pillai 708*7f7d7ea1SAurabindo Pillai void dmub_dcn60_write_reg_outbox0_rsp(struct dmub_srv *dmub, uint32_t *rsp) 709*7f7d7ea1SAurabindo Pillai { 710*7f7d7ea1SAurabindo Pillai REG_WRITE(DMCUB_REG_OUTBOX0_RSP, *rsp); 711*7f7d7ea1SAurabindo Pillai } 712*7f7d7ea1SAurabindo Pillai 713*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_read_reg_outbox0_rsp_int_status(struct dmub_srv *dmub) 714*7f7d7ea1SAurabindo Pillai { 715*7f7d7ea1SAurabindo Pillai uint32_t status; 716*7f7d7ea1SAurabindo Pillai 717*7f7d7ea1SAurabindo Pillai REG_GET(DMCUB_INTERRUPT_STATUS, DMCUB_REG_OUTBOX0_RSP_INT_STAT, &status); 718*7f7d7ea1SAurabindo Pillai return status; 719*7f7d7ea1SAurabindo Pillai } 720*7f7d7ea1SAurabindo Pillai 721*7f7d7ea1SAurabindo Pillai void dmub_dcn60_enable_reg_outbox0_rdy_int(struct dmub_srv *dmub, bool enable) 722*7f7d7ea1SAurabindo Pillai { 723*7f7d7ea1SAurabindo Pillai REG_UPDATE(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_EN, enable ? 1:0); 724*7f7d7ea1SAurabindo Pillai } 725*7f7d7ea1SAurabindo Pillai 726*7f7d7ea1SAurabindo Pillai uint32_t dmub_dcn60_read_reg_outbox0_rdy_int_status(struct dmub_srv *dmub) 727*7f7d7ea1SAurabindo Pillai { 728*7f7d7ea1SAurabindo Pillai uint32_t status; 729*7f7d7ea1SAurabindo Pillai 730*7f7d7ea1SAurabindo Pillai REG_GET(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_STAT, &status); 731*7f7d7ea1SAurabindo Pillai return status; 732*7f7d7ea1SAurabindo Pillai } 733