Commit a84f21c0 authored by Rodrigo Vivi's avatar Rodrigo Vivi Committed by Tony Lindgren

Adding support to rotation on blizzard

The LCD controller (EPSON S1D13744) supports
rotation (0, 90, 180 and 270 degrees) on hardware just setting
the bits 0 and 1 of 0x28 register (LCD Panel Configuration Register).
Now it is possible to use this caps only setting the angle degree on var rotate of fb_var_screeninfo using the FBIOPUT_VSCREENINFO ioctl.
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@openbossa.org>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 0ce52a74
......@@ -44,6 +44,7 @@
#define BLIZZARD_CLK_SRC 0x0e
#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
#define BLIZZARD_MEM_BANK0_STATUS 0x14
#define BLIZZARD_PANEL_CONFIGURATION 0x28
#define BLIZZARD_HDISP 0x2a
#define BLIZZARD_HNDP 0x2c
#define BLIZZARD_VDISP0 0x2e
......@@ -908,6 +909,35 @@ static int blizzard_set_scale(int plane, int orig_w, int orig_h,
return 0;
}
static int blizzard_set_rotate(int angle)
{
u32 l;
l = blizzard_read_reg(BLIZZARD_PANEL_CONFIGURATION);
l &= ~0x03;
switch (angle) {
case 0:
l = l | 0x00;
break;
case 90:
l = l | 0x03;
break;
case 180:
l = l | 0x02;
break;
case 270:
l = l | 0x01;
break;
default:
return -EINVAL;
}
blizzard_write_reg(BLIZZARD_PANEL_CONFIGURATION, l);
return 0;
}
static int blizzard_enable_plane(int plane, int enable)
{
if (enable)
......@@ -1285,7 +1315,8 @@ static void blizzard_get_caps(int plane, struct omapfb_caps *caps)
caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE |
OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE |
OMAPFB_CAPS_WINDOW_SCALE |
OMAPFB_CAPS_WINDOW_OVERLAY;
OMAPFB_CAPS_WINDOW_OVERLAY |
OMAPFB_CAPS_WINDOW_ROTATE;
if (blizzard.te_connected)
caps->ctrl |= OMAPFB_CAPS_TEARSYNC;
caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) |
......@@ -1560,6 +1591,7 @@ struct lcd_ctrl blizzard_ctrl = {
.setup_plane = blizzard_setup_plane,
.set_scale = blizzard_set_scale,
.enable_plane = blizzard_enable_plane,
.set_rotate = blizzard_set_rotate,
.update_window = blizzard_update_window_async,
.sync = blizzard_sync,
.suspend = blizzard_suspend,
......
......@@ -64,6 +64,7 @@ static struct caps_table_struct ctrl_caps[] = {
{ OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" },
{ OMAPFB_CAPS_WINDOW_SCALE, "scale window" },
{ OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" },
{ OMAPFB_CAPS_WINDOW_ROTATE, "rotate window" },
{ OMAPFB_CAPS_SET_BACKLIGHT, "backlight setting" },
};
......@@ -214,6 +215,13 @@ static int ctrl_change_mode(struct fb_info *fbi)
offset, var->xres_virtual,
plane->info.pos_x, plane->info.pos_y,
var->xres, var->yres, plane->color_mode);
if (r < 0)
return r;
if (fbdev->ctrl->set_rotate != NULL)
if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0)
return r;
if (fbdev->ctrl->set_scale != NULL)
r = fbdev->ctrl->set_scale(plane->idx,
var->xres, var->yres,
......@@ -597,7 +605,7 @@ static void omapfb_rotate(struct fb_info *fbi, int rotate)
struct omapfb_device *fbdev = plane->fbdev;
omapfb_rqueue_lock(fbdev);
if (cpu_is_omap15xx() && rotate != fbi->var.rotate) {
if (rotate != fbi->var.rotate) {
struct fb_var_screeninfo *new_var = &fbdev->new_var;
memcpy(new_var, &fbi->var, sizeof(*new_var));
......@@ -704,28 +712,42 @@ int omapfb_update_window_async(struct fb_info *fbi,
void (*callback)(void *),
void *callback_data)
{
int xres, yres;
struct omapfb_plane_struct *plane = fbi->par;
struct omapfb_device *fbdev = plane->fbdev;
struct fb_var_screeninfo *var;
struct fb_var_screeninfo *var = &fbi->var;
switch (var->rotate) {
case 0:
case 180:
xres = fbdev->panel->x_res;
yres = fbdev->panel->y_res;
break;
case 90:
case 270:
xres = fbdev->panel->y_res;
yres = fbdev->panel->x_res;
break;
default:
return -EINVAL;
}
var = &fbi->var;
if (win->x >= var->xres || win->y >= var->yres ||
win->out_x > var->xres || win->out_y >= var->yres)
if (win->x >= xres || win->y >= yres ||
win->out_x > xres || win->out_y > yres)
return -EINVAL;
if (!fbdev->ctrl->update_window ||
fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE)
return -ENODEV;
if (win->x + win->width >= var->xres)
win->width = var->xres - win->x;
if (win->y + win->height >= var->yres)
win->height = var->yres - win->y;
/* The out sizes should be cropped to the LCD size */
if (win->out_x + win->out_width > fbdev->panel->x_res)
win->out_width = fbdev->panel->x_res - win->out_x;
if (win->out_y + win->out_height > fbdev->panel->y_res)
win->out_height = fbdev->panel->y_res - win->out_y;
if (win->x + win->width > xres)
win->width = xres - win->x;
if (win->y + win->height > yres)
win->height = yres - win->y;
if (win->out_x + win->out_width > xres)
win->out_width = xres - win->out_x;
if (win->out_y + win->out_height > yres)
win->out_height = yres - win->out_y;
if (!win->width || !win->height || !win->out_width || !win->out_height)
return 0;
......
......@@ -62,6 +62,7 @@
#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
/* Values from DSP must map to lower 16-bits */
......@@ -305,6 +306,7 @@ struct lcd_ctrl {
int screen_width,
int pos_x, int pos_y, int width,
int height, int color_mode);
int (*set_rotate) (int angle);
int (*setup_mem) (int plane, size_t size,
int mem_type, unsigned long *paddr);
int (*mmap) (struct fb_info *info,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment