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