summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörgen Nilsson <jorgen.nilsson@stericsson.com>2011-12-15 08:09:12 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:04:22 +0200
commit01505bc0bb2b83630610521c252204cf8c263d57 (patch)
tree33c17f94ce9ed3036de0f59766c5d464984a50f0
parentb5478f54d905e5c81680d1974e3a5fae1ca8941d (diff)
misc: compdev: Handle rotation
Make sure to handle incoming rotated surfaces with MCDE. ST-Ericsson ID: 404691 ST-Ericsson FOSS-OUT ID: NA Change-Id: Ia3c836df61e266e3e3d95f2a2e44140c50cf55db Signed-off-by: Jörgen Nilsson <jorgen.nilsson@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/42891 Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
-rw-r--r--drivers/misc/compdev/compdev.c67
1 files changed, 62 insertions, 5 deletions
diff --git a/drivers/misc/compdev/compdev.c b/drivers/misc/compdev/compdev.c
index 7e840a59d9c..d7ed1c867e2 100644
--- a/drivers/misc/compdev/compdev.c
+++ b/drivers/misc/compdev/compdev.c
@@ -45,6 +45,8 @@ struct compdev {
struct mcde_overlay *ovly[NUM_COMPDEV_BUFS];
struct compdev_buffer ovly_buffer[NUM_COMPDEV_BUFS];
struct compdev_size phy_size;
+ enum mcde_display_rotation display_rotation;
+ enum compdev_rotation current_buffer_rotation;
};
static int compdev_open(struct inode *inode, struct file *file)
@@ -218,6 +220,37 @@ resolve_failed:
return ret;
}
+static int compdev_update_rotation(struct compdev *cd, enum compdev_rotation rotation)
+{
+ /* Set video mode */
+ struct mcde_video_mode vmode;
+ int ret = 0;
+
+ memset(&vmode, 0, sizeof(struct mcde_video_mode));
+ mcde_dss_get_video_mode(cd->ddev, &vmode);
+ if ((cd->display_rotation + rotation) % 180) {
+ vmode.xres = cd->phy_size.height;
+ vmode.yres = cd->phy_size.width;
+ } else {
+ vmode.xres = cd->phy_size.width;
+ vmode.yres = cd->phy_size.height;
+ }
+
+ ret = mcde_dss_set_video_mode(cd->ddev, &vmode);
+ if (ret != 0)
+ goto exit;
+
+ /* Set rotation */
+ ret = mcde_dss_set_rotation(cd->ddev, (cd->display_rotation + rotation) % 360);
+ if (ret != 0)
+ goto exit;
+
+ /* Apply */
+ ret = mcde_dss_apply_channel(cd->ddev);
+exit:
+ return ret;
+}
+
static int release_prev_frame(struct compdev *cd)
{
int ret = 0;
@@ -265,13 +298,24 @@ static int compdev_post_buffers(struct compdev *cd,
release_prev_frame(cd);
/* Validate buffer count */
- if (req->buffer_count > NUM_COMPDEV_BUFS || req->buffer_count == 0) {
+ if (req->buffer_count > NUM_COMPDEV_BUFS || req->buffer_count == 0) {
dev_warn(cd->mdev.this_device,
"Illegal buffer count, will be clamped to %d\n",
NUM_COMPDEV_BUFS);
req->buffer_count = NUM_COMPDEV_BUFS;
}
+ /* Set channel rotation */
+ if (req->buffer_count > 0 &&
+ (cd->current_buffer_rotation != req->rotation)) {
+ if (compdev_update_rotation(cd, req->rotation) != 0)
+ dev_warn(cd->mdev.this_device,
+ "Failed to update MCDE rotation (req->rotation = %d), %d\n",
+ req->rotation, ret);
+ else
+ cd->current_buffer_rotation = req->rotation;
+ }
+
/* Handle buffers */
for (i = 0; i < req->buffer_count; i++) {
int overlay_index = req->buffer_count - i - 1;
@@ -305,10 +349,20 @@ static long compdev_ioctl(struct file *file,
switch (cmd) {
case COMPDEV_GET_SIZE_IOC:
- ret = copy_to_user((void __user *)arg, &cd->phy_size,
- sizeof(cd->phy_size));
- if (ret)
- ret = -EFAULT;
+ {
+ struct compdev_size tmp;
+ if ((cd->display_rotation) % 180) {
+ tmp.height = cd->phy_size.width;
+ tmp.width = cd->phy_size.height;
+ } else {
+ tmp.height = cd->phy_size.height;
+ tmp.width = cd->phy_size.width;
+ }
+ ret = copy_to_user((void __user *)arg, &tmp,
+ sizeof(tmp));
+ if (ret)
+ ret = -EFAULT;
+ }
break;
case COMPDEV_POST_BUFFERS_IOC:
/* arg is user pointer to struct compdev_post_buffers_req */
@@ -399,6 +453,9 @@ int compdev_create(struct mcde_display_device *ddev,
mcde_dss_get_native_resolution(ddev, &cd->phy_size.width,
&cd->phy_size.height);
+ cd->display_rotation = mcde_dss_get_rotation(ddev);
+ cd->current_buffer_rotation = 0;
+
ret = misc_register(&cd->mdev);
if (ret)
goto fail_register_misc;