From: Ville Syrjälä ville.syrjala@linux.intel.com
Remainder of the patches from the per-plane rotation series [1]. Rebased and also Rob's r-b picked up from [2].
[1] https://lists.freedesktop.org/archives/dri-devel/2016-September/119451.html [2] https://lists.freedesktop.org/archives/dri-devel/2016-September/119468.html
Ville Syrjälä (6): drm/msm/mdp5: Use per-plane rotation property drm/msm/mdp5: Advertize 180 degree rotation drm: RIP mode_config->rotation_property drm/i915: Use & instead if == to check for rotations drm/i915: Clean up rotation DSPCNTR/DVSCNTR/etc. setup drm/i915: Add horizontal mirroring support for CHV pipe B planes
drivers/gpu/drm/drm_atomic.c | 6 ++--- drivers/gpu/drm/drm_blend.c | 32 ++++--------------------- drivers/gpu/drm/drm_fb_helper.c | 7 +----- drivers/gpu/drm/i915/intel_atomic_plane.c | 9 +++++++ drivers/gpu/drm/i915/intel_display.c | 39 ++++++++++++++++++++----------- drivers/gpu/drm/i915/intel_sprite.c | 39 ++++++++++++++++++++----------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 35 ++++++++++++++++----------- include/drm/drm_blend.h | 2 -- include/drm/drm_crtc.h | 5 ---- 9 files changed, 88 insertions(+), 86 deletions(-)
From: Ville Syrjälä ville.syrjala@linux.intel.com
The global mode_config.rotation_property is going away, switch over to per-plane rotation_property.
v2: Drop the BIT()
Cc: Rob Clark robdclark@gmail.com Cc: Jilai Wang jilaiw@codeaurora.org Cc: Archit Taneja architt@codeaurora.org Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Rob Clark robdclark@gmail.com --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 951c002b05df..2653ad893ebc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -75,15 +75,11 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) return;
- if (!dev->mode_config.rotation_property) - dev->mode_config.rotation_property = - drm_mode_create_rotation_property(dev, - DRM_ROTATE_0 | DRM_REFLECT_X | DRM_REFLECT_Y); - - if (dev->mode_config.rotation_property) - drm_object_attach_property(&plane->base, - dev->mode_config.rotation_property, - DRM_ROTATE_0); + drm_plane_create_rotation_property(plane, + DRM_ROTATE_0, + DRM_ROTATE_0 | + DRM_REFLECT_X | + DRM_REFLECT_Y); }
/* helper to install properties which are common to planes and crtcs */
Hi Ville,
On 10/22/2016 12:52 AM, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
The global mode_config.rotation_property is going away, switch over to per-plane rotation_property.
I was trying to test this on msm/drm using modetest. The 180 rotation works fine, but drm rejects reflect-x and reflect-y rotation prop values. Is this expected?
I needed to make this modification to get reflect-x/y working too:
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a747bb1..9fcc2c9 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -711,7 +711,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->src_h = val; } else if (property == config->rotation_property || property == plane->rotation_property) { - if (!is_power_of_2(val & DRM_ROTATE_MASK)) + if (!is_power_of_2(val & (DRM_ROTATE_MASK | DRM_REFLECT_MASK))) return -EINVAL; state->rotation = val; } else if (property == plane->zpos_property) {
Otherwise, the patches look fine to me.
Thanks, Archit
v2: Drop the BIT()
Cc: Rob Clark robdclark@gmail.com Cc: Jilai Wang jilaiw@codeaurora.org Cc: Archit Taneja architt@codeaurora.org Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Rob Clark robdclark@gmail.com
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 951c002b05df..2653ad893ebc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -75,15 +75,11 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) return;
- if (!dev->mode_config.rotation_property)
dev->mode_config.rotation_property =
drm_mode_create_rotation_property(dev,
DRM_ROTATE_0 | DRM_REFLECT_X | DRM_REFLECT_Y);
- if (dev->mode_config.rotation_property)
drm_object_attach_property(&plane->base,
dev->mode_config.rotation_property,
DRM_ROTATE_0);
- drm_plane_create_rotation_property(plane,
DRM_ROTATE_0,
DRM_ROTATE_0 |
DRM_REFLECT_X |
DRM_REFLECT_Y);
}
/* helper to install properties which are common to planes and crtcs */
On Mon, Oct 24, 2016 at 03:33:18PM +0530, Archit Taneja wrote:
Hi Ville,
On 10/22/2016 12:52 AM, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
The global mode_config.rotation_property is going away, switch over to per-plane rotation_property.
I was trying to test this on msm/drm using modetest. The 180 rotation works fine, but drm rejects reflect-x and reflect-y rotation prop values. Is this expected?
I needed to make this modification to get reflect-x/y working too:
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a747bb1..9fcc2c9 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -711,7 +711,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->src_h = val; } else if (property == config->rotation_property || property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_ROTATE_MASK))
if (!is_power_of_2(val & (DRM_ROTATE_MASK | DRM_REFLECT_MASK)))
That makes no sense. You _must_ to pass one and only one rotation angle. In *addition* you can pass any number of the reflection flags.
return -EINVAL; state->rotation = val;
} else if (property == plane->zpos_property) {
Otherwise, the patches look fine to me.
Thanks, Archit
v2: Drop the BIT()
Cc: Rob Clark robdclark@gmail.com Cc: Jilai Wang jilaiw@codeaurora.org Cc: Archit Taneja architt@codeaurora.org Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Rob Clark robdclark@gmail.com
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 951c002b05df..2653ad893ebc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -75,15 +75,11 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) return;
- if (!dev->mode_config.rotation_property)
dev->mode_config.rotation_property =
drm_mode_create_rotation_property(dev,
DRM_ROTATE_0 | DRM_REFLECT_X | DRM_REFLECT_Y);
- if (dev->mode_config.rotation_property)
drm_object_attach_property(&plane->base,
dev->mode_config.rotation_property,
DRM_ROTATE_0);
- drm_plane_create_rotation_property(plane,
DRM_ROTATE_0,
DRM_ROTATE_0 |
DRM_REFLECT_X |
DRM_REFLECT_Y);
}
/* helper to install properties which are common to planes and crtcs */
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
On 10/24/2016 03:45 PM, Ville Syrjälä wrote:
On Mon, Oct 24, 2016 at 03:33:18PM +0530, Archit Taneja wrote:
Hi Ville,
On 10/22/2016 12:52 AM, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
The global mode_config.rotation_property is going away, switch over to per-plane rotation_property.
I was trying to test this on msm/drm using modetest. The 180 rotation works fine, but drm rejects reflect-x and reflect-y rotation prop values. Is this expected?
I needed to make this modification to get reflect-x/y working too:
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a747bb1..9fcc2c9 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -711,7 +711,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->src_h = val; } else if (property == config->rotation_property || property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_ROTATE_MASK))
if (!is_power_of_2(val & (DRM_ROTATE_MASK | DRM_REFLECT_MASK)))
That makes no sense. You _must_ to pass one and only one rotation angle. In *addition* you can pass any number of the reflection flags.
Okay. Does the rotation property also include reflection flags, though?
When I dump plane properties using modetest, I get:
31 rotation: flags: bitmask values: rotate-0=0x1 rotate-180=0x4 reflect-x=0x10 reflect-y=0x20 value: 1
If I use modetest to set 0x10 or 0x20, it returns an error. I wanted to know if this is expected behavior or not?
Thanks, Archit
return -EINVAL; state->rotation = val;
} else if (property == plane->zpos_property) {
Otherwise, the patches look fine to me.
Thanks, Archit
v2: Drop the BIT()
Cc: Rob Clark robdclark@gmail.com Cc: Jilai Wang jilaiw@codeaurora.org Cc: Archit Taneja architt@codeaurora.org Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Rob Clark robdclark@gmail.com
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 951c002b05df..2653ad893ebc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -75,15 +75,11 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) return;
- if (!dev->mode_config.rotation_property)
dev->mode_config.rotation_property =
drm_mode_create_rotation_property(dev,
DRM_ROTATE_0 | DRM_REFLECT_X | DRM_REFLECT_Y);
- if (dev->mode_config.rotation_property)
drm_object_attach_property(&plane->base,
dev->mode_config.rotation_property,
DRM_ROTATE_0);
- drm_plane_create_rotation_property(plane,
DRM_ROTATE_0,
DRM_ROTATE_0 |
DRM_REFLECT_X |
DRM_REFLECT_Y);
}
/* helper to install properties which are common to planes and crtcs */
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
On Mon, Oct 24, 2016 at 03:52:09PM +0530, Archit Taneja wrote:
On 10/24/2016 03:45 PM, Ville Syrjälä wrote:
On Mon, Oct 24, 2016 at 03:33:18PM +0530, Archit Taneja wrote:
Hi Ville,
On 10/22/2016 12:52 AM, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
The global mode_config.rotation_property is going away, switch over to per-plane rotation_property.
I was trying to test this on msm/drm using modetest. The 180 rotation works fine, but drm rejects reflect-x and reflect-y rotation prop values. Is this expected?
I needed to make this modification to get reflect-x/y working too:
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a747bb1..9fcc2c9 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -711,7 +711,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->src_h = val; } else if (property == config->rotation_property || property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_ROTATE_MASK))
if (!is_power_of_2(val & (DRM_ROTATE_MASK | DRM_REFLECT_MASK)))
That makes no sense. You _must_ to pass one and only one rotation angle. In *addition* you can pass any number of the reflection flags.
Okay. Does the rotation property also include reflection flags, though?
Yes.
When I dump plane properties using modetest, I get:
31 rotation: flags: bitmask values: rotate-0=0x1 rotate-180=0x4 reflect-x=0x10 reflect-y=0x20 value: 1
If I use modetest to set 0x10 or 0x20, it returns an error. I wanted to know if this is expected behavior or not?
It is. If you want 0 degree rotation with X reflection you have to pass 0x11.
Thanks, Archit
return -EINVAL; state->rotation = val;
} else if (property == plane->zpos_property) {
Otherwise, the patches look fine to me.
Thanks, Archit
v2: Drop the BIT()
Cc: Rob Clark robdclark@gmail.com Cc: Jilai Wang jilaiw@codeaurora.org Cc: Archit Taneja architt@codeaurora.org Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Rob Clark robdclark@gmail.com
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 951c002b05df..2653ad893ebc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -75,15 +75,11 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) return;
- if (!dev->mode_config.rotation_property)
dev->mode_config.rotation_property =
drm_mode_create_rotation_property(dev,
DRM_ROTATE_0 | DRM_REFLECT_X | DRM_REFLECT_Y);
- if (dev->mode_config.rotation_property)
drm_object_attach_property(&plane->base,
dev->mode_config.rotation_property,
DRM_ROTATE_0);
- drm_plane_create_rotation_property(plane,
DRM_ROTATE_0,
DRM_ROTATE_0 |
DRM_REFLECT_X |
DRM_REFLECT_Y);
}
/* helper to install properties which are common to planes and crtcs */
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
On 10/24/2016 03:55 PM, Ville Syrjälä wrote:
On Mon, Oct 24, 2016 at 03:52:09PM +0530, Archit Taneja wrote:
On 10/24/2016 03:45 PM, Ville Syrjälä wrote:
On Mon, Oct 24, 2016 at 03:33:18PM +0530, Archit Taneja wrote:
Hi Ville,
On 10/22/2016 12:52 AM, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
The global mode_config.rotation_property is going away, switch over to per-plane rotation_property.
I was trying to test this on msm/drm using modetest. The 180 rotation works fine, but drm rejects reflect-x and reflect-y rotation prop values. Is this expected?
I needed to make this modification to get reflect-x/y working too:
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a747bb1..9fcc2c9 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -711,7 +711,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->src_h = val; } else if (property == config->rotation_property || property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_ROTATE_MASK))
if (!is_power_of_2(val & (DRM_ROTATE_MASK | DRM_REFLECT_MASK)))
That makes no sense. You _must_ to pass one and only one rotation angle. In *addition* you can pass any number of the reflection flags.
Okay. Does the rotation property also include reflection flags, though?
Yes.
When I dump plane properties using modetest, I get:
31 rotation: flags: bitmask values: rotate-0=0x1 rotate-180=0x4 reflect-x=0x10 reflect-y=0x20 value: 1
If I use modetest to set 0x10 or 0x20, it returns an error. I wanted to know if this is expected behavior or not?
It is. If you want 0 degree rotation with X reflection you have to pass 0x11.
Ah okay, didn't realize I had to put a 0 degree rotation along with the reflect. Works fine with 0x11. Thanks for the clarification.
Archit
Thanks, Archit
return -EINVAL; state->rotation = val;
} else if (property == plane->zpos_property) {
Otherwise, the patches look fine to me.
Thanks, Archit
v2: Drop the BIT()
Cc: Rob Clark robdclark@gmail.com Cc: Jilai Wang jilaiw@codeaurora.org Cc: Archit Taneja architt@codeaurora.org Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Rob Clark robdclark@gmail.com
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 951c002b05df..2653ad893ebc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -75,15 +75,11 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) return;
- if (!dev->mode_config.rotation_property)
dev->mode_config.rotation_property =
drm_mode_create_rotation_property(dev,
DRM_ROTATE_0 | DRM_REFLECT_X | DRM_REFLECT_Y);
- if (dev->mode_config.rotation_property)
drm_object_attach_property(&plane->base,
dev->mode_config.rotation_property,
DRM_ROTATE_0);
- drm_plane_create_rotation_property(plane,
DRM_ROTATE_0,
DRM_ROTATE_0 |
DRM_REFLECT_X |
DRM_REFLECT_Y);
}
/* helper to install properties which are common to planes and crtcs */
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
From: Ville Syrjälä ville.syrjala@linux.intel.com
Since the hardware can apparently do both X and Y reflection, we can advertize also 180 degree rotation as thats just X+Y reflection.
v2: Drop the BIT()
Cc: Rob Clark robdclark@gmail.com Cc: Jilai Wang jilaiw@codeaurora.org Cc: Archit Taneja architt@codeaurora.org Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Rob Clark robdclark@gmail.com --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 2653ad893ebc..cf50d3ec8d1b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -78,6 +78,7 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, drm_plane_create_rotation_property(plane, DRM_ROTATE_0, DRM_ROTATE_0 | + DRM_ROTATE_180 | DRM_REFLECT_X | DRM_REFLECT_Y); } @@ -285,6 +286,8 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, plane_enabled(old_state), plane_enabled(state));
if (plane_enabled(state)) { + unsigned int rotation; + format = to_mdp_format(msm_framebuffer_format(state->fb)); if (MDP_FORMAT_IS_YUV(format) && !pipe_supports_yuv(mdp5_plane->caps)) { @@ -305,8 +308,13 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, return -EINVAL; }
- hflip = !!(state->rotation & DRM_REFLECT_X); - vflip = !!(state->rotation & DRM_REFLECT_Y); + rotation = drm_rotation_simplify(state->rotation, + DRM_ROTATE_0 | + DRM_REFLECT_X | + DRM_REFLECT_Y); + hflip = !!(rotation & DRM_REFLECT_X); + vflip = !!(rotation & DRM_REFLECT_Y); + if ((vflip && !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) || (hflip && !(mdp5_plane->caps & MDP_PIPE_CAP_HFLIP))) { dev_err(plane->dev->dev, @@ -677,6 +685,7 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, int pe_top[COMP_MAX], pe_bottom[COMP_MAX]; uint32_t hdecm = 0, vdecm = 0; uint32_t pix_format; + unsigned int rotation; bool vflip, hflip; unsigned long flags; int ret; @@ -739,8 +748,12 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, config |= get_scale_config(format, src_h, crtc_h, false); DBG("scale config = %x", config);
- hflip = !!(pstate->rotation & DRM_REFLECT_X); - vflip = !!(pstate->rotation & DRM_REFLECT_Y); + rotation = drm_rotation_simplify(pstate->rotation, + DRM_ROTATE_0 | + DRM_REFLECT_X | + DRM_REFLECT_Y); + hflip = !!(rotation & DRM_REFLECT_X); + vflip = !!(rotation & DRM_REFLECT_Y);
spin_lock_irqsave(&mdp5_plane->pipe_lock, flags);
From: Ville Syrjälä ville.syrjala@linux.intel.com
Now that all drivers have been converted over to the per-plane rotation property, we can just nuke the global rotation property.
v2: Rebase due to BIT(),__builtin_ffs() & co. Deal with superfluous code shuffling
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/drm_atomic.c | 6 ++---- drivers/gpu/drm/drm_blend.c | 32 ++++---------------------------- drivers/gpu/drm/drm_fb_helper.c | 7 +------ include/drm/drm_blend.h | 2 -- include/drm/drm_crtc.h | 5 ----- 5 files changed, 7 insertions(+), 45 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index f81706387889..1b5a32df9a9a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -705,8 +705,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->src_w = val; } else if (property == config->prop_src_h) { state->src_h = val; - } else if (property == config->rotation_property || - property == plane->rotation_property) { + } else if (property == plane->rotation_property) { if (!is_power_of_2(val & DRM_ROTATE_MASK)) return -EINVAL; state->rotation = val; @@ -766,8 +765,7 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->src_w; } else if (property == config->prop_src_h) { *val = state->src_h; - } else if (property == config->rotation_property || - property == plane->rotation_property) { + } else if (property == plane->rotation_property) { *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos; diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index e52aece30900..1f2412c7ccfd 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -89,7 +89,7 @@ * On top of this basic transformation additional properties can be exposed by * the driver: * - * - Rotation is set up with drm_mode_create_rotation_property(). It adds a + * - Rotation is set up with drm_plane_create_rotation_property(). It adds a * rotation and reflection step between the source and destination rectangles. * Without this property the rectangle is only scaled, but not rotated or * reflected. @@ -105,18 +105,12 @@ */
/** - * drm_mode_create_rotation_property - create a new rotation property - * @dev: DRM device + * drm_plane_create_rotation_property - create a new rotation property + * @plane: drm plane + * @rotation: initial value of the rotation property * @supported_rotations: bitmask of supported rotations and reflections * * This creates a new property with the selected support for transformations. - * The resulting property should be stored in @rotation_property in - * &drm_mode_config. It then must be attached to each plane which supports - * rotations using drm_object_attach_property(). - * - * FIXME: Probably better if the rotation property is created on each plane, - * like the zpos property. Otherwise it's not possible to allow different - * rotation modes on different planes. * * Since a rotation by 180° degress is the same as reflecting both along the x * and the y axis the rotation property is somewhat redundant. Drivers can use @@ -144,24 +138,6 @@ * rotation. After reflection, the rotation is applied to the image sampled from * the source rectangle, before scaling it to fit the destination rectangle. */ -struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, - unsigned int supported_rotations) -{ - static const struct drm_prop_enum_list props[] = { - { __builtin_ffs(DRM_ROTATE_0) - 1, "rotate-0" }, - { __builtin_ffs(DRM_ROTATE_90) - 1, "rotate-90" }, - { __builtin_ffs(DRM_ROTATE_180) - 1, "rotate-180" }, - { __builtin_ffs(DRM_ROTATE_270) - 1, "rotate-270" }, - { __builtin_ffs(DRM_REFLECT_X) - 1, "reflect-x" }, - { __builtin_ffs(DRM_REFLECT_Y) - 1, "reflect-y" }, - }; - - return drm_property_create_bitmask(dev, 0, "rotation", - props, ARRAY_SIZE(props), - supported_rotations); -} -EXPORT_SYMBOL(drm_mode_create_rotation_property); - int drm_plane_create_rotation_property(struct drm_plane *plane, unsigned int rotation, unsigned int supported_rotations) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index e0d428f9d1cb..83dbae0fabcf 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -392,15 +392,10 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) if (plane->type != DRM_PLANE_TYPE_PRIMARY) drm_plane_force_disable(plane);
- if (plane->rotation_property) { + if (plane->rotation_property) drm_mode_plane_set_obj_prop(plane, plane->rotation_property, DRM_ROTATE_0); - } else if (dev->mode_config.rotation_property) { - drm_mode_plane_set_obj_prop(plane, - dev->mode_config.rotation_property, - DRM_ROTATE_0); - } }
for (i = 0; i < fb_helper->crtc_count; i++) { diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h index fd351924e1c5..13221cf9b3eb 100644 --- a/include/drm/drm_blend.h +++ b/include/drm/drm_blend.h @@ -52,8 +52,6 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation) return rotation & (DRM_ROTATE_90 | DRM_ROTATE_270); }
-struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, - unsigned int supported_rotations); int drm_plane_create_rotation_property(struct drm_plane *plane, unsigned int rotation, unsigned int supported_rotations); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 284c1b3aec10..bc860cfc67ca 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1156,11 +1156,6 @@ struct drm_mode_config { */ struct drm_property *plane_type_property; /** - * @rotation_property: Optional property for planes or CRTCs to specifiy - * rotation. - */ - struct drm_property *rotation_property; - /** * @prop_src_x: Default atomic plane property for the plane source * position in the connected &drm_framebuffer. */
On Fri, Oct 21, 2016 at 10:22:45PM +0300, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Now that all drivers have been converted over to the per-plane rotation property, we can just nuke the global rotation property.
v2: Rebase due to BIT(),__builtin_ffs() & co. Deal with superfluous code shuffling
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com
Merged up to this patch. I think it's better to land the follow-up i915 patches through drm-intel. I'll do backmerges next week anyway, you won't need to wait long.
Thanks, Daniel
drivers/gpu/drm/drm_atomic.c | 6 ++---- drivers/gpu/drm/drm_blend.c | 32 ++++---------------------------- drivers/gpu/drm/drm_fb_helper.c | 7 +------ include/drm/drm_blend.h | 2 -- include/drm/drm_crtc.h | 5 ----- 5 files changed, 7 insertions(+), 45 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index f81706387889..1b5a32df9a9a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -705,8 +705,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->src_w = val; } else if (property == config->prop_src_h) { state->src_h = val;
- } else if (property == config->rotation_property ||
property == plane->rotation_property) {
- } else if (property == plane->rotation_property) { if (!is_power_of_2(val & DRM_ROTATE_MASK)) return -EINVAL; state->rotation = val;
@@ -766,8 +765,7 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->src_w; } else if (property == config->prop_src_h) { *val = state->src_h;
- } else if (property == config->rotation_property ||
property == plane->rotation_property) {
- } else if (property == plane->rotation_property) { *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index e52aece30900..1f2412c7ccfd 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -89,7 +89,7 @@
- On top of this basic transformation additional properties can be exposed by
- the driver:
- Rotation is set up with drm_mode_create_rotation_property(). It adds a
- Rotation is set up with drm_plane_create_rotation_property(). It adds a
- rotation and reflection step between the source and destination rectangles.
- Without this property the rectangle is only scaled, but not rotated or
- reflected.
@@ -105,18 +105,12 @@ */
/**
- drm_mode_create_rotation_property - create a new rotation property
- @dev: DRM device
- drm_plane_create_rotation_property - create a new rotation property
- @plane: drm plane
- @rotation: initial value of the rotation property
- @supported_rotations: bitmask of supported rotations and reflections
- This creates a new property with the selected support for transformations.
- The resulting property should be stored in @rotation_property in
- &drm_mode_config. It then must be attached to each plane which supports
- rotations using drm_object_attach_property().
- FIXME: Probably better if the rotation property is created on each plane,
- like the zpos property. Otherwise it's not possible to allow different
- rotation modes on different planes.
- Since a rotation by 180° degress is the same as reflecting both along the x
- and the y axis the rotation property is somewhat redundant. Drivers can use
@@ -144,24 +138,6 @@
- rotation. After reflection, the rotation is applied to the image sampled from
- the source rectangle, before scaling it to fit the destination rectangle.
*/ -struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
unsigned int supported_rotations)
-{
- static const struct drm_prop_enum_list props[] = {
{ __builtin_ffs(DRM_ROTATE_0) - 1, "rotate-0" },
{ __builtin_ffs(DRM_ROTATE_90) - 1, "rotate-90" },
{ __builtin_ffs(DRM_ROTATE_180) - 1, "rotate-180" },
{ __builtin_ffs(DRM_ROTATE_270) - 1, "rotate-270" },
{ __builtin_ffs(DRM_REFLECT_X) - 1, "reflect-x" },
{ __builtin_ffs(DRM_REFLECT_Y) - 1, "reflect-y" },
- };
- return drm_property_create_bitmask(dev, 0, "rotation",
props, ARRAY_SIZE(props),
supported_rotations);
-} -EXPORT_SYMBOL(drm_mode_create_rotation_property);
int drm_plane_create_rotation_property(struct drm_plane *plane, unsigned int rotation, unsigned int supported_rotations) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index e0d428f9d1cb..83dbae0fabcf 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -392,15 +392,10 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) if (plane->type != DRM_PLANE_TYPE_PRIMARY) drm_plane_force_disable(plane);
if (plane->rotation_property) {
if (plane->rotation_property) drm_mode_plane_set_obj_prop(plane, plane->rotation_property, DRM_ROTATE_0);
} else if (dev->mode_config.rotation_property) {
drm_mode_plane_set_obj_prop(plane,
dev->mode_config.rotation_property,
DRM_ROTATE_0);
}
}
for (i = 0; i < fb_helper->crtc_count; i++) {
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h index fd351924e1c5..13221cf9b3eb 100644 --- a/include/drm/drm_blend.h +++ b/include/drm/drm_blend.h @@ -52,8 +52,6 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation) return rotation & (DRM_ROTATE_90 | DRM_ROTATE_270); }
-struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
unsigned int supported_rotations);
int drm_plane_create_rotation_property(struct drm_plane *plane, unsigned int rotation, unsigned int supported_rotations); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 284c1b3aec10..bc860cfc67ca 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1156,11 +1156,6 @@ struct drm_mode_config { */ struct drm_property *plane_type_property; /**
* @rotation_property: Optional property for planes or CRTCs to specifiy
* rotation.
*/
- struct drm_property *rotation_property;
- /**
*/
- @prop_src_x: Default atomic plane property for the plane source
- position in the connected &drm_framebuffer.
-- 2.7.4
From: Ville Syrjälä ville.syrjala@linux.intel.com
Using == to check for 180 degree rotation only works as long as the reflection bits aren't set. That will change soon enough for CHV, so let's stop doing things the wrong way.
v2: Drop the BIT()
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 8 ++++---- drivers/gpu/drm/i915/intel_sprite.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a94f7d195db4..7aaea7a44c0a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3087,7 +3087,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, intel_crtc->dspaddr_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
- if (rotation == DRM_ROTATE_180) { + if (rotation & DRM_ROTATE_180) { dspcntr |= DISPPLANE_ROTATE_180;
x += (crtc_state->pipe_src_w - 1); @@ -3188,7 +3188,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, intel_crtc->dspaddr_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
- if (rotation == DRM_ROTATE_180) { + if (rotation & DRM_ROTATE_180) { dspcntr |= DISPPLANE_ROTATE_180;
if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) { @@ -10871,7 +10871,7 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, if (HAS_DDI(dev_priv)) cntl |= CURSOR_PIPE_CSC_ENABLE;
- if (plane_state->base.rotation == DRM_ROTATE_180) + if (plane_state->base.rotation & DRM_ROTATE_180) cntl |= CURSOR_ROTATE_180; }
@@ -10917,7 +10917,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
/* ILK+ do this automagically */ if (HAS_GMCH_DISPLAY(dev_priv) && - plane_state->base.rotation == DRM_ROTATE_180) { + plane_state->base.rotation & DRM_ROTATE_180) { base += (plane_state->base.crtc_h * plane_state->base.crtc_w - 1) * 4; } diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 43d0350856e7..3821cf2a8209 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -436,7 +436,7 @@ vlv_update_plane(struct drm_plane *dplane, intel_add_fb_offsets(&x, &y, plane_state, 0); sprsurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
- if (rotation == DRM_ROTATE_180) { + if (rotation & DRM_ROTATE_180) { sprctl |= SP_ROTATE_180;
x += src_w; @@ -566,7 +566,7 @@ ivb_update_plane(struct drm_plane *plane, intel_add_fb_offsets(&x, &y, plane_state, 0); sprsurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
- if (rotation == DRM_ROTATE_180) { + if (rotation & DRM_ROTATE_180) { sprctl |= SPRITE_ROTATE_180;
/* HSW and BDW does this automagically in hardware */ @@ -700,7 +700,7 @@ ilk_update_plane(struct drm_plane *plane, intel_add_fb_offsets(&x, &y, plane_state, 0); dvssurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
- if (rotation == DRM_ROTATE_180) { + if (rotation & DRM_ROTATE_180) { dvscntr |= DVS_ROTATE_180;
x += src_w;
From: Ville Syrjälä ville.syrjala@linux.intel.com
Move the plane control register rotation setup away from the coordinate munging code. This will result in neater looking code once we add reflection support for CHV.
v2: Drop the BIT(), drop some usless parens,
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 24 +++++++++++++----------- drivers/gpu/drm/i915/intel_sprite.c | 26 ++++++++++++++------------ 2 files changed, 27 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7aaea7a44c0a..533442ac713c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3078,6 +3078,9 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, fb->modifier[0] == I915_FORMAT_MOD_X_TILED) dspcntr |= DISPPLANE_TILED;
+ if (rotation & DRM_ROTATE_180) + dspcntr |= DISPPLANE_ROTATE_180; + if (IS_G4X(dev_priv)) dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
@@ -3088,10 +3091,8 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, intel_compute_tile_offset(&x, &y, plane_state, 0);
if (rotation & DRM_ROTATE_180) { - dspcntr |= DISPPLANE_ROTATE_180; - - x += (crtc_state->pipe_src_w - 1); - y += (crtc_state->pipe_src_h - 1); + x += crtc_state->pipe_src_w - 1; + y += crtc_state->pipe_src_h - 1; }
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); @@ -3180,6 +3181,9 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED) dspcntr |= DISPPLANE_TILED;
+ if (rotation & DRM_ROTATE_180) + dspcntr |= DISPPLANE_ROTATE_180; + if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
@@ -3188,13 +3192,11 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, intel_crtc->dspaddr_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
- if (rotation & DRM_ROTATE_180) { - dspcntr |= DISPPLANE_ROTATE_180; - - if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) { - x += (crtc_state->pipe_src_w - 1); - y += (crtc_state->pipe_src_h - 1); - } + /* HSW+ does this automagically in hardware */ + if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv) && + rotation & DRM_ROTATE_180) { + x += crtc_state->pipe_src_w - 1; + y += crtc_state->pipe_src_h - 1; }
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 3821cf2a8209..9e002811e697 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -427,6 +427,9 @@ vlv_update_plane(struct drm_plane *dplane, if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED) sprctl |= SP_TILED;
+ if (rotation & DRM_ROTATE_180) + sprctl |= SP_ROTATE_180; + /* Sizes are 0 based */ src_w--; src_h--; @@ -437,8 +440,6 @@ vlv_update_plane(struct drm_plane *dplane, sprsurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
if (rotation & DRM_ROTATE_180) { - sprctl |= SP_ROTATE_180; - x += src_w; y += src_h; } @@ -546,6 +547,9 @@ ivb_update_plane(struct drm_plane *plane, if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED) sprctl |= SPRITE_TILED;
+ if (rotation & DRM_ROTATE_180) + sprctl |= SPRITE_ROTATE_180; + if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; else @@ -566,14 +570,11 @@ ivb_update_plane(struct drm_plane *plane, intel_add_fb_offsets(&x, &y, plane_state, 0); sprsurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
- if (rotation & DRM_ROTATE_180) { - sprctl |= SPRITE_ROTATE_180; - - /* HSW and BDW does this automagically in hardware */ - if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) { - x += src_w; - y += src_h; - } + /* HSW+ does this automagically in hardware */ + if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv) && + rotation & DRM_ROTATE_180) { + x += src_w; + y += src_h; }
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); @@ -684,6 +685,9 @@ ilk_update_plane(struct drm_plane *plane, if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED) dvscntr |= DVS_TILED;
+ if (rotation & DRM_ROTATE_180) + dvscntr |= DVS_ROTATE_180; + if (IS_GEN6(dev_priv)) dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
@@ -701,8 +705,6 @@ ilk_update_plane(struct drm_plane *plane, dvssurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
if (rotation & DRM_ROTATE_180) { - dvscntr |= DVS_ROTATE_180; - x += src_w; y += src_h; }
From: Ville Syrjälä ville.syrjala@linux.intel.com
The primary and sprite planes on CHV pipe B support horizontal mirroring. Expose it to the world.
Sadly the hardware ignores the mirror bit when the rotate bit is set, so we'll have to reject the 180+X case.
v2: Drop the BIT() v3: Pass dev_priv instead of dev to IS_CHERRYVIEW()
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/intel_atomic_plane.c | 9 +++++++++ drivers/gpu/drm/i915/intel_display.c | 9 +++++++++ drivers/gpu/drm/i915/intel_sprite.c | 9 +++++++++ 3 files changed, 27 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index c762ae549a1c..157248c6288a 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -108,6 +108,7 @@ intel_plane_destroy_state(struct drm_plane *plane, static int intel_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { + struct drm_i915_private *dev_priv = to_i915(plane->dev); struct drm_crtc *crtc = state->crtc; struct intel_crtc *intel_crtc; struct intel_crtc_state *crtc_state; @@ -169,6 +170,14 @@ static int intel_plane_atomic_check(struct drm_plane *plane, } }
+ /* CHV ignores the mirror bit when the rotate bit is set :( */ + if (IS_CHERRYVIEW(dev_priv) && + state->rotation & DRM_ROTATE_180 && + state->rotation & DRM_REFLECT_X) { + DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n"); + return -EINVAL; + } + intel_state->base.visible = false; ret = intel_plane->check_plane(plane, crtc_state, intel_state); if (ret) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 533442ac713c..190dfee17955 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3081,6 +3081,9 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, if (rotation & DRM_ROTATE_180) dspcntr |= DISPPLANE_ROTATE_180;
+ if (rotation & DRM_REFLECT_X) + dspcntr |= DISPPLANE_MIRROR; + if (IS_G4X(dev_priv)) dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
@@ -3093,6 +3096,8 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, if (rotation & DRM_ROTATE_180) { x += crtc_state->pipe_src_w - 1; y += crtc_state->pipe_src_h - 1; + } else if (rotation & DRM_REFLECT_X) { + x += crtc_state->pipe_src_w - 1; }
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); @@ -15080,6 +15085,10 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, supported_rotations = DRM_ROTATE_0 | DRM_ROTATE_90 | DRM_ROTATE_180 | DRM_ROTATE_270; + } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { + supported_rotations = + DRM_ROTATE_0 | DRM_ROTATE_180 | + DRM_REFLECT_X; } else if (INTEL_GEN(dev_priv) >= 4) { supported_rotations = DRM_ROTATE_0 | DRM_ROTATE_180; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 9e002811e697..d4c332115082 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -430,6 +430,9 @@ vlv_update_plane(struct drm_plane *dplane, if (rotation & DRM_ROTATE_180) sprctl |= SP_ROTATE_180;
+ if (rotation & DRM_REFLECT_X) + sprctl |= SP_MIRROR; + /* Sizes are 0 based */ src_w--; src_h--; @@ -442,6 +445,8 @@ vlv_update_plane(struct drm_plane *dplane, if (rotation & DRM_ROTATE_180) { x += src_w; y += src_h; + } else if (rotation & DRM_REFLECT_X) { + x += src_w; }
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); @@ -1132,6 +1137,10 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) supported_rotations = DRM_ROTATE_0 | DRM_ROTATE_90 | DRM_ROTATE_180 | DRM_ROTATE_270; + } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { + supported_rotations = + DRM_ROTATE_0 | DRM_ROTATE_180 | + DRM_REFLECT_X; } else { supported_rotations = DRM_ROTATE_0 | DRM_ROTATE_180;
dri-devel@lists.freedesktop.org