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

          Line data    Source code
       1             : /*
       2             :  * Copyright 2018 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 "reg_helper.h"
      27             : #include "core_types.h"
      28             : #include "dcn31_dccg.h"
      29             : #include "dal_asic_id.h"
      30             : 
      31             : #define TO_DCN_DCCG(dccg)\
      32             :         container_of(dccg, struct dcn_dccg, base)
      33             : 
      34             : #define REG(reg) \
      35             :         (dccg_dcn->regs->reg)
      36             : 
      37             : #undef FN
      38             : #define FN(reg_name, field_name) \
      39             :         dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
      40             : 
      41             : #define CTX \
      42             :         dccg_dcn->base.ctx
      43             : #define DC_LOGGER \
      44             :         dccg->ctx->logger
      45             : 
      46           0 : void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
      47             : {
      48           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
      49             : 
      50           0 :         if (dccg->ref_dppclk && req_dppclk) {
      51           0 :                 int ref_dppclk = dccg->ref_dppclk;
      52             :                 int modulo, phase;
      53             : 
      54             :                 // phase / modulo = dpp pipe clk / dpp global clk
      55           0 :                 modulo = 0xff;   // use FF at the end
      56           0 :                 phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
      57             : 
      58           0 :                 if (phase > 0xff) {
      59           0 :                         ASSERT(false);
      60             :                         phase = 0xff;
      61             :                 }
      62             : 
      63           0 :                 REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
      64             :                                 DPPCLK0_DTO_PHASE, phase,
      65             :                                 DPPCLK0_DTO_MODULO, modulo);
      66           0 :                 REG_UPDATE(DPPCLK_DTO_CTRL,
      67             :                                 DPPCLK_DTO_ENABLE[dpp_inst], 1);
      68             :         } else {
      69             :                 //DTO must be enabled to generate a 0Hz clock output
      70           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) {
      71           0 :                         REG_UPDATE(DPPCLK_DTO_CTRL,
      72             :                                         DPPCLK_DTO_ENABLE[dpp_inst], 1);
      73           0 :                         REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
      74             :                                         DPPCLK0_DTO_PHASE, 0,
      75             :                                         DPPCLK0_DTO_MODULO, 1);
      76             :                 } else {
      77           0 :                         REG_UPDATE(DPPCLK_DTO_CTRL,
      78             :                                         DPPCLK_DTO_ENABLE[dpp_inst], 0);
      79             :                 }
      80             :         }
      81           0 :         dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
      82           0 : }
      83             : 
      84             : static enum phyd32clk_clock_source get_phy_mux_symclk(
      85             :                 struct dcn_dccg *dccg_dcn,
      86             :                 enum phyd32clk_clock_source src)
      87             : {
      88           0 :         if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
      89           0 :                 if (src == PHYD32CLKC)
      90           0 :                         src = PHYD32CLKF;
      91           0 :                 if (src == PHYD32CLKD)
      92           0 :                         src = PHYD32CLKG;
      93             :         }
      94             :         return src;
      95             : }
      96             : 
      97           0 : static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst)
      98             : {
      99           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     100             : 
     101             :         /* enabled to select one of the DTBCLKs for pipe */
     102           0 :         switch (otg_inst) {
     103             :         case 0:
     104           0 :                 REG_UPDATE(DPSTREAMCLK_CNTL,
     105             :                                 DPSTREAMCLK_PIPE0_EN, 1);
     106           0 :                 break;
     107             :         case 1:
     108           0 :                 REG_UPDATE(DPSTREAMCLK_CNTL,
     109             :                                 DPSTREAMCLK_PIPE1_EN, 1);
     110           0 :                 break;
     111             :         case 2:
     112           0 :                 REG_UPDATE(DPSTREAMCLK_CNTL,
     113             :                                 DPSTREAMCLK_PIPE2_EN, 1);
     114           0 :                 break;
     115             :         case 3:
     116           0 :                 REG_UPDATE(DPSTREAMCLK_CNTL,
     117             :                                 DPSTREAMCLK_PIPE3_EN, 1);
     118           0 :                 break;
     119             :         default:
     120           0 :                 BREAK_TO_DEBUGGER();
     121           0 :                 return;
     122             :         }
     123           0 :         if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
     124           0 :                 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     125             :                         DPSTREAMCLK_GATE_DISABLE, 1,
     126             :                         DPSTREAMCLK_ROOT_GATE_DISABLE, 1);
     127             : }
     128             : 
     129           0 : static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst)
     130             : {
     131           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     132             : 
     133           0 :         if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
     134           0 :                 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     135             :                                 DPSTREAMCLK_ROOT_GATE_DISABLE, 0,
     136             :                                 DPSTREAMCLK_GATE_DISABLE, 0);
     137             : 
     138           0 :         switch (otg_inst) {
     139             :         case 0:
     140           0 :                 REG_UPDATE(DPSTREAMCLK_CNTL,
     141             :                                 DPSTREAMCLK_PIPE0_EN, 0);
     142           0 :                 break;
     143             :         case 1:
     144           0 :                 REG_UPDATE(DPSTREAMCLK_CNTL,
     145             :                                 DPSTREAMCLK_PIPE1_EN, 0);
     146           0 :                 break;
     147             :         case 2:
     148           0 :                 REG_UPDATE(DPSTREAMCLK_CNTL,
     149             :                                 DPSTREAMCLK_PIPE2_EN, 0);
     150           0 :                 break;
     151             :         case 3:
     152           0 :                 REG_UPDATE(DPSTREAMCLK_CNTL,
     153             :                                 DPSTREAMCLK_PIPE3_EN, 0);
     154           0 :                 break;
     155             :         default:
     156           0 :                 BREAK_TO_DEBUGGER();
     157           0 :                 return;
     158             :         }
     159             : }
     160             : 
     161           0 : void dccg31_set_dpstreamclk(
     162             :                 struct dccg *dccg,
     163             :                 enum streamclk_source src,
     164             :                 int otg_inst,
     165             :                 int dp_hpo_inst)
     166             : {
     167           0 :         if (src == REFCLK)
     168           0 :                 dccg31_disable_dpstreamclk(dccg, otg_inst);
     169             :         else
     170           0 :                 dccg31_enable_dpstreamclk(dccg, otg_inst);
     171           0 : }
     172             : 
     173           0 : void dccg31_enable_symclk32_se(
     174             :                 struct dccg *dccg,
     175             :                 int hpo_se_inst,
     176             :                 enum phyd32clk_clock_source phyd32clk)
     177             : {
     178           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     179             : 
     180           0 :         phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
     181             : 
     182             :         /* select one of the PHYD32CLKs as the source for symclk32_se */
     183           0 :         switch (hpo_se_inst) {
     184             :         case 0:
     185           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
     186           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     187             :                                         SYMCLK32_SE0_GATE_DISABLE, 1,
     188             :                                         SYMCLK32_ROOT_SE0_GATE_DISABLE, 1);
     189           0 :                 REG_UPDATE_2(SYMCLK32_SE_CNTL,
     190             :                                 SYMCLK32_SE0_SRC_SEL, phyd32clk,
     191             :                                 SYMCLK32_SE0_EN, 1);
     192           0 :                 break;
     193             :         case 1:
     194           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
     195           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     196             :                                         SYMCLK32_SE1_GATE_DISABLE, 1,
     197             :                                         SYMCLK32_ROOT_SE1_GATE_DISABLE, 1);
     198           0 :                 REG_UPDATE_2(SYMCLK32_SE_CNTL,
     199             :                                 SYMCLK32_SE1_SRC_SEL, phyd32clk,
     200             :                                 SYMCLK32_SE1_EN, 1);
     201           0 :                 break;
     202             :         case 2:
     203           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
     204           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     205             :                                         SYMCLK32_SE2_GATE_DISABLE, 1,
     206             :                                         SYMCLK32_ROOT_SE2_GATE_DISABLE, 1);
     207           0 :                 REG_UPDATE_2(SYMCLK32_SE_CNTL,
     208             :                                 SYMCLK32_SE2_SRC_SEL, phyd32clk,
     209             :                                 SYMCLK32_SE2_EN, 1);
     210           0 :                 break;
     211             :         case 3:
     212           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
     213           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     214             :                                         SYMCLK32_SE3_GATE_DISABLE, 1,
     215             :                                         SYMCLK32_ROOT_SE3_GATE_DISABLE, 1);
     216           0 :                 REG_UPDATE_2(SYMCLK32_SE_CNTL,
     217             :                                 SYMCLK32_SE3_SRC_SEL, phyd32clk,
     218             :                                 SYMCLK32_SE3_EN, 1);
     219           0 :                 break;
     220             :         default:
     221           0 :                 BREAK_TO_DEBUGGER();
     222           0 :                 return;
     223             :         }
     224             : }
     225             : 
     226           0 : void dccg31_disable_symclk32_se(
     227             :                 struct dccg *dccg,
     228             :                 int hpo_se_inst)
     229             : {
     230           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     231             : 
     232             :         /* set refclk as the source for symclk32_se */
     233           0 :         switch (hpo_se_inst) {
     234             :         case 0:
     235           0 :                 REG_UPDATE_2(SYMCLK32_SE_CNTL,
     236             :                                 SYMCLK32_SE0_SRC_SEL, 0,
     237             :                                 SYMCLK32_SE0_EN, 0);
     238           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
     239           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     240             :                                         SYMCLK32_SE0_GATE_DISABLE, 0,
     241             :                                         SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);
     242             :                 break;
     243             :         case 1:
     244           0 :                 REG_UPDATE_2(SYMCLK32_SE_CNTL,
     245             :                                 SYMCLK32_SE1_SRC_SEL, 0,
     246             :                                 SYMCLK32_SE1_EN, 0);
     247           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
     248           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     249             :                                         SYMCLK32_SE1_GATE_DISABLE, 0,
     250             :                                         SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);
     251             :                 break;
     252             :         case 2:
     253           0 :                 REG_UPDATE_2(SYMCLK32_SE_CNTL,
     254             :                                 SYMCLK32_SE2_SRC_SEL, 0,
     255             :                                 SYMCLK32_SE2_EN, 0);
     256           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
     257           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     258             :                                         SYMCLK32_SE2_GATE_DISABLE, 0,
     259             :                                         SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);
     260             :                 break;
     261             :         case 3:
     262           0 :                 REG_UPDATE_2(SYMCLK32_SE_CNTL,
     263             :                                 SYMCLK32_SE3_SRC_SEL, 0,
     264             :                                 SYMCLK32_SE3_EN, 0);
     265           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
     266           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     267             :                                         SYMCLK32_SE3_GATE_DISABLE, 0,
     268             :                                         SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);
     269             :                 break;
     270             :         default:
     271           0 :                 BREAK_TO_DEBUGGER();
     272           0 :                 return;
     273             :         }
     274             : }
     275             : 
     276           0 : void dccg31_enable_symclk32_le(
     277             :                 struct dccg *dccg,
     278             :                 int hpo_le_inst,
     279             :                 enum phyd32clk_clock_source phyd32clk)
     280             : {
     281           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     282             : 
     283           0 :         phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
     284             : 
     285             :         /* select one of the PHYD32CLKs as the source for symclk32_le */
     286           0 :         switch (hpo_le_inst) {
     287             :         case 0:
     288           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
     289           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     290             :                                         SYMCLK32_LE0_GATE_DISABLE, 1,
     291             :                                         SYMCLK32_ROOT_LE0_GATE_DISABLE, 1);
     292           0 :                 REG_UPDATE_2(SYMCLK32_LE_CNTL,
     293             :                                 SYMCLK32_LE0_SRC_SEL, phyd32clk,
     294             :                                 SYMCLK32_LE0_EN, 1);
     295           0 :                 break;
     296             :         case 1:
     297           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
     298           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     299             :                                         SYMCLK32_LE1_GATE_DISABLE, 1,
     300             :                                         SYMCLK32_ROOT_LE1_GATE_DISABLE, 1);
     301           0 :                 REG_UPDATE_2(SYMCLK32_LE_CNTL,
     302             :                                 SYMCLK32_LE1_SRC_SEL, phyd32clk,
     303             :                                 SYMCLK32_LE1_EN, 1);
     304           0 :                 break;
     305             :         default:
     306           0 :                 BREAK_TO_DEBUGGER();
     307           0 :                 return;
     308             :         }
     309             : }
     310             : 
     311           0 : void dccg31_disable_symclk32_le(
     312             :                 struct dccg *dccg,
     313             :                 int hpo_le_inst)
     314             : {
     315           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     316             : 
     317             :         /* set refclk as the source for symclk32_le */
     318           0 :         switch (hpo_le_inst) {
     319             :         case 0:
     320           0 :                 REG_UPDATE_2(SYMCLK32_LE_CNTL,
     321             :                                 SYMCLK32_LE0_SRC_SEL, 0,
     322             :                                 SYMCLK32_LE0_EN, 0);
     323           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
     324           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     325             :                                         SYMCLK32_LE0_GATE_DISABLE, 0,
     326             :                                         SYMCLK32_ROOT_LE0_GATE_DISABLE, 0);
     327             :                 break;
     328             :         case 1:
     329           0 :                 REG_UPDATE_2(SYMCLK32_LE_CNTL,
     330             :                                 SYMCLK32_LE1_SRC_SEL, 0,
     331             :                                 SYMCLK32_LE1_EN, 0);
     332           0 :                 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
     333           0 :                         REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
     334             :                                         SYMCLK32_LE1_GATE_DISABLE, 0,
     335             :                                         SYMCLK32_ROOT_LE1_GATE_DISABLE, 0);
     336             :                 break;
     337             :         default:
     338           0 :                 BREAK_TO_DEBUGGER();
     339           0 :                 return;
     340             :         }
     341             : }
     342             : 
     343           0 : void dccg31_disable_dscclk(struct dccg *dccg, int inst)
     344             : {
     345           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     346             : 
     347           0 :         if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
     348             :                 return;
     349             :         //DTO must be enabled to generate a 0 Hz clock output
     350           0 :         switch (inst) {
     351             :         case 0:
     352           0 :                 REG_UPDATE(DSCCLK_DTO_CTRL,
     353             :                                 DSCCLK0_DTO_ENABLE, 1);
     354           0 :                 REG_UPDATE_2(DSCCLK0_DTO_PARAM,
     355             :                                 DSCCLK0_DTO_PHASE, 0,
     356             :                                 DSCCLK0_DTO_MODULO, 1);
     357           0 :                 break;
     358             :         case 1:
     359           0 :                 REG_UPDATE(DSCCLK_DTO_CTRL,
     360             :                                 DSCCLK1_DTO_ENABLE, 1);
     361           0 :                 REG_UPDATE_2(DSCCLK1_DTO_PARAM,
     362             :                                 DSCCLK1_DTO_PHASE, 0,
     363             :                                 DSCCLK1_DTO_MODULO, 1);
     364           0 :                 break;
     365             :         case 2:
     366           0 :                 REG_UPDATE(DSCCLK_DTO_CTRL,
     367             :                                 DSCCLK2_DTO_ENABLE, 1);
     368           0 :                 REG_UPDATE_2(DSCCLK2_DTO_PARAM,
     369             :                                 DSCCLK2_DTO_PHASE, 0,
     370             :                                 DSCCLK2_DTO_MODULO, 1);
     371           0 :                 break;
     372             :         default:
     373           0 :                 BREAK_TO_DEBUGGER();
     374           0 :                 return;
     375             :         }
     376             : }
     377             : 
     378           0 : void dccg31_enable_dscclk(struct dccg *dccg, int inst)
     379             : {
     380           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     381             : 
     382           0 :         if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
     383             :                 return;
     384             :         //Disable DTO
     385           0 :         switch (inst) {
     386             :         case 0:
     387           0 :                 REG_UPDATE_2(DSCCLK0_DTO_PARAM,
     388             :                                 DSCCLK0_DTO_PHASE, 0,
     389             :                                 DSCCLK0_DTO_MODULO, 0);
     390           0 :                 REG_UPDATE(DSCCLK_DTO_CTRL,
     391             :                                 DSCCLK0_DTO_ENABLE, 0);
     392           0 :                 break;
     393             :         case 1:
     394           0 :                 REG_UPDATE_2(DSCCLK1_DTO_PARAM,
     395             :                                 DSCCLK1_DTO_PHASE, 0,
     396             :                                 DSCCLK1_DTO_MODULO, 0);
     397           0 :                 REG_UPDATE(DSCCLK_DTO_CTRL,
     398             :                                 DSCCLK1_DTO_ENABLE, 0);
     399           0 :                 break;
     400             :         case 2:
     401           0 :                 REG_UPDATE_2(DSCCLK2_DTO_PARAM,
     402             :                                 DSCCLK2_DTO_PHASE, 0,
     403             :                                 DSCCLK2_DTO_MODULO, 0);
     404           0 :                 REG_UPDATE(DSCCLK_DTO_CTRL,
     405             :                                 DSCCLK2_DTO_ENABLE, 0);
     406           0 :                 break;
     407             :         default:
     408           0 :                 BREAK_TO_DEBUGGER();
     409           0 :                 return;
     410             :         }
     411             : }
     412             : 
     413           0 : void dccg31_set_physymclk(
     414             :                 struct dccg *dccg,
     415             :                 int phy_inst,
     416             :                 enum physymclk_clock_source clk_src,
     417             :                 bool force_enable)
     418             : {
     419           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     420             : 
     421             :         /* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */
     422           0 :         switch (phy_inst) {
     423             :         case 0:
     424           0 :                 if (force_enable) {
     425           0 :                         REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
     426             :                                         PHYASYMCLK_FORCE_EN, 1,
     427             :                                         PHYASYMCLK_FORCE_SRC_SEL, clk_src);
     428           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     429           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     430             :                                         PHYASYMCLK_GATE_DISABLE, 1);
     431             :                 } else {
     432           0 :                         REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
     433             :                                         PHYASYMCLK_FORCE_EN, 0,
     434             :                                         PHYASYMCLK_FORCE_SRC_SEL, 0);
     435           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     436           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     437             :                                         PHYASYMCLK_GATE_DISABLE, 0);
     438             :                 }
     439             :                 break;
     440             :         case 1:
     441           0 :                 if (force_enable) {
     442           0 :                         REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
     443             :                                         PHYBSYMCLK_FORCE_EN, 1,
     444             :                                         PHYBSYMCLK_FORCE_SRC_SEL, clk_src);
     445           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     446           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     447             :                                         PHYBSYMCLK_GATE_DISABLE, 1);
     448             :                 } else {
     449           0 :                         REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
     450             :                                         PHYBSYMCLK_FORCE_EN, 0,
     451             :                                         PHYBSYMCLK_FORCE_SRC_SEL, 0);
     452           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     453           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     454             :                                         PHYBSYMCLK_GATE_DISABLE, 0);
     455             :                 }
     456             :                 break;
     457             :         case 2:
     458           0 :                 if (force_enable) {
     459           0 :                         REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
     460             :                                         PHYCSYMCLK_FORCE_EN, 1,
     461             :                                         PHYCSYMCLK_FORCE_SRC_SEL, clk_src);
     462           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     463           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     464             :                                         PHYCSYMCLK_GATE_DISABLE, 1);
     465             :                 } else {
     466           0 :                         REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
     467             :                                         PHYCSYMCLK_FORCE_EN, 0,
     468             :                                         PHYCSYMCLK_FORCE_SRC_SEL, 0);
     469           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     470           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     471             :                                         PHYCSYMCLK_GATE_DISABLE, 0);
     472             :                 }
     473             :                 break;
     474             :         case 3:
     475           0 :                 if (force_enable) {
     476           0 :                         REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
     477             :                                         PHYDSYMCLK_FORCE_EN, 1,
     478             :                                         PHYDSYMCLK_FORCE_SRC_SEL, clk_src);
     479           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     480           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     481             :                                         PHYDSYMCLK_GATE_DISABLE, 1);
     482             :                 } else {
     483           0 :                         REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
     484             :                                         PHYDSYMCLK_FORCE_EN, 0,
     485             :                                         PHYDSYMCLK_FORCE_SRC_SEL, 0);
     486           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     487           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     488             :                                         PHYDSYMCLK_GATE_DISABLE, 0);
     489             :                 }
     490             :                 break;
     491             :         case 4:
     492           0 :                 if (force_enable) {
     493           0 :                         REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
     494             :                                         PHYESYMCLK_FORCE_EN, 1,
     495             :                                         PHYESYMCLK_FORCE_SRC_SEL, clk_src);
     496           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     497           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     498             :                                         PHYESYMCLK_GATE_DISABLE, 1);
     499             :                 } else {
     500           0 :                         REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
     501             :                                         PHYESYMCLK_FORCE_EN, 0,
     502             :                                         PHYESYMCLK_FORCE_SRC_SEL, 0);
     503           0 :                         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
     504           0 :                                 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
     505             :                                         PHYESYMCLK_GATE_DISABLE, 0);
     506             :                 }
     507             :                 break;
     508             :         default:
     509           0 :                 BREAK_TO_DEBUGGER();
     510           0 :                 return;
     511             :         }
     512             : }
     513             : 
     514             : /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
     515           0 : void dccg31_set_dtbclk_dto(
     516             :                 struct dccg *dccg,
     517             :                 const struct dtbclk_dto_params *params)
     518             : {
     519           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     520           0 :         int req_dtbclk_khz = params->pixclk_khz;
     521             :         uint32_t dtbdto_div;
     522             : 
     523             :         /* Mode                 DTBDTO Rate       DTBCLK_DTO<x>_DIV Register
     524             :          * ODM 4:1 combine      pixel rate/4      2
     525             :          * ODM 2:1 combine      pixel rate/2      4
     526             :          * non-DSC 4:2:0 mode   pixel rate/2      4
     527             :          * DSC native 4:2:0     pixel rate/2      4
     528             :          * DSC native 4:2:2     pixel rate/2      4
     529             :          * Other modes          pixel rate        8
     530             :          */
     531           0 :         if (params->num_odm_segments == 4) {
     532           0 :                 dtbdto_div = 2;
     533           0 :                 req_dtbclk_khz = params->pixclk_khz / 4;
     534           0 :         } else if ((params->num_odm_segments == 2) ||
     535           0 :                         (params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
     536           0 :                         (params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
     537           0 :                                         && !params->timing->dsc_cfg.ycbcr422_simple)) {
     538           0 :                 dtbdto_div = 4;
     539           0 :                 req_dtbclk_khz = params->pixclk_khz / 2;
     540             :         } else
     541             :                 dtbdto_div = 8;
     542             : 
     543           0 :         if (params->ref_dtbclk_khz && req_dtbclk_khz) {
     544             :                 uint32_t modulo, phase;
     545             : 
     546             :                 // phase / modulo = dtbclk / dtbclk ref
     547           0 :                 modulo = params->ref_dtbclk_khz * 1000;
     548           0 :                 phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1),
     549             :                                 params->ref_dtbclk_khz);
     550             : 
     551           0 :                 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
     552             :                                 DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
     553             : 
     554           0 :                 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
     555           0 :                 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
     556             : 
     557           0 :                 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
     558             :                                 DTBCLK_DTO_ENABLE[params->otg_inst], 1);
     559             : 
     560           0 :                 REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
     561             :                                 DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
     562             :                                 1, 100);
     563             : 
     564             :                 /* The recommended programming sequence to enable DTBCLK DTO to generate
     565             :                  * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
     566             :                  * be set only after DTO is enabled
     567             :                  */
     568           0 :                 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
     569             :                                 PIPE_DTO_SRC_SEL[params->otg_inst], 1);
     570             :         } else {
     571           0 :                 REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst],
     572             :                                 DTBCLK_DTO_ENABLE[params->otg_inst], 0,
     573             :                                 PIPE_DTO_SRC_SEL[params->otg_inst], 0,
     574             :                                 DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
     575             : 
     576           0 :                 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
     577           0 :                 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
     578             :         }
     579           0 : }
     580             : 
     581           0 : void dccg31_set_audio_dtbclk_dto(
     582             :                 struct dccg *dccg,
     583             :                 const struct dtbclk_dto_params *params)
     584             : {
     585           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     586             : 
     587           0 :         if (params->ref_dtbclk_khz && params->req_audio_dtbclk_khz) {
     588             :                 uint32_t modulo, phase;
     589             : 
     590             :                 // phase / modulo = dtbclk / dtbclk ref
     591           0 :                 modulo = params->ref_dtbclk_khz * 1000;
     592           0 :                 phase = div_u64((((unsigned long long)modulo * params->req_audio_dtbclk_khz) + params->ref_dtbclk_khz - 1),
     593             :                         params->ref_dtbclk_khz);
     594             : 
     595             : 
     596           0 :                 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo);
     597           0 :                 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase);
     598             : 
     599             :                 //REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
     600             :                 //              DCCG_AUDIO_DTBCLK_DTO_USE_512FBR_DTO, 1);
     601             : 
     602           0 :                 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
     603             :                                 DCCG_AUDIO_DTO_SEL, 4);  //  04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK
     604             :         } else {
     605           0 :                 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0);
     606           0 :                 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0);
     607             : 
     608           0 :                 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
     609             :                                 DCCG_AUDIO_DTO_SEL, 3);  //  03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO
     610             :         }
     611           0 : }
     612             : 
     613           0 : void dccg31_get_dccg_ref_freq(struct dccg *dccg,
     614             :                 unsigned int xtalin_freq_inKhz,
     615             :                 unsigned int *dccg_ref_freq_inKhz)
     616             : {
     617             :         /*
     618             :          * Assume refclk is sourced from xtalin
     619             :          * expect 24MHz
     620             :          */
     621           0 :         *dccg_ref_freq_inKhz = xtalin_freq_inKhz;
     622           0 :         return;
     623             : }
     624             : 
     625           0 : void dccg31_set_dispclk_change_mode(
     626             :         struct dccg *dccg,
     627             :         enum dentist_dispclk_change_mode change_mode)
     628             : {
     629           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     630             : 
     631           0 :         REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE,
     632             :                    change_mode == DISPCLK_CHANGE_MODE_RAMPING ? 2 : 0);
     633           0 : }
     634             : 
     635           0 : void dccg31_init(struct dccg *dccg)
     636             : {
     637             :         /* Set HPO stream encoder to use refclk to avoid case where PHY is
     638             :          * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
     639             :          * will cause DCN to hang.
     640             :          */
     641           0 :         dccg31_disable_symclk32_se(dccg, 0);
     642           0 :         dccg31_disable_symclk32_se(dccg, 1);
     643           0 :         dccg31_disable_symclk32_se(dccg, 2);
     644           0 :         dccg31_disable_symclk32_se(dccg, 3);
     645             : 
     646           0 :         if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) {
     647           0 :                 dccg31_disable_symclk32_le(dccg, 0);
     648           0 :                 dccg31_disable_symclk32_le(dccg, 1);
     649             :         }
     650             : 
     651           0 :         if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
     652           0 :                 dccg31_disable_dpstreamclk(dccg, 0);
     653           0 :                 dccg31_disable_dpstreamclk(dccg, 1);
     654           0 :                 dccg31_disable_dpstreamclk(dccg, 2);
     655           0 :                 dccg31_disable_dpstreamclk(dccg, 3);
     656             :         }
     657             : 
     658           0 :         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) {
     659           0 :                 dccg31_set_physymclk(dccg, 0, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
     660           0 :                 dccg31_set_physymclk(dccg, 1, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
     661           0 :                 dccg31_set_physymclk(dccg, 2, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
     662           0 :                 dccg31_set_physymclk(dccg, 3, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
     663           0 :                 dccg31_set_physymclk(dccg, 4, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
     664             :         }
     665           0 : }
     666             : 
     667           0 : void dccg31_otg_add_pixel(struct dccg *dccg,
     668             :                                  uint32_t otg_inst)
     669             : {
     670           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     671             : 
     672           0 :         REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
     673             :                         OTG_ADD_PIXEL[otg_inst], 1);
     674           0 : }
     675             : 
     676           0 : void dccg31_otg_drop_pixel(struct dccg *dccg,
     677             :                                   uint32_t otg_inst)
     678             : {
     679           0 :         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     680             : 
     681           0 :         REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
     682             :                         OTG_DROP_PIXEL[otg_inst], 1);
     683           0 : }
     684             : 
     685             : static const struct dccg_funcs dccg31_funcs = {
     686             :         .update_dpp_dto = dccg31_update_dpp_dto,
     687             :         .get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
     688             :         .dccg_init = dccg31_init,
     689             :         .set_dpstreamclk = dccg31_set_dpstreamclk,
     690             :         .enable_symclk32_se = dccg31_enable_symclk32_se,
     691             :         .disable_symclk32_se = dccg31_disable_symclk32_se,
     692             :         .enable_symclk32_le = dccg31_enable_symclk32_le,
     693             :         .disable_symclk32_le = dccg31_disable_symclk32_le,
     694             :         .set_physymclk = dccg31_set_physymclk,
     695             :         .set_dtbclk_dto = dccg31_set_dtbclk_dto,
     696             :         .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
     697             :         .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
     698             :         .otg_add_pixel = dccg31_otg_add_pixel,
     699             :         .otg_drop_pixel = dccg31_otg_drop_pixel,
     700             :         .set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
     701             :         .disable_dsc = dccg31_disable_dscclk,
     702             :         .enable_dsc = dccg31_enable_dscclk,
     703             : };
     704             : 
     705           0 : struct dccg *dccg31_create(
     706             :         struct dc_context *ctx,
     707             :         const struct dccg_registers *regs,
     708             :         const struct dccg_shift *dccg_shift,
     709             :         const struct dccg_mask *dccg_mask)
     710             : {
     711           0 :         struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
     712             :         struct dccg *base;
     713             : 
     714           0 :         if (dccg_dcn == NULL) {
     715           0 :                 BREAK_TO_DEBUGGER();
     716           0 :                 return NULL;
     717             :         }
     718             : 
     719           0 :         base = &dccg_dcn->base;
     720           0 :         base->ctx = ctx;
     721           0 :         base->funcs = &dccg31_funcs;
     722             : 
     723           0 :         dccg_dcn->regs = regs;
     724           0 :         dccg_dcn->dccg_shift = dccg_shift;
     725           0 :         dccg_dcn->dccg_mask = dccg_mask;
     726             : 
     727           0 :         return &dccg_dcn->base;
     728             : }

Generated by: LCOV version 1.14