[U-Boot] [PATCH 01/10] video: Add S3C24xx framebuffer support

Add basic framebuffer driver for the S3C24xx family of CPUs.
Signed-off-by: Marek Vasut marex@denx.de Cc: Anatolij Gustschin agust@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com
V2: Keep the Makefile sorted. --- drivers/video/Makefile | 1 + drivers/video/cfb_console.c | 2 +- drivers/video/s3c-fb.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 drivers/video/s3c-fb.c
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 14a6781..0e407d0 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_VIDEO_MX3) += mx3fb.o videomodes.o obj-$(CONFIG_VIDEO_IPUV3) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o obj-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o +obj-$(CONFIG_VIDEO_S3C) += s3c-fb.o videomodes.o obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o obj-$(CONFIG_VIDEO_SED13806) += sed13806.o obj-$(CONFIG_VIDEO_SM501) += sm501.o diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 9231927..98d10e3 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -135,7 +135,7 @@ #endif #endif
-#ifdef CONFIG_VIDEO_MXS +#if defined(CONFIG_VIDEO_MXS) || defined(CONFIG_VIDEO_S3C) #define VIDEO_FB_16BPP_WORD_SWAP #endif
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c new file mode 100644 index 0000000..521eb75 --- /dev/null +++ b/drivers/video/s3c-fb.c @@ -0,0 +1,172 @@ +/* + * S3C24x0 LCD driver + * + * NOTE: Only 16/24 bpp operation with TFT LCD is supported. + * + * Copyright (C) 2014 Marek Vasut marex@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <malloc.h> +#include <video_fb.h> + +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/s3c24x0_cpu.h> + +#include "videomodes.h" + +static GraphicDevice panel; + +/* S3C requires the FB to be 4MiB aligned. */ +#define S3CFB_ALIGN (4 << 20) + +#define S3CFB_LCDCON1_CLKVAL(x) ((x) << 8) +#define S3CFB_LCDCON1_PNRMODE_TFT (0x3 << 5) +#define S3CFB_LCDCON1_BPPMODE_TFT_16BPP (0xc << 1) +#define S3CFB_LCDCON1_BPPMODE_TFT_24BPP (0xd << 1) + +#define S3CFB_LCDCON2_VBPD(x) ((x) << 24) +#define S3CFB_LCDCON2_LINEVAL(x) ((x) << 14) +#define S3CFB_LCDCON2_VFPD(x) ((x) << 6) +#define S3CFB_LCDCON2_VSPW(x) ((x) << 0) + +#define S3CFB_LCDCON3_HBPD(x) ((x) << 19) +#define S3CFB_LCDCON3_HOZVAL(x) ((x) << 8) +#define S3CFB_LCDCON3_HFPD(x) ((x) << 0) + +#define S3CFB_LCDCON4_HSPW(x) ((x) << 0) + +#define S3CFB_LCDCON5_BPP24BL (1 << 12) +#define S3CFB_LCDCON5_FRM565 (1 << 11) +#define S3CFB_LCDCON5_HWSWP (1 << 0) + +#define PS2KHZ(ps) (1000000000UL / (ps)) + +/* + * Example: + * setenv videomode video=ctfb:x:800,y:480,depth:16,mode:0,\ + * pclk:30066,le:41,ri:89,up:45,lo:12, + * hs:1,vs:1,sync:100663296,vmode:0 + */ +static void s3c_lcd_init(GraphicDevice *panel, + struct ctfb_res_modes *mode, int bpp) +{ + uint32_t clk_divider; + struct s3c24x0_lcd *regs = s3c24x0_get_base_lcd(); + + /* Stop the controller. */ + clrbits_le32(®s->lcdcon1, 1); + + /* Calculate clock divider. */ + clk_divider = (get_HCLK() / PS2KHZ(mode->pixclock)) / 1000; + clk_divider = DIV_ROUND_UP(clk_divider, 2); + if (clk_divider) + clk_divider -= 1; + + /* Program LCD configuration. */ + switch (bpp) { + case 16: + writel(S3CFB_LCDCON1_BPPMODE_TFT_16BPP | + S3CFB_LCDCON1_PNRMODE_TFT | + S3CFB_LCDCON1_CLKVAL(clk_divider), + ®s->lcdcon1); + writel(S3CFB_LCDCON5_HWSWP | S3CFB_LCDCON5_FRM565, + ®s->lcdcon5); + break; + case 24: + writel(S3CFB_LCDCON1_BPPMODE_TFT_24BPP | + S3CFB_LCDCON1_PNRMODE_TFT | + S3CFB_LCDCON1_CLKVAL(clk_divider), + ®s->lcdcon1); + writel(S3CFB_LCDCON5_BPP24BL, ®s->lcdcon5); + break; + } + + writel(S3CFB_LCDCON2_LINEVAL(mode->yres - 1) | + S3CFB_LCDCON2_VBPD(mode->upper_margin - 1) | + S3CFB_LCDCON2_VFPD(mode->lower_margin - 1) | + S3CFB_LCDCON2_VSPW(mode->vsync_len - 1), + ®s->lcdcon2); + + writel(S3CFB_LCDCON3_HBPD(mode->right_margin - 1) | + S3CFB_LCDCON3_HFPD(mode->left_margin - 1) | + S3CFB_LCDCON3_HOZVAL(mode->xres - 1), + ®s->lcdcon3); + + writel(S3CFB_LCDCON4_HSPW(mode->hsync_len - 1), + ®s->lcdcon4); + + /* Write FB address. */ + writel(panel->frameAdrs >> 1, ®s->lcdsaddr1); + writel((panel->frameAdrs + + (mode->xres * mode->yres * panel->gdfBytesPP)) >> 1, + ®s->lcdsaddr2); + writel(mode->xres * bpp / 16, ®s->lcdsaddr3); + + /* Start the controller. */ + setbits_le32(®s->lcdcon1, 1); +} + +void *video_hw_init(void) +{ + int bpp = -1; + char *penv; + void *fb; + struct ctfb_res_modes mode; + + puts("Video: "); + + /* Suck display configuration from "videomode" variable */ + penv = getenv("videomode"); + if (!penv) { + puts("S3CFB: 'videomode' variable not set!\n"); + return NULL; + } + + bpp = video_get_params(&mode, penv); + + /* fill in Graphic device struct */ + sprintf(panel.modeIdent, "%dx%dx%d", mode.xres, mode.yres, bpp); + + panel.winSizeX = mode.xres; + panel.winSizeY = mode.yres; + panel.plnSizeX = mode.xres; + panel.plnSizeY = mode.yres; + + switch (bpp) { + case 24: + panel.gdfBytesPP = 4; + panel.gdfIndex = GDF_32BIT_X888RGB; + break; + case 16: + panel.gdfBytesPP = 2; + panel.gdfIndex = GDF_16BIT_565RGB; + break; + default: + printf("S3CFB: Invalid BPP specified! (bpp = %i)\n", bpp); + return NULL; + } + + panel.memSize = mode.xres * mode.yres * panel.gdfBytesPP; + + /* Allocate framebuffer */ + fb = memalign(S3CFB_ALIGN, roundup(panel.memSize, S3CFB_ALIGN)); + if (!fb) { + printf("S3CFB: Error allocating framebuffer!\n"); + return NULL; + } + + /* Wipe framebuffer */ + memset(fb, 0, panel.memSize); + + panel.frameAdrs = (u32)fb; + + printf("%s\n", panel.modeIdent); + + /* Start framebuffer */ + s3c_lcd_init(&panel, &mode, bpp); + + return (void *)&panel; +}

The correct name of this symbol is CONFIG_S3C2410_NAND_HWECC , the _SYS is redundant.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Scott Wood scottwood@freescale.com Cc: Vladimir Zapolskiy vz@mleia.com --- include/configs/VCMA9.h | 2 +- include/configs/smdk2410.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index d40185e..a2ce7c5 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -201,7 +201,7 @@ /* NAND configuration */ #ifdef CONFIG_CMD_NAND #define CONFIG_NAND_S3C2410 -#define CONFIG_SYS_S3C2410_NAND_HWECC +#define CONFIG_S3C2410_NAND_HWECC #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE 0x4E000000 #define CONFIG_S3C24XX_CUSTOM_NAND_TIMING diff --git a/include/configs/smdk2410.h b/include/configs/smdk2410.h index d4ae19f..0d0da28 100644 --- a/include/configs/smdk2410.h +++ b/include/configs/smdk2410.h @@ -172,7 +172,7 @@ */ #ifdef CONFIG_CMD_NAND #define CONFIG_NAND_S3C2410 -#define CONFIG_SYS_S3C2410_NAND_HWECC +#define CONFIG_S3C2410_NAND_HWECC #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE 0x4E000000 #endif

On Sat, Oct 11, 2014 at 06:42:50PM +0200, Marek Vasut wrote:
The correct name of this symbol is CONFIG_S3C2410_NAND_HWECC , the _SYS is redundant.
What makes that the correct name? The symbol is not documented anywhere, and while nothing currently tests for the SYS version, nothing currently sets the non-SYS version.
What is SYS redundant with?
Is this meant to be a user config knob or something that is fixed for a given board?
-Scott

On Thursday, November 27, 2014 at 03:03:50 AM, Scott Wood wrote:
On Sat, Oct 11, 2014 at 06:42:50PM +0200, Marek Vasut wrote:
The correct name of this symbol is CONFIG_S3C2410_NAND_HWECC , the _SYS is redundant.
What makes that the correct name? The symbol is not documented anywhere, and while nothing currently tests for the SYS version, nothing currently sets the non-SYS version.
What is SYS redundant with?
Is this meant to be a user config knob or something that is fixed for a given board?
u-boot$ git grep CONFIG_SYS_S3C2410_NAND_HWECC include/configs/VCMA9.h:#define CONFIG_SYS_S3C2410_NAND_HWECC include/configs/smdk2410.h:#define CONFIG_SYS_S3C2410_NAND_HWECC
u-boot$ git grep CONFIG_S3C2410_NAND_HWECC drivers/mtd/nand/s3c2410_nand.c:#ifdef CONFIG_S3C2410_NAND_HWECC drivers/mtd/nand/s3c2410_nand.c:#ifdef CONFIG_S3C2410_NAND_HWECC
The driver checks the version without _SYS. This is a clear bugfix, so please apply.
Best regards, Marek Vasut

On Sat, 2015-05-02 at 02:46 +0200, Marek Vasut wrote:
On Thursday, November 27, 2014 at 03:03:50 AM, Scott Wood wrote:
On Sat, Oct 11, 2014 at 06:42:50PM +0200, Marek Vasut wrote:
The correct name of this symbol is CONFIG_S3C2410_NAND_HWECC , the _SYS is redundant.
What makes that the correct name? The symbol is not documented anywhere, and while nothing currently tests for the SYS version, nothing currently sets the non-SYS version.
What is SYS redundant with?
Is this meant to be a user config knob or something that is fixed for a given board?
u-boot$ git grep CONFIG_SYS_S3C2410_NAND_HWECC include/configs/VCMA9.h:#define CONFIG_SYS_S3C2410_NAND_HWECC include/configs/smdk2410.h:#define CONFIG_SYS_S3C2410_NAND_HWECC
u-boot$ git grep CONFIG_S3C2410_NAND_HWECC drivers/mtd/nand/s3c2410_nand.c:#ifdef CONFIG_S3C2410_NAND_HWECC drivers/mtd/nand/s3c2410_nand.c:#ifdef CONFIG_S3C2410_NAND_HWECC
The driver checks the version without _SYS. This is a clear bugfix, so please apply.
There's a clear bug. I asked questions to determine whether this is the proper fix (and encourage a better changelog), and you still haven't answered. It would also be nice if you'd document the symbol while you're at it.
In any case, I don't know why you're asking me to apply a patch with an "arm:" subject line, which only touches ARM board config files, instead of asking an ARM custodian.
-Scott

On Saturday, May 02, 2015 at 03:11:41 AM, Scott Wood wrote:
On Sat, 2015-05-02 at 02:46 +0200, Marek Vasut wrote:
On Thursday, November 27, 2014 at 03:03:50 AM, Scott Wood wrote:
On Sat, Oct 11, 2014 at 06:42:50PM +0200, Marek Vasut wrote:
The correct name of this symbol is CONFIG_S3C2410_NAND_HWECC , the _SYS is redundant.
What makes that the correct name? The symbol is not documented anywhere, and while nothing currently tests for the SYS version, nothing currently sets the non-SYS version.
What is SYS redundant with?
Is this meant to be a user config knob or something that is fixed for a given board?
u-boot$ git grep CONFIG_SYS_S3C2410_NAND_HWECC include/configs/VCMA9.h:#define CONFIG_SYS_S3C2410_NAND_HWECC include/configs/smdk2410.h:#define CONFIG_SYS_S3C2410_NAND_HWECC
u-boot$ git grep CONFIG_S3C2410_NAND_HWECC drivers/mtd/nand/s3c2410_nand.c:#ifdef CONFIG_S3C2410_NAND_HWECC drivers/mtd/nand/s3c2410_nand.c:#ifdef CONFIG_S3C2410_NAND_HWECC
The driver checks the version without _SYS. This is a clear bugfix, so please apply.
There's a clear bug. I asked questions to determine whether this is the proper fix (and encourage a better changelog), and you still haven't answered. It would also be nice if you'd document the symbol while you're at it.
Adding new stuff (like documentation) is now mandatory part of bugfix ? I'd expect bugfixes to be taken in to actually fix bugs and not kept out of the tree because the submitter didn't also do another random chore.
Also, I do not know what else should I say besides that the symbol name is incorrect and you can clearly see it. If that is not enough ...
In any case, I don't know why you're asking me to apply a patch with an "arm:" subject line, which only touches ARM board config files, instead of asking an ARM custodian.
You were the only one who responded, but I'm fine if Tom or whoever picks this.
Best regards, Marek Vasut

On Sat, 2015-05-02 at 03:18 +0200, Marek Vasut wrote:
On Saturday, May 02, 2015 at 03:11:41 AM, Scott Wood wrote:
On Sat, 2015-05-02 at 02:46 +0200, Marek Vasut wrote:
On Thursday, November 27, 2014 at 03:03:50 AM, Scott Wood wrote:
On Sat, Oct 11, 2014 at 06:42:50PM +0200, Marek Vasut wrote:
The correct name of this symbol is CONFIG_S3C2410_NAND_HWECC , the _SYS is redundant.
What makes that the correct name? The symbol is not documented anywhere, and while nothing currently tests for the SYS version, nothing currently sets the non-SYS version.
What is SYS redundant with?
Is this meant to be a user config knob or something that is fixed for a given board?
u-boot$ git grep CONFIG_SYS_S3C2410_NAND_HWECC include/configs/VCMA9.h:#define CONFIG_SYS_S3C2410_NAND_HWECC include/configs/smdk2410.h:#define CONFIG_SYS_S3C2410_NAND_HWECC
u-boot$ git grep CONFIG_S3C2410_NAND_HWECC drivers/mtd/nand/s3c2410_nand.c:#ifdef CONFIG_S3C2410_NAND_HWECC drivers/mtd/nand/s3c2410_nand.c:#ifdef CONFIG_S3C2410_NAND_HWECC
The driver checks the version without _SYS. This is a clear bugfix, so please apply.
There's a clear bug. I asked questions to determine whether this is the proper fix (and encourage a better changelog), and you still haven't answered. It would also be nice if you'd document the symbol while you're at it.
Adding new stuff (like documentation) is now mandatory part of bugfix ?
I didn't say mandatory. I said "would be nice".
I'd expect bugfixes to be taken in to actually fix bugs and not kept out of the tree because the submitter didn't also do another random chore.
In this case the lack of documentation feels related to the cause of the bug -- no authoritative place to say what the proper name is. I don't see it as "another random chore".
Also, I do not know what else should I say besides that the symbol name is incorrect and you can clearly see it. If that is not enough ...
The names don't match. That's a bug. I was wondering whether the right thing was to remove SYS in one place or add it in the other (or have we given up on maintaining the distinction?). I didn't expect asking that question to be a huge burden on the patch's progress. It was also bundled up in a patchset with a bunch of non-bugfixes, so it didn't seem like you were asking for urgent handling of this one.
In any case, I don't know why you're asking me to apply a patch with an "arm:" subject line, which only touches ARM board config files, instead of asking an ARM custodian.
You were the only one who responded,
And look at what I get for doing so. :-)
but I'm fine if Tom or whoever picks this.
While I would have liked an answer to the questions I asked, it's not worth arguing over, so:
Acked-by: Scott Wood scottwood@freescale.com
-Scott

Printing u32 with %02x is just a bad idea, fix it.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Scott Wood scottwood@freescale.com Cc: Vladimir Zapolskiy vz@mleia.com --- drivers/mtd/nand/s3c2410_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index db87d07..399f2bc 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -43,7 +43,7 @@ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) struct nand_chip *chip = mtd->priv; struct s3c2410_nand *nand = s3c2410_get_base_nand();
- debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl); + debug("hwcontrol(): 0x%02x 0x%08x\n", cmd & 0xff, ctrl);
if (ctrl & NAND_CTRL_CHANGE) { ulong IO_ADDR_W = (ulong)nand;

On Sat, Oct 11, 2014 at 06:42:51PM +0200, Marek Vasut wrote:
Printing u32 with %02x is just a bad idea, fix it.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Scott Wood scottwood@freescale.com Cc: Vladimir Zapolskiy vz@mleia.com
drivers/mtd/nand/s3c2410_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index db87d07..399f2bc 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -43,7 +43,7 @@ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) struct nand_chip *chip = mtd->priv; struct s3c2410_nand *nand = s3c2410_get_base_nand();
- debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
- debug("hwcontrol(): 0x%02x 0x%08x\n", cmd & 0xff, ctrl);
What is the purpose of forcing extra zeroes in ctrl all the time? Why is the lack of such ugliness "just a bad idea"?
Also, the masking of cmd is an unexplained change.
-Scott

Merge struct s3c2410_nand and struct s3c2440_nand into one unified struct s3c24x0_nand. While at it, fix up and rename the functions to retrieve the NAND base address and fix up the s3c NAND driver to reflect this change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Scott Wood scottwood@freescale.com Cc: Vladimir Zapolskiy vz@mleia.com --- arch/arm/include/asm/arch-s3c24x0/s3c2410.h | 4 +-- arch/arm/include/asm/arch-s3c24x0/s3c2440.h | 4 +-- arch/arm/include/asm/arch-s3c24x0/s3c24x0.h | 31 ++++++++++++----------- drivers/mtd/nand/s3c2410_nand.c | 38 ++++++++++++++--------------- 4 files changed, 38 insertions(+), 39 deletions(-)
diff --git a/arch/arm/include/asm/arch-s3c24x0/s3c2410.h b/arch/arm/include/asm/arch-s3c24x0/s3c2410.h index ce4186f..8773ce3 100644 --- a/arch/arm/include/asm/arch-s3c24x0/s3c2410.h +++ b/arch/arm/include/asm/arch-s3c24x0/s3c2410.h @@ -83,9 +83,9 @@ static inline struct s3c24x0_lcd *s3c24x0_get_base_lcd(void) return (struct s3c24x0_lcd *)S3C24X0_LCD_BASE; }
-static inline struct s3c2410_nand *s3c2410_get_base_nand(void) +static inline struct s3c24x0_nand *s3c24x0_get_base_nand(void) { - return (struct s3c2410_nand *)S3C2410_NAND_BASE; + return (struct s3c24x0_nand *)S3C2410_NAND_BASE; }
static inline struct s3c24x0_uart diff --git a/arch/arm/include/asm/arch-s3c24x0/s3c2440.h b/arch/arm/include/asm/arch-s3c24x0/s3c2440.h index 3f44bdc..7a525f2 100644 --- a/arch/arm/include/asm/arch-s3c24x0/s3c2440.h +++ b/arch/arm/include/asm/arch-s3c24x0/s3c2440.h @@ -81,9 +81,9 @@ static inline struct s3c24x0_lcd *s3c24x0_get_base_lcd(void) return (struct s3c24x0_lcd *)S3C24X0_LCD_BASE; }
-static inline struct s3c2440_nand *s3c2440_get_base_nand(void) +static inline struct s3c24x0_nand *s3c24x0_get_base_nand(void) { - return (struct s3c2440_nand *)S3C2440_NAND_BASE; + return (struct s3c24x0_nand *)S3C2440_NAND_BASE; }
static inline struct s3c24x0_uart diff --git a/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h b/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h index ed9df34..2dae9fc 100644 --- a/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h +++ b/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h @@ -135,34 +135,33 @@ struct s3c24x0_lcd { };
-#ifdef CONFIG_S3C2410 -/* NAND FLASH (see S3C2410 manual chapter 6) */ -struct s3c2410_nand { - u32 nfconf; - u32 nfcmd; - u32 nfaddr; - u32 nfdata; - u32 nfstat; - u32 nfecc; -}; -#endif -#ifdef CONFIG_S3C2440 -/* NAND FLASH (see S3C2440 manual chapter 6) */ -struct s3c2440_nand { +/* NAND FLASH (see manual chapter 6) */ +struct s3c24x0_nand { u32 nfconf; +#ifndef CONFIG_S3C2410 u32 nfcont; +#endif u32 nfcmd; u32 nfaddr; u32 nfdata; +#ifndef CONFIG_S3C2410 u32 nfeccd0; u32 nfeccd1; u32 nfeccd; +#endif u32 nfstat; +#ifdef CONFIG_S3C2410 + u32 nfecc; +#else u32 nfstat0; u32 nfstat1; -}; + u32 nfmecc0; + u32 nfmecc1; + u32 nfsecc; + u32 nfsblk; + u32 nfeblk; #endif - +};
/* UART (see manual chapter 11) */ struct s3c24x0_uart { diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index 399f2bc..8db432f 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -38,10 +38,10 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) } #endif
-static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; - struct s3c2410_nand *nand = s3c2410_get_base_nand(); + struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
debug("hwcontrol(): 0x%02x 0x%08x\n", cmd & 0xff, ctrl);
@@ -67,35 +67,35 @@ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) writeb(cmd, chip->IO_ADDR_W); }
-static int s3c2410_dev_ready(struct mtd_info *mtd) +static int s3c24x0_dev_ready(struct mtd_info *mtd) { - struct s3c2410_nand *nand = s3c2410_get_base_nand(); + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); debug("dev_ready\n"); return readl(&nand->nfstat) & 0x01; }
#ifdef CONFIG_S3C2410_NAND_HWECC -void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) +void s3c24x0_nand_enable_hwecc(struct mtd_info *mtd, int mode) { - struct s3c2410_nand *nand = s3c2410_get_base_nand(); - debug("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode); + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); + debug("s3c24x0_nand_enable_hwecc(%p, %d)\n", mtd, mode); writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf); }
-static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, +static int s3c24x0_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { - struct s3c2410_nand *nand = s3c2410_get_base_nand(); + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); ecc_code[0] = readb(&nand->nfecc); ecc_code[1] = readb(&nand->nfecc + 1); ecc_code[2] = readb(&nand->nfecc + 2); - debug("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", - mtd , ecc_code[0], ecc_code[1], ecc_code[2]); + debug("s3c24x0_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", + mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
return 0; }
-static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, +static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { if (read_ecc[0] == calc_ecc[0] && @@ -103,7 +103,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, read_ecc[2] == calc_ecc[2]) return 0;
- printf("s3c2410_nand_correct_data: not implemented\n"); + printf("s3c24x0_nand_correct_data: not implemented\n"); return -1; } #endif @@ -113,7 +113,7 @@ int board_nand_init(struct nand_chip *nand) u_int32_t cfg; u_int8_t tacls, twrph0, twrph1; struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - struct s3c2410_nand *nand_reg = s3c2410_get_base_nand(); + struct s3c24x0_nand *nand_reg = s3c24x0_get_base_nand();
debug("board_nand_init()\n");
@@ -149,14 +149,14 @@ int board_nand_init(struct nand_chip *nand) #endif
/* hwcontrol always must be implemented */ - nand->cmd_ctrl = s3c2410_hwcontrol; + nand->cmd_ctrl = s3c24x0_hwcontrol;
- nand->dev_ready = s3c2410_dev_ready; + nand->dev_ready = s3c24x0_dev_ready;
#ifdef CONFIG_S3C2410_NAND_HWECC - nand->ecc.hwctl = s3c2410_nand_enable_hwecc; - nand->ecc.calculate = s3c2410_nand_calculate_ecc; - nand->ecc.correct = s3c2410_nand_correct_data; + nand->ecc.hwctl = s3c24x0_nand_enable_hwecc; + nand->ecc.calculate = s3c24x0_nand_calculate_ecc; + nand->ecc.correct = s3c24x0_nand_correct_data; nand->ecc.mode = NAND_ECC_HW; nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;

Add support for S3C2440 into the NAND driver by filling in the S3C2440 bits and differences.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Scott Wood scottwood@freescale.com Cc: Vladimir Zapolskiy vz@mleia.com --- drivers/mtd/nand/s3c2410_nand.c | 55 ++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 12 deletions(-)
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index 8db432f..4971342 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -12,13 +12,22 @@ #include <asm/io.h>
#define S3C2410_NFCONF_EN (1<<15) +#define S3C2440_NFCONT_EN (1<<0) #define S3C2410_NFCONF_512BYTE (1<<14) #define S3C2410_NFCONF_4STEP (1<<13) #define S3C2410_NFCONF_INITECC (1<<12) +#define S3C2440_NFCONT_INITECC (1<<4) #define S3C2410_NFCONF_nFCE (1<<11) +#define S3C2440_NFCONT_nFCE (1<<1) +#ifdef CONFIG_S3C2410 #define S3C2410_NFCONF_TACLS(x) ((x)<<8) #define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) #define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) +#else /* S3C2412, S3C2440 */ +#define S3C2410_NFCONF_TACLS(x) ((x)<<12) +#define S3C2410_NFCONF_TWRPH0(x) ((x)<<8) +#define S3C2410_NFCONF_TWRPH1(x) ((x)<<4) +#endif
#define S3C2410_ADDR_NALE 4 #define S3C2410_ADDR_NCLE 8 @@ -42,25 +51,30 @@ static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); + uint32_t sel_reg, sel_bit;
debug("hwcontrol(): 0x%02x 0x%08x\n", cmd & 0xff, ctrl);
if (ctrl & NAND_CTRL_CHANGE) { - ulong IO_ADDR_W = (ulong)nand; + chip->IO_ADDR_W = &nand->nfconf;
if (!(ctrl & NAND_CLE)) - IO_ADDR_W |= S3C2410_ADDR_NCLE; + chip->IO_ADDR_W = &nand->nfaddr; if (!(ctrl & NAND_ALE)) - IO_ADDR_W |= S3C2410_ADDR_NALE; + chip->IO_ADDR_W = &nand->nfcmd;
- chip->IO_ADDR_W = (void *)IO_ADDR_W; +#ifdef CONFIG_S3C2410 + sel_reg = (uint32_t)&nand->nfconf; + sel_bit = S3C2410_NFCONF_nFCE; +#else + sel_reg = (uint32_t)&nand->nfcont; + sel_bit = S3C2440_NFCONT_nFCE; +#endif
if (ctrl & NAND_NCE) - writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE, - &nand->nfconf); + clrbits_le32(sel_reg, sel_bit); else - writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE, - &nand->nfconf); + setbits_le32(sel_reg, sel_bit); }
if (cmd != NAND_CMD_NONE) @@ -79,16 +93,27 @@ void s3c24x0_nand_enable_hwecc(struct mtd_info *mtd, int mode) { struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); debug("s3c24x0_nand_enable_hwecc(%p, %d)\n", mtd, mode); - writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf); +#ifdef CONFIG_S3C2410 + setbits_le32(&nand->nfconf, S3C2410_NFCONF_INITECC); +#else + setbits_le32(&nand->nfcont, S3C2440_NFCONT_INITECC); +#endif }
static int s3c24x0_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); +#ifdef CONFIG_S3C2410 ecc_code[0] = readb(&nand->nfecc); ecc_code[1] = readb(&nand->nfecc + 1); ecc_code[2] = readb(&nand->nfecc + 2); +#else + uint32_t ecc = readl(&nand->nfmecc0); + ecc_code[0] = ecc; + ecc_code[1] = ecc >> 8; + ecc_code[2] = ecc >> 16; +#endif debug("s3c24x0_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
@@ -110,14 +135,14 @@ static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat,
int board_nand_init(struct nand_chip *nand) { - u_int32_t cfg; + uint32_t cfg = 0; u_int8_t tacls, twrph0, twrph1; struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); struct s3c24x0_nand *nand_reg = s3c24x0_get_base_nand();
debug("board_nand_init()\n");
- writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon); + setbits_le32(&clk_power->clkcon, 1 << 4);
/* initialize hardware */ #if defined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING) @@ -130,12 +155,18 @@ int board_nand_init(struct nand_chip *nand) twrph1 = 8; #endif
- cfg = S3C2410_NFCONF_EN; +#ifdef CONFIG_S3C2410 + cfg |= S3C2410_NFCONF_EN; +#endif cfg |= S3C2410_NFCONF_TACLS(tacls - 1); cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); writel(cfg, &nand_reg->nfconf);
+#ifndef CONFIG_S3C2410 + writel(S3C2440_NFCONT_EN, &nand_reg->nfcont); +#endif + /* initialize nand_chip data structure */ nand->IO_ADDR_R = (void *)&nand_reg->nfdata; nand->IO_ADDR_W = (void *)&nand_reg->nfdata;

On Sat, Oct 11, 2014 at 06:42:53PM +0200, Marek Vasut wrote:
+#ifdef CONFIG_S3C2410 #define S3C2410_NFCONF_TACLS(x) ((x)<<8) #define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) #define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) +#else /* S3C2412, S3C2440 */ +#define S3C2410_NFCONF_TACLS(x) ((x)<<12) +#define S3C2410_NFCONF_TWRPH0(x) ((x)<<8) +#define S3C2410_NFCONF_TWRPH1(x) ((x)<<4) +#endif
Is there any chance there will be a third variant? Perhaps the S3C2440 variant should be explicitly requested with an #error if no variant is selected.
#define S3C2410_ADDR_NALE 4 #define S3C2410_ADDR_NCLE 8 @@ -42,25 +51,30 @@ static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
uint32_t sel_reg, sel_bit;
debug("hwcontrol(): 0x%02x 0x%08x\n", cmd & 0xff, ctrl);
if (ctrl & NAND_CTRL_CHANGE) {
ulong IO_ADDR_W = (ulong)nand;
chip->IO_ADDR_W = &nand->nfconf;
if (!(ctrl & NAND_CLE))
IO_ADDR_W |= S3C2410_ADDR_NCLE;
if (!(ctrl & NAND_ALE))chip->IO_ADDR_W = &nand->nfaddr;
IO_ADDR_W |= S3C2410_ADDR_NALE;
chip->IO_ADDR_W = &nand->nfcmd;
chip->IO_ADDR_W = (void *)IO_ADDR_W;
+#ifdef CONFIG_S3C2410
sel_reg = (uint32_t)&nand->nfconf;
sel_bit = S3C2410_NFCONF_nFCE;
+#else
sel_reg = (uint32_t)&nand->nfcont;
sel_bit = S3C2440_NFCONT_nFCE;
+#endif
Why are you casting &nand->nfcon[ft] to an integer...
if (ctrl & NAND_NCE)
writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,
&nand->nfconf);
elseclrbits_le32(sel_reg, sel_bit);
writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE,
&nand->nfconf);
setbits_le32(sel_reg, sel_bit);
...only to pass that integer to something that normally accepts a pointer, which doesn't cause a warning only because of ARM's crappy I/O accessors that don't do type checking?
At least the code that was there before used ulong for inappropriate pointer-to-integer casts rather than uint32_t. :-P
- writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
- setbits_le32(&clk_power->clkcon, 1 << 4);
This change seems unrelated to adding s3c2440 support. It'd be clearer if the {clr,set,clrset}bits_le32() conversion were done separately, before the s3c2440 stuff. I'm not insisting that you redo this one, but next time try to keep cleanup separate.
-Scott

On Thursday, November 27, 2014 at 03:20:53 AM, Scott Wood wrote:
On Sat, Oct 11, 2014 at 06:42:53PM +0200, Marek Vasut wrote:
+#ifdef CONFIG_S3C2410
#define S3C2410_NFCONF_TACLS(x) ((x)<<8) #define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) #define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
+#else /* S3C2412, S3C2440 */ +#define S3C2410_NFCONF_TACLS(x) ((x)<<12) +#define S3C2410_NFCONF_TWRPH0(x) ((x)<<8) +#define S3C2410_NFCONF_TWRPH1(x) ((x)<<4) +#endif
Is there any chance there will be a third variant? Perhaps the S3C2440 variant should be explicitly requested with an #error if no variant is selected.
No, Samsung has moved on.
#define S3C2410_ADDR_NALE 4 #define S3C2410_ADDR_NCLE 8
@@ -42,25 +51,30 @@ static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv; struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
uint32_t sel_reg, sel_bit;
debug("hwcontrol(): 0x%02x 0x%08x\n", cmd & 0xff, ctrl);
if (ctrl & NAND_CTRL_CHANGE) {
ulong IO_ADDR_W = (ulong)nand;
chip->IO_ADDR_W = &nand->nfconf;
if (!(ctrl & NAND_CLE))
IO_ADDR_W |= S3C2410_ADDR_NCLE;
chip->IO_ADDR_W = &nand->nfaddr;
if (!(ctrl & NAND_ALE))
IO_ADDR_W |= S3C2410_ADDR_NALE;
chip->IO_ADDR_W = &nand->nfcmd;
chip->IO_ADDR_W = (void *)IO_ADDR_W;
+#ifdef CONFIG_S3C2410
sel_reg = (uint32_t)&nand->nfconf;
sel_bit = S3C2410_NFCONF_nFCE;
+#else
sel_reg = (uint32_t)&nand->nfcont;
sel_bit = S3C2440_NFCONT_nFCE;
+#endif
Why are you casting &nand->nfcon[ft] to an integer...
Where exactly ?
if (ctrl & NAND_NCE)
writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,
&nand->nfconf);
clrbits_le32(sel_reg, sel_bit);
else
writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE,
&nand->nfconf);
setbits_le32(sel_reg, sel_bit);
...only to pass that integer to something that normally accepts a pointer, which doesn't cause a warning only because of ARM's crappy I/O accessors that don't do type checking?
At least the code that was there before used ulong for inappropriate pointer-to-integer casts rather than uint32_t. :-P
So what do you suggest ?
- writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
- setbits_le32(&clk_power->clkcon, 1 << 4);
This change seems unrelated to adding s3c2440 support. It'd be clearer if the {clr,set,clrset}bits_le32() conversion were done separately, before the s3c2440 stuff. I'm not insisting that you redo this one, but next time try to keep cleanup separate.
If that's the case, then please apply.

On Sat, 2015-05-02 at 02:48 +0200, Marek Vasut wrote:
On Thursday, November 27, 2014 at 03:20:53 AM, Scott Wood wrote:
On Sat, Oct 11, 2014 at 06:42:53PM +0200, Marek Vasut wrote:
+#ifdef CONFIG_S3C2410
sel_reg = (uint32_t)&nand->nfconf;
sel_bit = S3C2410_NFCONF_nFCE;
+#else
sel_reg = (uint32_t)&nand->nfcont;
sel_bit = S3C2440_NFCONT_nFCE;
+#endif
Why are you casting &nand->nfcon[ft] to an integer...
Where exactly ?
sel_reg = (uint32_t)&nand->nfconf;
if (ctrl & NAND_NCE)
writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,
&nand->nfconf);
clrbits_le32(sel_reg, sel_bit);
else
writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE,
&nand->nfconf);
setbits_le32(sel_reg, sel_bit);
...only to pass that integer to something that normally accepts a pointer, which doesn't cause a warning only because of ARM's crappy I/O accessors that don't do type checking?
At least the code that was there before used ulong for inappropriate pointer-to-integer casts rather than uint32_t. :-P
So what do you suggest ?
Store it in a proper pointer type.
-Scott

Add buffer reading code, should make the IO a little faster.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Scott Wood scottwood@freescale.com Cc: Vladimir Zapolskiy vz@mleia.com --- drivers/mtd/nand/s3c2410_nand.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index 4971342..91db6ca 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -10,6 +10,7 @@ #include <nand.h> #include <asm/arch/s3c24x0_cpu.h> #include <asm/io.h> +#include <asm/unaligned.h>
#define S3C2410_NFCONF_EN (1<<15) #define S3C2440_NFCONT_EN (1<<0) @@ -45,6 +46,39 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) for (i = 0; i < len; i++) buf[i] = readb(this->IO_ADDR_R); } +#elif !defined(CONFIG_S3C2410) +static void s3c2440_read_buf(struct mtd_info *mtd, u_char *buf, int len) +{ + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); + uint32_t data; + + while (len >= 4) { + data = readl(&nand->nfdata); + put_unaligned_le32(data, buf); + buf += 4; + len -= 4; + } + + for (; len & 3; len--) + *buf++ = readb(&nand->nfdata); +} + +static void s3c2440_write_buf(struct mtd_info *mtd, const u_char *buf, + int len) +{ + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); + uint32_t data; + + while (len >= 4) { + data = get_unaligned_le32(buf); + writel(data, &nand->nfdata); + buf += 4; + len -= 4; + } + + for (; len & 3; len--, buf++) + writeb(*buf, &nand->nfdata); +} #endif
static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) @@ -177,6 +211,9 @@ int board_nand_init(struct nand_chip *nand) /* read_byte and write_byte are default */ #ifdef CONFIG_NAND_SPL nand->read_buf = nand_read_buf; +#elif !defined(CONFIG_S3C2410) + nand->read_buf = s3c2440_read_buf; + nand->write_buf = s3c2440_write_buf; #endif
/* hwcontrol always must be implemented */

Implant a missing ECC correction implementation and select_chip implementation from Linux.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Scott Wood scottwood@freescale.com Cc: Vladimir Zapolskiy vz@mleia.com --- drivers/mtd/nand/s3c2410_nand.c | 89 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 5 deletions(-)
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index 91db6ca..f23a1c8 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -157,16 +157,93 @@ static int s3c24x0_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { - if (read_ecc[0] == calc_ecc[0] && - read_ecc[1] == calc_ecc[1] && - read_ecc[2] == calc_ecc[2]) + unsigned int diff0, diff1, diff2; + unsigned int bit, byte; + + debug("%s(%p,%p,%p,%p)\n", __func__, mtd, dat, read_ecc, calc_ecc); + + diff0 = read_ecc[0] ^ calc_ecc[0]; + diff1 = read_ecc[1] ^ calc_ecc[1]; + diff2 = read_ecc[2] ^ calc_ecc[2]; + + debug("%s: rd %*phN calc %*phN diff %02x%02x%02x\n", + __func__, 3, read_ecc, 3, calc_ecc, + diff0, diff1, diff2); + + if (diff0 == 0 && diff1 == 0 && diff2 == 0) + return 0; /* ECC is ok */ + + /* sometimes people do not think about using the ECC, so check + * to see if we have an 0xff,0xff,0xff read ECC and then ignore + * the error, on the assumption that this is an un-eccd page. + */ + if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2] == 0xff + /*&& info->platform->ignore_unset_ecc*/) return 0;
- printf("s3c24x0_nand_correct_data: not implemented\n"); + /* Can we correct this ECC (ie, one row and column change). + * Note, this is similar to the 256 error code on smartmedia */ + + if (((diff0 ^ (diff0 >> 1)) & 0x55) == 0x55 && + ((diff1 ^ (diff1 >> 1)) & 0x55) == 0x55 && + ((diff2 ^ (diff2 >> 1)) & 0x55) == 0x55) { + /* calculate the bit position of the error */ + + bit = ((diff2 >> 3) & 1) | + ((diff2 >> 4) & 2) | + ((diff2 >> 5) & 4); + + /* calculate the byte position of the error */ + + byte = ((diff2 << 7) & 0x100) | + ((diff1 << 0) & 0x80) | + ((diff1 << 1) & 0x40) | + ((diff1 << 2) & 0x20) | + ((diff1 << 3) & 0x10) | + ((diff0 >> 4) & 0x08) | + ((diff0 >> 3) & 0x04) | + ((diff0 >> 2) & 0x02) | + ((diff0 >> 1) & 0x01); + + debug("correcting error bit %d, byte %d\n", bit, byte); + + dat[byte] ^= (1 << bit); + return 1; + } + + /* if there is only one bit difference in the ECC, then + * one of only a row or column parity has changed, which + * means the error is most probably in the ECC itself */ + + diff0 |= (diff1 << 8); + diff0 |= (diff2 << 16); + + if ((diff0 & ~(1<<fls(diff0))) == 0) + return 1; + return -1; } #endif
+static void s3c24x0_nand_select_chip(struct mtd_info *mtd, int chip) +{ + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); + uint32_t sel_reg, sel_bit; + +#ifdef CONFIG_S3C2410 + sel_reg = (uint32_t)&nand->nfconf; + sel_bit = S3C2410_NFCONF_nFCE; +#else + sel_reg = (uint32_t)&nand->nfcont; + sel_bit = S3C2440_NFCONT_nFCE; +#endif + + if (chip == -1) + setbits_le32(sel_reg, sel_bit); + else + clrbits_le32(sel_reg, sel_bit); +} + int board_nand_init(struct nand_chip *nand) { uint32_t cfg = 0; @@ -205,7 +282,7 @@ int board_nand_init(struct nand_chip *nand) nand->IO_ADDR_R = (void *)&nand_reg->nfdata; nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
- nand->select_chip = NULL; + nand->select_chip = s3c24x0_nand_select_chip;
/* read_buf and write_buf are default */ /* read_byte and write_byte are default */ @@ -221,6 +298,8 @@ int board_nand_init(struct nand_chip *nand)
nand->dev_ready = s3c24x0_dev_ready;
+ nand->chip_delay = 50; + #ifdef CONFIG_S3C2410_NAND_HWECC nand->ecc.hwctl = s3c24x0_nand_enable_hwecc; nand->ecc.calculate = s3c24x0_nand_calculate_ecc;

On Sat, 2014-10-11 at 18:42 +0200, Marek Vasut wrote:
- /* sometimes people do not think about using the ECC, so check
* to see if we have an 0xff,0xff,0xff read ECC and then ignore
* the error, on the assumption that this is an un-eccd page.
*/
Eww. I suppose I won't argue too loudly if Linux is doing the same thing, but what if it's a corrupted blank page, or the ECC just happened to turn out as all 0xff? It seems like there should at least be a warning the first time this happens, and ideally it should be configurable.
- if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2] == 0xff
return 0;/*&& info->platform->ignore_unset_ecc*/)
So it looks like it is configurable in Linux, but you've commented it out here.
@@ -221,6 +298,8 @@ int board_nand_init(struct nand_chip *nand)
nand->dev_ready = s3c24x0_dev_ready;
- nand->chip_delay = 50;
I'm not sure how this is related to the changes described in the changelog...
-Scott

On Tuesday, October 28, 2014 at 11:45:08 PM, Scott Wood wrote:
On Sat, 2014-10-11 at 18:42 +0200, Marek Vasut wrote:
- /* sometimes people do not think about using the ECC, so check
* to see if we have an 0xff,0xff,0xff read ECC and then ignore
* the error, on the assumption that this is an un-eccd page.
*/
Eww. I suppose I won't argue too loudly if Linux is doing the same thing, but what if it's a corrupted blank page, or the ECC just happened to turn out as all 0xff? It seems like there should at least be a warning the first time this happens, and ideally it should be configurable.
if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2] == 0xff
/*&& info->platform->ignore_unset_ecc*/)
return 0;
So it looks like it is configurable in Linux, but you've commented it out here.
@@ -221,6 +298,8 @@ int board_nand_init(struct nand_chip *nand)
nand->dev_ready = s3c24x0_dev_ready;
- nand->chip_delay = 50;
I'm not sure how this is related to the changes described in the changelog...
Can you collect the MTD patches which are applicable at least and drop this one?
Best regards, Marek Vasut

On Thu, 2016-01-14 at 02:41 +0100, Marek Vasut wrote:
On Tuesday, October 28, 2014 at 11:45:08 PM, Scott Wood wrote:
On Sat, 2014-10-11 at 18:42 +0200, Marek Vasut wrote:
- /* sometimes people do not think about using the ECC, so check
* to see if we have an 0xff,0xff,0xff read ECC and then ignore
* the error, on the assumption that this is an un-eccd page.
*/
Eww. I suppose I won't argue too loudly if Linux is doing the same thing, but what if it's a corrupted blank page, or the ECC just happened to turn out as all 0xff? It seems like there should at least be a warning the first time this happens, and ideally it should be configurable.
- if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2]
== 0xff
/*&& info->platform->ignore_unset_ecc*/)
return 0;
So it looks like it is configurable in Linux, but you've commented it out here.
@@ -221,6 +298,8 @@ int board_nand_init(struct nand_chip *nand)
nand->dev_ready = s3c24x0_dev_ready;
- nand->chip_delay = 50;
I'm not sure how this is related to the changes described in the changelog...
Can you collect the MTD patches which are applicable at least and drop this one?
4/10 is already merged. Which patches are you referring to that don't have comments, still apply cleanly, and are patching a NAND file?
-Scott

On 02/13/2016 12:18 AM, Scott Wood wrote:
On Thu, 2016-01-14 at 02:41 +0100, Marek Vasut wrote:
On Tuesday, October 28, 2014 at 11:45:08 PM, Scott Wood wrote:
On Sat, 2014-10-11 at 18:42 +0200, Marek Vasut wrote:
- /* sometimes people do not think about using the ECC, so check
* to see if we have an 0xff,0xff,0xff read ECC and then ignore
* the error, on the assumption that this is an un-eccd page.
*/
Eww. I suppose I won't argue too loudly if Linux is doing the same thing, but what if it's a corrupted blank page, or the ECC just happened to turn out as all 0xff? It seems like there should at least be a warning the first time this happens, and ideally it should be configurable.
- if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2]
== 0xff
/*&& info->platform->ignore_unset_ecc*/)
return 0;
So it looks like it is configurable in Linux, but you've commented it out here.
@@ -221,6 +298,8 @@ int board_nand_init(struct nand_chip *nand)
nand->dev_ready = s3c24x0_dev_ready;
- nand->chip_delay = 50;
I'm not sure how this is related to the changes described in the changelog...
Can you collect the MTD patches which are applicable at least and drop this one?
4/10 is already merged. Which patches are you referring to that don't have comments, still apply cleanly, and are patching a NAND file?
Most of this patchset.

On Fri, 2016-02-19 at 18:53 +0100, Marek Vasut wrote:
On 02/13/2016 12:18 AM, Scott Wood wrote:
On Thu, 2016-01-14 at 02:41 +0100, Marek Vasut wrote:
On Tuesday, October 28, 2014 at 11:45:08 PM, Scott Wood wrote:
On Sat, 2014-10-11 at 18:42 +0200, Marek Vasut wrote:
- /* sometimes people do not think about using the ECC, so
check
* to see if we have an 0xff,0xff,0xff read ECC and then
ignore
* the error, on the assumption that this is an un-eccd
page.
*/
Eww. I suppose I won't argue too loudly if Linux is doing the same thing, but what if it's a corrupted blank page, or the ECC just happened to turn out as all 0xff? It seems like there should at least be a warning the first time this happens, and ideally it should be configurable.
- if (read_ecc[0] == 0xff && read_ecc[1] == 0xff &&
read_ecc[2] == 0xff
/*&& info->platform->ignore_unset_ecc*/)
return 0;
So it looks like it is configurable in Linux, but you've commented it out here.
@@ -221,6 +298,8 @@ int board_nand_init(struct nand_chip *nand)
nand->dev_ready = s3c24x0_dev_ready;
- nand->chip_delay = 50;
I'm not sure how this is related to the changes described in the changelog...
Can you collect the MTD patches which are applicable at least and drop this one?
4/10 is already merged. Which patches are you referring to that don't have comments, still apply cleanly, and are patching a NAND file?
Most of this patchset.
Give me one example. I couldn't find any last time I looked.
-Scott

This is a matter of simple additional ifdefery to cater for the different register layout of the S3C2440 chip.
Signed-off-by: Marek Vasut marex@denx.de Cc: Heiko Schocher hs@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com --- drivers/i2c/s3c24x0_i2c.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0..927cf61 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -153,7 +153,7 @@ static int GetI2CSDA(void) { struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
-#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) return (readl(&gpio->gpedat) & 0x8000) >> 15; #endif #ifdef CONFIG_S3C2400 @@ -165,7 +165,7 @@ static void SetI2CSCL(int x) { struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
-#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) writel((readl(&gpio->gpedat) & ~0x4000) | (x & 1) << 14, &gpio->gpedat); #endif @@ -427,7 +427,7 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) int i;
if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) { -#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) ulong old_gpecon = readl(&gpio->gpecon); #endif #ifdef CONFIG_S3C2400 @@ -436,7 +436,7 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) /* bus still busy probably by (most) previously interrupted transfer */
-#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) /* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */ writel((readl(&gpio->gpecon) & ~0xF0000000) | 0x10000000, &gpio->gpecon); @@ -462,7 +462,7 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) udelay(1000);
/* restore pin functions */ -#ifdef CONFIG_S3C2410 +#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) writel(old_gpecon, &gpio->gpecon); #endif #ifdef CONFIG_S3C2400

On Saturday, October 11, 2014 at 06:42:56 PM, Marek Vasut wrote:
This is a matter of simple additional ifdefery to cater for the different register layout of the S3C2440 chip.
Signed-off-by: Marek Vasut marex@denx.de Cc: Heiko Schocher hs@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com
Can this please be applied ?
Best regards, Marek Vasut

On 02/05/15 10:12, Marek Vasut wrote:
On Saturday, October 11, 2014 at 06:42:56 PM, Marek Vasut wrote:
This is a matter of simple additional ifdefery to cater for the different register layout of the S3C2440 chip.
Signed-off-by: Marek Vasut marex@denx.de Cc: Heiko Schocher hs@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com
Can this please be applied ?
Best regards, Marek Vasut
applied to u-boot-samsung.
Thanks, Minkyu Kang.

The GPIO driver didn't correctly compute the bank offset from the GPIO number and caused random writes into the GPIO block address space. Fix the driver so it actually does the writes correctly. While at it, make use of the clrsetbits_le32() mechanisms.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com --- drivers/gpio/s3c2440_gpio.c | 75 +++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 33 deletions(-)
diff --git a/drivers/gpio/s3c2440_gpio.c b/drivers/gpio/s3c2440_gpio.c index e1e2d3f..d6c7eeb 100644 --- a/drivers/gpio/s3c2440_gpio.c +++ b/drivers/gpio/s3c2440_gpio.c @@ -8,53 +8,50 @@ #include <asm/arch/s3c2440.h> #include <asm/gpio.h> #include <asm/io.h> +#include <errno.h>
#define GPIO_INPUT 0x0 #define GPIO_OUTPUT 0x1
-/* 0x4 means that we want DAT and not CON register */ -#define GPIO_PORT(x) ((((x) >> 5) & 0x3) + 0x4) -#define GPIO_BIT(x) ((x) & 0x3f) +#define S3C_GPIO_CON 0x0 +#define S3C_GPIO_DAT 0x4
-/* - * It's how we calculate the full port address - * We have to get the number of the port + 1 (Port A is at 0x56000001 ...) - * We move it at the second digit, and finally we add 0x4 because we want - * to modify GPIO DAT and not CON - */ -#define GPIO_FULLPORT(x) (S3C24X0_GPIO_BASE | ((GPIO_PORT(gpio) + 1) << 1)) +static uint32_t s3c_gpio_get_bank_addr(unsigned gpio) +{ + /* There is up to 16 pins per bank, one bank is 0x10 big. */ + uint32_t addr = gpio & ~0xf; + + if (addr >= 0x80 && addr != 0xd0) { /* Wrong GPIO bank. */ + printf("Invalid GPIO bank (bank %02x)\n", addr); + return 0xffffffff; + } + + return addr | S3C24X0_GPIO_BASE; +}
int gpio_set_value(unsigned gpio, int value) { - unsigned l = readl(GPIO_FULLPORT(gpio)); - unsigned bit; - unsigned port = GPIO_FULLPORT(gpio); - - /* - * All GPIO Port have a configuration on - * 2 bits excepted the first GPIO (A) which - * have only 1 bit of configuration. - */ - if (!GPIO_PORT(gpio)) - bit = (0x1 << GPIO_BIT(gpio)); - else - bit = (0x3 << GPIO_BIT(gpio)); + uint32_t addr = s3c_gpio_get_bank_addr(gpio); + + if (addr == 0xffffffff) + return -EINVAL;
if (value) - l |= bit; + setbits_le32(addr | S3C_GPIO_DAT, 1 << (gpio & 0xf)); else - l &= ~bit; + clrbits_le32(addr | S3C_GPIO_DAT, 1 << (gpio & 0xf));
- return writel(l, port); + return 0; }
int gpio_get_value(unsigned gpio) { - unsigned l = readl(GPIO_FULLPORT(gpio)); + uint32_t addr = s3c_gpio_get_bank_addr(gpio); + + if (addr == 0xffffffff) + return -EINVAL;
- if (GPIO_PORT(gpio) == 0) /* PORT A */ - return (l >> GPIO_BIT(gpio)) & 0x1; - return (l >> GPIO_BIT(gpio)) & 0x3; + return !!(readl(addr | S3C_GPIO_DAT) & (1 << (gpio & 0xf))); }
int gpio_request(unsigned gpio, const char *label) @@ -67,13 +64,25 @@ int gpio_free(unsigned gpio) return 0; }
+static int s3c_gpio_direction(unsigned gpio, uint8_t dir) +{ + uint32_t addr = s3c_gpio_get_bank_addr(gpio); + const uint32_t mask = 0x3 << ((gpio & 0xf) << 1); + const uint32_t dirm = dir << ((gpio & 0xf) << 1); + + if (addr == 0xffffffff) + return -EINVAL; + + clrsetbits_le32(addr | S3C_GPIO_CON, mask, dirm); + return 0; +} + int gpio_direction_input(unsigned gpio) { - return writel(GPIO_INPUT << GPIO_BIT(gpio), GPIO_FULLPORT(gpio)); + return s3c_gpio_direction(gpio, GPIO_INPUT); }
int gpio_direction_output(unsigned gpio, int value) { - writel(GPIO_OUTPUT << GPIO_BIT(gpio), GPIO_FULLPORT(gpio)); - return gpio_set_value(gpio, value); + return s3c_gpio_direction(gpio, GPIO_OUTPUT); }

On Saturday, October 11, 2014 at 06:42:57 PM, Marek Vasut wrote:
The GPIO driver didn't correctly compute the bank offset from the GPIO number and caused random writes into the GPIO block address space. Fix the driver so it actually does the writes correctly. While at it, make use of the clrsetbits_le32() mechanisms.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com
Can this please be applied ?
Best regards, Marek Vasut

On 02/05/15 10:12, Marek Vasut wrote:
On Saturday, October 11, 2014 at 06:42:57 PM, Marek Vasut wrote:
The GPIO driver didn't correctly compute the bank offset from the GPIO number and caused random writes into the GPIO block address space. Fix the driver so it actually does the writes correctly. While at it, make use of the clrsetbits_le32() mechanisms.
Signed-off-by: Marek Vasut marex@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com
Can this please be applied ?
Best regards, Marek Vasut
applied to u-boot-samsung.
Thanks, Minkyu Kang.

Make sure to keep the MAC address programmed in the SMC911x ADDRH and ADDRL registers. Linux can read those registers to determine the MAC address on EEPROM-less configurations.
Signed-off-by: Marek Vasut marex@denx.de Cc: Joe Hershberger joe.hershberger@ni.com Cc: Tom Rini trini@ti.com --- drivers/net/smc911x.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index b097c1a..5959672 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -187,6 +187,7 @@ static int smc911x_send(struct eth_device *dev, void *packet, int length) static void smc911x_halt(struct eth_device *dev) { smc911x_reset(dev); + smc911x_handle_mac_address(dev); }
static int smc911x_rx(struct eth_device *dev)

On Sat, Oct 11, 2014 at 06:42:58PM +0200, Marek Vasut wrote:
Make sure to keep the MAC address programmed in the SMC911x ADDRH and ADDRL registers. Linux can read those registers to determine the MAC address on EEPROM-less configurations.
Signed-off-by: Marek Vasut marex@denx.de Cc: Joe Hershberger joe.hershberger@ni.com Cc: Tom Rini trini@ti.com
Applied to u-boot/master, thanks!

Hi Marek,
On Sat, 11 Oct 2014 18:42:49 +0200 Marek Vasut marex@denx.de wrote:
Add basic framebuffer driver for the S3C24xx family of CPUs.
Signed-off-by: Marek Vasut marex@denx.de Cc: Anatolij Gustschin agust@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com
V2: Keep the Makefile sorted.
drivers/video/Makefile | 1 + drivers/video/cfb_console.c | 2 +- drivers/video/s3c-fb.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 drivers/video/s3c-fb.c
Acked-by: Anatolij Gustschin agust@denx.de
Thanks,
Anatolij

On Thursday, October 16, 2014 at 11:28:44 AM, Anatolij Gustschin wrote:
Hi Marek,
On Sat, 11 Oct 2014 18:42:49 +0200
Marek Vasut marex@denx.de wrote:
Add basic framebuffer driver for the S3C24xx family of CPUs.
Signed-off-by: Marek Vasut marex@denx.de Cc: Anatolij Gustschin agust@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com
V2: Keep the Makefile sorted.
drivers/video/Makefile | 1 + drivers/video/cfb_console.c | 2 +- drivers/video/s3c-fb.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 drivers/video/s3c-fb.c
Acked-by: Anatolij Gustschin agust@denx.de
Can this please be applied ?
Best regards, Marek Vasut

Hi Marek,
On Sat, 2 May 2015 03:12:03 +0200 Marek Vasut marex@denx.de wrote: ...
drivers/video/Makefile | 1 + drivers/video/cfb_console.c | 2 +- drivers/video/s3c-fb.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 drivers/video/s3c-fb.c
Acked-by: Anatolij Gustschin agust@denx.de
Can this please be applied ?
I can apply this patch. Is there a user? Or do you plan to submit patches for a board enabling this driver?
Anatolij

On 02/19/2016 07:02 PM, Anatolij Gustschin wrote:
Hi Marek,
Hi!
On Sat, 2 May 2015 03:12:03 +0200 Marek Vasut marex@denx.de wrote: ...
drivers/video/Makefile | 1 + drivers/video/cfb_console.c | 2 +- drivers/video/s3c-fb.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 drivers/video/s3c-fb.c
Acked-by: Anatolij Gustschin agust@denx.de
Can this please be applied ?
I can apply this patch. Is there a user? Or do you plan to submit patches for a board enabling this driver?
There is an OOT board which I have here. I am not allowed to submit the board, but I can use it for testing.

Hi Marek,
On Sat, 11 Oct 2014 18:42:49 +0200 Marek Vasut marex@denx.de wrote:
Add basic framebuffer driver for the S3C24xx family of CPUs.
Signed-off-by: Marek Vasut marex@denx.de Cc: Anatolij Gustschin agust@denx.de Cc: Kyungmin Park kyungmin.park@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Vladimir Zapolskiy vz@mleia.com
V2: Keep the Makefile sorted.
drivers/video/Makefile | 1 + drivers/video/cfb_console.c | 2 +- drivers/video/s3c-fb.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 drivers/video/s3c-fb.c
applied to u-boot-video/master, thanks!
-- Anatolij
participants (6)
-
Anatolij Gustschin
-
Marek Vasut
-
Minkyu Kang
-
Scott Wood
-
Scott Wood
-
Tom Rini