Hey,
  I played with the Glamo framebuffer and did some changes, see
attachments and pick the changes you like.

First patch (against recent -andy) fixes some Kconfig confusion,
letting me build without GTA01 and KEXEC disabled.  At least one of
the changes in this patch is correct ;)  The Kconfig dependency pieces
for S3C24xx seem to be needlessly complicated and also broken.

The second file implements hardware cursor in the glamo-fb,
unfortunately this doesn't mean that you can go and use it.  There had
been some code for the hw cursor in the driver already but it was
missing some important parts and other parts were wrong.  I fixed this
and the cursor now looks very pretty, but now I see the Glamo blow up
after a random amount of screen activity and the screen fades to
white, while the rest of the system is unaffected.  Thus, the hw
cursor code is still left #ifdef'ed out, it's just more correct now.

There's some misc clean-up too because glamo-fb.c is cluttered with
lots of commented out and unused code.

In addition I allocate a FB type number in include/linux/fb.h for fb
identification purposes once we implement scrolling/blitting/blending
in hw (not meaning that I'm going to do this now ;)).  I see this
functionality as optional and perhaps enabled with a second Kconfig
option.  I would also like to see some form of malloc for the Glamo
memory instead of hardcoding offsets like we do now.  IIRC Dodji's
Xglamo implemented something like this.

I'll keep playing with different "engines" of the graphics chip in my
free time and see what I come up with.
From a08730c6b72486faf78d2fe098df6af9d998c1e9 Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <[EMAIL PROTECTED]>
Date: Wed, 4 Jun 2008 18:06:17 +0200
Subject: [PATCH] Build fixes.

---
 arch/arm/mach-s3c2442/Kconfig           |    3 ++-
 arch/arm/plat-s3c24xx/Kconfig           |    2 +-
 arch/arm/plat-s3c24xx/time.c            |    4 ++--
 include/asm-arm/arch-s3c2410/regs-dsc.h |    4 ++--
 include/asm-arm/kexec.h                 |    4 ++--
 include/linux/kexec.h                   |    3 ++-
 6 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig
index 6cc68a1..f9aa91c 100644
--- a/arch/arm/mach-s3c2442/Kconfig
+++ b/arch/arm/mach-s3c2442/Kconfig
@@ -6,10 +6,11 @@
 
 config CPU_S3C2442
 	bool
-	depends on ARCH_S3C2440
+	depends on CPU_S3C2440
 	select S3C2410_CLOCK
 	select S3C2410_GPIO
 	select S3C2410_PM if PM
+	select S3C2440_DMA if S3C2410_DMA
 	select CPU_S3C244X
 	select CPU_LLSERIAL_S3C2440
 	help
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 7ee4b82..9e1691f 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -16,7 +16,7 @@ if PLAT_S3C24XX
 
 config CPU_S3C244X
 	bool
-	depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
+	default y if CPU_S3C2440 || CPU_S3C2442
 	help
 	  Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
 
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
index 6989eea..39fc33d 100644
--- a/arch/arm/plat-s3c24xx/time.c
+++ b/arch/arm/plat-s3c24xx/time.c
@@ -202,12 +202,12 @@ static void s3c2410_timer_setup (void)
 
 		pclk = clk_get_rate(clk);
 
-		printk("pclk = %d\n", pclk);
+		printk("pclk = %lu\n", pclk);
 
 		/* configure clock tick */
 
 		timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
-		printk("timer_usec_ticks = %d\n", timer_usec_ticks);
+		printk("timer_usec_ticks = %lu\n", timer_usec_ticks);
 
 		tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
 		tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
diff --git a/include/asm-arm/arch-s3c2410/regs-dsc.h b/include/asm-arm/arch-s3c2410/regs-dsc.h
index c074851..f9d0c3d 100644
--- a/include/asm-arm/arch-s3c2410/regs-dsc.h
+++ b/include/asm-arm/arch-s3c2410/regs-dsc.h
@@ -19,7 +19,7 @@
 #define S3C2412_DSC1	   S3C2410_GPIOREG(0xe0)
 #endif
 
-#if defined(CONFIG_CPU_S3C2440)
+#if defined(CONFIG_CPU_S3C244X)
 
 #define S3C2440_DSC0	   S3C2410_GPIOREG(0xc4)
 #define S3C2440_DSC1	   S3C2410_GPIOREG(0xc8)
@@ -178,7 +178,7 @@
 #define S3C2440_DSC1_CS0_4mA    (3<<0)
 #define S3C2440_DSC1_CS0_MASK   (3<<0)
 
-#endif /* CONFIG_CPU_S3C2440 */
+#endif /* CONFIG_CPU_S3C244X */
 
 #endif	/* __ASM_ARCH_REGS_DSC_H */
 
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
index 1ee17b6..0fb508b 100644
--- a/include/asm-arm/kexec.h
+++ b/include/asm-arm/kexec.h
@@ -1,8 +1,6 @@
 #ifndef _ARM_KEXEC_H
 #define _ARM_KEXEC_H
 
-#ifdef CONFIG_KEXEC
-
 /* Maximum physical address we can use pages from */
 #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
 /* Maximum address we can reach in physical address mode */
@@ -16,6 +14,8 @@
 
 #define KEXEC_BOOT_PARAMS_SIZE 1536
 
+#ifdef CONFIG_KEXEC
+
 #define KEXEC_ARM_ATAGS_OFFSET  0x1000
 #define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
 
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 2d9c448..9f1a644 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -1,7 +1,6 @@
 #ifndef LINUX_KEXEC_H
 #define LINUX_KEXEC_H
 
-#ifdef CONFIG_KEXEC
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/linkage.h>
@@ -11,6 +10,8 @@
 #include <linux/elf.h>
 #include <asm/kexec.h>
 
+#ifdef CONFIG_KEXEC
+
 /* Verify architecture specific macros are defined */
 
 #ifndef KEXEC_SOURCE_MEMORY_LIMIT
-- 
1.5.3.4

From b3057a63ab3e84b93a3704be7239e56d094fcf06 Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <[EMAIL PROTECTED]>
Date: Wed, 4 Jun 2008 18:08:18 +0200
Subject: [PATCH] Hardware glamo-fb cursor, some clean-up.

---
 drivers/mfd/glamo/glamo-fb.c |  103 ++++++++++++++++++++---------------------
 include/linux/fb.h           |    1 +
 2 files changed, 51 insertions(+), 53 deletions(-)

diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
index 44b1947..d5060c8 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;
@@ -495,23 +496,18 @@ static int glamofb_setcolreg(unsigned regno,
 	return 0;
 }
 
-#ifdef NOT_CURRENTLY_USED
 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,
@@ -521,29 +517,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) {
@@ -558,16 +561,28 @@ 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 +591,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 +607,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 +615,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 +626,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 +649,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 +658,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 +672,7 @@ static struct fb_ops glamofb_ops = {
 	.fb_set_par	= glamofb_set_par,
 	.fb_blank	= glamofb_blank,
 	.fb_setcolreg	= glamofb_setcolreg,
-	//.fb_cursor	= glamofb_cursor,
+	.fb_cursor	= glamofb_cursor,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
@@ -743,6 +756,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 +768,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;
@@ -832,26 +846,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 58c57a3..c114328 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.3.4

Reply via email to