diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c42b636c2087..06679f164b3e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -74,7 +74,7 @@ struct intel_sdvo { | |||
| 74 | struct i2c_adapter ddc; | 74 | struct i2c_adapter ddc; |
| 75 | 75 | ||
| 76 | /* Register for the SDVO device: SDVOB or SDVOC */ | 76 | /* Register for the SDVO device: SDVOB or SDVOC */ |
| 77 | uint32_t sdvo_reg; | 77 | i915_reg_t sdvo_reg; |
| 78 | 78 | ||
| 79 | /* Active outputs controlled by this SDVO output */ | 79 | /* Active outputs controlled by this SDVO output */ |
| 80 | uint16_t controlled_output; | 80 | uint16_t controlled_output; |
| @@ -120,8 +120,7 @@ struct intel_sdvo { | |||
| 120 | */ | 120 | */ |
| 121 | bool is_tv; | 121 | bool is_tv; |
| 122 | 122 | ||
| 123 | /* On different gens SDVOB is at different places. */ | 123 | enum port port; |
| 124 | bool is_sdvob; | ||
| 125 | 124 | ||
| 126 | /* This is for current tv format name */ | 125 | /* This is for current tv format name */ |
| 127 | int tv_format_index; | 126 | int tv_format_index; |
| @@ -245,7 +244,7 @@ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) | |||
| 245 | u32 bval = val, cval = val; | 244 | u32 bval = val, cval = val; |
| 246 | int i; | 245 | int i; |
| 247 | 246 | ||
| 248 | if (intel_sdvo->sdvo_reg == PCH_SDVOB) { | 247 | if (HAS_PCH_SPLIT(dev_priv)) { |
| 249 | I915_WRITE(intel_sdvo->sdvo_reg, val); | 248 | I915_WRITE(intel_sdvo->sdvo_reg, val); |
| 250 | POSTING_READ(intel_sdvo->sdvo_reg); | 249 | POSTING_READ(intel_sdvo->sdvo_reg); |
| 251 | /* | 250 | /* |
| @@ -259,7 +258,7 @@ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) | |||
| 259 | return; | 258 | return; |
| 260 | } | 259 | } |
| 261 | 260 | ||
| 262 | if (intel_sdvo->sdvo_reg == GEN3_SDVOB) | 261 | if (intel_sdvo->port == PORT_B) |
| 263 | cval = I915_READ(GEN3_SDVOC); | 262 | cval = I915_READ(GEN3_SDVOC); |
| 264 | else | 263 | else |
| 265 | bval = I915_READ(GEN3_SDVOB); | 264 | bval = I915_READ(GEN3_SDVOB); |
| @@ -422,7 +421,7 @@ static const struct _sdvo_cmd_name { | |||
| 422 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), | 421 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), |
| 423 | }; | 422 | }; |
| 424 | 423 | ||
| 425 | #define SDVO_NAME(svdo) ((svdo)->is_sdvob ? "SDVOB" : "SDVOC") | 424 | #define SDVO_NAME(svdo) ((svdo)->port == PORT_B ? "SDVOB" : "SDVOC") |
| 426 | 425 | ||
| 427 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, | 426 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, |
| 428 | const void *args, int args_len) | 427 | const void *args, int args_len) |
| @@ -1282,14 +1281,10 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder) | |||
| 1282 | sdvox |= SDVO_BORDER_ENABLE; | 1281 | sdvox |= SDVO_BORDER_ENABLE; |
| 1283 | } else { | 1282 | } else { |
| 1284 | sdvox = I915_READ(intel_sdvo->sdvo_reg); | 1283 | sdvox = I915_READ(intel_sdvo->sdvo_reg); |
| 1285 | switch (intel_sdvo->sdvo_reg) { | 1284 | if (intel_sdvo->port == PORT_B) |
| 1286 | case GEN3_SDVOB: | ||
| 1287 | sdvox &= SDVOB_PRESERVE_MASK; | 1285 | sdvox &= SDVOB_PRESERVE_MASK; |
| 1288 | break; | 1286 | else |
| 1289 | case GEN3_SDVOC: | ||
| 1290 | sdvox &= SDVOC_PRESERVE_MASK; | 1287 | sdvox &= SDVOC_PRESERVE_MASK; |
| 1291 | break; | ||
| 1292 | } | ||
| 1293 | sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; | 1288 | sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; |
| 1294 | } | 1289 | } |
| 1295 | 1290 | ||
| @@ -1464,12 +1459,23 @@ static void intel_disable_sdvo(struct intel_encoder *encoder) | |||
| 1464 | * matching DP port to be enabled on transcoder A. | 1459 | * matching DP port to be enabled on transcoder A. |
| 1465 | */ | 1460 | */ |
| 1466 | if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) { | 1461 | if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) { |
| 1462 | /* | ||
| 1463 | * We get CPU/PCH FIFO underruns on the other pipe when | ||
| 1464 | * doing the workaround. Sweep them under the rug. | ||
| 1465 | */ | ||
| 1466 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false); | ||
| 1467 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); | ||
| 1468 | |||
| 1467 | temp &= ~SDVO_PIPE_B_SELECT; | 1469 | temp &= ~SDVO_PIPE_B_SELECT; |
| 1468 | temp |= SDVO_ENABLE; | 1470 | temp |= SDVO_ENABLE; |
| 1469 | intel_sdvo_write_sdvox(intel_sdvo, temp); | 1471 | intel_sdvo_write_sdvox(intel_sdvo, temp); |
| 1470 | 1472 | ||
| 1471 | temp &= ~SDVO_ENABLE; | 1473 | temp &= ~SDVO_ENABLE; |
| 1472 | intel_sdvo_write_sdvox(intel_sdvo, temp); | 1474 | intel_sdvo_write_sdvox(intel_sdvo, temp); |
| 1475 | |||
| 1476 | intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A); | ||
| 1477 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); | ||
| 1478 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); | ||
| 1473 | } | 1479 | } |
| 1474 | } | 1480 | } |
| 1475 | 1481 | ||
| @@ -2251,7 +2257,7 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
| 2251 | { | 2257 | { |
| 2252 | struct sdvo_device_mapping *mapping; | 2258 | struct sdvo_device_mapping *mapping; |
| 2253 | 2259 | ||
| 2254 | if (sdvo->is_sdvob) | 2260 | if (sdvo->port == PORT_B) |
| 2255 | mapping = &(dev_priv->sdvo_mappings[0]); | 2261 | mapping = &(dev_priv->sdvo_mappings[0]); |
| 2256 | else | 2262 | else |
| 2257 | mapping = &(dev_priv->sdvo_mappings[1]); | 2263 | mapping = &(dev_priv->sdvo_mappings[1]); |
| @@ -2269,7 +2275,7 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, | |||
| 2269 | struct sdvo_device_mapping *mapping; | 2275 | struct sdvo_device_mapping *mapping; |
| 2270 | u8 pin; | 2276 | u8 pin; |
| 2271 | 2277 | ||
| 2272 | if (sdvo->is_sdvob) | 2278 | if (sdvo->port == PORT_B) |
| 2273 | mapping = &dev_priv->sdvo_mappings[0]; | 2279 | mapping = &dev_priv->sdvo_mappings[0]; |
| 2274 | else | 2280 | else |
| 2275 | mapping = &dev_priv->sdvo_mappings[1]; | 2281 | mapping = &dev_priv->sdvo_mappings[1]; |
| @@ -2307,7 +2313,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo) | |||
| 2307 | struct drm_i915_private *dev_priv = dev->dev_private; | 2313 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2308 | struct sdvo_device_mapping *my_mapping, *other_mapping; | 2314 | struct sdvo_device_mapping *my_mapping, *other_mapping; |
| 2309 | 2315 | ||
| 2310 | if (sdvo->is_sdvob) { | 2316 | if (sdvo->port == PORT_B) { |
| 2311 | my_mapping = &dev_priv->sdvo_mappings[0]; | 2317 | my_mapping = &dev_priv->sdvo_mappings[0]; |
| 2312 | other_mapping = &dev_priv->sdvo_mappings[1]; | 2318 | other_mapping = &dev_priv->sdvo_mappings[1]; |
| 2313 | } else { | 2319 | } else { |
| @@ -2332,7 +2338,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo) | |||
| 2332 | /* No SDVO device info is found for another DVO port, | 2338 | /* No SDVO device info is found for another DVO port, |
| 2333 | * so use mapping assumption we had before BIOS parsing. | 2339 | * so use mapping assumption we had before BIOS parsing. |
| 2334 | */ | 2340 | */ |
| 2335 | if (sdvo->is_sdvob) | 2341 | if (sdvo->port == PORT_B) |
| 2336 | return 0x70; | 2342 | return 0x70; |
| 2337 | else | 2343 | else |
| 2338 | return 0x72; | 2344 | return 0x72; |
| @@ -2939,18 +2945,31 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo, | |||
| 2939 | return i2c_add_adapter(&sdvo->ddc) == 0; | 2945 | return i2c_add_adapter(&sdvo->ddc) == 0; |
| 2940 | } | 2946 | } |
| 2941 | 2947 | ||
| 2942 | bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | 2948 | static void assert_sdvo_port_valid(const struct drm_i915_private *dev_priv, |
| 2949 | enum port port) | ||
| 2950 | { | ||
| 2951 | if (HAS_PCH_SPLIT(dev_priv)) | ||
| 2952 | WARN_ON(port != PORT_B); | ||
| 2953 | else | ||
| 2954 | WARN_ON(port != PORT_B && port != PORT_C); | ||
| 2955 | } | ||
| 2956 | |||
| 2957 | bool intel_sdvo_init(struct drm_device *dev, | ||
| 2958 | i915_reg_t sdvo_reg, enum port port) | ||
| 2943 | { | 2959 | { |
| 2944 | struct drm_i915_private *dev_priv = dev->dev_private; | 2960 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2945 | struct intel_encoder *intel_encoder; | 2961 | struct intel_encoder *intel_encoder; |
| 2946 | struct intel_sdvo *intel_sdvo; | 2962 | struct intel_sdvo *intel_sdvo; |
| 2947 | int i; | 2963 | int i; |
| 2964 | |||
| 2965 | assert_sdvo_port_valid(dev_priv, port); | ||
| 2966 | |||
| 2948 | intel_sdvo = kzalloc(sizeof(*intel_sdvo), GFP_KERNEL); | 2967 | intel_sdvo = kzalloc(sizeof(*intel_sdvo), GFP_KERNEL); |
| 2949 | if (!intel_sdvo) | 2968 | if (!intel_sdvo) |
| 2950 | return false; | 2969 | return false; |
| 2951 | 2970 | ||
| 2952 | intel_sdvo->sdvo_reg = sdvo_reg; | 2971 | intel_sdvo->sdvo_reg = sdvo_reg; |
| 2953 | intel_sdvo->is_sdvob = is_sdvob; | 2972 | intel_sdvo->port = port; |
| 2954 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, intel_sdvo) >> 1; | 2973 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, intel_sdvo) >> 1; |
| 2955 | intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo); | 2974 | intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo); |
| 2956 | if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev)) | 2975 | if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev)) |
| @@ -3000,8 +3019,10 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
| 3000 | * hotplug lines. | 3019 | * hotplug lines. |
| 3001 | */ | 3020 | */ |
| 3002 | if (intel_sdvo->hotplug_active) { | 3021 | if (intel_sdvo->hotplug_active) { |
| 3003 | intel_encoder->hpd_pin = | 3022 | if (intel_sdvo->port == PORT_B) |
| 3004 | intel_sdvo->is_sdvob ? HPD_SDVO_B : HPD_SDVO_C; | 3023 | intel_encoder->hpd_pin = HPD_SDVO_B; |
| 3024 | else | ||
| 3025 | intel_encoder->hpd_pin = HPD_SDVO_C; | ||
| 3005 | } | 3026 | } |
| 3006 | 3027 | ||
| 3007 | /* | 3028 | /* |
