diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2014-04-09 06:29:05 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-06-11 10:57:29 -0400 |
commit | 9197c88bf946cf792ad5124f00bd51a0bc18f8c2 (patch) | |
tree | fc3f7a0357006194bd7b7dd06ba59f7bc249f22b | |
parent | 13a5660c137e4c9ca88e0bb20d518eff016bcfbc (diff) |
drm/i915/chv: Try to program the PHY used clock channel overrides
These should make it possible to feed port C from pipe A or port B from
pipe B. Didn't quite seem to work though.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 46 |
3 files changed, 99 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 53db3a2db3df..fd541fc7d70d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -771,6 +771,8 @@ enum punit_power_well { | |||
771 | 771 | ||
772 | #define _VLV_PCS_DW8_CH0 0x8220 | 772 | #define _VLV_PCS_DW8_CH0 0x8220 |
773 | #define _VLV_PCS_DW8_CH1 0x8420 | 773 | #define _VLV_PCS_DW8_CH1 0x8420 |
774 | #define CHV_PCS_USEDCLKCHANNEL_OVRRIDE (1 << 20) | ||
775 | #define CHV_PCS_USEDCLKCHANNEL (1 << 21) | ||
774 | #define VLV_PCS_DW8(ch) _PORT(ch, _VLV_PCS_DW8_CH0, _VLV_PCS_DW8_CH1) | 776 | #define VLV_PCS_DW8(ch) _PORT(ch, _VLV_PCS_DW8_CH0, _VLV_PCS_DW8_CH1) |
775 | 777 | ||
776 | #define _VLV_PCS01_DW8_CH0 0x0220 | 778 | #define _VLV_PCS01_DW8_CH0 0x0220 |
@@ -895,6 +897,11 @@ enum punit_power_well { | |||
895 | #define DPIO_DCLKP_EN (1 << 13) | 897 | #define DPIO_DCLKP_EN (1 << 13) |
896 | #define CHV_CMN_DW14(ch) _PIPE(ch, _CHV_CMN_DW14_CH0, _CHV_CMN_DW1_CH1) | 898 | #define CHV_CMN_DW14(ch) _PIPE(ch, _CHV_CMN_DW14_CH0, _CHV_CMN_DW1_CH1) |
897 | 899 | ||
900 | #define _CHV_CMN_DW19_CH0 0x814c | ||
901 | #define _CHV_CMN_DW6_CH1 0x8098 | ||
902 | #define CHV_CMN_USEDCLKCHANNEL (1 << 13) | ||
903 | #define CHV_CMN_DW19(ch) _PIPE(ch, _CHV_CMN_DW19_CH0, _CHV_CMN_DW6_CH1) | ||
904 | |||
898 | #define CHV_CMN_DW30 0x8178 | 905 | #define CHV_CMN_DW30 0x8178 |
899 | #define DPIO_LRC_BYPASS (1 << 3) | 906 | #define DPIO_LRC_BYPASS (1 << 3) |
900 | 907 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 82edfbceb1ff..709f049114dd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -2119,6 +2119,51 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) | |||
2119 | vlv_wait_port_ready(dev_priv, dport); | 2119 | vlv_wait_port_ready(dev_priv, dport); |
2120 | } | 2120 | } |
2121 | 2121 | ||
2122 | static void chv_dp_pre_pll_enable(struct intel_encoder *encoder) | ||
2123 | { | ||
2124 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | ||
2125 | struct drm_device *dev = encoder->base.dev; | ||
2126 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2127 | struct intel_crtc *intel_crtc = | ||
2128 | to_intel_crtc(encoder->base.crtc); | ||
2129 | enum dpio_channel ch = vlv_dport_to_channel(dport); | ||
2130 | enum pipe pipe = intel_crtc->pipe; | ||
2131 | u32 val; | ||
2132 | |||
2133 | mutex_lock(&dev_priv->dpio_lock); | ||
2134 | |||
2135 | /* program clock channel usage */ | ||
2136 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch)); | ||
2137 | val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE; | ||
2138 | if (pipe != PIPE_B) | ||
2139 | val &= ~CHV_PCS_USEDCLKCHANNEL; | ||
2140 | else | ||
2141 | val |= CHV_PCS_USEDCLKCHANNEL; | ||
2142 | vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val); | ||
2143 | |||
2144 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch)); | ||
2145 | val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE; | ||
2146 | if (pipe != PIPE_B) | ||
2147 | val &= ~CHV_PCS_USEDCLKCHANNEL; | ||
2148 | else | ||
2149 | val |= CHV_PCS_USEDCLKCHANNEL; | ||
2150 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val); | ||
2151 | |||
2152 | /* | ||
2153 | * This a a bit weird since generally CL | ||
2154 | * matches the pipe, but here we need to | ||
2155 | * pick the CL based on the port. | ||
2156 | */ | ||
2157 | val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch)); | ||
2158 | if (pipe != PIPE_B) | ||
2159 | val &= ~CHV_CMN_USEDCLKCHANNEL; | ||
2160 | else | ||
2161 | val |= CHV_CMN_USEDCLKCHANNEL; | ||
2162 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val); | ||
2163 | |||
2164 | mutex_unlock(&dev_priv->dpio_lock); | ||
2165 | } | ||
2166 | |||
2122 | /* | 2167 | /* |
2123 | * Native read with retry for link status and receiver capability reads for | 2168 | * Native read with retry for link status and receiver capability reads for |
2124 | * cases where the sink may still be asleep. | 2169 | * cases where the sink may still be asleep. |
@@ -4335,6 +4380,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) | |||
4335 | intel_encoder->get_hw_state = intel_dp_get_hw_state; | 4380 | intel_encoder->get_hw_state = intel_dp_get_hw_state; |
4336 | intel_encoder->get_config = intel_dp_get_config; | 4381 | intel_encoder->get_config = intel_dp_get_config; |
4337 | if (IS_CHERRYVIEW(dev)) { | 4382 | if (IS_CHERRYVIEW(dev)) { |
4383 | intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; | ||
4338 | intel_encoder->pre_enable = chv_pre_enable_dp; | 4384 | intel_encoder->pre_enable = chv_pre_enable_dp; |
4339 | intel_encoder->enable = vlv_enable_dp; | 4385 | intel_encoder->enable = vlv_enable_dp; |
4340 | intel_encoder->post_disable = chv_post_disable_dp; | 4386 | intel_encoder->post_disable = chv_post_disable_dp; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index eee2bbec2958..8da29d158315 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -1229,6 +1229,51 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder) | |||
1229 | mutex_unlock(&dev_priv->dpio_lock); | 1229 | mutex_unlock(&dev_priv->dpio_lock); |
1230 | } | 1230 | } |
1231 | 1231 | ||
1232 | static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder) | ||
1233 | { | ||
1234 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | ||
1235 | struct drm_device *dev = encoder->base.dev; | ||
1236 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1237 | struct intel_crtc *intel_crtc = | ||
1238 | to_intel_crtc(encoder->base.crtc); | ||
1239 | enum dpio_channel ch = vlv_dport_to_channel(dport); | ||
1240 | enum pipe pipe = intel_crtc->pipe; | ||
1241 | u32 val; | ||
1242 | |||
1243 | mutex_lock(&dev_priv->dpio_lock); | ||
1244 | |||
1245 | /* program clock channel usage */ | ||
1246 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch)); | ||
1247 | val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE; | ||
1248 | if (pipe != PIPE_B) | ||
1249 | val &= ~CHV_PCS_USEDCLKCHANNEL; | ||
1250 | else | ||
1251 | val |= CHV_PCS_USEDCLKCHANNEL; | ||
1252 | vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val); | ||
1253 | |||
1254 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch)); | ||
1255 | val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE; | ||
1256 | if (pipe != PIPE_B) | ||
1257 | val &= ~CHV_PCS_USEDCLKCHANNEL; | ||
1258 | else | ||
1259 | val |= CHV_PCS_USEDCLKCHANNEL; | ||
1260 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val); | ||
1261 | |||
1262 | /* | ||
1263 | * This a a bit weird since generally CL | ||
1264 | * matches the pipe, but here we need to | ||
1265 | * pick the CL based on the port. | ||
1266 | */ | ||
1267 | val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch)); | ||
1268 | if (pipe != PIPE_B) | ||
1269 | val &= ~CHV_CMN_USEDCLKCHANNEL; | ||
1270 | else | ||
1271 | val |= CHV_CMN_USEDCLKCHANNEL; | ||
1272 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val); | ||
1273 | |||
1274 | mutex_unlock(&dev_priv->dpio_lock); | ||
1275 | } | ||
1276 | |||
1232 | static void vlv_hdmi_post_disable(struct intel_encoder *encoder) | 1277 | static void vlv_hdmi_post_disable(struct intel_encoder *encoder) |
1233 | { | 1278 | { |
1234 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 1279 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
@@ -1528,6 +1573,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) | |||
1528 | intel_encoder->get_hw_state = intel_hdmi_get_hw_state; | 1573 | intel_encoder->get_hw_state = intel_hdmi_get_hw_state; |
1529 | intel_encoder->get_config = intel_hdmi_get_config; | 1574 | intel_encoder->get_config = intel_hdmi_get_config; |
1530 | if (IS_CHERRYVIEW(dev)) { | 1575 | if (IS_CHERRYVIEW(dev)) { |
1576 | intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable; | ||
1531 | intel_encoder->pre_enable = chv_hdmi_pre_enable; | 1577 | intel_encoder->pre_enable = chv_hdmi_pre_enable; |
1532 | intel_encoder->enable = vlv_enable_hdmi; | 1578 | intel_encoder->enable = vlv_enable_hdmi; |
1533 | intel_encoder->post_disable = chv_hdmi_post_disable; | 1579 | intel_encoder->post_disable = chv_hdmi_post_disable; |