aboutsummaryrefslogtreecommitdiff
path: root/drivers/mfd/glamo/glamo-fb.c
diff options
context:
space:
mode:
authorNelson Castillo <arhuaco@freaks-unidos.net>2009-04-19 14:41:33 -0500
committerNelson Castillo <arhuaco@freaks-unidos.net>2009-04-19 14:41:33 -0500
commit08c73c0533ec33dba5676d1124634dd1654aef8b (patch)
tree22fd6386ac6baf17e1c1ead7a69325ef2f0c4e65 /drivers/mfd/glamo/glamo-fb.c
parentaa2dbc74bed8cf60e591c654ba1882011b9a8ece (diff)
Revert "Revert "Fixed the LCM driver state transition delay and pixel clock issue""
This reverts commit aa2dbc74bed8cf60e591c654ba1882011b9a8ece. Reverting the revert. Sorry for the noise. Check: http://lists.openmoko.org/pipermail/openmoko-kernel/2009-April/010023.html
Diffstat (limited to 'drivers/mfd/glamo/glamo-fb.c')
-rw-r--r--drivers/mfd/glamo/glamo-fb.c127
1 files changed, 74 insertions, 53 deletions
diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
index 4eb81a508e5..5491dadbf8a 100644
--- a/drivers/mfd/glamo/glamo-fb.c
+++ b/drivers/mfd/glamo/glamo-fb.c
@@ -37,9 +37,9 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
#include <asm/div64.h>
#ifdef CONFIG_PM
@@ -76,6 +76,7 @@ struct glamofb_handle {
u_int32_t pseudo_pal[16];
spinlock_t lock_cmd;
int angle; /* Current rotation angle */
+ int blank_mode;
};
/* 'sibling' spi device for lcm init */
@@ -89,7 +90,7 @@ static int reg_read(struct glamofb_handle *glamo,
{
int i = 0;
- for (i = 0; i != 2; i ++)
+ for (i = 0; i != 2; i++)
nop();
return readw(glamo->base + reg);
@@ -100,7 +101,7 @@ static void reg_write(struct glamofb_handle *glamo,
{
int i = 0;
- for (i = 0; i != 2; i ++)
+ for (i = 0; i != 2; i++)
nop();
writew(val, glamo->base + reg);
@@ -141,7 +142,8 @@ static int glamofb_run_script(struct glamofb_handle *glamo,
int i;
if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_run_script while "
+ dev_err(&glamo->mach_info->glamo->pdev->dev,
+ "IGNORING glamofb_run_script while "
"suspended\n");
return -EBUSY;
}
@@ -166,7 +168,8 @@ static int glamofb_check_var(struct fb_var_screeninfo *var,
struct glamofb_handle *glamo = info->par;
if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_check_var while "
+ dev_err(&glamo->mach_info->glamo->pdev->dev,
+ "IGNORING glamofb_check_var while "
"suspended\n");
return -EBUSY;
}
@@ -263,32 +266,33 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation)
int glamo_rot;
if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING rotate_lcd while "
+ dev_err(&glamo->mach_info->glamo->pdev->dev,
+ "IGNORING rotate_lcd while "
"suspended\n");
return;
}
switch (rotation) {
- case FB_ROTATE_UR:
- glamo_rot = GLAMO_LCD_ROT_MODE_0;
- glamo->angle = 0;
- break;
- case FB_ROTATE_CW:
- glamo_rot = GLAMO_LCD_ROT_MODE_90;
- glamo->angle = 90;
- break;
- case FB_ROTATE_UD:
- glamo_rot = GLAMO_LCD_ROT_MODE_180;
- glamo->angle = 180;
- break;
- case FB_ROTATE_CCW:
- glamo_rot = GLAMO_LCD_ROT_MODE_270;
- glamo->angle = 270;
- break;
- default:
- glamo->angle = 0;
- glamo_rot = GLAMO_LCD_ROT_MODE_0;
- break;
+ case FB_ROTATE_UR:
+ glamo_rot = GLAMO_LCD_ROT_MODE_0;
+ glamo->angle = 0;
+ break;
+ case FB_ROTATE_CW:
+ glamo_rot = GLAMO_LCD_ROT_MODE_90;
+ glamo->angle = 90;
+ break;
+ case FB_ROTATE_UD:
+ glamo_rot = GLAMO_LCD_ROT_MODE_180;
+ glamo->angle = 180;
+ break;
+ case FB_ROTATE_CCW:
+ glamo_rot = GLAMO_LCD_ROT_MODE_270;
+ glamo->angle = 270;
+ break;
+ default:
+ glamo->angle = 0;
+ glamo_rot = GLAMO_LCD_ROT_MODE_0;
+ break;
}
reg_set_bit_mask(glamo,
@@ -298,7 +302,7 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation)
reg_set_bit_mask(glamo,
GLAMO_REG_LCD_MODE1,
GLAMO_LCD_MODE1_ROTATE_EN,
- (glamo_rot != GLAMO_LCD_ROT_MODE_0)?
+ (glamo_rot != GLAMO_LCD_ROT_MODE_0) ?
GLAMO_LCD_MODE1_ROTATE_EN : 0);
}
@@ -313,7 +317,8 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
return;
if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_update_lcd_controller while "
+ dev_err(&glamo->mach_info->glamo->pdev->dev,
+ "IGNORING glamofb_update_lcd_controller while "
"suspended\n");
return;
}
@@ -331,10 +336,10 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
var->pixclock);
if (glamo->angle == 90 || glamo->angle == 270) {
- /*
+ /*
* But if we are going back to portrait mode from here,
- * we get inverted values from Xglamo
- */
+ * we get inverted values from Xglamo
+ */
if (!(var->rotate == FB_ROTATE_UR ||
var->rotate == FB_ROTATE_UD)) {
width = var->yres;
@@ -354,7 +359,8 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
/* We don't need to set xres and yres in this particular case
* because Xglamo does it for us */
if (!(glamo->angle == 90 || glamo->angle == 270)) {
- var->xres = width;var->yres = height;
+ var->xres = width;
+ var->yres = height;
}
var->xres_virtual = width;
@@ -427,7 +433,8 @@ out_unlock:
spin_unlock_irqrestore(&glamo->lock_cmd, flags);
}
-static int glamofb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+static int glamofb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
struct glamofb_handle *glamo = info->par;
u_int16_t page = var->yoffset / glamo->mach_info->yres.defval;
@@ -442,7 +449,8 @@ static int glamofb_set_par(struct fb_info *info)
struct fb_var_screeninfo *var = &info->var;
if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_set_par while "
+ dev_err(&glamo->mach_info->glamo->pdev->dev,
+ "IGNORING glamofb_set_par while "
"suspended\n");
return -EBUSY;
}
@@ -488,17 +496,29 @@ static int glamofb_blank(int blank_mode, struct fb_info *info)
* we should already switch off pixel clock here */
break;
case FB_BLANK_POWERDOWN:
+ /* Simulating FB_BLANK_NORMAL allow turning off backlight */
+ if (gfb->blank_mode != FB_BLANK_NORMAL)
+ notify_blank(info, FB_BLANK_NORMAL);
+
+ /* LCM need notification before pixel clock is stopped */
+ notify_blank(info, blank_mode);
+
/* disable the pixel clock */
glamo_engine_clkreg_set(gcore, GLAMO_ENGINE_LCD,
GLAMO_CLOCK_LCD_EN_DCLK, 0);
+ gfb->blank_mode = blank_mode;
break;
case FB_BLANK_UNBLANK:
case FB_BLANK_NORMAL:
- /* enable the pixel clock */
- glamo_engine_clkreg_set(gcore, GLAMO_ENGINE_LCD,
+ /* enable the pixel clock if off */
+ if (gfb->blank_mode == FB_BLANK_POWERDOWN)
+ glamo_engine_clkreg_set(gcore,
+ GLAMO_ENGINE_LCD,
GLAMO_CLOCK_LCD_EN_DCLK,
GLAMO_CLOCK_LCD_EN_DCLK);
+
notify_blank(info, blank_mode);
+ gfb->blank_mode = blank_mode;
break;
}
@@ -524,7 +544,8 @@ static int glamofb_setcolreg(unsigned regno,
unsigned int val;
if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_set_par while "
+ dev_err(&glamo->mach_info->glamo->pdev->dev,
+ "IGNORING glamofb_set_par while "
"suspended\n");
return -EBUSY;
}
@@ -692,7 +713,8 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
int timeout = 2000000;
if (gfb->mach_info->glamo->suspending) {
- dev_err(&gfb->mach_info->glamo->pdev->dev, "IGNORING glamofb_cmd_mode while "
+ dev_err(&gfb->mach_info->glamo->pdev->dev,
+ "IGNORING glamofb_cmd_mode while "
"suspended\n");
return -EBUSY;
}
@@ -700,7 +722,7 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on);
if (on) {
dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
- __FUNCTION__);
+ __func__);
while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
/* yield() */;
if (timeout < 0) {
@@ -755,12 +777,13 @@ int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val)
int timeout = 200000;
if (gfb->mach_info->glamo->suspending) {
- dev_err(&gfb->mach_info->glamo->pdev->dev, "IGNORING glamofb_cmd_write while "
+ dev_err(&gfb->mach_info->glamo->pdev->dev,
+ "IGNORING glamofb_cmd_write while "
"suspended\n");
return -EBUSY;
}
- dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n", __FUNCTION__);
+ dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n", __func__);
while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
yield();
if (timeout < 0) {
@@ -822,6 +845,7 @@ static int __init glamofb_probe(struct platform_device *pdev)
glamofb->dev = &pdev->dev;
glamofb->angle = 0;
+ glamofb->blank_mode = FB_BLANK_POWERDOWN;
strcpy(fbinfo->fix.id, "SMedia Glamo");
@@ -976,38 +1000,35 @@ static int glamofb_suspend(struct platform_device *pdev, pm_message_t state)
struct glamofb_handle *gfb = platform_get_drvdata(pdev);
/* we need to stop anything touching our framebuffer */
-// fb_blank(gfb->fb, FB_BLANK_NORMAL);
fb_set_suspend(gfb->fb, 1);
/* seriously -- nobody is allowed to touch glamo memory when we
* are suspended or we lock on nWAIT
*/
-// iounmap(gfb->fb->screen_base);
+ /* iounmap(gfb->fb->screen_base); */
return 0;
}
static int glamofb_resume(struct platform_device *pdev)
{
- struct glamofb_handle *glamofb = platform_get_drvdata(pdev);
+ struct glamofb_handle *gfb = platform_get_drvdata(pdev);
struct glamofb_platform_data *mach_info = pdev->dev.platform_data;
/* OK let's allow framebuffer ops again */
-// gfb->fb->screen_base = ioremap(gfb->fb_res->start,
-// RESSIZE(gfb->fb_res));
+ /* gfb->fb->screen_base = ioremap(gfb->fb_res->start,
+ RESSIZE(gfb->fb_res)); */
glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD);
glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD);
printk(KERN_ERR"spin_lock_init\n");
- spin_lock_init(&glamofb->lock_cmd);
- glamofb_init_regs(glamofb);
+ spin_lock_init(&gfb->lock_cmd);
+ glamofb_init_regs(gfb);
#ifdef CONFIG_MFD_GLAMO_HWACCEL
- glamofb_cursor_onoff(glamofb, 1);
+ glamofb_cursor_onoff(gfb, 1);
#endif
-
- fb_set_suspend(glamofb->fb, 0);
-// fb_blank(gfb->fb, FB_BLANK_UNBLANK);
+ fb_set_suspend(gfb->fb, 0);
return 0;
}