Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2022 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "../dmub_srv.h"
0027 #include "dmub_reg.h"
0028 #include "dmub_dcn32.h"
0029 
0030 #include "dcn/dcn_3_2_0_offset.h"
0031 #include "dcn/dcn_3_2_0_sh_mask.h"
0032 
0033 #define DCN_BASE__INST0_SEG2                       0x000034C0
0034 
0035 #define BASE_INNER(seg) DCN_BASE__INST0_SEG##seg
0036 #define CTX dmub
0037 #define REGS dmub->regs_dcn32
0038 #define REG_OFFSET_EXP(reg_name) (BASE(reg##reg_name##_BASE_IDX) + reg##reg_name)
0039 
0040 const struct dmub_srv_dcn32_regs dmub_srv_dcn32_regs = {
0041 #define DMUB_SR(reg) REG_OFFSET_EXP(reg),
0042     {
0043         DMUB_DCN32_REGS()
0044         DMCUB_INTERNAL_REGS()
0045     },
0046 #undef DMUB_SR
0047 
0048 #define DMUB_SF(reg, field) FD_MASK(reg, field),
0049         { DMUB_DCN32_FIELDS() },
0050 #undef DMUB_SF
0051 
0052 #define DMUB_SF(reg, field) FD_SHIFT(reg, field),
0053         { DMUB_DCN32_FIELDS() },
0054 #undef DMUB_SF
0055 };
0056 
0057 static void dmub_dcn32_get_fb_base_offset(struct dmub_srv *dmub,
0058         uint64_t *fb_base,
0059         uint64_t *fb_offset)
0060 {
0061     uint32_t tmp;
0062 
0063     if (dmub->fb_base || dmub->fb_offset) {
0064         *fb_base = dmub->fb_base;
0065         *fb_offset = dmub->fb_offset;
0066         return;
0067     }
0068 
0069     REG_GET(DCN_VM_FB_LOCATION_BASE, FB_BASE, &tmp);
0070     *fb_base = (uint64_t)tmp << 24;
0071 
0072     REG_GET(DCN_VM_FB_OFFSET, FB_OFFSET, &tmp);
0073     *fb_offset = (uint64_t)tmp << 24;
0074 }
0075 
0076 static inline void dmub_dcn32_translate_addr(const union dmub_addr *addr_in,
0077         uint64_t fb_base,
0078         uint64_t fb_offset,
0079         union dmub_addr *addr_out)
0080 {
0081     addr_out->quad_part = addr_in->quad_part - fb_base + fb_offset;
0082 }
0083 
0084 void dmub_dcn32_reset(struct dmub_srv *dmub)
0085 {
0086     union dmub_gpint_data_register cmd;
0087     const uint32_t timeout = 30;
0088     uint32_t in_reset, scratch, i;
0089 
0090     REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset);
0091 
0092     if (in_reset == 0) {
0093         cmd.bits.status = 1;
0094         cmd.bits.command_code = DMUB_GPINT__STOP_FW;
0095         cmd.bits.param = 0;
0096 
0097         dmub->hw_funcs.set_gpint(dmub, cmd);
0098 
0099         /**
0100          * Timeout covers both the ACK and the wait
0101          * for remaining work to finish.
0102          *
0103          * This is mostly bound by the PHY disable sequence.
0104          * Each register check will be greater than 1us, so
0105          * don't bother using udelay.
0106          */
0107 
0108         for (i = 0; i < timeout; ++i) {
0109             if (dmub->hw_funcs.is_gpint_acked(dmub, cmd))
0110                 break;
0111         }
0112 
0113         for (i = 0; i < timeout; ++i) {
0114             scratch = dmub->hw_funcs.get_gpint_response(dmub);
0115             if (scratch == DMUB_GPINT__STOP_FW_RESPONSE)
0116                 break;
0117         }
0118 
0119         /* Clear the GPINT command manually so we don't reset again. */
0120         cmd.all = 0;
0121         dmub->hw_funcs.set_gpint(dmub, cmd);
0122 
0123         /* Force reset in case we timed out, DMCUB is likely hung. */
0124     }
0125 
0126     REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);
0127     REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0);
0128     REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1);
0129     REG_WRITE(DMCUB_INBOX1_RPTR, 0);
0130     REG_WRITE(DMCUB_INBOX1_WPTR, 0);
0131     REG_WRITE(DMCUB_OUTBOX1_RPTR, 0);
0132     REG_WRITE(DMCUB_OUTBOX1_WPTR, 0);
0133     REG_WRITE(DMCUB_SCRATCH0, 0);
0134 }
0135 
0136 void dmub_dcn32_reset_release(struct dmub_srv *dmub)
0137 {
0138     REG_WRITE(DMCUB_GPINT_DATAIN1, 0);
0139     REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 0);
0140     REG_WRITE(DMCUB_SCRATCH15, dmub->psp_version & 0x001100FF);
0141     REG_UPDATE_2(DMCUB_CNTL, DMCUB_ENABLE, 1, DMCUB_TRACEPORT_EN, 1);
0142     REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 0);
0143 }
0144 
0145 void dmub_dcn32_backdoor_load(struct dmub_srv *dmub,
0146         const struct dmub_window *cw0,
0147         const struct dmub_window *cw1)
0148 {
0149     union dmub_addr offset;
0150     uint64_t fb_base, fb_offset;
0151 
0152     dmub_dcn32_get_fb_base_offset(dmub, &fb_base, &fb_offset);
0153 
0154     REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1);
0155 
0156     dmub_dcn32_translate_addr(&cw0->offset, fb_base, fb_offset, &offset);
0157 
0158     REG_WRITE(DMCUB_REGION3_CW0_OFFSET, offset.u.low_part);
0159     REG_WRITE(DMCUB_REGION3_CW0_OFFSET_HIGH, offset.u.high_part);
0160     REG_WRITE(DMCUB_REGION3_CW0_BASE_ADDRESS, cw0->region.base);
0161     REG_SET_2(DMCUB_REGION3_CW0_TOP_ADDRESS, 0,
0162             DMCUB_REGION3_CW0_TOP_ADDRESS, cw0->region.top,
0163             DMCUB_REGION3_CW0_ENABLE, 1);
0164 
0165     dmub_dcn32_translate_addr(&cw1->offset, fb_base, fb_offset, &offset);
0166 
0167     REG_WRITE(DMCUB_REGION3_CW1_OFFSET, offset.u.low_part);
0168     REG_WRITE(DMCUB_REGION3_CW1_OFFSET_HIGH, offset.u.high_part);
0169     REG_WRITE(DMCUB_REGION3_CW1_BASE_ADDRESS, cw1->region.base);
0170     REG_SET_2(DMCUB_REGION3_CW1_TOP_ADDRESS, 0,
0171             DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top,
0172             DMCUB_REGION3_CW1_ENABLE, 1);
0173 
0174     REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID,
0175             0x20);
0176 }
0177 
0178 void dmub_dcn32_backdoor_load_zfb_mode(struct dmub_srv *dmub,
0179               const struct dmub_window *cw0,
0180               const struct dmub_window *cw1)
0181 {
0182     union dmub_addr offset;
0183 
0184     REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1);
0185 
0186     offset = cw0->offset;
0187 
0188     REG_WRITE(DMCUB_REGION3_CW0_OFFSET, offset.u.low_part);
0189     REG_WRITE(DMCUB_REGION3_CW0_OFFSET_HIGH, offset.u.high_part);
0190     REG_WRITE(DMCUB_REGION3_CW0_BASE_ADDRESS, cw0->region.base);
0191     REG_SET_2(DMCUB_REGION3_CW0_TOP_ADDRESS, 0,
0192             DMCUB_REGION3_CW0_TOP_ADDRESS, cw0->region.top,
0193             DMCUB_REGION3_CW0_ENABLE, 1);
0194 
0195     offset = cw1->offset;
0196 
0197     REG_WRITE(DMCUB_REGION3_CW1_OFFSET, offset.u.low_part);
0198     REG_WRITE(DMCUB_REGION3_CW1_OFFSET_HIGH, offset.u.high_part);
0199     REG_WRITE(DMCUB_REGION3_CW1_BASE_ADDRESS, cw1->region.base);
0200     REG_SET_2(DMCUB_REGION3_CW1_TOP_ADDRESS, 0,
0201             DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top,
0202             DMCUB_REGION3_CW1_ENABLE, 1);
0203 
0204     REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID,
0205             0x20);
0206 }
0207 
0208 void dmub_dcn32_setup_windows(struct dmub_srv *dmub,
0209         const struct dmub_window *cw2,
0210         const struct dmub_window *cw3,
0211         const struct dmub_window *cw4,
0212         const struct dmub_window *cw5,
0213         const struct dmub_window *cw6)
0214 {
0215     union dmub_addr offset;
0216 
0217     offset = cw3->offset;
0218 
0219     REG_WRITE(DMCUB_REGION3_CW3_OFFSET, offset.u.low_part);
0220     REG_WRITE(DMCUB_REGION3_CW3_OFFSET_HIGH, offset.u.high_part);
0221     REG_WRITE(DMCUB_REGION3_CW3_BASE_ADDRESS, cw3->region.base);
0222     REG_SET_2(DMCUB_REGION3_CW3_TOP_ADDRESS, 0,
0223             DMCUB_REGION3_CW3_TOP_ADDRESS, cw3->region.top,
0224             DMCUB_REGION3_CW3_ENABLE, 1);
0225 
0226     offset = cw4->offset;
0227 
0228     REG_WRITE(DMCUB_REGION3_CW4_OFFSET, offset.u.low_part);
0229     REG_WRITE(DMCUB_REGION3_CW4_OFFSET_HIGH, offset.u.high_part);
0230     REG_WRITE(DMCUB_REGION3_CW4_BASE_ADDRESS, cw4->region.base);
0231     REG_SET_2(DMCUB_REGION3_CW4_TOP_ADDRESS, 0,
0232             DMCUB_REGION3_CW4_TOP_ADDRESS, cw4->region.top,
0233             DMCUB_REGION3_CW4_ENABLE, 1);
0234 
0235     offset = cw5->offset;
0236 
0237     REG_WRITE(DMCUB_REGION3_CW5_OFFSET, offset.u.low_part);
0238     REG_WRITE(DMCUB_REGION3_CW5_OFFSET_HIGH, offset.u.high_part);
0239     REG_WRITE(DMCUB_REGION3_CW5_BASE_ADDRESS, cw5->region.base);
0240     REG_SET_2(DMCUB_REGION3_CW5_TOP_ADDRESS, 0,
0241             DMCUB_REGION3_CW5_TOP_ADDRESS, cw5->region.top,
0242             DMCUB_REGION3_CW5_ENABLE, 1);
0243 
0244     REG_WRITE(DMCUB_REGION5_OFFSET, offset.u.low_part);
0245     REG_WRITE(DMCUB_REGION5_OFFSET_HIGH, offset.u.high_part);
0246     REG_SET_2(DMCUB_REGION5_TOP_ADDRESS, 0,
0247             DMCUB_REGION5_TOP_ADDRESS,
0248             cw5->region.top - cw5->region.base - 1,
0249             DMCUB_REGION5_ENABLE, 1);
0250 
0251     offset = cw6->offset;
0252 
0253     REG_WRITE(DMCUB_REGION3_CW6_OFFSET, offset.u.low_part);
0254     REG_WRITE(DMCUB_REGION3_CW6_OFFSET_HIGH, offset.u.high_part);
0255     REG_WRITE(DMCUB_REGION3_CW6_BASE_ADDRESS, cw6->region.base);
0256     REG_SET_2(DMCUB_REGION3_CW6_TOP_ADDRESS, 0,
0257             DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top,
0258             DMCUB_REGION3_CW6_ENABLE, 1);
0259 }
0260 
0261 void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub,
0262         const struct dmub_region *inbox1)
0263 {
0264     REG_WRITE(DMCUB_INBOX1_BASE_ADDRESS, inbox1->base);
0265     REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);
0266 }
0267 
0268 uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub)
0269 {
0270     return REG_READ(DMCUB_INBOX1_RPTR);
0271 }
0272 
0273 void dmub_dcn32_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset)
0274 {
0275     REG_WRITE(DMCUB_INBOX1_WPTR, wptr_offset);
0276 }
0277 
0278 void dmub_dcn32_setup_out_mailbox(struct dmub_srv *dmub,
0279         const struct dmub_region *outbox1)
0280 {
0281     REG_WRITE(DMCUB_OUTBOX1_BASE_ADDRESS, outbox1->base);
0282     REG_WRITE(DMCUB_OUTBOX1_SIZE, outbox1->top - outbox1->base);
0283 }
0284 
0285 uint32_t dmub_dcn32_get_outbox1_wptr(struct dmub_srv *dmub)
0286 {
0287     /**
0288      * outbox1 wptr register is accessed without locks (dal & dc)
0289      * and to be called only by dmub_srv_stat_get_notification()
0290      */
0291     return REG_READ(DMCUB_OUTBOX1_WPTR);
0292 }
0293 
0294 void dmub_dcn32_set_outbox1_rptr(struct dmub_srv *dmub, uint32_t rptr_offset)
0295 {
0296     /**
0297      * outbox1 rptr register is accessed without locks (dal & dc)
0298      * and to be called only by dmub_srv_stat_get_notification()
0299      */
0300     REG_WRITE(DMCUB_OUTBOX1_RPTR, rptr_offset);
0301 }
0302 
0303 bool dmub_dcn32_is_hw_init(struct dmub_srv *dmub)
0304 {
0305     union dmub_fw_boot_status status;
0306     uint32_t is_hw_init;
0307 
0308     status.all = REG_READ(DMCUB_SCRATCH0);
0309     REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_hw_init);
0310 
0311     return is_hw_init != 0 && status.bits.dal_fw;
0312 }
0313 
0314 bool dmub_dcn32_is_supported(struct dmub_srv *dmub)
0315 {
0316     uint32_t supported = 0;
0317 
0318     REG_GET(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE, &supported);
0319 
0320     return supported;
0321 }
0322 
0323 void dmub_dcn32_set_gpint(struct dmub_srv *dmub,
0324         union dmub_gpint_data_register reg)
0325 {
0326     REG_WRITE(DMCUB_GPINT_DATAIN1, reg.all);
0327 }
0328 
0329 bool dmub_dcn32_is_gpint_acked(struct dmub_srv *dmub,
0330         union dmub_gpint_data_register reg)
0331 {
0332     union dmub_gpint_data_register test;
0333 
0334     reg.bits.status = 0;
0335     test.all = REG_READ(DMCUB_GPINT_DATAIN1);
0336 
0337     return test.all == reg.all;
0338 }
0339 
0340 uint32_t dmub_dcn32_get_gpint_response(struct dmub_srv *dmub)
0341 {
0342     return REG_READ(DMCUB_SCRATCH7);
0343 }
0344 
0345 uint32_t dmub_dcn32_get_gpint_dataout(struct dmub_srv *dmub)
0346 {
0347     uint32_t dataout = REG_READ(DMCUB_GPINT_DATAOUT);
0348 
0349     REG_UPDATE(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN, 0);
0350 
0351     REG_WRITE(DMCUB_GPINT_DATAOUT, 0);
0352     REG_UPDATE(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK, 1);
0353     REG_UPDATE(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK, 0);
0354 
0355     REG_UPDATE(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN, 1);
0356 
0357     return dataout;
0358 }
0359 
0360 union dmub_fw_boot_status dmub_dcn32_get_fw_boot_status(struct dmub_srv *dmub)
0361 {
0362     union dmub_fw_boot_status status;
0363 
0364     status.all = REG_READ(DMCUB_SCRATCH0);
0365     return status;
0366 }
0367 
0368 void dmub_dcn32_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmub_srv_hw_params *params)
0369 {
0370     union dmub_fw_boot_options boot_options = {0};
0371 
0372     boot_options.bits.z10_disable = params->disable_z10;
0373 
0374     REG_WRITE(DMCUB_SCRATCH14, boot_options.all);
0375 }
0376 
0377 void dmub_dcn32_skip_dmub_panel_power_sequence(struct dmub_srv *dmub, bool skip)
0378 {
0379     union dmub_fw_boot_options boot_options;
0380     boot_options.all = REG_READ(DMCUB_SCRATCH14);
0381     boot_options.bits.skip_phy_init_panel_sequence = skip;
0382     REG_WRITE(DMCUB_SCRATCH14, boot_options.all);
0383 }
0384 
0385 void dmub_dcn32_setup_outbox0(struct dmub_srv *dmub,
0386         const struct dmub_region *outbox0)
0387 {
0388     REG_WRITE(DMCUB_OUTBOX0_BASE_ADDRESS, outbox0->base);
0389 
0390     REG_WRITE(DMCUB_OUTBOX0_SIZE, outbox0->top - outbox0->base);
0391 }
0392 
0393 uint32_t dmub_dcn32_get_outbox0_wptr(struct dmub_srv *dmub)
0394 {
0395     return REG_READ(DMCUB_OUTBOX0_WPTR);
0396 }
0397 
0398 void dmub_dcn32_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset)
0399 {
0400     REG_WRITE(DMCUB_OUTBOX0_RPTR, rptr_offset);
0401 }
0402 
0403 uint32_t dmub_dcn32_get_current_time(struct dmub_srv *dmub)
0404 {
0405     return REG_READ(DMCUB_TIMER_CURRENT);
0406 }
0407 
0408 void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data)
0409 {
0410     uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset;
0411     uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled;
0412 
0413     if (!dmub || !diag_data)
0414         return;
0415 
0416     memset(diag_data, 0, sizeof(*diag_data));
0417 
0418     diag_data->dmcub_version = dmub->fw_version;
0419 
0420     diag_data->scratch[0] = REG_READ(DMCUB_SCRATCH0);
0421     diag_data->scratch[1] = REG_READ(DMCUB_SCRATCH1);
0422     diag_data->scratch[2] = REG_READ(DMCUB_SCRATCH2);
0423     diag_data->scratch[3] = REG_READ(DMCUB_SCRATCH3);
0424     diag_data->scratch[4] = REG_READ(DMCUB_SCRATCH4);
0425     diag_data->scratch[5] = REG_READ(DMCUB_SCRATCH5);
0426     diag_data->scratch[6] = REG_READ(DMCUB_SCRATCH6);
0427     diag_data->scratch[7] = REG_READ(DMCUB_SCRATCH7);
0428     diag_data->scratch[8] = REG_READ(DMCUB_SCRATCH8);
0429     diag_data->scratch[9] = REG_READ(DMCUB_SCRATCH9);
0430     diag_data->scratch[10] = REG_READ(DMCUB_SCRATCH10);
0431     diag_data->scratch[11] = REG_READ(DMCUB_SCRATCH11);
0432     diag_data->scratch[12] = REG_READ(DMCUB_SCRATCH12);
0433     diag_data->scratch[13] = REG_READ(DMCUB_SCRATCH13);
0434     diag_data->scratch[14] = REG_READ(DMCUB_SCRATCH14);
0435     diag_data->scratch[15] = REG_READ(DMCUB_SCRATCH15);
0436 
0437     diag_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR);
0438     diag_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR);
0439     diag_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR);
0440 
0441     diag_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR);
0442     diag_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR);
0443     diag_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE);
0444 
0445     diag_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR);
0446     diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR);
0447     diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE);
0448 
0449     REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled);
0450     diag_data->is_dmcub_enabled = is_dmub_enabled;
0451 
0452     REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset);
0453     diag_data->is_dmcub_soft_reset = is_soft_reset;
0454 
0455     REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset);
0456     diag_data->is_dmcub_secure_reset = is_sec_reset;
0457 
0458     REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled);
0459     diag_data->is_traceport_en  = is_traceport_enabled;
0460 
0461     REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled);
0462     diag_data->is_cw0_enabled = is_cw0_enabled;
0463 
0464     REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled);
0465     diag_data->is_cw6_enabled = is_cw6_enabled;
0466 }
0467 void dmub_dcn32_configure_dmub_in_system_memory(struct dmub_srv *dmub)
0468 {
0469     /* DMCUB_REGION3_TMR_AXI_SPACE values:
0470      * 0b011 (0x3) - FB physical address
0471      * 0b100 (0x4) - GPU virtual address
0472      *
0473      * Default value is 0x3 (FB Physical address for TMR). When programming
0474      * DMUB to be in system memory, change to 0x4. The system memory allocated
0475      * is accessible by both GPU and CPU, so we use GPU virtual address.
0476      */
0477     REG_WRITE(DMCUB_REGION3_TMR_AXI_SPACE, 0x4);
0478 }
0479 
0480 void dmub_dcn32_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data)
0481 {
0482     REG_WRITE(DMCUB_INBOX0_WPTR, data.inbox0_cmd_common.all);
0483 }
0484 
0485 void dmub_dcn32_clear_inbox0_ack_register(struct dmub_srv *dmub)
0486 {
0487     REG_WRITE(DMCUB_SCRATCH17, 0);
0488 }
0489 
0490 uint32_t dmub_dcn32_read_inbox0_ack_register(struct dmub_srv *dmub)
0491 {
0492     return REG_READ(DMCUB_SCRATCH17);
0493 }