0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <drm/drm_crtc_helper.h>
0028 #include <drm/drm_fb_helper.h>
0029 #include <drm/drm_fixed.h>
0030 #include <drm/drm_fourcc.h>
0031 #include <drm/drm_framebuffer.h>
0032 #include <drm/drm_vblank.h>
0033 #include <drm/radeon_drm.h>
0034
0035 #include "radeon.h"
0036 #include "atom.h"
0037 #include "atom-bits.h"
0038
0039 static void atombios_overscan_setup(struct drm_crtc *crtc,
0040 struct drm_display_mode *mode,
0041 struct drm_display_mode *adjusted_mode)
0042 {
0043 struct drm_device *dev = crtc->dev;
0044 struct radeon_device *rdev = dev->dev_private;
0045 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0046 SET_CRTC_OVERSCAN_PS_ALLOCATION args;
0047 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
0048 int a1, a2;
0049
0050 memset(&args, 0, sizeof(args));
0051
0052 args.ucCRTC = radeon_crtc->crtc_id;
0053
0054 switch (radeon_crtc->rmx_type) {
0055 case RMX_CENTER:
0056 args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
0057 args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
0058 args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
0059 args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
0060 break;
0061 case RMX_ASPECT:
0062 a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
0063 a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
0064
0065 if (a1 > a2) {
0066 args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
0067 args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
0068 } else if (a2 > a1) {
0069 args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
0070 args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
0071 }
0072 break;
0073 case RMX_FULL:
0074 default:
0075 args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border);
0076 args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border);
0077 args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border);
0078 args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border);
0079 break;
0080 }
0081 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0082 }
0083
0084 static void atombios_scaler_setup(struct drm_crtc *crtc)
0085 {
0086 struct drm_device *dev = crtc->dev;
0087 struct radeon_device *rdev = dev->dev_private;
0088 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0089 ENABLE_SCALER_PS_ALLOCATION args;
0090 int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
0091 struct radeon_encoder *radeon_encoder =
0092 to_radeon_encoder(radeon_crtc->encoder);
0093
0094 enum radeon_tv_std tv_std = TV_STD_NTSC;
0095 bool is_tv = false, is_cv = false;
0096
0097 if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
0098 return;
0099
0100 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
0101 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
0102 tv_std = tv_dac->tv_std;
0103 is_tv = true;
0104 }
0105
0106 memset(&args, 0, sizeof(args));
0107
0108 args.ucScaler = radeon_crtc->crtc_id;
0109
0110 if (is_tv) {
0111 switch (tv_std) {
0112 case TV_STD_NTSC:
0113 default:
0114 args.ucTVStandard = ATOM_TV_NTSC;
0115 break;
0116 case TV_STD_PAL:
0117 args.ucTVStandard = ATOM_TV_PAL;
0118 break;
0119 case TV_STD_PAL_M:
0120 args.ucTVStandard = ATOM_TV_PALM;
0121 break;
0122 case TV_STD_PAL_60:
0123 args.ucTVStandard = ATOM_TV_PAL60;
0124 break;
0125 case TV_STD_NTSC_J:
0126 args.ucTVStandard = ATOM_TV_NTSCJ;
0127 break;
0128 case TV_STD_SCART_PAL:
0129 args.ucTVStandard = ATOM_TV_PAL;
0130 break;
0131 case TV_STD_SECAM:
0132 args.ucTVStandard = ATOM_TV_SECAM;
0133 break;
0134 case TV_STD_PAL_CN:
0135 args.ucTVStandard = ATOM_TV_PALCN;
0136 break;
0137 }
0138 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
0139 } else if (is_cv) {
0140 args.ucTVStandard = ATOM_TV_CV;
0141 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
0142 } else {
0143 switch (radeon_crtc->rmx_type) {
0144 case RMX_FULL:
0145 args.ucEnable = ATOM_SCALER_EXPANSION;
0146 break;
0147 case RMX_CENTER:
0148 args.ucEnable = ATOM_SCALER_CENTER;
0149 break;
0150 case RMX_ASPECT:
0151 args.ucEnable = ATOM_SCALER_EXPANSION;
0152 break;
0153 default:
0154 if (ASIC_IS_AVIVO(rdev))
0155 args.ucEnable = ATOM_SCALER_DISABLE;
0156 else
0157 args.ucEnable = ATOM_SCALER_CENTER;
0158 break;
0159 }
0160 }
0161 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0162 if ((is_tv || is_cv)
0163 && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
0164 atom_rv515_force_tv_scaler(rdev, radeon_crtc);
0165 }
0166 }
0167
0168 static void atombios_lock_crtc(struct drm_crtc *crtc, int lock)
0169 {
0170 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0171 struct drm_device *dev = crtc->dev;
0172 struct radeon_device *rdev = dev->dev_private;
0173 int index =
0174 GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
0175 ENABLE_CRTC_PS_ALLOCATION args;
0176
0177 memset(&args, 0, sizeof(args));
0178
0179 args.ucCRTC = radeon_crtc->crtc_id;
0180 args.ucEnable = lock;
0181
0182 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0183 }
0184
0185 static void atombios_enable_crtc(struct drm_crtc *crtc, int state)
0186 {
0187 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0188 struct drm_device *dev = crtc->dev;
0189 struct radeon_device *rdev = dev->dev_private;
0190 int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
0191 ENABLE_CRTC_PS_ALLOCATION args;
0192
0193 memset(&args, 0, sizeof(args));
0194
0195 args.ucCRTC = radeon_crtc->crtc_id;
0196 args.ucEnable = state;
0197
0198 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0199 }
0200
0201 static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
0202 {
0203 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0204 struct drm_device *dev = crtc->dev;
0205 struct radeon_device *rdev = dev->dev_private;
0206 int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
0207 ENABLE_CRTC_PS_ALLOCATION args;
0208
0209 memset(&args, 0, sizeof(args));
0210
0211 args.ucCRTC = radeon_crtc->crtc_id;
0212 args.ucEnable = state;
0213
0214 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0215 }
0216
0217 static const u32 vga_control_regs[6] =
0218 {
0219 AVIVO_D1VGA_CONTROL,
0220 AVIVO_D2VGA_CONTROL,
0221 EVERGREEN_D3VGA_CONTROL,
0222 EVERGREEN_D4VGA_CONTROL,
0223 EVERGREEN_D5VGA_CONTROL,
0224 EVERGREEN_D6VGA_CONTROL,
0225 };
0226
0227 static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
0228 {
0229 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0230 struct drm_device *dev = crtc->dev;
0231 struct radeon_device *rdev = dev->dev_private;
0232 int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
0233 BLANK_CRTC_PS_ALLOCATION args;
0234 u32 vga_control = 0;
0235
0236 memset(&args, 0, sizeof(args));
0237
0238 if (ASIC_IS_DCE8(rdev)) {
0239 vga_control = RREG32(vga_control_regs[radeon_crtc->crtc_id]);
0240 WREG32(vga_control_regs[radeon_crtc->crtc_id], vga_control | 1);
0241 }
0242
0243 args.ucCRTC = radeon_crtc->crtc_id;
0244 args.ucBlanking = state;
0245
0246 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0247
0248 if (ASIC_IS_DCE8(rdev))
0249 WREG32(vga_control_regs[radeon_crtc->crtc_id], vga_control);
0250 }
0251
0252 static void atombios_powergate_crtc(struct drm_crtc *crtc, int state)
0253 {
0254 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0255 struct drm_device *dev = crtc->dev;
0256 struct radeon_device *rdev = dev->dev_private;
0257 int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
0258 ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args;
0259
0260 memset(&args, 0, sizeof(args));
0261
0262 args.ucDispPipeId = radeon_crtc->crtc_id;
0263 args.ucEnable = state;
0264
0265 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0266 }
0267
0268 void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
0269 {
0270 struct drm_device *dev = crtc->dev;
0271 struct radeon_device *rdev = dev->dev_private;
0272 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0273
0274 switch (mode) {
0275 case DRM_MODE_DPMS_ON:
0276 radeon_crtc->enabled = true;
0277 atombios_enable_crtc(crtc, ATOM_ENABLE);
0278 if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
0279 atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
0280 atombios_blank_crtc(crtc, ATOM_DISABLE);
0281 if (dev->num_crtcs > radeon_crtc->crtc_id)
0282 drm_crtc_vblank_on(crtc);
0283 radeon_crtc_load_lut(crtc);
0284 break;
0285 case DRM_MODE_DPMS_STANDBY:
0286 case DRM_MODE_DPMS_SUSPEND:
0287 case DRM_MODE_DPMS_OFF:
0288 if (dev->num_crtcs > radeon_crtc->crtc_id)
0289 drm_crtc_vblank_off(crtc);
0290 if (radeon_crtc->enabled)
0291 atombios_blank_crtc(crtc, ATOM_ENABLE);
0292 if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
0293 atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
0294 atombios_enable_crtc(crtc, ATOM_DISABLE);
0295 radeon_crtc->enabled = false;
0296 break;
0297 }
0298
0299 radeon_pm_compute_clocks(rdev);
0300 }
0301
0302 static void
0303 atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
0304 struct drm_display_mode *mode)
0305 {
0306 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0307 struct drm_device *dev = crtc->dev;
0308 struct radeon_device *rdev = dev->dev_private;
0309 SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
0310 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
0311 u16 misc = 0;
0312
0313 memset(&args, 0, sizeof(args));
0314 args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2));
0315 args.usH_Blanking_Time =
0316 cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2));
0317 args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2));
0318 args.usV_Blanking_Time =
0319 cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2));
0320 args.usH_SyncOffset =
0321 cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border);
0322 args.usH_SyncWidth =
0323 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
0324 args.usV_SyncOffset =
0325 cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border);
0326 args.usV_SyncWidth =
0327 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
0328 args.ucH_Border = radeon_crtc->h_border;
0329 args.ucV_Border = radeon_crtc->v_border;
0330
0331 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
0332 misc |= ATOM_VSYNC_POLARITY;
0333 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
0334 misc |= ATOM_HSYNC_POLARITY;
0335 if (mode->flags & DRM_MODE_FLAG_CSYNC)
0336 misc |= ATOM_COMPOSITESYNC;
0337 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
0338 misc |= ATOM_INTERLACE;
0339 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
0340 misc |= ATOM_DOUBLE_CLOCK_MODE;
0341 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
0342 misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
0343
0344 args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
0345 args.ucCRTC = radeon_crtc->crtc_id;
0346
0347 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0348 }
0349
0350 static void atombios_crtc_set_timing(struct drm_crtc *crtc,
0351 struct drm_display_mode *mode)
0352 {
0353 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0354 struct drm_device *dev = crtc->dev;
0355 struct radeon_device *rdev = dev->dev_private;
0356 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args;
0357 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
0358 u16 misc = 0;
0359
0360 memset(&args, 0, sizeof(args));
0361 args.usH_Total = cpu_to_le16(mode->crtc_htotal);
0362 args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay);
0363 args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start);
0364 args.usH_SyncWidth =
0365 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
0366 args.usV_Total = cpu_to_le16(mode->crtc_vtotal);
0367 args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay);
0368 args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start);
0369 args.usV_SyncWidth =
0370 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
0371
0372 args.ucOverscanRight = radeon_crtc->h_border;
0373 args.ucOverscanLeft = radeon_crtc->h_border;
0374 args.ucOverscanBottom = radeon_crtc->v_border;
0375 args.ucOverscanTop = radeon_crtc->v_border;
0376
0377 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
0378 misc |= ATOM_VSYNC_POLARITY;
0379 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
0380 misc |= ATOM_HSYNC_POLARITY;
0381 if (mode->flags & DRM_MODE_FLAG_CSYNC)
0382 misc |= ATOM_COMPOSITESYNC;
0383 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
0384 misc |= ATOM_INTERLACE;
0385 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
0386 misc |= ATOM_DOUBLE_CLOCK_MODE;
0387 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
0388 misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
0389
0390 args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
0391 args.ucCRTC = radeon_crtc->crtc_id;
0392
0393 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0394 }
0395
0396 static void atombios_disable_ss(struct radeon_device *rdev, int pll_id)
0397 {
0398 u32 ss_cntl;
0399
0400 if (ASIC_IS_DCE4(rdev)) {
0401 switch (pll_id) {
0402 case ATOM_PPLL1:
0403 ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
0404 ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
0405 WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
0406 break;
0407 case ATOM_PPLL2:
0408 ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
0409 ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
0410 WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
0411 break;
0412 case ATOM_DCPLL:
0413 case ATOM_PPLL_INVALID:
0414 return;
0415 }
0416 } else if (ASIC_IS_AVIVO(rdev)) {
0417 switch (pll_id) {
0418 case ATOM_PPLL1:
0419 ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
0420 ss_cntl &= ~1;
0421 WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
0422 break;
0423 case ATOM_PPLL2:
0424 ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
0425 ss_cntl &= ~1;
0426 WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
0427 break;
0428 case ATOM_DCPLL:
0429 case ATOM_PPLL_INVALID:
0430 return;
0431 }
0432 }
0433 }
0434
0435
0436 union atom_enable_ss {
0437 ENABLE_LVDS_SS_PARAMETERS lvds_ss;
0438 ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2;
0439 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
0440 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2;
0441 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
0442 };
0443
0444 static void atombios_crtc_program_ss(struct radeon_device *rdev,
0445 int enable,
0446 int pll_id,
0447 int crtc_id,
0448 struct radeon_atom_ss *ss)
0449 {
0450 unsigned i;
0451 int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
0452 union atom_enable_ss args;
0453
0454 if (enable) {
0455
0456
0457
0458
0459
0460 if (ss->percentage == 0)
0461 return;
0462 if (ss->type & ATOM_EXTERNAL_SS_MASK)
0463 return;
0464 } else {
0465 for (i = 0; i < rdev->num_crtc; i++) {
0466 if (rdev->mode_info.crtcs[i] &&
0467 rdev->mode_info.crtcs[i]->enabled &&
0468 i != crtc_id &&
0469 pll_id == rdev->mode_info.crtcs[i]->pll_id) {
0470
0471
0472
0473
0474 return;
0475 }
0476 }
0477 }
0478
0479 memset(&args, 0, sizeof(args));
0480
0481 if (ASIC_IS_DCE5(rdev)) {
0482 args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0);
0483 args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
0484 switch (pll_id) {
0485 case ATOM_PPLL1:
0486 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
0487 break;
0488 case ATOM_PPLL2:
0489 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
0490 break;
0491 case ATOM_DCPLL:
0492 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
0493 break;
0494 case ATOM_PPLL_INVALID:
0495 return;
0496 }
0497 args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
0498 args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
0499 args.v3.ucEnable = enable;
0500 } else if (ASIC_IS_DCE4(rdev)) {
0501 args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
0502 args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
0503 switch (pll_id) {
0504 case ATOM_PPLL1:
0505 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL;
0506 break;
0507 case ATOM_PPLL2:
0508 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL;
0509 break;
0510 case ATOM_DCPLL:
0511 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL;
0512 break;
0513 case ATOM_PPLL_INVALID:
0514 return;
0515 }
0516 args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
0517 args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step);
0518 args.v2.ucEnable = enable;
0519 } else if (ASIC_IS_DCE3(rdev)) {
0520 args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
0521 args.v1.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
0522 args.v1.ucSpreadSpectrumStep = ss->step;
0523 args.v1.ucSpreadSpectrumDelay = ss->delay;
0524 args.v1.ucSpreadSpectrumRange = ss->range;
0525 args.v1.ucPpll = pll_id;
0526 args.v1.ucEnable = enable;
0527 } else if (ASIC_IS_AVIVO(rdev)) {
0528 if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
0529 (ss->type & ATOM_EXTERNAL_SS_MASK)) {
0530 atombios_disable_ss(rdev, pll_id);
0531 return;
0532 }
0533 args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
0534 args.lvds_ss_2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
0535 args.lvds_ss_2.ucSpreadSpectrumStep = ss->step;
0536 args.lvds_ss_2.ucSpreadSpectrumDelay = ss->delay;
0537 args.lvds_ss_2.ucSpreadSpectrumRange = ss->range;
0538 args.lvds_ss_2.ucEnable = enable;
0539 } else {
0540 if (enable == ATOM_DISABLE) {
0541 atombios_disable_ss(rdev, pll_id);
0542 return;
0543 }
0544 args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
0545 args.lvds_ss.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
0546 args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2;
0547 args.lvds_ss.ucSpreadSpectrumStepSize_Delay |= (ss->delay & 7) << 4;
0548 args.lvds_ss.ucEnable = enable;
0549 }
0550 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0551 }
0552
0553 union adjust_pixel_clock {
0554 ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
0555 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
0556 };
0557
0558 static u32 atombios_adjust_pll(struct drm_crtc *crtc,
0559 struct drm_display_mode *mode)
0560 {
0561 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0562 struct drm_device *dev = crtc->dev;
0563 struct radeon_device *rdev = dev->dev_private;
0564 struct drm_encoder *encoder = radeon_crtc->encoder;
0565 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0566 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
0567 u32 adjusted_clock = mode->clock;
0568 int encoder_mode = atombios_get_encoder_mode(encoder);
0569 u32 dp_clock = mode->clock;
0570 u32 clock = mode->clock;
0571 int bpc = radeon_crtc->bpc;
0572 bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
0573
0574
0575 radeon_crtc->pll_flags = 0;
0576
0577 if (ASIC_IS_AVIVO(rdev)) {
0578 if ((rdev->family == CHIP_RS600) ||
0579 (rdev->family == CHIP_RS690) ||
0580 (rdev->family == CHIP_RS740))
0581 radeon_crtc->pll_flags |= (
0582 RADEON_PLL_PREFER_CLOSEST_LOWER);
0583
0584 if (ASIC_IS_DCE32(rdev) && mode->clock > 200000)
0585 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
0586 else
0587 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
0588
0589 if (rdev->family < CHIP_RV770)
0590 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
0591
0592 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
0593 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
0594
0595 if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
0596 && !radeon_crtc->ss_enabled)
0597 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
0598 if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
0599 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
0600 } else {
0601 radeon_crtc->pll_flags |= RADEON_PLL_LEGACY;
0602
0603 if (mode->clock > 200000)
0604 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
0605 else
0606 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
0607 }
0608
0609 if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
0610 (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
0611 if (connector) {
0612 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
0613 struct radeon_connector_atom_dig *dig_connector =
0614 radeon_connector->con_priv;
0615
0616 dp_clock = dig_connector->dp_clock;
0617 }
0618 }
0619
0620 if (radeon_encoder->is_mst_encoder) {
0621 struct radeon_encoder_mst *mst_enc = radeon_encoder->enc_priv;
0622 struct radeon_connector_atom_dig *dig_connector = mst_enc->connector->con_priv;
0623
0624 dp_clock = dig_connector->dp_clock;
0625 }
0626
0627
0628 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
0629 if (radeon_crtc->ss_enabled) {
0630 if (radeon_crtc->ss.refdiv) {
0631 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
0632 radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
0633 if (ASIC_IS_AVIVO(rdev) &&
0634 rdev->family != CHIP_RS780 &&
0635 rdev->family != CHIP_RS880)
0636 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
0637 }
0638 }
0639 }
0640
0641 if (ASIC_IS_AVIVO(rdev)) {
0642
0643 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
0644 adjusted_clock = mode->clock * 2;
0645 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
0646 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
0647 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
0648 radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD;
0649 } else {
0650 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
0651 radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
0652 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
0653 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
0654 }
0655
0656
0657 if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
0658 switch (bpc) {
0659 case 8:
0660 default:
0661 break;
0662 case 10:
0663 clock = (clock * 5) / 4;
0664 break;
0665 case 12:
0666 clock = (clock * 3) / 2;
0667 break;
0668 case 16:
0669 clock = clock * 2;
0670 break;
0671 }
0672 }
0673
0674
0675
0676
0677
0678 if (ASIC_IS_DCE3(rdev)) {
0679 union adjust_pixel_clock args;
0680 u8 frev, crev;
0681 int index;
0682
0683 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
0684 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
0685 &crev))
0686 return adjusted_clock;
0687
0688 memset(&args, 0, sizeof(args));
0689
0690 switch (frev) {
0691 case 1:
0692 switch (crev) {
0693 case 1:
0694 case 2:
0695 args.v1.usPixelClock = cpu_to_le16(clock / 10);
0696 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
0697 args.v1.ucEncodeMode = encoder_mode;
0698 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
0699 args.v1.ucConfig |=
0700 ADJUST_DISPLAY_CONFIG_SS_ENABLE;
0701
0702 atom_execute_table(rdev->mode_info.atom_context,
0703 index, (uint32_t *)&args);
0704 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
0705 break;
0706 case 3:
0707 args.v3.sInput.usPixelClock = cpu_to_le16(clock / 10);
0708 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
0709 args.v3.sInput.ucEncodeMode = encoder_mode;
0710 args.v3.sInput.ucDispPllConfig = 0;
0711 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
0712 args.v3.sInput.ucDispPllConfig |=
0713 DISPPLL_CONFIG_SS_ENABLE;
0714 if (ENCODER_MODE_IS_DP(encoder_mode)) {
0715 args.v3.sInput.ucDispPllConfig |=
0716 DISPPLL_CONFIG_COHERENT_MODE;
0717
0718 args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
0719 } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
0720 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
0721 if (dig->coherent_mode)
0722 args.v3.sInput.ucDispPllConfig |=
0723 DISPPLL_CONFIG_COHERENT_MODE;
0724 if (is_duallink)
0725 args.v3.sInput.ucDispPllConfig |=
0726 DISPPLL_CONFIG_DUAL_LINK;
0727 }
0728 if (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
0729 ENCODER_OBJECT_ID_NONE)
0730 args.v3.sInput.ucExtTransmitterID =
0731 radeon_encoder_get_dp_bridge_encoder_id(encoder);
0732 else
0733 args.v3.sInput.ucExtTransmitterID = 0;
0734
0735 atom_execute_table(rdev->mode_info.atom_context,
0736 index, (uint32_t *)&args);
0737 adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
0738 if (args.v3.sOutput.ucRefDiv) {
0739 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
0740 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
0741 radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv;
0742 }
0743 if (args.v3.sOutput.ucPostDiv) {
0744 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
0745 radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV;
0746 radeon_crtc->pll_post_div = args.v3.sOutput.ucPostDiv;
0747 }
0748 break;
0749 default:
0750 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
0751 return adjusted_clock;
0752 }
0753 break;
0754 default:
0755 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
0756 return adjusted_clock;
0757 }
0758 }
0759 return adjusted_clock;
0760 }
0761
0762 union set_pixel_clock {
0763 SET_PIXEL_CLOCK_PS_ALLOCATION base;
0764 PIXEL_CLOCK_PARAMETERS v1;
0765 PIXEL_CLOCK_PARAMETERS_V2 v2;
0766 PIXEL_CLOCK_PARAMETERS_V3 v3;
0767 PIXEL_CLOCK_PARAMETERS_V5 v5;
0768 PIXEL_CLOCK_PARAMETERS_V6 v6;
0769 };
0770
0771
0772
0773
0774 static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev,
0775 u32 dispclk)
0776 {
0777 u8 frev, crev;
0778 int index;
0779 union set_pixel_clock args;
0780
0781 memset(&args, 0, sizeof(args));
0782
0783 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
0784 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
0785 &crev))
0786 return;
0787
0788 switch (frev) {
0789 case 1:
0790 switch (crev) {
0791 case 5:
0792
0793
0794
0795 args.v5.ucCRTC = ATOM_CRTC_INVALID;
0796 args.v5.usPixelClock = cpu_to_le16(dispclk);
0797 args.v5.ucPpll = ATOM_DCPLL;
0798 break;
0799 case 6:
0800
0801
0802
0803 args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
0804 if (ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
0805 args.v6.ucPpll = ATOM_EXT_PLL1;
0806 else if (ASIC_IS_DCE6(rdev))
0807 args.v6.ucPpll = ATOM_PPLL0;
0808 else
0809 args.v6.ucPpll = ATOM_DCPLL;
0810 break;
0811 default:
0812 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
0813 return;
0814 }
0815 break;
0816 default:
0817 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
0818 return;
0819 }
0820 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0821 }
0822
0823 static void atombios_crtc_program_pll(struct drm_crtc *crtc,
0824 u32 crtc_id,
0825 int pll_id,
0826 u32 encoder_mode,
0827 u32 encoder_id,
0828 u32 clock,
0829 u32 ref_div,
0830 u32 fb_div,
0831 u32 frac_fb_div,
0832 u32 post_div,
0833 int bpc,
0834 bool ss_enabled,
0835 struct radeon_atom_ss *ss)
0836 {
0837 struct drm_device *dev = crtc->dev;
0838 struct radeon_device *rdev = dev->dev_private;
0839 u8 frev, crev;
0840 int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
0841 union set_pixel_clock args;
0842
0843 memset(&args, 0, sizeof(args));
0844
0845 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
0846 &crev))
0847 return;
0848
0849 switch (frev) {
0850 case 1:
0851 switch (crev) {
0852 case 1:
0853 if (clock == ATOM_DISABLE)
0854 return;
0855 args.v1.usPixelClock = cpu_to_le16(clock / 10);
0856 args.v1.usRefDiv = cpu_to_le16(ref_div);
0857 args.v1.usFbDiv = cpu_to_le16(fb_div);
0858 args.v1.ucFracFbDiv = frac_fb_div;
0859 args.v1.ucPostDiv = post_div;
0860 args.v1.ucPpll = pll_id;
0861 args.v1.ucCRTC = crtc_id;
0862 args.v1.ucRefDivSrc = 1;
0863 break;
0864 case 2:
0865 args.v2.usPixelClock = cpu_to_le16(clock / 10);
0866 args.v2.usRefDiv = cpu_to_le16(ref_div);
0867 args.v2.usFbDiv = cpu_to_le16(fb_div);
0868 args.v2.ucFracFbDiv = frac_fb_div;
0869 args.v2.ucPostDiv = post_div;
0870 args.v2.ucPpll = pll_id;
0871 args.v2.ucCRTC = crtc_id;
0872 args.v2.ucRefDivSrc = 1;
0873 break;
0874 case 3:
0875 args.v3.usPixelClock = cpu_to_le16(clock / 10);
0876 args.v3.usRefDiv = cpu_to_le16(ref_div);
0877 args.v3.usFbDiv = cpu_to_le16(fb_div);
0878 args.v3.ucFracFbDiv = frac_fb_div;
0879 args.v3.ucPostDiv = post_div;
0880 args.v3.ucPpll = pll_id;
0881 if (crtc_id == ATOM_CRTC2)
0882 args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
0883 else
0884 args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1;
0885 if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
0886 args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
0887 args.v3.ucTransmitterId = encoder_id;
0888 args.v3.ucEncoderMode = encoder_mode;
0889 break;
0890 case 5:
0891 args.v5.ucCRTC = crtc_id;
0892 args.v5.usPixelClock = cpu_to_le16(clock / 10);
0893 args.v5.ucRefDiv = ref_div;
0894 args.v5.usFbDiv = cpu_to_le16(fb_div);
0895 args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
0896 args.v5.ucPostDiv = post_div;
0897 args.v5.ucMiscInfo = 0;
0898 if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
0899 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
0900 if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
0901 switch (bpc) {
0902 case 8:
0903 default:
0904 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
0905 break;
0906 case 10:
0907
0908 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
0909 break;
0910 case 12:
0911
0912 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
0913 break;
0914 }
0915 }
0916 args.v5.ucTransmitterID = encoder_id;
0917 args.v5.ucEncoderMode = encoder_mode;
0918 args.v5.ucPpll = pll_id;
0919 break;
0920 case 6:
0921 args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10);
0922 args.v6.ucRefDiv = ref_div;
0923 args.v6.usFbDiv = cpu_to_le16(fb_div);
0924 args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
0925 args.v6.ucPostDiv = post_div;
0926 args.v6.ucMiscInfo = 0;
0927 if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
0928 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
0929 if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
0930 switch (bpc) {
0931 case 8:
0932 default:
0933 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
0934 break;
0935 case 10:
0936 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6;
0937 break;
0938 case 12:
0939 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6;
0940 break;
0941 case 16:
0942 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
0943 break;
0944 }
0945 }
0946 args.v6.ucTransmitterID = encoder_id;
0947 args.v6.ucEncoderMode = encoder_mode;
0948 args.v6.ucPpll = pll_id;
0949 break;
0950 default:
0951 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
0952 return;
0953 }
0954 break;
0955 default:
0956 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
0957 return;
0958 }
0959
0960 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0961 }
0962
0963 static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
0964 {
0965 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
0966 struct drm_device *dev = crtc->dev;
0967 struct radeon_device *rdev = dev->dev_private;
0968 struct radeon_encoder *radeon_encoder =
0969 to_radeon_encoder(radeon_crtc->encoder);
0970 int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
0971
0972 radeon_crtc->bpc = 8;
0973 radeon_crtc->ss_enabled = false;
0974
0975 if (radeon_encoder->is_mst_encoder) {
0976 radeon_dp_mst_prepare_pll(crtc, mode);
0977 } else if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
0978 (radeon_encoder_get_dp_bridge_encoder_id(radeon_crtc->encoder) != ENCODER_OBJECT_ID_NONE)) {
0979 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
0980 struct drm_connector *connector =
0981 radeon_get_connector_for_encoder(radeon_crtc->encoder);
0982 struct radeon_connector *radeon_connector =
0983 to_radeon_connector(connector);
0984 struct radeon_connector_atom_dig *dig_connector =
0985 radeon_connector->con_priv;
0986 int dp_clock;
0987
0988
0989 radeon_connector->pixelclock_for_modeset = mode->clock;
0990 radeon_crtc->bpc = radeon_get_monitor_bpc(connector);
0991
0992 switch (encoder_mode) {
0993 case ATOM_ENCODER_MODE_DP_MST:
0994 case ATOM_ENCODER_MODE_DP:
0995
0996 dp_clock = dig_connector->dp_clock / 10;
0997 if (ASIC_IS_DCE4(rdev))
0998 radeon_crtc->ss_enabled =
0999 radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss,
1000 ASIC_INTERNAL_SS_ON_DP,
1001 dp_clock);
1002 else {
1003 if (dp_clock == 16200) {
1004 radeon_crtc->ss_enabled =
1005 radeon_atombios_get_ppll_ss_info(rdev,
1006 &radeon_crtc->ss,
1007 ATOM_DP_SS_ID2);
1008 if (!radeon_crtc->ss_enabled)
1009 radeon_crtc->ss_enabled =
1010 radeon_atombios_get_ppll_ss_info(rdev,
1011 &radeon_crtc->ss,
1012 ATOM_DP_SS_ID1);
1013 } else {
1014 radeon_crtc->ss_enabled =
1015 radeon_atombios_get_ppll_ss_info(rdev,
1016 &radeon_crtc->ss,
1017 ATOM_DP_SS_ID1);
1018 }
1019
1020 radeon_crtc->ss_enabled = false;
1021 }
1022 break;
1023 case ATOM_ENCODER_MODE_LVDS:
1024 if (ASIC_IS_DCE4(rdev))
1025 radeon_crtc->ss_enabled =
1026 radeon_atombios_get_asic_ss_info(rdev,
1027 &radeon_crtc->ss,
1028 dig->lcd_ss_id,
1029 mode->clock / 10);
1030 else
1031 radeon_crtc->ss_enabled =
1032 radeon_atombios_get_ppll_ss_info(rdev,
1033 &radeon_crtc->ss,
1034 dig->lcd_ss_id);
1035 break;
1036 case ATOM_ENCODER_MODE_DVI:
1037 if (ASIC_IS_DCE4(rdev))
1038 radeon_crtc->ss_enabled =
1039 radeon_atombios_get_asic_ss_info(rdev,
1040 &radeon_crtc->ss,
1041 ASIC_INTERNAL_SS_ON_TMDS,
1042 mode->clock / 10);
1043 break;
1044 case ATOM_ENCODER_MODE_HDMI:
1045 if (ASIC_IS_DCE4(rdev))
1046 radeon_crtc->ss_enabled =
1047 radeon_atombios_get_asic_ss_info(rdev,
1048 &radeon_crtc->ss,
1049 ASIC_INTERNAL_SS_ON_HDMI,
1050 mode->clock / 10);
1051 break;
1052 default:
1053 break;
1054 }
1055 }
1056
1057
1058 radeon_crtc->adjusted_clock = atombios_adjust_pll(crtc, mode);
1059
1060 return true;
1061 }
1062
1063 static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
1064 {
1065 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1066 struct drm_device *dev = crtc->dev;
1067 struct radeon_device *rdev = dev->dev_private;
1068 struct radeon_encoder *radeon_encoder =
1069 to_radeon_encoder(radeon_crtc->encoder);
1070 u32 pll_clock = mode->clock;
1071 u32 clock = mode->clock;
1072 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
1073 struct radeon_pll *pll;
1074 int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
1075
1076
1077 if (ASIC_IS_DCE5(rdev) &&
1078 (encoder_mode == ATOM_ENCODER_MODE_HDMI) &&
1079 (radeon_crtc->bpc > 8))
1080 clock = radeon_crtc->adjusted_clock;
1081
1082 switch (radeon_crtc->pll_id) {
1083 case ATOM_PPLL1:
1084 pll = &rdev->clock.p1pll;
1085 break;
1086 case ATOM_PPLL2:
1087 pll = &rdev->clock.p2pll;
1088 break;
1089 case ATOM_DCPLL:
1090 case ATOM_PPLL_INVALID:
1091 default:
1092 pll = &rdev->clock.dcpll;
1093 break;
1094 }
1095
1096
1097 pll->flags = radeon_crtc->pll_flags;
1098 pll->reference_div = radeon_crtc->pll_reference_div;
1099 pll->post_div = radeon_crtc->pll_post_div;
1100
1101 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
1102
1103 radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
1104 &fb_div, &frac_fb_div, &ref_div, &post_div);
1105 else if (ASIC_IS_AVIVO(rdev))
1106 radeon_compute_pll_avivo(pll, radeon_crtc->adjusted_clock, &pll_clock,
1107 &fb_div, &frac_fb_div, &ref_div, &post_div);
1108 else
1109 radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
1110 &fb_div, &frac_fb_div, &ref_div, &post_div);
1111
1112 atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id,
1113 radeon_crtc->crtc_id, &radeon_crtc->ss);
1114
1115 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1116 encoder_mode, radeon_encoder->encoder_id, clock,
1117 ref_div, fb_div, frac_fb_div, post_div,
1118 radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss);
1119
1120 if (radeon_crtc->ss_enabled) {
1121
1122 if (ASIC_IS_DCE4(rdev)) {
1123 u32 step_size;
1124 u32 amount = (((fb_div * 10) + frac_fb_div) *
1125 (u32)radeon_crtc->ss.percentage) /
1126 (100 * (u32)radeon_crtc->ss.percentage_divider);
1127 radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
1128 radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
1129 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
1130 if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
1131 step_size = (4 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) /
1132 (125 * 25 * pll->reference_freq / 100);
1133 else
1134 step_size = (2 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) /
1135 (125 * 25 * pll->reference_freq / 100);
1136 radeon_crtc->ss.step = step_size;
1137 }
1138
1139 atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id,
1140 radeon_crtc->crtc_id, &radeon_crtc->ss);
1141 }
1142 }
1143
1144 static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
1145 struct drm_framebuffer *fb,
1146 int x, int y, int atomic)
1147 {
1148 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1149 struct drm_device *dev = crtc->dev;
1150 struct radeon_device *rdev = dev->dev_private;
1151 struct drm_framebuffer *target_fb;
1152 struct drm_gem_object *obj;
1153 struct radeon_bo *rbo;
1154 uint64_t fb_location;
1155 uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1156 unsigned bankw, bankh, mtaspect, tile_split;
1157 u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
1158 u32 tmp, viewport_w, viewport_h;
1159 int r;
1160 bool bypass_lut = false;
1161
1162
1163 if (!atomic && !crtc->primary->fb) {
1164 DRM_DEBUG_KMS("No FB bound\n");
1165 return 0;
1166 }
1167
1168 if (atomic)
1169 target_fb = fb;
1170 else
1171 target_fb = crtc->primary->fb;
1172
1173
1174
1175
1176 obj = target_fb->obj[0];
1177 rbo = gem_to_radeon_bo(obj);
1178 r = radeon_bo_reserve(rbo, false);
1179 if (unlikely(r != 0))
1180 return r;
1181
1182 if (atomic)
1183 fb_location = radeon_bo_gpu_offset(rbo);
1184 else {
1185 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1186 if (unlikely(r != 0)) {
1187 radeon_bo_unreserve(rbo);
1188 return -EINVAL;
1189 }
1190 }
1191
1192 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
1193 radeon_bo_unreserve(rbo);
1194
1195 switch (target_fb->format->format) {
1196 case DRM_FORMAT_C8:
1197 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
1198 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
1199 break;
1200 case DRM_FORMAT_XRGB4444:
1201 case DRM_FORMAT_ARGB4444:
1202 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1203 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB4444));
1204 #ifdef __BIG_ENDIAN
1205 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1206 #endif
1207 break;
1208 case DRM_FORMAT_XRGB1555:
1209 case DRM_FORMAT_ARGB1555:
1210 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1211 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
1212 #ifdef __BIG_ENDIAN
1213 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1214 #endif
1215 break;
1216 case DRM_FORMAT_BGRX5551:
1217 case DRM_FORMAT_BGRA5551:
1218 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1219 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA5551));
1220 #ifdef __BIG_ENDIAN
1221 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1222 #endif
1223 break;
1224 case DRM_FORMAT_RGB565:
1225 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1226 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
1227 #ifdef __BIG_ENDIAN
1228 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1229 #endif
1230 break;
1231 case DRM_FORMAT_XRGB8888:
1232 case DRM_FORMAT_ARGB8888:
1233 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1234 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
1235 #ifdef __BIG_ENDIAN
1236 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1237 #endif
1238 break;
1239 case DRM_FORMAT_XRGB2101010:
1240 case DRM_FORMAT_ARGB2101010:
1241 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1242 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB2101010));
1243 #ifdef __BIG_ENDIAN
1244 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1245 #endif
1246
1247 bypass_lut = true;
1248 break;
1249 case DRM_FORMAT_BGRX1010102:
1250 case DRM_FORMAT_BGRA1010102:
1251 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1252 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA1010102));
1253 #ifdef __BIG_ENDIAN
1254 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1255 #endif
1256
1257 bypass_lut = true;
1258 break;
1259 case DRM_FORMAT_XBGR8888:
1260 case DRM_FORMAT_ABGR8888:
1261 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1262 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
1263 fb_swap = (EVERGREEN_GRPH_RED_CROSSBAR(EVERGREEN_GRPH_RED_SEL_B) |
1264 EVERGREEN_GRPH_BLUE_CROSSBAR(EVERGREEN_GRPH_BLUE_SEL_R));
1265 #ifdef __BIG_ENDIAN
1266 fb_swap |= EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1267 #endif
1268 break;
1269 default:
1270 DRM_ERROR("Unsupported screen format %p4cc\n",
1271 &target_fb->format->format);
1272 return -EINVAL;
1273 }
1274
1275 if (tiling_flags & RADEON_TILING_MACRO) {
1276 evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split);
1277
1278
1279 if (rdev->family >= CHIP_TAHITI) {
1280 unsigned index, num_banks;
1281
1282 if (rdev->family >= CHIP_BONAIRE) {
1283 unsigned tileb, tile_split_bytes;
1284
1285
1286 tile_split_bytes = 64 << tile_split;
1287 tileb = 8 * 8 * target_fb->format->cpp[0];
1288 tileb = min(tile_split_bytes, tileb);
1289
1290 for (index = 0; tileb > 64; index++)
1291 tileb >>= 1;
1292
1293 if (index >= 16) {
1294 DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
1295 target_fb->format->cpp[0] * 8,
1296 tile_split);
1297 return -EINVAL;
1298 }
1299
1300 num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3;
1301 } else {
1302 switch (target_fb->format->cpp[0] * 8) {
1303 case 8:
1304 index = 10;
1305 break;
1306 case 16:
1307 index = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1308 break;
1309 default:
1310 case 32:
1311 index = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1312 break;
1313 }
1314
1315 num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3;
1316 }
1317
1318 fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks);
1319 } else {
1320
1321 if (rdev->family >= CHIP_CAYMAN)
1322 tmp = rdev->config.cayman.tile_config;
1323 else
1324 tmp = rdev->config.evergreen.tile_config;
1325
1326 switch ((tmp & 0xf0) >> 4) {
1327 case 0:
1328 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
1329 break;
1330 case 1:
1331 default:
1332 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
1333 break;
1334 case 2:
1335 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
1336 break;
1337 }
1338 }
1339
1340 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
1341 fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split);
1342 fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
1343 fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
1344 fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
1345 if (rdev->family >= CHIP_BONAIRE) {
1346
1347 fb_format |= CIK_GRPH_MICRO_TILE_MODE(CIK_DISPLAY_MICRO_TILING);
1348 }
1349 } else if (tiling_flags & RADEON_TILING_MICRO)
1350 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
1351
1352 if (rdev->family >= CHIP_BONAIRE) {
1353
1354
1355
1356 u32 pipe_config = (rdev->config.cik.tile_mode_array[10] >> 6) & 0x1f;
1357
1358 fb_format |= CIK_GRPH_PIPE_CONFIG(pipe_config);
1359 } else if ((rdev->family == CHIP_TAHITI) ||
1360 (rdev->family == CHIP_PITCAIRN))
1361 fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16);
1362 else if ((rdev->family == CHIP_VERDE) ||
1363 (rdev->family == CHIP_OLAND) ||
1364 (rdev->family == CHIP_HAINAN))
1365 fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16);
1366
1367 switch (radeon_crtc->crtc_id) {
1368 case 0:
1369 WREG32(AVIVO_D1VGA_CONTROL, 0);
1370 break;
1371 case 1:
1372 WREG32(AVIVO_D2VGA_CONTROL, 0);
1373 break;
1374 case 2:
1375 WREG32(EVERGREEN_D3VGA_CONTROL, 0);
1376 break;
1377 case 3:
1378 WREG32(EVERGREEN_D4VGA_CONTROL, 0);
1379 break;
1380 case 4:
1381 WREG32(EVERGREEN_D5VGA_CONTROL, 0);
1382 break;
1383 case 5:
1384 WREG32(EVERGREEN_D6VGA_CONTROL, 0);
1385 break;
1386 default:
1387 break;
1388 }
1389
1390
1391
1392
1393 WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
1394
1395 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
1396 upper_32_bits(fb_location));
1397 WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
1398 upper_32_bits(fb_location));
1399 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1400 (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
1401 WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1402 (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
1403 WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
1404 WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
1405
1406
1407
1408
1409
1410
1411 WREG32_P(EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL + radeon_crtc->crtc_offset,
1412 (bypass_lut ? EVERGREEN_LUT_10BIT_BYPASS_EN : 0),
1413 ~EVERGREEN_LUT_10BIT_BYPASS_EN);
1414
1415 if (bypass_lut)
1416 DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
1417
1418 WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
1419 WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
1420 WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
1421 WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
1422 WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
1423 WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
1424
1425 fb_pitch_pixels = target_fb->pitches[0] / target_fb->format->cpp[0];
1426 WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
1427 WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
1428
1429 if (rdev->family >= CHIP_BONAIRE)
1430 WREG32(CIK_LB_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1431 target_fb->height);
1432 else
1433 WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1434 target_fb->height);
1435 x &= ~3;
1436 y &= ~1;
1437 WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
1438 (x << 16) | y);
1439 viewport_w = crtc->mode.hdisplay;
1440 viewport_h = (crtc->mode.vdisplay + 1) & ~1;
1441 if ((rdev->family >= CHIP_BONAIRE) &&
1442 (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE))
1443 viewport_h *= 2;
1444 WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1445 (viewport_w << 16) | viewport_h);
1446
1447
1448 WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
1449
1450 if (!atomic && fb && fb != crtc->primary->fb) {
1451 rbo = gem_to_radeon_bo(fb->obj[0]);
1452 r = radeon_bo_reserve(rbo, false);
1453 if (unlikely(r != 0))
1454 return r;
1455 radeon_bo_unpin(rbo);
1456 radeon_bo_unreserve(rbo);
1457 }
1458
1459
1460 radeon_bandwidth_update(rdev);
1461
1462 return 0;
1463 }
1464
1465 static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
1466 struct drm_framebuffer *fb,
1467 int x, int y, int atomic)
1468 {
1469 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1470 struct drm_device *dev = crtc->dev;
1471 struct radeon_device *rdev = dev->dev_private;
1472 struct drm_gem_object *obj;
1473 struct radeon_bo *rbo;
1474 struct drm_framebuffer *target_fb;
1475 uint64_t fb_location;
1476 uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1477 u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
1478 u32 viewport_w, viewport_h;
1479 int r;
1480 bool bypass_lut = false;
1481
1482
1483 if (!atomic && !crtc->primary->fb) {
1484 DRM_DEBUG_KMS("No FB bound\n");
1485 return 0;
1486 }
1487
1488 if (atomic)
1489 target_fb = fb;
1490 else
1491 target_fb = crtc->primary->fb;
1492
1493 obj = target_fb->obj[0];
1494 rbo = gem_to_radeon_bo(obj);
1495 r = radeon_bo_reserve(rbo, false);
1496 if (unlikely(r != 0))
1497 return r;
1498
1499
1500
1501
1502 if (atomic)
1503 fb_location = radeon_bo_gpu_offset(rbo);
1504 else {
1505 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1506 if (unlikely(r != 0)) {
1507 radeon_bo_unreserve(rbo);
1508 return -EINVAL;
1509 }
1510 }
1511 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
1512 radeon_bo_unreserve(rbo);
1513
1514 switch (target_fb->format->format) {
1515 case DRM_FORMAT_C8:
1516 fb_format =
1517 AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
1518 AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
1519 break;
1520 case DRM_FORMAT_XRGB4444:
1521 case DRM_FORMAT_ARGB4444:
1522 fb_format =
1523 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1524 AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444;
1525 #ifdef __BIG_ENDIAN
1526 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
1527 #endif
1528 break;
1529 case DRM_FORMAT_XRGB1555:
1530 fb_format =
1531 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1532 AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
1533 #ifdef __BIG_ENDIAN
1534 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
1535 #endif
1536 break;
1537 case DRM_FORMAT_RGB565:
1538 fb_format =
1539 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1540 AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
1541 #ifdef __BIG_ENDIAN
1542 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
1543 #endif
1544 break;
1545 case DRM_FORMAT_XRGB8888:
1546 case DRM_FORMAT_ARGB8888:
1547 fb_format =
1548 AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
1549 AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
1550 #ifdef __BIG_ENDIAN
1551 fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
1552 #endif
1553 break;
1554 case DRM_FORMAT_XRGB2101010:
1555 case DRM_FORMAT_ARGB2101010:
1556 fb_format =
1557 AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
1558 AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010;
1559 #ifdef __BIG_ENDIAN
1560 fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
1561 #endif
1562
1563 bypass_lut = true;
1564 break;
1565 case DRM_FORMAT_XBGR8888:
1566 case DRM_FORMAT_ABGR8888:
1567 fb_format =
1568 AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
1569 AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
1570 if (rdev->family >= CHIP_R600)
1571 fb_swap =
1572 (R600_D1GRPH_RED_CROSSBAR(R600_D1GRPH_RED_SEL_B) |
1573 R600_D1GRPH_BLUE_CROSSBAR(R600_D1GRPH_BLUE_SEL_R));
1574 else
1575 fb_format |= AVIVO_D1GRPH_SWAP_RB;
1576 #ifdef __BIG_ENDIAN
1577 fb_swap |= R600_D1GRPH_SWAP_ENDIAN_32BIT;
1578 #endif
1579 break;
1580 default:
1581 DRM_ERROR("Unsupported screen format %p4cc\n",
1582 &target_fb->format->format);
1583 return -EINVAL;
1584 }
1585
1586 if (rdev->family >= CHIP_R600) {
1587 if (tiling_flags & RADEON_TILING_MACRO)
1588 fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1;
1589 else if (tiling_flags & RADEON_TILING_MICRO)
1590 fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1;
1591 } else {
1592 if (tiling_flags & RADEON_TILING_MACRO)
1593 fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
1594
1595 if (tiling_flags & RADEON_TILING_MICRO)
1596 fb_format |= AVIVO_D1GRPH_TILED;
1597 }
1598
1599 if (radeon_crtc->crtc_id == 0)
1600 WREG32(AVIVO_D1VGA_CONTROL, 0);
1601 else
1602 WREG32(AVIVO_D2VGA_CONTROL, 0);
1603
1604
1605
1606
1607 WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
1608
1609 if (rdev->family >= CHIP_RV770) {
1610 if (radeon_crtc->crtc_id) {
1611 WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1612 WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1613 } else {
1614 WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1615 WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1616 }
1617 }
1618 WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1619 (u32) fb_location);
1620 WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
1621 radeon_crtc->crtc_offset, (u32) fb_location);
1622 WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
1623 if (rdev->family >= CHIP_R600)
1624 WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
1625
1626
1627 WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset,
1628 (bypass_lut ? AVIVO_LUT_10BIT_BYPASS_EN : 0), ~AVIVO_LUT_10BIT_BYPASS_EN);
1629
1630 if (bypass_lut)
1631 DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
1632
1633 WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
1634 WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
1635 WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
1636 WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
1637 WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
1638 WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
1639
1640 fb_pitch_pixels = target_fb->pitches[0] / target_fb->format->cpp[0];
1641 WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
1642 WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
1643
1644 WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1645 target_fb->height);
1646 x &= ~3;
1647 y &= ~1;
1648 WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
1649 (x << 16) | y);
1650 viewport_w = crtc->mode.hdisplay;
1651 viewport_h = (crtc->mode.vdisplay + 1) & ~1;
1652 WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1653 (viewport_w << 16) | viewport_h);
1654
1655
1656 WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
1657
1658 if (!atomic && fb && fb != crtc->primary->fb) {
1659 rbo = gem_to_radeon_bo(fb->obj[0]);
1660 r = radeon_bo_reserve(rbo, false);
1661 if (unlikely(r != 0))
1662 return r;
1663 radeon_bo_unpin(rbo);
1664 radeon_bo_unreserve(rbo);
1665 }
1666
1667
1668 radeon_bandwidth_update(rdev);
1669
1670 return 0;
1671 }
1672
1673 int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
1674 struct drm_framebuffer *old_fb)
1675 {
1676 struct drm_device *dev = crtc->dev;
1677 struct radeon_device *rdev = dev->dev_private;
1678
1679 if (ASIC_IS_DCE4(rdev))
1680 return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0);
1681 else if (ASIC_IS_AVIVO(rdev))
1682 return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
1683 else
1684 return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
1685 }
1686
1687 int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
1688 struct drm_framebuffer *fb,
1689 int x, int y, enum mode_set_atomic state)
1690 {
1691 struct drm_device *dev = crtc->dev;
1692 struct radeon_device *rdev = dev->dev_private;
1693
1694 if (ASIC_IS_DCE4(rdev))
1695 return dce4_crtc_do_set_base(crtc, fb, x, y, 1);
1696 else if (ASIC_IS_AVIVO(rdev))
1697 return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
1698 else
1699 return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
1700 }
1701
1702
1703 static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
1704 {
1705 struct drm_device *dev = crtc->dev;
1706 struct radeon_device *rdev = dev->dev_private;
1707 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1708 u32 disp_merge_cntl;
1709
1710 switch (radeon_crtc->crtc_id) {
1711 case 0:
1712 disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
1713 disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
1714 WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
1715 break;
1716 case 1:
1717 disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
1718 disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
1719 WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
1720 WREG32(RADEON_FP_H2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
1721 WREG32(RADEON_FP_V2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
1722 break;
1723 }
1724 }
1725
1726
1727
1728
1729
1730
1731
1732
1733 static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
1734 {
1735 struct drm_device *dev = crtc->dev;
1736 struct drm_crtc *test_crtc;
1737 struct radeon_crtc *test_radeon_crtc;
1738 u32 pll_in_use = 0;
1739
1740 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1741 if (crtc == test_crtc)
1742 continue;
1743
1744 test_radeon_crtc = to_radeon_crtc(test_crtc);
1745 if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
1746 pll_in_use |= (1 << test_radeon_crtc->pll_id);
1747 }
1748 return pll_in_use;
1749 }
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760 static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
1761 {
1762 struct drm_device *dev = crtc->dev;
1763 struct radeon_device *rdev = dev->dev_private;
1764 struct drm_crtc *test_crtc;
1765 struct radeon_crtc *test_radeon_crtc;
1766
1767 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1768 if (crtc == test_crtc)
1769 continue;
1770 test_radeon_crtc = to_radeon_crtc(test_crtc);
1771 if (test_radeon_crtc->encoder &&
1772 ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
1773
1774 if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
1775 test_radeon_crtc->pll_id == ATOM_PPLL2)
1776 continue;
1777
1778 if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
1779 return test_radeon_crtc->pll_id;
1780 }
1781 }
1782 return ATOM_PPLL_INVALID;
1783 }
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793 static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
1794 {
1795 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1796 struct drm_device *dev = crtc->dev;
1797 struct radeon_device *rdev = dev->dev_private;
1798 struct drm_crtc *test_crtc;
1799 struct radeon_crtc *test_radeon_crtc;
1800 u32 adjusted_clock, test_adjusted_clock;
1801
1802 adjusted_clock = radeon_crtc->adjusted_clock;
1803
1804 if (adjusted_clock == 0)
1805 return ATOM_PPLL_INVALID;
1806
1807 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1808 if (crtc == test_crtc)
1809 continue;
1810 test_radeon_crtc = to_radeon_crtc(test_crtc);
1811 if (test_radeon_crtc->encoder &&
1812 !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
1813
1814 if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
1815 test_radeon_crtc->pll_id == ATOM_PPLL2)
1816 continue;
1817
1818 if (test_radeon_crtc->connector == radeon_crtc->connector) {
1819
1820 if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
1821 return test_radeon_crtc->pll_id;
1822 }
1823
1824 test_adjusted_clock = test_radeon_crtc->adjusted_clock;
1825 if ((crtc->mode.clock == test_crtc->mode.clock) &&
1826 (adjusted_clock == test_adjusted_clock) &&
1827 (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) &&
1828 (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID))
1829 return test_radeon_crtc->pll_id;
1830 }
1831 }
1832 return ATOM_PPLL_INVALID;
1833 }
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872 static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1873 {
1874 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1875 struct drm_device *dev = crtc->dev;
1876 struct radeon_device *rdev = dev->dev_private;
1877 struct radeon_encoder *radeon_encoder =
1878 to_radeon_encoder(radeon_crtc->encoder);
1879 u32 pll_in_use;
1880 int pll;
1881
1882 if (ASIC_IS_DCE8(rdev)) {
1883 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
1884 if (rdev->clock.dp_extclk)
1885
1886 return ATOM_PPLL_INVALID;
1887 else {
1888
1889 pll = radeon_get_shared_dp_ppll(crtc);
1890 if (pll != ATOM_PPLL_INVALID)
1891 return pll;
1892 }
1893 } else {
1894
1895 pll = radeon_get_shared_nondp_ppll(crtc);
1896 if (pll != ATOM_PPLL_INVALID)
1897 return pll;
1898 }
1899
1900 if ((rdev->family == CHIP_KABINI) ||
1901 (rdev->family == CHIP_MULLINS)) {
1902
1903 pll_in_use = radeon_get_pll_use_mask(crtc);
1904 if (!(pll_in_use & (1 << ATOM_PPLL2)))
1905 return ATOM_PPLL2;
1906 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1907 return ATOM_PPLL1;
1908 DRM_ERROR("unable to allocate a PPLL\n");
1909 return ATOM_PPLL_INVALID;
1910 } else {
1911
1912 pll_in_use = radeon_get_pll_use_mask(crtc);
1913 if (!(pll_in_use & (1 << ATOM_PPLL2)))
1914 return ATOM_PPLL2;
1915 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1916 return ATOM_PPLL1;
1917 if (!(pll_in_use & (1 << ATOM_PPLL0)))
1918 return ATOM_PPLL0;
1919 DRM_ERROR("unable to allocate a PPLL\n");
1920 return ATOM_PPLL_INVALID;
1921 }
1922 } else if (ASIC_IS_DCE61(rdev)) {
1923 struct radeon_encoder_atom_dig *dig =
1924 radeon_encoder->enc_priv;
1925
1926 if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
1927 (dig->linkb == false))
1928
1929 return ATOM_PPLL2;
1930 else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
1931
1932 if (rdev->clock.dp_extclk)
1933
1934 return ATOM_PPLL_INVALID;
1935 else {
1936
1937 pll = radeon_get_shared_dp_ppll(crtc);
1938 if (pll != ATOM_PPLL_INVALID)
1939 return pll;
1940 }
1941 } else {
1942
1943 pll = radeon_get_shared_nondp_ppll(crtc);
1944 if (pll != ATOM_PPLL_INVALID)
1945 return pll;
1946 }
1947
1948 pll_in_use = radeon_get_pll_use_mask(crtc);
1949 if (!(pll_in_use & (1 << ATOM_PPLL0)))
1950 return ATOM_PPLL0;
1951 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1952 return ATOM_PPLL1;
1953 DRM_ERROR("unable to allocate a PPLL\n");
1954 return ATOM_PPLL_INVALID;
1955 } else if (ASIC_IS_DCE41(rdev)) {
1956
1957 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
1958 if (rdev->clock.dp_extclk)
1959
1960 return ATOM_PPLL_INVALID;
1961 }
1962 pll_in_use = radeon_get_pll_use_mask(crtc);
1963 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1964 return ATOM_PPLL1;
1965 if (!(pll_in_use & (1 << ATOM_PPLL2)))
1966 return ATOM_PPLL2;
1967 DRM_ERROR("unable to allocate a PPLL\n");
1968 return ATOM_PPLL_INVALID;
1969 } else if (ASIC_IS_DCE4(rdev)) {
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
1981 if (rdev->clock.dp_extclk)
1982
1983 return ATOM_PPLL_INVALID;
1984 else if (ASIC_IS_DCE6(rdev))
1985
1986 return ATOM_PPLL0;
1987 else if (ASIC_IS_DCE5(rdev))
1988
1989 return ATOM_DCPLL;
1990 else {
1991
1992 pll = radeon_get_shared_dp_ppll(crtc);
1993 if (pll != ATOM_PPLL_INVALID)
1994 return pll;
1995 }
1996 } else {
1997
1998 pll = radeon_get_shared_nondp_ppll(crtc);
1999 if (pll != ATOM_PPLL_INVALID)
2000 return pll;
2001 }
2002
2003 pll_in_use = radeon_get_pll_use_mask(crtc);
2004 if (!(pll_in_use & (1 << ATOM_PPLL1)))
2005 return ATOM_PPLL1;
2006 if (!(pll_in_use & (1 << ATOM_PPLL2)))
2007 return ATOM_PPLL2;
2008 DRM_ERROR("unable to allocate a PPLL\n");
2009 return ATOM_PPLL_INVALID;
2010 } else {
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026 return radeon_crtc->crtc_id;
2027 }
2028 }
2029
2030 void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
2031 {
2032
2033 if (ASIC_IS_DCE6(rdev))
2034 atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
2035 else if (ASIC_IS_DCE4(rdev)) {
2036 struct radeon_atom_ss ss;
2037 bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
2038 ASIC_INTERNAL_SS_ON_DCPLL,
2039 rdev->clock.default_dispclk);
2040 if (ss_enabled)
2041 atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss);
2042
2043 atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
2044 if (ss_enabled)
2045 atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss);
2046 }
2047
2048 }
2049
2050 int atombios_crtc_mode_set(struct drm_crtc *crtc,
2051 struct drm_display_mode *mode,
2052 struct drm_display_mode *adjusted_mode,
2053 int x, int y, struct drm_framebuffer *old_fb)
2054 {
2055 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
2056 struct drm_device *dev = crtc->dev;
2057 struct radeon_device *rdev = dev->dev_private;
2058 struct radeon_encoder *radeon_encoder =
2059 to_radeon_encoder(radeon_crtc->encoder);
2060 bool is_tvcv = false;
2061
2062 if (radeon_encoder->active_device &
2063 (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
2064 is_tvcv = true;
2065
2066 if (!radeon_crtc->adjusted_clock)
2067 return -EINVAL;
2068
2069 atombios_crtc_set_pll(crtc, adjusted_mode);
2070
2071 if (ASIC_IS_DCE4(rdev))
2072 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
2073 else if (ASIC_IS_AVIVO(rdev)) {
2074 if (is_tvcv)
2075 atombios_crtc_set_timing(crtc, adjusted_mode);
2076 else
2077 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
2078 } else {
2079 atombios_crtc_set_timing(crtc, adjusted_mode);
2080 if (radeon_crtc->crtc_id == 0)
2081 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
2082 radeon_legacy_atom_fixup(crtc);
2083 }
2084 atombios_crtc_set_base(crtc, x, y, old_fb);
2085 atombios_overscan_setup(crtc, mode, adjusted_mode);
2086 atombios_scaler_setup(crtc);
2087 radeon_cursor_reset(crtc);
2088
2089 radeon_crtc->hw_mode = *adjusted_mode;
2090
2091 return 0;
2092 }
2093
2094 static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
2095 const struct drm_display_mode *mode,
2096 struct drm_display_mode *adjusted_mode)
2097 {
2098 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
2099 struct drm_device *dev = crtc->dev;
2100 struct drm_encoder *encoder;
2101
2102
2103 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
2104 if (encoder->crtc == crtc) {
2105 radeon_crtc->encoder = encoder;
2106 radeon_crtc->connector = radeon_get_connector_for_encoder(encoder);
2107 break;
2108 }
2109 }
2110 if ((radeon_crtc->encoder == NULL) || (radeon_crtc->connector == NULL)) {
2111 radeon_crtc->encoder = NULL;
2112 radeon_crtc->connector = NULL;
2113 return false;
2114 }
2115 if (radeon_crtc->encoder) {
2116 struct radeon_encoder *radeon_encoder =
2117 to_radeon_encoder(radeon_crtc->encoder);
2118
2119 radeon_crtc->output_csc = radeon_encoder->output_csc;
2120 }
2121 if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
2122 return false;
2123 if (!atombios_crtc_prepare_pll(crtc, adjusted_mode))
2124 return false;
2125
2126 radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
2127
2128 if ((radeon_crtc->pll_id == ATOM_PPLL_INVALID) &&
2129 !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder)))
2130 return false;
2131
2132 return true;
2133 }
2134
2135 static void atombios_crtc_prepare(struct drm_crtc *crtc)
2136 {
2137 struct drm_device *dev = crtc->dev;
2138 struct radeon_device *rdev = dev->dev_private;
2139
2140
2141 if (ASIC_IS_DCE6(rdev))
2142 atombios_powergate_crtc(crtc, ATOM_DISABLE);
2143
2144 atombios_lock_crtc(crtc, ATOM_ENABLE);
2145 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
2146 }
2147
2148 static void atombios_crtc_commit(struct drm_crtc *crtc)
2149 {
2150 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
2151 atombios_lock_crtc(crtc, ATOM_DISABLE);
2152 }
2153
2154 static void atombios_crtc_disable(struct drm_crtc *crtc)
2155 {
2156 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
2157 struct drm_device *dev = crtc->dev;
2158 struct radeon_device *rdev = dev->dev_private;
2159 struct radeon_atom_ss ss;
2160 int i;
2161
2162 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
2163 if (crtc->primary->fb) {
2164 int r;
2165 struct radeon_bo *rbo;
2166
2167 rbo = gem_to_radeon_bo(crtc->primary->fb->obj[0]);
2168 r = radeon_bo_reserve(rbo, false);
2169 if (unlikely(r))
2170 DRM_ERROR("failed to reserve rbo before unpin\n");
2171 else {
2172 radeon_bo_unpin(rbo);
2173 radeon_bo_unreserve(rbo);
2174 }
2175 }
2176
2177 if (ASIC_IS_DCE4(rdev))
2178 WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 0);
2179 else if (ASIC_IS_AVIVO(rdev))
2180 WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 0);
2181
2182 if (ASIC_IS_DCE6(rdev))
2183 atombios_powergate_crtc(crtc, ATOM_ENABLE);
2184
2185 for (i = 0; i < rdev->num_crtc; i++) {
2186 if (rdev->mode_info.crtcs[i] &&
2187 rdev->mode_info.crtcs[i]->enabled &&
2188 i != radeon_crtc->crtc_id &&
2189 radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) {
2190
2191
2192
2193 goto done;
2194 }
2195 }
2196
2197 switch (radeon_crtc->pll_id) {
2198 case ATOM_PPLL1:
2199 case ATOM_PPLL2:
2200
2201 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
2202 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
2203 break;
2204 case ATOM_PPLL0:
2205
2206 if ((rdev->family == CHIP_ARUBA) ||
2207 (rdev->family == CHIP_KAVERI) ||
2208 (rdev->family == CHIP_BONAIRE) ||
2209 (rdev->family == CHIP_HAWAII))
2210 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
2211 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
2212 break;
2213 default:
2214 break;
2215 }
2216 done:
2217 radeon_crtc->pll_id = ATOM_PPLL_INVALID;
2218 radeon_crtc->adjusted_clock = 0;
2219 radeon_crtc->encoder = NULL;
2220 radeon_crtc->connector = NULL;
2221 }
2222
2223 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
2224 .dpms = atombios_crtc_dpms,
2225 .mode_fixup = atombios_crtc_mode_fixup,
2226 .mode_set = atombios_crtc_mode_set,
2227 .mode_set_base = atombios_crtc_set_base,
2228 .mode_set_base_atomic = atombios_crtc_set_base_atomic,
2229 .prepare = atombios_crtc_prepare,
2230 .commit = atombios_crtc_commit,
2231 .disable = atombios_crtc_disable,
2232 .get_scanout_position = radeon_get_crtc_scanout_position,
2233 };
2234
2235 void radeon_atombios_init_crtc(struct drm_device *dev,
2236 struct radeon_crtc *radeon_crtc)
2237 {
2238 struct radeon_device *rdev = dev->dev_private;
2239
2240 if (ASIC_IS_DCE4(rdev)) {
2241 switch (radeon_crtc->crtc_id) {
2242 case 0:
2243 default:
2244 radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
2245 break;
2246 case 1:
2247 radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
2248 break;
2249 case 2:
2250 radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
2251 break;
2252 case 3:
2253 radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
2254 break;
2255 case 4:
2256 radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
2257 break;
2258 case 5:
2259 radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
2260 break;
2261 }
2262 } else {
2263 if (radeon_crtc->crtc_id == 1)
2264 radeon_crtc->crtc_offset =
2265 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
2266 else
2267 radeon_crtc->crtc_offset = 0;
2268 }
2269 radeon_crtc->pll_id = ATOM_PPLL_INVALID;
2270 radeon_crtc->adjusted_clock = 0;
2271 radeon_crtc->encoder = NULL;
2272 radeon_crtc->connector = NULL;
2273 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
2274 }