LCOV - code coverage report
Current view: top level - dev/pci/drm/radeon - atombios_crtc.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1224 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          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             : #include <dev/pci/drm/drmP.h>
      27             : #include <dev/pci/drm/drm_crtc_helper.h>
      28             : #include <dev/pci/drm/radeon_drm.h>
      29             : #include <dev/pci/drm/drm_fixed.h>
      30             : #include "radeon.h"
      31             : #include "atom.h"
      32             : #include "atom-bits.h"
      33             : 
      34           0 : static void atombios_overscan_setup(struct drm_crtc *crtc,
      35             :                                     struct drm_display_mode *mode,
      36             :                                     struct drm_display_mode *adjusted_mode)
      37             : {
      38           0 :         struct drm_device *dev = crtc->dev;
      39           0 :         struct radeon_device *rdev = dev->dev_private;
      40           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
      41           0 :         SET_CRTC_OVERSCAN_PS_ALLOCATION args;
      42             :         int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
      43             :         int a1, a2;
      44             : 
      45           0 :         memset(&args, 0, sizeof(args));
      46             : 
      47           0 :         args.ucCRTC = radeon_crtc->crtc_id;
      48             : 
      49           0 :         switch (radeon_crtc->rmx_type) {
      50             :         case RMX_CENTER:
      51           0 :                 args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
      52           0 :                 args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
      53           0 :                 args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
      54           0 :                 args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
      55           0 :                 break;
      56             :         case RMX_ASPECT:
      57           0 :                 a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
      58           0 :                 a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
      59             : 
      60           0 :                 if (a1 > a2) {
      61           0 :                         args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
      62           0 :                         args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
      63           0 :                 } else if (a2 > a1) {
      64           0 :                         args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
      65           0 :                         args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
      66           0 :                 }
      67             :                 break;
      68             :         case RMX_FULL:
      69             :         default:
      70           0 :                 args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border);
      71           0 :                 args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border);
      72           0 :                 args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border);
      73           0 :                 args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border);
      74           0 :                 break;
      75             :         }
      76           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
      77           0 : }
      78             : 
      79           0 : static void atombios_scaler_setup(struct drm_crtc *crtc)
      80             : {
      81           0 :         struct drm_device *dev = crtc->dev;
      82           0 :         struct radeon_device *rdev = dev->dev_private;
      83           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
      84           0 :         ENABLE_SCALER_PS_ALLOCATION args;
      85             :         int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
      86             :         struct radeon_encoder *radeon_encoder =
      87           0 :                 to_radeon_encoder(radeon_crtc->encoder);
      88             :         /* fixme - fill in enc_priv for atom dac */
      89             :         enum radeon_tv_std tv_std = TV_STD_NTSC;
      90             :         bool is_tv = false, is_cv = false;
      91             : 
      92           0 :         if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
      93           0 :                 return;
      94             : 
      95           0 :         if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
      96           0 :                 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
      97           0 :                 tv_std = tv_dac->tv_std;
      98             :                 is_tv = true;
      99           0 :         }
     100             : 
     101           0 :         memset(&args, 0, sizeof(args));
     102             : 
     103           0 :         args.ucScaler = radeon_crtc->crtc_id;
     104             : 
     105           0 :         if (is_tv) {
     106           0 :                 switch (tv_std) {
     107             :                 case TV_STD_NTSC:
     108             :                 default:
     109           0 :                         args.ucTVStandard = ATOM_TV_NTSC;
     110           0 :                         break;
     111             :                 case TV_STD_PAL:
     112           0 :                         args.ucTVStandard = ATOM_TV_PAL;
     113           0 :                         break;
     114             :                 case TV_STD_PAL_M:
     115           0 :                         args.ucTVStandard = ATOM_TV_PALM;
     116           0 :                         break;
     117             :                 case TV_STD_PAL_60:
     118           0 :                         args.ucTVStandard = ATOM_TV_PAL60;
     119           0 :                         break;
     120             :                 case TV_STD_NTSC_J:
     121           0 :                         args.ucTVStandard = ATOM_TV_NTSCJ;
     122           0 :                         break;
     123             :                 case TV_STD_SCART_PAL:
     124           0 :                         args.ucTVStandard = ATOM_TV_PAL; /* ??? */
     125           0 :                         break;
     126             :                 case TV_STD_SECAM:
     127           0 :                         args.ucTVStandard = ATOM_TV_SECAM;
     128           0 :                         break;
     129             :                 case TV_STD_PAL_CN:
     130           0 :                         args.ucTVStandard = ATOM_TV_PALCN;
     131           0 :                         break;
     132             :                 }
     133           0 :                 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
     134           0 :         } else if (is_cv) {
     135           0 :                 args.ucTVStandard = ATOM_TV_CV;
     136           0 :                 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
     137           0 :         } else {
     138           0 :                 switch (radeon_crtc->rmx_type) {
     139             :                 case RMX_FULL:
     140           0 :                         args.ucEnable = ATOM_SCALER_EXPANSION;
     141           0 :                         break;
     142             :                 case RMX_CENTER:
     143           0 :                         args.ucEnable = ATOM_SCALER_CENTER;
     144           0 :                         break;
     145             :                 case RMX_ASPECT:
     146           0 :                         args.ucEnable = ATOM_SCALER_EXPANSION;
     147           0 :                         break;
     148             :                 default:
     149           0 :                         if (ASIC_IS_AVIVO(rdev))
     150           0 :                                 args.ucEnable = ATOM_SCALER_DISABLE;
     151             :                         else
     152           0 :                                 args.ucEnable = ATOM_SCALER_CENTER;
     153             :                         break;
     154             :                 }
     155             :         }
     156           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     157           0 :         if ((is_tv || is_cv)
     158           0 :             && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
     159           0 :                 atom_rv515_force_tv_scaler(rdev, radeon_crtc);
     160           0 :         }
     161           0 : }
     162             : 
     163           0 : static void atombios_lock_crtc(struct drm_crtc *crtc, int lock)
     164             : {
     165           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     166           0 :         struct drm_device *dev = crtc->dev;
     167           0 :         struct radeon_device *rdev = dev->dev_private;
     168             :         int index =
     169             :             GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
     170           0 :         ENABLE_CRTC_PS_ALLOCATION args;
     171             : 
     172           0 :         memset(&args, 0, sizeof(args));
     173             : 
     174           0 :         args.ucCRTC = radeon_crtc->crtc_id;
     175           0 :         args.ucEnable = lock;
     176             : 
     177           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     178           0 : }
     179             : 
     180           0 : static void atombios_enable_crtc(struct drm_crtc *crtc, int state)
     181             : {
     182           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     183           0 :         struct drm_device *dev = crtc->dev;
     184           0 :         struct radeon_device *rdev = dev->dev_private;
     185             :         int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
     186           0 :         ENABLE_CRTC_PS_ALLOCATION args;
     187             : 
     188           0 :         memset(&args, 0, sizeof(args));
     189             : 
     190           0 :         args.ucCRTC = radeon_crtc->crtc_id;
     191           0 :         args.ucEnable = state;
     192             : 
     193           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     194           0 : }
     195             : 
     196           0 : static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
     197             : {
     198           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     199           0 :         struct drm_device *dev = crtc->dev;
     200           0 :         struct radeon_device *rdev = dev->dev_private;
     201             :         int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
     202           0 :         ENABLE_CRTC_PS_ALLOCATION args;
     203             : 
     204           0 :         memset(&args, 0, sizeof(args));
     205             : 
     206           0 :         args.ucCRTC = radeon_crtc->crtc_id;
     207           0 :         args.ucEnable = state;
     208             : 
     209           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     210           0 : }
     211             : 
     212             : static const u32 vga_control_regs[6] =
     213             : {
     214             :         AVIVO_D1VGA_CONTROL,
     215             :         AVIVO_D2VGA_CONTROL,
     216             :         EVERGREEN_D3VGA_CONTROL,
     217             :         EVERGREEN_D4VGA_CONTROL,
     218             :         EVERGREEN_D5VGA_CONTROL,
     219             :         EVERGREEN_D6VGA_CONTROL,
     220             : };
     221             : 
     222           0 : static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
     223             : {
     224           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     225           0 :         struct drm_device *dev = crtc->dev;
     226           0 :         struct radeon_device *rdev = dev->dev_private;
     227             :         int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
     228           0 :         BLANK_CRTC_PS_ALLOCATION args;
     229             :         u32 vga_control = 0;
     230             : 
     231           0 :         memset(&args, 0, sizeof(args));
     232             : 
     233           0 :         if (ASIC_IS_DCE8(rdev)) {
     234           0 :                 vga_control = RREG32(vga_control_regs[radeon_crtc->crtc_id]);
     235           0 :                 WREG32(vga_control_regs[radeon_crtc->crtc_id], vga_control | 1);
     236           0 :         }
     237             : 
     238           0 :         args.ucCRTC = radeon_crtc->crtc_id;
     239           0 :         args.ucBlanking = state;
     240             : 
     241           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     242             : 
     243           0 :         if (ASIC_IS_DCE8(rdev)) {
     244           0 :                 WREG32(vga_control_regs[radeon_crtc->crtc_id], vga_control);
     245           0 :         }
     246           0 : }
     247             : 
     248           0 : static void atombios_powergate_crtc(struct drm_crtc *crtc, int state)
     249             : {
     250           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     251           0 :         struct drm_device *dev = crtc->dev;
     252           0 :         struct radeon_device *rdev = dev->dev_private;
     253             :         int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
     254           0 :         ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args;
     255             : 
     256           0 :         memset(&args, 0, sizeof(args));
     257             : 
     258           0 :         args.ucDispPipeId = radeon_crtc->crtc_id;
     259           0 :         args.ucEnable = state;
     260             : 
     261           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     262           0 : }
     263             : 
     264           0 : void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
     265             : {
     266           0 :         struct drm_device *dev = crtc->dev;
     267           0 :         struct radeon_device *rdev = dev->dev_private;
     268           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     269             : 
     270           0 :         switch (mode) {
     271             :         case DRM_MODE_DPMS_ON:
     272           0 :                 radeon_crtc->enabled = true;
     273           0 :                 atombios_enable_crtc(crtc, ATOM_ENABLE);
     274           0 :                 if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
     275           0 :                         atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
     276           0 :                 atombios_blank_crtc(crtc, ATOM_DISABLE);
     277           0 :                 drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
     278             :                 /* Make sure vblank interrupt is still enabled if needed */
     279           0 :                 radeon_irq_set(rdev);
     280           0 :                 radeon_crtc_load_lut(crtc);
     281           0 :                 break;
     282             :         case DRM_MODE_DPMS_STANDBY:
     283             :         case DRM_MODE_DPMS_SUSPEND:
     284             :         case DRM_MODE_DPMS_OFF:
     285           0 :                 drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
     286           0 :                 if (radeon_crtc->enabled)
     287           0 :                         atombios_blank_crtc(crtc, ATOM_ENABLE);
     288           0 :                 if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
     289           0 :                         atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
     290           0 :                 atombios_enable_crtc(crtc, ATOM_DISABLE);
     291           0 :                 radeon_crtc->enabled = false;
     292           0 :                 break;
     293             :         }
     294             :         /* adjust pm to dpms */
     295           0 :         radeon_pm_compute_clocks(rdev);
     296           0 : }
     297             : 
     298             : static void
     299           0 : atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
     300             :                              struct drm_display_mode *mode)
     301             : {
     302           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     303           0 :         struct drm_device *dev = crtc->dev;
     304           0 :         struct radeon_device *rdev = dev->dev_private;
     305           0 :         SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
     306             :         int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
     307             :         u16 misc = 0;
     308             : 
     309           0 :         memset(&args, 0, sizeof(args));
     310           0 :         args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2));
     311           0 :         args.usH_Blanking_Time =
     312           0 :                 cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2));
     313           0 :         args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2));
     314           0 :         args.usV_Blanking_Time =
     315           0 :                 cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2));
     316           0 :         args.usH_SyncOffset =
     317           0 :                 cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border);
     318           0 :         args.usH_SyncWidth =
     319           0 :                 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
     320           0 :         args.usV_SyncOffset =
     321           0 :                 cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border);
     322           0 :         args.usV_SyncWidth =
     323           0 :                 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
     324           0 :         args.ucH_Border = radeon_crtc->h_border;
     325           0 :         args.ucV_Border = radeon_crtc->v_border;
     326             : 
     327           0 :         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
     328           0 :                 misc |= ATOM_VSYNC_POLARITY;
     329           0 :         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
     330           0 :                 misc |= ATOM_HSYNC_POLARITY;
     331           0 :         if (mode->flags & DRM_MODE_FLAG_CSYNC)
     332           0 :                 misc |= ATOM_COMPOSITESYNC;
     333           0 :         if (mode->flags & DRM_MODE_FLAG_INTERLACE)
     334           0 :                 misc |= ATOM_INTERLACE;
     335           0 :         if (mode->flags & DRM_MODE_FLAG_DBLCLK)
     336           0 :                 misc |= ATOM_DOUBLE_CLOCK_MODE;
     337           0 :         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
     338           0 :                 misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
     339             : 
     340           0 :         args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
     341           0 :         args.ucCRTC = radeon_crtc->crtc_id;
     342             : 
     343           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     344           0 : }
     345             : 
     346           0 : static void atombios_crtc_set_timing(struct drm_crtc *crtc,
     347             :                                      struct drm_display_mode *mode)
     348             : {
     349           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     350           0 :         struct drm_device *dev = crtc->dev;
     351           0 :         struct radeon_device *rdev = dev->dev_private;
     352           0 :         SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args;
     353             :         int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
     354             :         u16 misc = 0;
     355             : 
     356           0 :         memset(&args, 0, sizeof(args));
     357           0 :         args.usH_Total = cpu_to_le16(mode->crtc_htotal);
     358           0 :         args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay);
     359           0 :         args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start);
     360           0 :         args.usH_SyncWidth =
     361           0 :                 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
     362           0 :         args.usV_Total = cpu_to_le16(mode->crtc_vtotal);
     363           0 :         args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay);
     364           0 :         args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start);
     365           0 :         args.usV_SyncWidth =
     366           0 :                 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
     367             : 
     368           0 :         args.ucOverscanRight = radeon_crtc->h_border;
     369           0 :         args.ucOverscanLeft = radeon_crtc->h_border;
     370           0 :         args.ucOverscanBottom = radeon_crtc->v_border;
     371           0 :         args.ucOverscanTop = radeon_crtc->v_border;
     372             : 
     373           0 :         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
     374           0 :                 misc |= ATOM_VSYNC_POLARITY;
     375           0 :         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
     376           0 :                 misc |= ATOM_HSYNC_POLARITY;
     377           0 :         if (mode->flags & DRM_MODE_FLAG_CSYNC)
     378           0 :                 misc |= ATOM_COMPOSITESYNC;
     379           0 :         if (mode->flags & DRM_MODE_FLAG_INTERLACE)
     380           0 :                 misc |= ATOM_INTERLACE;
     381           0 :         if (mode->flags & DRM_MODE_FLAG_DBLCLK)
     382           0 :                 misc |= ATOM_DOUBLE_CLOCK_MODE;
     383           0 :         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
     384           0 :                 misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
     385             : 
     386           0 :         args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
     387           0 :         args.ucCRTC = radeon_crtc->crtc_id;
     388             : 
     389           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     390           0 : }
     391             : 
     392           0 : static void atombios_disable_ss(struct radeon_device *rdev, int pll_id)
     393             : {
     394             :         u32 ss_cntl;
     395             : 
     396           0 :         if (ASIC_IS_DCE4(rdev)) {
     397           0 :                 switch (pll_id) {
     398             :                 case ATOM_PPLL1:
     399           0 :                         ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
     400           0 :                         ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
     401           0 :                         WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
     402           0 :                         break;
     403             :                 case ATOM_PPLL2:
     404           0 :                         ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
     405           0 :                         ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
     406           0 :                         WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
     407           0 :                         break;
     408             :                 case ATOM_DCPLL:
     409             :                 case ATOM_PPLL_INVALID:
     410           0 :                         return;
     411             :                 }
     412           0 :         } else if (ASIC_IS_AVIVO(rdev)) {
     413           0 :                 switch (pll_id) {
     414             :                 case ATOM_PPLL1:
     415           0 :                         ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
     416           0 :                         ss_cntl &= ~1;
     417           0 :                         WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
     418           0 :                         break;
     419             :                 case ATOM_PPLL2:
     420           0 :                         ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
     421           0 :                         ss_cntl &= ~1;
     422           0 :                         WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
     423           0 :                         break;
     424             :                 case ATOM_DCPLL:
     425             :                 case ATOM_PPLL_INVALID:
     426           0 :                         return;
     427             :                 }
     428             :         }
     429           0 : }
     430             : 
     431             : 
     432             : union atom_enable_ss {
     433             :         ENABLE_LVDS_SS_PARAMETERS lvds_ss;
     434             :         ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2;
     435             :         ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
     436             :         ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2;
     437             :         ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
     438             : };
     439             : 
     440           0 : static void atombios_crtc_program_ss(struct radeon_device *rdev,
     441             :                                      int enable,
     442             :                                      int pll_id,
     443             :                                      int crtc_id,
     444             :                                      struct radeon_atom_ss *ss)
     445             : {
     446             :         unsigned i;
     447             :         int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
     448           0 :         union atom_enable_ss args;
     449             : 
     450           0 :         if (enable) {
     451             :                 /* Don't mess with SS if percentage is 0 or external ss.
     452             :                  * SS is already disabled previously, and disabling it
     453             :                  * again can cause display problems if the pll is already
     454             :                  * programmed.
     455             :                  */
     456           0 :                 if (ss->percentage == 0)
     457           0 :                         return;
     458           0 :                 if (ss->type & ATOM_EXTERNAL_SS_MASK)
     459           0 :                         return;
     460             :         } else {
     461           0 :                 for (i = 0; i < rdev->num_crtc; i++) {
     462           0 :                         if (rdev->mode_info.crtcs[i] &&
     463           0 :                             rdev->mode_info.crtcs[i]->enabled &&
     464           0 :                             i != crtc_id &&
     465           0 :                             pll_id == rdev->mode_info.crtcs[i]->pll_id) {
     466             :                                 /* one other crtc is using this pll don't turn
     467             :                                  * off spread spectrum as it might turn off
     468             :                                  * display on active crtc
     469             :                                  */
     470           0 :                                 return;
     471             :                         }
     472             :                 }
     473             :         }
     474             : 
     475           0 :         memset(&args, 0, sizeof(args));
     476             : 
     477           0 :         if (ASIC_IS_DCE5(rdev)) {
     478           0 :                 args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0);
     479           0 :                 args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
     480           0 :                 switch (pll_id) {
     481             :                 case ATOM_PPLL1:
     482           0 :                         args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
     483           0 :                         break;
     484             :                 case ATOM_PPLL2:
     485           0 :                         args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
     486           0 :                         break;
     487             :                 case ATOM_DCPLL:
     488           0 :                         args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
     489           0 :                         break;
     490             :                 case ATOM_PPLL_INVALID:
     491           0 :                         return;
     492             :                 }
     493           0 :                 args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
     494           0 :                 args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
     495           0 :                 args.v3.ucEnable = enable;
     496           0 :         } else if (ASIC_IS_DCE4(rdev)) {
     497           0 :                 args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
     498           0 :                 args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
     499           0 :                 switch (pll_id) {
     500             :                 case ATOM_PPLL1:
     501           0 :                         args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL;
     502           0 :                         break;
     503             :                 case ATOM_PPLL2:
     504           0 :                         args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL;
     505           0 :                         break;
     506             :                 case ATOM_DCPLL:
     507           0 :                         args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL;
     508           0 :                         break;
     509             :                 case ATOM_PPLL_INVALID:
     510           0 :                         return;
     511             :                 }
     512           0 :                 args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
     513           0 :                 args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step);
     514           0 :                 args.v2.ucEnable = enable;
     515           0 :         } else if (ASIC_IS_DCE3(rdev)) {
     516           0 :                 args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
     517           0 :                 args.v1.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
     518           0 :                 args.v1.ucSpreadSpectrumStep = ss->step;
     519           0 :                 args.v1.ucSpreadSpectrumDelay = ss->delay;
     520           0 :                 args.v1.ucSpreadSpectrumRange = ss->range;
     521           0 :                 args.v1.ucPpll = pll_id;
     522           0 :                 args.v1.ucEnable = enable;
     523           0 :         } else if (ASIC_IS_AVIVO(rdev)) {
     524           0 :                 if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
     525           0 :                     (ss->type & ATOM_EXTERNAL_SS_MASK)) {
     526           0 :                         atombios_disable_ss(rdev, pll_id);
     527           0 :                         return;
     528             :                 }
     529           0 :                 args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
     530           0 :                 args.lvds_ss_2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
     531           0 :                 args.lvds_ss_2.ucSpreadSpectrumStep = ss->step;
     532           0 :                 args.lvds_ss_2.ucSpreadSpectrumDelay = ss->delay;
     533           0 :                 args.lvds_ss_2.ucSpreadSpectrumRange = ss->range;
     534           0 :                 args.lvds_ss_2.ucEnable = enable;
     535           0 :         } else {
     536           0 :                 if (enable == ATOM_DISABLE) {
     537           0 :                         atombios_disable_ss(rdev, pll_id);
     538           0 :                         return;
     539             :                 }
     540           0 :                 args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
     541           0 :                 args.lvds_ss.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
     542           0 :                 args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2;
     543           0 :                 args.lvds_ss.ucSpreadSpectrumStepSize_Delay |= (ss->delay & 7) << 4;
     544           0 :                 args.lvds_ss.ucEnable = enable;
     545             :         }
     546           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     547           0 : }
     548             : 
     549             : union adjust_pixel_clock {
     550             :         ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
     551             :         ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
     552             : };
     553             : 
     554           0 : static u32 atombios_adjust_pll(struct drm_crtc *crtc,
     555             :                                struct drm_display_mode *mode)
     556             : {
     557           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     558           0 :         struct drm_device *dev = crtc->dev;
     559           0 :         struct radeon_device *rdev = dev->dev_private;
     560           0 :         struct drm_encoder *encoder = radeon_crtc->encoder;
     561           0 :         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
     562           0 :         struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
     563           0 :         u32 adjusted_clock = mode->clock;
     564           0 :         int encoder_mode = atombios_get_encoder_mode(encoder);
     565           0 :         u32 dp_clock = mode->clock;
     566             :         u32 clock = mode->clock;
     567           0 :         int bpc = radeon_crtc->bpc;
     568           0 :         bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
     569             : 
     570             :         /* reset the pll flags */
     571           0 :         radeon_crtc->pll_flags = 0;
     572             : 
     573           0 :         if (ASIC_IS_AVIVO(rdev)) {
     574           0 :                 if ((rdev->family == CHIP_RS600) ||
     575           0 :                     (rdev->family == CHIP_RS690) ||
     576           0 :                     (rdev->family == CHIP_RS740))
     577           0 :                         radeon_crtc->pll_flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
     578             :                                 RADEON_PLL_PREFER_CLOSEST_LOWER);
     579             : 
     580           0 :                 if (ASIC_IS_DCE32(rdev) && mode->clock > 200000)  /* range limits??? */
     581           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
     582             :                 else
     583           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
     584             : 
     585           0 :                 if (rdev->family < CHIP_RV770)
     586           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
     587             :                 /* use frac fb div on APUs */
     588           0 :                 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
     589           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
     590             :                 /* use frac fb div on RS780/RS880 */
     591           0 :                 if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
     592           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
     593           0 :                 if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
     594           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
     595             :         } else {
     596           0 :                 radeon_crtc->pll_flags |= RADEON_PLL_LEGACY;
     597             : 
     598           0 :                 if (mode->clock > 200000) /* range limits??? */
     599           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
     600             :                 else
     601           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
     602             :         }
     603             : 
     604           0 :         if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
     605           0 :             (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
     606           0 :                 if (connector) {
     607           0 :                         struct radeon_connector *radeon_connector = to_radeon_connector(connector);
     608             :                         struct radeon_connector_atom_dig *dig_connector =
     609           0 :                                 radeon_connector->con_priv;
     610             : 
     611           0 :                         dp_clock = dig_connector->dp_clock;
     612           0 :                 }
     613             :         }
     614             : 
     615           0 :         if (radeon_encoder->is_mst_encoder) {
     616           0 :                 struct radeon_encoder_mst *mst_enc = radeon_encoder->enc_priv;
     617           0 :                 struct radeon_connector_atom_dig *dig_connector = mst_enc->connector->con_priv;
     618             : 
     619           0 :                 dp_clock = dig_connector->dp_clock;
     620           0 :         }
     621             : 
     622             :         /* use recommended ref_div for ss */
     623           0 :         if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
     624           0 :                 if (radeon_crtc->ss_enabled) {
     625           0 :                         if (radeon_crtc->ss.refdiv) {
     626           0 :                                 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
     627           0 :                                 radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
     628           0 :                                 if (ASIC_IS_AVIVO(rdev))
     629           0 :                                         radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
     630             :                         }
     631             :                 }
     632             :         }
     633             : 
     634           0 :         if (ASIC_IS_AVIVO(rdev)) {
     635             :                 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
     636           0 :                 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
     637           0 :                         adjusted_clock = mode->clock * 2;
     638           0 :                 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
     639           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
     640           0 :                 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
     641           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD;
     642             :         } else {
     643           0 :                 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
     644           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
     645           0 :                 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
     646           0 :                         radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
     647             :         }
     648             : 
     649             :         /* adjust pll for deep color modes */
     650           0 :         if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
     651           0 :                 switch (bpc) {
     652             :                 case 8:
     653             :                 default:
     654             :                         break;
     655             :                 case 10:
     656           0 :                         clock = (clock * 5) / 4;
     657           0 :                         break;
     658             :                 case 12:
     659           0 :                         clock = (clock * 3) / 2;
     660           0 :                         break;
     661             :                 case 16:
     662           0 :                         clock = clock * 2;
     663           0 :                         break;
     664             :                 }
     665             :         }
     666             : 
     667             :         /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
     668             :          * accordingly based on the encoder/transmitter to work around
     669             :          * special hw requirements.
     670             :          */
     671           0 :         if (ASIC_IS_DCE3(rdev)) {
     672           0 :                 union adjust_pixel_clock args;
     673           0 :                 u8 frev, crev;
     674             :                 int index;
     675             : 
     676             :                 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
     677           0 :                 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
     678             :                                            &crev))
     679           0 :                         return adjusted_clock;
     680             : 
     681           0 :                 memset(&args, 0, sizeof(args));
     682             : 
     683           0 :                 switch (frev) {
     684             :                 case 1:
     685           0 :                         switch (crev) {
     686             :                         case 1:
     687             :                         case 2:
     688           0 :                                 args.v1.usPixelClock = cpu_to_le16(clock / 10);
     689           0 :                                 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
     690           0 :                                 args.v1.ucEncodeMode = encoder_mode;
     691           0 :                                 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
     692           0 :                                         args.v1.ucConfig |=
     693             :                                                 ADJUST_DISPLAY_CONFIG_SS_ENABLE;
     694             : 
     695           0 :                                 atom_execute_table(rdev->mode_info.atom_context,
     696           0 :                                                    index, (uint32_t *)&args);
     697           0 :                                 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
     698           0 :                                 break;
     699             :                         case 3:
     700           0 :                                 args.v3.sInput.usPixelClock = cpu_to_le16(clock / 10);
     701           0 :                                 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
     702           0 :                                 args.v3.sInput.ucEncodeMode = encoder_mode;
     703           0 :                                 args.v3.sInput.ucDispPllConfig = 0;
     704           0 :                                 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
     705           0 :                                         args.v3.sInput.ucDispPllConfig |=
     706             :                                                 DISPPLL_CONFIG_SS_ENABLE;
     707           0 :                                 if (ENCODER_MODE_IS_DP(encoder_mode)) {
     708           0 :                                         args.v3.sInput.ucDispPllConfig |=
     709             :                                                 DISPPLL_CONFIG_COHERENT_MODE;
     710             :                                         /* 16200 or 27000 */
     711           0 :                                         args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
     712           0 :                                 } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
     713           0 :                                         struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
     714           0 :                                         if (dig->coherent_mode)
     715           0 :                                                 args.v3.sInput.ucDispPllConfig |=
     716             :                                                         DISPPLL_CONFIG_COHERENT_MODE;
     717           0 :                                         if (is_duallink)
     718           0 :                                                 args.v3.sInput.ucDispPllConfig |=
     719             :                                                         DISPPLL_CONFIG_DUAL_LINK;
     720           0 :                                 }
     721           0 :                                 if (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
     722             :                                     ENCODER_OBJECT_ID_NONE)
     723           0 :                                         args.v3.sInput.ucExtTransmitterID =
     724           0 :                                                 radeon_encoder_get_dp_bridge_encoder_id(encoder);
     725             :                                 else
     726           0 :                                         args.v3.sInput.ucExtTransmitterID = 0;
     727             : 
     728           0 :                                 atom_execute_table(rdev->mode_info.atom_context,
     729           0 :                                                    index, (uint32_t *)&args);
     730           0 :                                 adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
     731           0 :                                 if (args.v3.sOutput.ucRefDiv) {
     732           0 :                                         radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
     733           0 :                                         radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
     734           0 :                                         radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv;
     735           0 :                                 }
     736           0 :                                 if (args.v3.sOutput.ucPostDiv) {
     737           0 :                                         radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
     738           0 :                                         radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV;
     739           0 :                                         radeon_crtc->pll_post_div = args.v3.sOutput.ucPostDiv;
     740           0 :                                 }
     741             :                                 break;
     742             :                         default:
     743           0 :                                 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     744           0 :                                 return adjusted_clock;
     745             :                         }
     746             :                         break;
     747             :                 default:
     748           0 :                         DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     749           0 :                         return adjusted_clock;
     750             :                 }
     751           0 :         }
     752           0 :         return adjusted_clock;
     753           0 : }
     754             : 
     755             : union set_pixel_clock {
     756             :         SET_PIXEL_CLOCK_PS_ALLOCATION base;
     757             :         PIXEL_CLOCK_PARAMETERS v1;
     758             :         PIXEL_CLOCK_PARAMETERS_V2 v2;
     759             :         PIXEL_CLOCK_PARAMETERS_V3 v3;
     760             :         PIXEL_CLOCK_PARAMETERS_V5 v5;
     761             :         PIXEL_CLOCK_PARAMETERS_V6 v6;
     762             : };
     763             : 
     764             : /* on DCE5, make sure the voltage is high enough to support the
     765             :  * required disp clk.
     766             :  */
     767           0 : static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev,
     768             :                                     u32 dispclk)
     769             : {
     770           0 :         u8 frev, crev;
     771             :         int index;
     772           0 :         union set_pixel_clock args;
     773             : 
     774           0 :         memset(&args, 0, sizeof(args));
     775             : 
     776             :         index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
     777           0 :         if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
     778             :                                    &crev))
     779           0 :                 return;
     780             : 
     781           0 :         switch (frev) {
     782             :         case 1:
     783           0 :                 switch (crev) {
     784             :                 case 5:
     785             :                         /* if the default dcpll clock is specified,
     786             :                          * SetPixelClock provides the dividers
     787             :                          */
     788           0 :                         args.v5.ucCRTC = ATOM_CRTC_INVALID;
     789           0 :                         args.v5.usPixelClock = cpu_to_le16(dispclk);
     790           0 :                         args.v5.ucPpll = ATOM_DCPLL;
     791           0 :                         break;
     792             :                 case 6:
     793             :                         /* if the default dcpll clock is specified,
     794             :                          * SetPixelClock provides the dividers
     795             :                          */
     796           0 :                         args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
     797           0 :                         if (ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
     798           0 :                                 args.v6.ucPpll = ATOM_EXT_PLL1;
     799             :                         else if (ASIC_IS_DCE6(rdev))
     800             :                                 args.v6.ucPpll = ATOM_PPLL0;
     801             :                         else
     802             :                                 args.v6.ucPpll = ATOM_DCPLL;
     803             :                         break;
     804             :                 default:
     805           0 :                         DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     806           0 :                         return;
     807             :                 }
     808             :                 break;
     809             :         default:
     810           0 :                 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     811           0 :                 return;
     812             :         }
     813           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     814           0 : }
     815             : 
     816           0 : static void atombios_crtc_program_pll(struct drm_crtc *crtc,
     817             :                                       u32 crtc_id,
     818             :                                       int pll_id,
     819             :                                       u32 encoder_mode,
     820             :                                       u32 encoder_id,
     821             :                                       u32 clock,
     822             :                                       u32 ref_div,
     823             :                                       u32 fb_div,
     824             :                                       u32 frac_fb_div,
     825             :                                       u32 post_div,
     826             :                                       int bpc,
     827             :                                       bool ss_enabled,
     828             :                                       struct radeon_atom_ss *ss)
     829             : {
     830           0 :         struct drm_device *dev = crtc->dev;
     831           0 :         struct radeon_device *rdev = dev->dev_private;
     832           0 :         u8 frev, crev;
     833             :         int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
     834           0 :         union set_pixel_clock args;
     835             : 
     836           0 :         memset(&args, 0, sizeof(args));
     837             : 
     838           0 :         if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
     839             :                                    &crev))
     840           0 :                 return;
     841             : 
     842           0 :         switch (frev) {
     843             :         case 1:
     844           0 :                 switch (crev) {
     845             :                 case 1:
     846           0 :                         if (clock == ATOM_DISABLE)
     847           0 :                                 return;
     848           0 :                         args.v1.usPixelClock = cpu_to_le16(clock / 10);
     849           0 :                         args.v1.usRefDiv = cpu_to_le16(ref_div);
     850           0 :                         args.v1.usFbDiv = cpu_to_le16(fb_div);
     851           0 :                         args.v1.ucFracFbDiv = frac_fb_div;
     852           0 :                         args.v1.ucPostDiv = post_div;
     853           0 :                         args.v1.ucPpll = pll_id;
     854           0 :                         args.v1.ucCRTC = crtc_id;
     855           0 :                         args.v1.ucRefDivSrc = 1;
     856           0 :                         break;
     857             :                 case 2:
     858           0 :                         args.v2.usPixelClock = cpu_to_le16(clock / 10);
     859           0 :                         args.v2.usRefDiv = cpu_to_le16(ref_div);
     860           0 :                         args.v2.usFbDiv = cpu_to_le16(fb_div);
     861           0 :                         args.v2.ucFracFbDiv = frac_fb_div;
     862           0 :                         args.v2.ucPostDiv = post_div;
     863           0 :                         args.v2.ucPpll = pll_id;
     864           0 :                         args.v2.ucCRTC = crtc_id;
     865           0 :                         args.v2.ucRefDivSrc = 1;
     866           0 :                         break;
     867             :                 case 3:
     868           0 :                         args.v3.usPixelClock = cpu_to_le16(clock / 10);
     869           0 :                         args.v3.usRefDiv = cpu_to_le16(ref_div);
     870           0 :                         args.v3.usFbDiv = cpu_to_le16(fb_div);
     871           0 :                         args.v3.ucFracFbDiv = frac_fb_div;
     872           0 :                         args.v3.ucPostDiv = post_div;
     873           0 :                         args.v3.ucPpll = pll_id;
     874           0 :                         if (crtc_id == ATOM_CRTC2)
     875           0 :                                 args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
     876             :                         else
     877           0 :                                 args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1;
     878           0 :                         if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
     879           0 :                                 args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
     880           0 :                         args.v3.ucTransmitterId = encoder_id;
     881           0 :                         args.v3.ucEncoderMode = encoder_mode;
     882           0 :                         break;
     883             :                 case 5:
     884           0 :                         args.v5.ucCRTC = crtc_id;
     885           0 :                         args.v5.usPixelClock = cpu_to_le16(clock / 10);
     886           0 :                         args.v5.ucRefDiv = ref_div;
     887           0 :                         args.v5.usFbDiv = cpu_to_le16(fb_div);
     888           0 :                         args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
     889           0 :                         args.v5.ucPostDiv = post_div;
     890           0 :                         args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
     891           0 :                         if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
     892           0 :                                 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
     893           0 :                         if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
     894           0 :                                 switch (bpc) {
     895             :                                 case 8:
     896             :                                 default:
     897           0 :                                         args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
     898           0 :                                         break;
     899             :                                 case 10:
     900             :                                         /* yes this is correct, the atom define is wrong */
     901           0 :                                         args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
     902           0 :                                         break;
     903             :                                 case 12:
     904             :                                         /* yes this is correct, the atom define is wrong */
     905           0 :                                         args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
     906           0 :                                         break;
     907             :                                 }
     908             :                         }
     909           0 :                         args.v5.ucTransmitterID = encoder_id;
     910           0 :                         args.v5.ucEncoderMode = encoder_mode;
     911           0 :                         args.v5.ucPpll = pll_id;
     912           0 :                         break;
     913             :                 case 6:
     914           0 :                         args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10);
     915           0 :                         args.v6.ucRefDiv = ref_div;
     916           0 :                         args.v6.usFbDiv = cpu_to_le16(fb_div);
     917           0 :                         args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
     918           0 :                         args.v6.ucPostDiv = post_div;
     919           0 :                         args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
     920           0 :                         if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
     921           0 :                                 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
     922           0 :                         if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
     923           0 :                                 switch (bpc) {
     924             :                                 case 8:
     925             :                                 default:
     926           0 :                                         args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
     927           0 :                                         break;
     928             :                                 case 10:
     929           0 :                                         args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6;
     930           0 :                                         break;
     931             :                                 case 12:
     932           0 :                                         args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6;
     933           0 :                                         break;
     934             :                                 case 16:
     935           0 :                                         args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
     936           0 :                                         break;
     937             :                                 }
     938             :                         }
     939           0 :                         args.v6.ucTransmitterID = encoder_id;
     940           0 :                         args.v6.ucEncoderMode = encoder_mode;
     941           0 :                         args.v6.ucPpll = pll_id;
     942           0 :                         break;
     943             :                 default:
     944           0 :                         DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     945           0 :                         return;
     946             :                 }
     947             :                 break;
     948             :         default:
     949           0 :                 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
     950           0 :                 return;
     951             :         }
     952             : 
     953           0 :         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
     954           0 : }
     955             : 
     956           0 : static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
     957             : {
     958           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     959           0 :         struct drm_device *dev = crtc->dev;
     960           0 :         struct radeon_device *rdev = dev->dev_private;
     961             :         struct radeon_encoder *radeon_encoder =
     962           0 :                 to_radeon_encoder(radeon_crtc->encoder);
     963           0 :         int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
     964             : 
     965           0 :         radeon_crtc->bpc = 8;
     966           0 :         radeon_crtc->ss_enabled = false;
     967             : 
     968           0 :         if (radeon_encoder->is_mst_encoder) {
     969           0 :                 radeon_dp_mst_prepare_pll(crtc, mode);
     970           0 :         } else if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
     971           0 :             (radeon_encoder_get_dp_bridge_encoder_id(radeon_crtc->encoder) != ENCODER_OBJECT_ID_NONE)) {
     972           0 :                 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
     973             :                 struct drm_connector *connector =
     974           0 :                         radeon_get_connector_for_encoder(radeon_crtc->encoder);
     975             :                 struct radeon_connector *radeon_connector =
     976           0 :                         to_radeon_connector(connector);
     977             :                 struct radeon_connector_atom_dig *dig_connector =
     978           0 :                         radeon_connector->con_priv;
     979             :                 int dp_clock;
     980             : 
     981             :                 /* Assign mode clock for hdmi deep color max clock limit check */
     982           0 :                 radeon_connector->pixelclock_for_modeset = mode->clock;
     983           0 :                 radeon_crtc->bpc = radeon_get_monitor_bpc(connector);
     984             : 
     985           0 :                 switch (encoder_mode) {
     986             :                 case ATOM_ENCODER_MODE_DP_MST:
     987             :                 case ATOM_ENCODER_MODE_DP:
     988             :                         /* DP/eDP */
     989           0 :                         dp_clock = dig_connector->dp_clock / 10;
     990           0 :                         if (ASIC_IS_DCE4(rdev))
     991           0 :                                 radeon_crtc->ss_enabled =
     992           0 :                                         radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss,
     993             :                                                                          ASIC_INTERNAL_SS_ON_DP,
     994             :                                                                          dp_clock);
     995             :                         else {
     996           0 :                                 if (dp_clock == 16200) {
     997           0 :                                         radeon_crtc->ss_enabled =
     998           0 :                                                 radeon_atombios_get_ppll_ss_info(rdev,
     999             :                                                                                  &radeon_crtc->ss,
    1000             :                                                                                  ATOM_DP_SS_ID2);
    1001           0 :                                         if (!radeon_crtc->ss_enabled)
    1002           0 :                                                 radeon_crtc->ss_enabled =
    1003           0 :                                                         radeon_atombios_get_ppll_ss_info(rdev,
    1004             :                                                                                          &radeon_crtc->ss,
    1005             :                                                                                          ATOM_DP_SS_ID1);
    1006             :                                 } else {
    1007           0 :                                         radeon_crtc->ss_enabled =
    1008           0 :                                                 radeon_atombios_get_ppll_ss_info(rdev,
    1009             :                                                                                  &radeon_crtc->ss,
    1010             :                                                                                  ATOM_DP_SS_ID1);
    1011             :                                 }
    1012             :                                 /* disable spread spectrum on DCE3 DP */
    1013           0 :                                 radeon_crtc->ss_enabled = false;
    1014             :                         }
    1015             :                         break;
    1016             :                 case ATOM_ENCODER_MODE_LVDS:
    1017           0 :                         if (ASIC_IS_DCE4(rdev))
    1018           0 :                                 radeon_crtc->ss_enabled =
    1019           0 :                                         radeon_atombios_get_asic_ss_info(rdev,
    1020             :                                                                          &radeon_crtc->ss,
    1021             :                                                                          dig->lcd_ss_id,
    1022           0 :                                                                          mode->clock / 10);
    1023             :                         else
    1024           0 :                                 radeon_crtc->ss_enabled =
    1025           0 :                                         radeon_atombios_get_ppll_ss_info(rdev,
    1026             :                                                                          &radeon_crtc->ss,
    1027             :                                                                          dig->lcd_ss_id);
    1028             :                         break;
    1029             :                 case ATOM_ENCODER_MODE_DVI:
    1030           0 :                         if (ASIC_IS_DCE4(rdev))
    1031           0 :                                 radeon_crtc->ss_enabled =
    1032           0 :                                         radeon_atombios_get_asic_ss_info(rdev,
    1033           0 :                                                                          &radeon_crtc->ss,
    1034             :                                                                          ASIC_INTERNAL_SS_ON_TMDS,
    1035           0 :                                                                          mode->clock / 10);
    1036             :                         break;
    1037             :                 case ATOM_ENCODER_MODE_HDMI:
    1038           0 :                         if (ASIC_IS_DCE4(rdev))
    1039           0 :                                 radeon_crtc->ss_enabled =
    1040           0 :                                         radeon_atombios_get_asic_ss_info(rdev,
    1041           0 :                                                                          &radeon_crtc->ss,
    1042             :                                                                          ASIC_INTERNAL_SS_ON_HDMI,
    1043           0 :                                                                          mode->clock / 10);
    1044             :                         break;
    1045             :                 default:
    1046             :                         break;
    1047             :                 }
    1048           0 :         }
    1049             : 
    1050             :         /* adjust pixel clock as needed */
    1051           0 :         radeon_crtc->adjusted_clock = atombios_adjust_pll(crtc, mode);
    1052             : 
    1053           0 :         return true;
    1054             : }
    1055             : 
    1056           0 : static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
    1057             : {
    1058           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    1059           0 :         struct drm_device *dev = crtc->dev;
    1060           0 :         struct radeon_device *rdev = dev->dev_private;
    1061             :         struct radeon_encoder *radeon_encoder =
    1062           0 :                 to_radeon_encoder(radeon_crtc->encoder);
    1063           0 :         u32 pll_clock = mode->clock;
    1064           0 :         u32 clock = mode->clock;
    1065           0 :         u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
    1066             :         struct radeon_pll *pll;
    1067           0 :         int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
    1068             : 
    1069             :         /* pass the actual clock to atombios_crtc_program_pll for DCE5,6 for HDMI */
    1070           0 :         if (ASIC_IS_DCE5(rdev) &&
    1071           0 :             (encoder_mode == ATOM_ENCODER_MODE_HDMI) &&
    1072           0 :             (radeon_crtc->bpc > 8))
    1073           0 :                 clock = radeon_crtc->adjusted_clock;
    1074             : 
    1075           0 :         switch (radeon_crtc->pll_id) {
    1076             :         case ATOM_PPLL1:
    1077           0 :                 pll = &rdev->clock.p1pll;
    1078           0 :                 break;
    1079             :         case ATOM_PPLL2:
    1080           0 :                 pll = &rdev->clock.p2pll;
    1081           0 :                 break;
    1082             :         case ATOM_DCPLL:
    1083             :         case ATOM_PPLL_INVALID:
    1084             :         default:
    1085           0 :                 pll = &rdev->clock.dcpll;
    1086           0 :                 break;
    1087             :         }
    1088             : 
    1089             :         /* update pll params */
    1090           0 :         pll->flags = radeon_crtc->pll_flags;
    1091           0 :         pll->reference_div = radeon_crtc->pll_reference_div;
    1092           0 :         pll->post_div = radeon_crtc->pll_post_div;
    1093             : 
    1094           0 :         if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
    1095             :                 /* TV seems to prefer the legacy algo on some boards */
    1096           0 :                 radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
    1097             :                                           &fb_div, &frac_fb_div, &ref_div, &post_div);
    1098           0 :         else if (ASIC_IS_AVIVO(rdev))
    1099           0 :                 radeon_compute_pll_avivo(pll, radeon_crtc->adjusted_clock, &pll_clock,
    1100             :                                          &fb_div, &frac_fb_div, &ref_div, &post_div);
    1101             :         else
    1102           0 :                 radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
    1103             :                                           &fb_div, &frac_fb_div, &ref_div, &post_div);
    1104             : 
    1105           0 :         atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id,
    1106           0 :                                  radeon_crtc->crtc_id, &radeon_crtc->ss);
    1107             : 
    1108           0 :         atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
    1109           0 :                                   encoder_mode, radeon_encoder->encoder_id, clock,
    1110           0 :                                   ref_div, fb_div, frac_fb_div, post_div,
    1111           0 :                                   radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss);
    1112             : 
    1113           0 :         if (radeon_crtc->ss_enabled) {
    1114             :                 /* calculate ss amount and step size */
    1115           0 :                 if (ASIC_IS_DCE4(rdev)) {
    1116             :                         u32 step_size;
    1117           0 :                         u32 amount = (((fb_div * 10) + frac_fb_div) *
    1118           0 :                                       (u32)radeon_crtc->ss.percentage) /
    1119           0 :                                 (100 * (u32)radeon_crtc->ss.percentage_divider);
    1120           0 :                         radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
    1121           0 :                         radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
    1122             :                                 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
    1123           0 :                         if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
    1124           0 :                                 step_size = (4 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) /
    1125           0 :                                         (125 * 25 * pll->reference_freq / 100);
    1126             :                         else
    1127           0 :                                 step_size = (2 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) /
    1128           0 :                                         (125 * 25 * pll->reference_freq / 100);
    1129           0 :                         radeon_crtc->ss.step = step_size;
    1130           0 :                 }
    1131             : 
    1132           0 :                 atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id,
    1133           0 :                                          radeon_crtc->crtc_id, &radeon_crtc->ss);
    1134           0 :         }
    1135           0 : }
    1136             : 
    1137           0 : static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
    1138             :                                  struct drm_framebuffer *fb,
    1139             :                                  int x, int y, int atomic)
    1140             : {
    1141           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    1142           0 :         struct drm_device *dev = crtc->dev;
    1143           0 :         struct radeon_device *rdev = dev->dev_private;
    1144             :         struct radeon_framebuffer *radeon_fb;
    1145             :         struct drm_framebuffer *target_fb;
    1146             :         struct drm_gem_object *obj;
    1147             :         struct radeon_bo *rbo;
    1148           0 :         uint64_t fb_location;
    1149           0 :         uint32_t fb_format, fb_pitch_pixels, tiling_flags;
    1150           0 :         unsigned bankw, bankh, mtaspect, tile_split;
    1151             :         u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
    1152             :         u32 tmp, viewport_w, viewport_h;
    1153             :         int r;
    1154             :         bool bypass_lut = false;
    1155             : 
    1156             :         /* no fb bound */
    1157           0 :         if (!atomic && !crtc->primary->fb) {
    1158             :                 DRM_DEBUG_KMS("No FB bound\n");
    1159           0 :                 return 0;
    1160             :         }
    1161             : 
    1162           0 :         if (atomic) {
    1163           0 :                 radeon_fb = to_radeon_framebuffer(fb);
    1164             :                 target_fb = fb;
    1165           0 :         }
    1166             :         else {
    1167           0 :                 radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
    1168             :                 target_fb = crtc->primary->fb;
    1169             :         }
    1170             : 
    1171             :         /* If atomic, assume fb object is pinned & idle & fenced and
    1172             :          * just update base pointers
    1173             :          */
    1174           0 :         obj = radeon_fb->obj;
    1175           0 :         rbo = gem_to_radeon_bo(obj);
    1176           0 :         r = radeon_bo_reserve(rbo, false);
    1177           0 :         if (unlikely(r != 0))
    1178           0 :                 return r;
    1179             : 
    1180           0 :         if (atomic)
    1181           0 :                 fb_location = radeon_bo_gpu_offset(rbo);
    1182             :         else {
    1183           0 :                 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
    1184           0 :                 if (unlikely(r != 0)) {
    1185           0 :                         radeon_bo_unreserve(rbo);
    1186           0 :                         return -EINVAL;
    1187             :                 }
    1188             :         }
    1189             : 
    1190           0 :         radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
    1191           0 :         radeon_bo_unreserve(rbo);
    1192             : 
    1193           0 :         switch (target_fb->pixel_format) {
    1194             :         case DRM_FORMAT_C8:
    1195             :                 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
    1196             :                              EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
    1197           0 :                 break;
    1198             :         case DRM_FORMAT_XRGB4444:
    1199             :         case DRM_FORMAT_ARGB4444:
    1200             :                 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
    1201             :                              EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB4444));
    1202             : #ifdef __BIG_ENDIAN
    1203             :                 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
    1204             : #endif
    1205           0 :                 break;
    1206             :         case DRM_FORMAT_XRGB1555:
    1207             :         case DRM_FORMAT_ARGB1555:
    1208             :                 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
    1209             :                              EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
    1210             : #ifdef __BIG_ENDIAN
    1211             :                 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
    1212             : #endif
    1213           0 :                 break;
    1214             :         case DRM_FORMAT_BGRX5551:
    1215             :         case DRM_FORMAT_BGRA5551:
    1216             :                 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
    1217             :                              EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA5551));
    1218             : #ifdef __BIG_ENDIAN
    1219             :                 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
    1220             : #endif
    1221           0 :                 break;
    1222             :         case DRM_FORMAT_RGB565:
    1223             :                 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
    1224             :                              EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
    1225             : #ifdef __BIG_ENDIAN
    1226             :                 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
    1227             : #endif
    1228           0 :                 break;
    1229             :         case DRM_FORMAT_XRGB8888:
    1230             :         case DRM_FORMAT_ARGB8888:
    1231             :                 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
    1232             :                              EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
    1233             : #ifdef __BIG_ENDIAN
    1234             :                 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
    1235             : #endif
    1236           0 :                 break;
    1237             :         case DRM_FORMAT_XRGB2101010:
    1238             :         case DRM_FORMAT_ARGB2101010:
    1239             :                 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
    1240             :                              EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB2101010));
    1241             : #ifdef __BIG_ENDIAN
    1242             :                 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
    1243             : #endif
    1244             :                 /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
    1245             :                 bypass_lut = true;
    1246           0 :                 break;
    1247             :         case DRM_FORMAT_BGRX1010102:
    1248             :         case DRM_FORMAT_BGRA1010102:
    1249             :                 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
    1250             :                              EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA1010102));
    1251             : #ifdef __BIG_ENDIAN
    1252             :                 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
    1253             : #endif
    1254             :                 /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
    1255             :                 bypass_lut = true;
    1256           0 :                 break;
    1257             :         default:
    1258           0 :                 DRM_ERROR("Unsupported screen format %s\n",
    1259             :                           drm_get_format_name(target_fb->pixel_format));
    1260           0 :                 return -EINVAL;
    1261             :         }
    1262             : 
    1263           0 :         if (tiling_flags & RADEON_TILING_MACRO) {
    1264           0 :                 evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split);
    1265             : 
    1266             :                 /* Set NUM_BANKS. */
    1267           0 :                 if (rdev->family >= CHIP_TAHITI) {
    1268             :                         unsigned index, num_banks;
    1269             : 
    1270           0 :                         if (rdev->family >= CHIP_BONAIRE) {
    1271             :                                 unsigned tileb, tile_split_bytes;
    1272             : 
    1273             :                                 /* Calculate the macrotile mode index. */
    1274           0 :                                 tile_split_bytes = 64 << tile_split;
    1275           0 :                                 tileb = 8 * 8 * target_fb->bits_per_pixel / 8;
    1276           0 :                                 tileb = min(tile_split_bytes, tileb);
    1277             : 
    1278           0 :                                 for (index = 0; tileb > 64; index++)
    1279           0 :                                         tileb >>= 1;
    1280             : 
    1281           0 :                                 if (index >= 16) {
    1282           0 :                                         DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
    1283             :                                                   target_fb->bits_per_pixel, tile_split);
    1284           0 :                                         return -EINVAL;
    1285             :                                 }
    1286             : 
    1287           0 :                                 num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3;
    1288           0 :                         } else {
    1289           0 :                                 switch (target_fb->bits_per_pixel) {
    1290             :                                 case 8:
    1291             :                                         index = 10;
    1292           0 :                                         break;
    1293             :                                 case 16:
    1294             :                                         index = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
    1295           0 :                                         break;
    1296             :                                 default:
    1297             :                                 case 32:
    1298             :                                         index = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
    1299           0 :                                         break;
    1300             :                                 }
    1301             : 
    1302           0 :                                 num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3;
    1303             :                         }
    1304             : 
    1305           0 :                         fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks);
    1306           0 :                 } else {
    1307             :                         /* NI and older. */
    1308           0 :                         if (rdev->family >= CHIP_CAYMAN)
    1309           0 :                                 tmp = rdev->config.cayman.tile_config;
    1310             :                         else
    1311           0 :                                 tmp = rdev->config.evergreen.tile_config;
    1312             : 
    1313           0 :                         switch ((tmp & 0xf0) >> 4) {
    1314             :                         case 0: /* 4 banks */
    1315           0 :                                 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
    1316           0 :                                 break;
    1317             :                         case 1: /* 8 banks */
    1318             :                         default:
    1319           0 :                                 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
    1320           0 :                                 break;
    1321             :                         case 2: /* 16 banks */
    1322           0 :                                 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
    1323           0 :                                 break;
    1324             :                         }
    1325             :                 }
    1326             : 
    1327           0 :                 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
    1328           0 :                 fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split);
    1329           0 :                 fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
    1330           0 :                 fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
    1331           0 :                 fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
    1332           0 :                 if (rdev->family >= CHIP_BONAIRE) {
    1333             :                         /* XXX need to know more about the surface tiling mode */
    1334             :                         fb_format |= CIK_GRPH_MICRO_TILE_MODE(CIK_DISPLAY_MICRO_TILING);
    1335           0 :                 }
    1336           0 :         } else if (tiling_flags & RADEON_TILING_MICRO)
    1337           0 :                 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
    1338             : 
    1339           0 :         if (rdev->family >= CHIP_BONAIRE) {
    1340             :                 /* Read the pipe config from the 2D TILED SCANOUT mode.
    1341             :                  * It should be the same for the other modes too, but not all
    1342             :                  * modes set the pipe config field. */
    1343           0 :                 u32 pipe_config = (rdev->config.cik.tile_mode_array[10] >> 6) & 0x1f;
    1344             : 
    1345           0 :                 fb_format |= CIK_GRPH_PIPE_CONFIG(pipe_config);
    1346           0 :         } else if ((rdev->family == CHIP_TAHITI) ||
    1347           0 :                    (rdev->family == CHIP_PITCAIRN))
    1348           0 :                 fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16);
    1349           0 :         else if ((rdev->family == CHIP_VERDE) ||
    1350           0 :                  (rdev->family == CHIP_OLAND) ||
    1351           0 :                  (rdev->family == CHIP_HAINAN)) /* for completeness.  HAINAN has no display hw */
    1352           0 :                 fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16);
    1353             : 
    1354           0 :         switch (radeon_crtc->crtc_id) {
    1355             :         case 0:
    1356           0 :                 WREG32(AVIVO_D1VGA_CONTROL, 0);
    1357           0 :                 break;
    1358             :         case 1:
    1359           0 :                 WREG32(AVIVO_D2VGA_CONTROL, 0);
    1360           0 :                 break;
    1361             :         case 2:
    1362           0 :                 WREG32(EVERGREEN_D3VGA_CONTROL, 0);
    1363           0 :                 break;
    1364             :         case 3:
    1365           0 :                 WREG32(EVERGREEN_D4VGA_CONTROL, 0);
    1366           0 :                 break;
    1367             :         case 4:
    1368           0 :                 WREG32(EVERGREEN_D5VGA_CONTROL, 0);
    1369           0 :                 break;
    1370             :         case 5:
    1371           0 :                 WREG32(EVERGREEN_D6VGA_CONTROL, 0);
    1372           0 :                 break;
    1373             :         default:
    1374             :                 break;
    1375             :         }
    1376             : 
    1377           0 :         WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
    1378             :                upper_32_bits(fb_location));
    1379           0 :         WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
    1380             :                upper_32_bits(fb_location));
    1381           0 :         WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
    1382             :                (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
    1383           0 :         WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
    1384             :                (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
    1385           0 :         WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
    1386           0 :         WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
    1387             : 
    1388             :         /*
    1389             :          * The LUT only has 256 slots for indexing by a 8 bpc fb. Bypass the LUT
    1390             :          * for > 8 bpc scanout to avoid truncation of fb indices to 8 msb's, to
    1391             :          * retain the full precision throughout the pipeline.
    1392             :          */
    1393           0 :         WREG32_P(EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL + radeon_crtc->crtc_offset,
    1394             :                  (bypass_lut ? EVERGREEN_LUT_10BIT_BYPASS_EN : 0),
    1395             :                  ~EVERGREEN_LUT_10BIT_BYPASS_EN);
    1396             : 
    1397             :         if (bypass_lut)
    1398             :                 DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
    1399             : 
    1400           0 :         WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
    1401           0 :         WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
    1402           0 :         WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
    1403           0 :         WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
    1404           0 :         WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
    1405           0 :         WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
    1406             : 
    1407           0 :         fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8);
    1408           0 :         WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
    1409           0 :         WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
    1410             : 
    1411           0 :         if (rdev->family >= CHIP_BONAIRE)
    1412           0 :                 WREG32(CIK_LB_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
    1413             :                        target_fb->height);
    1414             :         else
    1415           0 :                 WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
    1416             :                        target_fb->height);
    1417           0 :         x &= ~3;
    1418           0 :         y &= ~1;
    1419           0 :         WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
    1420             :                (x << 16) | y);
    1421           0 :         viewport_w = crtc->mode.hdisplay;
    1422           0 :         viewport_h = (crtc->mode.vdisplay + 1) & ~1;
    1423           0 :         if ((rdev->family >= CHIP_BONAIRE) &&
    1424           0 :             (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE))
    1425           0 :                 viewport_h *= 2;
    1426           0 :         WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
    1427             :                (viewport_w << 16) | viewport_h);
    1428             : 
    1429             :         /* pageflip setup */
    1430             :         /* make sure flip is at vb rather than hb */
    1431           0 :         tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
    1432           0 :         tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN;
    1433           0 :         WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
    1434             : 
    1435             :         /* set pageflip to happen only at start of vblank interval (front porch) */
    1436           0 :         WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
    1437             : 
    1438           0 :         if (!atomic && fb && fb != crtc->primary->fb) {
    1439           0 :                 radeon_fb = to_radeon_framebuffer(fb);
    1440           0 :                 rbo = gem_to_radeon_bo(radeon_fb->obj);
    1441           0 :                 r = radeon_bo_reserve(rbo, false);
    1442           0 :                 if (unlikely(r != 0))
    1443           0 :                         return r;
    1444           0 :                 radeon_bo_unpin(rbo);
    1445           0 :                 radeon_bo_unreserve(rbo);
    1446           0 :         }
    1447             : 
    1448             :         /* Bytes per pixel may have changed */
    1449           0 :         radeon_bandwidth_update(rdev);
    1450             : 
    1451           0 :         return 0;
    1452           0 : }
    1453             : 
    1454           0 : static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
    1455             :                                   struct drm_framebuffer *fb,
    1456             :                                   int x, int y, int atomic)
    1457             : {
    1458           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    1459           0 :         struct drm_device *dev = crtc->dev;
    1460           0 :         struct radeon_device *rdev = dev->dev_private;
    1461             :         struct radeon_framebuffer *radeon_fb;
    1462             :         struct drm_gem_object *obj;
    1463             :         struct radeon_bo *rbo;
    1464             :         struct drm_framebuffer *target_fb;
    1465           0 :         uint64_t fb_location;
    1466           0 :         uint32_t fb_format, fb_pitch_pixels, tiling_flags;
    1467             :         u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
    1468             :         u32 tmp, viewport_w, viewport_h;
    1469             :         int r;
    1470             :         bool bypass_lut = false;
    1471             : 
    1472             :         /* no fb bound */
    1473           0 :         if (!atomic && !crtc->primary->fb) {
    1474             :                 DRM_DEBUG_KMS("No FB bound\n");
    1475           0 :                 return 0;
    1476             :         }
    1477             : 
    1478           0 :         if (atomic) {
    1479           0 :                 radeon_fb = to_radeon_framebuffer(fb);
    1480             :                 target_fb = fb;
    1481           0 :         }
    1482             :         else {
    1483           0 :                 radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
    1484             :                 target_fb = crtc->primary->fb;
    1485             :         }
    1486             : 
    1487           0 :         obj = radeon_fb->obj;
    1488           0 :         rbo = gem_to_radeon_bo(obj);
    1489           0 :         r = radeon_bo_reserve(rbo, false);
    1490           0 :         if (unlikely(r != 0))
    1491           0 :                 return r;
    1492             : 
    1493             :         /* If atomic, assume fb object is pinned & idle & fenced and
    1494             :          * just update base pointers
    1495             :          */
    1496           0 :         if (atomic)
    1497           0 :                 fb_location = radeon_bo_gpu_offset(rbo);
    1498             :         else {
    1499           0 :                 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
    1500           0 :                 if (unlikely(r != 0)) {
    1501           0 :                         radeon_bo_unreserve(rbo);
    1502           0 :                         return -EINVAL;
    1503             :                 }
    1504             :         }
    1505           0 :         radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
    1506           0 :         radeon_bo_unreserve(rbo);
    1507             : 
    1508           0 :         switch (target_fb->pixel_format) {
    1509             :         case DRM_FORMAT_C8:
    1510             :                 fb_format =
    1511             :                     AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
    1512             :                     AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
    1513           0 :                 break;
    1514             :         case DRM_FORMAT_XRGB4444:
    1515             :         case DRM_FORMAT_ARGB4444:
    1516             :                 fb_format =
    1517             :                     AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
    1518             :                     AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444;
    1519             : #ifdef __BIG_ENDIAN
    1520             :                 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
    1521             : #endif
    1522           0 :                 break;
    1523             :         case DRM_FORMAT_XRGB1555:
    1524             :                 fb_format =
    1525             :                     AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
    1526             :                     AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
    1527             : #ifdef __BIG_ENDIAN
    1528             :                 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
    1529             : #endif
    1530           0 :                 break;
    1531             :         case DRM_FORMAT_RGB565:
    1532             :                 fb_format =
    1533             :                     AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
    1534             :                     AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
    1535             : #ifdef __BIG_ENDIAN
    1536             :                 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
    1537             : #endif
    1538           0 :                 break;
    1539             :         case DRM_FORMAT_XRGB8888:
    1540             :         case DRM_FORMAT_ARGB8888:
    1541             :                 fb_format =
    1542             :                     AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
    1543             :                     AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
    1544             : #ifdef __BIG_ENDIAN
    1545             :                 fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
    1546             : #endif
    1547           0 :                 break;
    1548             :         case DRM_FORMAT_XRGB2101010:
    1549             :         case DRM_FORMAT_ARGB2101010:
    1550             :                 fb_format =
    1551             :                     AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
    1552             :                     AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010;
    1553             : #ifdef __BIG_ENDIAN
    1554             :                 fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
    1555             : #endif
    1556             :                 /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
    1557             :                 bypass_lut = true;
    1558           0 :                 break;
    1559             :         default:
    1560           0 :                 DRM_ERROR("Unsupported screen format %s\n",
    1561             :                           drm_get_format_name(target_fb->pixel_format));
    1562           0 :                 return -EINVAL;
    1563             :         }
    1564             : 
    1565           0 :         if (rdev->family >= CHIP_R600) {
    1566           0 :                 if (tiling_flags & RADEON_TILING_MACRO)
    1567           0 :                         fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1;
    1568           0 :                 else if (tiling_flags & RADEON_TILING_MICRO)
    1569           0 :                         fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1;
    1570             :         } else {
    1571           0 :                 if (tiling_flags & RADEON_TILING_MACRO)
    1572           0 :                         fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
    1573             : 
    1574           0 :                 if (tiling_flags & RADEON_TILING_MICRO)
    1575           0 :                         fb_format |= AVIVO_D1GRPH_TILED;
    1576             :         }
    1577             : 
    1578           0 :         if (radeon_crtc->crtc_id == 0)
    1579           0 :                 WREG32(AVIVO_D1VGA_CONTROL, 0);
    1580             :         else
    1581           0 :                 WREG32(AVIVO_D2VGA_CONTROL, 0);
    1582             : 
    1583           0 :         if (rdev->family >= CHIP_RV770) {
    1584           0 :                 if (radeon_crtc->crtc_id) {
    1585           0 :                         WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
    1586           0 :                         WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
    1587           0 :                 } else {
    1588           0 :                         WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
    1589           0 :                         WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
    1590             :                 }
    1591             :         }
    1592           0 :         WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
    1593             :                (u32) fb_location);
    1594           0 :         WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
    1595             :                radeon_crtc->crtc_offset, (u32) fb_location);
    1596           0 :         WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
    1597           0 :         if (rdev->family >= CHIP_R600)
    1598           0 :                 WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
    1599             : 
    1600             :         /* LUT only has 256 slots for 8 bpc fb. Bypass for > 8 bpc scanout for precision */
    1601           0 :         WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset,
    1602             :                  (bypass_lut ? AVIVO_LUT_10BIT_BYPASS_EN : 0), ~AVIVO_LUT_10BIT_BYPASS_EN);
    1603             : 
    1604             :         if (bypass_lut)
    1605             :                 DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
    1606             : 
    1607           0 :         WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
    1608           0 :         WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
    1609           0 :         WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
    1610           0 :         WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
    1611           0 :         WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
    1612           0 :         WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
    1613             : 
    1614           0 :         fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8);
    1615           0 :         WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
    1616           0 :         WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
    1617             : 
    1618           0 :         WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
    1619             :                target_fb->height);
    1620           0 :         x &= ~3;
    1621           0 :         y &= ~1;
    1622           0 :         WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
    1623             :                (x << 16) | y);
    1624           0 :         viewport_w = crtc->mode.hdisplay;
    1625           0 :         viewport_h = (crtc->mode.vdisplay + 1) & ~1;
    1626           0 :         WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
    1627             :                (viewport_w << 16) | viewport_h);
    1628             : 
    1629             :         /* pageflip setup */
    1630             :         /* make sure flip is at vb rather than hb */
    1631           0 :         tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
    1632           0 :         tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN;
    1633           0 :         WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
    1634             : 
    1635             :         /* set pageflip to happen only at start of vblank interval (front porch) */
    1636           0 :         WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
    1637             : 
    1638           0 :         if (!atomic && fb && fb != crtc->primary->fb) {
    1639           0 :                 radeon_fb = to_radeon_framebuffer(fb);
    1640           0 :                 rbo = gem_to_radeon_bo(radeon_fb->obj);
    1641           0 :                 r = radeon_bo_reserve(rbo, false);
    1642           0 :                 if (unlikely(r != 0))
    1643           0 :                         return r;
    1644           0 :                 radeon_bo_unpin(rbo);
    1645           0 :                 radeon_bo_unreserve(rbo);
    1646           0 :         }
    1647             : 
    1648             :         /* Bytes per pixel may have changed */
    1649           0 :         radeon_bandwidth_update(rdev);
    1650             : 
    1651           0 :         return 0;
    1652           0 : }
    1653             : 
    1654           0 : int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
    1655             :                            struct drm_framebuffer *old_fb)
    1656             : {
    1657           0 :         struct drm_device *dev = crtc->dev;
    1658           0 :         struct radeon_device *rdev = dev->dev_private;
    1659             : 
    1660           0 :         if (ASIC_IS_DCE4(rdev))
    1661           0 :                 return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0);
    1662           0 :         else if (ASIC_IS_AVIVO(rdev))
    1663           0 :                 return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
    1664             :         else
    1665           0 :                 return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
    1666           0 : }
    1667             : 
    1668           0 : int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
    1669             :                                   struct drm_framebuffer *fb,
    1670             :                                   int x, int y, enum mode_set_atomic state)
    1671             : {
    1672           0 :        struct drm_device *dev = crtc->dev;
    1673           0 :        struct radeon_device *rdev = dev->dev_private;
    1674             : 
    1675           0 :         if (ASIC_IS_DCE4(rdev))
    1676           0 :                 return dce4_crtc_do_set_base(crtc, fb, x, y, 1);
    1677           0 :         else if (ASIC_IS_AVIVO(rdev))
    1678           0 :                 return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
    1679             :         else
    1680           0 :                 return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
    1681           0 : }
    1682             : 
    1683             : /* properly set additional regs when using atombios */
    1684           0 : static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
    1685             : {
    1686           0 :         struct drm_device *dev = crtc->dev;
    1687           0 :         struct radeon_device *rdev = dev->dev_private;
    1688           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    1689             :         u32 disp_merge_cntl;
    1690             : 
    1691           0 :         switch (radeon_crtc->crtc_id) {
    1692             :         case 0:
    1693           0 :                 disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
    1694           0 :                 disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
    1695           0 :                 WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
    1696           0 :                 break;
    1697             :         case 1:
    1698           0 :                 disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
    1699           0 :                 disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
    1700           0 :                 WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
    1701           0 :                 WREG32(RADEON_FP_H2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
    1702           0 :                 WREG32(RADEON_FP_V2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
    1703           0 :                 break;
    1704             :         }
    1705           0 : }
    1706             : 
    1707             : /**
    1708             :  * radeon_get_pll_use_mask - look up a mask of which pplls are in use
    1709             :  *
    1710             :  * @crtc: drm crtc
    1711             :  *
    1712             :  * Returns the mask of which PPLLs (Pixel PLLs) are in use.
    1713             :  */
    1714           0 : static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
    1715             : {
    1716           0 :         struct drm_device *dev = crtc->dev;
    1717             :         struct drm_crtc *test_crtc;
    1718             :         struct radeon_crtc *test_radeon_crtc;
    1719             :         u32 pll_in_use = 0;
    1720             : 
    1721           0 :         list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
    1722           0 :                 if (crtc == test_crtc)
    1723             :                         continue;
    1724             : 
    1725           0 :                 test_radeon_crtc = to_radeon_crtc(test_crtc);
    1726           0 :                 if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
    1727           0 :                         pll_in_use |= (1 << test_radeon_crtc->pll_id);
    1728             :         }
    1729           0 :         return pll_in_use;
    1730             : }
    1731             : 
    1732             : /**
    1733             :  * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
    1734             :  *
    1735             :  * @crtc: drm crtc
    1736             :  *
    1737             :  * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
    1738             :  * also in DP mode.  For DP, a single PPLL can be used for all DP
    1739             :  * crtcs/encoders.
    1740             :  */
    1741           0 : static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
    1742             : {
    1743           0 :         struct drm_device *dev = crtc->dev;
    1744           0 :         struct radeon_device *rdev = dev->dev_private;
    1745             :         struct drm_crtc *test_crtc;
    1746             :         struct radeon_crtc *test_radeon_crtc;
    1747             : 
    1748           0 :         list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
    1749           0 :                 if (crtc == test_crtc)
    1750             :                         continue;
    1751           0 :                 test_radeon_crtc = to_radeon_crtc(test_crtc);
    1752           0 :                 if (test_radeon_crtc->encoder &&
    1753           0 :                     ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
    1754             :                         /* PPLL2 is exclusive to UNIPHYA on DCE61 */
    1755           0 :                         if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
    1756           0 :                             test_radeon_crtc->pll_id == ATOM_PPLL2)
    1757             :                                 continue;
    1758             :                         /* for DP use the same PLL for all */
    1759           0 :                         if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
    1760           0 :                                 return test_radeon_crtc->pll_id;
    1761             :                 }
    1762             :         }
    1763           0 :         return ATOM_PPLL_INVALID;
    1764           0 : }
    1765             : 
    1766             : /**
    1767             :  * radeon_get_shared_nondp_ppll - return the PPLL used by another non-DP crtc
    1768             :  *
    1769             :  * @crtc: drm crtc
    1770             :  * @encoder: drm encoder
    1771             :  *
    1772             :  * Returns the PPLL (Pixel PLL) used by another non-DP crtc/encoder which can
    1773             :  * be shared (i.e., same clock).
    1774             :  */
    1775           0 : static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
    1776             : {
    1777           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    1778           0 :         struct drm_device *dev = crtc->dev;
    1779           0 :         struct radeon_device *rdev = dev->dev_private;
    1780             :         struct drm_crtc *test_crtc;
    1781             :         struct radeon_crtc *test_radeon_crtc;
    1782             :         u32 adjusted_clock, test_adjusted_clock;
    1783             : 
    1784           0 :         adjusted_clock = radeon_crtc->adjusted_clock;
    1785             : 
    1786           0 :         if (adjusted_clock == 0)
    1787           0 :                 return ATOM_PPLL_INVALID;
    1788             : 
    1789           0 :         list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
    1790           0 :                 if (crtc == test_crtc)
    1791             :                         continue;
    1792           0 :                 test_radeon_crtc = to_radeon_crtc(test_crtc);
    1793           0 :                 if (test_radeon_crtc->encoder &&
    1794           0 :                     !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
    1795             :                         /* PPLL2 is exclusive to UNIPHYA on DCE61 */
    1796           0 :                         if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
    1797           0 :                             test_radeon_crtc->pll_id == ATOM_PPLL2)
    1798             :                                 continue;
    1799             :                         /* check if we are already driving this connector with another crtc */
    1800           0 :                         if (test_radeon_crtc->connector == radeon_crtc->connector) {
    1801             :                                 /* if we are, return that pll */
    1802           0 :                                 if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
    1803           0 :                                         return test_radeon_crtc->pll_id;
    1804             :                         }
    1805             :                         /* for non-DP check the clock */
    1806           0 :                         test_adjusted_clock = test_radeon_crtc->adjusted_clock;
    1807           0 :                         if ((crtc->mode.clock == test_crtc->mode.clock) &&
    1808           0 :                             (adjusted_clock == test_adjusted_clock) &&
    1809           0 :                             (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) &&
    1810           0 :                             (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID))
    1811           0 :                                 return test_radeon_crtc->pll_id;
    1812             :                 }
    1813             :         }
    1814           0 :         return ATOM_PPLL_INVALID;
    1815           0 : }
    1816             : 
    1817             : /**
    1818             :  * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
    1819             :  *
    1820             :  * @crtc: drm crtc
    1821             :  *
    1822             :  * Returns the PPLL (Pixel PLL) to be used by the crtc.  For DP monitors
    1823             :  * a single PPLL can be used for all DP crtcs/encoders.  For non-DP
    1824             :  * monitors a dedicated PPLL must be used.  If a particular board has
    1825             :  * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
    1826             :  * as there is no need to program the PLL itself.  If we are not able to
    1827             :  * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
    1828             :  * avoid messing up an existing monitor.
    1829             :  *
    1830             :  * Asic specific PLL information
    1831             :  *
    1832             :  * DCE 8.x
    1833             :  * KB/KV
    1834             :  * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP)
    1835             :  * CI
    1836             :  * - PPLL0, PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
    1837             :  *
    1838             :  * DCE 6.1
    1839             :  * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
    1840             :  * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
    1841             :  *
    1842             :  * DCE 6.0
    1843             :  * - PPLL0 is available to all UNIPHY (DP only)
    1844             :  * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
    1845             :  *
    1846             :  * DCE 5.0
    1847             :  * - DCPLL is available to all UNIPHY (DP only)
    1848             :  * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
    1849             :  *
    1850             :  * DCE 3.0/4.0/4.1
    1851             :  * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
    1852             :  *
    1853             :  */
    1854           0 : static int radeon_atom_pick_pll(struct drm_crtc *crtc)
    1855             : {
    1856           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    1857           0 :         struct drm_device *dev = crtc->dev;
    1858           0 :         struct radeon_device *rdev = dev->dev_private;
    1859             :         struct radeon_encoder *radeon_encoder =
    1860           0 :                 to_radeon_encoder(radeon_crtc->encoder);
    1861             :         u32 pll_in_use;
    1862             :         int pll;
    1863             : 
    1864           0 :         if (ASIC_IS_DCE8(rdev)) {
    1865           0 :                 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
    1866           0 :                         if (rdev->clock.dp_extclk)
    1867             :                                 /* skip PPLL programming if using ext clock */
    1868           0 :                                 return ATOM_PPLL_INVALID;
    1869             :                         else {
    1870             :                                 /* use the same PPLL for all DP monitors */
    1871           0 :                                 pll = radeon_get_shared_dp_ppll(crtc);
    1872           0 :                                 if (pll != ATOM_PPLL_INVALID)
    1873           0 :                                         return pll;
    1874             :                         }
    1875             :                 } else {
    1876             :                         /* use the same PPLL for all monitors with the same clock */
    1877           0 :                         pll = radeon_get_shared_nondp_ppll(crtc);
    1878           0 :                         if (pll != ATOM_PPLL_INVALID)
    1879           0 :                                 return pll;
    1880             :                 }
    1881             :                 /* otherwise, pick one of the plls */
    1882           0 :                 if ((rdev->family == CHIP_KABINI) ||
    1883           0 :                     (rdev->family == CHIP_MULLINS)) {
    1884             :                         /* KB/ML has PPLL1 and PPLL2 */
    1885           0 :                         pll_in_use = radeon_get_pll_use_mask(crtc);
    1886           0 :                         if (!(pll_in_use & (1 << ATOM_PPLL2)))
    1887           0 :                                 return ATOM_PPLL2;
    1888           0 :                         if (!(pll_in_use & (1 << ATOM_PPLL1)))
    1889           0 :                                 return ATOM_PPLL1;
    1890           0 :                         DRM_ERROR("unable to allocate a PPLL\n");
    1891           0 :                         return ATOM_PPLL_INVALID;
    1892             :                 } else {
    1893             :                         /* CI/KV has PPLL0, PPLL1, and PPLL2 */
    1894           0 :                         pll_in_use = radeon_get_pll_use_mask(crtc);
    1895           0 :                         if (!(pll_in_use & (1 << ATOM_PPLL2)))
    1896           0 :                                 return ATOM_PPLL2;
    1897           0 :                         if (!(pll_in_use & (1 << ATOM_PPLL1)))
    1898           0 :                                 return ATOM_PPLL1;
    1899           0 :                         if (!(pll_in_use & (1 << ATOM_PPLL0)))
    1900           0 :                                 return ATOM_PPLL0;
    1901           0 :                         DRM_ERROR("unable to allocate a PPLL\n");
    1902           0 :                         return ATOM_PPLL_INVALID;
    1903             :                 }
    1904           0 :         } else if (ASIC_IS_DCE61(rdev)) {
    1905             :                 struct radeon_encoder_atom_dig *dig =
    1906           0 :                         radeon_encoder->enc_priv;
    1907             : 
    1908           0 :                 if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
    1909           0 :                     (dig->linkb == false))
    1910             :                         /* UNIPHY A uses PPLL2 */
    1911           0 :                         return ATOM_PPLL2;
    1912           0 :                 else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
    1913             :                         /* UNIPHY B/C/D/E/F */
    1914           0 :                         if (rdev->clock.dp_extclk)
    1915             :                                 /* skip PPLL programming if using ext clock */
    1916           0 :                                 return ATOM_PPLL_INVALID;
    1917             :                         else {
    1918             :                                 /* use the same PPLL for all DP monitors */
    1919           0 :                                 pll = radeon_get_shared_dp_ppll(crtc);
    1920           0 :                                 if (pll != ATOM_PPLL_INVALID)
    1921           0 :                                         return pll;
    1922             :                         }
    1923             :                 } else {
    1924             :                         /* use the same PPLL for all monitors with the same clock */
    1925           0 :                         pll = radeon_get_shared_nondp_ppll(crtc);
    1926           0 :                         if (pll != ATOM_PPLL_INVALID)
    1927           0 :                                 return pll;
    1928             :                 }
    1929             :                 /* UNIPHY B/C/D/E/F */
    1930           0 :                 pll_in_use = radeon_get_pll_use_mask(crtc);
    1931           0 :                 if (!(pll_in_use & (1 << ATOM_PPLL0)))
    1932           0 :                         return ATOM_PPLL0;
    1933           0 :                 if (!(pll_in_use & (1 << ATOM_PPLL1)))
    1934           0 :                         return ATOM_PPLL1;
    1935           0 :                 DRM_ERROR("unable to allocate a PPLL\n");
    1936           0 :                 return ATOM_PPLL_INVALID;
    1937           0 :         } else if (ASIC_IS_DCE41(rdev)) {
    1938             :                 /* Don't share PLLs on DCE4.1 chips */
    1939           0 :                 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
    1940           0 :                         if (rdev->clock.dp_extclk)
    1941             :                                 /* skip PPLL programming if using ext clock */
    1942           0 :                                 return ATOM_PPLL_INVALID;
    1943             :                 }
    1944           0 :                 pll_in_use = radeon_get_pll_use_mask(crtc);
    1945           0 :                 if (!(pll_in_use & (1 << ATOM_PPLL1)))
    1946           0 :                         return ATOM_PPLL1;
    1947           0 :                 if (!(pll_in_use & (1 << ATOM_PPLL2)))
    1948           0 :                         return ATOM_PPLL2;
    1949           0 :                 DRM_ERROR("unable to allocate a PPLL\n");
    1950           0 :                 return ATOM_PPLL_INVALID;
    1951           0 :         } else if (ASIC_IS_DCE4(rdev)) {
    1952             :                 /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
    1953             :                  * depending on the asic:
    1954             :                  * DCE4: PPLL or ext clock
    1955             :                  * DCE5: PPLL, DCPLL, or ext clock
    1956             :                  * DCE6: PPLL, PPLL0, or ext clock
    1957             :                  *
    1958             :                  * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
    1959             :                  * PPLL/DCPLL programming and only program the DP DTO for the
    1960             :                  * crtc virtual pixel clock.
    1961             :                  */
    1962           0 :                 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
    1963           0 :                         if (rdev->clock.dp_extclk)
    1964             :                                 /* skip PPLL programming if using ext clock */
    1965           0 :                                 return ATOM_PPLL_INVALID;
    1966           0 :                         else if (ASIC_IS_DCE6(rdev))
    1967             :                                 /* use PPLL0 for all DP */
    1968           0 :                                 return ATOM_PPLL0;
    1969           0 :                         else if (ASIC_IS_DCE5(rdev))
    1970             :                                 /* use DCPLL for all DP */
    1971           0 :                                 return ATOM_DCPLL;
    1972             :                         else {
    1973             :                                 /* use the same PPLL for all DP monitors */
    1974           0 :                                 pll = radeon_get_shared_dp_ppll(crtc);
    1975           0 :                                 if (pll != ATOM_PPLL_INVALID)
    1976           0 :                                         return pll;
    1977             :                         }
    1978             :                 } else {
    1979             :                         /* use the same PPLL for all monitors with the same clock */
    1980           0 :                         pll = radeon_get_shared_nondp_ppll(crtc);
    1981           0 :                         if (pll != ATOM_PPLL_INVALID)
    1982           0 :                                 return pll;
    1983             :                 }
    1984             :                 /* all other cases */
    1985           0 :                 pll_in_use = radeon_get_pll_use_mask(crtc);
    1986           0 :                 if (!(pll_in_use & (1 << ATOM_PPLL1)))
    1987           0 :                         return ATOM_PPLL1;
    1988           0 :                 if (!(pll_in_use & (1 << ATOM_PPLL2)))
    1989           0 :                         return ATOM_PPLL2;
    1990           0 :                 DRM_ERROR("unable to allocate a PPLL\n");
    1991           0 :                 return ATOM_PPLL_INVALID;
    1992             :         } else {
    1993             :                 /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
    1994             :                 /* some atombios (observed in some DCE2/DCE3) code have a bug,
    1995             :                  * the matching btw pll and crtc is done through
    1996             :                  * PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the
    1997             :                  * pll (1 or 2) to select which register to write. ie if using
    1998             :                  * pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2
    1999             :                  * it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to
    2000             :                  * choose which value to write. Which is reverse order from
    2001             :                  * register logic. So only case that works is when pllid is
    2002             :                  * same as crtcid or when both pll and crtc are enabled and
    2003             :                  * both use same clock.
    2004             :                  *
    2005             :                  * So just return crtc id as if crtc and pll were hard linked
    2006             :                  * together even if they aren't
    2007             :                  */
    2008           0 :                 return radeon_crtc->crtc_id;
    2009             :         }
    2010           0 : }
    2011             : 
    2012           0 : void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
    2013             : {
    2014             :         /* always set DCPLL */
    2015           0 :         if (ASIC_IS_DCE6(rdev))
    2016           0 :                 atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
    2017           0 :         else if (ASIC_IS_DCE4(rdev)) {
    2018           0 :                 struct radeon_atom_ss ss;
    2019           0 :                 bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
    2020             :                                                                    ASIC_INTERNAL_SS_ON_DCPLL,
    2021           0 :                                                                    rdev->clock.default_dispclk);
    2022           0 :                 if (ss_enabled)
    2023           0 :                         atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss);
    2024             :                 /* XXX: DCE5, make sure voltage, dispclk is high enough */
    2025           0 :                 atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
    2026           0 :                 if (ss_enabled)
    2027           0 :                         atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss);
    2028           0 :         }
    2029             : 
    2030           0 : }
    2031             : 
    2032           0 : int atombios_crtc_mode_set(struct drm_crtc *crtc,
    2033             :                            struct drm_display_mode *mode,
    2034             :                            struct drm_display_mode *adjusted_mode,
    2035             :                            int x, int y, struct drm_framebuffer *old_fb)
    2036             : {
    2037           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    2038           0 :         struct drm_device *dev = crtc->dev;
    2039           0 :         struct radeon_device *rdev = dev->dev_private;
    2040             :         struct radeon_encoder *radeon_encoder =
    2041           0 :                 to_radeon_encoder(radeon_crtc->encoder);
    2042             :         bool is_tvcv = false;
    2043             : 
    2044           0 :         if (radeon_encoder->active_device &
    2045             :             (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
    2046             :                 is_tvcv = true;
    2047             : 
    2048           0 :         if (!radeon_crtc->adjusted_clock)
    2049           0 :                 return -EINVAL;
    2050             : 
    2051           0 :         atombios_crtc_set_pll(crtc, adjusted_mode);
    2052             : 
    2053           0 :         if (ASIC_IS_DCE4(rdev))
    2054           0 :                 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
    2055           0 :         else if (ASIC_IS_AVIVO(rdev)) {
    2056           0 :                 if (is_tvcv)
    2057           0 :                         atombios_crtc_set_timing(crtc, adjusted_mode);
    2058             :                 else
    2059           0 :                         atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
    2060             :         } else {
    2061           0 :                 atombios_crtc_set_timing(crtc, adjusted_mode);
    2062           0 :                 if (radeon_crtc->crtc_id == 0)
    2063           0 :                         atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
    2064           0 :                 radeon_legacy_atom_fixup(crtc);
    2065             :         }
    2066           0 :         atombios_crtc_set_base(crtc, x, y, old_fb);
    2067           0 :         atombios_overscan_setup(crtc, mode, adjusted_mode);
    2068           0 :         atombios_scaler_setup(crtc);
    2069           0 :         radeon_cursor_reset(crtc);
    2070             :         /* update the hw version fpr dpm */
    2071           0 :         radeon_crtc->hw_mode = *adjusted_mode;
    2072             : 
    2073           0 :         return 0;
    2074           0 : }
    2075             : 
    2076           0 : static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
    2077             :                                      const struct drm_display_mode *mode,
    2078             :                                      struct drm_display_mode *adjusted_mode)
    2079             : {
    2080           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    2081           0 :         struct drm_device *dev = crtc->dev;
    2082             :         struct drm_encoder *encoder;
    2083             : 
    2084             :         /* assign the encoder to the radeon crtc to avoid repeated lookups later */
    2085           0 :         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
    2086           0 :                 if (encoder->crtc == crtc) {
    2087           0 :                         radeon_crtc->encoder = encoder;
    2088           0 :                         radeon_crtc->connector = radeon_get_connector_for_encoder(encoder);
    2089           0 :                         break;
    2090             :                 }
    2091             :         }
    2092           0 :         if ((radeon_crtc->encoder == NULL) || (radeon_crtc->connector == NULL)) {
    2093           0 :                 radeon_crtc->encoder = NULL;
    2094           0 :                 radeon_crtc->connector = NULL;
    2095           0 :                 return false;
    2096             :         }
    2097           0 :         if (radeon_crtc->encoder) {
    2098             :                 struct radeon_encoder *radeon_encoder =
    2099           0 :                         to_radeon_encoder(radeon_crtc->encoder);
    2100             : 
    2101           0 :                 radeon_crtc->output_csc = radeon_encoder->output_csc;
    2102           0 :         }
    2103           0 :         if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
    2104           0 :                 return false;
    2105           0 :         if (!atombios_crtc_prepare_pll(crtc, adjusted_mode))
    2106           0 :                 return false;
    2107             :         /* pick pll */
    2108           0 :         radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
    2109             :         /* if we can't get a PPLL for a non-DP encoder, fail */
    2110           0 :         if ((radeon_crtc->pll_id == ATOM_PPLL_INVALID) &&
    2111           0 :             !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder)))
    2112           0 :                 return false;
    2113             : 
    2114           0 :         return true;
    2115           0 : }
    2116             : 
    2117           0 : static void atombios_crtc_prepare(struct drm_crtc *crtc)
    2118             : {
    2119           0 :         struct drm_device *dev = crtc->dev;
    2120           0 :         struct radeon_device *rdev = dev->dev_private;
    2121             : 
    2122             :         /* disable crtc pair power gating before programming */
    2123           0 :         if (ASIC_IS_DCE6(rdev))
    2124           0 :                 atombios_powergate_crtc(crtc, ATOM_DISABLE);
    2125             : 
    2126           0 :         atombios_lock_crtc(crtc, ATOM_ENABLE);
    2127           0 :         atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
    2128           0 : }
    2129             : 
    2130           0 : static void atombios_crtc_commit(struct drm_crtc *crtc)
    2131             : {
    2132           0 :         atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
    2133           0 :         atombios_lock_crtc(crtc, ATOM_DISABLE);
    2134           0 : }
    2135             : 
    2136           0 : static void atombios_crtc_disable(struct drm_crtc *crtc)
    2137             : {
    2138           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
    2139           0 :         struct drm_device *dev = crtc->dev;
    2140           0 :         struct radeon_device *rdev = dev->dev_private;
    2141           0 :         struct radeon_atom_ss ss;
    2142             :         int i;
    2143             : 
    2144           0 :         atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
    2145           0 :         if (crtc->primary->fb) {
    2146             :                 int r;
    2147             :                 struct radeon_framebuffer *radeon_fb;
    2148             :                 struct radeon_bo *rbo;
    2149             : 
    2150           0 :                 radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
    2151           0 :                 rbo = gem_to_radeon_bo(radeon_fb->obj);
    2152           0 :                 r = radeon_bo_reserve(rbo, false);
    2153           0 :                 if (unlikely(r))
    2154           0 :                         DRM_ERROR("failed to reserve rbo before unpin\n");
    2155             :                 else {
    2156           0 :                         radeon_bo_unpin(rbo);
    2157           0 :                         radeon_bo_unreserve(rbo);
    2158             :                 }
    2159           0 :         }
    2160             :         /* disable the GRPH */
    2161           0 :         if (ASIC_IS_DCE4(rdev))
    2162           0 :                 WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 0);
    2163           0 :         else if (ASIC_IS_AVIVO(rdev))
    2164           0 :                 WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 0);
    2165             : 
    2166           0 :         if (ASIC_IS_DCE6(rdev))
    2167           0 :                 atombios_powergate_crtc(crtc, ATOM_ENABLE);
    2168             : 
    2169           0 :         for (i = 0; i < rdev->num_crtc; i++) {
    2170           0 :                 if (rdev->mode_info.crtcs[i] &&
    2171           0 :                     rdev->mode_info.crtcs[i]->enabled &&
    2172           0 :                     i != radeon_crtc->crtc_id &&
    2173           0 :                     radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) {
    2174             :                         /* one other crtc is using this pll don't turn
    2175             :                          * off the pll
    2176             :                          */
    2177             :                         goto done;
    2178             :                 }
    2179             :         }
    2180             : 
    2181           0 :         switch (radeon_crtc->pll_id) {
    2182             :         case ATOM_PPLL1:
    2183             :         case ATOM_PPLL2:
    2184             :                 /* disable the ppll */
    2185           0 :                 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
    2186             :                                           0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
    2187           0 :                 break;
    2188             :         case ATOM_PPLL0:
    2189             :                 /* disable the ppll */
    2190           0 :                 if ((rdev->family == CHIP_ARUBA) ||
    2191           0 :                     (rdev->family == CHIP_KAVERI) ||
    2192           0 :                     (rdev->family == CHIP_BONAIRE) ||
    2193           0 :                     (rdev->family == CHIP_HAWAII))
    2194           0 :                         atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
    2195             :                                                   0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
    2196             :                 break;
    2197             :         default:
    2198             :                 break;
    2199             :         }
    2200             : done:
    2201           0 :         radeon_crtc->pll_id = ATOM_PPLL_INVALID;
    2202           0 :         radeon_crtc->adjusted_clock = 0;
    2203           0 :         radeon_crtc->encoder = NULL;
    2204           0 :         radeon_crtc->connector = NULL;
    2205           0 : }
    2206             : 
    2207             : static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
    2208             :         .dpms = atombios_crtc_dpms,
    2209             :         .mode_fixup = atombios_crtc_mode_fixup,
    2210             :         .mode_set = atombios_crtc_mode_set,
    2211             :         .mode_set_base = atombios_crtc_set_base,
    2212             :         .mode_set_base_atomic = atombios_crtc_set_base_atomic,
    2213             :         .prepare = atombios_crtc_prepare,
    2214             :         .commit = atombios_crtc_commit,
    2215             :         .load_lut = radeon_crtc_load_lut,
    2216             :         .disable = atombios_crtc_disable,
    2217             : };
    2218             : 
    2219           0 : void radeon_atombios_init_crtc(struct drm_device *dev,
    2220             :                                struct radeon_crtc *radeon_crtc)
    2221             : {
    2222           0 :         struct radeon_device *rdev = dev->dev_private;
    2223             : 
    2224           0 :         if (ASIC_IS_DCE4(rdev)) {
    2225           0 :                 switch (radeon_crtc->crtc_id) {
    2226             :                 case 0:
    2227             :                 default:
    2228           0 :                         radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
    2229           0 :                         break;
    2230             :                 case 1:
    2231           0 :                         radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
    2232           0 :                         break;
    2233             :                 case 2:
    2234           0 :                         radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
    2235           0 :                         break;
    2236             :                 case 3:
    2237           0 :                         radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
    2238           0 :                         break;
    2239             :                 case 4:
    2240           0 :                         radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
    2241           0 :                         break;
    2242             :                 case 5:
    2243           0 :                         radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
    2244           0 :                         break;
    2245             :                 }
    2246             :         } else {
    2247           0 :                 if (radeon_crtc->crtc_id == 1)
    2248           0 :                         radeon_crtc->crtc_offset =
    2249             :                                 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
    2250             :                 else
    2251           0 :                         radeon_crtc->crtc_offset = 0;
    2252             :         }
    2253           0 :         radeon_crtc->pll_id = ATOM_PPLL_INVALID;
    2254           0 :         radeon_crtc->adjusted_clock = 0;
    2255           0 :         radeon_crtc->encoder = NULL;
    2256           0 :         radeon_crtc->connector = NULL;
    2257           0 :         drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
    2258           0 : }

Generated by: LCOV version 1.13