diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-05-21 18:50:22 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-05-31 14:54:03 -0400 |
commit | eccb140bca6727f2ef849e8811d5fe4c9fbfd5dd (patch) | |
tree | 44c64e283db337fd8e7a1f8b1b06851d2d6fd613 | |
parent | a01025afa89ccaf1b0521f5862cbfcc73f970481 (diff) |
drm/i915: hw state readout&check support for cpu_transcoder
This allows us to drop a bunch of ugly hacks and finally implement
what
commit cc464b2a17c59adedbdc02cc54341d630354edc3
Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
Date: Fri Jan 25 16:59:16 2013 -0200
drm/i915: set TRANSCODER_EDP even earlier
tried to achieve, but that was reverted again in
commit bba2181c49f1dddf8b592804a1b53cc1a3cf408a
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Fri Mar 22 10:53:40 2013 +0100
Revert "drm/i915: set TRANSCODER_EDP even earlier"
Now we should always have a consistent cpu_transcoder in the
pipe_config.
v2: Fix up the code as spotted by Paulo:
- read the register for real
- assign the right pipes
- break out if the hw state doesn't make sense
v3: Shut up gcc.
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 90 |
2 files changed, 37 insertions, 57 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 1fdd3b0b7040..9649df806079 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -1291,9 +1291,13 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, | |||
1291 | struct intel_crtc_config *pipe_config) | 1291 | struct intel_crtc_config *pipe_config) |
1292 | { | 1292 | { |
1293 | int type = encoder->type; | 1293 | int type = encoder->type; |
1294 | int port = intel_ddi_get_encoder_port(encoder); | ||
1294 | 1295 | ||
1295 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); | 1296 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); |
1296 | 1297 | ||
1298 | if (port == PORT_A) | ||
1299 | pipe_config->cpu_transcoder = TRANSCODER_EDP; | ||
1300 | |||
1297 | if (type == INTEL_OUTPUT_HDMI) | 1301 | if (type == INTEL_OUTPUT_HDMI) |
1298 | return intel_hdmi_compute_config(encoder, pipe_config); | 1302 | return intel_hdmi_compute_config(encoder, pipe_config); |
1299 | else | 1303 | else |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2a9d0671f8c3..cb2437d1e0ea 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3469,12 +3469,6 @@ static void ironlake_crtc_off(struct drm_crtc *crtc) | |||
3469 | 3469 | ||
3470 | static void haswell_crtc_off(struct drm_crtc *crtc) | 3470 | static void haswell_crtc_off(struct drm_crtc *crtc) |
3471 | { | 3471 | { |
3472 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3473 | |||
3474 | /* Stop saying we're using TRANSCODER_EDP because some other CRTC might | ||
3475 | * start using it. */ | ||
3476 | intel_crtc->config.cpu_transcoder = (enum transcoder) intel_crtc->pipe; | ||
3477 | |||
3478 | intel_ddi_put_crtc_pll(crtc); | 3472 | intel_ddi_put_crtc_pll(crtc); |
3479 | } | 3473 | } |
3480 | 3474 | ||
@@ -4925,6 +4919,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, | |||
4925 | struct drm_i915_private *dev_priv = dev->dev_private; | 4919 | struct drm_i915_private *dev_priv = dev->dev_private; |
4926 | uint32_t tmp; | 4920 | uint32_t tmp; |
4927 | 4921 | ||
4922 | pipe_config->cpu_transcoder = crtc->pipe; | ||
4923 | |||
4928 | tmp = I915_READ(PIPECONF(crtc->pipe)); | 4924 | tmp = I915_READ(PIPECONF(crtc->pipe)); |
4929 | if (!(tmp & PIPECONF_ENABLE)) | 4925 | if (!(tmp & PIPECONF_ENABLE)) |
4930 | return false; | 4926 | return false; |
@@ -5647,8 +5643,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5647 | WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), | 5643 | WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), |
5648 | "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); | 5644 | "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); |
5649 | 5645 | ||
5650 | intel_crtc->config.cpu_transcoder = pipe; | ||
5651 | |||
5652 | ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, | 5646 | ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, |
5653 | &has_reduced_clock, &reduced_clock); | 5647 | &has_reduced_clock, &reduced_clock); |
5654 | if (!ok) { | 5648 | if (!ok) { |
@@ -5784,6 +5778,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, | |||
5784 | struct drm_i915_private *dev_priv = dev->dev_private; | 5778 | struct drm_i915_private *dev_priv = dev->dev_private; |
5785 | uint32_t tmp; | 5779 | uint32_t tmp; |
5786 | 5780 | ||
5781 | pipe_config->cpu_transcoder = crtc->pipe; | ||
5782 | |||
5787 | tmp = I915_READ(PIPECONF(crtc->pipe)); | 5783 | tmp = I915_READ(PIPECONF(crtc->pipe)); |
5788 | if (!(tmp & PIPECONF_ENABLE)) | 5784 | if (!(tmp & PIPECONF_ENABLE)) |
5789 | return false; | 5785 | return false; |
@@ -5860,11 +5856,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, | |||
5860 | num_connectors++; | 5856 | num_connectors++; |
5861 | } | 5857 | } |
5862 | 5858 | ||
5863 | if (is_cpu_edp) | ||
5864 | intel_crtc->config.cpu_transcoder = TRANSCODER_EDP; | ||
5865 | else | ||
5866 | intel_crtc->config.cpu_transcoder = pipe; | ||
5867 | |||
5868 | /* We are not sure yet this won't happen. */ | 5859 | /* We are not sure yet this won't happen. */ |
5869 | WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n", | 5860 | WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n", |
5870 | INTEL_PCH_TYPE(dev)); | 5861 | INTEL_PCH_TYPE(dev)); |
@@ -5918,15 +5909,37 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, | |||
5918 | { | 5909 | { |
5919 | struct drm_device *dev = crtc->base.dev; | 5910 | struct drm_device *dev = crtc->base.dev; |
5920 | struct drm_i915_private *dev_priv = dev->dev_private; | 5911 | struct drm_i915_private *dev_priv = dev->dev_private; |
5921 | enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; | ||
5922 | enum intel_display_power_domain pfit_domain; | 5912 | enum intel_display_power_domain pfit_domain; |
5923 | uint32_t tmp; | 5913 | uint32_t tmp; |
5924 | 5914 | ||
5915 | pipe_config->cpu_transcoder = crtc->pipe; | ||
5916 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); | ||
5917 | if (tmp & TRANS_DDI_FUNC_ENABLE) { | ||
5918 | enum pipe trans_edp_pipe; | ||
5919 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { | ||
5920 | default: | ||
5921 | WARN(1, "unknown pipe linked to edp transcoder\n"); | ||
5922 | case TRANS_DDI_EDP_INPUT_A_ONOFF: | ||
5923 | case TRANS_DDI_EDP_INPUT_A_ON: | ||
5924 | trans_edp_pipe = PIPE_A; | ||
5925 | break; | ||
5926 | case TRANS_DDI_EDP_INPUT_B_ONOFF: | ||
5927 | trans_edp_pipe = PIPE_B; | ||
5928 | break; | ||
5929 | case TRANS_DDI_EDP_INPUT_C_ONOFF: | ||
5930 | trans_edp_pipe = PIPE_C; | ||
5931 | break; | ||
5932 | } | ||
5933 | |||
5934 | if (trans_edp_pipe == crtc->pipe) | ||
5935 | pipe_config->cpu_transcoder = TRANSCODER_EDP; | ||
5936 | } | ||
5937 | |||
5925 | if (!intel_display_power_enabled(dev, | 5938 | if (!intel_display_power_enabled(dev, |
5926 | POWER_DOMAIN_TRANSCODER(cpu_transcoder))) | 5939 | POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) |
5927 | return false; | 5940 | return false; |
5928 | 5941 | ||
5929 | tmp = I915_READ(PIPECONF(cpu_transcoder)); | 5942 | tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder)); |
5930 | if (!(tmp & PIPECONF_ENABLE)) | 5943 | if (!(tmp & PIPECONF_ENABLE)) |
5931 | return false; | 5944 | return false; |
5932 | 5945 | ||
@@ -5935,7 +5948,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, | |||
5935 | * DDI E. So just check whether this pipe is wired to DDI E and whether | 5948 | * DDI E. So just check whether this pipe is wired to DDI E and whether |
5936 | * the PCH transcoder is on. | 5949 | * the PCH transcoder is on. |
5937 | */ | 5950 | */ |
5938 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); | 5951 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder)); |
5939 | if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) && | 5952 | if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) && |
5940 | I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) { | 5953 | I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) { |
5941 | pipe_config->has_pch_encoder = true; | 5954 | pipe_config->has_pch_encoder = true; |
@@ -7690,6 +7703,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, | |||
7690 | 7703 | ||
7691 | drm_mode_copy(&pipe_config->adjusted_mode, mode); | 7704 | drm_mode_copy(&pipe_config->adjusted_mode, mode); |
7692 | drm_mode_copy(&pipe_config->requested_mode, mode); | 7705 | drm_mode_copy(&pipe_config->requested_mode, mode); |
7706 | pipe_config->cpu_transcoder = to_intel_crtc(crtc)->pipe; | ||
7693 | 7707 | ||
7694 | plane_bpp = pipe_config_set_bpp(crtc, fb, pipe_config); | 7708 | plane_bpp = pipe_config_set_bpp(crtc, fb, pipe_config); |
7695 | if (plane_bpp < 0) | 7709 | if (plane_bpp < 0) |
@@ -7940,6 +7954,8 @@ intel_pipe_config_compare(struct drm_device *dev, | |||
7940 | return false; \ | 7954 | return false; \ |
7941 | } | 7955 | } |
7942 | 7956 | ||
7957 | PIPE_CONF_CHECK_I(cpu_transcoder); | ||
7958 | |||
7943 | PIPE_CONF_CHECK_I(has_pch_encoder); | 7959 | PIPE_CONF_CHECK_I(has_pch_encoder); |
7944 | PIPE_CONF_CHECK_I(fdi_lanes); | 7960 | PIPE_CONF_CHECK_I(fdi_lanes); |
7945 | PIPE_CONF_CHECK_I(fdi_m_n.gmch_m); | 7961 | PIPE_CONF_CHECK_I(fdi_m_n.gmch_m); |
@@ -8091,7 +8107,6 @@ intel_modeset_check_state(struct drm_device *dev) | |||
8091 | "crtc's computed enabled state doesn't match tracked enabled state " | 8107 | "crtc's computed enabled state doesn't match tracked enabled state " |
8092 | "(expected %i, found %i)\n", enabled, crtc->base.enabled); | 8108 | "(expected %i, found %i)\n", enabled, crtc->base.enabled); |
8093 | 8109 | ||
8094 | pipe_config.cpu_transcoder = crtc->config.cpu_transcoder; | ||
8095 | active = dev_priv->display.get_pipe_config(crtc, | 8110 | active = dev_priv->display.get_pipe_config(crtc, |
8096 | &pipe_config); | 8111 | &pipe_config); |
8097 | WARN(crtc->active != active, | 8112 | WARN(crtc->active != active, |
@@ -8154,12 +8169,10 @@ static int __intel_set_mode(struct drm_crtc *crtc, | |||
8154 | * to set it here already despite that we pass it down the callchain. | 8169 | * to set it here already despite that we pass it down the callchain. |
8155 | */ | 8170 | */ |
8156 | if (modeset_pipes) { | 8171 | if (modeset_pipes) { |
8157 | enum transcoder tmp = to_intel_crtc(crtc)->config.cpu_transcoder; | ||
8158 | crtc->mode = *mode; | 8172 | crtc->mode = *mode; |
8159 | /* mode_set/enable/disable functions rely on a correct pipe | 8173 | /* mode_set/enable/disable functions rely on a correct pipe |
8160 | * config. */ | 8174 | * config. */ |
8161 | to_intel_crtc(crtc)->config = *pipe_config; | 8175 | to_intel_crtc(crtc)->config = *pipe_config; |
8162 | to_intel_crtc(crtc)->config.cpu_transcoder = tmp; | ||
8163 | } | 8176 | } |
8164 | 8177 | ||
8165 | /* Only after disabling all output pipelines that will be changed can we | 8178 | /* Only after disabling all output pipelines that will be changed can we |
@@ -8570,7 +8583,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
8570 | /* Swap pipes & planes for FBC on pre-965 */ | 8583 | /* Swap pipes & planes for FBC on pre-965 */ |
8571 | intel_crtc->pipe = pipe; | 8584 | intel_crtc->pipe = pipe; |
8572 | intel_crtc->plane = pipe; | 8585 | intel_crtc->plane = pipe; |
8573 | intel_crtc->config.cpu_transcoder = pipe; | ||
8574 | if (IS_MOBILE(dev) && IS_GEN3(dev)) { | 8586 | if (IS_MOBILE(dev) && IS_GEN3(dev)) { |
8575 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); | 8587 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); |
8576 | intel_crtc->plane = !pipe; | 8588 | intel_crtc->plane = !pipe; |
@@ -9436,50 +9448,14 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, | |||
9436 | { | 9448 | { |
9437 | struct drm_i915_private *dev_priv = dev->dev_private; | 9449 | struct drm_i915_private *dev_priv = dev->dev_private; |
9438 | enum pipe pipe; | 9450 | enum pipe pipe; |
9439 | u32 tmp; | ||
9440 | struct drm_plane *plane; | 9451 | struct drm_plane *plane; |
9441 | struct intel_crtc *crtc; | 9452 | struct intel_crtc *crtc; |
9442 | struct intel_encoder *encoder; | 9453 | struct intel_encoder *encoder; |
9443 | struct intel_connector *connector; | 9454 | struct intel_connector *connector; |
9444 | 9455 | ||
9445 | if (HAS_DDI(dev)) { | ||
9446 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); | ||
9447 | |||
9448 | if (tmp & TRANS_DDI_FUNC_ENABLE) { | ||
9449 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { | ||
9450 | case TRANS_DDI_EDP_INPUT_A_ON: | ||
9451 | case TRANS_DDI_EDP_INPUT_A_ONOFF: | ||
9452 | pipe = PIPE_A; | ||
9453 | break; | ||
9454 | case TRANS_DDI_EDP_INPUT_B_ONOFF: | ||
9455 | pipe = PIPE_B; | ||
9456 | break; | ||
9457 | case TRANS_DDI_EDP_INPUT_C_ONOFF: | ||
9458 | pipe = PIPE_C; | ||
9459 | break; | ||
9460 | default: | ||
9461 | /* A bogus value has been programmed, disable | ||
9462 | * the transcoder */ | ||
9463 | WARN(1, "Bogus eDP source %08x\n", tmp); | ||
9464 | intel_ddi_disable_transcoder_func(dev_priv, | ||
9465 | TRANSCODER_EDP); | ||
9466 | goto setup_pipes; | ||
9467 | } | ||
9468 | |||
9469 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | ||
9470 | crtc->config.cpu_transcoder = TRANSCODER_EDP; | ||
9471 | |||
9472 | DRM_DEBUG_KMS("Pipe %c using transcoder EDP\n", | ||
9473 | pipe_name(pipe)); | ||
9474 | } | ||
9475 | } | ||
9476 | |||
9477 | setup_pipes: | ||
9478 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, | 9456 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, |
9479 | base.head) { | 9457 | base.head) { |
9480 | enum transcoder tmp = crtc->config.cpu_transcoder; | ||
9481 | memset(&crtc->config, 0, sizeof(crtc->config)); | 9458 | memset(&crtc->config, 0, sizeof(crtc->config)); |
9482 | crtc->config.cpu_transcoder = tmp; | ||
9483 | 9459 | ||
9484 | crtc->active = dev_priv->display.get_pipe_config(crtc, | 9460 | crtc->active = dev_priv->display.get_pipe_config(crtc, |
9485 | &crtc->config); | 9461 | &crtc->config); |