xref: /openbmc/linux/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c (revision 93707cbabcc8baf2b2b5f4a99c1f08ee83eb7abd)
1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include "dm_services.h"
27 #include "dcn10_hubp.h"
28 #include "dcn10_hubbub.h"
29 #include "reg_helper.h"
30 
31 #define CTX \
32 	hubbub->ctx
33 #define REG(reg)\
34 	hubbub->regs->reg
35 
36 #undef FN
37 #define FN(reg_name, field_name) \
38 	hubbub->shifts->field_name, hubbub->masks->field_name
39 
40 void hubbub1_wm_read_state(struct hubbub *hubbub,
41 		struct dcn_hubbub_wm *wm)
42 {
43 	struct dcn_hubbub_wm_set *s;
44 
45 	memset(wm, 0, sizeof(struct dcn_hubbub_wm));
46 
47 	s = &wm->sets[0];
48 	s->wm_set = 0;
49 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);
50 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A);
51 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
52 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A);
53 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A);
54 	}
55 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A);
56 
57 	s = &wm->sets[1];
58 	s->wm_set = 1;
59 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B);
60 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B);
61 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
62 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B);
63 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B);
64 	}
65 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B);
66 
67 	s = &wm->sets[2];
68 	s->wm_set = 2;
69 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C);
70 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C);
71 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
72 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C);
73 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C);
74 	}
75 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C);
76 
77 	s = &wm->sets[3];
78 	s->wm_set = 3;
79 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D);
80 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D);
81 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
82 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D);
83 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D);
84 	}
85 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D);
86 }
87 
88 bool hubbub1_verify_allow_pstate_change_high(
89 	struct hubbub *hubbub)
90 {
91 	/* pstate latency is ~20us so if we wait over 40us and pstate allow
92 	 * still not asserted, we are probably stuck and going to hang
93 	 *
94 	 * TODO: Figure out why it takes ~100us on linux
95 	 * pstate takes around ~100us on linux. Unknown currently as to
96 	 * why it takes that long on linux
97 	 */
98 	static unsigned int pstate_wait_timeout_us = 200;
99 	static unsigned int pstate_wait_expected_timeout_us = 40;
100 	static unsigned int max_sampled_pstate_wait_us; /* data collection */
101 	static bool forced_pstate_allow; /* help with revert wa */
102 
103 	unsigned int debug_index = 0x7;
104 	unsigned int debug_data;
105 	unsigned int i;
106 
107 	if (forced_pstate_allow) {
108 		/* we hacked to force pstate allow to prevent hang last time
109 		 * we verify_allow_pstate_change_high.  so disable force
110 		 * here so we can check status
111 		 */
112 		REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
113 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
114 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
115 		forced_pstate_allow = false;
116 	}
117 
118 	/* description "3-0:   Pipe0 cursor0 QOS
119 	 * 7-4:   Pipe1 cursor0 QOS
120 	 * 11-8:  Pipe2 cursor0 QOS
121 	 * 15-12: Pipe3 cursor0 QOS
122 	 * 16:    Pipe0 Plane0 Allow Pstate Change
123 	 * 17:    Pipe1 Plane0 Allow Pstate Change
124 	 * 18:    Pipe2 Plane0 Allow Pstate Change
125 	 * 19:    Pipe3 Plane0 Allow Pstate Change
126 	 * 20:    Pipe0 Plane1 Allow Pstate Change
127 	 * 21:    Pipe1 Plane1 Allow Pstate Change
128 	 * 22:    Pipe2 Plane1 Allow Pstate Change
129 	 * 23:    Pipe3 Plane1 Allow Pstate Change
130 	 * 24:    Pipe0 cursor0 Allow Pstate Change
131 	 * 25:    Pipe1 cursor0 Allow Pstate Change
132 	 * 26:    Pipe2 cursor0 Allow Pstate Change
133 	 * 27:    Pipe3 cursor0 Allow Pstate Change
134 	 * 28:    WB0 Allow Pstate Change
135 	 * 29:    WB1 Allow Pstate Change
136 	 * 30:    Arbiter's allow_pstate_change
137 	 * 31:    SOC pstate change request
138 	 */
139 
140 	REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, debug_index);
141 
142 	for (i = 0; i < pstate_wait_timeout_us; i++) {
143 		debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
144 
145 		if (debug_data & (1 << 30)) {
146 
147 			if (i > pstate_wait_expected_timeout_us)
148 				dm_logger_write(hubbub->ctx->logger, LOG_WARNING,
149 						"pstate took longer than expected ~%dus\n",
150 						i);
151 
152 			return true;
153 		}
154 		if (max_sampled_pstate_wait_us < i)
155 			max_sampled_pstate_wait_us = i;
156 
157 		udelay(1);
158 	}
159 
160 	/* force pstate allow to prevent system hang
161 	 * and break to debugger to investigate
162 	 */
163 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
164 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
165 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
166 	forced_pstate_allow = true;
167 
168 	dm_logger_write(hubbub->ctx->logger, LOG_WARNING,
169 			"pstate TEST_DEBUG_DATA: 0x%X\n",
170 			debug_data);
171 
172 	return false;
173 }
174 
175 static uint32_t convert_and_clamp(
176 	uint32_t wm_ns,
177 	uint32_t refclk_mhz,
178 	uint32_t clamp_value)
179 {
180 	uint32_t ret_val = 0;
181 	ret_val = wm_ns * refclk_mhz;
182 	ret_val /= 1000;
183 
184 	if (ret_val > clamp_value)
185 		ret_val = clamp_value;
186 
187 	return ret_val;
188 }
189 
190 
191 void hubbub1_program_watermarks(
192 		struct hubbub *hubbub,
193 		struct dcn_watermark_set *watermarks,
194 		unsigned int refclk_mhz)
195 {
196 	uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0;
197 	/*
198 	 * Need to clamp to max of the register values (i.e. no wrap)
199 	 * for dcn1, all wm registers are 21-bit wide
200 	 */
201 	uint32_t prog_wm_value;
202 
203 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
204 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0);
205 
206 	/* Repeat for water mark set A, B, C and D. */
207 	/* clock state A */
208 	prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
209 			refclk_mhz, 0x1fffff);
210 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
211 
212 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
213 		"URGENCY_WATERMARK_A calculated =%d\n"
214 		"HW register value = 0x%x\n",
215 		watermarks->a.urgent_ns, prog_wm_value);
216 
217 	prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
218 			refclk_mhz, 0x1fffff);
219 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
220 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
221 		"PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
222 		"HW register value = 0x%x\n",
223 		watermarks->a.pte_meta_urgent_ns, prog_wm_value);
224 
225 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
226 		prog_wm_value = convert_and_clamp(
227 				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
228 				refclk_mhz, 0x1fffff);
229 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
230 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
231 			"SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
232 			"HW register value = 0x%x\n",
233 			watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
234 
235 
236 		prog_wm_value = convert_and_clamp(
237 				watermarks->a.cstate_pstate.cstate_exit_ns,
238 				refclk_mhz, 0x1fffff);
239 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
240 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
241 			"SR_EXIT_WATERMARK_A calculated =%d\n"
242 			"HW register value = 0x%x\n",
243 			watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
244 	}
245 
246 	prog_wm_value = convert_and_clamp(
247 			watermarks->a.cstate_pstate.pstate_change_ns,
248 			refclk_mhz, 0x1fffff);
249 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
250 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
251 		"DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
252 		"HW register value = 0x%x\n\n",
253 		watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
254 
255 
256 	/* clock state B */
257 	prog_wm_value = convert_and_clamp(
258 			watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
259 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
260 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
261 		"URGENCY_WATERMARK_B calculated =%d\n"
262 		"HW register value = 0x%x\n",
263 		watermarks->b.urgent_ns, prog_wm_value);
264 
265 
266 	prog_wm_value = convert_and_clamp(
267 			watermarks->b.pte_meta_urgent_ns,
268 			refclk_mhz, 0x1fffff);
269 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
270 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
271 		"PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
272 		"HW register value = 0x%x\n",
273 		watermarks->b.pte_meta_urgent_ns, prog_wm_value);
274 
275 
276 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
277 		prog_wm_value = convert_and_clamp(
278 				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
279 				refclk_mhz, 0x1fffff);
280 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
281 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
282 			"SR_ENTER_WATERMARK_B calculated =%d\n"
283 			"HW register value = 0x%x\n",
284 			watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
285 
286 
287 		prog_wm_value = convert_and_clamp(
288 				watermarks->b.cstate_pstate.cstate_exit_ns,
289 				refclk_mhz, 0x1fffff);
290 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
291 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
292 			"SR_EXIT_WATERMARK_B calculated =%d\n"
293 			"HW register value = 0x%x\n",
294 			watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
295 	}
296 
297 	prog_wm_value = convert_and_clamp(
298 			watermarks->b.cstate_pstate.pstate_change_ns,
299 			refclk_mhz, 0x1fffff);
300 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
301 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
302 		"DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
303 		"HW register value = 0x%x\n",
304 		watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
305 
306 	/* clock state C */
307 	prog_wm_value = convert_and_clamp(
308 			watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
309 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
310 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
311 		"URGENCY_WATERMARK_C calculated =%d\n"
312 		"HW register value = 0x%x\n",
313 		watermarks->c.urgent_ns, prog_wm_value);
314 
315 
316 	prog_wm_value = convert_and_clamp(
317 			watermarks->c.pte_meta_urgent_ns,
318 			refclk_mhz, 0x1fffff);
319 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
320 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
321 		"PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
322 		"HW register value = 0x%x\n",
323 		watermarks->c.pte_meta_urgent_ns, prog_wm_value);
324 
325 
326 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
327 		prog_wm_value = convert_and_clamp(
328 				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
329 				refclk_mhz, 0x1fffff);
330 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
331 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
332 			"SR_ENTER_WATERMARK_C calculated =%d\n"
333 			"HW register value = 0x%x\n",
334 			watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
335 
336 
337 		prog_wm_value = convert_and_clamp(
338 				watermarks->c.cstate_pstate.cstate_exit_ns,
339 				refclk_mhz, 0x1fffff);
340 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
341 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
342 			"SR_EXIT_WATERMARK_C calculated =%d\n"
343 			"HW register value = 0x%x\n",
344 			watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
345 	}
346 
347 	prog_wm_value = convert_and_clamp(
348 			watermarks->c.cstate_pstate.pstate_change_ns,
349 			refclk_mhz, 0x1fffff);
350 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
351 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
352 		"DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
353 		"HW register value = 0x%x\n",
354 		watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
355 
356 	/* clock state D */
357 	prog_wm_value = convert_and_clamp(
358 			watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
359 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
360 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
361 		"URGENCY_WATERMARK_D calculated =%d\n"
362 		"HW register value = 0x%x\n",
363 		watermarks->d.urgent_ns, prog_wm_value);
364 
365 	prog_wm_value = convert_and_clamp(
366 			watermarks->d.pte_meta_urgent_ns,
367 			refclk_mhz, 0x1fffff);
368 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
369 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
370 		"PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
371 		"HW register value = 0x%x\n",
372 		watermarks->d.pte_meta_urgent_ns, prog_wm_value);
373 
374 
375 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
376 		prog_wm_value = convert_and_clamp(
377 				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
378 				refclk_mhz, 0x1fffff);
379 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
380 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
381 			"SR_ENTER_WATERMARK_D calculated =%d\n"
382 			"HW register value = 0x%x\n",
383 			watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
384 
385 
386 		prog_wm_value = convert_and_clamp(
387 				watermarks->d.cstate_pstate.cstate_exit_ns,
388 				refclk_mhz, 0x1fffff);
389 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
390 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
391 			"SR_EXIT_WATERMARK_D calculated =%d\n"
392 			"HW register value = 0x%x\n",
393 			watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
394 	}
395 
396 
397 	prog_wm_value = convert_and_clamp(
398 			watermarks->d.cstate_pstate.pstate_change_ns,
399 			refclk_mhz, 0x1fffff);
400 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
401 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
402 		"DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
403 		"HW register value = 0x%x\n\n",
404 		watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
405 
406 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
407 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
408 
409 	REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
410 			DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
411 	REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
412 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
413 
414 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
415 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
416 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en);
417 
418 #if 0
419 	REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
420 			DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
421 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
422 #endif
423 }
424 
425 void hubbub1_update_dchub(
426 	struct hubbub *hubbub,
427 	struct dchub_init_data *dh_data)
428 {
429 	/* TODO: port code from dal2 */
430 	switch (dh_data->fb_mode) {
431 	case FRAME_BUFFER_MODE_ZFB_ONLY:
432 		/*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
433 		REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP,
434 				SDPIF_FB_TOP, 0);
435 
436 		REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE,
437 				SDPIF_FB_BASE, 0x0FFFF);
438 
439 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
440 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
441 
442 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
443 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
444 
445 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
446 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
447 						dh_data->zfb_size_in_byte - 1) >> 22);
448 		break;
449 	case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
450 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
451 
452 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
453 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
454 
455 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
456 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
457 
458 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
459 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
460 						dh_data->zfb_size_in_byte - 1) >> 22);
461 		break;
462 	case FRAME_BUFFER_MODE_LOCAL_ONLY:
463 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
464 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
465 				SDPIF_AGP_BASE, 0);
466 
467 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
468 				SDPIF_AGP_BOT, 0X03FFFF);
469 
470 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
471 				SDPIF_AGP_TOP, 0);
472 		break;
473 	default:
474 		break;
475 	}
476 
477 	dh_data->dchub_initialzied = true;
478 	dh_data->dchub_info_valid = false;
479 }
480 
481 void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub)
482 {
483 	uint32_t watermark_change_req;
484 
485 	REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
486 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req);
487 
488 	if (watermark_change_req)
489 		watermark_change_req = 0;
490 	else
491 		watermark_change_req = 1;
492 
493 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
494 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req);
495 }
496 
497 static const struct hubbub_funcs hubbub1_funcs = {
498 	.update_dchub = hubbub1_update_dchub
499 };
500 
501 void hubbub1_construct(struct hubbub *hubbub,
502 	struct dc_context *ctx,
503 	const struct dcn_hubbub_registers *hubbub_regs,
504 	const struct dcn_hubbub_shift *hubbub_shift,
505 	const struct dcn_hubbub_mask *hubbub_mask)
506 {
507 	hubbub->ctx = ctx;
508 
509 	hubbub->funcs = &hubbub1_funcs;
510 
511 	hubbub->regs = hubbub_regs;
512 	hubbub->shifts = hubbub_shift;
513 	hubbub->masks = hubbub_mask;
514 
515 }
516 
517