Merge tag 'v4.6-rc7' into drm-next
Merge this back as we've built up a fair few conflicts, and I have some newer trees to pull in.
This commit is contained in:
@@ -2613,10 +2613,152 @@ static void evergreen_agp_enable(struct radeon_device *rdev)
|
||||
WREG32(VM_CONTEXT1_CNTL, 0);
|
||||
}
|
||||
|
||||
static const unsigned ni_dig_offsets[] =
|
||||
{
|
||||
NI_DIG0_REGISTER_OFFSET,
|
||||
NI_DIG1_REGISTER_OFFSET,
|
||||
NI_DIG2_REGISTER_OFFSET,
|
||||
NI_DIG3_REGISTER_OFFSET,
|
||||
NI_DIG4_REGISTER_OFFSET,
|
||||
NI_DIG5_REGISTER_OFFSET
|
||||
};
|
||||
|
||||
static const unsigned ni_tx_offsets[] =
|
||||
{
|
||||
NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1,
|
||||
NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1,
|
||||
NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1,
|
||||
NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1,
|
||||
NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1,
|
||||
NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1
|
||||
};
|
||||
|
||||
static const unsigned evergreen_dp_offsets[] =
|
||||
{
|
||||
EVERGREEN_DP0_REGISTER_OFFSET,
|
||||
EVERGREEN_DP1_REGISTER_OFFSET,
|
||||
EVERGREEN_DP2_REGISTER_OFFSET,
|
||||
EVERGREEN_DP3_REGISTER_OFFSET,
|
||||
EVERGREEN_DP4_REGISTER_OFFSET,
|
||||
EVERGREEN_DP5_REGISTER_OFFSET
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc
|
||||
* We go from crtc to connector and it is not relible since it
|
||||
* should be an opposite direction .If crtc is enable then
|
||||
* find the dig_fe which selects this crtc and insure that it enable.
|
||||
* if such dig_fe is found then find dig_be which selects found dig_be and
|
||||
* insure that it enable and in DP_SST mode.
|
||||
* if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing
|
||||
* from dp symbols clocks .
|
||||
*/
|
||||
static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev,
|
||||
unsigned crtc_id, unsigned *ret_dig_fe)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned dig_fe;
|
||||
unsigned dig_be;
|
||||
unsigned dig_en_be;
|
||||
unsigned uniphy_pll;
|
||||
unsigned digs_fe_selected;
|
||||
unsigned dig_be_mode;
|
||||
unsigned dig_fe_mask;
|
||||
bool is_enabled = false;
|
||||
bool found_crtc = false;
|
||||
|
||||
/* loop through all running dig_fe to find selected crtc */
|
||||
for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
|
||||
dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]);
|
||||
if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON &&
|
||||
crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) {
|
||||
/* found running pipe */
|
||||
found_crtc = true;
|
||||
dig_fe_mask = 1 << i;
|
||||
dig_fe = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_crtc) {
|
||||
/* loop through all running dig_be to find selected dig_fe */
|
||||
for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
|
||||
dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]);
|
||||
/* if dig_fe_selected by dig_be? */
|
||||
digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be);
|
||||
dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be);
|
||||
if (dig_fe_mask & digs_fe_selected &&
|
||||
/* if dig_be in sst mode? */
|
||||
dig_be_mode == NI_DIG_BE_DPSST) {
|
||||
dig_en_be = RREG32(NI_DIG_BE_EN_CNTL +
|
||||
ni_dig_offsets[i]);
|
||||
uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 +
|
||||
ni_tx_offsets[i]);
|
||||
/* dig_be enable and tx is running */
|
||||
if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE &&
|
||||
dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON &&
|
||||
uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) {
|
||||
is_enabled = true;
|
||||
*ret_dig_fe = dig_fe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return is_enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
* Blank dig when in dp sst mode
|
||||
* Dig ignores crtc timing
|
||||
*/
|
||||
static void evergreen_blank_dp_output(struct radeon_device *rdev,
|
||||
unsigned dig_fe)
|
||||
{
|
||||
unsigned stream_ctrl;
|
||||
unsigned fifo_ctrl;
|
||||
unsigned counter = 0;
|
||||
|
||||
if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) {
|
||||
DRM_ERROR("invalid dig_fe %d\n", dig_fe);
|
||||
return;
|
||||
}
|
||||
|
||||
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
|
||||
evergreen_dp_offsets[dig_fe]);
|
||||
if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) {
|
||||
DRM_ERROR("dig %d , should be enable\n", dig_fe);
|
||||
return;
|
||||
}
|
||||
|
||||
stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE;
|
||||
WREG32(EVERGREEN_DP_VID_STREAM_CNTL +
|
||||
evergreen_dp_offsets[dig_fe], stream_ctrl);
|
||||
|
||||
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
|
||||
evergreen_dp_offsets[dig_fe]);
|
||||
while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) {
|
||||
msleep(1);
|
||||
counter++;
|
||||
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
|
||||
evergreen_dp_offsets[dig_fe]);
|
||||
}
|
||||
if (counter >= 32 )
|
||||
DRM_ERROR("counter exceeds %d\n", counter);
|
||||
|
||||
fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]);
|
||||
fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET;
|
||||
WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl);
|
||||
|
||||
}
|
||||
|
||||
void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
|
||||
{
|
||||
u32 crtc_enabled, tmp, frame_count, blackout;
|
||||
int i, j;
|
||||
unsigned dig_fe;
|
||||
|
||||
if (!ASIC_IS_NODCE(rdev)) {
|
||||
save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
|
||||
@@ -2656,7 +2798,17 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
/*we should disable dig if it drives dp sst*/
|
||||
/*but we are in radeon_device_init and the topology is unknown*/
|
||||
/*and it is available after radeon_modeset_init*/
|
||||
/*the following method radeon_atom_encoder_dpms_dig*/
|
||||
/*does the job if we initialize it properly*/
|
||||
/*for now we do it this manually*/
|
||||
/**/
|
||||
if (ASIC_IS_DCE5(rdev) &&
|
||||
evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe))
|
||||
evergreen_blank_dp_output(rdev, dig_fe);
|
||||
/*we could remove 6 lines below*/
|
||||
/* XXX this is a hack to avoid strange behavior with EFI on certain systems */
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
|
||||
tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
|
||||
|
Reference in New Issue
Block a user