diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2010-06-23 18:25:50 +0200 |
---|---|---|
committer | Lars-Peter Clausen <lars@metafoo.de> | 2010-06-23 18:25:50 +0200 |
commit | 4ce5f33cd4bcde2e25d50ae0880eb39213e2b6d2 (patch) | |
tree | 521d081151c260f2ecccfa334a184547caf7fbb2 | |
parent | b8fd949e585e9b991b36f9edc40ebec1a7dd885b (diff) | |
parent | c42fae0d24de8e7590a0b36e66eb6bc3b3e773c7 (diff) |
Merge branch 'glamo-2.6.34' into om-gta02-2.6.34
-rw-r--r-- | drivers/video/glamo-fb.c | 242 | ||||
-rw-r--r-- | include/linux/glamofb.h | 16 |
2 files changed, 101 insertions, 157 deletions
diff --git a/drivers/video/glamo-fb.c b/drivers/video/glamo-fb.c index c74ea733a8c..517cc5c711e 100644 --- a/drivers/video/glamo-fb.c +++ b/drivers/video/glamo-fb.c @@ -43,25 +43,29 @@ #include <linux/glamofb.h> -static void glamofb_program_mode(struct glamofb_handle *glamo); - struct glamofb_handle { struct glamo_core *core; struct fb_info *fb; struct device *dev; + struct resource *reg; struct resource *fb_res; - char __iomem *base; + void __iomem *base; + void __iomem *cursor_addr; + struct glamo_fb_platform_data *mach_info; - char __iomem *cursor_addr; + int cursor_on; - u_int32_t pseudo_pal[16]; - spinlock_t lock_cmd; int blank_mode; int mode_set; /* 0 if the current display mode hasn't been set on the glamo */ int output_enabled; /* 0 if the video output is disabled */ + + spinlock_t lock_cmd; + uint32_t pseudo_pal[16]; }; +static void glamofb_program_mode(struct glamofb_handle *glamo); + static void glamo_output_enable(struct glamofb_handle *gfb) { struct glamo_core *gcore = gfb->core; @@ -91,29 +95,18 @@ static void glamo_output_disable(struct glamofb_handle *gfb) } -static int reg_read(struct glamofb_handle *glamo, - u_int16_t reg) +static inline int reg_read(struct glamofb_handle *glamo, uint16_t reg) { - int i = 0; - - for (i = 0; i != 2; i++) - nop(); - return readw(glamo->base + reg); } -static void reg_write(struct glamofb_handle *glamo, - uint16_t reg, uint16_t val) +static inline void reg_write(struct glamofb_handle *glamo, uint16_t reg, + uint16_t val) { - int i = 0; - - for (i = 0; i != 2; i++) - nop(); - writew(val, glamo->base + reg); } -static struct glamo_script glamo_regs[] = { +static const struct glamo_script glamo_regs[] = { { GLAMO_REG_LCD_MODE1, 0x0020 }, /* no display rotation, no hardware cursor, no dither, no gamma, * no retrace flip, vsync low-active, hsync low active, @@ -141,12 +134,12 @@ static struct glamo_script glamo_regs[] = { }; static int glamofb_run_script(struct glamofb_handle *glamo, - struct glamo_script *script, int len) + const struct glamo_script *script, size_t len) { - int i; + size_t i; for (i = 0; i < len; i++) { - struct glamo_script *line = &script[i]; + const struct glamo_script *line = &script[i]; if (line->reg == 0xffff) return 0; @@ -160,7 +153,7 @@ static int glamofb_run_script(struct glamofb_handle *glamo, } static int glamofb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) + struct fb_info *info) { struct glamofb_handle *glamo = info->par; @@ -209,19 +202,16 @@ static int glamofb_check_var(struct fb_var_screeninfo *var, case 32: default: /* The Smedia Glamo doesn't support anything but 16bit color */ - printk(KERN_ERR - "Smedia driver does not [yet?] support 24/32bpp\n"); return -EINVAL; } return 0; } -static void reg_set_bit_mask(struct glamofb_handle *glamo, - uint16_t reg, uint16_t mask, - uint16_t val) +static void reg_set_bit_mask(struct glamofb_handle *glamo, uint16_t reg, + uint16_t mask, uint16_t val) { - u_int16_t tmp; + uint16_t tmp; val &= mask; @@ -241,9 +231,9 @@ static void reg_set_bit_mask(struct glamofb_handle *glamo, #define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF /* the caller has to ensure lock_cmd is held and we are in cmd mode */ -static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) +static void __rotate_lcd(struct glamofb_handle *glamo, uint32_t rotation) { - int glamo_rot; + uint32_t glamo_rot; switch (rotation) { case FB_ROTATE_CW: @@ -271,9 +261,69 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) GLAMO_LCD_MODE1_ROTATE_EN : 0); } +static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb) +{ + /* DGCMdQempty -- 1 == command queue is empty */ + return reg_read(gfb, GLAMO_REG_LCD_STATUS1) & (1 << 15); +} + +/* call holding gfb->lock_cmd when locking, until you unlock */ +static int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) +{ + int timeout = 2000000; + + 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: ", + __func__); + while (!glamofb_cmdq_empty(gfb) && (timeout--)) + cpu_relax(); + if (timeout < 0) { + printk(KERN_ERR "glamofb cmd_queue never got empty\n"); + return -EIO; + } + dev_dbg(gfb->dev, "empty!\n"); + + /* display the entire frame then switch to command */ + reg_write(gfb, GLAMO_REG_LCD_COMMAND1, + GLAMO_LCD_CMD_TYPE_DISP | + GLAMO_LCD_CMD_DATA_FIRE_VSYNC); + + /* wait until lcd idle */ + dev_dbg(gfb->dev, "waiting for lcd idle: "); + timeout = 2000000; + while (!(reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12)) && + (timeout--)) + cpu_relax(); + if (timeout < 0) { + printk(KERN_ERR"*************" + "glamofb lcd never idle" + "*************\n"); + return -EIO; + } + + mdelay(100); + + dev_dbg(gfb->dev, "cmd mode entered\n"); + + } else { + /* RGB interface needs vsync/hsync */ + if (reg_read(gfb, GLAMO_REG_LCD_MODE3) & GLAMO_LCD_MODE3_RGB) + reg_write(gfb, GLAMO_REG_LCD_COMMAND1, + GLAMO_LCD_CMD_TYPE_DISP | + GLAMO_LCD_CMD_DATA_DISP_SYNC); + + reg_write(gfb, GLAMO_REG_LCD_COMMAND1, + GLAMO_LCD_CMD_TYPE_DISP | + GLAMO_LCD_CMD_DATA_DISP_FIRE); + } + + return 0; +} + static void glamofb_program_mode(struct glamofb_handle *gfb) { - int sync, bp, disp, fp, total; + unsigned int sync, bp, disp, fp, total; unsigned long flags; struct glamo_core *gcore = gfb->core; struct fb_var_screeninfo *var = &gfb->fb->var; @@ -350,15 +400,8 @@ out_unlock: spin_unlock_irqrestore(&gfb->lock_cmd, flags); } - -static int glamofb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - return 0; -} - static struct fb_videomode *glamofb_find_mode(struct fb_info *info, - struct fb_var_screeninfo *var) + struct fb_var_screeninfo *var) { struct glamofb_handle *glamo = info->par; struct glamo_fb_platform_data *pdata = glamo->mach_info; @@ -439,16 +482,15 @@ static int glamofb_blank(int blank_mode, struct fb_info *info) } static inline unsigned int chan_to_field(unsigned int chan, - struct fb_bitfield *bf) + struct fb_bitfield *bf) { chan &= 0xffff; chan >>= 16 - bf->length; return chan << bf->offset; } -static int glamofb_setcolreg(unsigned regno, - unsigned red, unsigned green, unsigned blue, - unsigned transp, struct fb_info *info) +static int glamofb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info) { struct glamofb_handle *glamo = info->par; unsigned int val; @@ -476,7 +518,7 @@ static int glamofb_setcolreg(unsigned regno, } static int glamofb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) + unsigned long arg) { struct glamofb_handle *gfb = (struct glamofb_handle *)info->par; struct glamo_core *gcore = gfb->core; @@ -502,8 +544,8 @@ static int glamofb_ioctl(struct fb_info *info, unsigned int cmd, #ifdef CONFIG_MFD_GLAMO_HWACCEL -static inline void glamofb_vsync_wait(struct glamofb_handle *glamo, - int line, int size, int range) +static inline void glamofb_vsync_wait(struct glamofb_handle *glamo, int line, + int size, int range) { int count[2]; @@ -630,93 +672,9 @@ static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor) } #endif -static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb) -{ - /* DGCMdQempty -- 1 == command queue is empty */ - return reg_read(gfb, GLAMO_REG_LCD_STATUS1) & (1 << 15); -} - -/* call holding gfb->lock_cmd when locking, until you unlock */ -int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) -{ - int timeout = 2000000; - - 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: ", - __func__); - while (!glamofb_cmdq_empty(gfb) && (timeout--)) - cpu_relax(); - if (timeout < 0) { - printk(KERN_ERR "glamofb cmd_queue never got empty\n"); - return -EIO; - } - dev_dbg(gfb->dev, "empty!\n"); - - /* display the entire frame then switch to command */ - reg_write(gfb, GLAMO_REG_LCD_COMMAND1, - GLAMO_LCD_CMD_TYPE_DISP | - GLAMO_LCD_CMD_DATA_FIRE_VSYNC); - - /* wait until lcd idle */ - dev_dbg(gfb->dev, "waiting for lcd idle: "); - timeout = 2000000; - while (!(reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12)) && - (timeout--)) - cpu_relax(); - if (timeout < 0) { - printk(KERN_ERR"*************" - "glamofb lcd never idle" - "*************\n"); - return -EIO; - } - - mdelay(100); - - dev_dbg(gfb->dev, "cmd mode entered\n"); - - } else { - /* RGB interface needs vsync/hsync */ - if (reg_read(gfb, GLAMO_REG_LCD_MODE3) & GLAMO_LCD_MODE3_RGB) - reg_write(gfb, GLAMO_REG_LCD_COMMAND1, - GLAMO_LCD_CMD_TYPE_DISP | - GLAMO_LCD_CMD_DATA_DISP_SYNC); - - reg_write(gfb, GLAMO_REG_LCD_COMMAND1, - GLAMO_LCD_CMD_TYPE_DISP | - GLAMO_LCD_CMD_DATA_DISP_FIRE); - } - - return 0; -} -EXPORT_SYMBOL_GPL(glamofb_cmd_mode); - - -int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val) -{ - int timeout = 200000; - - dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n", __func__); - while ((!glamofb_cmdq_empty(gfb)) && (timeout--)) - yield(); - if (timeout < 0) { - printk(KERN_ERR"*************" - "glamofb cmd_queue never got empty" - "*************\n"); - return 1; - } - dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val); - - reg_write(gfb, GLAMO_REG_LCD_COMMAND1, val); - - return 0; -} -EXPORT_SYMBOL_GPL(glamofb_cmd_write); - static struct fb_ops glamofb_ops = { .owner = THIS_MODULE, .fb_check_var = glamofb_check_var, - .fb_pan_display = glamofb_pan_display, .fb_set_par = glamofb_set_par, .fb_blank = glamofb_blank, .fb_setcolreg = glamofb_setcolreg, @@ -740,7 +698,7 @@ static int glamofb_init_regs(struct glamofb_handle *glamo) return 0; } -static int __init glamofb_probe(struct platform_device *pdev) +static int __devinit glamofb_probe(struct platform_device *pdev) { int rc = -EIO; struct fb_info *fbinfo; @@ -809,8 +767,8 @@ static int __init glamofb_probe(struct platform_device *pdev) goto out_release_fb; } - fbinfo->fix.smem_start = (unsigned long) glamofb->fb_res->start; - fbinfo->fix.smem_len = (__u32) resource_size(glamofb->fb_res); + fbinfo->fix.smem_start = (unsigned long)glamofb->fb_res->start; + fbinfo->fix.smem_len = (__u32)resource_size(glamofb->fb_res); fbinfo->screen_base = ioremap(glamofb->fb_res->start, resource_size(glamofb->fb_res)); @@ -889,17 +847,18 @@ out_free: return rc; } -static int glamofb_remove(struct platform_device *pdev) +static int __devexit glamofb_remove(struct platform_device *pdev) { struct glamofb_handle *glamofb = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, NULL); iounmap(glamofb->fb->screen_base); iounmap(glamofb->base); + release_mem_region(glamofb->fb_res->start, resource_size(glamofb->fb_res)); release_mem_region(glamofb->reg->start, resource_size(glamofb->reg)); + platform_set_drvdata(pdev, NULL); framebuffer_release(glamofb->fb); return 0; @@ -958,7 +917,7 @@ static const struct dev_pm_ops glamofb_pm_ops = { static struct platform_driver glamofb_driver = { .probe = glamofb_probe, - .remove = glamofb_remove, + .remove = __devexit_p(glamofb_remove), .driver = { .name = "glamo-fb", .owner = THIS_MODULE, @@ -966,17 +925,16 @@ static struct platform_driver glamofb_driver = { }, }; -static int __devinit glamofb_init(void) +static int __init glamofb_init(void) { return platform_driver_register(&glamofb_driver); } +module_init(glamofb_init); static void __exit glamofb_cleanup(void) { platform_driver_unregister(&glamofb_driver); } - -module_init(glamofb_init); module_exit(glamofb_cleanup); MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h index 5f9fab5a487..896579be1a0 100644 --- a/include/linux/glamofb.h +++ b/include/linux/glamofb.h @@ -1,31 +1,17 @@ #ifndef _LINUX_GLAMOFB_H #define _LINUX_GLAMOFB_H -#include <linux/fb.h> - #ifdef __KERNEL__ -struct glamo_core; -struct glamofb_handle; +#include <linux/fb.h> struct glamo_fb_platform_data { int width, height; int num_modes; struct fb_videomode *modes; - - struct glamo_core *core; }; -int glamofb_cmd_mode(struct glamofb_handle *gfb, int on); -int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val); - -#ifdef CONFIG_MFD_GLAMO -void glamo_lcm_reset(struct platform_device *pdev, int level); -#else -#define glamo_lcm_reset(...) do {} while (0) -#endif - #endif #define GLAMOFB_ENGINE_ENABLE _IOW('F', 0x1, __u32) |