aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-07-02 07:26:27 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-09-06 01:58:18 -0400
commit19d8fe154497bc48e25cbed61066731daca3df43 (patch)
treecc1c1ab95e56bf7b451568e09be91d8181184e6b /drivers/gpu/drm
parentf0947c376f6944ade7079df9f84bbc958a893e0f (diff)
drm/i915/dp: implement get_hw_state
Also add some macros to make the pipe computation a bit easier. v2: I've mixed up the CPT and !CPT PORT_TO_PIPE macro variants ... Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c50
2 files changed, 52 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index fd6a26a49b42..1e5f77a4a1e2 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4029,6 +4029,8 @@
4029#define PORT_TRANS_C_SEL_CPT (2<<29) 4029#define PORT_TRANS_C_SEL_CPT (2<<29)
4030#define PORT_TRANS_SEL_MASK (3<<29) 4030#define PORT_TRANS_SEL_MASK (3<<29)
4031#define PORT_TRANS_SEL_CPT(pipe) ((pipe) << 29) 4031#define PORT_TRANS_SEL_CPT(pipe) ((pipe) << 29)
4032#define PORT_TO_PIPE(val) (((val) & (1<<30)) >> 30)
4033#define PORT_TO_PIPE_CPT(val) (((val) & PORT_TRANS_SEL_MASK) >> 29)
4032 4034
4033#define TRANS_DP_CTL_A 0xe0300 4035#define TRANS_DP_CTL_A 0xe0300
4034#define TRANS_DP_CTL_B 0xe1300 4036#define TRANS_DP_CTL_B 0xe1300
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ff993a01d039..e3928b922825 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1250,6 +1250,54 @@ static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
1250 } 1250 }
1251} 1251}
1252 1252
1253static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
1254 enum pipe *pipe)
1255{
1256 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
1257 struct drm_device *dev = encoder->base.dev;
1258 struct drm_i915_private *dev_priv = dev->dev_private;
1259 u32 tmp = I915_READ(intel_dp->output_reg);
1260
1261 if (!(tmp & DP_PORT_EN))
1262 return false;
1263
1264 if (is_cpu_edp(intel_dp) && IS_GEN7(dev)) {
1265 *pipe = PORT_TO_PIPE_CPT(tmp);
1266 } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
1267 *pipe = PORT_TO_PIPE(tmp);
1268 } else {
1269 u32 trans_sel;
1270 u32 trans_dp;
1271 int i;
1272
1273 switch (intel_dp->output_reg) {
1274 case PCH_DP_B:
1275 trans_sel = TRANS_DP_PORT_SEL_B;
1276 break;
1277 case PCH_DP_C:
1278 trans_sel = TRANS_DP_PORT_SEL_C;
1279 break;
1280 case PCH_DP_D:
1281 trans_sel = TRANS_DP_PORT_SEL_D;
1282 break;
1283 default:
1284 return true;
1285 }
1286
1287 for_each_pipe(i) {
1288 trans_dp = I915_READ(TRANS_DP_CTL(i));
1289 if ((trans_dp & TRANS_DP_PORT_SEL_MASK) == trans_sel) {
1290 *pipe = i;
1291 return true;
1292 }
1293 }
1294 }
1295
1296 DRM_DEBUG_KMS("No pipe for dp port 0x%x found\n", intel_dp->output_reg);
1297
1298 return true;
1299}
1300
1253static void intel_disable_dp(struct intel_encoder *encoder) 1301static void intel_disable_dp(struct intel_encoder *encoder)
1254{ 1302{
1255 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); 1303 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
@@ -2486,6 +2534,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
2486 2534
2487 intel_encoder->enable = intel_enable_dp; 2535 intel_encoder->enable = intel_enable_dp;
2488 intel_encoder->disable = intel_disable_dp; 2536 intel_encoder->disable = intel_disable_dp;
2537 intel_encoder->get_hw_state = intel_dp_get_hw_state;
2538 intel_connector->get_hw_state = intel_connector_get_hw_state;
2489 2539
2490 /* Set up the DDC bus. */ 2540 /* Set up the DDC bus. */
2491 switch (port) { 2541 switch (port) {