Rev 2160 | Rev 3031 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2160 | Rev 2997 | ||
---|---|---|---|
Line 81... | Line 81... | ||
81 | struct drm_device *dev = crtc->dev; |
81 | struct drm_device *dev = crtc->dev; |
82 | struct radeon_device *rdev = dev->dev_private; |
82 | struct radeon_device *rdev = dev->dev_private; |
83 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
83 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
84 | ENABLE_SCALER_PS_ALLOCATION args; |
84 | ENABLE_SCALER_PS_ALLOCATION args; |
85 | int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); |
85 | int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); |
86 | - | ||
- | 86 | struct radeon_encoder *radeon_encoder = |
|
- | 87 | to_radeon_encoder(radeon_crtc->encoder); |
|
87 | /* fixme - fill in enc_priv for atom dac */ |
88 | /* fixme - fill in enc_priv for atom dac */ |
88 | enum radeon_tv_std tv_std = TV_STD_NTSC; |
89 | enum radeon_tv_std tv_std = TV_STD_NTSC; |
89 | bool is_tv = false, is_cv = false; |
90 | bool is_tv = false, is_cv = false; |
90 | struct drm_encoder *encoder; |
- | |
Line 91... | Line 91... | ||
91 | 91 | ||
92 | if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) |
92 | if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) |
Line 93... | Line -... | ||
93 | return; |
- | |
94 | - | ||
95 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
- | |
96 | /* find tv std */ |
- | |
97 | if (encoder->crtc == crtc) { |
93 | return; |
98 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
94 | |
99 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { |
95 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { |
100 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
96 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
101 | tv_std = tv_dac->tv_std; |
97 | tv_std = tv_dac->tv_std; |
102 | is_tv = true; |
- | |
103 | } |
- | |
Line 104... | Line 98... | ||
104 | } |
98 | is_tv = true; |
Line 105... | Line 99... | ||
105 | } |
99 | } |
Line 229... | Line 223... | ||
229 | args.ucBlanking = state; |
223 | args.ucBlanking = state; |
Line 230... | Line 224... | ||
230 | 224 | ||
231 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
225 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
Line -... | Line 226... | ||
- | 226 | } |
|
- | 227 | ||
- | 228 | static void atombios_powergate_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, EnableDispPowerGating); |
|
- | 234 | ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args; |
|
- | 235 | ||
- | 236 | memset(&args, 0, sizeof(args)); |
|
- | 237 | ||
- | 238 | args.ucDispPipeId = radeon_crtc->crtc_id; |
|
- | 239 | args.ucEnable = state; |
|
- | 240 | ||
- | 241 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
232 | } |
242 | } |
233 | 243 | ||
234 | void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) |
244 | void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) |
235 | { |
245 | { |
236 | struct drm_device *dev = crtc->dev; |
246 | struct drm_device *dev = crtc->dev; |
Line 240... | Line 250... | ||
240 | switch (mode) { |
250 | switch (mode) { |
241 | case DRM_MODE_DPMS_ON: |
251 | case DRM_MODE_DPMS_ON: |
242 | radeon_crtc->enabled = true; |
252 | radeon_crtc->enabled = true; |
243 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
253 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
244 | radeon_pm_compute_clocks(rdev); |
254 | radeon_pm_compute_clocks(rdev); |
- | 255 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
|
- | 256 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
|
245 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
257 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
246 | if (ASIC_IS_DCE3(rdev)) |
258 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
247 | atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); |
259 | atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); |
248 | atombios_blank_crtc(crtc, ATOM_DISABLE); |
260 | atombios_blank_crtc(crtc, ATOM_DISABLE); |
249 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); |
261 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); |
250 | radeon_crtc_load_lut(crtc); |
262 | radeon_crtc_load_lut(crtc); |
251 | break; |
263 | break; |
252 | case DRM_MODE_DPMS_STANDBY: |
264 | case DRM_MODE_DPMS_STANDBY: |
253 | case DRM_MODE_DPMS_SUSPEND: |
265 | case DRM_MODE_DPMS_SUSPEND: |
254 | case DRM_MODE_DPMS_OFF: |
266 | case DRM_MODE_DPMS_OFF: |
255 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); |
267 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); |
256 | if (radeon_crtc->enabled) |
268 | if (radeon_crtc->enabled) |
257 | atombios_blank_crtc(crtc, ATOM_ENABLE); |
269 | atombios_blank_crtc(crtc, ATOM_ENABLE); |
258 | if (ASIC_IS_DCE3(rdev)) |
270 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
259 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); |
271 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); |
260 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
272 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
261 | radeon_crtc->enabled = false; |
273 | radeon_crtc->enabled = false; |
- | 274 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
|
- | 275 | atombios_powergate_crtc(crtc, ATOM_ENABLE); |
|
262 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
276 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
263 | radeon_pm_compute_clocks(rdev); |
277 | radeon_pm_compute_clocks(rdev); |
264 | break; |
278 | break; |
265 | } |
279 | } |
266 | } |
280 | } |
Line 353... | Line 367... | ||
353 | args.ucCRTC = radeon_crtc->crtc_id; |
367 | args.ucCRTC = radeon_crtc->crtc_id; |
Line 354... | Line 368... | ||
354 | 368 | ||
355 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
369 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
Line 356... | Line 370... | ||
356 | } |
370 | } |
357 | 371 | ||
358 | static void atombios_disable_ss(struct drm_crtc *crtc) |
- | |
359 | { |
- | |
360 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
- | |
361 | struct drm_device *dev = crtc->dev; |
372 | static void atombios_disable_ss(struct radeon_device *rdev, int pll_id) |
Line 362... | Line 373... | ||
362 | struct radeon_device *rdev = dev->dev_private; |
373 | { |
363 | u32 ss_cntl; |
374 | u32 ss_cntl; |
364 | 375 | ||
365 | if (ASIC_IS_DCE4(rdev)) { |
376 | if (ASIC_IS_DCE4(rdev)) { |
366 | switch (radeon_crtc->pll_id) { |
377 | switch (pll_id) { |
367 | case ATOM_PPLL1: |
378 | case ATOM_PPLL1: |
368 | ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); |
379 | ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); |
Line 377... | Line 388... | ||
377 | case ATOM_DCPLL: |
388 | case ATOM_DCPLL: |
378 | case ATOM_PPLL_INVALID: |
389 | case ATOM_PPLL_INVALID: |
379 | return; |
390 | return; |
380 | } |
391 | } |
381 | } else if (ASIC_IS_AVIVO(rdev)) { |
392 | } else if (ASIC_IS_AVIVO(rdev)) { |
382 | switch (radeon_crtc->pll_id) { |
393 | switch (pll_id) { |
383 | case ATOM_PPLL1: |
394 | case ATOM_PPLL1: |
384 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); |
395 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); |
385 | ss_cntl &= ~1; |
396 | ss_cntl &= ~1; |
386 | WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl); |
397 | WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl); |
387 | break; |
398 | break; |
Line 404... | Line 415... | ||
404 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; |
415 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; |
405 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2; |
416 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2; |
406 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; |
417 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; |
407 | }; |
418 | }; |
Line 408... | Line 419... | ||
408 | 419 | ||
409 | static void atombios_crtc_program_ss(struct drm_crtc *crtc, |
420 | static void atombios_crtc_program_ss(struct radeon_device *rdev, |
410 | int enable, |
421 | int enable, |
- | 422 | int pll_id, |
|
411 | int pll_id, |
423 | int crtc_id, |
412 | struct radeon_atom_ss *ss) |
424 | struct radeon_atom_ss *ss) |
413 | { |
425 | { |
414 | struct drm_device *dev = crtc->dev; |
- | |
415 | struct radeon_device *rdev = dev->dev_private; |
426 | unsigned i; |
416 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); |
427 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); |
Line -... | Line 428... | ||
- | 428 | union atom_enable_ss args; |
|
- | 429 | ||
- | 430 | if (!enable) { |
|
- | 431 | for (i = 0; i < rdev->num_crtc; i++) { |
|
- | 432 | if (rdev->mode_info.crtcs[i] && |
|
- | 433 | rdev->mode_info.crtcs[i]->enabled && |
|
- | 434 | i != crtc_id && |
|
- | 435 | pll_id == rdev->mode_info.crtcs[i]->pll_id) { |
|
- | 436 | /* one other crtc is using this pll don't turn |
|
- | 437 | * off spread spectrum as it might turn off |
|
- | 438 | * display on active crtc |
|
- | 439 | */ |
|
- | 440 | return; |
|
- | 441 | } |
|
- | 442 | } |
|
417 | union atom_enable_ss args; |
443 | } |
Line 418... | Line 444... | ||
418 | 444 | ||
419 | memset(&args, 0, sizeof(args)); |
445 | memset(&args, 0, sizeof(args)); |
420 | 446 | ||
421 | if (ASIC_IS_DCE5(rdev)) { |
447 | if (ASIC_IS_DCE5(rdev)) { |
422 | args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0); |
448 | args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0); |
423 | args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; |
449 | args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; |
424 | switch (pll_id) { |
- | |
425 | case ATOM_PPLL1: |
- | |
426 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; |
450 | switch (pll_id) { |
427 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
451 | case ATOM_PPLL1: |
428 | args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
452 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; |
429 | break; |
- | |
430 | case ATOM_PPLL2: |
- | |
431 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; |
453 | break; |
432 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
454 | case ATOM_PPLL2: |
433 | args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
455 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; |
434 | break; |
- | |
435 | case ATOM_DCPLL: |
- | |
436 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; |
456 | break; |
437 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(0); |
457 | case ATOM_DCPLL: |
438 | args.v3.usSpreadSpectrumStep = cpu_to_le16(0); |
458 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; |
439 | break; |
459 | break; |
- | 460 | case ATOM_PPLL_INVALID: |
|
- | 461 | return; |
|
440 | case ATOM_PPLL_INVALID: |
462 | } |
441 | return; |
463 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
442 | } |
464 | args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
443 | args.v3.ucEnable = enable; |
465 | args.v3.ucEnable = enable; |
444 | if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK)) |
466 | if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE61(rdev)) |
445 | args.v3.ucEnable = ATOM_DISABLE; |
467 | args.v3.ucEnable = ATOM_DISABLE; |
446 | } else if (ASIC_IS_DCE4(rdev)) { |
468 | } else if (ASIC_IS_DCE4(rdev)) { |
447 | args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
469 | args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
448 | args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; |
470 | args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; |
449 | switch (pll_id) { |
- | |
450 | case ATOM_PPLL1: |
- | |
451 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; |
471 | switch (pll_id) { |
452 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
472 | case ATOM_PPLL1: |
453 | args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
473 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; |
454 | break; |
- | |
455 | case ATOM_PPLL2: |
- | |
456 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; |
474 | break; |
457 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
475 | case ATOM_PPLL2: |
458 | args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
476 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; |
459 | break; |
- | |
460 | case ATOM_DCPLL: |
- | |
461 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; |
477 | break; |
462 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(0); |
478 | case ATOM_DCPLL: |
463 | args.v2.usSpreadSpectrumStep = cpu_to_le16(0); |
479 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; |
464 | break; |
480 | break; |
- | 481 | case ATOM_PPLL_INVALID: |
|
- | 482 | return; |
|
465 | case ATOM_PPLL_INVALID: |
483 | } |
466 | return; |
484 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
467 | } |
485 | args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
468 | args.v2.ucEnable = enable; |
486 | args.v2.ucEnable = enable; |
469 | if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK)) |
487 | if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev)) |
470 | args.v2.ucEnable = ATOM_DISABLE; |
488 | args.v2.ucEnable = ATOM_DISABLE; |
471 | } else if (ASIC_IS_DCE3(rdev)) { |
489 | } else if (ASIC_IS_DCE3(rdev)) { |
Line 477... | Line 495... | ||
477 | args.v1.ucPpll = pll_id; |
495 | args.v1.ucPpll = pll_id; |
478 | args.v1.ucEnable = enable; |
496 | args.v1.ucEnable = enable; |
479 | } else if (ASIC_IS_AVIVO(rdev)) { |
497 | } else if (ASIC_IS_AVIVO(rdev)) { |
480 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || |
498 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || |
481 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { |
499 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { |
482 | atombios_disable_ss(crtc); |
500 | atombios_disable_ss(rdev, pll_id); |
483 | return; |
501 | return; |
484 | } |
502 | } |
485 | args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
503 | args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
486 | args.lvds_ss_2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; |
504 | args.lvds_ss_2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; |
487 | args.lvds_ss_2.ucSpreadSpectrumStep = ss->step; |
505 | args.lvds_ss_2.ucSpreadSpectrumStep = ss->step; |
Line 489... | Line 507... | ||
489 | args.lvds_ss_2.ucSpreadSpectrumRange = ss->range; |
507 | args.lvds_ss_2.ucSpreadSpectrumRange = ss->range; |
490 | args.lvds_ss_2.ucEnable = enable; |
508 | args.lvds_ss_2.ucEnable = enable; |
491 | } else { |
509 | } else { |
492 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || |
510 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || |
493 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { |
511 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { |
494 | atombios_disable_ss(crtc); |
512 | atombios_disable_ss(rdev, pll_id); |
495 | return; |
513 | return; |
496 | } |
514 | } |
497 | args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
515 | args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
498 | args.lvds_ss.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; |
516 | args.lvds_ss.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; |
499 | args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2; |
517 | args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2; |
Line 507... | Line 525... | ||
507 | ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; |
525 | ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; |
508 | ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3; |
526 | ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3; |
509 | }; |
527 | }; |
Line 510... | Line 528... | ||
510 | 528 | ||
511 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, |
529 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, |
512 | struct drm_display_mode *mode, |
- | |
513 | struct radeon_pll *pll, |
- | |
514 | bool ss_enabled, |
- | |
515 | struct radeon_atom_ss *ss) |
530 | struct drm_display_mode *mode) |
- | 531 | { |
|
516 | { |
532 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
517 | struct drm_device *dev = crtc->dev; |
533 | struct drm_device *dev = crtc->dev; |
518 | struct radeon_device *rdev = dev->dev_private; |
534 | struct radeon_device *rdev = dev->dev_private; |
519 | struct drm_encoder *encoder = NULL; |
535 | struct drm_encoder *encoder = radeon_crtc->encoder; |
520 | struct radeon_encoder *radeon_encoder = NULL; |
536 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
521 | struct drm_connector *connector = NULL; |
537 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
522 | u32 adjusted_clock = mode->clock; |
538 | u32 adjusted_clock = mode->clock; |
523 | int encoder_mode = 0; |
539 | int encoder_mode = atombios_get_encoder_mode(encoder); |
524 | u32 dp_clock = mode->clock; |
540 | u32 dp_clock = mode->clock; |
- | 541 | int bpc = radeon_get_monitor_bpc(connector); |
|
Line 525... | Line 542... | ||
525 | int bpc = 8; |
542 | bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); |
526 | 543 | ||
Line 527... | Line 544... | ||
527 | /* reset the pll flags */ |
544 | /* reset the pll flags */ |
528 | pll->flags = 0; |
545 | radeon_crtc->pll_flags = 0; |
529 | 546 | ||
530 | if (ASIC_IS_AVIVO(rdev)) { |
547 | if (ASIC_IS_AVIVO(rdev)) { |
531 | if ((rdev->family == CHIP_RS600) || |
548 | if ((rdev->family == CHIP_RS600) || |
532 | (rdev->family == CHIP_RS690) || |
549 | (rdev->family == CHIP_RS690) || |
Line 533... | Line 550... | ||
533 | (rdev->family == CHIP_RS740)) |
550 | (rdev->family == CHIP_RS740)) |
534 | pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ |
551 | radeon_crtc->pll_flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ |
535 | RADEON_PLL_PREFER_CLOSEST_LOWER); |
552 | RADEON_PLL_PREFER_CLOSEST_LOWER); |
536 | 553 | ||
Line 537... | Line 554... | ||
537 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ |
554 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ |
538 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
555 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
- | 556 | else |
|
- | 557 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
|
- | 558 | ||
539 | else |
559 | if (rdev->family < CHIP_RV770) |
540 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
560 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; |
Line 541... | Line 561... | ||
541 | 561 | /* use frac fb div on APUs */ |
|
542 | if (rdev->family < CHIP_RV770) |
562 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) |
543 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; |
563 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
544 | } else { |
564 | } else { |
545 | pll->flags |= RADEON_PLL_LEGACY; |
565 | radeon_crtc->pll_flags |= RADEON_PLL_LEGACY; |
Line 546... | Line -... | ||
546 | - | ||
547 | if (mode->clock > 200000) /* range limits??? */ |
- | |
548 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
- | |
549 | else |
- | |
550 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
- | |
551 | } |
- | |
552 | - | ||
553 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
566 | |
554 | if (encoder->crtc == crtc) { |
567 | if (mode->clock > 200000) /* range limits??? */ |
555 | radeon_encoder = to_radeon_encoder(encoder); |
568 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
556 | connector = radeon_get_connector_for_encoder(encoder); |
569 | else |
557 | if (connector) |
570 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
558 | bpc = connector->display_info.bpc; |
571 | } |
Line 568... | Line 581... | ||
568 | } |
581 | } |
569 | } |
582 | } |
Line 570... | Line 583... | ||
570 | 583 | ||
571 | /* use recommended ref_div for ss */ |
584 | /* use recommended ref_div for ss */ |
572 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
585 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
573 | if (ss_enabled) { |
586 | if (radeon_crtc->ss_enabled) { |
574 | if (ss->refdiv) { |
587 | if (radeon_crtc->ss.refdiv) { |
575 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
588 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
576 | pll->reference_div = ss->refdiv; |
589 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; |
577 | if (ASIC_IS_AVIVO(rdev)) |
590 | if (ASIC_IS_AVIVO(rdev)) |
578 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
591 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
579 | } |
592 | } |
580 | } |
593 | } |
Line 581... | Line 594... | ||
581 | } |
594 | } |
582 | 595 | ||
583 | if (ASIC_IS_AVIVO(rdev)) { |
596 | if (ASIC_IS_AVIVO(rdev)) { |
584 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
597 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
585 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
598 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
586 | adjusted_clock = mode->clock * 2; |
599 | adjusted_clock = mode->clock * 2; |
587 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
600 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
588 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; |
601 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; |
589 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
602 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
590 | pll->flags |= RADEON_PLL_IS_LCD; |
603 | radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD; |
591 | } else { |
604 | } else { |
592 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
605 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
593 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; |
606 | radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; |
594 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) |
- | |
595 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
- | |
596 | } |
- | |
597 | break; |
607 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) |
Line 598... | Line 608... | ||
598 | } |
608 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
599 | } |
609 | } |
600 | 610 | ||
Line 620... | Line 630... | ||
620 | case 1: |
630 | case 1: |
621 | case 2: |
631 | case 2: |
622 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
632 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
623 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
633 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
624 | args.v1.ucEncodeMode = encoder_mode; |
634 | args.v1.ucEncodeMode = encoder_mode; |
625 | if (ss_enabled && ss->percentage) |
635 | if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage) |
626 | args.v1.ucConfig |= |
636 | args.v1.ucConfig |= |
627 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; |
637 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; |
Line 628... | Line 638... | ||
628 | 638 | ||
629 | atom_execute_table(rdev->mode_info.atom_context, |
639 | atom_execute_table(rdev->mode_info.atom_context, |
Line 633... | Line 643... | ||
633 | case 3: |
643 | case 3: |
634 | args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10); |
644 | args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10); |
635 | args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; |
645 | args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; |
636 | args.v3.sInput.ucEncodeMode = encoder_mode; |
646 | args.v3.sInput.ucEncodeMode = encoder_mode; |
637 | args.v3.sInput.ucDispPllConfig = 0; |
647 | args.v3.sInput.ucDispPllConfig = 0; |
638 | if (ss_enabled && ss->percentage) |
648 | if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage) |
639 | args.v3.sInput.ucDispPllConfig |= |
649 | args.v3.sInput.ucDispPllConfig |= |
640 | DISPPLL_CONFIG_SS_ENABLE; |
650 | DISPPLL_CONFIG_SS_ENABLE; |
641 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT) || |
- | |
642 | radeon_encoder_is_dp_bridge(encoder)) { |
651 | if (ENCODER_MODE_IS_DP(encoder_mode)) { |
643 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | |
644 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
- | |
645 | args.v3.sInput.ucDispPllConfig |= |
652 | args.v3.sInput.ucDispPllConfig |= |
646 | DISPPLL_CONFIG_COHERENT_MODE; |
653 | DISPPLL_CONFIG_COHERENT_MODE; |
647 | /* 16200 or 27000 */ |
654 | /* 16200 or 27000 */ |
648 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); |
655 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); |
649 | } else { |
656 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
- | 657 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
|
650 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { |
658 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) |
651 | /* deep color support */ |
659 | /* deep color support */ |
652 | args.v3.sInput.usPixelClock = |
660 | args.v3.sInput.usPixelClock = |
653 | cpu_to_le16((mode->clock * bpc / 8) / 10); |
661 | cpu_to_le16((mode->clock * bpc / 8) / 10); |
654 | } |
- | |
655 | if (dig->coherent_mode) |
662 | if (dig->coherent_mode) |
656 | args.v3.sInput.ucDispPllConfig |= |
663 | args.v3.sInput.ucDispPllConfig |= |
657 | DISPPLL_CONFIG_COHERENT_MODE; |
664 | DISPPLL_CONFIG_COHERENT_MODE; |
658 | if (mode->clock > 165000) |
665 | if (is_duallink) |
659 | args.v3.sInput.ucDispPllConfig |= |
666 | args.v3.sInput.ucDispPllConfig |= |
660 | DISPPLL_CONFIG_DUAL_LINK; |
667 | DISPPLL_CONFIG_DUAL_LINK; |
661 | } |
668 | } |
662 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
669 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != |
663 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
- | |
664 | args.v3.sInput.ucDispPllConfig |= |
- | |
665 | DISPPLL_CONFIG_COHERENT_MODE; |
670 | ENCODER_OBJECT_ID_NONE) |
666 | /* 16200 or 27000 */ |
- | |
667 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); |
- | |
668 | } else if (encoder_mode != ATOM_ENCODER_MODE_LVDS) { |
- | |
669 | if (mode->clock > 165000) |
- | |
670 | args.v3.sInput.ucDispPllConfig |= |
671 | args.v3.sInput.ucExtTransmitterID = |
671 | DISPPLL_CONFIG_DUAL_LINK; |
- | |
672 | } |
- | |
673 | } |
- | |
674 | if (radeon_encoder_is_dp_bridge(encoder)) { |
672 | radeon_encoder_get_dp_bridge_encoder_id(encoder); |
675 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); |
- | |
676 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); |
- | |
677 | args.v3.sInput.ucExtTransmitterID = ext_radeon_encoder->encoder_id; |
- | |
678 | } else |
673 | else |
679 | args.v3.sInput.ucExtTransmitterID = 0; |
674 | args.v3.sInput.ucExtTransmitterID = 0; |
Line 680... | Line 675... | ||
680 | 675 | ||
681 | atom_execute_table(rdev->mode_info.atom_context, |
676 | atom_execute_table(rdev->mode_info.atom_context, |
682 | index, (uint32_t *)&args); |
677 | index, (uint32_t *)&args); |
683 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; |
678 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; |
684 | if (args.v3.sOutput.ucRefDiv) { |
679 | if (args.v3.sOutput.ucRefDiv) { |
685 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
680 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
686 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
681 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
687 | pll->reference_div = args.v3.sOutput.ucRefDiv; |
682 | radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv; |
688 | } |
683 | } |
689 | if (args.v3.sOutput.ucPostDiv) { |
684 | if (args.v3.sOutput.ucPostDiv) { |
690 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
685 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
691 | pll->flags |= RADEON_PLL_USE_POST_DIV; |
686 | radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV; |
692 | pll->post_div = args.v3.sOutput.ucPostDiv; |
687 | radeon_crtc->pll_post_div = args.v3.sOutput.ucPostDiv; |
693 | } |
688 | } |
694 | break; |
689 | break; |
695 | default: |
690 | default: |
696 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
691 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
Line 715... | Line 710... | ||
715 | }; |
710 | }; |
Line 716... | Line 711... | ||
716 | 711 | ||
717 | /* on DCE5, make sure the voltage is high enough to support the |
712 | /* on DCE5, make sure the voltage is high enough to support the |
718 | * required disp clk. |
713 | * required disp clk. |
719 | */ |
714 | */ |
720 | static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, |
715 | static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev, |
721 | u32 dispclk) |
716 | u32 dispclk) |
722 | { |
- | |
723 | struct drm_device *dev = crtc->dev; |
- | |
724 | struct radeon_device *rdev = dev->dev_private; |
717 | { |
725 | u8 frev, crev; |
718 | u8 frev, crev; |
726 | int index; |
719 | int index; |
Line 727... | Line 720... | ||
727 | union set_pixel_clock args; |
720 | union set_pixel_clock args; |
Line 747... | Line 740... | ||
747 | case 6: |
740 | case 6: |
748 | /* if the default dcpll clock is specified, |
741 | /* if the default dcpll clock is specified, |
749 | * SetPixelClock provides the dividers |
742 | * SetPixelClock provides the dividers |
750 | */ |
743 | */ |
751 | args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk); |
744 | args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk); |
- | 745 | if (ASIC_IS_DCE61(rdev)) |
|
- | 746 | args.v6.ucPpll = ATOM_EXT_PLL1; |
|
- | 747 | else if (ASIC_IS_DCE6(rdev)) |
|
- | 748 | args.v6.ucPpll = ATOM_PPLL0; |
|
- | 749 | else |
|
752 | args.v6.ucPpll = ATOM_DCPLL; |
750 | args.v6.ucPpll = ATOM_DCPLL; |
753 | break; |
751 | break; |
754 | default: |
752 | default: |
755 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
753 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
756 | return; |
754 | return; |
Line 819... | Line 817... | ||
819 | args.v3.usRefDiv = cpu_to_le16(ref_div); |
817 | args.v3.usRefDiv = cpu_to_le16(ref_div); |
820 | args.v3.usFbDiv = cpu_to_le16(fb_div); |
818 | args.v3.usFbDiv = cpu_to_le16(fb_div); |
821 | args.v3.ucFracFbDiv = frac_fb_div; |
819 | args.v3.ucFracFbDiv = frac_fb_div; |
822 | args.v3.ucPostDiv = post_div; |
820 | args.v3.ucPostDiv = post_div; |
823 | args.v3.ucPpll = pll_id; |
821 | args.v3.ucPpll = pll_id; |
- | 822 | if (crtc_id == ATOM_CRTC2) |
|
- | 823 | args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2; |
|
- | 824 | else |
|
824 | args.v3.ucMiscInfo = (pll_id << 2); |
825 | args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1; |
825 | if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) |
826 | if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) |
826 | args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; |
827 | args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; |
827 | args.v3.ucTransmitterId = encoder_id; |
828 | args.v3.ucTransmitterId = encoder_id; |
828 | args.v3.ucEncoderMode = encoder_mode; |
829 | args.v3.ucEncoderMode = encoder_mode; |
829 | break; |
830 | break; |
Line 889... | Line 890... | ||
889 | } |
890 | } |
Line 890... | Line 891... | ||
890 | 891 | ||
891 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
892 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
Line 892... | Line 893... | ||
892 | } |
893 | } |
893 | 894 | ||
894 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
895 | static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
895 | { |
896 | { |
896 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
897 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
897 | struct drm_device *dev = crtc->dev; |
898 | struct drm_device *dev = crtc->dev; |
898 | struct radeon_device *rdev = dev->dev_private; |
899 | struct radeon_device *rdev = dev->dev_private; |
899 | struct drm_encoder *encoder = NULL; |
- | |
900 | struct radeon_encoder *radeon_encoder = NULL; |
900 | struct radeon_encoder *radeon_encoder = |
901 | u32 pll_clock = mode->clock; |
- | |
902 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; |
- | |
903 | struct radeon_pll *pll; |
- | |
904 | u32 adjusted_clock; |
- | |
905 | int encoder_mode = 0; |
- | |
906 | struct radeon_atom_ss ss; |
- | |
Line 907... | Line -... | ||
907 | bool ss_enabled = false; |
- | |
908 | int bpc = 8; |
- | |
909 | - | ||
910 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
- | |
911 | if (encoder->crtc == crtc) { |
- | |
912 | radeon_encoder = to_radeon_encoder(encoder); |
- | |
913 | encoder_mode = atombios_get_encoder_mode(encoder); |
- | |
914 | break; |
- | |
915 | } |
- | |
916 | } |
- | |
917 | - | ||
918 | if (!radeon_encoder) |
901 | to_radeon_encoder(radeon_crtc->encoder); |
919 | return; |
- | |
920 | - | ||
921 | switch (radeon_crtc->pll_id) { |
- | |
922 | case ATOM_PPLL1: |
- | |
923 | pll = &rdev->clock.p1pll; |
- | |
924 | break; |
- | |
925 | case ATOM_PPLL2: |
- | |
926 | pll = &rdev->clock.p2pll; |
- | |
927 | break; |
- | |
928 | case ATOM_DCPLL: |
902 | int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder); |
929 | case ATOM_PPLL_INVALID: |
- | |
930 | default: |
- | |
Line 931... | Line 903... | ||
931 | pll = &rdev->clock.dcpll; |
903 | |
932 | break; |
904 | radeon_crtc->bpc = 8; |
933 | } |
905 | radeon_crtc->ss_enabled = false; |
934 | 906 | ||
935 | if (radeon_encoder->active_device & |
907 | if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
936 | (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { |
908 | (radeon_encoder_get_dp_bridge_encoder_id(radeon_crtc->encoder) != ENCODER_OBJECT_ID_NONE)) { |
937 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
909 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
938 | struct drm_connector *connector = |
910 | struct drm_connector *connector = |
939 | radeon_get_connector_for_encoder(encoder); |
911 | radeon_get_connector_for_encoder(radeon_crtc->encoder); |
940 | struct radeon_connector *radeon_connector = |
912 | struct radeon_connector *radeon_connector = |
941 | to_radeon_connector(connector); |
913 | to_radeon_connector(connector); |
Line 942... | Line 914... | ||
942 | struct radeon_connector_atom_dig *dig_connector = |
914 | struct radeon_connector_atom_dig *dig_connector = |
- | 915 | radeon_connector->con_priv; |
|
943 | radeon_connector->con_priv; |
916 | int dp_clock; |
944 | int dp_clock; |
917 | radeon_crtc->bpc = radeon_get_monitor_bpc(connector); |
945 | bpc = connector->display_info.bpc; |
918 | |
946 | 919 | switch (encoder_mode) { |
|
947 | switch (encoder_mode) { |
920 | case ATOM_ENCODER_MODE_DP_MST: |
948 | case ATOM_ENCODER_MODE_DP: |
921 | case ATOM_ENCODER_MODE_DP: |
949 | /* DP/eDP */ |
922 | /* DP/eDP */ |
950 | dp_clock = dig_connector->dp_clock / 10; |
923 | dp_clock = dig_connector->dp_clock / 10; |
951 | if (ASIC_IS_DCE4(rdev)) |
924 | if (ASIC_IS_DCE4(rdev)) |
952 | ss_enabled = |
925 | radeon_crtc->ss_enabled = |
953 | radeon_atombios_get_asic_ss_info(rdev, &ss, |
926 | radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss, |
954 | ASIC_INTERNAL_SS_ON_DP, |
927 | ASIC_INTERNAL_SS_ON_DP, |
- | 928 | dp_clock); |
|
955 | dp_clock); |
929 | else { |
956 | else { |
930 | if (dp_clock == 16200) { |
957 | if (dp_clock == 16200) { |
931 | radeon_crtc->ss_enabled = |
958 | ss_enabled = |
932 | radeon_atombios_get_ppll_ss_info(rdev, |
- | 933 | &radeon_crtc->ss, |
|
959 | radeon_atombios_get_ppll_ss_info(rdev, &ss, |
934 | ATOM_DP_SS_ID2); |
960 | ATOM_DP_SS_ID2); |
935 | if (!radeon_crtc->ss_enabled) |
961 | if (!ss_enabled) |
936 | radeon_crtc->ss_enabled = |
962 | ss_enabled = |
937 | radeon_atombios_get_ppll_ss_info(rdev, |
- | 938 | &radeon_crtc->ss, |
|
963 | radeon_atombios_get_ppll_ss_info(rdev, &ss, |
939 | ATOM_DP_SS_ID1); |
964 | ATOM_DP_SS_ID1); |
940 | } else |
965 | } else |
941 | radeon_crtc->ss_enabled = |
966 | ss_enabled = |
942 | radeon_atombios_get_ppll_ss_info(rdev, |
967 | radeon_atombios_get_ppll_ss_info(rdev, &ss, |
943 | &radeon_crtc->ss, |
- | 944 | ATOM_DP_SS_ID1); |
|
968 | ATOM_DP_SS_ID1); |
945 | } |
- | 946 | break; |
|
969 | } |
947 | case ATOM_ENCODER_MODE_LVDS: |
970 | break; |
948 | if (ASIC_IS_DCE4(rdev)) |
971 | case ATOM_ENCODER_MODE_LVDS: |
949 | radeon_crtc->ss_enabled = |
- | 950 | radeon_atombios_get_asic_ss_info(rdev, |
|
972 | if (ASIC_IS_DCE4(rdev)) |
951 | &radeon_crtc->ss, |
- | 952 | dig->lcd_ss_id, |
|
973 | ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, |
953 | mode->clock / 10); |
974 | dig->lcd_ss_id, |
954 | else |
975 | mode->clock / 10); |
955 | radeon_crtc->ss_enabled = |
976 | else |
956 | radeon_atombios_get_ppll_ss_info(rdev, |
977 | ss_enabled = radeon_atombios_get_ppll_ss_info(rdev, &ss, |
957 | &radeon_crtc->ss, |
978 | dig->lcd_ss_id); |
958 | dig->lcd_ss_id); |
- | 959 | break; |
|
979 | break; |
960 | case ATOM_ENCODER_MODE_DVI: |
980 | case ATOM_ENCODER_MODE_DVI: |
961 | if (ASIC_IS_DCE4(rdev)) |
981 | if (ASIC_IS_DCE4(rdev)) |
962 | radeon_crtc->ss_enabled = |
982 | ss_enabled = |
963 | radeon_atombios_get_asic_ss_info(rdev, |
983 | radeon_atombios_get_asic_ss_info(rdev, &ss, |
964 | &radeon_crtc->ss, |
984 | ASIC_INTERNAL_SS_ON_TMDS, |
965 | ASIC_INTERNAL_SS_ON_TMDS, |
985 | mode->clock / 10); |
966 | mode->clock / 10); |
- | 967 | break; |
|
986 | break; |
968 | case ATOM_ENCODER_MODE_HDMI: |
987 | case ATOM_ENCODER_MODE_HDMI: |
969 | if (ASIC_IS_DCE4(rdev)) |
988 | if (ASIC_IS_DCE4(rdev)) |
970 | radeon_crtc->ss_enabled = |
989 | ss_enabled = |
971 | radeon_atombios_get_asic_ss_info(rdev, |
990 | radeon_atombios_get_asic_ss_info(rdev, &ss, |
972 | &radeon_crtc->ss, |
991 | ASIC_INTERNAL_SS_ON_HDMI, |
973 | ASIC_INTERNAL_SS_ON_HDMI, |
992 | mode->clock / 10); |
974 | mode->clock / 10); |
Line 993... | Line 975... | ||
993 | break; |
975 | break; |
994 | default: |
976 | default: |
- | 977 | break; |
|
- | 978 | } |
|
- | 979 | } |
|
- | 980 | ||
- | 981 | /* adjust pixel clock as needed */ |
|
- | 982 | radeon_crtc->adjusted_clock = atombios_adjust_pll(crtc, mode); |
|
- | 983 | ||
- | 984 | return true; |
|
- | 985 | } |
|
- | 986 | ||
- | 987 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
|
- | 988 | { |
|
- | 989 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 990 | struct drm_device *dev = crtc->dev; |
|
- | 991 | struct radeon_device *rdev = dev->dev_private; |
|
- | 992 | struct radeon_encoder *radeon_encoder = |
|
- | 993 | to_radeon_encoder(radeon_crtc->encoder); |
|
- | 994 | u32 pll_clock = mode->clock; |
|
- | 995 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; |
|
- | 996 | struct radeon_pll *pll; |
|
- | 997 | int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder); |
|
- | 998 | ||
- | 999 | switch (radeon_crtc->pll_id) { |
|
- | 1000 | case ATOM_PPLL1: |
|
- | 1001 | pll = &rdev->clock.p1pll; |
|
- | 1002 | break; |
|
- | 1003 | case ATOM_PPLL2: |
|
- | 1004 | pll = &rdev->clock.p2pll; |
|
- | 1005 | break; |
|
- | 1006 | case ATOM_DCPLL: |
|
- | 1007 | case ATOM_PPLL_INVALID: |
|
- | 1008 | default: |
|
- | 1009 | pll = &rdev->clock.dcpll; |
|
- | 1010 | break; |
|
Line 995... | Line 1011... | ||
995 | break; |
1011 | } |
996 | } |
1012 | |
997 | } |
1013 | /* update pll params */ |
998 | 1014 | pll->flags = radeon_crtc->pll_flags; |
|
999 | /* adjust pixel clock as needed */ |
1015 | pll->reference_div = radeon_crtc->pll_reference_div; |
1000 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); |
1016 | pll->post_div = radeon_crtc->pll_post_div; |
1001 | 1017 | ||
1002 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
1018 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
1003 | /* TV seems to prefer the legacy algo on some boards */ |
1019 | /* TV seems to prefer the legacy algo on some boards */ |
1004 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
1020 | radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock, |
Line 1005... | Line 1021... | ||
1005 | &ref_div, &post_div); |
1021 | &fb_div, &frac_fb_div, &ref_div, &post_div); |
- | 1022 | else if (ASIC_IS_AVIVO(rdev)) |
|
Line 1006... | Line 1023... | ||
1006 | else if (ASIC_IS_AVIVO(rdev)) |
1023 | radeon_compute_pll_avivo(pll, radeon_crtc->adjusted_clock, &pll_clock, |
1007 | radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
1024 | &fb_div, &frac_fb_div, &ref_div, &post_div); |
1008 | &ref_div, &post_div); |
1025 | else |
- | 1026 | radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock, |
|
Line 1009... | Line 1027... | ||
1009 | else |
1027 | &fb_div, &frac_fb_div, &ref_div, &post_div); |
1010 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
1028 | |
1011 | &ref_div, &post_div); |
1029 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, |
1012 | 1030 | radeon_crtc->crtc_id, &radeon_crtc->ss); |
|
1013 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss); |
1031 | |
1014 | 1032 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
|
1015 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
1033 | encoder_mode, radeon_encoder->encoder_id, mode->clock, |
1016 | encoder_mode, radeon_encoder->encoder_id, mode->clock, |
1034 | ref_div, fb_div, frac_fb_div, post_div, |
1017 | ref_div, fb_div, frac_fb_div, post_div, bpc, ss_enabled, &ss); |
1035 | radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss); |
1018 | 1036 | ||
1019 | if (ss_enabled) { |
1037 | if (radeon_crtc->ss_enabled) { |
1020 | /* calculate ss amount and step size */ |
1038 | /* calculate ss amount and step size */ |
1021 | if (ASIC_IS_DCE4(rdev)) { |
1039 | if (ASIC_IS_DCE4(rdev)) { |
1022 | u32 step_size; |
1040 | u32 step_size; |
1023 | u32 amount = (((fb_div * 10) + frac_fb_div) * ss.percentage) / 10000; |
1041 | u32 amount = (((fb_div * 10) + frac_fb_div) * radeon_crtc->ss.percentage) / 10000; |
1024 | ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK; |
1042 | radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK; |
Line 1025... | Line 1043... | ||
1025 | ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) & |
1043 | radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) & |
- | 1044 | ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK; |
|
1026 | ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK; |
1045 | if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD) |
1027 | if (ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD) |
1046 | step_size = (4 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) / |
Line 1028... | Line 1047... | ||
1028 | step_size = (4 * amount * ref_div * (ss.rate * 2048)) / |
1047 | (125 * 25 * pll->reference_freq / 100); |
1029 | (125 * 25 * pll->reference_freq / 100); |
1048 | else |
Line 1048... | Line 1067... | ||
1048 | struct drm_framebuffer *target_fb; |
1067 | struct drm_framebuffer *target_fb; |
1049 | struct drm_gem_object *obj; |
1068 | struct drm_gem_object *obj; |
1050 | struct radeon_bo *rbo; |
1069 | struct radeon_bo *rbo; |
1051 | uint64_t fb_location; |
1070 | uint64_t fb_location; |
1052 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
1071 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
- | 1072 | unsigned bankw, bankh, mtaspect, tile_split; |
|
1053 | u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); |
1073 | u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); |
1054 | u32 tmp, viewport_w, viewport_h; |
1074 | u32 tmp, viewport_w, viewport_h; |
1055 | int r; |
1075 | int r; |
Line 1056... | Line 1076... | ||
1056 | 1076 | ||
Line 1063... | Line 1083... | ||
1063 | if (atomic) { |
1083 | if (atomic) { |
1064 | radeon_fb = to_radeon_framebuffer(fb); |
1084 | radeon_fb = to_radeon_framebuffer(fb); |
1065 | target_fb = fb; |
1085 | target_fb = fb; |
1066 | } |
1086 | } |
1067 | else { |
1087 | else { |
1068 | radeon_fb = to_radeon_framebuffer(crtc->fb); |
1088 | radeon_fb = to_radeon_framebuffer(crtc->fb); |
1069 | target_fb = crtc->fb; |
1089 | target_fb = crtc->fb; |
1070 | } |
1090 | } |
Line 1071... | Line 1091... | ||
1071 | 1091 | ||
1072 | /* If atomic, assume fb object is pinned & idle & fenced and |
1092 | /* If atomic, assume fb object is pinned & idle & fenced and |
Line 1079... | Line 1099... | ||
1079 | return r; |
1099 | return r; |
Line 1080... | Line 1100... | ||
1080 | 1100 | ||
1081 | if (atomic) |
1101 | if (atomic) |
1082 | fb_location = radeon_bo_gpu_offset(rbo); |
1102 | fb_location = radeon_bo_gpu_offset(rbo); |
1083 | else { |
1103 | else { |
1084 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); |
1104 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); |
1085 | if (unlikely(r != 0)) { |
1105 | if (unlikely(r != 0)) { |
1086 | radeon_bo_unreserve(rbo); |
1106 | radeon_bo_unreserve(rbo); |
1087 | return -EINVAL; |
1107 | return -EINVAL; |
1088 | } |
1108 | } |
Line 1089... | Line 1109... | ||
1089 | } |
1109 | } |
1090 | 1110 | ||
Line 1119... | Line 1139... | ||
1119 | DRM_ERROR("Unsupported screen depth %d\n", |
1139 | DRM_ERROR("Unsupported screen depth %d\n", |
1120 | target_fb->bits_per_pixel); |
1140 | target_fb->bits_per_pixel); |
1121 | return -EINVAL; |
1141 | return -EINVAL; |
1122 | } |
1142 | } |
Line 1123... | Line 1143... | ||
1123 | 1143 | ||
- | 1144 | if (tiling_flags & RADEON_TILING_MACRO) { |
|
- | 1145 | if (rdev->family >= CHIP_TAHITI) |
|
- | 1146 | tmp = rdev->config.si.tile_config; |
|
- | 1147 | else if (rdev->family >= CHIP_CAYMAN) |
|
- | 1148 | tmp = rdev->config.cayman.tile_config; |
|
- | 1149 | else |
|
- | 1150 | tmp = rdev->config.evergreen.tile_config; |
|
- | 1151 | ||
- | 1152 | switch ((tmp & 0xf0) >> 4) { |
|
- | 1153 | case 0: /* 4 banks */ |
|
- | 1154 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK); |
|
- | 1155 | break; |
|
- | 1156 | case 1: /* 8 banks */ |
|
- | 1157 | default: |
|
- | 1158 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK); |
|
- | 1159 | break; |
|
- | 1160 | case 2: /* 16 banks */ |
|
- | 1161 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK); |
|
- | 1162 | break; |
|
- | 1163 | } |
|
1124 | if (tiling_flags & RADEON_TILING_MACRO) |
1164 | |
- | 1165 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); |
|
- | 1166 | ||
- | 1167 | evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); |
|
- | 1168 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split); |
|
- | 1169 | fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw); |
|
- | 1170 | fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh); |
|
1125 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); |
1171 | fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect); |
1126 | else if (tiling_flags & RADEON_TILING_MICRO) |
1172 | } else if (tiling_flags & RADEON_TILING_MICRO) |
Line -... | Line 1173... | ||
- | 1173 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); |
|
- | 1174 | ||
- | 1175 | if ((rdev->family == CHIP_TAHITI) || |
|
- | 1176 | (rdev->family == CHIP_PITCAIRN)) |
|
- | 1177 | fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); |
|
- | 1178 | else if (rdev->family == CHIP_VERDE) |
|
1127 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); |
1179 | fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); |
1128 | 1180 | ||
1129 | switch (radeon_crtc->crtc_id) { |
1181 | switch (radeon_crtc->crtc_id) { |
1130 | case 0: |
1182 | case 0: |
1131 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
1183 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
Line 1165... | Line 1217... | ||
1165 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); |
1217 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); |
1166 | WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
1218 | WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
1167 | WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); |
1219 | WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); |
1168 | WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); |
1220 | WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); |
Line 1169... | Line 1221... | ||
1169 | 1221 | ||
1170 | fb_pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8); |
1222 | fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8); |
1171 | WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
1223 | WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
Line 1172... | Line 1224... | ||
1172 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
1224 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
1173 | 1225 | ||
1174 | WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
1226 | WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
1175 | crtc->mode.vdisplay); |
1227 | target_fb->height); |
1176 | x &= ~3; |
1228 | x &= ~3; |
1177 | y &= ~1; |
1229 | y &= ~1; |
1178 | WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, |
1230 | WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, |
Line 1334... | Line 1386... | ||
1334 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); |
1386 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); |
1335 | WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
1387 | WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
1336 | WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); |
1388 | WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); |
1337 | WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); |
1389 | WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); |
Line 1338... | Line 1390... | ||
1338 | 1390 | ||
1339 | fb_pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8); |
1391 | fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8); |
1340 | WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
1392 | WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
Line 1341... | Line 1393... | ||
1341 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
1393 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
1342 | 1394 | ||
1343 | WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
1395 | WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
1344 | crtc->mode.vdisplay); |
1396 | target_fb->height); |
1345 | x &= ~3; |
1397 | x &= ~3; |
1346 | y &= ~1; |
1398 | y &= ~1; |
1347 | WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, |
1399 | WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, |
Line 1427... | Line 1479... | ||
1427 | WREG32(RADEON_FP_V2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_V_SYNC_STRT_WID)); |
1479 | WREG32(RADEON_FP_V2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_V_SYNC_STRT_WID)); |
1428 | break; |
1480 | break; |
1429 | } |
1481 | } |
1430 | } |
1482 | } |
Line -... | Line 1483... | ||
- | 1483 | ||
- | 1484 | /** |
|
- | 1485 | * radeon_get_pll_use_mask - look up a mask of which pplls are in use |
|
- | 1486 | * |
|
- | 1487 | * @crtc: drm crtc |
|
- | 1488 | * |
|
- | 1489 | * Returns the mask of which PPLLs (Pixel PLLs) are in use. |
|
- | 1490 | */ |
|
- | 1491 | static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc) |
|
- | 1492 | { |
|
- | 1493 | struct drm_device *dev = crtc->dev; |
|
- | 1494 | struct drm_crtc *test_crtc; |
|
- | 1495 | struct radeon_crtc *test_radeon_crtc; |
|
- | 1496 | u32 pll_in_use = 0; |
|
- | 1497 | ||
- | 1498 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { |
|
- | 1499 | if (crtc == test_crtc) |
|
- | 1500 | continue; |
|
- | 1501 | ||
- | 1502 | test_radeon_crtc = to_radeon_crtc(test_crtc); |
|
- | 1503 | if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) |
|
- | 1504 | pll_in_use |= (1 << test_radeon_crtc->pll_id); |
|
- | 1505 | } |
|
- | 1506 | return pll_in_use; |
|
- | 1507 | } |
|
- | 1508 | ||
- | 1509 | /** |
|
- | 1510 | * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP |
|
- | 1511 | * |
|
- | 1512 | * @crtc: drm crtc |
|
- | 1513 | * |
|
- | 1514 | * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is |
|
- | 1515 | * also in DP mode. For DP, a single PPLL can be used for all DP |
|
- | 1516 | * crtcs/encoders. |
|
1431 | 1517 | */ |
|
- | 1518 | static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) |
|
- | 1519 | { |
|
- | 1520 | struct drm_device *dev = crtc->dev; |
|
- | 1521 | struct drm_crtc *test_crtc; |
|
- | 1522 | struct radeon_crtc *test_radeon_crtc; |
|
- | 1523 | ||
- | 1524 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { |
|
- | 1525 | if (crtc == test_crtc) |
|
- | 1526 | continue; |
|
- | 1527 | test_radeon_crtc = to_radeon_crtc(test_crtc); |
|
- | 1528 | if (test_radeon_crtc->encoder && |
|
- | 1529 | ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) { |
|
- | 1530 | /* for DP use the same PLL for all */ |
|
- | 1531 | if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) |
|
- | 1532 | return test_radeon_crtc->pll_id; |
|
- | 1533 | } |
|
- | 1534 | } |
|
- | 1535 | return ATOM_PPLL_INVALID; |
|
- | 1536 | } |
|
- | 1537 | ||
- | 1538 | /** |
|
- | 1539 | * radeon_get_shared_nondp_ppll - return the PPLL used by another non-DP crtc |
|
- | 1540 | * |
|
- | 1541 | * @crtc: drm crtc |
|
- | 1542 | * @encoder: drm encoder |
|
- | 1543 | * |
|
- | 1544 | * Returns the PPLL (Pixel PLL) used by another non-DP crtc/encoder which can |
|
- | 1545 | * be shared (i.e., same clock). |
|
- | 1546 | */ |
|
1432 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) |
1547 | static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc) |
1433 | { |
1548 | { |
1434 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1549 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1435 | struct drm_device *dev = crtc->dev; |
- | |
1436 | struct radeon_device *rdev = dev->dev_private; |
- | |
1437 | struct drm_encoder *test_encoder; |
1550 | struct drm_device *dev = crtc->dev; |
- | 1551 | struct drm_crtc *test_crtc; |
|
1438 | struct drm_crtc *test_crtc; |
1552 | struct radeon_crtc *test_radeon_crtc; |
Line -... | Line 1553... | ||
- | 1553 | u32 adjusted_clock, test_adjusted_clock; |
|
- | 1554 | ||
1439 | uint32_t pll_in_use = 0; |
1555 | adjusted_clock = radeon_crtc->adjusted_clock; |
- | 1556 | ||
- | 1557 | if (adjusted_clock == 0) |
|
1440 | 1558 | return ATOM_PPLL_INVALID; |
|
- | 1559 | ||
- | 1560 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { |
|
- | 1561 | if (crtc == test_crtc) |
|
- | 1562 | continue; |
|
- | 1563 | test_radeon_crtc = to_radeon_crtc(test_crtc); |
|
- | 1564 | if (test_radeon_crtc->encoder && |
|
1441 | if (ASIC_IS_DCE4(rdev)) { |
1565 | !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) { |
- | 1566 | /* check if we are already driving this connector with another crtc */ |
|
- | 1567 | if (test_radeon_crtc->connector == radeon_crtc->connector) { |
|
- | 1568 | /* if we are, return that pll */ |
|
- | 1569 | if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) |
|
- | 1570 | return test_radeon_crtc->pll_id; |
|
- | 1571 | } |
|
- | 1572 | /* for non-DP check the clock */ |
|
- | 1573 | test_adjusted_clock = test_radeon_crtc->adjusted_clock; |
|
- | 1574 | if ((crtc->mode.clock == test_crtc->mode.clock) && |
|
- | 1575 | (adjusted_clock == test_adjusted_clock) && |
|
- | 1576 | (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) && |
|
- | 1577 | (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)) |
|
- | 1578 | return test_radeon_crtc->pll_id; |
|
- | 1579 | } |
|
- | 1580 | } |
|
- | 1581 | return ATOM_PPLL_INVALID; |
|
- | 1582 | } |
|
- | 1583 | ||
- | 1584 | /** |
|
- | 1585 | * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc. |
|
- | 1586 | * |
|
- | 1587 | * @crtc: drm crtc |
|
- | 1588 | * |
|
- | 1589 | * Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors |
|
- | 1590 | * a single PPLL can be used for all DP crtcs/encoders. For non-DP |
|
- | 1591 | * monitors a dedicated PPLL must be used. If a particular board has |
|
- | 1592 | * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming |
|
- | 1593 | * as there is no need to program the PLL itself. If we are not able to |
|
- | 1594 | * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to |
|
- | 1595 | * avoid messing up an existing monitor. |
|
- | 1596 | * |
|
- | 1597 | * Asic specific PLL information |
|
- | 1598 | * |
|
- | 1599 | * DCE 6.1 |
|
- | 1600 | * - PPLL2 is only available to UNIPHYA (both DP and non-DP) |
|
- | 1601 | * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP) |
|
- | 1602 | * |
|
- | 1603 | * DCE 6.0 |
|
- | 1604 | * - PPLL0 is available to all UNIPHY (DP only) |
|
- | 1605 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC |
|
- | 1606 | * |
|
- | 1607 | * DCE 5.0 |
|
- | 1608 | * - DCPLL is available to all UNIPHY (DP only) |
|
- | 1609 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC |
|
- | 1610 | * |
|
- | 1611 | * DCE 3.0/4.0/4.1 |
|
- | 1612 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC |
|
- | 1613 | * |
|
- | 1614 | */ |
|
- | 1615 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) |
|
- | 1616 | { |
|
- | 1617 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 1618 | struct drm_device *dev = crtc->dev; |
|
- | 1619 | struct radeon_device *rdev = dev->dev_private; |
|
- | 1620 | struct radeon_encoder *radeon_encoder = |
|
- | 1621 | to_radeon_encoder(radeon_crtc->encoder); |
|
- | 1622 | u32 pll_in_use; |
|
- | 1623 | int pll; |
|
- | 1624 | ||
- | 1625 | if (ASIC_IS_DCE61(rdev)) { |
|
- | 1626 | struct radeon_encoder_atom_dig *dig = |
|
- | 1627 | radeon_encoder->enc_priv; |
|
- | 1628 | ||
- | 1629 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && |
|
- | 1630 | (dig->linkb == false)) |
|
- | 1631 | /* UNIPHY A uses PPLL2 */ |
|
- | 1632 | return ATOM_PPLL2; |
|
- | 1633 | else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { |
|
- | 1634 | /* UNIPHY B/C/D/E/F */ |
|
- | 1635 | if (rdev->clock.dp_extclk) |
|
- | 1636 | /* skip PPLL programming if using ext clock */ |
|
- | 1637 | return ATOM_PPLL_INVALID; |
|
- | 1638 | else { |
|
- | 1639 | /* use the same PPLL for all DP monitors */ |
|
- | 1640 | pll = radeon_get_shared_dp_ppll(crtc); |
|
- | 1641 | if (pll != ATOM_PPLL_INVALID) |
|
- | 1642 | return pll; |
|
- | 1643 | } |
|
- | 1644 | } else { |
|
- | 1645 | /* use the same PPLL for all monitors with the same clock */ |
|
- | 1646 | pll = radeon_get_shared_nondp_ppll(crtc); |
|
- | 1647 | if (pll != ATOM_PPLL_INVALID) |
|
- | 1648 | return pll; |
|
- | 1649 | } |
|
- | 1650 | /* UNIPHY B/C/D/E/F */ |
|
- | 1651 | pll_in_use = radeon_get_pll_use_mask(crtc); |
|
- | 1652 | if (!(pll_in_use & (1 << ATOM_PPLL0))) |
|
- | 1653 | return ATOM_PPLL0; |
|
- | 1654 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
|
- | 1655 | return ATOM_PPLL1; |
|
- | 1656 | DRM_ERROR("unable to allocate a PPLL\n"); |
|
1442 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { |
1657 | return ATOM_PPLL_INVALID; |
1443 | if (test_encoder->crtc && (test_encoder->crtc == crtc)) { |
1658 | } else if (ASIC_IS_DCE4(rdev)) { |
1444 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, |
1659 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, |
1445 | * depending on the asic: |
1660 | * depending on the asic: |
- | 1661 | * DCE4: PPLL or ext clock |
|
1446 | * DCE4: PPLL or ext clock |
1662 | * DCE5: PPLL, DCPLL, or ext clock |
1447 | * DCE5: DCPLL or ext clock |
1663 | * DCE6: PPLL, PPLL0, or ext clock |
1448 | * |
1664 | * |
1449 | * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip |
1665 | * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip |
1450 | * PPLL/DCPLL programming and only program the DP DTO for the |
1666 | * PPLL/DCPLL programming and only program the DP DTO for the |
1451 | * crtc virtual pixel clock. |
1667 | * crtc virtual pixel clock. |
1452 | */ |
1668 | */ |
- | 1669 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { |
|
1453 | if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) { |
1670 | if (rdev->clock.dp_extclk) |
- | 1671 | /* skip PPLL programming if using ext clock */ |
|
- | 1672 | return ATOM_PPLL_INVALID; |
|
- | 1673 | else if (ASIC_IS_DCE6(rdev)) |
|
- | 1674 | /* use PPLL0 for all DP */ |
|
- | 1675 | return ATOM_PPLL0; |
|
- | 1676 | else if (ASIC_IS_DCE5(rdev)) |
|
- | 1677 | /* use DCPLL for all DP */ |
|
- | 1678 | return ATOM_DCPLL; |
|
- | 1679 | else { |
|
- | 1680 | /* use the same PPLL for all DP monitors */ |
|
- | 1681 | pll = radeon_get_shared_dp_ppll(crtc); |
|
1454 | if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk) |
1682 | if (pll != ATOM_PPLL_INVALID) |
- | 1683 | return pll; |
|
- | 1684 | } |
|
- | 1685 | } else { |
|
- | 1686 | /* use the same PPLL for all monitors with the same clock */ |
|
- | 1687 | pll = radeon_get_shared_nondp_ppll(crtc); |
|
1455 | return ATOM_PPLL_INVALID; |
1688 | if (pll != ATOM_PPLL_INVALID) |
- | 1689 | return pll; |
|
- | 1690 | } |
|
- | 1691 | /* all other cases */ |
|
- | 1692 | pll_in_use = radeon_get_pll_use_mask(crtc); |
|
- | 1693 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
|
- | 1694 | return ATOM_PPLL1; |
|
- | 1695 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
|
- | 1696 | return ATOM_PPLL2; |
|
- | 1697 | DRM_ERROR("unable to allocate a PPLL\n"); |
|
- | 1698 | return ATOM_PPLL_INVALID; |
|
- | 1699 | } else { |
|
- | 1700 | if (ASIC_IS_AVIVO(rdev)) { |
|
- | 1701 | /* in DP mode, the DP ref clock can come from either PPLL |
|
- | 1702 | * depending on the asic: |
|
- | 1703 | * DCE3: PPLL1 or PPLL2 |
|
- | 1704 | */ |
|
- | 1705 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { |
|
- | 1706 | /* use the same PPLL for all DP monitors */ |
|
- | 1707 | pll = radeon_get_shared_dp_ppll(crtc); |
|
- | 1708 | if (pll != ATOM_PPLL_INVALID) |
|
- | 1709 | return pll; |
|
- | 1710 | } else { |
|
- | 1711 | /* use the same PPLL for all monitors with the same clock */ |
|
- | 1712 | pll = radeon_get_shared_nondp_ppll(crtc); |
|
1456 | } |
1713 | if (pll != ATOM_PPLL_INVALID) |
1457 | } |
- | |
1458 | } |
- | |
1459 | - | ||
1460 | /* otherwise, pick one of the plls */ |
- | |
1461 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { |
- | |
1462 | struct radeon_crtc *radeon_test_crtc; |
1714 | return pll; |
1463 | - | ||
1464 | if (crtc == test_crtc) |
- | |
1465 | continue; |
- | |
1466 | - | ||
1467 | radeon_test_crtc = to_radeon_crtc(test_crtc); |
- | |
1468 | if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && |
1715 | } |
1469 | (radeon_test_crtc->pll_id <= ATOM_PPLL2)) |
- | |
1470 | pll_in_use |= (1 << radeon_test_crtc->pll_id); |
1716 | /* all other cases */ |
1471 | } |
1717 | pll_in_use = radeon_get_pll_use_mask(crtc); |
- | 1718 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
|
1472 | if (!(pll_in_use & 1)) |
1719 | return ATOM_PPLL1; |
- | 1720 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
|
- | 1721 | return ATOM_PPLL2; |
|
1473 | return ATOM_PPLL1; |
1722 | DRM_ERROR("unable to allocate a PPLL\n"); |
- | 1723 | return ATOM_PPLL_INVALID; |
|
1474 | return ATOM_PPLL2; |
1724 | } else { |
- | 1725 | /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ |
|
- | 1726 | return radeon_crtc->crtc_id; |
|
- | 1727 | } |
|
- | 1728 | } |
|
- | 1729 | } |
|
- | 1730 | ||
- | 1731 | void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev) |
|
- | 1732 | { |
|
- | 1733 | /* always set DCPLL */ |
|
- | 1734 | if (ASIC_IS_DCE6(rdev)) |
|
- | 1735 | atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); |
|
- | 1736 | else if (ASIC_IS_DCE4(rdev)) { |
|
- | 1737 | struct radeon_atom_ss ss; |
|
- | 1738 | bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, |
|
- | 1739 | ASIC_INTERNAL_SS_ON_DCPLL, |
|
- | 1740 | rdev->clock.default_dispclk); |
|
- | 1741 | if (ss_enabled) |
|
- | 1742 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss); |
|
- | 1743 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ |
|
- | 1744 | atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); |
|
- | 1745 | if (ss_enabled) |
|
Line 1475... | Line 1746... | ||
1475 | } else |
1746 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss); |
Line 1476... | Line 1747... | ||
1476 | return radeon_crtc->crtc_id; |
1747 | } |
1477 | 1748 | ||
Line 1483... | Line 1754... | ||
1483 | int x, int y, struct drm_framebuffer *old_fb) |
1754 | int x, int y, struct drm_framebuffer *old_fb) |
1484 | { |
1755 | { |
1485 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1756 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1486 | struct drm_device *dev = crtc->dev; |
1757 | struct drm_device *dev = crtc->dev; |
1487 | struct radeon_device *rdev = dev->dev_private; |
1758 | struct radeon_device *rdev = dev->dev_private; |
1488 | struct drm_encoder *encoder; |
1759 | struct radeon_encoder *radeon_encoder = |
- | 1760 | to_radeon_encoder(radeon_crtc->encoder); |
|
1489 | bool is_tvcv = false; |
1761 | bool is_tvcv = false; |
Line 1490... | Line -... | ||
1490 | - | ||
1491 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
- | |
1492 | /* find tv std */ |
- | |
1493 | if (encoder->crtc == crtc) { |
- | |
1494 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1762 | |
1495 | if (radeon_encoder->active_device & |
1763 | if (radeon_encoder->active_device & |
1496 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
1764 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
1497 | is_tvcv = true; |
- | |
1498 | } |
- | |
Line 1499... | Line -... | ||
1499 | } |
- | |
1500 | - | ||
1501 | /* always set DCPLL */ |
- | |
1502 | if (ASIC_IS_DCE4(rdev)) { |
- | |
1503 | struct radeon_atom_ss ss; |
- | |
1504 | bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, |
- | |
1505 | ASIC_INTERNAL_SS_ON_DCPLL, |
- | |
1506 | rdev->clock.default_dispclk); |
- | |
1507 | if (ss_enabled) |
- | |
1508 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss); |
- | |
1509 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ |
- | |
1510 | atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk); |
- | |
1511 | if (ss_enabled) |
- | |
1512 | atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss); |
1765 | is_tvcv = true; |
Line 1513... | Line 1766... | ||
1513 | } |
1766 | |
1514 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1767 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1515 | 1768 | ||
Line 1531... | Line 1784... | ||
1531 | atombios_scaler_setup(crtc); |
1784 | atombios_scaler_setup(crtc); |
1532 | return 0; |
1785 | return 0; |
1533 | } |
1786 | } |
Line 1534... | Line 1787... | ||
1534 | 1787 | ||
1535 | static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, |
1788 | static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, |
1536 | struct drm_display_mode *mode, |
1789 | const struct drm_display_mode *mode, |
1537 | struct drm_display_mode *adjusted_mode) |
1790 | struct drm_display_mode *adjusted_mode) |
- | 1791 | { |
|
1538 | { |
1792 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1539 | struct drm_device *dev = crtc->dev; |
1793 | struct drm_device *dev = crtc->dev; |
1540 | struct radeon_device *rdev = dev->dev_private; |
- | |
1541 | - | ||
1542 | /* adjust pm to upcoming mode change */ |
- | |
Line -... | Line 1794... | ||
- | 1794 | struct drm_encoder *encoder; |
|
- | 1795 | ||
- | 1796 | /* assign the encoder to the radeon crtc to avoid repeated lookups later */ |
|
- | 1797 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
|
- | 1798 | if (encoder->crtc == crtc) { |
|
- | 1799 | radeon_crtc->encoder = encoder; |
|
- | 1800 | radeon_crtc->connector = radeon_get_connector_for_encoder(encoder); |
|
- | 1801 | break; |
|
- | 1802 | } |
|
- | 1803 | } |
|
- | 1804 | if ((radeon_crtc->encoder == NULL) || (radeon_crtc->connector == NULL)) { |
|
- | 1805 | radeon_crtc->encoder = NULL; |
|
- | 1806 | radeon_crtc->connector = NULL; |
|
1543 | radeon_pm_compute_clocks(rdev); |
1807 | return false; |
1544 | 1808 | } |
|
- | 1809 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
|
- | 1810 | return false; |
|
- | 1811 | if (!atombios_crtc_prepare_pll(crtc, adjusted_mode)) |
|
- | 1812 | return false; |
|
- | 1813 | /* pick pll */ |
|
- | 1814 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); |
|
- | 1815 | /* if we can't get a PPLL for a non-DP encoder, fail */ |
|
- | 1816 | if ((radeon_crtc->pll_id == ATOM_PPLL_INVALID) && |
|
- | 1817 | !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) |
|
1545 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
1818 | return false; |
1546 | return false; |
1819 | |
Line 1547... | Line 1820... | ||
1547 | return true; |
1820 | return true; |
1548 | } |
1821 | } |
1549 | 1822 | ||
- | 1823 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
|
- | 1824 | { |
|
Line -... | Line 1825... | ||
- | 1825 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 1826 | struct drm_device *dev = crtc->dev; |
|
- | 1827 | struct radeon_device *rdev = dev->dev_private; |
|
1550 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
1828 | |
1551 | { |
1829 | radeon_crtc->in_mode_set = true; |
Line 1552... | Line 1830... | ||
1552 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1830 | |
1553 | 1831 | /* disable crtc pair power gating before programming */ |
|
1554 | /* pick pll */ |
1832 | if (ASIC_IS_DCE6(rdev)) |
Line 1555... | Line 1833... | ||
1555 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); |
1833 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
1556 | 1834 | ||
- | 1835 | atombios_lock_crtc(crtc, ATOM_ENABLE); |
|
- | 1836 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
|
1557 | atombios_lock_crtc(crtc, ATOM_ENABLE); |
1837 | } |
1558 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
1838 | |
- | 1839 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
|
1559 | } |
1840 | { |
Line 1560... | Line 1841... | ||
1560 | 1841 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
1561 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
1842 | |
1562 | { |
1843 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
- | 1844 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
|
- | 1845 | radeon_crtc->in_mode_set = false; |
|
1563 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
1846 | } |
- | 1847 | ||
Line 1564... | Line 1848... | ||
1564 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
1848 | static void atombios_crtc_disable(struct drm_crtc *crtc) |
Line -... | Line 1849... | ||
- | 1849 | { |
|
- | 1850 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 1851 | struct drm_device *dev = crtc->dev; |
|
- | 1852 | struct radeon_device *rdev = dev->dev_private; |
|
- | 1853 | struct radeon_atom_ss ss; |
|
- | 1854 | int i; |
|
- | 1855 | ||
- | 1856 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
|
- | 1857 | ||
- | 1858 | for (i = 0; i < rdev->num_crtc; i++) { |
|
- | 1859 | if (rdev->mode_info.crtcs[i] && |
|
- | 1860 | rdev->mode_info.crtcs[i]->enabled && |
|
1565 | } |
1861 | i != radeon_crtc->crtc_id && |
1566 | 1862 | radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) { |
|
1567 | static void atombios_crtc_disable(struct drm_crtc *crtc) |
1863 | /* one other crtc is using this pll don't turn |
1568 | { |
1864 | * off the pll |
1569 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1865 | */ |
1570 | struct radeon_atom_ss ss; |
1866 | goto done; |
1571 | 1867 | } |
|
- | 1868 | } |
|
- | 1869 | ||
- | 1870 | switch (radeon_crtc->pll_id) { |
|
- | 1871 | case ATOM_PPLL1: |
|
- | 1872 | case ATOM_PPLL2: |
|
- | 1873 | /* disable the ppll */ |
|
1572 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
1874 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
1573 | 1875 | 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); |
|
1574 | switch (radeon_crtc->pll_id) { |
1876 | break; |
- | 1877 | case ATOM_PPLL0: |
|
- | 1878 | /* disable the ppll */ |
|
- | 1879 | if (ASIC_IS_DCE61(rdev)) |
|
1575 | case ATOM_PPLL1: |
1880 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
- | 1881 | 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); |
|
1576 | case ATOM_PPLL2: |
1882 | break; |
Line 1577... | Line 1883... | ||
1577 | /* disable the ppll */ |
1883 | default: |
1578 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
1884 | break; |
1579 | 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); |
1885 | } |
Line 1628... | Line 1934... | ||
1628 | radeon_crtc->crtc_offset = |
1934 | radeon_crtc->crtc_offset = |
1629 | AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; |
1935 | AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; |
1630 | else |
1936 | else |
1631 | radeon_crtc->crtc_offset = 0; |
1937 | radeon_crtc->crtc_offset = 0; |
1632 | } |
1938 | } |
- | 1939 | radeon_crtc->pll_id = ATOM_PPLL_INVALID; |
|
- | 1940 | radeon_crtc->adjusted_clock = 0; |
|
1633 | radeon_crtc->pll_id = -1; |
1941 | radeon_crtc->encoder = NULL; |
- | 1942 | radeon_crtc->connector = NULL; |
|
1634 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); |
1943 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); |
1635 | }><>=>><>><>><>><>><>><>><>>><>><>=> |
1944 | }>><>><>><>><>><>><>><>><>><>><>><>><>><>>><>><>>=> |