1 From 824fc22a0aaacf942eb3b3dfa6aad32c7285669f Mon Sep 17 00:00:00 2001
2 From: Andrzej Zaborowski <balrog@zabor.org>
3 Date: Fri, 25 Jul 2008 23:06:11 +0100
4 Subject: [PATCH] Subject: [PATCH] Hardware glamo-fb cursor, some clean-up.
7 drivers/mfd/glamo/glamo-fb.c | 105 +++++++++++++++++++++--------------------
8 include/linux/fb.h | 1 +
9 2 files changed, 55 insertions(+), 51 deletions(-)
11 diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
12 index edc6d9c..30cdb38 100644
13 --- a/drivers/mfd/glamo/glamo-fb.c
14 +++ b/drivers/mfd/glamo/glamo-fb.c
15 @@ -117,6 +117,8 @@ static struct glamo_script glamo_regs[] = {
16 * 01 00 0 100 0 000 01 0 0 */
17 { GLAMO_REG_LCD_A_BASE1, 0x0000 }, /* display A base address 15:0 */
18 { GLAMO_REG_LCD_A_BASE2, 0x0000 }, /* display A base address 22:16 */
19 + { GLAMO_REG_LCD_CURSOR_BASE1, 0x0000 }, /* cursor base address 15:0 */
20 + { GLAMO_REG_LCD_CURSOR_BASE2, 0x000f }, /* cursor base address 22:16 */
23 static int glamofb_run_script(struct glamofb_handle *glamo,
24 @@ -200,7 +202,6 @@ static int glamofb_check_var(struct fb_var_screeninfo *var,
26 "Smedia driver does not [yet?] support 24/32bpp\n");
32 @@ -497,22 +498,19 @@ static int glamofb_setcolreg(unsigned regno,
36 +#ifdef CONFIG_MFD_GLAMO_HWACCEL
37 static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
39 struct glamofb_handle *glamo = info->par;
41 + unsigned long flags;
43 if (cursor->image.depth > 2)
46 - reg = reg_read(glamo, GLAMO_REG_LCD_MODE1);
47 + spin_lock_irqsave(&glamo->lock_cmd, flags);
50 - reg_write(glamo, GLAMO_REG_LCD_MODE1,
51 - reg | GLAMO_LCD_MODE1_CURSOR_EN);
53 - reg_write(glamo, GLAMO_REG_LCD_MODE1,
54 - reg & ~GLAMO_LCD_MODE1_CURSOR_EN);
55 + reg_set_bit_mask(glamo, GLAMO_REG_LCD_MODE1,
56 + GLAMO_LCD_MODE1_CURSOR_EN, 0);
58 if (cursor->set & FB_CUR_SETPOS) {
59 reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_POS,
60 @@ -522,29 +520,36 @@ static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
63 if (cursor->set & FB_CUR_SETCMAP) {
65 + uint16_t fg = cursor->image.fg_color;
66 + uint16_t bg = cursor->image.bg_color;
68 + reg_write(glamo, GLAMO_REG_LCD_CURSOR_FG_COLOR, fg);
69 + reg_write(glamo, GLAMO_REG_LCD_CURSOR_BG_COLOR, bg);
70 + reg_write(glamo, GLAMO_REG_LCD_CURSOR_DST_COLOR, bg);
73 - if (cursor->set & FB_CUR_SETSIZE ||
74 - cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE)) {
76 + if (cursor->set & FB_CUR_SETHOT)
77 + reg_write(glamo, GLAMO_REG_LCD_CURSOR_PRESET,
78 + (cursor->hot.x << 8) | cursor->hot.y);
80 + if ((cursor->set & FB_CUR_SETSIZE) ||
81 + (cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE))) {
83 const unsigned char *pcol = cursor->image.data;
84 const unsigned char *pmsk = cursor->mask;
85 void __iomem *dst = glamo->cursor_addr;
86 unsigned char dcol = 0;
87 unsigned char dmsk = 0;
88 + unsigned char byte = 0;
90 + pitch = (cursor->image.width + 3) >> 2;
91 reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_SIZE,
93 reg_write(glamo, GLAMO_REG_LCD_CURSOR_PITCH,
94 - cursor->image.width * 2);
96 reg_write(glamo, GLAMO_REG_LCD_CURSOR_Y_SIZE,
97 cursor->image.height);
99 - for (op = 0; op < (cursor->image.width *
100 - cursor->image.height * 2)/8; op += 4)
101 - writel(0x0, dst + op);
103 for (y = 0; y < cursor->image.height; y++) {
104 for (x = 0; x < cursor->image.width; x++) {
106 @@ -559,15 +564,29 @@ static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
109 op = (dcol & 1) ? 1 : 3;
110 - op <<= ((x % 4) * 2);
111 + byte |= op << ((x % 4) * 2);
114 - op |= readb(dst + (x / 4));
115 - writeb(op, dst + (x / 4));
116 + if ((x % 4) == 0) {
117 + writeb(byte, dst + x / 4);
126 + if (cursor->enable)
127 + reg_set_bit_mask(glamo, GLAMO_REG_LCD_MODE1,
128 + GLAMO_LCD_MODE1_CURSOR_EN,
129 + GLAMO_LCD_MODE1_CURSOR_EN);
131 + spin_unlock_irqrestore(&glamo->lock_cmd, flags);
137 static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb)
139 @@ -576,15 +595,14 @@ static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb)
142 /* call holding gfb->lock_cmd when locking, until you unlock */
144 int glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
146 int timeout = 200000;
148 -/* dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on); */
149 + dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on);
151 -/* dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
153 + dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
155 while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
158 @@ -593,7 +611,7 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
162 -/* dev_dbg(gfb->dev, "empty!\n"); */
163 + dev_dbg(gfb->dev, "empty!\n");
165 /* display the entire frame then switch to command */
166 reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
167 @@ -601,7 +619,7 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
168 GLAMO_LCD_CMD_DATA_FIRE_VSYNC);
170 /* wait until LCD is idle */
171 -/* dev_dbg(gfb->dev, "waiting for LCD idle: "); */
172 + dev_dbg(gfb->dev, "waiting for LCD idle: ");
174 while ((!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12)) &&
176 @@ -612,7 +630,7 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
180 -/* dev_dbg(gfb->dev, "idle!\n"); */
181 + dev_dbg(gfb->dev, "idle!\n");
185 @@ -635,8 +653,7 @@ int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val)
187 int timeout = 200000;
189 -/* dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n",
191 + dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n", __FUNCTION__);
192 while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
195 @@ -645,7 +662,7 @@ int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val)
199 -/* dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val); */
200 + dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val);
202 reg_write(gfb, GLAMO_REG_LCD_COMMAND1, val);
204 @@ -659,7 +676,9 @@ static struct fb_ops glamofb_ops = {
205 .fb_set_par = glamofb_set_par,
206 .fb_blank = glamofb_blank,
207 .fb_setcolreg = glamofb_setcolreg,
208 - //.fb_cursor = glamofb_cursor,
209 +#ifdef CONFIG_MFD_GLAMO_HWACCEL
210 + .fb_cursor = glamofb_cursor,
212 .fb_fillrect = cfb_fillrect,
213 .fb_copyarea = cfb_copyarea,
214 .fb_imageblit = cfb_imageblit,
215 @@ -743,6 +762,7 @@ static int __init glamofb_probe(struct platform_device *pdev)
216 dev_err(&pdev->dev, "failed to ioremap() vram memory\n");
219 + glamofb->cursor_addr = fbinfo->screen_base + 0xf0000;
221 platform_set_drvdata(pdev, fbinfo);
223 @@ -754,13 +774,13 @@ static int __init glamofb_probe(struct platform_device *pdev)
224 fbinfo->fix.xpanstep = 0;
225 fbinfo->fix.ypanstep = 0;
226 fbinfo->fix.ywrapstep = 0;
227 - fbinfo->fix.accel = FB_ACCEL_NONE; /* FIXME */
228 + fbinfo->fix.accel = FB_ACCEL_GLAMO;
230 fbinfo->var.nonstd = 0;
231 fbinfo->var.activate = FB_ACTIVATE_NOW;
232 fbinfo->var.height = mach_info->height;
233 fbinfo->var.width = mach_info->width;
234 - fbinfo->var.accel_flags = 0;
235 + fbinfo->var.accel_flags = 0; /* FIXME */
236 fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
238 fbinfo->fbops = &glamofb_ops;
239 @@ -833,26 +853,9 @@ static int glamofb_remove(struct platform_device *pdev)
244 -static int glamofb_suspend(struct platform_device *pdev, pm_message_t state)
249 -static int glamofb_resume(struct platform_device *pdev)
254 -#define glamofb_suspend NULL
255 -#define glamofb_resume NULL
258 static struct platform_driver glamofb_driver = {
259 .probe = glamofb_probe,
260 .remove = glamofb_remove,
261 - .suspend = glamofb_suspend,
262 - .resume = glamofb_resume,
265 .owner = THIS_MODULE,
266 diff --git a/include/linux/fb.h b/include/linux/fb.h
267 index 72295b0..1df1225 100644
268 --- a/include/linux/fb.h
269 +++ b/include/linux/fb.h
270 @@ -120,6 +120,7 @@ struct dentry;
271 #define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */
272 #define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
273 #define FB_ACCEL_OMAP1610 49 /* TI OMAP16xx */
274 +#define FB_ACCEL_GLAMO 50 /* SMedia Glamo */
275 #define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */
276 #define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */
277 #define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */