281 lines
8.6 KiB
Diff
Executable File
281 lines
8.6 KiB
Diff
Executable File
From 824fc22a0aaacf942eb3b3dfa6aad32c7285669f Mon Sep 17 00:00:00 2001
|
|
From: Andrzej Zaborowski <balrog@zabor.org>
|
|
Date: Fri, 25 Jul 2008 23:06:11 +0100
|
|
Subject: [PATCH] Subject: [PATCH] Hardware glamo-fb cursor, some clean-up.
|
|
|
|
---
|
|
drivers/mfd/glamo/glamo-fb.c | 105 +++++++++++++++++++++--------------------
|
|
include/linux/fb.h | 1 +
|
|
2 files changed, 55 insertions(+), 51 deletions(-)
|
|
|
|
diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
|
|
index edc6d9c..30cdb38 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,
|
|
diff --git a/include/linux/fb.h b/include/linux/fb.h
|
|
index 72295b0..1df1225 100644
|
|
--- a/include/linux/fb.h
|
|
+++ b/include/linux/fb.h
|
|
@@ -120,6 +120,7 @@ struct dentry;
|
|
#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */
|
|
#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
|
|
#define FB_ACCEL_OMAP1610 49 /* TI OMAP16xx */
|
|
+#define FB_ACCEL_GLAMO 50 /* SMedia Glamo */
|
|
#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */
|
|
#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */
|
|
#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */
|
|
--
|
|
1.5.6.3
|
|
|