root/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hubbub1_wm_read_state
  2. hubbub1_allow_self_refresh_control
  3. hubbub1_is_allow_self_refresh_enabled
  4. hubbub1_verify_allow_pstate_change_high
  5. convert_and_clamp
  6. hubbub1_wm_change_req_wa
  7. hubbub1_program_urgent_watermarks
  8. hubbub1_program_stutter_watermarks
  9. hubbub1_program_pstate_watermarks
  10. hubbub1_program_watermarks
  11. hubbub1_update_dchub
  12. hubbub1_toggle_watermark_change_req
  13. hubbub1_soft_reset
  14. hubbub1_dcc_support_swizzle
  15. hubbub1_dcc_support_pixel_format
  16. hubbub1_get_blk256_size
  17. hubbub1_det_request_size
  18. hubbub1_get_dcc_compression_cap
  19. hubbub1_construct

   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 = width * blk256_height * bpe;
 844         swath_bytes_vert_wc = height * 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 

/* [<][>][^][v][top][bottom][index][help] */