From 4fce011aacb14285f7644be650f85603bc9b778f Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Wed, 19 Nov 2008 17:09:45 +0000 Subject: Subject: [PATCH] Hardware glamo-fb cursor, some clean-up. --- drivers/mfd/glamo/glamo-fb.c | 105 ++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 51 deletions(-) (limited to 'drivers/mfd/glamo/glamo-fb.c') diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c index edc6d9c3086..30cdb386476 100644 --- a/drivers/mfd/glamo/glamo-fb.c +++ b/drivers/mfd/glamo/glamo-fb.c @@ -117,6 +117,8 @@ static struct glamo_script glamo_regs[] = { * 01 00 0 100 0 000 01 0 0 */ { GLAMO_REG_LCD_A_BASE1, 0x0000 }, /* display A base address 15:0 */ { GLAMO_REG_LCD_A_BASE2, 0x0000 }, /* display A base address 22:16 */ + { GLAMO_REG_LCD_CURSOR_BASE1, 0x0000 }, /* cursor base address 15:0 */ + { GLAMO_REG_LCD_CURSOR_BASE2, 0x000f }, /* cursor base address 22:16 */ }; static int glamofb_run_script(struct glamofb_handle *glamo, @@ -200,7 +202,6 @@ static int glamofb_check_var(struct fb_var_screeninfo *var, printk(KERN_ERR "Smedia driver does not [yet?] support 24/32bpp\n"); return -EINVAL; - break; } return 0; @@ -497,22 +498,19 @@ static int glamofb_setcolreg(unsigned regno, return 0; } +#ifdef CONFIG_MFD_GLAMO_HWACCEL static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct glamofb_handle *glamo = info->par; - u_int16_t reg; + unsigned long flags; if (cursor->image.depth > 2) return -EINVAL; - reg = reg_read(glamo, GLAMO_REG_LCD_MODE1); + spin_lock_irqsave(&glamo->lock_cmd, flags); - if (cursor->enable) - reg_write(glamo, GLAMO_REG_LCD_MODE1, - reg | GLAMO_LCD_MODE1_CURSOR_EN); - else - reg_write(glamo, GLAMO_REG_LCD_MODE1, - reg & ~GLAMO_LCD_MODE1_CURSOR_EN); + reg_set_bit_mask(glamo, GLAMO_REG_LCD_MODE1, + GLAMO_LCD_MODE1_CURSOR_EN, 0); if (cursor->set & FB_CUR_SETPOS) { reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_POS, @@ -522,29 +520,36 @@ static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor) } if (cursor->set & FB_CUR_SETCMAP) { - /* FIXME */ + uint16_t fg = cursor->image.fg_color; + uint16_t bg = cursor->image.bg_color; + + reg_write(glamo, GLAMO_REG_LCD_CURSOR_FG_COLOR, fg); + reg_write(glamo, GLAMO_REG_LCD_CURSOR_BG_COLOR, bg); + reg_write(glamo, GLAMO_REG_LCD_CURSOR_DST_COLOR, bg); } - if (cursor->set & FB_CUR_SETSIZE || - cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE)) { - int x, y, op; + if (cursor->set & FB_CUR_SETHOT) + reg_write(glamo, GLAMO_REG_LCD_CURSOR_PRESET, + (cursor->hot.x << 8) | cursor->hot.y); + + if ((cursor->set & FB_CUR_SETSIZE) || + (cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE))) { + int x, y, pitch; const unsigned char *pcol = cursor->image.data; const unsigned char *pmsk = cursor->mask; void __iomem *dst = glamo->cursor_addr; unsigned char dcol = 0; unsigned char dmsk = 0; + unsigned char byte = 0; + pitch = (cursor->image.width + 3) >> 2; reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_SIZE, cursor->image.width); reg_write(glamo, GLAMO_REG_LCD_CURSOR_PITCH, - cursor->image.width * 2); + pitch); reg_write(glamo, GLAMO_REG_LCD_CURSOR_Y_SIZE, cursor->image.height); - for (op = 0; op < (cursor->image.width * - cursor->image.height * 2)/8; op += 4) - writel(0x0, dst + op); - for (y = 0; y < cursor->image.height; y++) { for (x = 0; x < cursor->image.width; x++) { if ((x % 8) == 0) { @@ -559,15 +564,29 @@ static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor) unsigned int op; op = (dcol & 1) ? 1 : 3; - op <<= ((x % 4) * 2); + byte |= op << ((x % 4) * 2); + } - op |= readb(dst + (x / 4)); - writeb(op, dst + (x / 4)); + if ((x % 4) == 0) { + writeb(byte, dst + x / 4); + byte = 0; } } + + dst += pitch; } } + + if (cursor->enable) + reg_set_bit_mask(glamo, GLAMO_REG_LCD_MODE1, + GLAMO_LCD_MODE1_CURSOR_EN, + GLAMO_LCD_MODE1_CURSOR_EN); + + spin_unlock_irqrestore(&glamo->lock_cmd, flags); + + return 0; } +#endif static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb) { @@ -576,15 +595,14 @@ static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb) } /* call holding gfb->lock_cmd when locking, until you unlock */ - int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) { int timeout = 200000; -/* dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, 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__); */ + dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ", + __FUNCTION__); while ((!glamofb_cmdq_empty(gfb)) && (timeout--)) yield(); if (timeout < 0) { @@ -593,7 +611,7 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) "*************\n"); return -EIO; } -/* dev_dbg(gfb->dev, "empty!\n"); */ + dev_dbg(gfb->dev, "empty!\n"); /* display the entire frame then switch to command */ reg_write(gfb, GLAMO_REG_LCD_COMMAND1, @@ -601,7 +619,7 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) GLAMO_LCD_CMD_DATA_FIRE_VSYNC); /* wait until LCD is idle */ -/* dev_dbg(gfb->dev, "waiting for LCD idle: "); */ + dev_dbg(gfb->dev, "waiting for LCD idle: "); timeout = 200000; while ((!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12)) && (timeout--)) @@ -612,7 +630,7 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) "*************\n"); return -EIO; } -/* dev_dbg(gfb->dev, "idle!\n"); */ + dev_dbg(gfb->dev, "idle!\n"); mdelay(100); } else { @@ -635,8 +653,7 @@ 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", - __FUNCTION__); */ + dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n", __FUNCTION__); while ((!glamofb_cmdq_empty(gfb)) && (timeout--)) yield(); if (timeout < 0) { @@ -645,7 +662,7 @@ int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val) "*************\n"); return 1; } -/* dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val); */ + dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val); reg_write(gfb, GLAMO_REG_LCD_COMMAND1, val); @@ -659,7 +676,9 @@ static struct fb_ops glamofb_ops = { .fb_set_par = glamofb_set_par, .fb_blank = glamofb_blank, .fb_setcolreg = glamofb_setcolreg, - //.fb_cursor = glamofb_cursor, +#ifdef CONFIG_MFD_GLAMO_HWACCEL + .fb_cursor = glamofb_cursor, +#endif .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, @@ -743,6 +762,7 @@ static int __init glamofb_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to ioremap() vram memory\n"); goto out_release_fb; } + glamofb->cursor_addr = fbinfo->screen_base + 0xf0000; platform_set_drvdata(pdev, fbinfo); @@ -754,13 +774,13 @@ static int __init glamofb_probe(struct platform_device *pdev) fbinfo->fix.xpanstep = 0; fbinfo->fix.ypanstep = 0; fbinfo->fix.ywrapstep = 0; - fbinfo->fix.accel = FB_ACCEL_NONE; /* FIXME */ + fbinfo->fix.accel = FB_ACCEL_GLAMO; fbinfo->var.nonstd = 0; fbinfo->var.activate = FB_ACTIVATE_NOW; fbinfo->var.height = mach_info->height; fbinfo->var.width = mach_info->width; - fbinfo->var.accel_flags = 0; + fbinfo->var.accel_flags = 0; /* FIXME */ fbinfo->var.vmode = FB_VMODE_NONINTERLACED; fbinfo->fbops = &glamofb_ops; @@ -833,26 +853,9 @@ static int glamofb_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int glamofb_suspend(struct platform_device *pdev, pm_message_t state) -{ - return 0; -} - -static int glamofb_resume(struct platform_device *pdev) -{ - return 0; -} -#else -#define glamofb_suspend NULL -#define glamofb_resume NULL -#endif - static struct platform_driver glamofb_driver = { .probe = glamofb_probe, .remove = glamofb_remove, - .suspend = glamofb_suspend, - .resume = glamofb_resume, .driver = { .name = "glamo-fb", .owner = THIS_MODULE, -- cgit v1.2.3