xref: /linux/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.c (revision 4e69c1856bfd9ffb7e9d335a25842fa211628929)
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