xref: /openbmc/linux/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c (revision 2e35facf82bcdd9b9eb9129f4fb31127b79249ec)
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 	hubbub1->base.ctx
33 #define DC_LOGGER \
34 	hubbub1->base.ctx->logger
35 #define REG(reg)\
36 	hubbub1->regs->reg
37 
38 #undef FN
39 #define FN(reg_name, field_name) \
40 	hubbub1->shifts->field_name, hubbub1->masks->field_name
41 
42 void hubbub1_wm_read_state(struct hubbub *hubbub,
43 		struct dcn_hubbub_wm *wm)
44 {
45 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
46 	struct dcn_hubbub_wm_set *s;
47 
48 	memset(wm, 0, sizeof(struct dcn_hubbub_wm));
49 
50 	s = &wm->sets[0];
51 	s->wm_set = 0;
52 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);
53 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A);
54 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
55 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A);
56 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A);
57 	}
58 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A);
59 
60 	s = &wm->sets[1];
61 	s->wm_set = 1;
62 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B);
63 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B);
64 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
65 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B);
66 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B);
67 	}
68 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B);
69 
70 	s = &wm->sets[2];
71 	s->wm_set = 2;
72 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C);
73 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C);
74 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
75 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C);
76 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C);
77 	}
78 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C);
79 
80 	s = &wm->sets[3];
81 	s->wm_set = 3;
82 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D);
83 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D);
84 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
85 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D);
86 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D);
87 	}
88 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D);
89 }
90 
91 void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow)
92 {
93 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
94 
95 	/*
96 	 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 1 means do not allow stutter
97 	 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0 means allow stutter
98 	 */
99 
100 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
101 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
102 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow);
103 }
104 
105 bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
106 {
107 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
108 	uint32_t enable = 0;
109 
110 	REG_GET(DCHUBBUB_ARB_DRAM_STATE_CNTL,
111 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, &enable);
112 
113 	return enable ? true : false;
114 }
115 
116 
117 bool hubbub1_verify_allow_pstate_change_high(
118 	struct hubbub *hubbub)
119 {
120 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
121 
122 	/* pstate latency is ~20us so if we wait over 40us and pstate allow
123 	 * still not asserted, we are probably stuck and going to hang
124 	 *
125 	 * TODO: Figure out why it takes ~100us on linux
126 	 * pstate takes around ~100us on linux. Unknown currently as to
127 	 * why it takes that long on linux
128 	 */
129 	static unsigned int pstate_wait_timeout_us = 200;
130 	static unsigned int pstate_wait_expected_timeout_us = 40;
131 	static unsigned int max_sampled_pstate_wait_us; /* data collection */
132 	static bool forced_pstate_allow; /* help with revert wa */
133 
134 	unsigned int debug_data;
135 	unsigned int i;
136 
137 	if (forced_pstate_allow) {
138 		/* we hacked to force pstate allow to prevent hang last time
139 		 * we verify_allow_pstate_change_high.  so disable force
140 		 * here so we can check status
141 		 */
142 		REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
143 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
144 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
145 		forced_pstate_allow = false;
146 	}
147 
148 	/* RV2:
149 	 * dchubbubdebugind, at: 0xB
150 	 * description
151 	 * 0:     Pipe0 Plane0 Allow Pstate Change
152 	 * 1:     Pipe0 Plane1 Allow Pstate Change
153 	 * 2:     Pipe0 Cursor0 Allow Pstate Change
154 	 * 3:     Pipe0 Cursor1 Allow Pstate Change
155 	 * 4:     Pipe1 Plane0 Allow Pstate Change
156 	 * 5:     Pipe1 Plane1 Allow Pstate Change
157 	 * 6:     Pipe1 Cursor0 Allow Pstate Change
158 	 * 7:     Pipe1 Cursor1 Allow Pstate Change
159 	 * 8:     Pipe2 Plane0 Allow Pstate Change
160 	 * 9:     Pipe2 Plane1 Allow Pstate Change
161 	 * 10:    Pipe2 Cursor0 Allow Pstate Change
162 	 * 11:    Pipe2 Cursor1 Allow Pstate Change
163 	 * 12:    Pipe3 Plane0 Allow Pstate Change
164 	 * 13:    Pipe3 Plane1 Allow Pstate Change
165 	 * 14:    Pipe3 Cursor0 Allow Pstate Change
166 	 * 15:    Pipe3 Cursor1 Allow Pstate Change
167 	 * 16:    Pipe4 Plane0 Allow Pstate Change
168 	 * 17:    Pipe4 Plane1 Allow Pstate Change
169 	 * 18:    Pipe4 Cursor0 Allow Pstate Change
170 	 * 19:    Pipe4 Cursor1 Allow Pstate Change
171 	 * 20:    Pipe5 Plane0 Allow Pstate Change
172 	 * 21:    Pipe5 Plane1 Allow Pstate Change
173 	 * 22:    Pipe5 Cursor0 Allow Pstate Change
174 	 * 23:    Pipe5 Cursor1 Allow Pstate Change
175 	 * 24:    Pipe6 Plane0 Allow Pstate Change
176 	 * 25:    Pipe6 Plane1 Allow Pstate Change
177 	 * 26:    Pipe6 Cursor0 Allow Pstate Change
178 	 * 27:    Pipe6 Cursor1 Allow Pstate Change
179 	 * 28:    WB0 Allow Pstate Change
180 	 * 29:    WB1 Allow Pstate Change
181 	 * 30:    Arbiter's allow_pstate_change
182 	 * 31:    SOC pstate change request"
183 	 *
184 	 * RV1:
185 	 * dchubbubdebugind, at: 0x7
186 	 * description "3-0:   Pipe0 cursor0 QOS
187 	 * 7-4:   Pipe1 cursor0 QOS
188 	 * 11-8:  Pipe2 cursor0 QOS
189 	 * 15-12: Pipe3 cursor0 QOS
190 	 * 16:    Pipe0 Plane0 Allow Pstate Change
191 	 * 17:    Pipe1 Plane0 Allow Pstate Change
192 	 * 18:    Pipe2 Plane0 Allow Pstate Change
193 	 * 19:    Pipe3 Plane0 Allow Pstate Change
194 	 * 20:    Pipe0 Plane1 Allow Pstate Change
195 	 * 21:    Pipe1 Plane1 Allow Pstate Change
196 	 * 22:    Pipe2 Plane1 Allow Pstate Change
197 	 * 23:    Pipe3 Plane1 Allow Pstate Change
198 	 * 24:    Pipe0 cursor0 Allow Pstate Change
199 	 * 25:    Pipe1 cursor0 Allow Pstate Change
200 	 * 26:    Pipe2 cursor0 Allow Pstate Change
201 	 * 27:    Pipe3 cursor0 Allow Pstate Change
202 	 * 28:    WB0 Allow Pstate Change
203 	 * 29:    WB1 Allow Pstate Change
204 	 * 30:    Arbiter's allow_pstate_change
205 	 * 31:    SOC pstate change request
206 	 */
207 
208 	REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub1->debug_test_index_pstate);
209 
210 	for (i = 0; i < pstate_wait_timeout_us; i++) {
211 		debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
212 
213 		if (debug_data & (1 << 30)) {
214 
215 			if (i > pstate_wait_expected_timeout_us)
216 				DC_LOG_WARNING("pstate took longer than expected ~%dus\n",
217 						i);
218 
219 			return true;
220 		}
221 		if (max_sampled_pstate_wait_us < i)
222 			max_sampled_pstate_wait_us = i;
223 
224 		udelay(1);
225 	}
226 
227 	/* force pstate allow to prevent system hang
228 	 * and break to debugger to investigate
229 	 */
230 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
231 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
232 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
233 	forced_pstate_allow = true;
234 
235 	DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n",
236 			debug_data);
237 
238 	return false;
239 }
240 
241 static uint32_t convert_and_clamp(
242 	uint32_t wm_ns,
243 	uint32_t refclk_mhz,
244 	uint32_t clamp_value)
245 {
246 	uint32_t ret_val = 0;
247 	ret_val = wm_ns * refclk_mhz;
248 	ret_val /= 1000;
249 
250 	if (ret_val > clamp_value)
251 		ret_val = clamp_value;
252 
253 	return ret_val;
254 }
255 
256 
257 void hubbub1_wm_change_req_wa(struct hubbub *hubbub)
258 {
259 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
260 
261 	REG_UPDATE_SEQ_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
262 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0,
263 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
264 }
265 
266 void hubbub1_program_urgent_watermarks(
267 		struct hubbub *hubbub,
268 		struct dcn_watermark_set *watermarks,
269 		unsigned int refclk_mhz,
270 		bool safe_to_lower)
271 {
272 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
273 	uint32_t prog_wm_value;
274 
275 	/* Repeat for water mark set A, B, C and D. */
276 	/* clock state A */
277 	if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) {
278 		hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
279 		prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
280 				refclk_mhz, 0x1fffff);
281 		REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
282 				DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
283 
284 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
285 			"HW register value = 0x%x\n",
286 			watermarks->a.urgent_ns, prog_wm_value);
287 	}
288 
289 	if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub1->watermarks.a.pte_meta_urgent_ns) {
290 		hubbub1->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns;
291 		prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
292 				refclk_mhz, 0x1fffff);
293 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
294 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
295 			"HW register value = 0x%x\n",
296 			watermarks->a.pte_meta_urgent_ns, prog_wm_value);
297 	}
298 
299 	/* clock state B */
300 	if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) {
301 		hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
302 		prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
303 				refclk_mhz, 0x1fffff);
304 		REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
305 				DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
306 
307 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
308 			"HW register value = 0x%x\n",
309 			watermarks->b.urgent_ns, prog_wm_value);
310 	}
311 
312 	if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub1->watermarks.b.pte_meta_urgent_ns) {
313 		hubbub1->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns;
314 		prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns,
315 				refclk_mhz, 0x1fffff);
316 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
317 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
318 			"HW register value = 0x%x\n",
319 			watermarks->b.pte_meta_urgent_ns, prog_wm_value);
320 	}
321 
322 	/* clock state C */
323 	if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) {
324 		hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
325 		prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
326 				refclk_mhz, 0x1fffff);
327 		REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
328 				DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
329 
330 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
331 			"HW register value = 0x%x\n",
332 			watermarks->c.urgent_ns, prog_wm_value);
333 	}
334 
335 	if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub1->watermarks.c.pte_meta_urgent_ns) {
336 		hubbub1->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns;
337 		prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns,
338 				refclk_mhz, 0x1fffff);
339 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
340 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
341 			"HW register value = 0x%x\n",
342 			watermarks->c.pte_meta_urgent_ns, prog_wm_value);
343 	}
344 
345 	/* clock state D */
346 	if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) {
347 		hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
348 		prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
349 				refclk_mhz, 0x1fffff);
350 		REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
351 				DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
352 
353 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
354 			"HW register value = 0x%x\n",
355 			watermarks->d.urgent_ns, prog_wm_value);
356 	}
357 
358 	if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub1->watermarks.d.pte_meta_urgent_ns) {
359 		hubbub1->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns;
360 		prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns,
361 				refclk_mhz, 0x1fffff);
362 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
363 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
364 			"HW register value = 0x%x\n",
365 			watermarks->d.pte_meta_urgent_ns, prog_wm_value);
366 	}
367 }
368 
369 void hubbub1_program_stutter_watermarks(
370 		struct hubbub *hubbub,
371 		struct dcn_watermark_set *watermarks,
372 		unsigned int refclk_mhz,
373 		bool safe_to_lower)
374 {
375 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
376 	uint32_t prog_wm_value;
377 
378 	/* clock state A */
379 	if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
380 			> hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
381 		hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
382 				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
383 		prog_wm_value = convert_and_clamp(
384 				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
385 				refclk_mhz, 0x1fffff);
386 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
387 				DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
388 		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
389 			"HW register value = 0x%x\n",
390 			watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
391 	}
392 
393 	if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
394 			> hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) {
395 		hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns =
396 				watermarks->a.cstate_pstate.cstate_exit_ns;
397 		prog_wm_value = convert_and_clamp(
398 				watermarks->a.cstate_pstate.cstate_exit_ns,
399 				refclk_mhz, 0x1fffff);
400 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
401 				DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
402 		DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
403 			"HW register value = 0x%x\n",
404 			watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
405 	}
406 
407 	/* clock state B */
408 	if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
409 			> hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
410 		hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
411 				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
412 		prog_wm_value = convert_and_clamp(
413 				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
414 				refclk_mhz, 0x1fffff);
415 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
416 				DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
417 		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
418 			"HW register value = 0x%x\n",
419 			watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
420 	}
421 
422 	if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
423 			> hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) {
424 		hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns =
425 				watermarks->b.cstate_pstate.cstate_exit_ns;
426 		prog_wm_value = convert_and_clamp(
427 				watermarks->b.cstate_pstate.cstate_exit_ns,
428 				refclk_mhz, 0x1fffff);
429 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
430 				DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
431 		DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
432 			"HW register value = 0x%x\n",
433 			watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
434 	}
435 
436 	/* clock state C */
437 	if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
438 			> hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
439 		hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
440 				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
441 		prog_wm_value = convert_and_clamp(
442 				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
443 				refclk_mhz, 0x1fffff);
444 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
445 				DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
446 		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
447 			"HW register value = 0x%x\n",
448 			watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
449 	}
450 
451 	if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
452 			> hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) {
453 		hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns =
454 				watermarks->c.cstate_pstate.cstate_exit_ns;
455 		prog_wm_value = convert_and_clamp(
456 				watermarks->c.cstate_pstate.cstate_exit_ns,
457 				refclk_mhz, 0x1fffff);
458 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
459 				DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
460 		DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
461 			"HW register value = 0x%x\n",
462 			watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
463 	}
464 
465 	/* clock state D */
466 	if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
467 			> hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
468 		hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
469 				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
470 		prog_wm_value = convert_and_clamp(
471 				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
472 				refclk_mhz, 0x1fffff);
473 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
474 				DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
475 		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
476 			"HW register value = 0x%x\n",
477 			watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
478 	}
479 
480 	if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
481 			> hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) {
482 		hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns =
483 				watermarks->d.cstate_pstate.cstate_exit_ns;
484 		prog_wm_value = convert_and_clamp(
485 				watermarks->d.cstate_pstate.cstate_exit_ns,
486 				refclk_mhz, 0x1fffff);
487 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
488 				DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
489 		DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
490 			"HW register value = 0x%x\n",
491 			watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
492 	}
493 
494 }
495 
496 void hubbub1_program_pstate_watermarks(
497 		struct hubbub *hubbub,
498 		struct dcn_watermark_set *watermarks,
499 		unsigned int refclk_mhz,
500 		bool safe_to_lower)
501 {
502 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
503 	uint32_t prog_wm_value;
504 
505 	/* clock state A */
506 	if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
507 			> hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) {
508 		hubbub1->watermarks.a.cstate_pstate.pstate_change_ns =
509 				watermarks->a.cstate_pstate.pstate_change_ns;
510 		prog_wm_value = convert_and_clamp(
511 				watermarks->a.cstate_pstate.pstate_change_ns,
512 				refclk_mhz, 0x1fffff);
513 		REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0,
514 				DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
515 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
516 			"HW register value = 0x%x\n\n",
517 			watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
518 	}
519 
520 	/* clock state B */
521 	if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
522 			> hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) {
523 		hubbub1->watermarks.b.cstate_pstate.pstate_change_ns =
524 				watermarks->b.cstate_pstate.pstate_change_ns;
525 		prog_wm_value = convert_and_clamp(
526 				watermarks->b.cstate_pstate.pstate_change_ns,
527 				refclk_mhz, 0x1fffff);
528 		REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0,
529 				DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
530 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
531 			"HW register value = 0x%x\n\n",
532 			watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
533 	}
534 
535 	/* clock state C */
536 	if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
537 			> hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) {
538 		hubbub1->watermarks.c.cstate_pstate.pstate_change_ns =
539 				watermarks->c.cstate_pstate.pstate_change_ns;
540 		prog_wm_value = convert_and_clamp(
541 				watermarks->c.cstate_pstate.pstate_change_ns,
542 				refclk_mhz, 0x1fffff);
543 		REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0,
544 				DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
545 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
546 			"HW register value = 0x%x\n\n",
547 			watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
548 	}
549 
550 	/* clock state D */
551 	if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
552 			> hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) {
553 		hubbub1->watermarks.d.cstate_pstate.pstate_change_ns =
554 				watermarks->d.cstate_pstate.pstate_change_ns;
555 		prog_wm_value = convert_and_clamp(
556 				watermarks->d.cstate_pstate.pstate_change_ns,
557 				refclk_mhz, 0x1fffff);
558 		REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0,
559 				DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
560 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
561 			"HW register value = 0x%x\n\n",
562 			watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
563 	}
564 }
565 
566 void hubbub1_program_watermarks(
567 		struct hubbub *hubbub,
568 		struct dcn_watermark_set *watermarks,
569 		unsigned int refclk_mhz,
570 		bool safe_to_lower)
571 {
572 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
573 	/*
574 	 * Need to clamp to max of the register values (i.e. no wrap)
575 	 * for dcn1, all wm registers are 21-bit wide
576 	 */
577 	hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
578 	hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
579 	hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
580 
581 	REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
582 			DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
583 	REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
584 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
585 
586 	hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
587 
588 #if 0
589 	REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
590 			DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
591 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
592 #endif
593 }
594 
595 void hubbub1_update_dchub(
596 	struct hubbub *hubbub,
597 	struct dchub_init_data *dh_data)
598 {
599 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
600 
601 	if (REG(DCHUBBUB_SDPIF_FB_TOP) == 0) {
602 		ASSERT(false);
603 		/*should not come here*/
604 		return;
605 	}
606 	/* TODO: port code from dal2 */
607 	switch (dh_data->fb_mode) {
608 	case FRAME_BUFFER_MODE_ZFB_ONLY:
609 		/*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
610 		REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP,
611 				SDPIF_FB_TOP, 0);
612 
613 		REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE,
614 				SDPIF_FB_BASE, 0x0FFFF);
615 
616 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
617 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
618 
619 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
620 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
621 
622 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
623 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
624 						dh_data->zfb_size_in_byte - 1) >> 22);
625 		break;
626 	case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
627 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
628 
629 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
630 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
631 
632 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
633 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
634 
635 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
636 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
637 						dh_data->zfb_size_in_byte - 1) >> 22);
638 		break;
639 	case FRAME_BUFFER_MODE_LOCAL_ONLY:
640 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
641 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
642 				SDPIF_AGP_BASE, 0);
643 
644 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
645 				SDPIF_AGP_BOT, 0X03FFFF);
646 
647 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
648 				SDPIF_AGP_TOP, 0);
649 		break;
650 	default:
651 		break;
652 	}
653 
654 	dh_data->dchub_initialzied = true;
655 	dh_data->dchub_info_valid = false;
656 }
657 
658 void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub)
659 {
660 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
661 
662 	uint32_t watermark_change_req;
663 
664 	REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
665 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req);
666 
667 	if (watermark_change_req)
668 		watermark_change_req = 0;
669 	else
670 		watermark_change_req = 1;
671 
672 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
673 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req);
674 }
675 
676 void hubbub1_soft_reset(struct hubbub *hubbub, bool reset)
677 {
678 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
679 
680 	uint32_t reset_en = reset ? 1 : 0;
681 
682 	REG_UPDATE(DCHUBBUB_SOFT_RESET,
683 			DCHUBBUB_GLOBAL_SOFT_RESET, reset_en);
684 }
685 
686 static bool hubbub1_dcc_support_swizzle(
687 		enum swizzle_mode_values swizzle,
688 		unsigned int bytes_per_element,
689 		enum segment_order *segment_order_horz,
690 		enum segment_order *segment_order_vert)
691 {
692 	bool standard_swizzle = false;
693 	bool display_swizzle = false;
694 
695 	switch (swizzle) {
696 	case DC_SW_4KB_S:
697 	case DC_SW_64KB_S:
698 	case DC_SW_VAR_S:
699 	case DC_SW_4KB_S_X:
700 	case DC_SW_64KB_S_X:
701 	case DC_SW_VAR_S_X:
702 		standard_swizzle = true;
703 		break;
704 	case DC_SW_4KB_D:
705 	case DC_SW_64KB_D:
706 	case DC_SW_VAR_D:
707 	case DC_SW_4KB_D_X:
708 	case DC_SW_64KB_D_X:
709 	case DC_SW_VAR_D_X:
710 		display_swizzle = true;
711 		break;
712 	default:
713 		break;
714 	}
715 
716 	if (bytes_per_element == 1 && standard_swizzle) {
717 		*segment_order_horz = segment_order__contiguous;
718 		*segment_order_vert = segment_order__na;
719 		return true;
720 	}
721 	if (bytes_per_element == 2 && standard_swizzle) {
722 		*segment_order_horz = segment_order__non_contiguous;
723 		*segment_order_vert = segment_order__contiguous;
724 		return true;
725 	}
726 	if (bytes_per_element == 4 && standard_swizzle) {
727 		*segment_order_horz = segment_order__non_contiguous;
728 		*segment_order_vert = segment_order__contiguous;
729 		return true;
730 	}
731 	if (bytes_per_element == 8 && standard_swizzle) {
732 		*segment_order_horz = segment_order__na;
733 		*segment_order_vert = segment_order__contiguous;
734 		return true;
735 	}
736 	if (bytes_per_element == 8 && display_swizzle) {
737 		*segment_order_horz = segment_order__contiguous;
738 		*segment_order_vert = segment_order__non_contiguous;
739 		return true;
740 	}
741 
742 	return false;
743 }
744 
745 static bool hubbub1_dcc_support_pixel_format(
746 		enum surface_pixel_format format,
747 		unsigned int *bytes_per_element)
748 {
749 	/* DML: get_bytes_per_element */
750 	switch (format) {
751 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
752 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
753 		*bytes_per_element = 2;
754 		return true;
755 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
756 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
757 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
758 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
759 		*bytes_per_element = 4;
760 		return true;
761 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
762 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
763 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
764 		*bytes_per_element = 8;
765 		return true;
766 	default:
767 		return false;
768 	}
769 }
770 
771 static void hubbub1_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height,
772 		unsigned int bytes_per_element)
773 {
774 	/* copied from DML.  might want to refactor DML to leverage from DML */
775 	/* DML : get_blk256_size */
776 	if (bytes_per_element == 1) {
777 		*blk256_width = 16;
778 		*blk256_height = 16;
779 	} else if (bytes_per_element == 2) {
780 		*blk256_width = 16;
781 		*blk256_height = 8;
782 	} else if (bytes_per_element == 4) {
783 		*blk256_width = 8;
784 		*blk256_height = 8;
785 	} else if (bytes_per_element == 8) {
786 		*blk256_width = 8;
787 		*blk256_height = 4;
788 	}
789 }
790 
791 static void hubbub1_det_request_size(
792 		unsigned int height,
793 		unsigned int width,
794 		unsigned int bpe,
795 		bool *req128_horz_wc,
796 		bool *req128_vert_wc)
797 {
798 	unsigned int detile_buf_size = 164 * 1024;  /* 164KB for DCN1.0 */
799 
800 	unsigned int blk256_height = 0;
801 	unsigned int blk256_width = 0;
802 	unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
803 
804 	hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe);
805 
806 	swath_bytes_horz_wc = height * blk256_height * bpe;
807 	swath_bytes_vert_wc = width * blk256_width * bpe;
808 
809 	*req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ?
810 			false : /* full 256B request */
811 			true; /* half 128b request */
812 
813 	*req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ?
814 			false : /* full 256B request */
815 			true; /* half 128b request */
816 }
817 
818 static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub,
819 		const struct dc_dcc_surface_param *input,
820 		struct dc_surface_dcc_cap *output)
821 {
822 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
823 	struct dc *dc = hubbub1->base.ctx->dc;
824 
825 	/* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */
826 	enum dcc_control dcc_control;
827 	unsigned int bpe;
828 	enum segment_order segment_order_horz, segment_order_vert;
829 	bool req128_horz_wc, req128_vert_wc;
830 
831 	memset(output, 0, sizeof(*output));
832 
833 	if (dc->debug.disable_dcc == DCC_DISABLE)
834 		return false;
835 
836 	if (!hubbub1->base.funcs->dcc_support_pixel_format(input->format, &bpe))
837 		return false;
838 
839 	if (!hubbub1->base.funcs->dcc_support_swizzle(input->swizzle_mode, bpe,
840 			&segment_order_horz, &segment_order_vert))
841 		return false;
842 
843 	hubbub1_det_request_size(input->surface_size.height,  input->surface_size.width,
844 			bpe, &req128_horz_wc, &req128_vert_wc);
845 
846 	if (!req128_horz_wc && !req128_vert_wc) {
847 		dcc_control = dcc_control__256_256_xxx;
848 	} else if (input->scan == SCAN_DIRECTION_HORIZONTAL) {
849 		if (!req128_horz_wc)
850 			dcc_control = dcc_control__256_256_xxx;
851 		else if (segment_order_horz == segment_order__contiguous)
852 			dcc_control = dcc_control__128_128_xxx;
853 		else
854 			dcc_control = dcc_control__256_64_64;
855 	} else if (input->scan == SCAN_DIRECTION_VERTICAL) {
856 		if (!req128_vert_wc)
857 			dcc_control = dcc_control__256_256_xxx;
858 		else if (segment_order_vert == segment_order__contiguous)
859 			dcc_control = dcc_control__128_128_xxx;
860 		else
861 			dcc_control = dcc_control__256_64_64;
862 	} else {
863 		if ((req128_horz_wc &&
864 			segment_order_horz == segment_order__non_contiguous) ||
865 			(req128_vert_wc &&
866 			segment_order_vert == segment_order__non_contiguous))
867 			/* access_dir not known, must use most constraining */
868 			dcc_control = dcc_control__256_64_64;
869 		else
870 			/* reg128 is true for either horz and vert
871 			 * but segment_order is contiguous
872 			 */
873 			dcc_control = dcc_control__128_128_xxx;
874 	}
875 
876 	if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
877 		dcc_control != dcc_control__256_256_xxx)
878 		return false;
879 
880 	switch (dcc_control) {
881 	case dcc_control__256_256_xxx:
882 		output->grph.rgb.max_uncompressed_blk_size = 256;
883 		output->grph.rgb.max_compressed_blk_size = 256;
884 		output->grph.rgb.independent_64b_blks = false;
885 		break;
886 	case dcc_control__128_128_xxx:
887 		output->grph.rgb.max_uncompressed_blk_size = 128;
888 		output->grph.rgb.max_compressed_blk_size = 128;
889 		output->grph.rgb.independent_64b_blks = false;
890 		break;
891 	case dcc_control__256_64_64:
892 		output->grph.rgb.max_uncompressed_blk_size = 256;
893 		output->grph.rgb.max_compressed_blk_size = 64;
894 		output->grph.rgb.independent_64b_blks = true;
895 		break;
896 	}
897 
898 	output->capable = true;
899 	output->const_color_support = false;
900 
901 	return true;
902 }
903 
904 static const struct hubbub_funcs hubbub1_funcs = {
905 	.update_dchub = hubbub1_update_dchub,
906 	.dcc_support_swizzle = hubbub1_dcc_support_swizzle,
907 	.dcc_support_pixel_format = hubbub1_dcc_support_pixel_format,
908 	.get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
909 	.wm_read_state = hubbub1_wm_read_state,
910 	.program_watermarks = hubbub1_program_watermarks,
911 };
912 
913 void hubbub1_construct(struct hubbub *hubbub,
914 	struct dc_context *ctx,
915 	const struct dcn_hubbub_registers *hubbub_regs,
916 	const struct dcn_hubbub_shift *hubbub_shift,
917 	const struct dcn_hubbub_mask *hubbub_mask)
918 {
919 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
920 
921 	hubbub1->base.ctx = ctx;
922 
923 	hubbub1->base.funcs = &hubbub1_funcs;
924 
925 	hubbub1->regs = hubbub_regs;
926 	hubbub1->shifts = hubbub_shift;
927 	hubbub1->masks = hubbub_mask;
928 
929 	hubbub1->debug_test_index_pstate = 0x7;
930 	if (ctx->dce_version == DCN_VERSION_1_01)
931 		hubbub1->debug_test_index_pstate = 0xB;
932 }
933 
934