diff options
author | Koen Kooi <koen@openembedded.org> | 2009-07-30 11:19:10 +0200 |
---|---|---|
committer | Koen Kooi <koen@openembedded.org> | 2009-07-30 11:19:10 +0200 |
commit | f2e6ca6bfa79d166ee72224bbb95ca1a71125d43 (patch) | |
tree | b2facdc46191d38b9917a7d390c44f668f19183f /recipes/linux/linux-omap-pm/dss2/0072-DSS2-Allow-independent-rotation-for-each-plane.patch | |
parent | 0501fbe7b6f99eddc8ee9b0d3dab9ebac4722166 (diff) |
linux-omap-pm git: add patch for fix musb oops and dss2 patches
Diffstat (limited to 'recipes/linux/linux-omap-pm/dss2/0072-DSS2-Allow-independent-rotation-for-each-plane.patch')
-rw-r--r-- | recipes/linux/linux-omap-pm/dss2/0072-DSS2-Allow-independent-rotation-for-each-plane.patch | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-pm/dss2/0072-DSS2-Allow-independent-rotation-for-each-plane.patch b/recipes/linux/linux-omap-pm/dss2/0072-DSS2-Allow-independent-rotation-for-each-plane.patch new file mode 100644 index 0000000000..4fccaa65d1 --- /dev/null +++ b/recipes/linux/linux-omap-pm/dss2/0072-DSS2-Allow-independent-rotation-for-each-plane.patch @@ -0,0 +1,277 @@ +From d2bb6e5832085247afc9a925ce2c4fc76a84db0e Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com> +Date: Thu, 14 May 2009 15:03:50 +0200 +Subject: [PATCH 072/146] DSS2: Allow independent rotation for each plane +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit + +Allow overlays attached to the same framebuffer to have different +rotation settings. A new sysfs file overlays_rotate can be used to +configure the rotation settings for each overlay. The total rotation +for a single overlay is now '(var.rotate + overlays_rotate) % 4'. + +Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com> +--- + drivers/video/omap2/omapfb/omapfb-main.c | 42 ++++++++----- + drivers/video/omap2/omapfb/omapfb-sysfs.c | 91 ++++++++++++++++++++++++++++- + drivers/video/omap2/omapfb/omapfb.h | 2 +- + 3 files changed, 115 insertions(+), 20 deletions(-) + +diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c +index 0cdf36e..c4bd081 100644 +--- a/drivers/video/omap2/omapfb/omapfb-main.c ++++ b/drivers/video/omap2/omapfb/omapfb-main.c +@@ -174,11 +174,11 @@ static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) + return offset; + } + +-static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi) ++static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot) + { + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { +- return ofbi->region.vrfb.paddr[ofbi->rotation] +- + omapfb_get_vrfb_offset(ofbi, ofbi->rotation); ++ return ofbi->region.vrfb.paddr[rot] ++ + omapfb_get_vrfb_offset(ofbi, rot); + } else { + return ofbi->region.paddr; + } +@@ -391,11 +391,7 @@ void set_fb_fix(struct fb_info *fbi) + /* used by open/write in fbmem.c */ + fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi); + +- if (ofbi->rotation != var->rotate) { +- DBG("changing rotation %d -> %d\n", +- ofbi->rotation, var->rotate); +- ofbi->rotation = var->rotate; +- } ++ DBG("changing rotation to %d\n", var->rotate); + + /* used by mmap in fbmem.c */ + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { +@@ -665,11 +661,21 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, + int xres, yres; + int screen_width; + int mirror; ++ int rotation = var->rotate; ++ int i; ++ ++ for (i = 0; i < ofbi->num_overlays; i++) { ++ if (ovl != ofbi->overlays[i]) ++ continue; ++ ++ rotation = (rotation + ofbi->rotation[i]) % 4; ++ break; ++ } + + DBG("setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->id, + posx, posy, outw, outh); + +- if (ofbi->rotation == FB_ROTATE_CW || ofbi->rotation == FB_ROTATE_CCW) { ++ if (rotation == FB_ROTATE_CW || rotation == FB_ROTATE_CCW) { + xres = var->yres; + yres = var->xres; + } else { +@@ -681,7 +687,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, + var->xoffset) * var->bits_per_pixel) >> 3; + + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { +- data_start_p = omapfb_get_region_rot_paddr(ofbi); ++ data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation); + data_start_v = NULL; + } else { + data_start_p = omapfb_get_region_paddr(ofbi); +@@ -726,7 +732,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, + info.height = yres; + info.color_mode = mode; + info.rotation_type = ofbi->rotation_type; +- info.rotation = ofbi->rotation; ++ info.rotation = rotation; + info.mirror = mirror; + + info.pos_x = posx; +@@ -777,8 +783,9 @@ int omapfb_apply_changes(struct fb_info *fbi, int init) + } + + if (init || (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { +- if (ofbi->rotation == FB_ROTATE_CW || +- ofbi->rotation == FB_ROTATE_CCW) { ++ int rotation = (var->rotate + ofbi->rotation[i]) % 4; ++ if (rotation == FB_ROTATE_CW || ++ rotation == FB_ROTATE_CCW) { + outw = var->yres; + outh = var->xres; + } else { +@@ -1575,7 +1582,7 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) + var->nonstd = 0; + var->bits_per_pixel = 0; + +- var->rotate = ofbi->rotation; ++ var->rotate = def_rotate; + + /* + * Check if there is a default color format set in the board file, +@@ -1605,10 +1612,12 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) + + if (display) { + u16 w, h; ++ int rotation = (var->rotate + ofbi->rotation[0]) % 4; ++ + display->get_resolution(display, &w, &h); + +- if (ofbi->rotation == FB_ROTATE_CW || +- ofbi->rotation == FB_ROTATE_CCW) { ++ if (rotation == FB_ROTATE_CW || ++ rotation == FB_ROTATE_CCW) { + var->xres = h; + var->yres = w; + } else { +@@ -1724,7 +1733,6 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) + /* assign these early, so that fb alloc can use them */ + ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : + OMAP_DSS_ROT_DMA; +- ofbi->rotation = def_rotate; + ofbi->mirror = def_mirror; + + fbdev->num_fbs++; +diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c +index 702199d..dcec42b 100644 +--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c ++++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c +@@ -259,8 +259,10 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, + if (ovl->manager) + ovl->manager->apply(ovl->manager); + +- for (t = i + 1; t < ofbi->num_overlays; t++) ++ for (t = i + 1; t < ofbi->num_overlays; t++) { ++ ofbi->rotation[t-1] = ofbi->rotation[t]; + ofbi->overlays[t-1] = ofbi->overlays[t]; ++ } + + ofbi->num_overlays--; + i--; +@@ -282,7 +284,7 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, + + if (found) + continue; +- ++ ofbi->rotation[ofbi->num_overlays] = 0; + ofbi->overlays[ofbi->num_overlays++] = ovl; + + added = true; +@@ -301,6 +303,90 @@ out: + return r; + } + ++static ssize_t show_overlays_rotate(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct fb_info *fbi = dev_get_drvdata(dev); ++ struct omapfb_info *ofbi = FB2OFB(fbi); ++ ssize_t l = 0; ++ int t; ++ ++ for (t = 0; t < ofbi->num_overlays; t++) { ++ l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", ++ t == 0 ? "" : ",", ofbi->rotation[t]); ++ } ++ ++ l += snprintf(buf + l, PAGE_SIZE - l, "\n"); ++ ++ return l; ++} ++ ++static ssize_t store_overlays_rotate(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct fb_info *fbi = dev_get_drvdata(dev); ++ struct omapfb_info *ofbi = FB2OFB(fbi); ++ struct omapfb2_device *fbdev = ofbi->fbdev; ++ int num_ovls = 0, r, i; ++ int len; ++ bool changed = false; ++ u8 rotation[OMAPFB_MAX_OVL_PER_FB]; ++ ++ len = strlen(buf); ++ if (buf[len - 1] == '\n') ++ len = len - 1; ++ ++ omapfb_lock(fbdev); ++ ++ if (len > 0) { ++ char *p = (char *)buf; ++ ++ while (p < buf + len) { ++ int rot; ++ ++ if (num_ovls == ofbi->num_overlays) { ++ r = -EINVAL; ++ goto out; ++ } ++ ++ rot = simple_strtoul(p, &p, 0); ++ if (rot < 0 || rot > 3) { ++ r = -EINVAL; ++ goto out; ++ } ++ ++ if (ofbi->rotation[num_ovls] != rot) ++ changed = true; ++ ++ rotation[num_ovls++] = rot; ++ ++ p++; ++ } ++ } ++ ++ if (num_ovls != ofbi->num_overlays) { ++ r = -EINVAL; ++ goto out; ++ } ++ ++ if (changed) { ++ for (i = 0; i < num_ovls; ++i) ++ ofbi->rotation[i] = rotation[i]; ++ ++ r = omapfb_apply_changes(fbi, 0); ++ if (r) ++ goto out; ++ ++ /* FIXME error handling? */ ++ } ++ ++ r = count; ++out: ++ omapfb_unlock(fbdev); ++ ++ return r; ++} ++ + static ssize_t show_size(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -369,6 +455,7 @@ static struct device_attribute omapfb_attrs[] = { + __ATTR(mirror, S_IRUGO | S_IWUSR, show_mirror, store_mirror), + __ATTR(size, S_IRUGO | S_IWUSR, show_size, store_size), + __ATTR(overlays, S_IRUGO | S_IWUSR, show_overlays, store_overlays), ++ __ATTR(overlays_rotate, S_IRUGO | S_IWUSR, show_overlays_rotate, store_overlays_rotate), + __ATTR(phys_addr, S_IRUGO, show_phys, NULL), + __ATTR(virt_addr, S_IRUGO, show_virt, NULL), + }; +diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h +index 43f6922..f40fcce 100644 +--- a/drivers/video/omap2/omapfb/omapfb.h ++++ b/drivers/video/omap2/omapfb/omapfb.h +@@ -62,7 +62,7 @@ struct omapfb_info { + struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB]; + struct omapfb2_device *fbdev; + enum omap_dss_rotation_type rotation_type; +- u8 rotation; ++ u8 rotation[OMAPFB_MAX_OVL_PER_FB]; + bool mirror; + }; + +-- +1.6.2.4 + |