summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/radeon_dp_mst.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-04-15 14:59:28 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-04-15 14:59:28 -0700
commitab5f9ebac1fcdf7feaf41a55e463e181ea0b4ea2 (patch)
treec9e3d2571a83ed9793866d7635163b5c1761ebb7 /drivers/gpu/drm/radeon/radeon_dp_mst.c
parent60ea7bb0077b38f80a3a27b9e32ad45879944a57 (diff)
parentff3e84e8e479c3ba7148f8dc35a56cf091ab56d9 (diff)
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "This contains fixes for exynos, amdgpu, radeon, i915 and qxl. It also contains some fixes to the core drm edid parser. qxl: - fix for a cursor hotspot issue radeon: - some MST fixes that I've been running locally and make my monitor a bit happier exynos: - fix some regressions and build fixes amdgpu: - a couple of small fixes i915: - two DP MST fixes and a couple of other regression fixes Nothing too out of the ordinary or surprising at this point" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/exynos: Use VIDEO_SAMSUNG_S5P_G2D=n as G2D Kconfig dependency drm/exynos: fix a warning message drm/exynos: mic: fix an error code drm/exynos: fimd: fix broken dp_clock control drm/exynos: build fbdev code conditionally drm/exynos: fix adjusted_mode pointer in exynos_plane_mode_set drm/exynos: fix error handling in exynos_drm_subdrv_open drm/amd/amdgpu: fix irq domain remove for tonga ih drm/i915: fix deadlock on lid open drm/radeon: use helper for mst connector dpms. drm/radeon/mst: port some MST setup code from DAL. drm/amdgpu: add invisible pin size statistic drm/edid: Fix DMT 1024x768@43Hz (interlaced) timings drm/i915: Exit cherryview_irq_handler() after one pass drm/i915: Call intel_dp_mst_resume() before resuming displays drm/i915: Fix race condition in intel_dp_destroy_mst_connector() drm/edid: Fix parsing of EDID 1.4 Established Timings III descriptor drm/edid: Fix EDID Established Timings I and II drm/qxl: fix cursor position with non-zero hotspot
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_dp_mst.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_dp_mst.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 43cffb526b0c..de504ea29c06 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -89,8 +89,16 @@ static int radeon_dp_mst_set_stream_attrib(struct radeon_encoder *primary,
WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1);
do {
+ unsigned value1, value2;
+ udelay(10);
temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset);
- } while ((temp & 0x1) && retries++ < 10000);
+
+ value1 = temp & NI_DP_MSE_SAT_UPDATE_MASK;
+ value2 = temp & NI_DP_MSE_16_MTP_KEEPOUT;
+
+ if (!value1 && !value2)
+ break;
+ } while (retries++ < 50);
if (retries == 10000)
DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset);
@@ -150,7 +158,7 @@ static int radeon_dp_mst_update_stream_attribs(struct radeon_connector *mst_conn
return 0;
}
-static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, uint32_t y)
+static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, s64 avg_time_slots_per_mtp)
{
struct drm_device *dev = mst->base.dev;
struct radeon_device *rdev = dev->dev_private;
@@ -158,6 +166,8 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui
uint32_t val, temp;
uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe);
int retries = 0;
+ uint32_t x = drm_fixp2int(avg_time_slots_per_mtp);
+ uint32_t y = drm_fixp2int_ceil((avg_time_slots_per_mtp - x) << 26);
val = NI_DP_MSE_RATE_X(x) | NI_DP_MSE_RATE_Y(y);
@@ -165,6 +175,7 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui
do {
temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset);
+ udelay(10);
} while ((temp & 0x1) && (retries++ < 10000));
if (retries >= 10000)
@@ -246,14 +257,8 @@ radeon_dp_mst_connector_destroy(struct drm_connector *connector)
kfree(radeon_connector);
}
-static int radeon_connector_dpms(struct drm_connector *connector, int mode)
-{
- DRM_DEBUG_KMS("\n");
- return 0;
-}
-
static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = {
- .dpms = radeon_connector_dpms,
+ .dpms = drm_helper_connector_dpms,
.detect = radeon_dp_mst_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = radeon_dp_mst_connector_destroy,
@@ -394,7 +399,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
struct drm_crtc *crtc;
struct radeon_crtc *radeon_crtc;
int ret, slots;
-
+ s64 fixed_pbn, fixed_pbn_per_slot, avg_time_slots_per_mtp;
if (!ASIC_IS_DCE5(rdev)) {
DRM_ERROR("got mst dpms on non-DCE5\n");
return;
@@ -456,7 +461,11 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
mst_enc->enc_active = true;
radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary);
- radeon_dp_mst_set_vcp_size(radeon_encoder, slots, 0);
+
+ fixed_pbn = drm_int2fixp(mst_enc->pbn);
+ fixed_pbn_per_slot = drm_int2fixp(radeon_connector->mst_port->mst_mgr.pbn_div);
+ avg_time_slots_per_mtp = drm_fixp_div(fixed_pbn, fixed_pbn_per_slot);
+ radeon_dp_mst_set_vcp_size(radeon_encoder, avg_time_slots_per_mtp);
atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0,
mst_enc->fe);