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