Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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