LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dcn10 - dcn10_hubbub.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 396 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 16 0.0 %

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

Generated by: LCOV version 1.14