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 <linux/delay.h> 27 28 #include "dm_services.h" 29 #include "dcn10_hubp.h" 30 #include "dcn10_hubbub.h" 31 #include "reg_helper.h" 32 33 #define CTX \ 34 hubbub1->base.ctx 35 #define DC_LOGGER \ 36 hubbub1->base.ctx->logger 37 #define REG(reg)\ 38 hubbub1->regs->reg 39 40 #undef FN 41 #define FN(reg_name, field_name) \ 42 hubbub1->shifts->field_name, hubbub1->masks->field_name 43 44 void hubbub1_wm_read_state(struct hubbub *hubbub, 45 struct dcn_hubbub_wm *wm) 46 { 47 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 48 struct dcn_hubbub_wm_set *s; 49 50 memset(wm, 0, sizeof(struct dcn_hubbub_wm)); 51 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); 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 } 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); 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 } 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); 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 } 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); 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 } 90 s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D); 91 } 92 93 void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow) 94 { 95 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 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); 105 } 106 107 bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubbub) 108 { 109 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 110 uint32_t enable = 0; 111 112 REG_GET(DCHUBBUB_ARB_DRAM_STATE_CNTL, 113 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, &enable); 114 115 return enable ? true : false; 116 } 117 118 119 bool hubbub1_verify_allow_pstate_change_high( 120 struct hubbub *hubbub) 121 { 122 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 123 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 */ 135 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 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" 185 */ 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 */ 221 /* RV1: 222 * dchubbubdebugind, at: 0x7 223 * description "3-0: Pipe0 cursor0 QOS 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 245 REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub1->debug_test_index_pstate); 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) 253 DC_LOG_WARNING("pstate took longer than expected ~%dus\n", 254 i); 255 256 return true; 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 272 DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n", 273 debug_data); 274 275 return false; 276 } 277 278 static 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 294 void hubbub1_wm_change_req_wa(struct hubbub *hubbub) 295 { 296 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 297 298 REG_UPDATE_SEQ_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 299 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0, 300 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); 301 } 302 303 void hubbub1_program_urgent_watermarks( 304 struct hubbub *hubbub, 305 struct dcn_watermark_set *watermarks, 306 unsigned int refclk_mhz, 307 bool safe_to_lower) 308 { 309 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 310 uint32_t prog_wm_value; 311 312 /* Repeat for water mark set A, B, C and D. */ 313 /* clock state A */ 314 if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) { 315 hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns; 316 prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, 317 refclk_mhz, 0x1fffff); 318 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0, 319 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 320 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 } 325 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, 329 refclk_mhz, 0x1fffff); 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); 334 } 335 336 /* clock state B */ 337 if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { 338 hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns; 339 prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, 340 refclk_mhz, 0x1fffff); 341 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0, 342 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); 343 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 } 348 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, 352 refclk_mhz, 0x1fffff); 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); 357 } 358 359 /* clock state C */ 360 if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { 361 hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns; 362 prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, 363 refclk_mhz, 0x1fffff); 364 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0, 365 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); 366 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 } 371 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, 375 refclk_mhz, 0x1fffff); 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); 380 } 381 382 /* clock state D */ 383 if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { 384 hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; 385 prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, 386 refclk_mhz, 0x1fffff); 387 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0, 388 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); 389 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 } 394 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 406 void 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); 428 } 429 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 } 443 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); 457 } 458 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 533 void 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 */ 588 if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns 589 > hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) { 590 hubbub1->watermarks.d.cstate_pstate.pstate_change_ns = 591 watermarks->d.cstate_pstate.pstate_change_ns; 592 prog_wm_value = convert_and_clamp( 593 watermarks->d.cstate_pstate.pstate_change_ns, 594 refclk_mhz, 0x1fffff); 595 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0, 596 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 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); 600 } 601 } 602 603 void 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); 617 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 623 hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); 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 632 void hubbub1_update_dchub( 633 struct hubbub *hubbub, 634 struct dchub_init_data *dh_data) 635 { 636 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 637 638 if (REG(DCHUBBUB_SDPIF_FB_TOP) == 0) { 639 ASSERT(false); 640 /*should not come here*/ 641 return; 642 } 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 695 void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub) 696 { 697 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 698 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 713 void hubbub1_soft_reset(struct hubbub *hubbub, bool reset) 714 { 715 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 716 717 uint32_t reset_en = reset ? 1 : 0; 718 719 REG_UPDATE(DCHUBBUB_SOFT_RESET, 720 DCHUBBUB_GLOBAL_SOFT_RESET, reset_en); 721 } 722 723 static 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 782 static 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 808 static 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 828 static 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 843 swath_bytes_horz_wc = height * blk256_height * bpe; 844 swath_bytes_vert_wc = width * blk256_width * bpe; 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 855 static 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 { 859 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 860 struct dc *dc = hubbub1->base.ctx->dc; 861 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 873 if (!hubbub1->base.funcs->dcc_support_pixel_format(input->format, &bpe)) 874 return false; 875 876 if (!hubbub1->base.funcs->dcc_support_swizzle(input->swizzle_mode, bpe, 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; 933 } 934 935 output->capable = true; 936 output->const_color_support = false; 937 938 return true; 939 } 940 941 static const struct hubbub_funcs hubbub1_funcs = { 942 .update_dchub = hubbub1_update_dchub, 943 .dcc_support_swizzle = hubbub1_dcc_support_swizzle, 944 .dcc_support_pixel_format = hubbub1_dcc_support_pixel_format, 945 .get_dcc_compression_cap = hubbub1_get_dcc_compression_cap, 946 .wm_read_state = hubbub1_wm_read_state, 947 .program_watermarks = hubbub1_program_watermarks, 948 .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, 949 .allow_self_refresh_control = hubbub1_allow_self_refresh_control, 950 }; 951 952 void hubbub1_construct(struct hubbub *hubbub, 953 struct dc_context *ctx, 954 const struct dcn_hubbub_registers *hubbub_regs, 955 const struct dcn_hubbub_shift *hubbub_shift, 956 const struct dcn_hubbub_mask *hubbub_mask) 957 { 958 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 959 960 hubbub1->base.ctx = ctx; 961 962 hubbub1->base.funcs = &hubbub1_funcs; 963 964 hubbub1->regs = hubbub_regs; 965 hubbub1->shifts = hubbub_shift; 966 hubbub1->masks = hubbub_mask; 967 968 hubbub1->debug_test_index_pstate = 0x7; 969 if (ctx->dce_version == DCN_VERSION_1_01) 970 hubbub1->debug_test_index_pstate = 0xB; 971 } 972 973