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 <drm/drmP.h> 27 #include <drm/drm_crtc_helper.h> 28 #include <drm/radeon_drm.h> 29 #include "radeon_fixed.h" 30 #include "radeon.h" 31 #include "atom.h" 32 #include "atom-bits.h" 33 34 static void atombios_overscan_setup(struct drm_crtc *crtc, 35 struct drm_display_mode *mode, 36 struct drm_display_mode *adjusted_mode) 37 { 38 struct drm_device *dev = crtc->dev; 39 struct radeon_device *rdev = dev->dev_private; 40 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 41 SET_CRTC_OVERSCAN_PS_ALLOCATION args; 42 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan); 43 int a1, a2; 44 45 memset(&args, 0, sizeof(args)); 46 47 args.usOverscanRight = 0; 48 args.usOverscanLeft = 0; 49 args.usOverscanBottom = 0; 50 args.usOverscanTop = 0; 51 args.ucCRTC = radeon_crtc->crtc_id; 52 53 switch (radeon_crtc->rmx_type) { 54 case RMX_CENTER: 55 args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; 56 args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; 57 args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; 58 args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; 59 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 60 break; 61 case RMX_ASPECT: 62 a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; 63 a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; 64 65 if (a1 > a2) { 66 args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; 67 args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; 68 } else if (a2 > a1) { 69 args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; 70 args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; 71 } 72 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 73 break; 74 case RMX_FULL: 75 default: 76 args.usOverscanRight = 0; 77 args.usOverscanLeft = 0; 78 args.usOverscanBottom = 0; 79 args.usOverscanTop = 0; 80 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 81 break; 82 } 83 } 84 85 static void atombios_scaler_setup(struct drm_crtc *crtc) 86 { 87 struct drm_device *dev = crtc->dev; 88 struct radeon_device *rdev = dev->dev_private; 89 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 90 ENABLE_SCALER_PS_ALLOCATION args; 91 int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); 92 93 /* fixme - fill in enc_priv for atom dac */ 94 enum radeon_tv_std tv_std = TV_STD_NTSC; 95 bool is_tv = false, is_cv = false; 96 struct drm_encoder *encoder; 97 98 if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) 99 return; 100 101 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 102 /* find tv std */ 103 if (encoder->crtc == crtc) { 104 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 105 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { 106 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; 107 tv_std = tv_dac->tv_std; 108 is_tv = true; 109 } 110 } 111 } 112 113 memset(&args, 0, sizeof(args)); 114 115 args.ucScaler = radeon_crtc->crtc_id; 116 117 if (is_tv) { 118 switch (tv_std) { 119 case TV_STD_NTSC: 120 default: 121 args.ucTVStandard = ATOM_TV_NTSC; 122 break; 123 case TV_STD_PAL: 124 args.ucTVStandard = ATOM_TV_PAL; 125 break; 126 case TV_STD_PAL_M: 127 args.ucTVStandard = ATOM_TV_PALM; 128 break; 129 case TV_STD_PAL_60: 130 args.ucTVStandard = ATOM_TV_PAL60; 131 break; 132 case TV_STD_NTSC_J: 133 args.ucTVStandard = ATOM_TV_NTSCJ; 134 break; 135 case TV_STD_SCART_PAL: 136 args.ucTVStandard = ATOM_TV_PAL; /* ??? */ 137 break; 138 case TV_STD_SECAM: 139 args.ucTVStandard = ATOM_TV_SECAM; 140 break; 141 case TV_STD_PAL_CN: 142 args.ucTVStandard = ATOM_TV_PALCN; 143 break; 144 } 145 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; 146 } else if (is_cv) { 147 args.ucTVStandard = ATOM_TV_CV; 148 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; 149 } else { 150 switch (radeon_crtc->rmx_type) { 151 case RMX_FULL: 152 args.ucEnable = ATOM_SCALER_EXPANSION; 153 break; 154 case RMX_CENTER: 155 args.ucEnable = ATOM_SCALER_CENTER; 156 break; 157 case RMX_ASPECT: 158 args.ucEnable = ATOM_SCALER_EXPANSION; 159 break; 160 default: 161 if (ASIC_IS_AVIVO(rdev)) 162 args.ucEnable = ATOM_SCALER_DISABLE; 163 else 164 args.ucEnable = ATOM_SCALER_CENTER; 165 break; 166 } 167 } 168 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 169 if ((is_tv || is_cv) 170 && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) { 171 atom_rv515_force_tv_scaler(rdev, radeon_crtc); 172 } 173 } 174 175 static void atombios_lock_crtc(struct drm_crtc *crtc, int lock) 176 { 177 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 178 struct drm_device *dev = crtc->dev; 179 struct radeon_device *rdev = dev->dev_private; 180 int index = 181 GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters); 182 ENABLE_CRTC_PS_ALLOCATION args; 183 184 memset(&args, 0, sizeof(args)); 185 186 args.ucCRTC = radeon_crtc->crtc_id; 187 args.ucEnable = lock; 188 189 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 190 } 191 192 static void atombios_enable_crtc(struct drm_crtc *crtc, int state) 193 { 194 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 195 struct drm_device *dev = crtc->dev; 196 struct radeon_device *rdev = dev->dev_private; 197 int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC); 198 ENABLE_CRTC_PS_ALLOCATION args; 199 200 memset(&args, 0, sizeof(args)); 201 202 args.ucCRTC = radeon_crtc->crtc_id; 203 args.ucEnable = state; 204 205 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 206 } 207 208 static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state) 209 { 210 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 211 struct drm_device *dev = crtc->dev; 212 struct radeon_device *rdev = dev->dev_private; 213 int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq); 214 ENABLE_CRTC_PS_ALLOCATION args; 215 216 memset(&args, 0, sizeof(args)); 217 218 args.ucCRTC = radeon_crtc->crtc_id; 219 args.ucEnable = state; 220 221 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 222 } 223 224 static void atombios_blank_crtc(struct drm_crtc *crtc, int state) 225 { 226 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 227 struct drm_device *dev = crtc->dev; 228 struct radeon_device *rdev = dev->dev_private; 229 int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC); 230 BLANK_CRTC_PS_ALLOCATION args; 231 232 memset(&args, 0, sizeof(args)); 233 234 args.ucCRTC = radeon_crtc->crtc_id; 235 args.ucBlanking = state; 236 237 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 238 } 239 240 void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) 241 { 242 struct drm_device *dev = crtc->dev; 243 struct radeon_device *rdev = dev->dev_private; 244 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 245 246 switch (mode) { 247 case DRM_MODE_DPMS_ON: 248 atombios_enable_crtc(crtc, 1); 249 if (ASIC_IS_DCE3(rdev)) 250 atombios_enable_crtc_memreq(crtc, 1); 251 atombios_blank_crtc(crtc, 0); 252 drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); 253 radeon_crtc_load_lut(crtc); 254 break; 255 case DRM_MODE_DPMS_STANDBY: 256 case DRM_MODE_DPMS_SUSPEND: 257 case DRM_MODE_DPMS_OFF: 258 drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); 259 atombios_blank_crtc(crtc, 1); 260 if (ASIC_IS_DCE3(rdev)) 261 atombios_enable_crtc_memreq(crtc, 0); 262 atombios_enable_crtc(crtc, 0); 263 break; 264 } 265 } 266 267 static void 268 atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, 269 struct drm_display_mode *mode) 270 { 271 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 272 struct drm_device *dev = crtc->dev; 273 struct radeon_device *rdev = dev->dev_private; 274 SET_CRTC_USING_DTD_TIMING_PARAMETERS args; 275 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); 276 u16 misc = 0; 277 278 memset(&args, 0, sizeof(args)); 279 args.usH_Size = cpu_to_le16(mode->crtc_hdisplay); 280 args.usH_Blanking_Time = 281 cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay); 282 args.usV_Size = cpu_to_le16(mode->crtc_vdisplay); 283 args.usV_Blanking_Time = 284 cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay); 285 args.usH_SyncOffset = 286 cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay); 287 args.usH_SyncWidth = 288 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); 289 args.usV_SyncOffset = 290 cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay); 291 args.usV_SyncWidth = 292 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); 293 /*args.ucH_Border = mode->hborder;*/ 294 /*args.ucV_Border = mode->vborder;*/ 295 296 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 297 misc |= ATOM_VSYNC_POLARITY; 298 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 299 misc |= ATOM_HSYNC_POLARITY; 300 if (mode->flags & DRM_MODE_FLAG_CSYNC) 301 misc |= ATOM_COMPOSITESYNC; 302 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 303 misc |= ATOM_INTERLACE; 304 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 305 misc |= ATOM_DOUBLE_CLOCK_MODE; 306 307 args.susModeMiscInfo.usAccess = cpu_to_le16(misc); 308 args.ucCRTC = radeon_crtc->crtc_id; 309 310 printk("executing set crtc dtd timing\n"); 311 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 312 } 313 314 static void atombios_crtc_set_timing(struct drm_crtc *crtc, 315 struct drm_display_mode *mode) 316 { 317 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 318 struct drm_device *dev = crtc->dev; 319 struct radeon_device *rdev = dev->dev_private; 320 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args; 321 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); 322 u16 misc = 0; 323 324 memset(&args, 0, sizeof(args)); 325 args.usH_Total = cpu_to_le16(mode->crtc_htotal); 326 args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay); 327 args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start); 328 args.usH_SyncWidth = 329 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); 330 args.usV_Total = cpu_to_le16(mode->crtc_vtotal); 331 args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay); 332 args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start); 333 args.usV_SyncWidth = 334 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); 335 336 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 337 misc |= ATOM_VSYNC_POLARITY; 338 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 339 misc |= ATOM_HSYNC_POLARITY; 340 if (mode->flags & DRM_MODE_FLAG_CSYNC) 341 misc |= ATOM_COMPOSITESYNC; 342 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 343 misc |= ATOM_INTERLACE; 344 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 345 misc |= ATOM_DOUBLE_CLOCK_MODE; 346 347 args.susModeMiscInfo.usAccess = cpu_to_le16(misc); 348 args.ucCRTC = radeon_crtc->crtc_id; 349 350 printk("executing set crtc timing\n"); 351 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 352 } 353 354 static void atombios_set_ss(struct drm_crtc *crtc, int enable) 355 { 356 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 357 struct drm_device *dev = crtc->dev; 358 struct radeon_device *rdev = dev->dev_private; 359 struct drm_encoder *encoder = NULL; 360 struct radeon_encoder *radeon_encoder = NULL; 361 struct radeon_encoder_atom_dig *dig = NULL; 362 int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); 363 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args; 364 ENABLE_LVDS_SS_PARAMETERS legacy_args; 365 uint16_t percentage = 0; 366 uint8_t type = 0, step = 0, delay = 0, range = 0; 367 368 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 369 if (encoder->crtc == crtc) { 370 radeon_encoder = to_radeon_encoder(encoder); 371 /* only enable spread spectrum on LVDS */ 372 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 373 dig = radeon_encoder->enc_priv; 374 if (dig && dig->ss) { 375 percentage = dig->ss->percentage; 376 type = dig->ss->type; 377 step = dig->ss->step; 378 delay = dig->ss->delay; 379 range = dig->ss->range; 380 } else if (enable) 381 return; 382 } else if (enable) 383 return; 384 break; 385 } 386 } 387 388 if (!radeon_encoder) 389 return; 390 391 if (ASIC_IS_AVIVO(rdev)) { 392 memset(&args, 0, sizeof(args)); 393 args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); 394 args.ucSpreadSpectrumType = type; 395 args.ucSpreadSpectrumStep = step; 396 args.ucSpreadSpectrumDelay = delay; 397 args.ucSpreadSpectrumRange = range; 398 args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 399 args.ucEnable = enable; 400 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 401 } else { 402 memset(&legacy_args, 0, sizeof(legacy_args)); 403 legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); 404 legacy_args.ucSpreadSpectrumType = type; 405 legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; 406 legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; 407 legacy_args.ucEnable = enable; 408 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args); 409 } 410 } 411 412 void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) 413 { 414 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 415 struct drm_device *dev = crtc->dev; 416 struct radeon_device *rdev = dev->dev_private; 417 struct drm_encoder *encoder = NULL; 418 struct radeon_encoder *radeon_encoder = NULL; 419 uint8_t frev, crev; 420 int index; 421 SET_PIXEL_CLOCK_PS_ALLOCATION args; 422 PIXEL_CLOCK_PARAMETERS *spc1_ptr; 423 PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; 424 PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; 425 uint32_t pll_clock = mode->clock; 426 uint32_t adjusted_clock; 427 uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; 428 struct radeon_pll *pll; 429 int pll_flags = 0; 430 431 memset(&args, 0, sizeof(args)); 432 433 if (ASIC_IS_AVIVO(rdev)) { 434 if ((rdev->family == CHIP_RS600) || 435 (rdev->family == CHIP_RS690) || 436 (rdev->family == CHIP_RS740)) 437 pll_flags |= (RADEON_PLL_USE_FRAC_FB_DIV | 438 RADEON_PLL_PREFER_CLOSEST_LOWER); 439 440 if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ 441 pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; 442 else 443 pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; 444 } else { 445 pll_flags |= RADEON_PLL_LEGACY; 446 447 if (mode->clock > 200000) /* range limits??? */ 448 pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; 449 else 450 pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; 451 452 } 453 454 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 455 if (encoder->crtc == crtc) { 456 if (!ASIC_IS_AVIVO(rdev)) { 457 if (encoder->encoder_type != 458 DRM_MODE_ENCODER_DAC) 459 pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; 460 if (encoder->encoder_type == 461 DRM_MODE_ENCODER_LVDS) 462 pll_flags |= RADEON_PLL_USE_REF_DIV; 463 } 464 radeon_encoder = to_radeon_encoder(encoder); 465 break; 466 } 467 } 468 469 /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock 470 * accordingly based on the encoder/transmitter to work around 471 * special hw requirements. 472 */ 473 if (ASIC_IS_DCE3(rdev)) { 474 ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args; 475 476 if (!encoder) 477 return; 478 479 memset(&adjust_pll_args, 0, sizeof(adjust_pll_args)); 480 adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10); 481 adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id; 482 adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder); 483 484 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); 485 atom_execute_table(rdev->mode_info.atom_context, 486 index, (uint32_t *)&adjust_pll_args); 487 adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10; 488 } else { 489 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ 490 if (ASIC_IS_AVIVO(rdev) && 491 (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)) 492 adjusted_clock = mode->clock * 2; 493 else 494 adjusted_clock = mode->clock; 495 } 496 497 if (radeon_crtc->crtc_id == 0) 498 pll = &rdev->clock.p1pll; 499 else 500 pll = &rdev->clock.p2pll; 501 502 if (ASIC_IS_AVIVO(rdev)) { 503 if (radeon_new_pll) 504 radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, 505 &fb_div, &frac_fb_div, 506 &ref_div, &post_div, pll_flags); 507 else 508 radeon_compute_pll(pll, adjusted_clock, &pll_clock, 509 &fb_div, &frac_fb_div, 510 &ref_div, &post_div, pll_flags); 511 } else 512 radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, 513 &ref_div, &post_div, pll_flags); 514 515 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); 516 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 517 &crev); 518 519 switch (frev) { 520 case 1: 521 switch (crev) { 522 case 1: 523 spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; 524 spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); 525 spc1_ptr->usRefDiv = cpu_to_le16(ref_div); 526 spc1_ptr->usFbDiv = cpu_to_le16(fb_div); 527 spc1_ptr->ucFracFbDiv = frac_fb_div; 528 spc1_ptr->ucPostDiv = post_div; 529 spc1_ptr->ucPpll = 530 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 531 spc1_ptr->ucCRTC = radeon_crtc->crtc_id; 532 spc1_ptr->ucRefDivSrc = 1; 533 break; 534 case 2: 535 spc2_ptr = 536 (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; 537 spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); 538 spc2_ptr->usRefDiv = cpu_to_le16(ref_div); 539 spc2_ptr->usFbDiv = cpu_to_le16(fb_div); 540 spc2_ptr->ucFracFbDiv = frac_fb_div; 541 spc2_ptr->ucPostDiv = post_div; 542 spc2_ptr->ucPpll = 543 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 544 spc2_ptr->ucCRTC = radeon_crtc->crtc_id; 545 spc2_ptr->ucRefDivSrc = 1; 546 break; 547 case 3: 548 if (!encoder) 549 return; 550 spc3_ptr = 551 (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; 552 spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); 553 spc3_ptr->usRefDiv = cpu_to_le16(ref_div); 554 spc3_ptr->usFbDiv = cpu_to_le16(fb_div); 555 spc3_ptr->ucFracFbDiv = frac_fb_div; 556 spc3_ptr->ucPostDiv = post_div; 557 spc3_ptr->ucPpll = 558 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 559 spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2); 560 spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id; 561 spc3_ptr->ucEncoderMode = 562 atombios_get_encoder_mode(encoder); 563 break; 564 default: 565 DRM_ERROR("Unknown table version %d %d\n", frev, crev); 566 return; 567 } 568 break; 569 default: 570 DRM_ERROR("Unknown table version %d %d\n", frev, crev); 571 return; 572 } 573 574 printk("executing set pll\n"); 575 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 576 } 577 578 int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, 579 struct drm_framebuffer *old_fb) 580 { 581 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 582 struct drm_device *dev = crtc->dev; 583 struct radeon_device *rdev = dev->dev_private; 584 struct radeon_framebuffer *radeon_fb; 585 struct drm_gem_object *obj; 586 struct radeon_bo *rbo; 587 uint64_t fb_location; 588 uint32_t fb_format, fb_pitch_pixels, tiling_flags; 589 int r; 590 591 /* no fb bound */ 592 if (!crtc->fb) { 593 DRM_DEBUG("No FB bound\n"); 594 return 0; 595 } 596 597 radeon_fb = to_radeon_framebuffer(crtc->fb); 598 599 /* Pin framebuffer & get tilling informations */ 600 obj = radeon_fb->obj; 601 rbo = obj->driver_private; 602 r = radeon_bo_reserve(rbo, false); 603 if (unlikely(r != 0)) 604 return r; 605 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); 606 if (unlikely(r != 0)) { 607 radeon_bo_unreserve(rbo); 608 return -EINVAL; 609 } 610 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); 611 radeon_bo_unreserve(rbo); 612 613 switch (crtc->fb->bits_per_pixel) { 614 case 8: 615 fb_format = 616 AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | 617 AVIVO_D1GRPH_CONTROL_8BPP_INDEXED; 618 break; 619 case 15: 620 fb_format = 621 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | 622 AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555; 623 break; 624 case 16: 625 fb_format = 626 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | 627 AVIVO_D1GRPH_CONTROL_16BPP_RGB565; 628 break; 629 case 24: 630 case 32: 631 fb_format = 632 AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | 633 AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; 634 break; 635 default: 636 DRM_ERROR("Unsupported screen depth %d\n", 637 crtc->fb->bits_per_pixel); 638 return -EINVAL; 639 } 640 641 if (tiling_flags & RADEON_TILING_MACRO) 642 fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; 643 644 if (tiling_flags & RADEON_TILING_MICRO) 645 fb_format |= AVIVO_D1GRPH_TILED; 646 647 if (radeon_crtc->crtc_id == 0) 648 WREG32(AVIVO_D1VGA_CONTROL, 0); 649 else 650 WREG32(AVIVO_D2VGA_CONTROL, 0); 651 652 if (rdev->family >= CHIP_RV770) { 653 if (radeon_crtc->crtc_id) { 654 WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); 655 WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); 656 } else { 657 WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); 658 WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); 659 } 660 } 661 WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, 662 (u32) fb_location); 663 WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + 664 radeon_crtc->crtc_offset, (u32) fb_location); 665 WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); 666 667 WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); 668 WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); 669 WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); 670 WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); 671 WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); 672 WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); 673 674 fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); 675 WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); 676 WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); 677 678 WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, 679 crtc->mode.vdisplay); 680 x &= ~3; 681 y &= ~1; 682 WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, 683 (x << 16) | y); 684 WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, 685 (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); 686 687 if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) 688 WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 689 AVIVO_D1MODE_INTERLEAVE_EN); 690 else 691 WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); 692 693 if (old_fb && old_fb != crtc->fb) { 694 radeon_fb = to_radeon_framebuffer(old_fb); 695 rbo = radeon_fb->obj->driver_private; 696 r = radeon_bo_reserve(rbo, false); 697 if (unlikely(r != 0)) 698 return r; 699 radeon_bo_unpin(rbo); 700 radeon_bo_unreserve(rbo); 701 } 702 703 /* Bytes per pixel may have changed */ 704 radeon_bandwidth_update(rdev); 705 706 return 0; 707 } 708 709 int atombios_crtc_mode_set(struct drm_crtc *crtc, 710 struct drm_display_mode *mode, 711 struct drm_display_mode *adjusted_mode, 712 int x, int y, struct drm_framebuffer *old_fb) 713 { 714 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 715 struct drm_device *dev = crtc->dev; 716 struct radeon_device *rdev = dev->dev_private; 717 718 /* TODO color tiling */ 719 720 atombios_set_ss(crtc, 0); 721 atombios_crtc_set_pll(crtc, adjusted_mode); 722 atombios_set_ss(crtc, 1); 723 atombios_crtc_set_timing(crtc, adjusted_mode); 724 725 if (ASIC_IS_AVIVO(rdev)) 726 atombios_crtc_set_base(crtc, x, y, old_fb); 727 else { 728 if (radeon_crtc->crtc_id == 0) 729 atombios_set_crtc_dtd_timing(crtc, adjusted_mode); 730 radeon_crtc_set_base(crtc, x, y, old_fb); 731 radeon_legacy_atom_set_surface(crtc); 732 } 733 atombios_overscan_setup(crtc, mode, adjusted_mode); 734 atombios_scaler_setup(crtc); 735 return 0; 736 } 737 738 static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, 739 struct drm_display_mode *mode, 740 struct drm_display_mode *adjusted_mode) 741 { 742 if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) 743 return false; 744 return true; 745 } 746 747 static void atombios_crtc_prepare(struct drm_crtc *crtc) 748 { 749 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 750 atombios_lock_crtc(crtc, 1); 751 } 752 753 static void atombios_crtc_commit(struct drm_crtc *crtc) 754 { 755 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 756 atombios_lock_crtc(crtc, 0); 757 } 758 759 static const struct drm_crtc_helper_funcs atombios_helper_funcs = { 760 .dpms = atombios_crtc_dpms, 761 .mode_fixup = atombios_crtc_mode_fixup, 762 .mode_set = atombios_crtc_mode_set, 763 .mode_set_base = atombios_crtc_set_base, 764 .prepare = atombios_crtc_prepare, 765 .commit = atombios_crtc_commit, 766 .load_lut = radeon_crtc_load_lut, 767 }; 768 769 void radeon_atombios_init_crtc(struct drm_device *dev, 770 struct radeon_crtc *radeon_crtc) 771 { 772 if (radeon_crtc->crtc_id == 1) 773 radeon_crtc->crtc_offset = 774 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; 775 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); 776 } 777