@@ -184,6 +184,11 @@ static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
{
if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ if (rot == FB_ROTATE_CW)
+ rot = FB_ROTATE_CCW;
+ else if (rot == FB_ROTATE_CCW)
+ rot = FB_ROTATE_CW;
+
return ofbi->region.vrfb.paddr[rot]
+ omapfb_get_vrfb_offset(ofbi, rot);
} else {
@@ -191,20 +196,32 @@ static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
}
}
-static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
+static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi, int rot)
{
- if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
- return ofbi->region.vrfb.paddr[0];
- else
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ if (rot == FB_ROTATE_CW)
+ rot = FB_ROTATE_CCW;
+ else if (rot == FB_ROTATE_CCW)
+ rot = FB_ROTATE_CW;
+
+ return ofbi->region.vrfb.paddr[rot];
+ } else {
return ofbi->region.paddr;
+ }
}
-static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
+static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi, int rot)
{
- if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
- return ofbi->region.vrfb.vaddr[0];
- else
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ if (rot == FB_ROTATE_CW)
+ rot = FB_ROTATE_CCW;
+ else if (rot == FB_ROTATE_CCW)
+ rot = FB_ROTATE_CW;
+
+ return ofbi->region.vrfb.vaddr[rot];
+ } else {
return ofbi->region.vaddr;
+ }
}
static struct omapfb_colormode omapfb_colormodes[] = {
@@ -503,7 +520,7 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
unsigned bytespp;
bool yuv_mode;
enum omap_color_mode mode;
- int r;
+ int r, rotation = var->rotate;
bool reconf;
if (!rg->size || ofbi->rotation_type != OMAP_DSS_ROT_VRFB)
@@ -511,6 +528,11 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
DBG("setup_vrfb_rotation\n");
+ if (rotation == FB_ROTATE_CW)
+ rotation = FB_ROTATE_CCW;
+ else if (rotation == FB_ROTATE_CCW)
+ rotation = FB_ROTATE_CW;
+
r = fb_mode_to_dss_mode(var, &mode);
if (r)
return r;
@@ -534,32 +556,35 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
vrfb->yres != var->yres_virtual)
reconf = true;
- if (vrfb->vaddr[0] && reconf) {
+ if (vrfb->vaddr[rotation] && reconf) {
fbi->screen_base = NULL;
fix->smem_start = 0;
fix->smem_len = 0;
- iounmap(vrfb->vaddr[0]);
- vrfb->vaddr[0] = NULL;
+ iounmap(vrfb->vaddr[rotation]);
+ vrfb->vaddr[rotation] = NULL;
DBG("setup_vrfb_rotation: reset fb\n");
}
- if (vrfb->vaddr[0])
+ if (vrfb->vaddr[rotation])
return 0;
- omap_vrfb_setup(&rg->vrfb, rg->paddr,
- var->xres_virtual,
- var->yres_virtual,
- bytespp, yuv_mode);
+ if (rotation == FB_ROTATE_CW || rotation == FB_ROTATE_CCW)
+ omap_vrfb_setup(&rg->vrfb, rg->paddr,
+ var->yres_virtual, var->xres_virtual,
+ bytespp, yuv_mode);
+ else
+ omap_vrfb_setup(&rg->vrfb, rg->paddr,
+ var->xres_virtual, var->yres_virtual,
+ bytespp, yuv_mode);
- /* Now one can ioremap the 0 angle view */
- r = omap_vrfb_map_angle(vrfb, var->yres_virtual, 0);
+ /* Now one can ioremap the rotation angle view */
+ r = omap_vrfb_map_angle(vrfb, var->yres_virtual, rotation);
if (r)
return r;
-
/* used by open/write in fbmem.c */
- fbi->screen_base = ofbi->region.vrfb.vaddr[0];
+ fbi->screen_base = ofbi->region.vrfb.vaddr[rotation];
- fix->smem_start = ofbi->region.vrfb.paddr[0];
+ fix->smem_start = ofbi->region.vrfb.paddr[rotation];
switch (var->nonstd) {
case OMAPFB_COLOR_YUV422:
@@ -603,7 +628,8 @@ void set_fb_fix(struct fb_info *fbi)
DBG("set_fb_fix\n");
/* used by open/write in fbmem.c */
- fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi);
+ fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi,
+ var->rotate);
/* used by mmap in fbmem.c */
if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
@@ -626,7 +652,7 @@ void set_fb_fix(struct fb_info *fbi)
fix->smem_len = rg->size;
}
- fix->smem_start = omapfb_get_region_paddr(ofbi);
+ fix->smem_start = omapfb_get_region_paddr(ofbi, var->rotate);
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -862,15 +888,15 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
- data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation);
+ data_start_p = omapfb_get_region_rot_paddr(ofbi, 0);
data_start_v = NULL;
} else {
- data_start_p = omapfb_get_region_paddr(ofbi);
- data_start_v = omapfb_get_region_vaddr(ofbi);
+ data_start_p = omapfb_get_region_paddr(ofbi, 0);
+ data_start_v = omapfb_get_region_vaddr(ofbi, 0);
}
if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
- offset = calc_rotation_offset_vrfb(var, fix, rotation);
+ offset = calc_rotation_offset_vrfb(var, fix, 0);
else
offset = calc_rotation_offset_dma(var, fix, rotation);
@@ -1078,6 +1104,7 @@ static struct vm_operations_struct mmap_user_ops = {
static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct fb_var_screeninfo *var = &fbi->var;
struct fb_fix_screeninfo *fix = &fbi->fix;
unsigned long off;
unsigned long start;
@@ -1089,7 +1116,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
return -EINVAL;
off = vma->vm_pgoff << PAGE_SHIFT;
- start = omapfb_get_region_paddr(ofbi);
+ start = omapfb_get_region_paddr(ofbi, var->rotate);
len = fix->smem_len;
if (off >= len)
return -EINVAL;