LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/amdgpu - atombios_crtc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 453 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 15 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2007-8 Advanced Micro Devices, Inc.
       3             :  * Copyright 2008 Red Hat Inc.
       4             :  *
       5             :  * Permission is hereby granted, free of charge, to any person obtaining a
       6             :  * copy of this software and associated documentation files (the "Software"),
       7             :  * to deal in the Software without restriction, including without limitation
       8             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       9             :  * and/or sell copies of the Software, and to permit persons to whom the
      10             :  * Software is furnished to do so, subject to the following conditions:
      11             :  *
      12             :  * The above copyright notice and this permission notice shall be included in
      13             :  * all copies or substantial portions of the Software.
      14             :  *
      15             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      19             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      20             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      21             :  * OTHER DEALINGS IN THE SOFTWARE.
      22             :  *
      23             :  * Authors: Dave Airlie
      24             :  *          Alex Deucher
      25             :  */
      26             : 
      27             : #include <drm/drm_crtc_helper.h>
      28             : #include <drm/amdgpu_drm.h>
      29             : #include <drm/drm_fixed.h>
      30             : #include "amdgpu.h"
      31             : #include "atom.h"
      32             : #include "atom-bits.h"
      33             : #include "atombios_encoders.h"
      34             : #include "atombios_crtc.h"
      35             : #include "amdgpu_atombios.h"
      36             : #include "amdgpu_pll.h"
      37             : #include "amdgpu_connectors.h"
      38             : 
      39           0 : void amdgpu_atombios_crtc_overscan_setup(struct drm_crtc *crtc,
      40             :                                   struct drm_display_mode *mode,
      41             :                                   struct drm_display_mode *adjusted_mode)
      42             : {
      43           0 :         struct drm_device *dev = crtc->dev;
      44           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
      45           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
      46             :         SET_CRTC_OVERSCAN_PS_ALLOCATION args;
      47           0 :         int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
      48             :         int a1, a2;
      49             : 
      50           0 :         memset(&args, 0, sizeof(args));
      51             : 
      52           0 :         args.ucCRTC = amdgpu_crtc->crtc_id;
      53             : 
      54           0 :         switch (amdgpu_crtc->rmx_type) {
      55             :         case RMX_CENTER:
      56           0 :                 args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
      57           0 :                 args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
      58           0 :                 args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
      59           0 :                 args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
      60           0 :                 break;
      61             :         case RMX_ASPECT:
      62           0 :                 a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
      63           0 :                 a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
      64             : 
      65           0 :                 if (a1 > a2) {
      66           0 :                         args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
      67           0 :                         args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
      68           0 :                 } else if (a2 > a1) {
      69           0 :                         args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
      70           0 :                         args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
      71             :                 }
      72             :                 break;
      73             :         case RMX_FULL:
      74             :         default:
      75           0 :                 args.usOverscanRight = cpu_to_le16(amdgpu_crtc->h_border);
      76           0 :                 args.usOverscanLeft = cpu_to_le16(amdgpu_crtc->h_border);
      77           0 :                 args.usOverscanBottom = cpu_to_le16(amdgpu_crtc->v_border);
      78           0 :                 args.usOverscanTop = cpu_to_le16(amdgpu_crtc->v_border);
      79           0 :                 break;
      80             :         }
      81           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
      82           0 : }
      83             : 
      84           0 : void amdgpu_atombios_crtc_scaler_setup(struct drm_crtc *crtc)
      85             : {
      86           0 :         struct drm_device *dev = crtc->dev;
      87           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
      88           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
      89             :         ENABLE_SCALER_PS_ALLOCATION args;
      90           0 :         int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
      91             : 
      92           0 :         memset(&args, 0, sizeof(args));
      93             : 
      94           0 :         args.ucScaler = amdgpu_crtc->crtc_id;
      95             : 
      96           0 :         switch (amdgpu_crtc->rmx_type) {
      97             :         case RMX_FULL:
      98           0 :                 args.ucEnable = ATOM_SCALER_EXPANSION;
      99           0 :                 break;
     100             :         case RMX_CENTER:
     101           0 :                 args.ucEnable = ATOM_SCALER_CENTER;
     102           0 :                 break;
     103             :         case RMX_ASPECT:
     104           0 :                 args.ucEnable = ATOM_SCALER_EXPANSION;
     105           0 :                 break;
     106             :         default:
     107           0 :                 args.ucEnable = ATOM_SCALER_DISABLE;
     108           0 :                 break;
     109             :         }
     110           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     111           0 : }
     112             : 
     113           0 : void amdgpu_atombios_crtc_lock(struct drm_crtc *crtc, int lock)
     114             : {
     115           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
     116           0 :         struct drm_device *dev = crtc->dev;
     117           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     118           0 :         int index =
     119             :             GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
     120             :         ENABLE_CRTC_PS_ALLOCATION args;
     121             : 
     122           0 :         memset(&args, 0, sizeof(args));
     123             : 
     124           0 :         args.ucCRTC = amdgpu_crtc->crtc_id;
     125           0 :         args.ucEnable = lock;
     126             : 
     127           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     128           0 : }
     129             : 
     130           0 : void amdgpu_atombios_crtc_enable(struct drm_crtc *crtc, int state)
     131             : {
     132           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
     133           0 :         struct drm_device *dev = crtc->dev;
     134           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     135           0 :         int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
     136             :         ENABLE_CRTC_PS_ALLOCATION args;
     137             : 
     138           0 :         memset(&args, 0, sizeof(args));
     139             : 
     140           0 :         args.ucCRTC = amdgpu_crtc->crtc_id;
     141           0 :         args.ucEnable = state;
     142             : 
     143           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     144           0 : }
     145             : 
     146           0 : void amdgpu_atombios_crtc_blank(struct drm_crtc *crtc, int state)
     147             : {
     148           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
     149           0 :         struct drm_device *dev = crtc->dev;
     150           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     151           0 :         int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
     152             :         BLANK_CRTC_PS_ALLOCATION args;
     153             : 
     154           0 :         memset(&args, 0, sizeof(args));
     155             : 
     156           0 :         args.ucCRTC = amdgpu_crtc->crtc_id;
     157           0 :         args.ucBlanking = state;
     158             : 
     159           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     160           0 : }
     161             : 
     162           0 : void amdgpu_atombios_crtc_powergate(struct drm_crtc *crtc, int state)
     163             : {
     164           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
     165           0 :         struct drm_device *dev = crtc->dev;
     166           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     167           0 :         int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
     168             :         ENABLE_DISP_POWER_GATING_PS_ALLOCATION args;
     169             : 
     170           0 :         memset(&args, 0, sizeof(args));
     171             : 
     172           0 :         args.ucDispPipeId = amdgpu_crtc->crtc_id;
     173           0 :         args.ucEnable = state;
     174             : 
     175           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     176           0 : }
     177             : 
     178           0 : void amdgpu_atombios_crtc_powergate_init(struct amdgpu_device *adev)
     179             : {
     180           0 :         int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
     181             :         ENABLE_DISP_POWER_GATING_PS_ALLOCATION args;
     182             : 
     183           0 :         memset(&args, 0, sizeof(args));
     184             : 
     185           0 :         args.ucEnable = ATOM_INIT;
     186             : 
     187           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     188           0 : }
     189             : 
     190           0 : void amdgpu_atombios_crtc_set_dtd_timing(struct drm_crtc *crtc,
     191             :                                   struct drm_display_mode *mode)
     192             : {
     193           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
     194           0 :         struct drm_device *dev = crtc->dev;
     195           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     196             :         SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
     197           0 :         int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
     198           0 :         u16 misc = 0;
     199             : 
     200           0 :         memset(&args, 0, sizeof(args));
     201           0 :         args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (amdgpu_crtc->h_border * 2));
     202           0 :         args.usH_Blanking_Time =
     203           0 :                 cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (amdgpu_crtc->h_border * 2));
     204           0 :         args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (amdgpu_crtc->v_border * 2));
     205           0 :         args.usV_Blanking_Time =
     206           0 :                 cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (amdgpu_crtc->v_border * 2));
     207           0 :         args.usH_SyncOffset =
     208           0 :                 cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + amdgpu_crtc->h_border);
     209           0 :         args.usH_SyncWidth =
     210           0 :                 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
     211           0 :         args.usV_SyncOffset =
     212           0 :                 cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + amdgpu_crtc->v_border);
     213           0 :         args.usV_SyncWidth =
     214           0 :                 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
     215           0 :         args.ucH_Border = amdgpu_crtc->h_border;
     216           0 :         args.ucV_Border = amdgpu_crtc->v_border;
     217             : 
     218           0 :         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
     219           0 :                 misc |= ATOM_VSYNC_POLARITY;
     220           0 :         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
     221           0 :                 misc |= ATOM_HSYNC_POLARITY;
     222           0 :         if (mode->flags & DRM_MODE_FLAG_CSYNC)
     223           0 :                 misc |= ATOM_COMPOSITESYNC;
     224           0 :         if (mode->flags & DRM_MODE_FLAG_INTERLACE)
     225           0 :                 misc |= ATOM_INTERLACE;
     226           0 :         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
     227           0 :                 misc |= ATOM_DOUBLE_CLOCK_MODE;
     228             : 
     229           0 :         args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
     230           0 :         args.ucCRTC = amdgpu_crtc->crtc_id;
     231             : 
     232           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     233           0 : }
     234             : 
     235             : union atom_enable_ss {
     236             :         ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
     237             :         ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2;
     238             :         ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
     239             : };
     240             : 
     241           0 : static void amdgpu_atombios_crtc_program_ss(struct amdgpu_device *adev,
     242             :                                      int enable,
     243             :                                      int pll_id,
     244             :                                      int crtc_id,
     245             :                                      struct amdgpu_atom_ss *ss)
     246             : {
     247             :         unsigned i;
     248           0 :         int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
     249             :         union atom_enable_ss args;
     250             : 
     251           0 :         if (enable) {
     252             :                 /* Don't mess with SS if percentage is 0 or external ss.
     253             :                  * SS is already disabled previously, and disabling it
     254             :                  * again can cause display problems if the pll is already
     255             :                  * programmed.
     256             :                  */
     257           0 :                 if (ss->percentage == 0)
     258           0 :                         return;
     259           0 :                 if (ss->type & ATOM_EXTERNAL_SS_MASK)
     260             :                         return;
     261             :         } else {
     262           0 :                 for (i = 0; i < adev->mode_info.num_crtc; i++) {
     263           0 :                         if (adev->mode_info.crtcs[i] &&
     264           0 :                             adev->mode_info.crtcs[i]->enabled &&
     265           0 :                             i != crtc_id &&
     266           0 :                             pll_id == adev->mode_info.crtcs[i]->pll_id) {
     267             :                                 /* one other crtc is using this pll don't turn
     268             :                                  * off spread spectrum as it might turn off
     269             :                                  * display on active crtc
     270             :                                  */
     271             :                                 return;
     272             :                         }
     273             :                 }
     274             :         }
     275             : 
     276           0 :         memset(&args, 0, sizeof(args));
     277             : 
     278           0 :         args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0);
     279           0 :         args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
     280           0 :         switch (pll_id) {
     281             :         case ATOM_PPLL1:
     282             :                 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
     283             :                 break;
     284             :         case ATOM_PPLL2:
     285           0 :                 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
     286           0 :                 break;
     287             :         case ATOM_DCPLL:
     288           0 :                 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
     289           0 :                 break;
     290             :         case ATOM_PPLL_INVALID:
     291             :                 return;
     292             :         }
     293           0 :         args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
     294           0 :         args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
     295           0 :         args.v3.ucEnable = enable;
     296             : 
     297           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     298             : }
     299             : 
     300             : union adjust_pixel_clock {
     301             :         ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
     302             :         ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
     303             : };
     304             : 
     305           0 : static u32 amdgpu_atombios_crtc_adjust_pll(struct drm_crtc *crtc,
     306             :                                     struct drm_display_mode *mode)
     307             : {
     308           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
     309           0 :         struct drm_device *dev = crtc->dev;
     310           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     311           0 :         struct drm_encoder *encoder = amdgpu_crtc->encoder;
     312           0 :         struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
     313           0 :         struct drm_connector *connector = amdgpu_get_connector_for_encoder(encoder);
     314           0 :         u32 adjusted_clock = mode->clock;
     315           0 :         int encoder_mode = amdgpu_atombios_encoder_get_encoder_mode(encoder);
     316           0 :         u32 dp_clock = mode->clock;
     317           0 :         u32 clock = mode->clock;
     318           0 :         int bpc = amdgpu_crtc->bpc;
     319           0 :         bool is_duallink = amdgpu_dig_monitor_is_duallink(encoder, mode->clock);
     320             :         union adjust_pixel_clock args;
     321             :         u8 frev, crev;
     322             :         int index;
     323             : 
     324           0 :         amdgpu_crtc->pll_flags = AMDGPU_PLL_USE_FRAC_FB_DIV;
     325             : 
     326           0 :         if ((amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
     327           0 :             (amdgpu_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
     328           0 :                 if (connector) {
     329           0 :                         struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
     330           0 :                         struct amdgpu_connector_atom_dig *dig_connector =
     331             :                                 amdgpu_connector->con_priv;
     332             : 
     333           0 :                         dp_clock = dig_connector->dp_clock;
     334             :                 }
     335             :         }
     336             : 
     337             :         /* use recommended ref_div for ss */
     338           0 :         if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
     339           0 :                 if (amdgpu_crtc->ss_enabled) {
     340           0 :                         if (amdgpu_crtc->ss.refdiv) {
     341           0 :                                 amdgpu_crtc->pll_flags |= AMDGPU_PLL_USE_REF_DIV;
     342           0 :                                 amdgpu_crtc->pll_reference_div = amdgpu_crtc->ss.refdiv;
     343           0 :                                 amdgpu_crtc->pll_flags |= AMDGPU_PLL_USE_FRAC_FB_DIV;
     344             :                         }
     345             :                 }
     346             :         }
     347             : 
     348             :         /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
     349           0 :         if (amdgpu_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
     350           0 :                 adjusted_clock = mode->clock * 2;
     351           0 :         if (amdgpu_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
     352           0 :                 amdgpu_crtc->pll_flags |= AMDGPU_PLL_PREFER_CLOSEST_LOWER;
     353           0 :         if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
     354           0 :                 amdgpu_crtc->pll_flags |= AMDGPU_PLL_IS_LCD;
     355             : 
     356             : 
     357             :         /* adjust pll for deep color modes */
     358           0 :         if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
     359           0 :                 switch (bpc) {
     360             :                 case 8:
     361             :                 default:
     362             :                         break;
     363             :                 case 10:
     364           0 :                         clock = (clock * 5) / 4;
     365             :                         break;
     366             :                 case 12:
     367           0 :                         clock = (clock * 3) / 2;
     368             :                         break;
     369             :                 case 16:
     370           0 :                         clock = clock * 2;
     371             :                         break;
     372             :                 }
     373             :         }
     374             : 
     375             :         /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
     376             :          * accordingly based on the encoder/transmitter to work around
     377             :          * special hw requirements.
     378             :          */
     379           0 :         index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
     380           0 :         if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev,
     381             :                                    &crev))
     382             :                 return adjusted_clock;
     383             : 
     384           0 :         memset(&args, 0, sizeof(args));
     385             : 
     386           0 :         switch (frev) {
     387             :         case 1:
     388           0 :                 switch (crev) {
     389             :                 case 1:
     390             :                 case 2:
     391           0 :                         args.v1.usPixelClock = cpu_to_le16(clock / 10);
     392           0 :                         args.v1.ucTransmitterID = amdgpu_encoder->encoder_id;
     393           0 :                         args.v1.ucEncodeMode = encoder_mode;
     394           0 :                         if (amdgpu_crtc->ss_enabled && amdgpu_crtc->ss.percentage)
     395           0 :                                 args.v1.ucConfig |=
     396             :                                         ADJUST_DISPLAY_CONFIG_SS_ENABLE;
     397             : 
     398           0 :                         amdgpu_atom_execute_table(adev->mode_info.atom_context,
     399             :                                            index, (uint32_t *)&args);
     400           0 :                         adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
     401             :                         break;
     402             :                 case 3:
     403           0 :                         args.v3.sInput.usPixelClock = cpu_to_le16(clock / 10);
     404           0 :                         args.v3.sInput.ucTransmitterID = amdgpu_encoder->encoder_id;
     405           0 :                         args.v3.sInput.ucEncodeMode = encoder_mode;
     406           0 :                         args.v3.sInput.ucDispPllConfig = 0;
     407           0 :                         if (amdgpu_crtc->ss_enabled && amdgpu_crtc->ss.percentage)
     408           0 :                                 args.v3.sInput.ucDispPllConfig |=
     409             :                                         DISPPLL_CONFIG_SS_ENABLE;
     410           0 :                         if (ENCODER_MODE_IS_DP(encoder_mode)) {
     411           0 :                                 args.v3.sInput.ucDispPllConfig |=
     412             :                                         DISPPLL_CONFIG_COHERENT_MODE;
     413             :                                 /* 16200 or 27000 */
     414           0 :                                 args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
     415           0 :                         } else if (amdgpu_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
     416           0 :                                 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
     417           0 :                                 if (dig->coherent_mode)
     418           0 :                                         args.v3.sInput.ucDispPllConfig |=
     419             :                                                 DISPPLL_CONFIG_COHERENT_MODE;
     420           0 :                                 if (is_duallink)
     421           0 :                                         args.v3.sInput.ucDispPllConfig |=
     422             :                                                 DISPPLL_CONFIG_DUAL_LINK;
     423             :                         }
     424           0 :                         if (amdgpu_encoder_get_dp_bridge_encoder_id(encoder) !=
     425             :                             ENCODER_OBJECT_ID_NONE)
     426           0 :                                 args.v3.sInput.ucExtTransmitterID =
     427           0 :                                         amdgpu_encoder_get_dp_bridge_encoder_id(encoder);
     428             :                         else
     429           0 :                                 args.v3.sInput.ucExtTransmitterID = 0;
     430             : 
     431           0 :                         amdgpu_atom_execute_table(adev->mode_info.atom_context,
     432             :                                            index, (uint32_t *)&args);
     433           0 :                         adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
     434           0 :                         if (args.v3.sOutput.ucRefDiv) {
     435           0 :                                 amdgpu_crtc->pll_flags |= AMDGPU_PLL_USE_FRAC_FB_DIV;
     436           0 :                                 amdgpu_crtc->pll_flags |= AMDGPU_PLL_USE_REF_DIV;
     437           0 :                                 amdgpu_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv;
     438             :                         }
     439           0 :                         if (args.v3.sOutput.ucPostDiv) {
     440           0 :                                 amdgpu_crtc->pll_flags |= AMDGPU_PLL_USE_FRAC_FB_DIV;
     441           0 :                                 amdgpu_crtc->pll_flags |= AMDGPU_PLL_USE_POST_DIV;
     442           0 :                                 amdgpu_crtc->pll_post_div = args.v3.sOutput.ucPostDiv;
     443             :                         }
     444             :                         break;
     445             :                 default:
     446           0 :                         DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     447             :                         return adjusted_clock;
     448             :                 }
     449             :                 break;
     450             :         default:
     451           0 :                 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     452             :                 return adjusted_clock;
     453             :         }
     454             : 
     455             :         return adjusted_clock;
     456             : }
     457             : 
     458             : union set_pixel_clock {
     459             :         SET_PIXEL_CLOCK_PS_ALLOCATION base;
     460             :         PIXEL_CLOCK_PARAMETERS v1;
     461             :         PIXEL_CLOCK_PARAMETERS_V2 v2;
     462             :         PIXEL_CLOCK_PARAMETERS_V3 v3;
     463             :         PIXEL_CLOCK_PARAMETERS_V5 v5;
     464             :         PIXEL_CLOCK_PARAMETERS_V6 v6;
     465             :         PIXEL_CLOCK_PARAMETERS_V7 v7;
     466             : };
     467             : 
     468             : /* on DCE5, make sure the voltage is high enough to support the
     469             :  * required disp clk.
     470             :  */
     471           0 : void amdgpu_atombios_crtc_set_disp_eng_pll(struct amdgpu_device *adev,
     472             :                                            u32 dispclk)
     473             : {
     474             :         u8 frev, crev;
     475             :         int index;
     476             :         union set_pixel_clock args;
     477             : 
     478           0 :         memset(&args, 0, sizeof(args));
     479             : 
     480           0 :         index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
     481           0 :         if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev,
     482             :                                    &crev))
     483           0 :                 return;
     484             : 
     485           0 :         switch (frev) {
     486             :         case 1:
     487           0 :                 switch (crev) {
     488             :                 case 5:
     489             :                         /* if the default dcpll clock is specified,
     490             :                          * SetPixelClock provides the dividers
     491             :                          */
     492           0 :                         args.v5.ucCRTC = ATOM_CRTC_INVALID;
     493           0 :                         args.v5.usPixelClock = cpu_to_le16(dispclk);
     494           0 :                         args.v5.ucPpll = ATOM_DCPLL;
     495           0 :                         break;
     496             :                 case 6:
     497             :                         /* if the default dcpll clock is specified,
     498             :                          * SetPixelClock provides the dividers
     499             :                          */
     500           0 :                         args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
     501           0 :                         if (adev->asic_type == CHIP_TAHITI ||
     502             :                             adev->asic_type == CHIP_PITCAIRN ||
     503             :                             adev->asic_type == CHIP_VERDE ||
     504             :                             adev->asic_type == CHIP_OLAND)
     505           0 :                                 args.v6.ucPpll = ATOM_PPLL0;
     506             :                         else
     507           0 :                                 args.v6.ucPpll = ATOM_EXT_PLL1;
     508             :                         break;
     509             :                 default:
     510           0 :                         DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     511           0 :                         return;
     512             :                 }
     513             :                 break;
     514             :         default:
     515           0 :                 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     516           0 :                 return;
     517             :         }
     518           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     519             : }
     520             : 
     521             : union set_dce_clock {
     522             :         SET_DCE_CLOCK_PS_ALLOCATION_V1_1 v1_1;
     523             :         SET_DCE_CLOCK_PS_ALLOCATION_V2_1 v2_1;
     524             : };
     525             : 
     526           0 : u32 amdgpu_atombios_crtc_set_dce_clock(struct amdgpu_device *adev,
     527             :                                        u32 freq, u8 clk_type, u8 clk_src)
     528             : {
     529             :         u8 frev, crev;
     530             :         int index;
     531             :         union set_dce_clock args;
     532           0 :         u32 ret_freq = 0;
     533             : 
     534           0 :         memset(&args, 0, sizeof(args));
     535             : 
     536           0 :         index = GetIndexIntoMasterTable(COMMAND, SetDCEClock);
     537           0 :         if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev,
     538             :                                    &crev))
     539             :                 return 0;
     540             : 
     541           0 :         switch (frev) {
     542             :         case 2:
     543           0 :                 switch (crev) {
     544             :                 case 1:
     545           0 :                         args.v2_1.asParam.ulDCEClkFreq = cpu_to_le32(freq); /* 10kHz units */
     546           0 :                         args.v2_1.asParam.ucDCEClkType = clk_type;
     547           0 :                         args.v2_1.asParam.ucDCEClkSrc = clk_src;
     548           0 :                         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     549           0 :                         ret_freq = le32_to_cpu(args.v2_1.asParam.ulDCEClkFreq) * 10;
     550             :                         break;
     551             :                 default:
     552           0 :                         DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     553           0 :                         return 0;
     554             :                 }
     555             :                 break;
     556             :         default:
     557           0 :                 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     558           0 :                 return 0;
     559             :         }
     560             : 
     561           0 :         return ret_freq;
     562             : }
     563             : 
     564             : static bool is_pixel_clock_source_from_pll(u32 encoder_mode, int pll_id)
     565             : {
     566             :         if (ENCODER_MODE_IS_DP(encoder_mode)) {
     567             :                 if (pll_id < ATOM_EXT_PLL1)
     568             :                         return true;
     569             :                 else
     570             :                         return false;
     571             :         } else {
     572             :                 return true;
     573             :         }
     574             : }
     575             : 
     576           0 : void amdgpu_atombios_crtc_program_pll(struct drm_crtc *crtc,
     577             :                                       u32 crtc_id,
     578             :                                       int pll_id,
     579             :                                       u32 encoder_mode,
     580             :                                       u32 encoder_id,
     581             :                                       u32 clock,
     582             :                                       u32 ref_div,
     583             :                                       u32 fb_div,
     584             :                                       u32 frac_fb_div,
     585             :                                       u32 post_div,
     586             :                                       int bpc,
     587             :                                       bool ss_enabled,
     588             :                                       struct amdgpu_atom_ss *ss)
     589             : {
     590           0 :         struct drm_device *dev = crtc->dev;
     591           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     592             :         u8 frev, crev;
     593           0 :         int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
     594             :         union set_pixel_clock args;
     595             : 
     596           0 :         memset(&args, 0, sizeof(args));
     597             : 
     598           0 :         if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev,
     599             :                                    &crev))
     600           0 :                 return;
     601             : 
     602           0 :         switch (frev) {
     603             :         case 1:
     604           0 :                 switch (crev) {
     605             :                 case 1:
     606           0 :                         if (clock == ATOM_DISABLE)
     607             :                                 return;
     608           0 :                         args.v1.usPixelClock = cpu_to_le16(clock / 10);
     609           0 :                         args.v1.usRefDiv = cpu_to_le16(ref_div);
     610           0 :                         args.v1.usFbDiv = cpu_to_le16(fb_div);
     611           0 :                         args.v1.ucFracFbDiv = frac_fb_div;
     612           0 :                         args.v1.ucPostDiv = post_div;
     613           0 :                         args.v1.ucPpll = pll_id;
     614           0 :                         args.v1.ucCRTC = crtc_id;
     615           0 :                         args.v1.ucRefDivSrc = 1;
     616           0 :                         break;
     617             :                 case 2:
     618           0 :                         args.v2.usPixelClock = cpu_to_le16(clock / 10);
     619           0 :                         args.v2.usRefDiv = cpu_to_le16(ref_div);
     620           0 :                         args.v2.usFbDiv = cpu_to_le16(fb_div);
     621           0 :                         args.v2.ucFracFbDiv = frac_fb_div;
     622           0 :                         args.v2.ucPostDiv = post_div;
     623           0 :                         args.v2.ucPpll = pll_id;
     624           0 :                         args.v2.ucCRTC = crtc_id;
     625           0 :                         args.v2.ucRefDivSrc = 1;
     626           0 :                         break;
     627             :                 case 3:
     628           0 :                         args.v3.usPixelClock = cpu_to_le16(clock / 10);
     629           0 :                         args.v3.usRefDiv = cpu_to_le16(ref_div);
     630           0 :                         args.v3.usFbDiv = cpu_to_le16(fb_div);
     631           0 :                         args.v3.ucFracFbDiv = frac_fb_div;
     632           0 :                         args.v3.ucPostDiv = post_div;
     633           0 :                         args.v3.ucPpll = pll_id;
     634           0 :                         if (crtc_id == ATOM_CRTC2)
     635           0 :                                 args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
     636             :                         else
     637           0 :                                 args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1;
     638           0 :                         if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
     639           0 :                                 args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
     640           0 :                         args.v3.ucTransmitterId = encoder_id;
     641           0 :                         args.v3.ucEncoderMode = encoder_mode;
     642           0 :                         break;
     643             :                 case 5:
     644           0 :                         args.v5.ucCRTC = crtc_id;
     645           0 :                         args.v5.usPixelClock = cpu_to_le16(clock / 10);
     646           0 :                         args.v5.ucRefDiv = ref_div;
     647           0 :                         args.v5.usFbDiv = cpu_to_le16(fb_div);
     648           0 :                         args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
     649           0 :                         args.v5.ucPostDiv = post_div;
     650           0 :                         args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
     651           0 :                         if ((ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) &&
     652             :                             (pll_id < ATOM_EXT_PLL1))
     653           0 :                                 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
     654           0 :                         if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
     655           0 :                                 switch (bpc) {
     656             :                                 case 8:
     657             :                                 default:
     658             :                                         args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
     659             :                                         break;
     660             :                                 case 10:
     661             :                                         /* yes this is correct, the atom define is wrong */
     662           0 :                                         args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
     663           0 :                                         break;
     664             :                                 case 12:
     665             :                                         /* yes this is correct, the atom define is wrong */
     666           0 :                                         args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
     667           0 :                                         break;
     668             :                                 }
     669             :                         }
     670           0 :                         args.v5.ucTransmitterID = encoder_id;
     671           0 :                         args.v5.ucEncoderMode = encoder_mode;
     672           0 :                         args.v5.ucPpll = pll_id;
     673           0 :                         break;
     674             :                 case 6:
     675           0 :                         args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10);
     676           0 :                         args.v6.ucRefDiv = ref_div;
     677           0 :                         args.v6.usFbDiv = cpu_to_le16(fb_div);
     678           0 :                         args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
     679           0 :                         args.v6.ucPostDiv = post_div;
     680           0 :                         args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
     681             :                         if ((ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) &&
     682             :                             (pll_id < ATOM_EXT_PLL1) &&
     683             :                             !is_pixel_clock_source_from_pll(encoder_mode, pll_id))
     684             :                                 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
     685           0 :                         if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
     686           0 :                                 switch (bpc) {
     687             :                                 case 8:
     688             :                                 default:
     689             :                                         args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
     690             :                                         break;
     691             :                                 case 10:
     692           0 :                                         args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6;
     693           0 :                                         break;
     694             :                                 case 12:
     695           0 :                                         args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6;
     696           0 :                                         break;
     697             :                                 case 16:
     698           0 :                                         args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
     699           0 :                                         break;
     700             :                                 }
     701             :                         }
     702           0 :                         args.v6.ucTransmitterID = encoder_id;
     703           0 :                         args.v6.ucEncoderMode = encoder_mode;
     704           0 :                         args.v6.ucPpll = pll_id;
     705           0 :                         break;
     706             :                 case 7:
     707           0 :                         args.v7.ulPixelClock = cpu_to_le32(clock * 10); /* 100 hz units */
     708           0 :                         args.v7.ucMiscInfo = 0;
     709           0 :                         if ((encoder_mode == ATOM_ENCODER_MODE_DVI) &&
     710           0 :                             (clock > 165000))
     711           0 :                                 args.v7.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
     712           0 :                         args.v7.ucCRTC = crtc_id;
     713           0 :                         if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
     714           0 :                                 switch (bpc) {
     715             :                                 case 8:
     716             :                                 default:
     717           0 :                                         args.v7.ucDeepColorRatio = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_DIS;
     718           0 :                                         break;
     719             :                                 case 10:
     720           0 :                                         args.v7.ucDeepColorRatio = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_5_4;
     721           0 :                                         break;
     722             :                                 case 12:
     723           0 :                                         args.v7.ucDeepColorRatio = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_3_2;
     724           0 :                                         break;
     725             :                                 case 16:
     726           0 :                                         args.v7.ucDeepColorRatio = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_2_1;
     727           0 :                                         break;
     728             :                                 }
     729             :                         }
     730           0 :                         args.v7.ucTransmitterID = encoder_id;
     731           0 :                         args.v7.ucEncoderMode = encoder_mode;
     732           0 :                         args.v7.ucPpll = pll_id;
     733           0 :                         break;
     734             :                 default:
     735           0 :                         DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     736           0 :                         return;
     737             :                 }
     738             :                 break;
     739             :         default:
     740           0 :                 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     741           0 :                 return;
     742             :         }
     743             : 
     744           0 :         amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
     745             : }
     746             : 
     747           0 : int amdgpu_atombios_crtc_prepare_pll(struct drm_crtc *crtc,
     748             :                               struct drm_display_mode *mode)
     749             : {
     750           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
     751           0 :         struct drm_device *dev = crtc->dev;
     752           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     753           0 :         struct amdgpu_encoder *amdgpu_encoder =
     754           0 :                 to_amdgpu_encoder(amdgpu_crtc->encoder);
     755           0 :         int encoder_mode = amdgpu_atombios_encoder_get_encoder_mode(amdgpu_crtc->encoder);
     756             : 
     757           0 :         amdgpu_crtc->bpc = 8;
     758           0 :         amdgpu_crtc->ss_enabled = false;
     759             : 
     760           0 :         if ((amdgpu_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
     761           0 :             (amdgpu_encoder_get_dp_bridge_encoder_id(amdgpu_crtc->encoder) != ENCODER_OBJECT_ID_NONE)) {
     762           0 :                 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
     763           0 :                 struct drm_connector *connector =
     764           0 :                         amdgpu_get_connector_for_encoder(amdgpu_crtc->encoder);
     765           0 :                 struct amdgpu_connector *amdgpu_connector =
     766           0 :                         to_amdgpu_connector(connector);
     767           0 :                 struct amdgpu_connector_atom_dig *dig_connector =
     768             :                         amdgpu_connector->con_priv;
     769             :                 int dp_clock;
     770             : 
     771             :                 /* Assign mode clock for hdmi deep color max clock limit check */
     772           0 :                 amdgpu_connector->pixelclock_for_modeset = mode->clock;
     773           0 :                 amdgpu_crtc->bpc = amdgpu_connector_get_monitor_bpc(connector);
     774             : 
     775           0 :                 switch (encoder_mode) {
     776             :                 case ATOM_ENCODER_MODE_DP_MST:
     777             :                 case ATOM_ENCODER_MODE_DP:
     778             :                         /* DP/eDP */
     779           0 :                         dp_clock = dig_connector->dp_clock / 10;
     780           0 :                         amdgpu_crtc->ss_enabled =
     781           0 :                                 amdgpu_atombios_get_asic_ss_info(adev, &amdgpu_crtc->ss,
     782             :                                                                  ASIC_INTERNAL_SS_ON_DP,
     783             :                                                                  dp_clock);
     784           0 :                         break;
     785             :                 case ATOM_ENCODER_MODE_LVDS:
     786           0 :                         amdgpu_crtc->ss_enabled =
     787           0 :                                 amdgpu_atombios_get_asic_ss_info(adev,
     788             :                                                                  &amdgpu_crtc->ss,
     789           0 :                                                                  dig->lcd_ss_id,
     790           0 :                                                                  mode->clock / 10);
     791           0 :                         break;
     792             :                 case ATOM_ENCODER_MODE_DVI:
     793           0 :                         amdgpu_crtc->ss_enabled =
     794           0 :                                 amdgpu_atombios_get_asic_ss_info(adev,
     795             :                                                                  &amdgpu_crtc->ss,
     796             :                                                                  ASIC_INTERNAL_SS_ON_TMDS,
     797           0 :                                                                  mode->clock / 10);
     798           0 :                         break;
     799             :                 case ATOM_ENCODER_MODE_HDMI:
     800           0 :                         amdgpu_crtc->ss_enabled =
     801           0 :                                 amdgpu_atombios_get_asic_ss_info(adev,
     802             :                                                                  &amdgpu_crtc->ss,
     803             :                                                                  ASIC_INTERNAL_SS_ON_HDMI,
     804           0 :                                                                  mode->clock / 10);
     805           0 :                         break;
     806             :                 default:
     807             :                         break;
     808             :                 }
     809             :         }
     810             : 
     811             :         /* adjust pixel clock as needed */
     812           0 :         amdgpu_crtc->adjusted_clock = amdgpu_atombios_crtc_adjust_pll(crtc, mode);
     813             : 
     814           0 :         return 0;
     815             : }
     816             : 
     817           0 : void amdgpu_atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
     818             : {
     819           0 :         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
     820           0 :         struct drm_device *dev = crtc->dev;
     821           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
     822           0 :         struct amdgpu_encoder *amdgpu_encoder =
     823           0 :                 to_amdgpu_encoder(amdgpu_crtc->encoder);
     824           0 :         u32 pll_clock = mode->clock;
     825           0 :         u32 clock = mode->clock;
     826           0 :         u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
     827             :         struct amdgpu_pll *pll;
     828           0 :         int encoder_mode = amdgpu_atombios_encoder_get_encoder_mode(amdgpu_crtc->encoder);
     829             : 
     830             :         /* pass the actual clock to amdgpu_atombios_crtc_program_pll for HDMI */
     831           0 :         if ((encoder_mode == ATOM_ENCODER_MODE_HDMI) &&
     832           0 :             (amdgpu_crtc->bpc > 8))
     833           0 :                 clock = amdgpu_crtc->adjusted_clock;
     834             : 
     835           0 :         switch (amdgpu_crtc->pll_id) {
     836             :         case ATOM_PPLL1:
     837           0 :                 pll = &adev->clock.ppll[0];
     838           0 :                 break;
     839             :         case ATOM_PPLL2:
     840           0 :                 pll = &adev->clock.ppll[1];
     841           0 :                 break;
     842             :         case ATOM_PPLL0:
     843             :         case ATOM_PPLL_INVALID:
     844             :         default:
     845           0 :                 pll = &adev->clock.ppll[2];
     846           0 :                 break;
     847             :         }
     848             : 
     849             :         /* update pll params */
     850           0 :         pll->flags = amdgpu_crtc->pll_flags;
     851           0 :         pll->reference_div = amdgpu_crtc->pll_reference_div;
     852           0 :         pll->post_div = amdgpu_crtc->pll_post_div;
     853             : 
     854           0 :         amdgpu_pll_compute(adev, pll, amdgpu_crtc->adjusted_clock, &pll_clock,
     855             :                             &fb_div, &frac_fb_div, &ref_div, &post_div);
     856             : 
     857           0 :         amdgpu_atombios_crtc_program_ss(adev, ATOM_DISABLE, amdgpu_crtc->pll_id,
     858             :                                  amdgpu_crtc->crtc_id, &amdgpu_crtc->ss);
     859             : 
     860           0 :         amdgpu_atombios_crtc_program_pll(crtc, amdgpu_crtc->crtc_id, amdgpu_crtc->pll_id,
     861             :                                   encoder_mode, amdgpu_encoder->encoder_id, clock,
     862             :                                   ref_div, fb_div, frac_fb_div, post_div,
     863           0 :                                   amdgpu_crtc->bpc, amdgpu_crtc->ss_enabled, &amdgpu_crtc->ss);
     864             : 
     865           0 :         if (amdgpu_crtc->ss_enabled) {
     866             :                 /* calculate ss amount and step size */
     867             :                 u32 step_size;
     868           0 :                 u32 amount = (((fb_div * 10) + frac_fb_div) *
     869           0 :                               (u32)amdgpu_crtc->ss.percentage) /
     870           0 :                         (100 * (u32)amdgpu_crtc->ss.percentage_divider);
     871           0 :                 amdgpu_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
     872           0 :                 amdgpu_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
     873             :                         ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
     874           0 :                 if (amdgpu_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
     875           0 :                         step_size = (4 * amount * ref_div * ((u32)amdgpu_crtc->ss.rate * 2048)) /
     876           0 :                                 (125 * 25 * pll->reference_freq / 100);
     877             :                 else
     878           0 :                         step_size = (2 * amount * ref_div * ((u32)amdgpu_crtc->ss.rate * 2048)) /
     879           0 :                                 (125 * 25 * pll->reference_freq / 100);
     880           0 :                 amdgpu_crtc->ss.step = step_size;
     881             : 
     882           0 :                 amdgpu_atombios_crtc_program_ss(adev, ATOM_ENABLE, amdgpu_crtc->pll_id,
     883             :                                          amdgpu_crtc->crtc_id, &amdgpu_crtc->ss);
     884             :         }
     885           0 : }
     886             : 

Generated by: LCOV version 1.14