drm/i915: Fix the VLV/CHV DSI panel orientation hw readout

Let's make sure the DSI port is actually on before we go
poking at the plane register to determine which way
it's rotated. Otherwise we could be looking at a plane
that is feeding a HDMI port for instance.

And in order to read the plane register we need the power
well to be on. Make sure that is indeed the case. We'll
also make sure the plane is actually enabled before we
trust the rotation bit to tell us the truth.

v2: s/intel_dsi/vlv_dsi/

Cc: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022141953.3889-1-ville.syrjala@linux.intel.com
Tested-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> #irc
This commit is contained in:
Ville Syrjälä 2018-10-22 17:19:53 +03:00
parent f255c624c1
commit 86ef615fa1

View File

@ -1566,27 +1566,57 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
.atomic_duplicate_state = intel_digital_connector_duplicate_state, .atomic_duplicate_state = intel_digital_connector_duplicate_state,
}; };
static int intel_dsi_get_panel_orientation(struct intel_connector *connector) static enum drm_panel_orientation
vlv_dsi_get_hw_panel_orientation(struct intel_connector *connector)
{ {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; struct intel_encoder *encoder = connector->encoder;
enum i9xx_plane_id i9xx_plane; enum intel_display_power_domain power_domain;
enum drm_panel_orientation orientation;
struct intel_plane *plane;
struct intel_crtc *crtc;
enum pipe pipe;
u32 val; u32 val;
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { if (!encoder->get_hw_state(encoder, &pipe))
if (connector->encoder->crtc_mask == BIT(PIPE_B)) return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
i9xx_plane = PLANE_B;
else
i9xx_plane = PLANE_A;
val = I915_READ(DSPCNTR(i9xx_plane)); crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
if (val & DISPPLANE_ROTATE_180) plane = to_intel_plane(crtc->base.primary);
orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
} power_domain = POWER_DOMAIN_PIPE(pipe);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
val = I915_READ(DSPCNTR(plane->i9xx_plane));
if (!(val & DISPLAY_PLANE_ENABLE))
orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
else if (val & DISPPLANE_ROTATE_180)
orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
else
orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
intel_display_power_put(dev_priv, power_domain);
return orientation; return orientation;
} }
static enum drm_panel_orientation
vlv_dsi_get_panel_orientation(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
enum drm_panel_orientation orientation;
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
orientation = vlv_dsi_get_hw_panel_orientation(connector);
if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
return orientation;
}
return DRM_MODE_PANEL_ORIENTATION_NORMAL;
}
static void intel_dsi_add_properties(struct intel_connector *connector) static void intel_dsi_add_properties(struct intel_connector *connector)
{ {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@ -1604,7 +1634,7 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT; connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
connector->base.display_info.panel_orientation = connector->base.display_info.panel_orientation =
intel_dsi_get_panel_orientation(connector); vlv_dsi_get_panel_orientation(connector);
drm_connector_init_panel_orientation_property( drm_connector_init_panel_orientation_property(
&connector->base, &connector->base,
connector->panel.fixed_mode->hdisplay, connector->panel.fixed_mode->hdisplay,