radeon_hd: rework some pll code
* Force fractional feedback divider on APU's * Spread Spectrum is now probed more correctly across multiple encoders and cards * SS still disabled however.
This commit is contained in:
parent
63624e404b
commit
817c114de7
|
@ -255,9 +255,6 @@ radeon_init_accelerant(int device)
|
|||
// probe firmware information
|
||||
radeon_gpu_probe();
|
||||
|
||||
// disable spread spectrum as it requires lots of extra calculations
|
||||
radeon_gpu_ss_disable();
|
||||
|
||||
// program external pll clock
|
||||
pll_external_init();
|
||||
|
||||
|
|
|
@ -76,6 +76,8 @@ struct accelerant_info {
|
|||
uint32 displayClockFrequency;
|
||||
uint32 dpExternalClock;
|
||||
|
||||
uint32 lvdsSpreadSpectrumID;
|
||||
|
||||
RingQueue* ringQueue[RADEON_QUEUE_MAX]; // Ring buffer command processor
|
||||
};
|
||||
|
||||
|
|
|
@ -200,6 +200,9 @@ connector_read_mode_lvds(uint32 connectorIndex, display_mode* mode)
|
|||
// Store special lvds flags the encoder setup needs
|
||||
gConnector[connectorIndex]->lvdsFlags = lvdsInfo->info.ucLVDS_Misc;
|
||||
|
||||
// Spread Spectrum ID (in SS table)
|
||||
gInfo->lvdsSpreadSpectrumID = lvdsInfo->info.ucSS_Id;
|
||||
|
||||
uint16 flags = B_LENDIAN_TO_HOST_INT16(
|
||||
lvdsInfo->info.sLCDTiming.susModeMiscInfo.usAccess);
|
||||
|
||||
|
|
|
@ -951,8 +951,7 @@ display_crtc_ss(uint8 crtcID, int command)
|
|||
} else if (info.dceMajor >= 2) {
|
||||
if ((command == ATOM_DISABLE) || (pll->ssPercentage == 0)
|
||||
|| (pll->ssType & ATOM_EXTERNAL_SS_MASK)) {
|
||||
// TODO: gpu_ss_disable needs pll id
|
||||
radeon_gpu_ss_disable();
|
||||
radeon_gpu_ss_control(pll, false);
|
||||
return;
|
||||
}
|
||||
args.lvds_ss_2.usSpreadSpectrumPercentage
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "accelerant.h"
|
||||
#include "atom.h"
|
||||
#include "bios.h"
|
||||
#include "pll.h"
|
||||
#include "utility.h"
|
||||
|
||||
|
||||
|
@ -715,7 +716,7 @@ radeon_gpu_ring_boot(uint32 ringType)
|
|||
|
||||
|
||||
status_t
|
||||
radeon_gpu_ss_disable()
|
||||
radeon_gpu_ss_control(pll_info* pll, bool enable)
|
||||
{
|
||||
TRACE("%s called\n", __func__);
|
||||
|
||||
|
@ -723,25 +724,52 @@ radeon_gpu_ss_disable()
|
|||
uint32 ssControl;
|
||||
|
||||
if (info.chipsetID >= RADEON_CEDAR) {
|
||||
// PLL1
|
||||
ssControl = Read32(OUT, EVERGREEN_P1PLL_SS_CNTL);
|
||||
ssControl &= ~EVERGREEN_PxPLL_SS_EN;
|
||||
Write32(OUT, EVERGREEN_P1PLL_SS_CNTL, ssControl);
|
||||
// PLL2
|
||||
ssControl = Read32(OUT, EVERGREEN_P2PLL_SS_CNTL);
|
||||
ssControl &= ~EVERGREEN_PxPLL_SS_EN;
|
||||
Write32(OUT, EVERGREEN_P2PLL_SS_CNTL, ssControl);
|
||||
switch (pll->id) {
|
||||
case ATOM_PPLL1:
|
||||
// PLL1
|
||||
ssControl = Read32(OUT, EVERGREEN_P1PLL_SS_CNTL);
|
||||
if (enable)
|
||||
ssControl |= EVERGREEN_PxPLL_SS_EN;
|
||||
else
|
||||
ssControl &= ~EVERGREEN_PxPLL_SS_EN;
|
||||
Write32(OUT, EVERGREEN_P1PLL_SS_CNTL, ssControl);
|
||||
break;
|
||||
case ATOM_PPLL2:
|
||||
// PLL2
|
||||
ssControl = Read32(OUT, EVERGREEN_P2PLL_SS_CNTL);
|
||||
if (enable)
|
||||
ssControl |= EVERGREEN_PxPLL_SS_EN;
|
||||
else
|
||||
ssControl &= ~EVERGREEN_PxPLL_SS_EN;
|
||||
Write32(OUT, EVERGREEN_P2PLL_SS_CNTL, ssControl);
|
||||
break;
|
||||
}
|
||||
// DCPLL, no action
|
||||
return B_OK;
|
||||
} else if (info.chipsetID >= RADEON_RS600) {
|
||||
// PLL1
|
||||
ssControl = Read32(OUT, AVIVO_P1PLL_INT_SS_CNTL);
|
||||
ssControl &= ~1;
|
||||
Write32(OUT, AVIVO_P1PLL_INT_SS_CNTL, ssControl);
|
||||
// PLL2
|
||||
ssControl = Read32(OUT, AVIVO_P2PLL_INT_SS_CNTL);
|
||||
ssControl &= ~1;
|
||||
Write32(OUT, AVIVO_P2PLL_INT_SS_CNTL, ssControl);
|
||||
} else
|
||||
return B_ERROR;
|
||||
switch (pll->id) {
|
||||
case ATOM_PPLL1:
|
||||
// PLL1
|
||||
ssControl = Read32(OUT, AVIVO_P1PLL_INT_SS_CNTL);
|
||||
if (enable)
|
||||
ssControl |= 1;
|
||||
else
|
||||
ssControl &= ~1;
|
||||
Write32(OUT, AVIVO_P1PLL_INT_SS_CNTL, ssControl);
|
||||
break;
|
||||
case ATOM_PPLL2:
|
||||
// PLL2
|
||||
ssControl = Read32(OUT, AVIVO_P2PLL_INT_SS_CNTL);
|
||||
if (enable)
|
||||
ssControl |= 1;
|
||||
else
|
||||
ssControl &= ~1;
|
||||
Write32(OUT, AVIVO_P2PLL_INT_SS_CNTL, ssControl);
|
||||
break;
|
||||
}
|
||||
// DCPLL, no action
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include <video_configuration.h>
|
||||
|
||||
#include "pll.h"
|
||||
|
||||
|
||||
// GPU Control registers. These are combined as
|
||||
// the registers exist on all models, some flags
|
||||
|
@ -172,7 +174,8 @@ status_t radeon_gpu_mc_idlewait();
|
|||
status_t radeon_gpu_mc_setup();
|
||||
status_t radeon_gpu_ring_setup();
|
||||
status_t radeon_gpu_ring_boot(uint32 ringType);
|
||||
status_t radeon_gpu_ss_disable();
|
||||
status_t radeon_gpu_ss_control(pll_info* pll, bool enable);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -128,7 +128,7 @@ pll_limit_probe(pll_info* pll)
|
|||
|
||||
|
||||
status_t
|
||||
pll_dp_ss_probe(pll_info* pll)
|
||||
pll_ppll_ss_probe(pll_info* pll, uint32 ssID)
|
||||
{
|
||||
uint8 tableMajor;
|
||||
uint8 tableMinor;
|
||||
|
@ -151,7 +151,7 @@ pll_dp_ss_probe(pll_info* pll)
|
|||
|
||||
int i;
|
||||
for (i = 0; i < indices; i++) {
|
||||
if (ss_info->asSS_Info[i].ucSS_Id == pll->id) {
|
||||
if (ss_info->asSS_Info[i].ucSS_Id == ssID) {
|
||||
pll->ssPercentage = B_LENDIAN_TO_HOST_INT16(
|
||||
ss_info->asSS_Info[i].usSpreadSpectrumPercentage);
|
||||
pll->ssType = ss_info->asSS_Info[i].ucSpreadSpectrumType;
|
||||
|
@ -175,7 +175,7 @@ pll_dp_ss_probe(pll_info* pll)
|
|||
|
||||
|
||||
status_t
|
||||
pll_asic_ss_probe(pll_info* pll)
|
||||
pll_asic_ss_probe(pll_info* pll, uint32 ssID)
|
||||
{
|
||||
uint8 tableMajor;
|
||||
uint8 tableMinor;
|
||||
|
@ -207,7 +207,7 @@ pll_asic_ss_probe(pll_info* pll)
|
|||
|
||||
for (i = 0; i < indices; i++) {
|
||||
if (ss_info->info.asSpreadSpectrum[i].ucClockIndication
|
||||
!= pll->id) {
|
||||
!= ssID) {
|
||||
continue;
|
||||
}
|
||||
TRACE("%s: ss match found\n", __func__);
|
||||
|
@ -234,7 +234,7 @@ pll_asic_ss_probe(pll_info* pll)
|
|||
|
||||
for (i = 0; i < indices; i++) {
|
||||
if (ss_info->info_2.asSpreadSpectrum[i].ucClockIndication
|
||||
!= pll->id) {
|
||||
!= ssID) {
|
||||
continue;
|
||||
}
|
||||
TRACE("%s: ss match found\n", __func__);
|
||||
|
@ -262,7 +262,7 @@ pll_asic_ss_probe(pll_info* pll)
|
|||
|
||||
for (i = 0; i < indices; i++) {
|
||||
if (ss_info->info_3.asSpreadSpectrum[i].ucClockIndication
|
||||
!= pll->id) {
|
||||
!= ssID) {
|
||||
continue;
|
||||
}
|
||||
TRACE("%s: ss match found\n", __func__);
|
||||
|
@ -492,6 +492,11 @@ pll_setup_flags(pll_info* pll, uint8 crtcID)
|
|||
|
||||
if ((encoderFlags & ATOM_DEVICE_TV_SUPPORT) != 0)
|
||||
pll->flags |= PLL_PREFER_CLOSEST_LOWER;
|
||||
|
||||
if ((info.chipsetFlags & CHIP_APU) != 0) {
|
||||
// Use fractional feedback on APU's
|
||||
pll->flags |= PLL_USE_FRAC_FB_DIV;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -657,12 +662,38 @@ pll_set(display_mode* mode, uint8 crtcID)
|
|||
pll_compute(pll);
|
||||
// compute dividers
|
||||
|
||||
pll_asic_ss_probe(pll);
|
||||
// probe spread spectrum metrics (TODO: pll_dp_ss_probe)
|
||||
radeon_shared_info &info = *gInfo->shared_info;
|
||||
pll->ssType = 0;
|
||||
|
||||
switch (display_get_encoder_mode(connectorIndex)) {
|
||||
case ATOM_ENCODER_MODE_DP_MST:
|
||||
case ATOM_ENCODER_MODE_DP:
|
||||
if (info.dceMajor >= 4)
|
||||
pll_asic_ss_probe(pll, ASIC_INTERNAL_SS_ON_DP);
|
||||
else {
|
||||
// TODO: DP Clock == 1.62Ghz?
|
||||
pll_ppll_ss_probe(pll, ATOM_DP_SS_ID1);
|
||||
}
|
||||
break;
|
||||
case ATOM_ENCODER_MODE_LVDS:
|
||||
if (info.dceMajor >= 4)
|
||||
pll_asic_ss_probe(pll, gInfo->lvdsSpreadSpectrumID);
|
||||
else
|
||||
pll_ppll_ss_probe(pll, gInfo->lvdsSpreadSpectrumID);
|
||||
break;
|
||||
case ATOM_ENCODER_MODE_DVI:
|
||||
if (info.dceMajor >= 4)
|
||||
pll_asic_ss_probe(pll, ASIC_INTERNAL_SS_ON_TMDS);
|
||||
break;
|
||||
case ATOM_ENCODER_MODE_HDMI:
|
||||
if (info.dceMajor >= 4)
|
||||
pll_asic_ss_probe(pll, ASIC_INTERNAL_SS_ON_HDMI);
|
||||
break;
|
||||
}
|
||||
|
||||
display_crtc_ss(crtcID, ATOM_DISABLE);
|
||||
// disable ss
|
||||
|
||||
|
||||
uint8 tableMajor;
|
||||
uint8 tableMinor;
|
||||
|
||||
|
|
|
@ -103,8 +103,8 @@ status_t pll_adjust(pll_info* pll, display_mode* mode, uint8 crtcID);
|
|||
status_t pll_compute(pll_info* pll);
|
||||
void pll_setup_flags(pll_info* pll, uint8 crtcID);
|
||||
status_t pll_limit_probe(pll_info* pll);
|
||||
status_t pll_dp_ss_probe(pll_info* pll);
|
||||
status_t pll_asic_ss_probe(pll_info* pll);
|
||||
status_t pll_ppll_ss_probe(pll_info* pll, uint32 ssID);
|
||||
status_t pll_asic_ss_probe(pll_info* pll, uint32 ssID);
|
||||
status_t pll_set(display_mode* mode, uint8 crtcID);
|
||||
status_t pll_pick(uint32 connectorIndex);
|
||||
|
||||
|
|
Loading…
Reference in New Issue