From marc at cpdesign.com.au  Fri Oct  1 00:30:59 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri,  1 Oct 2010 14:30:59 +1000
Subject: [PATCH v2] i2c-imx: wait for STOP before disabling controller
Message-ID: <1285907459-9374-1-git-send-email-marc@cpdesign.com.au>

Makes sure that the STOP condition is transmitted before the I2C
controller is disabled.
This fixes a problem where writing to an external EEPROM was not working
because the EEPROM waits until the STOP before initiating the write
internally.

Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
---
 drivers/i2c/i2c-imx.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/i2c-imx.c b/drivers/i2c/i2c-imx.c
index cc64d94..ef7be65 100644
--- a/drivers/i2c/i2c-imx.c
+++ b/drivers/i2c/i2c-imx.c
@@ -265,7 +265,9 @@ static void i2c_imx_stop(struct i2c_adapter *adapter)
 		temp = readb(base + IMX_I2C_I2CR);
 		temp &= ~(I2CR_MSTA | I2CR_MTX);
 		writeb(temp, base + IMX_I2C_I2CR);
-		i2c_imx->stopped = 1;
+		/* wait for the stop condition to be send, otherwise the i2c 
+		 * controller is disabled before the STOP is sent completely */
+		i2c_imx->stopped = i2c_imx_bus_busy(adapter, 0) ? 0 : 1;
 	}
 	if (cpu_is_mx1()) {
 		/*
@@ -275,11 +277,9 @@ static void i2c_imx_stop(struct i2c_adapter *adapter)
 		udelay(i2c_imx->disable_delay);
 	}
 
-	if (!i2c_imx->stopped)
-		i2c_imx_bus_busy(adapter, 0);
-
-	/* Disable I2C controller */
+	/* Disable I2C controller, and force our state to stopped */
 	writeb(0, base + IMX_I2C_I2CR);
+	i2c_imx->stopped = 1;
 }
 
 static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
-- 
1.7.1



From plagnioj at jcrosoft.com  Fri Oct  1 00:29:59 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 1 Oct 2010 06:29:59 +0200
Subject: [PATCH 1/2] imx: Internal boot sources, handle all header offsets
In-Reply-To: <1285904458-7015-1-git-send-email-marc@cpdesign.com.au>
References: <1285904458-7015-1-git-send-email-marc@cpdesign.com.au>
Message-ID: <20101001042959.GE25320@game.jcrosoft.org>

>  
>  #define __flash_header_start		__section(.flash_header_start)
>  
> -#define __flash_header_0x100		__section(.flash_header_0x100)
> -#define __dcd_entry_0x100		__section(.dcd_entry_0x100)
> -#define __image_len_0x100		__section(.image_len_0x100)
> +#if defined(CONFIG_ARCH_IMX_INTERNAL_BOOT_NOR)
> +	#define __flash_header_section		__section(.flash_header_0x1000)
> +	#define __dcd_entry_section		__section(.dcd_entry_0x1000)
> +	#define __image_len_section		__section(.image_len_0x1000)
> +	#define FLASH_HEADER_OFFSET 0x1000
> +#elif defined(CONFIG_ARCH_IMX_INTERNAL_BOOT_ONENAND)
> +	#define __flash_header_section		__section(.flash_header_0x0100)
> +	#define __dcd_entry_section		__section(.dcd_entry_0x0100)
> +	#define __image_len_section		__section(.image_len_0x0100)
> +	#define FLASH_HEADER_OFFSET 0x0100
nor and onenand are the same why duplicate them?

Best Regards,
J.


From marc at cpdesign.com.au  Fri Oct  1 00:58:24 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri, 1 Oct 2010 14:58:24 +1000
Subject: [PATCH 1/2] imx: Internal boot sources, handle all header offsets
In-Reply-To: <20101001042959.GE25320@game.jcrosoft.org>
References: <1285904458-7015-1-git-send-email-marc@cpdesign.com.au>
	<20101001042959.GE25320@game.jcrosoft.org>
Message-ID: <201010011458.24626.marc@cpdesign.com.au>

Hi,

> > -#define __image_len_0x100		__section(.image_len_0x100)
> > +#if defined(CONFIG_ARCH_IMX_INTERNAL_BOOT_NOR)
> > +	#define __flash_header_section		__section(.flash_header_0x1000)
> > +	#define __dcd_entry_section		__section(.dcd_entry_0x1000)
> > +	#define __image_len_section		__section(.image_len_0x1000)
> > +	#define FLASH_HEADER_OFFSET 0x1000
> > +#elif defined(CONFIG_ARCH_IMX_INTERNAL_BOOT_ONENAND)
> > +	#define __flash_header_section		__section(.flash_header_0x0100)
> > +	#define __dcd_entry_section		__section(.dcd_entry_0x0100)
> > +	#define __image_len_section		__section(.image_len_0x0100)
> > +	#define FLASH_HEADER_OFFSET 0x0100
> 
> nor and onenand are the same why duplicate them?

They look similar but, NOR offset is at 4Kb (0x1000), OneNand is 256b (0x100).  

(The leading zero for 0x0100 doesn't help, but is necessary otherwise the 
blah_0x1000 matches the blah_0x100* linker section.)

Cheers
Marc



 


From s.hauer at pengutronix.de  Fri Oct  1 03:16:18 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 1 Oct 2010 09:16:18 +0200
Subject: [PATCH v3] MAKEALL: make it generic
In-Reply-To: <1285903152-5840-1-git-send-email-plagnioj@jcrosoft.com>
References: <1285567954-1394-1-git-send-email-plagnioj@jcrosoft.com>
	<1285903152-5840-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <20101001071618.GA28242@pengutronix.de>

On Fri, Oct 01, 2010 at 05:19:12AM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> it's allow you to compile specific defconfig or ARCH or all
> as
> 
> CROSS_COMPILE=arm-linux- ARCH=arm ./MAKEALL at91sam9263ek_defconfig
> CROSS_COMPILE=arm-linux- ARCH=arm ./MAKEALL
> 
> The cross-compiler can be specify via
>     CROSS_COMPILE               default
>     CROSS_COMPILE_<arch>        arch default
>     CROSS_COMPILE_<target>      deconfig specifc
> 
> it will be evaluated in the invert order
> 
> or via config
> 
> you can specify it via env CONFIG or option -c (overwrite env)
> 
> CONFIG=./MAKEALL.cfg ARCH=arm ./MAKEALL at91sam9263ek_defconfig
> CONFIG=./MAKEALL.cfg ARCH=arm ./MAKEALL
> 
> and for all
> 
> CONFIG=./MAKEALL.cfg ./MAKEALL
> 
> you can specify via env or option
> env       option
> ARCH      -a      arch
> CONFIG    -c      config
> JOBS      -j      jobs
> BUILDDIR  -O      build dir
> LOGDIR    -l      log dir
> 
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> ---
> v3:
> add getopts supports
> 
> add usage support
> 
> Best Rebards,
> J.
>  MAKEALL |  286 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
>  1 files changed, 227 insertions(+), 59 deletions(-)
> 
> diff --git a/MAKEALL b/MAKEALL
> index dd0f66b..d42be6e 100755
> --- a/MAKEALL
> +++ b/MAKEALL
> @@ -1,89 +1,257 @@
> -#!/bin/bash
> +#!/bin/sh

With /bin/sh here ./MAKEALL -c MAKEALL.cfg does not work. I have to
explicitely call ./MAKEALL -c ./MAKEALL.cfg. Can we keep /bin/bash here
or has anybody a better idea?


> +
> +if [ "${CONFIG}" ]
> +then
> +	source "${CONFIG}"
> +fi

It fails here with:

./MAKEALL: line 230: source: MAKEALL.cfg: file not found

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From r.schwebel at pengutronix.de  Fri Oct  1 03:27:52 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 1 Oct 2010 09:27:52 +0200
Subject: [PATCH] imx35: add base addresses for I2C and SDHC
In-Reply-To: <1285903297-6779-1-git-send-email-marc@cpdesign.com.au>
References: <1285903297-6779-1-git-send-email-marc@cpdesign.com.au>
Message-ID: <20101001072752.GL10841@pengutronix.de>

On Fri, Oct 01, 2010 at 01:21:37PM +1000, Marc Reilly wrote:
> Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
> ---
>  arch/arm/mach-imx/include/mach/imx35-regs.h |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h
> index c394a2a..b24674c 100644
> --- a/arch/arm/mach-imx/include/mach/imx35-regs.h
> +++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
> @@ -46,6 +46,11 @@
>  #define IMX_NFC_BASE		0xBB000000
>  #define IMX_FEC_BASE		0x50038000
>  #define IMX_I2C1_BASE		0x43F80000
> +#define IMX_I2C2_BASE		0x43F98000
> +#define IMX_IC23_BASE		0x43F84000
               ^^^^
Shouldn't that be I2C3?

rsc

> +#define IMX_SDHC1_BASE		0x53FB4000
> +#define IMX_SDHC2_BASE		0x53FB8000
> +#define IMX_SDHC3_BASE		0x53FBC000
>  
>  /*
>   * Clock Controller Module (CCM)
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From marc at cpdesign.com.au  Fri Oct  1 03:42:37 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri, 1 Oct 2010 17:42:37 +1000
Subject: [PATCH] imx35: add base addresses for I2C and SDHC
In-Reply-To: <20101001072752.GL10841@pengutronix.de>
References: <1285903297-6779-1-git-send-email-marc@cpdesign.com.au>
	<20101001072752.GL10841@pengutronix.de>
Message-ID: <201010011742.37136.marc@cpdesign.com.au>


> > --- a/arch/arm/mach-imx/include/mach/imx35-regs.h
> > +++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
> > @@ -46,6 +46,11 @@
> > 
> >  #define IMX_NFC_BASE		0xBB000000
> >  #define IMX_FEC_BASE		0x50038000
> >  #define IMX_I2C1_BASE		0x43F80000
> > 
> > +#define IMX_I2C2_BASE		0x43F98000
> > +#define IMX_IC23_BASE		0x43F84000
> 
>                ^^^^
> Shouldn't that be I2C3?
> 
> rsc

Ouch, how embarrassing.

Please ignore this for the moment. I'll resubmit later, but it's a sunny 
friday afternoon and the outside is calling.

Cheers,
Marc


From s.hauer at pengutronix.de  Fri Oct  1 04:02:35 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 1 Oct 2010 10:02:35 +0200
Subject: [PATCH] imx35: add base addresses for I2C and SDHC
In-Reply-To: <201010011742.37136.marc@cpdesign.com.au>
References: <1285903297-6779-1-git-send-email-marc@cpdesign.com.au>
	<20101001072752.GL10841@pengutronix.de>
	<201010011742.37136.marc@cpdesign.com.au>
Message-ID: <20101001080235.GB28242@pengutronix.de>

On Fri, Oct 01, 2010 at 05:42:37PM +1000, Marc Reilly wrote:
> 
> > > --- a/arch/arm/mach-imx/include/mach/imx35-regs.h
> > > +++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
> > > @@ -46,6 +46,11 @@
> > > 
> > >  #define IMX_NFC_BASE		0xBB000000
> > >  #define IMX_FEC_BASE		0x50038000
> > >  #define IMX_I2C1_BASE		0x43F80000
> > > 
> > > +#define IMX_I2C2_BASE		0x43F98000
> > > +#define IMX_IC23_BASE		0x43F84000
> > 
> >                ^^^^
> > Shouldn't that be I2C3?
> > 
> > rsc
> 
> Ouch, how embarrassing.
> 
> Please ignore this for the moment. I'll resubmit later, but it's a sunny 
> friday afternoon and the outside is calling.

I just fixed it up. It's a rainy friday morning here ;)

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From gausinghnsit at gmail.com  Fri Oct  1 07:10:25 2010
From: gausinghnsit at gmail.com (Gaurav Singh)
Date: Fri, 1 Oct 2010 16:40:25 +0530
Subject: Failing to load Barebox Environment
In-Reply-To: <AANLkTikrna=mcBoayqbAezJdvuo1oUhs3XEUrf+W3kpA@mail.gmail.com>
References: <AANLkTi=k3qTJtQeuOMoBDJMrrR3DQbF7GunjT10FRDSW@mail.gmail.com>
	<AANLkTinsWzaMthMo2djN17hWUMG5+4K+Y-H-YZPs-q-H@mail.gmail.com>
	<201009291108.18378.jbe@pengutronix.de>
	<201009291123.19306.jbe@pengutronix.de>
	<AANLkTikrna=mcBoayqbAezJdvuo1oUhs3XEUrf+W3kpA@mail.gmail.com>
Message-ID: <AANLkTikcCPfcaDAdmLajCY-Y9RQn=9gqz28VfZELfTb8@mail.gmail.com>

Hi all,
Well turns out my character device inode values were being overwritten
by the NAND buffer contents... this was because I have to change
NAND_MAX_PAGESIZE from 2048 to 4096 ! I have a NAND on my board where
Page size is 4096.
It is working fine now - no need for a seperate envfs_nand_load function.

Thanks
Regards
Gaurav

On Thu, Sep 30, 2010 at 12:09 PM, Gaurav Singh <gausinghnsit at gmail.com> wrote:
> Hi Sascha, Juergen,
> I did a rather crude workaround for this. Copied the NAND partition
> containing the environment from NAND on startup into a file using
> run_command.
> run_command("cp /dev/env0 /env_temp",0);
> then
> envfs_load("/env_temp", "/env")
>
> This is working fine.
> I think - overall the enfs_load logic has to be tweaked for NAND devices.
>
> Now I wrote a new enfs_nand_load function - This basically reads a
> Page of NAND (which works fine if my env file is less than 4096 :))
> into the buffer and manipulates it to prepare the Environment
> correctly. So basically we can read the entire environment partition
> from NAND in one go and then manipulate it to prepare the env in RAM.
>
> int envfs_nand_load(char *filename, char *dir)
> {
> ? ? ? ?struct envfs_super* super;
> ? ? ? ?void *buf = NULL, *buf_free = NULL;
> ? ? ? ?int envfd;
> ? ? ? ?int fd, ret = 0;
> ? ? ? ?char *str, *tmp;
> ? ? ? ?int namelen_full;
> ? ? ? ?unsigned long size;
>
> ? ? ? ?envfd = open(filename, O_RDONLY);
> ? ? ? ?if (envfd < 0) {
> ? ? ? ? ? ? ? ?printf("Open %s %s\n", filename, errno_str());
> ? ? ? ? ? ? ? ?return -1;
> ? ? ? ?}
> ? ? ? ?/* Reading a Page into Buf */
> ? ? ? ?size = ENVFS_32(4096);
> ? ? ? ?buf = xzalloc(size);
> ? ? ? ?buf_free = buf;
> ? ? ? ?printf("1\n");
> ? ? ? ?ret = read(envfd, buf, size);
> ? ? ? ?if (ret < size) {
> ? ? ? ? ? ? ? ?perror("read");
> ? ? ? ? ? ? ? ?ret = errno;
> ? ? ? ? ? ? ? ?goto out;
> ? ? ? ?}
>
> ? ? ? ?super = (struct envfs_super *)buf;
>
> ? ? ? ?if ( ENVFS_32(super->magic) != ENVFS_MAGIC) {
> ? ? ? ? ? ? ? ?printf("envfs: wrong magic on %s\n", filename);
> ? ? ? ? ? ? ? ?ret = -EIO;
> ? ? ? ? ? ? ? ?goto out;
> ? ? ? ?}
>
> ? ? ? ?if (crc32(0, (unsigned char *)super, sizeof(struct envfs_super) - 4)
> ? ? ? ? ? ? ? ? ? != ENVFS_32(super->sb_crc)) {
> ? ? ? ? ? ? ? ?printf("wrong crc on env superblock\n");
> ? ? ? ? ? ? ? ?ret = -EIO;
> ? ? ? ? ? ? ? ?goto out;
> ? ? ? ?}
>
> ? ? ? ?void *buf2;
> ? ? ? ?size = ENVFS_32(super->size);
> ? ? ? ?/* Rest on ENV except Superblock to be kept in buf2 */
> ? ? ? ?buf2 = (void *)((char *)buf + sizeof(struct envfs_super));
>
> ? ? ? ?if (crc32(0, (unsigned char *)buf2, size)
> ? ? ? ? ? ? ? ? ? ? != ENVFS_32(super->crc)) {
> ? ? ? ? ? ? ? ?printf("wrong crc on env\n");
> ? ? ? ? ? ? ? ?ret = -EIO;
> ? ? ? ? ? ? ? ?goto out;
> ? ? ? ?}
>
> ? ? ? ?while (size) {
> ? ? ? ? ? ? ? ?struct envfs_inode *inode;
> ? ? ? ? ? ? ? ?uint32_t inode_size, inode_namelen;
>
> ? ? ? ? ? ? ? ?inode = (struct envfs_inode *)buf2;
>
> ? ? ? ? ? ? ? ?if (ENVFS_32(inode->magic) != ENVFS_INODE_MAGIC) {
> ? ? ? ? ? ? ? ? ? ? ? ?printf("envfs: wrong magic on %s\n", filename);
> ? ? ? ? ? ? ? ? ? ? ? ?ret = -EIO;
> ? ? ? ? ? ? ? ? ? ? ? ?goto out;
> ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ?inode_size = ENVFS_32(inode->size);
> ? ? ? ? ? ? ? ?inode_namelen = ENVFS_32(inode->namelen);
>
> ? ? ? ? ? ? ? ?debug("loading %s size %d namelen %d\n", inode->data,
> ? ? ? ? ? ? ? ? ? ? ? ?inode_size, inode_namelen);
>
> ? ? ? ? ? ? ? ?str = concat_path_file(dir, inode->data);
> ? ? ? ? ? ? ? ?tmp = strdup(str);
> ? ? ? ? ? ? ? ?make_directory(dirname(tmp));
> ? ? ? ? ? ? ? ?free(tmp);
>
> ? ? ? ? ? ? ? ?fd = open(str, O_WRONLY | O_CREAT | O_TRUNC, 0644);
> ? ? ? ? ? ? ? ?free(str);
> ? ? ? ? ? ? ? ?if (fd < 0) {
> ? ? ? ? ? ? ? ? ? ? ? ?printf("Open %s\n", errno_str());
> ? ? ? ? ? ? ? ? ? ? ? ?ret = fd;
> ? ? ? ? ? ? ? ? ? ? ? ?goto out;
> ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ?namelen_full = PAD4(inode_namelen);
> ? ? ? ? ? ? ? ?ret = write(fd, buf2 + namelen_full + sizeof(struct
> envfs_inode),
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?inode_size);
> ? ? ? ? ? ? ? ?if (ret < inode_size) {
> ? ? ? ? ? ? ? ? ? ? ? ?perror("write");
> ? ? ? ? ? ? ? ? ? ? ? ?ret = errno;
> ? ? ? ? ? ? ? ? ? ? ? ?close(fd);
> ? ? ? ? ? ? ? ? ? ? ? ?goto out;
> ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ?close(fd);
>
> ? ? ? ? ? ? ? ?buf2 += PAD4(inode_namelen) + PAD4(inode_size) +
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(struct envfs_inode);
> ? ? ? ? ? ? ? ?size -= PAD4(inode_namelen) + PAD4(inode_size) +
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(struct envfs_inode);
> ? ? ? ?}
>
> ? ? ? ?ret = 0;
> out:
> ? ? ? ?close(envfd);
> ? ? ? ?if (buf_free)
> ? ? ? ? ? ? ? ?free(buf_free);
> ? ? ? ?return ret;
> }
>
>
>
>
> On Wed, Sep 29, 2010 at 2:53 PM, Juergen Beisert <jbe at pengutronix.de> wrote:
>> Juergen Beisert wrote:
>>> Just a note:
>>>
>>> You configure:
>>> > >> devfs_add_partition("nand0", 0x00000, 0x200000, PARTITION_FIXED,
>>> > >> "self_raw"); dev_add_bb_dev("self_raw", "self0");
>>> > >> devfs_add_partition("nand0", 0x200000, 0x200000, PARTITION_FIXED,
>>> > >> "env_raw"); dev_add_bb_dev("env_raw", "env0");
>>>
>>> And then:
>>> > EVB2065> addpart /dev/nand0 4M(barebox)ro,2M(kernel)ro,-(root)
>>>
>>> Both must match!
>>>
>>> Try instead:
>>>
>>> EVB2065> addpart /dev/nand0 256k(barebox)ro,256k(env),2M(kernel)ro,-(root)
>>>
>>> jbe
>>
>> Ups, sorry: 0x200000 != 256k (didn't count the '0' right...)
>>
>> EVB2065> addpart /dev/nand0 2M(barebox)ro,2M(env),2M(kernel)ro,-(root)
>>
>> jbe
>>
>> --
>> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Beisert ? ? ? ? ? ? |
>> Linux Solutions for Science and Industry ? ? ?| Phone: +49-8766-939 228 ? ? |
>> Vertretung Sued/Muenchen, Germany ? ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? ? ?| http://www.pengutronix.de/ ?|
>>
>


From plagnioj at jcrosoft.com  Fri Oct  1 12:48:11 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 1 Oct 2010 18:48:11 +0200
Subject: [PATCH v3] MAKEALL: make it generic
In-Reply-To: <20101001071618.GA28242@pengutronix.de>
References: <1285567954-1394-1-git-send-email-plagnioj@jcrosoft.com>
	<1285903152-5840-1-git-send-email-plagnioj@jcrosoft.com>
	<20101001071618.GA28242@pengutronix.de>
Message-ID: <20101001164811.GF25320@game.jcrosoft.org>

On 09:16 Fri 01 Oct     , Sascha Hauer wrote:
> On Fri, Oct 01, 2010 at 05:19:12AM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > it's allow you to compile specific defconfig or ARCH or all
> > as
> > 
> > CROSS_COMPILE=arm-linux- ARCH=arm ./MAKEALL at91sam9263ek_defconfig
> > CROSS_COMPILE=arm-linux- ARCH=arm ./MAKEALL
> > 
> > The cross-compiler can be specify via
> >     CROSS_COMPILE               default
> >     CROSS_COMPILE_<arch>        arch default
> >     CROSS_COMPILE_<target>      deconfig specifc
> > 
> > it will be evaluated in the invert order
> > 
> > or via config
> > 
> > you can specify it via env CONFIG or option -c (overwrite env)
> > 
> > CONFIG=./MAKEALL.cfg ARCH=arm ./MAKEALL at91sam9263ek_defconfig
> > CONFIG=./MAKEALL.cfg ARCH=arm ./MAKEALL
> > 
> > and for all
> > 
> > CONFIG=./MAKEALL.cfg ./MAKEALL
> > 
> > you can specify via env or option
> > env       option
> > ARCH      -a      arch
> > CONFIG    -c      config
> > JOBS      -j      jobs
> > BUILDDIR  -O      build dir
> > LOGDIR    -l      log dir
> > 
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> > ---
> > v3:
> > add getopts supports
> > 
> > add usage support
> > 
> > Best Rebards,
> > J.
> >  MAKEALL |  286 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
> >  1 files changed, 227 insertions(+), 59 deletions(-)
> > 
> > diff --git a/MAKEALL b/MAKEALL
> > index dd0f66b..d42be6e 100755
> > --- a/MAKEALL
> > +++ b/MAKEALL
> > @@ -1,89 +1,257 @@
> > -#!/bin/bash
> > +#!/bin/sh
> 
> With /bin/sh here ./MAKEALL -c MAKEALL.cfg does not work. I have to
> explicitely call ./MAKEALL -c ./MAKEALL.cfg. Can we keep /bin/bash here
> or has anybody a better idea?

I found the them issue and how to fix it

Best Regards,
J.


From plagnioj at jcrosoft.com  Fri Oct  1 12:48:47 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri,  1 Oct 2010 18:48:47 +0200
Subject: [PATCH v4] MAKEALL: make it generic
In-Reply-To: <1285903152-5840-1-git-send-email-plagnioj@jcrosoft.com>
References: <1285903152-5840-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <1285951727-16500-1-git-send-email-plagnioj@jcrosoft.com>

it's allow you to compile specific defconfig or ARCH or all
as

CROSS_COMPILE=arm-linux- ARCH=arm ./MAKEALL at91sam9263ek_defconfig
CROSS_COMPILE=arm-linux- ARCH=arm ./MAKEALL

The cross-compiler can be specify via
    CROSS_COMPILE               default
    CROSS_COMPILE_<arch>        arch default
    CROSS_COMPILE_<target>      deconfig specifc

it will be evaluated in the invert order

or via config

you can specify it via env CONFIG or option -c (overwrite env)

CONFIG=./MAKEALL.cfg ARCH=arm ./MAKEALL at91sam9263ek_defconfig
CONFIG=./MAKEALL.cfg ARCH=arm ./MAKEALL

and for all

CONFIG=./MAKEALL.cfg ./MAKEALL

you can specify via env or option
env       option
ARCH      -a      arch
CONFIG    -c      config
JOBS      -j      jobs
BUILDDIR  -O      build dir
LOGDIR    -l      log dir

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
v4:

	fix support of CONFIG=MAKEALL.cfg or -c MAKEALL.cfg

Best Regards,
J.
 MAKEALL |  293 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 234 insertions(+), 59 deletions(-)

diff --git a/MAKEALL b/MAKEALL
index dd0f66b..9353cd8 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -1,89 +1,264 @@
-#!/bin/bash
+#!/bin/sh
 
-check_pipe_status() {
-        for i in  "${PIPESTATUS[@]}"; do
-		[ $i -gt 0 ] && return 1
-        done
-	return 0
-}
+# Print statistics when we exit
+trap exit 1 2 3 15
+trap stats 0
 
+# Keep track of the number of builds and errors
+nb_errors=0
+errors_list=""
+nb_defconfigs=0
+ret=0
 
-HERE=$(pwd)
-AUTOBUILD_DIR=${HERE}/autobuild
-REPORT=${AUTOBUILD_DIR}/REPORT
+here=$(pwd)
 
-if [ -d "${AUTOBUILD_DIR}" ]; then
-	echo "warning: ${AUTOBUILD_DIR} exists, press <ctrl-c> to exit or wait for 3 seconds"
-	sleep 3
-	rm -fr ${AUTOBUILD_DIR}
-fi
+time_start=$(date +%s)
+
+filename=`basename $0`
+
+is_print_stats=1
 
-mkdir -p ${AUTOBUILD_DIR}
+#-----------------------------------------------------------------------
 
-BOARDS="${BOARDS} sandbox"
-sandbox_ARCH=sandbox
-sandbox_CROSS_COMPILE=
+usage() {
+	is_print_stats=0
+	echo "Usage: ${filename} [OPTION]..."
+	echo "Barebox MAKEALL tools."
+	echo ""
+	echo "it's allow you to compile specific defconfig or ARCH or all"
+	echo "as"
+	echo ""
+	echo "CROSS_COMPILE=arm-linux- ARCH=arm ./MAKEALL at91sam9263ek_defconfig"
+	echo "CROSS_COMPILE=arm-linux- ARCH=arm ./MAKEALL"
+	echo ""
+	echo "The cross-compiler can be specify via"
+	echo "    CROSS_COMPILE               default"
+	echo "    CROSS_COMPILE_<arch>        arch default"
+	echo "    CROSS_COMPILE_<target>      deconfig specifc"
+	echo ""
+	echo "it will be evaluated in the invert order"
+	echo ""
+	echo "or via config"
+	echo ""
+	echo "you can specify it via env CONFIG or option -c (overwrite env)"
+	echo ""
+	echo "CONFIG=./MAKEALL.cfg ARCH=arm ./MAKEALL at91sam9263ek_defconfig"
+	echo "CONFIG=./MAKEALL.cfg ARCH=arm ./MAKEALL"
+	echo ""
+	echo "and for all"
+	echo ""
+	echo "CONFIG=./MAKEALL.cfg ./MAKEALL"
+	echo ""
+	echo "you can specify via env or option"
+	echo "env       option"
+	echo "ARCH      -a      arch"
+	echo "CONFIG    -c      config"
+	echo "JOBS      -j      jobs"
+	echo "BUILDDIR  -O      build dir"
+	echo "LOGDIR    -l      log dir"
+	echo ""
+}
 
-BOARDS="${BOARDS} ipe337"
-ipe337_ARCH=blackfin
-ipe337_CROSS_COMPILE=bfin-elf-
+stats() {
+	[ ${is_print_stats} -lt 1 ] && return
 
-BOARDS="${BOARDS} netx_nxdb500"
-netx_nxdb500_ARCH=arm
-netx_nxdb500_CROSS_COMPILE=arm-v4t-linux-gnueabi-
+	echo ""
+	echo "--------------------- SUMMARY ----------------------------"
+	echo "defconfigs compiled: ${nb_defconfigs}"
+	time_stop=$(date +%s)
+	time_diff=$((${time_stop} - ${time_start}))
+	printf "compiled in %4is\n" ${time_diff}
+	if [ ${nb_errors} -gt 0 ] ; then
+		echo "defcongids with warnings or errors: ${nb_errors} (${errors_list} )"
+	fi
+	echo "----------------------------------------------------------"
 
-BOARDS="${BOARDS} pcm030"
-pcm030_ARCH=ppc
-pcm030_CROSS_COMPILE=powerpc-603e-linux-gnu-
+	exit ${ret}
+}
 
-BOARDS="${BOARDS} pcm037"
-pcm037_ARCH=arm
-pcm037_CROSS_COMPILE=arm-1136jfs-linux-gnueabi-
+check_pipe_status() {
+	for i in "${PIPESTATUS[@]}"
+	do
+		[ $i -gt 0 ] && return 1
+	done
+	return 0
+}
 
-BOARDS="${BOARDS} pcm038"
-pcm038_ARCH=arm
-pcm038_CROSS_COMPILE=arm-v4t-linux-gnueabi-
+do_build_target() {
+	local arch=$1
+	local target=$2
+	local target_time_start=$(date +%s)
+	local log_report="${LOGDIR}/${target}/report.log"
+	local log_err="${LOGDIR}/${target}/errors.log"
 
-for board in ${BOARDS}; do
+	rm -rf "${BUILDDIR}"
+	mkdir -p "${BUILDDIR}"
+	mkdir -p "${LOGDIR}/${target}"
+	printf "Building ${arch} ${target} \n" >&2 | tee -a "${log_report}"
 
-	time_start=$(date +%s)
-	arch=${board}_ARCH
-	cross_compile=${board}_CROSS_COMPILE
-	mkdir -p ${AUTOBUILD_DIR}/${board}
-	printf "%-20s defconfig: " ${board} | tee -a ${REPORT}
+	cross_compile=`eval echo '$CROSS_COMPILE_'${target}`
+	if [ ! "${cross_compile}" ]
+	then
+		cross_compile=`eval echo '$CROSS_COMPILE_'${arch}`
+		if [ ! "${cross_compile}" ]
+		then
+			cross_compile=${CROSS_COMPILE}
+		fi
+	fi
 
-	make -C ${HERE} \
-		O=${AUTOBUILD_DIR}/${board} \
-		ARCH=${!arch} \
-		${board}_defconfig \
-		> ${AUTOBUILD_DIR}/${board}.log 2>&1
+	MAKE="make -C ${here} CROSS_COMPILE=${cross_compile} ARCH=${arch} O=${BUILDDIR}"
+	${MAKE} -j${JOBS} ${target} 2>&1 > "${log_report}" | tee "${log_err}"
 
+	printf "Configure: " | tee -a "${log_report}"
 	check_pipe_status
 	if [ "$?" = "0" ]; then
+		printf "OK     \n" | tee -a "${log_report}"
 
-		printf "OK     " | tee -a ${REPORT}
-		printf "compile: " ${board} | tee -a ${REPORT}
+		${MAKE} -j${JOBS} -s 2>&1 >> "${log_report}" | tee -a "${log_err}"
 
-		make -C ${HERE} \
-			O=${AUTOBUILD_DIR}/${board} \
-			ARCH=${!arch} \
-			CROSS_COMPILE=${!cross_compile} \
-			> ${AUTOBUILD_DIR}/${board}.log 2>&1
+		printf "Compile: " ${target} | tee -a "${log_report}"
 
 		check_pipe_status
 		if [ "$?" = "0" ]; then
-			printf "OK     " | tee -a ${REPORT}
+			printf "OK     \n" | tee -a "${log_report}"
+			${cross_compile}size ${BUILDDIR}/barebox | tee -a "${log_report}"
 		else
-			printf "FAILED " | tee -a ${REPORT}
+			printf "FAILED \n" | tee -a "${log_report}"
+			ret=1
 		fi
+	else
+		printf "FAILED \n" | tee -a "${log_report}"
+		printf "Compile: ------ \n" | tee -a "${log_report}"
+		ret=1
+	fi
 
+	if [ -s "${log_err}" ] ; then
+		nb_errors=$((nb_errors + 1))
+		errors_list="${errors_list} ${target}"
 	else
-		printf "FAILED " | tee -a ${REPORT}
-		printf "compile: ------ " | tee -a ${REPORT}
+		rm "${log_err}"
 	fi
 
-	time_stop=$(date +%s)
-	time_diff=$(($time_stop - $time_start))
-	printf "%4is\n" $time_diff | tee -a ${REPORT}
+	nb_defconfigs=$((nb_defconfigs + 1))
+
+	target_time_stop=$(date +%s)
+	target_time_diff=$((${target_time_stop} - ${target_time_start}))
+	printf "Compiled in %4is\n" ${target_time_diff} | tee -a "${log_report}"
+}
+
+do_build() {
+	local arch=$1
+
+	for i in arch/${arch}/configs/*_defconfig
+	do
+		local target=$(basename $i)
+
+		do_build_target ${arch} ${target}
+	done
+}
+
+do_build_all() {
+	local build_target=0
+
+	for i in arch/*
+	do
+		local arch=$(basename $i)
+
+		if [ -d $i ]
+		then
+			do_build ${arch}
+			build_target=$((build_target + 1))
+		fi
+	done
+
+	return $build_target
+}
+
+while getopts "hc:j:O:l:a:" Option
+do
+case $Option in
+	a )
+		ARCH=${OPTARG}
+		;;
+	c )
+		CONFIG=${OPTARG}
+		;;
+	j )
+		JOBS=${OPTARG}
+		;;
+	l )
+		LOGDIR=${OPTARG}
+		;;
+	O )
+		BUILDDIR=${OPTARG}
+		;;
+	h )
+		usage
+		exit 0
+		;;
+esac
 done
 
+shift $((OPTIND - 1))
+
+if [ ! "${JOBS}" ] ; then
+	#linux, BSD, MacOS
+	nb_cpu=`getconf _NPROCESSORS_ONLN`
+
+	if [ $? -gt 0 ]
+	then
+		nb_cpu=1
+	fi
+
+	JOBS=$((${nb_cpu} * 2))
+fi
+
+if [ ! "${LOGDIR}" ]
+then
+	LOGDIR="log"
+fi
+
+if [ ! "${BUILDDIR}" ]
+then
+	BUILDDIR="makeall_builddir"
+fi
+
+if [ "${CONFIG}" ]
+then
+	basedir=`dirname ${CONFIG}`
+
+	if [ ! "${basedir}" ] || [ "${basedir}" = "." ]
+	then
+		CONFIG="./${CONFIG}"
+	fi
+
+	source "${CONFIG}"
+fi
+
+[ -d "${LOGDIR}" ] || mkdir ${LOGDIR} || exit 1
+
+if [ ! "${CONFIG}" ] && [ ! "${CROSS_COMPILE}" ]
+then
+	echo "You need to specify a CONFIG or a CROSS_COMPILE"
+	usage
+	exit 1
+fi
+
+if [ ! "${ARCH}" ] || [ ! -d arch/${ARCH} ]
+then
+	do_build_all
+	if [ $? -eq 0 ]
+	then
+		echo "You need to specify the ARCH or CROSS_COMPILE_<arch> or CROSS_COMPILE_<target> in your config file"
+		usage
+		exit 1
+	fi
+	exit 0
+fi
+
+if [ $# -eq 0 ]
+then
+	do_build ${ARCH}
+else
+	do_build_target ${ARCH} $1
+fi
-- 
1.7.1



From plagnioj at jcrosoft.com  Fri Oct  1 12:53:24 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 1 Oct 2010 18:53:24 +0200
Subject: [PATCH 1/2] imx: Internal boot sources, handle all header offsets
In-Reply-To: <201010011458.24626.marc@cpdesign.com.au>
References: <1285904458-7015-1-git-send-email-marc@cpdesign.com.au>
	<20101001042959.GE25320@game.jcrosoft.org>
	<201010011458.24626.marc@cpdesign.com.au>
Message-ID: <20101001165324.GG25320@game.jcrosoft.org>

On 14:58 Fri 01 Oct     , Marc Reilly wrote:
> Hi,
> 
> > > -#define __image_len_0x100		__section(.image_len_0x100)
> > > +#if defined(CONFIG_ARCH_IMX_INTERNAL_BOOT_NOR)
> > > +	#define __flash_header_section		__section(.flash_header_0x1000)
> > > +	#define __dcd_entry_section		__section(.dcd_entry_0x1000)
> > > +	#define __image_len_section		__section(.image_len_0x1000)
> > > +	#define FLASH_HEADER_OFFSET 0x1000
> > > +#elif defined(CONFIG_ARCH_IMX_INTERNAL_BOOT_ONENAND)
> > > +	#define __flash_header_section		__section(.flash_header_0x0100)
> > > +	#define __dcd_entry_section		__section(.dcd_entry_0x0100)
> > > +	#define __image_len_section		__section(.image_len_0x0100)
> > > +	#define FLASH_HEADER_OFFSET 0x0100
> > 
> > nor and onenand are the same why duplicate them?
> 
> They look similar but, NOR offset is at 4Kb (0x1000), OneNand is 256b (0x100).  
> 
> (The leading zero for 0x0100 doesn't help, but is necessary otherwise the 
> blah_0x1000 matches the blah_0x100* linker section.)
why do we need specific section name?

Best Regards,
J.


From marc at cpdesign.com.au  Fri Oct  1 22:20:47 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Sat, 2 Oct 2010 12:20:47 +1000
Subject: [PATCH 1/2] imx: Internal boot sources, handle all header offsets
In-Reply-To: <20101001165324.GG25320@game.jcrosoft.org>
References: <1285904458-7015-1-git-send-email-marc@cpdesign.com.au>
	<201010011458.24626.marc@cpdesign.com.au>
	<20101001165324.GG25320@game.jcrosoft.org>
Message-ID: <201010021220.48068.marc@cpdesign.com.au>

On Saturday, October 02, 2010 02:53:24 am Jean-Christophe PLAGNIOL-VILLARD 
wrote:
> On 14:58 Fri 01 Oct     , Marc Reilly wrote:
> > Hi,
> > 
> > > > -#define __image_len_0x100		__section(.image_len_0x100)
> > > > +#if defined(CONFIG_ARCH_IMX_INTERNAL_BOOT_NOR)
> > > > +	#define __flash_header_section		__section(.flash_header_0x1000)
> > > > +	#define __dcd_entry_section		__section(.dcd_entry_0x1000)
> > > > +	#define __image_len_section		__section(.image_len_0x1000)
> > > > +	#define FLASH_HEADER_OFFSET 0x1000
> > > > +#elif defined(CONFIG_ARCH_IMX_INTERNAL_BOOT_ONENAND)
> > > > +	#define __flash_header_section		__section(.flash_header_0x0100)
> > > > +	#define __dcd_entry_section		__section(.dcd_entry_0x0100)
> > > > +	#define __image_len_section		__section(.image_len_0x0100)
> > > > +	#define FLASH_HEADER_OFFSET 0x0100
> > > 
> > > nor and onenand are the same why duplicate them?
> > 
> > They look similar but, NOR offset is at 4Kb (0x1000), OneNand is 256b
> > (0x100).
> > 
> > (The leading zero for 0x0100 doesn't help, but is necessary otherwise the

(Clarification here, I meant that the leading zero potentially makes them look 
more similar)

> > blah_0x1000 matches the blah_0x100* linker section.)
> 
> why do we need specific section name?

Only the the final link location really matters, there are three locations 
that the internal boot ROM could look for the flash header info, depending on 
the type of external media. 
The way it was set up was that there were the three predefined sections that 
would be located at the correct address. The approach I took with these 
patches was to just keep that the same.

Looking back, possibly there is a simpler way to do it, but I've got to move 
on to other things.

Cheers
Marc


From plagnioj at jcrosoft.com  Fri Oct  1 23:57:43 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sat, 2 Oct 2010 05:57:43 +0200
Subject: m68k pull request
Message-ID: <20101002035743.GH25320@game.jcrosoft.org>

Hi,

please pull The following changes since commit f6c9a980791489e27b564750478cde498b2a1a42:

  Update flash headers for boards supporting internal boot. (2010-10-01 10:01:14 +0200)

are available in the git repository at:
  git://git.jcrosoft.org/barebox.git m68k

Jean-Christophe PLAGNIOL-VILLARD (1):
      remove m68k arch support

 Documentation/boards.dox                           |    5 -
 TODO                                               |    1 -
 arch/architecture.dox                              |    1 -
 arch/m68k/Kconfig                                  |  182 --
 arch/m68k/Makefile                                 |   82 -
 arch/m68k/boards/kp_ukd_r1_num/Makefile            |   31 -
 arch/m68k/boards/kp_ukd_r1_num/env/bin/_update     |   36 -
 arch/m68k/boards/kp_ukd_r1_num/env/bin/boot        |   38 -
 arch/m68k/boards/kp_ukd_r1_num/env/bin/init        |   20 -
 arch/m68k/boards/kp_ukd_r1_num/env/bin/pcidmaloop  |   14 -
 arch/m68k/boards/kp_ukd_r1_num/env/bin/pciloop     |   13 -
 .../boards/kp_ukd_r1_num/env/bin/update_kernel     |    8 -
 arch/m68k/boards/kp_ukd_r1_num/env/bin/update_root |    8 -
 arch/m68k/boards/kp_ukd_r1_num/env/config          |   32 -
 arch/m68k/boards/kp_ukd_r1_num/highlevel_init.c    |  124 -
 arch/m68k/boards/kp_ukd_r1_num/kp_ukd_r1_num.c     |  160 --
 arch/m68k/boards/kp_ukd_r1_num/kp_ukd_r1_num.dox   |   13 -
 arch/m68k/boards/kp_ukd_r1_num/lowlevel_init.c     |  183 --
 arch/m68k/boards/kp_ukd_r1_num/pci-stubs.c         |   41 -
 arch/m68k/boards/phycore_mcf54xx/Makefile          |   31 -
 arch/m68k/boards/phycore_mcf54xx/env/bin/_update   |   36 -
 arch/m68k/boards/phycore_mcf54xx/env/bin/boot      |   38 -
 arch/m68k/boards/phycore_mcf54xx/env/bin/init      |   20 -
 .../m68k/boards/phycore_mcf54xx/env/bin/pcidmaloop |   14 -
 arch/m68k/boards/phycore_mcf54xx/env/bin/pciloop   |   13 -
 .../boards/phycore_mcf54xx/env/bin/update_kernel   |    8 -
 .../boards/phycore_mcf54xx/env/bin/update_root     |    8 -
 arch/m68k/boards/phycore_mcf54xx/env/config        |   32 -
 arch/m68k/boards/phycore_mcf54xx/highlevel_init.c  |  124 -
 arch/m68k/boards/phycore_mcf54xx/lowlevel_init.c   |  194 --
 arch/m68k/boards/phycore_mcf54xx/pci-stubs.c       |   41 -
 arch/m68k/boards/phycore_mcf54xx/phyCore_MCF54xx.c |  139 --
 .../boards/phycore_mcf54xx/phyCore_MCF54xx.dox     |   14 -
 .../m68k/configs/phycore_kpukdr1_5475num_defconfig |   36 -
 arch/m68k/configs/phycore_mcf54xx_defconfig        |   36 -
 arch/m68k/cpu/Makefile                             |   41 -
 arch/m68k/cpu/cpu.c                                |  185 --
 arch/m68k/cpu/cw_console_io.c                      |  116 -
 arch/m68k/cpu/early_init_support.c                 |   41 -
 arch/m68k/cpu/interrupts.c                         |  246 --
 arch/m68k/cpu/start-mcfv4e.S                       |  677 ------
 arch/m68k/include/asm/atomic.h                     |   25 -
 arch/m68k/include/asm/barebox-m68k.h               |   40 -
 arch/m68k/include/asm/barebox.h                    |   33 -
 arch/m68k/include/asm/bitops.h                     |  141 --
 arch/m68k/include/asm/bootinfo.h                   |  381 ---
 arch/m68k/include/asm/byteorder.h                  |   43 -
 arch/m68k/include/asm/coldfire/mcf548x.h           |   63 -
 .../include/asm/coldfire/mcf548x/mcf548x_can.h     |  159 --
 .../include/asm/coldfire/mcf548x/mcf548x_ctm.h     |   88 -
 .../include/asm/coldfire/mcf548x/mcf548x_dma.h     |  121 -
 .../asm/coldfire/mcf548x/mcf548x_dma_ereq.h        |   62 -
 .../include/asm/coldfire/mcf548x/mcf548x_dspi.h    |  155 --
 .../include/asm/coldfire/mcf548x/mcf548x_eport.h   |   98 -
 .../include/asm/coldfire/mcf548x/mcf548x_fbcs.h    |   97 -
 .../include/asm/coldfire/mcf548x/mcf548x_fec.h     |  623 -----
 .../include/asm/coldfire/mcf548x/mcf548x_gpio.h    |  708 ------
 .../include/asm/coldfire/mcf548x/mcf548x_gpt.h     |  100 -
 .../include/asm/coldfire/mcf548x/mcf548x_i2c.h     |   69 -
 .../include/asm/coldfire/mcf548x/mcf548x_intc.h    |  329 ---
 .../include/asm/coldfire/mcf548x/mcf548x_pci.h     |  349 ---
 .../include/asm/coldfire/mcf548x/mcf548x_pciarb.h  |   50 -
 .../include/asm/coldfire/mcf548x/mcf548x_psc.h     |  486 ----
 .../include/asm/coldfire/mcf548x/mcf548x_sdramc.h  |  109 -
 .../include/asm/coldfire/mcf548x/mcf548x_sec.h     |  389 ----
 .../include/asm/coldfire/mcf548x/mcf548x_siu.h     |   69 -
 .../include/asm/coldfire/mcf548x/mcf548x_slt.h     |   71 -
 .../include/asm/coldfire/mcf548x/mcf548x_sram.h    |   66 -
 .../include/asm/coldfire/mcf548x/mcf548x_uart.h    |  233 --
 .../include/asm/coldfire/mcf548x/mcf548x_usb.h     |  509 ----
 .../include/asm/coldfire/mcf548x/mcf548x_xlbarb.h  |   45 -
 arch/m68k/include/asm/coldfire/mcf5xxx.h           |  258 --
 arch/m68k/include/asm/common.h                     |   25 -
 arch/m68k/include/asm/elf.h                        |  146 --
 arch/m68k/include/asm/hardware.h                   |   30 -
 arch/m68k/include/asm/io.h                         |  304 ---
 arch/m68k/include/asm/mach-types.h                 |   48 -
 arch/m68k/include/asm/memory.h                     |   28 -
 arch/m68k/include/asm/module.h                     |   36 -
 arch/m68k/include/asm/posix_types.h                |   86 -
 arch/m68k/include/asm/processor.h                  |   46 -
 arch/m68k/include/asm/ptrace.h                     |   55 -
 arch/m68k/include/asm/setup.h                      |  412 ----
 arch/m68k/include/asm/string.h                     |   32 -
 arch/m68k/include/asm/types.h                      |   82 -
 arch/m68k/lib/Makefile                             |   31 -
 arch/m68k/lib/barebox.lds.S                        |   92 -
 arch/m68k/lib/m68k-linuxboot.c                     |  177 --
 arch/m68k/lib/m68k-meminit.c                       |   43 -
 arch/m68k/lib/m68k-module.c                        |  110 -
 arch/m68k/mach-mcfv4e.dox                          |   39 -
 arch/m68k/mach-mcfv4e/Kconfig                      |   18 -
 arch/m68k/mach-mcfv4e/Makefile                     |   19 -
 arch/m68k/mach-mcfv4e/dma_utils.c                  |  502 ----
 arch/m68k/mach-mcfv4e/fec.c                        | 1440 ------------
 arch/m68k/mach-mcfv4e/fecbd.c                      |  232 --
 arch/m68k/mach-mcfv4e/include/mach/clocks.h        |   30 -
 arch/m68k/mach-mcfv4e/include/mach/debug_ll.h      |   33 -
 arch/m68k/mach-mcfv4e/include/mach/hardware.h      |   33 -
 arch/m68k/mach-mcfv4e/include/mach/mcf54xx-regs.h  |   30 -
 arch/m68k/mach-mcfv4e/include/proc/dma_utils.h     |   80 -
 arch/m68k/mach-mcfv4e/include/proc/fec.h           |  130 --
 arch/m68k/mach-mcfv4e/include/proc/fecbd.h         |  115 -
 .../m68k/mach-mcfv4e/include/proc/mcdapi/MCD_dma.h |  379 ---
 .../include/proc/mcdapi/MCD_progCheck.h            |   27 -
 .../include/proc/mcdapi/MCD_tasksInit.h            |   66 -
 arch/m68k/mach-mcfv4e/include/proc/net/eth.h       |   70 -
 arch/m68k/mach-mcfv4e/include/proc/net/nbuf.h      |   88 -
 arch/m68k/mach-mcfv4e/include/proc/net/net.h       |   39 -
 arch/m68k/mach-mcfv4e/include/proc/net/queue.h     |   54 -
 arch/m68k/mach-mcfv4e/include/proc/processor.h     |   33 -
 arch/m68k/mach-mcfv4e/include/proc/ptrace.h        |  119 -
 arch/m68k/mach-mcfv4e/mcdapi/MCD_dmaApi.c          |  907 --------
 arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox       |   10 -
 arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c           | 2449 --------------------
 arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c       |  225 --
 arch/m68k/mach-mcfv4e/mcdapi/Makefile              |   26 -
 arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt      |   27 -
 arch/m68k/mach-mcfv4e/mcf_clocksource.c            |  138 --
 arch/m68k/mach-mcfv4e/mcf_reset_cpu.c              |   45 -
 arch/m68k/mach-mcfv4e/multichannel_dma.c           |   51 -
 arch/m68k/mach-mcfv4e/net/Makefile                 |   26 -
 arch/m68k/mach-mcfv4e/net/nbuf.c                   |  239 --
 arch/m68k/mach-mcfv4e/net/net.c                    |  156 --
 arch/m68k/mach-mcfv4e/net/queue.c                  |  128 -
 commands/bootm.c                                   |    1 -
 126 files changed, 0 insertions(+), 18838 deletions(-)
 delete mode 100644 arch/m68k/Kconfig
 delete mode 100644 arch/m68k/Makefile
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/Makefile
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/env/bin/_update
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/env/bin/boot
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/env/bin/init
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/env/bin/pcidmaloop
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/env/bin/pciloop
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/env/bin/update_kernel
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/env/bin/update_root
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/env/config
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/highlevel_init.c
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/kp_ukd_r1_num.c
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/kp_ukd_r1_num.dox
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/lowlevel_init.c
 delete mode 100644 arch/m68k/boards/kp_ukd_r1_num/pci-stubs.c
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/Makefile
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/env/bin/_update
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/env/bin/boot
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/env/bin/init
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/env/bin/pcidmaloop
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/env/bin/pciloop
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/env/bin/update_kernel
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/env/bin/update_root
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/env/config
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/highlevel_init.c
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/lowlevel_init.c
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/pci-stubs.c
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/phyCore_MCF54xx.c
 delete mode 100644 arch/m68k/boards/phycore_mcf54xx/phyCore_MCF54xx.dox
 delete mode 100644 arch/m68k/configs/phycore_kpukdr1_5475num_defconfig
 delete mode 100644 arch/m68k/configs/phycore_mcf54xx_defconfig
 delete mode 100644 arch/m68k/cpu/Makefile
 delete mode 100644 arch/m68k/cpu/cpu.c
 delete mode 100644 arch/m68k/cpu/cw_console_io.c
 delete mode 100644 arch/m68k/cpu/early_init_support.c
 delete mode 100644 arch/m68k/cpu/interrupts.c
 delete mode 100644 arch/m68k/cpu/start-mcfv4e.S
 delete mode 100644 arch/m68k/include/asm/atomic.h
 delete mode 100644 arch/m68k/include/asm/barebox-m68k.h
 delete mode 100644 arch/m68k/include/asm/barebox.h
 delete mode 100644 arch/m68k/include/asm/bitops.h
 delete mode 100644 arch/m68k/include/asm/bootinfo.h
 delete mode 100644 arch/m68k/include/asm/byteorder.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_can.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_ctm.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_dma.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_dma_ereq.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_dspi.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_eport.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_fbcs.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_fec.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_gpio.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_gpt.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_i2c.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_intc.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_pci.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_pciarb.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_psc.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_sdramc.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_sec.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_siu.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_slt.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_sram.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_uart.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_usb.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf548x/mcf548x_xlbarb.h
 delete mode 100644 arch/m68k/include/asm/coldfire/mcf5xxx.h
 delete mode 100644 arch/m68k/include/asm/common.h
 delete mode 100644 arch/m68k/include/asm/elf.h
 delete mode 100644 arch/m68k/include/asm/hardware.h
 delete mode 100644 arch/m68k/include/asm/io.h
 delete mode 100644 arch/m68k/include/asm/mach-types.h
 delete mode 100644 arch/m68k/include/asm/memory.h
 delete mode 100644 arch/m68k/include/asm/module.h
 delete mode 100644 arch/m68k/include/asm/posix_types.h
 delete mode 100644 arch/m68k/include/asm/processor.h
 delete mode 100644 arch/m68k/include/asm/ptrace.h
 delete mode 100644 arch/m68k/include/asm/setup.h
 delete mode 100644 arch/m68k/include/asm/string.h
 delete mode 100644 arch/m68k/include/asm/types.h
 delete mode 100644 arch/m68k/lib/Makefile
 delete mode 100644 arch/m68k/lib/barebox.lds.S
 delete mode 100644 arch/m68k/lib/m68k-linuxboot.c
 delete mode 100644 arch/m68k/lib/m68k-meminit.c
 delete mode 100644 arch/m68k/lib/m68k-module.c
 delete mode 100644 arch/m68k/mach-mcfv4e.dox
 delete mode 100644 arch/m68k/mach-mcfv4e/Kconfig
 delete mode 100644 arch/m68k/mach-mcfv4e/Makefile
 delete mode 100644 arch/m68k/mach-mcfv4e/dma_utils.c
 delete mode 100644 arch/m68k/mach-mcfv4e/fec.c
 delete mode 100644 arch/m68k/mach-mcfv4e/fecbd.c
 delete mode 100644 arch/m68k/mach-mcfv4e/include/mach/clocks.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/mach/debug_ll.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/mach/hardware.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/mach/mcf54xx-regs.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/dma_utils.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/fec.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/fecbd.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/mcdapi/MCD_dma.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/mcdapi/MCD_progCheck.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/mcdapi/MCD_tasksInit.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/net/eth.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/net/nbuf.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/net/net.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/net/queue.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/processor.h
 delete mode 100644 arch/m68k/mach-mcfv4e/include/proc/ptrace.h
 delete mode 100644 arch/m68k/mach-mcfv4e/mcdapi/MCD_dmaApi.c
 delete mode 100644 arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox
 delete mode 100644 arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c
 delete mode 100644 arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c
 delete mode 100644 arch/m68k/mach-mcfv4e/mcdapi/Makefile
 delete mode 100644 arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt
 delete mode 100644 arch/m68k/mach-mcfv4e/mcf_clocksource.c
 delete mode 100644 arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
 delete mode 100644 arch/m68k/mach-mcfv4e/multichannel_dma.c
 delete mode 100644 arch/m68k/mach-mcfv4e/net/Makefile
 delete mode 100644 arch/m68k/mach-mcfv4e/net/nbuf.c
 delete mode 100644 arch/m68k/mach-mcfv4e/net/net.c
 delete mode 100644 arch/m68k/mach-mcfv4e/net/queue.c

Best Regards,
J.


From s.hauer at pengutronix.de  Sat Oct  2 07:16:30 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 2 Oct 2010 13:16:30 +0200
Subject: v2010.10.0
Message-ID: <20101002111630.GC28242@pengutronix.de>

Hi All,

Another month is over and we have a new release. It gets evident that
more and more patches come from !pengutronix. That's nice ;)

Have fun
 Sascha

The following changes since commit 3d5d2279c0c5d3a7e83f94d98434c1cf29e35311:

  Release v2010.09.0 (2010-08-30 20:47:59 +0200)

are available in the git repository at:
  git://git.pengutronix.de/git/barebox.git master

Baruch Siach (12):
      arm: add support for the serial ATAG
      imx25: add support for UID read from eFuse
      mx25 3ds: set CPU UID
      imx25: fix UID endianess
      mw: fix help text
      imx: move IIM registers to their own header
      imx: driver for the IIM fusebox
      imx iim: add mac address support
      imx25: add chip specific IIM fusebox defines
      imx25: add iim platform code
      fec_imx: add support for IIM stored mac address
      iim/imx25: fix MAC and UID offsets

Jean-Christophe PLAGNIOL-VILLARD (34):
      initcall: add postconsole_initcall
      clock: Introduce clock framework from Linux
      at91: implement clock framework
      string: add strlcpy support
      arm: add common clkdev
      amba: add pl011
      arm: add Nomadik 8815 SoC support
      nand: driver for Nomadik 8815 SoC
      arm: add nhk8815 board support
      init.h: introduce fake define (__init & __initdata) to simplify the linux sync
      stddef: introduce true/false enum
      gitignore: ignore .orig and .patch files
      Kconfig: sync with linux kernel v2.6.36-rc1-168-ge36c886
      mmccpu: fix typo in AT91_MAIN_CLOCK
      dm9000: allow to specify that no srom is present
      at91: rename clocksource.c -> at91sam926x_time.c
      macb: introduce HAS_MACB configuration
      at91: remove non used and obsolete at91rm9200 code
      udpate fixdep.c to linux kernel v2.6.36-rc1-168-ge36c886
      Makefile: fix autoconf.h location
      xfuncs.h: include linux/types.h to avoid non decleration of size_t
      introduce pure_initcall
      introduce phys_addr_t and resource_size_t
      use resource_size_t for device resources
      net: rework the mii support
      add WARN_ON and WARN support
      move include/unaligned to include/linux/unaligned/
      at91: remove non-needed include of autoconf.h
      module: move EXPORT_SYMBOL_GPL define to module.h
      initcall: add postconsole_initcall
      Add Menu Framework
      Menu/cmd: add sub menu entry command support
      blackfin: remove duplicated PAGE_SIZE define
      imx/fb: struct imx_ipu_fb_platform_data remove const for mode

Marek Belisko (1):
      mach-s3c24xx: Fix compilation problem when make a9m2410 or a9m2440 defconfig

Michael Grzeschik (11):
      ehci: add remove function
      usb: add twl4030 phy support
      ehci: add omap support
      beagle: add usb support
      beagle: add bootparams and architecture
      omap nand: bugfix configure ecc order
      loadb: get console baudrate from class_dev not dev
      armlinux: bugfix add parameter name into inline function
      omap: nand remove unnecessary condition
      beagle: defconfig cleanup for v2010.08.0
      beagle: fix usb dependencies

Sascha Hauer (30):
      i2c: Add missing defines for omap
      arm omap: Add I2C driver
      add twl4030 support
      arm omap: Add gpio support
      arm omap: Add cpu_is_ macros
      beagle: Add missing pinmux for usb
      ehci: Make has_tt configurable via platform data
      ehci: set CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS to 16
      add beagle board defconfig
      Add missing include
      menu: initialize entries list in menu_alloc
      menu: Use strdup instead of malloc/strncpy
      menu: simplify menu_free with list_for_each_entry_safe
      menu: remove superfluous struct menu_entry member from struct menu
      menu: use list_for_each_entry where appropriate
      menu: use an initialized struct list as menu list
      menu: do not go to free if there's nothing to free
      menu: simplify usage for clients
      Merge branch 'next'
      vsprintf: fix wrong EXPORT_SYMBOL
      fec_mpc5200: Fix compilation
      rename __initdata to __early_initdata
      ep93xx net driver: Fix compilation
      netx eth: Fix compilation
      scb9328: Fix compilation
      twl4030: Fix compiler warnings
      guf-neso: Fix compiler warnings
      pcm043: Fix compiler warnings
      pcm038: Fix compiler warnings
      Release v2010.10.0

Wolfram Sang (1):
      i2c: fix wrong comment and symbol export for i2c_add_numbered_adapter()

 .gitignore                                         |    4 +
 Makefile                                           |    8 +-
 arch/arm/Kconfig                                   |   16 +-
 arch/arm/Makefile                                  |    5 +-
 arch/arm/boards/at91sam9260ek/config.h             |    2 +-
 arch/arm/boards/at91sam9263ek/config.h             |    2 +-
 arch/arm/boards/at91sam9263ek/init.c               |    3 -
 arch/arm/boards/freescale-mx25-3-stack/3stack.c    |    2 +
 arch/arm/boards/guf-neso/lowlevel.c                |    5 +-
 arch/arm/boards/mmccpu/config.h                    |    2 +-
 arch/arm/boards/mmccpu/init.c                      |    3 -
 arch/arm/boards/nhk8815/Makefile                   |    1 +
 arch/arm/boards/nhk8815/env/bin/_update            |   36 +
 arch/arm/boards/nhk8815/env/bin/boot               |   38 +
 arch/arm/boards/nhk8815/env/bin/init               |   28 +
 .../boards/nhk8815/env/bin/update_barebox_xmodem   |   19 +
 arch/arm/boards/nhk8815/env/bin/update_kernel      |    8 +
 arch/arm/boards/nhk8815/env/bin/update_root        |    8 +
 arch/arm/boards/nhk8815/env/config                 |   32 +
 arch/arm/boards/nhk8815/setup.c                    |  106 ++
 arch/arm/boards/omap/board-beagle.c                |   64 +
 arch/arm/boards/pcm038/lowlevel.c                  |    5 +-
 arch/arm/boards/pcm043/lowlevel.c                  |    5 +-
 arch/arm/boards/pm9263/config.h                    |    2 +-
 arch/arm/boards/pm9263/init.c                      |    3 -
 arch/arm/boards/scb9328/scb9328.c                  |    1 +
 arch/arm/common/Kconfig                            |    2 +
 arch/arm/common/Makefile                           |    5 +
 arch/arm/common/clkdev.c                           |  160 ++
 arch/arm/configs/a9m2410_defconfig                 |    2 +-
 arch/arm/configs/a9m2440_defconfig                 |    2 +-
 arch/arm/configs/at91sam9260ek_defconfig           |    2 +-
 arch/arm/configs/at91sam9263ek_defconfig           |    2 +-
 arch/arm/configs/edb93xx_defconfig                 |    2 +-
 arch/arm/configs/eukrea_cpuimx25_defconfig         |    2 +-
 arch/arm/configs/eukrea_cpuimx27_defconfig         |    2 +-
 arch/arm/configs/eukrea_cpuimx35_defconfig         |    2 +-
 arch/arm/configs/freescale_mx25_3stack_defconfig   |    2 +-
 arch/arm/configs/freescale_mx35_3stack_defconfig   |    2 +-
 arch/arm/configs/mmccpu_defconfig                  |    2 +-
 arch/arm/configs/neso_defconfig                    |    2 +-
 arch/arm/configs/netx_nxdb500_defconfig            |    2 +-
 arch/arm/configs/nhk8815_defconfig                 |  232 +++
 arch/arm/configs/omap3530_beagle_defconfig         |  257 +++
 arch/arm/configs/pca100_defconfig                  |    2 +-
 arch/arm/configs/pcm037_defconfig                  |    2 +-
 arch/arm/configs/pcm038_defconfig                  |    2 +-
 arch/arm/configs/pcm043_defconfig                  |    2 +-
 arch/arm/configs/pm9263_defconfig                  |    2 +-
 arch/arm/configs/scb9328_defconfig                 |    2 +-
 arch/arm/include/asm/armlinux.h                    |    6 +-
 arch/arm/include/asm/clkdev.h                      |   30 +
 arch/arm/include/asm/unaligned.h                   |    6 +-
 arch/arm/lib/armlinux.c                            |   19 +
 arch/arm/mach-at91/Kconfig                         |    2 +
 arch/arm/mach-at91/Makefile                        |    6 +-
 arch/arm/mach-at91/at91sam9260.c                   |  207 +++
 arch/arm/mach-at91/at91sam9260_devices.c           |   18 +-
 arch/arm/mach-at91/at91sam9263.c                   |  217 +++
 arch/arm/mach-at91/at91sam9263_devices.c           |   13 +-
 .../{clocksource.c => at91sam926x_time.c}          |    0
 arch/arm/mach-at91/clock.c                         |  718 +++++++++
 arch/arm/mach-at91/clock.h                         |   31 +
 arch/arm/mach-at91/generic.h                       |   14 +
 arch/arm/mach-at91/gpio.c                          |    3 +
 arch/arm/mach-at91/include/mach/at91_dbgu.h        |   66 +
 arch/arm/mach-at91/include/mach/clk.h              |   39 -
 arch/arm/mach-at91/include/mach/cpu.h              |  158 ++
 arch/arm/mach-at91/include/mach/gpio.h             |    1 +
 arch/arm/mach-at91/lowlevel_init.S                 |    1 -
 arch/arm/mach-at91rm9200/Kconfig                   |   16 -
 arch/arm/mach-at91rm9200/include/mach/AT91RM9200.h |  762 ---------
 arch/arm/mach-at91rm9200/include/mach/hardware.h   |   78 -
 arch/arm/mach-imx/Kconfig                          |   18 +
 arch/arm/mach-imx/Makefile                         |    1 +
 arch/arm/mach-imx/iim.c                            |  311 ++++
 arch/arm/mach-imx/imx25.c                          |   62 +
 arch/arm/mach-imx/imx35.c                          |    1 +
 arch/arm/mach-imx/include/mach/generic.h           |    1 +
 arch/arm/mach-imx/include/mach/iim.h               |   57 +
 arch/arm/mach-imx/include/mach/imx-ipu-fb.h        |    2 +-
 arch/arm/mach-imx/include/mach/imx25-regs.h        |    9 +
 arch/arm/mach-imx/include/mach/imx35-regs.h        |   18 -
 arch/arm/mach-nomadik/8815.c                       |   76 +
 arch/arm/mach-nomadik/Kconfig                      |   24 +
 arch/arm/mach-nomadik/Makefile                     |    3 +
 arch/arm/mach-nomadik/clock.c                      |   52 +
 arch/arm/mach-nomadik/clock.h                      |   14 +
 arch/arm/mach-nomadik/include/mach/board.h         |   28 +
 arch/arm/mach-nomadik/include/mach/clkdev.h        |    7 +
 arch/arm/mach-nomadik/include/mach/fsmc.h          |   28 +
 arch/arm/mach-nomadik/include/mach/hardware.h      |   91 ++
 arch/arm/mach-nomadik/include/mach/mtu.h           |   46 +
 arch/arm/mach-nomadik/include/mach/nand.h          |   16 +
 arch/arm/mach-nomadik/include/mach/timex.h         |    6 +
 arch/arm/mach-nomadik/reset.c                      |   36 +
 arch/arm/mach-nomadik/timer.c                      |   81 +
 arch/arm/mach-omap/Kconfig                         |   15 +-
 arch/arm/mach-omap/Makefile                        |    1 +
 arch/arm/mach-omap/gpio.c                          |  206 +++
 arch/arm/mach-omap/include/mach/cm-regbits-34xx.h  |  799 ++++++++++
 arch/arm/mach-omap/include/mach/ehci.h             |  109 ++
 arch/arm/mach-omap/include/mach/generic.h          |   19 +
 arch/arm/mach-omap/include/mach/gpio.h             |   92 ++
 arch/arm/mach-omap/include/mach/omap3-clock.h      |   11 +
 arch/arm/mach-omap/include/mach/omap3-silicon.h    |    6 +
 arch/arm/mach-s3c24xx/Kconfig                      |    2 +
 arch/blackfin/configs/ipe337_defconfig             |    2 +-
 arch/blackfin/include/asm/page.h                   |    1 -
 .../m68k/configs/phycore_kpukdr1_5475num_defconfig |    2 +-
 arch/m68k/configs/phycore_mcf54xx_defconfig        |    2 +-
 arch/ppc/configs/pcm030_defconfig                  |    2 +-
 commands/Kconfig                                   |   10 +
 commands/Makefile                                  |    1 +
 commands/loadb.c                                   |    2 +-
 commands/mem.c                                     |    4 +-
 commands/menu.c                                    |  445 ++++++
 common/Kconfig                                     |   20 +
 common/Makefile                                    |    1 +
 common/console.c                                   |    4 +-
 common/menu.c                                      |  388 +++++
 drivers/i2c/Kconfig                                |    8 +
 drivers/i2c/Makefile                               |    2 +
 drivers/i2c/i2c-omap.c                             |  803 ++++++++++
 drivers/i2c/i2c.c                                  |   26 +-
 drivers/i2c/twl4030.c                              |  186 +++
 drivers/mtd/nand/Kconfig                           |    5 +
 drivers/mtd/nand/Makefile                          |    1 +
 drivers/mtd/nand/nand_omap_gpmc.c                  |   41 +-
 drivers/mtd/nand/nomadik_nand.c                    |  248 +++
 drivers/mtd/ubi/ubi-barebox.h                      |    1 -
 drivers/net/Kconfig                                |   23 +-
 drivers/net/Makefile                               |    2 +-
 drivers/net/at91_ether.c                           |   10 +-
 drivers/net/dm9000.c                               |   36 +-
 drivers/net/ep93xx.c                               |   45 +-
 drivers/net/ep93xx.h                               |    2 +-
 drivers/net/fec_imx.c                              |   37 +-
 drivers/net/fec_imx.h                              |    2 +-
 drivers/net/fec_mpc5200.c                          |   35 +-
 drivers/net/fec_mpc5200.h                          |    2 +-
 drivers/net/macb.c                                 |   44 +-
 drivers/net/{miiphy.c => miidev.c}                 |   96 +-
 drivers/net/netx_eth.c                             |   39 +-
 drivers/net/smc91111.c                             |   32 +-
 drivers/net/smc911x.c                              |   33 +-
 drivers/net/usb/Kconfig                            |    2 +-
 drivers/net/usb/asix.c                             |   26 +-
 drivers/net/usb/usbnet.c                           |    6 +-
 drivers/serial/Kconfig                             |    9 +
 drivers/serial/Makefile                            |    1 +
 drivers/serial/amba-pl011.c                        |  192 +++
 drivers/serial/atmel.c                             |   32 +-
 drivers/usb/host/Kconfig                           |    4 +
 drivers/usb/host/Makefile                          |    1 +
 drivers/usb/host/ehci-hcd.c                        |   21 +-
 drivers/usb/host/ehci-omap.c                       |  260 +++
 drivers/usb/host/ehci.h                            |    2 +-
 drivers/usb/otg/Kconfig                            |    3 +
 drivers/usb/otg/Makefile                           |    2 +
 drivers/usb/otg/twl4030.c                          |  199 +++
 include/asm-generic/barebox.lds.h                  |    3 +-
 include/common.h                                   |   25 +
 include/dm9000.h                                   |    1 +
 include/driver.h                                   |    5 +-
 include/i2c/i2c.h                                  |    2 +
 include/i2c/twl4030.h                              |  461 ++++++
 include/init.h                                     |   29 +-
 include/linux/amba/serial.h                        |  164 ++
 include/linux/clk.h                                |  158 ++
 include/{miiphy.h => linux/mii.h}                  |  132 ++-
 include/linux/stddef.h                             |    5 +
 include/linux/string.h                             |    3 +
 include/linux/types.h                              |    8 +
 include/{ => linux}/unaligned/access_ok.h          |    0
 include/{ => linux}/unaligned/be_byteshift.h       |    0
 include/{ => linux}/unaligned/be_memmove.h         |    0
 include/{ => linux}/unaligned/be_struct.h          |    0
 include/{ => linux}/unaligned/generic.h            |    0
 include/{ => linux}/unaligned/le_byteshift.h       |    0
 include/{ => linux}/unaligned/le_memmove.h         |    0
 include/{ => linux}/unaligned/le_struct.h          |    0
 include/{ => linux}/unaligned/memmove.h            |    0
 include/{ => linux}/unaligned/packed_struct.h      |    0
 include/menu.h                                     |   96 ++
 include/miidev.h                                   |   62 +
 include/module.h                                   |    4 +
 include/readkey.h                                  |    5 +
 include/reloc.h                                    |    4 +-
 include/stdio.h                                    |    1 +
 include/usb/ehci.h                                 |    2 +
 include/usb/twl4030.h                              |   28 +
 include/usb/usbnet.h                               |    4 +-
 include/xfuncs.h                                   |    2 +
 include/xyzModem.h                                 |    3 -
 lib/string.c                                       |   26 +
 lib/vsprintf.c                                     |   27 +-
 net/eth.c                                          |    2 +-
 scripts/basic/fixdep.c                             |   55 +-
 scripts/kconfig/.gitignore                         |    4 +
 scripts/kconfig/Makefile                           |  175 ++-
 scripts/kconfig/POTFILES.in                        |    7 +
 scripts/kconfig/check.sh                           |   14 +
 scripts/kconfig/conf.c                             |  439 +++---
 scripts/kconfig/confdata.c                         |  537 +++++--
 scripts/kconfig/expr.c                             |   65 +-
 scripts/kconfig/expr.h                             |  106 +-
 scripts/kconfig/gconf.c                            |  145 +--
 scripts/kconfig/gconf.glade                        |   30 +-
 scripts/kconfig/kxgettext.c                        |    8 +-
 scripts/kconfig/lex.zconf.c_shipped                |  127 ++-
 scripts/kconfig/lkc.h                              |   40 +-
 scripts/kconfig/lkc_proto.h                        |    9 +-
 scripts/kconfig/lxdialog/BIG.FAT.WARNING           |    2 +-
 scripts/kconfig/lxdialog/check-lxdialog.sh         |   20 +-
 scripts/kconfig/lxdialog/checklist.c               |   17 +-
 scripts/kconfig/lxdialog/dialog.h                  |   11 +-
 scripts/kconfig/lxdialog/inputbox.c                |   10 +-
 scripts/kconfig/lxdialog/menubox.c                 |   28 +-
 scripts/kconfig/lxdialog/textbox.c                 |    2 +-
 scripts/kconfig/lxdialog/util.c                    |   34 +-
 scripts/kconfig/lxdialog/yesno.c                   |    4 +-
 scripts/kconfig/mconf.c                            |  262 ++--
 scripts/kconfig/menu.c                             |  211 +++-
 scripts/kconfig/nconf.c                            | 1570 ++++++++++++++++++
 scripts/kconfig/nconf.gui.c                        |  617 ++++++++
 scripts/kconfig/nconf.h                            |   95 ++
 scripts/kconfig/qconf.cc                           |  255 ++--
 scripts/kconfig/qconf.h                            |   17 +-
 scripts/kconfig/streamline_config.pl               |  422 +++++
 scripts/kconfig/symbol.c                           |  501 +++++-
 scripts/kconfig/util.c                             |   44 +-
 scripts/kconfig/zconf.gperf                        |    6 +-
 scripts/kconfig/zconf.hash.c_shipped               |  225 ++--
 scripts/kconfig/zconf.l                            |   21 +-
 scripts/kconfig/zconf.tab.c_shipped                | 1665 +++++++++++---------
 scripts/kconfig/zconf.y                            |   62 +-
 237 files changed, 14928 insertions(+), 3360 deletions(-)
 create mode 100644 arch/arm/boards/nhk8815/Makefile
 create mode 100644 arch/arm/boards/nhk8815/config.h
 create mode 100644 arch/arm/boards/nhk8815/env/bin/_update
 create mode 100644 arch/arm/boards/nhk8815/env/bin/boot
 create mode 100644 arch/arm/boards/nhk8815/env/bin/init
 create mode 100644 arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem
 create mode 100644 arch/arm/boards/nhk8815/env/bin/update_kernel
 create mode 100644 arch/arm/boards/nhk8815/env/bin/update_root
 create mode 100644 arch/arm/boards/nhk8815/env/config
 create mode 100644 arch/arm/boards/nhk8815/setup.c
 create mode 100644 arch/arm/common/Kconfig
 create mode 100644 arch/arm/common/Makefile
 create mode 100644 arch/arm/common/clkdev.c
 create mode 100644 arch/arm/configs/nhk8815_defconfig
 create mode 100644 arch/arm/configs/omap3530_beagle_defconfig
 create mode 100644 arch/arm/include/asm/clkdev.h
 rename arch/arm/mach-at91/{clocksource.c => at91sam926x_time.c} (100%)
 create mode 100644 arch/arm/mach-at91/clock.c
 create mode 100644 arch/arm/mach-at91/clock.h
 create mode 100644 arch/arm/mach-at91/generic.h
 create mode 100644 arch/arm/mach-at91/include/mach/at91_dbgu.h
 delete mode 100644 arch/arm/mach-at91/include/mach/clk.h
 create mode 100644 arch/arm/mach-at91/include/mach/cpu.h
 delete mode 100644 arch/arm/mach-at91rm9200/Kconfig
 delete mode 100644 arch/arm/mach-at91rm9200/include/mach/AT91RM9200.h
 delete mode 100644 arch/arm/mach-at91rm9200/include/mach/hardware.h
 create mode 100644 arch/arm/mach-imx/iim.c
 create mode 100644 arch/arm/mach-imx/include/mach/iim.h
 create mode 100644 arch/arm/mach-nomadik/8815.c
 create mode 100644 arch/arm/mach-nomadik/Kconfig
 create mode 100644 arch/arm/mach-nomadik/Makefile
 create mode 100644 arch/arm/mach-nomadik/clock.c
 create mode 100644 arch/arm/mach-nomadik/clock.h
 create mode 100644 arch/arm/mach-nomadik/include/mach/board.h
 create mode 100644 arch/arm/mach-nomadik/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-nomadik/include/mach/fsmc.h
 create mode 100644 arch/arm/mach-nomadik/include/mach/hardware.h
 create mode 100644 arch/arm/mach-nomadik/include/mach/mtu.h
 create mode 100644 arch/arm/mach-nomadik/include/mach/nand.h
 create mode 100644 arch/arm/mach-nomadik/include/mach/timex.h
 create mode 100644 arch/arm/mach-nomadik/reset.c
 create mode 100644 arch/arm/mach-nomadik/timer.c
 create mode 100644 arch/arm/mach-omap/gpio.c
 create mode 100644 arch/arm/mach-omap/include/mach/cm-regbits-34xx.h
 create mode 100644 arch/arm/mach-omap/include/mach/ehci.h
 create mode 100644 arch/arm/mach-omap/include/mach/generic.h
 create mode 100644 arch/arm/mach-omap/include/mach/gpio.h
 create mode 100644 commands/menu.c
 create mode 100644 common/menu.c
 create mode 100644 drivers/i2c/i2c-omap.c
 create mode 100644 drivers/i2c/twl4030.c
 create mode 100644 drivers/mtd/nand/nomadik_nand.c
 rename drivers/net/{miiphy.c => miidev.c} (59%)
 create mode 100644 drivers/serial/amba-pl011.c
 create mode 100644 drivers/usb/host/ehci-omap.c
 create mode 100644 drivers/usb/otg/twl4030.c
 create mode 100644 include/i2c/twl4030.h
 create mode 100644 include/linux/amba/serial.h
 create mode 100644 include/linux/clk.h
 rename include/{miiphy.h => linux/mii.h} (74%)
 rename include/{ => linux}/unaligned/access_ok.h (100%)
 rename include/{ => linux}/unaligned/be_byteshift.h (100%)
 rename include/{ => linux}/unaligned/be_memmove.h (100%)
 rename include/{ => linux}/unaligned/be_struct.h (100%)
 rename include/{ => linux}/unaligned/generic.h (100%)
 rename include/{ => linux}/unaligned/le_byteshift.h (100%)
 rename include/{ => linux}/unaligned/le_memmove.h (100%)
 rename include/{ => linux}/unaligned/le_struct.h (100%)
 rename include/{ => linux}/unaligned/memmove.h (100%)
 rename include/{ => linux}/unaligned/packed_struct.h (100%)
 create mode 100644 include/menu.h
 create mode 100644 include/miidev.h
 create mode 100644 include/usb/twl4030.h
 create mode 100755 scripts/kconfig/check.sh
 create mode 100644 scripts/kconfig/nconf.c
 create mode 100644 scripts/kconfig/nconf.gui.c
 create mode 100644 scripts/kconfig/nconf.h
 create mode 100644 scripts/kconfig/streamline_config.pl
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From plagnioj at jcrosoft.com  Sat Oct  2 22:54:26 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sun,  3 Oct 2010 04:54:26 +0200
Subject: [PATCH] imx: fix Internal boot source default choice
Message-ID: <1286074466-12894-1-git-send-email-plagnioj@jcrosoft.com>

via
default ARCH_IMX_INTERNAL_BOOT_NAND

and not default y on ARCH_IMX_INTERNAL_BOOT_NAND

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 arch/arm/mach-imx/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 8a4e1ee..4f95393 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -43,6 +43,7 @@ config ARCH_IMX_INTERNAL_BOOT
 choice
 	depends on ARCH_IMX_INTERNAL_BOOT
 	prompt "Internal boot source"
+	default ARCH_IMX_INTERNAL_BOOT_NAND
 	help
 	  Determines the location of the header information for internal boot.
 	  0x100 for OneNAND
@@ -50,7 +51,6 @@ choice
 	  0x1000 for NOR
 
 config ARCH_IMX_INTERNAL_BOOT_NAND
-	default y
 	bool "NAND, SD/MMC, Serial ROM"
 	select NAND_IMX_BOOT
 
-- 
1.7.1



From nalyssa44 at hotmail.com  Sun Oct  3 14:22:09 2010
From: nalyssa44 at hotmail.com (Mr, Kim)
Date: Mon, 4 Oct 2010 02:22:09 +0800
Subject: Cheap online Marketing,Purchase Now
Message-ID: <1768696150722401431341@microsof-277d70>

Dear customer,

I came accross this website http://www.alphv.com and I made purchase from the website at a very discounted rate and very cheap not only that but also fast delivery to my address please have a look at the website.
Contact Email.below

Reply to[axelm at operamail.com]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20101004/46f78633/attachment.html>

From marc at cpdesign.com.au  Tue Oct  5 03:44:37 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Tue, 5 Oct 2010 18:44:37 +1100
Subject: SD/MMC driver for imx
Message-ID: <201010051844.37189.marc@cpdesign.com.au>

Hi,

Does anybody happen to be working on a driver for mmc/sd cards for imx(35)?

All I'm really looking for is something simple that can read a kernel image 
off a card, no file system need be involved.

Otherwise, any tips for a good starting point would be appreciated. I was 
thinking of using the uboot driver as a starting point.

Cheers,
Marc


From jbe at pengutronix.de  Tue Oct  5 04:21:55 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 5 Oct 2010 10:21:55 +0200
Subject: SD/MMC driver for imx
In-Reply-To: <201010051844.37189.marc@cpdesign.com.au>
References: <201010051844.37189.marc@cpdesign.com.au>
Message-ID: <201010051021.55643.jbe@pengutronix.de>

Marc Reilly wrote:
> Does anybody happen to be working on a driver for mmc/sd cards for imx(35)?
>
> All I'm really looking for is something simple that can read a kernel image
> off a card, no file system need be involved.
>
> Otherwise, any tips for a good starting point would be appreciated. I was
> thinking of using the uboot driver as a starting point.

I'm currently working on an SD/MMC framework and drivers for Samsung S3C2440, 
Freescale i.MX23 and i.MX27. S3C2440 is already working, i.MX23 can read from 
SD cards (but not write yet) and the state of the i.MX27 driver is currently 
unknown. I'm working on these topics in the next few days. I hope it will 
work on all these platforms by the end of this week.

BTW: A FAT filesystem support would be nice to access files on the SD card...

Regards
Juergen

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From wd at denx.de  Tue Oct  5 09:52:13 2010
From: wd at denx.de (Wolfgang Denk)
Date: Tue, 05 Oct 2010 15:52:13 +0200
Subject: Code "borrowed" without attribution to original authors
Message-ID: <20101005135213.24F871539A0@gemini.denx.de>

Hello,

it has been brought to my attention that lately a number of commits
have been added to the BareBox repository (and released as BareBox
v2010.10.0) that contain literal copies of hundreds of lines of code
taken from the U-Boot project.

While this is OK in general (U-Boot is covered by the GPLv2/GPLv2+),
in this case the code has been added to the BareBox repository
without any attribution to the original authors.  Instead, the
respective commits carry only SoB lines like these:

	Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
	Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>

Commits that very clearly show this problem are for example:

 d424ce7  image: factorise image printing contents
 0ceafe1  Replace direct header access with the API routines
 aba80a2  image: rename IH_CPU to IH_ARCH to be more concistant
 7bd7d59  image: factorise string helper

In the examples given, most of the copied code was actually written by
Marian Balakowicz and should be attributed to him.  Neither
Jean-Christophe nor Sascha have any credits on that code.


We all have been working long enough in free and open source software
projects that I can assume you are well aware of the basic principles
of open source software licensing and the requirement to attribute
code to its original authors.


Jean-Christophe, may I please ask you to stop copying code from other
projects without proper attribution?


Sascha, may I please ask you to make sure that proper attribution of
all such copied code gets added to the BareBox repository and released
code?


[Please make sure to keep me on cc: to any replies as I am not
subscribed to the BareBox mailing list.]


Thanks.

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
By the way, ALL software projects are done by iterative  prototyping.
Some companies call their prototypes "releases", that's all.


From plagnioj at jcrosoft.com  Tue Oct  5 12:00:42 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 5 Oct 2010 18:00:42 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101005135213.24F871539A0@gemini.denx.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
Message-ID: <20101005160042.GI25320@game.jcrosoft.org>

On 15:52 Tue 05 Oct     , Wolfgang Denk wrote:
> Hello,
> 
> it has been brought to my attention that lately a number of commits
> have been added to the BareBox repository (and released as BareBox
> v2010.10.0) that contain literal copies of hundreds of lines of code
> taken from the U-Boot project.
> 
> While this is OK in general (U-Boot is covered by the GPLv2/GPLv2+),
> in this case the code has been added to the BareBox repository
> without any attribution to the original authors.  Instead, the
> respective commits carry only SoB lines like these:
> 
> 	Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> 	Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> 
> Commits that very clearly show this problem are for example:
> 
>  d424ce7  image: factorise image printing contents
>  0ceafe1  Replace direct header access with the API routines
>  aba80a2  image: rename IH_CPU to IH_ARCH to be more concistant
>  7bd7d59  image: factorise string helper
> 
> In the examples given, most of the copied code was actually written by
> Marian Balakowicz and should be attributed to him.  Neither
> Jean-Christophe nor Sascha have any credits on that code.
we never take it first otherwise i'll have put a copyright

after if Marian have a copyright missing we will add it with pleasure
> 
> 
> We all have been working long enough in free and open source software
> projects that I can assume you are well aware of the basic principles
> of open source software licensing and the requirement to attribute
> code to its original authors.
> 
> 
> Jean-Christophe, may I please ask you to stop copying code from other
> projects without proper attribution?
we change no copyright ever, we keep them clean and we do let it the SoB are
here as we have apply the modification without any copyright modification

Best Regards,
J.


From plagnioj at jcrosoft.com  Tue Oct  5 12:20:19 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 5 Oct 2010 18:20:19 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101005160042.GI25320@game.jcrosoft.org>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101005160042.GI25320@game.jcrosoft.org>
Message-ID: <20101005162019.GK25320@game.jcrosoft.org>

On 18:00 Tue 05 Oct     , Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 15:52 Tue 05 Oct     , Wolfgang Denk wrote:
> > Hello,
> > 
> > it has been brought to my attention that lately a number of commits
> > have been added to the BareBox repository (and released as BareBox
> > v2010.10.0) that contain literal copies of hundreds of lines of code
> > taken from the U-Boot project.
> > 
> > While this is OK in general (U-Boot is covered by the GPLv2/GPLv2+),
> > in this case the code has been added to the BareBox repository
> > without any attribution to the original authors.  Instead, the
> > respective commits carry only SoB lines like these:
> > 
> > 	Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> > 	Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > 
> > Commits that very clearly show this problem are for example:
> > 
> >  d424ce7  image: factorise image printing contents
> >  0ceafe1  Replace direct header access with the API routines

> >  aba80a2  image: rename IH_CPU to IH_ARCH to be more concistant
> >  7bd7d59  image: factorise string helper
for the record the two are not borrowed at all from U-Boot but done based on
barebox

and as we all known the uImage format come from U-Boot I just sync it
recently without commit details as we do for Kconfig we do not trac
modifications details and we respect the copyright. SO I'll repeat myself
if Marian copyright is missing We will add it with pleasure.

Best Regards,
J.


From wd at denx.de  Tue Oct  5 13:53:54 2010
From: wd at denx.de (Wolfgang Denk)
Date: Tue, 05 Oct 2010 19:53:54 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101005162019.GK25320@game.jcrosoft.org>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101005160042.GI25320@game.jcrosoft.org>
	<20101005162019.GK25320@game.jcrosoft.org>
Message-ID: <20101005175354.E53D21539A0@gemini.denx.de>

Dear Jean-Christophe PLAGNIOL-VILLARD,

In message <20101005162019.GK25320 at game.jcrosoft.org> you wrote:
>
> > >  d424ce7  image: factorise image printing contents
> > >  0ceafe1  Replace direct header access with the API routines
> 
> > >  aba80a2  image: rename IH_CPU to IH_ARCH to be more concistant
> > >  7bd7d59  image: factorise string helper
> for the record the two are not borrowed at all from U-Boot but done based on
> barebox

Oh. Interesting statement. Let me check again. 

Your commit:

	commit aba80a2d2d0f1b25185246925577ce2108247dde
	Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
	Date:   Thu Sep 23 06:48:42 2010 +0200

	    image: rename IH_CPU to IH_ARCH to be more concistant

So BB used to have IH_CPU and switched to IH_ARCH :

Please compare against this U-Boot commit:

	commit b97a2a0a21f279d66de8a9bdbfe21920968bcb1c
	Author: Marian Balakowicz <m8 at semihalf.com>
	Date:   Tue Jan 8 18:14:09 2008 +0100

	    [new uImage] Define a API for image handling operations
	    
	    - Add inline helper macros for basic header processing
	    - Move common non inline code common/image.c
	    - Replace direct header access with the API routines
	    - Rename IH_CPU_* to IH_ARCH_*
	    
	    Signed-off-by: Marian Balakowicz <m8 at semihalf.com>

Pay special attention to the "Rename IH_CPU_* to IH_ARCH_*" part.

Not borrowed?  What an extremely unlikely coincidence then!  I think
you should try to explain that.

> and as we all known the uImage format come from U-Boot I just sync it
> recently without commit details as we do for Kconfig we do not trac
> modifications details and we respect the copyright. SO I'll repeat myself
> if Marian copyright is missing We will add it with pleasure.


I recommend you to get a clue about what is needed to properly
attribute code to the people who actually wrote it, instead of
submitting it without any due reference and then even claiming you
developed it yourself.  I guess you are not interested in having a
reputation as a plagiarist?

Despite your ludicrous statement of "not borrowed at all" I still
assume, for now, this was just an accident, and that bringing it to
your attention is all that is needed to settle the matter.  It is
your turn now.


Thanks.

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The following statement is not true.  The previous statement is true.


From plagnioj at jcrosoft.com  Tue Oct  5 23:03:24 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 6 Oct 2010 05:03:24 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101005175354.E53D21539A0@gemini.denx.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101005160042.GI25320@game.jcrosoft.org>
	<20101005162019.GK25320@game.jcrosoft.org>
	<20101005175354.E53D21539A0@gemini.denx.de>
Message-ID: <20101006030324.GA32214@game.jcrosoft.org>

On 19:53 Tue 05 Oct     , Wolfgang Denk wrote:
> Dear Jean-Christophe PLAGNIOL-VILLARD,
> 
> In message <20101005162019.GK25320 at game.jcrosoft.org> you wrote:
> >
> > > >  d424ce7  image: factorise image printing contents
> > > >  0ceafe1  Replace direct header access with the API routines
> > 
> > > >  aba80a2  image: rename IH_CPU to IH_ARCH to be more concistant
> > > >  7bd7d59  image: factorise string helper
> > for the record the two are not borrowed at all from U-Boot but done based on
> > barebox
> 
> Oh. Interesting statement. Let me check again. 
> 
> Your commit:
> 
> 	commit aba80a2d2d0f1b25185246925577ce2108247dde
> 	Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> 	Date:   Thu Sep 23 06:48:42 2010 +0200
> 
> 	    image: rename IH_CPU to IH_ARCH to be more concistant
> 
> So BB used to have IH_CPU and switched to IH_ARCH :
> 
> Please compare against this U-Boot commit:
> 
> 	commit b97a2a0a21f279d66de8a9bdbfe21920968bcb1c
> 	Author: Marian Balakowicz <m8 at semihalf.com>
> 	Date:   Tue Jan 8 18:14:09 2008 +0100
> 
> 	    [new uImage] Define a API for image handling operations
> 	    
> 	    - Add inline helper macros for basic header processing
> 	    - Move common non inline code common/image.c
> 	    - Replace direct header access with the API routines
> 	    - Rename IH_CPU_* to IH_ARCH_*
> 	    
> 	    Signed-off-by: Marian Balakowicz <m8 at semihalf.com>
> 
> Pay special attention to the "Rename IH_CPU_* to IH_ARCH_*" part.
> 
> Not borrowed?  What an extremely unlikely coincidence then!  I think
> you should try to explain that.
> 
> > and as we all known the uImage format come from U-Boot I just sync it
> > recently without commit details as we do for Kconfig we do not trac
> > modifications details and we respect the copyright. SO I'll repeat myself
> > if Marian copyright is missing We will add it with pleasure.
> 
> 
> I recommend you to get a clue about what is needed to properly
> attribute code to the people who actually wrote it, instead of
> submitting it without any due reference and then even claiming you
> developed it yourself.  I guess you are not interested in having a
> reputation as a plagiarist?
I'll repeat I'ev not borrow these two they look similar I agree but I do not
borrow them. And I'm fine to put Marian copyright I eally do not carefor the
other 2 commits. But these two I just had the same idea by looking at the
code of barebox when I was working to re-introduce the mutli-image support.

The two other commits are here for sync before finish the full sync of uImage
and I will not take Marina work as mine. I'll put my SoB as I apply it and
responsible for this integration as I did for kconfig and others without take
the copyright.

Best Regards,
J.


From s.hauer at pengutronix.de  Wed Oct  6 03:27:49 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 6 Oct 2010 09:27:49 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101005135213.24F871539A0@gemini.denx.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
Message-ID: <20101006072749.GR28242@pengutronix.de>

Hello WOlfgang,

On Tue, Oct 05, 2010 at 03:52:13PM +0200, Wolfgang Denk wrote:
> Hello,
> 
> it has been brought to my attention that lately a number of commits
> have been added to the BareBox repository (and released as BareBox
> v2010.10.0) that contain literal copies of hundreds of lines of code
> taken from the U-Boot project.
> 
> While this is OK in general (U-Boot is covered by the GPLv2/GPLv2+),
> in this case the code has been added to the BareBox repository
> without any attribution to the original authors.  Instead, the
> respective commits carry only SoB lines like these:
> 
> 	Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> 	Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> 
> Commits that very clearly show this problem are for example:
> 
>  d424ce7  image: factorise image printing contents
>  0ceafe1  Replace direct header access with the API routines
>  aba80a2  image: rename IH_CPU to IH_ARCH to be more concistant
>  7bd7d59  image: factorise string helper
> 
> In the examples given, most of the copied code was actually written by
> Marian Balakowicz and should be attributed to him.  Neither
> Jean-Christophe nor Sascha have any credits on that code.
> 
> 
> We all have been working long enough in free and open source software
> projects that I can assume you are well aware of the basic principles
> of open source software licensing and the requirement to attribute
> code to its original authors.

Does that mean U-Boot has credits to all the original mtd authors when
updating U-Boots mtd support to a newer kernel? /me is digging in the
archives; no, it has not. Does that mean with
9b7076229ec6a958bd835ab70745f7676297ce82 Ilya Yanok is the original
author of jffs2 summary support? No, it's the same in the Linux kernel.
Does that mean you are the original author of include/linux/list.h in
700a0c648df72f2c8e0589c0d0470b5ffd7cab7b? Obviously not.

Please lets go not down that road, it leads to nowhere.

We obviously copy code from other projects like U-Boot and the kernel
and we do our best to keep the copyrights intact, but we can only do
this on a per file base, not on a per commit base. That said,
common/image.c has a copyright to semihalf in U-Boot which is missing in
barebox, we can add this. Note that Jean-Christophe added a copyright to
*you* and not to *him* to this file, which means that he did not even
try to put this his own work.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From wd at denx.de  Wed Oct  6 09:56:44 2010
From: wd at denx.de (Wolfgang Denk)
Date: Wed, 06 Oct 2010 15:56:44 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101006072749.GR28242@pengutronix.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101006072749.GR28242@pengutronix.de>
Message-ID: <20101006135644.8D7051539A0@gemini.denx.de>

Dear Sascha,

In message <20101006072749.GR28242 at pengutronix.de> you wrote:
>
> > We all have been working long enough in free and open source software
> > projects that I can assume you are well aware of the basic principles
> > of open source software licensing and the requirement to attribute
> > code to its original authors.
>
> Does that mean U-Boot has credits to all the original mtd authors when
> updating U-Boots mtd support to a newer kernel? /me is digging in the
> archives; no, it has not. Does that mean with

We try hard to properly attribute code to the original sources. I do
not claim that everything in U-Boot is perfect, and if you look long
enough (and especially far enough back into our 10+ years of
history), you probably can find exceptions. We are trying to improve,
and we take all hints on such topics serious.

In each and everycase, whenever someone asked us (either on the
U-Boot mailing list or directly) about Copyright issues or similar
topics, we always addressed these questions directly and as good as
possible.  Please feel free to search the archives.


In the specific case of MTD updates you mention here the commit
messages (extracted with "git log drivers/mtd") contain for example:

commit 6cd752f9:
...
    The check condition is similat to what is in linux/next.

commit 18b5a4b4:
...
    This makes it similar to what is in the kernel NAND driver.

commit aad4a28b:
...
    This was originally part of Thomas Gleixner's patch for
    adding support for 4KiB pages.
    This is not part of the U-Boot NAND driver so updating the
    driver with this to sync up with the kernel NAND driver.

commit 4f41e7ea:
...
    This patch updates the "chip_shift" calculation in the
    NAND driver. This is being done to sync up the NAND driver with
    the kernel NAND driver.

commit aaa8eec5:
...
    This patch adds support for NANDs greater than 2 GB.
    Patch is based on the MTD NAND driver in the kernel.

commit 154b5484:
...
    Update chipselect handling in davinci_nand.c so that it can
    handle 2 GByte chips the same way Linux does:  as one device,

commit 8d2effea:
...
    This patch brings the U-Boot MTD infrastructure in sync with the current
    Linux MTD version (2.6.30-rc3). Biggest change is the 64bit device size
    support and a resync of the mtdpart.c file which has seen multiple fixes
    meanwhile.

commit c45912d8:
...
    NAND: sync with 2.6.27

    This brings the core NAND code up to date with the Linux kernel.

commit cfa460ad:
...
    Update MTD to that of Linux 2.6.22.1

    A lot changed in the Linux MTD code, since it was last ported from
    Linux to U-Boot. This patch takes U-Boot NAND support to the level
    of Linux 2.6.22.1 and will enable support for very large NAND devices

etc.

As you can see, we try to document where such code is coming from.


> 9b7076229ec6a958bd835ab70745f7676297ce82 Ilya Yanok is the original
> author of jffs2 summary support? No, it's the same in the Linux kernel.

No, he is not. Yes, you are right, proper attibution is missing in
this commit, too.  Such cases can happen, even with sevral people
reviewing the submitted patches.

But as you can see from the many examples above we at least _try_ to
be careful about code atributions and copyrights.


> Does that mean you are the original author of include/linux/list.h in
> 700a0c648df72f2c8e0589c0d0470b5ffd7cab7b? Obviously not.

Ah, you have to go back to an example from 5 years ago? At the time
of that patch, the whole git project was just a mere 4 months old,
and git version control had been used for the Linux kernel for just a
very few weeks. There was no tradition to have Signed-off-by: lines
yet, etc.  Many things were far from perfect, then.

But even then, the first line of the commit message reads:

	Add common (with Linux) MTD partition scheme and ...

The wording "common (with Linux)" may not be really good either, but
at least it's a pretty clear hint. And the file in question is
located in include/linux/ , which also carries a certain meaning.

We have learned our lessons since then.

And if someone points out errors in our processes, we are answerable
for our mistakes and try to improve.


> Please lets go not down that road, it leads to nowhere.
>
> We obviously copy code from other projects like U-Boot and the kernel
> and we do our best to keep the copyrights intact, but we can only do
> this on a per file base, not on a per commit base. That said,

Please explain why it should be impossible in a commit message to say
that the hundreds of lines of code you add were not written by the
signees, but taken from somewhare else?  In the examples I listed one
could even give the corresponding git commit ID from the U-Boot repo,
for example:

0ceafe1  Replace direct header access with the API routines
...
	Copied from U-Boot commit b97a2a0

Do you think such a short hint cannot be done?

For your reference:

	commit b97a2a0a21f279d66de8a9bdbfe21920968bcb1c
	Author: Marian Balakowicz <m8 at semihalf.com>
	Date:   Tue Jan 8 18:14:09 2008 +0100

	    [new uImage] Define a API for image handling operations

	    - Add inline helper macros for basic header processing
	    - Move common non inline code common/image.c
===>	    - Replace direct header access with the API routines
	    - Rename IH_CPU_* to IH_ARCH_*

	    Signed-off-by: Marian Balakowicz <m8 at semihalf.com>


> common/image.c has a copyright to semihalf in U-Boot which is missing in
> barebox, we can add this. Note that Jean-Christophe added a copyright to
> *you* and not to *him* to this file, which means that he did not even
> try to put this his own work.

The copyright in the files is one thing. Attribution of large blocks
of code you import is another thing. My request is to attribute such code.


From bogus@does.not.exist.com  Wed Oct  6 18:52:23 2010
From: bogus@does.not.exist.com ()
Date: Wed, 06 Oct 2010 22:52:23 -0000
Subject: No subject
Message-ID: <mailman.0.1286405810.390.barebox@lists.infradead.org>

assume that the code was written by Jean-Christophe, which is not
correct.

As I wrote before in my message to JC, I consider this an accident,
i. e. rather ignorance than intention.  However, I would be seriously
disappointed if such things should happen again.


Thanks.

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
All he had was nothing, but that was something, and now it  had  been
taken away.                             - Terry Pratchett, _Sourcery_


From u.kleine-koenig at pengutronix.de  Thu Oct  7 03:38:42 2010
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Thu, 7 Oct 2010 09:38:42 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101006135644.8D7051539A0@gemini.denx.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101006072749.GR28242@pengutronix.de>
	<20101006135644.8D7051539A0@gemini.denx.de>
Message-ID: <20101007073842.GP29673@pengutronix.de>

Hello Wolfgang,

On Wed, Oct 06, 2010 at 03:56:44PM +0200, Wolfgang Denk wrote:
> From the commits as they are now, most uninformed readers would
> assume that the code was written by Jean-Christophe, which is not
> correct.
I really wonder why you care about the commit log.  I would care more
about the copyright statements in the code.  (Nevertheless I consider it
correct and fair to attribute in the commit log where the code is taken
from.)

I don't know if you want to make it easier for people to get the
annotations right/better when copying from U-Boot or not.  But if you
do, you could change your standard copyright header to include the
project's name.  Something like:

	/*
	 * (C) Copyright bla blub
	 *
	 * This file is part of das U-Boot, a versatile boot loader for
	 * many platforms.  U-Boot is free software ...
	 * ...
	 */

This doesn't help for the commit logs though.

> As I wrote before in my message to JC, I consider this an accident,
> i. e. rather ignorance than intention.  However, I would be seriously
> disappointed if such things should happen again.
I don't speak for barebox in general or Sascha or Pengutronix or
Jean-Christophe, but I think you cannot expect this to happen never ever
again.  I think the best you can achieve here is that the barebox
contributers get more aware of these issues and try to get it done
better in the future.

(Note, there is no offence intended in the whole mail.)

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Thu Oct  7 04:06:46 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 Oct 2010 10:06:46 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101006135644.8D7051539A0@gemini.denx.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101006072749.GR28242@pengutronix.de>
	<20101006135644.8D7051539A0@gemini.denx.de>
Message-ID: <20101007080646.GB28242@pengutronix.de>

On Wed, Oct 06, 2010 at 03:56:44PM +0200, Wolfgang Denk wrote:
> Dear Sascha,
> 
> In message <20101006072749.GR28242 at pengutronix.de> you wrote:
> >
> > > We all have been working long enough in free and open source software
> > > projects that I can assume you are well aware of the basic principles
> > > of open source software licensing and the requirement to attribute
> > > code to its original authors.
> >
> > Does that mean U-Boot has credits to all the original mtd authors when
> > updating U-Boots mtd support to a newer kernel? /me is digging in the
> > archives; no, it has not. Does that mean with
> 
> We try hard to properly attribute code to the original sources. I do
> not claim that everything in U-Boot is perfect, and if you look long
> enough (and especially far enough back into our 10+ years of
> history), you probably can find exceptions. We are trying to improve,
> and we take all hints on such topics serious.
> 
> In each and everycase, whenever someone asked us (either on the
> U-Boot mailing list or directly) about Copyright issues or similar
> topics, we always addressed these questions directly and as good as
> possible.  Please feel free to search the archives.
> 
> 
> In the specific case of MTD updates you mention here the commit
> messages (extracted with "git log drivers/mtd") contain for example:
> 
> commit 6cd752f9:
> ...
>     The check condition is similat to what is in linux/next.
> 
> commit 18b5a4b4:
> ...
>     This makes it similar to what is in the kernel NAND driver.
> 
> commit aad4a28b:
> ...
>     This was originally part of Thomas Gleixner's patch for
>     adding support for 4KiB pages.
>     This is not part of the U-Boot NAND driver so updating the
>     driver with this to sync up with the kernel NAND driver.
> 
> commit 4f41e7ea:
> ...
>     This patch updates the "chip_shift" calculation in the
>     NAND driver. This is being done to sync up the NAND driver with
>     the kernel NAND driver.
> 
> commit aaa8eec5:
> ...
>     This patch adds support for NANDs greater than 2 GB.
>     Patch is based on the MTD NAND driver in the kernel.
> 
> commit 154b5484:
> ...
>     Update chipselect handling in davinci_nand.c so that it can
>     handle 2 GByte chips the same way Linux does:  as one device,
> 
> commit 8d2effea:
> ...
>     This patch brings the U-Boot MTD infrastructure in sync with the current
>     Linux MTD version (2.6.30-rc3). Biggest change is the 64bit device size
>     support and a resync of the mtdpart.c file which has seen multiple fixes
>     meanwhile.
> 
> commit c45912d8:
> ...
>     NAND: sync with 2.6.27
> 
>     This brings the core NAND code up to date with the Linux kernel.
> 
> commit cfa460ad:
> ...
>     Update MTD to that of Linux 2.6.22.1
> 
>     A lot changed in the Linux MTD code, since it was last ported from
>     Linux to U-Boot. This patch takes U-Boot NAND support to the level
>     of Linux 2.6.22.1 and will enable support for very large NAND devices
> 
> etc.
> 
> As you can see, we try to document where such code is coming from.
> 
> 
> > 9b7076229ec6a958bd835ab70745f7676297ce82 Ilya Yanok is the original
> > author of jffs2 summary support? No, it's the same in the Linux kernel.
> 
> No, he is not. Yes, you are right, proper attibution is missing in
> this commit, too.  Such cases can happen, even with sevral people
> reviewing the submitted patches.
> 
> But as you can see from the many examples above we at least _try_ to
> be careful about code atributions and copyrights.
> 
> 
> > Does that mean you are the original author of include/linux/list.h in
> > 700a0c648df72f2c8e0589c0d0470b5ffd7cab7b? Obviously not.
> 
> Ah, you have to go back to an example from 5 years ago? At the time
> of that patch, the whole git project was just a mere 4 months old,
> and git version control had been used for the Linux kernel for just a
> very few weeks. There was no tradition to have Signed-off-by: lines
> yet, etc.  Many things were far from perfect, then.
> 
> But even then, the first line of the commit message reads:
> 
> 	Add common (with Linux) MTD partition scheme and ...
> 
> The wording "common (with Linux)" may not be really good either, but
> at least it's a pretty clear hint. And the file in question is
> located in include/linux/ , which also carries a certain meaning.
> 
> We have learned our lessons since then.
> 
> And if someone points out errors in our processes, we are answerable
> for our mistakes and try to improve.
> 
> 
> > Please lets go not down that road, it leads to nowhere.
> >
> > We obviously copy code from other projects like U-Boot and the kernel
> > and we do our best to keep the copyrights intact, but we can only do
> > this on a per file base, not on a per commit base. That said,
> 
> Please explain why it should be impossible in a commit message to say
> that the hundreds of lines of code you add were not written by the
> signees, but taken from somewhare else?  In the examples I listed one
> could even give the corresponding git commit ID from the U-Boot repo,
> for example:
> 
> 0ceafe1  Replace direct header access with the API routines
> ...
> 	Copied from U-Boot commit b97a2a0
> 
> Do you think such a short hint cannot be done?

We can (and actually I prefered Jean-Christophe had done it) add a
hint in the commit log saying that the code is derived from U-Boot,
but I will not dig through the U-Boot commit log to see who actually
made a commit looking similar to a barebox commit, and I do not expect
anyone to do so.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From wd at denx.de  Thu Oct  7 04:08:10 2010
From: wd at denx.de (Wolfgang Denk)
Date: Thu, 07 Oct 2010 10:08:10 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101007073842.GP29673@pengutronix.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101006072749.GR28242@pengutronix.de>
	<20101006135644.8D7051539A0@gemini.denx.de>
	<20101007073842.GP29673@pengutronix.de>
Message-ID: <20101007080810.EFDC4153A7E@gemini.denx.de>

Dear Uwe,

In message <20101007073842.GP29673 at pengutronix.de> you wrote:
> 
> I really wonder why you care about the commit log.  I would care more
> about the copyright statements in the code.  (Nevertheless I consider it
> correct and fair to attribute in the commit log where the code is taken
> from.)

The introduction of the Signed-off-by: system to the Linux kernel has
been a significant improvement to make the origin of each and every
line of code clear, independent of the copyright statements which
quite often only list the original authors, even if the current file
does not contain much of the original code any more.

I think it i quite instructive to re-read the "12) Sign your work"
section of the Linux kernel's "SubmittingPatches" document. I think
our situation is best covered by the notes to back-porters there:

|  Special note to back-porters: It seems to be a common and useful practise
|  to insert an indication of the origin of a patch at the top of the commit
|  message (just after the subject line) to facilitate tracking. For instance,
|  here's what we see in 2.6-stable :
|  
|      Date:   Tue May 13 19:10:30 2008 +0000
|  
|          SCSI: libiscsi regression in 2.6.25: fix nop timer handling
|  
|          commit 4cf1043593db6a337f10e006c23c69e5fc93e722 upstream
|  
|  And here's what appears in 2.4 :
|  
|      Date:   Tue May 13 22:12:27 2008 +0200
|  
|          wireless, airo: waitbusy() won't delay
|  
|          [backport of 2.6 commit b7acbdfbd1f277c1eb23f344f899cfa4cd0bf36a]
|  
|  Whatever the format, this information provides a valuable help to people
|  tracking your trees, and to people trying to trouble-shoot bugs in your
|  tree.

Note that this is not only a topic from the point of code
attribution, but also from the point of bug tracking and quality
insurance.  I consider it a good thing in general.  I definitely
want to have this in U-Boot myself.


> I don't know if you want to make it easier for people to get the
> annotations right/better when copying from U-Boot or not.  But if you
> do, you could change your standard copyright header to include the
> project's name.  Something like:

Hm... we could do that, of course. But what exactly would it help or
change?  This is not done in Linux, either...

> I don't speak for barebox in general or Sascha or Pengutronix or
> Jean-Christophe, but I think you cannot expect this to happen never ever
> again.  I think the best you can achieve here is that the barebox
> contributers get more aware of these issues and try to get it done
> better in the future.

Nobody is perfect.  I am well aware of that, including my own
deficiencies and that of the U-Boot project.

> (Note, there is no offence intended in the whole mail.)

None taken.

Thanks.

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"What is wanted is not the will to believe, but the will to find out,
which is the exact opposite." - Bertrand Russell, _Sceptical_Essays_,
1928


From u.kleine-koenig at pengutronix.de  Thu Oct  7 04:37:02 2010
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Thu, 7 Oct 2010 10:37:02 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101007080810.EFDC4153A7E@gemini.denx.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101006072749.GR28242@pengutronix.de>
	<20101006135644.8D7051539A0@gemini.denx.de>
	<20101007073842.GP29673@pengutronix.de>
	<20101007080810.EFDC4153A7E@gemini.denx.de>
Message-ID: <20101007083702.GQ29673@pengutronix.de>

Hi Wolfgang,

On Thu, Oct 07, 2010 at 10:08:10AM +0200, Wolfgang Denk wrote:
> In message <20101007073842.GP29673 at pengutronix.de> you wrote:
> > 
> > I really wonder why you care about the commit log.  I would care more
> > about the copyright statements in the code.  (Nevertheless I consider it
> > correct and fair to attribute in the commit log where the code is taken
> > from.)
> 
> The introduction of the Signed-off-by: system to the Linux kernel has
> been a significant improvement to make the origin of each and every
> line of code clear, independent of the copyright statements which
> quite often only list the original authors, even if the current file
> does not contain much of the original code any more.
Yep, it's a hard job to keep copyright statements up to date (and
sensible).  Updating the in-file statements is the best thing the
barebox people can do now.
 
> I think it i quite instructive to re-read the "12) Sign your work"
> section of the Linux kernel's "SubmittingPatches" document. I think
> our situation is best covered by the notes to back-porters there:
> 
> |  Special note to back-porters: It seems to be a common and useful practise
> |  to insert an indication of the origin of a patch at the top of the commit
> |  message (just after the subject line) to facilitate tracking. For instance,
> |  here's what we see in 2.6-stable :
> |  
> |      Date:   Tue May 13 19:10:30 2008 +0000
> |  
> |          SCSI: libiscsi regression in 2.6.25: fix nop timer handling
> |  
> |          commit 4cf1043593db6a337f10e006c23c69e5fc93e722 upstream
> |  
> |  And here's what appears in 2.4 :
> |  
> |      Date:   Tue May 13 22:12:27 2008 +0200
> |  
> |          wireless, airo: waitbusy() won't delay
> |  
> |          [backport of 2.6 commit b7acbdfbd1f277c1eb23f344f899cfa4cd0bf36a]
> |  
> |  Whatever the format, this information provides a valuable help to people
> |  tracking your trees, and to people trying to trouble-shoot bugs in your
> |  tree.
> 
> Note that this is not only a topic from the point of code
> attribution, but also from the point of bug tracking and quality
> insurance.  I consider it a good thing in general.  I definitely
> want to have this in U-Boot myself.
full ack.  But the impression I got on your first mails is not that you
care much about bug tracking and quality assurance in barebox.  I
thought it's more about missing fame for U-Boot and it's contributors.

And it needs an adaption if you copy code that was added and changed by
several commits.  Then I would not add the "original" Sobs to my commit
log, only reference the HEAD commit where the code is taken from.)

> > I don't know if you want to make it easier for people to get the
> > annotations right/better when copying from U-Boot or not.  But if you
> > do, you could change your standard copyright header to include the
> > project's name.  Something like:
> 
> Hm... we could do that, of course. But what exactly would it help or
> change?
If Joe Developer copies a file from U-Boot to barebox, he automatically
get's the in-file attribution right/better.

>          This is not done in Linux, either...
So you scruple to make U-Boot better than the Linux kernel? ;-)

In the section "How to Apply These Terms to Your New Programs" of the
GPL-2 it's even suggested to add 

	<one line to give the program's name and a brief idea of what it does.>

I prefer my suggestion, but YMMV.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From wd at denx.de  Thu Oct  7 04:45:30 2010
From: wd at denx.de (Wolfgang Denk)
Date: Thu, 07 Oct 2010 10:45:30 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101007080646.GB28242@pengutronix.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101006072749.GR28242@pengutronix.de>
	<20101006135644.8D7051539A0@gemini.denx.de>
	<20101007080646.GB28242@pengutronix.de>
Message-ID: <20101007084530.82D8E153A7E@gemini.denx.de>

Dear Sascha,

In message <20101007080646.GB28242 at pengutronix.de> you wrote:
>
> > Do you think such a short hint cannot be done?
> 
> We can (and actually I prefered Jean-Christophe had done it) add a
> hint in the commit log saying that the code is derived from U-Boot,
> but I will not dig through the U-Boot commit log to see who actually
> made a commit looking similar to a barebox commit, and I do not expect
> anyone to do so.

It is trivial to find the commits that added the lines you are
copying from - just run "git blame" on that file.

Thanks.

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
All he had was nothing, but that was something, and now it  had  been
taken away.                             - Terry Pratchett, _Sourcery_


From jbe at pengutronix.de  Thu Oct  7 08:28:52 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 14:28:52 +0200
Subject: [RFC] Add MMC support to barebox
Message-ID: <1286454535-695-1-git-send-email-jbe@pengutronix.de>

This patch is based on some work Sascha made already. I tried to bring in some
light into the MCI framework routines as they are based on code from another
project. Bear with me, if I didn't add useful comments all over the code. I
just wasn't able to understand what happen... If someone has more knowledge
about MCI cards, please take a look at the FIXME/TODOs and make me understand
why the code does what it does.

There is no regular user, yet. The first platform (S3C2440 based) I did the
tests on, is not part of barebox (and will not) and the other platfrom (i.MX23
ChumbOne) is not yet part of barebox. But will coming soon.

Regards,
Juergen



From jbe at pengutronix.de  Thu Oct  7 08:28:55 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 14:28:55 +0200
Subject: [PATCH 3/3] Add S3C2440 MCI card support
In-Reply-To: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
References: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286454535-695-4-git-send-email-jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>

Adding MCI card support for S3C2440 CPUs. This is for reference only, as there
is currently no user in the barebox tree. Maybe one with access to the A9M2440
development kit can check it on his/her system.
Checked here with my own S3C2440 based system which is not in the barebox tree.

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
---
 arch/arm/mach-s3c24xx/include/mach/mci.h |   42 ++
 drivers/mci/Kconfig                      |    8 +-
 drivers/mci/Makefile                     |    1 +
 drivers/mci/s3c.c                        |  799 ++++++++++++++++++++++++++++++
 4 files changed, 849 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-s3c24xx/include/mach/mci.h
 create mode 100644 drivers/mci/s3c.c

diff --git a/arch/arm/mach-s3c24xx/include/mach/mci.h b/arch/arm/mach-s3c24xx/include/mach/mci.h
new file mode 100644
index 0000000..fc3a4d6
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/mci.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MACH_MMC_H_
+#define __MACH_MMC_H_
+
+struct s3c_mci_platform_data {
+	unsigned caps;	/**< supported operating modes (MMC_MODE_*) */
+	unsigned voltages; /**< supported voltage range (MMC_VDD_*) */
+	unsigned f_min;	/**< min operating frequency in Hz (0 -> no limit) */
+	unsigned f_max;	/**< max operating frequency in Hz (0 -> no limit) */
+	/* TODO */
+	/* function to modify the voltage */
+	/* function to switch the voltage */
+	/* function to detect the presence of a SD card in the socket */
+	unsigned gpio_detect;
+	unsigned detect_invert;
+};
+
+#endif /* __MACH_MMC_H_ */
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index d67e383..644c0a3 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -34,5 +34,11 @@ config MCI_STM378X
 	  Enable this entry to add support to read and write SD cards on a
 	  i.MX23 based system.
 
-endif
+config MCI_S3C
+	bool "S3C"
+	depends on ARCH_S3C24xx
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  Samsung S3C24xx based system.
 
+endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index e5e19b0..be18446 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_MCI)	+= mci-core.o
 obj-$(CONFIG_MCI_STM378X) += stm378x.o
+obj-$(CONFIG_MCI_S3C) += s3c.o
diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
new file mode 100644
index 0000000..d164834
--- /dev/null
+++ b/drivers/mci/s3c.c
@@ -0,0 +1,799 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert <juergen at kreuzholzen.de>
+ *
+ * This code is based on various Linux and u-boot sources:
+ *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk at maintech.de>
+ *  Copyright (C) 2008 Simtec Electronics <ben-linux at fluff.org>
+ *  (C) Copyright 2006 by OpenMoko, Inc.
+ *  Author: Harald Welte <laforge at openmoko.org>
+ *  based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
+ *  (C) 2005-2005 Thomas Kleffel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * @file
+ * @brief MCI card host interface for S3C2440 CPU
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <mci.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+#include <mach/mci.h>
+#include <mach/s3c24xx-generic.h>
+#include <mach/s3c24x0-iomap.h>
+
+#define SDICON 0x0
+# define SDICON_SDRESET (1 << 8)
+# define SDICON_MMCCLOCK (1 << 5) /* this is a clock type SD or MMC style WTF? */
+# define SDICON_BYTEORDER (1 << 4)
+# define SDICON_SDIOIRQ (1 << 3)
+# define SDICON_RWAITEN (1 << 2)
+# define SDICON_FIFORESET (1 << 1) /* reserved bit on 2440 ????? */
+# define SDICON_CLKEN (1 << 0) /* enable/disable external clock */
+
+#define SDIPRE 0x4
+
+#define SDICMDARG 0x8
+
+#define SDICMDCON 0xc
+# define SDICMDCON_ABORT (1 << 12)
+# define SDICMDCON_WITHDATA (1 << 11)
+# define SDICMDCON_LONGRSP (1 << 10)
+# define SDICMDCON_WAITRSP (1 << 9)
+# define SDICMDCON_CMDSTART (1 << 8)
+# define SDICMDCON_SENDERHOST (1 << 6)
+# define SDICMDCON_INDEX (0x3f)
+
+#define SDICMDSTAT 0x10
+# define SDICMDSTAT_CRCFAIL (1 << 12)
+# define SDICMDSTAT_CMDSENT (1 << 11)
+# define SDICMDSTAT_CMDTIMEOUT (1 << 10)
+# define SDICMDSTAT_RSPFIN (1 << 9)
+# define SDICMDSTAT_XFERING (1 << 8)
+# define SDICMDSTAT_INDEX (0xff)
+
+#define SDIRSP0 0x14
+#define SDIRSP1 0x18
+#define SDIRSP2 0x1C
+#define SDIRSP3 0x20
+
+#define SDITIMER 0x24
+#define SDIBSIZE 0x28
+
+#define SDIDCON 0x2c
+# define SDIDCON_DS_BYTE (0 << 22)
+# define SDIDCON_DS_HALFWORD (1 << 22)
+# define SDIDCON_DS_WORD (2 << 22)
+# define SDIDCON_IRQPERIOD (1 << 21)
+# define SDIDCON_TXAFTERRESP (1 << 20)
+# define SDIDCON_RXAFTERCMD (1 << 19)
+# define SDIDCON_BUSYAFTERCMD (1 << 18)
+# define SDIDCON_BLOCKMODE (1 << 17)
+# define SDIDCON_WIDEBUS (1 << 16)
+# define SDIDCON_DMAEN (1 << 15)
+# define SDIDCON_STOP (0 << 14)
+# define SDIDCON_DATSTART (1 << 14)
+# define SDIDCON_DATMODE (3 << 12)
+# define SDIDCON_BLKNUM (0xfff)
+# define SDIDCON_XFER_READY    (0 << 12)
+# define SDIDCON_XFER_CHKSTART (1 << 12)
+# define SDIDCON_XFER_RXSTART  (2 << 12)
+# define SDIDCON_XFER_TXSTART  (3 << 12)
+
+#define SDIDCNT 0x30
+# define SDIDCNT_BLKNUM_SHIFT 12
+
+#define SDIDSTA 0x34
+# define SDIDSTA_RDYWAITREQ (1 << 10)
+# define SDIDSTA_SDIOIRQDETECT (1 << 9)
+# define SDIDSTA_FIFOFAIL (1 << 8) /* reserved on 2440 */
+# define SDIDSTA_CRCFAIL (1 << 7)
+# define SDIDSTA_RXCRCFAIL (1 << 6)
+# define SDIDSTA_DATATIMEOUT (1 << 5)
+# define SDIDSTA_XFERFINISH (1 << 4)
+# define SDIDSTA_BUSYFINISH (1 << 3)
+# define SDIDSTA_SBITERR (1 << 2) /* reserved on 2410a/2440 */
+# define SDIDSTA_TXDATAON (1 << 1)
+# define SDIDSTA_RXDATAON (1 << 0)
+
+#define SDIFSTA 0x38
+# define SDIFSTA_FIFORESET (1<<16)
+# define SDIFSTA_FIFOFAIL (3<<14)  /* 3 is correct (2 bits) */
+# define SDIFSTA_TFDET (1<<13)
+# define SDIFSTA_RFDET (1<<12)
+# define SDIFSTA_TFHALF (1<<11)
+# define SDIFSTA_TFEMPTY (1<<10)
+# define SDIFSTA_RFLAST (1<<9)
+# define SDIFSTA_RFFULL (1<<8)
+# define SDIFSTA_RFHALF (1<<7)
+# define SDIFSTA_COUNTMASK (0x7f)
+
+#define SDIIMSK 0x3C
+# define SDIIMSK_RESPONSECRC    (1<<17)
+# define SDIIMSK_CMDSENT        (1<<16)
+# define SDIIMSK_CMDTIMEOUT     (1<<15)
+# define SDIIMSK_RESPONSEND     (1<<14)
+# define SDIIMSK_READWAIT       (1<<13)
+# define SDIIMSK_SDIOIRQ        (1<<12)
+# define SDIIMSK_FIFOFAIL       (1<<11)
+# define SDIIMSK_CRCSTATUS      (1<<10)
+# define SDIIMSK_DATACRC        (1<<9)
+# define SDIIMSK_DATATIMEOUT    (1<<8)
+# define SDIIMSK_DATAFINISH     (1<<7)
+# define SDIIMSK_BUSYFINISH     (1<<6)
+# define SDIIMSK_SBITERR        (1<<5) /* reserved 2440/2410a */
+# define SDIIMSK_TXFIFOHALF     (1<<4)
+# define SDIIMSK_TXFIFOEMPTY    (1<<3)
+# define SDIIMSK_RXFIFOLAST     (1<<2)
+# define SDIIMSK_RXFIFOFULL     (1<<1)
+# define SDIIMSK_RXFIFOHALF     (1<<0)
+
+#define SDIDATA 0x40
+
+#define CLOCKRATE_MIN (1 * 1000 * 1000)
+#define CLOCKRATE_MAX (480 * 1000 * 1000)
+
+struct s3c_mci_host {
+	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
+	unsigned	clock;	/* current clock in Hz */
+	unsigned	data_size;	/* data transfer in bytes */
+};
+
+/*
+ * There is only one host MCI hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct s3c_mci_host host_data;
+
+/**
+ * Finish a request
+ * @param hw_dev Host interface instance
+ *
+ * Just a little bit paranoia.
+ */
+static void s3c_finish_request(struct device_d *hw_dev)
+{
+	/* TODO ensure the engines are stopped */
+}
+
+/* TODO GPIO feature is required for this architecture */
+static unsigned gpio_get_value(unsigned val)
+{
+	return 0;
+}
+
+/**
+ * Detect if a card is plugged in
+ * @param hw_dev Host interface instance
+ * @return 0 if a card is plugged in
+ *
+ * Note: If there is no GPIO registered to detect if a card is present, we
+ * assume a card _is_ present.
+ */
+static int s3c_mci_card_present(struct device_d *hw_dev)
+{
+	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)GET_HOST_PDATA(hw_dev);
+	int ret;
+
+	if (pd->gpio_detect == 0)
+		return 0;	/* assume the card is present */
+
+	ret = gpio_get_value(pd->gpio_detect) ? 0 : 1;
+	return ret ^ pd->detect_invert;
+}
+
+/**
+ * Setup a new clock frequency on this MCI bus
+ * @param hw_dev Host interface instance
+ * @param nc New clock value in Hz (can be 0)
+ * @return New clock value (may differ from 'nc')
+ */
+static unsigned s3c_setup_clock_speed(struct device_d *hw_dev, unsigned nc)
+{
+	unsigned clock;
+	uint32_t mci_psc;
+
+	if (nc == 0)
+		return 0;
+
+	clock = s3c24xx_get_pclk();
+	/* Calculate the required prescaler value to get the requested frequency */
+	mci_psc = (clock + (nc >> 2)) / nc;
+
+	if (mci_psc > 256) {
+		mci_psc = 256;
+		pr_warning("SD/MMC clock might be too high!\n");
+	}
+
+	writel(mci_psc - 1, hw_dev->map_base + SDIPRE);
+
+	return clock / mci_psc;
+}
+
+/**
+ * Reset the MCI engine (the hard way)
+ * @param hw_dev Host interface instance
+ *
+ * This will reset everything in all registers of this unit!
+ */
+static void s3c_mci_reset(struct device_d *hw_dev)
+{
+	/* reset the hardware */
+	writel(SDICON_SDRESET, hw_dev->map_base + SDICON);
+	/* wait until reset it finished */
+	while (readl(hw_dev->map_base + SDICON) & SDICON_SDRESET)
+		;
+}
+
+/**
+ * Initialize hard and software
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance (might be NULL)
+ */
+static int s3c_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
+
+	s3c_mci_reset(hw_dev);
+
+	/* restore last settings */
+	host_data->clock = s3c_setup_clock_speed(hw_dev, host_data->clock);
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+	writel(SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
+	writel(512, hw_dev->map_base + SDIBSIZE);
+
+	return 0;
+}
+
+/**
+ * Prepare engine's bits for the next command transfer
+ * @param cmd_flags MCI's command flags
+ * @param data_flags MCI's data flags
+ * @return Register bits for this transfer
+ */
+static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned data_flags)
+{
+	uint32_t reg;
+
+	/* source (=host) */
+	reg = SDICMDCON_SENDERHOST;
+
+	if (cmd_flags & MMC_RSP_PRESENT) {
+		reg |= SDICMDCON_WAITRSP;
+		pr_debug("Command with response\n");
+	}
+	if (cmd_flags & MMC_RSP_136) {
+		reg |= SDICMDCON_LONGRSP;
+		pr_debug("Command with long response\n");
+	}
+	if (cmd_flags & MMC_RSP_CRC)
+		; /* FIXME */
+	if (cmd_flags & MMC_RSP_BUSY)
+		; /* FIXME */
+	if (cmd_flags & MMC_RSP_OPCODE)
+		; /* FIXME */
+	if (data_flags != 0)
+		reg |= SDICMDCON_WITHDATA;
+
+	return reg;
+}
+
+/**
+ * Prepare engine's bits for the next data transfer
+ * @param hw_dev Host interface device instance
+ * @param data_flags MCI's data flags
+ * @return Register bits for this transfer
+ */
+static uint32_t s3c_prepare_data_setup(struct device_d *hw_dev, unsigned data_flags)
+{
+	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
+	uint32_t reg = SDIDCON_BLOCKMODE;	/* block mode only is supported */
+
+	if (host_data->bus_width == 1)
+		reg |= SDIDCON_WIDEBUS;
+
+	/* enable any kind of data transfers on demand only */
+	if (data_flags & MMC_DATA_WRITE)
+		reg |= SDIDCON_TXAFTERRESP | SDIDCON_XFER_TXSTART;
+
+	if (data_flags & MMC_DATA_READ)
+		reg |= SDIDCON_RXAFTERCMD | SDIDCON_XFER_RXSTART;
+
+	/* TODO: Support more than the 2440 CPU */
+	reg |= SDIDCON_DS_WORD | SDIDCON_DATSTART;
+
+	return reg;
+}
+
+/**
+ * Terminate a current running transfer
+ * @param hw_dev Host interface device instance
+ * @return 0 on success
+ *
+ * Note: Try to stop a running transfer. This should not happen, as all
+ * transfers must complete in this driver. But who knows... ;-)
+ */
+static int s3c_terminate_transfer(struct device_d *hw_dev)
+{
+	unsigned stoptries = 3;
+
+	while (readl(hw_dev->map_base + SDIDSTA) & (SDIDSTA_TXDATAON | SDIDSTA_RXDATAON)) {
+		pr_debug("Transfer still in progress.\n");
+
+		writel(SDIDCON_STOP, hw_dev->map_base + SDIDCON);
+		s3c_mci_initialize(hw_dev, NULL);
+
+		if ((stoptries--) == 0) {
+			pr_warning("Cannot stop the engine!\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Setup registers for data transfer
+ * @param hw_dev Host interface device instance
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_prepare_data_transfer(struct device_d *hw_dev, struct mci_data *data)
+{
+	uint32_t reg;
+
+	writel(data->blocksize, hw_dev->map_base + SDIBSIZE);
+	reg = s3c_prepare_data_setup(hw_dev, data->flags);
+	reg |= data->blocks & SDIDCON_BLKNUM;
+	writel(reg, hw_dev->map_base + SDIDCON);
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+
+	return 0;
+}
+
+/**
+ * Send a command and receive the response
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_send_command(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	uint32_t reg, t1;
+	int rc;
+
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+
+	/* setup argument */
+	writel(cmd->cmdarg, hw_dev->map_base + SDICMDARG);
+
+	/* setup command and transfer characteristic */
+	reg = s3c_prepare_command_setup(cmd->resp_type, data != NULL ? data->flags : 0);
+	reg |= cmd->cmdidx & SDICMDCON_INDEX;
+
+	/* run the command right now */
+	writel(reg | SDICMDCON_CMDSTART, hw_dev->map_base + SDICMDCON);
+	t1 = readl(hw_dev->map_base + SDICMDSTAT);
+	/* wait until command is done */
+	while (1) {
+		reg = readl(hw_dev->map_base + SDICMDSTAT);
+		/* done? */
+		if (cmd->resp_type & MMC_RSP_PRESENT) {
+			if (reg & SDICMDSTAT_RSPFIN) {
+				writel(SDICMDSTAT_RSPFIN, hw_dev->map_base + SDICMDSTAT); /* required??? */
+				rc = 0;
+				break;
+			}
+		} else {
+			if (reg & SDICMDSTAT_CMDSENT) {
+					writel(SDICMDSTAT_CMDSENT, hw_dev->map_base + SDICMDSTAT); /* required??? */
+					rc = 0;
+					break;
+			}
+		}
+		/* timeout? */
+		if (reg & SDICMDSTAT_CMDTIMEOUT) {
+			writel(SDICMDSTAT_CMDTIMEOUT, hw_dev->map_base + SDICMDSTAT); /* required??? */
+			rc = -ETIMEDOUT;
+			break;
+		}
+	}
+
+	if ((rc == 0) && (cmd->resp_type & MMC_RSP_PRESENT)) {
+		cmd->response[0] = readl(hw_dev->map_base + SDIRSP0);
+		cmd->response[1] = readl(hw_dev->map_base + SDIRSP1);
+		cmd->response[2] = readl(hw_dev->map_base + SDIRSP2);
+		cmd->response[3] = readl(hw_dev->map_base + SDIRSP3);
+	}
+	/* do not disable the clock! */
+	return rc;
+}
+
+/**
+ * Clear major registers prior a new transaction
+ * @param hw_dev Host interface device instance
+ * @return 0 on success
+ *
+ * FIFO clear is only necessary on 2440, but doesn't hurt on 2410
+ */
+static int s3c_prepare_engine(struct device_d *hw_dev)
+{
+	int rc;
+
+	rc = s3c_terminate_transfer(hw_dev);
+	if (rc != 0)
+		return rc;
+
+	writel(-1, hw_dev->map_base + SDICMDSTAT);
+	writel(-1, hw_dev->map_base + SDIDSTA);
+	writel(-1, hw_dev->map_base + SDIFSTA);
+
+	return 0;
+}
+
+/**
+ * Handle MCI commands without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @return 0 on success
+ *
+ * This functions handles the following MCI commands:
+ * - "broadcast command (BC)" without a response
+ * - "broadcast commands with response (BCR)"
+ * - "addressed command (AC)" with response, but without data
+ */
+static int s3c_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	int rc;
+
+	rc = s3c_prepare_engine(hw_dev);
+	if (rc != 0)
+		return 0;
+
+	return s3c_send_command(hw_dev, cmd, NULL);
+}
+
+/**
+ * Read one block of data from the FIFO
+ * @param hw_dev Host interface device instance
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_mci_read_block(struct device_d *hw_dev, struct mci_data *data)
+{
+	uint32_t *p;
+	unsigned cnt, data_size;
+
+#define READ_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_RXCRCFAIL | SDIDSTA_DATATIMEOUT)
+
+	p = (uint32_t*)data->dest;
+	data_size = data->blocksize * data->blocks;
+
+	while (data_size > 0) {
+
+		/* serious error? */
+		if (readl(hw_dev->map_base + SDIDSTA) & READ_REASON_TO_FAIL) {
+			pr_err("Failed while reading data\n");
+			return -EIO;
+		}
+
+		/* now check the FIFO status */
+		if (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_FIFOFAIL) {
+			pr_err("Data loss due to FIFO overflow when reading\n");
+			return -EIO;
+		}
+
+		/* we only want to read full words */
+		cnt = (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) >> 2;
+
+		/* read one chunk of data from the FIFO */
+		while (cnt--) {
+			*p = readl(hw_dev->map_base + SDIDATA);
+			p++;
+			if (data_size >= 4)
+				data_size -= 4;
+			else {
+				data_size = 0;
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Write one block of data into the FIFO
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ *
+ * We must ensure data in the FIFO when the command phase changes into the
+ * data phase. To ensure this, the FIFO gets filled first, then the command.
+ */
+static int s3c_mci_write_block(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	const uint32_t *p = (const uint32_t*)data->src;
+	unsigned cnt, data_size;
+	uint32_t reg;
+
+#define WRITE_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_DATATIMEOUT)
+
+	data_size = data->blocksize * data->blocks;
+	/*
+	 * With high clock rates we must fill the FIFO as early as possible
+	 * Its size is 16 words. We assume its empty, when this function is
+	 * entered.
+	 */
+	cnt = 16;
+	while (cnt--) {
+		writel(*p, hw_dev->map_base + SDIDATA);
+		p++;
+		if (data_size >= 4)
+			data_size -= 4;
+		else {
+			data_size = 0;
+			break;
+		}
+	}
+
+	/* data is now in place and waits for transmitt. Start the command right now */
+	s3c_send_command(hw_dev, cmd, data);
+
+	if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
+		pr_err("Command fails immediatly due to FIFO underrun when writing %08X\n", reg);
+		return -EIO;
+	}
+
+	while (data_size > 0) {
+
+		if (readl(hw_dev->map_base + SDIDSTA) & WRITE_REASON_TO_FAIL) {
+			pr_err("Failed writing data\n");
+			return -EIO;
+		}
+
+		/* now check the FIFO status */
+		if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
+			pr_err("Data loss due to FIFO underrun when writing %08X\n", reg);
+			return -EIO;
+		}
+
+		/* we only want to write full words */
+		cnt = 16 - (((readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) + 3) >> 2);
+
+		/* fill the FIFO if it has free entries */
+		while (cnt--) {
+			writel(*p, hw_dev->map_base + SDIDATA);
+			p++;
+			if (data_size >= 4)
+				data_size -= 4;
+			else {
+				data_size = 0;
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Handle MCI commands with or without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+*/
+static int s3c_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	int rc;
+
+	rc = s3c_prepare_engine(hw_dev);
+	if (rc != 0)
+		return rc;
+
+	rc = s3c_prepare_data_transfer(hw_dev, data);
+	if (rc != 0)
+		return rc;
+
+	if (data->flags & MMC_DATA_READ) {
+		s3c_send_command(hw_dev, cmd, data);
+		rc = s3c_mci_read_block(hw_dev, data);
+		if (rc == 0) {
+			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
+				;
+		} else
+			s3c_terminate_transfer(hw_dev);
+	}
+
+	if (data->flags & MMC_DATA_WRITE) {
+		rc = s3c_mci_write_block(hw_dev, cmd, data);
+		if (rc == 0) {
+			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
+				;
+		} else
+			s3c_terminate_transfer(hw_dev);
+	}
+	writel(0, hw_dev->map_base + SDIDCON);
+
+	return rc;
+}
+
+/* ------------------------- MCI API -------------------------------------- */
+
+/**
+ * Keep the attached MMC/SD unit in a well know state
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative value else
+ */
+static int mci_reset(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	return s3c_mci_initialize(hw_dev, mci_dev);
+}
+
+/**
+ * Process one command to the MCI card
+ * @param hw_dev Host interface instance
+ * @param cmd The command to process
+ * @param data The data to handle in the command (can be NULL)
+ * @return 0 on success, negative value else
+ */
+static int mci_request(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	int rc;
+
+	/* enable clock */
+	writel(readl(hw_dev->map_base + SDICON) | SDICON_CLKEN, hw_dev->map_base + SDICON);
+
+	if ((cmd->resp_type == 0) || (data == NULL))
+		rc = s3c_mci_std_cmds(hw_dev, cmd);
+	else
+		rc = s3c_mci_adtc(hw_dev, cmd, data);	/* with response and data */
+
+	s3c_finish_request(hw_dev);
+
+	/* disable clock */
+	writel(readl(hw_dev->map_base + SDICON) & ~SDICON_CLKEN, hw_dev->map_base + SDICON);
+	return rc;
+}
+
+/**
+ * Setup the bus width and IO speed
+ * @param hw_dev Host interface device instance
+ * @param mci_dev MCI device instance
+ * @param bus_width New bus width value (1, 4 or 8)
+ * @param clock New clock in Hz (can be '0' to disable the clock)
+ */
+static void mci_set_ios(struct device_d *hw_dev, struct device_d *mci_dev, unsigned bus_width, unsigned clock)
+{
+	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
+	struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
+	uint32_t reg;
+
+	switch (bus_width) {
+	case 8:		/* no 8 bit support, fall back to 4 bit */
+	case 4:
+		host_data->bus_width = 1;
+		mci_pdata->bus_width = 4;	/* 4 bit is possible */
+		break;
+	default:
+		host_data->bus_width = 0;
+		mci_pdata->bus_width = 1;	/* 1 bit is possible */
+		break;
+	}
+
+	reg = readl(hw_dev->map_base + SDICON);
+	if (clock) {
+		/* setup the IO clock frequency and enable it */
+		mci_pdata->clock = host_data->clock = s3c_setup_clock_speed(hw_dev, clock);
+		reg |= SDICON_CLKEN;	/* enable the clock */
+	} else {
+		reg &= ~SDICON_CLKEN;	/* disable the clock */
+		mci_pdata->clock = host_data->clock = 0;
+	}
+	writel(reg, hw_dev->map_base + SDICON);
+
+	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", mci_pdata->bus_width, mci_pdata->clock);
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+static void s3c_info(struct device_d *hw_dev)
+{
+	struct s3c_mci_host *host = (struct s3c_mci_host*)hw_dev->priv;
+	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
+
+	printf("  Bus data width: %d bit\n", host->bus_width == 1 ? 4 : 1);
+	printf("  Bus frequency: %u Hz\n", host->clock);
+	printf("   Frequency limits: ");
+	if (pd->f_min == 0)
+		printf("no lower limit ");
+	else
+		printf("%u Hz lower limit ", pd->f_min);
+	if (pd->f_max == 0)
+		printf("- no upper limit");
+	else
+		printf("- %u Hz upper limit", pd->f_max);
+	printf("\n  Card detection support: %s\n", pd->gpio_detect != 0 ? "yes" : "no");
+}
+#endif
+
+/*
+ * There is only one host MCI hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct mci_platformdata mci_pdata = {
+	.send_cmd = mci_request,
+	.set_ios = mci_set_ios,
+	.init = mci_reset,
+};
+
+static int s3c_mci_probe(struct device_d *hw_dev)
+{
+	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
+
+	/* TODO replace by the global func: enable the SDI unit clock */
+	writel(readl(S3C24X0_CLOCK_POWER_BASE + 0x0c) | 0x200,S3C24X0_CLOCK_POWER_BASE + 0x0c);
+
+	if (pd == NULL) {
+		pr_err("Missing platform data\n");
+		return -EINVAL;
+	}
+
+	hw_dev->priv = &host_data;
+	mci_pdata.hw_dev = hw_dev;
+
+	/* feed forward the platform specific values */
+	mci_pdata.voltages = pd->voltages;
+	mci_pdata.host_caps = pd->caps;
+	mci_pdata.f_min = pd->f_min == 0 ? CLOCKRATE_MIN : pd->f_min;
+	mci_pdata.f_max = pd->f_max == 0 ? CLOCKRATE_MAX : pd->f_max;
+
+	/*
+	 * Start the clock to let the engine and the card finishes its startup
+	 */
+	host_data.clock = s3c_setup_clock_speed(hw_dev, mci_pdata.f_min);
+	writel(SDICON_FIFORESET | SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
+
+	return mci_register(&mci_pdata);
+}
+
+static struct driver_d s3c_mci_driver = {
+        .name  = "s3c_mci",
+        .probe = s3c_mci_probe,
+#ifdef CONFIG_MCI_INFO
+	.info = s3c_info,
+#endif
+};
+
+static int s3c_mci_init_driver(void)
+{
+        register_driver(&s3c_mci_driver);
+        return 0;
+}
+
+device_initcall(s3c_mci_init_driver);
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 08:28:54 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 14:28:54 +0200
Subject: =?UTF-8?q?=5BPATCH=202/3=5D=20Add=20i=2EMX23=20MCI=20card=20support?=
In-Reply-To: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
References: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286454535-695-3-git-send-email-jbe@pengutronix.de>

Adding MCI card support for STM378x/i.MX23 CPUs. This is for reference only,
as this architecture is currently not part of barebox (but will coming soon).
Its tested on the i.MX23 based ChumbyOne.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/Kconfig   |    7 +
 drivers/mci/Makefile  |    1 +
 drivers/mci/stm378x.c |  687 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 695 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/stm378x.c

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 28f3283..d67e383 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -27,5 +27,12 @@ config MCI_INFO
 
 comment "--- MCI host drivers ---"
 
+config MCI_STM378X
+	bool "i.MX23"
+	depends on ARCH_STM
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  i.MX23 based system.
+
 endif
 
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index 927618f..e5e19b0 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MCI)	+= mci-core.o
+obj-$(CONFIG_MCI_STM378X) += stm378x.o
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
new file mode 100644
index 0000000..a8508a4
--- /dev/null
+++ b/drivers/mci/stm378x.c
@@ -0,0 +1,687 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe at pengutronix.de>
+ *
+ * This code is based on:
+ *
+ * Copyright (C) 2007 SigmaTel, Inc., Ioannis Kappas <ikappas at sigmatel.com>
+ *
+ * Portions copyright (C) 2003 Russell King, PXA MMCI Driver
+ * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * @file
+ * @brief MCI card host interface for i.MX23 CPU
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <mci.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <mach/imx-regs.h>
+#include <mach/mci.h>
+#include <mach/clock-imx23.h>
+
+#define CLOCKRATE_MIN (1 * 1000 * 1000)
+#define CLOCKRATE_MAX (480 * 1000 * 1000)
+
+#define HW_SSP_CTRL0 0x000
+# define SSP_CTRL0_SFTRST (1 << 31)
+# define SSP_CTRL0_CLKGATE (1 << 30)
+# define SSP_CTRL0_RUN (1 << 29)
+# define SSP_CTRL0_LOCK_CS (1 << 29)
+# define SSP_CTRL0_READ (1 << 25)
+# define SSP_CTRL0_IGNORE_CRC (1 << 26)
+# define SSP_CTRL0_DATA_XFER (1 << 24)
+# define SSP_CTRL0_BUS_WIDTH(x) (((x) & 0x3) << 22)
+# define SSP_CTRL0_WAIT_FOR_IRQ (1 << 21)
+# define SSP_CTRL0_LONG_RESP (1 << 19)
+# define SSP_CTRL0_GET_RESP (1 << 17)
+# define SSP_CTRL0_ENABLE (1 << 16)
+# define SSP_CTRL0_XFER_COUNT(x) ((x) & 0xffff)
+
+#define HW_SSP_CMD0 0x010
+# define SSP_CMD0_SLOW_CLK (1 << 22)
+# define SSP_CMD0_CONT_CLK (1 << 21)
+# define SSP_CMD0_APPEND_8CYC (1 << 20)
+# define SSP_CMD0_BLOCK_SIZE(x) (((x) & 0xf) << 16)
+# define SSP_CMD0_BLOCK_COUNT(x) (((x) & 0xff) << 8)
+# define SSP_CMD0_CMD(x) ((x) & 0xff)
+
+#define HW_SSP_CMD1 0x020
+#define HW_SSP_COMPREF 0x030
+#define HW_SSP_COMPMASK 0x040
+#define HW_SSP_TIMING 0x050
+# define SSP_TIMING_TIMEOUT_MASK (0xffff0000)
+# define SSP_TIMING_TIMEOUT(x) ((x) << 16)
+# define SSP_TIMING_CLOCK_DIVIDE(x) (((x) & 0xff) << 8)
+# define SSP_TIMING_CLOCK_RATE(x) ((x) & 0xff)
+
+#define HW_SSP_CTRL1 0x060
+# define SSP_CTRL1_POLARITY (1 << 9)
+# define SSP_CTRL1_WORD_LENGTH(x) (((x) & 0xf) << 4)
+# define SSP_CTRL1_SSP_MODE(x) ((x) & 0xf)
+
+#define HW_SSP_DATA 0x070
+#define HW_SSP_SDRESP0 0x080
+#define HW_SSP_SDRESP1 0x090
+#define HW_SSP_SDRESP2 0x0A0
+#define HW_SSP_SDRESP3 0x0B0
+
+#define HW_SSP_STATUS 0x0C0
+# define SSP_STATUS_PRESENT (1 << 31)
+# define SSP_STATUS_SD_PRESENT (1 << 29)
+# define SSP_STATUS_CARD_DETECT (1 << 28)
+# define SSP_STATUS_RESP_CRC_ERR (1 << 16)
+# define SSP_STATUS_RESP_ERR (1 << 15)
+# define SSP_STATUS_RESP_TIMEOUT (1 << 14)
+# define SSP_STATUS_DATA_CRC_ERR (1 << 13)
+# define SSP_STATUS_TIMEOUT (1 << 12)
+# define SSP_STATUS_FIFO_OVRFLW (1 << 9)
+# define SSP_STATUS_FIFO_FULL (1 << 8)
+# define SSP_STATUS_FIFO_EMPTY (1 << 5)
+# define SSP_STATUS_FIFO_UNDRFLW (1 << 4)
+# define SSP_STATUS_CMD_BUSY (1 << 3)
+# define SSP_STATUS_DATA_BUSY (1 << 2)
+# define SSP_STATUS_BUSY (1 << 0)
+# define SSP_STATUS_ERROR (SSP_STATUS_FIFO_OVRFLW | SSP_STATUS_FIFO_UNDRFLW | SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR | SSP_STATUS_RESP_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | SSP_STATUS_TIMEOUT)
+
+#define HW_SSP_DEBUG 0x100
+#define HW_SSP_VERSION 0x110
+
+struct stm_mci_host {
+	unsigned	clock;	/* current clock speed in Hz ("0" if disabled) */
+#ifdef CONFIG_MCI_INFO
+	unsigned	f_min;
+	unsigned	f_max;
+#endif
+	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
+};
+
+/**
+ * Get MCI cards response if defined for the type of command
+ * @param hw_dev Host interface device instance
+ * @param cmd Command description
+ * @return Response bytes count, -EINVAL for unsupported response types
+ */
+static int get_cards_response(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	switch (cmd->resp_type) {
+	case MMC_RSP_NONE:
+		return 0;
+
+	case MMC_RSP_R1:
+	case MMC_RSP_R1b:
+	case MMC_RSP_R3:
+		cmd->response[0] = readl(hw_dev->map_base + HW_SSP_SDRESP0);
+		return 1;
+
+	case MMC_RSP_R2:
+		cmd->response[3] = readl(hw_dev->map_base + HW_SSP_SDRESP0);
+		cmd->response[2] = readl(hw_dev->map_base + HW_SSP_SDRESP1);
+		cmd->response[1] = readl(hw_dev->map_base + HW_SSP_SDRESP2);
+		cmd->response[0] = readl(hw_dev->map_base + HW_SSP_SDRESP3);
+		return 4;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * Finish a reques to the MCI card
+ * @param hw_dev Host interface device instance
+ *
+ * Can also stop the clock to save power
+ */
+static void finish_request(struct device_d *hw_dev)
+{
+	/* stop the engines (normaly already done) */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+}
+
+/**
+ * Check if the last command failed and if, why it failed
+ * @param status HW_SSP_STATUS's content
+ * @return 0 if no error, negative values else
+ */
+static int get_cmd_error(unsigned status)
+{
+	if (status & SSP_STATUS_ERROR)
+		pr_debug("Status Reg reports %08X\n", status);
+
+	if (status & SSP_STATUS_TIMEOUT) {
+		pr_debug("CMD timeout\n");
+		return -ETIMEDOUT;
+	} else if (status & SSP_STATUS_RESP_TIMEOUT) {
+		pr_debug("RESP timeout\n");
+		return -ETIMEDOUT;
+	} else if (status & SSP_STATUS_RESP_CRC_ERR) {
+		pr_debug("CMD crc error\n");
+		return -EILSEQ;
+	} else if (status & SSP_STATUS_RESP_ERR) {
+		pr_debug("RESP error\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * Define the timout for the next command
+ * @param hw_dev Host interface device instance
+ * @param to Timeout value in MCI card's bus clocks
+ */
+static void stm_setup_timout(struct device_d *hw_dev, unsigned to)
+{
+	uint32_t reg;
+
+	reg = readl(hw_dev->map_base + HW_SSP_TIMING) & ~SSP_TIMING_TIMEOUT_MASK;
+	reg |= SSP_TIMING_TIMEOUT(to);
+	writel(reg, hw_dev->map_base + HW_SSP_TIMING);
+}
+
+/**
+ * Read data from the MCI card
+ * @param hw_dev Host interface device instance
+ * @param buffer To write data into
+ * @param length Count of bytes to read (must be multiples of 4)
+ * @return 0 on success, negative values else
+ *
+ * @note This routine uses PIO to read in the data bytes from the FIFO. This
+ * may fail whith high clock speeds. If you receive -EIO errors you can try
+ * again with reduced clock speeds.
+ */
+static int read_data(struct device_d *hw_dev, void *buffer, unsigned length)
+{
+	uint32_t *p = buffer;
+
+	if (length & 0x3) {
+		pr_debug("Cannot read data sizes not multiple of 4 (request for %u detected)\n", length);
+		return -EINVAL;
+	}
+
+	while ((length != 0) && ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_ERROR) == 0)) {
+		/* TODO sort out FIFO overflows and emit -EOI for this case */
+		if ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_FIFO_EMPTY) == 0) {
+			*p = readl(hw_dev->map_base + HW_SSP_DATA);
+			p++;
+			length -= 4;
+		}
+	}
+
+	if (length == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+
+/**
+ * Write data into the MCI card
+ * @param hw_dev Host interface device instance
+ * @param buffer To read the data from
+ * @param length Count of bytes to write (must be multiples of 4)
+ * @return 0 on success, negative values else
+ *
+ * @note This routine uses PIO to write the data bytes into the FIFO. This
+ * may fail with high clock speeds. If you receive -EIO errors you can try
+ * again with reduced clock speeds.
+ */
+static int write_data(struct device_d *hw_dev, const void *buffer, unsigned length)
+{
+	const uint32_t *p = buffer;
+
+	if (length & 0x3) {
+		pr_debug("Cannot write data sizes not multiple of 4 (request for %u detected)\n", length);
+		return -EINVAL;
+	}
+
+	while ((length != 0) && ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_ERROR) == 0)) {
+		/* TODO sort out FIFO overflows and emit -EOI for this case */
+		if ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_FIFO_FULL) == 0) {
+			writel(*p, hw_dev->map_base + HW_SSP_DATA);
+			p++;
+			length -= 4;
+		}
+	}
+	if (length == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+/**
+ * Start the transaction with or without data
+ * @param hw_dev Host interface device instance
+ * @param data Data transfer description (might be NULL)
+ * @return 0 on success
+ */
+static int transfer_data(struct device_d *hw_dev, struct mci_data *data)
+{
+	unsigned length;
+
+	if (data != NULL) {
+		length = data->blocks * data->blocksize;
+#if 0
+		/*
+		 * For the records: When writing data with high clock speeds it
+		 * could be a good idea to fill the FIFO prior starting the
+		 * transaction.
+		 * But last time I tried it, it failed badly. Don't know why yet
+		 */
+		if (data->flags & MMC_DATA_WRITE) {
+			err = write_data(host, data->src, 16);
+			data->src += 16;
+			length -= 16;
+		}
+#endif
+	}
+
+	/*
+	 * Everything is ready for the transaction now:
+	 * - transfer configuration
+	 * - command and its parameters
+	 *
+	 * Start the transaction right now
+	 */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 4);
+
+	if (data != NULL) {
+		if (data->flags & MMC_DATA_READ)
+			return read_data(hw_dev, data->dest, length);
+		else
+			return write_data(hw_dev, data->src, length);
+	}
+
+	return 0;
+}
+
+/**
+ * Configure the MCI hardware for the next transaction
+ * @param cmd_flags Command information
+ * @param data_flags Data information (may be 0)
+ * @return Corresponding setting for the SSP_CTRL0 register
+ */
+static uint32_t prepare_transfer_setup(unsigned cmd_flags, unsigned data_flags)
+{
+	uint32_t reg = 0;
+
+	if (cmd_flags & MMC_RSP_PRESENT)
+		reg |= SSP_CTRL0_GET_RESP;
+	if ((cmd_flags & MMC_RSP_CRC) == 0)
+		reg |= SSP_CTRL0_IGNORE_CRC;
+	if (cmd_flags & MMC_RSP_136)
+		reg |= SSP_CTRL0_LONG_RESP;
+	if (cmd_flags & MMC_RSP_BUSY)
+		reg |= SSP_CTRL0_WAIT_FOR_IRQ;	/* FIXME correct? */
+#if 0
+	if (cmd_flags & MMC_RSP_OPCODE)
+		/* TODO */
+#endif
+	if (data_flags & MMC_DATA_READ)
+		reg |= SSP_CTRL0_READ;
+
+	return reg;
+}
+
+/**
+ * Handle MCI commands without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @return 0 on success
+ *
+ * This functions handles the following MCI commands:
+ * - "broadcast command (BC)" without a response
+ * - "broadcast commands with response (BCR)"
+ * - "addressed command (AC)" with response, but without data
+ */
+static int stm_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	int rc;
+
+	/* setup command and transfer parameters */
+	writel(prepare_transfer_setup(cmd->resp_type, 0) |
+		/* SSP_CTRL0_BUS_WIDTH(host->bus_width) | */	/* wird im Original-Treiber nicht gemacht???? wird nur beim Datenaustausch ben?tigt (Response z?hlt nicht dazu) */
+		SSP_CTRL0_ENABLE, hw_dev->map_base + HW_SSP_CTRL0);
+
+	/* prepare the command, when no response is expected add a few trailing clocks */
+	writel(SSP_CMD0_CMD(cmd->cmdidx) |
+		(cmd->resp_type & MMC_RSP_PRESENT ? 0 : SSP_CMD0_APPEND_8CYC),
+		hw_dev->map_base + HW_SSP_CMD0);
+
+	/* prepare command's arguments */
+	writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
+
+	stm_setup_timout(hw_dev, 0xffff);
+
+	/* start the transfer */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 4);
+
+	/* wait until finished */
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_RUN)
+		;
+
+	if (cmd->resp_type & MMC_RSP_PRESENT)
+		get_cards_response(hw_dev, cmd);
+
+	return get_cmd_error(readl(hw_dev->map_base + HW_SSP_STATUS));
+}
+
+/**
+ * Handle an "addressed data transfer command " with or without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.) May be NULL
+ * @return 0 on success
+ */
+static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+	uint32_t xfer_cnt, log2blocksize, block_cnt;
+	int err;
+
+	/* Note: 'data' can be NULL! */
+	if (data != NULL) {
+		xfer_cnt = data->blocks * data->blocksize;
+		block_cnt = data->blocks - 1;	/* can be 0 */
+		log2blocksize = find_first_bit((const unsigned long*)&data->blocksize, 32);
+	} else
+		xfer_cnt = log2blocksize = block_cnt = 0;
+
+	/* setup command and transfer parameters */
+	writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
+		SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
+		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
+		SSP_CTRL0_ENABLE |
+		SSP_CTRL0_XFER_COUNT(xfer_cnt), /* byte count to be transfered */
+		hw_dev->map_base + HW_SSP_CTRL0);
+
+	/* prepare the command and the transfered data count */
+	writel(SSP_CMD0_CMD(cmd->cmdidx) |
+		SSP_CMD0_BLOCK_SIZE(log2blocksize) |
+		SSP_CMD0_BLOCK_COUNT(block_cnt) |
+		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
+		hw_dev->map_base + HW_SSP_CMD0);
+
+	/* prepare command's arguments */
+	writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
+
+	stm_setup_timout(hw_dev, 0xffff);
+
+	err = transfer_data(hw_dev, data);
+	if (err != 0) {
+		pr_debug(" Transfering data failed\n");
+		return err;
+	}
+
+	/* wait until finished */
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_RUN)
+		;
+
+	get_cards_response(hw_dev, cmd);
+
+	return 0;
+}
+
+
+/**
+ * @param hw_dev Host interface device instance
+ * @param nc New Clock in [Hz] (may be 0 to disable the clock)
+ * @return The real clock frequency
+ *
+ * The SSP unit clock can base on the external 24 MHz or the internal 480 MHz
+ * Its unit clock value is derived from the io clock, from the SSP divider
+ * and at least the SSP bus clock itself is derived from the SSP unit's divider
+ *
+ * @code
+ * |------------------- generic -------------|-peripheral specific-|-----all SSPs-----|-per SSP unit-|
+ *  24 MHz ----------------------------
+ *          \                          \
+ *           \                          |----| FRAC |----IO CLK----| SSP unit DIV |---| SSP DIV |--- SSP output clock
+ *            \- | PLL |--- 480 MHz ---/
+ * @endcode
+ *
+ * @note Up to "SSP unit DIV" the outer world must care. This routine only
+ * handles the "SSP DIV".
+ */
+static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
+{
+	unsigned ssp, div1, div2, reg;
+
+	if (nc == 0U) {
+		/* TODO stop the clock */
+		return 0;
+	}
+
+	ssp = imx_get_sspclk() * 1000;
+
+	for (div1 = 2; div1 < 255; div1 += 2) {
+		div2 = ssp / nc / div1;
+		if (div2 <= 0x100)
+			break;
+	}
+	if (div1 >= 255) {
+		pr_warning("Cannot set clock to %d Hz\n", nc);
+		return 0;
+	}
+
+	reg = readl(hw_dev->map_base + HW_SSP_TIMING) & SSP_TIMING_TIMEOUT_MASK;
+	reg |= SSP_TIMING_CLOCK_DIVIDE(div1) | SSP_TIMING_CLOCK_RATE(div2 - 1);
+	writel(reg, hw_dev->map_base + HW_SSP_TIMING);
+
+	return ssp / div1 / div2;
+}
+
+/**
+ * Reset the MCI engine (the hard way)
+ * @param hw_dev Host interface instance
+ *
+ * This will reset everything in all registers of this unit! (FIXME)
+ */
+static void stm_mci_reset(struct device_d *hw_dev)
+{
+	writel(SSP_CTRL0_SFTRST, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_SFTRST)
+		;
+}
+
+/**
+ * Initialize the engine
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance
+ *
+ * @todo Initialisierung dieses Taktes und seiner Umschaltung: siehe mx23_evk.c aus u-boot
+ * der Takt muss von extern laufen, sonst geht hier nix!
+ */
+static int stm_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+
+	/* enable the clock to this unit to be able to reset it */
+	writel(SSP_CTRL0_CLKGATE, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+
+	/* reset the unit */
+	stm_mci_reset(hw_dev);
+
+	/* restore the last settings */
+	mci_pdata->clock = host_data->clock = setup_clock_speed(hw_dev, mci_pdata->clock);
+	stm_setup_timout(hw_dev, 0xffff);
+	writel(SSP_CTRL0_IGNORE_CRC |
+		SSP_CTRL0_BUS_WIDTH(host_data->bus_width), hw_dev->map_base + HW_SSP_CTRL0);
+	writel(SSP_CTRL1_POLARITY |
+		SSP_CTRL1_SSP_MODE(3) |
+		SSP_CTRL1_WORD_LENGTH(7), hw_dev->map_base + HW_SSP_CTRL1);
+
+	return 0;
+}
+
+/* ------------------------- MCI API -------------------------------------- */
+
+/**
+ * Keep the attached MMC/SD unit in a well know state
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative value else
+ */
+static int mci_reset(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	return stm_mci_initialize(hw_dev, mci_dev);
+}
+
+/**
+ * Process one command to the MCI card
+ * @param hw_dev Host interface instance
+ * @param cmd The command to process
+ * @param data The data to handle in the command (can be NULL)
+ * @return 0 on success, negative value else
+ */
+static int mci_request(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	int rc;
+
+	if ((cmd->resp_type == 0) || (data == NULL))
+		rc = stm_mci_std_cmds(hw_dev, cmd);
+	else
+		rc = stm_mci_adtc(hw_dev, cmd, data);	/* with response and data */
+
+	finish_request(hw_dev);	/* TODO */
+	return rc;
+}
+
+/**
+ * Setup the bus width and IO speed
+ * @param hw_dev Host interface device instance
+ * @param mci_dev MCI device instance
+ * @param bus_width New bus width value (1, 4 or 8)
+ * @param clock New clock in Hz (can be '0' to disable the clock)
+ *
+ * Drivers currently realized values are stored in MCI's platformdata
+ */
+static void mci_set_ios(struct device_d *hw_dev, struct device_d *mci_dev, unsigned bus_width, unsigned clock)
+{
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+	struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
+
+	switch (bus_width) {
+	case 8:
+		host_data->bus_width = 2;
+		mci_pdata->bus_width = 8;	/* 8 bit is possible */
+		break;
+	case 4:
+		host_data->bus_width = 1;
+		mci_pdata->bus_width = 4;	/* 4 bit is possible */
+		break;
+	default:
+		host_data->bus_width = 0;
+		mci_pdata->bus_width = 1;	/* 1 bit is possible */
+		break;
+	}
+
+	mci_pdata->clock = host_data->clock = setup_clock_speed(hw_dev, clock);
+	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", mci_pdata->bus_width, mci_pdata->clock);
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+const unsigned char bus_width[3] = { 1, 4, 8 };
+
+static void stm_info(struct device_d *hw_dev)
+{
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+
+	printf(" Interface\n");
+	printf("  Min. bus clock: %u Hz\n", host_data->f_min);
+	printf("  Max. bus clock: %u Hz\n", host_data->f_max);
+	printf("  Current bus clock: %u Hz\n", host_data->clock);
+	printf("  Bus width: %u bit\n", bus_width[host_data->bus_width]);
+	printf("\n");
+}
+#endif
+
+static int stm_mci_probe(struct device_d *hw_dev)
+{
+	struct stm_mci_platform_data *pd = (struct stm_mci_platform_data*)hw_dev->platform_data;
+	struct stm_mci_host *host_data;
+	struct mci_platformdata *mci_pdata;
+
+	if (hw_dev->platform_data == NULL) {
+		pr_err("Missing platform data\n");
+		return -EINVAL;
+	}
+
+	mci_pdata = xzalloc(sizeof(struct stm_mci_host) + sizeof(struct mci_platformdata));
+	host_data = (struct stm_mci_host*)&mci_pdata[1];
+
+	hw_dev->priv = host_data;
+	mci_pdata->hw_dev = hw_dev;
+	mci_pdata->send_cmd = mci_request,
+	mci_pdata->set_ios = mci_set_ios,
+	mci_pdata->init = mci_reset,
+
+	/* feed forward the platform specific values */
+	mci_pdata->voltages = pd->voltages;
+	mci_pdata->host_caps = pd->caps;
+
+	if (pd->f_min == 0) {
+		mci_pdata->f_min = imx_get_sspclk() / 254U / 256U * 1000U;
+		pr_debug("Min. frequency is %u Hz\n", mci_pdata->f_min);
+	} else {
+		mci_pdata->f_min = pd->f_min;
+		pr_debug("Min. frequency is %u Hz, could be %u Hz\n", mci_pdata->f_min, imx_get_sspclk() / 254U / 256U * 1000U);
+	}
+	if (pd->f_max == 0) {
+		mci_pdata->f_max = imx_get_sspclk() / 2U / 1U * 1000U;
+		pr_debug("Max. frequency is %u Hz\n", mci_pdata->f_max);
+	} else {
+		mci_pdata->f_max =  pd->f_max;
+		pr_debug("Max. frequency is %u Hz, could be %u Hz\n", mci_pdata->f_max, imx_get_sspclk() / 2U / 1U * 1000U);
+	}
+
+#ifdef CONFIG_MCI_INFO
+	host_data->f_min = mci_pdata->f_min;
+	host_data->f_max = mci_pdata->f_max;
+#endif
+
+	return mci_register(mci_pdata);
+}
+
+static struct driver_d stm_mci_driver = {
+        .name  = "stm_mci",
+        .probe = stm_mci_probe,
+#ifdef CONFIG_MCI_INFO
+	.info = stm_info,
+#endif
+};
+
+static int stm_mci_init_driver(void)
+{
+        register_driver(&stm_mci_driver);
+        return 0;
+}
+
+device_initcall(stm_mci_init_driver);
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 08:28:53 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 14:28:53 +0200
Subject: [PATCH 1/3] Add MMC support to barebox
In-Reply-To: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
References: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286454535-695-2-git-send-email-jbe@pengutronix.de>

This adds the basic framework to handle MCI cards in barebox.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/Kconfig        |    1 +
 drivers/Makefile       |    1 +
 drivers/mci/Kconfig    |   31 ++
 drivers/mci/Makefile   |    1 +
 drivers/mci/mci-core.c | 1308 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/mci.h          |  226 +++++++++
 6 files changed, 1568 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/Kconfig
 create mode 100644 drivers/mci/Makefile
 create mode 100644 drivers/mci/mci-core.c
 create mode 100644 include/mci.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index f7154c6..13235f3 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -9,6 +9,7 @@ source "drivers/mtd/Kconfig"
 source "drivers/ata/Kconfig"
 source "drivers/usb/Kconfig"
 source "drivers/video/Kconfig"
+source "drivers/mci/Kconfig"
 source "drivers/clk/Kconfig"
 
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 706e1c8..71d34f9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -6,5 +6,6 @@ obj-y	+= usb/
 obj-$(CONFIG_ATA) += ata/
 obj-$(CONFIG_SPI) += spi/
 obj-$(CONFIG_I2C) += i2c/
+obj-$(CONFIG_MCI) += mci/
 obj-$(CONFIG_VIDEO) += video/
 obj-y	+= clk/
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
new file mode 100644
index 0000000..28f3283
--- /dev/null
+++ b/drivers/mci/Kconfig
@@ -0,0 +1,31 @@
+menuconfig MCI
+	bool "MCI drivers                   "
+	select ATA
+	select ATA_DISK
+	help
+	  Add support for MCI drivers, used to handle MMC and SD cards
+
+if MCI
+
+comment "--- Feature list ---"
+
+config MCI_STARTUP
+	bool "Probe on system start"
+	help
+	  Say 'y' here if the MCI framework should probe for attached MCI cards
+	  on system start up. This is required if the card carries barebox's
+	  environment (for example on systems where the MCI card is the sole
+	  bootmedia). Otherwise probing run on demand with "mci*.probe=1"
+
+config MCI_INFO
+	bool "MCI Info"
+	depends on CMD_DEVINFO
+	default y
+	help
+	  This entry adds more info about the attached MCI card, when the
+	  'devinfo' command is used on the mci device.
+
+comment "--- MCI host drivers ---"
+
+endif
+
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
new file mode 100644
index 0000000..927618f
--- /dev/null
+++ b/drivers/mci/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MCI)	+= mci-core.o
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
new file mode 100644
index 0000000..c6d98be
--- /dev/null
+++ b/drivers/mci/mci-core.c
@@ -0,0 +1,1308 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is havily inspred and in parts based on:
+ *
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* #define DEBUG */
+
+#include <init.h>
+#include <common.h>
+#include <mci.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm-generic/div64.h>
+#include <asm/byteorder.h>
+#include <ata.h>
+
+#define MAX_BUFFER_NUMBER 0xffffffff
+
+/**
+ * @file
+ * @brief Memory Card framework
+ *
+ * Checked with the following cards:
+ * - old Canon SD 16 MiB, does not like the 0x08 command (SD_CMD_SEND_IF_COND) -> failed
+ * - Kingston 512 MiB
+ * - SanDisk 512 MiB
+ * - Transcend SD Ultra, 1 GiB (Industrial)
+ */
+
+/**
+ * Call the MMC/SD instance driver to run the command on the MMC/SD card
+ * @param mci_dev MCI instance
+ * @param cmd The information about the command to run
+ * @param data The data according to the command (can be NULL)
+ * @return Driver's answer (0 on success)
+ */
+static int mci_send_cmd(struct device_d *mci_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+
+	return (pdata->send_cmd)(pdata->hw_dev, cmd, data);
+}
+
+/**
+ * @param p Command definition to setup
+ * @param cmd Valid SD/MMC command (refer MMC_CMD_* / SD_CMD_*)
+ * @param arg Argument for the command (optional)
+ * @param response Command's response type (refer MMC_RSP_*)
+ *
+ * Note: When calling, the 'response' must match command's requirements
+ */
+static void mci_setup_cmd(struct mci_cmd *p, unsigned cmd, unsigned arg, unsigned response)
+{
+	p->cmdidx = cmd;
+	p->cmdarg = arg;
+	p->resp_type = response;
+}
+
+/**
+ * Setup SD/MMC card's blocklength to be used for future transmitts
+ * @param mci_dev MCI instance
+ * @param len Blocklength in bytes
+ * @return Transaction status (0 on success)
+ */
+static int mci_set_blocklen(struct device_d *mci_dev, unsigned len)
+{
+	struct mci_cmd cmd;
+
+	mci_setup_cmd(&cmd, MMC_CMD_SET_BLOCKLEN, len, MMC_RSP_R1);
+	return mci_send_cmd(mci_dev, &cmd, NULL);
+}
+
+/**
+ * Write one block of data to the card
+ * @param mci_dev MCI instance
+ * @param src Where to read from to write to the card
+ * @param blocknum Block number to write
+ * @return Transaction status (0 on success)
+ */
+static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned blocknum)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	mci_setup_cmd(&cmd,
+		MMC_CMD_WRITE_SINGLE_BLOCK,
+		mci->high_capacity != 0 ? blocknum : blocknum * mci->write_bl_len,
+		MMC_RSP_R1);
+
+	data.src = src;
+	data.blocks = 1;
+	data.blocksize = mci->write_bl_len;
+	data.flags = MMC_DATA_WRITE;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * Read one block of data from the card
+ * @param mci_dev MCI instance
+ * @param dst Where to store the data read from the card
+ * @param blocknum Block number to read
+ */
+static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned blocknum)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	mci_setup_cmd(&cmd,
+		MMC_CMD_READ_SINGLE_BLOCK,
+		mci->high_capacity != 0 ? blocknum : blocknum * mci->read_bl_len,
+		MMC_RSP_R1);
+
+	data.dest = dst;
+	data.blocks = 1;
+	data.blocksize = mci->read_bl_len;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * Reset the attached MMC/SD card
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mci_go_idle(struct device_d *mci_dev)
+{
+	struct mci_cmd cmd;
+	int err;
+
+	udelay(1000);
+
+	mci_setup_cmd(&cmd, MMC_CMD_GO_IDLE_STATE, 0, MMC_RSP_NONE);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+
+	if (err) {
+		pr_debug("Activating IDLE state failed: %d\n", err);
+		return err;
+	}
+
+	udelay(2000);	/* WTF? */
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int sd_send_op_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int timeout = 1000;
+	int err;
+
+	do {
+		mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, 0, MMC_RSP_R1);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+		if (err) {
+			pr_debug("Preparing SD for operating conditions failed: %d\n", err);
+			return err;
+		}
+
+		mci_setup_cmd(&cmd, SD_CMD_APP_SEND_OP_COND,
+			pdata->voltages | (mci->version == SD_VERSION_2 ? OCR_HCS : 0),
+			MMC_RSP_R3);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+		if (err) {
+			pr_debug("SD operation condition set failed: %d\n", err);
+			return err;
+		}
+		udelay(1000);
+	} while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
+
+	if (timeout <= 0) {
+		pr_debug("SD operation condition set timed out\n");
+		return -ENODEV;
+	}
+
+	if (mci->version != SD_VERSION_2)
+		mci->version = SD_VERSION_1_0;
+
+	mci->ocr = cmd.response[0];
+
+	mci->high_capacity = ((mci->ocr & OCR_HCS) == OCR_HCS);
+	mci->rca = 0;
+
+	return 0;
+}
+
+/**
+ * Setup the operation conditions to a MultiMediaCard
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mmc_send_op_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int timeout = 1000;
+	int err;
+
+	/* Some cards seem to need this */
+	mci_go_idle(mci_dev);
+
+	do {
+		mci_setup_cmd(&cmd, MMC_CMD_SEND_OP_COND, OCR_HCS | pdata->voltages, MMC_RSP_R3);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+
+		if (err) {
+			pr_debug("Preparing MMC for operating conditions failed: %d\n", err);
+			return err;
+		}
+
+		udelay(1000);
+	} while (!(cmd.response[0] & OCR_BUSY) && timeout--);
+
+	if (timeout <= 0) {
+		pr_debug("SD operation condition set timed out\n");
+		return -ENODEV;
+	}
+
+	mci->version = MMC_VERSION_UNKNOWN;
+	mci->ocr = cmd.response[0];
+
+	mci->high_capacity = ((mci->ocr & OCR_HCS) == OCR_HCS);
+	mci->rca = 0;
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param ext_csd Buffer for a 512 byte sized extended CSD
+ * @return Transaction status (0 on success)
+ *
+ * Note: Only cards newer than Version 1.1 (Physical Layer Spec) support this command
+ */
+static int mci_send_ext_csd(struct device_d *mci_dev, char *ext_csd)
+{
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	/* Get the Card Status Register */
+	mci_setup_cmd(&cmd, MMC_CMD_SEND_EXT_CSD, 0, MMC_RSP_R1);
+
+	data.dest = ext_csd;
+	data.blocks = 1;
+	data.blocksize = 512;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param set FIXME
+ * @param index FIXME
+ * @param value FIXME
+ * @return Transaction status (0 on success)
+ */
+static int mci_switch(struct device_d *mci_dev, unsigned set, unsigned index, unsigned value)
+{
+	struct mci_cmd cmd;
+
+	mci_setup_cmd(&cmd, MMC_CMD_SWITCH,
+		(MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+		(index << 16) |
+		(value << 8),
+		 MMC_RSP_R1b);
+
+	return mci_send_cmd(mci_dev, &cmd, NULL);
+}
+
+/**
+ * Change transfer frequency foa a MMC card
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mmc_change_freq(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	char ext_csd[512];	/* TODO why this works on ARM, while the same in the disk layer does not??? */
+	char cardtype;
+	int err;
+
+	mci->card_caps = 0;
+
+	/* Only version 4 supports high-speed */
+	if (mci->version < MMC_VERSION_4)
+		return 0;
+
+	mci->card_caps |= MMC_MODE_4BIT;
+
+	err = mci_send_ext_csd(mci_dev, ext_csd);
+	if (err) {
+		pr_debug("Preparing for frequency setup failed: %d\n", err);
+		return err;
+	}
+
+	if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
+		mci->high_capacity = 1;
+
+	cardtype = ext_csd[196] & 0xf;
+
+	err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
+
+	if (err) {
+		pr_debug("MMC frequency changing failed: %d\n", err);
+		return err;
+	}
+
+	/* Now check to see that it worked */
+	err = mci_send_ext_csd(mci_dev, ext_csd);
+
+	if (err) {
+		pr_debug("Verifying frequency change failed: %d\n", err);
+		return err;
+	}
+
+	/* No high-speed support */
+	if (!ext_csd[185])
+		return 0;
+
+	/* High Speed is set, there are two types: 52MHz and 26MHz */
+	if (cardtype & MMC_HS_52MHZ)
+		mci->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+	else
+		mci->card_caps |= MMC_MODE_HS;
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param mode FIXME
+ * @param group FIXME
+ * @param value FIXME
+ * @param resp FIXME
+ * @return Transaction status (0 on success)
+ */
+static int sd_switch(struct device_d *mci_dev, unsigned mode, unsigned group, unsigned value, uint8_t *resp)
+{
+	struct mci_cmd cmd;
+	struct mci_data data;
+	unsigned arg;
+
+	arg = (mode << 31) | 0xffffff;
+	arg &= ~(0xf << (group << 2));
+	arg |= value << (group << 2);
+
+	/* Switch the frequency */
+	mci_setup_cmd(&cmd, SD_CMD_SWITCH_FUNC, arg, MMC_RSP_R1);
+
+	data.dest = resp;
+	data.blocksize = 64;
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int sd_change_freq(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+	uint32_t switch_status[16];
+	uint scr[2];
+	int timeout;
+	int err;
+
+	pr_debug("Changing transfer frequency\n");
+	mci->card_caps = 0;
+
+	/* Read the SCR to find out if this card supports higher speeds */
+	mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, mci->rca << 16, MMC_RSP_R1);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Query SD card capabilities failed: %d\n", err);
+		return err;
+	}
+
+	mci_setup_cmd(&cmd, SD_CMD_APP_SEND_SCR, 0, MMC_RSP_R1);
+
+	timeout = 3;
+
+retry_scr:
+	pr_debug("Trying to read the SCR (try %d of %d)\n", 4 - timeout, 3);
+	data.dest = (char *)&scr;
+	data.blocksize = 8;
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+
+	err = mci_send_cmd(mci_dev, &cmd, &data);
+	if (err) {
+		pr_debug(" Catch error (%d)", err);
+		if (timeout--) {
+			pr_debug("-- retrying\n");
+			goto retry_scr;
+		}
+		pr_debug("-- giving up\n");
+		return err;
+	}
+
+	mci->scr[0] = __be32_to_cpu(scr[0]);
+	mci->scr[1] = __be32_to_cpu(scr[1]);
+
+	switch ((mci->scr[0] >> 24) & 0xf) {
+	case 0:
+		mci->version = SD_VERSION_1_0;
+		break;
+	case 1:
+		mci->version = SD_VERSION_1_10;
+		break;
+	case 2:
+		mci->version = SD_VERSION_2;
+		break;
+	default:
+		mci->version = SD_VERSION_1_0;
+		break;
+	}
+
+	/* Version 1.0 doesn't support switching */
+	if (mci->version == SD_VERSION_1_0)
+		return 0;
+
+	timeout = 4;
+	while (timeout--) {
+		err = sd_switch(mci_dev, SD_SWITCH_CHECK, 0, 1, (uint8_t*)&switch_status);
+		if (err) {
+			pr_debug("Checking SD transfer switch frequency feature failed: %d\n", err);
+			return err;
+		}
+
+		/* The high-speed function is busy.  Try again */
+		if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
+			break;
+	}
+
+	if (mci->scr[0] & SD_DATA_4BIT)
+		mci->card_caps |= MMC_MODE_4BIT;
+
+	/* If high-speed isn't supported, we return */
+	if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
+		return 0;
+
+	err = sd_switch(mci_dev, SD_SWITCH_SWITCH, 0, 1, (uint8_t*)&switch_status);
+	if (err) {
+		pr_debug("Switching SD transfer frequency failed: %d\n", err);
+		return err;
+	}
+
+	if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
+		mci->card_caps |= MMC_MODE_HS;
+
+	return 0;
+}
+
+/**
+ * Setup host's interface bus width and transfer frequency
+ * @param mci_dev MCI instance
+ */
+static void mci_set_ios(struct device_d *mci_dev)
+{
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+
+	(pdata->set_ios)(pdata->hw_dev, mci_dev, pdata->bus_width, pdata->clock);
+}
+
+/**
+ * Setup host's interface transfer frequency
+ * @param mci_dev MCI instance
+ * @param clock New clock in Hz to set
+ */
+static void mci_set_clock(struct device_d *mci_dev, unsigned clock)
+{
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+
+	/* check against any given limits */
+	if (clock > pdata->f_max)
+		clock = pdata->f_max;
+
+	if (clock < pdata->f_min)
+		clock = pdata->f_min;
+
+	pdata->clock = clock;	/* the new target frequency */
+	mci_set_ios(mci_dev);
+}
+
+/**
+ * Setup host's interface bus width
+ * @param mci_dev MCI instance
+ * @param width New interface bit width (1, 4 or 8)
+ */
+static void mci_set_bus_width(struct device_d *mci_dev, unsigned width)
+{
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+
+	pdata->bus_width = width;	/* the new target bus width */
+	mci_set_ios(mci_dev);
+}
+
+/**
+ * Extract card's version from its CSD
+ * @param mci_dev MCI instance
+ * @return 0 on success
+ */
+static void mci_detect_version_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int version;
+
+	if (mci->version == MMC_VERSION_UNKNOWN) {
+		/* the version is coded in the bits 127:126 (left aligned) */
+		version = (mci->csd[0] >> 26) & 0xf;	/* FIXME why other width? */
+
+		switch (version) {
+		case 0:
+			printf("Detecting a 1.2 revision card\n");
+			mci->version = MMC_VERSION_1_2;
+			break;
+		case 1:
+			printf("Detecting a 1.4 revision card\n");
+			mci->version = MMC_VERSION_1_4;
+			break;
+		case 2:
+			printf("Detecting a 2.2 revision card\n");
+			mci->version = MMC_VERSION_2_2;
+			break;
+		case 3:
+			printf("Detecting a 3.0 revision card\n");
+			mci->version = MMC_VERSION_3;
+			break;
+		case 4:
+			printf("Detecting a 4.0 revision card\n");
+			mci->version = MMC_VERSION_4;
+			break;
+		default:
+			printf("Unknow revision. Falling back to a 1.2 revision card\n");
+			mci->version = MMC_VERSION_1_2;
+			break;
+		}
+	}
+}
+
+/**
+ * meaning of the encoded 'unit' bits in the CSD's field 'TRAN_SPEED'
+ * (divided by 10 to be nice to platforms without floating point)
+ */
+static const unsigned tran_speed_unit[] = {
+	[0] = 10000,		/* 100 kbit/s */
+	[1] = 100000,		/* 1 Mbit/s */
+	[2] = 1000000,		/* 10 Mbit/s */
+	[3] = 10000000,		/* 100 Mbit/s */
+	/* [4]...[7] are reserved */
+};
+
+/**
+ * meaning of the 'time' bits  in the CSD's field 'TRAN_SPEED'
+ * (multiplied by 10 to be nice to platforms without floating point)
+ */
+static const unsigned char tran_speed_time[] = {
+	0,	/* reserved */
+	10,	/* 1.0 ns */
+	12,	/* 1.2 ns */
+	13,
+	15,
+	20,
+	25,
+	30,
+	35,
+	40,
+	45,
+	50,
+	55,
+	60,
+	70,	/* 7.0 ns */
+	80,	/* 8.0 ns */
+};
+
+/**
+ * Extract max. transfer speed from the CSD
+ * @param mci_dev MCI instance
+ *
+ * Encoded in bit 103:96 (103: reserved, 102:99: time, 98:96 unit)
+ */
+static void mci_extract_max_tran_speed_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	unsigned unit, time;
+
+	unit = tran_speed_unit[(mci->csd[0] & 0x7)];
+	time = tran_speed_time[((mci->csd[0] >> 3) & 0xf)];
+	if ((unit == 0) || (time == 0)) {
+		pr_warning("Unsupported 'TRAN_SPEED' unit/time value. Can't calculate card's max. transfer speed\n");
+		return;
+	}
+
+	mci->tran_speed = time * unit;
+	pr_debug("Transfer speed: %u\n", mci->tran_speed);
+}
+
+/**
+ * Extract max read and write block length from the CSD
+ * @param mci_dev MCI instance
+ *
+ * Encoded in bit 83:80 (read) and 25:22 (write)
+ */
+static void mci_extract_block_lengths_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	mci->read_bl_len = 1 << ((mci->csd[1] >> 16) & 0xf);
+
+	if (IS_SD(mci))
+		mci->write_bl_len = mci->read_bl_len;	/* FIXME why? */
+	else
+		mci->write_bl_len = 1 << ((mci->csd[3] >> 22) & 0xf);
+
+	pr_debug("Max. block length are: Write=%u, Read=%u Bytes\n", mci->read_bl_len, mci->write_bl_len);
+}
+
+/**
+ * Extract card's capacitiy from the CSD
+ * @param mci_dev MCI instance
+ */
+static void mci_extract_card_capacity_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	uint64_t csize, cmult;
+
+	if (mci->high_capacity) {
+		csize = (mci->csd[1] & 0x3f) << 16 | (mci->csd[2] & 0xffff0000) >> 16;
+		cmult = 8;
+	} else {
+		csize = (mci->csd[1] & 0x3ff) << 2 | (mci->csd[2] & 0xc0000000) >> 30;
+		cmult = (mci->csd[2] & 0x00038000) >> 15;
+	}
+
+	mci->capacity = (csize + 1) << (cmult + 2);
+	mci->capacity *= mci->read_bl_len;
+	pr_debug("Capacity: %u MiB\n", (unsigned)mci->capacity >> 20);
+}
+
+/**
+ * Scan the given host interfaces and detect connected MMC/SD cards
+ * @param mci_dev MCI instance
+ * @return 0 on success, negative value else
+ */
+static int mci_startup(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int err;
+
+	pr_debug("Put the Card in Identify Mode\n");
+
+	/* Put the Card in Identify Mode */
+	mci_setup_cmd(&cmd, MMC_CMD_ALL_SEND_CID, 0, MMC_RSP_R2);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Can't bring card into identify mode: %d\n", err);
+		return err;
+	}
+
+	memcpy(mci->cid, cmd.response, 16);
+
+	pr_debug("Card's identification data is: %08X-%08X-%08X-%08X\n", mci->cid[0], mci->cid[1], mci->cid[2], mci->cid[3]);
+
+	/*
+	 * For MMC cards, set the Relative Address.
+	 * For SD cards, get the Relatvie Address.
+	 * This also puts the cards into Standby State
+	 */
+	pr_debug("Get/Set relative address\n");
+	mci_setup_cmd(&cmd, SD_CMD_SEND_RELATIVE_ADDR, mci->rca << 16, MMC_RSP_R6);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Get/Set relative address failed: %d\n", err);
+		return err;
+	}
+
+	if (IS_SD(mci))
+		mci->rca = (cmd.response[0] >> 16) & 0xffff;
+
+	pr_debug("Get card's specific data\n");
+	/* Get the Card-Specific Data */
+	mci_setup_cmd(&cmd, MMC_CMD_SEND_CSD, mci->rca << 16, MMC_RSP_R2);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Getting card's specific data failed: %d\n", err);
+		return err;
+	}
+
+	/* CSD is of 128 bit */
+	memcpy(mci->csd, cmd.response, 16);
+
+	pr_debug("Card's specific data is: %08X-%08X-%08X-%08X\n", mci->csd[0], mci->csd[1], mci->csd[2], mci->csd[3]);
+
+	mci_detect_version_from_csd(mci_dev);
+	mci_extract_max_tran_speed_from_csd(mci_dev);
+	mci_extract_block_lengths_from_csd(mci_dev);
+	mci_extract_card_capacity_from_csd(mci_dev);
+
+	/* sanitiy? */
+	if (mci->read_bl_len > 512) {
+		mci->read_bl_len = 512;
+		pr_warning("Limiting max. read block size down to %u\n", mci->read_bl_len);
+	}
+
+	if (mci->write_bl_len > 512) {
+		mci->write_bl_len = 512;
+		pr_warning("Limiting max. write block size down to %u\n", mci->read_bl_len);
+	}
+	pr_debug("Read block length: %u, Write block length: %u\n", mci->read_bl_len, mci->write_bl_len);
+
+	pr_debug("Select the card, and put it into Transfer Mode\n");
+	/* Select the card, and put it into Transfer Mode */
+	mci_setup_cmd(&cmd, MMC_CMD_SELECT_CARD, mci->rca << 16, MMC_RSP_R1b);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Putting in transfer mode failed: %d\n", err);
+		return err;
+	}
+
+	if (IS_SD(mci))
+		err = sd_change_freq(mci_dev);
+	else
+		err = mmc_change_freq(mci_dev);
+
+	if (err)
+		return err;
+
+	/* Restrict card's capabilities by what the host can do */
+	mci->card_caps &= pdata->host_caps;
+
+	if (IS_SD(mci)) {
+		if (mci->card_caps & MMC_MODE_4BIT) {
+			pr_debug("Prepare for bus width change\n");
+			mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, mci->rca << 16, MMC_RSP_R1);
+			err = mci_send_cmd(mci_dev, &cmd, NULL);
+			if (err) {
+				pr_debug("Preparing SD for bus width change failed: %d\n", err);
+				return err;
+			}
+
+			pr_debug("Set SD bus width to 4 bit\n");
+			mci_setup_cmd(&cmd, SD_CMD_APP_SET_BUS_WIDTH, 2, MMC_RSP_R1);
+			err = mci_send_cmd(mci_dev, &cmd, NULL);
+			if (err) {
+				pr_debug("Changing SD bus width failed: %d\n", err);
+				/* TODO continue with 1 bit? */
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 4);
+		}
+		/* if possible, speed up the transfer */
+		if (mci->card_caps & MMC_MODE_HS)
+			mci_set_clock(mci_dev, 50000000);
+		else
+			mci_set_clock(mci_dev, 25000000);
+	} else {
+		if (mci->card_caps & MMC_MODE_4BIT) {
+			pr_debug("Set MMC bus width to 4 bit\n");
+			/* Set the card to use 4 bit*/
+			err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
+			if (err) {
+				pr_debug("Changing MMC bus width failed: %d\n", err);
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 4);
+		} else if (mci->card_caps & MMC_MODE_8BIT) {
+			pr_debug("Set MMC bus width to 8 bit\n");
+			/* Set the card to use 8 bit*/
+			err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);
+			if (err) {
+				pr_debug("Changing MMC bus width failed: %d\n", err);
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 8);
+		}
+		/* if possible, speed up the transfer */
+		if (mci->card_caps & MMC_MODE_HS) {
+			if (mci->card_caps & MMC_MODE_HS_52MHz)
+				mci_set_clock(mci_dev, 52000000);
+			else
+				mci_set_clock(mci_dev, 26000000);
+		} else
+			mci_set_clock(mci_dev, 20000000);
+	}
+
+	/* we setup the blocklength only one times for all accesses to this media  */
+	err = mci_set_blocklen(mci_dev, mci->read_bl_len);
+
+	return err;
+}
+
+/**
+ * Detect a SD 2.0 card and enable its features
+ * @param mci_dev MCI instance
+ * @return Transfer status (0 on success)
+ *
+ * By issuing the CMD8 command SDHC/SDXC cards realize that the host supports
+ * the Physical Layer Version 2.00 or later and the card can enable
+ * corresponding new functions.
+ *
+ * If this CMD8 command will end with a timeout it is a MultiMediaCard only.
+ */
+static int sd_send_if_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int err;
+
+	mci_setup_cmd(&cmd, SD_CMD_SEND_IF_COND,
+	/* We set the bit if the host supports voltages between 2.7 and 3.6 V */
+		((pdata->voltages & 0x00ff8000) != 0) << 8 | 0xaa,
+		MMC_RSP_R7);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Query interface conditions failed: %d\n", err);
+		return err;
+	}
+
+	if ((cmd.response[0] & 0xff) != 0xaa) {
+		pr_debug("Card cannot work with hosts supply voltages\n");
+		return -EINVAL;
+	} else {
+		pr_debug("SD Card Rev. 2.00 or later detected\n");
+		mci->version = SD_VERSION_2;
+	}
+
+	return 0;
+}
+
+/* ------------------ attach to the ATA API --------------------------- */
+
+/**
+ * Write a chunk of sectors to media
+ * @param disk_dev Disk device instance
+ * @param sector_start Sector's number to start write to
+ * @param sector_count Sectors to write
+ * @param buffer Buffer to write from
+ * @return 0 on success, anything else on failure
+ *
+ * This routine expects the buffer has the correct size to read all data!
+ */
+static int mci_sd_write(struct device_d *disk_dev, uint64_t sector_start, unsigned sector_count, const void *buffer)
+{
+	struct ata_interface *intf = disk_dev->platform_data;
+	struct device_d *mci_dev = intf->priv;
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int rc;
+
+	pr_debug("%s called: Write %u block(s), starting at %lu", __func__, sector_count, (unsigned)sector_count);
+
+	if (mci->write_bl_len != 512) {
+		pr_warning("MMC/SD block size is not 512 bytes (its %u bytes instead)\n", mci->read_bl_len);
+		return -EINVAL;
+	}
+
+	while (sector_count) {
+		/* size of the block number field in the MMC/SD command is 32 bit only */
+		if (sector_start > MAX_BUFFER_NUMBER) {
+			pr_err("Cannot handle block number %llu. Too large!\n", sector_start);
+			return -EINVAL;
+		}
+		rc = mci_block_write(mci_dev, buffer, sector_start);
+		if (rc != 0) {
+			pr_err("Writing block %u failed\n", (unsigned)sector_start);
+			return rc;
+		}
+		sector_count--;
+		buffer += mci->write_bl_len;
+		sector_start++;
+	}
+
+	return 0;
+}
+
+/**
+ * Read a chunk of sectors from media
+ * @param disk_dev Disk device instance
+ * @param sector_start Sector's number to start read from
+ * @param sector_count Sectors to read
+ * @param buffer Buffer to read into
+ * @return 0 on success, anything else on failure
+ *
+ * This routine expects the buffer has the correct size to store all data!
+ */
+static int mci_sd_read(struct device_d *disk_dev, uint64_t sector_start, unsigned sector_count, void *buffer)
+{
+	struct ata_interface *intf = disk_dev->platform_data;
+	struct device_d *mci_dev = intf->priv;
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int rc;
+
+	pr_debug("%s called: Read %u block(s), starting at %lu to %08X\n", __func__, sector_count, (unsigned)sector_start, buffer);
+
+	if (mci->read_bl_len != 512) {
+		pr_warning("MMC/SD block size is not 512 bytes (its %u bytes instead)\n", mci->read_bl_len);
+		return -EINVAL;
+	}
+
+	while (sector_count) {
+		if (sector_start > MAX_BUFFER_NUMBER) {
+			pr_err("Cannot handle block number %lu. Too large!\n", (unsigned)sector_start);
+			return -EINVAL;
+		}
+		rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start);
+		if (rc != 0) {
+			pr_err("Reading block %lu failed\n", (unsigned)sector_start);
+			return rc;
+		}
+		sector_count--;
+		buffer += mci->read_bl_len;	/* FIXME always 512 bytes? */
+		sector_start++;
+	}
+
+	return 0;
+}
+
+/* ------------------ attach to the device API --------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+/**
+ * Extract the Manufacturer ID from the CID
+ * @param mci Instance data
+ *
+ * The 'MID' is encoded in bit 127:120 in the CID
+ */
+static unsigned extract_mid(struct mci *mci)
+{
+	return mci->cid[0] >> 24;
+}
+
+/**
+ * Extract the OEM/Application ID from the CID
+ * @param mci Instance data
+ *
+ * The 'OID' is encoded in bit 119:104 in the CID
+ */
+static unsigned extract_oid(struct mci *mci)
+{
+	return (mci->cid[0] >> 8) & 0xffff;
+}
+
+/**
+ * Extract the product revision from the CID
+ * @param mci Instance data
+ *
+ * The 'PRV' is encoded in bit 63:56 in the CID
+ */
+static unsigned extract_prv(struct mci *mci)
+{
+	return mci->cid[2] >> 24;
+}
+
+/**
+ * Extract the product serial number from the CID
+ * @param mci Instance data
+ *
+ * The 'PSN' is encoded in bit 55:24 in the CID
+ */
+static unsigned extract_psn(struct mci *mci)
+{
+	return (mci->cid[2] << 8) | (mci->cid[3] >> 24);
+}
+
+/**
+ * Extract the month of the manufacturing date from the CID
+ * @param mci Instance data
+ *
+ * The 'MTD' is encoded in bit 19:8 in the CID, month in 11:8
+ */
+static unsigned extract_mtd_month(struct mci *mci)
+{
+	return (mci->cid[3] >> 8) & 0xf;
+}
+
+/**
+ * Extract the year of the manufacturing date from the CID
+ * @param mci Instance data
+ *
+ * The 'MTD' is encoded in bit 19:8 in the CID, year in 19:12
+ * An encoded 0 means the year 2000
+ */
+static unsigned extract_mtd_year(struct mci *mci)
+{
+	return ((mci->cid[3] >> 12) & 0xff) + 2000U;
+}
+
+/**
+ * Output some valuable information when the user runs 'devinfo' on an MCI device
+ * @param mci_dev MCI device instance
+ */
+static void mci_info(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	if (mci->ready_for_use == 0) {
+		printf(" No information available:\n  MCI card not probed yet\n");
+		return;
+	}
+
+	printf(" Card:\n");
+	if (mci->version < SD_VERSION_SD) {
+		printf("  Attached is a MultiMediaCard (Version: %u.%u)\n", (mci->version >> 4) & 0xf, mci->version & 0xf);
+	} else {
+		printf("  Attached is an SD Card (Version: %u.%u)\n", (mci->version >> 4) & 0xf, mci->version & 0xf);
+	}
+	printf("  Capacity: %u MiB\n", (unsigned)(mci->capacity >> 20));
+
+	if (mci->high_capacity)
+		printf("  High capacity card\n");
+	printf("   CID: %08X-%08X-%08X-%08X\n", mci->cid[0], mci->cid[1], mci->cid[2], mci->cid[3]);
+	printf("   CSD: %08X-%08X-%08X-%08X\n", mci->csd[0], mci->csd[1], mci->csd[2], mci->csd[3]);
+	printf("  Max. transfer speed: %u Hz\n", mci->tran_speed);
+	printf("  Manufacturer ID: %02X\n", extract_mid(mci));
+	printf("  OEM/Application ID: %04X\n", extract_oid(mci));
+	printf("  Product name: '%c%c%c%c%c'\n", mci->cid[0] & 0xff, (mci->cid[1] >> 24), (mci->cid[1] >> 16) & 0xff,
+			(mci->cid[1] >> 8) & 0xff, mci->cid[1] & 0xff);
+	printf("  Product revision: %u.%u\n", extract_prv(mci) >> 4, extract_prv(mci) & 0xf);
+	printf("  Serial no: %0u\n", extract_psn(mci));
+	printf("  Manufacturing date: %u.%u\n", extract_mtd_month(mci), extract_mtd_year(mci));
+}
+#endif
+
+/**
+ * Check if the MCI card is already probed
+ * @param mci_dev MCI device instance
+ * @return 0 when not probed yet, -EPERM if already probed
+ *
+ * @a barebox cannot really cope with hot plugging. So, probing an attached
+ * MCI card is a one time only job. If its already done, there is no way to
+ * return.
+ */
+static int mci_check_if_already_initialized(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	if (mci->ready_for_use != 0)
+		return -EPERM;
+
+	return 0;
+}
+
+/**
+ * Probe an MCI card at the given host interface
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative values else
+ */
+static int mci_card_probe(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct device_d *disk_dev;
+	struct ata_interface *p;
+	int rc;
+
+	/* start with a host interface reset */
+	rc = (pdata->init)(pdata->hw_dev, mci_dev);
+	if (rc) {
+		pr_err("Cannot reset the SD/MMC interface\n");
+		return rc;
+	}
+
+	mci_set_bus_width(mci_dev, 1);
+	mci_set_clock(mci_dev, 1);	/* set the lowest available clock */
+
+	/* reset the card */
+	rc = mci_go_idle(mci_dev);
+	if (rc) {
+		pr_warning("Cannot reset the SD/MMC card\n");
+		goto on_error;
+	}
+
+	/* Check if this card can handle the "SD Card Physical Layer Specification 2.0" */
+	rc = sd_send_if_cond(mci_dev);
+	if (rc) {
+		/* If the command timed out, we check for an MMC card */
+		if (rc == -ETIMEDOUT) {
+			pr_debug("Card seems to be a MultiMediaCard\n");
+			rc = mmc_send_op_cond(mci_dev);
+			if (rc) {
+				printf("MultiMediaCard did not respond to voltage select!\n");
+				rc = -ENODEV;
+				goto on_error;
+			}
+		} else
+			goto on_error;
+	} else {
+		/* Its a 2.xx card. Setup operation conditions */
+		rc = sd_send_op_cond(mci_dev);
+		if (rc) {
+			pr_debug("Cannot setup SD card's operation condition\n");
+			goto on_error;
+		}
+	}
+
+	rc = mci_startup(mci_dev);
+	if (rc) {
+		printf("Card's startup fails with %d\n", rc);
+		goto on_error;
+	}
+
+	pr_debug("Card is up and running now, registering as a disk\n");
+	mci->ready_for_use = 1;	/* TODO now or later? */
+
+	/*
+	 * An MMC/SD card acts like an ordinary disk.
+	 * So, re-use the disk driver to gain access to this media
+	 */
+	disk_dev = xzalloc(sizeof(struct device_d) + sizeof(struct ata_interface));
+	if (disk_dev == NULL) {
+		pr_err("Out of memory when registering the MMC/SD device\n");
+		rc = -ENOMEM;
+		goto on_error;
+	}
+	p = (struct ata_interface*)&disk_dev[1];
+
+	p->write = mci_sd_write;
+	p->read = mci_sd_read;
+	p->priv = mci_dev;
+
+	strcpy(disk_dev->name, "disk");
+	disk_dev->size = mci->capacity;
+	disk_dev->map_base = 0;
+	disk_dev->platform_data = p;
+
+	register_device(disk_dev);
+
+	pr_debug("SD Card successfully added\n");
+
+on_error:
+	if (rc != 0) {
+		pdata->clock = 0;	/* disable the MCI clock */
+		mci_set_ios(mci_dev);
+	}
+
+	return rc;
+}
+
+/**
+ * Trigger probing of an attached MCI card
+ * @param mci_dev MCI device instance
+ * @param param FIXME
+ * @param val "0" does nothing, a "1" will probe for a MCI card
+ * @return 0 on success
+ */
+static int mci_set_probe(struct device_d *mci_dev, struct param_d *param, const char *val)
+{
+	int rc, probe;
+
+	rc = mci_check_if_already_initialized(mci_dev);
+	if (rc != 0)
+		return rc;
+
+	probe = simple_strtoul(val, NULL, 0);
+	if (probe != 0) {
+		rc = mci_card_probe(mci_dev);
+		if (rc != 0)
+			return rc;
+	}
+
+	return dev_param_set_generic(mci_dev, param, val);
+}
+
+/**
+ * Add parameter to the MCI device on demand
+ * @param mci_dev MCI device instance
+ * @return 0 on success
+ *
+ * This parameter is only available (or usefull) if MCI card probing is delayed
+ */
+static int add_mci_parameter(struct device_d *mci_dev)
+{
+	int rc;
+
+	/* provide a 'probing right now' parameter for the user */
+	rc = dev_add_param(mci_dev, "probe", mci_set_probe, NULL, 0);
+	if (rc != 0)
+		return rc;
+
+	return dev_set_param(mci_dev, "probe", "0");
+}
+
+/**
+ * Prepare for MCI card's usage
+ * @param mci_dev MCI device instance
+ * @return 0 on success
+ *
+ * This routine will probe an attached MCI card immediately or provide
+ * a parameter to do it later on user's demand.
+ */
+static int mci_probe(struct device_d *mci_dev)
+{
+	struct mci *mci;
+	int rc;
+
+	mci = xzalloc(sizeof(struct mci));
+	mci_dev->priv = mci;
+
+#ifdef CONFIG_MCI_STARTUP
+	/* if enabled, probe the attached card immediately */
+	rc = mci_card_probe(mci_dev);
+	if (rc == -ENODEV) {
+		/*
+		 * If it fails, add the 'probe' parameter to give the user
+		 * a chance to insert a card and try again. Note: This may fail
+		 * systems that rely on the MCI card for startup (for the
+		 * persistant environment for example)
+		 */
+		rc = add_mci_parameter(mci_dev);
+		if (rc != 0) {
+			pr_err("Failed to add 'probe' parameter to the MCI device\n");
+			goto on_error;
+		}
+	}
+#endif
+
+#ifndef CONFIG_MCI_STARTUP
+	/* add params on demand */
+	rc = add_mci_parameter(mci_dev);
+	if (rc != 0) {
+		pr_err("Failed to add 'probe' parameter to the MCI device\n");
+		goto on_error;
+	}
+#endif
+
+	return rc;
+
+on_error:
+	free(mci);
+	return rc;
+}
+
+static struct driver_d mci_driver = {
+	.name	= "mci",
+	.probe	= mci_probe,
+	.info	= mci_info,
+};
+
+static int mci_init(void)
+{
+	return register_driver(&mci_driver);
+}
+
+device_initcall(mci_init);
+
+/**
+ * Create a new mci device (for convenience)
+ * @param pdata MCI device's platform data for this MCI device
+ * @return 0 on success
+ */
+int mci_register(struct mci_platformdata *pdata)
+{
+	struct device_d *mci_dev;
+
+	mci_dev = xzalloc(sizeof(struct device_d));
+
+	strcpy(mci_dev->name, mci_driver.name);
+	mci_dev->platform_data = (void*)pdata;
+
+	return register_device(mci_dev);
+}
diff --git a/include/mci.h b/include/mci.h
new file mode 100644
index 0000000..ec04f7d
--- /dev/null
+++ b/include/mci.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MCI_H_
+#define _MCI_H_
+
+#include <linux/list.h>
+
+/* Firmware revisions for SD cards */
+#define SD_VERSION_SD		0x20000
+#define SD_VERSION_2		(SD_VERSION_SD | 0x20)
+#define SD_VERSION_1_0		(SD_VERSION_SD | 0x10)
+#define SD_VERSION_1_10		(SD_VERSION_SD | 0x1a)
+
+/* Firmware revisions for MMC cards */
+#define MMC_VERSION_MMC		0x10000
+#define MMC_VERSION_UNKNOWN	(MMC_VERSION_MMC)
+#define MMC_VERSION_1_2		(MMC_VERSION_MMC | 0x12)
+#define MMC_VERSION_1_4		(MMC_VERSION_MMC | 0x14)
+#define MMC_VERSION_2_2		(MMC_VERSION_MMC | 0x22)
+#define MMC_VERSION_3		(MMC_VERSION_MMC | 0x30)
+#define MMC_VERSION_4		(MMC_VERSION_MMC | 0x40)
+
+#define MMC_MODE_HS		0x001
+#define MMC_MODE_HS_52MHz	0x010
+#define MMC_MODE_4BIT		0x100
+#define MMC_MODE_8BIT		0x200
+
+#define SD_DATA_4BIT		0x00040000
+
+#define IS_SD(x) (x->version & SD_VERSION_SD)
+
+#define MMC_DATA_READ		1
+#define MMC_DATA_WRITE		2
+
+/* command list */
+#define MMC_CMD_GO_IDLE_STATE		0
+#define MMC_CMD_SEND_OP_COND		1
+#define MMC_CMD_ALL_SEND_CID		2
+#define MMC_CMD_SET_RELATIVE_ADDR	3
+#define MMC_CMD_SET_DSR			4
+#define MMC_CMD_SWITCH			6
+#define MMC_CMD_SELECT_CARD		7
+#define MMC_CMD_SEND_EXT_CSD		8
+#define MMC_CMD_SEND_CSD		9
+#define MMC_CMD_SEND_CID		10
+#define MMC_CMD_STOP_TRANSMISSION	12
+#define MMC_CMD_SEND_STATUS		13
+#define MMC_CMD_SET_BLOCKLEN		16
+#define MMC_CMD_READ_SINGLE_BLOCK	17
+#define MMC_CMD_READ_MULTIPLE_BLOCK	18
+#define MMC_CMD_WRITE_SINGLE_BLOCK	24
+#define MMC_CMD_WRITE_MULTIPLE_BLOCK	25
+#define MMC_CMD_APP_CMD			55
+
+#define SD_CMD_SEND_RELATIVE_ADDR	3
+#define SD_CMD_SWITCH_FUNC		6
+#define SD_CMD_SEND_IF_COND		8
+
+#define SD_CMD_APP_SET_BUS_WIDTH	6
+#define SD_CMD_APP_SEND_OP_COND		41
+#define SD_CMD_APP_SEND_SCR		51
+
+/* SCR definitions in different words */
+#define SD_HIGHSPEED_BUSY	0x00020000
+#define SD_HIGHSPEED_SUPPORTED	0x00020000
+
+#define MMC_HS_TIMING		0x00000100
+#define MMC_HS_52MHZ		0x2
+
+#define OCR_BUSY		0x80000000
+/** card's response in its OCR if it is a high capacity card */
+#define OCR_HCS			0x40000000
+
+#define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
+#define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */
+#define MMC_VDD_21_22		0x00000200	/* VDD voltage 2.1 ~ 2.2 */
+#define MMC_VDD_22_23		0x00000400	/* VDD voltage 2.2 ~ 2.3 */
+#define MMC_VDD_23_24		0x00000800	/* VDD voltage 2.3 ~ 2.4 */
+#define MMC_VDD_24_25		0x00001000	/* VDD voltage 2.4 ~ 2.5 */
+#define MMC_VDD_25_26		0x00002000	/* VDD voltage 2.5 ~ 2.6 */
+#define MMC_VDD_26_27		0x00004000	/* VDD voltage 2.6 ~ 2.7 */
+#define MMC_VDD_27_28		0x00008000	/* VDD voltage 2.7 ~ 2.8 */
+#define MMC_VDD_28_29		0x00010000	/* VDD voltage 2.8 ~ 2.9 */
+#define MMC_VDD_29_30		0x00020000	/* VDD voltage 2.9 ~ 3.0 */
+#define MMC_VDD_30_31		0x00040000	/* VDD voltage 3.0 ~ 3.1 */
+#define MMC_VDD_31_32		0x00080000	/* VDD voltage 3.1 ~ 3.2 */
+#define MMC_VDD_32_33		0x00100000	/* VDD voltage 3.2 ~ 3.3 */
+#define MMC_VDD_33_34		0x00200000	/* VDD voltage 3.3 ~ 3.4 */
+#define MMC_VDD_34_35		0x00400000	/* VDD voltage 3.4 ~ 3.5 */
+#define MMC_VDD_35_36		0x00800000	/* VDD voltage 3.5 ~ 3.6 */
+
+#define MMC_SWITCH_MODE_CMD_SET		0x00 /** Change the command set */
+#define MMC_SWITCH_MODE_SET_BITS	0x01 /** Set bits in EXT_CSD byte addressed by index which are 1 in value field */
+#define MMC_SWITCH_MODE_CLEAR_BITS	0x02 /** Clear bits in EXT_CSD byte addressed by index, which are 1 in value field */
+#define MMC_SWITCH_MODE_WRITE_BYTE	0x03 /** Set target byte to value */
+
+#define SD_SWITCH_CHECK		0
+#define SD_SWITCH_SWITCH	1
+
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_BUS_WIDTH	183	/* R/W */
+#define EXT_CSD_HS_TIMING	185	/* R/W */
+#define EXT_CSD_CARD_TYPE	196	/* RO */
+#define EXT_CSD_REV		192	/* RO */
+#define EXT_CSD_SEC_CNT		212	/* RO, 4 bytes */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_CMD_SET_NORMAL		(1<<0)
+#define EXT_CSD_CMD_SET_SECURE		(1<<1)
+#define EXT_CSD_CMD_SET_CPSECURE	(1<<2)
+
+#define EXT_CSD_CARD_TYPE_26	(1<<0)	/* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52	(1<<1)	/* Card can run at 52MHz */
+
+#define EXT_CSD_BUS_WIDTH_1	0	/* Card is in 1 bit mode */
+#define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
+#define EXT_CSD_BUS_WIDTH_8	2	/* Card is in 8 bit mode */
+
+#define R1_ILLEGAL_COMMAND		(1 << 22)
+#define R1_APP_CMD			(1 << 5)
+
+/* response types */
+#define MMC_RSP_PRESENT (1 << 0)
+#define MMC_RSP_136     (1 << 1)                /* 136 bit response */
+#define MMC_RSP_CRC     (1 << 2)                /* expect valid crc */
+#define MMC_RSP_BUSY    (1 << 3)                /* card may send busy */
+#define MMC_RSP_OPCODE  (1 << 4)                /* response contains opcode */
+
+#define MMC_RSP_NONE    (0)
+#define MMC_RSP_R1      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R1b	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
+#define MMC_RSP_R2      (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
+#define MMC_RSP_R3      (MMC_RSP_PRESENT)
+#define MMC_RSP_R4      (MMC_RSP_PRESENT)
+#define MMC_RSP_R5      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R6      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R7      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+
+/** command information to be sent to the SD/MMC card */
+struct mci_cmd {
+	unsigned cmdidx;	/**< Command to be sent to the SD/MMC card */
+	unsigned resp_type;	/**< Type of expected response, refer MMC_RSP_* macros */
+	unsigned cmdarg;	/**< Command's arguments */
+	unsigned response[4];	/**< card's response */
+};
+
+/** data information to be used with some SD/MMC commands */
+struct mci_data {
+	union {
+		uint8_t *dest;
+		const uint8_t *src; /**< src buffers don't get written to */
+	};
+	unsigned flags;		/**< refer MMC_DATA_* to define direction */
+	unsigned blocks;	/**< block count to handle in this command */
+	unsigned blocksize;	/**< block size in bytes (mostly 512) */
+};
+
+/** host information */
+struct mci_platformdata {
+	struct device_d *hw_dev;	/**< the host MCI hardware device */
+	unsigned voltages;
+	unsigned host_caps;	/**< Host's interface capabilities, refer MMC_VDD_* and FIXME */
+	unsigned f_min;		/**< host interface lower limit */
+	unsigned f_max;		/**< host interface upper limit */
+	unsigned clock;		/**< Current clock used to talk to the card */
+	unsigned bus_width;	/**< used data bus width to the card */
+
+	int (*init)(struct device_d*, struct device_d*);	/**< init the host interface */
+	void (*set_ios)(struct device_d*, struct device_d*, unsigned, unsigned);	/**< change host interface settings */
+	int (*send_cmd)(struct device_d*, struct mci_cmd*, struct mci_data*);	/**< handle a command */
+};
+
+/** MMC/SD and interface instance information */
+struct mci {
+	unsigned version;
+	int high_capacity;	/**< != 0 when a high capacity card is connected (OCR -> OCR_HCS) */
+	unsigned card_caps;	/**< Card's capabilities */
+	unsigned ocr;		/**< card's "operation condition register" */
+	unsigned scr[2];
+	unsigned csd[4];	/**< card's "card specific data register" */
+	unsigned cid[4];	/**< card's "card identification register" */
+	unsigned short rca;	/* FIXME */
+	unsigned tran_speed;	/**< not yet used */
+	unsigned read_bl_len;	/**< currently used data block length for read accesses */
+	unsigned write_bl_len;	/**< currently used data block length for write accesses */
+	uint64_t capacity;	/**< Card's data capacity in bytes */
+	int ready_for_use;	/** true if already probed */
+};
+
+int mci_register(struct mci_platformdata*);
+
+#define GET_HOST_DATA(x) (x->priv)
+#define GET_HOST_PDATA(x) (x->platform_data)
+#define GET_MCI_DATA(x) (x->priv)
+#define GET_MCI_PDATA(x) (x->platform_data)
+
+#endif /* _MCI_H_ */
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 08:33:29 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu, 7 Oct 2010 14:33:29 +0200
Subject: [RFC] Add MMC support to barebox
In-Reply-To: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
References: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
Message-ID: <201010071433.29669.jbe@pengutronix.de>

Juergen Beisert wrote:
> [...]

Forget this series. git fools me.... :-(

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From marek.belisko at gmail.com  Thu Oct  7 08:42:33 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Thu, 7 Oct 2010 14:42:33 +0200
Subject: [PATCH 3/3] Add S3C2440 MCI card support
In-Reply-To: <1286454535-695-4-git-send-email-jbe@pengutronix.de>
References: <1286454535-695-1-git-send-email-jbe@pengutronix.de>
	<1286454535-695-4-git-send-email-jbe@pengutronix.de>
Message-ID: <AANLkTim9_RD6vdao_fUQ8n_jcXwk_atig6_d15_b54OE@mail.gmail.com>

On Thu, Oct 7, 2010 at 2:28 PM, Juergen Beisert <jbe at pengutronix.de> wrote:
> From: Juergen Beisert <juergen at kreuzholzen.de>
>
> Adding MCI card support for S3C2440 CPUs. This is for reference only, as there
> is currently no user in the barebox tree. Maybe one with access to the A9M2440
> development kit can check it on his/her system.
> Checked here with my own S3C2440 based system which is not in the barebox tree.
I will try tomorrow also on mini2440 dev. board.
>
> Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
> ---
> ?arch/arm/mach-s3c24xx/include/mach/mci.h | ? 42 ++
> ?drivers/mci/Kconfig ? ? ? ? ? ? ? ? ? ? ?| ? ?8 +-
> ?drivers/mci/Makefile ? ? ? ? ? ? ? ? ? ? | ? ?1 +
> ?drivers/mci/s3c.c ? ? ? ? ? ? ? ? ? ? ? ?| ?799 ++++++++++++++++++++++++++++++
> ?4 files changed, 849 insertions(+), 1 deletions(-)
> ?create mode 100644 arch/arm/mach-s3c24xx/include/mach/mci.h
> ?create mode 100644 drivers/mci/s3c.c
>
> diff --git a/arch/arm/mach-s3c24xx/include/mach/mci.h b/arch/arm/mach-s3c24xx/include/mach/mci.h
> new file mode 100644
> index 0000000..fc3a4d6
> --- /dev/null
> +++ b/arch/arm/mach-s3c24xx/include/mach/mci.h
> @@ -0,0 +1,42 @@
> +/*
> + * Copyright 2008, Freescale Semiconductor, Inc
> + * Andy Fleming
> + *
> + * Based (loosely) on the Linux code
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __MACH_MMC_H_
> +#define __MACH_MMC_H_
> +
> +struct s3c_mci_platform_data {
> + ? ? ? unsigned caps; ?/**< supported operating modes (MMC_MODE_*) */
> + ? ? ? unsigned voltages; /**< supported voltage range (MMC_VDD_*) */
> + ? ? ? unsigned f_min; /**< min operating frequency in Hz (0 -> no limit) */
> + ? ? ? unsigned f_max; /**< max operating frequency in Hz (0 -> no limit) */
> + ? ? ? /* TODO */
> + ? ? ? /* function to modify the voltage */
> + ? ? ? /* function to switch the voltage */
> + ? ? ? /* function to detect the presence of a SD card in the socket */
> + ? ? ? unsigned gpio_detect;
> + ? ? ? unsigned detect_invert;
> +};
> +
> +#endif /* __MACH_MMC_H_ */
> diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
> index d67e383..644c0a3 100644
> --- a/drivers/mci/Kconfig
> +++ b/drivers/mci/Kconfig
> @@ -34,5 +34,11 @@ config MCI_STM378X
> ? ? ? ? ?Enable this entry to add support to read and write SD cards on a
> ? ? ? ? ?i.MX23 based system.
>
> -endif
> +config MCI_S3C
> + ? ? ? bool "S3C"
> + ? ? ? depends on ARCH_S3C24xx
> + ? ? ? help
> + ? ? ? ? Enable this entry to add support to read and write SD cards on a
> + ? ? ? ? Samsung S3C24xx based system.
>
> +endif
> diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
> index e5e19b0..be18446 100644
> --- a/drivers/mci/Makefile
> +++ b/drivers/mci/Makefile
> @@ -1,2 +1,3 @@
> ?obj-$(CONFIG_MCI) ? ? ?+= mci-core.o
> ?obj-$(CONFIG_MCI_STM378X) += stm378x.o
> +obj-$(CONFIG_MCI_S3C) += s3c.o
> diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
> new file mode 100644
> index 0000000..d164834
> --- /dev/null
> +++ b/drivers/mci/s3c.c
> @@ -0,0 +1,799 @@
> +/*
> + * Copyright (C) 2010 Juergen Beisert <juergen at kreuzholzen.de>
> + *
> + * This code is based on various Linux and u-boot sources:
> + * ?Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk at maintech.de>
> + * ?Copyright (C) 2008 Simtec Electronics <ben-linux at fluff.org>
> + * ?(C) Copyright 2006 by OpenMoko, Inc.
> + * ?Author: Harald Welte <laforge at openmoko.org>
> + * ?based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
> + * ?(C) 2005-2005 Thomas Kleffel
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +/**
> + * @file
> + * @brief MCI card host interface for S3C2440 CPU
> + */
> +
> +/* #define DEBUG */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <mci.h>
> +#include <errno.h>
> +#include <clock.h>
> +#include <asm/io.h>
> +#include <mach/mci.h>
> +#include <mach/s3c24xx-generic.h>
> +#include <mach/s3c24x0-iomap.h>
> +
> +#define SDICON 0x0
> +# define SDICON_SDRESET (1 << 8)
> +# define SDICON_MMCCLOCK (1 << 5) /* this is a clock type SD or MMC style WTF? */
> +# define SDICON_BYTEORDER (1 << 4)
> +# define SDICON_SDIOIRQ (1 << 3)
> +# define SDICON_RWAITEN (1 << 2)
> +# define SDICON_FIFORESET (1 << 1) /* reserved bit on 2440 ????? */
> +# define SDICON_CLKEN (1 << 0) /* enable/disable external clock */
> +
> +#define SDIPRE 0x4
> +
> +#define SDICMDARG 0x8
> +
> +#define SDICMDCON 0xc
> +# define SDICMDCON_ABORT (1 << 12)
> +# define SDICMDCON_WITHDATA (1 << 11)
> +# define SDICMDCON_LONGRSP (1 << 10)
> +# define SDICMDCON_WAITRSP (1 << 9)
> +# define SDICMDCON_CMDSTART (1 << 8)
> +# define SDICMDCON_SENDERHOST (1 << 6)
> +# define SDICMDCON_INDEX (0x3f)
> +
> +#define SDICMDSTAT 0x10
> +# define SDICMDSTAT_CRCFAIL (1 << 12)
> +# define SDICMDSTAT_CMDSENT (1 << 11)
> +# define SDICMDSTAT_CMDTIMEOUT (1 << 10)
> +# define SDICMDSTAT_RSPFIN (1 << 9)
> +# define SDICMDSTAT_XFERING (1 << 8)
> +# define SDICMDSTAT_INDEX (0xff)
> +
> +#define SDIRSP0 0x14
> +#define SDIRSP1 0x18
> +#define SDIRSP2 0x1C
> +#define SDIRSP3 0x20
> +
> +#define SDITIMER 0x24
> +#define SDIBSIZE 0x28
> +
> +#define SDIDCON 0x2c
> +# define SDIDCON_DS_BYTE (0 << 22)
> +# define SDIDCON_DS_HALFWORD (1 << 22)
> +# define SDIDCON_DS_WORD (2 << 22)
> +# define SDIDCON_IRQPERIOD (1 << 21)
> +# define SDIDCON_TXAFTERRESP (1 << 20)
> +# define SDIDCON_RXAFTERCMD (1 << 19)
> +# define SDIDCON_BUSYAFTERCMD (1 << 18)
> +# define SDIDCON_BLOCKMODE (1 << 17)
> +# define SDIDCON_WIDEBUS (1 << 16)
> +# define SDIDCON_DMAEN (1 << 15)
> +# define SDIDCON_STOP (0 << 14)
> +# define SDIDCON_DATSTART (1 << 14)
> +# define SDIDCON_DATMODE (3 << 12)
> +# define SDIDCON_BLKNUM (0xfff)
> +# define SDIDCON_XFER_READY ? ?(0 << 12)
> +# define SDIDCON_XFER_CHKSTART (1 << 12)
> +# define SDIDCON_XFER_RXSTART ?(2 << 12)
> +# define SDIDCON_XFER_TXSTART ?(3 << 12)
> +
> +#define SDIDCNT 0x30
> +# define SDIDCNT_BLKNUM_SHIFT 12
> +
> +#define SDIDSTA 0x34
> +# define SDIDSTA_RDYWAITREQ (1 << 10)
> +# define SDIDSTA_SDIOIRQDETECT (1 << 9)
> +# define SDIDSTA_FIFOFAIL (1 << 8) /* reserved on 2440 */
> +# define SDIDSTA_CRCFAIL (1 << 7)
> +# define SDIDSTA_RXCRCFAIL (1 << 6)
> +# define SDIDSTA_DATATIMEOUT (1 << 5)
> +# define SDIDSTA_XFERFINISH (1 << 4)
> +# define SDIDSTA_BUSYFINISH (1 << 3)
> +# define SDIDSTA_SBITERR (1 << 2) /* reserved on 2410a/2440 */
> +# define SDIDSTA_TXDATAON (1 << 1)
> +# define SDIDSTA_RXDATAON (1 << 0)
> +
> +#define SDIFSTA 0x38
> +# define SDIFSTA_FIFORESET (1<<16)
> +# define SDIFSTA_FIFOFAIL (3<<14) ?/* 3 is correct (2 bits) */
> +# define SDIFSTA_TFDET (1<<13)
> +# define SDIFSTA_RFDET (1<<12)
> +# define SDIFSTA_TFHALF (1<<11)
> +# define SDIFSTA_TFEMPTY (1<<10)
> +# define SDIFSTA_RFLAST (1<<9)
> +# define SDIFSTA_RFFULL (1<<8)
> +# define SDIFSTA_RFHALF (1<<7)
> +# define SDIFSTA_COUNTMASK (0x7f)
> +
> +#define SDIIMSK 0x3C
> +# define SDIIMSK_RESPONSECRC ? ?(1<<17)
> +# define SDIIMSK_CMDSENT ? ? ? ?(1<<16)
> +# define SDIIMSK_CMDTIMEOUT ? ? (1<<15)
> +# define SDIIMSK_RESPONSEND ? ? (1<<14)
> +# define SDIIMSK_READWAIT ? ? ? (1<<13)
> +# define SDIIMSK_SDIOIRQ ? ? ? ?(1<<12)
> +# define SDIIMSK_FIFOFAIL ? ? ? (1<<11)
> +# define SDIIMSK_CRCSTATUS ? ? ?(1<<10)
> +# define SDIIMSK_DATACRC ? ? ? ?(1<<9)
> +# define SDIIMSK_DATATIMEOUT ? ?(1<<8)
> +# define SDIIMSK_DATAFINISH ? ? (1<<7)
> +# define SDIIMSK_BUSYFINISH ? ? (1<<6)
> +# define SDIIMSK_SBITERR ? ? ? ?(1<<5) /* reserved 2440/2410a */
> +# define SDIIMSK_TXFIFOHALF ? ? (1<<4)
> +# define SDIIMSK_TXFIFOEMPTY ? ?(1<<3)
> +# define SDIIMSK_RXFIFOLAST ? ? (1<<2)
> +# define SDIIMSK_RXFIFOFULL ? ? (1<<1)
> +# define SDIIMSK_RXFIFOHALF ? ? (1<<0)
> +
> +#define SDIDATA 0x40
> +
> +#define CLOCKRATE_MIN (1 * 1000 * 1000)
> +#define CLOCKRATE_MAX (480 * 1000 * 1000)
> +
> +struct s3c_mci_host {
> + ? ? ? int ? ? ? ? ? ? bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
> + ? ? ? unsigned ? ? ? ?clock; ?/* current clock in Hz */
> + ? ? ? unsigned ? ? ? ?data_size; ? ? ?/* data transfer in bytes */
> +};
> +
> +/*
> + * There is only one host MCI hardware instance available.
> + * It makes no sense to dynamically allocate this data
> + */
> +static struct s3c_mci_host host_data;
> +
> +/**
> + * Finish a request
> + * @param hw_dev Host interface instance
> + *
> + * Just a little bit paranoia.
> + */
> +static void s3c_finish_request(struct device_d *hw_dev)
> +{
> + ? ? ? /* TODO ensure the engines are stopped */
> +}
> +
> +/* TODO GPIO feature is required for this architecture */
> +static unsigned gpio_get_value(unsigned val)
> +{
> + ? ? ? return 0;
> +}
> +
> +/**
> + * Detect if a card is plugged in
> + * @param hw_dev Host interface instance
> + * @return 0 if a card is plugged in
> + *
> + * Note: If there is no GPIO registered to detect if a card is present, we
> + * assume a card _is_ present.
> + */
> +static int s3c_mci_card_present(struct device_d *hw_dev)
> +{
> + ? ? ? struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)GET_HOST_PDATA(hw_dev);
> + ? ? ? int ret;
> +
> + ? ? ? if (pd->gpio_detect == 0)
> + ? ? ? ? ? ? ? return 0; ? ? ? /* assume the card is present */
> +
> + ? ? ? ret = gpio_get_value(pd->gpio_detect) ? 0 : 1;
> + ? ? ? return ret ^ pd->detect_invert;
> +}
> +
> +/**
> + * Setup a new clock frequency on this MCI bus
> + * @param hw_dev Host interface instance
> + * @param nc New clock value in Hz (can be 0)
> + * @return New clock value (may differ from 'nc')
> + */
> +static unsigned s3c_setup_clock_speed(struct device_d *hw_dev, unsigned nc)
> +{
> + ? ? ? unsigned clock;
> + ? ? ? uint32_t mci_psc;
> +
> + ? ? ? if (nc == 0)
> + ? ? ? ? ? ? ? return 0;
> +
> + ? ? ? clock = s3c24xx_get_pclk();
> + ? ? ? /* Calculate the required prescaler value to get the requested frequency */
> + ? ? ? mci_psc = (clock + (nc >> 2)) / nc;
> +
> + ? ? ? if (mci_psc > 256) {
> + ? ? ? ? ? ? ? mci_psc = 256;
> + ? ? ? ? ? ? ? pr_warning("SD/MMC clock might be too high!\n");
> + ? ? ? }
> +
> + ? ? ? writel(mci_psc - 1, hw_dev->map_base + SDIPRE);
> +
> + ? ? ? return clock / mci_psc;
> +}
> +
> +/**
> + * Reset the MCI engine (the hard way)
> + * @param hw_dev Host interface instance
> + *
> + * This will reset everything in all registers of this unit!
> + */
> +static void s3c_mci_reset(struct device_d *hw_dev)
> +{
> + ? ? ? /* reset the hardware */
> + ? ? ? writel(SDICON_SDRESET, hw_dev->map_base + SDICON);
> + ? ? ? /* wait until reset it finished */
> + ? ? ? while (readl(hw_dev->map_base + SDICON) & SDICON_SDRESET)
> + ? ? ? ? ? ? ? ;
> +}
> +
> +/**
> + * Initialize hard and software
> + * @param hw_dev Host interface instance
> + * @param mci_dev MCI device instance (might be NULL)
> + */
> +static int s3c_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
> +{
> + ? ? ? struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> +
> + ? ? ? s3c_mci_reset(hw_dev);
> +
> + ? ? ? /* restore last settings */
> + ? ? ? host_data->clock = s3c_setup_clock_speed(hw_dev, host_data->clock);
> + ? ? ? writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> + ? ? ? writel(SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
> + ? ? ? writel(512, hw_dev->map_base + SDIBSIZE);
> +
> + ? ? ? return 0;
> +}
> +
> +/**
> + * Prepare engine's bits for the next command transfer
> + * @param cmd_flags MCI's command flags
> + * @param data_flags MCI's data flags
> + * @return Register bits for this transfer
> + */
> +static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned data_flags)
> +{
> + ? ? ? uint32_t reg;
> +
> + ? ? ? /* source (=host) */
> + ? ? ? reg = SDICMDCON_SENDERHOST;
> +
> + ? ? ? if (cmd_flags & MMC_RSP_PRESENT) {
> + ? ? ? ? ? ? ? reg |= SDICMDCON_WAITRSP;
> + ? ? ? ? ? ? ? pr_debug("Command with response\n");
> + ? ? ? }
> + ? ? ? if (cmd_flags & MMC_RSP_136) {
> + ? ? ? ? ? ? ? reg |= SDICMDCON_LONGRSP;
> + ? ? ? ? ? ? ? pr_debug("Command with long response\n");
> + ? ? ? }
> + ? ? ? if (cmd_flags & MMC_RSP_CRC)
> + ? ? ? ? ? ? ? ; /* FIXME */
> + ? ? ? if (cmd_flags & MMC_RSP_BUSY)
> + ? ? ? ? ? ? ? ; /* FIXME */
> + ? ? ? if (cmd_flags & MMC_RSP_OPCODE)
> + ? ? ? ? ? ? ? ; /* FIXME */
> + ? ? ? if (data_flags != 0)
> + ? ? ? ? ? ? ? reg |= SDICMDCON_WITHDATA;
> +
> + ? ? ? return reg;
> +}
> +
> +/**
> + * Prepare engine's bits for the next data transfer
> + * @param hw_dev Host interface device instance
> + * @param data_flags MCI's data flags
> + * @return Register bits for this transfer
> + */
> +static uint32_t s3c_prepare_data_setup(struct device_d *hw_dev, unsigned data_flags)
> +{
> + ? ? ? struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> + ? ? ? uint32_t reg = SDIDCON_BLOCKMODE; ? ? ? /* block mode only is supported */
> +
> + ? ? ? if (host_data->bus_width == 1)
> + ? ? ? ? ? ? ? reg |= SDIDCON_WIDEBUS;
> +
> + ? ? ? /* enable any kind of data transfers on demand only */
> + ? ? ? if (data_flags & MMC_DATA_WRITE)
> + ? ? ? ? ? ? ? reg |= SDIDCON_TXAFTERRESP | SDIDCON_XFER_TXSTART;
> +
> + ? ? ? if (data_flags & MMC_DATA_READ)
> + ? ? ? ? ? ? ? reg |= SDIDCON_RXAFTERCMD | SDIDCON_XFER_RXSTART;
> +
> + ? ? ? /* TODO: Support more than the 2440 CPU */
> + ? ? ? reg |= SDIDCON_DS_WORD | SDIDCON_DATSTART;
> +
> + ? ? ? return reg;
> +}
> +
> +/**
> + * Terminate a current running transfer
> + * @param hw_dev Host interface device instance
> + * @return 0 on success
> + *
> + * Note: Try to stop a running transfer. This should not happen, as all
> + * transfers must complete in this driver. But who knows... ;-)
> + */
> +static int s3c_terminate_transfer(struct device_d *hw_dev)
> +{
> + ? ? ? unsigned stoptries = 3;
> +
> + ? ? ? while (readl(hw_dev->map_base + SDIDSTA) & (SDIDSTA_TXDATAON | SDIDSTA_RXDATAON)) {
> + ? ? ? ? ? ? ? pr_debug("Transfer still in progress.\n");
> +
> + ? ? ? ? ? ? ? writel(SDIDCON_STOP, hw_dev->map_base + SDIDCON);
> + ? ? ? ? ? ? ? s3c_mci_initialize(hw_dev, NULL);
> +
> + ? ? ? ? ? ? ? if ((stoptries--) == 0) {
> + ? ? ? ? ? ? ? ? ? ? ? pr_warning("Cannot stop the engine!\n");
> + ? ? ? ? ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +/**
> + * Setup registers for data transfer
> + * @param hw_dev Host interface device instance
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_prepare_data_transfer(struct device_d *hw_dev, struct mci_data *data)
> +{
> + ? ? ? uint32_t reg;
> +
> + ? ? ? writel(data->blocksize, hw_dev->map_base + SDIBSIZE);
> + ? ? ? reg = s3c_prepare_data_setup(hw_dev, data->flags);
> + ? ? ? reg |= data->blocks & SDIDCON_BLKNUM;
> + ? ? ? writel(reg, hw_dev->map_base + SDIDCON);
> + ? ? ? writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> +
> + ? ? ? return 0;
> +}
> +
> +/**
> + * Send a command and receive the response
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_send_command(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> + ? ? ? uint32_t reg, t1;
> + ? ? ? int rc;
> +
> + ? ? ? writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> +
> + ? ? ? /* setup argument */
> + ? ? ? writel(cmd->cmdarg, hw_dev->map_base + SDICMDARG);
> +
> + ? ? ? /* setup command and transfer characteristic */
> + ? ? ? reg = s3c_prepare_command_setup(cmd->resp_type, data != NULL ? data->flags : 0);
> + ? ? ? reg |= cmd->cmdidx & SDICMDCON_INDEX;
> +
> + ? ? ? /* run the command right now */
> + ? ? ? writel(reg | SDICMDCON_CMDSTART, hw_dev->map_base + SDICMDCON);
> + ? ? ? t1 = readl(hw_dev->map_base + SDICMDSTAT);
> + ? ? ? /* wait until command is done */
> + ? ? ? while (1) {
> + ? ? ? ? ? ? ? reg = readl(hw_dev->map_base + SDICMDSTAT);
> + ? ? ? ? ? ? ? /* done? */
> + ? ? ? ? ? ? ? if (cmd->resp_type & MMC_RSP_PRESENT) {
> + ? ? ? ? ? ? ? ? ? ? ? if (reg & SDICMDSTAT_RSPFIN) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? writel(SDICMDSTAT_RSPFIN, hw_dev->map_base + SDICMDSTAT); /* required??? */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rc = 0;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? } else {
> + ? ? ? ? ? ? ? ? ? ? ? if (reg & SDICMDSTAT_CMDSENT) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? writel(SDICMDSTAT_CMDSENT, hw_dev->map_base + SDICMDSTAT); /* required??? */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rc = 0;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? /* timeout? */
> + ? ? ? ? ? ? ? if (reg & SDICMDSTAT_CMDTIMEOUT) {
> + ? ? ? ? ? ? ? ? ? ? ? writel(SDICMDSTAT_CMDTIMEOUT, hw_dev->map_base + SDICMDSTAT); /* required??? */
> + ? ? ? ? ? ? ? ? ? ? ? rc = -ETIMEDOUT;
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? if ((rc == 0) && (cmd->resp_type & MMC_RSP_PRESENT)) {
> + ? ? ? ? ? ? ? cmd->response[0] = readl(hw_dev->map_base + SDIRSP0);
> + ? ? ? ? ? ? ? cmd->response[1] = readl(hw_dev->map_base + SDIRSP1);
> + ? ? ? ? ? ? ? cmd->response[2] = readl(hw_dev->map_base + SDIRSP2);
> + ? ? ? ? ? ? ? cmd->response[3] = readl(hw_dev->map_base + SDIRSP3);
> + ? ? ? }
> + ? ? ? /* do not disable the clock! */
> + ? ? ? return rc;
> +}
> +
> +/**
> + * Clear major registers prior a new transaction
> + * @param hw_dev Host interface device instance
> + * @return 0 on success
> + *
> + * FIFO clear is only necessary on 2440, but doesn't hurt on 2410
> + */
> +static int s3c_prepare_engine(struct device_d *hw_dev)
> +{
> + ? ? ? int rc;
> +
> + ? ? ? rc = s3c_terminate_transfer(hw_dev);
> + ? ? ? if (rc != 0)
> + ? ? ? ? ? ? ? return rc;
> +
> + ? ? ? writel(-1, hw_dev->map_base + SDICMDSTAT);
> + ? ? ? writel(-1, hw_dev->map_base + SDIDSTA);
> + ? ? ? writel(-1, hw_dev->map_base + SDIFSTA);
> +
> + ? ? ? return 0;
> +}
> +
> +/**
> + * Handle MCI commands without data
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @return 0 on success
> + *
> + * This functions handles the following MCI commands:
> + * - "broadcast command (BC)" without a response
> + * - "broadcast commands with response (BCR)"
> + * - "addressed command (AC)" with response, but without data
> + */
> +static int s3c_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
> +{
> + ? ? ? int rc;
> +
> + ? ? ? rc = s3c_prepare_engine(hw_dev);
> + ? ? ? if (rc != 0)
> + ? ? ? ? ? ? ? return 0;
> +
> + ? ? ? return s3c_send_command(hw_dev, cmd, NULL);
> +}
> +
> +/**
> + * Read one block of data from the FIFO
> + * @param hw_dev Host interface device instance
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_mci_read_block(struct device_d *hw_dev, struct mci_data *data)
> +{
> + ? ? ? uint32_t *p;
> + ? ? ? unsigned cnt, data_size;
> +
> +#define READ_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_RXCRCFAIL | SDIDSTA_DATATIMEOUT)
> +
> + ? ? ? p = (uint32_t*)data->dest;
> + ? ? ? data_size = data->blocksize * data->blocks;
> +
> + ? ? ? while (data_size > 0) {
> +
> + ? ? ? ? ? ? ? /* serious error? */
> + ? ? ? ? ? ? ? if (readl(hw_dev->map_base + SDIDSTA) & READ_REASON_TO_FAIL) {
> + ? ? ? ? ? ? ? ? ? ? ? pr_err("Failed while reading data\n");
> + ? ? ? ? ? ? ? ? ? ? ? return -EIO;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? /* now check the FIFO status */
> + ? ? ? ? ? ? ? if (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_FIFOFAIL) {
> + ? ? ? ? ? ? ? ? ? ? ? pr_err("Data loss due to FIFO overflow when reading\n");
> + ? ? ? ? ? ? ? ? ? ? ? return -EIO;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? /* we only want to read full words */
> + ? ? ? ? ? ? ? cnt = (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) >> 2;
> +
> + ? ? ? ? ? ? ? /* read one chunk of data from the FIFO */
> + ? ? ? ? ? ? ? while (cnt--) {
> + ? ? ? ? ? ? ? ? ? ? ? *p = readl(hw_dev->map_base + SDIDATA);
> + ? ? ? ? ? ? ? ? ? ? ? p++;
> + ? ? ? ? ? ? ? ? ? ? ? if (data_size >= 4)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data_size -= 4;
> + ? ? ? ? ? ? ? ? ? ? ? else {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data_size = 0;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +/**
> + * Write one block of data into the FIFO
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + *
> + * We must ensure data in the FIFO when the command phase changes into the
> + * data phase. To ensure this, the FIFO gets filled first, then the command.
> + */
> +static int s3c_mci_write_block(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> + ? ? ? const uint32_t *p = (const uint32_t*)data->src;
> + ? ? ? unsigned cnt, data_size;
> + ? ? ? uint32_t reg;
> +
> +#define WRITE_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_DATATIMEOUT)
> +
> + ? ? ? data_size = data->blocksize * data->blocks;
> + ? ? ? /*
> + ? ? ? ?* With high clock rates we must fill the FIFO as early as possible
> + ? ? ? ?* Its size is 16 words. We assume its empty, when this function is
> + ? ? ? ?* entered.
> + ? ? ? ?*/
> + ? ? ? cnt = 16;
> + ? ? ? while (cnt--) {
> + ? ? ? ? ? ? ? writel(*p, hw_dev->map_base + SDIDATA);
> + ? ? ? ? ? ? ? p++;
> + ? ? ? ? ? ? ? if (data_size >= 4)
> + ? ? ? ? ? ? ? ? ? ? ? data_size -= 4;
> + ? ? ? ? ? ? ? else {
> + ? ? ? ? ? ? ? ? ? ? ? data_size = 0;
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? /* data is now in place and waits for transmitt. Start the command right now */
> + ? ? ? s3c_send_command(hw_dev, cmd, data);
> +
> + ? ? ? if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
> + ? ? ? ? ? ? ? pr_err("Command fails immediatly due to FIFO underrun when writing %08X\n", reg);
> + ? ? ? ? ? ? ? return -EIO;
> + ? ? ? }
> +
> + ? ? ? while (data_size > 0) {
> +
> + ? ? ? ? ? ? ? if (readl(hw_dev->map_base + SDIDSTA) & WRITE_REASON_TO_FAIL) {
> + ? ? ? ? ? ? ? ? ? ? ? pr_err("Failed writing data\n");
> + ? ? ? ? ? ? ? ? ? ? ? return -EIO;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? /* now check the FIFO status */
> + ? ? ? ? ? ? ? if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
> + ? ? ? ? ? ? ? ? ? ? ? pr_err("Data loss due to FIFO underrun when writing %08X\n", reg);
> + ? ? ? ? ? ? ? ? ? ? ? return -EIO;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? /* we only want to write full words */
> + ? ? ? ? ? ? ? cnt = 16 - (((readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) + 3) >> 2);
> +
> + ? ? ? ? ? ? ? /* fill the FIFO if it has free entries */
> + ? ? ? ? ? ? ? while (cnt--) {
> + ? ? ? ? ? ? ? ? ? ? ? writel(*p, hw_dev->map_base + SDIDATA);
> + ? ? ? ? ? ? ? ? ? ? ? p++;
> + ? ? ? ? ? ? ? ? ? ? ? if (data_size >= 4)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data_size -= 4;
> + ? ? ? ? ? ? ? ? ? ? ? else {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data_size = 0;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +/**
> + * Handle MCI commands with or without data
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> +*/
> +static int s3c_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> + ? ? ? int rc;
> +
> + ? ? ? rc = s3c_prepare_engine(hw_dev);
> + ? ? ? if (rc != 0)
> + ? ? ? ? ? ? ? return rc;
> +
> + ? ? ? rc = s3c_prepare_data_transfer(hw_dev, data);
> + ? ? ? if (rc != 0)
> + ? ? ? ? ? ? ? return rc;
> +
> + ? ? ? if (data->flags & MMC_DATA_READ) {
> + ? ? ? ? ? ? ? s3c_send_command(hw_dev, cmd, data);
> + ? ? ? ? ? ? ? rc = s3c_mci_read_block(hw_dev, data);
> + ? ? ? ? ? ? ? if (rc == 0) {
> + ? ? ? ? ? ? ? ? ? ? ? while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ;
> + ? ? ? ? ? ? ? } else
> + ? ? ? ? ? ? ? ? ? ? ? s3c_terminate_transfer(hw_dev);
> + ? ? ? }
> +
> + ? ? ? if (data->flags & MMC_DATA_WRITE) {
> + ? ? ? ? ? ? ? rc = s3c_mci_write_block(hw_dev, cmd, data);
> + ? ? ? ? ? ? ? if (rc == 0) {
> + ? ? ? ? ? ? ? ? ? ? ? while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ;
> + ? ? ? ? ? ? ? } else
> + ? ? ? ? ? ? ? ? ? ? ? s3c_terminate_transfer(hw_dev);
> + ? ? ? }
> + ? ? ? writel(0, hw_dev->map_base + SDIDCON);
> +
> + ? ? ? return rc;
> +}
> +
> +/* ------------------------- MCI API -------------------------------------- */
> +
> +/**
> + * Keep the attached MMC/SD unit in a well know state
> + * @param hw_dev Host interface instance
> + * @param mci_dev MCI device instance
> + * @return 0 on success, negative value else
> + */
> +static int mci_reset(struct device_d *hw_dev, struct device_d *mci_dev)
> +{
> + ? ? ? return s3c_mci_initialize(hw_dev, mci_dev);
> +}
> +
> +/**
> + * Process one command to the MCI card
> + * @param hw_dev Host interface instance
> + * @param cmd The command to process
> + * @param data The data to handle in the command (can be NULL)
> + * @return 0 on success, negative value else
> + */
> +static int mci_request(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> + ? ? ? int rc;
> +
> + ? ? ? /* enable clock */
> + ? ? ? writel(readl(hw_dev->map_base + SDICON) | SDICON_CLKEN, hw_dev->map_base + SDICON);
> +
> + ? ? ? if ((cmd->resp_type == 0) || (data == NULL))
> + ? ? ? ? ? ? ? rc = s3c_mci_std_cmds(hw_dev, cmd);
> + ? ? ? else
> + ? ? ? ? ? ? ? rc = s3c_mci_adtc(hw_dev, cmd, data); ? /* with response and data */
> +
> + ? ? ? s3c_finish_request(hw_dev);
> +
> + ? ? ? /* disable clock */
> + ? ? ? writel(readl(hw_dev->map_base + SDICON) & ~SDICON_CLKEN, hw_dev->map_base + SDICON);
> + ? ? ? return rc;
> +}
> +
> +/**
> + * Setup the bus width and IO speed
> + * @param hw_dev Host interface device instance
> + * @param mci_dev MCI device instance
> + * @param bus_width New bus width value (1, 4 or 8)
> + * @param clock New clock in Hz (can be '0' to disable the clock)
> + */
> +static void mci_set_ios(struct device_d *hw_dev, struct device_d *mci_dev, unsigned bus_width, unsigned clock)
> +{
> + ? ? ? struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> + ? ? ? struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
> + ? ? ? uint32_t reg;
> +
> + ? ? ? switch (bus_width) {
> + ? ? ? case 8: ? ? ? ? /* no 8 bit support, fall back to 4 bit */
> + ? ? ? case 4:
> + ? ? ? ? ? ? ? host_data->bus_width = 1;
> + ? ? ? ? ? ? ? mci_pdata->bus_width = 4; ? ? ? /* 4 bit is possible */
> + ? ? ? ? ? ? ? break;
> + ? ? ? default:
> + ? ? ? ? ? ? ? host_data->bus_width = 0;
> + ? ? ? ? ? ? ? mci_pdata->bus_width = 1; ? ? ? /* 1 bit is possible */
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> +
> + ? ? ? reg = readl(hw_dev->map_base + SDICON);
> + ? ? ? if (clock) {
> + ? ? ? ? ? ? ? /* setup the IO clock frequency and enable it */
> + ? ? ? ? ? ? ? mci_pdata->clock = host_data->clock = s3c_setup_clock_speed(hw_dev, clock);
> + ? ? ? ? ? ? ? reg |= SDICON_CLKEN; ? ?/* enable the clock */
> + ? ? ? } else {
> + ? ? ? ? ? ? ? reg &= ~SDICON_CLKEN; ? /* disable the clock */
> + ? ? ? ? ? ? ? mci_pdata->clock = host_data->clock = 0;
> + ? ? ? }
> + ? ? ? writel(reg, hw_dev->map_base + SDICON);
> +
> + ? ? ? pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", mci_pdata->bus_width, mci_pdata->clock);
> +}
> +
> +/* ----------------------------------------------------------------------- */
> +
> +#ifdef CONFIG_MCI_INFO
> +static void s3c_info(struct device_d *hw_dev)
> +{
> + ? ? ? struct s3c_mci_host *host = (struct s3c_mci_host*)hw_dev->priv;
> + ? ? ? struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
> +
> + ? ? ? printf(" ?Bus data width: %d bit\n", host->bus_width == 1 ? 4 : 1);
> + ? ? ? printf(" ?Bus frequency: %u Hz\n", host->clock);
> + ? ? ? printf(" ? Frequency limits: ");
> + ? ? ? if (pd->f_min == 0)
> + ? ? ? ? ? ? ? printf("no lower limit ");
> + ? ? ? else
> + ? ? ? ? ? ? ? printf("%u Hz lower limit ", pd->f_min);
> + ? ? ? if (pd->f_max == 0)
> + ? ? ? ? ? ? ? printf("- no upper limit");
> + ? ? ? else
> + ? ? ? ? ? ? ? printf("- %u Hz upper limit", pd->f_max);
> + ? ? ? printf("\n ?Card detection support: %s\n", pd->gpio_detect != 0 ? "yes" : "no");
> +}
> +#endif
> +
> +/*
> + * There is only one host MCI hardware instance available.
> + * It makes no sense to dynamically allocate this data
> + */
> +static struct mci_platformdata mci_pdata = {
> + ? ? ? .send_cmd = mci_request,
> + ? ? ? .set_ios = mci_set_ios,
> + ? ? ? .init = mci_reset,
> +};
> +
> +static int s3c_mci_probe(struct device_d *hw_dev)
> +{
> + ? ? ? struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
> +
> + ? ? ? /* TODO replace by the global func: enable the SDI unit clock */
> + ? ? ? writel(readl(S3C24X0_CLOCK_POWER_BASE + 0x0c) | 0x200,S3C24X0_CLOCK_POWER_BASE + 0x0c);
> +
> + ? ? ? if (pd == NULL) {
> + ? ? ? ? ? ? ? pr_err("Missing platform data\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? hw_dev->priv = &host_data;
> + ? ? ? mci_pdata.hw_dev = hw_dev;
> +
> + ? ? ? /* feed forward the platform specific values */
> + ? ? ? mci_pdata.voltages = pd->voltages;
> + ? ? ? mci_pdata.host_caps = pd->caps;
> + ? ? ? mci_pdata.f_min = pd->f_min == 0 ? CLOCKRATE_MIN : pd->f_min;
> + ? ? ? mci_pdata.f_max = pd->f_max == 0 ? CLOCKRATE_MAX : pd->f_max;
> +
> + ? ? ? /*
> + ? ? ? ?* Start the clock to let the engine and the card finishes its startup
> + ? ? ? ?*/
> + ? ? ? host_data.clock = s3c_setup_clock_speed(hw_dev, mci_pdata.f_min);
> + ? ? ? writel(SDICON_FIFORESET | SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
> +
> + ? ? ? return mci_register(&mci_pdata);
> +}
> +
> +static struct driver_d s3c_mci_driver = {
> + ? ? ? ?.name ?= "s3c_mci",
> + ? ? ? ?.probe = s3c_mci_probe,
> +#ifdef CONFIG_MCI_INFO
> + ? ? ? .info = s3c_info,
> +#endif
> +};
> +
> +static int s3c_mci_init_driver(void)
> +{
> + ? ? ? ?register_driver(&s3c_mci_driver);
> + ? ? ? ?return 0;
> +}
> +
> +device_initcall(s3c_mci_init_driver);
> --
> 1.7.2.3
>
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From s.hauer at pengutronix.de  Thu Oct  7 08:45:03 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 Oct 2010 14:45:03 +0200
Subject: Code "borrowed" without attribution to original authors
In-Reply-To: <20101007084530.82D8E153A7E@gemini.denx.de>
References: <20101005135213.24F871539A0@gemini.denx.de>
	<20101006072749.GR28242@pengutronix.de>
	<20101006135644.8D7051539A0@gemini.denx.de>
	<20101007080646.GB28242@pengutronix.de>
	<20101007084530.82D8E153A7E@gemini.denx.de>
Message-ID: <20101007124503.GF28242@pengutronix.de>

On Thu, Oct 07, 2010 at 10:45:30AM +0200, Wolfgang Denk wrote:
> Dear Sascha,
> 
> In message <20101007080646.GB28242 at pengutronix.de> you wrote:
> >
> > > Do you think such a short hint cannot be done?
> > 
> > We can (and actually I prefered Jean-Christophe had done it) add a
> > hint in the commit log saying that the code is derived from U-Boot,
> > but I will not dig through the U-Boot commit log to see who actually
> > made a commit looking similar to a barebox commit, and I do not expect
> > anyone to do so.
> 
> It is trivial to find the commits that added the lines you are
> copying from - just run "git blame" on that file.

You showed me in a long mail that it's enough of contribution if the
string 'Linux' shows up in the commit log and now you want me to
reference particular commits? That's cool.

Anyway, I don't want to run further into your
barebox-sucks-from-the-community argumentation.

Jean-Christophe, I just reverted the offending commits. Can you please
update the patches to contain credits to U-Boot and Marian
Balakowicz?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Thu Oct  7 09:24:11 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 15:24:11 +0200
Subject: [RFC] Add MCI card support to barebox
Message-ID: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>

This is the second try to send the patch stack via git...hopefully its
complete this time.

This patch is based on some work Sascha made already. I tried to bring in some
light into the MCI framework routines as they are based on code from another
project. Bear with me, if I didn't add useful comments all over the code. I
just wasn't able to understand what happen... If someone has more knowledge
about MCI cards, please take a look at the FIXME/TODOs and make me understand
why the code does what it does.

There is no regular user, yet. The first platform (S3C2440 based) I did the
tests on, is not part of barebox (and will not) and the other platfrom (i.MX23
ChumbOne) is not yet part of barebox. But will coming soon.

Comments are welcome.

Regards,
Juergen



From jbe at pengutronix.de  Thu Oct  7 09:24:12 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 15:24:12 +0200
Subject: [PATCH 1/7] x-functions do not return in case of failure.
In-Reply-To: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286457858-29771-2-git-send-email-jbe@pengutronix.de>

Remove error handling, because in case of failure the xzalloc() function
does not return.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/ata/disk_drive.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index 250dada..6d5c87a 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -281,10 +281,6 @@ static int disk_probe(struct device_d *dev)
 
 	/* It seems a valuable disk. Register it */
 	disk_cdev = xzalloc(sizeof(struct cdev));
-	if (disk_cdev == NULL) {
-		dev_err(dev, "Out of memory\n");
-		return -ENOMEM;
-	}
 
 	/*
 	 * BIOS based disks needs special handling. Not the driver can
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 09:24:13 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 15:24:13 +0200
Subject: [PATCH 2/7] Make the disk driver less noisy
In-Reply-To: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286457858-29771-3-git-send-email-jbe@pengutronix.de>

In real life this output is only a "nice to have", but most of the time
its useless and confusing. So, make it a debug feature for the interested
developer.

Note: This is in preparation to add MCI card support, which mostly come with
a partition table and can be handled like a disk drive.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/ata/disk_drive.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index 6d5c87a..a54a283 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -105,7 +105,7 @@ static int disk_register_partitions(struct device_d *dev, struct partition_entry
 			if (table[part_order[i]].partition_size > 0x7fffff)
 				continue;
 #endif
-			dev_info(dev, "Registering partition %s to drive %s\n", partition_name, drive_name);
+			dev_dbg(dev, "Registering partition %s to drive %s\n", partition_name, drive_name);
 			rc = devfs_add_partition(drive_name,
 				table[part_order[i]].partition_start * SECTOR_SIZE,
 				table[part_order[i]].partition_size * SECTOR_SIZE,
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 09:24:14 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 15:24:14 +0200
Subject: [PATCH 3/7] Don't use a sector buffer on stack
In-Reply-To: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286457858-29771-4-git-send-email-jbe@pengutronix.de>

Using a temp. buffer for a disk sector on the stack, seems not work. Doing so
lets the system run crazy (the stack seems to be destroyd). Don't know the
correct stack handling on ARM, but (IMHO) I also can exclude any writing across
the buffer boundaries.

Using a temp. buffer via malloc() runs also on ARM.

Note: This patch was required to add MCI card support, which can be handled
like a disk drive.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/ata/disk_drive.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index a54a283..e9d855b 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -34,6 +34,7 @@
 #include <errno.h>
 #include <string.h>
 #include <linux/kernel.h>
+#include <malloc.h>
 
 /**
  * Description of one partition table entry (D*S type)
@@ -268,15 +269,18 @@ static struct file_operations disk_ops = {
  */
 static int disk_probe(struct device_d *dev)
 {
-	uint8_t sector[512];
+	uint8_t *sector;
 	int rc;
 	struct ata_interface *intf = dev->platform_data;
 	struct cdev *disk_cdev;
 
+	sector = xmalloc(SECTOR_SIZE);
+
 	rc = intf->read(dev, 0, 1, sector);
 	if (rc != 0) {
 		dev_err(dev, "Cannot read MBR of this device\n");
-		return -1;
+		rc = -ENODEV;
+		goto on_error;
 	}
 
 	/* It seems a valuable disk. Register it */
@@ -305,7 +309,8 @@ static int disk_probe(struct device_d *dev)
 
 	if ((sector[510] != 0x55) || (sector[511] != 0xAA)) {
 		dev_info(dev, "No partition table found\n");
-		return 0;
+		rc = 0;
+		goto on_error;
 	}
 
 	/* guess the size of this drive */
@@ -313,9 +318,11 @@ static int disk_probe(struct device_d *dev)
 	dev_info(dev, "Drive size guessed to %u kiB\n", dev->size / 1024);
 	disk_cdev->size = dev->size;
 
-	disk_register_partitions(dev, (struct partition_entry*)&sector[446]);
+	rc = disk_register_partitions(dev, (struct partition_entry*)&sector[446]);
 
-	return 0;
+on_error:
+	free(sector);
+	return rc;
 }
 
 #ifdef CONFIG_ATA_BIOS
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 09:24:15 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 15:24:15 +0200
Subject: [PATCH 4/7] Don't try to guess the size of a disk if its size value
	is already given
In-Reply-To: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286457858-29771-5-git-send-email-jbe@pengutronix.de>

Guessing the size of an attached harddisk (access via x86 BIOS) was needed
due to the fact, barebox can't query this information from the BIOS easily.

But with the SD/MMC cards, there will be a second user of the generic disk
handling routines. And with this media it is very easy to know its size.

This patch provides a workaround to keep the guessing feature if the size of
the registered disk is 0. If it is not 0, the given value will be used instead.

Note: This is in preparation to add MCI card support, which can be handled
like a disk drive.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/x86/boards/x86_generic/generic_pc.c |    2 +-
 drivers/ata/disk_drive.c                 |   26 +++++++++++++++++---------
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/arch/x86/boards/x86_generic/generic_pc.c b/arch/x86/boards/x86_generic/generic_pc.c
index a6cd7e0..b9c31aa 100644
--- a/arch/x86/boards/x86_generic/generic_pc.c
+++ b/arch/x86/boards/x86_generic/generic_pc.c
@@ -46,7 +46,7 @@ static struct device_d sdram_dev = {
 static struct device_d bios_disk_dev = {
 	.id		= -1,
 	.name		= "biosdrive",
-	.size		= 1,
+	.size		= 0,	/* auto guess */
 };
 
 /*
diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index e9d855b..9db408c 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -23,6 +23,7 @@
  * @brief Generic disk drive support
  *
  * @todo Support for disks larger than 4 GiB
+ * @todo Reliable size detection for BIOS based disks (on x86 only)
  */
 
 #include <stdio.h>
@@ -298,11 +299,16 @@ static int disk_probe(struct device_d *dev)
 	else
 #endif
 		disk_cdev->name = asprintf("disk%d", dev->id);
-	/**
-	 * @todo we need the size of the drive, else its nearly impossible
-	 * to do anything with it (at least with the generic routines)
-	 */
-	disk_cdev->size = 32;	/* FIXME */
+
+	/* On x86, BIOS based disks are coming without a valid .size field */
+	if (dev->size == 0) {
+		/*
+		 * We need always the size of the drive, else its nearly impossible
+		 * to do anything with it (at least with the generic routines)
+		 */
+		disk_cdev->size = 32;
+	} else
+		disk_cdev->size = dev->size;
 	disk_cdev->ops = &disk_ops;
 	disk_cdev->dev = dev;
 	devfs_create(disk_cdev);
@@ -313,10 +319,12 @@ static int disk_probe(struct device_d *dev)
 		goto on_error;
 	}
 
-	/* guess the size of this drive */
-	dev->size = disk_guess_size(dev, (struct partition_entry*)&sector[446]) * SECTOR_SIZE;
-	dev_info(dev, "Drive size guessed to %u kiB\n", dev->size / 1024);
-	disk_cdev->size = dev->size;
+	if (dev->size == 0) {
+		/* guess the size of this drive if not otherwise given */
+		dev->size = disk_guess_size(dev, (struct partition_entry*)&sector[446]) * SECTOR_SIZE;
+		dev_info(dev, "Drive size guessed to %u kiB\n", dev->size / 1024);
+		disk_cdev->size = dev->size;
+	}
 
 	rc = disk_register_partitions(dev, (struct partition_entry*)&sector[446]);
 
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 09:24:16 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 15:24:16 +0200
Subject: [PATCH 5/7] Add MCI card support to barebox
In-Reply-To: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286457858-29771-6-git-send-email-jbe@pengutronix.de>

This adds the basic framework to handle MCI cards in barebox.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/Kconfig        |    1 +
 drivers/Makefile       |    1 +
 drivers/mci/Kconfig    |   30 ++
 drivers/mci/Makefile   |    1 +
 drivers/mci/mci-core.c | 1308 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/mci.h          |  230 +++++++++
 6 files changed, 1571 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/Kconfig
 create mode 100644 drivers/mci/Makefile
 create mode 100644 drivers/mci/mci-core.c
 create mode 100644 include/mci.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index f7154c6..13235f3 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -9,6 +9,7 @@ source "drivers/mtd/Kconfig"
 source "drivers/ata/Kconfig"
 source "drivers/usb/Kconfig"
 source "drivers/video/Kconfig"
+source "drivers/mci/Kconfig"
 source "drivers/clk/Kconfig"
 
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 706e1c8..71d34f9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -6,5 +6,6 @@ obj-y	+= usb/
 obj-$(CONFIG_ATA) += ata/
 obj-$(CONFIG_SPI) += spi/
 obj-$(CONFIG_I2C) += i2c/
+obj-$(CONFIG_MCI) += mci/
 obj-$(CONFIG_VIDEO) += video/
 obj-y	+= clk/
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
new file mode 100644
index 0000000..0abadb3
--- /dev/null
+++ b/drivers/mci/Kconfig
@@ -0,0 +1,30 @@
+menuconfig MCI
+	bool "MCI drivers                   "
+	select ATA
+	select ATA_DISK
+	help
+	  Add support for MCI drivers, used to handle MMC and SD cards
+
+if MCI
+
+comment "--- Feature list ---"
+
+config MCI_STARTUP
+	bool "Probe on system start"
+	help
+	  Say 'y' here if the MCI framework should probe for attached MCI cards
+	  on system start up. This is required if the card carries barebox's
+	  environment (for example on systems where the MCI card is the sole
+	  bootmedia). Otherwise probing run on demand with "mci*.probe=1"
+
+config MCI_INFO
+	bool "MCI Info"
+	depends on CMD_DEVINFO
+	default y
+	help
+	  This entry adds more info about the attached MCI card, when the
+	  'devinfo' command is used on the mci device.
+
+comment "--- MCI host drivers ---"
+
+endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
new file mode 100644
index 0000000..927618f
--- /dev/null
+++ b/drivers/mci/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MCI)	+= mci-core.o
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
new file mode 100644
index 0000000..a31b96f
--- /dev/null
+++ b/drivers/mci/mci-core.c
@@ -0,0 +1,1308 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is havily inspired and in parts from the u-boot project:
+ *
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* #define DEBUG */
+
+#include <init.h>
+#include <common.h>
+#include <mci.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm-generic/div64.h>
+#include <asm/byteorder.h>
+#include <ata.h>
+
+#define MAX_BUFFER_NUMBER 0xffffffff
+
+/**
+ * @file
+ * @brief Memory Card framework
+ *
+ * Checked with the following cards:
+ * - old Canon SD 16 MiB, does not like the 0x08 command (SD_CMD_SEND_IF_COND) -> failed
+ * - Kingston 512 MiB
+ * - SanDisk 512 MiB
+ * - Transcend SD Ultra, 1 GiB (Industrial)
+ */
+
+/**
+ * Call the MMC/SD instance driver to run the command on the MMC/SD card
+ * @param mci_dev MCI instance
+ * @param cmd The information about the command to run
+ * @param data The data according to the command (can be NULL)
+ * @return Driver's answer (0 on success)
+ */
+static int mci_send_cmd(struct device_d *mci_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+
+	return (pdata->send_cmd)(pdata->hw_dev, cmd, data);
+}
+
+/**
+ * @param p Command definition to setup
+ * @param cmd Valid SD/MMC command (refer MMC_CMD_* / SD_CMD_*)
+ * @param arg Argument for the command (optional)
+ * @param response Command's response type (refer MMC_RSP_*)
+ *
+ * Note: When calling, the 'response' must match command's requirements
+ */
+static void mci_setup_cmd(struct mci_cmd *p, unsigned cmd, unsigned arg, unsigned response)
+{
+	p->cmdidx = cmd;
+	p->cmdarg = arg;
+	p->resp_type = response;
+}
+
+/**
+ * Setup SD/MMC card's blocklength to be used for future transmitts
+ * @param mci_dev MCI instance
+ * @param len Blocklength in bytes
+ * @return Transaction status (0 on success)
+ */
+static int mci_set_blocklen(struct device_d *mci_dev, unsigned len)
+{
+	struct mci_cmd cmd;
+
+	mci_setup_cmd(&cmd, MMC_CMD_SET_BLOCKLEN, len, MMC_RSP_R1);
+	return mci_send_cmd(mci_dev, &cmd, NULL);
+}
+
+/**
+ * Write one block of data to the card
+ * @param mci_dev MCI instance
+ * @param src Where to read from to write to the card
+ * @param blocknum Block number to write
+ * @return Transaction status (0 on success)
+ */
+static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned blocknum)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	mci_setup_cmd(&cmd,
+		MMC_CMD_WRITE_SINGLE_BLOCK,
+		mci->high_capacity != 0 ? blocknum : blocknum * mci->write_bl_len,
+		MMC_RSP_R1);
+
+	data.src = src;
+	data.blocks = 1;
+	data.blocksize = mci->write_bl_len;
+	data.flags = MMC_DATA_WRITE;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * Read one block of data from the card
+ * @param mci_dev MCI instance
+ * @param dst Where to store the data read from the card
+ * @param blocknum Block number to read
+ */
+static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned blocknum)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	mci_setup_cmd(&cmd,
+		MMC_CMD_READ_SINGLE_BLOCK,
+		mci->high_capacity != 0 ? blocknum : blocknum * mci->read_bl_len,
+		MMC_RSP_R1);
+
+	data.dest = dst;
+	data.blocks = 1;
+	data.blocksize = mci->read_bl_len;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * Reset the attached MMC/SD card
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mci_go_idle(struct device_d *mci_dev)
+{
+	struct mci_cmd cmd;
+	int err;
+
+	udelay(1000);
+
+	mci_setup_cmd(&cmd, MMC_CMD_GO_IDLE_STATE, 0, MMC_RSP_NONE);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+
+	if (err) {
+		pr_debug("Activating IDLE state failed: %d\n", err);
+		return err;
+	}
+
+	udelay(2000);	/* WTF? */
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int sd_send_op_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int timeout = 1000;
+	int err;
+
+	do {
+		mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, 0, MMC_RSP_R1);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+		if (err) {
+			pr_debug("Preparing SD for operating conditions failed: %d\n", err);
+			return err;
+		}
+
+		mci_setup_cmd(&cmd, SD_CMD_APP_SEND_OP_COND,
+			pdata->voltages | (mci->version == SD_VERSION_2 ? OCR_HCS : 0),
+			MMC_RSP_R3);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+		if (err) {
+			pr_debug("SD operation condition set failed: %d\n", err);
+			return err;
+		}
+		udelay(1000);
+	} while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
+
+	if (timeout <= 0) {
+		pr_debug("SD operation condition set timed out\n");
+		return -ENODEV;
+	}
+
+	if (mci->version != SD_VERSION_2)
+		mci->version = SD_VERSION_1_0;
+
+	mci->ocr = cmd.response[0];
+
+	mci->high_capacity = ((mci->ocr & OCR_HCS) == OCR_HCS);
+	mci->rca = 0;
+
+	return 0;
+}
+
+/**
+ * Setup the operation conditions to a MultiMediaCard
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mmc_send_op_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int timeout = 1000;
+	int err;
+
+	/* Some cards seem to need this */
+	mci_go_idle(mci_dev);
+
+	do {
+		mci_setup_cmd(&cmd, MMC_CMD_SEND_OP_COND, OCR_HCS | pdata->voltages, MMC_RSP_R3);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+
+		if (err) {
+			pr_debug("Preparing MMC for operating conditions failed: %d\n", err);
+			return err;
+		}
+
+		udelay(1000);
+	} while (!(cmd.response[0] & OCR_BUSY) && timeout--);
+
+	if (timeout <= 0) {
+		pr_debug("SD operation condition set timed out\n");
+		return -ENODEV;
+	}
+
+	mci->version = MMC_VERSION_UNKNOWN;
+	mci->ocr = cmd.response[0];
+
+	mci->high_capacity = ((mci->ocr & OCR_HCS) == OCR_HCS);
+	mci->rca = 0;
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param ext_csd Buffer for a 512 byte sized extended CSD
+ * @return Transaction status (0 on success)
+ *
+ * Note: Only cards newer than Version 1.1 (Physical Layer Spec) support this command
+ */
+static int mci_send_ext_csd(struct device_d *mci_dev, char *ext_csd)
+{
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	/* Get the Card Status Register */
+	mci_setup_cmd(&cmd, MMC_CMD_SEND_EXT_CSD, 0, MMC_RSP_R1);
+
+	data.dest = ext_csd;
+	data.blocks = 1;
+	data.blocksize = 512;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param set FIXME
+ * @param index FIXME
+ * @param value FIXME
+ * @return Transaction status (0 on success)
+ */
+static int mci_switch(struct device_d *mci_dev, unsigned set, unsigned index, unsigned value)
+{
+	struct mci_cmd cmd;
+
+	mci_setup_cmd(&cmd, MMC_CMD_SWITCH,
+		(MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+		(index << 16) |
+		(value << 8),
+		 MMC_RSP_R1b);
+
+	return mci_send_cmd(mci_dev, &cmd, NULL);
+}
+
+/**
+ * Change transfer frequency foa a MMC card
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mmc_change_freq(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	char ext_csd[512];	/* TODO why this works on ARM, while the same in the disk layer does not??? */
+	char cardtype;
+	int err;
+
+	mci->card_caps = 0;
+
+	/* Only version 4 supports high-speed */
+	if (mci->version < MMC_VERSION_4)
+		return 0;
+
+	mci->card_caps |= MMC_MODE_4BIT;
+
+	err = mci_send_ext_csd(mci_dev, ext_csd);
+	if (err) {
+		pr_debug("Preparing for frequency setup failed: %d\n", err);
+		return err;
+	}
+
+	if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
+		mci->high_capacity = 1;
+
+	cardtype = ext_csd[196] & 0xf;
+
+	err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
+
+	if (err) {
+		pr_debug("MMC frequency changing failed: %d\n", err);
+		return err;
+	}
+
+	/* Now check to see that it worked */
+	err = mci_send_ext_csd(mci_dev, ext_csd);
+
+	if (err) {
+		pr_debug("Verifying frequency change failed: %d\n", err);
+		return err;
+	}
+
+	/* No high-speed support */
+	if (!ext_csd[185])
+		return 0;
+
+	/* High Speed is set, there are two types: 52MHz and 26MHz */
+	if (cardtype & MMC_HS_52MHZ)
+		mci->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+	else
+		mci->card_caps |= MMC_MODE_HS;
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param mode FIXME
+ * @param group FIXME
+ * @param value FIXME
+ * @param resp FIXME
+ * @return Transaction status (0 on success)
+ */
+static int sd_switch(struct device_d *mci_dev, unsigned mode, unsigned group, unsigned value, uint8_t *resp)
+{
+	struct mci_cmd cmd;
+	struct mci_data data;
+	unsigned arg;
+
+	arg = (mode << 31) | 0xffffff;
+	arg &= ~(0xf << (group << 2));
+	arg |= value << (group << 2);
+
+	/* Switch the frequency */
+	mci_setup_cmd(&cmd, SD_CMD_SWITCH_FUNC, arg, MMC_RSP_R1);
+
+	data.dest = resp;
+	data.blocksize = 64;
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int sd_change_freq(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+	uint32_t switch_status[16];
+	uint scr[2];
+	int timeout;
+	int err;
+
+	pr_debug("Changing transfer frequency\n");
+	mci->card_caps = 0;
+
+	/* Read the SCR to find out if this card supports higher speeds */
+	mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, mci->rca << 16, MMC_RSP_R1);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Query SD card capabilities failed: %d\n", err);
+		return err;
+	}
+
+	mci_setup_cmd(&cmd, SD_CMD_APP_SEND_SCR, 0, MMC_RSP_R1);
+
+	timeout = 3;
+
+retry_scr:
+	pr_debug("Trying to read the SCR (try %d of %d)\n", 4 - timeout, 3);
+	data.dest = (char *)&scr;
+	data.blocksize = 8;
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+
+	err = mci_send_cmd(mci_dev, &cmd, &data);
+	if (err) {
+		pr_debug(" Catch error (%d)", err);
+		if (timeout--) {
+			pr_debug("-- retrying\n");
+			goto retry_scr;
+		}
+		pr_debug("-- giving up\n");
+		return err;
+	}
+
+	mci->scr[0] = __be32_to_cpu(scr[0]);
+	mci->scr[1] = __be32_to_cpu(scr[1]);
+
+	switch ((mci->scr[0] >> 24) & 0xf) {
+	case 0:
+		mci->version = SD_VERSION_1_0;
+		break;
+	case 1:
+		mci->version = SD_VERSION_1_10;
+		break;
+	case 2:
+		mci->version = SD_VERSION_2;
+		break;
+	default:
+		mci->version = SD_VERSION_1_0;
+		break;
+	}
+
+	/* Version 1.0 doesn't support switching */
+	if (mci->version == SD_VERSION_1_0)
+		return 0;
+
+	timeout = 4;
+	while (timeout--) {
+		err = sd_switch(mci_dev, SD_SWITCH_CHECK, 0, 1, (uint8_t*)&switch_status);
+		if (err) {
+			pr_debug("Checking SD transfer switch frequency feature failed: %d\n", err);
+			return err;
+		}
+
+		/* The high-speed function is busy.  Try again */
+		if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
+			break;
+	}
+
+	if (mci->scr[0] & SD_DATA_4BIT)
+		mci->card_caps |= MMC_MODE_4BIT;
+
+	/* If high-speed isn't supported, we return */
+	if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
+		return 0;
+
+	err = sd_switch(mci_dev, SD_SWITCH_SWITCH, 0, 1, (uint8_t*)&switch_status);
+	if (err) {
+		pr_debug("Switching SD transfer frequency failed: %d\n", err);
+		return err;
+	}
+
+	if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
+		mci->card_caps |= MMC_MODE_HS;
+
+	return 0;
+}
+
+/**
+ * Setup host's interface bus width and transfer frequency
+ * @param mci_dev MCI instance
+ */
+static void mci_set_ios(struct device_d *mci_dev)
+{
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+
+	(pdata->set_ios)(pdata->hw_dev, mci_dev, pdata->bus_width, pdata->clock);
+}
+
+/**
+ * Setup host's interface transfer frequency
+ * @param mci_dev MCI instance
+ * @param clock New clock in Hz to set
+ */
+static void mci_set_clock(struct device_d *mci_dev, unsigned clock)
+{
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+
+	/* check against any given limits */
+	if (clock > pdata->f_max)
+		clock = pdata->f_max;
+
+	if (clock < pdata->f_min)
+		clock = pdata->f_min;
+
+	pdata->clock = clock;	/* the new target frequency */
+	mci_set_ios(mci_dev);
+}
+
+/**
+ * Setup host's interface bus width
+ * @param mci_dev MCI instance
+ * @param width New interface bit width (1, 4 or 8)
+ */
+static void mci_set_bus_width(struct device_d *mci_dev, unsigned width)
+{
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+
+	pdata->bus_width = width;	/* the new target bus width */
+	mci_set_ios(mci_dev);
+}
+
+/**
+ * Extract card's version from its CSD
+ * @param mci_dev MCI instance
+ * @return 0 on success
+ */
+static void mci_detect_version_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int version;
+
+	if (mci->version == MMC_VERSION_UNKNOWN) {
+		/* the version is coded in the bits 127:126 (left aligned) */
+		version = (mci->csd[0] >> 26) & 0xf;	/* FIXME why other width? */
+
+		switch (version) {
+		case 0:
+			printf("Detecting a 1.2 revision card\n");
+			mci->version = MMC_VERSION_1_2;
+			break;
+		case 1:
+			printf("Detecting a 1.4 revision card\n");
+			mci->version = MMC_VERSION_1_4;
+			break;
+		case 2:
+			printf("Detecting a 2.2 revision card\n");
+			mci->version = MMC_VERSION_2_2;
+			break;
+		case 3:
+			printf("Detecting a 3.0 revision card\n");
+			mci->version = MMC_VERSION_3;
+			break;
+		case 4:
+			printf("Detecting a 4.0 revision card\n");
+			mci->version = MMC_VERSION_4;
+			break;
+		default:
+			printf("Unknow revision. Falling back to a 1.2 revision card\n");
+			mci->version = MMC_VERSION_1_2;
+			break;
+		}
+	}
+}
+
+/**
+ * meaning of the encoded 'unit' bits in the CSD's field 'TRAN_SPEED'
+ * (divided by 10 to be nice to platforms without floating point)
+ */
+static const unsigned tran_speed_unit[] = {
+	[0] = 10000,		/* 100 kbit/s */
+	[1] = 100000,		/* 1 Mbit/s */
+	[2] = 1000000,		/* 10 Mbit/s */
+	[3] = 10000000,		/* 100 Mbit/s */
+	/* [4]...[7] are reserved */
+};
+
+/**
+ * meaning of the 'time' bits  in the CSD's field 'TRAN_SPEED'
+ * (multiplied by 10 to be nice to platforms without floating point)
+ */
+static const unsigned char tran_speed_time[] = {
+	0,	/* reserved */
+	10,	/* 1.0 ns */
+	12,	/* 1.2 ns */
+	13,
+	15,
+	20,
+	25,
+	30,
+	35,
+	40,
+	45,
+	50,
+	55,
+	60,
+	70,	/* 7.0 ns */
+	80,	/* 8.0 ns */
+};
+
+/**
+ * Extract max. transfer speed from the CSD
+ * @param mci_dev MCI instance
+ *
+ * Encoded in bit 103:96 (103: reserved, 102:99: time, 98:96 unit)
+ */
+static void mci_extract_max_tran_speed_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	unsigned unit, time;
+
+	unit = tran_speed_unit[(mci->csd[0] & 0x7)];
+	time = tran_speed_time[((mci->csd[0] >> 3) & 0xf)];
+	if ((unit == 0) || (time == 0)) {
+		pr_warning("Unsupported 'TRAN_SPEED' unit/time value. Can't calculate card's max. transfer speed\n");
+		return;
+	}
+
+	mci->tran_speed = time * unit;
+	pr_debug("Transfer speed: %u\n", mci->tran_speed);
+}
+
+/**
+ * Extract max read and write block length from the CSD
+ * @param mci_dev MCI instance
+ *
+ * Encoded in bit 83:80 (read) and 25:22 (write)
+ */
+static void mci_extract_block_lengths_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	mci->read_bl_len = 1 << ((mci->csd[1] >> 16) & 0xf);
+
+	if (IS_SD(mci))
+		mci->write_bl_len = mci->read_bl_len;	/* FIXME why? */
+	else
+		mci->write_bl_len = 1 << ((mci->csd[3] >> 22) & 0xf);
+
+	pr_debug("Max. block length are: Write=%u, Read=%u Bytes\n", mci->read_bl_len, mci->write_bl_len);
+}
+
+/**
+ * Extract card's capacitiy from the CSD
+ * @param mci_dev MCI instance
+ */
+static void mci_extract_card_capacity_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	uint64_t csize, cmult;
+
+	if (mci->high_capacity) {
+		csize = (mci->csd[1] & 0x3f) << 16 | (mci->csd[2] & 0xffff0000) >> 16;
+		cmult = 8;
+	} else {
+		csize = (mci->csd[1] & 0x3ff) << 2 | (mci->csd[2] & 0xc0000000) >> 30;
+		cmult = (mci->csd[2] & 0x00038000) >> 15;
+	}
+
+	mci->capacity = (csize + 1) << (cmult + 2);
+	mci->capacity *= mci->read_bl_len;
+	pr_debug("Capacity: %u MiB\n", (unsigned)mci->capacity >> 20);
+}
+
+/**
+ * Scan the given host interfaces and detect connected MMC/SD cards
+ * @param mci_dev MCI instance
+ * @return 0 on success, negative value else
+ */
+static int mci_startup(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int err;
+
+	pr_debug("Put the Card in Identify Mode\n");
+
+	/* Put the Card in Identify Mode */
+	mci_setup_cmd(&cmd, MMC_CMD_ALL_SEND_CID, 0, MMC_RSP_R2);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Can't bring card into identify mode: %d\n", err);
+		return err;
+	}
+
+	memcpy(mci->cid, cmd.response, 16);
+
+	pr_debug("Card's identification data is: %08X-%08X-%08X-%08X\n", mci->cid[0], mci->cid[1], mci->cid[2], mci->cid[3]);
+
+	/*
+	 * For MMC cards, set the Relative Address.
+	 * For SD cards, get the Relatvie Address.
+	 * This also puts the cards into Standby State
+	 */
+	pr_debug("Get/Set relative address\n");
+	mci_setup_cmd(&cmd, SD_CMD_SEND_RELATIVE_ADDR, mci->rca << 16, MMC_RSP_R6);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Get/Set relative address failed: %d\n", err);
+		return err;
+	}
+
+	if (IS_SD(mci))
+		mci->rca = (cmd.response[0] >> 16) & 0xffff;
+
+	pr_debug("Get card's specific data\n");
+	/* Get the Card-Specific Data */
+	mci_setup_cmd(&cmd, MMC_CMD_SEND_CSD, mci->rca << 16, MMC_RSP_R2);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Getting card's specific data failed: %d\n", err);
+		return err;
+	}
+
+	/* CSD is of 128 bit */
+	memcpy(mci->csd, cmd.response, 16);
+
+	pr_debug("Card's specific data is: %08X-%08X-%08X-%08X\n", mci->csd[0], mci->csd[1], mci->csd[2], mci->csd[3]);
+
+	mci_detect_version_from_csd(mci_dev);
+	mci_extract_max_tran_speed_from_csd(mci_dev);
+	mci_extract_block_lengths_from_csd(mci_dev);
+	mci_extract_card_capacity_from_csd(mci_dev);
+
+	/* sanitiy? */
+	if (mci->read_bl_len > 512) {
+		mci->read_bl_len = 512;
+		pr_warning("Limiting max. read block size down to %u\n", mci->read_bl_len);
+	}
+
+	if (mci->write_bl_len > 512) {
+		mci->write_bl_len = 512;
+		pr_warning("Limiting max. write block size down to %u\n", mci->read_bl_len);
+	}
+	pr_debug("Read block length: %u, Write block length: %u\n", mci->read_bl_len, mci->write_bl_len);
+
+	pr_debug("Select the card, and put it into Transfer Mode\n");
+	/* Select the card, and put it into Transfer Mode */
+	mci_setup_cmd(&cmd, MMC_CMD_SELECT_CARD, mci->rca << 16, MMC_RSP_R1b);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Putting in transfer mode failed: %d\n", err);
+		return err;
+	}
+
+	if (IS_SD(mci))
+		err = sd_change_freq(mci_dev);
+	else
+		err = mmc_change_freq(mci_dev);
+
+	if (err)
+		return err;
+
+	/* Restrict card's capabilities by what the host can do */
+	mci->card_caps &= pdata->host_caps;
+
+	if (IS_SD(mci)) {
+		if (mci->card_caps & MMC_MODE_4BIT) {
+			pr_debug("Prepare for bus width change\n");
+			mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, mci->rca << 16, MMC_RSP_R1);
+			err = mci_send_cmd(mci_dev, &cmd, NULL);
+			if (err) {
+				pr_debug("Preparing SD for bus width change failed: %d\n", err);
+				return err;
+			}
+
+			pr_debug("Set SD bus width to 4 bit\n");
+			mci_setup_cmd(&cmd, SD_CMD_APP_SET_BUS_WIDTH, 2, MMC_RSP_R1);
+			err = mci_send_cmd(mci_dev, &cmd, NULL);
+			if (err) {
+				pr_debug("Changing SD bus width failed: %d\n", err);
+				/* TODO continue with 1 bit? */
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 4);
+		}
+		/* if possible, speed up the transfer */
+		if (mci->card_caps & MMC_MODE_HS)
+			mci_set_clock(mci_dev, 50000000);
+		else
+			mci_set_clock(mci_dev, 25000000);
+	} else {
+		if (mci->card_caps & MMC_MODE_4BIT) {
+			pr_debug("Set MMC bus width to 4 bit\n");
+			/* Set the card to use 4 bit*/
+			err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
+			if (err) {
+				pr_debug("Changing MMC bus width failed: %d\n", err);
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 4);
+		} else if (mci->card_caps & MMC_MODE_8BIT) {
+			pr_debug("Set MMC bus width to 8 bit\n");
+			/* Set the card to use 8 bit*/
+			err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);
+			if (err) {
+				pr_debug("Changing MMC bus width failed: %d\n", err);
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 8);
+		}
+		/* if possible, speed up the transfer */
+		if (mci->card_caps & MMC_MODE_HS) {
+			if (mci->card_caps & MMC_MODE_HS_52MHz)
+				mci_set_clock(mci_dev, 52000000);
+			else
+				mci_set_clock(mci_dev, 26000000);
+		} else
+			mci_set_clock(mci_dev, 20000000);
+	}
+
+	/* we setup the blocklength only one times for all accesses to this media  */
+	err = mci_set_blocklen(mci_dev, mci->read_bl_len);
+
+	return err;
+}
+
+/**
+ * Detect a SD 2.0 card and enable its features
+ * @param mci_dev MCI instance
+ * @return Transfer status (0 on success)
+ *
+ * By issuing the CMD8 command SDHC/SDXC cards realize that the host supports
+ * the Physical Layer Version 2.00 or later and the card can enable
+ * corresponding new functions.
+ *
+ * If this CMD8 command will end with a timeout it is a MultiMediaCard only.
+ */
+static int sd_send_if_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int err;
+
+	mci_setup_cmd(&cmd, SD_CMD_SEND_IF_COND,
+	/* We set the bit if the host supports voltages between 2.7 and 3.6 V */
+		((pdata->voltages & 0x00ff8000) != 0) << 8 | 0xaa,
+		MMC_RSP_R7);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Query interface conditions failed: %d\n", err);
+		return err;
+	}
+
+	if ((cmd.response[0] & 0xff) != 0xaa) {
+		pr_debug("Card cannot work with hosts supply voltages\n");
+		return -EINVAL;
+	} else {
+		pr_debug("SD Card Rev. 2.00 or later detected\n");
+		mci->version = SD_VERSION_2;
+	}
+
+	return 0;
+}
+
+/* ------------------ attach to the ATA API --------------------------- */
+
+/**
+ * Write a chunk of sectors to media
+ * @param disk_dev Disk device instance
+ * @param sector_start Sector's number to start write to
+ * @param sector_count Sectors to write
+ * @param buffer Buffer to write from
+ * @return 0 on success, anything else on failure
+ *
+ * This routine expects the buffer has the correct size to read all data!
+ */
+static int mci_sd_write(struct device_d *disk_dev, uint64_t sector_start, unsigned sector_count, const void *buffer)
+{
+	struct ata_interface *intf = disk_dev->platform_data;
+	struct device_d *mci_dev = intf->priv;
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int rc;
+
+	pr_debug("%s called: Write %u block(s), starting at %lu", __func__, sector_count, (unsigned)sector_count);
+
+	if (mci->write_bl_len != 512) {
+		pr_warning("MMC/SD block size is not 512 bytes (its %u bytes instead)\n", mci->read_bl_len);
+		return -EINVAL;
+	}
+
+	while (sector_count) {
+		/* size of the block number field in the MMC/SD command is 32 bit only */
+		if (sector_start > MAX_BUFFER_NUMBER) {
+			pr_err("Cannot handle block number %llu. Too large!\n", sector_start);
+			return -EINVAL;
+		}
+		rc = mci_block_write(mci_dev, buffer, sector_start);
+		if (rc != 0) {
+			pr_err("Writing block %u failed\n", (unsigned)sector_start);
+			return rc;
+		}
+		sector_count--;
+		buffer += mci->write_bl_len;
+		sector_start++;
+	}
+
+	return 0;
+}
+
+/**
+ * Read a chunk of sectors from media
+ * @param disk_dev Disk device instance
+ * @param sector_start Sector's number to start read from
+ * @param sector_count Sectors to read
+ * @param buffer Buffer to read into
+ * @return 0 on success, anything else on failure
+ *
+ * This routine expects the buffer has the correct size to store all data!
+ */
+static int mci_sd_read(struct device_d *disk_dev, uint64_t sector_start, unsigned sector_count, void *buffer)
+{
+	struct ata_interface *intf = disk_dev->platform_data;
+	struct device_d *mci_dev = intf->priv;
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int rc;
+
+	pr_debug("%s called: Read %u block(s), starting at %lu to %08X\n", __func__, sector_count, (unsigned)sector_start, buffer);
+
+	if (mci->read_bl_len != 512) {
+		pr_warning("MMC/SD block size is not 512 bytes (its %u bytes instead)\n", mci->read_bl_len);
+		return -EINVAL;
+	}
+
+	while (sector_count) {
+		if (sector_start > MAX_BUFFER_NUMBER) {
+			pr_err("Cannot handle block number %lu. Too large!\n", (unsigned)sector_start);
+			return -EINVAL;
+		}
+		rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start);
+		if (rc != 0) {
+			pr_err("Reading block %lu failed\n", (unsigned)sector_start);
+			return rc;
+		}
+		sector_count--;
+		buffer += mci->read_bl_len;	/* FIXME always 512 bytes? */
+		sector_start++;
+	}
+
+	return 0;
+}
+
+/* ------------------ attach to the device API --------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+/**
+ * Extract the Manufacturer ID from the CID
+ * @param mci Instance data
+ *
+ * The 'MID' is encoded in bit 127:120 in the CID
+ */
+static unsigned extract_mid(struct mci *mci)
+{
+	return mci->cid[0] >> 24;
+}
+
+/**
+ * Extract the OEM/Application ID from the CID
+ * @param mci Instance data
+ *
+ * The 'OID' is encoded in bit 119:104 in the CID
+ */
+static unsigned extract_oid(struct mci *mci)
+{
+	return (mci->cid[0] >> 8) & 0xffff;
+}
+
+/**
+ * Extract the product revision from the CID
+ * @param mci Instance data
+ *
+ * The 'PRV' is encoded in bit 63:56 in the CID
+ */
+static unsigned extract_prv(struct mci *mci)
+{
+	return mci->cid[2] >> 24;
+}
+
+/**
+ * Extract the product serial number from the CID
+ * @param mci Instance data
+ *
+ * The 'PSN' is encoded in bit 55:24 in the CID
+ */
+static unsigned extract_psn(struct mci *mci)
+{
+	return (mci->cid[2] << 8) | (mci->cid[3] >> 24);
+}
+
+/**
+ * Extract the month of the manufacturing date from the CID
+ * @param mci Instance data
+ *
+ * The 'MTD' is encoded in bit 19:8 in the CID, month in 11:8
+ */
+static unsigned extract_mtd_month(struct mci *mci)
+{
+	return (mci->cid[3] >> 8) & 0xf;
+}
+
+/**
+ * Extract the year of the manufacturing date from the CID
+ * @param mci Instance data
+ *
+ * The 'MTD' is encoded in bit 19:8 in the CID, year in 19:12
+ * An encoded 0 means the year 2000
+ */
+static unsigned extract_mtd_year(struct mci *mci)
+{
+	return ((mci->cid[3] >> 12) & 0xff) + 2000U;
+}
+
+/**
+ * Output some valuable information when the user runs 'devinfo' on an MCI device
+ * @param mci_dev MCI device instance
+ */
+static void mci_info(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	if (mci->ready_for_use == 0) {
+		printf(" No information available:\n  MCI card not probed yet\n");
+		return;
+	}
+
+	printf(" Card:\n");
+	if (mci->version < SD_VERSION_SD) {
+		printf("  Attached is a MultiMediaCard (Version: %u.%u)\n", (mci->version >> 4) & 0xf, mci->version & 0xf);
+	} else {
+		printf("  Attached is an SD Card (Version: %u.%u)\n", (mci->version >> 4) & 0xf, mci->version & 0xf);
+	}
+	printf("  Capacity: %u MiB\n", (unsigned)(mci->capacity >> 20));
+
+	if (mci->high_capacity)
+		printf("  High capacity card\n");
+	printf("   CID: %08X-%08X-%08X-%08X\n", mci->cid[0], mci->cid[1], mci->cid[2], mci->cid[3]);
+	printf("   CSD: %08X-%08X-%08X-%08X\n", mci->csd[0], mci->csd[1], mci->csd[2], mci->csd[3]);
+	printf("  Max. transfer speed: %u Hz\n", mci->tran_speed);
+	printf("  Manufacturer ID: %02X\n", extract_mid(mci));
+	printf("  OEM/Application ID: %04X\n", extract_oid(mci));
+	printf("  Product name: '%c%c%c%c%c'\n", mci->cid[0] & 0xff, (mci->cid[1] >> 24), (mci->cid[1] >> 16) & 0xff,
+			(mci->cid[1] >> 8) & 0xff, mci->cid[1] & 0xff);
+	printf("  Product revision: %u.%u\n", extract_prv(mci) >> 4, extract_prv(mci) & 0xf);
+	printf("  Serial no: %0u\n", extract_psn(mci));
+	printf("  Manufacturing date: %u.%u\n", extract_mtd_month(mci), extract_mtd_year(mci));
+}
+#endif
+
+/**
+ * Check if the MCI card is already probed
+ * @param mci_dev MCI device instance
+ * @return 0 when not probed yet, -EPERM if already probed
+ *
+ * @a barebox cannot really cope with hot plugging. So, probing an attached
+ * MCI card is a one time only job. If its already done, there is no way to
+ * return.
+ */
+static int mci_check_if_already_initialized(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	if (mci->ready_for_use != 0)
+		return -EPERM;
+
+	return 0;
+}
+
+/**
+ * Probe an MCI card at the given host interface
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative values else
+ */
+static int mci_card_probe(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct device_d *disk_dev;
+	struct ata_interface *p;
+	int rc;
+
+	/* start with a host interface reset */
+	rc = (pdata->init)(pdata->hw_dev, mci_dev);
+	if (rc) {
+		pr_err("Cannot reset the SD/MMC interface\n");
+		return rc;
+	}
+
+	mci_set_bus_width(mci_dev, 1);
+	mci_set_clock(mci_dev, 1);	/* set the lowest available clock */
+
+	/* reset the card */
+	rc = mci_go_idle(mci_dev);
+	if (rc) {
+		pr_warning("Cannot reset the SD/MMC card\n");
+		goto on_error;
+	}
+
+	/* Check if this card can handle the "SD Card Physical Layer Specification 2.0" */
+	rc = sd_send_if_cond(mci_dev);
+	if (rc) {
+		/* If the command timed out, we check for an MMC card */
+		if (rc == -ETIMEDOUT) {
+			pr_debug("Card seems to be a MultiMediaCard\n");
+			rc = mmc_send_op_cond(mci_dev);
+			if (rc) {
+				printf("MultiMediaCard did not respond to voltage select!\n");
+				rc = -ENODEV;
+				goto on_error;
+			}
+		} else
+			goto on_error;
+	} else {
+		/* Its a 2.xx card. Setup operation conditions */
+		rc = sd_send_op_cond(mci_dev);
+		if (rc) {
+			pr_debug("Cannot setup SD card's operation condition\n");
+			goto on_error;
+		}
+	}
+
+	rc = mci_startup(mci_dev);
+	if (rc) {
+		printf("Card's startup fails with %d\n", rc);
+		goto on_error;
+	}
+
+	pr_debug("Card is up and running now, registering as a disk\n");
+	mci->ready_for_use = 1;	/* TODO now or later? */
+
+	/*
+	 * An MMC/SD card acts like an ordinary disk.
+	 * So, re-use the disk driver to gain access to this media
+	 */
+	disk_dev = xzalloc(sizeof(struct device_d) + sizeof(struct ata_interface));
+	if (disk_dev == NULL) {
+		pr_err("Out of memory when registering the MMC/SD device\n");
+		rc = -ENOMEM;
+		goto on_error;
+	}
+	p = (struct ata_interface*)&disk_dev[1];
+
+	p->write = mci_sd_write;
+	p->read = mci_sd_read;
+	p->priv = mci_dev;
+
+	strcpy(disk_dev->name, "disk");
+	disk_dev->size = mci->capacity;
+	disk_dev->map_base = 0;
+	disk_dev->platform_data = p;
+
+	register_device(disk_dev);
+
+	pr_debug("SD Card successfully added\n");
+
+on_error:
+	if (rc != 0) {
+		pdata->clock = 0;	/* disable the MCI clock */
+		mci_set_ios(mci_dev);
+	}
+
+	return rc;
+}
+
+/**
+ * Trigger probing of an attached MCI card
+ * @param mci_dev MCI device instance
+ * @param param FIXME
+ * @param val "0" does nothing, a "1" will probe for a MCI card
+ * @return 0 on success
+ */
+static int mci_set_probe(struct device_d *mci_dev, struct param_d *param, const char *val)
+{
+	int rc, probe;
+
+	rc = mci_check_if_already_initialized(mci_dev);
+	if (rc != 0)
+		return rc;
+
+	probe = simple_strtoul(val, NULL, 0);
+	if (probe != 0) {
+		rc = mci_card_probe(mci_dev);
+		if (rc != 0)
+			return rc;
+	}
+
+	return dev_param_set_generic(mci_dev, param, val);
+}
+
+/**
+ * Add parameter to the MCI device on demand
+ * @param mci_dev MCI device instance
+ * @return 0 on success
+ *
+ * This parameter is only available (or usefull) if MCI card probing is delayed
+ */
+static int add_mci_parameter(struct device_d *mci_dev)
+{
+	int rc;
+
+	/* provide a 'probing right now' parameter for the user */
+	rc = dev_add_param(mci_dev, "probe", mci_set_probe, NULL, 0);
+	if (rc != 0)
+		return rc;
+
+	return dev_set_param(mci_dev, "probe", "0");
+}
+
+/**
+ * Prepare for MCI card's usage
+ * @param mci_dev MCI device instance
+ * @return 0 on success
+ *
+ * This routine will probe an attached MCI card immediately or provide
+ * a parameter to do it later on user's demand.
+ */
+static int mci_probe(struct device_d *mci_dev)
+{
+	struct mci *mci;
+	int rc;
+
+	mci = xzalloc(sizeof(struct mci));
+	mci_dev->priv = mci;
+
+#ifdef CONFIG_MCI_STARTUP
+	/* if enabled, probe the attached card immediately */
+	rc = mci_card_probe(mci_dev);
+	if (rc == -ENODEV) {
+		/*
+		 * If it fails, add the 'probe' parameter to give the user
+		 * a chance to insert a card and try again. Note: This may fail
+		 * systems that rely on the MCI card for startup (for the
+		 * persistant environment for example)
+		 */
+		rc = add_mci_parameter(mci_dev);
+		if (rc != 0) {
+			pr_err("Failed to add 'probe' parameter to the MCI device\n");
+			goto on_error;
+		}
+	}
+#endif
+
+#ifndef CONFIG_MCI_STARTUP
+	/* add params on demand */
+	rc = add_mci_parameter(mci_dev);
+	if (rc != 0) {
+		pr_err("Failed to add 'probe' parameter to the MCI device\n");
+		goto on_error;
+	}
+#endif
+
+	return rc;
+
+on_error:
+	free(mci);
+	return rc;
+}
+
+static struct driver_d mci_driver = {
+	.name	= "mci",
+	.probe	= mci_probe,
+	.info	= mci_info,
+};
+
+static int mci_init(void)
+{
+	return register_driver(&mci_driver);
+}
+
+device_initcall(mci_init);
+
+/**
+ * Create a new mci device (for convenience)
+ * @param pdata MCI device's platform data for this MCI device
+ * @return 0 on success
+ */
+int mci_register(struct mci_platformdata *pdata)
+{
+	struct device_d *mci_dev;
+
+	mci_dev = xzalloc(sizeof(struct device_d));
+
+	strcpy(mci_dev->name, mci_driver.name);
+	mci_dev->platform_data = (void*)pdata;
+
+	return register_device(mci_dev);
+}
diff --git a/include/mci.h b/include/mci.h
new file mode 100644
index 0000000..b9d5c1c
--- /dev/null
+++ b/include/mci.h
@@ -0,0 +1,230 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is partially based on u-boot code:
+ *
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MCI_H_
+#define _MCI_H_
+
+#include <linux/list.h>
+
+/* Firmware revisions for SD cards */
+#define SD_VERSION_SD		0x20000
+#define SD_VERSION_2		(SD_VERSION_SD | 0x20)
+#define SD_VERSION_1_0		(SD_VERSION_SD | 0x10)
+#define SD_VERSION_1_10		(SD_VERSION_SD | 0x1a)
+
+/* Firmware revisions for MMC cards */
+#define MMC_VERSION_MMC		0x10000
+#define MMC_VERSION_UNKNOWN	(MMC_VERSION_MMC)
+#define MMC_VERSION_1_2		(MMC_VERSION_MMC | 0x12)
+#define MMC_VERSION_1_4		(MMC_VERSION_MMC | 0x14)
+#define MMC_VERSION_2_2		(MMC_VERSION_MMC | 0x22)
+#define MMC_VERSION_3		(MMC_VERSION_MMC | 0x30)
+#define MMC_VERSION_4		(MMC_VERSION_MMC | 0x40)
+
+#define MMC_MODE_HS		0x001
+#define MMC_MODE_HS_52MHz	0x010
+#define MMC_MODE_4BIT		0x100
+#define MMC_MODE_8BIT		0x200
+
+#define SD_DATA_4BIT		0x00040000
+
+#define IS_SD(x) (x->version & SD_VERSION_SD)
+
+#define MMC_DATA_READ		1
+#define MMC_DATA_WRITE		2
+
+/* command list */
+#define MMC_CMD_GO_IDLE_STATE		0
+#define MMC_CMD_SEND_OP_COND		1
+#define MMC_CMD_ALL_SEND_CID		2
+#define MMC_CMD_SET_RELATIVE_ADDR	3
+#define MMC_CMD_SET_DSR			4
+#define MMC_CMD_SWITCH			6
+#define MMC_CMD_SELECT_CARD		7
+#define MMC_CMD_SEND_EXT_CSD		8
+#define MMC_CMD_SEND_CSD		9
+#define MMC_CMD_SEND_CID		10
+#define MMC_CMD_STOP_TRANSMISSION	12
+#define MMC_CMD_SEND_STATUS		13
+#define MMC_CMD_SET_BLOCKLEN		16
+#define MMC_CMD_READ_SINGLE_BLOCK	17
+#define MMC_CMD_READ_MULTIPLE_BLOCK	18
+#define MMC_CMD_WRITE_SINGLE_BLOCK	24
+#define MMC_CMD_WRITE_MULTIPLE_BLOCK	25
+#define MMC_CMD_APP_CMD			55
+
+#define SD_CMD_SEND_RELATIVE_ADDR	3
+#define SD_CMD_SWITCH_FUNC		6
+#define SD_CMD_SEND_IF_COND		8
+
+#define SD_CMD_APP_SET_BUS_WIDTH	6
+#define SD_CMD_APP_SEND_OP_COND		41
+#define SD_CMD_APP_SEND_SCR		51
+
+/* SCR definitions in different words */
+#define SD_HIGHSPEED_BUSY	0x00020000
+#define SD_HIGHSPEED_SUPPORTED	0x00020000
+
+#define MMC_HS_TIMING		0x00000100
+#define MMC_HS_52MHZ		0x2
+
+#define OCR_BUSY		0x80000000
+/** card's response in its OCR if it is a high capacity card */
+#define OCR_HCS			0x40000000
+
+#define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
+#define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */
+#define MMC_VDD_21_22		0x00000200	/* VDD voltage 2.1 ~ 2.2 */
+#define MMC_VDD_22_23		0x00000400	/* VDD voltage 2.2 ~ 2.3 */
+#define MMC_VDD_23_24		0x00000800	/* VDD voltage 2.3 ~ 2.4 */
+#define MMC_VDD_24_25		0x00001000	/* VDD voltage 2.4 ~ 2.5 */
+#define MMC_VDD_25_26		0x00002000	/* VDD voltage 2.5 ~ 2.6 */
+#define MMC_VDD_26_27		0x00004000	/* VDD voltage 2.6 ~ 2.7 */
+#define MMC_VDD_27_28		0x00008000	/* VDD voltage 2.7 ~ 2.8 */
+#define MMC_VDD_28_29		0x00010000	/* VDD voltage 2.8 ~ 2.9 */
+#define MMC_VDD_29_30		0x00020000	/* VDD voltage 2.9 ~ 3.0 */
+#define MMC_VDD_30_31		0x00040000	/* VDD voltage 3.0 ~ 3.1 */
+#define MMC_VDD_31_32		0x00080000	/* VDD voltage 3.1 ~ 3.2 */
+#define MMC_VDD_32_33		0x00100000	/* VDD voltage 3.2 ~ 3.3 */
+#define MMC_VDD_33_34		0x00200000	/* VDD voltage 3.3 ~ 3.4 */
+#define MMC_VDD_34_35		0x00400000	/* VDD voltage 3.4 ~ 3.5 */
+#define MMC_VDD_35_36		0x00800000	/* VDD voltage 3.5 ~ 3.6 */
+
+#define MMC_SWITCH_MODE_CMD_SET		0x00 /** Change the command set */
+#define MMC_SWITCH_MODE_SET_BITS	0x01 /** Set bits in EXT_CSD byte addressed by index which are 1 in value field */
+#define MMC_SWITCH_MODE_CLEAR_BITS	0x02 /** Clear bits in EXT_CSD byte addressed by index, which are 1 in value field */
+#define MMC_SWITCH_MODE_WRITE_BYTE	0x03 /** Set target byte to value */
+
+#define SD_SWITCH_CHECK		0
+#define SD_SWITCH_SWITCH	1
+
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_BUS_WIDTH	183	/* R/W */
+#define EXT_CSD_HS_TIMING	185	/* R/W */
+#define EXT_CSD_CARD_TYPE	196	/* RO */
+#define EXT_CSD_REV		192	/* RO */
+#define EXT_CSD_SEC_CNT		212	/* RO, 4 bytes */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_CMD_SET_NORMAL		(1<<0)
+#define EXT_CSD_CMD_SET_SECURE		(1<<1)
+#define EXT_CSD_CMD_SET_CPSECURE	(1<<2)
+
+#define EXT_CSD_CARD_TYPE_26	(1<<0)	/* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52	(1<<1)	/* Card can run at 52MHz */
+
+#define EXT_CSD_BUS_WIDTH_1	0	/* Card is in 1 bit mode */
+#define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
+#define EXT_CSD_BUS_WIDTH_8	2	/* Card is in 8 bit mode */
+
+#define R1_ILLEGAL_COMMAND		(1 << 22)
+#define R1_APP_CMD			(1 << 5)
+
+/* response types */
+#define MMC_RSP_PRESENT (1 << 0)
+#define MMC_RSP_136     (1 << 1)                /* 136 bit response */
+#define MMC_RSP_CRC     (1 << 2)                /* expect valid crc */
+#define MMC_RSP_BUSY    (1 << 3)                /* card may send busy */
+#define MMC_RSP_OPCODE  (1 << 4)                /* response contains opcode */
+
+#define MMC_RSP_NONE    (0)
+#define MMC_RSP_R1      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R1b	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
+#define MMC_RSP_R2      (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
+#define MMC_RSP_R3      (MMC_RSP_PRESENT)
+#define MMC_RSP_R4      (MMC_RSP_PRESENT)
+#define MMC_RSP_R5      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R6      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R7      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+
+/** command information to be sent to the SD/MMC card */
+struct mci_cmd {
+	unsigned cmdidx;	/**< Command to be sent to the SD/MMC card */
+	unsigned resp_type;	/**< Type of expected response, refer MMC_RSP_* macros */
+	unsigned cmdarg;	/**< Command's arguments */
+	unsigned response[4];	/**< card's response */
+};
+
+/** data information to be used with some SD/MMC commands */
+struct mci_data {
+	union {
+		uint8_t *dest;
+		const uint8_t *src; /**< src buffers don't get written to */
+	};
+	unsigned flags;		/**< refer MMC_DATA_* to define direction */
+	unsigned blocks;	/**< block count to handle in this command */
+	unsigned blocksize;	/**< block size in bytes (mostly 512) */
+};
+
+/** host information */
+struct mci_platformdata {
+	struct device_d *hw_dev;	/**< the host MCI hardware device */
+	unsigned voltages;
+	unsigned host_caps;	/**< Host's interface capabilities, refer MMC_VDD_* and FIXME */
+	unsigned f_min;		/**< host interface lower limit */
+	unsigned f_max;		/**< host interface upper limit */
+	unsigned clock;		/**< Current clock used to talk to the card */
+	unsigned bus_width;	/**< used data bus width to the card */
+
+	int (*init)(struct device_d*, struct device_d*);	/**< init the host interface */
+	void (*set_ios)(struct device_d*, struct device_d*, unsigned, unsigned);	/**< change host interface settings */
+	int (*send_cmd)(struct device_d*, struct mci_cmd*, struct mci_data*);	/**< handle a command */
+};
+
+/** MMC/SD and interface instance information */
+struct mci {
+	unsigned version;
+	int high_capacity;	/**< != 0 when a high capacity card is connected (OCR -> OCR_HCS) */
+	unsigned card_caps;	/**< Card's capabilities */
+	unsigned ocr;		/**< card's "operation condition register" */
+	unsigned scr[2];
+	unsigned csd[4];	/**< card's "card specific data register" */
+	unsigned cid[4];	/**< card's "card identification register" */
+	unsigned short rca;	/* FIXME */
+	unsigned tran_speed;	/**< not yet used */
+	unsigned read_bl_len;	/**< currently used data block length for read accesses */
+	unsigned write_bl_len;	/**< currently used data block length for write accesses */
+	uint64_t capacity;	/**< Card's data capacity in bytes */
+	int ready_for_use;	/** true if already probed */
+};
+
+int mci_register(struct mci_platformdata*);
+
+#define GET_HOST_DATA(x) (x->priv)
+#define GET_HOST_PDATA(x) (x->platform_data)
+#define GET_MCI_DATA(x) (x->priv)
+#define GET_MCI_PDATA(x) (x->platform_data)
+
+#endif /* _MCI_H_ */
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 09:24:17 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 15:24:17 +0200
Subject: [PATCH 6/7] Add i.MX23 MCI card support
In-Reply-To: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286457858-29771-7-git-send-email-jbe@pengutronix.de>

Adding MCI card support for STM378x/i.MX23 CPUs. This is for reference only,
as this architecture is currently not part of barebox (but will coming soon).
Its tested on the i.MX23 based ChumbyOne.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/Kconfig   |    7 +
 drivers/mci/Makefile  |    1 +
 drivers/mci/stm378x.c |  686 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 694 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/stm378x.c

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 0abadb3..a24ae6d 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -27,4 +27,11 @@ config MCI_INFO
 
 comment "--- MCI host drivers ---"
 
+config MCI_STM378X
+	bool "i.MX23"
+	depends on ARCH_STM
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  i.MX23 based system.
+
 endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index 927618f..e5e19b0 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MCI)	+= mci-core.o
+obj-$(CONFIG_MCI_STM378X) += stm378x.o
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
new file mode 100644
index 0000000..c442325
--- /dev/null
+++ b/drivers/mci/stm378x.c
@@ -0,0 +1,686 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe at pengutronix.de>
+ *
+ * This code is based on:
+ *
+ * Copyright (C) 2007 SigmaTel, Inc., Ioannis Kappas <ikappas at sigmatel.com>
+ *
+ * Portions copyright (C) 2003 Russell King, PXA MMCI Driver
+ * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * @file
+ * @brief MCI card host interface for i.MX23 CPU
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <mci.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <mach/imx-regs.h>
+#include <mach/mci.h>
+#include <mach/clock-imx23.h>
+
+#define CLOCKRATE_MIN (1 * 1000 * 1000)
+#define CLOCKRATE_MAX (480 * 1000 * 1000)
+
+#define HW_SSP_CTRL0 0x000
+# define SSP_CTRL0_SFTRST (1 << 31)
+# define SSP_CTRL0_CLKGATE (1 << 30)
+# define SSP_CTRL0_RUN (1 << 29)
+# define SSP_CTRL0_LOCK_CS (1 << 29)
+# define SSP_CTRL0_READ (1 << 25)
+# define SSP_CTRL0_IGNORE_CRC (1 << 26)
+# define SSP_CTRL0_DATA_XFER (1 << 24)
+# define SSP_CTRL0_BUS_WIDTH(x) (((x) & 0x3) << 22)
+# define SSP_CTRL0_WAIT_FOR_IRQ (1 << 21)
+# define SSP_CTRL0_LONG_RESP (1 << 19)
+# define SSP_CTRL0_GET_RESP (1 << 17)
+# define SSP_CTRL0_ENABLE (1 << 16)
+# define SSP_CTRL0_XFER_COUNT(x) ((x) & 0xffff)
+
+#define HW_SSP_CMD0 0x010
+# define SSP_CMD0_SLOW_CLK (1 << 22)
+# define SSP_CMD0_CONT_CLK (1 << 21)
+# define SSP_CMD0_APPEND_8CYC (1 << 20)
+# define SSP_CMD0_BLOCK_SIZE(x) (((x) & 0xf) << 16)
+# define SSP_CMD0_BLOCK_COUNT(x) (((x) & 0xff) << 8)
+# define SSP_CMD0_CMD(x) ((x) & 0xff)
+
+#define HW_SSP_CMD1 0x020
+#define HW_SSP_COMPREF 0x030
+#define HW_SSP_COMPMASK 0x040
+#define HW_SSP_TIMING 0x050
+# define SSP_TIMING_TIMEOUT_MASK (0xffff0000)
+# define SSP_TIMING_TIMEOUT(x) ((x) << 16)
+# define SSP_TIMING_CLOCK_DIVIDE(x) (((x) & 0xff) << 8)
+# define SSP_TIMING_CLOCK_RATE(x) ((x) & 0xff)
+
+#define HW_SSP_CTRL1 0x060
+# define SSP_CTRL1_POLARITY (1 << 9)
+# define SSP_CTRL1_WORD_LENGTH(x) (((x) & 0xf) << 4)
+# define SSP_CTRL1_SSP_MODE(x) ((x) & 0xf)
+
+#define HW_SSP_DATA 0x070
+#define HW_SSP_SDRESP0 0x080
+#define HW_SSP_SDRESP1 0x090
+#define HW_SSP_SDRESP2 0x0A0
+#define HW_SSP_SDRESP3 0x0B0
+
+#define HW_SSP_STATUS 0x0C0
+# define SSP_STATUS_PRESENT (1 << 31)
+# define SSP_STATUS_SD_PRESENT (1 << 29)
+# define SSP_STATUS_CARD_DETECT (1 << 28)
+# define SSP_STATUS_RESP_CRC_ERR (1 << 16)
+# define SSP_STATUS_RESP_ERR (1 << 15)
+# define SSP_STATUS_RESP_TIMEOUT (1 << 14)
+# define SSP_STATUS_DATA_CRC_ERR (1 << 13)
+# define SSP_STATUS_TIMEOUT (1 << 12)
+# define SSP_STATUS_FIFO_OVRFLW (1 << 9)
+# define SSP_STATUS_FIFO_FULL (1 << 8)
+# define SSP_STATUS_FIFO_EMPTY (1 << 5)
+# define SSP_STATUS_FIFO_UNDRFLW (1 << 4)
+# define SSP_STATUS_CMD_BUSY (1 << 3)
+# define SSP_STATUS_DATA_BUSY (1 << 2)
+# define SSP_STATUS_BUSY (1 << 0)
+# define SSP_STATUS_ERROR (SSP_STATUS_FIFO_OVRFLW | SSP_STATUS_FIFO_UNDRFLW | SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR | SSP_STATUS_RESP_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | SSP_STATUS_TIMEOUT)
+
+#define HW_SSP_DEBUG 0x100
+#define HW_SSP_VERSION 0x110
+
+struct stm_mci_host {
+	unsigned	clock;	/* current clock speed in Hz ("0" if disabled) */
+#ifdef CONFIG_MCI_INFO
+	unsigned	f_min;
+	unsigned	f_max;
+#endif
+	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
+};
+
+/**
+ * Get MCI cards response if defined for the type of command
+ * @param hw_dev Host interface device instance
+ * @param cmd Command description
+ * @return Response bytes count, -EINVAL for unsupported response types
+ */
+static int get_cards_response(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	switch (cmd->resp_type) {
+	case MMC_RSP_NONE:
+		return 0;
+
+	case MMC_RSP_R1:
+	case MMC_RSP_R1b:
+	case MMC_RSP_R3:
+		cmd->response[0] = readl(hw_dev->map_base + HW_SSP_SDRESP0);
+		return 1;
+
+	case MMC_RSP_R2:
+		cmd->response[3] = readl(hw_dev->map_base + HW_SSP_SDRESP0);
+		cmd->response[2] = readl(hw_dev->map_base + HW_SSP_SDRESP1);
+		cmd->response[1] = readl(hw_dev->map_base + HW_SSP_SDRESP2);
+		cmd->response[0] = readl(hw_dev->map_base + HW_SSP_SDRESP3);
+		return 4;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * Finish a reques to the MCI card
+ * @param hw_dev Host interface device instance
+ *
+ * Can also stop the clock to save power
+ */
+static void finish_request(struct device_d *hw_dev)
+{
+	/* stop the engines (normaly already done) */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+}
+
+/**
+ * Check if the last command failed and if, why it failed
+ * @param status HW_SSP_STATUS's content
+ * @return 0 if no error, negative values else
+ */
+static int get_cmd_error(unsigned status)
+{
+	if (status & SSP_STATUS_ERROR)
+		pr_debug("Status Reg reports %08X\n", status);
+
+	if (status & SSP_STATUS_TIMEOUT) {
+		pr_debug("CMD timeout\n");
+		return -ETIMEDOUT;
+	} else if (status & SSP_STATUS_RESP_TIMEOUT) {
+		pr_debug("RESP timeout\n");
+		return -ETIMEDOUT;
+	} else if (status & SSP_STATUS_RESP_CRC_ERR) {
+		pr_debug("CMD crc error\n");
+		return -EILSEQ;
+	} else if (status & SSP_STATUS_RESP_ERR) {
+		pr_debug("RESP error\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * Define the timout for the next command
+ * @param hw_dev Host interface device instance
+ * @param to Timeout value in MCI card's bus clocks
+ */
+static void stm_setup_timout(struct device_d *hw_dev, unsigned to)
+{
+	uint32_t reg;
+
+	reg = readl(hw_dev->map_base + HW_SSP_TIMING) & ~SSP_TIMING_TIMEOUT_MASK;
+	reg |= SSP_TIMING_TIMEOUT(to);
+	writel(reg, hw_dev->map_base + HW_SSP_TIMING);
+}
+
+/**
+ * Read data from the MCI card
+ * @param hw_dev Host interface device instance
+ * @param buffer To write data into
+ * @param length Count of bytes to read (must be multiples of 4)
+ * @return 0 on success, negative values else
+ *
+ * @note This routine uses PIO to read in the data bytes from the FIFO. This
+ * may fail whith high clock speeds. If you receive -EIO errors you can try
+ * again with reduced clock speeds.
+ */
+static int read_data(struct device_d *hw_dev, void *buffer, unsigned length)
+{
+	uint32_t *p = buffer;
+
+	if (length & 0x3) {
+		pr_debug("Cannot read data sizes not multiple of 4 (request for %u detected)\n", length);
+		return -EINVAL;
+	}
+
+	while ((length != 0) && ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_ERROR) == 0)) {
+		/* TODO sort out FIFO overflows and emit -EOI for this case */
+		if ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_FIFO_EMPTY) == 0) {
+			*p = readl(hw_dev->map_base + HW_SSP_DATA);
+			p++;
+			length -= 4;
+		}
+	}
+
+	if (length == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+
+/**
+ * Write data into the MCI card
+ * @param hw_dev Host interface device instance
+ * @param buffer To read the data from
+ * @param length Count of bytes to write (must be multiples of 4)
+ * @return 0 on success, negative values else
+ *
+ * @note This routine uses PIO to write the data bytes into the FIFO. This
+ * may fail with high clock speeds. If you receive -EIO errors you can try
+ * again with reduced clock speeds.
+ */
+static int write_data(struct device_d *hw_dev, const void *buffer, unsigned length)
+{
+	const uint32_t *p = buffer;
+
+	if (length & 0x3) {
+		pr_debug("Cannot write data sizes not multiple of 4 (request for %u detected)\n", length);
+		return -EINVAL;
+	}
+
+	while ((length != 0) && ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_ERROR) == 0)) {
+		/* TODO sort out FIFO overflows and emit -EOI for this case */
+		if ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_FIFO_FULL) == 0) {
+			writel(*p, hw_dev->map_base + HW_SSP_DATA);
+			p++;
+			length -= 4;
+		}
+	}
+	if (length == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+/**
+ * Start the transaction with or without data
+ * @param hw_dev Host interface device instance
+ * @param data Data transfer description (might be NULL)
+ * @return 0 on success
+ */
+static int transfer_data(struct device_d *hw_dev, struct mci_data *data)
+{
+	unsigned length;
+
+	if (data != NULL) {
+		length = data->blocks * data->blocksize;
+#if 0
+		/*
+		 * For the records: When writing data with high clock speeds it
+		 * could be a good idea to fill the FIFO prior starting the
+		 * transaction.
+		 * But last time I tried it, it failed badly. Don't know why yet
+		 */
+		if (data->flags & MMC_DATA_WRITE) {
+			err = write_data(host, data->src, 16);
+			data->src += 16;
+			length -= 16;
+		}
+#endif
+	}
+
+	/*
+	 * Everything is ready for the transaction now:
+	 * - transfer configuration
+	 * - command and its parameters
+	 *
+	 * Start the transaction right now
+	 */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 4);
+
+	if (data != NULL) {
+		if (data->flags & MMC_DATA_READ)
+			return read_data(hw_dev, data->dest, length);
+		else
+			return write_data(hw_dev, data->src, length);
+	}
+
+	return 0;
+}
+
+/**
+ * Configure the MCI hardware for the next transaction
+ * @param cmd_flags Command information
+ * @param data_flags Data information (may be 0)
+ * @return Corresponding setting for the SSP_CTRL0 register
+ */
+static uint32_t prepare_transfer_setup(unsigned cmd_flags, unsigned data_flags)
+{
+	uint32_t reg = 0;
+
+	if (cmd_flags & MMC_RSP_PRESENT)
+		reg |= SSP_CTRL0_GET_RESP;
+	if ((cmd_flags & MMC_RSP_CRC) == 0)
+		reg |= SSP_CTRL0_IGNORE_CRC;
+	if (cmd_flags & MMC_RSP_136)
+		reg |= SSP_CTRL0_LONG_RESP;
+	if (cmd_flags & MMC_RSP_BUSY)
+		reg |= SSP_CTRL0_WAIT_FOR_IRQ;	/* FIXME correct? */
+#if 0
+	if (cmd_flags & MMC_RSP_OPCODE)
+		/* TODO */
+#endif
+	if (data_flags & MMC_DATA_READ)
+		reg |= SSP_CTRL0_READ;
+
+	return reg;
+}
+
+/**
+ * Handle MCI commands without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @return 0 on success
+ *
+ * This functions handles the following MCI commands:
+ * - "broadcast command (BC)" without a response
+ * - "broadcast commands with response (BCR)"
+ * - "addressed command (AC)" with response, but without data
+ */
+static int stm_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	int rc;
+
+	/* setup command and transfer parameters */
+	writel(prepare_transfer_setup(cmd->resp_type, 0) |
+		SSP_CTRL0_ENABLE, hw_dev->map_base + HW_SSP_CTRL0);
+
+	/* prepare the command, when no response is expected add a few trailing clocks */
+	writel(SSP_CMD0_CMD(cmd->cmdidx) |
+		(cmd->resp_type & MMC_RSP_PRESENT ? 0 : SSP_CMD0_APPEND_8CYC),
+		hw_dev->map_base + HW_SSP_CMD0);
+
+	/* prepare command's arguments */
+	writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
+
+	stm_setup_timout(hw_dev, 0xffff);
+
+	/* start the transfer */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 4);
+
+	/* wait until finished */
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_RUN)
+		;
+
+	if (cmd->resp_type & MMC_RSP_PRESENT)
+		get_cards_response(hw_dev, cmd);
+
+	return get_cmd_error(readl(hw_dev->map_base + HW_SSP_STATUS));
+}
+
+/**
+ * Handle an "addressed data transfer command " with or without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.) May be NULL
+ * @return 0 on success
+ */
+static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+	uint32_t xfer_cnt, log2blocksize, block_cnt;
+	int err;
+
+	/* Note: 'data' can be NULL! */
+	if (data != NULL) {
+		xfer_cnt = data->blocks * data->blocksize;
+		block_cnt = data->blocks - 1;	/* can be 0 */
+		log2blocksize = find_first_bit((const unsigned long*)&data->blocksize, 32);
+	} else
+		xfer_cnt = log2blocksize = block_cnt = 0;
+
+	/* setup command and transfer parameters */
+	writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
+		SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
+		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
+		SSP_CTRL0_ENABLE |
+		SSP_CTRL0_XFER_COUNT(xfer_cnt), /* byte count to be transfered */
+		hw_dev->map_base + HW_SSP_CTRL0);
+
+	/* prepare the command and the transfered data count */
+	writel(SSP_CMD0_CMD(cmd->cmdidx) |
+		SSP_CMD0_BLOCK_SIZE(log2blocksize) |
+		SSP_CMD0_BLOCK_COUNT(block_cnt) |
+		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
+		hw_dev->map_base + HW_SSP_CMD0);
+
+	/* prepare command's arguments */
+	writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
+
+	stm_setup_timout(hw_dev, 0xffff);
+
+	err = transfer_data(hw_dev, data);
+	if (err != 0) {
+		pr_debug(" Transfering data failed\n");
+		return err;
+	}
+
+	/* wait until finished */
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_RUN)
+		;
+
+	get_cards_response(hw_dev, cmd);
+
+	return 0;
+}
+
+
+/**
+ * @param hw_dev Host interface device instance
+ * @param nc New Clock in [Hz] (may be 0 to disable the clock)
+ * @return The real clock frequency
+ *
+ * The SSP unit clock can base on the external 24 MHz or the internal 480 MHz
+ * Its unit clock value is derived from the io clock, from the SSP divider
+ * and at least the SSP bus clock itself is derived from the SSP unit's divider
+ *
+ * @code
+ * |------------------- generic -------------|-peripheral specific-|-----all SSPs-----|-per SSP unit-|
+ *  24 MHz ----------------------------
+ *          \                          \
+ *           \                          |----| FRAC |----IO CLK----| SSP unit DIV |---| SSP DIV |--- SSP output clock
+ *            \- | PLL |--- 480 MHz ---/
+ * @endcode
+ *
+ * @note Up to "SSP unit DIV" the outer world must care. This routine only
+ * handles the "SSP DIV".
+ */
+static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
+{
+	unsigned ssp, div1, div2, reg;
+
+	if (nc == 0U) {
+		/* TODO stop the clock */
+		return 0;
+	}
+
+	ssp = imx_get_sspclk() * 1000;
+
+	for (div1 = 2; div1 < 255; div1 += 2) {
+		div2 = ssp / nc / div1;
+		if (div2 <= 0x100)
+			break;
+	}
+	if (div1 >= 255) {
+		pr_warning("Cannot set clock to %d Hz\n", nc);
+		return 0;
+	}
+
+	reg = readl(hw_dev->map_base + HW_SSP_TIMING) & SSP_TIMING_TIMEOUT_MASK;
+	reg |= SSP_TIMING_CLOCK_DIVIDE(div1) | SSP_TIMING_CLOCK_RATE(div2 - 1);
+	writel(reg, hw_dev->map_base + HW_SSP_TIMING);
+
+	return ssp / div1 / div2;
+}
+
+/**
+ * Reset the MCI engine (the hard way)
+ * @param hw_dev Host interface instance
+ *
+ * This will reset everything in all registers of this unit! (FIXME)
+ */
+static void stm_mci_reset(struct device_d *hw_dev)
+{
+	writel(SSP_CTRL0_SFTRST, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_SFTRST)
+		;
+}
+
+/**
+ * Initialize the engine
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance
+ *
+ * @todo Initialisierung dieses Taktes und seiner Umschaltung: siehe mx23_evk.c aus u-boot
+ * der Takt muss von extern laufen, sonst geht hier nix!
+ */
+static int stm_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+
+	/* enable the clock to this unit to be able to reset it */
+	writel(SSP_CTRL0_CLKGATE, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+
+	/* reset the unit */
+	stm_mci_reset(hw_dev);
+
+	/* restore the last settings */
+	mci_pdata->clock = host_data->clock = setup_clock_speed(hw_dev, mci_pdata->clock);
+	stm_setup_timout(hw_dev, 0xffff);
+	writel(SSP_CTRL0_IGNORE_CRC |
+		SSP_CTRL0_BUS_WIDTH(host_data->bus_width), hw_dev->map_base + HW_SSP_CTRL0);
+	writel(SSP_CTRL1_POLARITY |
+		SSP_CTRL1_SSP_MODE(3) |
+		SSP_CTRL1_WORD_LENGTH(7), hw_dev->map_base + HW_SSP_CTRL1);
+
+	return 0;
+}
+
+/* ------------------------- MCI API -------------------------------------- */
+
+/**
+ * Keep the attached MMC/SD unit in a well know state
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative value else
+ */
+static int mci_reset(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	return stm_mci_initialize(hw_dev, mci_dev);
+}
+
+/**
+ * Process one command to the MCI card
+ * @param hw_dev Host interface instance
+ * @param cmd The command to process
+ * @param data The data to handle in the command (can be NULL)
+ * @return 0 on success, negative value else
+ */
+static int mci_request(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	int rc;
+
+	if ((cmd->resp_type == 0) || (data == NULL))
+		rc = stm_mci_std_cmds(hw_dev, cmd);
+	else
+		rc = stm_mci_adtc(hw_dev, cmd, data);	/* with response and data */
+
+	finish_request(hw_dev);	/* TODO */
+	return rc;
+}
+
+/**
+ * Setup the bus width and IO speed
+ * @param hw_dev Host interface device instance
+ * @param mci_dev MCI device instance
+ * @param bus_width New bus width value (1, 4 or 8)
+ * @param clock New clock in Hz (can be '0' to disable the clock)
+ *
+ * Drivers currently realized values are stored in MCI's platformdata
+ */
+static void mci_set_ios(struct device_d *hw_dev, struct device_d *mci_dev, unsigned bus_width, unsigned clock)
+{
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+	struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
+
+	switch (bus_width) {
+	case 8:
+		host_data->bus_width = 2;
+		mci_pdata->bus_width = 8;	/* 8 bit is possible */
+		break;
+	case 4:
+		host_data->bus_width = 1;
+		mci_pdata->bus_width = 4;	/* 4 bit is possible */
+		break;
+	default:
+		host_data->bus_width = 0;
+		mci_pdata->bus_width = 1;	/* 1 bit is possible */
+		break;
+	}
+
+	mci_pdata->clock = host_data->clock = setup_clock_speed(hw_dev, clock);
+	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", mci_pdata->bus_width, mci_pdata->clock);
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+const unsigned char bus_width[3] = { 1, 4, 8 };
+
+static void stm_info(struct device_d *hw_dev)
+{
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+
+	printf(" Interface\n");
+	printf("  Min. bus clock: %u Hz\n", host_data->f_min);
+	printf("  Max. bus clock: %u Hz\n", host_data->f_max);
+	printf("  Current bus clock: %u Hz\n", host_data->clock);
+	printf("  Bus width: %u bit\n", bus_width[host_data->bus_width]);
+	printf("\n");
+}
+#endif
+
+static int stm_mci_probe(struct device_d *hw_dev)
+{
+	struct stm_mci_platform_data *pd = (struct stm_mci_platform_data*)hw_dev->platform_data;
+	struct stm_mci_host *host_data;
+	struct mci_platformdata *mci_pdata;
+
+	if (hw_dev->platform_data == NULL) {
+		pr_err("Missing platform data\n");
+		return -EINVAL;
+	}
+
+	mci_pdata = xzalloc(sizeof(struct stm_mci_host) + sizeof(struct mci_platformdata));
+	host_data = (struct stm_mci_host*)&mci_pdata[1];
+
+	hw_dev->priv = host_data;
+	mci_pdata->hw_dev = hw_dev;
+	mci_pdata->send_cmd = mci_request,
+	mci_pdata->set_ios = mci_set_ios,
+	mci_pdata->init = mci_reset,
+
+	/* feed forward the platform specific values */
+	mci_pdata->voltages = pd->voltages;
+	mci_pdata->host_caps = pd->caps;
+
+	if (pd->f_min == 0) {
+		mci_pdata->f_min = imx_get_sspclk() / 254U / 256U * 1000U;
+		pr_debug("Min. frequency is %u Hz\n", mci_pdata->f_min);
+	} else {
+		mci_pdata->f_min = pd->f_min;
+		pr_debug("Min. frequency is %u Hz, could be %u Hz\n", mci_pdata->f_min, imx_get_sspclk() / 254U / 256U * 1000U);
+	}
+	if (pd->f_max == 0) {
+		mci_pdata->f_max = imx_get_sspclk() / 2U / 1U * 1000U;
+		pr_debug("Max. frequency is %u Hz\n", mci_pdata->f_max);
+	} else {
+		mci_pdata->f_max =  pd->f_max;
+		pr_debug("Max. frequency is %u Hz, could be %u Hz\n", mci_pdata->f_max, imx_get_sspclk() / 2U / 1U * 1000U);
+	}
+
+#ifdef CONFIG_MCI_INFO
+	host_data->f_min = mci_pdata->f_min;
+	host_data->f_max = mci_pdata->f_max;
+#endif
+
+	return mci_register(mci_pdata);
+}
+
+static struct driver_d stm_mci_driver = {
+        .name  = "stm_mci",
+        .probe = stm_mci_probe,
+#ifdef CONFIG_MCI_INFO
+	.info = stm_info,
+#endif
+};
+
+static int stm_mci_init_driver(void)
+{
+        register_driver(&stm_mci_driver);
+        return 0;
+}
+
+device_initcall(stm_mci_init_driver);
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 09:24:18 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 15:24:18 +0200
Subject: [PATCH 7/7] Add S3C2440 MCI card support
In-Reply-To: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286457858-29771-8-git-send-email-jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>

Adding MCI card support for S3C2440 CPUs. This is for reference only, as there
is currently no user in the barebox tree. Maybe one with access to the A9M2440
development kit can check it on his/her system.
Checked here with my own S3C2440 based system which is not in the barebox tree.

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
---
 arch/arm/mach-s3c24xx/include/mach/mci.h |   46 ++
 drivers/mci/Kconfig                      |    7 +
 drivers/mci/Makefile                     |    1 +
 drivers/mci/s3c.c                        |  801 ++++++++++++++++++++++++++++++
 4 files changed, 855 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s3c24xx/include/mach/mci.h
 create mode 100644 drivers/mci/s3c.c

diff --git a/arch/arm/mach-s3c24xx/include/mach/mci.h b/arch/arm/mach-s3c24xx/include/mach/mci.h
new file mode 100644
index 0000000..6ba8961
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/mci.h
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is partially based on u-boot code:
+ *
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MACH_MMC_H_
+#define __MACH_MMC_H_
+
+struct s3c_mci_platform_data {
+	unsigned caps;	/**< supported operating modes (MMC_MODE_*) */
+	unsigned voltages; /**< supported voltage range (MMC_VDD_*) */
+	unsigned f_min;	/**< min operating frequency in Hz (0 -> no limit) */
+	unsigned f_max;	/**< max operating frequency in Hz (0 -> no limit) */
+	/* TODO */
+	/* function to modify the voltage */
+	/* function to switch the voltage */
+	/* function to detect the presence of a SD card in the socket */
+	unsigned gpio_detect;
+	unsigned detect_invert;
+};
+
+#endif /* __MACH_MMC_H_ */
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index a24ae6d..644c0a3 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -34,4 +34,11 @@ config MCI_STM378X
 	  Enable this entry to add support to read and write SD cards on a
 	  i.MX23 based system.
 
+config MCI_S3C
+	bool "S3C"
+	depends on ARCH_S3C24xx
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  Samsung S3C24xx based system.
+
 endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index e5e19b0..be18446 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_MCI)	+= mci-core.o
 obj-$(CONFIG_MCI_STM378X) += stm378x.o
+obj-$(CONFIG_MCI_S3C) += s3c.o
diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
new file mode 100644
index 0000000..3813be7
--- /dev/null
+++ b/drivers/mci/s3c.c
@@ -0,0 +1,801 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert <juergen at kreuzholzen.de>
+ *
+ * This code is partially based on u-boot code:
+ *
+ * This code is based on various Linux and u-boot sources:
+ *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk at maintech.de>
+ *  Copyright (C) 2008 Simtec Electronics <ben-linux at fluff.org>
+ *  (C) Copyright 2006 by OpenMoko, Inc.
+ *  Author: Harald Welte <laforge at openmoko.org>
+ *  based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
+ *  (C) 2005-2005 Thomas Kleffel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * @file
+ * @brief MCI card host interface for S3C2440 CPU
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <mci.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+#include <mach/mci.h>
+#include <mach/s3c24xx-generic.h>
+#include <mach/s3c24x0-iomap.h>
+
+#define SDICON 0x0
+# define SDICON_SDRESET (1 << 8)
+# define SDICON_MMCCLOCK (1 << 5) /* this is a clock type SD or MMC style WTF? */
+# define SDICON_BYTEORDER (1 << 4)
+# define SDICON_SDIOIRQ (1 << 3)
+# define SDICON_RWAITEN (1 << 2)
+# define SDICON_FIFORESET (1 << 1) /* reserved bit on 2440 ????? */
+# define SDICON_CLKEN (1 << 0) /* enable/disable external clock */
+
+#define SDIPRE 0x4
+
+#define SDICMDARG 0x8
+
+#define SDICMDCON 0xc
+# define SDICMDCON_ABORT (1 << 12)
+# define SDICMDCON_WITHDATA (1 << 11)
+# define SDICMDCON_LONGRSP (1 << 10)
+# define SDICMDCON_WAITRSP (1 << 9)
+# define SDICMDCON_CMDSTART (1 << 8)
+# define SDICMDCON_SENDERHOST (1 << 6)
+# define SDICMDCON_INDEX (0x3f)
+
+#define SDICMDSTAT 0x10
+# define SDICMDSTAT_CRCFAIL (1 << 12)
+# define SDICMDSTAT_CMDSENT (1 << 11)
+# define SDICMDSTAT_CMDTIMEOUT (1 << 10)
+# define SDICMDSTAT_RSPFIN (1 << 9)
+# define SDICMDSTAT_XFERING (1 << 8)
+# define SDICMDSTAT_INDEX (0xff)
+
+#define SDIRSP0 0x14
+#define SDIRSP1 0x18
+#define SDIRSP2 0x1C
+#define SDIRSP3 0x20
+
+#define SDITIMER 0x24
+#define SDIBSIZE 0x28
+
+#define SDIDCON 0x2c
+# define SDIDCON_DS_BYTE (0 << 22)
+# define SDIDCON_DS_HALFWORD (1 << 22)
+# define SDIDCON_DS_WORD (2 << 22)
+# define SDIDCON_IRQPERIOD (1 << 21)
+# define SDIDCON_TXAFTERRESP (1 << 20)
+# define SDIDCON_RXAFTERCMD (1 << 19)
+# define SDIDCON_BUSYAFTERCMD (1 << 18)
+# define SDIDCON_BLOCKMODE (1 << 17)
+# define SDIDCON_WIDEBUS (1 << 16)
+# define SDIDCON_DMAEN (1 << 15)
+# define SDIDCON_STOP (0 << 14)
+# define SDIDCON_DATSTART (1 << 14)
+# define SDIDCON_DATMODE (3 << 12)
+# define SDIDCON_BLKNUM (0xfff)
+# define SDIDCON_XFER_READY    (0 << 12)
+# define SDIDCON_XFER_CHKSTART (1 << 12)
+# define SDIDCON_XFER_RXSTART  (2 << 12)
+# define SDIDCON_XFER_TXSTART  (3 << 12)
+
+#define SDIDCNT 0x30
+# define SDIDCNT_BLKNUM_SHIFT 12
+
+#define SDIDSTA 0x34
+# define SDIDSTA_RDYWAITREQ (1 << 10)
+# define SDIDSTA_SDIOIRQDETECT (1 << 9)
+# define SDIDSTA_FIFOFAIL (1 << 8) /* reserved on 2440 */
+# define SDIDSTA_CRCFAIL (1 << 7)
+# define SDIDSTA_RXCRCFAIL (1 << 6)
+# define SDIDSTA_DATATIMEOUT (1 << 5)
+# define SDIDSTA_XFERFINISH (1 << 4)
+# define SDIDSTA_BUSYFINISH (1 << 3)
+# define SDIDSTA_SBITERR (1 << 2) /* reserved on 2410a/2440 */
+# define SDIDSTA_TXDATAON (1 << 1)
+# define SDIDSTA_RXDATAON (1 << 0)
+
+#define SDIFSTA 0x38
+# define SDIFSTA_FIFORESET (1<<16)
+# define SDIFSTA_FIFOFAIL (3<<14)  /* 3 is correct (2 bits) */
+# define SDIFSTA_TFDET (1<<13)
+# define SDIFSTA_RFDET (1<<12)
+# define SDIFSTA_TFHALF (1<<11)
+# define SDIFSTA_TFEMPTY (1<<10)
+# define SDIFSTA_RFLAST (1<<9)
+# define SDIFSTA_RFFULL (1<<8)
+# define SDIFSTA_RFHALF (1<<7)
+# define SDIFSTA_COUNTMASK (0x7f)
+
+#define SDIIMSK 0x3C
+# define SDIIMSK_RESPONSECRC    (1<<17)
+# define SDIIMSK_CMDSENT        (1<<16)
+# define SDIIMSK_CMDTIMEOUT     (1<<15)
+# define SDIIMSK_RESPONSEND     (1<<14)
+# define SDIIMSK_READWAIT       (1<<13)
+# define SDIIMSK_SDIOIRQ        (1<<12)
+# define SDIIMSK_FIFOFAIL       (1<<11)
+# define SDIIMSK_CRCSTATUS      (1<<10)
+# define SDIIMSK_DATACRC        (1<<9)
+# define SDIIMSK_DATATIMEOUT    (1<<8)
+# define SDIIMSK_DATAFINISH     (1<<7)
+# define SDIIMSK_BUSYFINISH     (1<<6)
+# define SDIIMSK_SBITERR        (1<<5) /* reserved 2440/2410a */
+# define SDIIMSK_TXFIFOHALF     (1<<4)
+# define SDIIMSK_TXFIFOEMPTY    (1<<3)
+# define SDIIMSK_RXFIFOLAST     (1<<2)
+# define SDIIMSK_RXFIFOFULL     (1<<1)
+# define SDIIMSK_RXFIFOHALF     (1<<0)
+
+#define SDIDATA 0x40
+
+#define CLOCKRATE_MIN (1 * 1000 * 1000)
+#define CLOCKRATE_MAX (480 * 1000 * 1000)
+
+struct s3c_mci_host {
+	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
+	unsigned	clock;	/* current clock in Hz */
+	unsigned	data_size;	/* data transfer in bytes */
+};
+
+/*
+ * There is only one host MCI hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct s3c_mci_host host_data;
+
+/**
+ * Finish a request
+ * @param hw_dev Host interface instance
+ *
+ * Just a little bit paranoia.
+ */
+static void s3c_finish_request(struct device_d *hw_dev)
+{
+	/* TODO ensure the engines are stopped */
+}
+
+/* TODO GPIO feature is required for this architecture */
+static unsigned gpio_get_value(unsigned val)
+{
+	return 0;
+}
+
+/**
+ * Detect if a card is plugged in
+ * @param hw_dev Host interface instance
+ * @return 0 if a card is plugged in
+ *
+ * Note: If there is no GPIO registered to detect if a card is present, we
+ * assume a card _is_ present.
+ */
+static int s3c_mci_card_present(struct device_d *hw_dev)
+{
+	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)GET_HOST_PDATA(hw_dev);
+	int ret;
+
+	if (pd->gpio_detect == 0)
+		return 0;	/* assume the card is present */
+
+	ret = gpio_get_value(pd->gpio_detect) ? 0 : 1;
+	return ret ^ pd->detect_invert;
+}
+
+/**
+ * Setup a new clock frequency on this MCI bus
+ * @param hw_dev Host interface instance
+ * @param nc New clock value in Hz (can be 0)
+ * @return New clock value (may differ from 'nc')
+ */
+static unsigned s3c_setup_clock_speed(struct device_d *hw_dev, unsigned nc)
+{
+	unsigned clock;
+	uint32_t mci_psc;
+
+	if (nc == 0)
+		return 0;
+
+	clock = s3c24xx_get_pclk();
+	/* Calculate the required prescaler value to get the requested frequency */
+	mci_psc = (clock + (nc >> 2)) / nc;
+
+	if (mci_psc > 256) {
+		mci_psc = 256;
+		pr_warning("SD/MMC clock might be too high!\n");
+	}
+
+	writel(mci_psc - 1, hw_dev->map_base + SDIPRE);
+
+	return clock / mci_psc;
+}
+
+/**
+ * Reset the MCI engine (the hard way)
+ * @param hw_dev Host interface instance
+ *
+ * This will reset everything in all registers of this unit!
+ */
+static void s3c_mci_reset(struct device_d *hw_dev)
+{
+	/* reset the hardware */
+	writel(SDICON_SDRESET, hw_dev->map_base + SDICON);
+	/* wait until reset it finished */
+	while (readl(hw_dev->map_base + SDICON) & SDICON_SDRESET)
+		;
+}
+
+/**
+ * Initialize hard and software
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance (might be NULL)
+ */
+static int s3c_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
+
+	s3c_mci_reset(hw_dev);
+
+	/* restore last settings */
+	host_data->clock = s3c_setup_clock_speed(hw_dev, host_data->clock);
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+	writel(SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
+	writel(512, hw_dev->map_base + SDIBSIZE);
+
+	return 0;
+}
+
+/**
+ * Prepare engine's bits for the next command transfer
+ * @param cmd_flags MCI's command flags
+ * @param data_flags MCI's data flags
+ * @return Register bits for this transfer
+ */
+static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned data_flags)
+{
+	uint32_t reg;
+
+	/* source (=host) */
+	reg = SDICMDCON_SENDERHOST;
+
+	if (cmd_flags & MMC_RSP_PRESENT) {
+		reg |= SDICMDCON_WAITRSP;
+		pr_debug("Command with response\n");
+	}
+	if (cmd_flags & MMC_RSP_136) {
+		reg |= SDICMDCON_LONGRSP;
+		pr_debug("Command with long response\n");
+	}
+	if (cmd_flags & MMC_RSP_CRC)
+		; /* FIXME */
+	if (cmd_flags & MMC_RSP_BUSY)
+		; /* FIXME */
+	if (cmd_flags & MMC_RSP_OPCODE)
+		; /* FIXME */
+	if (data_flags != 0)
+		reg |= SDICMDCON_WITHDATA;
+
+	return reg;
+}
+
+/**
+ * Prepare engine's bits for the next data transfer
+ * @param hw_dev Host interface device instance
+ * @param data_flags MCI's data flags
+ * @return Register bits for this transfer
+ */
+static uint32_t s3c_prepare_data_setup(struct device_d *hw_dev, unsigned data_flags)
+{
+	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
+	uint32_t reg = SDIDCON_BLOCKMODE;	/* block mode only is supported */
+
+	if (host_data->bus_width == 1)
+		reg |= SDIDCON_WIDEBUS;
+
+	/* enable any kind of data transfers on demand only */
+	if (data_flags & MMC_DATA_WRITE)
+		reg |= SDIDCON_TXAFTERRESP | SDIDCON_XFER_TXSTART;
+
+	if (data_flags & MMC_DATA_READ)
+		reg |= SDIDCON_RXAFTERCMD | SDIDCON_XFER_RXSTART;
+
+	/* TODO: Support more than the 2440 CPU */
+	reg |= SDIDCON_DS_WORD | SDIDCON_DATSTART;
+
+	return reg;
+}
+
+/**
+ * Terminate a current running transfer
+ * @param hw_dev Host interface device instance
+ * @return 0 on success
+ *
+ * Note: Try to stop a running transfer. This should not happen, as all
+ * transfers must complete in this driver. But who knows... ;-)
+ */
+static int s3c_terminate_transfer(struct device_d *hw_dev)
+{
+	unsigned stoptries = 3;
+
+	while (readl(hw_dev->map_base + SDIDSTA) & (SDIDSTA_TXDATAON | SDIDSTA_RXDATAON)) {
+		pr_debug("Transfer still in progress.\n");
+
+		writel(SDIDCON_STOP, hw_dev->map_base + SDIDCON);
+		s3c_mci_initialize(hw_dev, NULL);
+
+		if ((stoptries--) == 0) {
+			pr_warning("Cannot stop the engine!\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Setup registers for data transfer
+ * @param hw_dev Host interface device instance
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_prepare_data_transfer(struct device_d *hw_dev, struct mci_data *data)
+{
+	uint32_t reg;
+
+	writel(data->blocksize, hw_dev->map_base + SDIBSIZE);
+	reg = s3c_prepare_data_setup(hw_dev, data->flags);
+	reg |= data->blocks & SDIDCON_BLKNUM;
+	writel(reg, hw_dev->map_base + SDIDCON);
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+
+	return 0;
+}
+
+/**
+ * Send a command and receive the response
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_send_command(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	uint32_t reg, t1;
+	int rc;
+
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+
+	/* setup argument */
+	writel(cmd->cmdarg, hw_dev->map_base + SDICMDARG);
+
+	/* setup command and transfer characteristic */
+	reg = s3c_prepare_command_setup(cmd->resp_type, data != NULL ? data->flags : 0);
+	reg |= cmd->cmdidx & SDICMDCON_INDEX;
+
+	/* run the command right now */
+	writel(reg | SDICMDCON_CMDSTART, hw_dev->map_base + SDICMDCON);
+	t1 = readl(hw_dev->map_base + SDICMDSTAT);
+	/* wait until command is done */
+	while (1) {
+		reg = readl(hw_dev->map_base + SDICMDSTAT);
+		/* done? */
+		if (cmd->resp_type & MMC_RSP_PRESENT) {
+			if (reg & SDICMDSTAT_RSPFIN) {
+				writel(SDICMDSTAT_RSPFIN, hw_dev->map_base + SDICMDSTAT); /* required??? */
+				rc = 0;
+				break;
+			}
+		} else {
+			if (reg & SDICMDSTAT_CMDSENT) {
+					writel(SDICMDSTAT_CMDSENT, hw_dev->map_base + SDICMDSTAT); /* required??? */
+					rc = 0;
+					break;
+			}
+		}
+		/* timeout? */
+		if (reg & SDICMDSTAT_CMDTIMEOUT) {
+			writel(SDICMDSTAT_CMDTIMEOUT, hw_dev->map_base + SDICMDSTAT); /* required??? */
+			rc = -ETIMEDOUT;
+			break;
+		}
+	}
+
+	if ((rc == 0) && (cmd->resp_type & MMC_RSP_PRESENT)) {
+		cmd->response[0] = readl(hw_dev->map_base + SDIRSP0);
+		cmd->response[1] = readl(hw_dev->map_base + SDIRSP1);
+		cmd->response[2] = readl(hw_dev->map_base + SDIRSP2);
+		cmd->response[3] = readl(hw_dev->map_base + SDIRSP3);
+	}
+	/* do not disable the clock! */
+	return rc;
+}
+
+/**
+ * Clear major registers prior a new transaction
+ * @param hw_dev Host interface device instance
+ * @return 0 on success
+ *
+ * FIFO clear is only necessary on 2440, but doesn't hurt on 2410
+ */
+static int s3c_prepare_engine(struct device_d *hw_dev)
+{
+	int rc;
+
+	rc = s3c_terminate_transfer(hw_dev);
+	if (rc != 0)
+		return rc;
+
+	writel(-1, hw_dev->map_base + SDICMDSTAT);
+	writel(-1, hw_dev->map_base + SDIDSTA);
+	writel(-1, hw_dev->map_base + SDIFSTA);
+
+	return 0;
+}
+
+/**
+ * Handle MCI commands without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @return 0 on success
+ *
+ * This functions handles the following MCI commands:
+ * - "broadcast command (BC)" without a response
+ * - "broadcast commands with response (BCR)"
+ * - "addressed command (AC)" with response, but without data
+ */
+static int s3c_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	int rc;
+
+	rc = s3c_prepare_engine(hw_dev);
+	if (rc != 0)
+		return 0;
+
+	return s3c_send_command(hw_dev, cmd, NULL);
+}
+
+/**
+ * Read one block of data from the FIFO
+ * @param hw_dev Host interface device instance
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_mci_read_block(struct device_d *hw_dev, struct mci_data *data)
+{
+	uint32_t *p;
+	unsigned cnt, data_size;
+
+#define READ_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_RXCRCFAIL | SDIDSTA_DATATIMEOUT)
+
+	p = (uint32_t*)data->dest;
+	data_size = data->blocksize * data->blocks;
+
+	while (data_size > 0) {
+
+		/* serious error? */
+		if (readl(hw_dev->map_base + SDIDSTA) & READ_REASON_TO_FAIL) {
+			pr_err("Failed while reading data\n");
+			return -EIO;
+		}
+
+		/* now check the FIFO status */
+		if (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_FIFOFAIL) {
+			pr_err("Data loss due to FIFO overflow when reading\n");
+			return -EIO;
+		}
+
+		/* we only want to read full words */
+		cnt = (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) >> 2;
+
+		/* read one chunk of data from the FIFO */
+		while (cnt--) {
+			*p = readl(hw_dev->map_base + SDIDATA);
+			p++;
+			if (data_size >= 4)
+				data_size -= 4;
+			else {
+				data_size = 0;
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Write one block of data into the FIFO
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ *
+ * We must ensure data in the FIFO when the command phase changes into the
+ * data phase. To ensure this, the FIFO gets filled first, then the command.
+ */
+static int s3c_mci_write_block(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	const uint32_t *p = (const uint32_t*)data->src;
+	unsigned cnt, data_size;
+	uint32_t reg;
+
+#define WRITE_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_DATATIMEOUT)
+
+	data_size = data->blocksize * data->blocks;
+	/*
+	 * With high clock rates we must fill the FIFO as early as possible
+	 * Its size is 16 words. We assume its empty, when this function is
+	 * entered.
+	 */
+	cnt = 16;
+	while (cnt--) {
+		writel(*p, hw_dev->map_base + SDIDATA);
+		p++;
+		if (data_size >= 4)
+			data_size -= 4;
+		else {
+			data_size = 0;
+			break;
+		}
+	}
+
+	/* data is now in place and waits for transmitt. Start the command right now */
+	s3c_send_command(hw_dev, cmd, data);
+
+	if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
+		pr_err("Command fails immediatly due to FIFO underrun when writing %08X\n", reg);
+		return -EIO;
+	}
+
+	while (data_size > 0) {
+
+		if (readl(hw_dev->map_base + SDIDSTA) & WRITE_REASON_TO_FAIL) {
+			pr_err("Failed writing data\n");
+			return -EIO;
+		}
+
+		/* now check the FIFO status */
+		if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
+			pr_err("Data loss due to FIFO underrun when writing %08X\n", reg);
+			return -EIO;
+		}
+
+		/* we only want to write full words */
+		cnt = 16 - (((readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) + 3) >> 2);
+
+		/* fill the FIFO if it has free entries */
+		while (cnt--) {
+			writel(*p, hw_dev->map_base + SDIDATA);
+			p++;
+			if (data_size >= 4)
+				data_size -= 4;
+			else {
+				data_size = 0;
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Handle MCI commands with or without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+*/
+static int s3c_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	int rc;
+
+	rc = s3c_prepare_engine(hw_dev);
+	if (rc != 0)
+		return rc;
+
+	rc = s3c_prepare_data_transfer(hw_dev, data);
+	if (rc != 0)
+		return rc;
+
+	if (data->flags & MMC_DATA_READ) {
+		s3c_send_command(hw_dev, cmd, data);
+		rc = s3c_mci_read_block(hw_dev, data);
+		if (rc == 0) {
+			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
+				;
+		} else
+			s3c_terminate_transfer(hw_dev);
+	}
+
+	if (data->flags & MMC_DATA_WRITE) {
+		rc = s3c_mci_write_block(hw_dev, cmd, data);
+		if (rc == 0) {
+			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
+				;
+		} else
+			s3c_terminate_transfer(hw_dev);
+	}
+	writel(0, hw_dev->map_base + SDIDCON);
+
+	return rc;
+}
+
+/* ------------------------- MCI API -------------------------------------- */
+
+/**
+ * Keep the attached MMC/SD unit in a well know state
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative value else
+ */
+static int mci_reset(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	return s3c_mci_initialize(hw_dev, mci_dev);
+}
+
+/**
+ * Process one command to the MCI card
+ * @param hw_dev Host interface instance
+ * @param cmd The command to process
+ * @param data The data to handle in the command (can be NULL)
+ * @return 0 on success, negative value else
+ */
+static int mci_request(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	int rc;
+
+	/* enable clock */
+	writel(readl(hw_dev->map_base + SDICON) | SDICON_CLKEN, hw_dev->map_base + SDICON);
+
+	if ((cmd->resp_type == 0) || (data == NULL))
+		rc = s3c_mci_std_cmds(hw_dev, cmd);
+	else
+		rc = s3c_mci_adtc(hw_dev, cmd, data);	/* with response and data */
+
+	s3c_finish_request(hw_dev);
+
+	/* disable clock */
+	writel(readl(hw_dev->map_base + SDICON) & ~SDICON_CLKEN, hw_dev->map_base + SDICON);
+	return rc;
+}
+
+/**
+ * Setup the bus width and IO speed
+ * @param hw_dev Host interface device instance
+ * @param mci_dev MCI device instance
+ * @param bus_width New bus width value (1, 4 or 8)
+ * @param clock New clock in Hz (can be '0' to disable the clock)
+ */
+static void mci_set_ios(struct device_d *hw_dev, struct device_d *mci_dev, unsigned bus_width, unsigned clock)
+{
+	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
+	struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
+	uint32_t reg;
+
+	switch (bus_width) {
+	case 8:		/* no 8 bit support, fall back to 4 bit */
+	case 4:
+		host_data->bus_width = 1;
+		mci_pdata->bus_width = 4;	/* 4 bit is possible */
+		break;
+	default:
+		host_data->bus_width = 0;
+		mci_pdata->bus_width = 1;	/* 1 bit is possible */
+		break;
+	}
+
+	reg = readl(hw_dev->map_base + SDICON);
+	if (clock) {
+		/* setup the IO clock frequency and enable it */
+		mci_pdata->clock = host_data->clock = s3c_setup_clock_speed(hw_dev, clock);
+		reg |= SDICON_CLKEN;	/* enable the clock */
+	} else {
+		reg &= ~SDICON_CLKEN;	/* disable the clock */
+		mci_pdata->clock = host_data->clock = 0;
+	}
+	writel(reg, hw_dev->map_base + SDICON);
+
+	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", mci_pdata->bus_width, mci_pdata->clock);
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+static void s3c_info(struct device_d *hw_dev)
+{
+	struct s3c_mci_host *host = (struct s3c_mci_host*)hw_dev->priv;
+	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
+
+	printf("  Bus data width: %d bit\n", host->bus_width == 1 ? 4 : 1);
+	printf("  Bus frequency: %u Hz\n", host->clock);
+	printf("   Frequency limits: ");
+	if (pd->f_min == 0)
+		printf("no lower limit ");
+	else
+		printf("%u Hz lower limit ", pd->f_min);
+	if (pd->f_max == 0)
+		printf("- no upper limit");
+	else
+		printf("- %u Hz upper limit", pd->f_max);
+	printf("\n  Card detection support: %s\n", pd->gpio_detect != 0 ? "yes" : "no");
+}
+#endif
+
+/*
+ * There is only one host MCI hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct mci_platformdata mci_pdata = {
+	.send_cmd = mci_request,
+	.set_ios = mci_set_ios,
+	.init = mci_reset,
+};
+
+static int s3c_mci_probe(struct device_d *hw_dev)
+{
+	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
+
+	/* TODO replace by the global func: enable the SDI unit clock */
+	writel(readl(S3C24X0_CLOCK_POWER_BASE + 0x0c) | 0x200,S3C24X0_CLOCK_POWER_BASE + 0x0c);
+
+	if (pd == NULL) {
+		pr_err("Missing platform data\n");
+		return -EINVAL;
+	}
+
+	hw_dev->priv = &host_data;
+	mci_pdata.hw_dev = hw_dev;
+
+	/* feed forward the platform specific values */
+	mci_pdata.voltages = pd->voltages;
+	mci_pdata.host_caps = pd->caps;
+	mci_pdata.f_min = pd->f_min == 0 ? CLOCKRATE_MIN : pd->f_min;
+	mci_pdata.f_max = pd->f_max == 0 ? CLOCKRATE_MAX : pd->f_max;
+
+	/*
+	 * Start the clock to let the engine and the card finishes its startup
+	 */
+	host_data.clock = s3c_setup_clock_speed(hw_dev, mci_pdata.f_min);
+	writel(SDICON_FIFORESET | SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
+
+	return mci_register(&mci_pdata);
+}
+
+static struct driver_d s3c_mci_driver = {
+        .name  = "s3c_mci",
+        .probe = s3c_mci_probe,
+#ifdef CONFIG_MCI_INFO
+	.info = s3c_info,
+#endif
+};
+
+static int s3c_mci_init_driver(void)
+{
+        register_driver(&s3c_mci_driver);
+        return 0;
+}
+
+device_initcall(s3c_mci_init_driver);
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 10:59:53 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 16:59:53 +0200
Subject: Add the i.MX23/i.MX28 architecure
Message-ID: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>

This patch adds the basic support for the i.MX23/i.MX28 architecture. These
CPUs are branded with i.MX but they are mostly of type STMP378X from SigmaTel.
So, they do not share most of their internal devices with the other i.MX CPUs.
That's why I open a new sub architecture 'mach-stm'.

Comments are welcome.

Regards,
Juergen



From jbe at pengutronix.de  Thu Oct  7 10:59:55 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 16:59:55 +0200
Subject: [PATCH 2/4] Add the driver for the i.MX23 debug UART
In-Reply-To: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
References: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286463597-16948-3-git-send-email-jbe@pengutronix.de>

The i.MX23 comes with a special UART dedicated for debugging purposes. This one
is mostly used for the console the user can reach.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/serial/Kconfig      |    5 +
 drivers/serial/Makefile     |    1 +
 drivers/serial/stm-serial.c |  202 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 208 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/stm-serial.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index c7ea2d9..3a8882f 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -18,6 +18,11 @@ config DRIVER_SERIAL_IMX
 	default y
 	bool "i.MX serial driver"
 
+config DRIVER_SERIAL_STM378X
+	depends on ARCH_STM
+	default y
+	bool "i.MX23 serial driver"
+
 config DRIVER_SERIAL_NETX
 	depends on ARCH_NETX
 	default y
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 959290e..9f0e12b 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC)		+= arm_dcc.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_DRIVER_SERIAL_IMX)			+= serial_imx.o
+obj-$(CONFIG_DRIVER_SERIAL_STM378X)		+= stm-serial.o
 obj-$(CONFIG_DRIVER_SERIAL_ATMEL)		+= atmel.o
 obj-$(CONFIG_DRIVER_SERIAL_NETX)		+= serial_netx.o
 obj-$(CONFIG_DRIVER_SERIAL_LINUX_COMSOLE)	+= linux_console.o
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
new file mode 100644
index 0000000..1f08255
--- /dev/null
+++ b/drivers/serial/stm-serial.c
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This code was inspired by some patches made for u-boot covered by:
+ * (c) 2007 Sascha Hauer <s.hauer at pengutronix.de>
+ * (C) Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*
+ * Note: This is the driver for the debug UART. There is
+ * only one of these UARTs on the Freescale/SigmaTel parts
+ */
+
+#include <common.h>
+#include <init.h>
+#include <notifier.h>
+#include <gpio.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/clock-imx23.h>
+
+#define UARTDBGDR 0x00
+#define UARTDBGFR 0x18
+# define TXFF (1 << 5)
+# define RXFE (1 << 4)
+#define UARTDBGIBRD 0x24
+#define UARTDBGFBRD 0x28
+#define UARTDBGLCR_H 0x2c
+# define WLEN8 (3 << 5)
+# define WLEN7 (2 << 5)
+# define WLEN6 (1 << 5)
+# define WLEN5 (0 << 5)
+# define FEN (1 << 4)
+#define UARTDBGCR 0x30
+# define UARTEN (1 << 0)
+# define TXE (1 << 8)
+# define RXE (1 << 9)
+#define UARTDBGIMSC 0x38
+
+struct stm_serial_local {
+	struct console_device cdev;
+	int baudrate;
+	struct notifier_block notify;
+};
+
+static void stm_serial_putc(struct console_device *cdev, char c)
+{
+	struct device_d *dev = cdev->dev;
+
+	/* Wait for room in TX FIFO */
+	while (readl(dev->map_base + UARTDBGFR) & TXFF)
+		;
+
+	writel(c, dev->map_base + UARTDBGDR);
+}
+
+static int stm_serial_tstc(struct console_device *cdev)
+{
+	struct device_d *dev = cdev->dev;
+
+	/* Check if RX FIFO is not empty */
+	return !(readl(dev->map_base + UARTDBGFR) & RXFE);
+}
+
+static int stm_serial_getc(struct console_device *cdev)
+{
+	struct device_d *dev = cdev->dev;
+
+	/* Wait while TX FIFO is empty */
+	while (readl(dev->map_base + UARTDBGFR) & RXFE)
+		;
+
+	return readl(dev->map_base + UARTDBGDR) & 0xff;
+}
+
+static void stm_serial_flush(struct console_device *cdev)
+{
+	struct device_d *dev = cdev->dev;
+
+	/* Wait for TX FIFO empty */
+	while (readl(dev->map_base + UARTDBGFR) & TXFF)
+		;
+}
+
+static int stm_serial_setbaudrate(struct console_device *cdev, int new_baudrate)
+{
+	struct device_d *dev = cdev->dev;
+	struct stm_serial_local *local = container_of(cdev, struct stm_serial_local, cdev);
+	uint32_t cr, lcr_h, quot;
+
+	/* Disable everything */
+	cr = readl(dev->map_base + UARTDBGCR);
+	writel(0, dev->map_base + UARTDBGCR);
+
+	/* Calculate and set baudrate */
+	quot = (imx_get_xclk() * 4000) / new_baudrate;
+	writel(quot & 0x3f, dev->map_base + UARTDBGFBRD);
+	writel(quot >> 6, dev->map_base + UARTDBGIBRD);
+
+	/* Set 8n1 mode, enable FIFOs */
+	lcr_h = WLEN8 | FEN;
+	writel(lcr_h, dev->map_base + UARTDBGLCR_H);
+
+	/* Re-enable debug UART */
+	writel(cr, dev->map_base + UARTDBGCR);
+
+	local->baudrate = new_baudrate;
+
+	return 0;
+}
+
+static int stm_clocksource_clock_change(struct notifier_block *nb, unsigned long event, void *data)
+{
+	struct stm_serial_local *local = container_of(nb, struct stm_serial_local, notify);
+
+	return stm_serial_setbaudrate(&local->cdev, local->baudrate);
+}
+
+static int stm_serial_init_port(struct console_device *cdev)
+{
+	struct device_d *dev = cdev->dev;
+	/*
+	 * If the board specific file registers this console we should force
+	 * the usage of the debug UART pins, to be able to let the user see
+	 * the output, even if the board file forgets to configure these pins.
+	 */
+	imx_gpio_mode(PWM1_DUART_TX);
+	imx_gpio_mode(PWM0_DUART_RX);
+
+	/* Disable UART */
+	writel(0, dev->map_base + UARTDBGCR);
+
+	/* Mask interrupts */
+	writel(0, dev->map_base + UARTDBGIMSC);
+
+	return 0;
+}
+
+static struct stm_serial_local stm_device = {
+	.cdev = {
+		.f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR,
+		.tstc = stm_serial_tstc,
+		.putc = stm_serial_putc,
+		.getc = stm_serial_getc,
+		.flush = stm_serial_flush,
+		.setbrg = stm_serial_setbaudrate,
+	},
+};
+
+static int stm_serial_probe(struct device_d *dev)
+{
+	stm_device.cdev.dev = dev;
+	dev->type_data = &stm_device.cdev;
+
+	stm_serial_init_port(&stm_device.cdev);
+	stm_serial_setbaudrate(&stm_device.cdev, CONFIG_BAUDRATE);
+
+	/* Enable UART */
+	writel(TXE | RXE | UARTEN, dev->map_base + UARTDBGCR);
+
+	console_register(&stm_device.cdev);
+	stm_device.notify.notifier_call = stm_clocksource_clock_change;
+	clock_register_client(&stm_device.notify);
+
+	return 0;
+}
+
+static void stm_serial_remove(struct device_d *dev)
+{
+	struct console_device *cdev = dev->type_data;
+
+	stm_serial_flush(cdev);
+}
+
+static struct driver_d stm_serial_driver = {
+        .name   = "stm_serial",
+        .probe  = stm_serial_probe,
+	.remove = stm_serial_remove,
+};
+
+static int stm_serial_init(void)
+{
+	register_driver(&stm_serial_driver);
+	return 0;
+}
+
+console_initcall(stm_serial_init);
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 10:59:56 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 16:59:56 +0200
Subject: [PATCH 3/4] Add the i.MX23-EVK platform (WIP)
In-Reply-To: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
References: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286463597-16948-4-git-send-email-jbe@pengutronix.de>

Note: This is work in progress. Use with care.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/Makefile                             |    2 +
 arch/arm/boards/freescale-mx23-evk/Makefile   |    2 +
 arch/arm/boards/freescale-mx23-evk/config.h   |   16 ++
 arch/arm/boards/freescale-mx23-evk/mx23-evk.c |   80 +++++++++
 arch/arm/configs/imx23evk_defconfig           |  224 +++++++++++++++++++++++++
 arch/arm/mach-stm/Kconfig                     |    7 +
 6 files changed, 331 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/freescale-mx23-evk/Makefile
 create mode 100644 arch/arm/boards/freescale-mx23-evk/config.h
 create mode 100644 arch/arm/boards/freescale-mx23-evk/mx23-evk.c
 create mode 100644 arch/arm/configs/imx23evk_defconfig

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77b6cf4..75fa6d3 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -41,6 +41,7 @@ CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
 machine-$(CONFIG_ARCH_AT91)		:= at91
 machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_IMX)		:= imx
+machine-$(CONFIG_ARCH_STM)		:= stm
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_OMAP)		:= omap
@@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
 board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
+board-$(CONFIG_MACH_MX23EVK)			:= freescale-mx23-evk
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/freescale-mx23-evk/Makefile b/arch/arm/boards/freescale-mx23-evk/Makefile
new file mode 100644
index 0000000..cffb561
--- /dev/null
+++ b/arch/arm/boards/freescale-mx23-evk/Makefile
@@ -0,0 +1,2 @@
+#
+obj-y := mx23-evk.o
diff --git a/arch/arm/boards/freescale-mx23-evk/config.h b/arch/arm/boards/freescale-mx23-evk/config.h
new file mode 100644
index 0000000..4b3da8f
--- /dev/null
+++ b/arch/arm/boards/freescale-mx23-evk/config.h
@@ -0,0 +1,16 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
diff --git a/arch/arm/boards/freescale-mx23-evk/mx23-evk.c b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
new file mode 100644
index 0000000..d361320
--- /dev/null
+++ b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
@@ -0,0 +1,80 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <mach/imx-regs.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.name     = "mem",
+	.map_base = IMX_MEMORY_BASE,
+	.size     = 32 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+static int mx23_evk_devices_init(void)
+{
+	register_device(&sdram_dev);
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void*)(IMX_MEMORY_BASE + 0x100));
+	armlinux_set_architecture(MACH_TYPE_MX23EVK);
+
+	return 0;
+}
+
+device_initcall(mx23_evk_devices_init);
+
+static struct device_d mx23_evk_serial_device = {
+	.name     = "stm_serial",
+	.map_base = IMX_DBGUART_BASE,
+	.size     = 8192,
+};
+
+static int mx23_evk_console_init(void)
+{
+	return register_device(&mx23_evk_serial_device);
+}
+
+console_initcall(mx23_evk_console_init);
+
+/** @page mx23_evk Freescale's i.MX23 evaluation kit
+
+This CPU card is based on an i.MX23 CPU. The card is shipped with:
+
+- 32 MiB synchronous dynamic RAM (mobile DDR type)
+- ENC28j60 based network (over SPI)
+
+Memory layout when @b barebox is running:
+
+- 0x40000000 start of SDRAM
+- 0x40000100 start of kernel's boot parameters
+  - below malloc area: stack area
+  - below barebox: malloc area
+- 0x41000000 start of @b barebox
+*/
diff --git a/arch/arm/configs/imx23evk_defconfig b/arch/arm/configs/imx23evk_defconfig
new file mode 100644
index 0000000..a3d3e25
--- /dev/null
+++ b/arch/arm/configs/imx23evk_defconfig
@@ -0,0 +1,224 @@
+#
+# Automatically generated make config: don't edit
+# Linux barebox version: 2010.09.0
+# Thu Oct  7 16:36:33 2010
+#
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_ARM=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_IMX is not set
+CONFIG_ARCH_STM=y
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_S3C24xx is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+
+#
+# processor features
+#
+CONFIG_ARCH_TEXT_BASE=0x42000000
+CONFIG_BOARDINFO="Chumby Falconwing"
+
+#
+# SigmaTel/Freescale i.MX System-on-Chip
+#
+CONFIG_ARCH_IMX23=y
+# CONFIG_MACH_MX23EVK is not set
+CONFIG_MACH_CHUMBY=y
+
+#
+# Board specific settings       
+#
+CONFIG_AEABI=y
+
+#
+# Arm specific settings         
+#
+CONFIG_CMD_ARM_CPUINFO=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
+CONFIG_GREGORIAN_CALENDER=y
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+CONFIG_GENERIC_GPIO=y
+
+#
+# General Settings              
+#
+CONFIG_LOCALVERSION_AUTO=y
+
+#
+# memory layout                 
+#
+CONFIG_HAVE_MMU=y
+# CONFIG_MMU is not set
+CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
+CONFIG_TEXT_BASE=0x42000000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+# CONFIG_MEMORY_LAYOUT_FIXED is not set
+CONFIG_STACK_SIZE=0x8000
+CONFIG_MALLOC_SIZE=0x400000
+CONFIG_BROKEN=y
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_PROMPT="chumby:"
+CONFIG_BAUDRATE=115200
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+# CONFIG_GLOB is not set
+CONFIG_PROMPT_HUSH_PS2="> "
+# CONFIG_HUSH_FANCY_PROMPT is not set
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+# CONFIG_MENU is not set
+# CONFIG_PASSWORD is not set
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+CONFIG_TIMESTAMP=y
+CONFIG_CONSOLE_FULL=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+# CONFIG_OF_FLAT_TREE is not set
+CONFIG_PARTITION=y
+# CONFIG_DEFAULT_ENVIRONMENT is not set
+
+#
+# Debugging                     
+#
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+# CONFIG_ENABLE_DEVICE_NOISE is not set
+
+#
+# Commands                      
+#
+
+#
+# scripting                     
+#
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TRUE=y
+CONFIG_CMD_FALSE=y
+# CONFIG_CMD_LOGIN is not set
+# CONFIG_CMD_PASSWD is not set
+
+#
+# file commands                 
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+
+#
+# console                       
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_ECHO_E=y
+
+#
+# memory                        
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_MEMINFO is not set
+# CONFIG_CMD_CRC is not set
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+
+#
+# flash                         
+#
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_UBI is not set
+
+#
+# booting                       
+#
+CONFIG_CMD_BOOTM=y
+# CONFIG_CMD_BOOTM_ZLIB is not set
+# CONFIG_CMD_BOOTM_BZLIB is not set
+# CONFIG_CMD_BOOTM_SHOW_TYPE is not set
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTU=y
+CONFIG_CMD_RESET=y
+# CONFIG_CMD_GO is not set
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_CMD_VERSION=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_DEVINFO=y
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_UNLZO is not set
+# CONFIG_NET is not set
+
+#
+# Drivers                       
+#
+
+#
+# serial drivers                
+#
+# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
+CONFIG_DRIVER_SERIAL_STM378X=y
+# CONFIG_DRIVER_SERIAL_NS16550 is not set
+
+#
+# SPI drivers                   
+#
+# CONFIG_SPI is not set
+# CONFIG_I2C is not set
+
+#
+# flash drivers                 
+#
+# CONFIG_DRIVER_CFI is not set
+# CONFIG_MTD is not set
+# CONFIG_ATA is not set
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_VIDEO is not set
+
+#
+# Filesystem support            
+#
+# CONFIG_FS_CRAMFS is not set
+CONFIG_FS_RAMFS=y
+CONFIG_FS_DEVFS=y
+CONFIG_CRC32=y
+# CONFIG_DIGEST is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_PROCESS_ESCAPE_SEQUENCE=y
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 9858d3a..bbdea51 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -2,8 +2,10 @@ if ARCH_STM
 
 config ARCH_TEXT_BASE
 	hex
+	default 0x41000000 if MACH_MX23EVK
 
 config BOARDINFO
+	default "Freescale i.MX23-EVK" if MACH_MX23EVK
 
 comment "SigmaTel/Freescale i.MX System-on-Chip"
 
@@ -21,6 +23,11 @@ if ARCH_IMX23
 choice
 	prompt "i.MX23 Board Type"
 
+config MACH_MX23EVK
+	bool "mx23-evk"
+	help
+	  Say Y here if you are using the Freescale i.MX23-EVK board
+
 endchoice
 
 endif
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 10:59:54 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 16:59:54 +0200
Subject: [PATCH 1/4] Add the basic files for the i.MX23/i.MX28 familiy of CPUs
In-Reply-To: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
References: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286463597-16948-2-git-send-email-jbe@pengutronix.de>

These CPUs are called "i.MX", but they are of type STM378x from SigmaTel. They
do not share any devices with the other i.MX CPUs, so we need a separate
architecute directory to handle them without an ifdef hell in the native i.MX
files.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/Kconfig                             |    5 +
 arch/arm/mach-stm/Kconfig                    |   32 ++
 arch/arm/mach-stm/Makefile                   |    2 +
 arch/arm/mach-stm/clocksource-imx23.c        |   82 +++++
 arch/arm/mach-stm/imx23.c                    |   35 +++
 arch/arm/mach-stm/include/mach/clock-imx23.h |   34 ++
 arch/arm/mach-stm/include/mach/generic.h     |   24 ++
 arch/arm/mach-stm/include/mach/gpio.h        |   29 ++
 arch/arm/mach-stm/include/mach/imx-regs.h    |   27 ++
 arch/arm/mach-stm/include/mach/imx23-regs.h  |   41 +++
 arch/arm/mach-stm/include/mach/iomux-imx23.h |  424 ++++++++++++++++++++++++++
 arch/arm/mach-stm/iomux-imx23.c              |  117 +++++++
 arch/arm/mach-stm/reset-imx23.c              |   61 ++++
 arch/arm/mach-stm/speed-imx23.c              |  278 +++++++++++++++++
 14 files changed, 1191 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-stm/Kconfig
 create mode 100644 arch/arm/mach-stm/Makefile
 create mode 100644 arch/arm/mach-stm/clocksource-imx23.c
 create mode 100644 arch/arm/mach-stm/imx23.c
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx23.h
 create mode 100644 arch/arm/mach-stm/include/mach/generic.h
 create mode 100644 arch/arm/mach-stm/include/mach/gpio.h
 create mode 100644 arch/arm/mach-stm/include/mach/imx-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/imx23-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/iomux-imx23.h
 create mode 100644 arch/arm/mach-stm/iomux-imx23.c
 create mode 100644 arch/arm/mach-stm/reset-imx23.c
 create mode 100644 arch/arm/mach-stm/speed-imx23.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fa37036..bfee8cf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -39,6 +39,10 @@ config ARCH_IMX
 	bool "Freescale iMX-based"
 	select GENERIC_GPIO
 
+config ARCH_STM
+	bool "SigmaTel/FSL iMX-based"
+	select GENERIC_GPIO
+
 config ARCH_NETX
 	bool "Hilscher NetX based"
 	select CPU_ARM926T
@@ -62,6 +66,7 @@ source arch/arm/cpu/Kconfig
 source arch/arm/mach-at91/Kconfig
 source arch/arm/mach-ep93xx/Kconfig
 source arch/arm/mach-imx/Kconfig
+source arch/arm/mach-stm/Kconfig
 source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
 source arch/arm/mach-omap/Kconfig
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
new file mode 100644
index 0000000..9858d3a
--- /dev/null
+++ b/arch/arm/mach-stm/Kconfig
@@ -0,0 +1,32 @@
+if ARCH_STM
+
+config ARCH_TEXT_BASE
+	hex
+
+config BOARDINFO
+
+comment "SigmaTel/Freescale i.MX System-on-Chip"
+
+choice
+	prompt "Freescale i.MX Processor"
+
+config ARCH_IMX23
+	bool "i.MX23"
+	select CPU_ARM926T
+
+endchoice
+
+if ARCH_IMX23
+
+choice
+	prompt "i.MX23 Board Type"
+
+endchoice
+
+endif
+
+menu "Board specific settings       "
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-stm/Makefile b/arch/arm/mach-stm/Makefile
new file mode 100644
index 0000000..59d70b6
--- /dev/null
+++ b/arch/arm/mach-stm/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o imx23.o iomux-imx23.o clocksource-imx23.o reset-imx23.o
+
diff --git a/arch/arm/mach-stm/clocksource-imx23.c b/arch/arm/mach-stm/clocksource-imx23.c
new file mode 100644
index 0000000..b9782ee
--- /dev/null
+++ b/arch/arm/mach-stm/clocksource-imx23.c
@@ -0,0 +1,82 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <mach/clock-imx23.h>
+#include <asm/io.h>
+
+#define TIMROTCTRL 0x00
+#define TIMCTRL1 0x40
+#define TIMCTRL1_SET 0x44
+#define TIMCTRL1_CLR 0x48
+#define TIMCTRL1_TOG 0x4c
+# define TIMCTRL_RELOAD (1 << 6)
+# define TIMCTRL_UPDATE (1 << 7)
+# define TIMCTRL_PRESCALE(x) ((x & 0x3) << 4)
+# define TIMCTRL_SELECT(x) (x & 0xf)
+#define TIMCOUNT1 0x50
+
+static const unsigned long timer_base = IMX_TIM1_BASE;
+
+#define CLOCK_TICK_RATE (32000)
+
+static uint64_t imx23_clocksource_read(void)
+{
+	/* only the upper bits are the valid */
+	return ~(readl(timer_base + TIMCOUNT1) >> 16);
+}
+
+static struct clocksource cs = {
+	.read	= imx23_clocksource_read,
+	.mask	= 0x0000ffff,
+	.shift	= 10,
+};
+
+static int imx23_clocksource_clock_change(struct notifier_block *nb, unsigned long event, void *data)
+{
+	cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE/*imx_get_xclk()*/, cs.shift);
+	return 0;
+}
+
+static struct notifier_block imx23_clock_notifier = {
+	.notifier_call = imx23_clocksource_clock_change,
+};
+
+static int clocksource_init(void)
+{
+	/* enable the whole timer block */
+	writel(0x3e000000, timer_base + TIMROTCTRL);
+	/* setup general purpose timer 1 */
+	writel(0x00000000, timer_base + TIMCTRL1);
+	writel(TIMCTRL_UPDATE, timer_base + TIMCTRL1);
+	writel(0x0000ffff, timer_base + TIMCOUNT1);
+
+	writel(TIMCTRL_UPDATE | TIMCTRL_RELOAD | TIMCTRL_PRESCALE(0) | TIMCTRL_SELECT(8), timer_base + TIMCTRL1);
+	cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE/*imx_get_xclk()*/, cs.shift);
+	init_clock(&cs);
+
+	clock_register_client(&imx23_clock_notifier);
+	return 0;
+}
+
+core_initcall(clocksource_init);
diff --git a/arch/arm/mach-stm/imx23.c b/arch/arm/mach-stm/imx23.c
new file mode 100644
index 0000000..14a4249
--- /dev/null
+++ b/arch/arm/mach-stm/imx23.c
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+
+extern void imx_dump_clocks(void);
+
+static int do_clocks(struct command *cmdtp, int argc, char *argv[])
+{
+	imx_dump_clocks();
+
+	return 0;
+}
+
+BAREBOX_CMD_START(dump_clocks)
+	.cmd		= do_clocks,
+	.usage		= "show clock frequencies",
+BAREBOX_CMD_END
diff --git a/arch/arm/mach-stm/include/mach/clock-imx23.h b/arch/arm/mach-stm/include/mach/clock-imx23.h
new file mode 100644
index 0000000..b308ff0
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/clock-imx23.h
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef ASM_ARCH_CLOCK_IMX23_H
+#define ASM_ARCH_CLOCK_IMX23_H
+
+unsigned imx_get_mpllclk(void);
+unsigned imx_get_emiclk(void);
+unsigned imx_get_ioclk(void);
+unsigned imx_get_armclk(void);
+unsigned imx_get_hclk(void);
+unsigned imx_get_xclk(void);
+unsigned imx_get_sspclk(void);
+unsigned imx_set_sspclk(unsigned, int);
+unsigned imx_set_ioclk(unsigned);
+
+#endif /* ASM_ARCH_CLOCK_IMX23_H */
+
diff --git a/arch/arm/mach-stm/include/mach/generic.h b/arch/arm/mach-stm/include/mach/generic.h
new file mode 100644
index 0000000..3a552a8
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/generic.h
@@ -0,0 +1,24 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifdef CONFIG_ARCH_IMX23
+# define cpu_is_mx23()	(1)
+#else
+# define cpu_is_mx23()	(0)
+#endif
diff --git a/arch/arm/mach-stm/include/mach/gpio.h b/arch/arm/mach-stm/include/mach/gpio.h
new file mode 100644
index 0000000..fa8263c
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/gpio.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_MACH_GPIO_H
+#define __ASM_MACH_GPIO_H
+
+#if defined CONFIG_ARCH_IMX23
+# include <mach/iomux-imx23.h>
+#endif
+
+void imx_gpio_mode(unsigned);
+
+#endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-stm/include/mach/imx-regs.h b/arch/arm/mach-stm/include/mach/imx-regs.h
new file mode 100644
index 0000000..40dc742
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/imx-regs.h
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _IMX_REGS_H
+# define _IMX_REGS_H
+
+#if defined CONFIG_ARCH_IMX23
+# include <mach/imx23-regs.h>
+#endif
+
+#endif /* _IMX_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/imx23-regs.h b/arch/arm/mach-stm/include/mach/imx23-regs.h
new file mode 100644
index 0000000..89ca453
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/imx23-regs.h
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MX23_REGS_H
+#define __ASM_ARCH_MX23_REGS_H
+
+/*
+ * sanity check
+ */
+#ifndef _IMX_REGS_H
+# error "Please do not include directly. Use imx-regs.h instead."
+#endif
+
+#define IMX_MEMORY_BASE		0x40000000
+#define IMX_UART1_BASE		0x8006c000
+#define IMX_UART2_BASE		0x8006e000
+#define IMX_DBGUART_BASE	0x80070000
+#define IMX_TIM1_BASE		0x80068000
+#define IMX_IOMUXC_BASE		0x80018000
+#define IMX_WDT_BASE		0x8005c000
+#define IMX_CCM_BASE		0x80040000
+#define IMX_I2C1_BASE		0x80058000
+#define IMX_SSP1_BASE		0x80010000
+#define IMX_SSP2_BASE		0x80034000
+
+#endif /* __ASM_ARCH_MX23_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/iomux-imx23.h b/arch/arm/mach-stm/include/mach/iomux-imx23.h
new file mode 100644
index 0000000..bebaf56
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/iomux-imx23.h
@@ -0,0 +1,424 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/* 3322222222221111111111
+ * 10987654321098765432109876543210
+ *                              ^^^_ Register Number
+ *                          ^^^^____ Bit offset
+ *                        ^^________ Function
+ *                       ^__________ Drive strength feature present
+ *                      ^___________ Pull up / bit keeper present
+ *                    ^^____________ Drive strength setting
+ *                   ^______________ Pull up / bit keeper setting
+ *                  ^_______________ Voltage select present
+ *                 ^________________ Voltage selection
+ *             ^____________________ direction if enabled as GPIO (1 = output)
+ *            ^_____________________ initial output value if enabled as GPIO and configured as output
+ */
+#ifndef __ASM_MACH_IOMUX_H
+#define __ASM_MACH_IOMUX_H
+
+/* control pad's function */
+#define FBIT_SHIFT (3)
+#define PORTF(bank,bit)	(((bit) << FBIT_SHIFT) | (bank))
+#define GET_PORTF(x) ((x) & 0x7)
+#define GET_FBITPOS(x) (((x) >> FBIT_SHIFT) & 0xf)
+#define GET_GPIO_NO(x) ((GET_PORTF(x) << 4) + GET_FBITPOS(m))
+#define FUNC_SHIFT 7
+#define FUNC(x)	((x) << FUNC_SHIFT)
+#define GET_FUNC(x) (((x) >> FUNC_SHIFT) & 3)
+#define IS_GPIO (3)
+
+/* control pad's GPIO feature if enabled */
+#define GPIO_OUT (1 << 19)
+#define GPIO_VALUE(x) ((x) << 20)
+#define GPIO_IN (0 << 19)
+#define GET_GPIODIR(x) (!!((x) & (1 << 19)))
+#define GET_GPIOVAL(x) (!!((x) & (1 << 20)))
+
+/* control pad's drive strength */
+#define SE (1 << 9)
+#define SE_PRESENT(x) (!!((x) & SE))
+#define STRENGTH(x) ((x) << 11)
+#define S4MA 0	/* used to define a 4 mA drive strength */
+#define S8MA 1	/* used to define a 8 mA drive strength */
+#define S12MA 2	/* used to define a 12 mA drive strength */
+#define S16MA 3	/* used to define a 16 mA drive strength, not all pads can drive this current! */
+#define GET_STRENGTH(x) (((x) >> 11) & 0x3)
+
+/* control pad's pull up / bit keeper feature */
+#define PE (1 << 10)
+#define PE_PRESENT(x) (!!((x) & PE))
+#define PULLUP(x) ((x) << 13)
+#define GET_PULLUP(x) (!!((x) & (1 << 13)))
+
+/* control pad's voltage feature */
+#define VE (1 << 14)
+#define VE_PRESENT(x) (!!((x) & VE))
+#define VE_1_8V (0 << 15)
+#define VE_2_5V (0 << 15) /* don't ask my why, RTFM */
+#define GET_VOLTAGE(x) (!!((x) & (1 << 15)))
+
+/* Bank 0, pins 0 ... 15, GPIO pins 0 ... 15 */
+#define GPMI_D15		(FUNC(0) | PORTF(0, 15) | SE | PE)
+#define GPMI_D15_AUART2_TX	(FUNC(1) | PORTF(0, 15) | SE | PE)
+#define GPMI_D15_GPMI_CE3N	(FUNC(2) | PORTF(0, 15) | SE | PE)
+#define GPMI_D15_GPIO		(FUNC(3) | PORTF(0, 15) | SE | PE)
+#define GPMI_D14		(FUNC(0) | PORTF(0, 14) | SE)
+#define GPMI_D14_AUART2_RX	(FUNC(1) | PORTF(0, 14) | SE)
+#define GPMI_D14_GPIO		(FUNC(3) | PORTF(0, 14) | SE)
+#define GPMI_D13		(FUNC(0) | PORTF(0, 13) | SE)
+#define GPMI_D13_LCD_D23	(FUNC(1) | PORTF(0, 13) | SE)
+#define GPMI_D13_GPIO		(FUNC(3) | PORTF(0, 13) | SE)
+#define GPMI_D12		(FUNC(0) | PORTF(0, 12) | SE)
+#define GPMI_D12_LCD_D22	(FUNC(1) | PORTF(0, 12) | SE)
+#define GPMI_D12_GPIO		(FUNC(3) | PORTF(0, 12) | SE)
+#define GPMI_D11		(FUNC(0) | PORTF(0, 11) | SE | PE)
+#define GPMI_D11_LCD_D21	(FUNC(1) | PORTF(0, 11) | SE | PE)
+#define GPMI_D11_SSP1_D7	(FUNC(2) | PORTF(0, 11) | SE | PE)
+#define GPMI_D11_GPIO		(FUNC(3) | PORTF(0, 11) | SE | PE)
+#define GPMI_D10		(FUNC(0) | PORTF(0, 10) | SE | PE)
+#define GPMI_D10_LCD_D20	(FUNC(1) | PORTF(0, 10) | SE | PE)
+#define GPMI_D10_SSP1_D6	(FUNC(2) | PORTF(0, 10) | SE | PE)
+#define GPMI_D10_GPIO		(FUNC(3) | PORTF(0, 10) | SE | PE)
+#define GPMI_D09		(FUNC(0) | PORTF(0, 9) | SE | PE)
+#define GPMI_D09_LCD_D19	(FUNC(1) | PORTF(0, 9) | SE | PE)
+#define GPMI_D09_SSP1_D5	(FUNC(2) | PORTF(0, 9) | SE | PE)
+#define GPMI_D09_GPIO		(FUNC(3) | PORTF(0, 9) | SE | PE)
+#define GPMI_D08		(FUNC(0) | PORTF(0, 8) | SE | PE)
+#define GPMI_D08_LCD_D18	(FUNC(1) | PORTF(0, 8) | SE | PE)
+#define GPMI_D08_SSP1_D4	(FUNC(2) | PORTF(0, 8) | SE | PE)
+#define GPMI_D08_GPIO		(FUNC(3) | PORTF(0, 8) | SE | PE)
+#define GPMI_D07		(FUNC(0) | PORTF(0, 7) | SE | PE)
+#define GPMI_D07_LCD_D15	(FUNC(1) | PORTF(0, 7) | SE | PE)
+#define GPMI_D07_SSP2_D7	(FUNC(2) | PORTF(0, 7) | SE | PE)
+#define GPMI_D07_GPIO		(FUNC(3) | PORTF(0, 7) | SE | PE)
+#define GPMI_D06		(FUNC(0) | PORTF(0, 6) | SE | PE)
+#define GPMI_D06_LCD_D14	(FUNC(1) | PORTF(0, 6) | SE | PE)
+#define GPMI_D06_SSP2_D6	(FUNC(2) | PORTF(0, 6) | SE | PE)
+#define GPMI_D06_GPIO		(FUNC(3) | PORTF(0, 6) | SE | PE)
+#define GPMI_D05		(FUNC(0) | PORTF(0, 5) | SE | PE)
+#define GPMI_D05_LCD_D13	(FUNC(1) | PORTF(0, 5) | SE | PE)
+#define GPMI_D05_SSP2_D5	(FUNC(2) | PORTF(0, 5) | SE | PE)
+#define GPMI_D05_GPIO		(FUNC(3) | PORTF(0, 5) | SE | PE)
+#define GPMI_D04		(FUNC(0) | PORTF(0, 4) | SE | PE)
+#define GPMI_D04_LCD_D12	(FUNC(1) | PORTF(0, 4) | SE | PE)
+#define GPMI_D04_SSP2_D4	(FUNC(2) | PORTF(0, 4) | SE | PE)
+#define GPMI_D04_GPIO		(FUNC(3) | PORTF(0, 4) | SE | PE)
+#define GPMI_D03		(FUNC(0) | PORTF(0, 3) | SE | PE)
+#define GPMI_D03_LCD_D11	(FUNC(1) | PORTF(0, 3) | SE | PE)
+#define GPMI_D03_SSP2_D3	(FUNC(2) | PORTF(0, 3) | SE | PE)
+#define GPMI_D03_GPIO		(FUNC(3) | PORTF(0, 3) | SE | PE)
+#define GPMI_D02		(FUNC(0) | PORTF(0, 2) | SE | PE)
+#define GPMI_D02_LCD_D10	(FUNC(1) | PORTF(0, 2) | SE | PE)
+#define GPMI_D02_SSP2_D2	(FUNC(2) | PORTF(0, 2) | SE | PE)
+#define GPMI_D02_GPIO		(FUNC(3) | PORTF(0, 2) | SE | PE)
+#define GPMI_D01		(FUNC(0) | PORTF(0, 1) | SE | PE)
+#define GPMI_D01_LCD_D9		(FUNC(1) | PORTF(0, 1) | SE | PE)
+#define GPMI_D01_SSP2_D1	(FUNC(2) | PORTF(0, 1) | SE | PE)
+#define GPMI_D01_GPIO		(FUNC(3) | PORTF(0, 1) | SE | PE)
+#define GPMI_D00		(FUNC(0) | PORTF(0, 0) | SE | PE)
+#define GPMI_D00_LCD_D8		(FUNC(1) | PORTF(0, 0) | SE | PE)
+#define GPMI_D00_SSP2_D0	(FUNC(2) | PORTF(0, 0) | SE | PE)
+#define GPMI_D00_GPIO		(FUNC(3) | PORTF(0, 0) | SE | PE)
+
+/* Bank 0, pins 16 ... 31 GPIO pins 16 ... 31 */
+#define I2C_SDA			(FUNC(0) | PORTF(1, 15) | SE)
+#define I2C_SDA_GPMI_CE2N	(FUNC(1) | PORTF(1, 15) | SE)
+#define I2C_SDA_AUART1_RX	(FUNC(2) | PORTF(1, 15) | SE)
+#define I2C_SDA_GPIO		(FUNC(3) | PORTF(1, 15) | SE)
+#define I2C_CLK			(FUNC(0) | PORTF(1, 14) | SE | PE)
+#define I2C_CLK_GPMI_RDY2	(FUNC(1) | PORTF(1, 14) | SE | PE)
+#define I2C_CLK_AUART1_TX	(FUNC(2) | PORTF(1, 14) | SE | PE)
+#define I2C_CLK_GPIO		(FUNC(3) | PORTF(1, 14) | SE | PE)
+#define AUART1_TX		(FUNC(0) | PORTF(1, 13) | SE | PE)
+#define AUART1_TX_SSP1_D7	(FUNC(2) | PORTF(1, 13) | SE | PE)
+#define AUART1_TX_GPIO		(FUNC(3) | PORTF(1, 13) | SE | PE)
+#define AUART1_RX		(FUNC(0) | PORTF(1, 12) | SE | PE)
+#define AUART1_RX_SSP1_D6	(FUNC(2) | PORTF(1, 12) | SE | PE)
+#define AUART1_RX_GPIO		(FUNC(3) | PORTF(1, 12) | SE | PE)
+#define AUART1_RTS		(FUNC(0) | PORTF(1, 11) | SE | PE)
+#define AUART1_RTS_SSP1_D5	(FUNC(2) | PORTF(1, 11) | SE | PE)
+#define AUART1_RTS_GPIO		(FUNC(3) | PORTF(1, 11) | SE | PE)
+#define AUART1_CTS		(FUNC(0) | PORTF(1, 10) | SE | PE)
+#define AUART1_CTS_SSP1_D4	(FUNC(2) | PORTF(1, 10) | SE | PE)
+#define AUART1_CTS_GPIO		(FUNC(3) | PORTF(1, 10) | SE | PE)
+#define GPMI_RDN		(FUNC(0) | PORTF(1, 9) | SE)
+#define GPMI_RDN_GPIO		(FUNC(3) | PORTF(1, 9) | SE)
+#define GPMI_WRN		(FUNC(0) | PORTF(1, 8) | SE)
+#define GPMI_WRN_SSP2_SCK	(FUNC(2) | PORTF(1, 8) | SE)
+#define GPMI_WRN_GPIO		(FUNC(3) | PORTF(1, 8) | SE)
+#define GPMI_WPM		(FUNC(0) | PORTF(1, 7) | SE)
+#define GPMI_WPM_GPIO		(FUNC(3) | PORTF(1, 7) | SE)
+#define GPMI_RDY3		(FUNC(0) | PORTF(1, 6) | SE | PE)
+#define GPMI_RDY3_GPIO		(FUNC(3) | PORTF(1, 6) | SE | PE)
+#define GPMI_RDY2		(FUNC(0) | PORTF(1, 5) | SE | PE)
+#define GPMI_RDY2_GPIO		(FUNC(3) | PORTF(1, 5) | SE | PE)
+#define GPMI_RDY1		(FUNC(0) | PORTF(1, 4) | SE | PE)
+#define GPMI_RDY1_SSP2_CMD	(FUNC(2) | PORTF(1, 4) | SE | PE)
+#define GPMI_RDY1_GPIO		(FUNC(3) | PORTF(1, 4) | SE | PE)
+#define GPMI_RDY0		(FUNC(0) | PORTF(1, 3) | SE | PE)
+#define GPMI_RDY0_SSP2_DETECT	(FUNC(2) | PORTF(1, 3) | SE | PE)
+#define GPMI_RDY0_GPIO		(FUNC(3) | PORTF(1, 3) | SE | PE)
+#define GPMI_CE2N		(FUNC(0) | PORTF(1, 2) | SE | PE)
+#define GPMI_CE2N_GPIO		(FUNC(3) | PORTF(1, 2) | SE | PE)
+#define GPMI_ALE		(FUNC(0) | PORTF(1, 1) | SE)
+#define GPMI_ALE_LCD_D17	(FUNC(1) | PORTF(1, 1) | SE)
+#define GPMI_ALE_GPIO		(FUNC(3) | PORTF(1, 1) | SE)
+#define GPMI_CLE		(FUNC(0) | PORTF(1, 0) | SE)
+#define GPMI_CLE_LCD_D16	(FUNC(1) | PORTF(1, 1) | SE)
+#define GPMI_CLE_GPIO		(FUNC(3) | PORTF(1, 0) | SE)
+
+/* Bank 1, pins 0 ... 15 GPIO pins 32 ... 47 */
+#define LCD_D15			(FUNC(0) | PORTF(2, 15) | SE)
+#define LCD_D15_ETM_DA7		(FUNC(1) | PORTF(2, 15) | SE)
+#define LCD_D15_SAIF1_SDATA1	(FUNC(2) | PORTF(2, 15) | SE)
+#define LCD_D15_GPIO		(FUNC(3) | PORTF(2, 15) | SE)
+#define LCD_D14			(FUNC(0) | PORTF(2, 14) | SE)
+#define LCD_D14_ETM_DA6		(FUNC(1) | PORTF(2, 14) | SE)
+#define LCD_D14_SAIF1_SDATA2	(FUNC(2) | PORTF(2, 14) | SE)
+#define LCD_D14_GPIO		(FUNC(3) | PORTF(2, 14) | SE)
+#define LCD_D13			(FUNC(0) | PORTF(2, 13) | SE)
+#define LCD_D13_ETM_DA5		(FUNC(1) | PORTF(2, 13) | SE)
+#define LCD_D13_SAIF2_SDATA2	(FUNC(2) | PORTF(2, 13) | SE)
+#define LCD_D13_GPIO		(FUNC(3) | PORTF(2, 13) | SE)
+#define LCD_D12			(FUNC(0) | PORTF(2, 12) | SE)
+#define LCD_D12_ETM_DA4		(FUNC(1) | PORTF(2, 12) | SE)
+#define LCD_D12_SAIF2_SDATA1	(FUNC(2) | PORTF(2, 12) | SE)
+#define LCD_D12_GPIO		(FUNC(3) | PORTF(2, 12) | SE)
+#define LCD_D11			(FUNC(0) | PORTF(2, 11) | SE)
+#define LCD_D11_ETM_DA3		(FUNC(1) | PORTF(2, 11) | SE)
+#define LCD_D11_SAIF_LRCLK	(FUNC(2) | PORTF(2, 11) | SE)
+#define LCD_D11_GPIO		(FUNC(3) | PORTF(2, 11) | SE)
+#define LCD_D10			(FUNC(0) | PORTF(2, 10) | SE)
+#define LCD_D10_ETM_DA2		(FUNC(1) | PORTF(2, 10) | SE)
+#define LCD_D10_SAIF_BITCLK	(FUNC(2) | PORTF(2, 10) | SE)
+#define LCD_D10_GPIO		(FUNC(3) | PORTF(2, 10) | SE)
+#define LCD_D9			(FUNC(0) | PORTF(2, 9) | SE)
+#define LCD_D9_ETM_DA1		(FUNC(1) | PORTF(2, 9) | SE)
+#define LCD_D9_SAIF1_SDATA0	(FUNC(2) | PORTF(2, 9) | SE)
+#define LCD_D9_GPIO		(FUNC(3) | PORTF(2, 9) | SE)
+#define LCD_D8			(FUNC(0) | PORTF(2, 8) | SE)
+#define LCD_D8_ETM_DA0		(FUNC(1) | PORTF(2, 8) | SE)
+#define LCD_D8_SAIF2_SDATA0	(FUNC(2) | PORTF(2, 8) | SE)
+#define LCD_D8_GPIO		(FUNC(3) | PORTF(2, 8) | SE)
+#define LCD_D7			(FUNC(0) | PORTF(2, 7) | SE)
+#define LCD_D7_ETM_DA15		(FUNC(1) | PORTF(2, 7) | SE)
+#define LCD_D7_GPIO		(FUNC(3) | PORTF(2, 7) | SE)
+#define LCD_D6			(FUNC(0) | PORTF(2, 6) | SE)
+#define LCD_D6_ETM_DA14		(FUNC(1) | PORTF(2, 6) | SE)
+#define LCD_D6_GPIO		(FUNC(3) | PORTF(2, 6) | SE)
+#define LCD_D5			(FUNC(0) | PORTF(2, 5) | SE)
+#define LCD_D5_ETM_DA13		(FUNC(1) | PORTF(2, 5) | SE)
+#define LCD_D5_GPIO		(FUNC(3) | PORTF(2, 5) | SE)
+#define LCD_D4			(FUNC(0) | PORTF(2, 4) | SE)
+#define LCD_D4_ETM_DA12		(FUNC(1) | PORTF(2, 4) | SE)
+#define LCD_D4_GPIO		(FUNC(3) | PORTF(2, 4) | SE)
+#define LCD_D3			(FUNC(0) | PORTF(2, 3) | SE)
+#define LCD_D3_ETM_DA11		(FUNC(1) | PORTF(2, 3) | SE)
+#define LCD_D3_GPIO		(FUNC(3) | PORTF(2, 3) | SE)
+#define LCD_D2			(FUNC(0) | PORTF(2, 2) | SE)
+#define LCD_D2_ETM_DA10		(FUNC(1) | PORTF(2, 2) | SE)
+#define LCD_D2_GPIO		(FUNC(3) | PORTF(2, 2) | SE)
+#define LCD_D1			(FUNC(0) | PORTF(2, 1) | SE)
+#define LCD_D1_ETM_DA9		(FUNC(1) | PORTF(2, 1) | SE)
+#define LCD_D1_GPIO		(FUNC(3) | PORTF(2, 1) | SE)
+#define LCD_D0			(FUNC(0) | PORTF(2, 0) | SE)
+#define LCD_D0_ETM_DA8		(FUNC(1) | PORTF(2, 0) | SE)
+#define LCD_D0_GPIO		(FUNC(3) | PORTF(2, 0) | SE)
+
+/* Bank 1, pins 16 ... 30 GPIO pins 48 ... 63 */
+#define PWM4			(FUNC(0) | PORTF(3, 14) | SE)
+#define PWM4_ETM_CLK		(FUNC(1) | PORTF(3, 14) | SE)
+#define PWM4_AUART1_RTS		(FUNC(2) | PORTF(3, 14) | SE)
+#define PWM4_GPIO		(FUNC(3) | PORTF(3, 14) | SE)
+#define PWM3			(FUNC(0) | PORTF(3, 13) | SE)
+#define PWM3_ETM_TCTL		(FUNC(1) | PORTF(3, 13) | SE)
+#define PWM3_AUART1_CTS		(FUNC(2) | PORTF(3, 13) | SE)
+#define PWM3_GPIO		(FUNC(3) | PORTF(3, 13) | SE)
+#define PWM2			(FUNC(0) | PORTF(3, 12) | SE | PE)
+#define PWM2_GPMI_READY3	(FUNC(1) | PORTF(3, 12) | SE | PE)
+#define PWM2_GPIO		(FUNC(3) | PORTF(3, 12) | SE | PE)
+#define PWM1			(FUNC(0) | PORTF(3, 11) | SE)
+#define PWM1_TIMROT2		(FUNC(1) | PORTF(3, 11) | SE)
+#define PWM1_DUART_TX		(FUNC(2) | PORTF(3, 11) | SE)
+#define PWM1_GPIO		(FUNC(3) | PORTF(3, 11) | SE)
+#define PWM0			(FUNC(0) | PORTF(3, 10) | SE)
+#define PWM0_TIMROT1		(FUNC(1) | PORTF(3, 10) | SE)
+#define PWM0_DUART_RX		(FUNC(2) | PORTF(3, 10) | SE)
+#define PWM0_GPIO		(FUNC(3) | PORTF(3, 10) | SE)
+#define LCD_VSYNC		(FUNC(0) | PORTF(3, 9) | SE)
+#define LCD_VSYNC_LCD_BUSY	(FUNC(1) | PORTF(3, 9) | SE)
+#define LCD_VSYNC_GPIO		(FUNC(3) | PORTF(3, 9) | SE)
+#define LCD_HSYNC		(FUNC(0) | PORTF(3, 8) | SE)
+#define LCD_HSYNC_I2C_SD	(FUNC(1) | PORTF(3, 8) | SE)
+#define LCD_HSYNC_GPIO		(FUNC(3) | PORTF(3, 8) | SE)
+#define LCD_ENABE		(FUNC(0) | PORTF(3, 7) | SE)
+#define LCD_ENABE_I2C_CLK	(FUNC(1) | PORTF(3, 7) | SE)
+#define LCD_ENABE_GPIO		(FUNC(3) | PORTF(3, 7) | SE)
+#define LCD_DOTCLOCK		(FUNC(0) | PORTF(3, 6) | SE | PE)
+#define LCD_DOTCLOCK_GPMI_READY3 (FUNC(1) | PORTF(3, 6) | SE | PE)
+#define LCD_DOTCLOCK_GPIO	(FUNC(3) | PORTF(3, 6) | SE | PE)
+#define LCD_CS			(FUNC(0) | PORTF(3, 5) | SE)
+#define LCD_CS_GPIO		(FUNC(3) | PORTF(3, 5) | SE)
+#define LCD_WR			(FUNC(0) | PORTF(3, 4) | SE)
+#define LCD_WR_GPIO		(FUNC(3) | PORTF(3, 4) | SE)
+#define LCD_RS			(FUNC(0) | PORTF(3, 3) | SE)
+#define LCD_RS_ETM_TCLK		(FUNC(1) | PORTF(3, 3) | SE)
+#define LCD_RS_GPIO		(FUNC(3) | PORTF(3, 3) | SE)
+#define LCD_RESET		(FUNC(0) | PORTF(3, 2) | SE | PE)
+#define LCD_RESET_ETM_TCTL	(FUNC(1) | PORTF(3, 2) | SE | PE)
+#define LCD_RESET_GPMI_CE3N	(FUNC(2) | PORTF(3, 2) | SE | PE)
+#define LCD_RESET_GPIO		(FUNC(3) | PORTF(3, 2) | SE | PE)
+#define LCD_D17			(FUNC(0) | PORTF(3, 1) | SE)
+#define LCD_D17_GPIO		(FUNC(3) | PORTF(3, 1) | SE)
+#define LCD_D16			(FUNC(0) | PORTF(3, 0) | SE)
+#define LCD_D16_SAIF_ALT_BITCLK	(FUNC(2) | PORTF(3, 0) | SE)
+#define LCD_D16_GPIO		(FUNC(3) | PORTF(3, 0) | SE)
+
+/* Bank 2, pins 0 ... 15 GPIO pins 64 ... 79 */
+#define EMI_A6			(FUNC(0) | PORTF(4, 15) | SE | VE)
+#define EMI_A6_GPIO		(FUNC(3) | PORTF(4, 15) | SE | VE)
+#define EMI_A5			(FUNC(0) | PORTF(4, 14) | SE | VE)
+#define EMI_A5_GPIO		(FUNC(3) | PORTF(4, 14) | SE | VE)
+#define EMI_A4			(FUNC(0) | PORTF(4, 13) | SE | VE)
+#define EMI_A4_GPIO		(FUNC(3) | PORTF(4, 13) | SE | VE)
+#define EMI_A3			(FUNC(0) | PORTF(4, 12) | SE | VE)
+#define EMI_A3_GPIO		(FUNC(3) | PORTF(4, 12) | SE | VE)
+#define EMI_A2			(FUNC(0) | PORTF(4, 11) | SE | VE)
+#define EMI_A2_GPIO		(FUNC(3) | PORTF(4, 11) | SE | VE)
+#define EMI_A1			(FUNC(0) | PORTF(4, 10) | SE | VE)
+#define EMI_A1_GPIO		(FUNC(3) | PORTF(4, 10) | SE | VE)
+#define EMI_A0			(FUNC(0) | PORTF(4, 9) | SE | VE)
+#define EMI_A0_GPIO		(FUNC(3) | PORTF(4, 9) | SE | VE)
+#define ROTARYB			(FUNC(0) | PORTF(4, 8) | SE | PE)
+#define ROTARYB_AUART2_CTS	(FUNC(1) | PORTF(4, 8) | SE | PE)
+#define ROTARYB_GPMI_CE3N	(FUNC(2) | PORTF(4, 8) | SE | PE)
+#define ROTARYB_GPIO		(FUNC(3) | PORTF(4, 8) | SE | PE)
+#define ROTARYA			(FUNC(0) | PORTF(4, 7) | SE)
+#define ROTARYA_AUART2_RTS	(FUNC(1) | PORTF(4, 7) | SE)
+#define ROTARYA_SPDIF		(FUNC(2) | PORTF(4, 7) | SE)
+#define ROTARYA_GPIO		(FUNC(3) | PORTF(4, 7) | SE)
+#define SSP1_SCK		(FUNC(0) | PORTF(4, 6) | SE)
+#define SSP1_SCK_ALT_JTAG_TRST	(FUNC(2) | PORTF(4, 6) | SE)
+#define SSP1_SCK_GPIO		(FUNC(3) | PORTF(4, 6) | SE)
+#define SSP1_DATA3		(FUNC(0) | PORTF(4, 5) | SE | PE)
+#define SSP1_DATA3_ALT_JTAG_TMS	(FUNC(2) | PORTF(4, 5) | SE | PE)
+#define SSP1_DATA3_GPIO		(FUNC(3) | PORTF(4, 5) | SE | PE)
+#define SSP1_DATA2		(FUNC(0) | PORTF(4, 4) | SE | PE)
+#define SSP1_DATA2_I2C_SD	(FUNC(1) | PORTF(4, 4) | SE | PE)
+#define SSP1_DATA2_ALT_JTAG_RTCK (FUNC(2) | PORTF(4, 4) | SE | PE)
+#define SSP1_DATA2_GPIO		(FUNC(3) | PORTF(4, 4) | SE | PE)
+#define SSP1_DATA1		(FUNC(0) | PORTF(4, 3) | SE | PE)
+#define SSP1_DATA1_I2C_CLK	(FUNC(1) | PORTF(4, 3) | SE | PE)
+#define SSP1_DATA1_ALT_JTAG_TCK	(FUNC(2) | PORTF(4, 3) | SE | PE)
+#define SSP1_DATA1_GPIO		(FUNC(3) | PORTF(4, 3) | SE | PE)
+#define SSP1_DATA0		(FUNC(0) | PORTF(4, 2) | SE | PE)
+#define SSP1_DATA0_ALT_JTAG_TDI	(FUNC(2) | PORTF(4, 2) | SE | PE)
+#define SSP1_DATA0_GPIO		(FUNC(3) | PORTF(4, 2) | SE | PE)
+#define SSP1_DETECT		(FUNC(0) | PORTF(4, 1) | SE | PE)
+#define SSP1_DETECT_GPMI_CE3N	(FUNC(1) | PORTF(4, 1) | SE | PE)
+#define SSP1_DETECT_USB_ID	(FUNC(2) | PORTF(4, 1) | SE | PE)
+#define SSP1_DETECT_GPIO	(FUNC(3) | PORTF(4, 1) | SE | PE)
+#define SSP1_CMD		(FUNC(0) | PORTF(4, 0) | SE | PE)
+#define SSP1_CMD_JTAG_TDO	(FUNC(2) | PORTF(4, 0) | SE | PE)
+#define SSP1_CMD_GPIO		(FUNC(3) | PORTF(4, 0) | SE | PE)
+
+/* Bank 2, pins 16 ... 31 GPIO pins 80 ... 95 */
+#define EMI_WEN			(FUNC(0) | PORTF(5, 15) | SE | VE)
+#define EMI_WEN_GPIO		(FUNC(3) | PORTF(5, 15) | SE | VE)
+#define EMI_RASN		(FUNC(0) | PORTF(5, 14) | SE | VE)
+#define EMI_RASN_GPIO		(FUNC(3) | PORTF(5, 14) | SE | VE)
+#define EMI_CKE			(FUNC(0) | PORTF(5, 13) | SE | VE)
+#define EMI_CKE_GPIO		(FUNC(3) | PORTF(5, 13) | SE | VE)
+#define GPMI_CE0N		(FUNC(0) | PORTF(5, 12) | SE)
+#define GPMI_CE0N_GPIO		(FUNC(3) | PORTF(5, 12) | SE)
+#define GPMI_CE1N		(FUNC(0) | PORTF(5, 11) | SE | PE)
+#define GPMI_CE1N_GPIO		(FUNC(3) | PORTF(5, 11) | SE | PE)
+#define EMI_CE1N		(FUNC(0) | PORTF(5, 10) | SE | VE | PE)
+#define EMI_CE1N_GPIO		(FUNC(3) | PORTF(5, 10) | SE | VE | PE)
+#define EMI_CE0N		(FUNC(0) | PORTF(5, 9) | SE | VE)
+#define EMI_CE0N_GPIO		(FUNC(3) | PORTF(5, 9) | SE | VE)
+#define EMI_CASN		(FUNC(0) | PORTF(5, 8) | SE | VE)
+#define EMI_CASN_GPIO		(FUNC(3) | PORTF(5, 8) | SE | VE)
+#define EMI_BA1			(FUNC(0) | PORTF(5, 7) | SE | VE)
+#define EMI_BA1_GPIO		(FUNC(3) | PORTF(5, 7) | SE | VE)
+#define EMI_BA0			(FUNC(0) | PORTF(5, 6) | SE | VE)
+#define EMI_BA0_GPIO		(FUNC(3) | PORTF(5, 6) | SE | VE)
+#define EMI_A12			(FUNC(0) | PORTF(5, 5) | SE | VE)
+#define EMI_A12_GPIO		(FUNC(3) | PORTF(5, 5) | SE | VE)
+#define EMI_A11			(FUNC(0) | PORTF(5, 4) | SE | VE)
+#define EMI_A11_GPIO		(FUNC(3) | PORTF(5, 4) | SE | VE)
+#define EMI_A10			(FUNC(0) | PORTF(5, 3) | SE | VE)
+#define EMI_A10_GPIO		(FUNC(3) | PORTF(5, 3) | SE | VE)
+#define EMI_A9			(FUNC(0) | PORTF(5, 2) | SE | VE)
+#define EMI_A9_GPIO		(FUNC(3) | PORTF(5, 2) | SE | VE)
+#define EMI_A8			(FUNC(0) | PORTF(5, 1) | SE | VE)
+#define EMI_A8_GPIO		(FUNC(3) | PORTF(5, 1) | SE | VE)
+#define EMI_A7			(FUNC(0) | PORTF(5, 0) | SE | VE)
+#define EMI_A7_GPIO		(FUNC(3) | PORTF(5, 0) | SE | VE)
+
+/* Bank 3, pins 0 ... 15 GPIO pins 96 ... 111 */
+#define EMI_D15			(FUNC(0) | PORTF(6, 15) | SE | VE | PE)
+#define EMI_D15_DISABLED	(FUNC(3) | PORTF(6, 15) | SE | VE | PE)
+#define EMI_D14			(FUNC(0) | PORTF(6, 14) | SE | VE | PE)
+#define EMI_D14_DISABLED	(FUNC(3) | PORTF(6, 14) | SE | VE | PE)
+#define EMI_D13			(FUNC(0) | PORTF(6, 13) | SE | VE | PE)
+#define EMI_D13_DISABLED	(FUNC(3) | PORTF(6, 13) | SE | VE | PE)
+#define EMI_D12			(FUNC(0) | PORTF(6, 12) | SE | VE | PE)
+#define EMI_D12_DISABLED	(FUNC(3) | PORTF(6, 12) | SE | VE | PE)
+#define EMI_D11			(FUNC(0) | PORTF(6, 11) | SE | VE | PE)
+#define EMI_D11_DISABLED	(FUNC(3) | PORTF(6, 11) | SE | VE | PE)
+#define EMI_D10			(FUNC(0) | PORTF(6, 10) | SE | VE | PE)
+#define EMI_D10_DISABLED	(FUNC(3) | PORTF(6, 10) | SE | VE | PE)
+#define EMI_D9			(FUNC(0) | PORTF(6, 9) | SE | VE | PE)
+#define EMI_D9_DISABLED		(FUNC(3) | PORTF(6, 9) | SE | VE | PE)
+#define EMI_D8			(FUNC(0) | PORTF(6, 8) | SE | VE | PE)
+#define EMI_D8_DISABLED		(FUNC(3) | PORTF(6, 8) | SE | VE | PE)
+#define EMI_D7			(FUNC(0) | PORTF(6, 7) | SE | VE | PE)
+#define EMI_D7_DISABLED		(FUNC(3) | PORTF(6, 7) | SE | VE | PE)
+#define EMI_D6			(FUNC(0) | PORTF(6, 6) | SE | VE | PE)
+#define EMI_D6_DISABLED		(FUNC(3) | PORTF(6, 6) | SE | VE | PE)
+#define EMI_D5			(FUNC(0) | PORTF(6, 5) | SE | VE | PE)
+#define EMI_D5_DISABLED		(FUNC(3) | PORTF(6, 5) | SE | VE | PE)
+#define EMI_D4			(FUNC(0) | PORTF(6, 4) | SE | VE | PE)
+#define EMI_D4_DISABLED		(FUNC(3) | PORTF(6, 4) | SE | VE | PE)
+#define EMI_D3			(FUNC(0) | PORTF(6, 3) | SE | VE | PE)
+#define EMI_D3_DISABLED		(FUNC(3) | PORTF(6, 3) | SE | VE | PE)
+#define EMI_D2			(FUNC(0) | PORTF(6, 2) | SE | VE | PE)
+#define EMI_D2_DISABLED		(FUNC(3) | PORTF(6, 2) | SE | VE | PE)
+#define EMI_D1			(FUNC(0) | PORTF(6, 1) | SE | VE | PE)
+#define EMI_D1_DISABLED		(FUNC(3) | PORTF(6, 1) | SE | VE | PE)
+#define EMI_D0			(FUNC(0) | PORTF(6, 0) | SE | VE | PE)
+#define EMI_D0_DISABLED		(FUNC(3) | PORTF(6, 0) | SE | VE | PE)
+
+/* Bank 3, pins 16 ... 21 GPIO pins 112 ... 117 */
+#define EMI_CLKN		(FUNC(0) | PORTF(7, 5) | SE | VE)
+#define EMI_CLKN_DISABLED	(FUNC(3) | PORTF(7, 5) | SE | VE)
+#define EMI_CLK			(FUNC(0) | PORTF(7, 4) | SE | VE)
+#define EMI_CLK_DISABLED	(FUNC(3) | PORTF(7, 4) | SE | VE)
+#define EMI_DQS1		(FUNC(0) | PORTF(7, 3) | SE | VE)
+#define EMI_DQS1_DISABLED	(FUNC(3) | PORTF(7, 3) | SE | VE)
+#define EMI_DQS0		(FUNC(0) | PORTF(7, 2) | SE | VE)
+#define EMI_DQS0_DISABLED	(FUNC(3) | PORTF(7, 2) | SE | VE)
+#define EMI_DQM1		(FUNC(0) | PORTF(7, 1) | SE | VE | PE)
+#define EMI_DQM1_DISABLED	(FUNC(3) | PORTF(7, 1) | SE | VE | PE)
+#define EMI_DQM0		(FUNC(0) | PORTF(7, 0) | SE | VE | PE)
+#define EMI_DQM0_DISABLED	(FUNC(3) | PORTF(7, 0) | SE | VE | PE)
+
+#endif /* __ASM_MACH_IOMUX_H */
diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx23.c
new file mode 100644
index 0000000..b0f4046
--- /dev/null
+++ b/arch/arm/mach-stm/iomux-imx23.c
@@ -0,0 +1,117 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+
+#define HW_PINCTRL_CTRL 0x000
+#define HW_PINCTRL_MUXSEL0 0x100
+#define HW_PINCTRL_DRIVE0 0x200
+#define HW_PINCTRL_PULL0 0x400
+#define HW_PINCTRL_DOUT0 0x500
+#define HW_PINCTRL_DIN0 0x600
+#define HW_PINCTRL_DOE0 0x700
+
+static uint32_t calc_mux_reg(uint32_t no)
+{
+	/* each register controls 16 pads */
+	return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0;
+}
+
+static uint32_t calc_strength_reg(uint32_t no)
+{
+	/* each register controls 8 pads */
+	return  ((no >> 3) << 4) + HW_PINCTRL_DRIVE0;
+}
+
+static uint32_t calc_pullup_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_PULL0;
+}
+
+static uint32_t calc_output_enable_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DOE0;
+}
+
+static uint32_t calc_output_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
+}
+
+/**
+ * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
+ */
+void imx_gpio_mode(unsigned m)
+{
+	uint32_t reg_offset, gpio_pin, reg;
+
+	gpio_pin = GET_GPIO_NO(m);
+
+	/* configure the pad to its function (always) */
+	reg_offset = calc_mux_reg(gpio_pin);
+	reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 16) << 1));
+	reg |= GET_FUNC(m) << ((gpio_pin % 16) << 1);
+	writel(reg, IMX_IOMUXC_BASE + reg_offset);
+
+	/* some pins are disabled when configured for GPIO */
+	if ((gpio_pin > 95) && (GET_FUNC(m) == IS_GPIO)) {
+		printf("Cannot configure pad %d to GPIO\n", gpio_pin);
+		return;
+	}
+
+	if (SE_PRESENT(m)) {
+		reg_offset = calc_strength_reg(gpio_pin);
+		reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 8) << 2));
+		reg |= GET_STRENGTH(m) << ((gpio_pin % 8) << 2);
+		writel(reg, IMX_IOMUXC_BASE + reg_offset);
+	}
+
+	if (VE_PRESENT(m)) {
+		reg_offset = calc_strength_reg(gpio_pin);
+		if (GET_VOLTAGE(m) == 1)
+			writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 4);
+		else
+			writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 8);
+	}
+
+	if (PE_PRESENT(m)) {
+		reg_offset = calc_pullup_reg(gpio_pin);
+		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8));
+	}
+
+	if (GET_FUNC(m) == IS_GPIO) {
+		if (GET_GPIODIR(m) == 1) {
+			/* first set the output value */
+			reg_offset = calc_output_reg(gpio_pin);
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
+			/* then the direction */
+			reg_offset = calc_output_enable_reg(gpio_pin);
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 4);
+		} else {
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 8);
+		}
+	}
+}
diff --git a/arch/arm/mach-stm/reset-imx23.c b/arch/arm/mach-stm/reset-imx23.c
new file mode 100644
index 0000000..db0b3f2
--- /dev/null
+++ b/arch/arm/mach-stm/reset-imx23.c
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <asm/io.h>
+
+#define HW_RTC_CTRL     0x000
+# define BM_RTC_CTRL_WATCHDOGEN (1 << 4)
+#define HW_RTC_CTRL_SET 0x004
+#define HW_RTC_CTRL_CLR 0x008
+#define HW_RTC_CTRL_TOG 0x00C
+
+#define HW_RTC_WATCHDOG     0x050
+#define HW_RTC_WATCHDOG_SET 0x054
+#define HW_RTC_WATCHDOG_CLR 0x058
+#define HW_RTC_WATCHDOG_TOG 0x05C
+
+#define WDOG_COUNTER_RATE	1000 /* 1 kHz clock */
+
+#define HW_RTC_PERSISTENT1     0x070
+# define BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER 0x80000000
+#define HW_RTC_PERSISTENT1_SET 0x074
+#define HW_RTC_PERSISTENT1_CLR 0x078
+#define HW_RTC_PERSISTENT1_TOG 0x07C
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let it time out
+ *
+ * TODO There is a much easier way to reset the CPU: Refer bit 2 in
+ *       the HW_CLKCTRL_RESET register, data sheet page 106/4-30
+ */
+void __noreturn reset_cpu (unsigned long ignored)
+{
+	writel(WDOG_COUNTER_RATE, IMX_WDT_BASE + HW_RTC_WATCHDOG);
+	writel(BM_RTC_CTRL_WATCHDOGEN, IMX_WDT_BASE + HW_RTC_CTRL_SET);
+	writel(BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER, IMX_WDT_BASE + HW_RTC_PERSISTENT1);
+
+	while (1)
+		;
+	/*NOTREACHED*/
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-stm/speed-imx23.c b/arch/arm/mach-stm/speed-imx23.c
new file mode 100644
index 0000000..f3d54e0
--- /dev/null
+++ b/arch/arm/mach-stm/speed-imx23.c
@@ -0,0 +1,278 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This code is based partially on code of:
+ *
+ * (c) 2008 Embedded Alley Solutions, Inc.
+ * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/generic.h>
+#include <mach/clock-imx23.h>
+
+/* Note: all clock frequencies are returned in kHz */
+
+#define HW_CLKCTRL_PLLCTRL0 0x000
+#define HW_CLKCTRL_PLLCTRL1 0x010
+#define HW_CLKCTRL_CPU 0x20
+# define GET_CPU_XTAL_DIV(x) (((x) >> 16) & 0x3ff)
+# define GET_CPU_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_HBUS 0x30
+#define HW_CLKCTRL_XBUS 0x40
+#define HW_CLKCTRL_XTAL 0x050
+#define HW_CLKCTRL_PIX 0x060
+/* note: no set/clear register! */
+#define HW_CLKCTRL_SSP 0x070
+/* note: no set/clear register! */
+# define CLKCTRL_SSP_CLKGATE (1 << 31)
+# define CLKCTRL_SSP_BUSY (1 << 29)
+# define CLKCTRL_SSP_DIV_MASK 0x1ff
+# define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+# define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+#define HW_CLKCTRL_GPMI 0x080
+/* note: no set/clear register! */
+#define HW_CLKCTRL_SPDIF 0x090
+/* note: no set/clear register! */
+#define HW_CLKCTRL_EMI	0xa0
+/* note: no set/clear register! */
+# define CLKCTRL_EMI_CLKGATE (1 << 31)
+# define GET_EMI_XTAL_DIV(x) (((x) >> 8) & 0xf)
+# define GET_EMI_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_SAIF 0x0c0
+#define HW_CLKCTRL_TV 0x0d0
+#define HW_CLKCTRL_ETM 0x0e0
+#define HW_CLKCTRL_FRAC 0xf0
+# define CLKCTRL_FRAC_CLKGATEIO (1 << 31)
+# define GET_IOFRAC(x) (((x) >> 24) & 0x3f)
+# define SET_IOFRAC(x) (((x) & 0x3f) << 24)
+# define CLKCTRL_FRAC_CLKGATEPIX (1 << 23)
+# define GET_PIXFRAC(x) (((x) >> 16) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATEEMI (1 << 15)
+# define GET_EMIFRAC(x) (((x) >> 8) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATECPU (1 << 7)
+# define GET_CPUFRAC(x) ((x) & 0x3f)
+#define HW_CLKCTRL_FRAC1 0x100
+#define HW_CLKCTRL_CLKSEQ 0x110
+# define CLKCTRL_CLKSEQ_BYPASS_ETM (1 << 8)
+# define CLKCTRL_CLKSEQ_BYPASS_CPU (1 << 7)
+# define CLKCTRL_CLKSEQ_BYPASS_EMI (1 << 6)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP (1 << 5)
+# define CLKCTRL_CLKSEQ_BYPASS_GPMI (1 << 4)
+#define HW_CLKCTRL_RESET 0x120
+#define HW_CLKCTRL_STATUS 0x130
+#define HW_CLKCTRL_VERSION 0x140
+
+unsigned imx_get_mpllclk(void)
+{
+	/* the main PLL runs at 480 MHz */
+	return 480U * 1000U;
+}
+
+unsigned imx_get_xtalclk(void)
+{
+	/* the external reference runs at 24 MHz */
+	return 24U * 1000U;
+}
+
+/* used for the SDRAM controller */
+unsigned imx_get_emiclk(void)
+{
+	uint32_t reg;
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_EMI) & CLKCTRL_EMI_CLKGATE)
+		return 0U;	/* clock is off */
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
+		return imx_get_xtalclk() / GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+
+	rate = imx_get_mpllclk();
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
+		rate *= 18U;
+		rate /= GET_EMIFRAC(reg);
+	}
+
+	return rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+}
+
+/*
+ * Source of ssp, gpmi, ir
+ */
+unsigned imx_get_ioclk(void)
+{
+	uint32_t reg;
+	unsigned rate = imx_get_mpllclk();
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	if (reg & CLKCTRL_FRAC_CLKGATEIO)
+		return 0U;	/* clock is off */
+
+	rate *= 18U;
+	rate /= GET_IOFRAC(reg);
+	return rate;
+}
+
+/**
+ * Setup a new frequency to the IOCLK domain.
+ * @param nc New frequency in [kHz]
+ *
+ * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
+ */
+unsigned imx_set_ioclk(unsigned nc)
+{
+	uint32_t reg;
+	unsigned div;
+
+	div = imx_get_mpllclk();
+	div *= 18U;
+	div += nc >> 1;
+	div /= nc;
+	if (div > 0x3f)
+		div = 0x3f;
+	/* mask the current settings */
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC) & ~(SET_IOFRAC(0x3f));
+	writel(reg | SET_IOFRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	/* enable the IO clock at its new frequency */
+	writel(CLKCTRL_FRAC_CLKGATEIO, IMX_CCM_BASE + HW_CLKCTRL_FRAC + 8);
+
+	return imx_get_ioclk();
+}
+
+/* this is CPU core clock */
+unsigned imx_get_armclk(void)
+{
+	uint32_t reg;
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_CPU)
+		return imx_get_xtalclk() / GET_CPU_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	if (reg & CLKCTRL_FRAC_CLKGATECPU)
+		return 0U;	/* should not possible, shouldn't it? */
+
+	rate = imx_get_mpllclk();
+	rate *= 18U;
+	rate /= GET_CPUFRAC(reg);
+
+	return rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+}
+
+/* this is the AHB and APBH bus clock */
+unsigned imx_get_hclk(void)
+{
+	unsigned rate = imx_get_armclk();
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
+		rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+		rate >>= 5U; /* / 32 */
+	} else
+		rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+	return rate;
+}
+
+/*
+ * Source of UART, debug UART, audio, PWM, dri, timer, digctl
+ */
+unsigned imx_get_xclk(void)
+{
+	unsigned rate = imx_get_xtalclk();	/* runs from the 24 MHz crystal reference */
+
+	return rate / (readl(IMX_CCM_BASE + HW_CLKCTRL_XBUS) & 0x3ff);
+}
+
+unsigned imx_get_sspclk(void)
+{
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_CLKGATE)
+		return 0U;	/* clock is off */
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_SSP)
+		rate = imx_get_xtalclk();
+	else
+		rate = imx_get_ioclk();
+
+	return rate / GET_SSP_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_SSP));
+}
+
+/**
+ * @param nc New frequency in [kHz]
+ * @param high != 0 if ioclk should be the source
+ * @return The new possible frequency
+ */
+unsigned imx_set_sspclk(unsigned nc, int high)
+{
+	uint32_t reg;
+	unsigned ssp_div;
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & ~CLKCTRL_SSP_CLKGATE;
+	/* Datasheet says: Do not change the DIV setting if the clock is off */
+	writel(reg, IMX_CCM_BASE + HW_CLKCTRL_SSP);
+	/* Wait while clock is gated */
+	while (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_CLKGATE)
+		;
+
+	if (high)
+		ssp_div = imx_get_ioclk();
+	else
+		ssp_div = imx_get_xtalclk();
+
+	if (nc > ssp_div) {
+		printf("Cannot setup SSP unit clock to %u Hz, base clock is only %u Hz\n", nc, ssp_div);
+		ssp_div = 1U;
+	} else {
+		ssp_div += nc - 1U;
+		ssp_div /= nc;
+		if (ssp_div > CLKCTRL_SSP_DIV_MASK)
+			ssp_div = CLKCTRL_SSP_DIV_MASK;
+	}
+
+	/* Set new divider value */
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & ~CLKCTRL_SSP_DIV_MASK;
+	writel(reg | SET_SSP_DIV(ssp_div), IMX_CCM_BASE + HW_CLKCTRL_SSP);
+
+	/* Wait until new divider value is set */
+	while (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_BUSY)
+		;
+
+	if (high)
+		/* switch to ioclock */
+		writel(CLKCTRL_CLKSEQ_BYPASS_SSP, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + 8);
+	else
+		/* switch to 24 MHz crystal */
+		writel(CLKCTRL_CLKSEQ_BYPASS_SSP, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + 4);
+
+	return imx_get_sspclk();
+}
+
+void imx_dump_clocks(void)
+{
+	printf("mpll:    %10u kHz\n", imx_get_mpllclk());
+	printf("arm:     %10u kHz\n", imx_get_armclk());
+	printf("ioclk:   %10u kHz\n", imx_get_ioclk());
+	printf("emiclk:  %10u kHz\n", imx_get_emiclk());
+	printf("hclk:    %10u kHz\n", imx_get_hclk());
+	printf("xclk:    %10u kHz\n", imx_get_xclk());
+	printf("ssp:     %10u kHz\n", imx_get_sspclk());
+}
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 10:59:57 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu,  7 Oct 2010 16:59:57 +0200
Subject: [PATCH 4/4] Add the i.MX23 based Chumby platform (WIP)
In-Reply-To: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
References: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286463597-16948-5-git-send-email-jbe@pengutronix.de>

The so called "chumby one" aka falconwing is an i.MX23 based platform.

Note: This is work in progress. Use with care.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/Makefile                              |    1 +
 arch/arm/boards/chumby_falconwing/Makefile     |    1 +
 arch/arm/boards/chumby_falconwing/config.h     |   21 ++
 arch/arm/boards/chumby_falconwing/falconwing.c |  271 ++++++++++++++++++++++++
 arch/arm/configs/chumbyone_defconfig           |  224 +++++++++++++++++++
 arch/arm/mach-stm/Kconfig                      |    9 +
 6 files changed, 527 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/chumby_falconwing/Makefile
 create mode 100644 arch/arm/boards/chumby_falconwing/config.h
 create mode 100644 arch/arm/boards/chumby_falconwing/falconwing.c
 create mode 100644 arch/arm/configs/chumbyone_defconfig

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 75fa6d3..b25f366 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -82,6 +82,7 @@ board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
 board-$(CONFIG_MACH_MX23EVK)			:= freescale-mx23-evk
+board-$(CONFIG_MACH_CHUMBY)			:= chumby_falconwing
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/chumby_falconwing/Makefile b/arch/arm/boards/chumby_falconwing/Makefile
new file mode 100644
index 0000000..0bc79d9
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/Makefile
@@ -0,0 +1 @@
+obj-y = falconwing.o
diff --git a/arch/arm/boards/chumby_falconwing/config.h b/arch/arm/boards/chumby_falconwing/config.h
new file mode 100644
index 0000000..87d9e2f
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/config.h
@@ -0,0 +1,21 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _CONFIG_H_
+# define _CONFIG_H_
+
+#endif /* _CONFIG_H_ */
diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
new file mode 100644
index 0000000..b28d0ba
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -0,0 +1,271 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <generated/mach-types.h>
+#include <mach/imx-regs.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.name     = "mem",
+	.map_base = IMX_MEMORY_BASE,
+	.size     = 64 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+static void falconwing_mmu_init(void)
+{
+#ifdef CONFIG_MMU
+	mmu_init();
+	arm_create_section(IMX_MEMORY_BASE, IMX_MEMORY_BASE, 64, PMD_SECT_DEF_CACHED);
+	arm_create_section(IMX_MEMORY_BASE + 128 * 1024 * 1024, IMX_MEMORY_BASE, 64, PMD_SECT_DEF_UNCACHED);
+	setup_dma_coherent(0x10000000);
+	arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
+	mmu_enable();
+#endif
+}
+
+extern void imx_dump_clocks(void);
+
+static const uint32_t pad_setup[] = {
+	/* may be not required as already done by the bootlet code */
+#if 0
+	/* SDRAM data signals */
+	EMI_D15 | STRENGTH(0) | VE_2_5V,
+	EMI_D14 | STRENGTH(0) | VE_2_5V,
+	EMI_D13 | STRENGTH(0) | VE_2_5V,
+	EMI_D12 | STRENGTH(0) | VE_2_5V,
+	EMI_D11 | STRENGTH(0) | VE_2_5V,
+	EMI_D10 | STRENGTH(0) | VE_2_5V,
+	EMI_D9 | STRENGTH(0) | VE_2_5V,
+	EMI_D8 | STRENGTH(0) | VE_2_5V,
+	EMI_D7 | STRENGTH(0) | VE_2_5V,
+	EMI_D6 | STRENGTH(0) | VE_2_5V,
+	EMI_D5 | STRENGTH(0) | VE_2_5V,
+	EMI_D4 | STRENGTH(0) | VE_2_5V,
+	EMI_D3 | STRENGTH(0) | VE_2_5V,
+	EMI_D2 | STRENGTH(0) | VE_2_5V,
+	EMI_D1 | STRENGTH(0) | VE_2_5V,
+	EMI_D0 | STRENGTH(0) | VE_2_5V,
+
+	/* SDRAM data control signals */
+	EMI_DQM0 | STRENGTH(0) | VE_2_5V,	/* LDM */
+	EMI_DQM1 | STRENGTH(0) | VE_2_5V,	/* UDM */
+
+	/* SDRAM address signals */
+	EMI_A0 | STRENGTH(0) | VE_2_5V,
+	EMI_A1 | STRENGTH(0) | VE_2_5V,
+	EMI_A2 | STRENGTH(0) | VE_2_5V,
+	EMI_A3 | STRENGTH(0) | VE_2_5V,
+	EMI_A4 | STRENGTH(0) | VE_2_5V,
+	EMI_A5 | STRENGTH(0) | VE_2_5V,
+	EMI_A6 | STRENGTH(0) | VE_2_5V,
+	EMI_A7 | STRENGTH(0) | VE_2_5V,
+	EMI_A8 | STRENGTH(0) | VE_2_5V,
+	EMI_A9 | STRENGTH(0) | VE_2_5V,
+	EMI_A10 | STRENGTH(0) | VE_2_5V,
+	EMI_A11 | STRENGTH(0) | VE_2_5V,
+	EMI_A12 | STRENGTH(0) | VE_2_5V,
+
+	/* SDRAM address control signals */
+	EMI_RASN | STRENGTH(0) | VE_2_5V,
+	EMI_CASN | STRENGTH(0) | VE_2_5V,
+
+	/* SDRAM control signals */
+	EMI_CE0N | STRENGTH(0) | VE_2_5V,
+	EMI_CLK | STRENGTH(0) | VE_2_5V,
+	EMI_CLKN | STRENGTH(0) | VE_2_5V,
+	EMI_CKE | STRENGTH(0) | VE_2_5V,
+	EMI_WEN | STRENGTH(0) | VE_2_5V,
+	EMI_BA0 | STRENGTH(0) | VE_2_5V,
+	EMI_BA1 | STRENGTH(0) | VE_2_5V,
+	EMI_DQS0 | STRENGTH(0) | VE_2_5V,
+	EMI_DQS1 | STRENGTH(0) | VE_2_5V,
+#endif
+	/* debug port */
+	PWM1_DUART_TX | STRENGTH(S4MA),	/*  strength is TBD */
+	PWM0_DUART_RX | STRENGTH(S4MA),	/*  strength is TBD */
+
+	/* lcd */
+	LCD_VSYNC,	/* kernel tries with 12 mA for all LCD related pins */
+	LCD_HSYNC,
+	LCD_ENABE,
+	LCD_DOTCLOCK,
+	LCD_D17,
+	LCD_D16,
+	LCD_D15,
+	LCD_D14,
+	LCD_D13,
+	LCD_D12,
+	LCD_D11,
+	LCD_D10,
+	LCD_D9,
+	LCD_D8,
+	LCD_D7,
+	LCD_D6,
+	LCD_D5,
+	LCD_D4,
+	LCD_D3,
+	LCD_D2,
+	LCD_D1,
+	LCD_D0,
+
+	/* LCD usage currently unknown */
+	LCD_CS,	/* used as SPI SS */
+	LCD_RS,	/* used as SPI CLK */
+	LCD_RESET,
+	LCD_WR,	/* used as SPI MOSI */
+
+	/* I2C to the MMA7455L, KXTE9, AT24C08 (DCID), AT24C128B (ID EEPROM) and QN8005B */
+	I2C_SDA,
+	I2C_CLK,
+
+	/* Rotary decoder (external pull ups) */
+	ROTARYA,
+	ROTARYB,
+
+	/* the chumby bend (external pull up) */
+	PWM4_GPIO | GPIO_IN,
+
+	/* backlight control, to be controled by PWM, here we only want to disable it */
+	PWM2_GPIO | GPIO_OUT | GPIO_VALUE(0),	/* 1 enables, 0 disables the backlight */
+
+	/* send a reset signal to the USB hub */
+	AUART1_TX_GPIO | GPIO_OUT | GPIO_VALUE(0),
+
+	/* USB power disable (FIXME what level to be switched off) */
+	AUART1_CTS_GPIO | GPIO_OUT | GPIO_VALUE(0),
+
+	/* Detecting if a display is connected (0 = display attached) (external pull up) */
+	AUART1_RTS_GPIO | GPIO_IN,
+
+	/* disable the audio amplifier */
+	GPMI_D08_GPIO | GPIO_OUT | GPIO_VALUE(0),
+
+	/* Head Phone detection (FIXME what level when plugged in) (external pull up) */
+	GPMI_D11_GPIO | GPIO_IN,
+
+#if 0
+	/* Enable the local 5V (FIXME what to do when the bootloader runs) */
+	GPMI_D12_GPIO | GPIO_OUT | GPIO_VALUE(1),
+#endif
+
+	/* not used pins */
+	GPMI_D09_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_D10_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_D13_GPIO | GPIO_IN | PULLUP(1),
+
+	/* unknown. Not connected to anything than test pin J113 */
+	GPMI_D14_GPIO | GPIO_IN | PULLUP(1),
+
+	/* unknown. Not connected to anything than test pin J114 */
+	GPMI_D15_GPIO | GPIO_IN | PULLUP(1),
+
+	/* NAND controller (Note: There is no NAND device on the board) */
+	GPMI_D00 | PULLUP(1),
+	GPMI_D01 | PULLUP(1),
+	GPMI_D02 | PULLUP(1),
+	GPMI_D03 | PULLUP(1),
+	GPMI_D04 | PULLUP(1),
+	GPMI_D05 | PULLUP(1),
+	GPMI_D06 | PULLUP(1),
+	GPMI_D07 | PULLUP(1),
+	GPMI_CE0N,
+	GPMI_RDY0 | PULLUP(1),
+	GPMI_WRN,	/* kernel tries here with 12 mA */
+	GPMI_RDN,	/* kernel tries here with 12 mA */
+	GPMI_WPM,	/* kernel tries here with 12 mA */
+	GPMI_CLE,
+	GPMI_ALE,
+
+	/* SD card interface */
+	SSP1_DATA0 | PULLUP(1),	/* available at J201 */
+	SSP1_DATA1 | PULLUP(1),	/* available at J200 */
+	SSP1_DATA2 | PULLUP(1),	/* available at J205 */
+	SSP1_DATA3 | PULLUP(1),	/* available at J204 */
+	SSP1_SCK,		/* available at J202 */
+	SSP1_CMD | PULLUP(1),	/* available at J203 */
+	SSP1_DETECT | PULLUP(1),	/* only connected to test pin J115 */
+
+	/* other not used pins */
+	GPMI_CE1N_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_CE2N_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_RDY1_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_RDY2_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_RDY3_GPIO | GPIO_IN | PULLUP(1),
+};
+
+static int falconwing_devices_init(void)
+{
+	int i;
+
+	falconwing_mmu_init();
+
+	/* initizalize gpios */
+	for (i = 0; i < ARRAY_SIZE(pad_setup); i++)
+		imx_gpio_mode(pad_setup[i]);
+
+	register_device(&sdram_dev);
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void*)(sdram_dev.map_base + 0x100));
+	armlinux_set_architecture(MACH_TYPE_CHUMBY);
+
+	imx_dump_clocks();
+
+	return 0;
+}
+
+device_initcall(falconwing_devices_init);
+
+static struct device_d falconwing_serial_device = {
+	.name     = "stm_serial",
+	.map_base = IMX_DBGUART_BASE,
+	.size     = 8192,
+};
+
+static int falconwing_console_init(void)
+{
+	return register_device(&falconwing_serial_device);
+}
+
+console_initcall(falconwing_console_init);
+
+/** @page chumby Chumby Industrie's Falconwing aka "chumby one" (http://www.chumby.com/)
+
+This CPU card is based on a Freescale i.MX23 CPU. The card is shipped with:
+
+- 64 MiB synchronous dynamic RAM (DDR type)
+
+Memory layout when @b barebox is running:
+
+- 0x40000000 start of SDRAM
+- 0x40000100 start of kernel's boot parameters
+  - below malloc area: stack area
+  - below barebox: malloc area
+- 0x42000000 start of @b barebox
+*/
diff --git a/arch/arm/configs/chumbyone_defconfig b/arch/arm/configs/chumbyone_defconfig
new file mode 100644
index 0000000..a3d3e25
--- /dev/null
+++ b/arch/arm/configs/chumbyone_defconfig
@@ -0,0 +1,224 @@
+#
+# Automatically generated make config: don't edit
+# Linux barebox version: 2010.09.0
+# Thu Oct  7 16:36:33 2010
+#
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_ARM=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_IMX is not set
+CONFIG_ARCH_STM=y
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_S3C24xx is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+
+#
+# processor features
+#
+CONFIG_ARCH_TEXT_BASE=0x42000000
+CONFIG_BOARDINFO="Chumby Falconwing"
+
+#
+# SigmaTel/Freescale i.MX System-on-Chip
+#
+CONFIG_ARCH_IMX23=y
+# CONFIG_MACH_MX23EVK is not set
+CONFIG_MACH_CHUMBY=y
+
+#
+# Board specific settings       
+#
+CONFIG_AEABI=y
+
+#
+# Arm specific settings         
+#
+CONFIG_CMD_ARM_CPUINFO=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
+CONFIG_GREGORIAN_CALENDER=y
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+CONFIG_GENERIC_GPIO=y
+
+#
+# General Settings              
+#
+CONFIG_LOCALVERSION_AUTO=y
+
+#
+# memory layout                 
+#
+CONFIG_HAVE_MMU=y
+# CONFIG_MMU is not set
+CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
+CONFIG_TEXT_BASE=0x42000000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+# CONFIG_MEMORY_LAYOUT_FIXED is not set
+CONFIG_STACK_SIZE=0x8000
+CONFIG_MALLOC_SIZE=0x400000
+CONFIG_BROKEN=y
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_PROMPT="chumby:"
+CONFIG_BAUDRATE=115200
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+# CONFIG_GLOB is not set
+CONFIG_PROMPT_HUSH_PS2="> "
+# CONFIG_HUSH_FANCY_PROMPT is not set
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+# CONFIG_MENU is not set
+# CONFIG_PASSWORD is not set
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+CONFIG_TIMESTAMP=y
+CONFIG_CONSOLE_FULL=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+# CONFIG_OF_FLAT_TREE is not set
+CONFIG_PARTITION=y
+# CONFIG_DEFAULT_ENVIRONMENT is not set
+
+#
+# Debugging                     
+#
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+# CONFIG_ENABLE_DEVICE_NOISE is not set
+
+#
+# Commands                      
+#
+
+#
+# scripting                     
+#
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TRUE=y
+CONFIG_CMD_FALSE=y
+# CONFIG_CMD_LOGIN is not set
+# CONFIG_CMD_PASSWD is not set
+
+#
+# file commands                 
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+
+#
+# console                       
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_ECHO_E=y
+
+#
+# memory                        
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_MEMINFO is not set
+# CONFIG_CMD_CRC is not set
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+
+#
+# flash                         
+#
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_UBI is not set
+
+#
+# booting                       
+#
+CONFIG_CMD_BOOTM=y
+# CONFIG_CMD_BOOTM_ZLIB is not set
+# CONFIG_CMD_BOOTM_BZLIB is not set
+# CONFIG_CMD_BOOTM_SHOW_TYPE is not set
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTU=y
+CONFIG_CMD_RESET=y
+# CONFIG_CMD_GO is not set
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_CMD_VERSION=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_DEVINFO=y
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_UNLZO is not set
+# CONFIG_NET is not set
+
+#
+# Drivers                       
+#
+
+#
+# serial drivers                
+#
+# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
+CONFIG_DRIVER_SERIAL_STM378X=y
+# CONFIG_DRIVER_SERIAL_NS16550 is not set
+
+#
+# SPI drivers                   
+#
+# CONFIG_SPI is not set
+# CONFIG_I2C is not set
+
+#
+# flash drivers                 
+#
+# CONFIG_DRIVER_CFI is not set
+# CONFIG_MTD is not set
+# CONFIG_ATA is not set
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_VIDEO is not set
+
+#
+# Filesystem support            
+#
+# CONFIG_FS_CRAMFS is not set
+CONFIG_FS_RAMFS=y
+CONFIG_FS_DEVFS=y
+CONFIG_CRC32=y
+# CONFIG_DIGEST is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_PROCESS_ESCAPE_SEQUENCE=y
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index bbdea51..021919a 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -3,9 +3,11 @@ if ARCH_STM
 config ARCH_TEXT_BASE
 	hex
 	default 0x41000000 if MACH_MX23EVK
+	default 0x42000000 if MACH_CHUMBY
 
 config BOARDINFO
 	default "Freescale i.MX23-EVK" if MACH_MX23EVK
+	default "Chumby Falconwing" if MACH_CHUMBY
 
 comment "SigmaTel/Freescale i.MX System-on-Chip"
 
@@ -28,6 +30,13 @@ config MACH_MX23EVK
 	help
 	  Say Y here if you are using the Freescale i.MX23-EVK board
 
+config MACH_CHUMBY
+	bool "Chumby Falconwing"
+	select HAVE_MMU
+	help
+	  Say Y here if you are using the "chumby one" aka falconwing from
+	  Chumby Industries
+
 endchoice
 
 endif
-- 
1.7.2.3



From plagnioj at jcrosoft.com  Thu Oct  7 11:16:48 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu, 7 Oct 2010 17:16:48 +0200
Subject: [RFC] Add MCI card support to barebox
In-Reply-To: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
Message-ID: <20101007151648.GD32214@game.jcrosoft.org>

Hi,

	I'll add at91 MCI support and test this framework

Best Regrds,
J.
On 15:24 Thu 07 Oct     , Juergen Beisert wrote:
> This is the second try to send the patch stack via git...hopefully its
> complete this time.
> 
> This patch is based on some work Sascha made already. I tried to bring in some
> light into the MCI framework routines as they are based on code from another
> project. Bear with me, if I didn't add useful comments all over the code. I
> just wasn't able to understand what happen... If someone has more knowledge
> about MCI cards, please take a look at the FIXME/TODOs and make me understand
> why the code does what it does.
> 
> There is no regular user, yet. The first platform (S3C2440 based) I did the
> tests on, is not part of barebox (and will not) and the other platfrom (i.MX23
> ChumbOne) is not yet part of barebox. But will coming soon.
> 
> Comments are welcome.
> 
> Regards,
> Juergen
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


From s.hauer at pengutronix.de  Thu Oct  7 11:37:14 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 Oct 2010 17:37:14 +0200
Subject: [PATCH 5/7] Add MCI card support to barebox
In-Reply-To: <1286457858-29771-6-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
	<1286457858-29771-6-git-send-email-jbe@pengutronix.de>
Message-ID: <20101007153713.GH28242@pengutronix.de>

Hi J?rgen,

On Thu, Oct 07, 2010 at 03:24:16PM +0200, Juergen Beisert wrote:
> This adds the basic framework to handle MCI cards in barebox.
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  drivers/Kconfig        |    1 +
>  drivers/Makefile       |    1 +
>  drivers/mci/Kconfig    |   30 ++
>  drivers/mci/Makefile   |    1 +
>  drivers/mci/mci-core.c | 1308 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/mci.h          |  230 +++++++++
>  6 files changed, 1571 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/mci/Kconfig
>  create mode 100644 drivers/mci/Makefile
>  create mode 100644 drivers/mci/mci-core.c
>  create mode 100644 include/mci.h
>

This whole patch looks quite good.
Please add some linebreaks in mci-core.c. I don't want strict 80
character lines, but some lines are really long.

[snip]

> +static int mci_probe(struct device_d *mci_dev)
> +{
> +	struct mci *mci;
> +	int rc;
> +
> +	mci = xzalloc(sizeof(struct mci));
> +	mci_dev->priv = mci;
> +
> +#ifdef CONFIG_MCI_STARTUP
> +	/* if enabled, probe the attached card immediately */
> +	rc = mci_card_probe(mci_dev);
> +	if (rc == -ENODEV) {
> +		/*
> +		 * If it fails, add the 'probe' parameter to give the user
> +		 * a chance to insert a card and try again. Note: This may fail
> +		 * systems that rely on the MCI card for startup (for the
> +		 * persistant environment for example)
> +		 */
> +		rc = add_mci_parameter(mci_dev);
> +		if (rc != 0) {
> +			pr_err("Failed to add 'probe' parameter to the MCI device\n");
> +			goto on_error;
> +		}
> +	}
> +#endif
> +
> +#ifndef CONFIG_MCI_STARTUP

#else instead?

> +	/* add params on demand */
> +	rc = add_mci_parameter(mci_dev);
> +	if (rc != 0) {
> +		pr_err("Failed to add 'probe' parameter to the MCI device\n");
> +		goto on_error;
> +	}
> +#endif
> +
> +	return rc;
> +
> +on_error:
> +	free(mci);
> +	return rc;
> +}
> +

[snip]

> +
> +/** host information */
> +struct mci_platformdata {
> +	struct device_d *hw_dev;	/**< the host MCI hardware device */
> +	unsigned voltages;
> +	unsigned host_caps;	/**< Host's interface capabilities, refer MMC_VDD_* and FIXME */
> +	unsigned f_min;		/**< host interface lower limit */
> +	unsigned f_max;		/**< host interface upper limit */
> +	unsigned clock;		/**< Current clock used to talk to the card */
> +	unsigned bus_width;	/**< used data bus width to the card */
> +
> +	int (*init)(struct device_d*, struct device_d*);	/**< init the host interface */
> +	void (*set_ios)(struct device_d*, struct device_d*, unsigned, unsigned);	/**< change host interface settings */
> +	int (*send_cmd)(struct device_d*, struct mci_cmd*, struct mci_data*);	/**< handle a command */
> +};

I prefer this struct named mci_host, this seems to match better what it
actually is. For the convenience of drivers set init/set_ios/send_cmd
functions should be passed a pointer to the mci_host, not the device,
because that's what they actually registered. I already prepared a patch
for this, I'll send it in a seperate mail.

> +
> +/** MMC/SD and interface instance information */
> +struct mci {
> +	unsigned version;
> +	int high_capacity;	/**< != 0 when a high capacity card is connected (OCR -> OCR_HCS) */
> +	unsigned card_caps;	/**< Card's capabilities */
> +	unsigned ocr;		/**< card's "operation condition register" */
> +	unsigned scr[2];
> +	unsigned csd[4];	/**< card's "card specific data register" */
> +	unsigned cid[4];	/**< card's "card identification register" */
> +	unsigned short rca;	/* FIXME */
> +	unsigned tran_speed;	/**< not yet used */
> +	unsigned read_bl_len;	/**< currently used data block length for read accesses */
> +	unsigned write_bl_len;	/**< currently used data block length for write accesses */
> +	uint64_t capacity;	/**< Card's data capacity in bytes */
> +	int ready_for_use;	/** true if already probed */
> +};
> +
> +int mci_register(struct mci_platformdata*);
> +
> +#define GET_HOST_DATA(x) (x->priv)
> +#define GET_HOST_PDATA(x) (x->platform_data)
> +#define GET_MCI_DATA(x) (x->priv)
> +#define GET_MCI_PDATA(x) (x->platform_data)
> +
> +#endif /* _MCI_H_ */
> -- 
> 1.7.2.3
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Thu Oct  7 11:37:48 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu,  7 Oct 2010 17:37:48 +0200
Subject: No subject
Message-ID: <1286465871-19953-1-git-send-email-s.hauer@pengutronix.de>

Hi all and J?rgen,

Here is the patch I mentioned in the mci review + support for the i.MX27/31
mci controller.

Sascha



From s.hauer at pengutronix.de  Thu Oct  7 11:37:51 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu,  7 Oct 2010 17:37:51 +0200
Subject: [PATCH 3/3] ARM pca100: Add mci support
In-Reply-To: <1286465871-19953-1-git-send-email-s.hauer@pengutronix.de>
References: <1286465871-19953-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286465871-19953-4-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/phycard-i.MX27/pca100.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/phycard-i.MX27/pca100.c b/arch/arm/boards/phycard-i.MX27/pca100.c
index 7328a6c..7460c00 100644
--- a/arch/arm/boards/phycard-i.MX27/pca100.c
+++ b/arch/arm/boards/phycard-i.MX27/pca100.c
@@ -109,6 +109,11 @@ static void pca100_usbh_init(void)
 }
 #endif
 
+static struct device_d mmc_dev = {
+	.name		= "imx-mmc",
+	.map_base	= 0x10014000,
+};
+
 #ifdef CONFIG_MMU
 static void pca100_mmu_init(void)
 {
@@ -180,8 +185,17 @@ static int pca100_devices_init(void)
 		PD23_AF_USBH2_DATA2,
 		PD24_AF_USBH2_DATA1,
 		PD26_AF_USBH2_DATA5,
+		/* SDHC */
+		PB4_PF_SD2_D0,
+		PB5_PF_SD2_D1,
+		PB6_PF_SD2_D2,
+		PB7_PF_SD2_D3,
+		PB8_PF_SD2_CMD,
+		PB9_PF_SD2_CLK,
 	};
 
+	PCCR0 |= PCCR0_SDHC2_EN;
+
 	/* disable the usb phys */
 	imx_gpio_mode((GPIO_PORTB | 23) | GPIO_GPIO | GPIO_IN);
 	gpio_direction_output(GPIO_PORTB + 23, 1);
@@ -195,6 +209,7 @@ static int pca100_devices_init(void)
 	register_device(&nand_dev);
 	register_device(&sdram_dev);
 	register_device(&fec_dev);
+	register_device(&mmc_dev);
 
 	PCCR1 |= PCCR1_PERCLK2_EN;
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Thu Oct  7 11:37:49 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu,  7 Oct 2010 17:37:49 +0200
Subject: [PATCH 1/3] mci: rename mci_platformdata to mci_host,
	pass mci_host to host drivers
In-Reply-To: <1286465871-19953-1-git-send-email-s.hauer@pengutronix.de>
References: <1286465871-19953-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286465871-19953-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/mci-core.c |   50 ++++++++++++++++++++++++------------------------
 include/mci.h          |   10 ++++----
 2 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index a31b96f..323b899 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -60,9 +60,9 @@
  */
 static int mci_send_cmd(struct device_d *mci_dev, struct mci_cmd *cmd, struct mci_data *data)
 {
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 
-	return (pdata->send_cmd)(pdata->hw_dev, cmd, data);
+	return host->send_cmd(host, cmd, data);
 }
 
 /**
@@ -178,7 +178,7 @@ static int mci_go_idle(struct device_d *mci_dev)
 static int sd_send_op_cond(struct device_d *mci_dev)
 {
 	struct mci *mci = GET_MCI_DATA(mci_dev);
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 	struct mci_cmd cmd;
 	int timeout = 1000;
 	int err;
@@ -192,7 +192,7 @@ static int sd_send_op_cond(struct device_d *mci_dev)
 		}
 
 		mci_setup_cmd(&cmd, SD_CMD_APP_SEND_OP_COND,
-			pdata->voltages | (mci->version == SD_VERSION_2 ? OCR_HCS : 0),
+			host->voltages | (mci->version == SD_VERSION_2 ? OCR_HCS : 0),
 			MMC_RSP_R3);
 		err = mci_send_cmd(mci_dev, &cmd, NULL);
 		if (err) {
@@ -226,7 +226,7 @@ static int sd_send_op_cond(struct device_d *mci_dev)
 static int mmc_send_op_cond(struct device_d *mci_dev)
 {
 	struct mci *mci = GET_MCI_DATA(mci_dev);
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 	struct mci_cmd cmd;
 	int timeout = 1000;
 	int err;
@@ -235,7 +235,7 @@ static int mmc_send_op_cond(struct device_d *mci_dev)
 	mci_go_idle(mci_dev);
 
 	do {
-		mci_setup_cmd(&cmd, MMC_CMD_SEND_OP_COND, OCR_HCS | pdata->voltages, MMC_RSP_R3);
+		mci_setup_cmd(&cmd, MMC_CMD_SEND_OP_COND, OCR_HCS | host->voltages, MMC_RSP_R3);
 		err = mci_send_cmd(mci_dev, &cmd, NULL);
 
 		if (err) {
@@ -502,9 +502,9 @@ retry_scr:
  */
 static void mci_set_ios(struct device_d *mci_dev)
 {
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 
-	(pdata->set_ios)(pdata->hw_dev, mci_dev, pdata->bus_width, pdata->clock);
+	host->set_ios(host, mci_dev, host->bus_width, host->clock);
 }
 
 /**
@@ -514,16 +514,16 @@ static void mci_set_ios(struct device_d *mci_dev)
  */
 static void mci_set_clock(struct device_d *mci_dev, unsigned clock)
 {
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 
 	/* check against any given limits */
-	if (clock > pdata->f_max)
-		clock = pdata->f_max;
+	if (clock > host->f_max)
+		clock = host->f_max;
 
-	if (clock < pdata->f_min)
-		clock = pdata->f_min;
+	if (clock < host->f_min)
+		clock = host->f_min;
 
-	pdata->clock = clock;	/* the new target frequency */
+	host->clock = clock;	/* the new target frequency */
 	mci_set_ios(mci_dev);
 }
 
@@ -534,9 +534,9 @@ static void mci_set_clock(struct device_d *mci_dev, unsigned clock)
  */
 static void mci_set_bus_width(struct device_d *mci_dev, unsigned width)
 {
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 
-	pdata->bus_width = width;	/* the new target bus width */
+	host->bus_width = width;	/* the new target bus width */
 	mci_set_ios(mci_dev);
 }
 
@@ -690,7 +690,7 @@ static void mci_extract_card_capacity_from_csd(struct device_d *mci_dev)
 static int mci_startup(struct device_d *mci_dev)
 {
 	struct mci *mci = GET_MCI_DATA(mci_dev);
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 	struct mci_cmd cmd;
 	int err;
 
@@ -773,7 +773,7 @@ static int mci_startup(struct device_d *mci_dev)
 		return err;
 
 	/* Restrict card's capabilities by what the host can do */
-	mci->card_caps &= pdata->host_caps;
+	mci->card_caps &= host->host_caps;
 
 	if (IS_SD(mci)) {
 		if (mci->card_caps & MMC_MODE_4BIT) {
@@ -850,13 +850,13 @@ static int mci_startup(struct device_d *mci_dev)
 static int sd_send_if_cond(struct device_d *mci_dev)
 {
 	struct mci *mci = GET_MCI_DATA(mci_dev);
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 	struct mci_cmd cmd;
 	int err;
 
 	mci_setup_cmd(&cmd, SD_CMD_SEND_IF_COND,
 	/* We set the bit if the host supports voltages between 2.7 and 3.6 V */
-		((pdata->voltages & 0x00ff8000) != 0) << 8 | 0xaa,
+		((host->voltages & 0x00ff8000) != 0) << 8 | 0xaa,
 		MMC_RSP_R7);
 	err = mci_send_cmd(mci_dev, &cmd, NULL);
 	if (err) {
@@ -1095,13 +1095,13 @@ static int mci_check_if_already_initialized(struct device_d *mci_dev)
 static int mci_card_probe(struct device_d *mci_dev)
 {
 	struct mci *mci = GET_MCI_DATA(mci_dev);
-	struct mci_platformdata *pdata = GET_MCI_PDATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
 	struct device_d *disk_dev;
 	struct ata_interface *p;
 	int rc;
 
 	/* start with a host interface reset */
-	rc = (pdata->init)(pdata->hw_dev, mci_dev);
+	rc = (host->init)(host, mci_dev);
 	if (rc) {
 		pr_err("Cannot reset the SD/MMC interface\n");
 		return rc;
@@ -1176,7 +1176,7 @@ static int mci_card_probe(struct device_d *mci_dev)
 
 on_error:
 	if (rc != 0) {
-		pdata->clock = 0;	/* disable the MCI clock */
+		host->clock = 0;	/* disable the MCI clock */
 		mci_set_ios(mci_dev);
 	}
 
@@ -1295,14 +1295,14 @@ device_initcall(mci_init);
  * @param pdata MCI device's platform data for this MCI device
  * @return 0 on success
  */
-int mci_register(struct mci_platformdata *pdata)
+int mci_register(struct mci_host *host)
 {
 	struct device_d *mci_dev;
 
 	mci_dev = xzalloc(sizeof(struct device_d));
 
 	strcpy(mci_dev->name, mci_driver.name);
-	mci_dev->platform_data = (void*)pdata;
+	mci_dev->platform_data = (void*)host;
 
 	return register_device(mci_dev);
 }
diff --git a/include/mci.h b/include/mci.h
index b9d5c1c..1e758d3 100644
--- a/include/mci.h
+++ b/include/mci.h
@@ -189,7 +189,7 @@ struct mci_data {
 };
 
 /** host information */
-struct mci_platformdata {
+struct mci_host {
 	struct device_d *hw_dev;	/**< the host MCI hardware device */
 	unsigned voltages;
 	unsigned host_caps;	/**< Host's interface capabilities, refer MMC_VDD_* and FIXME */
@@ -198,9 +198,9 @@ struct mci_platformdata {
 	unsigned clock;		/**< Current clock used to talk to the card */
 	unsigned bus_width;	/**< used data bus width to the card */
 
-	int (*init)(struct device_d*, struct device_d*);	/**< init the host interface */
-	void (*set_ios)(struct device_d*, struct device_d*, unsigned, unsigned);	/**< change host interface settings */
-	int (*send_cmd)(struct device_d*, struct mci_cmd*, struct mci_data*);	/**< handle a command */
+	int (*init)(struct mci_host*, struct device_d*);	/**< init the host interface */
+	void (*set_ios)(struct mci_host*, struct device_d*, unsigned, unsigned);	/**< change host interface settings */
+	int (*send_cmd)(struct mci_host*, struct mci_cmd*, struct mci_data*);	/**< handle a command */
 };
 
 /** MMC/SD and interface instance information */
@@ -220,7 +220,7 @@ struct mci {
 	int ready_for_use;	/** true if already probed */
 };
 
-int mci_register(struct mci_platformdata*);
+int mci_register(struct mci_host*);
 
 #define GET_HOST_DATA(x) (x->priv)
 #define GET_HOST_PDATA(x) (x->platform_data)
-- 
1.7.2.3



From s.hauer at pengutronix.de  Thu Oct  7 11:37:50 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu,  7 Oct 2010 17:37:50 +0200
Subject: [PATCH 2/3] mci: Add i.MX27/31 driver
In-Reply-To: <1286465871-19953-1-git-send-email-s.hauer@pengutronix.de>
References: <1286465871-19953-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286465871-19953-3-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/Kconfig  |    7 +
 drivers/mci/Makefile |    1 +
 drivers/mci/imx.c    |  521 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 529 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/imx.c

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 644c0a3..0bc4254 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -41,4 +41,11 @@ config MCI_S3C
 	  Enable this entry to add support to read and write SD cards on a
 	  Samsung S3C24xx based system.
 
+config MCI_IMX
+	bool "i.MX"
+	depends on ARCH_IMX27 || ARCH_IMX31
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  Freescale i.MX based system.
+
 endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index be18446..f393e93 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_MCI)	+= mci-core.o
 obj-$(CONFIG_MCI_STM378X) += stm378x.o
 obj-$(CONFIG_MCI_S3C) += s3c.o
+obj-$(CONFIG_MCI_IMX) += imx.o
diff --git a/drivers/mci/imx.c b/drivers/mci/imx.c
new file mode 100644
index 0000000..91e1095
--- /dev/null
+++ b/drivers/mci/imx.c
@@ -0,0 +1,521 @@
+/*
+ *  This is a driver for the SDHC controller found in Freescale MX2/MX3
+ *  SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
+ *  Unlike the hardware found on MX1, this hardware just works and does
+ *  not need all the quirks found in imxmmc.c, hence the seperate driver.
+ *
+ *  Copyright (C) 2009 Ilya Yanok, <yanok at emcraft.com>
+ *  Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer at pengutronix.de>
+ *  Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa at pikron.com>
+ *
+ *  derived from pxamci.c by Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <mci.h>
+#include <malloc.h>
+#include <errno.h>
+#include <clock.h>
+#include <init.h>
+#include <driver.h>
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#define DRIVER_NAME "imx-mmc"
+
+struct mxcmci_regs {
+	u32 str_stp_clk;
+	u32 status;
+	u32 clk_rate;
+	u32 cmd_dat_cont;
+	u32 res_to;
+	u32 read_to;
+	u32 blk_len;
+	u32 nob;
+	u32 rev_no;
+	u32 int_cntr;
+	u32 cmd;
+	u32 arg;
+	u32 pad;
+	u32 res_fifo;
+	u32 buffer_access;
+};
+
+#define STR_STP_CLK_RESET               (1 << 3)
+#define STR_STP_CLK_START_CLK           (1 << 1)
+#define STR_STP_CLK_STOP_CLK            (1 << 0)
+
+#define STATUS_CARD_INSERTION		(1 << 31)
+#define STATUS_CARD_REMOVAL		(1 << 30)
+#define STATUS_YBUF_EMPTY		(1 << 29)
+#define STATUS_XBUF_EMPTY		(1 << 28)
+#define STATUS_YBUF_FULL		(1 << 27)
+#define STATUS_XBUF_FULL		(1 << 26)
+#define STATUS_BUF_UND_RUN		(1 << 25)
+#define STATUS_BUF_OVFL			(1 << 24)
+#define STATUS_SDIO_INT_ACTIVE		(1 << 14)
+#define STATUS_END_CMD_RESP		(1 << 13)
+#define STATUS_WRITE_OP_DONE		(1 << 12)
+#define STATUS_DATA_TRANS_DONE		(1 << 11)
+#define STATUS_READ_OP_DONE		(1 << 11)
+#define STATUS_WR_CRC_ERROR_CODE_MASK	(3 << 10)
+#define STATUS_CARD_BUS_CLK_RUN		(1 << 8)
+#define STATUS_BUF_READ_RDY		(1 << 7)
+#define STATUS_BUF_WRITE_RDY		(1 << 6)
+#define STATUS_RESP_CRC_ERR		(1 << 5)
+#define STATUS_CRC_READ_ERR		(1 << 3)
+#define STATUS_CRC_WRITE_ERR		(1 << 2)
+#define STATUS_TIME_OUT_RESP		(1 << 1)
+#define STATUS_TIME_OUT_READ		(1 << 0)
+#define STATUS_ERR_MASK			0x2f
+
+#define CMD_DAT_CONT_CMD_RESP_LONG_OFF	(1 << 12)
+#define CMD_DAT_CONT_STOP_READWAIT	(1 << 11)
+#define CMD_DAT_CONT_START_READWAIT	(1 << 10)
+#define CMD_DAT_CONT_BUS_WIDTH_4	(2 << 8)
+#define CMD_DAT_CONT_INIT		(1 << 7)
+#define CMD_DAT_CONT_WRITE		(1 << 4)
+#define CMD_DAT_CONT_DATA_ENABLE	(1 << 3)
+#define CMD_DAT_CONT_RESPONSE_48BIT_CRC	(1 << 0)
+#define CMD_DAT_CONT_RESPONSE_136BIT	(2 << 0)
+#define CMD_DAT_CONT_RESPONSE_48BIT	(3 << 0)
+
+#define INT_SDIO_INT_WKP_EN		(1 << 18)
+#define INT_CARD_INSERTION_WKP_EN	(1 << 17)
+#define INT_CARD_REMOVAL_WKP_EN		(1 << 16)
+#define INT_CARD_INSERTION_EN		(1 << 15)
+#define INT_CARD_REMOVAL_EN		(1 << 14)
+#define INT_SDIO_IRQ_EN			(1 << 13)
+#define INT_DAT0_EN			(1 << 12)
+#define INT_BUF_READ_EN			(1 << 4)
+#define INT_BUF_WRITE_EN		(1 << 3)
+#define INT_END_CMD_RES_EN		(1 << 2)
+#define INT_WRITE_OP_DONE_EN		(1 << 1)
+#define INT_READ_OP_EN			(1 << 0)
+
+struct mxcmci_host {
+	struct mci_host		mci;
+	struct mxcmci_regs	*base;
+	int			irq;
+	int			detect_irq;
+	int			dma;
+	int			do_dma;
+	unsigned int		power_mode;
+
+	struct mci_cmd		*cmd;
+	struct mci_data		*data;
+
+	unsigned int		dma_nents;
+	unsigned int		datasize;
+	unsigned int		dma_dir;
+
+	u16			rev_no;
+	unsigned int		cmdat;
+
+	int			clock;
+};
+
+#define to_mxcmci(mci)	container_of(mci, struct mxcmci_host, mci)
+
+static void mxcmci_softreset(struct mxcmci_host *host)
+{
+	int i;
+
+	/* reset sequence */
+	writew(STR_STP_CLK_RESET, &host->base->str_stp_clk);
+	writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
+			&host->base->str_stp_clk);
+
+	for (i = 0; i < 8; i++)
+		writew(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
+
+	writew(0xff, &host->base->res_to);
+}
+
+static void mxcmci_setup_data(struct mxcmci_host *host, struct mci_data *data)
+{
+	unsigned int nob = data->blocks;
+	unsigned int blksz = data->blocksize;
+	unsigned int datasize = nob * blksz;
+
+	host->data = data;
+
+	writew(nob, &host->base->nob);
+	writew(blksz, &host->base->blk_len);
+	host->datasize = datasize;
+}
+
+static int mxcmci_start_cmd(struct mxcmci_host *host, struct mci_cmd *cmd,
+		unsigned int cmdat)
+{
+	if (host->cmd != NULL)
+		printf("mxcmci: error!\n");
+	host->cmd = cmd;
+
+	switch (cmd->resp_type) {
+	case MMC_RSP_R1: /* short CRC, OPCODE */
+	case MMC_RSP_R1b:/* short CRC, OPCODE, BUSY */
+		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
+		break;
+	case MMC_RSP_R2: /* long 136 bit + CRC */
+		cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
+		break;
+	case MMC_RSP_R3: /* short */
+		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
+		break;
+	case MMC_RSP_NONE:
+		break;
+	default:
+		printf("mxcmci: unhandled response type 0x%x\n",
+				cmd->resp_type);
+		return -EINVAL;
+	}
+
+	writew(cmd->cmdidx, &host->base->cmd);
+	writel(cmd->cmdarg, &host->base->arg);
+	writew(cmdat, &host->base->cmd_dat_cont);
+
+	return 0;
+}
+
+static void mxcmci_finish_request(struct mxcmci_host *host,
+		struct mci_cmd *cmd, struct mci_data *data)
+{
+	host->cmd = NULL;
+	host->data = NULL;
+}
+
+static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
+{
+	int data_error = 0;
+
+	if (stat & STATUS_ERR_MASK) {
+		printf("request failed. status: 0x%08x\n",
+				stat);
+		if (stat & STATUS_CRC_READ_ERR) {
+			data_error = -EILSEQ;
+		} else if (stat & STATUS_CRC_WRITE_ERR) {
+			u32 err_code = (stat >> 9) & 0x3;
+			if (err_code == 2) /* No CRC response */
+				data_error = -ETIMEDOUT;
+			else
+				data_error = -EILSEQ;
+		} else if (stat & STATUS_TIME_OUT_READ) {
+			data_error = -ETIMEDOUT;
+		} else {
+			data_error = -EIO;
+		}
+	}
+
+	host->data = NULL;
+
+	return data_error;
+}
+
+static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
+{
+	struct mci_cmd *cmd = host->cmd;
+	int i;
+	u32 a, b, c;
+	u32 *resp = (u32 *)cmd->response;
+
+	if (!cmd)
+		return 0;
+
+	if (stat & STATUS_TIME_OUT_RESP) {
+		printf("CMD TIMEOUT\n");
+		return -ETIMEDOUT;
+	} else if (stat & STATUS_RESP_CRC_ERR && cmd->resp_type & MMC_RSP_CRC) {
+		printf("cmd crc error\n");
+		return -EILSEQ;
+	}
+
+	if (cmd->resp_type & MMC_RSP_PRESENT) {
+		if (cmd->resp_type & MMC_RSP_136) {
+			for (i = 0; i < 4; i++) {
+				a = readw(&host->base->res_fifo);
+				b = readw(&host->base->res_fifo);
+				resp[i] = a << 16 | b;
+			}
+		} else {
+			a = readw(&host->base->res_fifo);
+			b = readw(&host->base->res_fifo);
+			c = readw(&host->base->res_fifo);
+			resp[0] = a << 24 | b << 8 | c >> 8;
+		}
+	}
+	return 0;
+}
+
+static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
+{
+	u32 stat;
+	uint64_t start = get_time_ns();
+
+	do {
+		stat = readl(&host->base->status);
+		if (stat & STATUS_ERR_MASK)
+			return stat;
+		if (is_timeout(start, SECOND))
+			return STATUS_TIME_OUT_READ;
+		if (stat & mask)
+			return 0;
+	} while (1);
+}
+
+static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
+{
+	unsigned int stat;
+	u32 *buf = _buf;
+
+	while (bytes > 3) {
+		stat = mxcmci_poll_status(host,
+				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+		if (stat)
+			return stat;
+		*buf++ = readl(&host->base->buffer_access);
+		bytes -= 4;
+	}
+
+	if (bytes) {
+		u8 *b = (u8 *)buf;
+		u32 tmp;
+
+		stat = mxcmci_poll_status(host,
+				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+		if (stat)
+			return stat;
+		tmp = readl(&host->base->buffer_access);
+		memcpy(b, &tmp, bytes);
+	}
+
+	return 0;
+}
+
+static int mxcmci_push(struct mxcmci_host *host, const void *_buf, int bytes)
+{
+	unsigned int stat;
+	const u32 *buf = _buf;
+
+	while (bytes > 3) {
+		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+		if (stat)
+			return stat;
+		writel(*buf++, &host->base->buffer_access);
+		bytes -= 4;
+	}
+
+	if (bytes) {
+		const u8 *b = (u8 *)buf;
+		u32 tmp;
+
+		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+		if (stat)
+			return stat;
+
+		memcpy(&tmp, b, bytes);
+		writel(tmp, &host->base->buffer_access);
+	}
+
+	stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+	if (stat)
+		return stat;
+
+	return 0;
+}
+
+static int mxcmci_transfer_data(struct mxcmci_host *host)
+{
+	struct mci_data *data = host->data;
+	int stat;
+	unsigned long length;
+
+	length = data->blocks * data->blocksize;
+	host->datasize = 0;
+
+	if (data->flags & MMC_DATA_READ) {
+		stat = mxcmci_pull(host, data->dest, length);
+		if (stat)
+			return stat;
+		host->datasize += length;
+	} else {
+		stat = mxcmci_push(host, (const void *)(data->src), length);
+		if (stat)
+			return stat;
+		host->datasize += length;
+		stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
+		if (stat)
+			return stat;
+	}
+	return 0;
+}
+
+static int mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
+{
+	int datastat;
+	int ret;
+
+	ret = mxcmci_read_response(host, stat);
+
+	if (ret) {
+		mxcmci_finish_request(host, host->cmd, host->data);
+		return ret;
+	}
+
+	if (!host->data) {
+		mxcmci_finish_request(host, host->cmd, host->data);
+		return 0;
+	}
+
+	datastat = mxcmci_transfer_data(host);
+	ret = mxcmci_finish_data(host, datastat);
+	mxcmci_finish_request(host, host->cmd, host->data);
+	return ret;
+}
+
+static int mxcmci_request(struct mci_host *mci, struct mci_cmd *cmd,
+		struct mci_data *data)
+{
+	struct mxcmci_host *host = to_mxcmci(mci);
+	unsigned int cmdat = host->cmdat;
+	u32 stat;
+	int ret;
+
+	host->cmdat &= ~CMD_DAT_CONT_INIT;
+	if (data) {
+		mxcmci_setup_data(host, data);
+
+		cmdat |= CMD_DAT_CONT_DATA_ENABLE;
+
+		if (data->flags & MMC_DATA_WRITE)
+			cmdat |= CMD_DAT_CONT_WRITE;
+	}
+
+	if ((ret = mxcmci_start_cmd(host, cmd, cmdat))) {
+		mxcmci_finish_request(host, cmd, data);
+		return ret;
+	}
+
+	do {
+		stat = readl(&host->base->status);
+		writel(stat, &host->base->status);
+	} while (!(stat & STATUS_END_CMD_RESP));
+
+	return mxcmci_cmd_done(host, stat);
+}
+
+static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
+{
+	unsigned int divider;
+	int prescaler = 0;
+	unsigned long clk_in = imx_get_mmcclk();
+
+	while (prescaler <= 0x800) {
+		for (divider = 1; divider <= 0xF; divider++) {
+			int x;
+
+			x = (clk_in / (divider + 1));
+
+			if (prescaler)
+				x /= (prescaler * 2);
+
+			if (x <= clk_ios)
+				break;
+		}
+		if (divider < 0x10)
+			break;
+
+		if (prescaler == 0)
+			prescaler = 1;
+		else
+			prescaler <<= 1;
+	}
+
+	writew((prescaler << 4) | divider, &host->base->clk_rate);
+}
+
+static void mxcmci_set_ios(struct mci_host *mci, struct device_d *dev,
+		unsigned bus_width, unsigned clock)
+{
+	struct mxcmci_host *host = to_mxcmci(mci);
+
+	if (bus_width == 4)
+		host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
+	else
+		host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
+
+	if (clock) {
+		mxcmci_set_clk_rate(host, clock);
+		writew(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
+	} else {
+		writew(STR_STP_CLK_STOP_CLK, &host->base->str_stp_clk);
+	}
+
+	host->clock = clock;
+}
+
+static int mxcmci_init(struct mci_host *mci, struct device_d *dev)
+{
+	struct mxcmci_host *host = to_mxcmci(mci);
+
+	mxcmci_softreset(host);
+
+	host->rev_no = readw(&host->base->rev_no);
+	if (host->rev_no != 0x400) {
+		printf("wrong rev.no. 0x%08x. aborting.\n",
+			host->rev_no);
+		return -ENODEV;
+	}
+
+	/* recommended in data sheet */
+	writew(0x2db4, &host->base->read_to);
+
+	writel(0, &host->base->int_cntr);
+
+	return 0;
+}
+
+static int mxcmci_probe(struct device_d *dev)
+{
+	struct mxcmci_host *host;
+
+	host = xzalloc(sizeof(*host));
+
+//	sprintf(mci->name, "MXC MCI");
+	host->mci.send_cmd = mxcmci_request;
+	host->mci.set_ios = mxcmci_set_ios;
+	host->mci.init = mxcmci_init;
+	host->mci.host_caps = MMC_MODE_4BIT;
+
+	host->base = (struct mxcmci_regs *)dev->map_base;
+
+	host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	host->mci.f_min = imx_get_mmcclk() >> 7;
+	host->mci.f_max = imx_get_mmcclk() >> 1;
+
+	mci_register(&host->mci);
+
+	return 0;
+}
+
+static struct driver_d mxcmci_driver = {
+        .name  = DRIVER_NAME,
+        .probe = mxcmci_probe,
+};
+
+static int mxcmci_init_driver(void)
+{
+        register_driver(&mxcmci_driver);
+        return 0;
+}
+
+device_initcall(mxcmci_init_driver);
+
-- 
1.7.2.3



From jbe at pengutronix.de  Thu Oct  7 12:00:06 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu, 7 Oct 2010 18:00:06 +0200
Subject: [PATCH 5/7] Add MCI card support to barebox
In-Reply-To: <20101007153713.GH28242@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
	<1286457858-29771-6-git-send-email-jbe@pengutronix.de>
	<20101007153713.GH28242@pengutronix.de>
Message-ID: <201010071800.06450.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Thu, Oct 07, 2010 at 03:24:16PM +0200, Juergen Beisert wrote:
> > This adds the basic framework to handle MCI cards in barebox.
> >
> > Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> > ---
> >  drivers/Kconfig        |    1 +
> >  drivers/Makefile       |    1 +
> >  drivers/mci/Kconfig    |   30 ++
> >  drivers/mci/Makefile   |    1 +
> >  drivers/mci/mci-core.c | 1308
> > ++++++++++++++++++++++++++++++++++++++++++++++++ include/mci.h          |
> >  230 +++++++++
> >  6 files changed, 1571 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/mci/Kconfig
> >  create mode 100644 drivers/mci/Makefile
> >  create mode 100644 drivers/mci/mci-core.c
> >  create mode 100644 include/mci.h
>
> This whole patch looks quite good.
> Please add some linebreaks in mci-core.c. I don't want strict 80
> character lines, but some lines are really long.
>
> [snip]
>
> > +static int mci_probe(struct device_d *mci_dev)
> > +{
> > +	struct mci *mci;
> > +	int rc;
> > +
> > +	mci = xzalloc(sizeof(struct mci));
> > +	mci_dev->priv = mci;
> > +
> > +#ifdef CONFIG_MCI_STARTUP
> > +	/* if enabled, probe the attached card immediately */
> > +	rc = mci_card_probe(mci_dev);
> > +	if (rc == -ENODEV) {
> > +		/*
> > +		 * If it fails, add the 'probe' parameter to give the user
> > +		 * a chance to insert a card and try again. Note: This may fail
> > +		 * systems that rely on the MCI card for startup (for the
> > +		 * persistant environment for example)
> > +		 */
> > +		rc = add_mci_parameter(mci_dev);
> > +		if (rc != 0) {
> > +			pr_err("Failed to add 'probe' parameter to the MCI device\n");
> > +			goto on_error;
> > +		}
> > +	}
> > +#endif
> > +
> > +#ifndef CONFIG_MCI_STARTUP
>
> #else instead?
>
> > +	/* add params on demand */
> > +	rc = add_mci_parameter(mci_dev);
> > +	if (rc != 0) {
> > +		pr_err("Failed to add 'probe' parameter to the MCI device\n");
> > +		goto on_error;
> > +	}
> > +#endif
> > +
> > +	return rc;
> > +
> > +on_error:
> > +	free(mci);
> > +	return rc;
> > +}
> > +
>
> [snip]
>
> > +
> > +/** host information */
> > +struct mci_platformdata {
> > +	struct device_d *hw_dev;	/**< the host MCI hardware device */
> > +	unsigned voltages;
> > +	unsigned host_caps;	/**< Host's interface capabilities, refer MMC_VDD_*
> > and FIXME */ +	unsigned f_min;		/**< host interface lower limit */
> > +	unsigned f_max;		/**< host interface upper limit */
> > +	unsigned clock;		/**< Current clock used to talk to the card */
> > +	unsigned bus_width;	/**< used data bus width to the card */
> > +
> > +	int (*init)(struct device_d*, struct device_d*);	/**< init the host
> > interface */ +	void (*set_ios)(struct device_d*, struct device_d*,
> > unsigned, unsigned);	/**< change host interface settings */ +	int
> > (*send_cmd)(struct device_d*, struct mci_cmd*, struct mci_data*);	/**<
> > handle a command */ +};
>
> I prefer this struct named mci_host, this seems to match better what it
> actually is.

Hmm, no, its not a "host". It is the MMC/SD card instance. The host is more 
the interface, isn't it (at least for me)?

> For the convenience of drivers set init/set_ios/send_cmd 
> functions should be passed a pointer to the mci_host, not the device,
> because that's what they actually registered. I already prepared a patch
> for this, I'll send it in a seperate mail.

I tried to layering the devices:

 disk_device -> knows how to handle disk drives and partition tables
    |
 mci_device -> knows how to probe and manage MMC/SD cards
    |
 hw_device -> knows how to transfer data

Most functions in the hw_device layer do not need access to any other 
structure data than their own device (okay, there is a exception). So, I 
tried to keep it simple.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From plagnioj at jcrosoft.com  Thu Oct  7 12:37:34 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu,  7 Oct 2010 18:37:34 +0200
Subject: [PATCH 1/5] defaultenv: introduce CONFIG_DEFAULT_ENVIRONMENT_GENERIC
	to enable it
Message-ID: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>

this will we usefull to enable functionnality if used

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 arch/arm/configs/neso_defconfig   |    3 ++-
 arch/arm/configs/pca100_defconfig |    3 ++-
 arch/arm/configs/pcm037_defconfig |    3 ++-
 arch/arm/configs/pcm038_defconfig |    3 ++-
 arch/arm/configs/pcm043_defconfig |    3 ++-
 common/Kconfig                    |    7 +++++++
 common/Makefile                   |    4 ++++
 7 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/arch/arm/configs/neso_defconfig b/arch/arm/configs/neso_defconfig
index 9f6e3f4..24125f9 100644
--- a/arch/arm/configs/neso_defconfig
+++ b/arch/arm/configs/neso_defconfig
@@ -12,7 +12,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/guf-neso/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/guf-neso/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/arch/arm/configs/pca100_defconfig b/arch/arm/configs/pca100_defconfig
index d1708a6..8c72bdf 100644
--- a/arch/arm/configs/pca100_defconfig
+++ b/arch/arm/configs/pca100_defconfig
@@ -12,7 +12,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/phycard-i.MX27/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/phycard-i.MX27/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig
index 8e60b0a..e12f690 100644
--- a/arch/arm/configs/pcm037_defconfig
+++ b/arch/arm/configs/pcm037_defconfig
@@ -10,7 +10,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/pcm037/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm037/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/arch/arm/configs/pcm038_defconfig b/arch/arm/configs/pcm038_defconfig
index eacbbc6..2038f14 100644
--- a/arch/arm/configs/pcm038_defconfig
+++ b/arch/arm/configs/pcm038_defconfig
@@ -13,7 +13,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/pcm038/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm038/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/arch/arm/configs/pcm043_defconfig b/arch/arm/configs/pcm043_defconfig
index 51ca833..2dd711b 100644
--- a/arch/arm/configs/pcm043_defconfig
+++ b/arch/arm/configs/pcm043_defconfig
@@ -13,7 +13,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/pcm043/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm043/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/common/Kconfig b/common/Kconfig
index ad70cde..485133e 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -382,6 +382,13 @@ config DEFAULT_ENVIRONMENT
 	  Enabling this option will give you a default environment when
 	  the environment found in the environment sector is invalid
 
+config DEFAULT_ENVIRONMENT_GENERIC
+	bool
+	depends on DEFAULT_ENVIRONMENT
+	prompt "Default environment generic"
+	help
+	  Generic barebox default env
+
 config DEFAULT_ENVIRONMENT_PATH
 	string
 	depends on DEFAULT_ENVIRONMENT
diff --git a/common/Makefile b/common/Makefile
index e56dbc2..b42ab7a 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -26,6 +26,10 @@ ifdef CONFIG_DEFAULT_ENVIRONMENT
 $(obj)/startup.o: include/generated/barebox_default_env.h
 $(obj)/env.o: include/generated/barebox_default_env.h
 
+ifeq ($(CONFIG_DEFAULT_ENVIRONMENT_GENERIC),y)
+CONFIG_DEFAULT_ENVIRONMENT_PATH += defaultenv
+endif
+
 ENV_FILES := $(shell cd $(srctree); for i in $(CONFIG_DEFAULT_ENVIRONMENT_PATH); do find $${i} -type f -exec readlink -f {} \;; done)
 
 endif # ifdef CONFIG_DEFAULT_ENVIRONMENT
-- 
1.7.1



From plagnioj at jcrosoft.com  Thu Oct  7 12:37:35 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu,  7 Oct 2010 18:37:35 +0200
Subject: [PATCH 2/5] commands/crc32: add compare 2 files crc
In-Reply-To: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
References: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <1286469458-11362-2-git-send-email-plagnioj@jcrosoft.com>

add -F options to compare to file crc

it's usefull to compare what you flash in a partition

it's selectable by CONFIG_CMD_CRC_CMP

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 commands/Kconfig |    5 ++
 commands/crc.c   |  111 ++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 79 insertions(+), 37 deletions(-)

diff --git a/commands/Kconfig b/commands/Kconfig
index 0fc80aa..5416073 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -202,6 +202,11 @@ config CMD_CRC
 	select CRC32
 	prompt "crc"
 
+config CMD_CRC_CMP
+	tristate
+	depends on CMD_CRC
+	prompt "compare 2 files crc"
+
 config CMD_MTEST
 	tristate
 	prompt "mtest"
diff --git a/commands/crc.c b/commands/crc.c
index 4842cdc..d3e0865 100644
--- a/commands/crc.c
+++ b/commands/crc.c
@@ -30,20 +30,80 @@
 #include <malloc.h>
 #include <linux/ctype.h>
 
+static int file_crc(char* filename, ulong start, ulong size, ulong *crc,
+		    ulong *total)
+{
+	int fd, now;
+	int ret = 0;
+	char *buf;
+
+	*total = 0;
+	*crc = 0;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		printf("open %s: %s\n", filename, errno_str());
+		return fd;
+	}
+
+	if (start > 0) {
+		ret = lseek(fd, start, SEEK_SET);
+		if (ret == -1) {
+			perror("lseek");
+			goto out;
+		}
+	}
+
+	buf = xmalloc(4096);
+
+	while (size) {
+		now = min((ulong)4096, size);
+		now = read(fd, buf, now);
+		if (now < 0) {
+			ret = now;
+			perror("read");
+			goto out_free;
+		}
+		if (!now)
+			break;
+		*crc = crc32(*crc, buf, now);
+		size -= now;
+		*total += now;
+	}
+
+	printf ("CRC32 for %s 0x%08lx ... 0x%08lx ==> 0x%08lx",
+			filename, start, start + *total - 1, *crc);
+
+out_free:
+	free(buf);
+out:
+	close(fd);
+
+	return ret;
+}
+
 static int do_crc(struct command *cmdtp, int argc, char *argv[])
 {
 	ulong start = 0, size = ~0, total = 0;
 	ulong crc = 0, vcrc = 0;
 	char *filename = "/dev/mem";
-	char *buf;
-	int fd, opt, err = 0, filegiven = 0, verify = 0, now;
+#ifdef CONFIG_CMD_CRC_CMP
+	char *vfilename = NULL;
+#endif
+	int opt, err = 0, filegiven = 0, verify = 0;
 
-	while((opt = getopt(argc, argv, "f:v:")) > 0) {
+	while((opt = getopt(argc, argv, "f:F:v:")) > 0) {
 		switch(opt) {
 		case 'f':
 			filename = optarg;
 			filegiven = 1;
 			break;
+#ifdef CONFIG_CMD_CRC_CMP
+		case 'F':
+			verify = 1;
+			vfilename = optarg;
+			break;
+#endif
 		case 'v':
 			verify = 1;
 			vcrc = simple_strtoul(optarg, NULL, 0);
@@ -61,38 +121,17 @@ static int do_crc(struct command *cmdtp, int argc, char *argv[])
 		}
 	}
 
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		printf("open %s: %s\n", filename, errno_str());
+	if (file_crc(filename, start, size, &crc, &total) < 0)
 		return 1;
-	}
 
-	if (start > 0) {
-		if (lseek(fd, start, SEEK_SET) == -1) {
-			perror("lseek");
-			err = 1;
-			goto out;
-		}
-	}
-
-	buf = xmalloc(4096);
-
-	while (size) {
-		now = min((ulong)4096, size);
-		now = read(fd, buf, now);
-		if (now < 0) {
-			perror("read");
-			goto out_free;
-		}
-		if (!now)
-			break;
-		crc = crc32(crc, buf, now);
-		size -= now;
-		total += now;
+#ifdef CONFIG_CMD_CRC_CMP
+	if (vfilename) {
+		size = total;
+		puts("\n");
+		if (file_crc(vfilename, start, size, &vcrc, &total) < 0)
+			return 1;
 	}
-
-	printf ("CRC32 for %s 0x%08lx ... 0x%08lx ==> 0x%08lx",
-			filename, start, start + total - 1, crc);
+#endif
 
 	if (verify && crc != vcrc) {
 		printf(" != 0x%08x ** ERROR **", vcrc);
@@ -101,11 +140,6 @@ static int do_crc(struct command *cmdtp, int argc, char *argv[])
 
 	printf("\n");
 
-out_free:
-	free(buf);
-out:
-	close(fd);
-
 	return err;
 }
 
@@ -114,6 +148,9 @@ static const __maybe_unused char cmd_crc_help[] =
 "Calculate a crc32 checksum of a memory area\n"
 "Options:\n"
 "  -f <file>   Use file instead of memory\n"
+#ifdef CONFIG_CMD_CRC_CMP
+"  -F <file>   Use file to compare\n"
+#endif
 "  -v <crc>    Verfify\n";
 
 BAREBOX_CMD_START(crc32)
-- 
1.7.1



From plagnioj at jcrosoft.com  Thu Oct  7 12:37:36 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu,  7 Oct 2010 18:37:36 +0200
Subject: [PATCH 3/5] defaultenv: add xmodem support for update
In-Reply-To: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
References: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <1286469458-11362-3-git-send-email-plagnioj@jcrosoft.com>

this is add as last parameter to do not change the default behavior

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 defaultenv/bin/_update       |   26 +++++++++++++++++---------
 defaultenv/bin/init          |    5 +++--
 defaultenv/bin/update_kernel |    7 ++++++-
 defaultenv/bin/update_rootfs |    7 ++++++-
 4 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/defaultenv/bin/_update b/defaultenv/bin/_update
index ddd6b84..c60ff88 100644
--- a/defaultenv/bin/_update
+++ b/defaultenv/bin/_update
@@ -14,14 +14,16 @@ if [ $# = 1 ]; then
 	image=$1
 fi
 
-if [ x$ip = xdhcp ]; then
-	dhcp
-fi
-
-ping $eth0.serverip
-if [ $? -ne 0 ] ; then
-	echo "Server did not reply! Update aborted."
-	exit 1
+if [ x$mode = xnet ]; then
+	if [ x$ip = xdhcp ]; then
+		dhcp
+	fi
+
+	ping $eth0.serverip
+	if [ $? -ne 0 ] ; then
+		echo "Server did not reply! Update aborted."
+		exit 1
+	fi
 fi
 
 unprotect $part
@@ -34,6 +36,12 @@ erase $part
 echo
 echo "flashing $image to $part"
 echo
-tftp $image $part
+
+if [ x$mode = xnet ]; then
+	tftp $image $part
+else
+	loadb -f $image -c
+	cp $image $part
+fi
 
 protect $part
diff --git a/defaultenv/bin/init b/defaultenv/bin/init
index a55e8e6..db2b525 100644
--- a/defaultenv/bin/init
+++ b/defaultenv/bin/init
@@ -25,8 +25,9 @@ echo -n "Hit any key to stop autoboot: "
 timeout -a $autoboot_timeout
 if [ $? != 0 ]; then
 	echo
-	echo "type update_kernel nand|nor [<imagename>] to update kernel into flash"
-	echo "type update_rootfs nand|nor [<imagename>] to update rootfs into flash"
+	echo "default mode is net"
+	echo "type update_kernel nand|nor [<imagename>] [net|xmodem] to update kernel into flash"
+	echo "type update_rootfs nand|nor [<imagename>] [net|xmodem] to update rootfs into flash"
 	echo
 	exit
 fi
diff --git a/defaultenv/bin/update_kernel b/defaultenv/bin/update_kernel
index 1d35ed9..b29927f 100644
--- a/defaultenv/bin/update_kernel
+++ b/defaultenv/bin/update_kernel
@@ -2,14 +2,19 @@
 
 . /env/config
 image=$kernelimage
+mode=net
 
 if [ x$1 = xnand ]; then
 	part=/dev/nand0.kernel.bb
 elif [ x$1 = xnor ]; then
 	part=/dev/nor0.kernel
 else
-	echo "usage: $0 nor|nand [imagename]"
+	echo "usage: $0 nor|nand [imagename] [net|xmodem]"
 	exit 1
 fi
 
+if [ x$3 != x ]; then
+	mode=$3
+fi
+
 . /env/bin/_update $2
diff --git a/defaultenv/bin/update_rootfs b/defaultenv/bin/update_rootfs
index 6366315..bac74ca 100644
--- a/defaultenv/bin/update_rootfs
+++ b/defaultenv/bin/update_rootfs
@@ -3,14 +3,19 @@
 . /env/config
 
 image=$rootfsimage
+mode=net
 
 if [ x$1 = xnand ]; then
 	part=/dev/nand0.root.bb
 elif [ x$1 = xnor ]; then
 	part=/dev/nor0.root
 else
-	echo "usage: $0 nor|nand [imagename]"
+	echo "usage: $0 nor|nand [imagename] [net|xmodem]"
 	exit 1
 fi
 
+if [ x$3 != x ]; then
+	mode=$3
+fi
+
 . /env/bin/_update $2
-- 
1.7.1



From plagnioj at jcrosoft.com  Thu Oct  7 12:37:37 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu,  7 Oct 2010 18:37:37 +0200
Subject: [PATCH 4/5] defaultenv: add update_barebox to update barebox easly
	for tftp or xmodem
In-Reply-To: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
References: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <1286469458-11362-4-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 commands/Kconfig              |    1 +
 defaultenv/bin/init           |    1 +
 defaultenv/bin/update_barebox |   21 +++++++++++++++++++++
 3 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 defaultenv/bin/update_barebox

diff --git a/commands/Kconfig b/commands/Kconfig
index 5416073..151758b 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -204,6 +204,7 @@ config CMD_CRC
 
 config CMD_CRC_CMP
 	tristate
+	default y if DEFAULT_ENVIRONMENT_GENERIC
 	depends on CMD_CRC
 	prompt "compare 2 files crc"
 
diff --git a/defaultenv/bin/init b/defaultenv/bin/init
index db2b525..18a0c95 100644
--- a/defaultenv/bin/init
+++ b/defaultenv/bin/init
@@ -28,6 +28,7 @@ if [ $? != 0 ]; then
 	echo "default mode is net"
 	echo "type update_kernel nand|nor [<imagename>] [net|xmodem] to update kernel into flash"
 	echo "type update_rootfs nand|nor [<imagename>] [net|xmodem] to update rootfs into flash"
+	echo "type update_barebox nand|nor [<imagename>] [net|xmodem] to update barebox into flash"
 	echo
 	exit
 fi
diff --git a/defaultenv/bin/update_barebox b/defaultenv/bin/update_barebox
new file mode 100644
index 0000000..2f3b1d9
--- /dev/null
+++ b/defaultenv/bin/update_barebox
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+. /env/config
+image=barebox.bin
+mode=net
+
+if [ x$1 = xnand ]; then
+	part=/dev/nand0.barebox.bb
+elif [ x$1 = xnor ]; then
+	part=/dev/nor0.barebox
+else
+	echo "usage: $0 nor|nand [imagename] [net|xmodem]"
+	exit 1
+fi
+
+if [ x$3 != x ]; then
+	mode=$3
+fi
+
+. /env/bin/_update $2
+crc32 -f $image -F $part
-- 
1.7.1



From plagnioj at jcrosoft.com  Thu Oct  7 12:37:38 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu,  7 Oct 2010 18:37:38 +0200
Subject: [PATCH 5/5] nhk8815: use defaultenv
In-Reply-To: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
References: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <1286469458-11362-5-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 arch/arm/boards/nhk8815/env/bin/_update            |   36 ----------------
 arch/arm/boards/nhk8815/env/bin/boot               |   38 -----------------
 arch/arm/boards/nhk8815/env/bin/init               |   28 ------------
 .../boards/nhk8815/env/bin/update_barebox_xmodem   |   19 --------
 arch/arm/boards/nhk8815/env/bin/update_kernel      |    8 ----
 arch/arm/boards/nhk8815/env/bin/update_root        |    8 ----
 arch/arm/boards/nhk8815/env/config                 |   44 +++++++++++++------
 arch/arm/configs/nhk8815_defconfig                 |    1 +
 8 files changed, 31 insertions(+), 151 deletions(-)
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/_update
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/boot
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/init
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_kernel
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_root

diff --git a/arch/arm/boards/nhk8815/env/bin/_update b/arch/arm/boards/nhk8815/env/bin/_update
deleted file mode 100644
index fb7cbe8..0000000
--- a/arch/arm/boards/nhk8815/env/bin/_update
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-
-if [ -z "$part" -o -z "$image" ]; then
-	echo "define \$part and \$image"
-	exit 1
-fi
-
-if [ \! -e "$part" ]; then
-	echo "Partition $part does not exist"
-	exit 1
-fi
-
-if [ $# = 1 ]; then
-	image=$1
-fi
-
-if [ x$ip = xdhcp ]; then
-	dhcp
-fi
-
-ping $eth0.serverip
-if [ $? -ne 0 ] ; then
-	echo "update aborted"
-	exit 1
-fi
-
-unprotect $part
-
-echo
-echo "erasing partition $part"
-erase $part
-
-echo
-echo "flashing $image to $part"
-echo
-tftp $image $part
diff --git a/arch/arm/boards/nhk8815/env/bin/boot b/arch/arm/boards/nhk8815/env/bin/boot
deleted file mode 100644
index fd8d957..0000000
--- a/arch/arm/boards/nhk8815/env/bin/boot
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-if [ x$1 = xflash ]; then
-	root=flash
-	kernel=flash
-fi
-
-if [ x$1 = xnet ]; then
-	root=net
-	kernel=net
-fi
-
-if [ x$ip = xdhcp ]; then
-	bootargs="$bootargs ip=dhcp"
-else
-	bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::"
-fi
-
-if [ x$root = xflash ]; then
-	bootargs="$bootargs root=$rootpart rootfstype=jffs2"
-else
-	bootargs="$bootargs root=/dev/nfs nfsroot=192.168.23.111:$nfsroot"
-fi
-
-bootargs="$bootargs"
-
-if [ $kernel = net ]; then
-	if [ x$ip = xdhcp ]; then
-		dhcp
-	fi
-	tftp $uimage uImage
-	bootm uImage
-else
-	bootm /dev/nor0.kernel
-fi
-
diff --git a/arch/arm/boards/nhk8815/env/bin/init b/arch/arm/boards/nhk8815/env/bin/init
deleted file mode 100644
index 5b45a70..0000000
--- a/arch/arm/boards/nhk8815/env/bin/init
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-PATH=/env/bin
-export PATH
-
-. /env/config
-
-if [ -e /dev/nand0 ]; then
-	addpart /dev/nand0 $nand_parts
-
-	# Uh, oh, hush first expands wildcards and then starts executing
-	# commands. What a bug!
-	source /env/bin/hush_hack
-fi
-
-echo
-echo -n "Hit any key to stop autoboot: "
-timeout -a $autoboot_timeout
-if [ $? != 0 ]; then
-	echo
-	echo "type update_kernel [<imagename>] to update kernel into flash"
-	echo "type udate_root [<imagename>] to update rootfs into flash"
-	echo "type update_barebox_xmodem nor to update barebox into flash"
-	echo
-	exit
-fi
-
-boot
diff --git a/arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem b/arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem
deleted file mode 100644
index 40f4ad3..0000000
--- a/arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-part=/dev/nand0.barebox
-
-loadb -f barebox.bin -c
-
-unprotect $part
-echo
-echo "erasing partition $part"
-erase $part
-
-echo
-echo "flashing barebox.bin to $part"
-echo
-cp barebox.bin $part
-crc32 -f barebox.bin
-crc32 -f $part
diff --git a/arch/arm/boards/nhk8815/env/bin/update_kernel b/arch/arm/boards/nhk8815/env/bin/update_kernel
deleted file mode 100644
index db0f4c2..0000000
--- a/arch/arm/boards/nhk8815/env/bin/update_kernel
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-image=$uimage
-part=/dev/nand0.kernel
-
-. /env/bin/_update $1
diff --git a/arch/arm/boards/nhk8815/env/bin/update_root b/arch/arm/boards/nhk8815/env/bin/update_root
deleted file mode 100644
index 9530e84..0000000
--- a/arch/arm/boards/nhk8815/env/bin/update_root
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-image=$jffs2
-part=/dev/nand0.rootfs
-
-. /env/bin/_update $1
diff --git a/arch/arm/boards/nhk8815/env/config b/arch/arm/boards/nhk8815/env/config
index 7e7fc45..e657a76 100644
--- a/arch/arm/boards/nhk8815/env/config
+++ b/arch/arm/boards/nhk8815/env/config
@@ -1,16 +1,33 @@
 #!/bin/sh
 
-# can be either 'net' or 'flash'
-kernel=net
-root=net
-
-# use 'dhcp' todo dhcp in uboot and in kernel
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
 ip=dhcp
 
-#
-# setup default ethernet address
-#
-#eth0.serverip=192.168.23.108
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.netmask=a.b.c.d
+#eth0.gateway=a.b.c.d
+#eth0.serverip=a.b.c.d
+
+# can be either 'net' or 'nand'
+kernel_loc=net
+# can be either 'net', 'nand' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+#kernelimage_type=zimage
+#kernelimage=zImage
+kernelimage_type=uimage
+kernelimage=uImage
+#kernelimage_type=raw
+#kernelimage=Image
+#kernelimage_type=raw_lzo
+#kernelimage=Image.lzo
 
 # Partition			Size	Start
 # XloaderTOC + X-Loader		256KB	0x00000000
@@ -22,11 +39,10 @@ ip=dhcp
 
 nand_parts="256k(xloader)ro,256k(meminit),2M(barebox),3M(kernel),22M(rootfs),100M(userfs),384k(free),128k(bareboxenv)"
 
-uimage=uImage-nhk15
-
-# use 'dhcp' to do dhcp in uboot and in kernel
-ip=dhcp
-
 autoboot_timeout=3
 
 bootargs="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc"
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m "
+
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index e3f4102..5e03d05 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -10,6 +10,7 @@ CONFIG_AUTO_COMPLETE=y
 CONFIG_MENU=y
 CONFIG_PASSWD_SUM_SHA1=y
 CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
 CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/nhk8815/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
-- 
1.7.1



From plagnioj at jcrosoft.com  Thu Oct  7 12:38:49 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu,  7 Oct 2010 18:38:49 +0200
Subject: [PATCH] MAKEALL: allow CROSS_COMPILE*=""
Message-ID: <1286469529-11579-1-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 MAKEALL |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/MAKEALL b/MAKEALL
index 9353cd8..e987de2 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -97,10 +97,12 @@ do_build_target() {
 	printf "Building ${arch} ${target} \n" >&2 | tee -a "${log_report}"
 
 	cross_compile=`eval echo '$CROSS_COMPILE_'${target}`
-	if [ ! "${cross_compile}" ]
+	cross_compile_set=`eval echo '${CROSS_COMPILE_'${target}'+set}'`
+	if [ "${cross_compile_set}" = "" ]
 	then
 		cross_compile=`eval echo '$CROSS_COMPILE_'${arch}`
-		if [ ! "${cross_compile}" ]
+		cross_compile_set=`eval echo '${CROSS_COMPILE_'${arch}'+set}'`
+		if [ "${cross_compile_set}" = "" ]
 		then
 			cross_compile=${CROSS_COMPILE}
 		fi
@@ -237,7 +239,7 @@ fi
 
 [ -d "${LOGDIR}" ] || mkdir ${LOGDIR} || exit 1
 
-if [ ! "${CONFIG}" ] && [ ! "${CROSS_COMPILE}" ]
+if [ ! "${CONFIG}" ] && [ ! "${CROSS_COMPILE+set}" ]
 then
 	echo "You need to specify a CONFIG or a CROSS_COMPILE"
 	usage
-- 
1.7.1



From s.hauer at pengutronix.de  Thu Oct  7 12:59:59 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 Oct 2010 18:59:59 +0200
Subject: [PATCH 5/7] Add MCI card support to barebox
In-Reply-To: <201010071800.06450.jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
	<1286457858-29771-6-git-send-email-jbe@pengutronix.de>
	<20101007153713.GH28242@pengutronix.de>
	<201010071800.06450.jbe@pengutronix.de>
Message-ID: <20101007165959.GJ28242@pengutronix.de>

On Thu, Oct 07, 2010 at 06:00:06PM +0200, Juergen Beisert wrote:
> Sascha Hauer wrote:
> > On Thu, Oct 07, 2010 at 03:24:16PM +0200, Juergen Beisert wrote:
> > > This adds the basic framework to handle MCI cards in barebox.
> > >
> > > Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> > > ---
> > >  drivers/Kconfig        |    1 +
> > >  drivers/Makefile       |    1 +
> > >  drivers/mci/Kconfig    |   30 ++
> > >  drivers/mci/Makefile   |    1 +
> > >  drivers/mci/mci-core.c | 1308
> > > ++++++++++++++++++++++++++++++++++++++++++++++++ include/mci.h          |
> > >  230 +++++++++
> > >  6 files changed, 1571 insertions(+), 0 deletions(-)
> > >  create mode 100644 drivers/mci/Kconfig
> > >  create mode 100644 drivers/mci/Makefile
> > >  create mode 100644 drivers/mci/mci-core.c
> > >  create mode 100644 include/mci.h
> >
> > This whole patch looks quite good.
> > Please add some linebreaks in mci-core.c. I don't want strict 80
> > character lines, but some lines are really long.
> >
> > [snip]
> >
> > > +static int mci_probe(struct device_d *mci_dev)
> > > +{
> > > +	struct mci *mci;
> > > +	int rc;
> > > +
> > > +	mci = xzalloc(sizeof(struct mci));
> > > +	mci_dev->priv = mci;
> > > +
> > > +#ifdef CONFIG_MCI_STARTUP
> > > +	/* if enabled, probe the attached card immediately */
> > > +	rc = mci_card_probe(mci_dev);
> > > +	if (rc == -ENODEV) {
> > > +		/*
> > > +		 * If it fails, add the 'probe' parameter to give the user
> > > +		 * a chance to insert a card and try again. Note: This may fail
> > > +		 * systems that rely on the MCI card for startup (for the
> > > +		 * persistant environment for example)
> > > +		 */
> > > +		rc = add_mci_parameter(mci_dev);
> > > +		if (rc != 0) {
> > > +			pr_err("Failed to add 'probe' parameter to the MCI device\n");
> > > +			goto on_error;
> > > +		}
> > > +	}
> > > +#endif
> > > +
> > > +#ifndef CONFIG_MCI_STARTUP
> >
> > #else instead?
> >
> > > +	/* add params on demand */
> > > +	rc = add_mci_parameter(mci_dev);
> > > +	if (rc != 0) {
> > > +		pr_err("Failed to add 'probe' parameter to the MCI device\n");
> > > +		goto on_error;
> > > +	}
> > > +#endif
> > > +
> > > +	return rc;
> > > +
> > > +on_error:
> > > +	free(mci);
> > > +	return rc;
> > > +}
> > > +
> >
> > [snip]
> >
> > > +
> > > +/** host information */
> > > +struct mci_platformdata {
> > > +	struct device_d *hw_dev;	/**< the host MCI hardware device */
> > > +	unsigned voltages;
> > > +	unsigned host_caps;	/**< Host's interface capabilities, refer MMC_VDD_*
> > > and FIXME */ +	unsigned f_min;		/**< host interface lower limit */
> > > +	unsigned f_max;		/**< host interface upper limit */
> > > +	unsigned clock;		/**< Current clock used to talk to the card */
> > > +	unsigned bus_width;	/**< used data bus width to the card */
> > > +
> > > +	int (*init)(struct device_d*, struct device_d*);	/**< init the host
> > > interface */ +	void (*set_ios)(struct device_d*, struct device_d*,
> > > unsigned, unsigned);	/**< change host interface settings */ +	int
> > > (*send_cmd)(struct device_d*, struct mci_cmd*, struct mci_data*);	/**<
> > > handle a command */ +};
> >
> > I prefer this struct named mci_host, this seems to match better what it
> > actually is.
> 
> Hmm, no, its not a "host". It is the MMC/SD card instance. The host is more 
> the interface, isn't it (at least for me)?

It's a host at least in the Linux terminology.

> 
> > For the convenience of drivers set init/set_ios/send_cmd 
> > functions should be passed a pointer to the mci_host, not the device,
> > because that's what they actually registered. I already prepared a patch
> > for this, I'll send it in a seperate mail.
> 
> I tried to layering the devices:
> 
>  disk_device -> knows how to handle disk drives and partition tables
>     |
>  mci_device -> knows how to probe and manage MMC/SD cards
>     |
>  hw_device -> knows how to transfer data
> 
> Most functions in the hw_device layer do not need access to any other 
> structure data than their own device (okay, there is a exception). So, I 
> tried to keep it simple.

I didn't change the underlying structure, only the pointer which is
passed to the functions.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Thu Oct  7 13:10:03 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 Oct 2010 19:10:03 +0200
Subject: [PATCH 7/7] Add S3C2440 MCI card support
In-Reply-To: <1286457858-29771-8-git-send-email-jbe@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
	<1286457858-29771-8-git-send-email-jbe@pengutronix.de>
Message-ID: <20101007171003.GK28242@pengutronix.de>

On Thu, Oct 07, 2010 at 03:24:18PM +0200, Juergen Beisert wrote:
> From: Juergen Beisert <juergen at kreuzholzen.de>
> 
> Adding MCI card support for S3C2440 CPUs. This is for reference only, as there
> is currently no user in the barebox tree. Maybe one with access to the A9M2440
> development kit can check it on his/her system.
> Checked here with my own S3C2440 based system which is not in the barebox tree.
> 
> Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
> ---
>  arch/arm/mach-s3c24xx/include/mach/mci.h |   46 ++
>  drivers/mci/Kconfig                      |    7 +
>  drivers/mci/Makefile                     |    1 +
>  drivers/mci/s3c.c                        |  801 ++++++++++++++++++++++++++++++
>  4 files changed, 855 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-s3c24xx/include/mach/mci.h
>  create mode 100644 drivers/mci/s3c.c
> 
> diff --git a/arch/arm/mach-s3c24xx/include/mach/mci.h b/arch/arm/mach-s3c24xx/include/mach/mci.h
> new file mode 100644
> index 0000000..6ba8961
> --- /dev/null
> +++ b/arch/arm/mach-s3c24xx/include/mach/mci.h
> @@ -0,0 +1,46 @@
> +/*
> + * (C) Copyright 2010 Juergen Beisert, Pengutronix
> + *
> + * This code is partially based on u-boot code:
> + *
> + * Copyright 2008, Freescale Semiconductor, Inc
> + * Andy Fleming
> + *
> + * Based (loosely) on the Linux code
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __MACH_MMC_H_
> +#define __MACH_MMC_H_
> +
> +struct s3c_mci_platform_data {
> +	unsigned caps;	/**< supported operating modes (MMC_MODE_*) */
> +	unsigned voltages; /**< supported voltage range (MMC_VDD_*) */
> +	unsigned f_min;	/**< min operating frequency in Hz (0 -> no limit) */
> +	unsigned f_max;	/**< max operating frequency in Hz (0 -> no limit) */
> +	/* TODO */
> +	/* function to modify the voltage */
> +	/* function to switch the voltage */
> +	/* function to detect the presence of a SD card in the socket */
> +	unsigned gpio_detect;
> +	unsigned detect_invert;
> +};
> +
> +#endif /* __MACH_MMC_H_ */
> diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
> index a24ae6d..644c0a3 100644
> --- a/drivers/mci/Kconfig
> +++ b/drivers/mci/Kconfig
> @@ -34,4 +34,11 @@ config MCI_STM378X
>  	  Enable this entry to add support to read and write SD cards on a
>  	  i.MX23 based system.
>  
> +config MCI_S3C
> +	bool "S3C"
> +	depends on ARCH_S3C24xx
> +	help
> +	  Enable this entry to add support to read and write SD cards on a
> +	  Samsung S3C24xx based system.
> +
>  endif
> diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
> index e5e19b0..be18446 100644
> --- a/drivers/mci/Makefile
> +++ b/drivers/mci/Makefile
> @@ -1,2 +1,3 @@
>  obj-$(CONFIG_MCI)	+= mci-core.o
>  obj-$(CONFIG_MCI_STM378X) += stm378x.o
> +obj-$(CONFIG_MCI_S3C) += s3c.o
> diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
> new file mode 100644
> index 0000000..3813be7
> --- /dev/null
> +++ b/drivers/mci/s3c.c
> @@ -0,0 +1,801 @@
> +/*
> + * Copyright (C) 2010 Juergen Beisert <juergen at kreuzholzen.de>
> + *
> + * This code is partially based on u-boot code:
> + *
> + * This code is based on various Linux and u-boot sources:
> + *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk at maintech.de>
> + *  Copyright (C) 2008 Simtec Electronics <ben-linux at fluff.org>
> + *  (C) Copyright 2006 by OpenMoko, Inc.
> + *  Author: Harald Welte <laforge at openmoko.org>
> + *  based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
> + *  (C) 2005-2005 Thomas Kleffel
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +/**
> + * @file
> + * @brief MCI card host interface for S3C2440 CPU
> + */
> +
> +/* #define DEBUG */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <mci.h>
> +#include <errno.h>
> +#include <clock.h>
> +#include <asm/io.h>
> +#include <mach/mci.h>
> +#include <mach/s3c24xx-generic.h>
> +#include <mach/s3c24x0-iomap.h>
> +
> +#define SDICON 0x0
> +# define SDICON_SDRESET (1 << 8)
> +# define SDICON_MMCCLOCK (1 << 5) /* this is a clock type SD or MMC style WTF? */
> +# define SDICON_BYTEORDER (1 << 4)
> +# define SDICON_SDIOIRQ (1 << 3)
> +# define SDICON_RWAITEN (1 << 2)
> +# define SDICON_FIFORESET (1 << 1) /* reserved bit on 2440 ????? */
> +# define SDICON_CLKEN (1 << 0) /* enable/disable external clock */
> +
> +#define SDIPRE 0x4
> +
> +#define SDICMDARG 0x8
> +
> +#define SDICMDCON 0xc
> +# define SDICMDCON_ABORT (1 << 12)
> +# define SDICMDCON_WITHDATA (1 << 11)
> +# define SDICMDCON_LONGRSP (1 << 10)
> +# define SDICMDCON_WAITRSP (1 << 9)
> +# define SDICMDCON_CMDSTART (1 << 8)
> +# define SDICMDCON_SENDERHOST (1 << 6)
> +# define SDICMDCON_INDEX (0x3f)
> +
> +#define SDICMDSTAT 0x10
> +# define SDICMDSTAT_CRCFAIL (1 << 12)
> +# define SDICMDSTAT_CMDSENT (1 << 11)
> +# define SDICMDSTAT_CMDTIMEOUT (1 << 10)
> +# define SDICMDSTAT_RSPFIN (1 << 9)
> +# define SDICMDSTAT_XFERING (1 << 8)
> +# define SDICMDSTAT_INDEX (0xff)
> +
> +#define SDIRSP0 0x14
> +#define SDIRSP1 0x18
> +#define SDIRSP2 0x1C
> +#define SDIRSP3 0x20
> +
> +#define SDITIMER 0x24
> +#define SDIBSIZE 0x28
> +
> +#define SDIDCON 0x2c
> +# define SDIDCON_DS_BYTE (0 << 22)
> +# define SDIDCON_DS_HALFWORD (1 << 22)
> +# define SDIDCON_DS_WORD (2 << 22)
> +# define SDIDCON_IRQPERIOD (1 << 21)
> +# define SDIDCON_TXAFTERRESP (1 << 20)
> +# define SDIDCON_RXAFTERCMD (1 << 19)
> +# define SDIDCON_BUSYAFTERCMD (1 << 18)
> +# define SDIDCON_BLOCKMODE (1 << 17)
> +# define SDIDCON_WIDEBUS (1 << 16)
> +# define SDIDCON_DMAEN (1 << 15)
> +# define SDIDCON_STOP (0 << 14)
> +# define SDIDCON_DATSTART (1 << 14)
> +# define SDIDCON_DATMODE (3 << 12)
> +# define SDIDCON_BLKNUM (0xfff)
> +# define SDIDCON_XFER_READY    (0 << 12)
> +# define SDIDCON_XFER_CHKSTART (1 << 12)
> +# define SDIDCON_XFER_RXSTART  (2 << 12)
> +# define SDIDCON_XFER_TXSTART  (3 << 12)
> +
> +#define SDIDCNT 0x30
> +# define SDIDCNT_BLKNUM_SHIFT 12
> +
> +#define SDIDSTA 0x34
> +# define SDIDSTA_RDYWAITREQ (1 << 10)
> +# define SDIDSTA_SDIOIRQDETECT (1 << 9)
> +# define SDIDSTA_FIFOFAIL (1 << 8) /* reserved on 2440 */
> +# define SDIDSTA_CRCFAIL (1 << 7)
> +# define SDIDSTA_RXCRCFAIL (1 << 6)
> +# define SDIDSTA_DATATIMEOUT (1 << 5)
> +# define SDIDSTA_XFERFINISH (1 << 4)
> +# define SDIDSTA_BUSYFINISH (1 << 3)
> +# define SDIDSTA_SBITERR (1 << 2) /* reserved on 2410a/2440 */
> +# define SDIDSTA_TXDATAON (1 << 1)
> +# define SDIDSTA_RXDATAON (1 << 0)
> +
> +#define SDIFSTA 0x38
> +# define SDIFSTA_FIFORESET (1<<16)
> +# define SDIFSTA_FIFOFAIL (3<<14)  /* 3 is correct (2 bits) */
> +# define SDIFSTA_TFDET (1<<13)
> +# define SDIFSTA_RFDET (1<<12)
> +# define SDIFSTA_TFHALF (1<<11)
> +# define SDIFSTA_TFEMPTY (1<<10)
> +# define SDIFSTA_RFLAST (1<<9)
> +# define SDIFSTA_RFFULL (1<<8)
> +# define SDIFSTA_RFHALF (1<<7)
> +# define SDIFSTA_COUNTMASK (0x7f)
> +
> +#define SDIIMSK 0x3C
> +# define SDIIMSK_RESPONSECRC    (1<<17)
> +# define SDIIMSK_CMDSENT        (1<<16)
> +# define SDIIMSK_CMDTIMEOUT     (1<<15)
> +# define SDIIMSK_RESPONSEND     (1<<14)
> +# define SDIIMSK_READWAIT       (1<<13)
> +# define SDIIMSK_SDIOIRQ        (1<<12)
> +# define SDIIMSK_FIFOFAIL       (1<<11)
> +# define SDIIMSK_CRCSTATUS      (1<<10)
> +# define SDIIMSK_DATACRC        (1<<9)
> +# define SDIIMSK_DATATIMEOUT    (1<<8)
> +# define SDIIMSK_DATAFINISH     (1<<7)
> +# define SDIIMSK_BUSYFINISH     (1<<6)
> +# define SDIIMSK_SBITERR        (1<<5) /* reserved 2440/2410a */
> +# define SDIIMSK_TXFIFOHALF     (1<<4)
> +# define SDIIMSK_TXFIFOEMPTY    (1<<3)
> +# define SDIIMSK_RXFIFOLAST     (1<<2)
> +# define SDIIMSK_RXFIFOFULL     (1<<1)
> +# define SDIIMSK_RXFIFOHALF     (1<<0)
> +
> +#define SDIDATA 0x40
> +
> +#define CLOCKRATE_MIN (1 * 1000 * 1000)

Isn't this a bit high? I thought the initialization frequnency should be
400Khz at maximum. Or does the hardware not allow lower rates?

> +#define CLOCKRATE_MAX (480 * 1000 * 1000)
> +
> +struct s3c_mci_host {
> +	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
> +	unsigned	clock;	/* current clock in Hz */
> +	unsigned	data_size;	/* data transfer in bytes */
> +};
> +
> +/*
> + * There is only one host MCI hardware instance available.
> + * It makes no sense to dynamically allocate this data
> + */
> +static struct s3c_mci_host host_data;
> +
> +/**
> + * Finish a request
> + * @param hw_dev Host interface instance
> + *
> + * Just a little bit paranoia.
> + */
> +static void s3c_finish_request(struct device_d *hw_dev)
> +{
> +	/* TODO ensure the engines are stopped */
> +}
> +
> +/* TODO GPIO feature is required for this architecture */
> +static unsigned gpio_get_value(unsigned val)
> +{
> +	return 0;
> +}
> +
> +/**
> + * Detect if a card is plugged in
> + * @param hw_dev Host interface instance
> + * @return 0 if a card is plugged in
> + *
> + * Note: If there is no GPIO registered to detect if a card is present, we
> + * assume a card _is_ present.
> + */
> +static int s3c_mci_card_present(struct device_d *hw_dev)
> +{
> +	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)GET_HOST_PDATA(hw_dev);
> +	int ret;
> +
> +	if (pd->gpio_detect == 0)
> +		return 0;	/* assume the card is present */
> +
> +	ret = gpio_get_value(pd->gpio_detect) ? 0 : 1;
> +	return ret ^ pd->detect_invert;
> +}
> +
> +/**
> + * Setup a new clock frequency on this MCI bus
> + * @param hw_dev Host interface instance
> + * @param nc New clock value in Hz (can be 0)
> + * @return New clock value (may differ from 'nc')
> + */
> +static unsigned s3c_setup_clock_speed(struct device_d *hw_dev, unsigned nc)
> +{
> +	unsigned clock;
> +	uint32_t mci_psc;
> +
> +	if (nc == 0)
> +		return 0;
> +
> +	clock = s3c24xx_get_pclk();
> +	/* Calculate the required prescaler value to get the requested frequency */
> +	mci_psc = (clock + (nc >> 2)) / nc;
> +
> +	if (mci_psc > 256) {
> +		mci_psc = 256;
> +		pr_warning("SD/MMC clock might be too high!\n");
> +	}
> +
> +	writel(mci_psc - 1, hw_dev->map_base + SDIPRE);
> +
> +	return clock / mci_psc;
> +}
> +
> +/**
> + * Reset the MCI engine (the hard way)
> + * @param hw_dev Host interface instance
> + *
> + * This will reset everything in all registers of this unit!
> + */
> +static void s3c_mci_reset(struct device_d *hw_dev)
> +{
> +	/* reset the hardware */
> +	writel(SDICON_SDRESET, hw_dev->map_base + SDICON);
> +	/* wait until reset it finished */
> +	while (readl(hw_dev->map_base + SDICON) & SDICON_SDRESET)
> +		;
> +}
> +
> +/**
> + * Initialize hard and software
> + * @param hw_dev Host interface instance
> + * @param mci_dev MCI device instance (might be NULL)
> + */
> +static int s3c_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
> +{
> +	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> +
> +	s3c_mci_reset(hw_dev);
> +
> +	/* restore last settings */
> +	host_data->clock = s3c_setup_clock_speed(hw_dev, host_data->clock);
> +	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> +	writel(SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
> +	writel(512, hw_dev->map_base + SDIBSIZE);
> +
> +	return 0;
> +}
> +
> +/**
> + * Prepare engine's bits for the next command transfer
> + * @param cmd_flags MCI's command flags
> + * @param data_flags MCI's data flags
> + * @return Register bits for this transfer
> + */
> +static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned data_flags)
> +{
> +	uint32_t reg;
> +
> +	/* source (=host) */
> +	reg = SDICMDCON_SENDERHOST;
> +
> +	if (cmd_flags & MMC_RSP_PRESENT) {
> +		reg |= SDICMDCON_WAITRSP;
> +		pr_debug("Command with response\n");
> +	}
> +	if (cmd_flags & MMC_RSP_136) {
> +		reg |= SDICMDCON_LONGRSP;
> +		pr_debug("Command with long response\n");
> +	}
> +	if (cmd_flags & MMC_RSP_CRC)
> +		; /* FIXME */
> +	if (cmd_flags & MMC_RSP_BUSY)
> +		; /* FIXME */
> +	if (cmd_flags & MMC_RSP_OPCODE)
> +		; /* FIXME */

It's ok that these flags are not handled in the first run, but I think
the driver should issue a warning when one of these flags is set.

> +	if (data_flags != 0)
> +		reg |= SDICMDCON_WITHDATA;
> +
> +	return reg;
> +}
> +
> +/**
> + * Prepare engine's bits for the next data transfer
> + * @param hw_dev Host interface device instance
> + * @param data_flags MCI's data flags
> + * @return Register bits for this transfer
> + */
> +static uint32_t s3c_prepare_data_setup(struct device_d *hw_dev, unsigned data_flags)
> +{
> +	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> +	uint32_t reg = SDIDCON_BLOCKMODE;	/* block mode only is supported */
> +
> +	if (host_data->bus_width == 1)
> +		reg |= SDIDCON_WIDEBUS;
> +
> +	/* enable any kind of data transfers on demand only */
> +	if (data_flags & MMC_DATA_WRITE)
> +		reg |= SDIDCON_TXAFTERRESP | SDIDCON_XFER_TXSTART;
> +
> +	if (data_flags & MMC_DATA_READ)
> +		reg |= SDIDCON_RXAFTERCMD | SDIDCON_XFER_RXSTART;
> +
> +	/* TODO: Support more than the 2440 CPU */
> +	reg |= SDIDCON_DS_WORD | SDIDCON_DATSTART;
> +
> +	return reg;
> +}
> +
> +/**
> + * Terminate a current running transfer
> + * @param hw_dev Host interface device instance
> + * @return 0 on success
> + *
> + * Note: Try to stop a running transfer. This should not happen, as all
> + * transfers must complete in this driver. But who knows... ;-)
> + */
> +static int s3c_terminate_transfer(struct device_d *hw_dev)
> +{
> +	unsigned stoptries = 3;
> +
> +	while (readl(hw_dev->map_base + SDIDSTA) & (SDIDSTA_TXDATAON | SDIDSTA_RXDATAON)) {
> +		pr_debug("Transfer still in progress.\n");
> +
> +		writel(SDIDCON_STOP, hw_dev->map_base + SDIDCON);
> +		s3c_mci_initialize(hw_dev, NULL);
> +
> +		if ((stoptries--) == 0) {
> +			pr_warning("Cannot stop the engine!\n");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * Setup registers for data transfer
> + * @param hw_dev Host interface device instance
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_prepare_data_transfer(struct device_d *hw_dev, struct mci_data *data)
> +{
> +	uint32_t reg;
> +
> +	writel(data->blocksize, hw_dev->map_base + SDIBSIZE);
> +	reg = s3c_prepare_data_setup(hw_dev, data->flags);
> +	reg |= data->blocks & SDIDCON_BLKNUM;
> +	writel(reg, hw_dev->map_base + SDIDCON);
> +	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> +
> +	return 0;
> +}
> +
> +/**
> + * Send a command and receive the response
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_send_command(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> +	uint32_t reg, t1;
> +	int rc;
> +
> +	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> +
> +	/* setup argument */
> +	writel(cmd->cmdarg, hw_dev->map_base + SDICMDARG);
> +
> +	/* setup command and transfer characteristic */
> +	reg = s3c_prepare_command_setup(cmd->resp_type, data != NULL ? data->flags : 0);
> +	reg |= cmd->cmdidx & SDICMDCON_INDEX;
> +
> +	/* run the command right now */
> +	writel(reg | SDICMDCON_CMDSTART, hw_dev->map_base + SDICMDCON);
> +	t1 = readl(hw_dev->map_base + SDICMDSTAT);
> +	/* wait until command is done */
> +	while (1) {
> +		reg = readl(hw_dev->map_base + SDICMDSTAT);
> +		/* done? */
> +		if (cmd->resp_type & MMC_RSP_PRESENT) {
> +			if (reg & SDICMDSTAT_RSPFIN) {
> +				writel(SDICMDSTAT_RSPFIN, hw_dev->map_base + SDICMDSTAT); /* required??? */
> +				rc = 0;
> +				break;
> +			}
> +		} else {
> +			if (reg & SDICMDSTAT_CMDSENT) {
> +					writel(SDICMDSTAT_CMDSENT, hw_dev->map_base + SDICMDSTAT); /* required??? */
> +					rc = 0;
> +					break;
> +			}
> +		}
> +		/* timeout? */
> +		if (reg & SDICMDSTAT_CMDTIMEOUT) {
> +			writel(SDICMDSTAT_CMDTIMEOUT, hw_dev->map_base + SDICMDSTAT); /* required??? */
> +			rc = -ETIMEDOUT;
> +			break;
> +		}
> +	}
> +
> +	if ((rc == 0) && (cmd->resp_type & MMC_RSP_PRESENT)) {
> +		cmd->response[0] = readl(hw_dev->map_base + SDIRSP0);
> +		cmd->response[1] = readl(hw_dev->map_base + SDIRSP1);
> +		cmd->response[2] = readl(hw_dev->map_base + SDIRSP2);
> +		cmd->response[3] = readl(hw_dev->map_base + SDIRSP3);
> +	}
> +	/* do not disable the clock! */
> +	return rc;
> +}
> +
> +/**
> + * Clear major registers prior a new transaction
> + * @param hw_dev Host interface device instance
> + * @return 0 on success
> + *
> + * FIFO clear is only necessary on 2440, but doesn't hurt on 2410
> + */
> +static int s3c_prepare_engine(struct device_d *hw_dev)
> +{
> +	int rc;
> +
> +	rc = s3c_terminate_transfer(hw_dev);
> +	if (rc != 0)
> +		return rc;
> +
> +	writel(-1, hw_dev->map_base + SDICMDSTAT);
> +	writel(-1, hw_dev->map_base + SDIDSTA);
> +	writel(-1, hw_dev->map_base + SDIFSTA);
> +
> +	return 0;
> +}
> +
> +/**
> + * Handle MCI commands without data
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @return 0 on success
> + *
> + * This functions handles the following MCI commands:
> + * - "broadcast command (BC)" without a response
> + * - "broadcast commands with response (BCR)"
> + * - "addressed command (AC)" with response, but without data
> + */
> +static int s3c_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
> +{
> +	int rc;
> +
> +	rc = s3c_prepare_engine(hw_dev);
> +	if (rc != 0)
> +		return 0;
> +
> +	return s3c_send_command(hw_dev, cmd, NULL);
> +}
> +
> +/**
> + * Read one block of data from the FIFO
> + * @param hw_dev Host interface device instance
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_mci_read_block(struct device_d *hw_dev, struct mci_data *data)
> +{
> +	uint32_t *p;
> +	unsigned cnt, data_size;
> +
> +#define READ_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_RXCRCFAIL | SDIDSTA_DATATIMEOUT)
> +
> +	p = (uint32_t*)data->dest;
> +	data_size = data->blocksize * data->blocks;
> +
> +	while (data_size > 0) {
> +
> +		/* serious error? */
> +		if (readl(hw_dev->map_base + SDIDSTA) & READ_REASON_TO_FAIL) {
> +			pr_err("Failed while reading data\n");
> +			return -EIO;
> +		}
> +
> +		/* now check the FIFO status */
> +		if (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_FIFOFAIL) {
> +			pr_err("Data loss due to FIFO overflow when reading\n");
> +			return -EIO;
> +		}
> +
> +		/* we only want to read full words */
> +		cnt = (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) >> 2;
> +
> +		/* read one chunk of data from the FIFO */
> +		while (cnt--) {
> +			*p = readl(hw_dev->map_base + SDIDATA);
> +			p++;
> +			if (data_size >= 4)
> +				data_size -= 4;
> +			else {
> +				data_size = 0;
> +				break;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * Write one block of data into the FIFO
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + *
> + * We must ensure data in the FIFO when the command phase changes into the
> + * data phase. To ensure this, the FIFO gets filled first, then the command.
> + */
> +static int s3c_mci_write_block(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> +	const uint32_t *p = (const uint32_t*)data->src;
> +	unsigned cnt, data_size;
> +	uint32_t reg;
> +
> +#define WRITE_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_DATATIMEOUT)
> +
> +	data_size = data->blocksize * data->blocks;
> +	/*
> +	 * With high clock rates we must fill the FIFO as early as possible
> +	 * Its size is 16 words. We assume its empty, when this function is
> +	 * entered.
> +	 */
> +	cnt = 16;
> +	while (cnt--) {
> +		writel(*p, hw_dev->map_base + SDIDATA);
> +		p++;
> +		if (data_size >= 4)
> +			data_size -= 4;
> +		else {
> +			data_size = 0;
> +			break;
> +		}
> +	}
> +
> +	/* data is now in place and waits for transmitt. Start the command right now */
> +	s3c_send_command(hw_dev, cmd, data);
> +
> +	if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
> +		pr_err("Command fails immediatly due to FIFO underrun when writing %08X\n", reg);
> +		return -EIO;
> +	}
> +
> +	while (data_size > 0) {
> +
> +		if (readl(hw_dev->map_base + SDIDSTA) & WRITE_REASON_TO_FAIL) {
> +			pr_err("Failed writing data\n");
> +			return -EIO;
> +		}
> +
> +		/* now check the FIFO status */
> +		if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
> +			pr_err("Data loss due to FIFO underrun when writing %08X\n", reg);
> +			return -EIO;
> +		}
> +
> +		/* we only want to write full words */
> +		cnt = 16 - (((readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) + 3) >> 2);
> +
> +		/* fill the FIFO if it has free entries */
> +		while (cnt--) {
> +			writel(*p, hw_dev->map_base + SDIDATA);
> +			p++;
> +			if (data_size >= 4)
> +				data_size -= 4;
> +			else {
> +				data_size = 0;
> +				break;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * Handle MCI commands with or without data
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> +*/
> +static int s3c_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> +	int rc;
> +
> +	rc = s3c_prepare_engine(hw_dev);
> +	if (rc != 0)
> +		return rc;
> +
> +	rc = s3c_prepare_data_transfer(hw_dev, data);
> +	if (rc != 0)
> +		return rc;
> +
> +	if (data->flags & MMC_DATA_READ) {
> +		s3c_send_command(hw_dev, cmd, data);
> +		rc = s3c_mci_read_block(hw_dev, data);
> +		if (rc == 0) {
> +			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
> +				;
> +		} else
> +			s3c_terminate_transfer(hw_dev);
> +	}
> +
> +	if (data->flags & MMC_DATA_WRITE) {
> +		rc = s3c_mci_write_block(hw_dev, cmd, data);
> +		if (rc == 0) {
> +			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
> +				;
> +		} else
> +			s3c_terminate_transfer(hw_dev);
> +	}
> +	writel(0, hw_dev->map_base + SDIDCON);
> +
> +	return rc;
> +}
> +
> +/* ------------------------- MCI API -------------------------------------- */
> +
> +/**
> + * Keep the attached MMC/SD unit in a well know state
> + * @param hw_dev Host interface instance
> + * @param mci_dev MCI device instance
> + * @return 0 on success, negative value else
> + */
> +static int mci_reset(struct device_d *hw_dev, struct device_d *mci_dev)
> +{
> +	return s3c_mci_initialize(hw_dev, mci_dev);
> +}
> +
> +/**
> + * Process one command to the MCI card
> + * @param hw_dev Host interface instance
> + * @param cmd The command to process
> + * @param data The data to handle in the command (can be NULL)
> + * @return 0 on success, negative value else
> + */
> +static int mci_request(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> +	int rc;
> +
> +	/* enable clock */
> +	writel(readl(hw_dev->map_base + SDICON) | SDICON_CLKEN, hw_dev->map_base + SDICON);
> +
> +	if ((cmd->resp_type == 0) || (data == NULL))
> +		rc = s3c_mci_std_cmds(hw_dev, cmd);
> +	else
> +		rc = s3c_mci_adtc(hw_dev, cmd, data);	/* with response and data */
> +
> +	s3c_finish_request(hw_dev);
> +
> +	/* disable clock */
> +	writel(readl(hw_dev->map_base + SDICON) & ~SDICON_CLKEN, hw_dev->map_base + SDICON);
> +	return rc;
> +}
> +
> +/**
> + * Setup the bus width and IO speed
> + * @param hw_dev Host interface device instance
> + * @param mci_dev MCI device instance
> + * @param bus_width New bus width value (1, 4 or 8)
> + * @param clock New clock in Hz (can be '0' to disable the clock)
> + */
> +static void mci_set_ios(struct device_d *hw_dev, struct device_d *mci_dev, unsigned bus_width, unsigned clock)
> +{
> +	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> +	struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
> +	uint32_t reg;
> +
> +	switch (bus_width) {
> +	case 8:		/* no 8 bit support, fall back to 4 bit */
> +	case 4:
> +		host_data->bus_width = 1;
> +		mci_pdata->bus_width = 4;	/* 4 bit is possible */
> +		break;
> +	default:
> +		host_data->bus_width = 0;
> +		mci_pdata->bus_width = 1;	/* 1 bit is possible */
> +		break;
> +	}
> +
> +	reg = readl(hw_dev->map_base + SDICON);
> +	if (clock) {
> +		/* setup the IO clock frequency and enable it */
> +		mci_pdata->clock = host_data->clock = s3c_setup_clock_speed(hw_dev, clock);
> +		reg |= SDICON_CLKEN;	/* enable the clock */
> +	} else {
> +		reg &= ~SDICON_CLKEN;	/* disable the clock */
> +		mci_pdata->clock = host_data->clock = 0;
> +	}
> +	writel(reg, hw_dev->map_base + SDICON);
> +
> +	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", mci_pdata->bus_width, mci_pdata->clock);
> +}
> +
> +/* ----------------------------------------------------------------------- */
> +
> +#ifdef CONFIG_MCI_INFO
> +static void s3c_info(struct device_d *hw_dev)
> +{
> +	struct s3c_mci_host *host = (struct s3c_mci_host*)hw_dev->priv;
> +	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
> +
> +	printf("  Bus data width: %d bit\n", host->bus_width == 1 ? 4 : 1);
> +	printf("  Bus frequency: %u Hz\n", host->clock);
> +	printf("   Frequency limits: ");
> +	if (pd->f_min == 0)
> +		printf("no lower limit ");
> +	else
> +		printf("%u Hz lower limit ", pd->f_min);
> +	if (pd->f_max == 0)
> +		printf("- no upper limit");
> +	else
> +		printf("- %u Hz upper limit", pd->f_max);
> +	printf("\n  Card detection support: %s\n", pd->gpio_detect != 0 ? "yes" : "no");
> +}
> +#endif
> +
> +/*
> + * There is only one host MCI hardware instance available.
> + * It makes no sense to dynamically allocate this data
> + */
> +static struct mci_platformdata mci_pdata = {
> +	.send_cmd = mci_request,
> +	.set_ios = mci_set_ios,
> +	.init = mci_reset,
> +};
> +
> +static int s3c_mci_probe(struct device_d *hw_dev)
> +{
> +	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
> +
> +	/* TODO replace by the global func: enable the SDI unit clock */
> +	writel(readl(S3C24X0_CLOCK_POWER_BASE + 0x0c) | 0x200,S3C24X0_CLOCK_POWER_BASE + 0x0c);
> +
> +	if (pd == NULL) {
> +		pr_err("Missing platform data\n");
> +		return -EINVAL;
> +	}
> +
> +	hw_dev->priv = &host_data;
> +	mci_pdata.hw_dev = hw_dev;
> +
> +	/* feed forward the platform specific values */
> +	mci_pdata.voltages = pd->voltages;
> +	mci_pdata.host_caps = pd->caps;
> +	mci_pdata.f_min = pd->f_min == 0 ? CLOCKRATE_MIN : pd->f_min;
> +	mci_pdata.f_max = pd->f_max == 0 ? CLOCKRATE_MAX : pd->f_max;
> +
> +	/*
> +	 * Start the clock to let the engine and the card finishes its startup
> +	 */
> +	host_data.clock = s3c_setup_clock_speed(hw_dev, mci_pdata.f_min);
> +	writel(SDICON_FIFORESET | SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
> +
> +	return mci_register(&mci_pdata);
> +}
> +
> +static struct driver_d s3c_mci_driver = {
> +        .name  = "s3c_mci",
> +        .probe = s3c_mci_probe,
> +#ifdef CONFIG_MCI_INFO
> +	.info = s3c_info,
> +#endif
> +};
> +
> +static int s3c_mci_init_driver(void)
> +{
> +        register_driver(&s3c_mci_driver);
> +        return 0;
> +}
> +
> +device_initcall(s3c_mci_init_driver);
> -- 
> 1.7.2.3
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Thu Oct  7 13:39:59 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu, 7 Oct 2010 19:39:59 +0200
Subject: [PATCH 5/7] Add MCI card support to barebox
In-Reply-To: <20101007165959.GJ28242@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
	<201010071800.06450.jbe@pengutronix.de>
	<20101007165959.GJ28242@pengutronix.de>
Message-ID: <201010071940.00015.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Thu, Oct 07, 2010 at 06:00:06PM +0200, Juergen Beisert wrote:
> > Sascha Hauer wrote:
> > > On Thu, Oct 07, 2010 at 03:24:16PM +0200, Juergen Beisert wrote:
> > > > This adds the basic framework to handle MCI cards in barebox.
> > > >
> > > > Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> > > > ---
> > > >  drivers/Kconfig        |    1 +
> > > >  drivers/Makefile       |    1 +
> > > >  drivers/mci/Kconfig    |   30 ++
> > > >  drivers/mci/Makefile   |    1 +
> > > >  drivers/mci/mci-core.c | 1308
> > > > ++++++++++++++++++++++++++++++++++++++++++++++++ include/mci.h       
> > > >   | 230 +++++++++
> > > >  6 files changed, 1571 insertions(+), 0 deletions(-)
> > > >  create mode 100644 drivers/mci/Kconfig
> > > >  create mode 100644 drivers/mci/Makefile
> > > >  create mode 100644 drivers/mci/mci-core.c
> > > >  create mode 100644 include/mci.h
> > >
> > > This whole patch looks quite good.
> > > Please add some linebreaks in mci-core.c. I don't want strict 80
> > > character lines, but some lines are really long.
> > >
> > > [snip]
> > >
> > > > +static int mci_probe(struct device_d *mci_dev)
> > > > +{
> > > > +	struct mci *mci;
> > > > +	int rc;
> > > > +
> > > > +	mci = xzalloc(sizeof(struct mci));
> > > > +	mci_dev->priv = mci;
> > > > +
> > > > +#ifdef CONFIG_MCI_STARTUP
> > > > +	/* if enabled, probe the attached card immediately */
> > > > +	rc = mci_card_probe(mci_dev);
> > > > +	if (rc == -ENODEV) {
> > > > +		/*
> > > > +		 * If it fails, add the 'probe' parameter to give the user
> > > > +		 * a chance to insert a card and try again. Note: This may fail
> > > > +		 * systems that rely on the MCI card for startup (for the
> > > > +		 * persistant environment for example)
> > > > +		 */
> > > > +		rc = add_mci_parameter(mci_dev);
> > > > +		if (rc != 0) {
> > > > +			pr_err("Failed to add 'probe' parameter to the MCI device\n");
> > > > +			goto on_error;
> > > > +		}
> > > > +	}
> > > > +#endif
> > > > +
> > > > +#ifndef CONFIG_MCI_STARTUP
> > >
> > > #else instead?
> > >
> > > > +	/* add params on demand */
> > > > +	rc = add_mci_parameter(mci_dev);
> > > > +	if (rc != 0) {
> > > > +		pr_err("Failed to add 'probe' parameter to the MCI device\n");
> > > > +		goto on_error;
> > > > +	}
> > > > +#endif
> > > > +
> > > > +	return rc;
> > > > +
> > > > +on_error:
> > > > +	free(mci);
> > > > +	return rc;
> > > > +}
> > > > +
> > >
> > > [snip]
> > >
> > > > +
> > > > +/** host information */
> > > > +struct mci_platformdata {
> > > > +	struct device_d *hw_dev;	/**< the host MCI hardware device */
> > > > +	unsigned voltages;
> > > > +	unsigned host_caps;	/**< Host's interface capabilities, refer
> > > > MMC_VDD_* and FIXME */ +	unsigned f_min;		/**< host interface lower
> > > > limit */ +	unsigned f_max;		/**< host interface upper limit */
> > > > +	unsigned clock;		/**< Current clock used to talk to the card */
> > > > +	unsigned bus_width;	/**< used data bus width to the card */
> > > > +
> > > > +	int (*init)(struct device_d*, struct device_d*);	/**< init the host
> > > > interface */ +	void (*set_ios)(struct device_d*, struct device_d*,
> > > > unsigned, unsigned);	/**< change host interface settings */ +	int
> > > > (*send_cmd)(struct device_d*, struct mci_cmd*, struct
> > > > mci_data*);	/**< handle a command */ +};
> > >
> > > I prefer this struct named mci_host, this seems to match better what it
> > > actually is.
> >
> > Hmm, no, its not a "host". It is the MMC/SD card instance. The host is
> > more the interface, isn't it (at least for me)?
>
> It's a host at least in the Linux terminology.

Yes. So, we name the platform like data of the MCI card device 
instance "mci_host".

host device
-----------

  hw_device
     ->priv: points to drivers private data
          names are: "s3c_mci_host" or "stm_mci_host"
     ->platform_data: points to data provided by the platform
          names are: "s3c_mci_platform_data" or "stm_mci_platform_data"

mci device
----------

  mci_device
     ->priv: points to mci layer's private data
           name is: "mci_data"
     ->platform_data: points to data provided by the host device
           name is: "mci_platformdata"
           name should be: "mci_host"

"host" in the name sounds IMHO wrong here. I'm not happy about that, but its 
okay. I will change the name.

> > > For the convenience of drivers set init/set_ios/send_cmd
> > > functions should be passed a pointer to the mci_host, not the device,
> > > because that's what they actually registered. I already prepared a
> > > patch for this, I'll send it in a seperate mail.
> >
> > I tried to layering the devices:
> >
> >  disk_device -> knows how to handle disk drives and partition tables
> >
> >  mci_device -> knows how to probe and manage MMC/SD cards
> >
> >  hw_device -> knows how to transfer data
> >
> > Most functions in the hw_device layer do not need access to any other
> > structure data than their own device (okay, there is a exception). So, I
> > tried to keep it simple.
>
> I didn't change the underlying structure, only the pointer which is
> passed to the functions.

Sure.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Thu Oct  7 13:51:24 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu, 7 Oct 2010 19:51:24 +0200
Subject: [PATCH 7/7] Add S3C2440 MCI card support
In-Reply-To: <20101007171003.GK28242@pengutronix.de>
References: <1286457858-29771-1-git-send-email-jbe@pengutronix.de>
	<1286457858-29771-8-git-send-email-jbe@pengutronix.de>
	<20101007171003.GK28242@pengutronix.de>
Message-ID: <201010071951.24867.jbe@pengutronix.de>

Sascha Hauer wrote:
> [...]
> > +#define CLOCKRATE_MIN (1 * 1000 * 1000)
>
> Isn't this a bit high? I thought the initialization frequnency should be
> 400Khz at maximum. Or does the hardware not allow lower rates?

I see you know more about MCI cards than me. This limit is a new fact to me.

Maybe this is the reason why the old 16 MiB MMC fails... will check.

And no: There is *mostly* no limit for the minimal clockrate. I should 
calculate it at runtime, because it depends on some other settings in the 
clock tree. In the i.MX23 driver I do so already.

> [...]
> > +/**
> > + * Prepare engine's bits for the next command transfer
> > + * @param cmd_flags MCI's command flags
> > + * @param data_flags MCI's data flags
> > + * @return Register bits for this transfer
> > + */
> > +static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned
> > data_flags) +{
> > +	uint32_t reg;
> > +
> > +	/* source (=host) */
> > +	reg = SDICMDCON_SENDERHOST;
> > +
> > +	if (cmd_flags & MMC_RSP_PRESENT) {
> > +		reg |= SDICMDCON_WAITRSP;
> > +		pr_debug("Command with response\n");
> > +	}
> > +	if (cmd_flags & MMC_RSP_136) {
> > +		reg |= SDICMDCON_LONGRSP;
> > +		pr_debug("Command with long response\n");
> > +	}
> > +	if (cmd_flags & MMC_RSP_CRC)
> > +		; /* FIXME */
> > +	if (cmd_flags & MMC_RSP_BUSY)
> > +		; /* FIXME */
> > +	if (cmd_flags & MMC_RSP_OPCODE)
> > +		; /* FIXME */
>
> It's ok that these flags are not handled in the first run, but I think
> the driver should issue a warning when one of these flags is set.

I'm still not sure what bits to set in the various registers to match these 
settings. So, a warning would be a good idea.

> [...]

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Fri Oct  8 02:59:33 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 8 Oct 2010 08:59:33 +0200
Subject: [PATCH 1/5] defaultenv: introduce
	CONFIG_DEFAULT_ENVIRONMENT_GENERIC to enable it
In-Reply-To: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
References: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <20101008065933.GM28242@pengutronix.de>

On Thu, Oct 07, 2010 at 06:37:34PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> this will we usefull to enable functionnality if used
> 
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> ---
>  arch/arm/configs/neso_defconfig   |    3 ++-
>  arch/arm/configs/pca100_defconfig |    3 ++-
>  arch/arm/configs/pcm037_defconfig |    3 ++-
>  arch/arm/configs/pcm038_defconfig |    3 ++-
>  arch/arm/configs/pcm043_defconfig |    3 ++-
>  common/Kconfig                    |    7 +++++++
>  common/Makefile                   |    4 ++++
>  7 files changed, 21 insertions(+), 5 deletions(-)
> 
>  
> +config DEFAULT_ENVIRONMENT_GENERIC
> +	bool
> +	depends on DEFAULT_ENVIRONMENT
> +	prompt "Default environment generic"
> +	help
> +	  Generic barebox default env

How about a bit more verbosity:

	prompt "Add generic default environment"
	help
	  With this option barebox will use the generic default
	  environment found under defaultenv/ in the src tree.
	  The Directory given with DEFAULT_ENVIRONMENT_PATH
	  will be added to the default environment. This should
	  at least contain a /env/config file.

> +
>  config DEFAULT_ENVIRONMENT_PATH
>  	string
>  	depends on DEFAULT_ENVIRONMENT
> diff --git a/common/Makefile b/common/Makefile
> index e56dbc2..b42ab7a 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -26,6 +26,10 @@ ifdef CONFIG_DEFAULT_ENVIRONMENT
>  $(obj)/startup.o: include/generated/barebox_default_env.h
>  $(obj)/env.o: include/generated/barebox_default_env.h
>  
> +ifeq ($(CONFIG_DEFAULT_ENVIRONMENT_GENERIC),y)
> +CONFIG_DEFAULT_ENVIRONMENT_PATH += defaultenv
> +endif

This reverses the order the different environment directories are
parsed. Now the files from defaultenv will overwrite the ones
from DEFAULT_ENVIRONMENT_PATH. I made it intentionally the other
way round.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Fri Oct  8 04:45:39 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 10:45:39 +0200
Subject: Switch the i.MX27's PLL in a safe manner
Message-ID: <1286527540-9857-1-git-send-email-jbe@pengutronix.de>

This patch is required to switch the PLL of the i.MX27 at runtime without data
loss and random system crashes (but it is only required in this way if the CPU
core does not run at 1.45 V immediatly after reset).

jbe



From jbe at pengutronix.de  Fri Oct  8 04:45:40 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 10:45:40 +0200
Subject: [PATCH] Switch the i.MX27's PLL in a safe manner
In-Reply-To: <1286527540-9857-1-git-send-email-jbe@pengutronix.de>
References: <1286527540-9857-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286527540-9857-2-git-send-email-jbe@pengutronix.de>

Changing PLL settings is somehow tricky on the i.MX27: Whenever the clock
speed of the main PLL is changed, the clock stops for about 100 us until the
PLL locks into the new frequency. While this clock stop, also the SDRAM
controller cannot refresh the memory, because it uses the same clock source.
This can lead into data loss and random system crashes.

This patch divides the PLL setting in two steps. First step is to re-program
the PLL and clock settings to values possible at a core supply of 1.25 V.
Second step is to increase the core power supply to 1.45 V and switch the
CPU clock to the specified 400 MHz.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/pcm038/Makefile   |    2 +-
 arch/arm/boards/pcm038/lowlevel.c |    7 ++++
 arch/arm/boards/pcm038/pcm038.c   |   65 ++++++++++++++++++++----------------
 arch/arm/boards/pcm038/pll_init.S |   48 ---------------------------
 4 files changed, 44 insertions(+), 78 deletions(-)
 delete mode 100644 arch/arm/boards/pcm038/pll_init.S

diff --git a/arch/arm/boards/pcm038/Makefile b/arch/arm/boards/pcm038/Makefile
index a681dda..970804e 100644
--- a/arch/arm/boards/pcm038/Makefile
+++ b/arch/arm/boards/pcm038/Makefile
@@ -1,3 +1,3 @@
 
-obj-y += lowlevel.o pll_init.o
+obj-y += lowlevel.o
 obj-y += pcm038.o
diff --git a/arch/arm/boards/pcm038/lowlevel.c b/arch/arm/boards/pcm038/lowlevel.c
index eb85e8f..b50e1c8 100644
--- a/arch/arm/boards/pcm038/lowlevel.c
+++ b/arch/arm/boards/pcm038/lowlevel.c
@@ -31,6 +31,8 @@
 #include <asm/system.h>
 #include <asm-generic/memory_layout.h>
 
+#include "pll.h"
+
 #ifdef CONFIG_NAND_IMX_BOOT
 static void __bare_init __naked insdram(void)
 {
@@ -68,6 +70,11 @@ void __bare_init __naked board_init_lowlevel(void)
 	if (r > 0xa0000000 && r < 0xb0000000)
 		board_init_lowlevel_return();
 
+	/* re-program the PLL prior(!) starting the SDRAM controller */
+	MPCTL0 = MPCTL0_VAL;
+	SPCTL0 = SPCTL0_VAL;
+	CSCR = CSCR_VAL | CSCR_UPDATE_DIS | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART;
+
 	/*
 	 * DDR on CSD0
 	 */
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index fda3262..3a9b413 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -44,6 +44,8 @@
 #include <mach/spi.h>
 #include <mach/iomux-mx27.h>
 
+#include "pll.h"
+
 static struct device_d cfi_dev = {
 	.id	  = -1,
 	.name     = "cfi_flash",
@@ -379,11 +381,6 @@ static struct device_d pcm038_serial_device = {
 
 static int pcm038_console_init(void)
 {
-	/* bring PLLs to reset default */
-	MPCTL0 = 0x00211803;
-	SPCTL0 = 0x1002700c;
-	CSCR = 0x33fc1307;
-
 	register_device(&pcm038_serial_device);
 
 	return 0;
@@ -391,40 +388,50 @@ static int pcm038_console_init(void)
 
 console_initcall(pcm038_console_init);
 
-extern void *pcm038_pll_init, *pcm038_pll_init_end;
-
-static int pcm038_power_init(void)
+/**
+ * The spctl0 register is a beast: Seems you can read it
+ * only one times without writing it again.
+ */
+static inline uint32_t get_pll_spctl10(void)
 {
-	int ret;
-	void *vram = (void*)0xffff4c00;
-	void (*pllfunc)(void) = vram;
+	uint32_t reg;
 
-	printf("initialising PLLs: 0x%p 0x%p\n", &pcm038_pll_init);
+	reg = SPCTL0;
+	SPCTL0 = reg;
 
-	memcpy(vram, &pcm038_pll_init, 0x100);
+	return reg;
+}
 
-	console_flush();
+/**
+ * If the PLL settings are in place switch the CPU core frequency to the max. value
+ */
+static int pcm038_power_init(void)
+{
+	uint32_t spctl0;
+	int ret;
 
-	ret = pmic_power();
-	if (ret) {
-		printf("Failed to initialize PMIC. Will continue with low CPU speed\n");
-		return 0;
+	spctl0 = get_pll_spctl10();
+
+	/* PLL registers already set to their final values? */
+	if (spctl0 == SPCTL0_VAL && MPCTL0 == MPCTL0_VAL) {
+		console_flush();
+		ret = pmic_power();
+		if (ret == 0) {
+			/* wait for required power level to run the CPU at 400 MHz */
+			udelay(100000);
+			CSCR = CSCR_VAL_FINAL;
+			PCDR0 = 0x130410c3;
+			PCDR1 = 0x09030911;
+			/* Clocks have changed. Notify clients */
+			clock_notifier_call_chain();
+		} else {
+			printf("Failed to initialize PMIC. Will continue with low CPU speed\n");
+		}
 	}
 
-	/* wait for good power level */
-	udelay(100000);
-
-	pllfunc();
-
 	/* clock gating enable */
 	GPCR = 0x00050f08;
 
-	PCDR0 = 0x130410c3;
-	PCDR1 = 0x09030911;
-
-	/* Clocks have changed. Notify clients */
-	clock_notifier_call_chain();
-
 	return 0;
 }
 
diff --git a/arch/arm/boards/pcm038/pll_init.S b/arch/arm/boards/pcm038/pll_init.S
deleted file mode 100644
index 0c1ff13..0000000
--- a/arch/arm/boards/pcm038/pll_init.S
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <config.h>
-#include <mach/imx-regs.h>
-#include <mach/imx-pll.h>
-#include <linux/linkage.h>
-
-#define writel(val, reg) \
-	ldr		r0,	=reg;	\
-	ldr		r1,	=val;	\
-	str		r1,   [r0];
-
-#define CSCR_VAL CSCR_USB_DIV(3) |	\
-		 CSCR_SD_CNT(3) |	\
-		 CSCR_MSHC_SEL |	\
-		 CSCR_H264_SEL |	\
-		 CSCR_SSI1_SEL |	\
-		 CSCR_SSI2_SEL |	\
-		 CSCR_MCU_SEL |		\
-		 CSCR_ARM_SRC_MPLL |	\
-		 CSCR_SP_SEL |		\
-		 CSCR_ARM_DIV(0) |	\
-		 CSCR_FPM_EN |		\
-		 CSCR_SPEN |		\
-		 CSCR_MPEN |		\
-		 CSCR_AHB_DIV(1)
-
-ENTRY(pcm038_pll_init)
-
-	writel(IMX_PLL_PD(0) |
-		 IMX_PLL_MFD(51) |
-		 IMX_PLL_MFI(7) |
-		 IMX_PLL_MFN(35), MPCTL0) /* 399 MHz */
-
-	writel(IMX_PLL_PD(1) |
-		 IMX_PLL_MFD(12) |
-		 IMX_PLL_MFI(9) |
-		 IMX_PLL_MFN(3), SPCTL0) /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */
-
-	writel(CSCR_VAL | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART, CSCR)
-
-	ldr r2, =16000
-1:
-	subs    r2, r2, #1
-	nop
-	bcs 1b
-
-	mov     pc, lr
-ENDPROC(pcm038_pll_init)
-
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 04:56:48 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 8 Oct 2010 10:56:48 +0200
Subject: Switch the i.MX27's PLL in a safe manner
In-Reply-To: <1286527540-9857-1-git-send-email-jbe@pengutronix.de>
References: <1286527540-9857-1-git-send-email-jbe@pengutronix.de>
Message-ID: <201010081056.48308.jbe@pengutronix.de>

Juergen Beisert wrote:
> This patch is required to switch the PLL of the i.MX27 at runtime without
> data loss and random system crashes (but it is only required in this way if
> the CPU core does not run at 1.45 V immediatly after reset).

:-( git does not like me (or I do not like git...) Must resend. This one is 
broken.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct  8 05:02:42 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 11:02:42 +0200
Subject: [2nd try] Switch the i.MX27's PLL in a safe manner
Message-ID: <1286528563-16026-1-git-send-email-jbe@pengutronix.de>

(hopefully this time with *all* files)

This patch is required to switch the PLL of the i.MX27 at runtime without data
loss and random system crashes (but it is only required in this way if the CPU
core does not run at 1.45 V immediatly after reset).

Currently related only to the phyCORE-i.MX27 platform.



From jbe at pengutronix.de  Fri Oct  8 05:02:43 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 11:02:43 +0200
Subject: [PATCH] Switch the i.MX27's PLL in a safe manner
In-Reply-To: <1286528563-16026-1-git-send-email-jbe@pengutronix.de>
References: <1286528563-16026-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286528563-16026-2-git-send-email-jbe@pengutronix.de>

Changing PLL settings is somehow tricky on the i.MX27: Whenever the clock
speed of the main PLL is changed, the clock stops for about 100 us until the
PLL locks into the new frequency. While this clock stop, also the SDRAM
controller cannot refresh the memory, because it uses the same clock source.
This can lead into data loss and random system crashes.

This patch divides the PLL setting in two steps. First step is to re-program
the PLL and clock settings to values possible at a core supply of 1.25 V.
Second step is to increase the core power supply to 1.45 V and switch the
CPU clock to the specified 400 MHz.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/pcm038/Makefile   |    2 +-
 arch/arm/boards/pcm038/lowlevel.c |    7 ++++
 arch/arm/boards/pcm038/pcm038.c   |   65 +++++++++++++++++++---------------
 arch/arm/boards/pcm038/pll.h      |   70 +++++++++++++++++++++++++++++++++++++
 arch/arm/boards/pcm038/pll_init.S |   48 -------------------------
 5 files changed, 114 insertions(+), 78 deletions(-)
 create mode 100644 arch/arm/boards/pcm038/pll.h
 delete mode 100644 arch/arm/boards/pcm038/pll_init.S

diff --git a/arch/arm/boards/pcm038/Makefile b/arch/arm/boards/pcm038/Makefile
index a681dda..970804e 100644
--- a/arch/arm/boards/pcm038/Makefile
+++ b/arch/arm/boards/pcm038/Makefile
@@ -1,3 +1,3 @@
 
-obj-y += lowlevel.o pll_init.o
+obj-y += lowlevel.o
 obj-y += pcm038.o
diff --git a/arch/arm/boards/pcm038/lowlevel.c b/arch/arm/boards/pcm038/lowlevel.c
index eb85e8f..b50e1c8 100644
--- a/arch/arm/boards/pcm038/lowlevel.c
+++ b/arch/arm/boards/pcm038/lowlevel.c
@@ -31,6 +31,8 @@
 #include <asm/system.h>
 #include <asm-generic/memory_layout.h>
 
+#include "pll.h"
+
 #ifdef CONFIG_NAND_IMX_BOOT
 static void __bare_init __naked insdram(void)
 {
@@ -68,6 +70,11 @@ void __bare_init __naked board_init_lowlevel(void)
 	if (r > 0xa0000000 && r < 0xb0000000)
 		board_init_lowlevel_return();
 
+	/* re-program the PLL prior(!) starting the SDRAM controller */
+	MPCTL0 = MPCTL0_VAL;
+	SPCTL0 = SPCTL0_VAL;
+	CSCR = CSCR_VAL | CSCR_UPDATE_DIS | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART;
+
 	/*
 	 * DDR on CSD0
 	 */
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index fda3262..3a9b413 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -44,6 +44,8 @@
 #include <mach/spi.h>
 #include <mach/iomux-mx27.h>
 
+#include "pll.h"
+
 static struct device_d cfi_dev = {
 	.id	  = -1,
 	.name     = "cfi_flash",
@@ -379,11 +381,6 @@ static struct device_d pcm038_serial_device = {
 
 static int pcm038_console_init(void)
 {
-	/* bring PLLs to reset default */
-	MPCTL0 = 0x00211803;
-	SPCTL0 = 0x1002700c;
-	CSCR = 0x33fc1307;
-
 	register_device(&pcm038_serial_device);
 
 	return 0;
@@ -391,40 +388,50 @@ static int pcm038_console_init(void)
 
 console_initcall(pcm038_console_init);
 
-extern void *pcm038_pll_init, *pcm038_pll_init_end;
-
-static int pcm038_power_init(void)
+/**
+ * The spctl0 register is a beast: Seems you can read it
+ * only one times without writing it again.
+ */
+static inline uint32_t get_pll_spctl10(void)
 {
-	int ret;
-	void *vram = (void*)0xffff4c00;
-	void (*pllfunc)(void) = vram;
+	uint32_t reg;
 
-	printf("initialising PLLs: 0x%p 0x%p\n", &pcm038_pll_init);
+	reg = SPCTL0;
+	SPCTL0 = reg;
 
-	memcpy(vram, &pcm038_pll_init, 0x100);
+	return reg;
+}
 
-	console_flush();
+/**
+ * If the PLL settings are in place switch the CPU core frequency to the max. value
+ */
+static int pcm038_power_init(void)
+{
+	uint32_t spctl0;
+	int ret;
 
-	ret = pmic_power();
-	if (ret) {
-		printf("Failed to initialize PMIC. Will continue with low CPU speed\n");
-		return 0;
+	spctl0 = get_pll_spctl10();
+
+	/* PLL registers already set to their final values? */
+	if (spctl0 == SPCTL0_VAL && MPCTL0 == MPCTL0_VAL) {
+		console_flush();
+		ret = pmic_power();
+		if (ret == 0) {
+			/* wait for required power level to run the CPU at 400 MHz */
+			udelay(100000);
+			CSCR = CSCR_VAL_FINAL;
+			PCDR0 = 0x130410c3;
+			PCDR1 = 0x09030911;
+			/* Clocks have changed. Notify clients */
+			clock_notifier_call_chain();
+		} else {
+			printf("Failed to initialize PMIC. Will continue with low CPU speed\n");
+		}
 	}
 
-	/* wait for good power level */
-	udelay(100000);
-
-	pllfunc();
-
 	/* clock gating enable */
 	GPCR = 0x00050f08;
 
-	PCDR0 = 0x130410c3;
-	PCDR1 = 0x09030911;
-
-	/* Clocks have changed. Notify clients */
-	clock_notifier_call_chain();
-
 	return 0;
 }
 
diff --git a/arch/arm/boards/pcm038/pll.h b/arch/arm/boards/pcm038/pll.h
new file mode 100644
index 0000000..13a7989
--- /dev/null
+++ b/arch/arm/boards/pcm038/pll.h
@@ -0,0 +1,70 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * @file
+ * @brief phyCORE-i.MX27 specific PLL setup
+ */
+
+#ifndef __PCM038_PLL_H
+#define __PCM038_PLL_H
+
+/* define the PLL setting we want to run the system  */
+
+/* main clock divider settings immediately after reset (at 1.25 V core supply) */
+#define CSCR_VAL (CSCR_USB_DIV(3) |	\
+		CSCR_SD_CNT(3) |	\
+		CSCR_MSHC_SEL |		\
+		CSCR_H264_SEL |		\
+		CSCR_SSI1_SEL |		\
+		CSCR_SSI2_SEL |		\
+		CSCR_SP_SEL | /* 26 MHz reference */ \
+		CSCR_MCU_SEL | /* 26 MHz reference */ \
+		CSCR_ARM_DIV(0) | /* CPU runs at MPLL/3 clock */ \
+		CSCR_AHB_DIV(1) | /* AHB runs at MPLL/6 clock */ \
+		CSCR_SPEN |		\
+		CSCR_MPEN)
+
+/* main clock divider settings after core voltage increases to 1.45 V */
+#define CSCR_VAL_FINAL (CSCR_USB_DIV(3) |	\
+		CSCR_SD_CNT(3) |	\
+		CSCR_MSHC_SEL |		\
+		CSCR_H264_SEL |		\
+		CSCR_SSI1_SEL |		\
+		CSCR_SSI2_SEL |		\
+		CSCR_SP_SEL | /* 26 MHz reference */ \
+		CSCR_MCU_SEL | /* 26 MHz reference */ \
+		CSCR_ARM_SRC_MPLL | /* use main MPLL clock */ \
+		CSCR_ARM_DIV(0) | /* CPU run at full MPLL clock */ \
+		CSCR_AHB_DIV(1) | /* AHB runs at MPLL/6 clock */ \
+		CSCR_SPEN |		\
+		CSCR_MPEN)
+
+/* MPLL should provide a 399 MHz clock from the 26 MHz reference */
+#define MPCTL0_VAL (IMX_PLL_PD(0) |	\
+		IMX_PLL_MFD(51) |	\
+		IMX_PLL_MFI(7) |	\
+		IMX_PLL_MFN(35))
+
+/* SPLL should provide a 240 MHz clock from the 26 MHz reference */
+#define SPCTL0_VAL (IMX_PLL_PD(1) |	\
+		IMX_PLL_MFD(12) |	\
+		IMX_PLL_MFI(9) |	\
+		IMX_PLL_MFN(3))
+
+
+#endif	/* __PCM038_PLL_H */
diff --git a/arch/arm/boards/pcm038/pll_init.S b/arch/arm/boards/pcm038/pll_init.S
deleted file mode 100644
index 0c1ff13..0000000
--- a/arch/arm/boards/pcm038/pll_init.S
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <config.h>
-#include <mach/imx-regs.h>
-#include <mach/imx-pll.h>
-#include <linux/linkage.h>
-
-#define writel(val, reg) \
-	ldr		r0,	=reg;	\
-	ldr		r1,	=val;	\
-	str		r1,   [r0];
-
-#define CSCR_VAL CSCR_USB_DIV(3) |	\
-		 CSCR_SD_CNT(3) |	\
-		 CSCR_MSHC_SEL |	\
-		 CSCR_H264_SEL |	\
-		 CSCR_SSI1_SEL |	\
-		 CSCR_SSI2_SEL |	\
-		 CSCR_MCU_SEL |		\
-		 CSCR_ARM_SRC_MPLL |	\
-		 CSCR_SP_SEL |		\
-		 CSCR_ARM_DIV(0) |	\
-		 CSCR_FPM_EN |		\
-		 CSCR_SPEN |		\
-		 CSCR_MPEN |		\
-		 CSCR_AHB_DIV(1)
-
-ENTRY(pcm038_pll_init)
-
-	writel(IMX_PLL_PD(0) |
-		 IMX_PLL_MFD(51) |
-		 IMX_PLL_MFI(7) |
-		 IMX_PLL_MFN(35), MPCTL0) /* 399 MHz */
-
-	writel(IMX_PLL_PD(1) |
-		 IMX_PLL_MFD(12) |
-		 IMX_PLL_MFI(9) |
-		 IMX_PLL_MFN(3), SPCTL0) /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */
-
-	writel(CSCR_VAL | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART, CSCR)
-
-	ldr r2, =16000
-1:
-	subs    r2, r2, #1
-	nop
-	bcs 1b
-
-	mov     pc, lr
-ENDPROC(pcm038_pll_init)
-
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct  8 08:24:31 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri,  8 Oct 2010 14:24:31 +0200
Subject: No subject
Message-ID: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>

Hi,

Here are some hush related fixes/improvements:

Sascha Hauer (3):
      hush: pass context around in shell
      hush: fix nasty memory leak in hush
      hush: implement getopt builtin

 common/hush.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 88 insertions(+), 10 deletions(-)



From s.hauer at pengutronix.de  Fri Oct  8 08:24:32 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri,  8 Oct 2010 14:24:32 +0200
Subject: [PATCH 1/3] hush: pass context around in shell
In-Reply-To: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
References: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286540674-17174-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/hush.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/common/hush.c b/common/hush.c
index 19e35f5..f22eca6 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -267,8 +267,8 @@ static void setup_string_in_str(struct in_str *i, const char *s);
 static int free_pipe_list(struct pipe *head, int indent);
 static int free_pipe(struct pipe *pi, int indent);
 /*  really run the final data structures: */
-static int run_list_real(struct pipe *pi);
-static int run_pipe_real(struct pipe *pi);
+static int run_list_real(struct p_context *ctx, struct pipe *pi);
+static int run_pipe_real(struct p_context *ctx, struct pipe *pi);
 /*   extended glob support: */
 /*   variable assignment: */
 static int is_assignment(const char *s);
@@ -515,7 +515,7 @@ static void setup_string_in_str(struct in_str *i, const char *s)
  * now has its stdout directed to the input of the appropriate pipe,
  * so this routine is noticeably simpler.
  */
-static int run_pipe_real(struct pipe *pi)
+static int run_pipe_real(struct p_context *ctx, struct pipe *pi)
 {
 	int i;
 	int nextin;
@@ -541,7 +541,7 @@ static int run_pipe_real(struct pipe *pi)
 	if (pi->num_progs == 1 && child->group) {
 		int rcode;
 		debug("non-subshell grouping\n");
-		rcode = run_list_real(child->group);
+		rcode = run_list_real(ctx, child->group);
 		return rcode;
 	} else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
 		for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ }
@@ -601,7 +601,7 @@ static int run_pipe_real(struct pipe *pi)
 	return -1;
 }
 
-static int run_list_real(struct pipe *pi)
+static int run_list_real(struct p_context *ctx, struct pipe *pi)
 {
 	char *save_name = NULL;
 	char **list = NULL;
@@ -699,7 +699,7 @@ static int run_list_real(struct pipe *pi)
 		}
 		if (pi->num_progs == 0)
 			continue;
-		rcode = run_pipe_real(pi);
+		rcode = run_pipe_real(ctx, pi);
 		debug("run_pipe_real returned %d\n",rcode);
 		if (rcode < -1) {
 			last_return_code = -rcode - 2;
@@ -853,11 +853,11 @@ static int xglob(o_string *dest, int flags, glob_t *pglob)
 }
 
 /* Select which version we will use */
-static int run_list(struct pipe *pi)
+static int run_list(struct p_context *ctx, struct pipe *pi)
 {
 	int rcode = 0;
 
-	rcode = run_list_real(pi);
+	rcode = run_list_real(ctx, pi);
 
 	/* free_pipe_list has the side effect of clearing memory
 	 * In the long run that function can be merged with run_list_real,
@@ -1371,7 +1371,7 @@ static int parse_stream_outer(struct p_context *ctx, struct in_str *inp, int fla
 			done_word(&temp, ctx);
 			done_pipe(ctx,PIPE_SEQ);
 			if (ctx->list_head->num_progs) {
-				code = run_list(ctx->list_head);
+				code = run_list(ctx, ctx->list_head);
 			} else {
 				free_pipe_list(ctx->list_head, 0);
 				continue;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct  8 08:24:33 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri,  8 Oct 2010 14:24:33 +0200
Subject: [PATCH 2/3] hush: fix nasty memory leak in hush
In-Reply-To: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
References: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286540674-17174-3-git-send-email-s.hauer@pengutronix.de>

Fix memory leak in globbing part of hush. a simple '['
on the command line was enough to trigger it.
We must call globfree() before setting the glob structure
to zero.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/hush.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/common/hush.c b/common/hush.c
index f22eca6..1b5cd99 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -790,6 +790,7 @@ static int globhack(const char *src, int flags, glob_t *pglob)
 	}
 	dest = xmalloc(cnt);
 	if (!(flags & GLOB_APPEND)) {
+		globfree(pglob);
 		pglob->gl_pathv = NULL;
 		pglob->gl_pathc = 0;
 		pglob->gl_offs = 0;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct  8 08:24:34 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri,  8 Oct 2010 14:24:34 +0200
Subject: [PATCH 3/3] hush: implement getopt builtin
In-Reply-To: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
References: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286540674-17174-4-git-send-email-s.hauer@pengutronix.de>

Positional parameters are not nice, so implement a getopt
function. This has to be done as a builtin because otherwise
we have no access to the parents argc/argv.

getopt works as expected, here is a little example:

while getopt "hs:" OPT
do
        if [ $OPT = h ]; then
                echo "usage"
                exit 1
        else
                echo "scr: opt: $OPT optarg: $OPTARG"
	fi
done

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/hush.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/common/hush.c b/common/hush.c
index 1b5cd99..d16783c 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -120,6 +120,8 @@
 #include <fs.h>
 #include <libbb.h>
 #include <glob.h>
+#include <getopt.h>
+#include <linux/list.h>
 
 /*cmd_boot.c*/
 extern int do_bootd(struct command *cmdtp, int flag, int argc, char *argv[]);      /* do_bootd */
@@ -174,6 +176,12 @@ typedef enum {
 #define FLAG_PARSE_SEMICOLON (1 << 1)	  /* symbol ';' is special for parser */
 #define FLAG_REPARSING       (1 << 2)	  /* >=2nd pass */
 
+struct option {
+	struct list_head	list;
+	char	opt;
+	char	*optarg;
+};
+
 /* This holds pointers to the various results of parsing */
 struct p_context {
 	struct child_prog *child;
@@ -187,6 +195,9 @@ struct p_context {
 
 	char **global_argv;
 	unsigned int global_argc;
+
+	int options_parsed;
+	struct list_head options;
 };
 
 
@@ -274,6 +285,7 @@ static int run_pipe_real(struct p_context *ctx, struct pipe *pi);
 static int is_assignment(const char *s);
 /*   data structure manipulation: */
 static void initialize_context(struct p_context *ctx);
+static void release_context(struct p_context *ctx);
 static int done_word(o_string *dest, struct p_context *ctx);
 static int done_command(struct p_context *ctx);
 static int done_pipe(struct p_context *ctx, pipe_style type);
@@ -498,6 +510,48 @@ static void setup_string_in_str(struct in_str *i, const char *s)
 	i->p = s;
 }
 
+static int builtin_getopt(struct p_context *ctx, struct child_prog *child)
+{
+	char *optstring, *var;
+	int opt;
+	char opta[2];
+	struct option *o;
+
+	if (child->argc != 3)
+		return -1;
+
+	optstring = child->argv[1];
+	var = child->argv[2];
+
+	getopt_reset();
+
+	if (!ctx->options_parsed) {
+		while((opt = getopt(ctx->global_argc, ctx->global_argv, optstring)) > 0) {
+			o = xzalloc(sizeof(*o));
+			o->opt = opt;
+			o->optarg = xstrdup(optarg);
+			list_add_tail(&o->list, &ctx->options);
+		}
+	}
+
+	ctx->options_parsed = 1;
+
+	if (list_empty(&ctx->options))
+		return -1;
+
+	o = list_first_entry(&ctx->options, struct option, list);
+
+	opta[0] = o->opt;
+	opta[1] = 0;
+	setenv(var, opta);
+	setenv("OPTARG", o->optarg);
+
+	free(o->optarg);
+	list_del(&o->list);
+	free(o);
+
+	return 0;
+}
 
 /* run_pipe_real() starts all the jobs, but doesn't wait for anything
  * to finish.  See checkjobs().
@@ -583,10 +637,14 @@ static int run_pipe_real(struct p_context *ctx, struct pipe *pi)
 			struct p_context ctx;
 			str = make_string((child->argv + i));
 			parse_string_outer(&ctx, str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
+			release_context(&ctx);
 			free(str);
 			return last_return_code;
 		}
 
+		if (!strcmp(child->argv[i], "getopt"))
+			return builtin_getopt(ctx, child);
+
 		if (strchr(child->argv[i], '/')) {
 			return execute_script(child->argv[i], child->argc-i, &child->argv[i]);
 		}
@@ -929,9 +987,21 @@ static void initialize_context(struct p_context *ctx)
 	ctx->w=RES_NONE;
 	ctx->stack=NULL;
 	ctx->old_flag=0;
+	ctx->options_parsed = 0;
+	INIT_LIST_HEAD(&ctx->options);
 	done_command(ctx);   /* creates the memory for working child */
 }
 
+static void release_context(struct p_context *ctx)
+{
+	struct option *opt, *tmp;
+
+	list_for_each_entry_safe(opt, tmp, &ctx->options, list) {
+		free(opt->optarg);
+		free(opt);
+	}
+}
+
 /* normal return is 0
  * if a reserved word is found, and processed, return 1
  * should handle if, then, elif, else, fi, for, while, until, do, done.
@@ -1534,7 +1604,12 @@ static char * make_string(char ** inp)
 int run_command (const char *cmd, int flag)
 {
 	struct p_context ctx;
-	return parse_string_outer(&ctx, cmd, FLAG_PARSE_SEMICOLON);
+	int ret;
+
+	ret = parse_string_outer(&ctx, cmd, FLAG_PARSE_SEMICOLON);
+	release_context(&ctx);
+
+	return ret;
 }
 
 static int execute_script(const char *path, int argc, char *argv[])
@@ -1565,6 +1640,7 @@ static int source_script(const char *path, int argc, char *argv[])
 
 	ret = parse_string_outer(&ctx, script, FLAG_PARSE_SEMICOLON);
 
+	release_context(&ctx);
 	free(script);
 
 	return ret;
@@ -1578,6 +1654,7 @@ int run_shell(void)
 
 	setup_file_in_str(&input);
 	rcode = parse_stream_outer(&ctx, &input, FLAG_PARSE_SEMICOLON);
+	release_context(&ctx);
 	return rcode;
 }
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct  8 08:27:48 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 8 Oct 2010 14:27:48 +0200
Subject: [PATCH 3/5] defaultenv: add xmodem support for update
In-Reply-To: <1286469458-11362-3-git-send-email-plagnioj@jcrosoft.com>
References: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
	<1286469458-11362-3-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <20101008122747.GN28242@pengutronix.de>

On Thu, Oct 07, 2010 at 06:37:36PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> this is add as last parameter to do not change the default behavior
> 
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> ---
>  defaultenv/bin/_update       |   26 +++++++++++++++++---------
>  defaultenv/bin/init          |    5 +++--
>  defaultenv/bin/update_kernel |    7 ++++++-
>  defaultenv/bin/update_rootfs |    7 ++++++-
>  4 files changed, 32 insertions(+), 13 deletions(-)
> 
> diff --git a/defaultenv/bin/_update b/defaultenv/bin/_update
> index ddd6b84..c60ff88 100644
> --- a/defaultenv/bin/_update
> +++ b/defaultenv/bin/_update
> @@ -14,14 +14,16 @@ if [ $# = 1 ]; then
>  	image=$1
>  fi
>  
> -if [ x$ip = xdhcp ]; then
> -	dhcp
> -fi
> -
> -ping $eth0.serverip
> -if [ $? -ne 0 ] ; then
> -	echo "Server did not reply! Update aborted."
> -	exit 1
> +if [ x$mode = xnet ]; then
> +	if [ x$ip = xdhcp ]; then
> +		dhcp
> +	fi
> +
> +	ping $eth0.serverip
> +	if [ $? -ne 0 ] ; then
> +		echo "Server did not reply! Update aborted."
> +		exit 1
> +	fi
>  fi
>  
>  unprotect $part
> @@ -34,6 +36,12 @@ erase $part
>  echo
>  echo "flashing $image to $part"
>  echo
> -tftp $image $part
> +
> +if [ x$mode = xnet ]; then
> +	tftp $image $part
> +else
> +	loadb -f $image -c
> +	cp $image $part
> +fi
>  
>  protect $part
> diff --git a/defaultenv/bin/init b/defaultenv/bin/init
> index a55e8e6..db2b525 100644
> --- a/defaultenv/bin/init
> +++ b/defaultenv/bin/init
> @@ -25,8 +25,9 @@ echo -n "Hit any key to stop autoboot: "
>  timeout -a $autoboot_timeout
>  if [ $? != 0 ]; then
>  	echo
> -	echo "type update_kernel nand|nor [<imagename>] to update kernel into flash"
> -	echo "type update_rootfs nand|nor [<imagename>] to update rootfs into flash"
> +	echo "default mode is net"
> +	echo "type update_kernel nand|nor [<imagename>] [net|xmodem] to update kernel into flash"
> +	echo "type update_rootfs nand|nor [<imagename>] [net|xmodem] to update rootfs into flash"
>  	echo
>  	exit
>  fi
> diff --git a/defaultenv/bin/update_kernel b/defaultenv/bin/update_kernel
> index 1d35ed9..b29927f 100644
> --- a/defaultenv/bin/update_kernel
> +++ b/defaultenv/bin/update_kernel
> @@ -2,14 +2,19 @@
>  
>  . /env/config
>  image=$kernelimage
> +mode=net
>  
>  if [ x$1 = xnand ]; then
>  	part=/dev/nand0.kernel.bb
>  elif [ x$1 = xnor ]; then
>  	part=/dev/nor0.kernel
>  else
> -	echo "usage: $0 nor|nand [imagename]"
> +	echo "usage: $0 nor|nand [imagename] [net|xmodem]"
>  	exit 1
>  fi
>  
> +if [ x$3 != x ]; then
> +	mode=$3
> +fi
> +
>  . /env/bin/_update $2
> diff --git a/defaultenv/bin/update_rootfs b/defaultenv/bin/update_rootfs
> index 6366315..bac74ca 100644
> --- a/defaultenv/bin/update_rootfs
> +++ b/defaultenv/bin/update_rootfs
> @@ -3,14 +3,19 @@
>  . /env/config
>  
>  image=$rootfsimage
> +mode=net
>  
>  if [ x$1 = xnand ]; then
>  	part=/dev/nand0.root.bb
>  elif [ x$1 = xnor ]; then
>  	part=/dev/nor0.root
>  else
> -	echo "usage: $0 nor|nand [imagename]"
> +	echo "usage: $0 nor|nand [imagename] [net|xmodem]"

I'm not really happy with this patch. We have 3 positional parameters
now and with xmodem it makes no sense to supply an image name,
nontheless we have to supply it because otherwise we do not have three
arguments.
I just posted a patch adding a getopt command to hush. Maybe this could
improve the situation here?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From plagnioj at jcrosoft.com  Fri Oct  8 08:36:27 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 8 Oct 2010 14:36:27 +0200
Subject: [PATCH 3/3] hush: implement getopt builtin
In-Reply-To: <1286540674-17174-4-git-send-email-s.hauer@pengutronix.de>
References: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
	<1286540674-17174-4-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20101008123627.GC30252@game.jcrosoft.org>

On 14:24 Fri 08 Oct     , Sascha Hauer wrote:
> Positional parameters are not nice, so implement a getopt
> function. This has to be done as a builtin because otherwise
> we have no access to the parents argc/argv.
> 
> getopt works as expected, here is a little example:
> 
> while getopt "hs:" OPT
> do
>         if [ $OPT = h ]; then
>                 echo "usage"
>                 exit 1
>         else
>                 echo "scr: opt: $OPT optarg: $OPTARG"
> 	fi
> done
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
how about make it optional?

Best Regards,
J.


From plagnioj at jcrosoft.com  Fri Oct  8 08:39:06 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 8 Oct 2010 14:39:06 +0200
Subject: [PATCH 1/5] defaultenv: introduce
	CONFIG_DEFAULT_ENVIRONMENT_GENERIC to enable it
In-Reply-To: <20101008065933.GM28242@pengutronix.de>
References: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
	<20101008065933.GM28242@pengutronix.de>
Message-ID: <20101008123906.GD30252@game.jcrosoft.org>

On 08:59 Fri 08 Oct     , Sascha Hauer wrote:
> On Thu, Oct 07, 2010 at 06:37:34PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > this will we usefull to enable functionnality if used
> > 
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> > ---
> >  arch/arm/configs/neso_defconfig   |    3 ++-
> >  arch/arm/configs/pca100_defconfig |    3 ++-
> >  arch/arm/configs/pcm037_defconfig |    3 ++-
> >  arch/arm/configs/pcm038_defconfig |    3 ++-
> >  arch/arm/configs/pcm043_defconfig |    3 ++-
> >  common/Kconfig                    |    7 +++++++
> >  common/Makefile                   |    4 ++++
> >  7 files changed, 21 insertions(+), 5 deletions(-)
> > 
> >  
> > +config DEFAULT_ENVIRONMENT_GENERIC
> > +	bool
> > +	depends on DEFAULT_ENVIRONMENT
> > +	prompt "Default environment generic"
> > +	help
> > +	  Generic barebox default env
> 
> How about a bit more verbosity:
> 
> 	prompt "Add generic default environment"
> 	help
> 	  With this option barebox will use the generic default
> 	  environment found under defaultenv/ in the src tree.
> 	  The Directory given with DEFAULT_ENVIRONMENT_PATH
> 	  will be added to the default environment. This should
> 	  at least contain a /env/config file.
> 
> > +
> >  config DEFAULT_ENVIRONMENT_PATH
> >  	string
> >  	depends on DEFAULT_ENVIRONMENT
> > diff --git a/common/Makefile b/common/Makefile
> > index e56dbc2..b42ab7a 100644
> > --- a/common/Makefile
> > +++ b/common/Makefile
> > @@ -26,6 +26,10 @@ ifdef CONFIG_DEFAULT_ENVIRONMENT
> >  $(obj)/startup.o: include/generated/barebox_default_env.h
> >  $(obj)/env.o: include/generated/barebox_default_env.h
> >  
> > +ifeq ($(CONFIG_DEFAULT_ENVIRONMENT_GENERIC),y)
> > +CONFIG_DEFAULT_ENVIRONMENT_PATH += defaultenv
> > +endif
> 
> This reverses the order the different environment directories are
> parsed. Now the files from defaultenv will overwrite the ones
> from DEFAULT_ENVIRONMENT_PATH. I made it intentionally the other
> way round.
so we need to specify it in the Kconfig

Best Regards,
J.


From s.hauer at pengutronix.de  Fri Oct  8 08:45:15 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 8 Oct 2010 14:45:15 +0200
Subject: [PATCH 3/3] hush: implement getopt builtin
In-Reply-To: <20101008123627.GC30252@game.jcrosoft.org>
References: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
	<1286540674-17174-4-git-send-email-s.hauer@pengutronix.de>
	<20101008123627.GC30252@game.jcrosoft.org>
Message-ID: <20101008124515.GP28242@pengutronix.de>

On Fri, Oct 08, 2010 at 02:36:27PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 14:24 Fri 08 Oct     , Sascha Hauer wrote:
> > Positional parameters are not nice, so implement a getopt
> > function. This has to be done as a builtin because otherwise
> > we have no access to the parents argc/argv.
> > 
> > getopt works as expected, here is a little example:
> > 
> > while getopt "hs:" OPT
> > do
> >         if [ $OPT = h ]; then
> >                 echo "usage"
> >                 exit 1
> >         else
> >                 echo "scr: opt: $OPT optarg: $OPTARG"
> > 	fi
> > done
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> how about make it optional?

Probably a good idea. I just had in mind that we need to adjust
the defconfigs then to still have a working defaultenv.

How about making it optional and combined with your defaultenv-Kconfig
patch we could do a

	select HUSH
	select HUSH_GETOPT

to make sure all commands needed by the defaultenv are in place.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct  8 09:31:31 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 8 Oct 2010 15:31:31 +0200
Subject: [PATCH 3/3 v2] hush: implement getopt builtin
In-Reply-To: <1286540674-17174-4-git-send-email-s.hauer@pengutronix.de>
References: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
	<1286540674-17174-4-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20101008133131.GS28242@pengutronix.de>


Positional parameters are not nice, so implement a getopt
function. This has to be done as a builtin because otherwise
we have no access to the parents argc/argv.

getopt works as expected, here is a little example:

while getopt "hs:" OPT
do
        if [ $OPT = h ]; then
                echo "usage"
                exit 1
        else
                echo "scr: opt: $OPT optarg: $OPTARG"
	fi
done

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---

v2: make getopt optional, add help text.

 common/Kconfig |    7 ++++
 common/hush.c  |  110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index ad70cde..123d070 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -248,6 +248,13 @@ config HUSH_FANCY_PROMPT
 	  Allow to set PS1 from the command line. PS1 can have several escaped commands
 	  like \h for CONFIG_BOARDINFO or \w for the current working directory.
 
+config HUSH_GETOPT
+	bool
+	depends on SHELL_HUSH
+	prompt "enable builtin getopt"
+	help
+	  This enables a getopt function builtin to hush.
+
 config CMDLINE_EDITING
 	bool
 	prompt "Enable command line editing"
diff --git a/common/hush.c b/common/hush.c
index 1b5cd99..3359f37 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -120,6 +120,8 @@
 #include <fs.h>
 #include <libbb.h>
 #include <glob.h>
+#include <getopt.h>
+#include <linux/list.h>
 
 /*cmd_boot.c*/
 extern int do_bootd(struct command *cmdtp, int flag, int argc, char *argv[]);      /* do_bootd */
@@ -174,6 +176,12 @@ typedef enum {
 #define FLAG_PARSE_SEMICOLON (1 << 1)	  /* symbol ';' is special for parser */
 #define FLAG_REPARSING       (1 << 2)	  /* >=2nd pass */
 
+struct option {
+	struct list_head	list;
+	char	opt;
+	char	*optarg;
+};
+
 /* This holds pointers to the various results of parsing */
 struct p_context {
 	struct child_prog *child;
@@ -187,6 +195,9 @@ struct p_context {
 
 	char **global_argv;
 	unsigned int global_argc;
+
+	int options_parsed;
+	struct list_head options;
 };
 
 
@@ -274,6 +285,7 @@ static int run_pipe_real(struct p_context *ctx, struct pipe *pi);
 static int is_assignment(const char *s);
 /*   data structure manipulation: */
 static void initialize_context(struct p_context *ctx);
+static void release_context(struct p_context *ctx);
 static int done_word(o_string *dest, struct p_context *ctx);
 static int done_command(struct p_context *ctx);
 static int done_pipe(struct p_context *ctx, pipe_style type);
@@ -498,6 +510,50 @@ static void setup_string_in_str(struct in_str *i, const char *s)
 	i->p = s;
 }
 
+#ifdef CONFIG_HUSH_GETOPT
+static int builtin_getopt(struct p_context *ctx, struct child_prog *child)
+{
+	char *optstring, *var;
+	int opt;
+	char opta[2];
+	struct option *o;
+
+	if (child->argc != 3)
+		return -2 - 1;
+
+	optstring = child->argv[1];
+	var = child->argv[2];
+
+	getopt_reset();
+
+	if (!ctx->options_parsed) {
+		while((opt = getopt(ctx->global_argc, ctx->global_argv, optstring)) > 0) {
+			o = xzalloc(sizeof(*o));
+			o->opt = opt;
+			o->optarg = xstrdup(optarg);
+			list_add_tail(&o->list, &ctx->options);
+		}
+	}
+
+	ctx->options_parsed = 1;
+
+	if (list_empty(&ctx->options))
+		return -1;
+
+	o = list_first_entry(&ctx->options, struct option, list);
+
+	opta[0] = o->opt;
+	opta[1] = 0;
+	setenv(var, opta);
+	setenv("OPTARG", o->optarg);
+
+	free(o->optarg);
+	list_del(&o->list);
+	free(o);
+
+	return 0;
+}
+#endif
 
 /* run_pipe_real() starts all the jobs, but doesn't wait for anything
  * to finish.  See checkjobs().
@@ -583,10 +639,14 @@ static int run_pipe_real(struct p_context *ctx, struct pipe *pi)
 			struct p_context ctx;
 			str = make_string((child->argv + i));
 			parse_string_outer(&ctx, str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
+			release_context(&ctx);
 			free(str);
 			return last_return_code;
 		}
-
+#ifdef CONFIG_HUSH_GETOPT
+		if (!strcmp(child->argv[i], "getopt"))
+			return builtin_getopt(ctx, child);
+#endif
 		if (strchr(child->argv[i], '/')) {
 			return execute_script(child->argv[i], child->argc-i, &child->argv[i]);
 		}
@@ -929,9 +989,23 @@ static void initialize_context(struct p_context *ctx)
 	ctx->w=RES_NONE;
 	ctx->stack=NULL;
 	ctx->old_flag=0;
+	ctx->options_parsed = 0;
+	INIT_LIST_HEAD(&ctx->options);
 	done_command(ctx);   /* creates the memory for working child */
 }
 
+static void release_context(struct p_context *ctx)
+{
+#ifdef CONFIG_HUSH_GETOPT
+	struct option *opt, *tmp;
+
+	list_for_each_entry_safe(opt, tmp, &ctx->options, list) {
+		free(opt->optarg);
+		free(opt);
+	}
+#endif
+}
+
 /* normal return is 0
  * if a reserved word is found, and processed, return 1
  * should handle if, then, elif, else, fi, for, while, until, do, done.
@@ -1534,7 +1608,12 @@ static char * make_string(char ** inp)
 int run_command (const char *cmd, int flag)
 {
 	struct p_context ctx;
-	return parse_string_outer(&ctx, cmd, FLAG_PARSE_SEMICOLON);
+	int ret;
+
+	ret = parse_string_outer(&ctx, cmd, FLAG_PARSE_SEMICOLON);
+	release_context(&ctx);
+
+	return ret;
 }
 
 static int execute_script(const char *path, int argc, char *argv[])
@@ -1565,6 +1644,7 @@ static int source_script(const char *path, int argc, char *argv[])
 
 	ret = parse_string_outer(&ctx, script, FLAG_PARSE_SEMICOLON);
 
+	release_context(&ctx);
 	free(script);
 
 	return ret;
@@ -1578,6 +1658,7 @@ int run_shell(void)
 
 	setup_file_in_str(&input);
 	rcode = parse_stream_outer(&ctx, &input, FLAG_PARSE_SEMICOLON);
+	release_context(&ctx);
 	return rcode;
 }
 
@@ -1628,6 +1709,31 @@ BAREBOX_CMD_START(source)
 	BAREBOX_CMD_HELP(cmd_source_help)
 BAREBOX_CMD_END
 
+#ifdef CONFIG_HUSH_GETOPT
+static int do_getopt(struct command *cmdtp, int argc, char *argv[])
+{
+	/*
+	 * This function is never reached. The 'getopt' command is
+	 * only here to provide a help text for the getopt builtin.
+	 */
+	return 0;
+}
+
+static const __maybe_unused char cmd_getopt_help[] =
+"Usage: getopt <optstring> <var>\n"
+"\n"
+"hush option parser. <optstring> is a string with valid options. Add\n"
+"a colon to an options if this option has a required argument or two\n"
+"colons for an optional argument. The current option is saved in <var>,\n"
+"arguments are saved in OPTARG.\n";
+
+BAREBOX_CMD_START(getopt)
+	.cmd		= do_getopt,
+	.usage		= "getopt <optstring> <var>",
+	BAREBOX_CMD_HELP(cmd_getopt_help)
+BAREBOX_CMD_END
+#endif
+
 /**
  * @file
  * @brief A prototype Bourne shell grammar parser
-- 
1.7.2.3

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct  8 09:41:41 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 8 Oct 2010 15:41:41 +0200
Subject: [PATCH 3/4] Add the i.MX23-EVK platform (WIP)
In-Reply-To: <1286463597-16948-4-git-send-email-jbe@pengutronix.de>
References: <1286463597-16948-1-git-send-email-jbe@pengutronix.de>
	<1286463597-16948-4-git-send-email-jbe@pengutronix.de>
Message-ID: <20101008134141.GT28242@pengutronix.de>

Hi J?rgen,

can you regenerate the config with make savedefconfig please? Also
applies to the chumby patch.

Sascha

On Thu, Oct 07, 2010 at 04:59:56PM +0200, Juergen Beisert wrote:
> Note: This is work in progress. Use with care.
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  arch/arm/Makefile                             |    2 +
>  arch/arm/boards/freescale-mx23-evk/Makefile   |    2 +
>  arch/arm/boards/freescale-mx23-evk/config.h   |   16 ++
>  arch/arm/boards/freescale-mx23-evk/mx23-evk.c |   80 +++++++++
>  arch/arm/configs/imx23evk_defconfig           |  224 +++++++++++++++++++++++++
>  arch/arm/mach-stm/Kconfig                     |    7 +
>  6 files changed, 331 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/boards/freescale-mx23-evk/Makefile
>  create mode 100644 arch/arm/boards/freescale-mx23-evk/config.h
>  create mode 100644 arch/arm/boards/freescale-mx23-evk/mx23-evk.c
>  create mode 100644 arch/arm/configs/imx23evk_defconfig
> 
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 77b6cf4..75fa6d3 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -41,6 +41,7 @@ CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
>  machine-$(CONFIG_ARCH_AT91)		:= at91
>  machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
>  machine-$(CONFIG_ARCH_IMX)		:= imx
> +machine-$(CONFIG_ARCH_STM)		:= stm
>  machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
>  machine-$(CONFIG_ARCH_NETX)		:= netx
>  machine-$(CONFIG_ARCH_OMAP)		:= omap
> @@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
>  board-$(CONFIG_MACH_PM9263)			:= pm9263
>  board-$(CONFIG_MACH_SCB9328)			:= scb9328
>  board-$(CONFIG_MACH_NESO)			:= guf-neso
> +board-$(CONFIG_MACH_MX23EVK)			:= freescale-mx23-evk
>  
>  machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
>  
> diff --git a/arch/arm/boards/freescale-mx23-evk/Makefile b/arch/arm/boards/freescale-mx23-evk/Makefile
> new file mode 100644
> index 0000000..cffb561
> --- /dev/null
> +++ b/arch/arm/boards/freescale-mx23-evk/Makefile
> @@ -0,0 +1,2 @@
> +#
> +obj-y := mx23-evk.o
> diff --git a/arch/arm/boards/freescale-mx23-evk/config.h b/arch/arm/boards/freescale-mx23-evk/config.h
> new file mode 100644
> index 0000000..4b3da8f
> --- /dev/null
> +++ b/arch/arm/boards/freescale-mx23-evk/config.h
> @@ -0,0 +1,16 @@
> +/*
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> diff --git a/arch/arm/boards/freescale-mx23-evk/mx23-evk.c b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
> new file mode 100644
> index 0000000..d361320
> --- /dev/null
> +++ b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
> @@ -0,0 +1,80 @@
> +/*
> + * (C) Copyright 2010 Juergen Beisert - Pengutronix
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <gpio.h>
> +#include <environment.h>
> +#include <asm/armlinux.h>
> +#include <generated/mach-types.h>
> +#include <mach/imx-regs.h>
> +
> +static struct memory_platform_data ram_pdata = {
> +	.name = "ram0",
> +	.flags = DEVFS_RDWR,
> +};
> +
> +static struct device_d sdram_dev = {
> +	.name     = "mem",
> +	.map_base = IMX_MEMORY_BASE,
> +	.size     = 32 * 1024 * 1024,
> +	.platform_data = &ram_pdata,
> +};
> +
> +static int mx23_evk_devices_init(void)
> +{
> +	register_device(&sdram_dev);
> +
> +	armlinux_add_dram(&sdram_dev);
> +	armlinux_set_bootparams((void*)(IMX_MEMORY_BASE + 0x100));
> +	armlinux_set_architecture(MACH_TYPE_MX23EVK);
> +
> +	return 0;
> +}
> +
> +device_initcall(mx23_evk_devices_init);
> +
> +static struct device_d mx23_evk_serial_device = {
> +	.name     = "stm_serial",
> +	.map_base = IMX_DBGUART_BASE,
> +	.size     = 8192,
> +};
> +
> +static int mx23_evk_console_init(void)
> +{
> +	return register_device(&mx23_evk_serial_device);
> +}
> +
> +console_initcall(mx23_evk_console_init);
> +
> +/** @page mx23_evk Freescale's i.MX23 evaluation kit
> +
> +This CPU card is based on an i.MX23 CPU. The card is shipped with:
> +
> +- 32 MiB synchronous dynamic RAM (mobile DDR type)
> +- ENC28j60 based network (over SPI)
> +
> +Memory layout when @b barebox is running:
> +
> +- 0x40000000 start of SDRAM
> +- 0x40000100 start of kernel's boot parameters
> +  - below malloc area: stack area
> +  - below barebox: malloc area
> +- 0x41000000 start of @b barebox
> +*/
> diff --git a/arch/arm/configs/imx23evk_defconfig b/arch/arm/configs/imx23evk_defconfig
> new file mode 100644
> index 0000000..a3d3e25
> --- /dev/null
> +++ b/arch/arm/configs/imx23evk_defconfig
> @@ -0,0 +1,224 @@
> +#
> +# Automatically generated make config: don't edit
> +# Linux barebox version: 2010.09.0
> +# Thu Oct  7 16:36:33 2010
> +#
> +# CONFIG_BOARD_LINKER_SCRIPT is not set
> +CONFIG_GENERIC_LINKER_SCRIPT=y
> +CONFIG_ARM=y
> +
> +#
> +# System Type
> +#
> +# CONFIG_ARCH_AT91 is not set
> +# CONFIG_ARCH_EP93XX is not set
> +# CONFIG_ARCH_IMX is not set
> +CONFIG_ARCH_STM=y
> +# CONFIG_ARCH_NETX is not set
> +# CONFIG_ARCH_NOMADIK is not set
> +# CONFIG_ARCH_OMAP is not set
> +# CONFIG_ARCH_S3C24xx is not set
> +
> +#
> +# Processor Type
> +#
> +CONFIG_CPU_32=y
> +CONFIG_CPU_ARM926T=y
> +CONFIG_CPU_32v5=y
> +
> +#
> +# processor features
> +#
> +CONFIG_ARCH_TEXT_BASE=0x42000000
> +CONFIG_BOARDINFO="Chumby Falconwing"
> +
> +#
> +# SigmaTel/Freescale i.MX System-on-Chip
> +#
> +CONFIG_ARCH_IMX23=y
> +# CONFIG_MACH_MX23EVK is not set
> +CONFIG_MACH_CHUMBY=y
> +
> +#
> +# Board specific settings       
> +#
> +CONFIG_AEABI=y
> +
> +#
> +# Arm specific settings         
> +#
> +CONFIG_CMD_ARM_CPUINFO=y
> +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
> +CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
> +CONFIG_GREGORIAN_CALENDER=y
> +CONFIG_HAS_KALLSYMS=y
> +CONFIG_HAS_MODULES=y
> +CONFIG_CMD_MEMORY=y
> +CONFIG_ENV_HANDLING=y
> +CONFIG_GENERIC_GPIO=y
> +
> +#
> +# General Settings              
> +#
> +CONFIG_LOCALVERSION_AUTO=y
> +
> +#
> +# memory layout                 
> +#
> +CONFIG_HAVE_MMU=y
> +# CONFIG_MMU is not set
> +CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
> +CONFIG_TEXT_BASE=0x42000000
> +CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
> +CONFIG_MEMORY_LAYOUT_DEFAULT=y
> +# CONFIG_MEMORY_LAYOUT_FIXED is not set
> +CONFIG_STACK_SIZE=0x8000
> +CONFIG_MALLOC_SIZE=0x400000
> +CONFIG_BROKEN=y
> +# CONFIG_EXPERIMENTAL is not set
> +# CONFIG_KALLSYMS is not set
> +CONFIG_PROMPT="chumby:"
> +CONFIG_BAUDRATE=115200
> +CONFIG_LONGHELP=y
> +CONFIG_CBSIZE=1024
> +CONFIG_MAXARGS=16
> +CONFIG_SHELL_HUSH=y
> +# CONFIG_SHELL_SIMPLE is not set
> +# CONFIG_GLOB is not set
> +CONFIG_PROMPT_HUSH_PS2="> "
> +# CONFIG_HUSH_FANCY_PROMPT is not set
> +CONFIG_CMDLINE_EDITING=y
> +CONFIG_AUTO_COMPLETE=y
> +# CONFIG_MENU is not set
> +# CONFIG_PASSWORD is not set
> +CONFIG_DYNAMIC_CRC_TABLE=y
> +CONFIG_ERRNO_MESSAGES=y
> +CONFIG_TIMESTAMP=y
> +CONFIG_CONSOLE_FULL=y
> +CONFIG_CONSOLE_ACTIVATE_FIRST=y
> +# CONFIG_OF_FLAT_TREE is not set
> +CONFIG_PARTITION=y
> +# CONFIG_DEFAULT_ENVIRONMENT is not set
> +
> +#
> +# Debugging                     
> +#
> +CONFIG_DEBUG_INFO=y
> +# CONFIG_ENABLE_FLASH_NOISE is not set
> +# CONFIG_ENABLE_PARTITION_NOISE is not set
> +# CONFIG_ENABLE_DEVICE_NOISE is not set
> +
> +#
> +# Commands                      
> +#
> +
> +#
> +# scripting                     
> +#
> +CONFIG_CMD_EDIT=y
> +CONFIG_CMD_SLEEP=y
> +CONFIG_CMD_SAVEENV=y
> +CONFIG_CMD_LOADENV=y
> +CONFIG_CMD_EXPORT=y
> +CONFIG_CMD_PRINTENV=y
> +CONFIG_CMD_READLINE=y
> +CONFIG_CMD_TRUE=y
> +CONFIG_CMD_FALSE=y
> +# CONFIG_CMD_LOGIN is not set
> +# CONFIG_CMD_PASSWD is not set
> +
> +#
> +# file commands                 
> +#
> +CONFIG_CMD_LS=y
> +CONFIG_CMD_RM=y
> +CONFIG_CMD_CAT=y
> +CONFIG_CMD_MKDIR=y
> +CONFIG_CMD_RMDIR=y
> +CONFIG_CMD_CP=y
> +CONFIG_CMD_PWD=y
> +CONFIG_CMD_CD=y
> +CONFIG_CMD_MOUNT=y
> +CONFIG_CMD_UMOUNT=y
> +
> +#
> +# console                       
> +#
> +CONFIG_CMD_CLEAR=y
> +CONFIG_CMD_ECHO=y
> +CONFIG_CMD_ECHO_E=y
> +
> +#
> +# memory                        
> +#
> +# CONFIG_CMD_LOADB is not set
> +# CONFIG_CMD_LOADS is not set
> +# CONFIG_CMD_MEMINFO is not set
> +# CONFIG_CMD_CRC is not set
> +CONFIG_CMD_MTEST=y
> +CONFIG_CMD_MTEST_ALTERNATIVE=y
> +
> +#
> +# flash                         
> +#
> +# CONFIG_CMD_FLASH is not set
> +# CONFIG_CMD_UBI is not set
> +
> +#
> +# booting                       
> +#
> +CONFIG_CMD_BOOTM=y
> +# CONFIG_CMD_BOOTM_ZLIB is not set
> +# CONFIG_CMD_BOOTM_BZLIB is not set
> +# CONFIG_CMD_BOOTM_SHOW_TYPE is not set
> +CONFIG_CMD_BOOTZ=y
> +CONFIG_CMD_BOOTU=y
> +CONFIG_CMD_RESET=y
> +# CONFIG_CMD_GO is not set
> +CONFIG_CMD_TIMEOUT=y
> +CONFIG_CMD_PARTITION=y
> +CONFIG_CMD_TEST=y
> +CONFIG_CMD_VERSION=y
> +CONFIG_CMD_HELP=y
> +CONFIG_CMD_DEVINFO=y
> +# CONFIG_CMD_GPIO is not set
> +# CONFIG_CMD_UNLZO is not set
> +# CONFIG_NET is not set
> +
> +#
> +# Drivers                       
> +#
> +
> +#
> +# serial drivers                
> +#
> +# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
> +CONFIG_DRIVER_SERIAL_STM378X=y
> +# CONFIG_DRIVER_SERIAL_NS16550 is not set
> +
> +#
> +# SPI drivers                   
> +#
> +# CONFIG_SPI is not set
> +# CONFIG_I2C is not set
> +
> +#
> +# flash drivers                 
> +#
> +# CONFIG_DRIVER_CFI is not set
> +# CONFIG_MTD is not set
> +# CONFIG_ATA is not set
> +# CONFIG_USB is not set
> +# CONFIG_USB_GADGET is not set
> +# CONFIG_VIDEO is not set
> +
> +#
> +# Filesystem support            
> +#
> +# CONFIG_FS_CRAMFS is not set
> +CONFIG_FS_RAMFS=y
> +CONFIG_FS_DEVFS=y
> +CONFIG_CRC32=y
> +# CONFIG_DIGEST is not set
> +# CONFIG_GENERIC_FIND_NEXT_BIT is not set
> +CONFIG_PROCESS_ESCAPE_SEQUENCE=y
> diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
> index 9858d3a..bbdea51 100644
> --- a/arch/arm/mach-stm/Kconfig
> +++ b/arch/arm/mach-stm/Kconfig
> @@ -2,8 +2,10 @@ if ARCH_STM
>  
>  config ARCH_TEXT_BASE
>  	hex
> +	default 0x41000000 if MACH_MX23EVK
>  
>  config BOARDINFO
> +	default "Freescale i.MX23-EVK" if MACH_MX23EVK
>  
>  comment "SigmaTel/Freescale i.MX System-on-Chip"
>  
> @@ -21,6 +23,11 @@ if ARCH_IMX23
>  choice
>  	prompt "i.MX23 Board Type"
>  
> +config MACH_MX23EVK
> +	bool "mx23-evk"
> +	help
> +	  Say Y here if you are using the Freescale i.MX23-EVK board
> +
>  endchoice
>  
>  endif
> -- 
> 1.7.2.3
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Fri Oct  8 12:30:48 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:48 +0200
Subject: [PATCH v2]  Add MCI card support to barebox
Message-ID: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>

This is the second series. Hopefully it include all suggestions made.
It also include Sascha's patches related to MCI.

This patch is based on some work Sascha made already. I tried to bring in some
light into the MCI framework routines as they are based on code from another
project. Bear with me, if I didn't add useful comments all over the code. I
just wasn't able to understand what happen... If someone has more knowledge
about MCI cards, please take a look at the FIXME/TODOs and make me understand
why the code does what it does.

There is only one regular user yet: The i.MX27 based PCA100 platform. The other
platform (S3C2440 based) I did the tests on, is not part of barebox (and will not)
and the i.MX23 based platform (ChumbyOne) is not yet part of barebox.

Comments are still welcome.

Regards,
Juergen



From jbe at pengutronix.de  Fri Oct  8 12:30:49 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:49 +0200
Subject: [PATCH 01/10] x-functions do not return in case of failure.
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-2-git-send-email-jbe@pengutronix.de>

Remove error handling, because in case of failure the xzalloc() function
does not return.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/ata/disk_drive.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index 250dada..6d5c87a 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -281,10 +281,6 @@ static int disk_probe(struct device_d *dev)
 
 	/* It seems a valuable disk. Register it */
 	disk_cdev = xzalloc(sizeof(struct cdev));
-	if (disk_cdev == NULL) {
-		dev_err(dev, "Out of memory\n");
-		return -ENOMEM;
-	}
 
 	/*
 	 * BIOS based disks needs special handling. Not the driver can
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:50 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:50 +0200
Subject: [PATCH 02/10] Make the disk driver less noisy
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-3-git-send-email-jbe@pengutronix.de>

In real life this output is only a "nice to have", but most of the time
its useless and confusing. So, make it a debug feature for the interested
developer.

Note: This is in preparation to add MCI card support, which mostly come with
a partition table and can be handled like a disk drive.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/ata/disk_drive.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index 6d5c87a..5b22e49 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -105,7 +105,8 @@ static int disk_register_partitions(struct device_d *dev, struct partition_entry
 			if (table[part_order[i]].partition_size > 0x7fffff)
 				continue;
 #endif
-			dev_info(dev, "Registering partition %s to drive %s\n", partition_name, drive_name);
+			dev_dbg(dev, "Registering partition %s to drive %s\n",
+				partition_name, drive_name);
 			rc = devfs_add_partition(drive_name,
 				table[part_order[i]].partition_start * SECTOR_SIZE,
 				table[part_order[i]].partition_size * SECTOR_SIZE,
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:51 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:51 +0200
Subject: [PATCH 03/10] Don't use a sector buffer on stack
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-4-git-send-email-jbe@pengutronix.de>

Using a temp. buffer for a disk sector on the stack, seems not work. Doing so
lets the system run crazy (the stack seems to be destroyd). Don't know the
correct stack handling on ARM, but (IMHO) I also can exclude any writing across
the buffer boundaries.

Using a temp. buffer via malloc() runs also on ARM.

Note: This patch was required to add MCI card support, which can be handled
like a disk drive.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/ata/disk_drive.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index 5b22e49..15ef5f4 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -34,6 +34,7 @@
 #include <errno.h>
 #include <string.h>
 #include <linux/kernel.h>
+#include <malloc.h>
 
 /**
  * Description of one partition table entry (D*S type)
@@ -269,15 +270,18 @@ static struct file_operations disk_ops = {
  */
 static int disk_probe(struct device_d *dev)
 {
-	uint8_t sector[512];
+	uint8_t *sector;
 	int rc;
 	struct ata_interface *intf = dev->platform_data;
 	struct cdev *disk_cdev;
 
+	sector = xmalloc(SECTOR_SIZE);
+
 	rc = intf->read(dev, 0, 1, sector);
 	if (rc != 0) {
 		dev_err(dev, "Cannot read MBR of this device\n");
-		return -1;
+		rc = -ENODEV;
+		goto on_error;
 	}
 
 	/* It seems a valuable disk. Register it */
@@ -306,7 +310,8 @@ static int disk_probe(struct device_d *dev)
 
 	if ((sector[510] != 0x55) || (sector[511] != 0xAA)) {
 		dev_info(dev, "No partition table found\n");
-		return 0;
+		rc = 0;
+		goto on_error;
 	}
 
 	/* guess the size of this drive */
@@ -314,9 +319,11 @@ static int disk_probe(struct device_d *dev)
 	dev_info(dev, "Drive size guessed to %u kiB\n", dev->size / 1024);
 	disk_cdev->size = dev->size;
 
-	disk_register_partitions(dev, (struct partition_entry*)&sector[446]);
+	rc = disk_register_partitions(dev, (struct partition_entry*)&sector[446]);
 
-	return 0;
+on_error:
+	free(sector);
+	return rc;
 }
 
 #ifdef CONFIG_ATA_BIOS
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:52 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:52 +0200
Subject: [PATCH 04/10] Don't try to guess the size of a disk if its size value
	is already given
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-5-git-send-email-jbe@pengutronix.de>

Guessing the size of an attached harddisk (access via x86 BIOS) was needed
due to the fact, barebox can't query this information from the BIOS easily.

But with the SD/MMC cards, there will be a second user of the generic disk
handling routines. And with this media it is very easy to know its size.

This patch provides a workaround to keep the guessing feature if the size of
the registered disk is 0. If it is not 0, the given value will be used instead.

Note: This is in preparation to add MCI card support, which can be handled
like a disk drive.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/x86/boards/x86_generic/generic_pc.c |    2 +-
 drivers/ata/disk_drive.c                 |   27 ++++++++++++++++++---------
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/arch/x86/boards/x86_generic/generic_pc.c b/arch/x86/boards/x86_generic/generic_pc.c
index a6cd7e0..b9c31aa 100644
--- a/arch/x86/boards/x86_generic/generic_pc.c
+++ b/arch/x86/boards/x86_generic/generic_pc.c
@@ -46,7 +46,7 @@ static struct device_d sdram_dev = {
 static struct device_d bios_disk_dev = {
 	.id		= -1,
 	.name		= "biosdrive",
-	.size		= 1,
+	.size		= 0,	/* auto guess */
 };
 
 /*
diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index 15ef5f4..a54429a 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -23,6 +23,7 @@
  * @brief Generic disk drive support
  *
  * @todo Support for disks larger than 4 GiB
+ * @todo Reliable size detection for BIOS based disks (on x86 only)
  */
 
 #include <stdio.h>
@@ -299,11 +300,16 @@ static int disk_probe(struct device_d *dev)
 	else
 #endif
 		disk_cdev->name = asprintf("disk%d", dev->id);
-	/**
-	 * @todo we need the size of the drive, else its nearly impossible
-	 * to do anything with it (at least with the generic routines)
-	 */
-	disk_cdev->size = 32;	/* FIXME */
+
+	/* On x86, BIOS based disks are coming without a valid .size field */
+	if (dev->size == 0) {
+		/*
+		 * We need always the size of the drive, else its nearly impossible
+		 * to do anything with it (at least with the generic routines)
+		 */
+		disk_cdev->size = 32;
+	} else
+		disk_cdev->size = dev->size;
 	disk_cdev->ops = &disk_ops;
 	disk_cdev->dev = dev;
 	devfs_create(disk_cdev);
@@ -314,10 +320,13 @@ static int disk_probe(struct device_d *dev)
 		goto on_error;
 	}
 
-	/* guess the size of this drive */
-	dev->size = disk_guess_size(dev, (struct partition_entry*)&sector[446]) * SECTOR_SIZE;
-	dev_info(dev, "Drive size guessed to %u kiB\n", dev->size / 1024);
-	disk_cdev->size = dev->size;
+	if (dev->size == 0) {
+		/* guess the size of this drive if not otherwise given */
+		dev->size = disk_guess_size(dev,
+			(struct partition_entry*)&sector[446]) * SECTOR_SIZE;
+		dev_info(dev, "Drive size guessed to %u kiB\n", dev->size / 1024);
+		disk_cdev->size = dev->size;
+	}
 
 	rc = disk_register_partitions(dev, (struct partition_entry*)&sector[446]);
 
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:54 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:54 +0200
Subject: [PATCH 06/10] Add i.MX23 MCI card support
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-7-git-send-email-jbe@pengutronix.de>

Adding MCI card support for STM378x/i.MX23 CPUs. This is for reference only,
as this architecture is currently not part of barebox (but will coming soon).
Its tested on the i.MX23 based ChumbyOne.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/Kconfig   |    7 +
 drivers/mci/Makefile  |    1 +
 drivers/mci/stm378x.c |  699 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 707 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/stm378x.c

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 0abadb3..a24ae6d 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -27,4 +27,11 @@ config MCI_INFO
 
 comment "--- MCI host drivers ---"
 
+config MCI_STM378X
+	bool "i.MX23"
+	depends on ARCH_STM
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  i.MX23 based system.
+
 endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index 927618f..e5e19b0 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MCI)	+= mci-core.o
+obj-$(CONFIG_MCI_STM378X) += stm378x.o
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
new file mode 100644
index 0000000..fbb9994
--- /dev/null
+++ b/drivers/mci/stm378x.c
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe at pengutronix.de>
+ *
+ * This code is based on:
+ *
+ * Copyright (C) 2007 SigmaTel, Inc., Ioannis Kappas <ikappas at sigmatel.com>
+ *
+ * Portions copyright (C) 2003 Russell King, PXA MMCI Driver
+ * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * @file
+ * @brief MCI card host interface for i.MX23 CPU
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <mci.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <mach/imx-regs.h>
+#include <mach/mci.h>
+#include <mach/clock.h>
+
+#define CLOCKRATE_MIN (1 * 1000 * 1000)
+#define CLOCKRATE_MAX (480 * 1000 * 1000)
+
+#define HW_SSP_CTRL0 0x000
+# define SSP_CTRL0_SFTRST (1 << 31)
+# define SSP_CTRL0_CLKGATE (1 << 30)
+# define SSP_CTRL0_RUN (1 << 29)
+# define SSP_CTRL0_LOCK_CS (1 << 29)
+# define SSP_CTRL0_READ (1 << 25)
+# define SSP_CTRL0_IGNORE_CRC (1 << 26)
+# define SSP_CTRL0_DATA_XFER (1 << 24)
+# define SSP_CTRL0_BUS_WIDTH(x) (((x) & 0x3) << 22)
+# define SSP_CTRL0_WAIT_FOR_IRQ (1 << 21)
+# define SSP_CTRL0_LONG_RESP (1 << 19)
+# define SSP_CTRL0_GET_RESP (1 << 17)
+# define SSP_CTRL0_ENABLE (1 << 16)
+# define SSP_CTRL0_XFER_COUNT(x) ((x) & 0xffff)
+
+#define HW_SSP_CMD0 0x010
+# define SSP_CMD0_SLOW_CLK (1 << 22)
+# define SSP_CMD0_CONT_CLK (1 << 21)
+# define SSP_CMD0_APPEND_8CYC (1 << 20)
+# define SSP_CMD0_BLOCK_SIZE(x) (((x) & 0xf) << 16)
+# define SSP_CMD0_BLOCK_COUNT(x) (((x) & 0xff) << 8)
+# define SSP_CMD0_CMD(x) ((x) & 0xff)
+
+#define HW_SSP_CMD1 0x020
+#define HW_SSP_COMPREF 0x030
+#define HW_SSP_COMPMASK 0x040
+#define HW_SSP_TIMING 0x050
+# define SSP_TIMING_TIMEOUT_MASK (0xffff0000)
+# define SSP_TIMING_TIMEOUT(x) ((x) << 16)
+# define SSP_TIMING_CLOCK_DIVIDE(x) (((x) & 0xff) << 8)
+# define SSP_TIMING_CLOCK_RATE(x) ((x) & 0xff)
+
+#define HW_SSP_CTRL1 0x060
+# define SSP_CTRL1_POLARITY (1 << 9)
+# define SSP_CTRL1_WORD_LENGTH(x) (((x) & 0xf) << 4)
+# define SSP_CTRL1_SSP_MODE(x) ((x) & 0xf)
+
+#define HW_SSP_DATA 0x070
+#define HW_SSP_SDRESP0 0x080
+#define HW_SSP_SDRESP1 0x090
+#define HW_SSP_SDRESP2 0x0A0
+#define HW_SSP_SDRESP3 0x0B0
+
+#define HW_SSP_STATUS 0x0C0
+# define SSP_STATUS_PRESENT (1 << 31)
+# define SSP_STATUS_SD_PRESENT (1 << 29)
+# define SSP_STATUS_CARD_DETECT (1 << 28)
+# define SSP_STATUS_RESP_CRC_ERR (1 << 16)
+# define SSP_STATUS_RESP_ERR (1 << 15)
+# define SSP_STATUS_RESP_TIMEOUT (1 << 14)
+# define SSP_STATUS_DATA_CRC_ERR (1 << 13)
+# define SSP_STATUS_TIMEOUT (1 << 12)
+# define SSP_STATUS_FIFO_OVRFLW (1 << 9)
+# define SSP_STATUS_FIFO_FULL (1 << 8)
+# define SSP_STATUS_FIFO_EMPTY (1 << 5)
+# define SSP_STATUS_FIFO_UNDRFLW (1 << 4)
+# define SSP_STATUS_CMD_BUSY (1 << 3)
+# define SSP_STATUS_DATA_BUSY (1 << 2)
+# define SSP_STATUS_BUSY (1 << 0)
+# define SSP_STATUS_ERROR (SSP_STATUS_FIFO_OVRFLW | SSP_STATUS_FIFO_UNDRFLW | \
+	SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR | \
+	SSP_STATUS_RESP_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | SSP_STATUS_TIMEOUT)
+
+#define HW_SSP_DEBUG 0x100
+#define HW_SSP_VERSION 0x110
+
+struct stm_mci_host {
+	unsigned	clock;	/* current clock speed in Hz ("0" if disabled) */
+#ifdef CONFIG_MCI_INFO
+	unsigned	f_min;
+	unsigned	f_max;
+#endif
+	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
+};
+
+/**
+ * Get MCI cards response if defined for the type of command
+ * @param hw_dev Host interface device instance
+ * @param cmd Command description
+ * @return Response bytes count, -EINVAL for unsupported response types
+ */
+static int get_cards_response(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	switch (cmd->resp_type) {
+	case MMC_RSP_NONE:
+		return 0;
+
+	case MMC_RSP_R1:
+	case MMC_RSP_R1b:
+	case MMC_RSP_R3:
+		cmd->response[0] = readl(hw_dev->map_base + HW_SSP_SDRESP0);
+		return 1;
+
+	case MMC_RSP_R2:
+		cmd->response[3] = readl(hw_dev->map_base + HW_SSP_SDRESP0);
+		cmd->response[2] = readl(hw_dev->map_base + HW_SSP_SDRESP1);
+		cmd->response[1] = readl(hw_dev->map_base + HW_SSP_SDRESP2);
+		cmd->response[0] = readl(hw_dev->map_base + HW_SSP_SDRESP3);
+		return 4;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * Finish a request to the MCI card
+ * @param hw_dev Host interface device instance
+ *
+ * Can also stop the clock to save power
+ */
+static void finish_request(struct device_d *hw_dev)
+{
+	/* stop the engines (normaly already done) */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+}
+
+/**
+ * Check if the last command failed and if, why it failed
+ * @param status HW_SSP_STATUS's content
+ * @return 0 if no error, negative values else
+ */
+static int get_cmd_error(unsigned status)
+{
+	if (status & SSP_STATUS_ERROR)
+		pr_debug("Status Reg reports %08X\n", status);
+
+	if (status & SSP_STATUS_TIMEOUT) {
+		pr_debug("CMD timeout\n");
+		return -ETIMEDOUT;
+	} else if (status & SSP_STATUS_RESP_TIMEOUT) {
+		pr_debug("RESP timeout\n");
+		return -ETIMEDOUT;
+	} else if (status & SSP_STATUS_RESP_CRC_ERR) {
+		pr_debug("CMD crc error\n");
+		return -EILSEQ;
+	} else if (status & SSP_STATUS_RESP_ERR) {
+		pr_debug("RESP error\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * Define the timout for the next command
+ * @param hw_dev Host interface device instance
+ * @param to Timeout value in MCI card's bus clocks
+ */
+static void stm_setup_timout(struct device_d *hw_dev, unsigned to)
+{
+	uint32_t reg;
+
+	reg = readl(hw_dev->map_base + HW_SSP_TIMING) & ~SSP_TIMING_TIMEOUT_MASK;
+	reg |= SSP_TIMING_TIMEOUT(to);
+	writel(reg, hw_dev->map_base + HW_SSP_TIMING);
+}
+
+/**
+ * Read data from the MCI card
+ * @param hw_dev Host interface device instance
+ * @param buffer To write data into
+ * @param length Count of bytes to read (must be multiples of 4)
+ * @return 0 on success, negative values else
+ *
+ * @note This routine uses PIO to read in the data bytes from the FIFO. This
+ * may fail whith high clock speeds. If you receive -EIO errors you can try
+ * again with reduced clock speeds.
+ */
+static int read_data(struct device_d *hw_dev, void *buffer, unsigned length)
+{
+	uint32_t *p = buffer;
+
+	if (length & 0x3) {
+		pr_debug("Cannot read data sizes not multiple of 4 (request for %u detected)\n",
+				length);
+		return -EINVAL;
+	}
+
+	while ((length != 0) &&
+		((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_ERROR) == 0)) {
+		/* TODO sort out FIFO overflows and emit -EOI for this case */
+		if ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_FIFO_EMPTY) == 0) {
+			*p = readl(hw_dev->map_base + HW_SSP_DATA);
+			p++;
+			length -= 4;
+		}
+	}
+
+	if (length == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+
+/**
+ * Write data into the MCI card
+ * @param hw_dev Host interface device instance
+ * @param buffer To read the data from
+ * @param length Count of bytes to write (must be multiples of 4)
+ * @return 0 on success, negative values else
+ *
+ * @note This routine uses PIO to write the data bytes into the FIFO. This
+ * may fail with high clock speeds. If you receive -EIO errors you can try
+ * again with reduced clock speeds.
+ */
+static int write_data(struct device_d *hw_dev, const void *buffer, unsigned length)
+{
+	const uint32_t *p = buffer;
+
+	if (length & 0x3) {
+		pr_debug("Cannot write data sizes not multiple of 4 (request for %u detected)\n",
+				length);
+		return -EINVAL;
+	}
+
+	while ((length != 0) &&
+		((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_ERROR) == 0)) {
+		/* TODO sort out FIFO overflows and emit -EOI for this case */
+		if ((readl(hw_dev->map_base + HW_SSP_STATUS) & SSP_STATUS_FIFO_FULL) == 0) {
+			writel(*p, hw_dev->map_base + HW_SSP_DATA);
+			p++;
+			length -= 4;
+		}
+	}
+	if (length == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+/**
+ * Start the transaction with or without data
+ * @param hw_dev Host interface device instance
+ * @param data Data transfer description (might be NULL)
+ * @return 0 on success
+ */
+static int transfer_data(struct device_d *hw_dev, struct mci_data *data)
+{
+	unsigned length;
+
+	if (data != NULL) {
+		length = data->blocks * data->blocksize;
+#if 0
+		/*
+		 * For the records: When writing data with high clock speeds it
+		 * could be a good idea to fill the FIFO prior starting the
+		 * transaction.
+		 * But last time I tried it, it failed badly. Don't know why yet
+		 */
+		if (data->flags & MMC_DATA_WRITE) {
+			err = write_data(host, data->src, 16);
+			data->src += 16;
+			length -= 16;
+		}
+#endif
+	}
+
+	/*
+	 * Everything is ready for the transaction now:
+	 * - transfer configuration
+	 * - command and its parameters
+	 *
+	 * Start the transaction right now
+	 */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 4);
+
+	if (data != NULL) {
+		if (data->flags & MMC_DATA_READ)
+			return read_data(hw_dev, data->dest, length);
+		else
+			return write_data(hw_dev, data->src, length);
+	}
+
+	return 0;
+}
+
+/**
+ * Configure the MCI hardware for the next transaction
+ * @param cmd_flags Command information
+ * @param data_flags Data information (may be 0)
+ * @return Corresponding setting for the SSP_CTRL0 register
+ */
+static uint32_t prepare_transfer_setup(unsigned cmd_flags, unsigned data_flags)
+{
+	uint32_t reg = 0;
+
+	if (cmd_flags & MMC_RSP_PRESENT)
+		reg |= SSP_CTRL0_GET_RESP;
+	if ((cmd_flags & MMC_RSP_CRC) == 0)
+		reg |= SSP_CTRL0_IGNORE_CRC;
+	if (cmd_flags & MMC_RSP_136)
+		reg |= SSP_CTRL0_LONG_RESP;
+	if (cmd_flags & MMC_RSP_BUSY)
+		reg |= SSP_CTRL0_WAIT_FOR_IRQ;	/* FIXME correct? */
+#if 0
+	if (cmd_flags & MMC_RSP_OPCODE)
+		/* TODO */
+#endif
+	if (data_flags & MMC_DATA_READ)
+		reg |= SSP_CTRL0_READ;
+
+	return reg;
+}
+
+/**
+ * Handle MCI commands without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @return 0 on success
+ *
+ * This functions handles the following MCI commands:
+ * - "broadcast command (BC)" without a response
+ * - "broadcast commands with response (BCR)"
+ * - "addressed command (AC)" with response, but without data
+ */
+static int stm_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	/* setup command and transfer parameters */
+	writel(prepare_transfer_setup(cmd->resp_type, 0) |
+		SSP_CTRL0_ENABLE, hw_dev->map_base + HW_SSP_CTRL0);
+
+	/* prepare the command, when no response is expected add a few trailing clocks */
+	writel(SSP_CMD0_CMD(cmd->cmdidx) |
+		(cmd->resp_type & MMC_RSP_PRESENT ? 0 : SSP_CMD0_APPEND_8CYC),
+		hw_dev->map_base + HW_SSP_CMD0);
+
+	/* prepare command's arguments */
+	writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
+
+	stm_setup_timout(hw_dev, 0xffff);
+
+	/* start the transfer */
+	writel(SSP_CTRL0_RUN, hw_dev->map_base + HW_SSP_CTRL0 + 4);
+
+	/* wait until finished */
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_RUN)
+		;
+
+	if (cmd->resp_type & MMC_RSP_PRESENT)
+		get_cards_response(hw_dev, cmd);
+
+	return get_cmd_error(readl(hw_dev->map_base + HW_SSP_STATUS));
+}
+
+/**
+ * Handle an "addressed data transfer command " with or without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.) May be NULL
+ * @return 0 on success
+ */
+static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
+			struct mci_data *data)
+{
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+	uint32_t xfer_cnt, log2blocksize, block_cnt;
+	int err;
+
+	/* Note: 'data' can be NULL! */
+	if (data != NULL) {
+		xfer_cnt = data->blocks * data->blocksize;
+		block_cnt = data->blocks - 1;	/* can be 0 */
+		log2blocksize = find_first_bit((const unsigned long*)&data->blocksize,
+						32);
+	} else
+		xfer_cnt = log2blocksize = block_cnt = 0;
+
+	/* setup command and transfer parameters */
+	writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
+		SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
+		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
+		SSP_CTRL0_ENABLE |
+		SSP_CTRL0_XFER_COUNT(xfer_cnt), /* byte count to be transfered */
+		hw_dev->map_base + HW_SSP_CTRL0);
+
+	/* prepare the command and the transfered data count */
+	writel(SSP_CMD0_CMD(cmd->cmdidx) |
+		SSP_CMD0_BLOCK_SIZE(log2blocksize) |
+		SSP_CMD0_BLOCK_COUNT(block_cnt) |
+		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
+		hw_dev->map_base + HW_SSP_CMD0);
+
+	/* prepare command's arguments */
+	writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
+
+	stm_setup_timout(hw_dev, 0xffff);
+
+	err = transfer_data(hw_dev, data);
+	if (err != 0) {
+		pr_debug(" Transfering data failed\n");
+		return err;
+	}
+
+	/* wait until finished */
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_RUN)
+		;
+
+	get_cards_response(hw_dev, cmd);
+
+	return 0;
+}
+
+
+/**
+ * @param hw_dev Host interface device instance
+ * @param nc New Clock in [Hz] (may be 0 to disable the clock)
+ * @return The real clock frequency
+ *
+ * The SSP unit clock can base on the external 24 MHz or the internal 480 MHz
+ * Its unit clock value is derived from the io clock, from the SSP divider
+ * and at least the SSP bus clock itself is derived from the SSP unit's divider
+ *
+ * @code
+ * |------------------- generic -------------|-peripheral specific-|-----all SSPs-----|-per SSP unit-|
+ *  24 MHz ----------------------------
+ *          \                          \
+ *           \                          |----| FRAC |----IO CLK----| SSP unit DIV |---| SSP DIV |--- SSP output clock
+ *            \- | PLL |--- 480 MHz ---/
+ * @endcode
+ *
+ * @note Up to "SSP unit DIV" the outer world must care. This routine only
+ * handles the "SSP DIV".
+ */
+static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
+{
+	unsigned ssp, div1, div2, reg;
+
+	if (nc == 0U) {
+		/* TODO stop the clock */
+		return 0;
+	}
+
+	ssp = imx_get_sspclk() * 1000;
+
+	for (div1 = 2; div1 < 255; div1 += 2) {
+		div2 = ssp / nc / div1;
+		if (div2 <= 0x100)
+			break;
+	}
+	if (div1 >= 255) {
+		pr_warning("Cannot set clock to %d Hz\n", nc);
+		return 0;
+	}
+
+	reg = readl(hw_dev->map_base + HW_SSP_TIMING) & SSP_TIMING_TIMEOUT_MASK;
+	reg |= SSP_TIMING_CLOCK_DIVIDE(div1) | SSP_TIMING_CLOCK_RATE(div2 - 1);
+	writel(reg, hw_dev->map_base + HW_SSP_TIMING);
+
+	return ssp / div1 / div2;
+}
+
+/**
+ * Reset the MCI engine (the hard way)
+ * @param hw_dev Host interface instance
+ *
+ * This will reset everything in all registers of this unit! (FIXME)
+ */
+static void stm_mci_reset(struct device_d *hw_dev)
+{
+	writel(SSP_CTRL0_SFTRST, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+	while (readl(hw_dev->map_base + HW_SSP_CTRL0) & SSP_CTRL0_SFTRST)
+		;
+}
+
+/**
+ * Initialize the engine
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance
+ */
+static int stm_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+
+	/* enable the clock to this unit to be able to reset it */
+	writel(SSP_CTRL0_CLKGATE, hw_dev->map_base + HW_SSP_CTRL0 + 8);
+
+	/* reset the unit */
+	stm_mci_reset(hw_dev);
+
+	/* restore the last settings */
+	host->clock = host_data->clock = setup_clock_speed(hw_dev, host->clock);
+	stm_setup_timout(hw_dev, 0xffff);
+	writel(SSP_CTRL0_IGNORE_CRC |
+		SSP_CTRL0_BUS_WIDTH(host_data->bus_width),
+		hw_dev->map_base + HW_SSP_CTRL0);
+	writel(SSP_CTRL1_POLARITY |
+		SSP_CTRL1_SSP_MODE(3) |
+		SSP_CTRL1_WORD_LENGTH(7), hw_dev->map_base + HW_SSP_CTRL1);
+
+	return 0;
+}
+
+/* ------------------------- MCI API -------------------------------------- */
+
+/**
+ * Keep the attached MMC/SD unit in a well know state
+ * @param mci_pdata MCI platform data
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative value else
+ */
+static int mci_reset(struct mci_host *mci_pdata, struct device_d *mci_dev)
+{
+	struct device_d *hw_dev = mci_pdata->hw_dev;
+
+	return stm_mci_initialize(hw_dev, mci_dev);
+}
+
+/**
+ * Process one command to the MCI card
+ * @param mci_pdata MCI platform data
+ * @param cmd The command to process
+ * @param data The data to handle in the command (can be NULL)
+ * @return 0 on success, negative value else
+ */
+static int mci_request(struct mci_host *mci_pdata, struct mci_cmd *cmd,
+			struct mci_data *data)
+{
+	struct device_d *hw_dev = mci_pdata->hw_dev;
+	int rc;
+
+	if ((cmd->resp_type == 0) || (data == NULL))
+		rc = stm_mci_std_cmds(hw_dev, cmd);
+	else
+		rc = stm_mci_adtc(hw_dev, cmd, data);	/* with response and data */
+
+	finish_request(hw_dev);	/* TODO */
+	return rc;
+}
+
+/**
+ * Setup the bus width and IO speed
+ * @param mci_pdata MCI platform data
+ * @param mci_dev MCI device instance
+ * @param bus_width New bus width value (1, 4 or 8)
+ * @param clock New clock in Hz (can be '0' to disable the clock)
+ *
+ * Drivers currently realized values are stored in MCI's platformdata
+ */
+static void mci_set_ios(struct mci_host *mci_pdata, struct device_d *mci_dev,
+			unsigned bus_width, unsigned clock)
+{
+	struct device_d *hw_dev = mci_pdata->hw_dev;
+	struct stm_mci_host *host_data = (struct stm_mci_host*)GET_HOST_DATA(hw_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+
+	switch (bus_width) {
+	case 8:
+		host_data->bus_width = 2;
+		host->bus_width = 8;	/* 8 bit is possible */
+		break;
+	case 4:
+		host_data->bus_width = 1;
+		host->bus_width = 4;	/* 4 bit is possible */
+		break;
+	default:
+		host_data->bus_width = 0;
+		host->bus_width = 1;	/* 1 bit is possible */
+		break;
+	}
+
+	host->clock = host_data->clock = setup_clock_speed(hw_dev, clock);
+	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", host->bus_width,
+			host->clock);
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+const unsigned char bus_width[3] = { 1, 4, 8 };
+
+static void stm_info(struct device_d *hw_dev)
+{
+	struct stm_mci_host *host_data = GET_HOST_DATA(hw_dev);
+
+	printf(" Interface\n");
+	printf("  Min. bus clock: %u Hz\n", host_data->f_min);
+	printf("  Max. bus clock: %u Hz\n", host_data->f_max);
+	printf("  Current bus clock: %u Hz\n", host_data->clock);
+	printf("  Bus width: %u bit\n", bus_width[host_data->bus_width]);
+	printf("\n");
+}
+#endif
+
+static int stm_mci_probe(struct device_d *hw_dev)
+{
+	struct stm_mci_platform_data *pd = hw_dev->platform_data;
+	struct stm_mci_host *host_data;
+	struct mci_host *host;
+
+	if (hw_dev->platform_data == NULL) {
+		pr_err("Missing platform data\n");
+		return -EINVAL;
+	}
+
+	host = xzalloc(sizeof(struct stm_mci_host) + sizeof(struct mci_host));
+	host_data = (struct stm_mci_host*)&host[1];
+
+	hw_dev->priv = host_data;
+	host->hw_dev = hw_dev;
+	host->send_cmd = mci_request,
+	host->set_ios = mci_set_ios,
+	host->init = mci_reset,
+
+	/* feed forward the platform specific values */
+	host->voltages = pd->voltages;
+	host->host_caps = pd->caps;
+
+	if (pd->f_min == 0) {
+		host->f_min = imx_get_sspclk() / 254U / 256U * 1000U;
+		pr_debug("Min. frequency is %u Hz\n", host->f_min);
+	} else {
+		host->f_min = pd->f_min;
+		pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
+			host->f_min, imx_get_sspclk() / 254U / 256U * 1000U);
+	}
+	if (pd->f_max == 0) {
+		host->f_max = imx_get_sspclk() / 2U / 1U * 1000U;
+		pr_debug("Max. frequency is %u Hz\n", host->f_max);
+	} else {
+		host->f_max =  pd->f_max;
+		pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
+			host->f_max, imx_get_sspclk() / 2U / 1U * 1000U);
+	}
+
+#ifdef CONFIG_MCI_INFO
+	host_data->f_min = host->f_min;
+	host_data->f_max = host->f_max;
+#endif
+
+	return mci_register(host);
+}
+
+static struct driver_d stm_mci_driver = {
+        .name  = "stm_mci",
+        .probe = stm_mci_probe,
+#ifdef CONFIG_MCI_INFO
+	.info = stm_info,
+#endif
+};
+
+static int stm_mci_init_driver(void)
+{
+        register_driver(&stm_mci_driver);
+        return 0;
+}
+
+device_initcall(stm_mci_init_driver);
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:53 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:53 +0200
Subject: [PATCH 05/10] Add MCI card support to barebox
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-6-git-send-email-jbe@pengutronix.de>

This adds the basic framework to handle MCI cards in barebox.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/Kconfig        |    1 +
 drivers/Makefile       |    1 +
 drivers/mci/Kconfig    |   30 ++
 drivers/mci/Makefile   |    1 +
 drivers/mci/mci-core.c | 1333 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/mci.h          |  239 +++++++++
 6 files changed, 1605 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/Kconfig
 create mode 100644 drivers/mci/Makefile
 create mode 100644 drivers/mci/mci-core.c
 create mode 100644 include/mci.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index f7154c6..13235f3 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -9,6 +9,7 @@ source "drivers/mtd/Kconfig"
 source "drivers/ata/Kconfig"
 source "drivers/usb/Kconfig"
 source "drivers/video/Kconfig"
+source "drivers/mci/Kconfig"
 source "drivers/clk/Kconfig"
 
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 706e1c8..71d34f9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -6,5 +6,6 @@ obj-y	+= usb/
 obj-$(CONFIG_ATA) += ata/
 obj-$(CONFIG_SPI) += spi/
 obj-$(CONFIG_I2C) += i2c/
+obj-$(CONFIG_MCI) += mci/
 obj-$(CONFIG_VIDEO) += video/
 obj-y	+= clk/
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
new file mode 100644
index 0000000..0abadb3
--- /dev/null
+++ b/drivers/mci/Kconfig
@@ -0,0 +1,30 @@
+menuconfig MCI
+	bool "MCI drivers                   "
+	select ATA
+	select ATA_DISK
+	help
+	  Add support for MCI drivers, used to handle MMC and SD cards
+
+if MCI
+
+comment "--- Feature list ---"
+
+config MCI_STARTUP
+	bool "Probe on system start"
+	help
+	  Say 'y' here if the MCI framework should probe for attached MCI cards
+	  on system start up. This is required if the card carries barebox's
+	  environment (for example on systems where the MCI card is the sole
+	  bootmedia). Otherwise probing run on demand with "mci*.probe=1"
+
+config MCI_INFO
+	bool "MCI Info"
+	depends on CMD_DEVINFO
+	default y
+	help
+	  This entry adds more info about the attached MCI card, when the
+	  'devinfo' command is used on the mci device.
+
+comment "--- MCI host drivers ---"
+
+endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
new file mode 100644
index 0000000..927618f
--- /dev/null
+++ b/drivers/mci/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MCI)	+= mci-core.o
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
new file mode 100644
index 0000000..f961e46
--- /dev/null
+++ b/drivers/mci/mci-core.c
@@ -0,0 +1,1333 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is havily inspired and in parts from the u-boot project:
+ *
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* #define DEBUG */
+
+#include <init.h>
+#include <common.h>
+#include <mci.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm-generic/div64.h>
+#include <asm/byteorder.h>
+#include <ata.h>
+
+#define MAX_BUFFER_NUMBER 0xffffffff
+
+/**
+ * @file
+ * @brief Memory Card framework
+ *
+ * Checked with the following cards:
+ * - old Canon SD 16 MiB, does not like the 0x08 command (SD_CMD_SEND_IF_COND) -> failed
+ * - Kingston 512 MiB
+ * - SanDisk 512 MiB
+ * - Transcend SD Ultra, 1 GiB (Industrial)
+ */
+
+/**
+ * Call the MMC/SD instance driver to run the command on the MMC/SD card
+ * @param mci_dev MCI instance
+ * @param cmd The information about the command to run
+ * @param data The data according to the command (can be NULL)
+ * @return Driver's answer (0 on success)
+ */
+static int mci_send_cmd(struct device_d *mci_dev, struct mci_cmd *cmd, struct mci_data *data)
+{
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+
+	return host->send_cmd(host, cmd, data);
+}
+
+/**
+ * @param p Command definition to setup
+ * @param cmd Valid SD/MMC command (refer MMC_CMD_* / SD_CMD_*)
+ * @param arg Argument for the command (optional)
+ * @param response Command's response type (refer MMC_RSP_*)
+ *
+ * Note: When calling, the 'response' must match command's requirements
+ */
+static void mci_setup_cmd(struct mci_cmd *p, unsigned cmd, unsigned arg, unsigned response)
+{
+	p->cmdidx = cmd;
+	p->cmdarg = arg;
+	p->resp_type = response;
+}
+
+/**
+ * Setup SD/MMC card's blocklength to be used for future transmitts
+ * @param mci_dev MCI instance
+ * @param len Blocklength in bytes
+ * @return Transaction status (0 on success)
+ */
+static int mci_set_blocklen(struct device_d *mci_dev, unsigned len)
+{
+	struct mci_cmd cmd;
+
+	mci_setup_cmd(&cmd, MMC_CMD_SET_BLOCKLEN, len, MMC_RSP_R1);
+	return mci_send_cmd(mci_dev, &cmd, NULL);
+}
+
+/**
+ * Write one block of data to the card
+ * @param mci_dev MCI instance
+ * @param src Where to read from to write to the card
+ * @param blocknum Block number to write
+ * @return Transaction status (0 on success)
+ */
+static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned blocknum)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	mci_setup_cmd(&cmd,
+		MMC_CMD_WRITE_SINGLE_BLOCK,
+		mci->high_capacity != 0 ? blocknum : blocknum * mci->write_bl_len,
+		MMC_RSP_R1);
+
+	data.src = src;
+	data.blocks = 1;
+	data.blocksize = mci->write_bl_len;
+	data.flags = MMC_DATA_WRITE;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * Read one block of data from the card
+ * @param mci_dev MCI instance
+ * @param dst Where to store the data read from the card
+ * @param blocknum Block number to read
+ */
+static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned blocknum)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	mci_setup_cmd(&cmd,
+		MMC_CMD_READ_SINGLE_BLOCK,
+		mci->high_capacity != 0 ? blocknum : blocknum * mci->read_bl_len,
+		MMC_RSP_R1);
+
+	data.dest = dst;
+	data.blocks = 1;
+	data.blocksize = mci->read_bl_len;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * Reset the attached MMC/SD card
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mci_go_idle(struct device_d *mci_dev)
+{
+	struct mci_cmd cmd;
+	int err;
+
+	udelay(1000);
+
+	mci_setup_cmd(&cmd, MMC_CMD_GO_IDLE_STATE, 0, MMC_RSP_NONE);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+
+	if (err) {
+		pr_debug("Activating IDLE state failed: %d\n", err);
+		return err;
+	}
+
+	udelay(2000);	/* WTF? */
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int sd_send_op_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int timeout = 1000;
+	int err;
+
+	do {
+		mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, 0, MMC_RSP_R1);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+		if (err) {
+			pr_debug("Preparing SD for operating conditions failed: %d\n", err);
+			return err;
+		}
+
+		mci_setup_cmd(&cmd, SD_CMD_APP_SEND_OP_COND,
+			host->voltages | (mci->version == SD_VERSION_2 ? OCR_HCS : 0),
+			MMC_RSP_R3);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+		if (err) {
+			pr_debug("SD operation condition set failed: %d\n", err);
+			return err;
+		}
+		udelay(1000);
+	} while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
+
+	if (timeout <= 0) {
+		pr_debug("SD operation condition set timed out\n");
+		return -ENODEV;
+	}
+
+	if (mci->version != SD_VERSION_2)
+		mci->version = SD_VERSION_1_0;
+
+	mci->ocr = cmd.response[0];
+
+	mci->high_capacity = ((mci->ocr & OCR_HCS) == OCR_HCS);
+	mci->rca = 0;
+
+	return 0;
+}
+
+/**
+ * Setup the operation conditions to a MultiMediaCard
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mmc_send_op_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int timeout = 1000;
+	int err;
+
+	/* Some cards seem to need this */
+	mci_go_idle(mci_dev);
+
+	do {
+		mci_setup_cmd(&cmd, MMC_CMD_SEND_OP_COND, OCR_HCS |
+				host->voltages, MMC_RSP_R3);
+		err = mci_send_cmd(mci_dev, &cmd, NULL);
+
+		if (err) {
+			pr_debug("Preparing MMC for operating conditions failed: %d\n", err);
+			return err;
+		}
+
+		udelay(1000);
+	} while (!(cmd.response[0] & OCR_BUSY) && timeout--);
+
+	if (timeout <= 0) {
+		pr_debug("SD operation condition set timed out\n");
+		return -ENODEV;
+	}
+
+	mci->version = MMC_VERSION_UNKNOWN;
+	mci->ocr = cmd.response[0];
+
+	mci->high_capacity = ((mci->ocr & OCR_HCS) == OCR_HCS);
+	mci->rca = 0;
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param ext_csd Buffer for a 512 byte sized extended CSD
+ * @return Transaction status (0 on success)
+ *
+ * Note: Only cards newer than Version 1.1 (Physical Layer Spec) support
+ * this command
+ */
+static int mci_send_ext_csd(struct device_d *mci_dev, char *ext_csd)
+{
+	struct mci_cmd cmd;
+	struct mci_data data;
+
+	/* Get the Card Status Register */
+	mci_setup_cmd(&cmd, MMC_CMD_SEND_EXT_CSD, 0, MMC_RSP_R1);
+
+	data.dest = ext_csd;
+	data.blocks = 1;
+	data.blocksize = 512;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param set FIXME
+ * @param index FIXME
+ * @param value FIXME
+ * @return Transaction status (0 on success)
+ */
+static int mci_switch(struct device_d *mci_dev, unsigned set, unsigned index,
+			unsigned value)
+{
+	struct mci_cmd cmd;
+
+	mci_setup_cmd(&cmd, MMC_CMD_SWITCH,
+		(MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+		(index << 16) |
+		(value << 8),
+		 MMC_RSP_R1b);
+
+	return mci_send_cmd(mci_dev, &cmd, NULL);
+}
+
+/**
+ * Change transfer frequency for an MMC card
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int mmc_change_freq(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	char ext_csd[512];
+	char cardtype;
+	int err;
+
+	mci->card_caps = 0;
+
+	/* Only version 4 supports high-speed */
+	if (mci->version < MMC_VERSION_4)
+		return 0;
+
+	mci->card_caps |= MMC_MODE_4BIT;
+
+	err = mci_send_ext_csd(mci_dev, ext_csd);
+	if (err) {
+		pr_debug("Preparing for frequency setup failed: %d\n", err);
+		return err;
+	}
+
+	if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
+		mci->high_capacity = 1;
+
+	cardtype = ext_csd[196] & 0xf;
+
+	err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
+
+	if (err) {
+		pr_debug("MMC frequency changing failed: %d\n", err);
+		return err;
+	}
+
+	/* Now check to see that it worked */
+	err = mci_send_ext_csd(mci_dev, ext_csd);
+
+	if (err) {
+		pr_debug("Verifying frequency change failed: %d\n", err);
+		return err;
+	}
+
+	/* No high-speed support */
+	if (!ext_csd[185])
+		return 0;
+
+	/* High Speed is set, there are two types: 52MHz and 26MHz */
+	if (cardtype & MMC_HS_52MHZ)
+		mci->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+	else
+		mci->card_caps |= MMC_MODE_HS;
+
+	return 0;
+}
+
+/**
+ * FIXME
+ * @param mci_dev MCI instance
+ * @param mode FIXME
+ * @param group FIXME
+ * @param value FIXME
+ * @param resp FIXME
+ * @return Transaction status (0 on success)
+ */
+static int sd_switch(struct device_d *mci_dev, unsigned mode, unsigned group,
+			unsigned value, uint8_t *resp)
+{
+	struct mci_cmd cmd;
+	struct mci_data data;
+	unsigned arg;
+
+	arg = (mode << 31) | 0xffffff;
+	arg &= ~(0xf << (group << 2));
+	arg |= value << (group << 2);
+
+	/* Switch the frequency */
+	mci_setup_cmd(&cmd, SD_CMD_SWITCH_FUNC, arg, MMC_RSP_R1);
+
+	data.dest = resp;
+	data.blocksize = 64;
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+
+	return mci_send_cmd(mci_dev, &cmd, &data);
+}
+
+/**
+ * Change transfer frequency for an SD card
+ * @param mci_dev MCI instance
+ * @return Transaction status (0 on success)
+ */
+static int sd_change_freq(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_cmd cmd;
+	struct mci_data data;
+	uint32_t switch_status[16];
+	uint scr[2];
+	int timeout;
+	int err;
+
+	pr_debug("Changing transfer frequency\n");
+	mci->card_caps = 0;
+
+	/* Read the SCR to find out if this card supports higher speeds */
+	mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, mci->rca << 16, MMC_RSP_R1);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Query SD card capabilities failed: %d\n", err);
+		return err;
+	}
+
+	mci_setup_cmd(&cmd, SD_CMD_APP_SEND_SCR, 0, MMC_RSP_R1);
+
+	timeout = 3;
+
+retry_scr:
+	pr_debug("Trying to read the SCR (try %d of %d)\n", 4 - timeout, 3);
+	data.dest = (char *)&scr;
+	data.blocksize = 8;
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+
+	err = mci_send_cmd(mci_dev, &cmd, &data);
+	if (err) {
+		pr_debug(" Catch error (%d)", err);
+		if (timeout--) {
+			pr_debug("-- retrying\n");
+			goto retry_scr;
+		}
+		pr_debug("-- giving up\n");
+		return err;
+	}
+
+	mci->scr[0] = __be32_to_cpu(scr[0]);
+	mci->scr[1] = __be32_to_cpu(scr[1]);
+
+	switch ((mci->scr[0] >> 24) & 0xf) {
+	case 0:
+		mci->version = SD_VERSION_1_0;
+		break;
+	case 1:
+		mci->version = SD_VERSION_1_10;
+		break;
+	case 2:
+		mci->version = SD_VERSION_2;
+		break;
+	default:
+		mci->version = SD_VERSION_1_0;
+		break;
+	}
+
+	/* Version 1.0 doesn't support switching */
+	if (mci->version == SD_VERSION_1_0)
+		return 0;
+
+	timeout = 4;
+	while (timeout--) {
+		err = sd_switch(mci_dev, SD_SWITCH_CHECK, 0, 1,
+				(uint8_t*)&switch_status);
+		if (err) {
+			pr_debug("Checking SD transfer switch frequency feature failed: %d\n", err);
+			return err;
+		}
+
+		/* The high-speed function is busy.  Try again */
+		if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
+			break;
+	}
+
+	if (mci->scr[0] & SD_DATA_4BIT)
+		mci->card_caps |= MMC_MODE_4BIT;
+
+	/* If high-speed isn't supported, we return */
+	if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
+		return 0;
+
+	err = sd_switch(mci_dev, SD_SWITCH_SWITCH, 0, 1, (uint8_t*)&switch_status);
+	if (err) {
+		pr_debug("Switching SD transfer frequency failed: %d\n", err);
+		return err;
+	}
+
+	if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
+		mci->card_caps |= MMC_MODE_HS;
+
+	return 0;
+}
+
+/**
+ * Setup host's interface bus width and transfer frequency
+ * @param mci_dev MCI instance
+ */
+static void mci_set_ios(struct device_d *mci_dev)
+{
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+
+	host->set_ios(host, mci_dev, host->bus_width, host->clock);
+}
+
+/**
+ * Setup host's interface transfer frequency
+ * @param mci_dev MCI instance
+ * @param clock New clock in Hz to set
+ */
+static void mci_set_clock(struct device_d *mci_dev, unsigned clock)
+{
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+
+	/* check against any given limits */
+	if (clock > host->f_max)
+		clock = host->f_max;
+
+	if (clock < host->f_min)
+		clock = host->f_min;
+
+	host->clock = clock;	/* the new target frequency */
+	mci_set_ios(mci_dev);
+}
+
+/**
+ * Setup host's interface bus width
+ * @param mci_dev MCI instance
+ * @param width New interface bit width (1, 4 or 8)
+ */
+static void mci_set_bus_width(struct device_d *mci_dev, unsigned width)
+{
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+
+	host->bus_width = width;	/* the new target bus width */
+	mci_set_ios(mci_dev);
+}
+
+/**
+ * Extract card's version from its CSD
+ * @param mci_dev MCI instance
+ * @return 0 on success
+ */
+static void mci_detect_version_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int version;
+
+	if (mci->version == MMC_VERSION_UNKNOWN) {
+		/* the version is coded in the bits 127:126 (left aligned) */
+		version = (mci->csd[0] >> 26) & 0xf;	/* FIXME why other width? */
+
+		switch (version) {
+		case 0:
+			printf("Detecting a 1.2 revision card\n");
+			mci->version = MMC_VERSION_1_2;
+			break;
+		case 1:
+			printf("Detecting a 1.4 revision card\n");
+			mci->version = MMC_VERSION_1_4;
+			break;
+		case 2:
+			printf("Detecting a 2.2 revision card\n");
+			mci->version = MMC_VERSION_2_2;
+			break;
+		case 3:
+			printf("Detecting a 3.0 revision card\n");
+			mci->version = MMC_VERSION_3;
+			break;
+		case 4:
+			printf("Detecting a 4.0 revision card\n");
+			mci->version = MMC_VERSION_4;
+			break;
+		default:
+			printf("Unknow revision. Falling back to a 1.2 revision card\n");
+			mci->version = MMC_VERSION_1_2;
+			break;
+		}
+	}
+}
+
+/**
+ * meaning of the encoded 'unit' bits in the CSD's field 'TRAN_SPEED'
+ * (divided by 10 to be nice to platforms without floating point)
+ */
+static const unsigned tran_speed_unit[] = {
+	[0] = 10000,		/* 100 kbit/s */
+	[1] = 100000,		/* 1 Mbit/s */
+	[2] = 1000000,		/* 10 Mbit/s */
+	[3] = 10000000,		/* 100 Mbit/s */
+	/* [4]...[7] are reserved */
+};
+
+/**
+ * meaning of the 'time' bits  in the CSD's field 'TRAN_SPEED'
+ * (multiplied by 10 to be nice to platforms without floating point)
+ */
+static const unsigned char tran_speed_time[] = {
+	0,	/* reserved */
+	10,	/* 1.0 ns */
+	12,	/* 1.2 ns */
+	13,
+	15,
+	20,
+	25,
+	30,
+	35,
+	40,
+	45,
+	50,
+	55,
+	60,
+	70,	/* 7.0 ns */
+	80,	/* 8.0 ns */
+};
+
+/**
+ * Extract max. transfer speed from the CSD
+ * @param mci_dev MCI instance
+ *
+ * Encoded in bit 103:96 (103: reserved, 102:99: time, 98:96 unit)
+ */
+static void mci_extract_max_tran_speed_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	unsigned unit, time;
+
+	unit = tran_speed_unit[(mci->csd[0] & 0x7)];
+	time = tran_speed_time[((mci->csd[0] >> 3) & 0xf)];
+	if ((unit == 0) || (time == 0)) {
+		pr_warning("Unsupported 'TRAN_SPEED' unit/time value."
+				" Can't calculate card's max. transfer speed\n");
+		return;
+	}
+
+	mci->tran_speed = time * unit;
+	pr_debug("Transfer speed: %u\n", mci->tran_speed);
+}
+
+/**
+ * Extract max read and write block length from the CSD
+ * @param mci_dev MCI instance
+ *
+ * Encoded in bit 83:80 (read) and 25:22 (write)
+ */
+static void mci_extract_block_lengths_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	mci->read_bl_len = 1 << ((mci->csd[1] >> 16) & 0xf);
+
+	if (IS_SD(mci))
+		mci->write_bl_len = mci->read_bl_len;	/* FIXME why? */
+	else
+		mci->write_bl_len = 1 << ((mci->csd[3] >> 22) & 0xf);
+
+	pr_debug("Max. block length are: Write=%u, Read=%u Bytes\n",
+		mci->read_bl_len, mci->write_bl_len);
+}
+
+/**
+ * Extract card's capacitiy from the CSD
+ * @param mci_dev MCI instance
+ */
+static void mci_extract_card_capacity_from_csd(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	uint64_t csize, cmult;
+
+	if (mci->high_capacity) {
+		csize = (mci->csd[1] & 0x3f) << 16 | (mci->csd[2] & 0xffff0000) >> 16;
+		cmult = 8;
+	} else {
+		csize = (mci->csd[1] & 0x3ff) << 2 | (mci->csd[2] & 0xc0000000) >> 30;
+		cmult = (mci->csd[2] & 0x00038000) >> 15;
+	}
+
+	mci->capacity = (csize + 1) << (cmult + 2);
+	mci->capacity *= mci->read_bl_len;
+	pr_debug("Capacity: %u MiB\n", (unsigned)mci->capacity >> 20);
+}
+
+/**
+ * Scan the given host interfaces and detect connected MMC/SD cards
+ * @param mci_dev MCI instance
+ * @return 0 on success, negative value else
+ */
+static int mci_startup(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int err;
+
+	pr_debug("Put the Card in Identify Mode\n");
+
+	/* Put the Card in Identify Mode */
+	mci_setup_cmd(&cmd, MMC_CMD_ALL_SEND_CID, 0, MMC_RSP_R2);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Can't bring card into identify mode: %d\n", err);
+		return err;
+	}
+
+	memcpy(mci->cid, cmd.response, 16);
+
+	pr_debug("Card's identification data is: %08X-%08X-%08X-%08X\n",
+		mci->cid[0], mci->cid[1], mci->cid[2], mci->cid[3]);
+
+	/*
+	 * For MMC cards, set the Relative Address.
+	 * For SD cards, get the Relatvie Address.
+	 * This also puts the cards into Standby State
+	 */
+	pr_debug("Get/Set relative address\n");
+	mci_setup_cmd(&cmd, SD_CMD_SEND_RELATIVE_ADDR, mci->rca << 16, MMC_RSP_R6);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Get/Set relative address failed: %d\n", err);
+		return err;
+	}
+
+	if (IS_SD(mci))
+		mci->rca = (cmd.response[0] >> 16) & 0xffff;
+
+	pr_debug("Get card's specific data\n");
+	/* Get the Card-Specific Data */
+	mci_setup_cmd(&cmd, MMC_CMD_SEND_CSD, mci->rca << 16, MMC_RSP_R2);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Getting card's specific data failed: %d\n", err);
+		return err;
+	}
+
+	/* CSD is of 128 bit */
+	memcpy(mci->csd, cmd.response, 16);
+
+	pr_debug("Card's specific data is: %08X-%08X-%08X-%08X\n",
+		mci->csd[0], mci->csd[1], mci->csd[2], mci->csd[3]);
+
+	mci_detect_version_from_csd(mci_dev);
+	mci_extract_max_tran_speed_from_csd(mci_dev);
+	mci_extract_block_lengths_from_csd(mci_dev);
+	mci_extract_card_capacity_from_csd(mci_dev);
+
+	/* sanitiy? */
+	if (mci->read_bl_len > 512) {
+		mci->read_bl_len = 512;
+		pr_warning("Limiting max. read block size down to %u\n",
+				mci->read_bl_len);
+	}
+
+	if (mci->write_bl_len > 512) {
+		mci->write_bl_len = 512;
+		pr_warning("Limiting max. write block size down to %u\n",
+				mci->read_bl_len);
+	}
+	pr_debug("Read block length: %u, Write block length: %u\n",
+		mci->read_bl_len, mci->write_bl_len);
+
+	pr_debug("Select the card, and put it into Transfer Mode\n");
+	/* Select the card, and put it into Transfer Mode */
+	mci_setup_cmd(&cmd, MMC_CMD_SELECT_CARD, mci->rca << 16, MMC_RSP_R1b);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Putting in transfer mode failed: %d\n", err);
+		return err;
+	}
+
+	if (IS_SD(mci))
+		err = sd_change_freq(mci_dev);
+	else
+		err = mmc_change_freq(mci_dev);
+
+	if (err)
+		return err;
+
+	/* Restrict card's capabilities by what the host can do */
+	mci->card_caps &= host->host_caps;
+
+	if (IS_SD(mci)) {
+		if (mci->card_caps & MMC_MODE_4BIT) {
+			pr_debug("Prepare for bus width change\n");
+			mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, mci->rca << 16, MMC_RSP_R1);
+			err = mci_send_cmd(mci_dev, &cmd, NULL);
+			if (err) {
+				pr_debug("Preparing SD for bus width change failed: %d\n", err);
+				return err;
+			}
+
+			pr_debug("Set SD bus width to 4 bit\n");
+			mci_setup_cmd(&cmd, SD_CMD_APP_SET_BUS_WIDTH, 2, MMC_RSP_R1);
+			err = mci_send_cmd(mci_dev, &cmd, NULL);
+			if (err) {
+				pr_debug("Changing SD bus width failed: %d\n", err);
+				/* TODO continue with 1 bit? */
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 4);
+		}
+		/* if possible, speed up the transfer */
+		if (mci->card_caps & MMC_MODE_HS)
+			mci_set_clock(mci_dev, 50000000);
+		else
+			mci_set_clock(mci_dev, 25000000);
+	} else {
+		if (mci->card_caps & MMC_MODE_4BIT) {
+			pr_debug("Set MMC bus width to 4 bit\n");
+			/* Set the card to use 4 bit*/
+			err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL,
+					EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
+			if (err) {
+				pr_debug("Changing MMC bus width failed: %d\n", err);
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 4);
+		} else if (mci->card_caps & MMC_MODE_8BIT) {
+			pr_debug("Set MMC bus width to 8 bit\n");
+			/* Set the card to use 8 bit*/
+			err = mci_switch(mci_dev, EXT_CSD_CMD_SET_NORMAL,
+					EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);
+			if (err) {
+				pr_debug("Changing MMC bus width failed: %d\n", err);
+				return err;
+			}
+			mci_set_bus_width(mci_dev, 8);
+		}
+		/* if possible, speed up the transfer */
+		if (mci->card_caps & MMC_MODE_HS) {
+			if (mci->card_caps & MMC_MODE_HS_52MHz)
+				mci_set_clock(mci_dev, 52000000);
+			else
+				mci_set_clock(mci_dev, 26000000);
+		} else
+			mci_set_clock(mci_dev, 20000000);
+	}
+
+	/* we setup the blocklength only one times for all accesses to this media  */
+	err = mci_set_blocklen(mci_dev, mci->read_bl_len);
+
+	return err;
+}
+
+/**
+ * Detect a SD 2.0 card and enable its features
+ * @param mci_dev MCI instance
+ * @return Transfer status (0 on success)
+ *
+ * By issuing the CMD8 command SDHC/SDXC cards realize that the host supports
+ * the Physical Layer Version 2.00 or later and the card can enable
+ * corresponding new functions.
+ *
+ * If this CMD8 command will end with a timeout it is a MultiMediaCard only.
+ */
+static int sd_send_if_cond(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+	struct mci_cmd cmd;
+	int err;
+
+	mci_setup_cmd(&cmd, SD_CMD_SEND_IF_COND,
+	/* We set the bit if the host supports voltages between 2.7 and 3.6 V */
+		((host->voltages & 0x00ff8000) != 0) << 8 | 0xaa,
+		MMC_RSP_R7);
+	err = mci_send_cmd(mci_dev, &cmd, NULL);
+	if (err) {
+		pr_debug("Query interface conditions failed: %d\n", err);
+		return err;
+	}
+
+	if ((cmd.response[0] & 0xff) != 0xaa) {
+		pr_debug("Card cannot work with hosts supply voltages\n");
+		return -EINVAL;
+	} else {
+		pr_debug("SD Card Rev. 2.00 or later detected\n");
+		mci->version = SD_VERSION_2;
+	}
+
+	return 0;
+}
+
+/* ------------------ attach to the ATA API --------------------------- */
+
+/**
+ * Write a chunk of sectors to media
+ * @param disk_dev Disk device instance
+ * @param sector_start Sector's number to start write to
+ * @param sector_count Sectors to write
+ * @param buffer Buffer to write from
+ * @return 0 on success, anything else on failure
+ *
+ * This routine expects the buffer has the correct size to read all data!
+ */
+static int mci_sd_write(struct device_d *disk_dev, uint64_t sector_start,
+			unsigned sector_count, const void *buffer)
+{
+	struct ata_interface *intf = disk_dev->platform_data;
+	struct device_d *mci_dev = intf->priv;
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int rc;
+
+	pr_debug("%s called: Write %u block(s), starting at %lu",
+		__func__, sector_count, (unsigned)sector_count);
+
+	if (mci->write_bl_len != 512) {
+		pr_warning("MMC/SD block size is not 512 bytes (its %u bytes instead)\n",
+				mci->read_bl_len);
+		return -EINVAL;
+	}
+
+	while (sector_count) {
+		/* size of the block number field in the MMC/SD command is 32 bit only */
+		if (sector_start > MAX_BUFFER_NUMBER) {
+			pr_err("Cannot handle block number %llu. Too large!\n",
+				sector_start);
+			return -EINVAL;
+		}
+		rc = mci_block_write(mci_dev, buffer, sector_start);
+		if (rc != 0) {
+			pr_err("Writing block %u failed\n", (unsigned)sector_start);
+			return rc;
+		}
+		sector_count--;
+		buffer += mci->write_bl_len;
+		sector_start++;
+	}
+
+	return 0;
+}
+
+/**
+ * Read a chunk of sectors from media
+ * @param disk_dev Disk device instance
+ * @param sector_start Sector's number to start read from
+ * @param sector_count Sectors to read
+ * @param buffer Buffer to read into
+ * @return 0 on success, anything else on failure
+ *
+ * This routine expects the buffer has the correct size to store all data!
+ */
+static int mci_sd_read(struct device_d *disk_dev, uint64_t sector_start,
+			unsigned sector_count, void *buffer)
+{
+	struct ata_interface *intf = disk_dev->platform_data;
+	struct device_d *mci_dev = intf->priv;
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	int rc;
+
+	pr_debug("%s called: Read %u block(s), starting at %lu to %08X\n",
+		__func__, sector_count, (unsigned)sector_start, buffer);
+
+	if (mci->read_bl_len != 512) {
+		pr_warning("MMC/SD block size is not 512 bytes (its %u bytes instead)\n",
+				mci->read_bl_len);
+		return -EINVAL;
+	}
+
+	while (sector_count) {
+		if (sector_start > MAX_BUFFER_NUMBER) {
+			pr_err("Cannot handle block number %lu. Too large!\n",
+				(unsigned)sector_start);
+			return -EINVAL;
+		}
+		rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start);
+		if (rc != 0) {
+			pr_err("Reading block %lu failed\n", (unsigned)sector_start);
+			return rc;
+		}
+		sector_count--;
+		buffer += mci->read_bl_len;
+		sector_start++;
+	}
+
+	return 0;
+}
+
+/* ------------------ attach to the device API --------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+/**
+ * Extract the Manufacturer ID from the CID
+ * @param mci Instance data
+ *
+ * The 'MID' is encoded in bit 127:120 in the CID
+ */
+static unsigned extract_mid(struct mci *mci)
+{
+	return mci->cid[0] >> 24;
+}
+
+/**
+ * Extract the OEM/Application ID from the CID
+ * @param mci Instance data
+ *
+ * The 'OID' is encoded in bit 119:104 in the CID
+ */
+static unsigned extract_oid(struct mci *mci)
+{
+	return (mci->cid[0] >> 8) & 0xffff;
+}
+
+/**
+ * Extract the product revision from the CID
+ * @param mci Instance data
+ *
+ * The 'PRV' is encoded in bit 63:56 in the CID
+ */
+static unsigned extract_prv(struct mci *mci)
+{
+	return mci->cid[2] >> 24;
+}
+
+/**
+ * Extract the product serial number from the CID
+ * @param mci Instance data
+ *
+ * The 'PSN' is encoded in bit 55:24 in the CID
+ */
+static unsigned extract_psn(struct mci *mci)
+{
+	return (mci->cid[2] << 8) | (mci->cid[3] >> 24);
+}
+
+/**
+ * Extract the month of the manufacturing date from the CID
+ * @param mci Instance data
+ *
+ * The 'MTD' is encoded in bit 19:8 in the CID, month in 11:8
+ */
+static unsigned extract_mtd_month(struct mci *mci)
+{
+	return (mci->cid[3] >> 8) & 0xf;
+}
+
+/**
+ * Extract the year of the manufacturing date from the CID
+ * @param mci Instance data
+ *
+ * The 'MTD' is encoded in bit 19:8 in the CID, year in 19:12
+ * An encoded 0 means the year 2000
+ */
+static unsigned extract_mtd_year(struct mci *mci)
+{
+	return ((mci->cid[3] >> 12) & 0xff) + 2000U;
+}
+
+/**
+ * Output some valuable information when the user runs 'devinfo' on an MCI device
+ * @param mci_dev MCI device instance
+ */
+static void mci_info(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	if (mci->ready_for_use == 0) {
+		printf(" No information available:\n  MCI card not probed yet\n");
+		return;
+	}
+
+	printf(" Card:\n");
+	if (mci->version < SD_VERSION_SD) {
+		printf("  Attached is a MultiMediaCard (Version: %u.%u)\n",
+			(mci->version >> 4) & 0xf, mci->version & 0xf);
+	} else {
+		printf("  Attached is an SD Card (Version: %u.%u)\n",
+			(mci->version >> 4) & 0xf, mci->version & 0xf);
+	}
+	printf("  Capacity: %u MiB\n", (unsigned)(mci->capacity >> 20));
+
+	if (mci->high_capacity)
+		printf("  High capacity card\n");
+	printf("   CID: %08X-%08X-%08X-%08X\n", mci->cid[0], mci->cid[1],
+		mci->cid[2], mci->cid[3]);
+	printf("   CSD: %08X-%08X-%08X-%08X\n", mci->csd[0], mci->csd[1],
+		mci->csd[2], mci->csd[3]);
+	printf("  Max. transfer speed: %u Hz\n", mci->tran_speed);
+	printf("  Manufacturer ID: %02X\n", extract_mid(mci));
+	printf("  OEM/Application ID: %04X\n", extract_oid(mci));
+	printf("  Product name: '%c%c%c%c%c'\n", mci->cid[0] & 0xff,
+		(mci->cid[1] >> 24), (mci->cid[1] >> 16) & 0xff,
+		(mci->cid[1] >> 8) & 0xff, mci->cid[1] & 0xff);
+	printf("  Product revision: %u.%u\n", extract_prv(mci) >> 4,
+		extract_prv(mci) & 0xf);
+	printf("  Serial no: %0u\n", extract_psn(mci));
+	printf("  Manufacturing date: %u.%u\n", extract_mtd_month(mci),
+		extract_mtd_year(mci));
+}
+#endif
+
+/**
+ * Check if the MCI card is already probed
+ * @param mci_dev MCI device instance
+ * @return 0 when not probed yet, -EPERM if already probed
+ *
+ * @a barebox cannot really cope with hot plugging. So, probing an attached
+ * MCI card is a one time only job. If its already done, there is no way to
+ * return.
+ */
+static int mci_check_if_already_initialized(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+
+	if (mci->ready_for_use != 0)
+		return -EPERM;
+
+	return 0;
+}
+
+/**
+ * Probe an MCI card at the given host interface
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative values else
+ */
+static int mci_card_probe(struct device_d *mci_dev)
+{
+	struct mci *mci = GET_MCI_DATA(mci_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+	struct device_d *disk_dev;
+	struct ata_interface *p;
+	int rc;
+
+	/* start with a host interface reset */
+	rc = (host->init)(host, mci_dev);
+	if (rc) {
+		pr_err("Cannot reset the SD/MMC interface\n");
+		return rc;
+	}
+
+	mci_set_bus_width(mci_dev, 1);
+	mci_set_clock(mci_dev, 1);	/* set the lowest available clock */
+
+	/* reset the card */
+	rc = mci_go_idle(mci_dev);
+	if (rc) {
+		pr_warning("Cannot reset the SD/MMC card\n");
+		goto on_error;
+	}
+
+	/* Check if this card can handle the "SD Card Physical Layer Specification 2.0" */
+	rc = sd_send_if_cond(mci_dev);
+	if (rc) {
+		/* If the command timed out, we check for an MMC card */
+		if (rc == -ETIMEDOUT) {
+			pr_debug("Card seems to be a MultiMediaCard\n");
+			rc = mmc_send_op_cond(mci_dev);
+			if (rc) {
+				pr_err("MultiMediaCard did not respond to voltage select!\n");
+				rc = -ENODEV;
+				goto on_error;
+			}
+		} else
+			goto on_error;
+	} else {
+		/* Its a 2.xx card. Setup operation conditions */
+		rc = sd_send_op_cond(mci_dev);
+		if (rc) {
+			pr_debug("Cannot setup SD card's operation condition\n");
+			goto on_error;
+		}
+	}
+
+	rc = mci_startup(mci_dev);
+	if (rc) {
+		printf("Card's startup fails with %d\n", rc);
+		goto on_error;
+	}
+
+	pr_debug("Card is up and running now, registering as a disk\n");
+	mci->ready_for_use = 1;	/* TODO now or later? */
+
+	/*
+	 * An MMC/SD card acts like an ordinary disk.
+	 * So, re-use the disk driver to gain access to this media
+	 */
+	disk_dev = xzalloc(sizeof(struct device_d) + sizeof(struct ata_interface));
+	p = (struct ata_interface*)&disk_dev[1];
+
+	p->write = mci_sd_write;
+	p->read = mci_sd_read;
+	p->priv = mci_dev;
+
+	strcpy(disk_dev->name, "disk");
+	disk_dev->size = mci->capacity;
+	disk_dev->map_base = 0;
+	disk_dev->platform_data = p;
+
+	register_device(disk_dev);
+
+	pr_debug("SD Card successfully added\n");
+
+on_error:
+	if (rc != 0) {
+		host->clock = 0;	/* disable the MCI clock */
+		mci_set_ios(mci_dev);
+	}
+
+	return rc;
+}
+
+/**
+ * Trigger probing of an attached MCI card
+ * @param mci_dev MCI device instance
+ * @param param FIXME
+ * @param val "0" does nothing, a "1" will probe for a MCI card
+ * @return 0 on success
+ */
+static int mci_set_probe(struct device_d *mci_dev, struct param_d *param,
+				const char *val)
+{
+	int rc, probe;
+
+	rc = mci_check_if_already_initialized(mci_dev);
+	if (rc != 0)
+		return rc;
+
+	probe = simple_strtoul(val, NULL, 0);
+	if (probe != 0) {
+		rc = mci_card_probe(mci_dev);
+		if (rc != 0)
+			return rc;
+	}
+
+	return dev_param_set_generic(mci_dev, param, val);
+}
+
+/**
+ * Add parameter to the MCI device on demand
+ * @param mci_dev MCI device instance
+ * @return 0 on success
+ *
+ * This parameter is only available (or usefull) if MCI card probing is delayed
+ */
+static int add_mci_parameter(struct device_d *mci_dev)
+{
+	int rc;
+
+	/* provide a 'probing right now' parameter for the user */
+	rc = dev_add_param(mci_dev, "probe", mci_set_probe, NULL, 0);
+	if (rc != 0)
+		return rc;
+
+	return dev_set_param(mci_dev, "probe", "0");
+}
+
+/**
+ * Prepare for MCI card's usage
+ * @param mci_dev MCI device instance
+ * @return 0 on success
+ *
+ * This routine will probe an attached MCI card immediately or provide
+ * a parameter to do it later on user's demand.
+ */
+static int mci_probe(struct device_d *mci_dev)
+{
+	struct mci *mci;
+	int rc;
+
+	mci = xzalloc(sizeof(struct mci));
+	mci_dev->priv = mci;
+
+#ifdef CONFIG_MCI_STARTUP
+	/* if enabled, probe the attached card immediately */
+	rc = mci_card_probe(mci_dev);
+	if (rc == -ENODEV) {
+		/*
+		 * If it fails, add the 'probe' parameter to give the user
+		 * a chance to insert a card and try again. Note: This may fail
+		 * systems that rely on the MCI card for startup (for the
+		 * persistant environment for example)
+		 */
+		rc = add_mci_parameter(mci_dev);
+		if (rc != 0) {
+			pr_err("Failed to add 'probe' parameter to the MCI device\n");
+			goto on_error;
+		}
+	}
+#endif
+
+#ifndef CONFIG_MCI_STARTUP
+	/* add params on demand */
+	rc = add_mci_parameter(mci_dev);
+	if (rc != 0) {
+		pr_err("Failed to add 'probe' parameter to the MCI device\n");
+		goto on_error;
+	}
+#endif
+
+	return rc;
+
+on_error:
+	free(mci);
+	return rc;
+}
+
+static struct driver_d mci_driver = {
+	.name	= "mci",
+	.probe	= mci_probe,
+	.info	= mci_info,
+};
+
+static int mci_init(void)
+{
+	return register_driver(&mci_driver);
+}
+
+device_initcall(mci_init);
+
+/**
+ * Create a new mci device (for convenience)
+ * @param pdata MCI device's platform data for this MCI device
+ * @return 0 on success
+ */
+int mci_register(struct mci_host *host)
+{
+	struct device_d *mci_dev;
+
+	mci_dev = xzalloc(sizeof(struct device_d));
+
+	strcpy(mci_dev->name, mci_driver.name);
+	mci_dev->platform_data = (void*)host;
+
+	return register_device(mci_dev);
+}
diff --git a/include/mci.h b/include/mci.h
new file mode 100644
index 0000000..8c669ca
--- /dev/null
+++ b/include/mci.h
@@ -0,0 +1,239 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is partially based on u-boot code:
+ *
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MCI_H_
+#define _MCI_H_
+
+#include <linux/list.h>
+
+/* Firmware revisions for SD cards */
+#define SD_VERSION_SD		0x20000
+#define SD_VERSION_2		(SD_VERSION_SD | 0x20)
+#define SD_VERSION_1_0		(SD_VERSION_SD | 0x10)
+#define SD_VERSION_1_10		(SD_VERSION_SD | 0x1a)
+
+/* Firmware revisions for MMC cards */
+#define MMC_VERSION_MMC		0x10000
+#define MMC_VERSION_UNKNOWN	(MMC_VERSION_MMC)
+#define MMC_VERSION_1_2		(MMC_VERSION_MMC | 0x12)
+#define MMC_VERSION_1_4		(MMC_VERSION_MMC | 0x14)
+#define MMC_VERSION_2_2		(MMC_VERSION_MMC | 0x22)
+#define MMC_VERSION_3		(MMC_VERSION_MMC | 0x30)
+#define MMC_VERSION_4		(MMC_VERSION_MMC | 0x40)
+
+#define MMC_MODE_HS		0x001
+#define MMC_MODE_HS_52MHz	0x010
+#define MMC_MODE_4BIT		0x100
+#define MMC_MODE_8BIT		0x200
+
+#define SD_DATA_4BIT		0x00040000
+
+#define IS_SD(x) (x->version & SD_VERSION_SD)
+
+#define MMC_DATA_READ		1
+#define MMC_DATA_WRITE		2
+
+/* command list */
+#define MMC_CMD_GO_IDLE_STATE		0
+#define MMC_CMD_SEND_OP_COND		1
+#define MMC_CMD_ALL_SEND_CID		2
+#define MMC_CMD_SET_RELATIVE_ADDR	3
+#define MMC_CMD_SET_DSR			4
+#define MMC_CMD_SWITCH			6
+#define MMC_CMD_SELECT_CARD		7
+#define MMC_CMD_SEND_EXT_CSD		8
+#define MMC_CMD_SEND_CSD		9
+#define MMC_CMD_SEND_CID		10
+#define MMC_CMD_STOP_TRANSMISSION	12
+#define MMC_CMD_SEND_STATUS		13
+#define MMC_CMD_SET_BLOCKLEN		16
+#define MMC_CMD_READ_SINGLE_BLOCK	17
+#define MMC_CMD_READ_MULTIPLE_BLOCK	18
+#define MMC_CMD_WRITE_SINGLE_BLOCK	24
+#define MMC_CMD_WRITE_MULTIPLE_BLOCK	25
+#define MMC_CMD_APP_CMD			55
+
+#define SD_CMD_SEND_RELATIVE_ADDR	3
+#define SD_CMD_SWITCH_FUNC		6
+#define SD_CMD_SEND_IF_COND		8
+
+#define SD_CMD_APP_SET_BUS_WIDTH	6
+#define SD_CMD_APP_SEND_OP_COND		41
+#define SD_CMD_APP_SEND_SCR		51
+
+/* SCR definitions in different words */
+#define SD_HIGHSPEED_BUSY	0x00020000
+#define SD_HIGHSPEED_SUPPORTED	0x00020000
+
+#define MMC_HS_TIMING		0x00000100
+#define MMC_HS_52MHZ		0x2
+
+#define OCR_BUSY		0x80000000
+/** card's response in its OCR if it is a high capacity card */
+#define OCR_HCS			0x40000000
+
+#define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
+#define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */
+#define MMC_VDD_21_22		0x00000200	/* VDD voltage 2.1 ~ 2.2 */
+#define MMC_VDD_22_23		0x00000400	/* VDD voltage 2.2 ~ 2.3 */
+#define MMC_VDD_23_24		0x00000800	/* VDD voltage 2.3 ~ 2.4 */
+#define MMC_VDD_24_25		0x00001000	/* VDD voltage 2.4 ~ 2.5 */
+#define MMC_VDD_25_26		0x00002000	/* VDD voltage 2.5 ~ 2.6 */
+#define MMC_VDD_26_27		0x00004000	/* VDD voltage 2.6 ~ 2.7 */
+#define MMC_VDD_27_28		0x00008000	/* VDD voltage 2.7 ~ 2.8 */
+#define MMC_VDD_28_29		0x00010000	/* VDD voltage 2.8 ~ 2.9 */
+#define MMC_VDD_29_30		0x00020000	/* VDD voltage 2.9 ~ 3.0 */
+#define MMC_VDD_30_31		0x00040000	/* VDD voltage 3.0 ~ 3.1 */
+#define MMC_VDD_31_32		0x00080000	/* VDD voltage 3.1 ~ 3.2 */
+#define MMC_VDD_32_33		0x00100000	/* VDD voltage 3.2 ~ 3.3 */
+#define MMC_VDD_33_34		0x00200000	/* VDD voltage 3.3 ~ 3.4 */
+#define MMC_VDD_34_35		0x00400000	/* VDD voltage 3.4 ~ 3.5 */
+#define MMC_VDD_35_36		0x00800000	/* VDD voltage 3.5 ~ 3.6 */
+
+#define MMC_SWITCH_MODE_CMD_SET		0x00 /** Change the command set */
+ /** Set bits in EXT_CSD byte addressed by index which are 1 in value field */
+#define MMC_SWITCH_MODE_SET_BITS	0x01
+ /** Clear bits in EXT_CSD byte addressed by index, which are 1 in value field */
+#define MMC_SWITCH_MODE_CLEAR_BITS	0x02
+ /** Set target byte to value */
+#define MMC_SWITCH_MODE_WRITE_BYTE	0x03
+
+#define SD_SWITCH_CHECK		0
+#define SD_SWITCH_SWITCH	1
+
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_BUS_WIDTH	183	/* R/W */
+#define EXT_CSD_HS_TIMING	185	/* R/W */
+#define EXT_CSD_CARD_TYPE	196	/* RO */
+#define EXT_CSD_REV		192	/* RO */
+#define EXT_CSD_SEC_CNT		212	/* RO, 4 bytes */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_CMD_SET_NORMAL		(1<<0)
+#define EXT_CSD_CMD_SET_SECURE		(1<<1)
+#define EXT_CSD_CMD_SET_CPSECURE	(1<<2)
+
+#define EXT_CSD_CARD_TYPE_26	(1<<0)	/* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52	(1<<1)	/* Card can run at 52MHz */
+
+#define EXT_CSD_BUS_WIDTH_1	0	/* Card is in 1 bit mode */
+#define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
+#define EXT_CSD_BUS_WIDTH_8	2	/* Card is in 8 bit mode */
+
+#define R1_ILLEGAL_COMMAND		(1 << 22)
+#define R1_APP_CMD			(1 << 5)
+
+/* response types */
+#define MMC_RSP_PRESENT (1 << 0)
+#define MMC_RSP_136     (1 << 1)                /* 136 bit response */
+#define MMC_RSP_CRC     (1 << 2)                /* expect valid crc */
+#define MMC_RSP_BUSY    (1 << 3)                /* card may send busy */
+#define MMC_RSP_OPCODE  (1 << 4)                /* response contains opcode */
+
+#define MMC_RSP_NONE    (0)
+#define MMC_RSP_R1      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R1b	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
+#define MMC_RSP_R2      (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
+#define MMC_RSP_R3      (MMC_RSP_PRESENT)
+#define MMC_RSP_R4      (MMC_RSP_PRESENT)
+#define MMC_RSP_R5      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R6      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R7      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+
+/** command information to be sent to the SD/MMC card */
+struct mci_cmd {
+	unsigned cmdidx;	/**< Command to be sent to the SD/MMC card */
+	unsigned resp_type;	/**< Type of expected response, refer MMC_RSP_* macros */
+	unsigned cmdarg;	/**< Command's arguments */
+	unsigned response[4];	/**< card's response */
+};
+
+/** data information to be used with some SD/MMC commands */
+struct mci_data {
+	union {
+		uint8_t *dest;
+		const uint8_t *src; /**< src buffers don't get written to */
+	};
+	unsigned flags;		/**< refer MMC_DATA_* to define direction */
+	unsigned blocks;	/**< block count to handle in this command */
+	unsigned blocksize;	/**< block size in bytes (mostly 512) */
+};
+
+/** host information */
+struct mci_host {
+	struct device_d *hw_dev;	/**< the host MCI hardware device */
+	unsigned voltages;
+	unsigned host_caps;	/**< Host's interface capabilities, refer MMC_VDD_* */
+	unsigned f_min;		/**< host interface lower limit */
+	unsigned f_max;		/**< host interface upper limit */
+	unsigned clock;		/**< Current clock used to talk to the card */
+	unsigned bus_width;	/**< used data bus width to the card */
+
+	/** init the host interface */
+	int (*init)(struct mci_host*, struct device_d*);
+	/** change host interface settings */
+	void (*set_ios)(struct mci_host*, struct device_d*, unsigned, unsigned);
+	/** handle a command */
+	int (*send_cmd)(struct mci_host*, struct mci_cmd*, struct mci_data*);
+};
+
+/** MMC/SD and interface instance information */
+struct mci {
+	unsigned version;
+	/** != 0 when a high capacity card is connected (OCR -> OCR_HCS) */
+	int high_capacity;
+	unsigned card_caps;	/**< Card's capabilities */
+	unsigned ocr;		/**< card's "operation condition register" */
+	unsigned scr[2];
+	unsigned csd[4];	/**< card's "card specific data register" */
+	unsigned cid[4];	/**< card's "card identification register" */
+	unsigned short rca;	/* FIXME */
+	unsigned tran_speed;	/**< not yet used */
+	/** currently used data block length for read accesses */
+	unsigned read_bl_len;
+	/** currently used data block length for write accesses */
+	unsigned write_bl_len;
+	uint64_t capacity;	/**< Card's data capacity in bytes */
+	int ready_for_use;	/** true if already probed */
+};
+
+int mci_register(struct mci_host*);
+
+#define GET_HOST_DATA(x) (x->priv)
+#define GET_HOST_PDATA(x) (x->platform_data)
+#define GET_MCI_DATA(x) (x->priv)
+#define GET_MCI_PDATA(x) (x->platform_data)
+
+#endif /* _MCI_H_ */
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:55 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:55 +0200
Subject: [PATCH 07/10] Add S3C2440 MCI card support
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-8-git-send-email-jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>

Adding MCI card support for S3C2440 CPUs. This is for reference only, as there
is currently no user in the barebox tree. Maybe one with access to the A9M2440
development kit can check it on his/her system.
Checked here with my own S3C2440 based system which is not in the barebox tree.

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
---
 arch/arm/mach-s3c24xx/include/mach/mci.h |   46 ++
 drivers/mci/Kconfig                      |    7 +
 drivers/mci/Makefile                     |    1 +
 drivers/mci/s3c.c                        |  817 ++++++++++++++++++++++++++++++
 4 files changed, 871 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s3c24xx/include/mach/mci.h
 create mode 100644 drivers/mci/s3c.c

diff --git a/arch/arm/mach-s3c24xx/include/mach/mci.h b/arch/arm/mach-s3c24xx/include/mach/mci.h
new file mode 100644
index 0000000..6ba8961
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/mci.h
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is partially based on u-boot code:
+ *
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MACH_MMC_H_
+#define __MACH_MMC_H_
+
+struct s3c_mci_platform_data {
+	unsigned caps;	/**< supported operating modes (MMC_MODE_*) */
+	unsigned voltages; /**< supported voltage range (MMC_VDD_*) */
+	unsigned f_min;	/**< min operating frequency in Hz (0 -> no limit) */
+	unsigned f_max;	/**< max operating frequency in Hz (0 -> no limit) */
+	/* TODO */
+	/* function to modify the voltage */
+	/* function to switch the voltage */
+	/* function to detect the presence of a SD card in the socket */
+	unsigned gpio_detect;
+	unsigned detect_invert;
+};
+
+#endif /* __MACH_MMC_H_ */
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index a24ae6d..644c0a3 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -34,4 +34,11 @@ config MCI_STM378X
 	  Enable this entry to add support to read and write SD cards on a
 	  i.MX23 based system.
 
+config MCI_S3C
+	bool "S3C"
+	depends on ARCH_S3C24xx
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  Samsung S3C24xx based system.
+
 endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index e5e19b0..be18446 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_MCI)	+= mci-core.o
 obj-$(CONFIG_MCI_STM378X) += stm378x.o
+obj-$(CONFIG_MCI_S3C) += s3c.o
diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
new file mode 100644
index 0000000..9810683
--- /dev/null
+++ b/drivers/mci/s3c.c
@@ -0,0 +1,817 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert <juergen at kreuzholzen.de>
+ *
+ * This code is partially based on u-boot code:
+ *
+ * This code is based on various Linux and u-boot sources:
+ *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk at maintech.de>
+ *  Copyright (C) 2008 Simtec Electronics <ben-linux at fluff.org>
+ *  (C) Copyright 2006 by OpenMoko, Inc.
+ *  Author: Harald Welte <laforge at openmoko.org>
+ *  based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
+ *  (C) 2005-2005 Thomas Kleffel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * @file
+ * @brief MCI card host interface for S3C2440 CPU
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <mci.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+#include <mach/mci.h>
+#include <mach/s3c24xx-generic.h>
+#include <mach/s3c24x0-iomap.h>
+
+#define SDICON 0x0
+# define SDICON_SDRESET (1 << 8)
+# define SDICON_MMCCLOCK (1 << 5) /* this is a clock type SD or MMC style WTF? */
+# define SDICON_BYTEORDER (1 << 4)
+# define SDICON_SDIOIRQ (1 << 3)
+# define SDICON_RWAITEN (1 << 2)
+# define SDICON_FIFORESET (1 << 1) /* reserved bit on 2440 ????? */
+# define SDICON_CLKEN (1 << 0) /* enable/disable external clock */
+
+#define SDIPRE 0x4
+
+#define SDICMDARG 0x8
+
+#define SDICMDCON 0xc
+# define SDICMDCON_ABORT (1 << 12)
+# define SDICMDCON_WITHDATA (1 << 11)
+# define SDICMDCON_LONGRSP (1 << 10)
+# define SDICMDCON_WAITRSP (1 << 9)
+# define SDICMDCON_CMDSTART (1 << 8)
+# define SDICMDCON_SENDERHOST (1 << 6)
+# define SDICMDCON_INDEX (0x3f)
+
+#define SDICMDSTAT 0x10
+# define SDICMDSTAT_CRCFAIL (1 << 12)
+# define SDICMDSTAT_CMDSENT (1 << 11)
+# define SDICMDSTAT_CMDTIMEOUT (1 << 10)
+# define SDICMDSTAT_RSPFIN (1 << 9)
+# define SDICMDSTAT_XFERING (1 << 8)
+# define SDICMDSTAT_INDEX (0xff)
+
+#define SDIRSP0 0x14
+#define SDIRSP1 0x18
+#define SDIRSP2 0x1C
+#define SDIRSP3 0x20
+
+#define SDITIMER 0x24
+#define SDIBSIZE 0x28
+
+#define SDIDCON 0x2c
+# define SDIDCON_DS_BYTE (0 << 22)
+# define SDIDCON_DS_HALFWORD (1 << 22)
+# define SDIDCON_DS_WORD (2 << 22)
+# define SDIDCON_IRQPERIOD (1 << 21)
+# define SDIDCON_TXAFTERRESP (1 << 20)
+# define SDIDCON_RXAFTERCMD (1 << 19)
+# define SDIDCON_BUSYAFTERCMD (1 << 18)
+# define SDIDCON_BLOCKMODE (1 << 17)
+# define SDIDCON_WIDEBUS (1 << 16)
+# define SDIDCON_DMAEN (1 << 15)
+# define SDIDCON_STOP (0 << 14)
+# define SDIDCON_DATSTART (1 << 14)
+# define SDIDCON_DATMODE (3 << 12)
+# define SDIDCON_BLKNUM (0xfff)
+# define SDIDCON_XFER_READY    (0 << 12)
+# define SDIDCON_XFER_CHKSTART (1 << 12)
+# define SDIDCON_XFER_RXSTART  (2 << 12)
+# define SDIDCON_XFER_TXSTART  (3 << 12)
+
+#define SDIDCNT 0x30
+# define SDIDCNT_BLKNUM_SHIFT 12
+
+#define SDIDSTA 0x34
+# define SDIDSTA_RDYWAITREQ (1 << 10)
+# define SDIDSTA_SDIOIRQDETECT (1 << 9)
+# define SDIDSTA_FIFOFAIL (1 << 8) /* reserved on 2440 */
+# define SDIDSTA_CRCFAIL (1 << 7)
+# define SDIDSTA_RXCRCFAIL (1 << 6)
+# define SDIDSTA_DATATIMEOUT (1 << 5)
+# define SDIDSTA_XFERFINISH (1 << 4)
+# define SDIDSTA_BUSYFINISH (1 << 3)
+# define SDIDSTA_SBITERR (1 << 2) /* reserved on 2410a/2440 */
+# define SDIDSTA_TXDATAON (1 << 1)
+# define SDIDSTA_RXDATAON (1 << 0)
+
+#define SDIFSTA 0x38
+# define SDIFSTA_FIFORESET (1<<16)
+# define SDIFSTA_FIFOFAIL (3<<14)  /* 3 is correct (2 bits) */
+# define SDIFSTA_TFDET (1<<13)
+# define SDIFSTA_RFDET (1<<12)
+# define SDIFSTA_TFHALF (1<<11)
+# define SDIFSTA_TFEMPTY (1<<10)
+# define SDIFSTA_RFLAST (1<<9)
+# define SDIFSTA_RFFULL (1<<8)
+# define SDIFSTA_RFHALF (1<<7)
+# define SDIFSTA_COUNTMASK (0x7f)
+
+#define SDIIMSK 0x3C
+# define SDIIMSK_RESPONSECRC    (1<<17)
+# define SDIIMSK_CMDSENT        (1<<16)
+# define SDIIMSK_CMDTIMEOUT     (1<<15)
+# define SDIIMSK_RESPONSEND     (1<<14)
+# define SDIIMSK_READWAIT       (1<<13)
+# define SDIIMSK_SDIOIRQ        (1<<12)
+# define SDIIMSK_FIFOFAIL       (1<<11)
+# define SDIIMSK_CRCSTATUS      (1<<10)
+# define SDIIMSK_DATACRC        (1<<9)
+# define SDIIMSK_DATATIMEOUT    (1<<8)
+# define SDIIMSK_DATAFINISH     (1<<7)
+# define SDIIMSK_BUSYFINISH     (1<<6)
+# define SDIIMSK_SBITERR        (1<<5) /* reserved 2440/2410a */
+# define SDIIMSK_TXFIFOHALF     (1<<4)
+# define SDIIMSK_TXFIFOEMPTY    (1<<3)
+# define SDIIMSK_RXFIFOLAST     (1<<2)
+# define SDIIMSK_RXFIFOFULL     (1<<1)
+# define SDIIMSK_RXFIFOHALF     (1<<0)
+
+#define SDIDATA 0x40
+
+struct s3c_mci_host {
+	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
+	unsigned	clock;	/* current clock in Hz */
+	unsigned	data_size;	/* data transfer in bytes */
+};
+
+/*
+ * There is only one host MCI hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct s3c_mci_host host_data;
+
+/**
+ * Finish a request
+ * @param hw_dev Host interface instance
+ *
+ * Just a little bit paranoia.
+ */
+static void s3c_finish_request(struct device_d *hw_dev)
+{
+	/* TODO ensure the engines are stopped */
+}
+
+/* TODO GPIO feature is required for this architecture */
+static unsigned gpio_get_value(unsigned val)
+{
+	return 0;
+}
+
+/**
+ * Detect if a card is plugged in
+ * @param hw_dev Host interface instance
+ * @return 0 if a card is plugged in
+ *
+ * Note: If there is no GPIO registered to detect if a card is present, we
+ * assume a card _is_ present.
+ */
+static int s3c_mci_card_present(struct device_d *hw_dev)
+{
+	struct s3c_mci_platform_data *pd = GET_HOST_PDATA(hw_dev);
+	int ret;
+
+	if (pd->gpio_detect == 0)
+		return 0;	/* assume the card is present */
+
+	ret = gpio_get_value(pd->gpio_detect) ? 0 : 1;
+	return ret ^ pd->detect_invert;
+}
+
+/**
+ * Setup a new clock frequency on this MCI bus
+ * @param hw_dev Host interface instance
+ * @param nc New clock value in Hz (can be 0)
+ * @return New clock value (may differ from 'nc')
+ */
+static unsigned s3c_setup_clock_speed(struct device_d *hw_dev, unsigned nc)
+{
+	unsigned clock;
+	uint32_t mci_psc;
+
+	if (nc == 0)
+		return 0;
+
+	clock = s3c24xx_get_pclk();
+	/* Calculate the required prescaler value to get the requested frequency */
+	mci_psc = (clock + (nc >> 2)) / nc;
+
+	if (mci_psc > 256) {
+		mci_psc = 256;
+		pr_warning("SD/MMC clock might be too high!\n");
+	}
+
+	writel(mci_psc - 1, hw_dev->map_base + SDIPRE);
+
+	return clock / mci_psc;
+}
+
+/**
+ * Reset the MCI engine (the hard way)
+ * @param hw_dev Host interface instance
+ *
+ * This will reset everything in all registers of this unit!
+ */
+static void s3c_mci_reset(struct device_d *hw_dev)
+{
+	/* reset the hardware */
+	writel(SDICON_SDRESET, hw_dev->map_base + SDICON);
+	/* wait until reset it finished */
+	while (readl(hw_dev->map_base + SDICON) & SDICON_SDRESET)
+		;
+}
+
+/**
+ * Initialize hard and software
+ * @param hw_dev Host interface instance
+ * @param mci_dev MCI device instance (might be NULL)
+ */
+static int s3c_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
+{
+	struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
+
+	s3c_mci_reset(hw_dev);
+
+	/* restore last settings */
+	host_data->clock = s3c_setup_clock_speed(hw_dev, host_data->clock);
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+	writel(SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
+	writel(512, hw_dev->map_base + SDIBSIZE);
+
+	return 0;
+}
+
+/**
+ * Prepare engine's bits for the next command transfer
+ * @param cmd_flags MCI's command flags
+ * @param data_flags MCI's data flags
+ * @return Register bits for this transfer
+ */
+static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned data_flags)
+{
+	uint32_t reg;
+
+	/* source (=host) */
+	reg = SDICMDCON_SENDERHOST;
+
+	if (cmd_flags & MMC_RSP_PRESENT) {
+		reg |= SDICMDCON_WAITRSP;
+		pr_debug("Command with response\n");
+	}
+	if (cmd_flags & MMC_RSP_136) {
+		reg |= SDICMDCON_LONGRSP;
+		pr_debug("Command with long response\n");
+	}
+	if (cmd_flags & MMC_RSP_CRC)
+		; /* FIXME */
+	if (cmd_flags & MMC_RSP_BUSY)
+		; /* FIXME */
+	if (cmd_flags & MMC_RSP_OPCODE)
+		; /* FIXME */
+	if (data_flags != 0)
+		reg |= SDICMDCON_WITHDATA;
+
+	return reg;
+}
+
+/**
+ * Prepare engine's bits for the next data transfer
+ * @param hw_dev Host interface device instance
+ * @param data_flags MCI's data flags
+ * @return Register bits for this transfer
+ */
+static uint32_t s3c_prepare_data_setup(struct device_d *hw_dev, unsigned data_flags)
+{
+	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
+	uint32_t reg = SDIDCON_BLOCKMODE;	/* block mode only is supported */
+
+	if (host_data->bus_width == 1)
+		reg |= SDIDCON_WIDEBUS;
+
+	/* enable any kind of data transfers on demand only */
+	if (data_flags & MMC_DATA_WRITE)
+		reg |= SDIDCON_TXAFTERRESP | SDIDCON_XFER_TXSTART;
+
+	if (data_flags & MMC_DATA_READ)
+		reg |= SDIDCON_RXAFTERCMD | SDIDCON_XFER_RXSTART;
+
+	/* TODO: Support more than the 2440 CPU */
+	reg |= SDIDCON_DS_WORD | SDIDCON_DATSTART;
+
+	return reg;
+}
+
+/**
+ * Terminate a current running transfer
+ * @param hw_dev Host interface device instance
+ * @return 0 on success
+ *
+ * Note: Try to stop a running transfer. This should not happen, as all
+ * transfers must complete in this driver. But who knows... ;-)
+ */
+static int s3c_terminate_transfer(struct device_d *hw_dev)
+{
+	unsigned stoptries = 3;
+
+	while (readl(hw_dev->map_base + SDIDSTA) & (SDIDSTA_TXDATAON | SDIDSTA_RXDATAON)) {
+		pr_debug("Transfer still in progress.\n");
+
+		writel(SDIDCON_STOP, hw_dev->map_base + SDIDCON);
+		s3c_mci_initialize(hw_dev, NULL);
+
+		if ((stoptries--) == 0) {
+			pr_warning("Cannot stop the engine!\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Setup registers for data transfer
+ * @param hw_dev Host interface device instance
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_prepare_data_transfer(struct device_d *hw_dev, struct mci_data *data)
+{
+	uint32_t reg;
+
+	writel(data->blocksize, hw_dev->map_base + SDIBSIZE);
+	reg = s3c_prepare_data_setup(hw_dev, data->flags);
+	reg |= data->blocks & SDIDCON_BLKNUM;
+	writel(reg, hw_dev->map_base + SDIDCON);
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+
+	return 0;
+}
+
+/**
+ * Send a command and receive the response
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_send_command(struct device_d *hw_dev, struct mci_cmd *cmd,
+				struct mci_data *data)
+{
+	uint32_t reg, t1;
+	int rc;
+
+	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
+
+	/* setup argument */
+	writel(cmd->cmdarg, hw_dev->map_base + SDICMDARG);
+
+	/* setup command and transfer characteristic */
+	reg = s3c_prepare_command_setup(cmd->resp_type, data != NULL ? data->flags : 0);
+	reg |= cmd->cmdidx & SDICMDCON_INDEX;
+
+	/* run the command right now */
+	writel(reg | SDICMDCON_CMDSTART, hw_dev->map_base + SDICMDCON);
+	t1 = readl(hw_dev->map_base + SDICMDSTAT);
+	/* wait until command is done */
+	while (1) {
+		reg = readl(hw_dev->map_base + SDICMDSTAT);
+		/* done? */
+		if (cmd->resp_type & MMC_RSP_PRESENT) {
+			if (reg & SDICMDSTAT_RSPFIN) {
+				writel(SDICMDSTAT_RSPFIN,
+					hw_dev->map_base + SDICMDSTAT);
+				rc = 0;
+				break;
+			}
+		} else {
+			if (reg & SDICMDSTAT_CMDSENT) {
+					writel(SDICMDSTAT_CMDSENT,
+						hw_dev->map_base + SDICMDSTAT);
+					rc = 0;
+					break;
+			}
+		}
+		/* timeout? */
+		if (reg & SDICMDSTAT_CMDTIMEOUT) {
+			writel(SDICMDSTAT_CMDTIMEOUT,
+				hw_dev->map_base + SDICMDSTAT);
+			rc = -ETIMEDOUT;
+			break;
+		}
+	}
+
+	if ((rc == 0) && (cmd->resp_type & MMC_RSP_PRESENT)) {
+		cmd->response[0] = readl(hw_dev->map_base + SDIRSP0);
+		cmd->response[1] = readl(hw_dev->map_base + SDIRSP1);
+		cmd->response[2] = readl(hw_dev->map_base + SDIRSP2);
+		cmd->response[3] = readl(hw_dev->map_base + SDIRSP3);
+	}
+	/* do not disable the clock! */
+	return rc;
+}
+
+/**
+ * Clear major registers prior a new transaction
+ * @param hw_dev Host interface device instance
+ * @return 0 on success
+ *
+ * FIFO clear is only necessary on 2440, but doesn't hurt on 2410
+ */
+static int s3c_prepare_engine(struct device_d *hw_dev)
+{
+	int rc;
+
+	rc = s3c_terminate_transfer(hw_dev);
+	if (rc != 0)
+		return rc;
+
+	writel(-1, hw_dev->map_base + SDICMDSTAT);
+	writel(-1, hw_dev->map_base + SDIDSTA);
+	writel(-1, hw_dev->map_base + SDIFSTA);
+
+	return 0;
+}
+
+/**
+ * Handle MCI commands without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @return 0 on success
+ *
+ * This functions handles the following MCI commands:
+ * - "broadcast command (BC)" without a response
+ * - "broadcast commands with response (BCR)"
+ * - "addressed command (AC)" with response, but without data
+ */
+static int s3c_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
+{
+	int rc;
+
+	rc = s3c_prepare_engine(hw_dev);
+	if (rc != 0)
+		return 0;
+
+	return s3c_send_command(hw_dev, cmd, NULL);
+}
+
+/**
+ * Read one block of data from the FIFO
+ * @param hw_dev Host interface device instance
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ */
+static int s3c_mci_read_block(struct device_d *hw_dev, struct mci_data *data)
+{
+	uint32_t *p;
+	unsigned cnt, data_size;
+
+#define READ_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_RXCRCFAIL | SDIDSTA_DATATIMEOUT)
+
+	p = (uint32_t*)data->dest;
+	data_size = data->blocksize * data->blocks;
+
+	while (data_size > 0) {
+
+		/* serious error? */
+		if (readl(hw_dev->map_base + SDIDSTA) & READ_REASON_TO_FAIL) {
+			pr_err("Failed while reading data\n");
+			return -EIO;
+		}
+
+		/* now check the FIFO status */
+		if (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_FIFOFAIL) {
+			pr_err("Data loss due to FIFO overflow when reading\n");
+			return -EIO;
+		}
+
+		/* we only want to read full words */
+		cnt = (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) >> 2;
+
+		/* read one chunk of data from the FIFO */
+		while (cnt--) {
+			*p = readl(hw_dev->map_base + SDIDATA);
+			p++;
+			if (data_size >= 4)
+				data_size -= 4;
+			else {
+				data_size = 0;
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Write one block of data into the FIFO
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+ *
+ * We must ensure data in the FIFO when the command phase changes into the
+ * data phase. To ensure this, the FIFO gets filled first, then the command.
+ */
+static int s3c_mci_write_block(struct device_d *hw_dev, struct mci_cmd *cmd,
+				struct mci_data *data)
+{
+	const uint32_t *p = (const uint32_t*)data->src;
+	unsigned cnt, data_size;
+	uint32_t reg;
+
+#define WRITE_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_DATATIMEOUT)
+
+	data_size = data->blocksize * data->blocks;
+	/*
+	 * With high clock rates we must fill the FIFO as early as possible
+	 * Its size is 16 words. We assume its empty, when this function is
+	 * entered.
+	 */
+	cnt = 16;
+	while (cnt--) {
+		writel(*p, hw_dev->map_base + SDIDATA);
+		p++;
+		if (data_size >= 4)
+			data_size -= 4;
+		else {
+			data_size = 0;
+			break;
+		}
+	}
+
+	/* data is now in place and waits for transmitt. Start the command right now */
+	s3c_send_command(hw_dev, cmd, data);
+
+	if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
+		pr_err("Command fails immediatly due to FIFO underrun when writing %08X\n",
+			reg);
+		return -EIO;
+	}
+
+	while (data_size > 0) {
+
+		if (readl(hw_dev->map_base + SDIDSTA) & WRITE_REASON_TO_FAIL) {
+			pr_err("Failed writing data\n");
+			return -EIO;
+		}
+
+		/* now check the FIFO status */
+		if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
+			pr_err("Data loss due to FIFO underrun when writing %08X\n",
+					reg);
+			return -EIO;
+		}
+
+		/* we only want to write full words */
+		cnt = 16 - (((readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) + 3) >> 2);
+
+		/* fill the FIFO if it has free entries */
+		while (cnt--) {
+			writel(*p, hw_dev->map_base + SDIDATA);
+			p++;
+			if (data_size >= 4)
+				data_size -= 4;
+			else {
+				data_size = 0;
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Handle MCI commands with or without data
+ * @param hw_dev Host interface device instance
+ * @param cmd The command to handle
+ * @param data The data information (buffer, direction aso.)
+ * @return 0 on success
+*/
+static int s3c_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
+			struct mci_data *data)
+{
+	int rc;
+
+	rc = s3c_prepare_engine(hw_dev);
+	if (rc != 0)
+		return rc;
+
+	rc = s3c_prepare_data_transfer(hw_dev, data);
+	if (rc != 0)
+		return rc;
+
+	if (data->flags & MMC_DATA_READ) {
+		s3c_send_command(hw_dev, cmd, data);
+		rc = s3c_mci_read_block(hw_dev, data);
+		if (rc == 0) {
+			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
+				;
+		} else
+			s3c_terminate_transfer(hw_dev);
+	}
+
+	if (data->flags & MMC_DATA_WRITE) {
+		rc = s3c_mci_write_block(hw_dev, cmd, data);
+		if (rc == 0) {
+			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
+				;
+		} else
+			s3c_terminate_transfer(hw_dev);
+	}
+	writel(0, hw_dev->map_base + SDIDCON);
+
+	return rc;
+}
+
+/* ------------------------- MCI API -------------------------------------- */
+
+/**
+ * Keep the attached MMC/SD unit in a well know state
+ * @param mci_pdata MCI platform data
+ * @param mci_dev MCI device instance
+ * @return 0 on success, negative value else
+ */
+static int mci_reset(struct mci_host *mci_pdata, struct device_d *mci_dev)
+{
+	struct device_d *hw_dev = mci_pdata->hw_dev;
+
+	return s3c_mci_initialize(hw_dev, mci_dev);
+}
+
+/**
+ * Process one command to the MCI card
+ * @param mci_pdata MCI platform data
+ * @param cmd The command to process
+ * @param data The data to handle in the command (can be NULL)
+ * @return 0 on success, negative value else
+ */
+static int mci_request(struct mci_host *mci_pdata, struct mci_cmd *cmd,
+			struct mci_data *data)
+{
+	struct device_d *hw_dev = mci_pdata->hw_dev;
+	int rc;
+
+	/* enable clock */
+	writel(readl(hw_dev->map_base + SDICON) | SDICON_CLKEN,
+		hw_dev->map_base + SDICON);
+
+	if ((cmd->resp_type == 0) || (data == NULL))
+		rc = s3c_mci_std_cmds(hw_dev, cmd);
+	else
+		rc = s3c_mci_adtc(hw_dev, cmd, data);	/* with response and data */
+
+	s3c_finish_request(hw_dev);
+
+	/* disable clock */
+	writel(readl(hw_dev->map_base + SDICON) & ~SDICON_CLKEN,
+		hw_dev->map_base + SDICON);
+	return rc;
+}
+
+/**
+ * Setup the bus width and IO speed
+ * @param mci_pdata MCI platform data
+ * @param mci_dev MCI device instance
+ * @param bus_width New bus width value (1, 4 or 8)
+ * @param clock New clock in Hz (can be '0' to disable the clock)
+ */
+static void mci_set_ios(struct mci_host *mci_pdata, struct device_d *mci_dev,
+			unsigned bus_width, unsigned clock)
+{
+	struct device_d *hw_dev = mci_pdata->hw_dev;
+	struct s3c_mci_host *host_data = GET_HOST_DATA(hw_dev);
+	struct mci_host *host = GET_MCI_PDATA(mci_dev);
+	uint32_t reg;
+
+	switch (bus_width) {
+	case 8:		/* no 8 bit support, fall back to 4 bit */
+	case 4:
+		host_data->bus_width = 1;
+		host->bus_width = 4;	/* 4 bit is possible */
+		break;
+	default:
+		host_data->bus_width = 0;
+		host->bus_width = 1;	/* 1 bit is possible */
+		break;
+	}
+
+	reg = readl(hw_dev->map_base + SDICON);
+	if (clock) {
+		/* setup the IO clock frequency and enable it */
+		host->clock = host_data->clock = s3c_setup_clock_speed(hw_dev, clock);
+		reg |= SDICON_CLKEN;	/* enable the clock */
+	} else {
+		reg &= ~SDICON_CLKEN;	/* disable the clock */
+		host->clock = host_data->clock = 0;
+	}
+	writel(reg, hw_dev->map_base + SDICON);
+
+	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n",
+		host->bus_width, host->clock);
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_MCI_INFO
+static void s3c_info(struct device_d *hw_dev)
+{
+	struct s3c_mci_host *host = hw_dev->priv;
+	struct s3c_mci_platform_data *pd = hw_dev->platform_data;
+
+	printf("  Bus data width: %d bit\n", host->bus_width == 1 ? 4 : 1);
+	printf("  Bus frequency: %u Hz\n", host->clock);
+	printf("   Frequency limits: ");
+	if (pd->f_min == 0)
+		printf("no lower limit ");
+	else
+		printf("%u Hz lower limit ", pd->f_min);
+	if (pd->f_max == 0)
+		printf("- no upper limit");
+	else
+		printf("- %u Hz upper limit", pd->f_max);
+	printf("\n  Card detection support: %s\n",
+		pd->gpio_detect != 0 ? "yes" : "no");
+}
+#endif
+
+/*
+ * There is only one host MCI hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct mci_host mci_pdata = {
+	.send_cmd = mci_request,
+	.set_ios = mci_set_ios,
+	.init = mci_reset,
+};
+
+static int s3c_mci_probe(struct device_d *hw_dev)
+{
+	struct s3c_mci_platform_data *pd = hw_dev->platform_data;
+
+	/* TODO replace by the global func: enable the SDI unit clock */
+	writel(readl(S3C24X0_CLOCK_POWER_BASE + 0x0c) | 0x200,
+		S3C24X0_CLOCK_POWER_BASE + 0x0c);
+
+	if (pd == NULL) {
+		pr_err("Missing platform data\n");
+		return -EINVAL;
+	}
+
+	hw_dev->priv = &host_data;
+	mci_pdata.hw_dev = hw_dev;
+
+	/* feed forward the platform specific values */
+	mci_pdata.voltages = pd->voltages;
+	mci_pdata.host_caps = pd->caps;
+	mci_pdata.f_min = pd->f_min == 0 ? s3c24xx_get_pclk() / 256 : pd->f_min;
+	mci_pdata.f_max = pd->f_max == 0 ? s3c24xx_get_pclk() / 2 : pd->f_max;
+
+	/*
+	 * Start the clock to let the engine and the card finishes its startup
+	 */
+	host_data.clock = s3c_setup_clock_speed(hw_dev, mci_pdata.f_min);
+	writel(SDICON_FIFORESET | SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
+
+	return mci_register(&mci_pdata);
+}
+
+static struct driver_d s3c_mci_driver = {
+        .name  = "s3c_mci",
+        .probe = s3c_mci_probe,
+#ifdef CONFIG_MCI_INFO
+	.info = s3c_info,
+#endif
+};
+
+static int s3c_mci_init_driver(void)
+{
+        register_driver(&s3c_mci_driver);
+        return 0;
+}
+
+device_initcall(s3c_mci_init_driver);
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:56 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:56 +0200
Subject: [PATCH 08/10] i.MX27: Add mmc clock support in order to add an i.MX
	MCI driver
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-9-git-send-email-jbe@pengutronix.de>

From: Sascha Hauer <s.hauer at pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Acked-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/clock.h |    1 +
 arch/arm/mach-imx/speed-imx27.c        |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/clock.h b/arch/arm/mach-imx/include/mach/clock.h
index 76ab4a5..bbe7a60 100644
--- a/arch/arm/mach-imx/include/mach/clock.h
+++ b/arch/arm/mach-imx/include/mach/clock.h
@@ -28,6 +28,7 @@ ulong imx_get_gptclk(void);
 ulong imx_get_uartclk(void);
 ulong imx_get_lcdclk(void);
 ulong imx_get_i2cclk(void);
+ulong imx_get_mmcclk(void);
 
 int imx_clko_set_div(int div);
 void imx_clko_set_src(int src);
diff --git a/arch/arm/mach-imx/speed-imx27.c b/arch/arm/mach-imx/speed-imx27.c
index cdcd419..0a92d29 100644
--- a/arch/arm/mach-imx/speed-imx27.c
+++ b/arch/arm/mach-imx/speed-imx27.c
@@ -159,6 +159,11 @@ ulong imx_get_i2cclk(void)
 	return imx_get_ipgclk();
 }
 
+ulong imx_get_mmcclk(void)
+{
+	return imx_get_perclk2();
+}
+
 void imx_dump_clocks(void)
 {
 	uint32_t	cid = CID;
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:58 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:58 +0200
Subject: [PATCH 10/10] ARM pca100: Add mci support
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-11-git-send-email-jbe@pengutronix.de>

From: Sascha Hauer <s.hauer at pengutronix.de>

Add mci support to the PCA100 platform

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/phycard-i.MX27/pca100.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/phycard-i.MX27/pca100.c b/arch/arm/boards/phycard-i.MX27/pca100.c
index 7328a6c..7460c00 100644
--- a/arch/arm/boards/phycard-i.MX27/pca100.c
+++ b/arch/arm/boards/phycard-i.MX27/pca100.c
@@ -109,6 +109,11 @@ static void pca100_usbh_init(void)
 }
 #endif
 
+static struct device_d mmc_dev = {
+	.name		= "imx-mmc",
+	.map_base	= 0x10014000,
+};
+
 #ifdef CONFIG_MMU
 static void pca100_mmu_init(void)
 {
@@ -180,8 +185,17 @@ static int pca100_devices_init(void)
 		PD23_AF_USBH2_DATA2,
 		PD24_AF_USBH2_DATA1,
 		PD26_AF_USBH2_DATA5,
+		/* SDHC */
+		PB4_PF_SD2_D0,
+		PB5_PF_SD2_D1,
+		PB6_PF_SD2_D2,
+		PB7_PF_SD2_D3,
+		PB8_PF_SD2_CMD,
+		PB9_PF_SD2_CLK,
 	};
 
+	PCCR0 |= PCCR0_SDHC2_EN;
+
 	/* disable the usb phys */
 	imx_gpio_mode((GPIO_PORTB | 23) | GPIO_GPIO | GPIO_IN);
 	gpio_direction_output(GPIO_PORTB + 23, 1);
@@ -195,6 +209,7 @@ static int pca100_devices_init(void)
 	register_device(&nand_dev);
 	register_device(&sdram_dev);
 	register_device(&fec_dev);
+	register_device(&mmc_dev);
 
 	PCCR1 |= PCCR1_PERCLK2_EN;
 
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct  8 12:30:57 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri,  8 Oct 2010 18:30:57 +0200
Subject: [PATCH 09/10] mci: Add i.MX27/31 driver
In-Reply-To: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
References: <1286555458-20125-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286555458-20125-10-git-send-email-jbe@pengutronix.de>

From: Sascha Hauer <s.hauer at pengutronix.de>

Add i.MX27/31 driver

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/Kconfig  |    7 +
 drivers/mci/Makefile |    1 +
 drivers/mci/imx.c    |  520 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 528 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/imx.c

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 644c0a3..0bc4254 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -41,4 +41,11 @@ config MCI_S3C
 	  Enable this entry to add support to read and write SD cards on a
 	  Samsung S3C24xx based system.
 
+config MCI_IMX
+	bool "i.MX"
+	depends on ARCH_IMX27 || ARCH_IMX31
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  Freescale i.MX based system.
+
 endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index be18446..f393e93 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_MCI)	+= mci-core.o
 obj-$(CONFIG_MCI_STM378X) += stm378x.o
 obj-$(CONFIG_MCI_S3C) += s3c.o
+obj-$(CONFIG_MCI_IMX) += imx.o
diff --git a/drivers/mci/imx.c b/drivers/mci/imx.c
new file mode 100644
index 0000000..8525692
--- /dev/null
+++ b/drivers/mci/imx.c
@@ -0,0 +1,520 @@
+/*
+ *  This is a driver for the SDHC controller found in Freescale MX2/MX3
+ *  SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
+ *  Unlike the hardware found on MX1, this hardware just works and does
+ *  not need all the quirks found in imxmmc.c, hence the seperate driver.
+ *
+ *  Copyright (C) 2009 Ilya Yanok, <yanok at emcraft.com>
+ *  Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer at pengutronix.de>
+ *  Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa at pikron.com>
+ *
+ *  derived from pxamci.c by Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <mci.h>
+#include <malloc.h>
+#include <errno.h>
+#include <clock.h>
+#include <init.h>
+#include <driver.h>
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#define DRIVER_NAME "imx-mmc"
+
+struct mxcmci_regs {
+	u32 str_stp_clk;
+	u32 status;
+	u32 clk_rate;
+	u32 cmd_dat_cont;
+	u32 res_to;
+	u32 read_to;
+	u32 blk_len;
+	u32 nob;
+	u32 rev_no;
+	u32 int_cntr;
+	u32 cmd;
+	u32 arg;
+	u32 pad;
+	u32 res_fifo;
+	u32 buffer_access;
+};
+
+#define STR_STP_CLK_RESET               (1 << 3)
+#define STR_STP_CLK_START_CLK           (1 << 1)
+#define STR_STP_CLK_STOP_CLK            (1 << 0)
+
+#define STATUS_CARD_INSERTION		(1 << 31)
+#define STATUS_CARD_REMOVAL		(1 << 30)
+#define STATUS_YBUF_EMPTY		(1 << 29)
+#define STATUS_XBUF_EMPTY		(1 << 28)
+#define STATUS_YBUF_FULL		(1 << 27)
+#define STATUS_XBUF_FULL		(1 << 26)
+#define STATUS_BUF_UND_RUN		(1 << 25)
+#define STATUS_BUF_OVFL			(1 << 24)
+#define STATUS_SDIO_INT_ACTIVE		(1 << 14)
+#define STATUS_END_CMD_RESP		(1 << 13)
+#define STATUS_WRITE_OP_DONE		(1 << 12)
+#define STATUS_DATA_TRANS_DONE		(1 << 11)
+#define STATUS_READ_OP_DONE		(1 << 11)
+#define STATUS_WR_CRC_ERROR_CODE_MASK	(3 << 10)
+#define STATUS_CARD_BUS_CLK_RUN		(1 << 8)
+#define STATUS_BUF_READ_RDY		(1 << 7)
+#define STATUS_BUF_WRITE_RDY		(1 << 6)
+#define STATUS_RESP_CRC_ERR		(1 << 5)
+#define STATUS_CRC_READ_ERR		(1 << 3)
+#define STATUS_CRC_WRITE_ERR		(1 << 2)
+#define STATUS_TIME_OUT_RESP		(1 << 1)
+#define STATUS_TIME_OUT_READ		(1 << 0)
+#define STATUS_ERR_MASK			0x2f
+
+#define CMD_DAT_CONT_CMD_RESP_LONG_OFF	(1 << 12)
+#define CMD_DAT_CONT_STOP_READWAIT	(1 << 11)
+#define CMD_DAT_CONT_START_READWAIT	(1 << 10)
+#define CMD_DAT_CONT_BUS_WIDTH_4	(2 << 8)
+#define CMD_DAT_CONT_INIT		(1 << 7)
+#define CMD_DAT_CONT_WRITE		(1 << 4)
+#define CMD_DAT_CONT_DATA_ENABLE	(1 << 3)
+#define CMD_DAT_CONT_RESPONSE_48BIT_CRC	(1 << 0)
+#define CMD_DAT_CONT_RESPONSE_136BIT	(2 << 0)
+#define CMD_DAT_CONT_RESPONSE_48BIT	(3 << 0)
+
+#define INT_SDIO_INT_WKP_EN		(1 << 18)
+#define INT_CARD_INSERTION_WKP_EN	(1 << 17)
+#define INT_CARD_REMOVAL_WKP_EN		(1 << 16)
+#define INT_CARD_INSERTION_EN		(1 << 15)
+#define INT_CARD_REMOVAL_EN		(1 << 14)
+#define INT_SDIO_IRQ_EN			(1 << 13)
+#define INT_DAT0_EN			(1 << 12)
+#define INT_BUF_READ_EN			(1 << 4)
+#define INT_BUF_WRITE_EN		(1 << 3)
+#define INT_END_CMD_RES_EN		(1 << 2)
+#define INT_WRITE_OP_DONE_EN		(1 << 1)
+#define INT_READ_OP_EN			(1 << 0)
+
+struct mxcmci_host {
+	struct mci_host		mci;
+	struct mxcmci_regs	*base;
+	int			irq;
+	int			detect_irq;
+	int			dma;
+	int			do_dma;
+	unsigned int		power_mode;
+
+	struct mci_cmd		*cmd;
+	struct mci_data		*data;
+
+	unsigned int		dma_nents;
+	unsigned int		datasize;
+	unsigned int		dma_dir;
+
+	u16			rev_no;
+	unsigned int		cmdat;
+
+	int			clock;
+};
+
+#define to_mxcmci(mci)	container_of(mci, struct mxcmci_host, mci)
+
+static void mxcmci_softreset(struct mxcmci_host *host)
+{
+	int i;
+
+	/* reset sequence */
+	writew(STR_STP_CLK_RESET, &host->base->str_stp_clk);
+	writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
+			&host->base->str_stp_clk);
+
+	for (i = 0; i < 8; i++)
+		writew(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
+
+	writew(0xff, &host->base->res_to);
+}
+
+static void mxcmci_setup_data(struct mxcmci_host *host, struct mci_data *data)
+{
+	unsigned int nob = data->blocks;
+	unsigned int blksz = data->blocksize;
+	unsigned int datasize = nob * blksz;
+
+	host->data = data;
+
+	writew(nob, &host->base->nob);
+	writew(blksz, &host->base->blk_len);
+	host->datasize = datasize;
+}
+
+static int mxcmci_start_cmd(struct mxcmci_host *host, struct mci_cmd *cmd,
+		unsigned int cmdat)
+{
+	if (host->cmd != NULL)
+		printf("mxcmci: error!\n");
+	host->cmd = cmd;
+
+	switch (cmd->resp_type) {
+	case MMC_RSP_R1: /* short CRC, OPCODE */
+	case MMC_RSP_R1b:/* short CRC, OPCODE, BUSY */
+		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
+		break;
+	case MMC_RSP_R2: /* long 136 bit + CRC */
+		cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
+		break;
+	case MMC_RSP_R3: /* short */
+		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
+		break;
+	case MMC_RSP_NONE:
+		break;
+	default:
+		printf("mxcmci: unhandled response type 0x%x\n",
+				cmd->resp_type);
+		return -EINVAL;
+	}
+
+	writew(cmd->cmdidx, &host->base->cmd);
+	writel(cmd->cmdarg, &host->base->arg);
+	writew(cmdat, &host->base->cmd_dat_cont);
+
+	return 0;
+}
+
+static void mxcmci_finish_request(struct mxcmci_host *host,
+		struct mci_cmd *cmd, struct mci_data *data)
+{
+	host->cmd = NULL;
+	host->data = NULL;
+}
+
+static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
+{
+	int data_error = 0;
+
+	if (stat & STATUS_ERR_MASK) {
+		printf("request failed. status: 0x%08x\n",
+				stat);
+		if (stat & STATUS_CRC_READ_ERR) {
+			data_error = -EILSEQ;
+		} else if (stat & STATUS_CRC_WRITE_ERR) {
+			u32 err_code = (stat >> 9) & 0x3;
+			if (err_code == 2) /* No CRC response */
+				data_error = -ETIMEDOUT;
+			else
+				data_error = -EILSEQ;
+		} else if (stat & STATUS_TIME_OUT_READ) {
+			data_error = -ETIMEDOUT;
+		} else {
+			data_error = -EIO;
+		}
+	}
+
+	host->data = NULL;
+
+	return data_error;
+}
+
+static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
+{
+	struct mci_cmd *cmd = host->cmd;
+	int i;
+	u32 a, b, c;
+	u32 *resp = (u32 *)cmd->response;
+
+	if (!cmd)
+		return 0;
+
+	if (stat & STATUS_TIME_OUT_RESP) {
+		printf("CMD TIMEOUT\n");
+		return -ETIMEDOUT;
+	} else if (stat & STATUS_RESP_CRC_ERR && cmd->resp_type & MMC_RSP_CRC) {
+		printf("cmd crc error\n");
+		return -EILSEQ;
+	}
+
+	if (cmd->resp_type & MMC_RSP_PRESENT) {
+		if (cmd->resp_type & MMC_RSP_136) {
+			for (i = 0; i < 4; i++) {
+				a = readw(&host->base->res_fifo);
+				b = readw(&host->base->res_fifo);
+				resp[i] = a << 16 | b;
+			}
+		} else {
+			a = readw(&host->base->res_fifo);
+			b = readw(&host->base->res_fifo);
+			c = readw(&host->base->res_fifo);
+			resp[0] = a << 24 | b << 8 | c >> 8;
+		}
+	}
+	return 0;
+}
+
+static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
+{
+	u32 stat;
+	uint64_t start = get_time_ns();
+
+	do {
+		stat = readl(&host->base->status);
+		if (stat & STATUS_ERR_MASK)
+			return stat;
+		if (is_timeout(start, SECOND))
+			return STATUS_TIME_OUT_READ;
+		if (stat & mask)
+			return 0;
+	} while (1);
+}
+
+static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
+{
+	unsigned int stat;
+	u32 *buf = _buf;
+
+	while (bytes > 3) {
+		stat = mxcmci_poll_status(host,
+				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+		if (stat)
+			return stat;
+		*buf++ = readl(&host->base->buffer_access);
+		bytes -= 4;
+	}
+
+	if (bytes) {
+		u8 *b = (u8 *)buf;
+		u32 tmp;
+
+		stat = mxcmci_poll_status(host,
+				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+		if (stat)
+			return stat;
+		tmp = readl(&host->base->buffer_access);
+		memcpy(b, &tmp, bytes);
+	}
+
+	return 0;
+}
+
+static int mxcmci_push(struct mxcmci_host *host, const void *_buf, int bytes)
+{
+	unsigned int stat;
+	const u32 *buf = _buf;
+
+	while (bytes > 3) {
+		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+		if (stat)
+			return stat;
+		writel(*buf++, &host->base->buffer_access);
+		bytes -= 4;
+	}
+
+	if (bytes) {
+		const u8 *b = (u8 *)buf;
+		u32 tmp;
+
+		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+		if (stat)
+			return stat;
+
+		memcpy(&tmp, b, bytes);
+		writel(tmp, &host->base->buffer_access);
+	}
+
+	stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+	if (stat)
+		return stat;
+
+	return 0;
+}
+
+static int mxcmci_transfer_data(struct mxcmci_host *host)
+{
+	struct mci_data *data = host->data;
+	int stat;
+	unsigned long length;
+
+	length = data->blocks * data->blocksize;
+	host->datasize = 0;
+
+	if (data->flags & MMC_DATA_READ) {
+		stat = mxcmci_pull(host, data->dest, length);
+		if (stat)
+			return stat;
+		host->datasize += length;
+	} else {
+		stat = mxcmci_push(host, (const void *)(data->src), length);
+		if (stat)
+			return stat;
+		host->datasize += length;
+		stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
+		if (stat)
+			return stat;
+	}
+	return 0;
+}
+
+static int mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
+{
+	int datastat;
+	int ret;
+
+	ret = mxcmci_read_response(host, stat);
+
+	if (ret) {
+		mxcmci_finish_request(host, host->cmd, host->data);
+		return ret;
+	}
+
+	if (!host->data) {
+		mxcmci_finish_request(host, host->cmd, host->data);
+		return 0;
+	}
+
+	datastat = mxcmci_transfer_data(host);
+	ret = mxcmci_finish_data(host, datastat);
+	mxcmci_finish_request(host, host->cmd, host->data);
+	return ret;
+}
+
+static int mxcmci_request(struct mci_host *mci, struct mci_cmd *cmd,
+		struct mci_data *data)
+{
+	struct mxcmci_host *host = to_mxcmci(mci);
+	unsigned int cmdat = host->cmdat;
+	u32 stat;
+	int ret;
+
+	host->cmdat &= ~CMD_DAT_CONT_INIT;
+	if (data) {
+		mxcmci_setup_data(host, data);
+
+		cmdat |= CMD_DAT_CONT_DATA_ENABLE;
+
+		if (data->flags & MMC_DATA_WRITE)
+			cmdat |= CMD_DAT_CONT_WRITE;
+	}
+
+	if ((ret = mxcmci_start_cmd(host, cmd, cmdat))) {
+		mxcmci_finish_request(host, cmd, data);
+		return ret;
+	}
+
+	do {
+		stat = readl(&host->base->status);
+		writel(stat, &host->base->status);
+	} while (!(stat & STATUS_END_CMD_RESP));
+
+	return mxcmci_cmd_done(host, stat);
+}
+
+static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
+{
+	unsigned int divider;
+	int prescaler = 0;
+	unsigned long clk_in = imx_get_mmcclk();
+
+	while (prescaler <= 0x800) {
+		for (divider = 1; divider <= 0xF; divider++) {
+			int x;
+
+			x = (clk_in / (divider + 1));
+
+			if (prescaler)
+				x /= (prescaler * 2);
+
+			if (x <= clk_ios)
+				break;
+		}
+		if (divider < 0x10)
+			break;
+
+		if (prescaler == 0)
+			prescaler = 1;
+		else
+			prescaler <<= 1;
+	}
+
+	writew((prescaler << 4) | divider, &host->base->clk_rate);
+}
+
+static void mxcmci_set_ios(struct mci_host *mci, struct device_d *dev,
+		unsigned bus_width, unsigned clock)
+{
+	struct mxcmci_host *host = to_mxcmci(mci);
+
+	if (bus_width == 4)
+		host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
+	else
+		host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
+
+	if (clock) {
+		mxcmci_set_clk_rate(host, clock);
+		writew(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
+	} else {
+		writew(STR_STP_CLK_STOP_CLK, &host->base->str_stp_clk);
+	}
+
+	host->clock = clock;
+}
+
+static int mxcmci_init(struct mci_host *mci, struct device_d *dev)
+{
+	struct mxcmci_host *host = to_mxcmci(mci);
+
+	mxcmci_softreset(host);
+
+	host->rev_no = readw(&host->base->rev_no);
+	if (host->rev_no != 0x400) {
+		printf("wrong rev.no. 0x%08x. aborting.\n",
+			host->rev_no);
+		return -ENODEV;
+	}
+
+	/* recommended in data sheet */
+	writew(0x2db4, &host->base->read_to);
+
+	writel(0, &host->base->int_cntr);
+
+	return 0;
+}
+
+static int mxcmci_probe(struct device_d *dev)
+{
+	struct mxcmci_host *host;
+
+	host = xzalloc(sizeof(*host));
+
+	host->mci.send_cmd = mxcmci_request;
+	host->mci.set_ios = mxcmci_set_ios;
+	host->mci.init = mxcmci_init;
+	host->mci.host_caps = MMC_MODE_4BIT;
+
+	host->base = (struct mxcmci_regs *)dev->map_base;
+
+	host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	host->mci.f_min = imx_get_mmcclk() >> 7;
+	host->mci.f_max = imx_get_mmcclk() >> 1;
+
+	mci_register(&host->mci);
+
+	return 0;
+}
+
+static struct driver_d mxcmci_driver = {
+        .name  = DRIVER_NAME,
+        .probe = mxcmci_probe,
+};
+
+static int mxcmci_init_driver(void)
+{
+        register_driver(&mxcmci_driver);
+        return 0;
+}
+
+device_initcall(mxcmci_init_driver);
+
-- 
1.7.2.3



From gadiyar at gmail.com  Sun Oct 10 04:37:34 2010
From: gadiyar at gmail.com (Anand Gadiyar)
Date: Sun, 10 Oct 2010 14:07:34 +0530
Subject: [PATCH 00/13] OMAP/Beagleboard ehci support
In-Reply-To: <1280915957-2910-1-git-send-email-m.grzeschik@pengutronix.de>
References: <1280915957-2910-1-git-send-email-m.grzeschik@pengutronix.de>
Message-ID: <AANLkTikinP9VqcUCWwNFdZpbtVQ6HG2=wYdxMXMv+MU0@mail.gmail.com>

On Wed, Aug 4, 2010 at 3:29 PM, Michael Grzeschik
<m.grzeschik at pengutronix.de> wrote:
> Hi all,
>
> this patchseries adds ehci support for the beagleboard, which includes
> i2c-omap, twl4030 phy and ehci-omap support.
>

Small comment - there shouldn't be any need for i2c-omap
and twl4030 phy support to get EHCI working on the beagleboard.
The EHCI ports are wired up through an SMSC332x PHY, while
the PHY in the TWL4030 is connected to the OTG port.

So this series likely ends up enabling the OTG port as well - or
brings us closer to that!

Thanks for the series - I'll try and test on my beagle.

- Anand


From alexey.zaytsev at gmail.com  Sun Oct 10 19:15:37 2010
From: alexey.zaytsev at gmail.com (Alexey Zaytsev)
Date: Sun, 10 Oct 2010 23:15:37 +0000
Subject: [PATCH] Add basic support from ARM Versatile/PB
Message-ID: <20101010230505.17833.46593.stgit@zaytsev.su>

Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
---

Hi.

It seems that barebox does not run on any ARM machines provided
by QEMU. This patch adds basic Versatile/PB support. It is far from
being complete and has not been tested on real hardware, but
seems to work fine in QEMU.

Please notice, that you need to set CONFIG_VERSATILE_SMC91C111
in order to have networking in QEMU, as it does not provide
smc91x found on the real hardware.

For a queck test, run:

	qemu-system-arm -kernel barebox.bin -M versatilepb -cpu arm926 -nographic -m 64 -net nic,model=smc91c111 -net user


 arch/arm/Kconfig                                |    4 
 arch/arm/Makefile                               |    2 
 arch/arm/boards/versatile/Kconfig               |   21 +
 arch/arm/boards/versatile/Makefile              |    2 
 arch/arm/boards/versatile/config.h              |    5 
 arch/arm/boards/versatile/env/bin/init          |    1 
 arch/arm/boards/versatile/versatilepb.c         |   56 +++
 arch/arm/configs/versatilepb_defconfig          |   12 +
 arch/arm/include/asm/arm_timer.h                |   33 ++
 arch/arm/mach-versatile/Kconfig                 |   16 +
 arch/arm/mach-versatile/Makefile                |    2 
 arch/arm/mach-versatile/core.c                  |  217 ++++++++++++
 arch/arm/mach-versatile/include/mach/clkdev.h   |    7 
 arch/arm/mach-versatile/include/mach/debug_ll.h |   37 ++
 arch/arm/mach-versatile/include/mach/init.h     |    9 
 arch/arm/mach-versatile/include/mach/platform.h |  417 +++++++++++++++++++++++
 16 files changed, 841 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/versatile/Kconfig
 create mode 100644 arch/arm/boards/versatile/Makefile
 create mode 100644 arch/arm/boards/versatile/config.h
 create mode 100644 arch/arm/boards/versatile/env/bin/init
 create mode 100644 arch/arm/boards/versatile/versatilepb.c
 create mode 100644 arch/arm/configs/versatilepb_defconfig
 create mode 100644 arch/arm/include/asm/arm_timer.h
 create mode 100644 arch/arm/mach-versatile/Kconfig
 create mode 100644 arch/arm/mach-versatile/Makefile
 create mode 100644 arch/arm/mach-versatile/core.c
 create mode 100644 arch/arm/mach-versatile/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-versatile/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-versatile/include/mach/init.h
 create mode 100644 arch/arm/mach-versatile/include/mach/platform.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fa37036..d90246a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -56,6 +56,9 @@ config ARCH_S3C24xx
 	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
 	select CPU_ARM920T
 
+config ARCH_VERSATILE
+	bool "ARM Versatile boards (ARM926EJ-S)"
+	select CPU_ARM926T
 endchoice
 
 source arch/arm/cpu/Kconfig
@@ -66,6 +69,7 @@ source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
 source arch/arm/mach-omap/Kconfig
 source arch/arm/mach-s3c24xx/Kconfig
+source arch/arm/mach-versatile/Kconfig
 
 config AEABI
 	bool "Use the ARM EABI to compile barebox"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77b6cf4..6ad14e7 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -45,6 +45,7 @@ machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_OMAP)		:= omap
 machine-$(CONFIG_ARCH_S3C24xx)		:= s3c24xx
+machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 
 # Board directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
 board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
+board-$(CONFIG_MACH_VERSATILEPB)		:= versatile
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/versatile/Kconfig b/arch/arm/boards/versatile/Kconfig
new file mode 100644
index 0000000..d5da87d
--- /dev/null
+++ b/arch/arm/boards/versatile/Kconfig
@@ -0,0 +1,21 @@
+
+
+if MACH_VERSATILEPB
+
+config ARCH_TEXT_BASE
+	hex
+	default 0
+
+config BOARDINFO
+	default "ARM Versatile/PB (ARM926EJ-S)"
+endif
+
+config VERSATILE_SMC91C111
+	bool "Use smc91c111 instead of smc91x (for QEMU)"
+	default 0
+	help
+	 Enable this option to run barebox inside qemu.
+	 Real versatile boards are equipped with smc911x,
+	 but qemu only provides smc91111, which is a bit different.
+
+
diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
new file mode 100644
index 0000000..a17aed3
--- /dev/null
+++ b/arch/arm/boards/versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
new file mode 100644
index 0000000..25bb18f
--- /dev/null
+++ b/arch/arm/boards/versatile/config.h
@@ -0,0 +1,5 @@
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/versatile/env/bin/init b/arch/arm/boards/versatile/env/bin/init
new file mode 100644
index 0000000..224a6b4
--- /dev/null
+++ b/arch/arm/boards/versatile/env/bin/init
@@ -0,0 +1 @@
+# Dummy Init environment script
diff --git a/arch/arm/boards/versatile/versatilepb.c b/arch/arm/boards/versatile/versatilepb.c
new file mode 100644
index 0000000..57e4991
--- /dev/null
+++ b/arch/arm/boards/versatile/versatilepb.c
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <mach/init.h>
+#include <mach/platform.h>
+
+static int vpb_console_init(void)
+{
+	versatile_register_uart(0);
+	return 0;
+}
+
+console_initcall(vpb_console_init);
+
+static struct device_d smc911x_dev = {
+	.id		= -1,
+#ifdef CONFIG_VERSATILE_SMC91C111
+	.name		= "smc91c111",
+#else
+	.name		= "smc911x",
+#endif
+	.map_base	= VERSATILE_ETH_BASE,
+	.size		= 64 * 1024
+};
+
+static int vpb_devices_init(void)
+{
+	versatile_add_sdram(64 * 1024 *1024);
+
+	register_device(&smc911x_dev);
+
+	armlinux_set_architecture(MACH_TYPE_VERSATILE_PB);
+	armlinux_set_bootparams((void *)(0x00000100));
+
+	return 0;
+}
+device_initcall(vpb_devices_init);
diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig
new file mode 100644
index 0000000..f505ac6
--- /dev/null
+++ b/arch/arm/configs/versatilepb_defconfig
@@ -0,0 +1,12 @@
+
+CONFIG_ARCH_VERSATILE=y
+CONFIG_MACH_VERSATILEPB=y
+
+CONFIG_TEXT_BASE=0x500000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+CONFIG_PROMPT="versatilepb> "
+CONFIG_DEFAULT_ENVIRONMENT=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/versatile/env"
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_DRIVER_NET_SMC911X=y
diff --git a/arch/arm/include/asm/arm_timer.h b/arch/arm/include/asm/arm_timer.h
new file mode 100644
index 0000000..0433279
--- /dev/null
+++ b/arch/arm/include/asm/arm_timer.h
@@ -0,0 +1,33 @@
+#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
+#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+
+/*
+ * From Linux v2.6.35
+ * arch/arm/include/asm/hardware/arm_timer.h
+ *
+ * ARM timer implementation, found in Integrator, Versatile and Realview
+ * platforms.  Not all platforms support all registers and bits in these
+ * registers, so we mark them with A for Integrator AP, C for Integrator
+ * CP, V for Versatile and R for Realview.
+ *
+ * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
+ * can have 16-bit or 32-bit selectable via a bit in the control register.
+ */
+#define TIMER_LOAD	0x00			/* ACVR rw */
+#define TIMER_VALUE	0x04			/* ACVR ro */
+#define TIMER_CTRL	0x08			/* ACVR rw */
+#define TIMER_CTRL_ONESHOT	(1 << 0)	/*  CVR */
+#define TIMER_CTRL_32BIT	(1 << 1)	/*  CVR */
+#define TIMER_CTRL_DIV1		(0 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV16	(1 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV256	(2 << 2)	/* ACVR */
+#define TIMER_CTRL_IE		(1 << 5)	/*   VR */
+#define TIMER_CTRL_PERIODIC	(1 << 6)	/* ACVR */
+#define TIMER_CTRL_ENABLE	(1 << 7)	/* ACVR */
+
+#define TIMER_INTCLR	0x0c			/* ACVR wo */
+#define TIMER_RIS	0x10			/*  CVR ro */
+#define TIMER_MIS	0x14			/*  CVR ro */
+#define TIMER_BGLOAD	0x18			/*  CVR rw */
+
+#endif
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
new file mode 100644
index 0000000..9a1bf95
--- /dev/null
+++ b/arch/arm/mach-versatile/Kconfig
@@ -0,0 +1,16 @@
+
+if ARCH_VERSATILE
+
+choice
+	prompt "ARM Board type"
+
+config MACH_VERSATILEPB
+	bool "ARM Versatile/PB (ARM926EJ-S)"
+	select ARM_AMBA
+	select CLKDEV_LOOKUP
+
+endchoice
+
+source arch/arm/boards/versatile/Kconfig
+
+endif
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
new file mode 100644
index 0000000..a8da54c
--- /dev/null
+++ b/arch/arm/mach-versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-y += core.o
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
new file mode 100644
index 0000000..9ea4e24
--- /dev/null
+++ b/arch/arm/mach-versatile/core.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd,
+ * http://l4dev.org
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * Based on mach-nomadik
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <debug_ll.h>
+
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <asm/arm_timer.h>
+#include <asm/armlinux.h>
+
+#include <mach/platform.h>
+#include <mach/init.h>
+
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.id = -1,
+	.name = "mem",
+	.map_base = 0x00000000,
+	.platform_data = &ram_pdata,
+};
+
+void versatile_add_sdram(u32 size)
+{
+	sdram_dev.size = size;
+	register_device(&sdram_dev);
+	armlinux_add_dram(&sdram_dev);
+}
+
+/* 4 uarts, yay! */
+static struct device_d uart0_serial_device = {
+	.id = 1,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART0_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart1_serial_device = {
+	.id = 2,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART1_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart2_serial_device = {
+	.id = 3,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART2_BASE,
+	.size = 4096,
+};
+static struct device_d uart3_serial_device = {
+	.id = 4,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART3_BASE,
+	.size = 4096,
+};
+
+
+struct clk {
+	unsigned long rate;
+};
+
+static struct clk ref_clk_24 = {
+	.rate = 24000000,
+};
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* enable and disable do nothing */
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Create a clock structure with the given name */
+int vpb_clk_create(struct clk *clk, const char *dev_id)
+{
+	struct clk_lookup *clkdev;
+
+	clkdev = clkdev_alloc(clk, NULL, dev_id);
+	if (!clkdev)
+		return -ENOMEM;
+
+	clkdev_add(clkdev);
+	return 0;
+}
+
+/* 1Mhz / 256 */
+#define TIMER_FREQ (1000000/256)
+
+#define TIMER0_BASE (VERSATILE_TIMER0_1_BASE)
+#define TIMER1_BASE ((VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_BASE (VERSATILE_TIMER2_3_BASE)
+#define TIMER3_BASE ((VERSATILE_TIMER2_3_BASE) + 0x20)
+
+
+static uint64_t vpb_clocksource_read(void)
+{
+	return ~readl(TIMER0_BASE + TIMER_VALUE);
+}
+
+static struct clocksource vpb_cs = {
+	.read = vpb_clocksource_read,
+	.mask = 0xffffffff,
+	.shift = 10,
+};
+
+/* From Linux v2.6.35
+ * arch/arm/mach-versatile/core.c */
+static void versatile_timer_init (void)
+{
+	u32 val;
+
+	/*
+	 * set clock frequency:
+	 *      VERSATILE_REFCLK is 32KHz
+	 *      VERSATILE_TIMCLK is 1MHz
+	 */
+
+	val = readl(VERSATILE_SCTL_BASE);
+	val |= (VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel);
+	writel(val, VERSATILE_SCTL_BASE);
+
+	/*
+	 * Disable all timers, just to be sure.
+	 */
+
+	writel(0, TIMER0_BASE + TIMER_CTRL);
+	writel(0, TIMER1_BASE + TIMER_CTRL);
+	writel(0, TIMER2_BASE + TIMER_CTRL);
+	writel(0, TIMER3_BASE + TIMER_CTRL);
+
+        writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_DIV256,
+			                TIMER0_BASE + TIMER_CTRL);
+}
+
+static int vpb_clocksource_init(void)
+{
+	versatile_timer_init();
+	vpb_cs.mult = clocksource_hz2mult(TIMER_FREQ, vpb_cs.shift);
+
+	return init_clock(&vpb_cs);
+}
+
+core_initcall(vpb_clocksource_init);
+
+void versatile_register_uart(unsigned id)
+{
+	switch (id) {
+	case 0:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart0_serial_device));
+		register_device(&uart0_serial_device);
+		break;
+	case 1:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart1_serial_device));
+		register_device(&uart1_serial_device);
+		break;
+	case 2:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart2_serial_device));
+		register_device(&uart2_serial_device);
+		break;
+	case 3:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart3_serial_device));
+		register_device(&uart3_serial_device);
+		break;
+	}
+}
+
+
+void __noreturn reset_cpu (unsigned long ignored)
+{
+	while (1);
+}
+EXPORT_SYMBOL(reset_cpu);
+
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
new file mode 100644
index 0000000..04b37a8
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/debug_ll.h b/arch/arm/mach-versatile/include/mach/debug_ll.h
new file mode 100644
index 0000000..514fcfb
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/debug_ll.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * barebox is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * barebox is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with barebox.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define   __MACH_DEBUG_LL_H__
+
+#include <linux/amba/serial.h>
+#include <asm/io.h>
+
+static inline void putc(char c)
+{
+	/* Wait until there is space in the FIFO */
+	while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+
+	/* Send the character */
+	writel(c, 0x101F1000 + UART01x_DR);
+
+	/* Wait to make sure it hits the line, in case we die too soon. */
+	while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+}
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/init.h b/arch/arm/mach-versatile/include/mach/init.h
new file mode 100644
index 0000000..7772e85
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/init.h
@@ -0,0 +1,9 @@
+
+#ifndef __VERSATILE_INIT_H__
+#define __VERSATILE_INIT_H__
+
+
+void versatile_add_sdram(u32 size);
+void versatile_register_uart(unsigned id);
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
new file mode 100644
index 0000000..88b8032
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/platform.h
@@ -0,0 +1,417 @@
+/*
+ * ach-arm926ejs/include/mach/platform.h
+ *
+ * Borrowed from Linux v2.6.35
+ * arch/arm/mach-versatile/include/mach/platform.h
+ *
+ * Copyright (c) ARM Limited 2003.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __address_h
+#define __address_h                     1
+
+/*
+ * Memory definitions
+ */
+#define VERSATILE_BOOT_ROM_LO          0x30000000		/* DoC Base (64Mb)...*/
+#define VERSATILE_BOOT_ROM_HI          0x30000000
+#define VERSATILE_BOOT_ROM_BASE        VERSATILE_BOOT_ROM_HI	 /*  Normal position */
+#define VERSATILE_BOOT_ROM_SIZE        SZ_64M
+
+#define VERSATILE_SSRAM_BASE           /* VERSATILE_SSMC_BASE ? */
+#define VERSATILE_SSRAM_SIZE           SZ_2M
+
+#define VERSATILE_FLASH_BASE           0x34000000
+#define VERSATILE_FLASH_SIZE           SZ_64M
+
+/* 
+ *  SDRAM
+ */
+#define VERSATILE_SDRAM_BASE           0x00000000
+
+/* 
+ *  Logic expansion modules
+ * 
+ */
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile Registers
+ * ------------------------------------------------------------------------
+ * 
+ */
+#define VERSATILE_SYS_ID_OFFSET               0x00
+#define VERSATILE_SYS_SW_OFFSET               0x04
+#define VERSATILE_SYS_LED_OFFSET              0x08
+#define VERSATILE_SYS_OSC0_OFFSET             0x0C
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC1_OFFSET             0x10
+#define VERSATILE_SYS_OSC2_OFFSET             0x14
+#define VERSATILE_SYS_OSC3_OFFSET             0x18
+#define VERSATILE_SYS_OSC4_OFFSET             0x1C
+#elif defined(CONFIG_MACH_VERSATILE_AB)
+#define VERSATILE_SYS_OSC1_OFFSET             0x1C
+#endif
+
+#define VERSATILE_SYS_OSCCLCD_OFFSET          0x1c
+
+#define VERSATILE_SYS_LOCK_OFFSET             0x20
+#define VERSATILE_SYS_100HZ_OFFSET            0x24
+#define VERSATILE_SYS_CFGDATA1_OFFSET         0x28
+#define VERSATILE_SYS_CFGDATA2_OFFSET         0x2C
+#define VERSATILE_SYS_FLAGS_OFFSET            0x30
+#define VERSATILE_SYS_FLAGSSET_OFFSET         0x30
+#define VERSATILE_SYS_FLAGSCLR_OFFSET         0x34
+#define VERSATILE_SYS_NVFLAGS_OFFSET          0x38
+#define VERSATILE_SYS_NVFLAGSSET_OFFSET       0x38
+#define VERSATILE_SYS_NVFLAGSCLR_OFFSET       0x3C
+#define VERSATILE_SYS_RESETCTL_OFFSET         0x40
+#define VERSATILE_SYS_PCICTL_OFFSET           0x44
+#define VERSATILE_SYS_MCI_OFFSET              0x48
+#define VERSATILE_SYS_FLASH_OFFSET            0x4C
+#define VERSATILE_SYS_CLCD_OFFSET             0x50
+#define VERSATILE_SYS_CLCDSER_OFFSET          0x54
+#define VERSATILE_SYS_BOOTCS_OFFSET           0x58
+#define VERSATILE_SYS_24MHz_OFFSET            0x5C
+#define VERSATILE_SYS_MISC_OFFSET             0x60
+#define VERSATILE_SYS_TEST_OSC0_OFFSET        0x80
+#define VERSATILE_SYS_TEST_OSC1_OFFSET        0x84
+#define VERSATILE_SYS_TEST_OSC2_OFFSET        0x88
+#define VERSATILE_SYS_TEST_OSC3_OFFSET        0x8C
+#define VERSATILE_SYS_TEST_OSC4_OFFSET        0x90
+
+#define VERSATILE_SYS_BASE                    0x10000000
+#define VERSATILE_SYS_ID                      (VERSATILE_SYS_BASE + VERSATILE_SYS_ID_OFFSET)
+#define VERSATILE_SYS_SW                      (VERSATILE_SYS_BASE + VERSATILE_SYS_SW_OFFSET)
+#define VERSATILE_SYS_LED                     (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET)
+#define VERSATILE_SYS_OSC0                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET)
+#define VERSATILE_SYS_OSC1                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET)
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC2                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET)
+#define VERSATILE_SYS_OSC3                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET)
+#define VERSATILE_SYS_OSC4                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET)
+#endif
+
+#define VERSATILE_SYS_LOCK                    (VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET)
+#define VERSATILE_SYS_100HZ                   (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET)
+#define VERSATILE_SYS_CFGDATA1                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET)
+#define VERSATILE_SYS_CFGDATA2                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA2_OFFSET)
+#define VERSATILE_SYS_FLAGS                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGS_OFFSET)
+#define VERSATILE_SYS_FLAGSSET                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSSET_OFFSET)
+#define VERSATILE_SYS_FLAGSCLR                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSCLR_OFFSET)
+#define VERSATILE_SYS_NVFLAGS                 (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGS_OFFSET)
+#define VERSATILE_SYS_NVFLAGSSET              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
+#define VERSATILE_SYS_NVFLAGSCLR              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
+#define VERSATILE_SYS_RESETCTL                (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
+#define VERSATILE_SYS_PCICTL                  (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
+#define VERSATILE_SYS_MCI                     (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYS_FLASH                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_SYS_CLCD                    (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
+#define VERSATILE_SYS_CLCDSER                 (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCDSER_OFFSET)
+#define VERSATILE_SYS_BOOTCS                  (VERSATILE_SYS_BASE + VERSATILE_SYS_BOOTCS_OFFSET)
+#define VERSATILE_SYS_24MHz                   (VERSATILE_SYS_BASE + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_SYS_MISC                    (VERSATILE_SYS_BASE + VERSATILE_SYS_MISC_OFFSET)
+#define VERSATILE_SYS_TEST_OSC0               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC0_OFFSET)
+#define VERSATILE_SYS_TEST_OSC1               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC1_OFFSET)
+#define VERSATILE_SYS_TEST_OSC2               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC2_OFFSET)
+#define VERSATILE_SYS_TEST_OSC3               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC3_OFFSET)
+#define VERSATILE_SYS_TEST_OSC4               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC4_OFFSET)
+
+/* 
+ * Values for VERSATILE_SYS_RESET_CTRL
+ */
+#define VERSATILE_SYS_CTRL_RESET_CONFIGCLR    0x01
+#define VERSATILE_SYS_CTRL_RESET_CONFIGINIT   0x02
+#define VERSATILE_SYS_CTRL_RESET_DLLRESET     0x03
+#define VERSATILE_SYS_CTRL_RESET_PLLRESET     0x04
+#define VERSATILE_SYS_CTRL_RESET_POR          0x05
+#define VERSATILE_SYS_CTRL_RESET_DoC          0x06
+
+#define VERSATILE_SYS_CTRL_LED         (1 << 0)
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile control registers
+ * ------------------------------------------------------------------------
+ */
+
+/* 
+ * VERSATILE_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4  = build value
+ * 3:0   = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * VERSATILE_SYS_LOCK
+ *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, 
+ *     SYS_CLD, SYS_BOOTCS
+ */
+#define VERSATILE_SYS_LOCK_LOCKED    (1 << 16)
+#define VERSATILE_SYS_LOCKVAL_MASK	0xFFFF		/* write 0xA05F to enable write access */
+
+/*
+ * VERSATILE_SYS_FLASH
+ */
+#define VERSATILE_FLASHPROG_FLVPPEN	(1 << 0)	/* Enable writing to flash */
+
+/*
+ * VERSATILE_INTREG
+ *     - used to acknowledge and control MMCI and UART interrupts 
+ */
+#define VERSATILE_INTREG_WPROT        0x00    /* MMC protection status (no interrupt generated) */
+#define VERSATILE_INTREG_RI0          0x01    /* Ring indicator UART0 is asserted,              */
+#define VERSATILE_INTREG_CARDIN       0x08    /* MMCI card in detect                            */
+                                                /* write 1 to acknowledge and clear               */
+#define VERSATILE_INTREG_RI1          0x02    /* Ring indicator UART1 is asserted,              */
+#define VERSATILE_INTREG_CARDINSERT   0x03    /* Signal insertion of MMC card                   */
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_PCI_CORE_BASE        0x10001000	/* PCI core control */
+#define VERSATILE_I2C_BASE             0x10002000	/* I2C control */
+#define VERSATILE_SIC_BASE             0x10003000	/* Secondary interrupt controller */
+#define VERSATILE_AACI_BASE            0x10004000	/* Audio */
+#define VERSATILE_MMCI0_BASE           0x10005000	/* MMC interface */
+#define VERSATILE_KMI0_BASE            0x10006000	/* KMI interface */
+#define VERSATILE_KMI1_BASE            0x10007000	/* KMI 2nd interface */
+#define VERSATILE_CHAR_LCD_BASE        0x10008000	/* Character LCD */
+#define VERSATILE_UART3_BASE           0x10009000	/* UART 3 */
+#define VERSATILE_SCI1_BASE            0x1000A000
+#define VERSATILE_MMCI1_BASE           0x1000B000    /* MMC Interface */
+	/* 0x1000C000 - 0x1000CFFF = reserved */
+#define VERSATILE_ETH_BASE             0x10010000	/* Ethernet */
+#define VERSATILE_USB_BASE             0x10020000	/* USB */
+	/* 0x10030000 - 0x100FFFFF = reserved */
+#define VERSATILE_SMC_BASE             0x10100000	/* SMC */
+#define VERSATILE_MPMC_BASE            0x10110000	/* MPMC */
+#define VERSATILE_CLCD_BASE            0x10120000	/* CLCD */
+#define VERSATILE_DMAC_BASE            0x10130000	/* DMA controller */
+#define VERSATILE_VIC_BASE             0x10140000	/* Vectored interrupt controller */
+#define VERSATILE_PERIPH_BASE          0x10150000	/* off-chip peripherals alias from */
+                                                /* 0x10000000 - 0x100FFFFF */
+#define VERSATILE_AHBM_BASE            0x101D0000	/* AHB monitor */
+#define VERSATILE_SCTL_BASE            0x101E0000	/* System controller */
+#define VERSATILE_WATCHDOG_BASE        0x101E1000	/* Watchdog */
+#define VERSATILE_TIMER0_1_BASE        0x101E2000	/* Timer 0 and 1 */
+#define VERSATILE_TIMER2_3_BASE        0x101E3000	/* Timer 2 and 3 */
+#define VERSATILE_GPIO0_BASE           0x101E4000	/* GPIO port 0 */
+#define VERSATILE_GPIO1_BASE           0x101E5000	/* GPIO port 1 */
+#define VERSATILE_GPIO2_BASE           0x101E6000	/* GPIO port 2 */
+#define VERSATILE_GPIO3_BASE           0x101E7000	/* GPIO port 3 */
+#define VERSATILE_RTC_BASE             0x101E8000	/* Real Time Clock */
+	/* 0x101E9000 - reserved */
+#define VERSATILE_SCI_BASE             0x101F0000	/* Smart card controller */
+#define VERSATILE_UART0_BASE           0x101F1000	/* Uart 0 */
+#define VERSATILE_UART1_BASE           0x101F2000	/* Uart 1 */
+#define VERSATILE_UART2_BASE           0x101F3000	/* Uart 2 */
+#define VERSATILE_SSP_BASE             0x101F4000	/* Synchronous Serial Port */
+
+#define VERSATILE_SSMC_BASE            0x20000000	/* SSMC */
+#define VERSATILE_IB2_BASE             0x24000000	/* IB2 module */
+#define VERSATILE_MBX_BASE             0x40000000	/* MBX */
+
+/* PCI space */
+#define VERSATILE_PCI_BASE             0x41000000	/* PCI Interface */
+#define VERSATILE_PCI_CFG_BASE	       0x42000000
+#define VERSATILE_PCI_MEM_BASE0        0x44000000
+#define VERSATILE_PCI_MEM_BASE1        0x50000000
+#define VERSATILE_PCI_MEM_BASE2        0x60000000
+/* Sizes of above maps */
+#define VERSATILE_PCI_BASE_SIZE	       0x01000000
+#define VERSATILE_PCI_CFG_BASE_SIZE    0x02000000
+#define VERSATILE_PCI_MEM_BASE0_SIZE   0x0c000000	/* 32Mb */
+#define VERSATILE_PCI_MEM_BASE1_SIZE   0x10000000	/* 256Mb */
+#define VERSATILE_PCI_MEM_BASE2_SIZE   0x10000000	/* 256Mb */
+
+#define VERSATILE_SDRAM67_BASE         0x70000000	/* SDRAM banks 6 and 7 */
+#define VERSATILE_LT_BASE              0x80000000	/* Logic Tile expansion */
+
+/*
+ * Disk on Chip
+ */
+#define VERSATILE_DOC_BASE             0x2C000000
+#define VERSATILE_DOC_SIZE             (16 << 20)
+#define VERSATILE_DOC_PAGE_SIZE        512
+#define VERSATILE_DOC_TOTAL_PAGES     (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES    32
+#define START_PAGE          0x80
+
+/* 
+ *  LED settings, bits [7:0]
+ */
+#define VERSATILE_SYS_LED0             (1 << 0)
+#define VERSATILE_SYS_LED1             (1 << 1)
+#define VERSATILE_SYS_LED2             (1 << 2)
+#define VERSATILE_SYS_LED3             (1 << 3)
+#define VERSATILE_SYS_LED4             (1 << 4)
+#define VERSATILE_SYS_LED5             (1 << 5)
+#define VERSATILE_SYS_LED6             (1 << 6)
+#define VERSATILE_SYS_LED7             (1 << 7)
+
+#define ALL_LEDS                  0xFF
+
+#define LED_BANK                  VERSATILE_SYS_LED
+
+/* 
+ * Control registers
+ */
+#define VERSATILE_IDFIELD_OFFSET	0x0	/* Versatile build information */
+#define VERSATILE_FLASHPROG_OFFSET	0x4	/* Flash devices */
+#define VERSATILE_INTREG_OFFSET		0x8	/* Interrupt control */
+#define VERSATILE_DECODE_OFFSET		0xC	/* Fitted logic modules */
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile Interrupt Controller - control registers
+ * ------------------------------------------------------------------------
+ * 
+ *  Offsets from interrupt controller base 
+ * 
+ *  System Controller interrupt controller base is
+ * 
+ * 	VERSATILE_IC_BASE
+ * 
+ *  Core Module interrupt controller base is
+ * 
+ * 	VERSATILE_SYS_IC 
+ * 
+ */
+/* VIC definitions in include/asm-arm/hardware/vic.h */
+
+#define SIC_IRQ_STATUS                  0
+#define SIC_IRQ_RAW_STATUS              0x04
+#define SIC_IRQ_ENABLE                  0x08
+#define SIC_IRQ_ENABLE_SET              0x08
+#define SIC_IRQ_ENABLE_CLEAR            0x0C
+#define SIC_INT_SOFT_SET                0x10
+#define SIC_INT_SOFT_CLEAR              0x14
+#define SIC_INT_PIC_ENABLE              0x20	/* read status of pass through mask */
+#define SIC_INT_PIC_ENABLES             0x20	/* set interrupt pass through bits */
+#define SIC_INT_PIC_ENABLEC             0x24	/* Clear interrupt pass through bits */
+
+/* ------------------------------------------------------------------------
+ *  Interrupts - bit assignment (primary)
+ * ------------------------------------------------------------------------
+ */
+
+#define INT_WDOGINT                     0	/* Watchdog timer */
+#define INT_SOFTINT                     1	/* Software interrupt */
+#define INT_COMMRx                      2	/* Debug Comm Rx interrupt */
+#define INT_COMMTx                      3	/* Debug Comm Tx interrupt */
+#define INT_TIMERINT0_1                 4	/* Timer 0 and 1 */
+#define INT_TIMERINT2_3                 5	/* Timer 2 and 3 */
+#define INT_GPIOINT0                    6	/* GPIO 0 */
+#define INT_GPIOINT1                    7	/* GPIO 1 */
+#define INT_GPIOINT2                    8	/* GPIO 2 */
+#define INT_GPIOINT3                    9	/* GPIO 3 */
+#define INT_RTCINT                      10	/* Real Time Clock */
+#define INT_SSPINT                      11	/* Synchronous Serial Port */
+#define INT_UARTINT0                    12	/* UART 0 on development chip */
+#define INT_UARTINT1                    13	/* UART 1 on development chip */
+#define INT_UARTINT2                    14	/* UART 2 on development chip */
+#define INT_SCIINT                      15	/* Smart Card Interface */
+#define INT_CLCDINT                     16	/* CLCD controller */
+#define INT_DMAINT                      17	/* DMA controller */
+#define INT_PWRFAILINT                  18	/* Power failure */
+#define INT_MBXINT                      19	/* Graphics processor */
+#define INT_GNDINT                      20	/* Reserved */
+	/* External interrupt signals from logic tiles or secondary controller */
+#define INT_VICSOURCE21                 21	/* Disk on Chip */
+#define INT_VICSOURCE22                 22	/* MCI0A */
+#define INT_VICSOURCE23                 23	/* MCI1A */
+#define INT_VICSOURCE24                 24	/* AACI */
+#define INT_VICSOURCE25                 25	/* Ethernet */
+#define INT_VICSOURCE26                 26	/* USB */
+#define INT_VICSOURCE27                 27	/* PCI 0 */
+#define INT_VICSOURCE28                 28	/* PCI 1 */
+#define INT_VICSOURCE29                 29	/* PCI 2 */
+#define INT_VICSOURCE30                 30	/* PCI 3 */
+#define INT_VICSOURCE31                 31	/* SIC source */
+
+#define VERSATILE_SC_VALID_INT               0x003FFFFF
+
+#define MAXIRQNUM                       31
+#define MAXFIQNUM                       31
+#define MAXSWINUM                       31
+
+/* ------------------------------------------------------------------------
+ *  Interrupts - bit assignment (secondary)
+ * ------------------------------------------------------------------------
+ */
+#define SIC_INT_MMCI0B                  1	/* Multimedia Card 0B */
+#define SIC_INT_MMCI1B                  2	/* Multimedia Card 1B */
+#define SIC_INT_KMI0                    3	/* Keyboard/Mouse port 0 */
+#define SIC_INT_KMI1                    4	/* Keyboard/Mouse port 1 */
+#define SIC_INT_SCI3                    5	/* Smart Card interface */
+#define SIC_INT_UART3                   6	/* UART 3 empty or data available */
+#define SIC_INT_CLCD                    7	/* Character LCD */
+#define SIC_INT_TOUCH                   8	/* Touchscreen */
+#define SIC_INT_KEYPAD                  9	/* Key pressed on display keypad */
+	/* 10:20 - reserved */
+#define SIC_INT_DoC                     21	/* Disk on Chip memory controller */
+#define SIC_INT_MMCI0A                  22	/* MMC 0A */
+#define SIC_INT_MMCI1A                  23	/* MMC 1A */
+#define SIC_INT_AACI                    24	/* Audio Codec */
+#define SIC_INT_ETH                     25	/* Ethernet controller */
+#define SIC_INT_USB                     26	/* USB controller */
+#define SIC_INT_PCI0                    27
+#define SIC_INT_PCI1                    28
+#define SIC_INT_PCI2                    29
+#define SIC_INT_PCI3                    30
+
+
+/*
+ * System controller bit assignment
+ */
+#define VERSATILE_REFCLK	0
+#define VERSATILE_TIMCLK	1
+
+#define VERSATILE_TIMER1_EnSel	15
+#define VERSATILE_TIMER2_EnSel	17
+#define VERSATILE_TIMER3_EnSel	19
+#define VERSATILE_TIMER4_EnSel	21
+
+
+#define VERSATILE_CSR_BASE             0x10000000
+#define VERSATILE_CSR_SIZE             0x10000000
+
+#ifdef CONFIG_MACH_VERSATILE_AB
+/*
+ * IB2 Versatile/AB expansion board definitions
+ */
+#define VERSATILE_IB2_CAMERA_BANK	VERSATILE_IB2_BASE
+#define VERSATILE_IB2_KBD_DATAREG	(VERSATILE_IB2_BASE + 0x01000000)
+
+/* VICINTSOURCE27 */
+#define VERSATILE_IB2_INT_BASE		(VERSATILE_IB2_BASE + 0x02000000)
+#define VERSATILE_IB2_IER		(VERSATILE_IB2_INT_BASE + 0)
+#define VERSATILE_IB2_ISR		(VERSATILE_IB2_INT_BASE + 4)
+
+#define VERSATILE_IB2_CTL_BASE		(VERSATILE_IB2_BASE + 0x03000000)
+#define VERSATILE_IB2_CTRL		(VERSATILE_IB2_CTL_BASE + 0)
+#define VERSATILE_IB2_STAT		(VERSATILE_IB2_CTL_BASE + 4)
+#endif
+
+#endif



From baruch at tkos.co.il  Mon Oct 11 00:56:51 2010
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 11 Oct 2010 06:56:51 +0200
Subject: [PATCH] Add basic support from ARM Versatile/PB
In-Reply-To: <20101010230505.17833.46593.stgit@zaytsev.su>
References: <20101010230505.17833.46593.stgit@zaytsev.su>
Message-ID: <20101011045651.GB6962@jasper.tkos.co.il>

Hi Alexey,

On Sun, Oct 10, 2010 at 11:15:37PM +0000, Alexey Zaytsev wrote:
> Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
> ---

[snip]

> +config VERSATILE_SMC91C111
> +	bool "Use smc91c111 instead of smc91x (for QEMU)"
> +	default 0
> +	help
> +	 Enable this option to run barebox inside qemu.
> +	 Real versatile boards are equipped with smc911x,
> +	 but qemu only provides smc91111, which is a bit different.

s/smc91111/smc9111/?

baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -


From plagnioj at jcrosoft.com  Mon Oct 11 01:08:17 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 07:08:17 +0200
Subject: [PATCH 3/3] hush: implement getopt builtin
In-Reply-To: <20101008124515.GP28242@pengutronix.de>
References: <1286540674-17174-1-git-send-email-s.hauer@pengutronix.de>
	<1286540674-17174-4-git-send-email-s.hauer@pengutronix.de>
	<20101008123627.GC30252@game.jcrosoft.org>
	<20101008124515.GP28242@pengutronix.de>
Message-ID: <20101011050817.GE30252@game.jcrosoft.org>

On 14:45 Fri 08 Oct     , Sascha Hauer wrote:
> On Fri, Oct 08, 2010 at 02:36:27PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 14:24 Fri 08 Oct     , Sascha Hauer wrote:
> > > Positional parameters are not nice, so implement a getopt
> > > function. This has to be done as a builtin because otherwise
> > > we have no access to the parents argc/argv.
> > > 
> > > getopt works as expected, here is a little example:
> > > 
> > > while getopt "hs:" OPT
> > > do
> > >         if [ $OPT = h ]; then
> > >                 echo "usage"
> > >                 exit 1
> > >         else
> > >                 echo "scr: opt: $OPT optarg: $OPTARG"
> > > 	fi
> > > done
> > > 
> > > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > how about make it optional?
> 
> Probably a good idea. I just had in mind that we need to adjust
> the defconfigs then to still have a working defaultenv.
> 
> How about making it optional and combined with your defaultenv-Kconfig
> patch we could do a
> 
> 	select HUSH
> 	select HUSH_GETOPT
> 
> to make sure all commands needed by the defaultenv are in place.
that's why I move the defaultenv to Kconfig, I'm still in vacation. I'll send
the patch tomorrow

Best Regards,
J.


From plagnioj at jcrosoft.com  Mon Oct 11 01:11:04 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 07:11:04 +0200
Subject: [PATCH 3/5] defaultenv: add xmodem support for update
In-Reply-To: <20101008122747.GN28242@pengutronix.de>
References: <1286469458-11362-1-git-send-email-plagnioj@jcrosoft.com>
	<1286469458-11362-3-git-send-email-plagnioj@jcrosoft.com>
	<20101008122747.GN28242@pengutronix.de>
Message-ID: <20101011051104.GF30252@game.jcrosoft.org>

> >  	exit 1
> >  fi
> >  
> > +if [ x$3 != x ]; then
> > +	mode=$3
> > +fi
> > +
> >  . /env/bin/_update $2
> > diff --git a/defaultenv/bin/update_rootfs b/defaultenv/bin/update_rootfs
> > index 6366315..bac74ca 100644
> > --- a/defaultenv/bin/update_rootfs
> > +++ b/defaultenv/bin/update_rootfs
> > @@ -3,14 +3,19 @@
> >  . /env/config
> >  
> >  image=$rootfsimage
> > +mode=net
> >  
> >  if [ x$1 = xnand ]; then
> >  	part=/dev/nand0.root.bb
> >  elif [ x$1 = xnor ]; then
> >  	part=/dev/nor0.root
> >  else
> > -	echo "usage: $0 nor|nand [imagename]"
> > +	echo "usage: $0 nor|nand [imagename] [net|xmodem]"
> 
> I'm not really happy with this patch. We have 3 positional parameters
> now and with xmodem it makes no sense to supply an image name,
> nontheless we have to supply it because otherwise we do not have three
> arguments.
> I just posted a patch adding a getopt command to hush. Maybe this could
> improve the situation here?
I get exactly the same idea

Best Regards,
J.


From alexey.zaytsev at gmail.com  Mon Oct 11 03:22:01 2010
From: alexey.zaytsev at gmail.com (Alexey Zaytsev)
Date: Mon, 11 Oct 2010 11:22:01 +0400
Subject: [PATCH] Add basic support from ARM Versatile/PB
In-Reply-To: <20101011045651.GB6962@jasper.tkos.co.il>
References: <20101010230505.17833.46593.stgit@zaytsev.su>
	<20101011045651.GB6962@jasper.tkos.co.il>
Message-ID: <AANLkTikGhog-CTPyswb0d9HosG14CUJswgzU=mA8-bvW@mail.gmail.com>

On Mon, Oct 11, 2010 at 08:56, Baruch Siach <baruch at tkos.co.il> wrote:
> Hi Alexey,
>
> On Sun, Oct 10, 2010 at 11:15:37PM +0000, Alexey Zaytsev wrote:
>> Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
>> ---
>
> [snip]
>
>> +config VERSATILE_SMC91C111
>> + ? ? bool "Use smc91c111 instead of smc91x (for QEMU)"
>> + ? ? default 0
>> + ? ? help
>> + ? ? ?Enable this option to run barebox inside qemu.
>> + ? ? ?Real versatile boards are equipped with smc911x,
>> + ? ? ?but qemu only provides smc91111, which is a bit different.
>
> s/smc91111/smc9111/?
>

The driver is implemented in smc91111.c, but it should probably be smc91c111.


From jbe at pengutronix.de  Mon Oct 11 04:50:28 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 10:50:28 +0200
Subject: [PATCH] barebox-next: Avoid a Kconfig warning
Message-ID: <201010111050.28141.jbe@pengutronix.de>

This patch removes the following warning in the current next-tree:

"arch/arm/mach-imx/Kconfig:53:warning: defaults for choice values not supported"

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>

---
 arch/arm/mach-imx/Kconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: arch/arm/mach-imx/Kconfig
===================================================================
--- arch/arm/mach-imx/Kconfig.orig
+++ arch/arm/mach-imx/Kconfig
@@ -42,6 +42,7 @@ config ARCH_IMX_INTERNAL_BOOT
 
 choice
 	depends on ARCH_IMX_INTERNAL_BOOT
+	default ARCH_IMX_INTERNAL_BOOT_NAND
 	prompt "Internal boot source"
 	help
 	  Determines the location of the header information for internal boot.
@@ -50,7 +51,6 @@ choice
 	  0x1000 for NOR
 
 config ARCH_IMX_INTERNAL_BOOT_NAND
-	default y
 	bool "NAND, SD/MMC, Serial ROM"
 	select NAND_IMX_BOOT
 

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Mon Oct 11 05:06:56 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 11:06:56 +0200
Subject: [PATCH v2] Add the i.MX23 architecure to barebox
Message-ID: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>

This patch adds the basic support for the i.MX23 architecture. This
CPUs is branded with i.MX, but they are mostly of type STMP378X from SigmaTel.
So, it does not share most of its internal devices with the other i.MX CPUs.
That's why I open a new sub architecture 'mach-stm'.

This is v2 of my patch series to add the i.MX23 architecture. Slightly
modified for easier i.MX28 addition later on. Defconfigs are regenerated.

jbe



From jbe at pengutronix.de  Mon Oct 11 05:06:59 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 11:06:59 +0200
Subject: [PATCH 3/4] Add the i.MX23-EVK platform (WIP)
In-Reply-To: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
References: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286788020-14077-4-git-send-email-jbe@pengutronix.de>

Note: This is work in progress. Use with care.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 Documentation/boards.dox                      |    1 +
 arch/arm/Makefile                             |    2 +
 arch/arm/boards/freescale-mx23-evk/Makefile   |    2 +
 arch/arm/boards/freescale-mx23-evk/config.h   |   16 ++
 arch/arm/boards/freescale-mx23-evk/mx23-evk.c |   96 +++++++++++
 arch/arm/configs/imx23evk_defconfig           |  222 +++++++++++++++++++++++++
 arch/arm/mach-stm/Kconfig                     |    7 +
 7 files changed, 346 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/freescale-mx23-evk/Makefile
 create mode 100644 arch/arm/boards/freescale-mx23-evk/config.h
 create mode 100644 arch/arm/boards/freescale-mx23-evk/mx23-evk.c
 create mode 100644 arch/arm/configs/imx23evk_defconfig

diff --git a/Documentation/boards.dox b/Documentation/boards.dox
index 3eb79b2..7b1450e 100644
--- a/Documentation/boards.dox
+++ b/Documentation/boards.dox
@@ -14,6 +14,7 @@ ARM type:
 @li @subpage imx21ads
 @li @subpage imx27ads
 @li @subpage the3stack
+ at li @subpage mx23_evk
 @li @subpage scb9328
 @li @subpage netx
 @li @subpage dev_omap_arch
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77b6cf4..75fa6d3 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -41,6 +41,7 @@ CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
 machine-$(CONFIG_ARCH_AT91)		:= at91
 machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_IMX)		:= imx
+machine-$(CONFIG_ARCH_STM)		:= stm
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_OMAP)		:= omap
@@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
 board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
+board-$(CONFIG_MACH_MX23EVK)			:= freescale-mx23-evk
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/freescale-mx23-evk/Makefile b/arch/arm/boards/freescale-mx23-evk/Makefile
new file mode 100644
index 0000000..cffb561
--- /dev/null
+++ b/arch/arm/boards/freescale-mx23-evk/Makefile
@@ -0,0 +1,2 @@
+#
+obj-y := mx23-evk.o
diff --git a/arch/arm/boards/freescale-mx23-evk/config.h b/arch/arm/boards/freescale-mx23-evk/config.h
new file mode 100644
index 0000000..4b3da8f
--- /dev/null
+++ b/arch/arm/boards/freescale-mx23-evk/config.h
@@ -0,0 +1,16 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
diff --git a/arch/arm/boards/freescale-mx23-evk/mx23-evk.c b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
new file mode 100644
index 0000000..1ce72be
--- /dev/null
+++ b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <mach/imx-regs.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.name     = "mem",
+	.map_base = IMX_MEMORY_BASE,
+	.size     = 32 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+static int mx23_evk_devices_init(void)
+{
+	register_device(&sdram_dev);
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void*)(sdram_dev.map_base + 0x100));
+	armlinux_set_architecture(MACH_TYPE_MX23EVK);
+
+	return 0;
+}
+
+device_initcall(mx23_evk_devices_init);
+
+static struct device_d mx23_evk_serial_device = {
+	.name     = "stm_serial",
+	.map_base = IMX_DBGUART_BASE,
+	.size     = 8192,
+};
+
+static int mx23_evk_console_init(void)
+{
+	return register_device(&mx23_evk_serial_device);
+}
+
+console_initcall(mx23_evk_console_init);
+
+/** @page mx23_evk Freescale's i.MX23 evaluation kit
+
+This CPU card is based on an i.MX23 CPU. The card is shipped with:
+
+- 32 MiB synchronous dynamic RAM (mobile DDR type)
+- ENC28j60 based network (over SPI)
+
+Memory layout when @b barebox is running:
+
+- 0x40000000 start of SDRAM
+- 0x40000100 start of kernel's boot parameters
+  - below malloc area: stack area
+  - below barebox: malloc area
+- 0x41000000 start of @b barebox
+
+ at section get_imx23evk_binary How to get the bootloader binary image:
+
+Using the default configuration:
+
+ at verbatim
+make ARCH=arm imx23evk_defconfig
+ at endverbatim
+
+Build the bootloader binary image:
+
+ at verbatim
+make ARCH=arm CROSS_COMPILE=armv5compiler
+ at endverbatim
+
+ at note replace the armv5compiler with your ARM v5 cross compiler.
+*/
diff --git a/arch/arm/configs/imx23evk_defconfig b/arch/arm/configs/imx23evk_defconfig
new file mode 100644
index 0000000..52eae05
--- /dev/null
+++ b/arch/arm/configs/imx23evk_defconfig
@@ -0,0 +1,222 @@
+#
+# Automatically generated make config: don't edit
+# Linux barebox version: 2010.09.0
+# Mon Oct 11 10:25:16 2010
+#
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_ARM=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_IMX is not set
+CONFIG_ARCH_STM=y
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_S3C24xx is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+
+#
+# processor features
+#
+CONFIG_ARCH_TEXT_BASE=0x41000000
+CONFIG_BOARDINFO="Freescale i.MX23-EVK"
+
+#
+# SigmaTel/Freescale i.MX System-on-Chip
+#
+CONFIG_ARCH_IMX23=y
+CONFIG_MACH_MX23EVK=y
+# CONFIG_MACH_CHUMBY is not set
+
+#
+# Board specific settings       
+#
+CONFIG_AEABI=y
+
+#
+# Arm specific settings         
+#
+CONFIG_CMD_ARM_CPUINFO=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
+CONFIG_GREGORIAN_CALENDER=y
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+CONFIG_GENERIC_GPIO=y
+
+#
+# General Settings              
+#
+CONFIG_LOCALVERSION_AUTO=y
+
+#
+# memory layout                 
+#
+CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
+CONFIG_TEXT_BASE=0x41000000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+# CONFIG_MEMORY_LAYOUT_FIXED is not set
+CONFIG_STACK_SIZE=0x8000
+CONFIG_MALLOC_SIZE=0x400000
+CONFIG_BROKEN=y
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_PROMPT="barebox:"
+CONFIG_BAUDRATE=115200
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+# CONFIG_GLOB is not set
+CONFIG_PROMPT_HUSH_PS2="> "
+# CONFIG_HUSH_FANCY_PROMPT is not set
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+# CONFIG_MENU is not set
+# CONFIG_PASSWORD is not set
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+CONFIG_TIMESTAMP=y
+CONFIG_CONSOLE_FULL=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+# CONFIG_OF_FLAT_TREE is not set
+CONFIG_PARTITION=y
+# CONFIG_DEFAULT_ENVIRONMENT is not set
+
+#
+# Debugging                     
+#
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+# CONFIG_ENABLE_DEVICE_NOISE is not set
+
+#
+# Commands                      
+#
+
+#
+# scripting                     
+#
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TRUE=y
+CONFIG_CMD_FALSE=y
+# CONFIG_CMD_LOGIN is not set
+# CONFIG_CMD_PASSWD is not set
+
+#
+# file commands                 
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+
+#
+# console                       
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_ECHO_E=y
+
+#
+# memory                        
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_MEMINFO is not set
+# CONFIG_CMD_CRC is not set
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+
+#
+# flash                         
+#
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_UBI is not set
+
+#
+# booting                       
+#
+CONFIG_CMD_BOOTM=y
+# CONFIG_CMD_BOOTM_ZLIB is not set
+# CONFIG_CMD_BOOTM_BZLIB is not set
+# CONFIG_CMD_BOOTM_SHOW_TYPE is not set
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTU=y
+CONFIG_CMD_RESET=y
+# CONFIG_CMD_GO is not set
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_CMD_VERSION=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_DEVINFO=y
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_UNLZO is not set
+# CONFIG_NET is not set
+
+#
+# Drivers                       
+#
+
+#
+# serial drivers                
+#
+# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
+CONFIG_DRIVER_SERIAL_STM378X=y
+# CONFIG_DRIVER_SERIAL_NS16550 is not set
+
+#
+# SPI drivers                   
+#
+# CONFIG_SPI is not set
+# CONFIG_I2C is not set
+
+#
+# flash drivers                 
+#
+# CONFIG_DRIVER_CFI is not set
+# CONFIG_MTD is not set
+# CONFIG_ATA is not set
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_VIDEO is not set
+
+#
+# Filesystem support            
+#
+# CONFIG_FS_CRAMFS is not set
+CONFIG_FS_RAMFS=y
+CONFIG_FS_DEVFS=y
+CONFIG_CRC32=y
+# CONFIG_DIGEST is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_PROCESS_ESCAPE_SEQUENCE=y
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 9858d3a..bbdea51 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -2,8 +2,10 @@ if ARCH_STM
 
 config ARCH_TEXT_BASE
 	hex
+	default 0x41000000 if MACH_MX23EVK
 
 config BOARDINFO
+	default "Freescale i.MX23-EVK" if MACH_MX23EVK
 
 comment "SigmaTel/Freescale i.MX System-on-Chip"
 
@@ -21,6 +23,11 @@ if ARCH_IMX23
 choice
 	prompt "i.MX23 Board Type"
 
+config MACH_MX23EVK
+	bool "mx23-evk"
+	help
+	  Say Y here if you are using the Freescale i.MX23-EVK board
+
 endchoice
 
 endif
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Oct 11 05:06:58 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 11:06:58 +0200
Subject: [PATCH 2/4] Add the driver for the i.MX23 debug UART
In-Reply-To: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
References: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286788020-14077-3-git-send-email-jbe@pengutronix.de>

The i.MX23 comes with a special UART dedicated for debugging purposes. This one
is mostly used for the console the user can reach.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/serial/Kconfig      |    5 +
 drivers/serial/Makefile     |    1 +
 drivers/serial/stm-serial.c |  202 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 208 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/stm-serial.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index c7ea2d9..3a8882f 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -18,6 +18,11 @@ config DRIVER_SERIAL_IMX
 	default y
 	bool "i.MX serial driver"
 
+config DRIVER_SERIAL_STM378X
+	depends on ARCH_STM
+	default y
+	bool "i.MX23 serial driver"
+
 config DRIVER_SERIAL_NETX
 	depends on ARCH_NETX
 	default y
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 959290e..9f0e12b 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC)		+= arm_dcc.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_DRIVER_SERIAL_IMX)			+= serial_imx.o
+obj-$(CONFIG_DRIVER_SERIAL_STM378X)		+= stm-serial.o
 obj-$(CONFIG_DRIVER_SERIAL_ATMEL)		+= atmel.o
 obj-$(CONFIG_DRIVER_SERIAL_NETX)		+= serial_netx.o
 obj-$(CONFIG_DRIVER_SERIAL_LINUX_COMSOLE)	+= linux_console.o
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
new file mode 100644
index 0000000..90563f5
--- /dev/null
+++ b/drivers/serial/stm-serial.c
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This code was inspired by some patches made for u-boot covered by:
+ * (c) 2007 Sascha Hauer <s.hauer at pengutronix.de>
+ * (C) Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*
+ * Note: This is the driver for the debug UART. There is
+ * only one of these UARTs on the Freescale/SigmaTel parts
+ */
+
+#include <common.h>
+#include <init.h>
+#include <notifier.h>
+#include <gpio.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+
+#define UARTDBGDR 0x00
+#define UARTDBGFR 0x18
+# define TXFF (1 << 5)
+# define RXFE (1 << 4)
+#define UARTDBGIBRD 0x24
+#define UARTDBGFBRD 0x28
+#define UARTDBGLCR_H 0x2c
+# define WLEN8 (3 << 5)
+# define WLEN7 (2 << 5)
+# define WLEN6 (1 << 5)
+# define WLEN5 (0 << 5)
+# define FEN (1 << 4)
+#define UARTDBGCR 0x30
+# define UARTEN (1 << 0)
+# define TXE (1 << 8)
+# define RXE (1 << 9)
+#define UARTDBGIMSC 0x38
+
+struct stm_serial_local {
+	struct console_device cdev;
+	int baudrate;
+	struct notifier_block notify;
+};
+
+static void stm_serial_putc(struct console_device *cdev, char c)
+{
+	struct device_d *dev = cdev->dev;
+
+	/* Wait for room in TX FIFO */
+	while (readl(dev->map_base + UARTDBGFR) & TXFF)
+		;
+
+	writel(c, dev->map_base + UARTDBGDR);
+}
+
+static int stm_serial_tstc(struct console_device *cdev)
+{
+	struct device_d *dev = cdev->dev;
+
+	/* Check if RX FIFO is not empty */
+	return !(readl(dev->map_base + UARTDBGFR) & RXFE);
+}
+
+static int stm_serial_getc(struct console_device *cdev)
+{
+	struct device_d *dev = cdev->dev;
+
+	/* Wait while TX FIFO is empty */
+	while (readl(dev->map_base + UARTDBGFR) & RXFE)
+		;
+
+	return readl(dev->map_base + UARTDBGDR) & 0xff;
+}
+
+static void stm_serial_flush(struct console_device *cdev)
+{
+	struct device_d *dev = cdev->dev;
+
+	/* Wait for TX FIFO empty */
+	while (readl(dev->map_base + UARTDBGFR) & TXFF)
+		;
+}
+
+static int stm_serial_setbaudrate(struct console_device *cdev, int new_baudrate)
+{
+	struct device_d *dev = cdev->dev;
+	struct stm_serial_local *local = container_of(cdev, struct stm_serial_local, cdev);
+	uint32_t cr, lcr_h, quot;
+
+	/* Disable everything */
+	cr = readl(dev->map_base + UARTDBGCR);
+	writel(0, dev->map_base + UARTDBGCR);
+
+	/* Calculate and set baudrate */
+	quot = (imx_get_xclk() * 4000) / new_baudrate;
+	writel(quot & 0x3f, dev->map_base + UARTDBGFBRD);
+	writel(quot >> 6, dev->map_base + UARTDBGIBRD);
+
+	/* Set 8n1 mode, enable FIFOs */
+	lcr_h = WLEN8 | FEN;
+	writel(lcr_h, dev->map_base + UARTDBGLCR_H);
+
+	/* Re-enable debug UART */
+	writel(cr, dev->map_base + UARTDBGCR);
+
+	local->baudrate = new_baudrate;
+
+	return 0;
+}
+
+static int stm_clocksource_clock_change(struct notifier_block *nb, unsigned long event, void *data)
+{
+	struct stm_serial_local *local = container_of(nb, struct stm_serial_local, notify);
+
+	return stm_serial_setbaudrate(&local->cdev, local->baudrate);
+}
+
+static int stm_serial_init_port(struct console_device *cdev)
+{
+	struct device_d *dev = cdev->dev;
+	/*
+	 * If the board specific file registers this console we should force
+	 * the usage of the debug UART pins, to be able to let the user see
+	 * the output, even if the board file forgets to configure these pins.
+	 */
+	imx_gpio_mode(PWM1_DUART_TX);
+	imx_gpio_mode(PWM0_DUART_RX);
+
+	/* Disable UART */
+	writel(0, dev->map_base + UARTDBGCR);
+
+	/* Mask interrupts */
+	writel(0, dev->map_base + UARTDBGIMSC);
+
+	return 0;
+}
+
+static struct stm_serial_local stm_device = {
+	.cdev = {
+		.f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR,
+		.tstc = stm_serial_tstc,
+		.putc = stm_serial_putc,
+		.getc = stm_serial_getc,
+		.flush = stm_serial_flush,
+		.setbrg = stm_serial_setbaudrate,
+	},
+};
+
+static int stm_serial_probe(struct device_d *dev)
+{
+	stm_device.cdev.dev = dev;
+	dev->type_data = &stm_device.cdev;
+
+	stm_serial_init_port(&stm_device.cdev);
+	stm_serial_setbaudrate(&stm_device.cdev, CONFIG_BAUDRATE);
+
+	/* Enable UART */
+	writel(TXE | RXE | UARTEN, dev->map_base + UARTDBGCR);
+
+	console_register(&stm_device.cdev);
+	stm_device.notify.notifier_call = stm_clocksource_clock_change;
+	clock_register_client(&stm_device.notify);
+
+	return 0;
+}
+
+static void stm_serial_remove(struct device_d *dev)
+{
+	struct console_device *cdev = dev->type_data;
+
+	stm_serial_flush(cdev);
+}
+
+static struct driver_d stm_serial_driver = {
+        .name   = "stm_serial",
+        .probe  = stm_serial_probe,
+	.remove = stm_serial_remove,
+};
+
+static int stm_serial_init(void)
+{
+	register_driver(&stm_serial_driver);
+	return 0;
+}
+
+console_initcall(stm_serial_init);
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Oct 11 05:07:00 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 11:07:00 +0200
Subject: [PATCH 4/4] Add the i.MX23 based Chumby platform (WIP)
In-Reply-To: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
References: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286788020-14077-5-git-send-email-jbe@pengutronix.de>

The so called "chumby one" aka falconwing is an i.MX23 based platform.

Note: This is work in progress. Use with care.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 Documentation/boards.dox                       |    1 +
 arch/arm/Makefile                              |    1 +
 arch/arm/boards/chumby_falconwing/Makefile     |    1 +
 arch/arm/boards/chumby_falconwing/config.h     |   21 ++
 arch/arm/boards/chumby_falconwing/falconwing.c |  271 ++++++++++++++++++++++++
 arch/arm/configs/chumbyone_defconfig           |  224 +++++++++++++++++++
 arch/arm/mach-stm/Kconfig                      |    9 +
 7 files changed, 528 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/chumby_falconwing/Makefile
 create mode 100644 arch/arm/boards/chumby_falconwing/config.h
 create mode 100644 arch/arm/boards/chumby_falconwing/falconwing.c
 create mode 100644 arch/arm/configs/chumbyone_defconfig

diff --git a/Documentation/boards.dox b/Documentation/boards.dox
index 7b1450e..0b7a198 100644
--- a/Documentation/boards.dox
+++ b/Documentation/boards.dox
@@ -15,6 +15,7 @@ ARM type:
 @li @subpage imx27ads
 @li @subpage the3stack
 @li @subpage mx23_evk
+ at li @subpage chumbyone
 @li @subpage scb9328
 @li @subpage netx
 @li @subpage dev_omap_arch
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 75fa6d3..b25f366 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -82,6 +82,7 @@ board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
 board-$(CONFIG_MACH_MX23EVK)			:= freescale-mx23-evk
+board-$(CONFIG_MACH_CHUMBY)			:= chumby_falconwing
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/chumby_falconwing/Makefile b/arch/arm/boards/chumby_falconwing/Makefile
new file mode 100644
index 0000000..0bc79d9
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/Makefile
@@ -0,0 +1 @@
+obj-y = falconwing.o
diff --git a/arch/arm/boards/chumby_falconwing/config.h b/arch/arm/boards/chumby_falconwing/config.h
new file mode 100644
index 0000000..87d9e2f
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/config.h
@@ -0,0 +1,21 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _CONFIG_H_
+# define _CONFIG_H_
+
+#endif /* _CONFIG_H_ */
diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
new file mode 100644
index 0000000..d209dd5
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -0,0 +1,271 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <generated/mach-types.h>
+#include <mach/imx-regs.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.name     = "mem",
+	.map_base = IMX_MEMORY_BASE,
+	.size     = 64 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+static const uint32_t pad_setup[] = {
+	/* may be not required as already done by the bootlet code */
+#if 0
+	/* SDRAM data signals */
+	EMI_D15 | STRENGTH(0) | VE_2_5V,
+	EMI_D14 | STRENGTH(0) | VE_2_5V,
+	EMI_D13 | STRENGTH(0) | VE_2_5V,
+	EMI_D12 | STRENGTH(0) | VE_2_5V,
+	EMI_D11 | STRENGTH(0) | VE_2_5V,
+	EMI_D10 | STRENGTH(0) | VE_2_5V,
+	EMI_D9 | STRENGTH(0) | VE_2_5V,
+	EMI_D8 | STRENGTH(0) | VE_2_5V,
+	EMI_D7 | STRENGTH(0) | VE_2_5V,
+	EMI_D6 | STRENGTH(0) | VE_2_5V,
+	EMI_D5 | STRENGTH(0) | VE_2_5V,
+	EMI_D4 | STRENGTH(0) | VE_2_5V,
+	EMI_D3 | STRENGTH(0) | VE_2_5V,
+	EMI_D2 | STRENGTH(0) | VE_2_5V,
+	EMI_D1 | STRENGTH(0) | VE_2_5V,
+	EMI_D0 | STRENGTH(0) | VE_2_5V,
+
+	/* SDRAM data control signals */
+	EMI_DQM0 | STRENGTH(0) | VE_2_5V,	/* LDM */
+	EMI_DQM1 | STRENGTH(0) | VE_2_5V,	/* UDM */
+
+	/* SDRAM address signals */
+	EMI_A0 | STRENGTH(0) | VE_2_5V,
+	EMI_A1 | STRENGTH(0) | VE_2_5V,
+	EMI_A2 | STRENGTH(0) | VE_2_5V,
+	EMI_A3 | STRENGTH(0) | VE_2_5V,
+	EMI_A4 | STRENGTH(0) | VE_2_5V,
+	EMI_A5 | STRENGTH(0) | VE_2_5V,
+	EMI_A6 | STRENGTH(0) | VE_2_5V,
+	EMI_A7 | STRENGTH(0) | VE_2_5V,
+	EMI_A8 | STRENGTH(0) | VE_2_5V,
+	EMI_A9 | STRENGTH(0) | VE_2_5V,
+	EMI_A10 | STRENGTH(0) | VE_2_5V,
+	EMI_A11 | STRENGTH(0) | VE_2_5V,
+	EMI_A12 | STRENGTH(0) | VE_2_5V,
+
+	/* SDRAM address control signals */
+	EMI_RASN | STRENGTH(0) | VE_2_5V,
+	EMI_CASN | STRENGTH(0) | VE_2_5V,
+
+	/* SDRAM control signals */
+	EMI_CE0N | STRENGTH(0) | VE_2_5V,
+	EMI_CLK | STRENGTH(0) | VE_2_5V,
+	EMI_CLKN | STRENGTH(0) | VE_2_5V,
+	EMI_CKE | STRENGTH(0) | VE_2_5V,
+	EMI_WEN | STRENGTH(0) | VE_2_5V,
+	EMI_BA0 | STRENGTH(0) | VE_2_5V,
+	EMI_BA1 | STRENGTH(0) | VE_2_5V,
+	EMI_DQS0 | STRENGTH(0) | VE_2_5V,
+	EMI_DQS1 | STRENGTH(0) | VE_2_5V,
+#endif
+	/* debug port */
+	PWM1_DUART_TX | STRENGTH(S4MA),	/*  strength is TBD */
+	PWM0_DUART_RX | STRENGTH(S4MA),	/*  strength is TBD */
+
+	/* lcd */
+	LCD_VSYNC,	/* kernel tries with 12 mA for all LCD related pins */
+	LCD_HSYNC,
+	LCD_ENABE,
+	LCD_DOTCLOCK,
+	LCD_D17,
+	LCD_D16,
+	LCD_D15,
+	LCD_D14,
+	LCD_D13,
+	LCD_D12,
+	LCD_D11,
+	LCD_D10,
+	LCD_D9,
+	LCD_D8,
+	LCD_D7,
+	LCD_D6,
+	LCD_D5,
+	LCD_D4,
+	LCD_D3,
+	LCD_D2,
+	LCD_D1,
+	LCD_D0,
+
+	/* LCD usage currently unknown */
+	LCD_CS,	/* used as SPI SS */
+	LCD_RS,	/* used as SPI CLK */
+	LCD_RESET,
+	LCD_WR,	/* used as SPI MOSI */
+
+	/* I2C to the MMA7455L, KXTE9, AT24C08 (DCID), AT24C128B (ID EEPROM) and QN8005B */
+	I2C_SDA,
+	I2C_CLK,
+
+	/* Rotary decoder (external pull ups) */
+	ROTARYA,
+	ROTARYB,
+
+	/* the chumby bend (external pull up) */
+	PWM4_GPIO | GPIO_IN,
+
+	/* backlight control, to be controled by PWM, here we only want to disable it */
+	PWM2_GPIO | GPIO_OUT | GPIO_VALUE(0),	/* 1 enables, 0 disables the backlight */
+
+	/* send a reset signal to the USB hub */
+	AUART1_TX_GPIO | GPIO_OUT | GPIO_VALUE(0),
+
+	/* USB power disable (FIXME what level to be switched off) */
+	AUART1_CTS_GPIO | GPIO_OUT | GPIO_VALUE(0),
+
+	/* Detecting if a display is connected (0 = display attached) (external pull up) */
+	AUART1_RTS_GPIO | GPIO_IN,
+
+	/* disable the audio amplifier */
+	GPMI_D08_GPIO | GPIO_OUT | GPIO_VALUE(0),
+
+	/* Head Phone detection (FIXME what level when plugged in) (external pull up) */
+	GPMI_D11_GPIO | GPIO_IN,
+
+#if 0
+	/* Enable the local 5V (FIXME what to do when the bootloader runs) */
+	GPMI_D12_GPIO | GPIO_OUT | GPIO_VALUE(1),
+#endif
+
+	/* not used pins */
+	GPMI_D09_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_D10_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_D13_GPIO | GPIO_IN | PULLUP(1),
+
+	/* unknown. Not connected to anything than test pin J113 */
+	GPMI_D14_GPIO | GPIO_IN | PULLUP(1),
+
+	/* unknown. Not connected to anything than test pin J114 */
+	GPMI_D15_GPIO | GPIO_IN | PULLUP(1),
+
+	/* NAND controller (Note: There is no NAND device on the board) */
+	GPMI_D00 | PULLUP(1),
+	GPMI_D01 | PULLUP(1),
+	GPMI_D02 | PULLUP(1),
+	GPMI_D03 | PULLUP(1),
+	GPMI_D04 | PULLUP(1),
+	GPMI_D05 | PULLUP(1),
+	GPMI_D06 | PULLUP(1),
+	GPMI_D07 | PULLUP(1),
+	GPMI_CE0N,
+	GPMI_RDY0 | PULLUP(1),
+	GPMI_WRN,	/* kernel tries here with 12 mA */
+	GPMI_RDN,	/* kernel tries here with 12 mA */
+	GPMI_WPM,	/* kernel tries here with 12 mA */
+	GPMI_CLE,
+	GPMI_ALE,
+
+	/* SD card interface */
+	SSP1_DATA0 | PULLUP(1),	/* available at J201 */
+	SSP1_DATA1 | PULLUP(1),	/* available at J200 */
+	SSP1_DATA2 | PULLUP(1),	/* available at J205 */
+	SSP1_DATA3 | PULLUP(1),	/* available at J204 */
+	SSP1_SCK,		/* available at J202 */
+	SSP1_CMD | PULLUP(1),	/* available at J203 */
+	SSP1_DETECT | PULLUP(1),	/* only connected to test pin J115 */
+
+	/* other not used pins */
+	GPMI_CE1N_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_CE2N_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_RDY1_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_RDY2_GPIO | GPIO_IN | PULLUP(1),
+	GPMI_RDY3_GPIO | GPIO_IN | PULLUP(1),
+};
+
+static int falconwing_devices_init(void)
+{
+	int i;
+
+	/* initizalize gpios */
+	for (i = 0; i < ARRAY_SIZE(pad_setup); i++)
+		imx_gpio_mode(pad_setup[i]);
+
+	register_device(&sdram_dev);
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void*)(sdram_dev.map_base + 0x100));
+	armlinux_set_architecture(MACH_TYPE_CHUMBY);
+
+	return 0;
+}
+
+device_initcall(falconwing_devices_init);
+
+static struct device_d falconwing_serial_device = {
+	.name     = "stm_serial",
+	.map_base = IMX_DBGUART_BASE,
+	.size     = 8192,
+};
+
+static int falconwing_console_init(void)
+{
+	return register_device(&falconwing_serial_device);
+}
+
+console_initcall(falconwing_console_init);
+
+/** @page chumbyone Chumby Industrie's Falconwing
+
+This device is also known as "chumby one" (http://www.chumby.com/)
+
+This CPU card is based on a Freescale i.MX23 CPU. The card is shipped with:
+
+- 64 MiB synchronous dynamic RAM (DDR type)
+
+Memory layout when @b barebox is running:
+
+- 0x40000000 start of SDRAM
+- 0x40000100 start of kernel's boot parameters
+  - below malloc area: stack area
+  - below barebox: malloc area
+- 0x42000000 start of @b barebox
+
+ at section get_falconwing_binary How to get the bootloader binary image:
+
+Using the default configuration:
+
+ at verbatim
+make ARCH=arm chumbyone_defconfig
+ at endverbatim
+
+Build the bootloader binary image:
+
+ at verbatim
+make ARCH=arm CROSS_COMPILE=armv5compiler
+ at endverbatim
+
+ at note replace the armv5compiler with your ARM v5 cross compiler.
+*/
diff --git a/arch/arm/configs/chumbyone_defconfig b/arch/arm/configs/chumbyone_defconfig
new file mode 100644
index 0000000..1e158dc
--- /dev/null
+++ b/arch/arm/configs/chumbyone_defconfig
@@ -0,0 +1,224 @@
+#
+# Automatically generated make config: don't edit
+# Linux barebox version: 2010.09.0
+# Mon Oct 11 10:23:23 2010
+#
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_ARM=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_IMX is not set
+CONFIG_ARCH_STM=y
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_S3C24xx is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+
+#
+# processor features
+#
+CONFIG_ARCH_TEXT_BASE=0x42000000
+CONFIG_BOARDINFO="Chumby Falconwing"
+
+#
+# SigmaTel/Freescale i.MX System-on-Chip
+#
+CONFIG_ARCH_IMX23=y
+# CONFIG_MACH_MX23EVK is not set
+CONFIG_MACH_CHUMBY=y
+
+#
+# Board specific settings       
+#
+CONFIG_AEABI=y
+
+#
+# Arm specific settings         
+#
+CONFIG_CMD_ARM_CPUINFO=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
+CONFIG_GREGORIAN_CALENDER=y
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+CONFIG_GENERIC_GPIO=y
+
+#
+# General Settings              
+#
+CONFIG_LOCALVERSION_AUTO=y
+
+#
+# memory layout                 
+#
+CONFIG_HAVE_MMU=y
+# CONFIG_MMU is not set
+CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
+CONFIG_TEXT_BASE=0x42000000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+# CONFIG_MEMORY_LAYOUT_FIXED is not set
+CONFIG_STACK_SIZE=0x8000
+CONFIG_MALLOC_SIZE=0x400000
+CONFIG_BROKEN=y
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_PROMPT="barebox:"
+CONFIG_BAUDRATE=115200
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+# CONFIG_GLOB is not set
+CONFIG_PROMPT_HUSH_PS2="> "
+# CONFIG_HUSH_FANCY_PROMPT is not set
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+# CONFIG_MENU is not set
+# CONFIG_PASSWORD is not set
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+CONFIG_TIMESTAMP=y
+CONFIG_CONSOLE_FULL=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+# CONFIG_OF_FLAT_TREE is not set
+CONFIG_PARTITION=y
+# CONFIG_DEFAULT_ENVIRONMENT is not set
+
+#
+# Debugging                     
+#
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+# CONFIG_ENABLE_DEVICE_NOISE is not set
+
+#
+# Commands                      
+#
+
+#
+# scripting                     
+#
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TRUE=y
+CONFIG_CMD_FALSE=y
+# CONFIG_CMD_LOGIN is not set
+# CONFIG_CMD_PASSWD is not set
+
+#
+# file commands                 
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+
+#
+# console                       
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_ECHO_E=y
+
+#
+# memory                        
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_MEMINFO is not set
+# CONFIG_CMD_CRC is not set
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+
+#
+# flash                         
+#
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_UBI is not set
+
+#
+# booting                       
+#
+CONFIG_CMD_BOOTM=y
+# CONFIG_CMD_BOOTM_ZLIB is not set
+# CONFIG_CMD_BOOTM_BZLIB is not set
+# CONFIG_CMD_BOOTM_SHOW_TYPE is not set
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTU=y
+CONFIG_CMD_RESET=y
+# CONFIG_CMD_GO is not set
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_CMD_VERSION=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_DEVINFO=y
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_UNLZO is not set
+# CONFIG_NET is not set
+
+#
+# Drivers                       
+#
+
+#
+# serial drivers                
+#
+# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
+CONFIG_DRIVER_SERIAL_STM378X=y
+# CONFIG_DRIVER_SERIAL_NS16550 is not set
+
+#
+# SPI drivers                   
+#
+# CONFIG_SPI is not set
+# CONFIG_I2C is not set
+
+#
+# flash drivers                 
+#
+# CONFIG_DRIVER_CFI is not set
+# CONFIG_MTD is not set
+# CONFIG_ATA is not set
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_VIDEO is not set
+
+#
+# Filesystem support            
+#
+# CONFIG_FS_CRAMFS is not set
+CONFIG_FS_RAMFS=y
+CONFIG_FS_DEVFS=y
+CONFIG_CRC32=y
+# CONFIG_DIGEST is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_PROCESS_ESCAPE_SEQUENCE=y
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index bbdea51..021919a 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -3,9 +3,11 @@ if ARCH_STM
 config ARCH_TEXT_BASE
 	hex
 	default 0x41000000 if MACH_MX23EVK
+	default 0x42000000 if MACH_CHUMBY
 
 config BOARDINFO
 	default "Freescale i.MX23-EVK" if MACH_MX23EVK
+	default "Chumby Falconwing" if MACH_CHUMBY
 
 comment "SigmaTel/Freescale i.MX System-on-Chip"
 
@@ -28,6 +30,13 @@ config MACH_MX23EVK
 	help
 	  Say Y here if you are using the Freescale i.MX23-EVK board
 
+config MACH_CHUMBY
+	bool "Chumby Falconwing"
+	select HAVE_MMU
+	help
+	  Say Y here if you are using the "chumby one" aka falconwing from
+	  Chumby Industries
+
 endchoice
 
 endif
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Oct 11 05:06:57 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 11:06:57 +0200
Subject: [PATCH 1/4] Add the basic files for the i.MX23/i.MX28 familiy of CPUs
In-Reply-To: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
References: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286788020-14077-2-git-send-email-jbe@pengutronix.de>

These CPUs are called "i.MX", but they are of type STM378x from SigmaTel. They
do not share any devices with the other i.MX CPUs, so we need a separate
architecute directory to handle them without an ifdef hell in the native i.MX
files.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/Kconfig                             |    5 +
 arch/arm/mach-stm/Kconfig                    |   32 ++
 arch/arm/mach-stm/Makefile                   |    2 +
 arch/arm/mach-stm/clocksource-imx23.c        |   82 +++++
 arch/arm/mach-stm/imx23.c                    |   35 +++
 arch/arm/mach-stm/include/mach/clock.h       |   34 ++
 arch/arm/mach-stm/include/mach/generic.h     |   24 ++
 arch/arm/mach-stm/include/mach/gpio.h        |   29 ++
 arch/arm/mach-stm/include/mach/imx-regs.h    |   27 ++
 arch/arm/mach-stm/include/mach/imx23-regs.h  |   41 +++
 arch/arm/mach-stm/include/mach/iomux-imx23.h |  424 ++++++++++++++++++++++++++
 arch/arm/mach-stm/iomux-imx23.c              |  117 +++++++
 arch/arm/mach-stm/reset-imx23.c              |   61 ++++
 arch/arm/mach-stm/speed-imx23.c              |  280 +++++++++++++++++
 14 files changed, 1193 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-stm/Kconfig
 create mode 100644 arch/arm/mach-stm/Makefile
 create mode 100644 arch/arm/mach-stm/clocksource-imx23.c
 create mode 100644 arch/arm/mach-stm/imx23.c
 create mode 100644 arch/arm/mach-stm/include/mach/clock.h
 create mode 100644 arch/arm/mach-stm/include/mach/generic.h
 create mode 100644 arch/arm/mach-stm/include/mach/gpio.h
 create mode 100644 arch/arm/mach-stm/include/mach/imx-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/imx23-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/iomux-imx23.h
 create mode 100644 arch/arm/mach-stm/iomux-imx23.c
 create mode 100644 arch/arm/mach-stm/reset-imx23.c
 create mode 100644 arch/arm/mach-stm/speed-imx23.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fa37036..bfee8cf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -39,6 +39,10 @@ config ARCH_IMX
 	bool "Freescale iMX-based"
 	select GENERIC_GPIO
 
+config ARCH_STM
+	bool "SigmaTel/FSL iMX-based"
+	select GENERIC_GPIO
+
 config ARCH_NETX
 	bool "Hilscher NetX based"
 	select CPU_ARM926T
@@ -62,6 +66,7 @@ source arch/arm/cpu/Kconfig
 source arch/arm/mach-at91/Kconfig
 source arch/arm/mach-ep93xx/Kconfig
 source arch/arm/mach-imx/Kconfig
+source arch/arm/mach-stm/Kconfig
 source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
 source arch/arm/mach-omap/Kconfig
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
new file mode 100644
index 0000000..9858d3a
--- /dev/null
+++ b/arch/arm/mach-stm/Kconfig
@@ -0,0 +1,32 @@
+if ARCH_STM
+
+config ARCH_TEXT_BASE
+	hex
+
+config BOARDINFO
+
+comment "SigmaTel/Freescale i.MX System-on-Chip"
+
+choice
+	prompt "Freescale i.MX Processor"
+
+config ARCH_IMX23
+	bool "i.MX23"
+	select CPU_ARM926T
+
+endchoice
+
+if ARCH_IMX23
+
+choice
+	prompt "i.MX23 Board Type"
+
+endchoice
+
+endif
+
+menu "Board specific settings       "
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-stm/Makefile b/arch/arm/mach-stm/Makefile
new file mode 100644
index 0000000..59d70b6
--- /dev/null
+++ b/arch/arm/mach-stm/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o imx23.o iomux-imx23.o clocksource-imx23.o reset-imx23.o
+
diff --git a/arch/arm/mach-stm/clocksource-imx23.c b/arch/arm/mach-stm/clocksource-imx23.c
new file mode 100644
index 0000000..7c0268c
--- /dev/null
+++ b/arch/arm/mach-stm/clocksource-imx23.c
@@ -0,0 +1,82 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#define TIMROTCTRL 0x00
+#define TIMCTRL1 0x40
+#define TIMCTRL1_SET 0x44
+#define TIMCTRL1_CLR 0x48
+#define TIMCTRL1_TOG 0x4c
+# define TIMCTRL_RELOAD (1 << 6)
+# define TIMCTRL_UPDATE (1 << 7)
+# define TIMCTRL_PRESCALE(x) ((x & 0x3) << 4)
+# define TIMCTRL_SELECT(x) (x & 0xf)
+#define TIMCOUNT1 0x50
+
+static const unsigned long timer_base = IMX_TIM1_BASE;
+
+#define CLOCK_TICK_RATE (32000)
+
+static uint64_t imx23_clocksource_read(void)
+{
+	/* only the upper bits are the valid */
+	return ~(readl(timer_base + TIMCOUNT1) >> 16);
+}
+
+static struct clocksource cs = {
+	.read	= imx23_clocksource_read,
+	.mask	= 0x0000ffff,
+	.shift	= 10,
+};
+
+static int imx23_clocksource_clock_change(struct notifier_block *nb, unsigned long event, void *data)
+{
+	cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE/*imx_get_xclk()*/, cs.shift);
+	return 0;
+}
+
+static struct notifier_block imx23_clock_notifier = {
+	.notifier_call = imx23_clocksource_clock_change,
+};
+
+static int clocksource_init(void)
+{
+	/* enable the whole timer block */
+	writel(0x3e000000, timer_base + TIMROTCTRL);
+	/* setup general purpose timer 1 */
+	writel(0x00000000, timer_base + TIMCTRL1);
+	writel(TIMCTRL_UPDATE, timer_base + TIMCTRL1);
+	writel(0x0000ffff, timer_base + TIMCOUNT1);
+
+	writel(TIMCTRL_UPDATE | TIMCTRL_RELOAD | TIMCTRL_PRESCALE(0) | TIMCTRL_SELECT(8), timer_base + TIMCTRL1);
+	cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE/*imx_get_xclk()*/, cs.shift);
+	init_clock(&cs);
+
+	clock_register_client(&imx23_clock_notifier);
+	return 0;
+}
+
+core_initcall(clocksource_init);
diff --git a/arch/arm/mach-stm/imx23.c b/arch/arm/mach-stm/imx23.c
new file mode 100644
index 0000000..14a4249
--- /dev/null
+++ b/arch/arm/mach-stm/imx23.c
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+
+extern void imx_dump_clocks(void);
+
+static int do_clocks(struct command *cmdtp, int argc, char *argv[])
+{
+	imx_dump_clocks();
+
+	return 0;
+}
+
+BAREBOX_CMD_START(dump_clocks)
+	.cmd		= do_clocks,
+	.usage		= "show clock frequencies",
+BAREBOX_CMD_END
diff --git a/arch/arm/mach-stm/include/mach/clock.h b/arch/arm/mach-stm/include/mach/clock.h
new file mode 100644
index 0000000..0e1a6d6
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/clock.h
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef ASM_ARCH_CLOCK_IMX23_H
+#define ASM_ARCH_CLOCK_IMX23_H
+
+unsigned imx_get_mpllclk(void);
+unsigned imx_get_emiclk(void);
+unsigned imx_get_ioclk(void);
+unsigned imx_get_armclk(void);
+unsigned imx_get_hclk(void);
+unsigned imx_get_xclk(void);
+unsigned imx_get_sspclk(unsigned);
+unsigned imx_set_sspclk(unsigned, unsigned, int);
+unsigned imx_set_ioclk(unsigned);
+
+#endif /* ASM_ARCH_CLOCK_IMX23_H */
+
diff --git a/arch/arm/mach-stm/include/mach/generic.h b/arch/arm/mach-stm/include/mach/generic.h
new file mode 100644
index 0000000..3a552a8
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/generic.h
@@ -0,0 +1,24 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifdef CONFIG_ARCH_IMX23
+# define cpu_is_mx23()	(1)
+#else
+# define cpu_is_mx23()	(0)
+#endif
diff --git a/arch/arm/mach-stm/include/mach/gpio.h b/arch/arm/mach-stm/include/mach/gpio.h
new file mode 100644
index 0000000..fa8263c
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/gpio.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_MACH_GPIO_H
+#define __ASM_MACH_GPIO_H
+
+#if defined CONFIG_ARCH_IMX23
+# include <mach/iomux-imx23.h>
+#endif
+
+void imx_gpio_mode(unsigned);
+
+#endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-stm/include/mach/imx-regs.h b/arch/arm/mach-stm/include/mach/imx-regs.h
new file mode 100644
index 0000000..40dc742
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/imx-regs.h
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _IMX_REGS_H
+# define _IMX_REGS_H
+
+#if defined CONFIG_ARCH_IMX23
+# include <mach/imx23-regs.h>
+#endif
+
+#endif /* _IMX_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/imx23-regs.h b/arch/arm/mach-stm/include/mach/imx23-regs.h
new file mode 100644
index 0000000..89ca453
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/imx23-regs.h
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MX23_REGS_H
+#define __ASM_ARCH_MX23_REGS_H
+
+/*
+ * sanity check
+ */
+#ifndef _IMX_REGS_H
+# error "Please do not include directly. Use imx-regs.h instead."
+#endif
+
+#define IMX_MEMORY_BASE		0x40000000
+#define IMX_UART1_BASE		0x8006c000
+#define IMX_UART2_BASE		0x8006e000
+#define IMX_DBGUART_BASE	0x80070000
+#define IMX_TIM1_BASE		0x80068000
+#define IMX_IOMUXC_BASE		0x80018000
+#define IMX_WDT_BASE		0x8005c000
+#define IMX_CCM_BASE		0x80040000
+#define IMX_I2C1_BASE		0x80058000
+#define IMX_SSP1_BASE		0x80010000
+#define IMX_SSP2_BASE		0x80034000
+
+#endif /* __ASM_ARCH_MX23_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/iomux-imx23.h b/arch/arm/mach-stm/include/mach/iomux-imx23.h
new file mode 100644
index 0000000..bebaf56
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/iomux-imx23.h
@@ -0,0 +1,424 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/* 3322222222221111111111
+ * 10987654321098765432109876543210
+ *                              ^^^_ Register Number
+ *                          ^^^^____ Bit offset
+ *                        ^^________ Function
+ *                       ^__________ Drive strength feature present
+ *                      ^___________ Pull up / bit keeper present
+ *                    ^^____________ Drive strength setting
+ *                   ^______________ Pull up / bit keeper setting
+ *                  ^_______________ Voltage select present
+ *                 ^________________ Voltage selection
+ *             ^____________________ direction if enabled as GPIO (1 = output)
+ *            ^_____________________ initial output value if enabled as GPIO and configured as output
+ */
+#ifndef __ASM_MACH_IOMUX_H
+#define __ASM_MACH_IOMUX_H
+
+/* control pad's function */
+#define FBIT_SHIFT (3)
+#define PORTF(bank,bit)	(((bit) << FBIT_SHIFT) | (bank))
+#define GET_PORTF(x) ((x) & 0x7)
+#define GET_FBITPOS(x) (((x) >> FBIT_SHIFT) & 0xf)
+#define GET_GPIO_NO(x) ((GET_PORTF(x) << 4) + GET_FBITPOS(m))
+#define FUNC_SHIFT 7
+#define FUNC(x)	((x) << FUNC_SHIFT)
+#define GET_FUNC(x) (((x) >> FUNC_SHIFT) & 3)
+#define IS_GPIO (3)
+
+/* control pad's GPIO feature if enabled */
+#define GPIO_OUT (1 << 19)
+#define GPIO_VALUE(x) ((x) << 20)
+#define GPIO_IN (0 << 19)
+#define GET_GPIODIR(x) (!!((x) & (1 << 19)))
+#define GET_GPIOVAL(x) (!!((x) & (1 << 20)))
+
+/* control pad's drive strength */
+#define SE (1 << 9)
+#define SE_PRESENT(x) (!!((x) & SE))
+#define STRENGTH(x) ((x) << 11)
+#define S4MA 0	/* used to define a 4 mA drive strength */
+#define S8MA 1	/* used to define a 8 mA drive strength */
+#define S12MA 2	/* used to define a 12 mA drive strength */
+#define S16MA 3	/* used to define a 16 mA drive strength, not all pads can drive this current! */
+#define GET_STRENGTH(x) (((x) >> 11) & 0x3)
+
+/* control pad's pull up / bit keeper feature */
+#define PE (1 << 10)
+#define PE_PRESENT(x) (!!((x) & PE))
+#define PULLUP(x) ((x) << 13)
+#define GET_PULLUP(x) (!!((x) & (1 << 13)))
+
+/* control pad's voltage feature */
+#define VE (1 << 14)
+#define VE_PRESENT(x) (!!((x) & VE))
+#define VE_1_8V (0 << 15)
+#define VE_2_5V (0 << 15) /* don't ask my why, RTFM */
+#define GET_VOLTAGE(x) (!!((x) & (1 << 15)))
+
+/* Bank 0, pins 0 ... 15, GPIO pins 0 ... 15 */
+#define GPMI_D15		(FUNC(0) | PORTF(0, 15) | SE | PE)
+#define GPMI_D15_AUART2_TX	(FUNC(1) | PORTF(0, 15) | SE | PE)
+#define GPMI_D15_GPMI_CE3N	(FUNC(2) | PORTF(0, 15) | SE | PE)
+#define GPMI_D15_GPIO		(FUNC(3) | PORTF(0, 15) | SE | PE)
+#define GPMI_D14		(FUNC(0) | PORTF(0, 14) | SE)
+#define GPMI_D14_AUART2_RX	(FUNC(1) | PORTF(0, 14) | SE)
+#define GPMI_D14_GPIO		(FUNC(3) | PORTF(0, 14) | SE)
+#define GPMI_D13		(FUNC(0) | PORTF(0, 13) | SE)
+#define GPMI_D13_LCD_D23	(FUNC(1) | PORTF(0, 13) | SE)
+#define GPMI_D13_GPIO		(FUNC(3) | PORTF(0, 13) | SE)
+#define GPMI_D12		(FUNC(0) | PORTF(0, 12) | SE)
+#define GPMI_D12_LCD_D22	(FUNC(1) | PORTF(0, 12) | SE)
+#define GPMI_D12_GPIO		(FUNC(3) | PORTF(0, 12) | SE)
+#define GPMI_D11		(FUNC(0) | PORTF(0, 11) | SE | PE)
+#define GPMI_D11_LCD_D21	(FUNC(1) | PORTF(0, 11) | SE | PE)
+#define GPMI_D11_SSP1_D7	(FUNC(2) | PORTF(0, 11) | SE | PE)
+#define GPMI_D11_GPIO		(FUNC(3) | PORTF(0, 11) | SE | PE)
+#define GPMI_D10		(FUNC(0) | PORTF(0, 10) | SE | PE)
+#define GPMI_D10_LCD_D20	(FUNC(1) | PORTF(0, 10) | SE | PE)
+#define GPMI_D10_SSP1_D6	(FUNC(2) | PORTF(0, 10) | SE | PE)
+#define GPMI_D10_GPIO		(FUNC(3) | PORTF(0, 10) | SE | PE)
+#define GPMI_D09		(FUNC(0) | PORTF(0, 9) | SE | PE)
+#define GPMI_D09_LCD_D19	(FUNC(1) | PORTF(0, 9) | SE | PE)
+#define GPMI_D09_SSP1_D5	(FUNC(2) | PORTF(0, 9) | SE | PE)
+#define GPMI_D09_GPIO		(FUNC(3) | PORTF(0, 9) | SE | PE)
+#define GPMI_D08		(FUNC(0) | PORTF(0, 8) | SE | PE)
+#define GPMI_D08_LCD_D18	(FUNC(1) | PORTF(0, 8) | SE | PE)
+#define GPMI_D08_SSP1_D4	(FUNC(2) | PORTF(0, 8) | SE | PE)
+#define GPMI_D08_GPIO		(FUNC(3) | PORTF(0, 8) | SE | PE)
+#define GPMI_D07		(FUNC(0) | PORTF(0, 7) | SE | PE)
+#define GPMI_D07_LCD_D15	(FUNC(1) | PORTF(0, 7) | SE | PE)
+#define GPMI_D07_SSP2_D7	(FUNC(2) | PORTF(0, 7) | SE | PE)
+#define GPMI_D07_GPIO		(FUNC(3) | PORTF(0, 7) | SE | PE)
+#define GPMI_D06		(FUNC(0) | PORTF(0, 6) | SE | PE)
+#define GPMI_D06_LCD_D14	(FUNC(1) | PORTF(0, 6) | SE | PE)
+#define GPMI_D06_SSP2_D6	(FUNC(2) | PORTF(0, 6) | SE | PE)
+#define GPMI_D06_GPIO		(FUNC(3) | PORTF(0, 6) | SE | PE)
+#define GPMI_D05		(FUNC(0) | PORTF(0, 5) | SE | PE)
+#define GPMI_D05_LCD_D13	(FUNC(1) | PORTF(0, 5) | SE | PE)
+#define GPMI_D05_SSP2_D5	(FUNC(2) | PORTF(0, 5) | SE | PE)
+#define GPMI_D05_GPIO		(FUNC(3) | PORTF(0, 5) | SE | PE)
+#define GPMI_D04		(FUNC(0) | PORTF(0, 4) | SE | PE)
+#define GPMI_D04_LCD_D12	(FUNC(1) | PORTF(0, 4) | SE | PE)
+#define GPMI_D04_SSP2_D4	(FUNC(2) | PORTF(0, 4) | SE | PE)
+#define GPMI_D04_GPIO		(FUNC(3) | PORTF(0, 4) | SE | PE)
+#define GPMI_D03		(FUNC(0) | PORTF(0, 3) | SE | PE)
+#define GPMI_D03_LCD_D11	(FUNC(1) | PORTF(0, 3) | SE | PE)
+#define GPMI_D03_SSP2_D3	(FUNC(2) | PORTF(0, 3) | SE | PE)
+#define GPMI_D03_GPIO		(FUNC(3) | PORTF(0, 3) | SE | PE)
+#define GPMI_D02		(FUNC(0) | PORTF(0, 2) | SE | PE)
+#define GPMI_D02_LCD_D10	(FUNC(1) | PORTF(0, 2) | SE | PE)
+#define GPMI_D02_SSP2_D2	(FUNC(2) | PORTF(0, 2) | SE | PE)
+#define GPMI_D02_GPIO		(FUNC(3) | PORTF(0, 2) | SE | PE)
+#define GPMI_D01		(FUNC(0) | PORTF(0, 1) | SE | PE)
+#define GPMI_D01_LCD_D9		(FUNC(1) | PORTF(0, 1) | SE | PE)
+#define GPMI_D01_SSP2_D1	(FUNC(2) | PORTF(0, 1) | SE | PE)
+#define GPMI_D01_GPIO		(FUNC(3) | PORTF(0, 1) | SE | PE)
+#define GPMI_D00		(FUNC(0) | PORTF(0, 0) | SE | PE)
+#define GPMI_D00_LCD_D8		(FUNC(1) | PORTF(0, 0) | SE | PE)
+#define GPMI_D00_SSP2_D0	(FUNC(2) | PORTF(0, 0) | SE | PE)
+#define GPMI_D00_GPIO		(FUNC(3) | PORTF(0, 0) | SE | PE)
+
+/* Bank 0, pins 16 ... 31 GPIO pins 16 ... 31 */
+#define I2C_SDA			(FUNC(0) | PORTF(1, 15) | SE)
+#define I2C_SDA_GPMI_CE2N	(FUNC(1) | PORTF(1, 15) | SE)
+#define I2C_SDA_AUART1_RX	(FUNC(2) | PORTF(1, 15) | SE)
+#define I2C_SDA_GPIO		(FUNC(3) | PORTF(1, 15) | SE)
+#define I2C_CLK			(FUNC(0) | PORTF(1, 14) | SE | PE)
+#define I2C_CLK_GPMI_RDY2	(FUNC(1) | PORTF(1, 14) | SE | PE)
+#define I2C_CLK_AUART1_TX	(FUNC(2) | PORTF(1, 14) | SE | PE)
+#define I2C_CLK_GPIO		(FUNC(3) | PORTF(1, 14) | SE | PE)
+#define AUART1_TX		(FUNC(0) | PORTF(1, 13) | SE | PE)
+#define AUART1_TX_SSP1_D7	(FUNC(2) | PORTF(1, 13) | SE | PE)
+#define AUART1_TX_GPIO		(FUNC(3) | PORTF(1, 13) | SE | PE)
+#define AUART1_RX		(FUNC(0) | PORTF(1, 12) | SE | PE)
+#define AUART1_RX_SSP1_D6	(FUNC(2) | PORTF(1, 12) | SE | PE)
+#define AUART1_RX_GPIO		(FUNC(3) | PORTF(1, 12) | SE | PE)
+#define AUART1_RTS		(FUNC(0) | PORTF(1, 11) | SE | PE)
+#define AUART1_RTS_SSP1_D5	(FUNC(2) | PORTF(1, 11) | SE | PE)
+#define AUART1_RTS_GPIO		(FUNC(3) | PORTF(1, 11) | SE | PE)
+#define AUART1_CTS		(FUNC(0) | PORTF(1, 10) | SE | PE)
+#define AUART1_CTS_SSP1_D4	(FUNC(2) | PORTF(1, 10) | SE | PE)
+#define AUART1_CTS_GPIO		(FUNC(3) | PORTF(1, 10) | SE | PE)
+#define GPMI_RDN		(FUNC(0) | PORTF(1, 9) | SE)
+#define GPMI_RDN_GPIO		(FUNC(3) | PORTF(1, 9) | SE)
+#define GPMI_WRN		(FUNC(0) | PORTF(1, 8) | SE)
+#define GPMI_WRN_SSP2_SCK	(FUNC(2) | PORTF(1, 8) | SE)
+#define GPMI_WRN_GPIO		(FUNC(3) | PORTF(1, 8) | SE)
+#define GPMI_WPM		(FUNC(0) | PORTF(1, 7) | SE)
+#define GPMI_WPM_GPIO		(FUNC(3) | PORTF(1, 7) | SE)
+#define GPMI_RDY3		(FUNC(0) | PORTF(1, 6) | SE | PE)
+#define GPMI_RDY3_GPIO		(FUNC(3) | PORTF(1, 6) | SE | PE)
+#define GPMI_RDY2		(FUNC(0) | PORTF(1, 5) | SE | PE)
+#define GPMI_RDY2_GPIO		(FUNC(3) | PORTF(1, 5) | SE | PE)
+#define GPMI_RDY1		(FUNC(0) | PORTF(1, 4) | SE | PE)
+#define GPMI_RDY1_SSP2_CMD	(FUNC(2) | PORTF(1, 4) | SE | PE)
+#define GPMI_RDY1_GPIO		(FUNC(3) | PORTF(1, 4) | SE | PE)
+#define GPMI_RDY0		(FUNC(0) | PORTF(1, 3) | SE | PE)
+#define GPMI_RDY0_SSP2_DETECT	(FUNC(2) | PORTF(1, 3) | SE | PE)
+#define GPMI_RDY0_GPIO		(FUNC(3) | PORTF(1, 3) | SE | PE)
+#define GPMI_CE2N		(FUNC(0) | PORTF(1, 2) | SE | PE)
+#define GPMI_CE2N_GPIO		(FUNC(3) | PORTF(1, 2) | SE | PE)
+#define GPMI_ALE		(FUNC(0) | PORTF(1, 1) | SE)
+#define GPMI_ALE_LCD_D17	(FUNC(1) | PORTF(1, 1) | SE)
+#define GPMI_ALE_GPIO		(FUNC(3) | PORTF(1, 1) | SE)
+#define GPMI_CLE		(FUNC(0) | PORTF(1, 0) | SE)
+#define GPMI_CLE_LCD_D16	(FUNC(1) | PORTF(1, 1) | SE)
+#define GPMI_CLE_GPIO		(FUNC(3) | PORTF(1, 0) | SE)
+
+/* Bank 1, pins 0 ... 15 GPIO pins 32 ... 47 */
+#define LCD_D15			(FUNC(0) | PORTF(2, 15) | SE)
+#define LCD_D15_ETM_DA7		(FUNC(1) | PORTF(2, 15) | SE)
+#define LCD_D15_SAIF1_SDATA1	(FUNC(2) | PORTF(2, 15) | SE)
+#define LCD_D15_GPIO		(FUNC(3) | PORTF(2, 15) | SE)
+#define LCD_D14			(FUNC(0) | PORTF(2, 14) | SE)
+#define LCD_D14_ETM_DA6		(FUNC(1) | PORTF(2, 14) | SE)
+#define LCD_D14_SAIF1_SDATA2	(FUNC(2) | PORTF(2, 14) | SE)
+#define LCD_D14_GPIO		(FUNC(3) | PORTF(2, 14) | SE)
+#define LCD_D13			(FUNC(0) | PORTF(2, 13) | SE)
+#define LCD_D13_ETM_DA5		(FUNC(1) | PORTF(2, 13) | SE)
+#define LCD_D13_SAIF2_SDATA2	(FUNC(2) | PORTF(2, 13) | SE)
+#define LCD_D13_GPIO		(FUNC(3) | PORTF(2, 13) | SE)
+#define LCD_D12			(FUNC(0) | PORTF(2, 12) | SE)
+#define LCD_D12_ETM_DA4		(FUNC(1) | PORTF(2, 12) | SE)
+#define LCD_D12_SAIF2_SDATA1	(FUNC(2) | PORTF(2, 12) | SE)
+#define LCD_D12_GPIO		(FUNC(3) | PORTF(2, 12) | SE)
+#define LCD_D11			(FUNC(0) | PORTF(2, 11) | SE)
+#define LCD_D11_ETM_DA3		(FUNC(1) | PORTF(2, 11) | SE)
+#define LCD_D11_SAIF_LRCLK	(FUNC(2) | PORTF(2, 11) | SE)
+#define LCD_D11_GPIO		(FUNC(3) | PORTF(2, 11) | SE)
+#define LCD_D10			(FUNC(0) | PORTF(2, 10) | SE)
+#define LCD_D10_ETM_DA2		(FUNC(1) | PORTF(2, 10) | SE)
+#define LCD_D10_SAIF_BITCLK	(FUNC(2) | PORTF(2, 10) | SE)
+#define LCD_D10_GPIO		(FUNC(3) | PORTF(2, 10) | SE)
+#define LCD_D9			(FUNC(0) | PORTF(2, 9) | SE)
+#define LCD_D9_ETM_DA1		(FUNC(1) | PORTF(2, 9) | SE)
+#define LCD_D9_SAIF1_SDATA0	(FUNC(2) | PORTF(2, 9) | SE)
+#define LCD_D9_GPIO		(FUNC(3) | PORTF(2, 9) | SE)
+#define LCD_D8			(FUNC(0) | PORTF(2, 8) | SE)
+#define LCD_D8_ETM_DA0		(FUNC(1) | PORTF(2, 8) | SE)
+#define LCD_D8_SAIF2_SDATA0	(FUNC(2) | PORTF(2, 8) | SE)
+#define LCD_D8_GPIO		(FUNC(3) | PORTF(2, 8) | SE)
+#define LCD_D7			(FUNC(0) | PORTF(2, 7) | SE)
+#define LCD_D7_ETM_DA15		(FUNC(1) | PORTF(2, 7) | SE)
+#define LCD_D7_GPIO		(FUNC(3) | PORTF(2, 7) | SE)
+#define LCD_D6			(FUNC(0) | PORTF(2, 6) | SE)
+#define LCD_D6_ETM_DA14		(FUNC(1) | PORTF(2, 6) | SE)
+#define LCD_D6_GPIO		(FUNC(3) | PORTF(2, 6) | SE)
+#define LCD_D5			(FUNC(0) | PORTF(2, 5) | SE)
+#define LCD_D5_ETM_DA13		(FUNC(1) | PORTF(2, 5) | SE)
+#define LCD_D5_GPIO		(FUNC(3) | PORTF(2, 5) | SE)
+#define LCD_D4			(FUNC(0) | PORTF(2, 4) | SE)
+#define LCD_D4_ETM_DA12		(FUNC(1) | PORTF(2, 4) | SE)
+#define LCD_D4_GPIO		(FUNC(3) | PORTF(2, 4) | SE)
+#define LCD_D3			(FUNC(0) | PORTF(2, 3) | SE)
+#define LCD_D3_ETM_DA11		(FUNC(1) | PORTF(2, 3) | SE)
+#define LCD_D3_GPIO		(FUNC(3) | PORTF(2, 3) | SE)
+#define LCD_D2			(FUNC(0) | PORTF(2, 2) | SE)
+#define LCD_D2_ETM_DA10		(FUNC(1) | PORTF(2, 2) | SE)
+#define LCD_D2_GPIO		(FUNC(3) | PORTF(2, 2) | SE)
+#define LCD_D1			(FUNC(0) | PORTF(2, 1) | SE)
+#define LCD_D1_ETM_DA9		(FUNC(1) | PORTF(2, 1) | SE)
+#define LCD_D1_GPIO		(FUNC(3) | PORTF(2, 1) | SE)
+#define LCD_D0			(FUNC(0) | PORTF(2, 0) | SE)
+#define LCD_D0_ETM_DA8		(FUNC(1) | PORTF(2, 0) | SE)
+#define LCD_D0_GPIO		(FUNC(3) | PORTF(2, 0) | SE)
+
+/* Bank 1, pins 16 ... 30 GPIO pins 48 ... 63 */
+#define PWM4			(FUNC(0) | PORTF(3, 14) | SE)
+#define PWM4_ETM_CLK		(FUNC(1) | PORTF(3, 14) | SE)
+#define PWM4_AUART1_RTS		(FUNC(2) | PORTF(3, 14) | SE)
+#define PWM4_GPIO		(FUNC(3) | PORTF(3, 14) | SE)
+#define PWM3			(FUNC(0) | PORTF(3, 13) | SE)
+#define PWM3_ETM_TCTL		(FUNC(1) | PORTF(3, 13) | SE)
+#define PWM3_AUART1_CTS		(FUNC(2) | PORTF(3, 13) | SE)
+#define PWM3_GPIO		(FUNC(3) | PORTF(3, 13) | SE)
+#define PWM2			(FUNC(0) | PORTF(3, 12) | SE | PE)
+#define PWM2_GPMI_READY3	(FUNC(1) | PORTF(3, 12) | SE | PE)
+#define PWM2_GPIO		(FUNC(3) | PORTF(3, 12) | SE | PE)
+#define PWM1			(FUNC(0) | PORTF(3, 11) | SE)
+#define PWM1_TIMROT2		(FUNC(1) | PORTF(3, 11) | SE)
+#define PWM1_DUART_TX		(FUNC(2) | PORTF(3, 11) | SE)
+#define PWM1_GPIO		(FUNC(3) | PORTF(3, 11) | SE)
+#define PWM0			(FUNC(0) | PORTF(3, 10) | SE)
+#define PWM0_TIMROT1		(FUNC(1) | PORTF(3, 10) | SE)
+#define PWM0_DUART_RX		(FUNC(2) | PORTF(3, 10) | SE)
+#define PWM0_GPIO		(FUNC(3) | PORTF(3, 10) | SE)
+#define LCD_VSYNC		(FUNC(0) | PORTF(3, 9) | SE)
+#define LCD_VSYNC_LCD_BUSY	(FUNC(1) | PORTF(3, 9) | SE)
+#define LCD_VSYNC_GPIO		(FUNC(3) | PORTF(3, 9) | SE)
+#define LCD_HSYNC		(FUNC(0) | PORTF(3, 8) | SE)
+#define LCD_HSYNC_I2C_SD	(FUNC(1) | PORTF(3, 8) | SE)
+#define LCD_HSYNC_GPIO		(FUNC(3) | PORTF(3, 8) | SE)
+#define LCD_ENABE		(FUNC(0) | PORTF(3, 7) | SE)
+#define LCD_ENABE_I2C_CLK	(FUNC(1) | PORTF(3, 7) | SE)
+#define LCD_ENABE_GPIO		(FUNC(3) | PORTF(3, 7) | SE)
+#define LCD_DOTCLOCK		(FUNC(0) | PORTF(3, 6) | SE | PE)
+#define LCD_DOTCLOCK_GPMI_READY3 (FUNC(1) | PORTF(3, 6) | SE | PE)
+#define LCD_DOTCLOCK_GPIO	(FUNC(3) | PORTF(3, 6) | SE | PE)
+#define LCD_CS			(FUNC(0) | PORTF(3, 5) | SE)
+#define LCD_CS_GPIO		(FUNC(3) | PORTF(3, 5) | SE)
+#define LCD_WR			(FUNC(0) | PORTF(3, 4) | SE)
+#define LCD_WR_GPIO		(FUNC(3) | PORTF(3, 4) | SE)
+#define LCD_RS			(FUNC(0) | PORTF(3, 3) | SE)
+#define LCD_RS_ETM_TCLK		(FUNC(1) | PORTF(3, 3) | SE)
+#define LCD_RS_GPIO		(FUNC(3) | PORTF(3, 3) | SE)
+#define LCD_RESET		(FUNC(0) | PORTF(3, 2) | SE | PE)
+#define LCD_RESET_ETM_TCTL	(FUNC(1) | PORTF(3, 2) | SE | PE)
+#define LCD_RESET_GPMI_CE3N	(FUNC(2) | PORTF(3, 2) | SE | PE)
+#define LCD_RESET_GPIO		(FUNC(3) | PORTF(3, 2) | SE | PE)
+#define LCD_D17			(FUNC(0) | PORTF(3, 1) | SE)
+#define LCD_D17_GPIO		(FUNC(3) | PORTF(3, 1) | SE)
+#define LCD_D16			(FUNC(0) | PORTF(3, 0) | SE)
+#define LCD_D16_SAIF_ALT_BITCLK	(FUNC(2) | PORTF(3, 0) | SE)
+#define LCD_D16_GPIO		(FUNC(3) | PORTF(3, 0) | SE)
+
+/* Bank 2, pins 0 ... 15 GPIO pins 64 ... 79 */
+#define EMI_A6			(FUNC(0) | PORTF(4, 15) | SE | VE)
+#define EMI_A6_GPIO		(FUNC(3) | PORTF(4, 15) | SE | VE)
+#define EMI_A5			(FUNC(0) | PORTF(4, 14) | SE | VE)
+#define EMI_A5_GPIO		(FUNC(3) | PORTF(4, 14) | SE | VE)
+#define EMI_A4			(FUNC(0) | PORTF(4, 13) | SE | VE)
+#define EMI_A4_GPIO		(FUNC(3) | PORTF(4, 13) | SE | VE)
+#define EMI_A3			(FUNC(0) | PORTF(4, 12) | SE | VE)
+#define EMI_A3_GPIO		(FUNC(3) | PORTF(4, 12) | SE | VE)
+#define EMI_A2			(FUNC(0) | PORTF(4, 11) | SE | VE)
+#define EMI_A2_GPIO		(FUNC(3) | PORTF(4, 11) | SE | VE)
+#define EMI_A1			(FUNC(0) | PORTF(4, 10) | SE | VE)
+#define EMI_A1_GPIO		(FUNC(3) | PORTF(4, 10) | SE | VE)
+#define EMI_A0			(FUNC(0) | PORTF(4, 9) | SE | VE)
+#define EMI_A0_GPIO		(FUNC(3) | PORTF(4, 9) | SE | VE)
+#define ROTARYB			(FUNC(0) | PORTF(4, 8) | SE | PE)
+#define ROTARYB_AUART2_CTS	(FUNC(1) | PORTF(4, 8) | SE | PE)
+#define ROTARYB_GPMI_CE3N	(FUNC(2) | PORTF(4, 8) | SE | PE)
+#define ROTARYB_GPIO		(FUNC(3) | PORTF(4, 8) | SE | PE)
+#define ROTARYA			(FUNC(0) | PORTF(4, 7) | SE)
+#define ROTARYA_AUART2_RTS	(FUNC(1) | PORTF(4, 7) | SE)
+#define ROTARYA_SPDIF		(FUNC(2) | PORTF(4, 7) | SE)
+#define ROTARYA_GPIO		(FUNC(3) | PORTF(4, 7) | SE)
+#define SSP1_SCK		(FUNC(0) | PORTF(4, 6) | SE)
+#define SSP1_SCK_ALT_JTAG_TRST	(FUNC(2) | PORTF(4, 6) | SE)
+#define SSP1_SCK_GPIO		(FUNC(3) | PORTF(4, 6) | SE)
+#define SSP1_DATA3		(FUNC(0) | PORTF(4, 5) | SE | PE)
+#define SSP1_DATA3_ALT_JTAG_TMS	(FUNC(2) | PORTF(4, 5) | SE | PE)
+#define SSP1_DATA3_GPIO		(FUNC(3) | PORTF(4, 5) | SE | PE)
+#define SSP1_DATA2		(FUNC(0) | PORTF(4, 4) | SE | PE)
+#define SSP1_DATA2_I2C_SD	(FUNC(1) | PORTF(4, 4) | SE | PE)
+#define SSP1_DATA2_ALT_JTAG_RTCK (FUNC(2) | PORTF(4, 4) | SE | PE)
+#define SSP1_DATA2_GPIO		(FUNC(3) | PORTF(4, 4) | SE | PE)
+#define SSP1_DATA1		(FUNC(0) | PORTF(4, 3) | SE | PE)
+#define SSP1_DATA1_I2C_CLK	(FUNC(1) | PORTF(4, 3) | SE | PE)
+#define SSP1_DATA1_ALT_JTAG_TCK	(FUNC(2) | PORTF(4, 3) | SE | PE)
+#define SSP1_DATA1_GPIO		(FUNC(3) | PORTF(4, 3) | SE | PE)
+#define SSP1_DATA0		(FUNC(0) | PORTF(4, 2) | SE | PE)
+#define SSP1_DATA0_ALT_JTAG_TDI	(FUNC(2) | PORTF(4, 2) | SE | PE)
+#define SSP1_DATA0_GPIO		(FUNC(3) | PORTF(4, 2) | SE | PE)
+#define SSP1_DETECT		(FUNC(0) | PORTF(4, 1) | SE | PE)
+#define SSP1_DETECT_GPMI_CE3N	(FUNC(1) | PORTF(4, 1) | SE | PE)
+#define SSP1_DETECT_USB_ID	(FUNC(2) | PORTF(4, 1) | SE | PE)
+#define SSP1_DETECT_GPIO	(FUNC(3) | PORTF(4, 1) | SE | PE)
+#define SSP1_CMD		(FUNC(0) | PORTF(4, 0) | SE | PE)
+#define SSP1_CMD_JTAG_TDO	(FUNC(2) | PORTF(4, 0) | SE | PE)
+#define SSP1_CMD_GPIO		(FUNC(3) | PORTF(4, 0) | SE | PE)
+
+/* Bank 2, pins 16 ... 31 GPIO pins 80 ... 95 */
+#define EMI_WEN			(FUNC(0) | PORTF(5, 15) | SE | VE)
+#define EMI_WEN_GPIO		(FUNC(3) | PORTF(5, 15) | SE | VE)
+#define EMI_RASN		(FUNC(0) | PORTF(5, 14) | SE | VE)
+#define EMI_RASN_GPIO		(FUNC(3) | PORTF(5, 14) | SE | VE)
+#define EMI_CKE			(FUNC(0) | PORTF(5, 13) | SE | VE)
+#define EMI_CKE_GPIO		(FUNC(3) | PORTF(5, 13) | SE | VE)
+#define GPMI_CE0N		(FUNC(0) | PORTF(5, 12) | SE)
+#define GPMI_CE0N_GPIO		(FUNC(3) | PORTF(5, 12) | SE)
+#define GPMI_CE1N		(FUNC(0) | PORTF(5, 11) | SE | PE)
+#define GPMI_CE1N_GPIO		(FUNC(3) | PORTF(5, 11) | SE | PE)
+#define EMI_CE1N		(FUNC(0) | PORTF(5, 10) | SE | VE | PE)
+#define EMI_CE1N_GPIO		(FUNC(3) | PORTF(5, 10) | SE | VE | PE)
+#define EMI_CE0N		(FUNC(0) | PORTF(5, 9) | SE | VE)
+#define EMI_CE0N_GPIO		(FUNC(3) | PORTF(5, 9) | SE | VE)
+#define EMI_CASN		(FUNC(0) | PORTF(5, 8) | SE | VE)
+#define EMI_CASN_GPIO		(FUNC(3) | PORTF(5, 8) | SE | VE)
+#define EMI_BA1			(FUNC(0) | PORTF(5, 7) | SE | VE)
+#define EMI_BA1_GPIO		(FUNC(3) | PORTF(5, 7) | SE | VE)
+#define EMI_BA0			(FUNC(0) | PORTF(5, 6) | SE | VE)
+#define EMI_BA0_GPIO		(FUNC(3) | PORTF(5, 6) | SE | VE)
+#define EMI_A12			(FUNC(0) | PORTF(5, 5) | SE | VE)
+#define EMI_A12_GPIO		(FUNC(3) | PORTF(5, 5) | SE | VE)
+#define EMI_A11			(FUNC(0) | PORTF(5, 4) | SE | VE)
+#define EMI_A11_GPIO		(FUNC(3) | PORTF(5, 4) | SE | VE)
+#define EMI_A10			(FUNC(0) | PORTF(5, 3) | SE | VE)
+#define EMI_A10_GPIO		(FUNC(3) | PORTF(5, 3) | SE | VE)
+#define EMI_A9			(FUNC(0) | PORTF(5, 2) | SE | VE)
+#define EMI_A9_GPIO		(FUNC(3) | PORTF(5, 2) | SE | VE)
+#define EMI_A8			(FUNC(0) | PORTF(5, 1) | SE | VE)
+#define EMI_A8_GPIO		(FUNC(3) | PORTF(5, 1) | SE | VE)
+#define EMI_A7			(FUNC(0) | PORTF(5, 0) | SE | VE)
+#define EMI_A7_GPIO		(FUNC(3) | PORTF(5, 0) | SE | VE)
+
+/* Bank 3, pins 0 ... 15 GPIO pins 96 ... 111 */
+#define EMI_D15			(FUNC(0) | PORTF(6, 15) | SE | VE | PE)
+#define EMI_D15_DISABLED	(FUNC(3) | PORTF(6, 15) | SE | VE | PE)
+#define EMI_D14			(FUNC(0) | PORTF(6, 14) | SE | VE | PE)
+#define EMI_D14_DISABLED	(FUNC(3) | PORTF(6, 14) | SE | VE | PE)
+#define EMI_D13			(FUNC(0) | PORTF(6, 13) | SE | VE | PE)
+#define EMI_D13_DISABLED	(FUNC(3) | PORTF(6, 13) | SE | VE | PE)
+#define EMI_D12			(FUNC(0) | PORTF(6, 12) | SE | VE | PE)
+#define EMI_D12_DISABLED	(FUNC(3) | PORTF(6, 12) | SE | VE | PE)
+#define EMI_D11			(FUNC(0) | PORTF(6, 11) | SE | VE | PE)
+#define EMI_D11_DISABLED	(FUNC(3) | PORTF(6, 11) | SE | VE | PE)
+#define EMI_D10			(FUNC(0) | PORTF(6, 10) | SE | VE | PE)
+#define EMI_D10_DISABLED	(FUNC(3) | PORTF(6, 10) | SE | VE | PE)
+#define EMI_D9			(FUNC(0) | PORTF(6, 9) | SE | VE | PE)
+#define EMI_D9_DISABLED		(FUNC(3) | PORTF(6, 9) | SE | VE | PE)
+#define EMI_D8			(FUNC(0) | PORTF(6, 8) | SE | VE | PE)
+#define EMI_D8_DISABLED		(FUNC(3) | PORTF(6, 8) | SE | VE | PE)
+#define EMI_D7			(FUNC(0) | PORTF(6, 7) | SE | VE | PE)
+#define EMI_D7_DISABLED		(FUNC(3) | PORTF(6, 7) | SE | VE | PE)
+#define EMI_D6			(FUNC(0) | PORTF(6, 6) | SE | VE | PE)
+#define EMI_D6_DISABLED		(FUNC(3) | PORTF(6, 6) | SE | VE | PE)
+#define EMI_D5			(FUNC(0) | PORTF(6, 5) | SE | VE | PE)
+#define EMI_D5_DISABLED		(FUNC(3) | PORTF(6, 5) | SE | VE | PE)
+#define EMI_D4			(FUNC(0) | PORTF(6, 4) | SE | VE | PE)
+#define EMI_D4_DISABLED		(FUNC(3) | PORTF(6, 4) | SE | VE | PE)
+#define EMI_D3			(FUNC(0) | PORTF(6, 3) | SE | VE | PE)
+#define EMI_D3_DISABLED		(FUNC(3) | PORTF(6, 3) | SE | VE | PE)
+#define EMI_D2			(FUNC(0) | PORTF(6, 2) | SE | VE | PE)
+#define EMI_D2_DISABLED		(FUNC(3) | PORTF(6, 2) | SE | VE | PE)
+#define EMI_D1			(FUNC(0) | PORTF(6, 1) | SE | VE | PE)
+#define EMI_D1_DISABLED		(FUNC(3) | PORTF(6, 1) | SE | VE | PE)
+#define EMI_D0			(FUNC(0) | PORTF(6, 0) | SE | VE | PE)
+#define EMI_D0_DISABLED		(FUNC(3) | PORTF(6, 0) | SE | VE | PE)
+
+/* Bank 3, pins 16 ... 21 GPIO pins 112 ... 117 */
+#define EMI_CLKN		(FUNC(0) | PORTF(7, 5) | SE | VE)
+#define EMI_CLKN_DISABLED	(FUNC(3) | PORTF(7, 5) | SE | VE)
+#define EMI_CLK			(FUNC(0) | PORTF(7, 4) | SE | VE)
+#define EMI_CLK_DISABLED	(FUNC(3) | PORTF(7, 4) | SE | VE)
+#define EMI_DQS1		(FUNC(0) | PORTF(7, 3) | SE | VE)
+#define EMI_DQS1_DISABLED	(FUNC(3) | PORTF(7, 3) | SE | VE)
+#define EMI_DQS0		(FUNC(0) | PORTF(7, 2) | SE | VE)
+#define EMI_DQS0_DISABLED	(FUNC(3) | PORTF(7, 2) | SE | VE)
+#define EMI_DQM1		(FUNC(0) | PORTF(7, 1) | SE | VE | PE)
+#define EMI_DQM1_DISABLED	(FUNC(3) | PORTF(7, 1) | SE | VE | PE)
+#define EMI_DQM0		(FUNC(0) | PORTF(7, 0) | SE | VE | PE)
+#define EMI_DQM0_DISABLED	(FUNC(3) | PORTF(7, 0) | SE | VE | PE)
+
+#endif /* __ASM_MACH_IOMUX_H */
diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx23.c
new file mode 100644
index 0000000..b0f4046
--- /dev/null
+++ b/arch/arm/mach-stm/iomux-imx23.c
@@ -0,0 +1,117 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+
+#define HW_PINCTRL_CTRL 0x000
+#define HW_PINCTRL_MUXSEL0 0x100
+#define HW_PINCTRL_DRIVE0 0x200
+#define HW_PINCTRL_PULL0 0x400
+#define HW_PINCTRL_DOUT0 0x500
+#define HW_PINCTRL_DIN0 0x600
+#define HW_PINCTRL_DOE0 0x700
+
+static uint32_t calc_mux_reg(uint32_t no)
+{
+	/* each register controls 16 pads */
+	return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0;
+}
+
+static uint32_t calc_strength_reg(uint32_t no)
+{
+	/* each register controls 8 pads */
+	return  ((no >> 3) << 4) + HW_PINCTRL_DRIVE0;
+}
+
+static uint32_t calc_pullup_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_PULL0;
+}
+
+static uint32_t calc_output_enable_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DOE0;
+}
+
+static uint32_t calc_output_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
+}
+
+/**
+ * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
+ */
+void imx_gpio_mode(unsigned m)
+{
+	uint32_t reg_offset, gpio_pin, reg;
+
+	gpio_pin = GET_GPIO_NO(m);
+
+	/* configure the pad to its function (always) */
+	reg_offset = calc_mux_reg(gpio_pin);
+	reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 16) << 1));
+	reg |= GET_FUNC(m) << ((gpio_pin % 16) << 1);
+	writel(reg, IMX_IOMUXC_BASE + reg_offset);
+
+	/* some pins are disabled when configured for GPIO */
+	if ((gpio_pin > 95) && (GET_FUNC(m) == IS_GPIO)) {
+		printf("Cannot configure pad %d to GPIO\n", gpio_pin);
+		return;
+	}
+
+	if (SE_PRESENT(m)) {
+		reg_offset = calc_strength_reg(gpio_pin);
+		reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 8) << 2));
+		reg |= GET_STRENGTH(m) << ((gpio_pin % 8) << 2);
+		writel(reg, IMX_IOMUXC_BASE + reg_offset);
+	}
+
+	if (VE_PRESENT(m)) {
+		reg_offset = calc_strength_reg(gpio_pin);
+		if (GET_VOLTAGE(m) == 1)
+			writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 4);
+		else
+			writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 8);
+	}
+
+	if (PE_PRESENT(m)) {
+		reg_offset = calc_pullup_reg(gpio_pin);
+		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8));
+	}
+
+	if (GET_FUNC(m) == IS_GPIO) {
+		if (GET_GPIODIR(m) == 1) {
+			/* first set the output value */
+			reg_offset = calc_output_reg(gpio_pin);
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
+			/* then the direction */
+			reg_offset = calc_output_enable_reg(gpio_pin);
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 4);
+		} else {
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 8);
+		}
+	}
+}
diff --git a/arch/arm/mach-stm/reset-imx23.c b/arch/arm/mach-stm/reset-imx23.c
new file mode 100644
index 0000000..db0b3f2
--- /dev/null
+++ b/arch/arm/mach-stm/reset-imx23.c
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <asm/io.h>
+
+#define HW_RTC_CTRL     0x000
+# define BM_RTC_CTRL_WATCHDOGEN (1 << 4)
+#define HW_RTC_CTRL_SET 0x004
+#define HW_RTC_CTRL_CLR 0x008
+#define HW_RTC_CTRL_TOG 0x00C
+
+#define HW_RTC_WATCHDOG     0x050
+#define HW_RTC_WATCHDOG_SET 0x054
+#define HW_RTC_WATCHDOG_CLR 0x058
+#define HW_RTC_WATCHDOG_TOG 0x05C
+
+#define WDOG_COUNTER_RATE	1000 /* 1 kHz clock */
+
+#define HW_RTC_PERSISTENT1     0x070
+# define BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER 0x80000000
+#define HW_RTC_PERSISTENT1_SET 0x074
+#define HW_RTC_PERSISTENT1_CLR 0x078
+#define HW_RTC_PERSISTENT1_TOG 0x07C
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let it time out
+ *
+ * TODO There is a much easier way to reset the CPU: Refer bit 2 in
+ *       the HW_CLKCTRL_RESET register, data sheet page 106/4-30
+ */
+void __noreturn reset_cpu (unsigned long ignored)
+{
+	writel(WDOG_COUNTER_RATE, IMX_WDT_BASE + HW_RTC_WATCHDOG);
+	writel(BM_RTC_CTRL_WATCHDOGEN, IMX_WDT_BASE + HW_RTC_CTRL_SET);
+	writel(BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER, IMX_WDT_BASE + HW_RTC_PERSISTENT1);
+
+	while (1)
+		;
+	/*NOTREACHED*/
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-stm/speed-imx23.c b/arch/arm/mach-stm/speed-imx23.c
new file mode 100644
index 0000000..7418ad5
--- /dev/null
+++ b/arch/arm/mach-stm/speed-imx23.c
@@ -0,0 +1,280 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This code is based partially on code of:
+ *
+ * (c) 2008 Embedded Alley Solutions, Inc.
+ * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/generic.h>
+#include <mach/clock.h>
+
+/* Note: all clock frequencies are returned in kHz */
+
+#define HW_CLKCTRL_PLLCTRL0 0x000
+#define HW_CLKCTRL_PLLCTRL1 0x010
+#define HW_CLKCTRL_CPU 0x20
+# define GET_CPU_XTAL_DIV(x) (((x) >> 16) & 0x3ff)
+# define GET_CPU_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_HBUS 0x30
+#define HW_CLKCTRL_XBUS 0x40
+#define HW_CLKCTRL_XTAL 0x050
+#define HW_CLKCTRL_PIX 0x060
+/* note: no set/clear register! */
+#define HW_CLKCTRL_SSP 0x070
+/* note: no set/clear register! */
+# define CLKCTRL_SSP_CLKGATE (1 << 31)
+# define CLKCTRL_SSP_BUSY (1 << 29)
+# define CLKCTRL_SSP_DIV_MASK 0x1ff
+# define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+# define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+#define HW_CLKCTRL_GPMI 0x080
+/* note: no set/clear register! */
+#define HW_CLKCTRL_SPDIF 0x090
+/* note: no set/clear register! */
+#define HW_CLKCTRL_EMI	0xa0
+/* note: no set/clear register! */
+# define CLKCTRL_EMI_CLKGATE (1 << 31)
+# define GET_EMI_XTAL_DIV(x) (((x) >> 8) & 0xf)
+# define GET_EMI_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_SAIF 0x0c0
+#define HW_CLKCTRL_TV 0x0d0
+#define HW_CLKCTRL_ETM 0x0e0
+#define HW_CLKCTRL_FRAC 0xf0
+# define CLKCTRL_FRAC_CLKGATEIO (1 << 31)
+# define GET_IOFRAC(x) (((x) >> 24) & 0x3f)
+# define SET_IOFRAC(x) (((x) & 0x3f) << 24)
+# define CLKCTRL_FRAC_CLKGATEPIX (1 << 23)
+# define GET_PIXFRAC(x) (((x) >> 16) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATEEMI (1 << 15)
+# define GET_EMIFRAC(x) (((x) >> 8) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATECPU (1 << 7)
+# define GET_CPUFRAC(x) ((x) & 0x3f)
+#define HW_CLKCTRL_FRAC1 0x100
+#define HW_CLKCTRL_CLKSEQ 0x110
+# define CLKCTRL_CLKSEQ_BYPASS_ETM (1 << 8)
+# define CLKCTRL_CLKSEQ_BYPASS_CPU (1 << 7)
+# define CLKCTRL_CLKSEQ_BYPASS_EMI (1 << 6)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP (1 << 5)
+# define CLKCTRL_CLKSEQ_BYPASS_GPMI (1 << 4)
+#define HW_CLKCTRL_RESET 0x120
+#define HW_CLKCTRL_STATUS 0x130
+#define HW_CLKCTRL_VERSION 0x140
+
+unsigned imx_get_mpllclk(void)
+{
+	/* the main PLL runs at 480 MHz */
+	return 480U * 1000U;
+}
+
+unsigned imx_get_xtalclk(void)
+{
+	/* the external reference runs at 24 MHz */
+	return 24U * 1000U;
+}
+
+/* used for the SDRAM controller */
+unsigned imx_get_emiclk(void)
+{
+	uint32_t reg;
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_EMI) & CLKCTRL_EMI_CLKGATE)
+		return 0U;	/* clock is off */
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
+		return imx_get_xtalclk() / GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+
+	rate = imx_get_mpllclk();
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
+		rate *= 18U;
+		rate /= GET_EMIFRAC(reg);
+	}
+
+	return rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+}
+
+/*
+ * Source of ssp, gpmi, ir
+ */
+unsigned imx_get_ioclk(void)
+{
+	uint32_t reg;
+	unsigned rate = imx_get_mpllclk();
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	if (reg & CLKCTRL_FRAC_CLKGATEIO)
+		return 0U;	/* clock is off */
+
+	rate *= 18U;
+	rate /= GET_IOFRAC(reg);
+	return rate;
+}
+
+/**
+ * Setup a new frequency to the IOCLK domain.
+ * @param nc New frequency in [kHz]
+ *
+ * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
+ */
+unsigned imx_set_ioclk(unsigned nc)
+{
+	uint32_t reg;
+	unsigned div;
+
+	div = imx_get_mpllclk();
+	div *= 18U;
+	div += nc >> 1;
+	div /= nc;
+	if (div > 0x3f)
+		div = 0x3f;
+	/* mask the current settings */
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC) & ~(SET_IOFRAC(0x3f));
+	writel(reg | SET_IOFRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	/* enable the IO clock at its new frequency */
+	writel(CLKCTRL_FRAC_CLKGATEIO, IMX_CCM_BASE + HW_CLKCTRL_FRAC + 8);
+
+	return imx_get_ioclk();
+}
+
+/* this is CPU core clock */
+unsigned imx_get_armclk(void)
+{
+	uint32_t reg;
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_CPU)
+		return imx_get_xtalclk() / GET_CPU_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	if (reg & CLKCTRL_FRAC_CLKGATECPU)
+		return 0U;	/* should not possible, shouldn't it? */
+
+	rate = imx_get_mpllclk();
+	rate *= 18U;
+	rate /= GET_CPUFRAC(reg);
+
+	return rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+}
+
+/* this is the AHB and APBH bus clock */
+unsigned imx_get_hclk(void)
+{
+	unsigned rate = imx_get_armclk();
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
+		rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+		rate >>= 5U; /* / 32 */
+	} else
+		rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+	return rate;
+}
+
+/*
+ * Source of UART, debug UART, audio, PWM, dri, timer, digctl
+ */
+unsigned imx_get_xclk(void)
+{
+	unsigned rate = imx_get_xtalclk();	/* runs from the 24 MHz crystal reference */
+
+	return rate / (readl(IMX_CCM_BASE + HW_CLKCTRL_XBUS) & 0x3ff);
+}
+
+/* 'index' gets ignored on i.MX23 */
+unsigned imx_get_sspclk(unsigned index)
+{
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_CLKGATE)
+		return 0U;	/* clock is off */
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_SSP)
+		rate = imx_get_xtalclk();
+	else
+		rate = imx_get_ioclk();
+
+	return rate / GET_SSP_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_SSP));
+}
+
+/**
+ * @param index Unit index (ignored on i.MX23)
+ * @param nc New frequency in [kHz]
+ * @param high != 0 if ioclk should be the source
+ * @return The new possible frequency in [kHz]
+ */
+unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
+{
+	uint32_t reg;
+	unsigned ssp_div;
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & ~CLKCTRL_SSP_CLKGATE;
+	/* Datasheet says: Do not change the DIV setting if the clock is off */
+	writel(reg, IMX_CCM_BASE + HW_CLKCTRL_SSP);
+	/* Wait while clock is gated */
+	while (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_CLKGATE)
+		;
+
+	if (high)
+		ssp_div = imx_get_ioclk();
+	else
+		ssp_div = imx_get_xtalclk();
+
+	if (nc > ssp_div) {
+		printf("Cannot setup SSP unit clock to %u Hz, base clock is only %u Hz\n", nc, ssp_div);
+		ssp_div = 1U;
+	} else {
+		ssp_div += nc - 1U;
+		ssp_div /= nc;
+		if (ssp_div > CLKCTRL_SSP_DIV_MASK)
+			ssp_div = CLKCTRL_SSP_DIV_MASK;
+	}
+
+	/* Set new divider value */
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & ~CLKCTRL_SSP_DIV_MASK;
+	writel(reg | SET_SSP_DIV(ssp_div), IMX_CCM_BASE + HW_CLKCTRL_SSP);
+
+	/* Wait until new divider value is set */
+	while (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_BUSY)
+		;
+
+	if (high)
+		/* switch to ioclock */
+		writel(CLKCTRL_CLKSEQ_BYPASS_SSP, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + 8);
+	else
+		/* switch to 24 MHz crystal */
+		writel(CLKCTRL_CLKSEQ_BYPASS_SSP, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + 4);
+
+	return imx_get_sspclk(index);
+}
+
+void imx_dump_clocks(void)
+{
+	printf("mpll:    %10u kHz\n", imx_get_mpllclk());
+	printf("arm:     %10u kHz\n", imx_get_armclk());
+	printf("ioclk:   %10u kHz\n", imx_get_ioclk());
+	printf("emiclk:  %10u kHz\n", imx_get_emiclk());
+	printf("hclk:    %10u kHz\n", imx_get_hclk());
+	printf("xclk:    %10u kHz\n", imx_get_xclk());
+	printf("ssp:     %10u kHz\n", imx_get_sspclk(0));
+}
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Oct 11 05:11:30 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 11:11:30 +0200
Subject: [PATCH 3/4] Add the i.MX23-EVK platform (WIP)
In-Reply-To: <1286788020-14077-4-git-send-email-jbe@pengutronix.de>
References: <1286788020-14077-1-git-send-email-jbe@pengutronix.de>
	<1286788020-14077-4-git-send-email-jbe@pengutronix.de>
Message-ID: <201010111111.30135.jbe@pengutronix.de>

Me wrote:
> Note: This is work in progress. Use with care.
>
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  Documentation/boards.dox                      |    1 +
>  arch/arm/Makefile                             |    2 +
>  arch/arm/boards/freescale-mx23-evk/Makefile   |    2 +
>  arch/arm/boards/freescale-mx23-evk/config.h   |   16 ++
>  arch/arm/boards/freescale-mx23-evk/mx23-evk.c |   96 +++++++++++
>  arch/arm/configs/imx23evk_defconfig           |  222
> +++++++++++++++++++++++++ arch/arm/mach-stm/Kconfig                     |  
>  7 +
>  7 files changed, 346 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/boards/freescale-mx23-evk/Makefile
>  create mode 100644 arch/arm/boards/freescale-mx23-evk/config.h
>  create mode 100644 arch/arm/boards/freescale-mx23-evk/mx23-evk.c
>  create mode 100644 arch/arm/configs/imx23evk_defconfig
>
> [...]
>
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 77b6cf4..75fa6d3 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -41,6 +41,7 @@ CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
>  machine-$(CONFIG_ARCH_AT91)		:= at91
>  machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
>  machine-$(CONFIG_ARCH_IMX)		:= imx
> +machine-$(CONFIG_ARCH_STM)		:= stm
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Ups, this should be part of the first architecture patch, not this platform 
patch. Resent the whole series?

> [...]

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Mon Oct 11 07:28:09 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:09 +0200
Subject: [PATCH 01/17] i.MX27: Add support for SDHC pins
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/iomux-mx27.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/iomux-mx27.h b/arch/arm/mach-imx/include/mach/iomux-mx27.h
index 993b141..23e448b 100644
--- a/arch/arm/mach-imx/include/mach/iomux-mx27.h
+++ b/arch/arm/mach-imx/include/mach/iomux-mx27.h
@@ -28,6 +28,12 @@
 #define PA2_PF_USBH2_DATA7	(GPIO_PORTA | GPIO_PF | 2)
 #define PA3_PF_USBH2_NXT	(GPIO_PORTA | GPIO_PF | 3)
 #define PA4_PF_USBH2_STP	(GPIO_PORTA | GPIO_PF | 4)
+#define PB4_PF_SD2_D0		(GPIO_PORTB | GPIO_PF | 4)
+#define PB5_PF_SD2_D1		(GPIO_PORTB | GPIO_PF | 5)
+#define PB6_PF_SD2_D2		(GPIO_PORTB | GPIO_PF | 6)
+#define PB7_PF_SD2_D3		(GPIO_PORTB | GPIO_PF | 7)
+#define PB8_PF_SD2_CMD		(GPIO_PORTB | GPIO_PF | 8)
+#define PB9_PF_SD2_CLK		(GPIO_PORTB | GPIO_PF | 9)
 #define PB22_PF_USBH1_SUSP	(GPIO_PORTB | GPIO_PF | 22)
 #define PB25_PF_USBH1_RCV	(GPIO_PORTB | GPIO_PF | 25)
 #define PC5_PF_I2C2_SDA		(GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:11 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:11 +0200
Subject: [PATCH 03/17] mci: print error code on failure
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-4-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/mci-core.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index f961e46..a6c81b8 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -927,7 +927,7 @@ static int mci_sd_write(struct device_d *disk_dev, uint64_t sector_start,
 		}
 		rc = mci_block_write(mci_dev, buffer, sector_start);
 		if (rc != 0) {
-			pr_err("Writing block %u failed\n", (unsigned)sector_start);
+			pr_err("Writing block %u failed with %d\n", (unsigned)sector_start, rc);
 			return rc;
 		}
 		sector_count--;
@@ -973,7 +973,7 @@ static int mci_sd_read(struct device_d *disk_dev, uint64_t sector_start,
 		}
 		rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start);
 		if (rc != 0) {
-			pr_err("Reading block %lu failed\n", (unsigned)sector_start);
+			pr_err("Reading block %lu failed with %d\n", (unsigned)sector_start, rc);
 			return rc;
 		}
 		sector_count--;
@@ -1154,8 +1154,7 @@ static int mci_card_probe(struct device_d *mci_dev)
 			pr_debug("Card seems to be a MultiMediaCard\n");
 			rc = mmc_send_op_cond(mci_dev);
 			if (rc) {
-				pr_err("MultiMediaCard did not respond to voltage select!\n");
-				rc = -ENODEV;
+				pr_err("MultiMediaCard voltage select failed with %d\n", rc);
 				goto on_error;
 			}
 		} else
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:21 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:21 +0200
Subject: [PATCH 13/17] defaultenv: handle disk partitions
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-14-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 defaultenv/bin/init |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/defaultenv/bin/init b/defaultenv/bin/init
index a55e8e6..526e3db 100644
--- a/defaultenv/bin/init
+++ b/defaultenv/bin/init
@@ -8,6 +8,10 @@ if [ -e /dev/nor0 ]; then
 	addpart /dev/nor0 $nor_parts
 fi
 
+if [ -e /dev/disk0 ]; then
+	addpart /dev/disk0 $disk_parts
+fi
+
 if [ -e /dev/nand0 ]; then
 	addpart /dev/nand0 $nand_parts
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:19 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:19 +0200
Subject: [PATCH 11/17] mci: handle SD cards < 2.0 correctly
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-12-git-send-email-s.hauer@pengutronix.de>

With SD cards older than 2.0 the sd_send_if_cond() fails. Do
not assume it's an MMC card in this case. Instead, assume
it's a MMC card if sd_send_op_cond() fails.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/mci-core.c |   24 +++++++-----------------
 1 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index a6c81b8..57b82bf 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1148,26 +1148,16 @@ static int mci_card_probe(struct device_d *mci_dev)
 
 	/* Check if this card can handle the "SD Card Physical Layer Specification 2.0" */
 	rc = sd_send_if_cond(mci_dev);
-	if (rc) {
+	rc = sd_send_op_cond(mci_dev);
+	if (rc && rc == -ETIMEDOUT) {
 		/* If the command timed out, we check for an MMC card */
-		if (rc == -ETIMEDOUT) {
-			pr_debug("Card seems to be a MultiMediaCard\n");
-			rc = mmc_send_op_cond(mci_dev);
-			if (rc) {
-				pr_err("MultiMediaCard voltage select failed with %d\n", rc);
-				goto on_error;
-			}
-		} else
-			goto on_error;
-	} else {
-		/* Its a 2.xx card. Setup operation conditions */
-		rc = sd_send_op_cond(mci_dev);
-		if (rc) {
-			pr_debug("Cannot setup SD card's operation condition\n");
-			goto on_error;
-		}
+		pr_debug("Card seems to be a MultiMediaCard\n");
+		rc = mmc_send_op_cond(mci_dev);
 	}
 
+	if (rc)
+		goto on_error;
+
 	rc = mci_startup(mci_dev);
 	if (rc) {
 		printf("Card's startup fails with %d\n", rc);
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:08 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:08 +0200
Subject: Patches for -next
Message-ID: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>

Hi All,

Here are several patches leading to i.MX51 babbage support in the end.
Not all patches are directly i.MX51/babbage related but are needed
to make it work.

Sascha

The following changes since commit 3eec12c24a53e7b9b9c1c5d9778fc4357aaaedef:

  ARM pca100: Add mci support (2010-10-11 13:08:28 +0200)

are available in the git repository at:
  git://git.pengutronix.de/git/barebox.git mx51

Sascha Hauer (17):
      i.MX27: Add support for SDHC pins
      mci: Add i.MX esdhc support
      mci: print error code on failure
      spi i.MX: add spi version namespace to register defines
      spi i.MX: redirect functions to version specific functions
      spi i.MX: Add i.MX51 support
      Move mfd drivers to drivers/mfd
      move include files for mfd drivers to include/mfd
      mfd mc13892: Add spi support
      mfd mc13892: support reading the revision
      mci: handle SD cards < 2.0 correctly
      mci: align write buffer if necessary
      defaultenv: handle disk partitions
      imx_serial: Add mx51 support
      ARM mmu: Call __mmu_cache_flush instead of hardcoded v4/v5 only function
      ARM i.MX: Add basic i.MX51 support
      ARM i.MX51: Add babbage board support

 arch/arm/Makefile                                  |    1 +
 arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c  |    2 +-
 arch/arm/boards/freescale-mx25-3-stack/3stack.c    |    2 +-
 arch/arm/boards/freescale-mx35-3-stack/3stack.c    |    6 +-
 arch/arm/boards/freescale-mx51-pdk/Makefile        |    3 +
 arch/arm/boards/freescale-mx51-pdk/board.c         |  318 +++++++++
 arch/arm/boards/freescale-mx51-pdk/config.h        |   24 +
 arch/arm/boards/freescale-mx51-pdk/env/config      |   52 ++
 arch/arm/boards/freescale-mx51-pdk/flash_header.c  |   85 +++
 arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S |  216 ++++++
 arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox    |    4 +
 arch/arm/boards/freescale-mx51-pdk/spi.c           |  340 ++++++++++
 arch/arm/configs/freescale_mx51_babbage_defconfig  |   43 ++
 arch/arm/cpu/mmu.c                                 |    6 +-
 arch/arm/mach-imx/Kconfig                          |   24 +-
 arch/arm/mach-imx/Makefile                         |    1 +
 arch/arm/mach-imx/imx51.c                          |   51 ++
 arch/arm/mach-imx/include/mach/clock-imx51.h       |  696 ++++++++++++++++++++
 arch/arm/mach-imx/include/mach/generic.h           |    6 +
 arch/arm/mach-imx/include/mach/imx-regs.h          |    2 +
 arch/arm/mach-imx/include/mach/imx51-regs.h        |  131 ++++
 arch/arm/mach-imx/include/mach/iomux-mx27.h        |    6 +
 arch/arm/mach-imx/include/mach/iomux-mx51.h        |  330 +++++++++
 arch/arm/mach-imx/include/mach/iomux-v3.h          |   10 +-
 arch/arm/mach-imx/speed-imx51.c                    |  163 +++++
 defaultenv/bin/init                                |    4 +
 drivers/Kconfig                                    |    1 +
 drivers/Makefile                                   |    1 +
 drivers/i2c/Kconfig                                |   16 -
 drivers/i2c/Makefile                               |    6 -
 drivers/i2c/mc13892.c                              |  164 -----
 drivers/mci/Kconfig                                |   13 +
 drivers/mci/Makefile                               |    1 +
 drivers/mci/imx-esdhc.c                            |  512 ++++++++++++++
 drivers/mci/imx-esdhc.h                            |  164 +++++
 drivers/mci/mci-core.c                             |   45 +-
 drivers/mfd/Kconfig                                |   28 +
 drivers/mfd/Makefile                               |    6 +
 drivers/{i2c => mfd}/lp3972.c                      |    0
 drivers/{spi => mfd}/mc13783.c                     |    0
 drivers/mfd/mc13892.c                              |  327 +++++++++
 drivers/{i2c => mfd}/mc34704.c                     |    2 +-
 drivers/{i2c => mfd}/mc9sdz60.c                    |    2 +-
 drivers/{i2c => mfd}/twl4030.c                     |    2 +-
 drivers/serial/serial_imx.c                        |    3 +-
 drivers/spi/Kconfig                                |   12 +-
 drivers/spi/Makefile                               |    2 -
 drivers/spi/imx_spi.c                              |  347 ++++++++--
 drivers/usb/host/ehci-omap.c                       |    2 +-
 drivers/usb/otg/twl4030.c                          |    2 +-
 include/asm-generic/barebox.lds.h                  |    2 +-
 include/{i2c => mfd}/lp3972.h                      |    0
 include/{i2c => mfd}/mc13892.h                     |   28 +
 include/{i2c => mfd}/mc34704.h                     |    0
 include/{i2c => mfd}/mc9sdz60.h                    |    0
 include/{i2c => mfd}/twl4030.h                     |    0
 56 files changed, 3911 insertions(+), 303 deletions(-)
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/Makefile
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/board.c
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/config.h
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/env/config
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/flash_header.c
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/spi.c
 create mode 100644 arch/arm/configs/freescale_mx51_babbage_defconfig
 create mode 100644 arch/arm/mach-imx/include/mach/clock-imx51.h
 create mode 100644 arch/arm/mach-imx/include/mach/imx51-regs.h
 create mode 100644 arch/arm/mach-imx/include/mach/iomux-mx51.h
 create mode 100644 arch/arm/mach-imx/speed-imx51.c
 delete mode 100644 drivers/i2c/mc13892.c
 create mode 100644 drivers/mci/imx-esdhc.c
 create mode 100644 drivers/mci/imx-esdhc.h
 create mode 100644 drivers/mfd/Kconfig
 create mode 100644 drivers/mfd/Makefile
 rename drivers/{i2c => mfd}/lp3972.c (100%)
 rename drivers/{spi => mfd}/mc13783.c (100%)
 create mode 100644 drivers/mfd/mc13892.c
 rename drivers/{i2c => mfd}/mc34704.c (99%)
 rename drivers/{i2c => mfd}/mc9sdz60.c (99%)
 rename drivers/{i2c => mfd}/twl4030.c (99%)
 rename include/{i2c => mfd}/lp3972.h (100%)
 rename include/{i2c => mfd}/mc13892.h (82%)
 rename include/{i2c => mfd}/mc34704.h (100%)
 rename include/{i2c => mfd}/mc9sdz60.h (100%)
 rename include/{i2c => mfd}/twl4030.h (100%)


From s.hauer at pengutronix.de  Mon Oct 11 07:28:22 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:22 +0200
Subject: [PATCH 14/17] imx_serial: Add mx51 support
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-15-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/serial/serial_imx.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index 801004e..25e6a0c 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -160,7 +160,8 @@
 # define	UCR3_VAL (0x700 | UCR3_RXDMUXSEL)
 # define	UCR4_VAL UCR4_CTSTL_32
 #endif
-#if defined CONFIG_ARCH_IMX31 || defined CONFIG_ARCH_IMX35 || defined CONFIG_ARCH_IMX25
+#if defined CONFIG_ARCH_IMX31 || defined CONFIG_ARCH_IMX35 || \
+	defined CONFIG_ARCH_IMX25 || defined CONFIG_ARCH_IMX51
 # define	UCR1_VAL (0)
 # define	UCR3_VAL (0x700 | UCR3_RXDMUXSEL)
 # define	UCR4_VAL UCR4_CTSTL_32
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:14 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:14 +0200
Subject: [PATCH 06/17] spi i.MX: Add i.MX51 support
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-7-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/spi/Kconfig   |   10 +++
 drivers/spi/imx_spi.c |  169 ++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 171 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 3eebd08..2b8d2f4 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -9,6 +9,16 @@ config DRIVER_SPI_IMX
 	depends on ARCH_IMX
 	depends on SPI
 
+config DRIVER_SPI_IMX_0_0
+	bool
+	depends on ARCH_IMX27
+	default y
+
+config DRIVER_SPI_IMX_2_3
+	bool
+	depends on ARCH_IMX51
+	default y
+
 config DRIVER_SPI_MC13783
 	bool "MC13783 a.k.a. PMIC driver"
 	depends on SPI
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 1abab5f..2ad1bfa 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -65,6 +65,30 @@
 
 #define CSPI_0_0_TEST_LBC		(1 << 14)
 
+#define CSPI_2_3_RXDATA		0x00
+#define CSPI_2_3_TXDATA		0x04
+#define CSPI_2_3_CTRL		0x08
+#define CSPI_2_3_CTRL_ENABLE		(1 <<  0)
+#define CSPI_2_3_CTRL_XCH		(1 <<  2)
+#define CSPI_2_3_CTRL_MODE(cs)	(1 << ((cs) +  4))
+#define CSPI_2_3_CTRL_POSTDIV_OFFSET	8
+#define CSPI_2_3_CTRL_PREDIV_OFFSET	12
+#define CSPI_2_3_CTRL_CS(cs)		((cs) << 18)
+#define CSPI_2_3_CTRL_BL_OFFSET	20
+
+#define CSPI_2_3_CONFIG	0x0c
+#define CSPI_2_3_CONFIG_SCLKPHA(cs)	(1 << ((cs) +  0))
+#define CSPI_2_3_CONFIG_SCLKPOL(cs)	(1 << ((cs) +  4))
+#define CSPI_2_3_CONFIG_SBBCTRL(cs)	(1 << ((cs) +  8))
+#define CSPI_2_3_CONFIG_SSBPOL(cs)	(1 << ((cs) + 12))
+
+#define CSPI_2_3_INT		0x10
+#define CSPI_2_3_INT_TEEN		(1 <<  0)
+#define CSPI_2_3_INT_RREN		(1 <<  3)
+
+#define CSPI_2_3_STAT		0x18
+#define CSPI_2_3_STAT_RR		(1 <<  3)
+
 enum imx_spi_devtype {
 #ifdef CONFIG_DRIVER_SPI_IMX1
 	SPI_IMX_VER_IMX1,
@@ -93,11 +117,13 @@ struct imx_spi {
 
 	unsigned int		(*xchg_single)(struct imx_spi *imx, u32 data);
 	void			(*chipselect)(struct spi_device *spi, int active);
+	void			(*init)(struct imx_spi *imx);
 };
 
 struct spi_imx_devtype_data {
 	unsigned int		(*xchg_single)(struct imx_spi *imx, u32 data);
 	void			(*chipselect)(struct spi_device *spi, int active);
+	void			(*init)(struct imx_spi *imx);
 };
 
 static int imx_spi_setup(struct spi_device *spi)
@@ -130,7 +156,7 @@ static void cspi_0_0_chipselect(struct spi_device *spi, int is_active)
 {
 	struct spi_master *master = spi->master;
 	struct imx_spi *imx = container_of(master, struct imx_spi, master);
-	ulong base = master->dev->map_base;
+	void __iomem *base = imx->regs;
 	unsigned int cs = 0;
 	int gpio = imx->cs_array[spi->chip_select];
 	u32 ctrl_reg;
@@ -165,6 +191,126 @@ static void cspi_0_0_chipselect(struct spi_device *spi, int is_active)
 	if (gpio >= 0)
 		gpio_set_value(gpio, cs);
 }
+
+static void cspi_0_0_init(struct imx_spi *imx)
+{
+	void __iomem *base = imx->regs;
+
+	writel(CSPI_0_0_CTRL_ENABLE | CSPI_0_0_CTRL_MASTER,
+		     base + CSPI_0_0_CTRL);
+	writel(CSPI_0_0_PERIOD_32KHZ,
+		     base + CSPI_0_0_PERIOD);
+	while (readl(base + CSPI_0_0_INT) & CSPI_0_0_STAT_RR)
+		readl(base + CSPI_0_0_RXDATA);
+	writel(0, base + CSPI_0_0_INT);
+}
+#endif
+
+#ifdef CONFIG_DRIVER_SPI_IMX_2_3
+static unsigned int cspi_2_3_xchg_single(struct imx_spi *imx, unsigned int data)
+{
+	void __iomem *base = imx->regs;
+
+	unsigned int cfg_reg = readl(base + CSPI_2_3_CTRL);
+
+	writel(data, base + CSPI_2_3_TXDATA);
+
+	cfg_reg |= CSPI_2_3_CTRL_XCH;
+
+	writel(cfg_reg, base + CSPI_2_3_CTRL);
+
+	while (!(readl(base + CSPI_2_3_STAT) & CSPI_2_3_STAT_RR));
+
+	return readl(base + CSPI_2_3_RXDATA);
+}
+
+/* FIXME: include/linux/kernel.h */
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
+static unsigned int cspi_2_3_clkdiv(unsigned int fin, unsigned int fspi)
+{
+	/*
+	 * there are two 4-bit dividers, the pre-divider divides by
+	 * $pre, the post-divider by 2^$post
+	 */
+	unsigned int pre, post;
+
+	if (unlikely(fspi > fin))
+		return 0;
+
+	post = fls(fin) - fls(fspi);
+	if (fin > fspi << post)
+		post++;
+
+	/* now we have: (fin <= fspi << post) with post being minimal */
+
+	post = max(4U, post) - 4;
+	if (unlikely(post > 0xf)) {
+		pr_err("%s: cannot set clock freq: %u (base freq: %u)\n",
+				__func__, fspi, fin);
+		return 0xff;
+	}
+
+	pre = DIV_ROUND_UP(fin, fspi << post) - 1;
+
+	pr_debug("%s: fin: %u, fspi: %u, post: %u, pre: %u\n",
+			__func__, fin, fspi, post, pre);
+	return (pre << CSPI_2_3_CTRL_PREDIV_OFFSET) |
+		(post << CSPI_2_3_CTRL_POSTDIV_OFFSET);
+}
+
+static void cspi_2_3_chipselect(struct spi_device *spi, int is_active)
+{
+	struct spi_master *master = spi->master;
+	struct imx_spi *imx = container_of(master, struct imx_spi, master);
+	void __iomem *base = imx->regs;
+	unsigned int cs = spi->chip_select, gpio_cs = 0;
+	int gpio = imx->cs_array[spi->chip_select];
+	u32 ctrl, cfg = 0;
+
+	if (spi->mode & SPI_CS_HIGH)
+		gpio_cs = 1;
+
+	if (!is_active) {
+		if (gpio >= 0)
+			gpio_set_value(gpio, !gpio_cs);
+		return;
+	}
+
+	ctrl = CSPI_2_3_CTRL_ENABLE;
+
+	/* set master mode */
+	ctrl |= CSPI_2_3_CTRL_MODE(cs);
+
+	/* set clock speed */
+	ctrl |= cspi_2_3_clkdiv(166000000, spi->max_speed_hz);
+
+	/* set chip select to use */
+	ctrl |= CSPI_2_3_CTRL_CS(cs);
+
+	ctrl |= (spi->bits_per_word - 1) << CSPI_2_3_CTRL_BL_OFFSET;
+
+	cfg |= CSPI_2_3_CONFIG_SBBCTRL(cs);
+
+	if (spi->mode & SPI_CPHA)
+		cfg |= CSPI_2_3_CONFIG_SCLKPHA(cs);
+
+	if (spi->mode & SPI_CPOL)
+		cfg |= CSPI_2_3_CONFIG_SCLKPOL(cs);
+
+	if (spi->mode & SPI_CS_HIGH)
+		cfg |= CSPI_2_3_CONFIG_SSBPOL(cs);
+
+	writel(ctrl, base + CSPI_2_3_CTRL);
+	writel(cfg, base + CSPI_2_3_CONFIG);
+
+	if (gpio >= 0)
+		gpio_set_value(gpio, gpio_cs);
+}
+
+static void cspi_2_3_init(struct imx_spi *imx)
+{
+}
 #endif
 
 static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
@@ -196,6 +342,14 @@ static struct spi_imx_devtype_data spi_imx_devtype_data[] = {
 	[SPI_IMX_VER_0_0] = {
 		.chipselect = cspi_0_0_chipselect,
 		.xchg_single = cspi_0_0_xchg_single,
+		.init = cspi_0_0_init,
+	},
+#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_2_3
+	[SPI_IMX_VER_2_3] = {
+		.chipselect = cspi_2_3_chipselect,
+		.xchg_single = cspi_2_3_xchg_single,
+		.init = cspi_2_3_init,
 	},
 #endif
 };
@@ -221,17 +375,16 @@ static int imx_spi_probe(struct device_d *dev)
 	if (cpu_is_mx27())
 		version = SPI_IMX_VER_0_0;
 #endif
+#ifdef CONFIG_DRIVER_SPI_IMX_2_3
+	if (cpu_is_mx51())
+		version = SPI_IMX_VER_2_3;
+#endif
 	imx->chipselect = spi_imx_devtype_data[version].chipselect;
 	imx->xchg_single = spi_imx_devtype_data[version].xchg_single;
+	imx->init = spi_imx_devtype_data[version].init;
 	imx->regs = (void __iomem *)dev->map_base;
 
-	writel(CSPI_0_0_CTRL_ENABLE | CSPI_0_0_CTRL_MASTER,
-		     dev->map_base + CSPI_0_0_CTRL);
-	writel(CSPI_0_0_PERIOD_32KHZ,
-		     dev->map_base + CSPI_0_0_PERIOD);
-	while (readl(dev->map_base + CSPI_0_0_INT) & CSPI_0_0_STAT_RR)
-		readl(dev->map_base + CSPI_0_0_RXDATA);
-	writel(0, dev->map_base + CSPI_0_0_INT);
+	imx->init(imx);
 
 	spi_register_master(master);
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:23 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:23 +0200
Subject: [PATCH 15/17] ARM mmu: Call __mmu_cache_flush instead of hardcoded
	v4/v5 only function
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-16-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/cpu/mmu.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 5bf31c0..08a57ce 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -16,12 +16,10 @@ void arm_create_section(unsigned long virt, unsigned long phys, int size_m,
 		ttb[virt] = (phys << 20) | flags;
 
 	asm volatile (
-		"mov r0, #0;"
-		"mcr p15, 0, r0, c7, c6, 0;" /* flush d-cache */
-		"mcr p15, 0, r0, c8, c7, 0;" /* flush i+d-TLBs */
+		"bl __mmu_cache_flush;"
 		:
 		:
-		: "r0","memory" /* clobber list */
+		: "r0", "r1", "r2", "r3", "r6", "r10", "r12", "cc", "memory"
 	);
 }
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:17 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:17 +0200
Subject: [PATCH 09/17] mfd mc13892: Add spi support
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-10-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/freescale-mx35-3-stack/3stack.c |    2 +-
 drivers/mfd/Kconfig                             |    2 +-
 drivers/mfd/mc13892.c                           |  119 +++++++++++++++++++++--
 3 files changed, 112 insertions(+), 11 deletions(-)

diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
index 9b8d718..d6699cd 100644
--- a/arch/arm/boards/freescale-mx35-3-stack/3stack.c
+++ b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
@@ -111,7 +111,7 @@ static struct device_d smc911x_dev = {
 
 static struct i2c_board_info i2c_devices[] = {
 	{
-		I2C_BOARD_INFO("mc13892", 0x08),
+		I2C_BOARD_INFO("mc13892-i2c", 0x08),
 	}, {
 		I2C_BOARD_INFO("mc9sdz60", 0x69),
 	},
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 7c27418..96440d8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1,7 +1,7 @@
 menu MFD
 
 config I2C_MC13892
-	depends on I2C
+	depends on I2C || SPI
 	bool "MC13892 a.k.a. PMIC driver"
 
 config I2C_MC34704
diff --git a/drivers/mfd/mc13892.c b/drivers/mfd/mc13892.c
index 240a7a9..2f415fc 100644
--- a/drivers/mfd/mc13892.c
+++ b/drivers/mfd/mc13892.c
@@ -24,6 +24,7 @@
 #include <driver.h>
 #include <xfuncs.h>
 #include <errno.h>
+#include <spi/spi.h>
 
 #include <i2c/i2c.h>
 #include <mfd/mc13892.h>
@@ -43,7 +44,56 @@ struct mc13892 *mc13892_get(void)
 }
 EXPORT_SYMBOL(mc13892_get);
 
-int mc13892_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val)
+#ifdef CONFIG_SPI
+static int spi_rw(struct spi_device *spi, void * buf, size_t len)
+{
+	int ret;
+
+	struct spi_transfer t = {
+		.tx_buf = (const void *)buf,
+		.rx_buf = buf,
+		.len = len,
+		.cs_change = 0,
+		.delay_usecs = 0,
+	};
+	struct spi_message m;
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	if ((ret = spi_sync(spi, &m)))
+		return ret;
+	return 0;
+}
+
+#define MXC_PMIC_REG_NUM(reg)	(((reg) & 0x3f) << 25)
+#define MXC_PMIC_WRITE		(1 << 31)
+
+static int mc13892_spi_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val)
+{
+	uint32_t buf;
+
+	buf = MXC_PMIC_REG_NUM(reg);
+
+	spi_rw(mc13892->spi, &buf, 4);
+
+	*val = buf;
+
+	return 0;
+}
+
+static int mc13892_spi_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val)
+{
+	uint32_t buf = MXC_PMIC_REG_NUM(reg) | MXC_PMIC_WRITE | (val & 0xffffff);
+
+	spi_rw(mc13892->spi, &buf, 4);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_I2C
+static int mc13892_i2c_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val)
 {
 	u8 buf[3];
 	int ret;
@@ -53,9 +103,8 @@ int mc13892_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val)
 
 	return ret == 3 ? 0 : ret;
 }
-EXPORT_SYMBOL(mc13892_reg_read)
 
-int mc13892_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val)
+static int mc13892_i2c_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val)
 {
 	u8 buf[] = {
 		val >> 16,
@@ -68,8 +117,36 @@ int mc13892_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val)
 
 	return ret == 3 ? 0 : ret;
 }
+#endif
+
+int mc13892_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val)
+{
+#ifdef CONFIG_I2C
+	if (mc13892->mode == MC13892_MODE_I2C)
+		return mc13892_i2c_reg_write(mc13892, reg, val);
+#endif
+#ifdef CONFIG_SPI
+	if (mc13892->mode == MC13892_MODE_SPI)
+		return mc13892_spi_reg_write(mc13892, reg, val);
+#endif
+	return -EINVAL;
+}
 EXPORT_SYMBOL(mc13892_reg_write)
 
+int mc13892_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val)
+{
+#ifdef CONFIG_I2C
+	if (mc13892->mode == MC13892_MODE_I2C)
+		return mc13892_i2c_reg_read(mc13892, reg, val);
+#endif
+#ifdef CONFIG_SPI
+	if (mc13892->mode == MC13892_MODE_SPI)
+		return mc13892_spi_reg_read(mc13892, reg, val);
+#endif
+	return -EINVAL;
+}
+EXPORT_SYMBOL(mc13892_reg_read)
+
 int mc13892_set_bits(struct mc13892 *mc13892, enum mc13892_reg reg, u32 mask, u32 val)
 {
 	u32 tmp;
@@ -133,14 +210,22 @@ static struct file_operations mc_fops = {
 	.write	= mc_write,
 };
 
-static int mc_probe(struct device_d *dev)
+static int mc_probe(struct device_d *dev, enum mc13892_mode mode)
 {
 	if (mc_dev)
 		return -EBUSY;
 
 	mc_dev = xzalloc(sizeof(struct mc13892));
+	mc_dev->mode = mode;
 	mc_dev->cdev.name = DRIVERNAME;
-	mc_dev->client = to_i2c_client(dev);
+	if (mode == MC13892_MODE_I2C) {
+		mc_dev->client = to_i2c_client(dev);
+	}
+	if (mode == MC13892_MODE_SPI) {
+		mc_dev->spi = dev->type_data;
+		mc_dev->spi->mode = SPI_MODE_0 | SPI_CS_HIGH;
+		mc_dev->spi->bits_per_word = 32;
+	}
 	mc_dev->cdev.size = 256;
 	mc_dev->cdev.dev = dev;
 	mc_dev->cdev.ops = &mc_fops;
@@ -150,14 +235,30 @@ static int mc_probe(struct device_d *dev)
 	return 0;
 }
 
-static struct driver_d mc_driver = {
-	.name  = DRIVERNAME,
-	.probe = mc_probe,
+static int mc_i2c_probe(struct device_d *dev)
+{
+	return mc_probe(dev, MC13892_MODE_I2C);
+}
+
+static int mc_spi_probe(struct device_d *dev)
+{
+	return mc_probe(dev, MC13892_MODE_SPI);
+}
+
+static struct driver_d mc_i2c_driver = {
+	.name  = "mc13892-i2c",
+	.probe = mc_i2c_probe,
+};
+
+static struct driver_d mc_spi_driver = {
+	.name  = "mc13892-spi",
+	.probe = mc_spi_probe,
 };
 
 static int mc_init(void)
 {
-        register_driver(&mc_driver);
+        register_driver(&mc_i2c_driver);
+        register_driver(&mc_spi_driver);
         return 0;
 }
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:13 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:13 +0200
Subject: [PATCH 05/17] spi i.MX: redirect functions to version specific
	functions
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-6-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/spi/imx_spi.c |   72 ++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 809a5f8..1abab5f 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -26,6 +26,7 @@
 #include <asm/io.h>
 #include <gpio.h>
 #include <mach/spi.h>
+#include <mach/generic.h>
 
 #define CSPI_0_0_RXDATA		0x00
 #define CSPI_0_0_TXDATA		0x04
@@ -64,9 +65,39 @@
 
 #define CSPI_0_0_TEST_LBC		(1 << 14)
 
+enum imx_spi_devtype {
+#ifdef CONFIG_DRIVER_SPI_IMX1
+	SPI_IMX_VER_IMX1,
+#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_0_0
+	SPI_IMX_VER_0_0,
+#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_0_4
+	SPI_IMX_VER_0_4,
+#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_0_5
+	SPI_IMX_VER_0_5,
+#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_0_7
+	SPI_IMX_VER_0_7,
+#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_2_3
+	SPI_IMX_VER_2_3,
+#endif
+};
+
 struct imx_spi {
-	struct spi_master master;
-	int *chipselect;
+	struct spi_master	master;
+	int			*cs_array;
+	void __iomem		*regs;
+
+	unsigned int		(*xchg_single)(struct imx_spi *imx, u32 data);
+	void			(*chipselect)(struct spi_device *spi, int active);
+};
+
+struct spi_imx_devtype_data {
+	unsigned int		(*xchg_single)(struct imx_spi *imx, u32 data);
+	void			(*chipselect)(struct spi_device *spi, int active);
 };
 
 static int imx_spi_setup(struct spi_device *spi)
@@ -77,8 +108,10 @@ static int imx_spi_setup(struct spi_device *spi)
 	return 0;
 }
 
-static unsigned int spi_xchg_single(ulong base, unsigned int data)
+#ifdef CONFIG_DRIVER_SPI_IMX_0_0
+static unsigned int cspi_0_0_xchg_single(struct imx_spi *imx, unsigned int data)
 {
+	void __iomem *base = imx->regs;
 
 	unsigned int cfg_reg = readl(base + CSPI_0_0_CTRL);
 
@@ -93,13 +126,13 @@ static unsigned int spi_xchg_single(ulong base, unsigned int data)
 	return readl(base + CSPI_0_0_RXDATA);
 }
 
-static void mxc_spi_chipselect(struct spi_device *spi, int is_active)
+static void cspi_0_0_chipselect(struct spi_device *spi, int is_active)
 {
 	struct spi_master *master = spi->master;
 	struct imx_spi *imx = container_of(master, struct imx_spi, master);
 	ulong base = master->dev->map_base;
 	unsigned int cs = 0;
-	int gpio = imx->chipselect[spi->chip_select];
+	int gpio = imx->cs_array[spi->chip_select];
 	u32 ctrl_reg;
 
 	if (spi->mode & SPI_CS_HIGH)
@@ -132,14 +165,15 @@ static void mxc_spi_chipselect(struct spi_device *spi, int is_active)
 	if (gpio >= 0)
 		gpio_set_value(gpio, cs);
 }
+#endif
 
 static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
 {
 	struct spi_master *master = spi->master;
-	ulong base = master->dev->map_base;
+	struct imx_spi *imx = container_of(master, struct imx_spi, master);
 	struct spi_transfer	*t = NULL;
 
-	mxc_spi_chipselect(spi, 1);
+	imx->chipselect(spi, 1);
 
 	list_for_each_entry (t, &mesg->transfers, transfer_list) {
 		const u32 *txbuf = t->tx_buf;
@@ -147,21 +181,31 @@ static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
 		int i = 0;
 
 		while(i < t->len >> 2) {
-			rxbuf[i] = spi_xchg_single(base, txbuf[i]);
+			rxbuf[i] = imx->xchg_single(imx, txbuf[i]);
 			i++;
 		}
 	}
 
-	mxc_spi_chipselect(spi, 0);
+	imx->chipselect(spi, 0);
 
 	return 0;
 }
 
+static struct spi_imx_devtype_data spi_imx_devtype_data[] = {
+#ifdef CONFIG_DRIVER_SPI_IMX_0_0
+	[SPI_IMX_VER_0_0] = {
+		.chipselect = cspi_0_0_chipselect,
+		.xchg_single = cspi_0_0_xchg_single,
+	},
+#endif
+};
+
 static int imx_spi_probe(struct device_d *dev)
 {
 	struct spi_master *master;
 	struct imx_spi *imx;
 	struct spi_imx_master *pdata = dev->platform_data;
+	enum imx_spi_devtype version;
 
 	imx = xzalloc(sizeof(*imx));
 
@@ -171,7 +215,15 @@ static int imx_spi_probe(struct device_d *dev)
 	master->setup = imx_spi_setup;
 	master->transfer = imx_spi_transfer;
 	master->num_chipselect = pdata->num_chipselect;
-	imx->chipselect = pdata->chipselect;
+	imx->cs_array = pdata->chipselect;
+
+#ifdef CONFIG_DRIVER_SPI_IMX_0_0
+	if (cpu_is_mx27())
+		version = SPI_IMX_VER_0_0;
+#endif
+	imx->chipselect = spi_imx_devtype_data[version].chipselect;
+	imx->xchg_single = spi_imx_devtype_data[version].xchg_single;
+	imx->regs = (void __iomem *)dev->map_base;
 
 	writel(CSPI_0_0_CTRL_ENABLE | CSPI_0_0_CTRL_MASTER,
 		     dev->map_base + CSPI_0_0_CTRL);
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:20 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:20 +0200
Subject: [PATCH 12/17] mci: align write buffer if necessary
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-13-git-send-email-s.hauer@pengutronix.de>

Most SD controllers need some kind of alignment for writing
blocks. Instead of coding this in every driver, align write
blocks to a 4 byte alignment in the mci layer. For DMA
accesses we may need bigger alignment, but let's solve this
problem when we have it.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/mci-core.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 57b82bf..6a35d54 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -94,6 +94,8 @@ static int mci_set_blocklen(struct device_d *mci_dev, unsigned len)
 	return mci_send_cmd(mci_dev, &cmd, NULL);
 }
 
+static void *sector_buf;
+
 /**
  * Write one block of data to the card
  * @param mci_dev MCI instance
@@ -106,13 +108,21 @@ static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned b
 	struct mci *mci = GET_MCI_DATA(mci_dev);
 	struct mci_cmd cmd;
 	struct mci_data data;
+	const void *buf;
+
+	if ((unsigned long)src & 0x3) {
+		memcpy(sector_buf, src, 512);
+		buf = sector_buf;
+	} else {
+		buf = src;
+	}
 
 	mci_setup_cmd(&cmd,
 		MMC_CMD_WRITE_SINGLE_BLOCK,
 		mci->high_capacity != 0 ? blocknum : blocknum * mci->write_bl_len,
 		MMC_RSP_R1);
 
-	data.src = src;
+	data.src = buf;
 	data.blocks = 1;
 	data.blocksize = mci->write_bl_len;
 	data.flags = MMC_DATA_WRITE;
@@ -1299,6 +1309,10 @@ static struct driver_d mci_driver = {
 
 static int mci_init(void)
 {
+	sector_buf = memalign(32, 512);
+	if (!sector_buf)
+		return -ENOMEM;
+
 	return register_driver(&mci_driver);
 }
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:12 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:12 +0200
Subject: [PATCH 04/17] spi i.MX: add spi version namespace to register defines
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-5-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/spi/imx_spi.c |  116 ++++++++++++++++++++++++------------------------
 1 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 5c97919..809a5f8 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -27,42 +27,42 @@
 #include <gpio.h>
 #include <mach/spi.h>
 
-#define MXC_CSPIRXDATA		0x00
-#define MXC_CSPITXDATA		0x04
-#define MXC_CSPICTRL		0x08
-#define MXC_CSPIINT		0x0C
-#define MXC_CSPIDMA		0x18
-#define MXC_CSPISTAT		0x0C
-#define MXC_CSPIPERIOD		0x14
-#define MXC_CSPITEST		0x10
-#define MXC_CSPIRESET		0x1C
-
-#define MXC_CSPICTRL_ENABLE	(1 << 10)
-#define MXC_CSPICTRL_MASTER	(1 << 11)
-#define MXC_CSPICTRL_XCH	(1 << 9)
-#define MXC_CSPICTRL_LOWPOL	(1 << 5)
-#define MXC_CSPICTRL_PHA	(1 << 6)
-#define MXC_CSPICTRL_SSCTL	(1 << 7)
-#define MXC_CSPICTRL_HIGHSSPOL 	(1 << 8)
-#define MXC_CSPICTRL_CS(x)	(((x) & 0x3) << 19)
-#define MXC_CSPICTRL_BITCOUNT(x)	(((x) & 0x1f) << 0)
-#define MXC_CSPICTRL_DATARATE(x)	(((x) & 0x7) << 14)
-
-#define MXC_CSPICTRL_MAXDATRATE	0x10
-#define MXC_CSPICTRL_DATAMASK	0x1F
-#define MXC_CSPICTRL_DATASHIFT 	14
-
-#define MXC_CSPISTAT_TE		(1 << 0)
-#define MXC_CSPISTAT_TH		(1 << 1)
-#define MXC_CSPISTAT_TF		(1 << 2)
-#define MXC_CSPISTAT_RR		(1 << 4)
-#define MXC_CSPISTAT_RH         (1 << 5)
-#define MXC_CSPISTAT_RF         (1 << 6)
-#define MXC_CSPISTAT_RO         (1 << 7)
-
-#define MXC_CSPIPERIOD_32KHZ	(1 << 15)
-
-#define MXC_CSPITEST_LBC	(1 << 14)
+#define CSPI_0_0_RXDATA		0x00
+#define CSPI_0_0_TXDATA		0x04
+#define CSPI_0_0_CTRL		0x08
+#define CSPI_0_0_INT		0x0C
+#define CSPI_0_0_DMA		0x18
+#define CSPI_0_0_STAT		0x0C
+#define CSPI_0_0_PERIOD		0x14
+#define CSPI_0_0_TEST		0x10
+#define CSPI_0_0_RESET		0x1C
+
+#define CSPI_0_0_CTRL_ENABLE		(1 << 10)
+#define CSPI_0_0_CTRL_MASTER		(1 << 11)
+#define CSPI_0_0_CTRL_XCH		(1 << 9)
+#define CSPI_0_0_CTRL_LOWPOL		(1 << 5)
+#define CSPI_0_0_CTRL_PHA		(1 << 6)
+#define CSPI_0_0_CTRL_SSCTL		(1 << 7)
+#define CSPI_0_0_CTRL_HIGHSSPOL 	(1 << 8)
+#define CSPI_0_0_CTRL_CS(x)		(((x) & 0x3) << 19)
+#define CSPI_0_0_CTRL_BITCOUNT(x)	(((x) & 0x1f) << 0)
+#define CSPI_0_0_CTRL_DATARATE(x)	(((x) & 0x7) << 14)
+
+#define CSPI_0_0_CTRL_MAXDATRATE	0x10
+#define CSPI_0_0_CTRL_DATAMASK		0x1F
+#define CSPI_0_0_CTRL_DATASHIFT 	14
+
+#define CSPI_0_0_STAT_TE		(1 << 0)
+#define CSPI_0_0_STAT_TH		(1 << 1)
+#define CSPI_0_0_STAT_TF		(1 << 2)
+#define CSPI_0_0_STAT_RR		(1 << 4)
+#define CSPI_0_0_STAT_RH		(1 << 5)
+#define CSPI_0_0_STAT_RF		(1 << 6)
+#define CSPI_0_0_STAT_RO		(1 << 7)
+
+#define CSPI_0_0_PERIOD_32KHZ		(1 << 15)
+
+#define CSPI_0_0_TEST_LBC		(1 << 14)
 
 struct imx_spi {
 	struct spi_master master;
@@ -80,17 +80,17 @@ static int imx_spi_setup(struct spi_device *spi)
 static unsigned int spi_xchg_single(ulong base, unsigned int data)
 {
 
-	unsigned int cfg_reg = readl(base + MXC_CSPICTRL);
+	unsigned int cfg_reg = readl(base + CSPI_0_0_CTRL);
 
-	writel(data, base + MXC_CSPITXDATA);
+	writel(data, base + CSPI_0_0_TXDATA);
 
-	cfg_reg |= MXC_CSPICTRL_XCH;
+	cfg_reg |= CSPI_0_0_CTRL_XCH;
 
-	writel(cfg_reg, base + MXC_CSPICTRL);
+	writel(cfg_reg, base + CSPI_0_0_CTRL);
 
-	while (!(readl(base + MXC_CSPIINT) & MXC_CSPISTAT_RR));
+	while (!(readl(base + CSPI_0_0_INT) & CSPI_0_0_STAT_RR));
 
-	return readl(base + MXC_CSPIRXDATA);
+	return readl(base + CSPI_0_0_RXDATA);
 }
 
 static void mxc_spi_chipselect(struct spi_device *spi, int is_active)
@@ -111,23 +111,23 @@ static void mxc_spi_chipselect(struct spi_device *spi, int is_active)
 		return;
 	}
 
-	ctrl_reg = MXC_CSPICTRL_BITCOUNT(spi->bits_per_word - 1)
-		| MXC_CSPICTRL_DATARATE(7) /* FIXME: calculate data rate */
-		| MXC_CSPICTRL_ENABLE
-		| MXC_CSPICTRL_MASTER;
+	ctrl_reg = CSPI_0_0_CTRL_BITCOUNT(spi->bits_per_word - 1)
+		| CSPI_0_0_CTRL_DATARATE(7) /* FIXME: calculate data rate */
+		| CSPI_0_0_CTRL_ENABLE
+		| CSPI_0_0_CTRL_MASTER;
 
 	if (gpio < 0) {
-		ctrl_reg |= MXC_CSPICTRL_CS(gpio + 32);
+		ctrl_reg |= CSPI_0_0_CTRL_CS(gpio + 32);
 	}
 
 	if (spi->mode & SPI_CPHA)
-		ctrl_reg |= MXC_CSPICTRL_PHA;
+		ctrl_reg |= CSPI_0_0_CTRL_PHA;
 	if (spi->mode & SPI_CPOL)
-		ctrl_reg |= MXC_CSPICTRL_LOWPOL;
+		ctrl_reg |= CSPI_0_0_CTRL_LOWPOL;
 	if (spi->mode & SPI_CS_HIGH)
-		ctrl_reg |= MXC_CSPICTRL_HIGHSSPOL;
+		ctrl_reg |= CSPI_0_0_CTRL_HIGHSSPOL;
 
-	writel(ctrl_reg, base + MXC_CSPICTRL);
+	writel(ctrl_reg, base + CSPI_0_0_CTRL);
 
 	if (gpio >= 0)
 		gpio_set_value(gpio, cs);
@@ -173,13 +173,13 @@ static int imx_spi_probe(struct device_d *dev)
 	master->num_chipselect = pdata->num_chipselect;
 	imx->chipselect = pdata->chipselect;
 
-	writel(MXC_CSPICTRL_ENABLE | MXC_CSPICTRL_MASTER,
-		     dev->map_base + MXC_CSPICTRL);
-	writel(MXC_CSPIPERIOD_32KHZ,
-		     dev->map_base + MXC_CSPIPERIOD);
-	while (readl(dev->map_base + MXC_CSPIINT) & MXC_CSPISTAT_RR)
-		readl(dev->map_base + MXC_CSPIRXDATA);
-	writel(0, dev->map_base + MXC_CSPIINT);
+	writel(CSPI_0_0_CTRL_ENABLE | CSPI_0_0_CTRL_MASTER,
+		     dev->map_base + CSPI_0_0_CTRL);
+	writel(CSPI_0_0_PERIOD_32KHZ,
+		     dev->map_base + CSPI_0_0_PERIOD);
+	while (readl(dev->map_base + CSPI_0_0_INT) & CSPI_0_0_STAT_RR)
+		readl(dev->map_base + CSPI_0_0_RXDATA);
+	writel(0, dev->map_base + CSPI_0_0_INT);
 
 	spi_register_master(master);
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:18 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:18 +0200
Subject: [PATCH 10/17] mfd mc13892: support reading the revision
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-11-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mfd/mc13892.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/mfd/mc13892.h |   22 ++++++++++++++++-
 2 files changed, 83 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/mc13892.c b/drivers/mfd/mc13892.c
index 2f415fc..08a439b 100644
--- a/drivers/mfd/mc13892.c
+++ b/drivers/mfd/mc13892.c
@@ -25,6 +25,7 @@
 #include <xfuncs.h>
 #include <errno.h>
 #include <spi/spi.h>
+#include <malloc.h>
 
 #include <i2c/i2c.h>
 #include <mfd/mc13892.h>
@@ -210,8 +211,63 @@ static struct file_operations mc_fops = {
 	.write	= mc_write,
 };
 
+struct mc13892_rev {
+	u16 rev_id;
+	enum mc13892_revision rev;
+	char *revstr;
+};
+
+static struct mc13892_rev mc13892_revisions[] = {
+	{ 0x01, MC13892_REVISION_1_0, "1.0" },
+	{ 0x09, MC13892_REVISION_1_1, "1.1" },
+	{ 0x0a, MC13892_REVISION_1_2, "1.2" },
+	{ 0x10, MC13892_REVISION_2_0, "2.0" },
+	{ 0x11, MC13892_REVISION_2_1, "2.1" },
+	{ 0x18, MC13892_REVISION_3_0, "3.0" },
+	{ 0x19, MC13892_REVISION_3_1, "3.1" },
+	{ 0x1a, MC13892_REVISION_3_2, "3.2" },
+	{ 0x02, MC13892_REVISION_3_2a, "3.2a" },
+	{ 0x1b, MC13892_REVISION_3_3, "3.3" },
+	{ 0x1d, MC13892_REVISION_3_5, "3.5" },
+};
+
+static int mc13893_query_revision(struct mc13892 *mc13892)
+{
+	unsigned int rev_id;
+	char *revstr;
+	int rev, i;
+
+	mc13892_reg_read(mc13892, 7, &rev_id);
+
+	for (i = 0; i < ARRAY_SIZE(mc13892_revisions); i++)
+		if ((rev_id & 0x1f) == mc13892_revisions[i].rev_id)
+			break;
+
+	if (i == ARRAY_SIZE(mc13892_revisions))
+		return -EINVAL;
+
+	rev = mc13892_revisions[i].rev;
+	revstr = mc13892_revisions[i].revstr;
+
+	if (rev == MC13892_REVISION_2_0) {
+		if ((rev_id >> 9) & 0x3) {
+			rev = MC13892_REVISION_2_0a;
+			revstr = "2.0a";
+		}
+	}
+
+	dev_info(mc_dev->cdev.dev, "PMIC ID: 0x%08x [Rev: %s]\n",
+			rev_id, revstr);
+
+	mc13892->revision = rev;
+
+	return rev;
+}
+
 static int mc_probe(struct device_d *dev, enum mc13892_mode mode)
 {
+	int rev;
+
 	if (mc_dev)
 		return -EBUSY;
 
@@ -230,6 +286,12 @@ static int mc_probe(struct device_d *dev, enum mc13892_mode mode)
 	mc_dev->cdev.dev = dev;
 	mc_dev->cdev.ops = &mc_fops;
 
+	rev = mc13893_query_revision(mc_dev);
+	if (rev < 0) {
+		free(mc_dev);
+		return -EINVAL;
+	}
+
 	devfs_create(&mc_dev->cdev);
 
 	return 0;
diff --git a/include/mfd/mc13892.h b/include/mfd/mc13892.h
index 11ae878..78a42e9 100644
--- a/include/mfd/mc13892.h
+++ b/include/mfd/mc13892.h
@@ -79,6 +79,21 @@ enum mc13892_reg {
 	MC13892_REG_TEST4		= 0x3f,
 };
 
+enum mc13892_revision {
+	MC13892_REVISION_1_0,
+	MC13892_REVISION_1_1,
+	MC13892_REVISION_1_2,
+	MC13892_REVISION_2_0,
+	MC13892_REVISION_2_0a,
+	MC13892_REVISION_2_1,
+	MC13892_REVISION_3_0,
+	MC13892_REVISION_3_1,
+	MC13892_REVISION_3_2,
+	MC13892_REVISION_3_2a,
+	MC13892_REVISION_3_3,
+	MC13892_REVISION_3_5,
+};
+
 enum mc13892_mode {
 	MC13892_MODE_I2C,
 	MC13892_MODE_SPI,
@@ -89,7 +104,7 @@ struct mc13892 {
 	struct i2c_client	*client;
 	struct spi_device	*spi;
 	enum mc13892_mode	mode;
-	
+	enum mc13892_revision	revision;
 };
 
 extern struct mc13892 *mc13892_get(void);
@@ -98,4 +113,9 @@ extern int mc13892_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *
 extern int mc13892_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val);
 extern int mc13892_set_bits(struct mc13892 *mc13892, enum mc13892_reg reg, u32 mask, u32 val);
 
+static inline enum mc13892_revision mc13892_get_revision(struct mc13892 *mc13892)
+{
+	return mc13892->revision;
+}
+
 #endif /* __ASM_ARCH_MC13892_H */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:15 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:15 +0200
Subject: [PATCH 07/17] Move mfd drivers to drivers/mfd
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-8-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/Kconfig                 |    1 +
 drivers/Makefile                |    1 +
 drivers/i2c/Kconfig             |   16 ----------------
 drivers/i2c/Makefile            |    6 ------
 drivers/mfd/Kconfig             |   28 ++++++++++++++++++++++++++++
 drivers/mfd/Makefile            |    6 ++++++
 drivers/{i2c => mfd}/lp3972.c   |    0
 drivers/{spi => mfd}/mc13783.c  |    0
 drivers/{i2c => mfd}/mc13892.c  |    0
 drivers/{i2c => mfd}/mc34704.c  |    0
 drivers/{i2c => mfd}/mc9sdz60.c |    0
 drivers/{i2c => mfd}/twl4030.c  |    0
 drivers/spi/Kconfig             |    4 ----
 drivers/spi/Makefile            |    2 --
 14 files changed, 36 insertions(+), 28 deletions(-)
 create mode 100644 drivers/mfd/Kconfig
 create mode 100644 drivers/mfd/Makefile
 rename drivers/{i2c => mfd}/lp3972.c (100%)
 rename drivers/{spi => mfd}/mc13783.c (100%)
 rename drivers/{i2c => mfd}/mc13892.c (100%)
 rename drivers/{i2c => mfd}/mc34704.c (100%)
 rename drivers/{i2c => mfd}/mc9sdz60.c (100%)
 rename drivers/{i2c => mfd}/twl4030.c (100%)

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 13235f3..d94017b 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -11,5 +11,6 @@ source "drivers/usb/Kconfig"
 source "drivers/video/Kconfig"
 source "drivers/mci/Kconfig"
 source "drivers/clk/Kconfig"
+source "drivers/mfd/Kconfig"
 
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 71d34f9..242a564 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_I2C) += i2c/
 obj-$(CONFIG_MCI) += mci/
 obj-$(CONFIG_VIDEO) += video/
 obj-y	+= clk/
+obj-y	+= mfd/
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 9ce1655..c2af818 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -5,20 +5,4 @@ if I2C
 
 source drivers/i2c/busses/Kconfig
 
-config I2C_MC13892
-	bool "MC13892 a.k.a. PMIC driver"
-
-config I2C_MC34704
-	bool "MC34704 PMIC driver"
-
-config I2C_MC9SDZ60
-	bool "MC9SDZ60 driver"
-
-config I2C_LP3972
-	bool "LP3972 driver"
-
-config I2C_TWL4030
-	bool "TWL4030 driver"
-	select GPIO
-
 endif
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 0584b55..42e22c0 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -1,7 +1 @@
 obj-$(CONFIG_I2C) += i2c.o busses/
-
-obj-$(CONFIG_I2C_MC13892) += mc13892.o
-obj-$(CONFIG_I2C_MC34704) += mc34704.o
-obj-$(CONFIG_I2C_MC9SDZ60) += mc9sdz60.o
-obj-$(CONFIG_I2C_LP3972) += lp3972.o
-obj-$(CONFIG_I2C_TWL4030) += twl4030.o
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
new file mode 100644
index 0000000..7c27418
--- /dev/null
+++ b/drivers/mfd/Kconfig
@@ -0,0 +1,28 @@
+menu MFD
+
+config I2C_MC13892
+	depends on I2C
+	bool "MC13892 a.k.a. PMIC driver"
+
+config I2C_MC34704
+	depends on I2C
+	bool "MC34704 PMIC driver"
+
+config I2C_MC9SDZ60
+	depends on I2C
+	bool "MC9SDZ60 driver"
+
+config I2C_LP3972
+	depends on I2C
+	bool "LP3972 driver"
+
+config I2C_TWL4030
+	depends on I2C
+	bool "TWL4030 driver"
+	select GPIO
+
+config DRIVER_SPI_MC13783
+	depends on SPI
+	bool "MC13783 a.k.a. PMIC driver"
+
+endmenu
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
new file mode 100644
index 0000000..d411f23
--- /dev/null
+++ b/drivers/mfd/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_I2C_MC13892) += mc13892.o
+obj-$(CONFIG_I2C_MC34704) += mc34704.o
+obj-$(CONFIG_I2C_MC9SDZ60) += mc9sdz60.o
+obj-$(CONFIG_I2C_LP3972) += lp3972.o
+obj-$(CONFIG_I2C_TWL4030) += twl4030.o
+obj-$(CONFIG_DRIVER_SPI_MC13783) += mc13783.o
diff --git a/drivers/i2c/lp3972.c b/drivers/mfd/lp3972.c
similarity index 100%
rename from drivers/i2c/lp3972.c
rename to drivers/mfd/lp3972.c
diff --git a/drivers/spi/mc13783.c b/drivers/mfd/mc13783.c
similarity index 100%
rename from drivers/spi/mc13783.c
rename to drivers/mfd/mc13783.c
diff --git a/drivers/i2c/mc13892.c b/drivers/mfd/mc13892.c
similarity index 100%
rename from drivers/i2c/mc13892.c
rename to drivers/mfd/mc13892.c
diff --git a/drivers/i2c/mc34704.c b/drivers/mfd/mc34704.c
similarity index 100%
rename from drivers/i2c/mc34704.c
rename to drivers/mfd/mc34704.c
diff --git a/drivers/i2c/mc9sdz60.c b/drivers/mfd/mc9sdz60.c
similarity index 100%
rename from drivers/i2c/mc9sdz60.c
rename to drivers/mfd/mc9sdz60.c
diff --git a/drivers/i2c/twl4030.c b/drivers/mfd/twl4030.c
similarity index 100%
rename from drivers/i2c/twl4030.c
rename to drivers/mfd/twl4030.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 2b8d2f4..a88e179 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -19,8 +19,4 @@ config DRIVER_SPI_IMX_2_3
 	depends on ARCH_IMX51
 	default y
 
-config DRIVER_SPI_MC13783
-	bool "MC13783 a.k.a. PMIC driver"
-	depends on SPI
-
 endmenu
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 81f2c6b..b2b2f67 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -1,4 +1,2 @@
 obj-$(CONFIG_SPI) += spi.o
 obj-$(CONFIG_DRIVER_SPI_IMX) += imx_spi.o
-
-obj-$(CONFIG_DRIVER_SPI_MC13783) += mc13783.o
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:16 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:16 +0200
Subject: [PATCH 08/17] move include files for mfd drivers to include/mfd
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-9-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c |    2 +-
 arch/arm/boards/freescale-mx25-3-stack/3stack.c   |    2 +-
 arch/arm/boards/freescale-mx35-3-stack/3stack.c   |    4 ++--
 drivers/mfd/mc13892.c                             |    2 +-
 drivers/mfd/mc34704.c                             |    2 +-
 drivers/mfd/mc9sdz60.c                            |    2 +-
 drivers/mfd/twl4030.c                             |    2 +-
 drivers/usb/host/ehci-omap.c                      |    2 +-
 drivers/usb/otg/twl4030.c                         |    2 +-
 include/{i2c => mfd}/lp3972.h                     |    0
 include/{i2c => mfd}/mc13892.h                    |    8 ++++++++
 include/{i2c => mfd}/mc34704.h                    |    0
 include/{i2c => mfd}/mc9sdz60.h                   |    0
 include/{i2c => mfd}/twl4030.h                    |    0
 14 files changed, 18 insertions(+), 10 deletions(-)
 rename include/{i2c => mfd}/lp3972.h (100%)
 rename include/{i2c => mfd}/mc13892.h (95%)
 rename include/{i2c => mfd}/mc34704.h (100%)
 rename include/{i2c => mfd}/mc9sdz60.h (100%)
 rename include/{i2c => mfd}/twl4030.h (100%)

diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
index 4d1797b..cbc7500 100644
--- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
+++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
@@ -44,7 +44,7 @@
 #include <ns16550.h>
 #include <asm/mmu.h>
 #include <i2c/i2c.h>
-#include <i2c/lp3972.h>
+#include <mfd/lp3972.h>
 #include <mach/iomux-mx27.h>
 
 static struct device_d cfi_dev = {
diff --git a/arch/arm/boards/freescale-mx25-3-stack/3stack.c b/arch/arm/boards/freescale-mx25-3-stack/3stack.c
index 70de7958..25945f1 100644
--- a/arch/arm/boards/freescale-mx25-3-stack/3stack.c
+++ b/arch/arm/boards/freescale-mx25-3-stack/3stack.c
@@ -39,7 +39,7 @@
 #include <mach/generic.h>
 #include <linux/err.h>
 #include <i2c/i2c.h>
-#include <i2c/mc34704.h>
+#include <mfd/mc34704.h>
 
 extern unsigned long _stext;
 extern void exception_vectors(void);
diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
index 71aaa92..9b8d718 100644
--- a/arch/arm/boards/freescale-mx35-3-stack/3stack.c
+++ b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
@@ -50,8 +50,8 @@
 #include <mach/generic.h>
 
 #include <i2c/i2c.h>
-#include <i2c/mc13892.h>
-#include <i2c/mc9sdz60.h>
+#include <mfd/mc13892.h>
+#include <mfd/mc9sdz60.h>
 
 
 /* Board rev for the PDK 3stack */
diff --git a/drivers/mfd/mc13892.c b/drivers/mfd/mc13892.c
index 67d4232..240a7a9 100644
--- a/drivers/mfd/mc13892.c
+++ b/drivers/mfd/mc13892.c
@@ -26,7 +26,7 @@
 #include <errno.h>
 
 #include <i2c/i2c.h>
-#include <i2c/mc13892.h>
+#include <mfd/mc13892.h>
 
 #define DRIVERNAME		"mc13892"
 
diff --git a/drivers/mfd/mc34704.c b/drivers/mfd/mc34704.c
index 51a8737..a2171b3 100644
--- a/drivers/mfd/mc34704.c
+++ b/drivers/mfd/mc34704.c
@@ -27,7 +27,7 @@
 #include <errno.h>
 
 #include <i2c/i2c.h>
-#include <i2c/mc34704.h>
+#include <mfd/mc34704.h>
 
 #define DRIVERNAME		"mc34704"
 
diff --git a/drivers/mfd/mc9sdz60.c b/drivers/mfd/mc9sdz60.c
index 3580af8..db208ec 100644
--- a/drivers/mfd/mc9sdz60.c
+++ b/drivers/mfd/mc9sdz60.c
@@ -26,7 +26,7 @@
 #include <errno.h>
 
 #include <i2c/i2c.h>
-#include <i2c/mc9sdz60.h>
+#include <mfd/mc9sdz60.h>
 
 #define DRIVERNAME		"mc9sdz60"
 
diff --git a/drivers/mfd/twl4030.c b/drivers/mfd/twl4030.c
index 5305ec6..81bf48b 100644
--- a/drivers/mfd/twl4030.c
+++ b/drivers/mfd/twl4030.c
@@ -12,7 +12,7 @@
 #include <errno.h>
 
 #include <i2c/i2c.h>
-#include <i2c/twl4030.h>
+#include <mfd/twl4030.h>
 
 #define DRIVERNAME		"twl4030"
 
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 0c30c52..05f1628 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -11,7 +11,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-#include <i2c/twl4030.h>
+#include <mfd/twl4030.h>
 #include <usb/twl4030.h>
 #include <mach/ehci.h>
 #include <common.h>
diff --git a/drivers/usb/otg/twl4030.c b/drivers/usb/otg/twl4030.c
index 72edf25..4077169 100644
--- a/drivers/usb/otg/twl4030.c
+++ b/drivers/usb/otg/twl4030.c
@@ -37,7 +37,7 @@
  * MA 02111-1307 USA
  */
 
-#include <i2c/twl4030.h>
+#include <mfd/twl4030.h>
 #include <usb/twl4030.h>
 #include <clock.h>
 
diff --git a/include/i2c/lp3972.h b/include/mfd/lp3972.h
similarity index 100%
rename from include/i2c/lp3972.h
rename to include/mfd/lp3972.h
diff --git a/include/i2c/mc13892.h b/include/mfd/mc13892.h
similarity index 95%
rename from include/i2c/mc13892.h
rename to include/mfd/mc13892.h
index 112d05b..11ae878 100644
--- a/include/i2c/mc13892.h
+++ b/include/mfd/mc13892.h
@@ -79,9 +79,17 @@ enum mc13892_reg {
 	MC13892_REG_TEST4		= 0x3f,
 };
 
+enum mc13892_mode {
+	MC13892_MODE_I2C,
+	MC13892_MODE_SPI,
+};
+
 struct mc13892 {
 	struct cdev		cdev;
 	struct i2c_client	*client;
+	struct spi_device	*spi;
+	enum mc13892_mode	mode;
+	
 };
 
 extern struct mc13892 *mc13892_get(void);
diff --git a/include/i2c/mc34704.h b/include/mfd/mc34704.h
similarity index 100%
rename from include/i2c/mc34704.h
rename to include/mfd/mc34704.h
diff --git a/include/i2c/mc9sdz60.h b/include/mfd/mc9sdz60.h
similarity index 100%
rename from include/i2c/mc9sdz60.h
rename to include/mfd/mc9sdz60.h
diff --git a/include/i2c/twl4030.h b/include/mfd/twl4030.h
similarity index 100%
rename from include/i2c/twl4030.h
rename to include/mfd/twl4030.h
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:10 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:10 +0200
Subject: [PATCH 02/17] mci: Add i.MX esdhc support
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-3-git-send-email-s.hauer@pengutronix.de>

This adds a driver for the esdhc controller found on Freescale
i.MX25/35/51 SoCs.

This code is based on the U-Boot driver.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/Kconfig     |   13 ++
 drivers/mci/Makefile    |    1 +
 drivers/mci/imx-esdhc.c |  512 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mci/imx-esdhc.h |  164 +++++++++++++++
 4 files changed, 690 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mci/imx-esdhc.c
 create mode 100644 drivers/mci/imx-esdhc.h

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 0bc4254..b1f2773 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -48,4 +48,17 @@ config MCI_IMX
 	  Enable this entry to add support to read and write SD cards on a
 	  Freescale i.MX based system.
 
+config MCI_IMX_ESDHC
+	bool "i.MX esdhc"
+	depends on ARCH_IMX25 || ARCH_IMX35 || ARCH_IMX51
+	help
+	  Enable this entry to add support to read and write SD cards on a
+	  Freescale i.MX25/35/51 based system.
+
+config MCI_IMX_ESDHC_PIO
+	bool "use PIO mode"
+	depends on MCI_IMX_ESDHC
+	help
+	  mostly useful for debugging. Normally you should use DMA.
+
 endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index f393e93..a10cb47 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_MCI)	+= mci-core.o
 obj-$(CONFIG_MCI_STM378X) += stm378x.o
 obj-$(CONFIG_MCI_S3C) += s3c.o
 obj-$(CONFIG_MCI_IMX) += imx.o
+obj-$(CONFIG_MCI_IMX_ESDHC) += imx-esdhc.o
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
new file mode 100644
index 0000000..63cd059
--- /dev/null
+++ b/drivers/mci/imx-esdhc.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright 2007,2010 Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the pxa mmc code:
+ * (C) Copyright 2003
+ * Kyle Harris, Nexus Technologies, Inc. kharris at nexus-tech.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <malloc.h>
+#include <mci.h>
+#include <clock.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+#include <mach/clock.h>
+
+#include "imx-esdhc.h"
+
+struct fsl_esdhc {
+	u32	dsaddr;
+	u32	blkattr;
+	u32	cmdarg;
+	u32	xfertyp;
+	u32	cmdrsp0;
+	u32	cmdrsp1;
+	u32	cmdrsp2;
+	u32	cmdrsp3;
+	u32	datport;
+	u32	prsstat;
+	u32	proctl;
+	u32	sysctl;
+	u32	irqstat;
+	u32	irqstaten;
+	u32	irqsigen;
+	u32	autoc12err;
+	u32	hostcapblt;
+	u32	wml;
+	char	reserved1[8];
+	u32	fevt;
+	char	reserved2[168];
+	u32	hostver;
+	char	reserved3[780];
+	u32	scr;
+};
+
+struct fsl_esdhc_host {
+	struct mci_host		mci;
+	struct fsl_esdhc	*regs;
+	u32			no_snoop;
+	unsigned long		cur_clock;
+	struct device_d		*dev;
+};
+
+#define to_fsl_esdhc(mci)	container_of(mci, struct fsl_esdhc_host, mci)
+
+/* Return the XFERTYP flags for a given command and data packet */
+u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
+{
+	u32 xfertyp = 0;
+
+	if (data) {
+		xfertyp |= XFERTYP_DPSEL;
+#ifndef CONFIG_MCI_IMX_ESDHC_PIO
+		xfertyp |= XFERTYP_DMAEN;
+#endif
+		if (data->blocks > 1) {
+			xfertyp |= XFERTYP_MSBSEL;
+			xfertyp |= XFERTYP_BCEN;
+		}
+
+		if (data->flags & MMC_DATA_READ)
+			xfertyp |= XFERTYP_DTDSEL;
+	}
+
+	if (cmd->resp_type & MMC_RSP_CRC)
+		xfertyp |= XFERTYP_CCCEN;
+	if (cmd->resp_type & MMC_RSP_OPCODE)
+		xfertyp |= XFERTYP_CICEN;
+	if (cmd->resp_type & MMC_RSP_136)
+		xfertyp |= XFERTYP_RSPTYP_136;
+	else if (cmd->resp_type & MMC_RSP_BUSY)
+		xfertyp |= XFERTYP_RSPTYP_48_BUSY;
+	else if (cmd->resp_type & MMC_RSP_PRESENT)
+		xfertyp |= XFERTYP_RSPTYP_48;
+
+	return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
+}
+
+#ifdef CONFIG_MCI_IMX_ESDHC_PIO
+/*
+ * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
+ */
+static void
+esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
+{
+	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+	struct fsl_esdhc *regs = host->regs;
+	u32 blocks;
+	char *buffer;
+	u32 databuf;
+	u32 size;
+	u32 irqstat;
+	u32 timeout;
+
+	if (data->flags & MMC_DATA_READ) {
+		blocks = data->blocks;
+		buffer = data->dest;
+		while (blocks) {
+			timeout = PIO_TIMEOUT;
+			size = data->blocksize;
+			irqstat = esdhc_read32(&regs->irqstat);
+			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)
+				&& --timeout);
+			if (timeout <= 0) {
+				printf("\nData Read Failed in PIO Mode.");
+				return;
+			}
+			while (size && (!(irqstat & IRQSTAT_TC))) {
+				udelay(100); /* Wait before last byte transfer complete */
+				irqstat = esdhc_read32(&regs->irqstat);
+				databuf = esdhc_read32(&regs->datport);
+				*((u32 *)buffer) = databuf;
+				buffer += 4;
+				size -= 4;
+			}
+			blocks--;
+		}
+	} else {
+		blocks = data->blocks;
+		buffer = (char *)data->src;
+		while (blocks) {
+			timeout = PIO_TIMEOUT;
+			size = data->blocksize;
+			irqstat = esdhc_read32(&regs->irqstat);
+			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)
+				&& --timeout);
+			if (timeout <= 0) {
+				printf("\nData Write Failed in PIO Mode.");
+				return;
+			}
+			while (size && (!(irqstat & IRQSTAT_TC))) {
+				udelay(100); /* Wait before last byte transfer complete */
+				databuf = *((u32 *)buffer);
+				buffer += 4;
+				size -= 4;
+				irqstat = esdhc_read32(&regs->irqstat);
+				esdhc_write32(&regs->datport, databuf);
+			}
+			blocks--;
+		}
+	}
+}
+#endif
+
+static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
+{
+	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+	struct fsl_esdhc *regs = host->regs;
+#ifndef CONFIG_MCI_IMX_ESDHC_PIO
+	u32 wml_value;
+
+	wml_value = data->blocksize/4;
+
+	if (data->flags & MMC_DATA_READ) {
+		if (wml_value > 0x10)
+			wml_value = 0x10;
+
+		esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
+		esdhc_write32(&regs->dsaddr, (u32)data->dest);
+	} else {
+		if (wml_value > 0x80)
+			wml_value = 0x80;
+		if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
+			printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
+			return -ETIMEDOUT;
+		}
+
+		esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
+					wml_value << 16);
+		esdhc_write32(&regs->dsaddr, (u32)data->src);
+	}
+#else	/* CONFIG_MCI_IMX_ESDHC_PIO */
+	if (!(data->flags & MMC_DATA_READ)) {
+		if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
+			printf("\nThe SD card is locked. "
+				"Can not write to a locked card.\n\n");
+			return -ETIMEDOUT;
+		}
+		esdhc_write32(&regs->dsaddr, (u32)data->src);
+	} else
+		esdhc_write32(&regs->dsaddr, (u32)data->dest);
+#endif	/* CONFIG_MCI_IMX_ESDHC_PIO */
+
+	esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
+
+	return 0;
+}
+
+
+/*
+ * Sends a command out on the bus.  Takes the mci pointer,
+ * a command pointer, and an optional data pointer.
+ */
+static int
+esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
+{
+	u32	xfertyp;
+	u32	irqstat;
+	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+	struct fsl_esdhc *regs = host->regs;
+
+	esdhc_write32(&regs->irqstat, -1);
+
+	/* Wait for the bus to be idle */
+	while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
+			(esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
+		;
+
+	while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
+		;
+
+	/* Wait at least 8 SD clock cycles before the next command */
+	/*
+	 * Note: This is way more than 8 cycles, but 1ms seems to
+	 * resolve timing issues with some cards
+	 */
+	udelay(1000);
+
+	/* Set up for a data transfer if we have one */
+	if (data) {
+		int err;
+
+		err = esdhc_setup_data(mci, data);
+		if(err)
+			return err;
+		if (data->flags & MMC_DATA_WRITE) {
+			dma_flush_range((unsigned long)data->src,
+				(unsigned long)(data->src + 512));
+		} else
+			dma_clean_range((unsigned long)data->src,
+				(unsigned long)(data->src + 512));
+
+	}
+
+	/* Figure out the transfer arguments */
+	xfertyp = esdhc_xfertyp(cmd, data);
+
+	/* Send the command */
+	esdhc_write32(&regs->cmdarg, cmd->cmdarg);
+	esdhc_write32(&regs->xfertyp, xfertyp);
+
+	/* Wait for the command to complete */
+	while (!(esdhc_read32(&regs->irqstat) & IRQSTAT_CC))
+		;
+
+	irqstat = esdhc_read32(&regs->irqstat);
+	esdhc_write32(&regs->irqstat, irqstat);
+
+	if (irqstat & CMD_ERR)
+		return -EIO;
+
+	if (irqstat & IRQSTAT_CTOE)
+		return -ETIMEDOUT;
+
+	/* Copy the response to the response buffer */
+	if (cmd->resp_type & MMC_RSP_136) {
+		u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
+
+		cmdrsp3 = esdhc_read32(&regs->cmdrsp3);
+		cmdrsp2 = esdhc_read32(&regs->cmdrsp2);
+		cmdrsp1 = esdhc_read32(&regs->cmdrsp1);
+		cmdrsp0 = esdhc_read32(&regs->cmdrsp0);
+		cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
+		cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
+		cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
+		cmd->response[3] = (cmdrsp0 << 8);
+	} else
+		cmd->response[0] = esdhc_read32(&regs->cmdrsp0);
+
+	/* Wait until all of the blocks are transferred */
+	if (data) {
+#ifdef CONFIG_MCI_IMX_ESDHC_PIO
+		esdhc_pio_read_write(mci, data);
+#else
+		do {
+			irqstat = esdhc_read32(&regs->irqstat);
+
+			if (irqstat & DATA_ERR)
+				return -EIO;
+
+			if (irqstat & IRQSTAT_DTOE)
+				return -ETIMEDOUT;
+		} while (!(irqstat & IRQSTAT_TC) &&
+				(esdhc_read32(&regs->prsstat) & PRSSTAT_DLA));
+
+		if (data->flags & MMC_DATA_READ) {
+			dma_inv_range((unsigned long)data->dest,
+					(unsigned long)(data->dest + 512));
+		}
+#endif
+	}
+
+	esdhc_write32(&regs->irqstat, -1);
+
+	return 0;
+}
+
+void set_sysctl(struct mci_host *mci, u32 clock)
+{
+	int div, pre_div;
+	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+	struct fsl_esdhc *regs = host->regs;
+	int sdhc_clk = imx_get_mmcclk();
+	u32 clk;
+
+	if (clock < mci->f_min)
+		clock = mci->f_min;
+
+	pre_div = 0;
+
+	for (pre_div = 1; pre_div < 256; pre_div <<= 1) {
+		if (sdhc_clk / pre_div < clock * 16)
+			break;
+	};
+
+	div = sdhc_clk / pre_div / clock;
+
+	if (sdhc_clk / pre_div / div > clock)
+		div++;
+
+	host->cur_clock = sdhc_clk / pre_div / div;
+
+	div -= 1;
+	pre_div >>= 1;
+
+	dev_dbg(host->dev, "set clock: wanted: %d got: %d\n", clock, host->cur_clock);
+	dev_dbg(host->dev, "pre_div: %d div: %d\n", pre_div, div);
+
+	clk = (pre_div << 8) | (div << 4);
+
+	esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
+
+	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
+
+	udelay(10000);
+
+	clk = SYSCTL_PEREN | SYSCTL_CKEN;
+
+	esdhc_setbits32(&regs->sysctl, clk);
+}
+
+static void esdhc_set_ios(struct mci_host *mci, struct device_d *dev,
+		unsigned bus_width, unsigned clock)
+{
+	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+	struct fsl_esdhc *regs = host->regs;
+
+	/* Set the clock speed */
+	set_sysctl(mci, clock);
+
+	/* Set the bus width */
+	esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
+
+	if (bus_width == 4)
+		esdhc_setbits32(&regs->proctl, PROCTL_DTW_4);
+	else if (bus_width == 8)
+		esdhc_setbits32(&regs->proctl, PROCTL_DTW_8);
+
+}
+
+static int esdhc_init(struct mci_host *mci, struct device_d *dev)
+{
+	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+	struct fsl_esdhc *regs = host->regs;
+	int timeout = 1000;
+	int ret = 0;
+
+	/* Enable cache snooping */
+	if (host && !host->no_snoop)
+		esdhc_write32(&regs->scr, 0x00000040);
+
+	/* Reset the entire host controller */
+	esdhc_write32(&regs->sysctl, SYSCTL_RSTA);
+
+	/* Wait until the controller is available */
+	while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA) && --timeout)
+		udelay(1000);
+
+	esdhc_write32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
+
+	/* Set the initial clock speed */
+	set_sysctl(mci, 400000);
+
+	/* Disable the BRR and BWR bits in IRQSTAT */
+	esdhc_clrbits32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
+
+	/* Put the PROCTL reg back to the default */
+	esdhc_write32(&regs->proctl, PROCTL_INIT);
+
+	/* Set timout to the maximum value */
+	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
+
+	return ret;
+}
+
+static int esdhc_reset(struct fsl_esdhc *regs)
+{
+	uint64_t start;
+
+	/* reset the controller */
+	esdhc_write32(&regs->sysctl, SYSCTL_RSTA);
+
+	start = get_time_ns();
+	/* hardware clears the bit when it is done */
+	while (1) {
+		if (!(esdhc_read32(&regs->sysctl) & SYSCTL_RSTA))
+			break;
+		if (is_timeout(start, 100 * MSECOND)) {
+			printf("MMC/SD: Reset never completed.\n");
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static int fsl_esdhc_probe(struct device_d *dev)
+{
+	struct fsl_esdhc_host *host;
+	struct mci_host *mci;
+	u32 caps;
+	int ret;
+
+	host = xzalloc(sizeof(*host));
+	mci = &host->mci;
+
+	host->dev = dev;
+	host->regs = (struct fsl_esdhc *)dev->map_base;
+
+	/* First reset the eSDHC controller */
+	ret = esdhc_reset(host->regs);
+	if (ret) {
+		free(host);
+		return ret;
+	}
+
+	caps = esdhc_read32(&host->regs->hostcapblt);
+
+	if (caps & ESDHC_HOSTCAPBLT_VS18)
+		mci->voltages |= MMC_VDD_165_195;
+	if (caps & ESDHC_HOSTCAPBLT_VS30)
+		mci->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
+	if (caps & ESDHC_HOSTCAPBLT_VS33)
+		mci->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	mci->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
+
+	if (caps & ESDHC_HOSTCAPBLT_HSS)
+		mci->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+
+	host->mci.send_cmd = esdhc_send_cmd;
+	host->mci.set_ios = esdhc_set_ios;
+	host->mci.init = esdhc_init;
+	host->mci.host_caps = MMC_MODE_4BIT;
+
+	host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	host->mci.f_min = imx_get_mmcclk() >> 12;
+	if (host->mci.f_min < 200000)
+		host->mci.f_min = 200000;
+	host->mci.f_max = imx_get_mmcclk();
+
+	mci_register(&host->mci);
+
+	return 0;
+}
+
+static struct driver_d fsl_esdhc_driver = {
+        .name  = "imx-esdhc",
+        .probe = fsl_esdhc_probe,
+};
+
+static int fsl_esdhc_init_driver(void)
+{
+        register_driver(&fsl_esdhc_driver);
+        return 0;
+}
+
+device_initcall(fsl_esdhc_init_driver);
+
diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h
new file mode 100644
index 0000000..19fed5a
--- /dev/null
+++ b/drivers/mci/imx-esdhc.h
@@ -0,0 +1,164 @@
+/*
+ * FSL SD/MMC Defines
+ *-------------------------------------------------------------------
+ *
+ * Copyright 2007-2008,2010 Freescale Semiconductor, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *-------------------------------------------------------------------
+ *
+ */
+
+#ifndef  __FSL_ESDHC_H__
+#define	__FSL_ESDHC_H__
+
+#include <errno.h>
+#include <asm/byteorder.h>
+
+/* FSL eSDHC-specific constants */
+#define SYSCTL			0x0002e02c
+#define SYSCTL_INITA		0x08000000
+#define SYSCTL_TIMEOUT_MASK	0x000f0000
+#define SYSCTL_CLOCK_MASK	0x0000fff0
+#define SYSCTL_RSTA		0x01000000
+#define SYSCTL_CKEN		0x00000008
+#define SYSCTL_PEREN		0x00000004
+#define SYSCTL_HCKEN		0x00000002
+#define SYSCTL_IPGEN		0x00000001
+#define SYSCTL_RSTA		0x01000000
+
+#define IRQSTAT			0x0002e030
+#define IRQSTAT_DMAE		(0x10000000)
+#define IRQSTAT_AC12E		(0x01000000)
+#define IRQSTAT_DEBE		(0x00400000)
+#define IRQSTAT_DCE		(0x00200000)
+#define IRQSTAT_DTOE		(0x00100000)
+#define IRQSTAT_CIE		(0x00080000)
+#define IRQSTAT_CEBE		(0x00040000)
+#define IRQSTAT_CCE		(0x00020000)
+#define IRQSTAT_CTOE		(0x00010000)
+#define IRQSTAT_CINT		(0x00000100)
+#define IRQSTAT_CRM		(0x00000080)
+#define IRQSTAT_CINS		(0x00000040)
+#define IRQSTAT_BRR		(0x00000020)
+#define IRQSTAT_BWR		(0x00000010)
+#define IRQSTAT_DINT		(0x00000008)
+#define IRQSTAT_BGE		(0x00000004)
+#define IRQSTAT_TC		(0x00000002)
+#define IRQSTAT_CC		(0x00000001)
+
+#define CMD_ERR		(IRQSTAT_CIE | IRQSTAT_CEBE | IRQSTAT_CCE)
+#define DATA_ERR	(IRQSTAT_DEBE | IRQSTAT_DCE | IRQSTAT_DTOE)
+
+#define IRQSTATEN		0x0002e034
+#define IRQSTATEN_DMAE		(0x10000000)
+#define IRQSTATEN_AC12E		(0x01000000)
+#define IRQSTATEN_DEBE		(0x00400000)
+#define IRQSTATEN_DCE		(0x00200000)
+#define IRQSTATEN_DTOE		(0x00100000)
+#define IRQSTATEN_CIE		(0x00080000)
+#define IRQSTATEN_CEBE		(0x00040000)
+#define IRQSTATEN_CCE		(0x00020000)
+#define IRQSTATEN_CTOE		(0x00010000)
+#define IRQSTATEN_CINT		(0x00000100)
+#define IRQSTATEN_CRM		(0x00000080)
+#define IRQSTATEN_CINS		(0x00000040)
+#define IRQSTATEN_BRR		(0x00000020)
+#define IRQSTATEN_BWR		(0x00000010)
+#define IRQSTATEN_DINT		(0x00000008)
+#define IRQSTATEN_BGE		(0x00000004)
+#define IRQSTATEN_TC		(0x00000002)
+#define IRQSTATEN_CC		(0x00000001)
+
+#define PRSSTAT			0x0002e024
+#define PRSSTAT_CLSL		(0x00800000)
+#define PRSSTAT_WPSPL		(0x00080000)
+#define PRSSTAT_CDPL		(0x00040000)
+#define PRSSTAT_CINS		(0x00010000)
+#define PRSSTAT_BREN		(0x00000800)
+#define PRSSTAT_BWEN		(0x00000400)
+#define PRSSTAT_DLA		(0x00000004)
+#define PRSSTAT_CICHB		(0x00000002)
+#define PRSSTAT_CIDHB		(0x00000001)
+
+#define PROCTL			0x0002e028
+#define PROCTL_INIT		0x00000020
+#define PROCTL_DTW_4		0x00000002
+#define PROCTL_DTW_8		0x00000004
+
+#define CMDARG			0x0002e008
+
+#define XFERTYP			0x0002e00c
+#define XFERTYP_CMD(x)		((x & 0x3f) << 24)
+#define XFERTYP_CMDTYP_NORMAL	0x0
+#define XFERTYP_CMDTYP_SUSPEND	0x00400000
+#define XFERTYP_CMDTYP_RESUME	0x00800000
+#define XFERTYP_CMDTYP_ABORT	0x00c00000
+#define XFERTYP_DPSEL		0x00200000
+#define XFERTYP_CICEN		0x00100000
+#define XFERTYP_CCCEN		0x00080000
+#define XFERTYP_RSPTYP_NONE	0
+#define XFERTYP_RSPTYP_136	0x00010000
+#define XFERTYP_RSPTYP_48	0x00020000
+#define XFERTYP_RSPTYP_48_BUSY	0x00030000
+#define XFERTYP_MSBSEL		0x00000020
+#define XFERTYP_DTDSEL		0x00000010
+#define XFERTYP_AC12EN		0x00000004
+#define XFERTYP_BCEN		0x00000002
+#define XFERTYP_DMAEN		0x00000001
+
+#define CINS_TIMEOUT		1000
+#define PIO_TIMEOUT		100000
+
+#define DSADDR		0x2e004
+
+#define CMDRSP0		0x2e010
+#define CMDRSP1		0x2e014
+#define CMDRSP2		0x2e018
+#define CMDRSP3		0x2e01c
+
+#define DATPORT		0x2e020
+
+#define WML		0x2e044
+#define WML_WRITE	0x00010000
+#define WML_RD_WML_MASK	0xff
+#define WML_WR_WML_MASK	0xff0000
+
+#define BLKATTR		0x2e004
+#define BLKATTR_CNT(x)	((x & 0xffff) << 16)
+#define BLKATTR_SIZE(x)	(x & 0x1fff)
+#define MAX_BLK_CNT	0x7fff	/* so malloc will have enough room with 32M */
+
+#define ESDHC_HOSTCAPBLT_VS18	0x04000000
+#define ESDHC_HOSTCAPBLT_VS30	0x02000000
+#define ESDHC_HOSTCAPBLT_VS33	0x01000000
+#define ESDHC_HOSTCAPBLT_SRS	0x00800000
+#define ESDHC_HOSTCAPBLT_DMAS	0x00400000
+#define ESDHC_HOSTCAPBLT_HSS	0x00200000
+
+struct fsl_esdhc_cfg {
+	u32	esdhc_base;
+	u32	no_snoop;
+};
+
+#define esdhc_read32(a)			readl(a)
+#define esdhc_write32(a, v)		writel(v,a)
+#define esdhc_clrsetbits32(a, c, s)	writel((readl(a) & ~(c)) | (s), (a))
+#define esdhc_clrbits32(a, c)		writel(readl(a) & ~(c), (a))
+#define esdhc_setbits32(a, s)		writel(readl(a) | (s), (a))
+
+#endif  /* __FSL_ESDHC_H__ */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:25 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:25 +0200
Subject: [PATCH 17/17] ARM i.MX51: Add babbage board support
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-18-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/Makefile                                  |    1 +
 arch/arm/boards/freescale-mx51-pdk/Makefile        |    3 +
 arch/arm/boards/freescale-mx51-pdk/board.c         |  318 ++++++++++++++++++
 arch/arm/boards/freescale-mx51-pdk/config.h        |   24 ++
 arch/arm/boards/freescale-mx51-pdk/env/config      |   52 +++
 arch/arm/boards/freescale-mx51-pdk/flash_header.c  |   85 +++++
 arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S |  216 +++++++++++++
 arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox    |    4 +
 arch/arm/boards/freescale-mx51-pdk/spi.c           |  340 ++++++++++++++++++++
 arch/arm/configs/freescale_mx51_babbage_defconfig  |   43 +++
 arch/arm/mach-imx/Kconfig                          |    7 +
 11 files changed, 1093 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/Makefile
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/board.c
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/config.h
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/env/config
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/flash_header.c
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/spi.c
 create mode 100644 arch/arm/configs/freescale_mx51_babbage_defconfig

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77b6cf4..7f171c4 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -80,6 +80,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
 board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
+board-$(CONFIG_MACH_FREESCALE_MX51_PDK)		:= freescale-mx51-pdk
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/freescale-mx51-pdk/Makefile b/arch/arm/boards/freescale-mx51-pdk/Makefile
new file mode 100644
index 0000000..8e0c87c
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/Makefile
@@ -0,0 +1,3 @@
+obj-y += lowlevel_init.o
+obj-y += board.o
+obj-y += flash_header.o
diff --git a/arch/arm/boards/freescale-mx51-pdk/board.c b/arch/arm/boards/freescale-mx51-pdk/board.c
new file mode 100644
index 0000000..5197c55
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/board.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2007 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <net.h>
+#include <init.h>
+#include <environment.h>
+#include <mach/imx-regs.h>
+#include <fec.h>
+#include <mach/gpio.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <partition.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <nand.h>
+#include <spi/spi.h>
+#include <mfd/mc13892.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+#include <mach/imx-nand.h>
+#include <mach/spi.h>
+#include <mach/generic.h>
+#include <mach/iomux-mx51.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.id       = -1,
+	.name     = "mem",
+	.map_base = 0x90000000,
+	.size     = 512 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+static struct fec_platform_data fec_info = {
+	.xcv_type = MII100,
+};
+
+static struct device_d fec_dev = {
+	.name     = "fec_imx",
+	.map_base = 0x83fec000,
+	.platform_data	= &fec_info,
+};
+
+static struct device_d esdhc_dev = {
+	.name     = "imx-esdhc",
+	.map_base = 0x70004000,
+};
+
+static struct pad_desc f3s_pads[] = {
+	MX51_PAD_EIM_EB2__FEC_MDIO,
+	MX51_PAD_EIM_EB3__FEC_RDATA1,
+	MX51_PAD_EIM_CS2__FEC_RDATA2,
+	MX51_PAD_EIM_CS3__FEC_RDATA3,
+	MX51_PAD_EIM_CS4__FEC_RX_ER,
+	MX51_PAD_EIM_CS5__FEC_CRS,
+	MX51_PAD_NANDF_RB2__FEC_COL,
+	MX51_PAD_NANDF_RB3__FEC_RX_CLK,
+	MX51_PAD_NANDF_RB7__FEC_TX_ER,
+	MX51_PAD_NANDF_CS3__FEC_MDC,
+	MX51_PAD_NANDF_CS4__FEC_TDATA1,
+	MX51_PAD_NANDF_CS5__FEC_TDATA2,
+	MX51_PAD_NANDF_CS6__FEC_TDATA3,
+	MX51_PAD_NANDF_CS7__FEC_TX_EN,
+	MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK,
+	MX51_PAD_NANDF_D11__FEC_RX_DV,
+	MX51_PAD_NANDF_RB6__FEC_RDATA0,
+	MX51_PAD_NANDF_D8__FEC_TDATA0,
+	MX51_PAD_CSPI1_SS0__CSPI1_SS0,
+	MX51_PAD_CSPI1_MOSI__CSPI1_MOSI,
+	MX51_PAD_CSPI1_MISO__CSPI1_MISO,
+	MX51_PAD_CSPI1_RDY__CSPI1_RDY,
+	MX51_PAD_CSPI1_SCLK__CSPI1_SCLK,
+	MX51_PAD_EIM_A20__GPIO2_14, /* LAN8700 reset pin */
+	IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, 0x85), /* FIXME: needed? */
+};
+
+#ifdef CONFIG_MMU
+static void babbage_mmu_init(void)
+{
+	mmu_init();
+
+	arm_create_section(0x90000000, 0x90000000, 512, PMD_SECT_DEF_CACHED);
+	arm_create_section(0xb0000000, 0x90000000, 512, PMD_SECT_DEF_UNCACHED);
+
+	setup_dma_coherent(0x20000000);
+
+#if TEXT_BASE & (0x100000 - 1)
+#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
+#else
+	arm_create_section(0x0,        TEXT_BASE,   1, PMD_SECT_DEF_UNCACHED);
+#endif
+
+	mmu_enable();
+}
+#else
+static void babbage_mmu_init(void)
+{
+}
+#endif
+
+//extern int babbage_power_init(void);
+
+#define BABBAGE_ECSPI1_CS0	(3 * 32 + 24)
+static int spi_0_cs[] = {BABBAGE_ECSPI1_CS0};
+
+static struct spi_imx_master spi_0_data = {
+	.chipselect = spi_0_cs,
+	.num_chipselect = ARRAY_SIZE(spi_0_cs),
+};
+
+static struct device_d spi_dev = {
+	.id       = -1,
+	.name     = "imx_spi",
+	.map_base = MX51_CSPI1_BASE_ADDR,
+	.platform_data = &spi_0_data,
+};
+
+static const struct spi_board_info mx51_babbage_spi_board_info[] = {
+	{
+		.name = "mc13892-spi",
+		.max_speed_hz = 300000,
+		.bus_num = 0,
+		.chip_select = 0,
+	},
+};
+
+#define MX51_CCM_CACRR 0x10
+
+static void babbage_power_init(void)
+{
+	struct mc13892 *mc13892;
+	u32 val;
+
+	mc13892 = mc13892_get();
+	if (!mc13892) {
+		printf("could not get mc13892\n");
+		return;
+	}
+
+	/* Write needed to Power Gate 2 register */
+	mc13892_reg_read(mc13892, 34, &val);
+	val &= ~0x10000;
+	mc13892_reg_write(mc13892, 34, val);
+
+	/* Write needed to update Charger 0 */
+	mc13892_reg_write(mc13892, 48, 0x0023807F);
+
+	/* power up the system first */
+	mc13892_reg_write(mc13892, 34, 0x00200000);
+
+	if (imx_silicon_revision() < MX51_CHIP_REV_3_0) {
+		/* Set core voltage to 1.1V */
+		mc13892_reg_read(mc13892, 24, &val);
+		val &= ~0x1f;
+		val |= 0x14;
+		mc13892_reg_write(mc13892, 24, val);
+
+		/* Setup VCC (SW2) to 1.25 */
+		mc13892_reg_read(mc13892, 25, &val);
+		val &= ~0x1f;
+		val |= 0x1a;
+		mc13892_reg_write(mc13892, 25, val);
+
+		/* Setup 1V2_DIG1 (SW3) to 1.25 */
+		mc13892_reg_read(mc13892, 26, &val);
+		val &= ~0x1f;
+		val |= 0x1a;
+		mc13892_reg_write(mc13892, 26, val);
+		udelay(50);
+		/* Raise the core frequency to 800MHz */
+		writel(0x0, MX51_CCM_BASE_ADDR + MX51_CCM_CACRR);
+	} else {
+		/* Setup VCC (SW2) to 1.225 */
+		mc13892_reg_read(mc13892, 25, &val);
+		val &= ~0x1f;
+		val |= 0x19;
+		mc13892_reg_write(mc13892, 25, val);
+
+		/* Setup 1V2_DIG1 (SW3) to 1.2 */
+		mc13892_reg_read(mc13892, 26, &val);
+		val &= ~0x1f;
+		val |= 0x18;
+		mc13892_reg_write(mc13892, 26, val);
+	}
+
+	if (mc13892_get_revision(mc13892) < MC13892_REVISION_2_0) {
+		/* Set switchers in PWM mode for Atlas 2.0 and lower */
+		/* Setup the switcher mode for SW1 & SW2*/
+		mc13892_reg_read(mc13892, 28, &val);
+		val &= ~0x3c0f;
+		val |= 0x1405;
+		mc13892_reg_write(mc13892, 28, val);
+
+		/* Setup the switcher mode for SW3 & SW4 */
+		mc13892_reg_read(mc13892, 29, &val);
+		val &= ~0xf0f;
+		val |= 0x505;
+		mc13892_reg_write(mc13892, 29, val);
+	} else {
+		/* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */
+		/* Setup the switcher mode for SW1 & SW2*/
+		mc13892_reg_read(mc13892, 28, &val);
+		val &= ~0x3c0f;
+		val |= 0x2008;
+		mc13892_reg_write(mc13892, 28, val);
+
+		/* Setup the switcher mode for SW3 & SW4 */
+		mc13892_reg_read(mc13892, 29, &val);
+		val &= ~0xf0f;
+		val |= 0x808;
+		mc13892_reg_write(mc13892, 29, val);
+	}
+
+	/* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */
+	mc13892_reg_read(mc13892, 30, &val);
+	val &= ~0x34030;
+	val |= 0x10020;
+	mc13892_reg_write(mc13892, 30, val);
+
+	/* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */
+	mc13892_reg_read(mc13892, 31, &val);
+	val &= ~0x1FC;
+	val |= 0x1F4;
+	mc13892_reg_write(mc13892, 31, val);
+
+	/* Configure VGEN3 and VCAM regulators to use external PNP */
+	val = 0x208;
+	mc13892_reg_write(mc13892, 33, val);
+	udelay(200);
+#define GPIO_LAN8700_RESET	(1 * 32 + 14)
+
+	/* Reset the ethernet controller over GPIO */
+	gpio_direction_output(GPIO_LAN8700_RESET, 0);
+
+	/* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */
+	val = 0x49249;
+	mc13892_reg_write(mc13892, 33, val);
+
+	udelay(500);
+
+	gpio_set_value(GPIO_LAN8700_RESET, 1);
+}
+
+static int f3s_devices_init(void)
+{
+	babbage_mmu_init();
+
+	register_device(&sdram_dev);
+	register_device(&fec_dev);
+	register_device(&esdhc_dev);
+
+	spi_register_board_info(mx51_babbage_spi_board_info,
+			ARRAY_SIZE(mx51_babbage_spi_board_info));
+	register_device(&spi_dev);
+
+	babbage_power_init();
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void *)0x90000100);
+	armlinux_set_architecture(MACH_TYPE_MX51_BABBAGE);
+
+	return 0;
+}
+
+device_initcall(f3s_devices_init);
+
+static int f3s_part_init(void)
+{
+	devfs_add_partition("disk0", 0x00000, 0x40000, PARTITION_FIXED, "self0");
+	devfs_add_partition("disk0", 0x40000, 0x20000, PARTITION_FIXED, "env0");
+
+	return 0;
+}
+late_initcall(f3s_part_init);
+
+static struct device_d f3s_serial_device = {
+	.name     = "imx_serial",
+	.map_base = 0x73fbc000,
+	.size     = 4096,
+};
+
+static int f3s_console_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(f3s_pads, ARRAY_SIZE(f3s_pads));
+
+	writel(0, 0x73fa8228);
+	writel(0, 0x73fa822c);
+	writel(0, 0x73fa8230);
+	writel(0, 0x73fa8234);
+
+	register_device(&f3s_serial_device);
+	return 0;
+}
+
+console_initcall(f3s_console_init);
+
diff --git a/arch/arm/boards/freescale-mx51-pdk/config.h b/arch/arm/boards/freescale-mx51-pdk/config.h
new file mode 100644
index 0000000..b7effe5
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/config.h
@@ -0,0 +1,24 @@
+/**
+ * @file
+ * @brief Global defintions for the ARM i.MX51 based babbage board
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/freescale-mx51-pdk/env/config b/arch/arm/boards/freescale-mx51-pdk/env/config
new file mode 100644
index 0000000..d9b8407
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/env/config
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+machine=babbage
+eth0.serverip=
+user=
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.netmask=a.b.c.d
+#eth0.gateway=a.b.c.d
+#eth0.serverip=a.b.c.d
+
+# can be either 'net', 'nor' or 'nand'
+kernel_loc=net
+# can be either 'net', 'nor', 'nand' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root-$machine.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+kernelimage_type=zimage
+kernelimage=zImage-$machine
+#kernelimage_type=uimage
+#kernelimage=uImage-$machine
+#kernelimage_type=raw
+#kernelimage=Image-$machine
+#kernelimage_type=raw_lzo
+#kernelimage=Image-$machine.lzo
+
+if [ -n $user ]; then
+	kernelimage="$user"-"$kernelimage"
+	nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine"
+	rootfsimage="$user"-"$rootfsimage"
+else
+	nfsroot="$eth0.serverip:/path/to/nfs/root"
+fi
+
+autoboot_timeout=3
+
+bootargs="console=ttymxc0,115200"
+
+disk_parts="256k(barebox)ro,128k(bareboxenv),4M(kernel),-(root)"
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m "
+
diff --git a/arch/arm/boards/freescale-mx51-pdk/flash_header.c b/arch/arm/boards/freescale-mx51-pdk/flash_header.c
new file mode 100644
index 0000000..5f94506
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/flash_header.c
@@ -0,0 +1,85 @@
+#include <common.h>
+#include <mach/imx-flash-header.h>
+
+extern unsigned long _stext;
+
+void __naked __flash_header_start go(void)
+{
+	__asm__ __volatile__("b exception_vectors\n");
+}
+
+struct imx_dcd_entry __dcd_entry_section dcd_entry[] = {
+	{ .ptr_type = 4, .addr = 0x73fa88a0, .val = 0x00000200, },
+	{ .ptr_type = 4, .addr = 0x73fa850c, .val = 0x000020c5, },
+	{ .ptr_type = 4, .addr = 0x73fa8510, .val = 0x000020c5, },
+	{ .ptr_type = 4, .addr = 0x73fa883c, .val = 0x00000002, },
+	{ .ptr_type = 4, .addr = 0x73fa8848, .val = 0x00000002, },
+	{ .ptr_type = 4, .addr = 0x73fa84b8, .val = 0x000000e7, },
+	{ .ptr_type = 4, .addr = 0x73fa84bc, .val = 0x00000045, },
+	{ .ptr_type = 4, .addr = 0x73fa84c0, .val = 0x00000045, },
+	{ .ptr_type = 4, .addr = 0x73fa84c4, .val = 0x00000045, },
+	{ .ptr_type = 4, .addr = 0x73fa84c8, .val = 0x00000045, },
+	{ .ptr_type = 4, .addr = 0x73fa8820, .val = 0x00000000, },
+	{ .ptr_type = 4, .addr = 0x73fa84a4, .val = 0x00000003, },
+	{ .ptr_type = 4, .addr = 0x73fa84a8, .val = 0x00000003, },
+	{ .ptr_type = 4, .addr = 0x73fa84ac, .val = 0x000000e3, },
+	{ .ptr_type = 4, .addr = 0x73fa84b0, .val = 0x000000e3, },
+	{ .ptr_type = 4, .addr = 0x73fa84b4, .val = 0x000000e3, },
+	{ .ptr_type = 4, .addr = 0x73fa84cc, .val = 0x000000e3, },
+	{ .ptr_type = 4, .addr = 0x73fa84d0, .val = 0x000000e2, },
+	{ .ptr_type = 4, .addr = 0x73fa882c, .val = 0x00000004, },
+	{ .ptr_type = 4, .addr = 0x73fa88a4, .val = 0x00000004, },
+	{ .ptr_type = 4, .addr = 0x73fa88ac, .val = 0x00000004, },
+	{ .ptr_type = 4, .addr = 0x73fa88b8, .val = 0x00000004, },
+	{ .ptr_type = 4, .addr = 0x83fd9000, .val = 0x82a20000, },
+	{ .ptr_type = 4, .addr = 0x83fd9008, .val = 0x82a20000, },
+	{ .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad0d0, },
+	{ .ptr_type = 4, .addr = 0x83fd9004, .val = 0x3f3584ab, },
+	{ .ptr_type = 4, .addr = 0x83fd900c, .val = 0x3f3584ab, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801a, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801b, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00448019, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x07328018, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x06328018, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x03808019, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00408019, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008000, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801e, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801f, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801d, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0732801c, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0632801c, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0380801d, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0040801d, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008004, },
+	{ .ptr_type = 4, .addr = 0x83fd9000, .val = 0xb2a20000, },
+	{ .ptr_type = 4, .addr = 0x83fd9008, .val = 0xb2a20000, },
+	{ .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad6d0, },
+	{ .ptr_type = 4, .addr = 0x83fd9034, .val = 0x90000000, },
+	{ .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00000000, },
+};
+
+#define APP_DEST	0x90000000
+
+struct imx_flash_header __flash_header_section flash_header = {
+	.app_code_jump_vector	= APP_DEST + 0x1000,
+	.app_code_barker	= APP_CODE_BARKER,
+	.app_code_csf		= 0,
+	.dcd_ptr_ptr		= APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd),
+	.super_root_key		= 0,
+	.dcd			= APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd_barker),
+	.app_dest		= APP_DEST,
+	.dcd_barker		= DCD_BARKER,
+	.dcd_block_len		= sizeof (dcd_entry),
+};
+
+unsigned long __image_len_section barebox_len = 0x40000;
+
diff --git a/arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S b/arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S
new file mode 100644
index 0000000..793104c
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S
@@ -0,0 +1,216 @@
+/*
+ * This code is based on the ecos babbage startup code
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <mach/imx-regs.h>
+#include <mach/clock-imx51.h>
+
+#define ROM_SI_REV_OFFSET                   0x48
+
+.macro setup_pll pll, freq
+	ldr r2, =\pll
+	ldr r1, =0x00001232
+	str r1, [r2, #MX51_PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
+	mov r1, #0x2
+	str r1, [r2, #MX51_PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
+
+	str r3, [r2, #MX51_PLL_DP_OP]
+	str r3, [r2, #MX51_PLL_DP_HFS_OP]
+
+	str r4, [r2, #MX51_PLL_DP_MFD]
+	str r4, [r2, #MX51_PLL_DP_HFS_MFD]
+
+	str r5, [r2, #MX51_PLL_DP_MFN]
+	str r5, [r2, #MX51_PLL_DP_HFS_MFN]
+
+	ldr r1, =0x00001232
+	str r1, [r2, #MX51_PLL_DP_CTL]
+1:	ldr r1, [r2, #MX51_PLL_DP_CTL]
+	ands r1, r1, #0x1
+	beq 1b
+.endm
+
+#define writel(val, reg) \
+	ldr		r0,	=reg;	\
+	ldr		r1,	=val;	\
+	str		r1,   [r0];
+
+#define IMX51_TO_2
+
+.globl board_init_lowlevel
+board_init_lowlevel:
+	mov     r10, lr
+
+	/* explicitly disable L2 cache */
+	mrc 15, 0, r0, c1, c0, 1
+	bic r0, r0, #0x2
+	mcr 15, 0, r0, c1, c0, 1
+
+	/* reconfigure L2 cache aux control reg */
+	mov r0, #0xC0               /* tag RAM */
+	add r0, r0, #0x4    /* data RAM */
+	orr r0, r0, #(1 << 24)    /* disable write allocate delay */
+	orr r0, r0, #(1 << 23)    /* disable write allocate combine */
+	orr r0, r0, #(1 << 22)    /* disable write allocate */
+
+	ldr r1, =MX51_IROM_BASE_ADDR
+	ldr r3, [r1, #ROM_SI_REV_OFFSET]
+	cmp r3, #0x10
+	orrls r0, r0, #(1 << 25)    /* disable write combine for TO 2 and lower revs */
+
+	mcr 15, 1, r0, c9, c0, 2
+
+	ldr r0, =MX51_CCM_BASE_ADDR
+
+	/* Gate of clocks to the peripherals first */
+	ldr r1, =0x3FFFFFFF
+	str r1, [r0, #MX51_CCM_CCGR0]
+	ldr r1, =0x0
+	str r1, [r0, #MX51_CCM_CCGR1]
+	str r1, [r0, #MX51_CCM_CCGR2]
+	str r1, [r0, #MX51_CCM_CCGR3]
+
+	ldr r1, =0x00030000
+	str r1, [r0, #MX51_CCM_CCGR4]
+	ldr r1, =0x00FFF030
+	str r1, [r0, #MX51_CCM_CCGR5]
+	ldr r1, =0x00000300
+	str r1, [r0, #MX51_CCM_CCGR6]
+
+	/* Disable IPU and HSC dividers */
+	mov r1, #0x60000
+	str r1, [r0, #MX51_CCM_CCDR]
+
+#ifdef IMX51_TO_2
+	/* Make sure to switch the DDR away from PLL 1 */
+	ldr r1, =0x19239145
+	str r1, [r0, #MX51_CCM_CBCDR]
+	/* make sure divider effective */
+1:	ldr r1, [r0, #MX51_CCM_CDHIPR]
+	cmp r1, #0x0
+	bne 1b
+#endif
+
+	/* Switch ARM to step clock */
+	mov r1, #0x4
+	str r1, [r0, #MX51_CCM_CCSR]
+
+	mov r3, #MX51_PLL_DP_OP_800
+	mov r4, #MX51_PLL_DP_MFD_800
+	mov r5, #MX51_PLL_DP_MFN_800
+	setup_pll MX51_PLL1_BASE_ADDR
+
+	mov r3, #MX51_PLL_DP_OP_665
+	mov r4, #MX51_PLL_DP_MFD_665
+	mov r5, #MX51_PLL_DP_MFN_665
+	setup_pll MX51_PLL3_BASE_ADDR
+
+	/* Switch peripheral to PLL 3 */
+	ldr r1, =0x000010C0
+	str r1, [r0, #MX51_CCM_CBCMR]
+	ldr r1, =0x13239145
+	str r1, [r0, #MX51_CCM_CBCDR]
+
+	mov r3, #MX51_PLL_DP_OP_665
+	mov r4, #MX51_PLL_DP_MFD_665
+	mov r5, #MX51_PLL_DP_MFN_665
+	setup_pll MX51_PLL2_BASE_ADDR
+
+	/* Switch peripheral to PLL2 */
+	ldr r1, =0x19239145
+	str r1, [r0, #MX51_CCM_CBCDR]
+	ldr r1, =0x000020C0
+	str r1, [r0, #MX51_CCM_CBCMR]
+
+	mov r3, #MX51_PLL_DP_OP_216
+	mov r4, #MX51_PLL_DP_MFD_216
+	mov r5, #MX51_PLL_DP_MFN_216
+	setup_pll MX51_PLL3_BASE_ADDR
+
+	/* Set the platform clock dividers */
+	ldr r2, =MX51_ARM_BASE_ADDR
+	ldr r1, =0x00000124
+	str r1, [r2, #0x14]
+
+	/* Run TO 3.0 at Full speed, for other TO's wait till we increase VDDGP */
+	ldr r1, =MX51_IROM_BASE_ADDR
+	ldr r3, [r1, #ROM_SI_REV_OFFSET]
+	cmp r3, #0x10
+	movls r1, #0x1
+	movhi r1, #0
+	str r1, [r0, #MX51_CCM_CACRR]
+
+	/* Switch ARM back to PLL 1 */
+	mov r1, #0
+	str r1, [r0,  #MX51_CCM_CCSR]
+
+        /* setup the rest */
+        /* Use lp_apm (24MHz) source for perclk */
+#ifdef IMX51_TO_2
+        ldr r1, =0x000020C2
+        str r1, [r0, #MX51_CCM_CBCMR]
+        // ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz
+        ldr r1, =0x59239100
+        str r1, [r0, #MX51_CCM_CBCDR]
+#else
+        ldr r1, =0x0000E3C2
+        str r1, [r0, #MX51_CCM_CBCMR]
+        // emi=ahb, all perclk dividers are 1 since using 24MHz
+        // DDR divider=6 to have 665/6=110MHz
+        ldr r1, =0x013B9100
+        str r1, [r0, #MX51_CCM_CBCDR]
+#endif
+
+        /* Restore the default values in the Gate registers */
+        ldr r1, =0xFFFFFFFF
+        str r1, [r0, #MX51_CCM_CCGR0]
+        str r1, [r0, #MX51_CCM_CCGR1]
+        str r1, [r0, #MX51_CCM_CCGR2]
+        str r1, [r0, #MX51_CCM_CCGR3]
+        str r1, [r0, #MX51_CCM_CCGR4]
+        str r1, [r0, #MX51_CCM_CCGR5]
+        str r1, [r0, #MX51_CCM_CCGR6]
+
+        /* Use PLL 2 for UART's, get 66.5MHz from it */
+        ldr r1, =0xA5A2A020
+        str r1, [r0, #MX51_CCM_CSCMR1]
+        ldr r1, =0x00C30321
+        str r1, [r0, #MX51_CCM_CSCDR1]
+
+        /* make sure divider effective */
+    1:  ldr r1, [r0, #MX51_CCM_CDHIPR]
+        cmp r1, #0x0
+        bne 1b
+
+	mov r1, #0x0
+	str r1, [r0, #MX51_CCM_CCDR]
+
+	writel(0x1, 0x73fa8074)
+	ldr	r0, =0x73f88000
+	ldr	r1, [r0]
+	orr	r1, #0x40
+	str	r1, [r0]
+
+	ldr	r0, =0x73f88004
+	ldr	r1, [r0]
+	orr	r1, #0x40
+	str	r1, [r0]
+
+	mov	pc, r10
+
diff --git a/arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox b/arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox
new file mode 100644
index 0000000..7d04df6
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox
@@ -0,0 +1,4 @@
+/** @page Freescale i.MX51 PDK (Babbage) Board
+
+
+*/
diff --git a/arch/arm/boards/freescale-mx51-pdk/spi.c b/arch/arm/boards/freescale-mx51-pdk/spi.c
new file mode 100644
index 0000000..8eabe81
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/spi.c
@@ -0,0 +1,340 @@
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <gpio.h>
+
+#define IMX_SPI_ACTIVE_HIGH	1
+#define SPI_RETRY_TIMES		100
+#define CLKCTL_CACRR		0x10
+#define REV_ATLAS_LITE_2_0	0x10
+
+/* Only for SPI master support */
+struct imx_spi_dev {
+	unsigned int base;	// base address of SPI module the device is connected to
+	unsigned int freq;	// desired clock freq in Hz for this device
+	unsigned int ss_pol;	// ss polarity: 1=active high; 0=active low
+	unsigned int ss;	// slave select
+	unsigned int in_sctl;	// inactive sclk ctl: 1=stay low; 0=stay high
+	unsigned int in_dctl;	// inactive data ctl: 1=stay low; 0=stay high
+	unsigned int ssctl;	// single burst mode vs multiple: 0=single; 1=multi
+	unsigned int sclkpol;	// sclk polarity: active high=0; active low=1
+	unsigned int sclkpha;	// sclk phase: 0=phase 0; 1=phase1
+	unsigned int fifo_sz;	// fifo size in bytes for either tx or rx. Don't add them up!
+	unsigned int ctrl_reg;
+	unsigned int cfg_reg;
+};
+
+struct imx_spi_dev imx_spi_pmic = {
+      .base	= MX51_CSPI1_BASE_ADDR,
+      .freq	= 25000000,
+      .ss_pol	= IMX_SPI_ACTIVE_HIGH,
+      .ss	= 0, /* slave select 0 */
+      .fifo_sz	= 32,
+};
+
+/*
+ * Initialization function for a spi slave device. It must be called BEFORE
+ * any spi operations. The SPI module will be -disabled- after this call.
+ */
+static int imx_spi_init(struct imx_spi_dev *dev)
+{
+	unsigned int clk_src = 66500000;
+	unsigned int pre_div = 0, post_div = 0, i, reg_ctrl = 0, reg_config = 0;
+
+	if (dev->freq == 0) {
+		printf("Error: desired clock is 0\n");
+		return -1;
+	}
+
+	/* control register setup */
+	if (clk_src > dev->freq) {
+		pre_div = clk_src / dev->freq;
+		if (pre_div > 16) {
+			post_div = pre_div / 16;
+			pre_div = 15;
+		}
+		if (post_div != 0) {
+			for (i = 0; i < 16; i++) {
+				if ((1 << i) >= post_div)
+					break;
+			}
+			if (i == 16) {
+				printf
+				    ("Error: no divider can meet the freq: %d\n",
+				     dev->freq);
+				return -1;
+			}
+			post_div = i;
+		}
+	}
+	debug("pre_div = %d, post_div=%d\n", pre_div, post_div);
+	reg_ctrl |= pre_div << 12;
+	reg_ctrl |= post_div << 8;
+	reg_ctrl |= 1 << (dev->ss + 4);	/* always set to master mode */
+
+	/* configuration register setup */
+	reg_config |= dev->ss_pol << (dev->ss + 12);
+	reg_config |= dev->in_sctl << (dev->ss + 20);
+	reg_config |= dev->in_dctl << (dev->ss + 16);
+	reg_config |= dev->ssctl << (dev->ss + 8);
+	reg_config |= dev->sclkpol << (dev->ss + 4);
+	reg_config |= dev->sclkpha << (dev->ss + 0);
+
+	debug("reg_ctrl = 0x%x\n", reg_ctrl);
+	/* reset the spi */
+	writel(0, dev->base + 0x8);
+	writel(reg_ctrl, dev->base + 0x8);
+	debug("reg_config = 0x%x\n", reg_config);
+	writel(reg_config, dev->base + 0xC);
+	/* save control register */
+	dev->cfg_reg = reg_config;
+	dev->ctrl_reg = reg_ctrl;
+
+	/* clear interrupt reg */
+	writel(0, dev->base + 0x10);
+	writel(3 << 6, dev->base + 0x18);
+
+	return 0;
+}
+
+static int imx_spi_xfer(struct imx_spi_dev *dev,	/* spi device pointer */
+		  void *tx_buf,	/* tx buffer (has to be 4-byte aligned) */
+		  void *rx_buf,	/* rx buffer (has to be 4-byte aligned) */
+		  int burst_bits	/* total number of bits in one burst (or xfer) */
+    )
+{
+	int val = SPI_RETRY_TIMES;
+	unsigned int *p_buf;
+	unsigned int reg;
+	int len, ret_val = 0;
+	int burst_bytes = burst_bits / 8;
+
+	/* Account for rounding of non-byte aligned burst sizes */
+	if ((burst_bits % 8) != 0)
+		burst_bytes++;
+
+	if (burst_bytes > dev->fifo_sz) {
+		printf("Error: maximum burst size is 0x%x bytes, asking 0x%x\n",
+		       dev->fifo_sz, burst_bytes);
+		return -1;
+	}
+
+	dev->ctrl_reg = (dev->ctrl_reg & ~0xFFF00000) | ((burst_bits - 1) << 20);
+	writel(dev->ctrl_reg | 0x1, dev->base + 0x8);
+	writel(dev->cfg_reg, dev->base + 0xC);
+	debug("ctrl_reg=0x%x, cfg_reg=0x%x\n",
+	       readl(dev->base + 0x8), readl(dev->base + 0xC));
+
+	/* move data to the tx fifo */
+	len = burst_bytes;
+	for (p_buf = tx_buf; len > 0; p_buf++, len -= 4)
+		writel(*p_buf, dev->base + 0x4);
+
+	reg = readl(dev->base + 0x8);
+	reg |= (1 << 2);	/* set xch bit */
+	writel(reg, dev->base + 0x8);
+
+	/* poll on the TC bit (transfer complete) */
+	while ((val-- > 0) && (readl(dev->base + 0x18) & (1 << 7)) == 0);
+
+	/* clear the TC bit */
+	writel(3 << 6, dev->base + 0x18);
+
+	if (val == 0) {
+		printf("Error: re-tried %d times without response. Give up\n",
+		       SPI_RETRY_TIMES);
+		ret_val = -1;
+		goto error;
+	}
+
+	/* move data in the rx buf */
+	len = burst_bytes;
+	for (p_buf = rx_buf; len > 0; p_buf++, len -= 4)
+		*p_buf = readl(dev->base + 0x0);
+
+error:
+	writel(0, dev->base + 0x8);
+	return ret_val;
+}
+
+/*
+ * To read/write to a PMIC register. For write, it does another read for the
+ * actual register value.
+ *
+ * @param   reg         register number inside the PMIC
+ * @param   val         data to be written to the register; don't care for read
+ * @param   write       0 for read; 1 for write
+ *
+ * @return              the actual data in the PMIC register
+ */
+static unsigned int
+pmic_reg(unsigned int reg, unsigned int val, unsigned int write)
+{
+	static unsigned int pmic_tx, pmic_rx;
+
+	if (reg > 63 || write > 1) {
+		printf("<reg num> = %d is invalid. Should be less then 63\n",
+		       reg);
+		return 0;
+	}
+	pmic_tx = (write << 31) | (reg << 25) | (val & 0x00FFFFFF);
+	debug("reg=0x%x, val=0x%08x\n", reg, pmic_tx);
+
+	imx_spi_xfer(&imx_spi_pmic, (unsigned char *) &pmic_tx,
+			  (unsigned char *) &pmic_rx, (4 * 8));
+
+	if (write) {
+		pmic_tx &= ~(1 << 31);
+		imx_spi_xfer(&imx_spi_pmic, (unsigned char *) &pmic_tx,
+				  (unsigned char *) &pmic_rx, (4 * 8));
+	}
+
+	return pmic_rx;
+}
+
+static void show_pmic_info(void)
+{
+	unsigned int rev_id;
+	char *rev;
+
+	rev_id = pmic_reg(7, 0, 0);
+
+	switch (rev_id & 0x1F) {
+	case 0x1: rev = "1.0"; break;
+	case 0x9: rev = "1.1"; break;
+	case 0xa: rev = "1.2"; break;
+	case 0x10:
+		if (((rev_id >> 9) & 0x3) == 0)
+			rev = "2.0";
+		else
+			rev = "2.0a";
+		break;
+	case 0x11: rev = "2.1"; break;
+	case 0x18: rev = "3.0"; break;
+	case 0x19: rev = "3.1"; break;
+	case 0x1a: rev = "3.2"; break;
+	case 0x2: rev = "3.2a"; break;
+	case 0x1b: rev = "3.3"; break;
+	case 0x1d: rev = "3.5"; break;
+	default: rev = "unknown"; break;
+	}
+
+	printf("PMIC ID: 0x%08x [Rev: %s]\n", rev_id, rev);
+}
+
+int babbage_power_init(void)
+{
+	unsigned int val;
+	unsigned int reg;
+
+	imx_spi_init(&imx_spi_pmic);
+
+	show_pmic_info();
+
+	/* Write needed to Power Gate 2 register */
+	val = pmic_reg(34, 0, 0);
+	val &= ~0x10000;
+	pmic_reg(34, val, 1);
+
+	/* Write needed to update Charger 0 */
+	pmic_reg(48, 0x0023807F, 1);
+
+	/* power up the system first */
+	pmic_reg(34, 0x00200000, 1);
+
+	if (1) {
+		/* Set core voltage to 1.1V */
+		val = pmic_reg(24, 0, 0);
+		val &= ~0x1f;
+		val |= 0x14;
+		pmic_reg(24, val, 1);
+
+		/* Setup VCC (SW2) to 1.25 */
+		val = pmic_reg(25, 0, 0);
+		val &= ~0x1f;
+		val |= 0x1a;
+		pmic_reg(25, val, 1);
+
+		/* Setup 1V2_DIG1 (SW3) to 1.25 */
+		val = pmic_reg(26, 0, 0);
+		val &= ~0x1f;
+		val |= 0x1a;
+		pmic_reg(26, val, 1);
+		udelay(50);
+		/* Raise the core frequency to 800MHz */
+		writel(0x0, MX51_CCM_BASE_ADDR + CLKCTL_CACRR);
+	} else {
+		/* TO 3.0 */
+		/* Setup VCC (SW2) to 1.225 */
+		val = pmic_reg(25, 0, 0);
+		val &= ~0x1f;
+		val |= 0x19;
+		pmic_reg(25, val, 1);
+
+		/* Setup 1V2_DIG1 (SW3) to 1.2 */
+		val = pmic_reg(26, 0, 0);
+		val &= ~0x1f;
+		val |= 0x18;
+		pmic_reg(26, val, 1);
+	}
+
+	if (((pmic_reg(7, 0, 0) & 0x1F) < REV_ATLAS_LITE_2_0)
+	    || (((pmic_reg(7, 0, 0) >> 9) & 0x3) == 0)) {
+		/* Set switchers in PWM mode for Atlas 2.0 and lower */
+		/* Setup the switcher mode for SW1 & SW2 */
+		val = pmic_reg(28, 0, 0);
+		val &= ~0x3c0f;
+		val |= 0x1405;
+		pmic_reg(28, val, 1);
+
+		/* Setup the switcher mode for SW3 & SW4 */
+		val = pmic_reg(29, 0, 0);
+		val &= ~0xf0f;
+		val |= 0x505;
+		pmic_reg(29, val, 1);
+	} else {
+		/* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */
+		/* Setup the switcher mode for SW1 & SW2 */
+		val = pmic_reg(28, 0, 0);
+		val &= ~0x3c0f;
+		val |= 0x2008;
+		pmic_reg(28, val, 1);
+
+		/* Setup the switcher mode for SW3 & SW4 */
+		val = pmic_reg(29, 0, 0);
+		val &= ~0xf0f;
+		val |= 0x808;
+		pmic_reg(29, val, 1);
+	}
+
+	/* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */
+	val = pmic_reg(30, 0, 0);
+	val &= ~0x34030;
+	val |= 0x10020;
+	pmic_reg(30, val, 1);
+
+	/* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */
+	val = pmic_reg(31, 0, 0);
+	val &= ~0x1FC;
+	val |= 0x1F4;
+	pmic_reg(31, val, 1);
+
+	/* Configure VGEN3 and VCAM regulators to use external PNP */
+	val = 0x208;
+	pmic_reg(33, val, 1);
+	udelay(200);
+
+	gpio_direction_output(32 + 14, 0); /* Lower reset line */
+
+	/* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */
+	val = 0x49249;
+	pmic_reg(33, val, 1);
+
+	udelay(500);
+
+	gpio_set_value(32 + 14, 1);
+
+	return 0;
+}
+
diff --git a/arch/arm/configs/freescale_mx51_babbage_defconfig b/arch/arm/configs/freescale_mx51_babbage_defconfig
new file mode 100644
index 0000000..d99d91a
--- /dev/null
+++ b/arch/arm/configs/freescale_mx51_babbage_defconfig
@@ -0,0 +1,43 @@
+CONFIG_ARCH_IMX=y
+CONFIG_ARCH_IMX_INTERNAL_BOOT=y
+CONFIG_ARCH_IMX51=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_TEXT_BASE=0x97f00000
+CONFIG_MALLOC_SIZE=0x2000000
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/freescale-mx51-pdk/env/"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+CONFIG_DRIVER_SPI_IMX=y
+CONFIG_DRIVER_CFI=y
+CONFIG_CFI_BUFFER_WRITE=y
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_IMX_ESDHC=y
+CONFIG_I2C_MC13892=y
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index f143e60..d451875 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -17,6 +17,7 @@ config ARCH_TEXT_BASE
 	default 0x87f00000 if MACH_PCM043
 	default 0x08f80000 if MACH_SCB9328
 	default 0xa7e00000 if MACH_NESO
+	default 0x97f00000 if MACH_MX51_PDK
 
 config BOARDINFO
 	default "Eukrea CPUIMX25" if MACH_EUKREA_CPUIMX25
@@ -32,6 +33,7 @@ config BOARDINFO
 	default "Phytec phyCORE-i.MX35" if MACH_PCM043
 	default "Synertronixx scb9328" if MACH_SCB9328
 	default "Garz+Fricke Neso" if MACH_NESO
+	default "Freescale i.MX51 PDK" if MACH_FREESCALE_MX51_PDK
 
 config ARCH_HAS_FEC_IMX
 	bool
@@ -309,6 +311,11 @@ choice
 
 	prompt "i.MX51 Board Type"
 
+config MACH_FREESCALE_MX51_PDK
+	bool "Freescale i.MX51 PDK"
+	select HAVE_MMU
+	select MACH_HAS_LOWLEVEL_INIT
+
 endchoice
 
 endif
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Oct 11 07:28:24 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 13:28:24 +0200
Subject: [PATCH 16/17] ARM i.MX: Add basic i.MX51 support
In-Reply-To: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1286796505-16049-17-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/Kconfig                    |   17 +-
 arch/arm/mach-imx/Makefile                   |    1 +
 arch/arm/mach-imx/imx51.c                    |   51 ++
 arch/arm/mach-imx/include/mach/clock-imx51.h |  696 ++++++++++++++++++++++++++
 arch/arm/mach-imx/include/mach/generic.h     |    6 +
 arch/arm/mach-imx/include/mach/imx-regs.h    |    2 +
 arch/arm/mach-imx/include/mach/imx51-regs.h  |  131 +++++
 arch/arm/mach-imx/include/mach/iomux-mx51.h  |  330 ++++++++++++
 arch/arm/mach-imx/include/mach/iomux-v3.h    |   10 +-
 arch/arm/mach-imx/speed-imx51.c              |  163 ++++++
 include/asm-generic/barebox.lds.h            |    2 +-
 11 files changed, 1404 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/mach-imx/include/mach/clock-imx51.h
 create mode 100644 arch/arm/mach-imx/include/mach/imx51-regs.h
 create mode 100644 arch/arm/mach-imx/include/mach/iomux-mx51.h
 create mode 100644 arch/arm/mach-imx/speed-imx51.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 4f95393..f143e60 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -38,7 +38,7 @@ config ARCH_HAS_FEC_IMX
 
 config ARCH_IMX_INTERNAL_BOOT
 	bool "support internal boot mode"
-	depends on ARCH_IMX25 || ARCH_IMX35
+	depends on ARCH_IMX25 || ARCH_IMX35 || ARCH_IMX51
 
 choice
 	depends on ARCH_IMX_INTERNAL_BOOT
@@ -94,6 +94,11 @@ config ARCH_IMX35
 	select CPU_V6
 	select ARCH_HAS_FEC_IMX
 
+config ARCH_IMX51
+	bool "i.MX51"
+	select CPU_V7
+	select ARCH_HAS_FEC_IMX
+
 endchoice
 
 # ----------------------------------------------------------
@@ -298,6 +303,16 @@ endif
 
 # ----------------------------------------------------------
 
+if ARCH_IMX51
+
+choice
+
+	prompt "i.MX51 Board Type"
+
+endchoice
+
+endif
+
 menu "Board specific settings       "
 
 if MACH_PCM043
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index de62f7e..ce38566 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_ARCH_IMX21) += speed-imx21.o imx21.o iomux-v1.o
 obj-$(CONFIG_ARCH_IMX27) += speed-imx27.o imx27.o iomux-v1.o
 obj-$(CONFIG_ARCH_IMX31) += speed-imx31.o imx31.o iomux-v2.o
 obj-$(CONFIG_ARCH_IMX35) += speed-imx35.o imx35.o iomux-v3.o
+obj-$(CONFIG_ARCH_IMX51) += speed-imx51.o imx51.o iomux-v3.o
 obj-$(CONFIG_IMX_CLKO)	+= clko.o
 obj-$(CONFIG_IMX_IIM)	+= iim.o
 obj-$(CONFIG_NAND_IMX) += nand.o
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index 8c4fc11..075ed22 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -15,7 +15,10 @@
  * MA 02111-1307 USA
  */
 
+#include <init.h>
 #include <common.h>
+#include <asm/io.h>
+#include <mach/imx51-regs.h>
 
 #include "gpio.h"
 
@@ -28,3 +31,51 @@ void *imx_gpio_base[] = {
 
 int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32;
 
+#define SI_REV 0x48
+
+static u32 mx51_silicon_revision;
+static char *mx51_rev_string = "unknown";
+
+int imx_silicon_revision(void)
+{
+	return mx51_silicon_revision;
+}
+
+static int query_silicon_revision(void)
+{
+	void __iomem *rom = MX51_IROM_BASE_ADDR;
+	u32 rev;
+
+	rev = readl(rom + SI_REV);
+	switch (rev) {
+	case 0x1:
+		mx51_silicon_revision = MX51_CHIP_REV_1_0;
+		mx51_rev_string = "1.0";
+		break;
+	case 0x2:
+		mx51_silicon_revision = MX51_CHIP_REV_1_1;
+		mx51_rev_string = "1.1";
+		break;
+	case 0x10:
+		mx51_silicon_revision = MX51_CHIP_REV_2_0;
+		mx51_rev_string = "2.0";
+		break;
+	case 0x20:
+		mx51_silicon_revision = MX51_CHIP_REV_3_0;
+		mx51_rev_string = "3.0";
+		break;
+	default:
+		mx51_silicon_revision = 0;
+	}
+
+	return 0;
+}
+core_initcall(query_silicon_revision);
+
+static int imx51_print_silicon_rev(void)
+{
+	printf("detected i.MX51 rev %s\n", mx51_rev_string);
+
+	return 0;
+}
+device_initcall(imx51_print_silicon_rev);
diff --git a/arch/arm/mach-imx/include/mach/clock-imx51.h b/arch/arm/mach-imx/include/mach/clock-imx51.h
new file mode 100644
index 0000000..0dee7c3
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/clock-imx51.h
@@ -0,0 +1,696 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+
+/* PLL Register Offsets */
+#define MX51_PLL_DP_CTL			0x00
+#define MX51_PLL_DP_CONFIG		0x04
+#define MX51_PLL_DP_OP			0x08
+#define MX51_PLL_DP_MFD			0x0C
+#define MX51_PLL_DP_MFN			0x10
+#define MX51_PLL_DP_MFNMINUS		0x14
+#define MX51_PLL_DP_MFNPLUS		0x18
+#define MX51_PLL_DP_HFS_OP		0x1C
+#define MX51_PLL_DP_HFS_MFD		0x20
+#define MX51_PLL_DP_HFS_MFN		0x24
+#define MX51_PLL_DP_MFN_TOGC		0x28
+#define MX51_PLL_DP_DESTAT		0x2c
+
+/* PLL Register Bit definitions */
+#define MX51_PLL_DP_CTL_MUL_CTRL		0x2000
+#define MX51_PLL_DP_CTL_DPDCK0_2_EN	0x1000
+#define MX51_PLL_DP_CTL_DPDCK0_2_OFFSET	12
+#define MX51_PLL_DP_CTL_ADE		0x800
+#define MX51_PLL_DP_CTL_REF_CLK_DIV	0x400
+#define MX51_PLL_DP_CTL_REF_CLK_SEL_MASK	(3 << 8)
+#define MX51_PLL_DP_CTL_REF_CLK_SEL_OFFSET	8
+#define MX51_PLL_DP_CTL_HFSM		0x80
+#define MX51_PLL_DP_CTL_PRE		0x40
+#define MX51_PLL_DP_CTL_UPEN		0x20
+#define MX51_PLL_DP_CTL_RST		0x10
+#define MX51_PLL_DP_CTL_RCP		0x8
+#define MX51_PLL_DP_CTL_PLM		0x4
+#define MX51_PLL_DP_CTL_BRM0		0x2
+#define MX51_PLL_DP_CTL_LRF		0x1
+
+#define MX51_PLL_DP_CONFIG_BIST		0x8
+#define MX51_PLL_DP_CONFIG_SJC_CE	0x4
+#define MX51_PLL_DP_CONFIG_AREN		0x2
+#define MX51_PLL_DP_CONFIG_LDREQ		0x1
+
+#define MX51_PLL_DP_OP_MFI_OFFSET	4
+#define MX51_PLL_DP_OP_MFI_MASK		(0xF << 4)
+#define MX51_PLL_DP_OP_PDF_OFFSET	0
+#define MX51_PLL_DP_OP_PDF_MASK		0xF
+
+#define MX51_PLL_DP_MFD_OFFSET		0
+#define MX51_PLL_DP_MFD_MASK		0x07FFFFFF
+
+#define MX51_PLL_DP_MFN_OFFSET		0x0
+#define MX51_PLL_DP_MFN_MASK		0x07FFFFFF
+
+#define MX51_PLL_DP_MFN_TOGC_TOG_DIS	(1 << 17)
+#define MX51_PLL_DP_MFN_TOGC_TOG_EN	(1 << 16)
+#define MX51_PLL_DP_MFN_TOGC_CNT_OFFSET	0x0
+#define MX51_PLL_DP_MFN_TOGC_CNT_MASK	0xFFFF
+
+#define MX51_PLL_DP_DESTAT_TOG_SEL	(1 << 31)
+#define MX51_PLL_DP_DESTAT_MFN		0x07FFFFFF
+
+/* Assuming 24MHz input clock with doubler ON */
+/*                            MFI         PDF */
+#define MX51_PLL_DP_OP_850	((8 << 4) + ((1 - 1)  << 0))
+#define MX51_PLL_DP_MFD_850	(48 - 1)
+#define MX51_PLL_DP_MFN_850	41
+
+#define MX51_PLL_DP_OP_800	((8 << 4) + ((1 - 1)  << 0))
+#define MX51_PLL_DP_MFD_800	(3 - 1)
+#define MX51_PLL_DP_MFN_800	1
+
+#define MX51_PLL_DP_OP_700	((7 << 4) + ((1 - 1)  << 0))
+#define MX51_PLL_DP_MFD_700	(24 - 1)
+#define MX51_PLL_DP_MFN_700	7
+
+#define MX51_PLL_DP_OP_665	((6 << 4) + ((1 - 1)  << 0))
+#define MX51_PLL_DP_MFD_665	(96 - 1)
+#define MX51_PLL_DP_MFN_665	89
+
+#define MX51_PLL_DP_OP_532	((5 << 4) + ((1 - 1)  << 0))
+#define MX51_PLL_DP_MFD_532	(24 - 1)
+#define MX51_PLL_DP_MFN_532	13
+
+#define MX51_PLL_DP_OP_400	((8 << 4) + ((2 - 1)  << 0))
+#define MX51_PLL_DP_MFD_400	(3 - 1)
+#define MX51_PLL_DP_MFN_400	1
+
+#define MX51_PLL_DP_OP_216	((6 << 4) + ((3 - 1)  << 0))
+#define MX51_PLL_DP_MFD_216	(4 - 1)
+#define MX51_PLL_DP_MFN_216	3
+
+/* Register addresses of CCM*/
+#define MX51_CCM_CCR		0x00
+#define MX51_CCM_CCDR		0x04
+#define MX51_CCM_CSR		0x08
+#define MX51_CCM_CCSR		0x0C
+#define MX51_CCM_CACRR		0x10
+#define MX51_CCM_CBCDR		0x14
+#define MX51_CCM_CBCMR		0x18
+#define MX51_CCM_CSCMR1		0x1C
+#define MX51_CCM_CSCMR2		0x20
+#define MX51_CCM_CSCDR1		0x24
+#define MX51_CCM_CS1CDR		0x28
+#define MX51_CCM_CS2CDR		0x2C
+#define MX51_CCM_CDCDR		0x30
+#define MX51_CCM_CHSCDR		0x34
+#define MX51_CCM_CSCDR2		0x38
+#define MX51_CCM_CSCDR3		0x3C
+#define MX51_CCM_CSCDR4		0x40
+#define MX51_CCM_CWDR		0x44
+#define MX51_CCM_CDHIPR		0x48
+#define MX51_CCM_CDCR		0x4C
+#define MX51_CCM_CTOR		0x50
+#define MX51_CCM_CLPCR		0x54
+#define MX51_CCM_CISR		0x58
+#define MX51_CCM_CIMR		0x5C
+#define MX51_CCM_CCOSR		0x60
+#define MX51_CCM_CGPR		0x64
+#define MX51_CCM_CCGR0		0x68
+#define MX51_CCM_CCGR1		0x6C
+#define MX51_CCM_CCGR2		0x70
+#define MX51_CCM_CCGR3		0x74
+#define MX51_CCM_CCGR4		0x78
+#define MX51_CCM_CCGR5		0x7C
+#define MX51_CCM_CCGR6		0x80
+#define MX51_CCM_CMEOR		0x84
+
+/* Define the bits in register CCR */
+#define MX51_CCM_CCR_COSC_EN		(1 << 12)
+#define MX51_CCM_CCR_FPM_MULT_MASK	(1 << 11)
+#define MX51_CCM_CCR_CAMP2_EN		(1 << 10)
+#define MX51_CCM_CCR_CAMP1_EN		(1 << 9)
+#define MX51_CCM_CCR_FPM_EN		(1 << 8)
+#define MX51_CCM_CCR_OSCNT_OFFSET	(0)
+#define MX51_CCM_CCR_OSCNT_MASK	(0xFF)
+
+/* Define the bits in register CCDR */
+#define MX51_CCM_CCDR_HSC_HS_MASK	(0x1 << 18)
+#define MX51_CCM_CCDR_IPU_HS_MASK	(0x1 << 17)
+#define MX51_CCM_CCDR_EMI_HS_MASK	(0x1 << 16)
+
+/* Define the bits in register CSR */
+#define MX51_CCM_CSR_COSR_READY	(1 << 5)
+#define MX51_CCM_CSR_LVS_VALUE		(1 << 4)
+#define MX51_CCM_CSR_CAMP2_READY	(1 << 3)
+#define MX51_CCM_CSR_CAMP1_READY	(1 << 2)
+#define MX51_CCM_CSR_FPM_READY	(1 << 1)
+#define MX51_CCM_CSR_REF_EN_B		(1 << 0)
+
+/* Define the bits in register CCSR */
+#define MX51_CCM_CCSR_LP_APM_SEL		(0x1 << 9)
+#define MX51_CCM_CCSR_STEP_SEL_OFFSET		(7)
+#define MX51_CCM_CCSR_STEP_SEL_MASK		(0x3 << 7)
+#define MX51_CCM_CCSR_PLL2_PODF_OFFSET	(5)
+#define MX51_CCM_CCSR_PLL2_PODF_MASK		(0x3 << 5)
+#define MX51_CCM_CCSR_PLL3_PODF_OFFSET	(3)
+#define MX51_CCM_CCSR_PLL3_PODF_MASK		(0x3 << 3)
+#define MX51_CCM_CCSR_PLL1_SW_CLK_SEL		(1 << 2)
+#define MX51_CCM_CCSR_PLL2_SW_CLK_SEL		(1 << 1)
+#define MX51_CCM_CCSR_PLL3_SW_CLK_SEL		(1 << 0)
+
+/* Define the bits in register CACRR */
+#define MX51_CCM_CACRR_ARM_PODF_OFFSET	(0)
+#define MX51_CCM_CACRR_ARM_PODF_MASK		(0x7)
+
+/* Define the bits in register CBCDR */
+#define MX51_CCM_CBCDR_EMI_CLK_SEL			(0x1 << 26)
+#define MX51_CCM_CBCDR_PERIPH_CLK_SEL			(0x1 << 25)
+#define MX51_CCM_CBCDR_DDR_HF_SEL_OFFSET		(30)
+#define MX51_CCM_CBCDR_DDR_HF_SEL			(0x1 << 30)
+#define MX51_CCM_CBCDR_DDR_PODF_OFFSET		(27)
+#define MX51_CCM_CBCDR_DDR_PODF_MASK			(0x7 << 27)
+#define MX51_CCM_CBCDR_EMI_PODF_OFFSET		(22)
+#define MX51_CCM_CBCDR_EMI_PODF_MASK			(0x7 << 22)
+#define MX51_CCM_CBCDR_AXI_B_PODF_OFFSET		(19)
+#define MX51_CCM_CBCDR_AXI_B_PODF_MASK		(0x7 << 19)
+#define MX51_CCM_CBCDR_AXI_A_PODF_OFFSET		(16)
+#define MX51_CCM_CBCDR_AXI_A_PODF_MASK		(0x7 << 16)
+#define MX51_CCM_CBCDR_NFC_PODF_OFFSET		(13)
+#define MX51_CCM_CBCDR_NFC_PODF_MASK			(0x7 << 13)
+#define MX51_CCM_CBCDR_AHB_PODF_OFFSET		(10)
+#define MX51_CCM_CBCDR_AHB_PODF_MASK			(0x7 << 10)
+#define MX51_CCM_CBCDR_IPG_PODF_OFFSET		(8)
+#define MX51_CCM_CBCDR_IPG_PODF_MASK			(0x3 << 8)
+#define MX51_CCM_CBCDR_PERCLK_PRED1_OFFSET		(6)
+#define MX51_CCM_CBCDR_PERCLK_PRED1_MASK		(0x3 << 6)
+#define MX51_CCM_CBCDR_PERCLK_PRED2_OFFSET		(3)
+#define MX51_CCM_CBCDR_PERCLK_PRED2_MASK		(0x7 << 3)
+#define MX51_CCM_CBCDR_PERCLK_PODF_OFFSET		(0)
+#define MX51_CCM_CBCDR_PERCLK_PODF_MASK		(0x7)
+
+/* Define the bits in register CBCMR */
+#define MX51_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET	(14)
+#define MX51_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK		(0x3 << 14)
+#define MX51_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET		(12)
+#define MX51_CCM_CBCMR_PERIPH_CLK_SEL_MASK		(0x3 << 12)
+#define MX51_CCM_CBCMR_DDR_CLK_SEL_OFFSET		(10)
+#define MX51_CCM_CBCMR_DDR_CLK_SEL_MASK		(0x3 << 10)
+#define MX51_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET	(8)
+#define MX51_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK		(0x3 << 8)
+#define MX51_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET	(6)
+#define MX51_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK		(0x3 << 6)
+#define MX51_CCM_CBCMR_GPU_CLK_SEL_OFFSET		(4)
+#define MX51_CCM_CBCMR_GPU_CLK_SEL_MASK		(0x3 << 4)
+#define MX51_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET        (14)
+#define MX51_CCM_CBCMR_GPU2D_CLK_SEL_MASK      (0x3 << 14)
+#define MX51_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL		(0x1 << 1)
+#define MX51_CCM_CBCMR_PERCLK_IPG_CLK_SEL		(0x1 << 0)
+
+/* Define the bits in register CSCMR1 */
+#define MX51_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET		(30)
+#define MX51_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK		(0x3 << 30)
+#define MX51_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET		(28)
+#define MX51_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK		(0x3 << 28)
+#define MX51_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET		(26)
+#define MX51_CCM_CSCMR1_USB_PHY_CLK_SEL			(0x1 << 26)
+#define MX51_CCM_CSCMR1_UART_CLK_SEL_OFFSET			(24)
+#define MX51_CCM_CSCMR1_UART_CLK_SEL_MASK			(0x3 << 24)
+#define MX51_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET		(22)
+#define MX51_CCM_CSCMR1_USBOH3_CLK_SEL_MASK			(0x3 << 22)
+#define MX51_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET	(20)
+#define MX51_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK		(0x3 << 20)
+#define MX51_CCM_CSCMR1_ESDHC3_CLK_SEL			(0x1 << 19)
+#define MX51_CCM_CSCMR1_ESDHC4_CLK_SEL			(0x1 << 18)
+#define MX51_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET	(16)
+#define MX51_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK		(0x3 << 16)
+#define MX51_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET			(14)
+#define MX51_CCM_CSCMR1_SSI1_CLK_SEL_MASK			(0x3 << 14)
+#define MX51_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET			(12)
+#define MX51_CCM_CSCMR1_SSI2_CLK_SEL_MASK			(0x3 << 12)
+#define MX51_CCM_CSCMR1_SSI3_CLK_SEL				(0x1 << 11)
+#define MX51_CCM_CSCMR1_VPU_RCLK_SEL				(0x1 << 10)
+#define MX51_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET		(8)
+#define MX51_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK		(0x3 << 8)
+#define MX51_CCM_CSCMR1_TVE_CLK_SEL				(0x1 << 7)
+#define MX51_CCM_CSCMR1_TVE_EXT_CLK_SEL			(0x1 << 6)
+#define MX51_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET			(4)
+#define MX51_CCM_CSCMR1_CSPI_CLK_SEL_MASK			(0x3 << 4)
+#define MX51_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET			(2)
+#define MX51_CCM_CSCMR1_SPDIF_CLK_SEL_MASK			(0x3 << 2)
+#define MX51_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL			(0x1 << 1)
+#define MX51_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL			(0x1)
+
+/* Define the bits in register CSCMR2 */
+#define MX51_CCM_CSCMR2_DI_CLK_SEL_OFFSET(n)		(26+n*3)
+#define MX51_CCM_CSCMR2_DI_CLK_SEL_MASK(n)		(0x7 << (26+n*3))
+#define MX51_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET	(24)
+#define MX51_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK	(0x3 << 24)
+#define MX51_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET	(22)
+#define MX51_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK	(0x3 << 22)
+#define MX51_CCM_CSCMR2_ESC_CLK_SEL_OFFSET		(20)
+#define MX51_CCM_CSCMR2_ESC_CLK_SEL_MASK		(0x3 << 20)
+#define MX51_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET		(18)
+#define MX51_CCM_CSCMR2_HSC2_CLK_SEL_MASK		(0x3 << 18)
+#define MX51_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET		(16)
+#define MX51_CCM_CSCMR2_HSC1_CLK_SEL_MASK		(0x3 << 16)
+#define MX51_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET		(14)
+#define MX51_CCM_CSCMR2_HSI2C_CLK_SEL_MASK		(0x3 << 14)
+#define MX51_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET		(12)
+#define MX51_CCM_CSCMR2_FIRI_CLK_SEL_MASK		(0x3 << 12)
+#define MX51_CCM_CSCMR2_SIM_CLK_SEL_OFFSET		(10)
+#define MX51_CCM_CSCMR2_SIM_CLK_SEL_MASK		(0x3 << 10)
+#define MX51_CCM_CSCMR2_SLIMBUS_COM			(0x1 << 9)
+#define MX51_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET	(6)
+#define MX51_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK		(0x7 << 6)
+#define MX51_CCM_CSCMR2_SPDIF1_COM			(1 << 5)
+#define MX51_CCM_CSCMR2_SPDIF0_COM			(1 << 4)
+#define MX51_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET	(2)
+#define MX51_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK		(0x3 << 2)
+#define MX51_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET	(0)
+#define MX51_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK		(0x3)
+
+/* Define the bits in register CSCDR1 */
+#define MX51_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET	(22)
+#define MX51_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK		(0x7 << 22)
+#define MX51_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET	(19)
+#define MX51_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK		(0x7 << 19)
+#define MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET	(16)
+#define MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK		(0x7 << 16)
+#define MX51_CCM_CSCDR1_PGC_CLK_PODF_OFFSET			(14)
+#define MX51_CCM_CSCDR1_PGC_CLK_PODF_MASK			(0x3 << 14)
+#define MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET	(11)
+#define MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK		(0x7 << 11)
+#define MX51_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET		(8)
+#define MX51_CCM_CSCDR1_USBOH3_CLK_PRED_MASK		(0x7 << 8)
+#define MX51_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET		(6)
+#define MX51_CCM_CSCDR1_USBOH3_CLK_PODF_MASK		(0x3 << 6)
+#define MX51_CCM_CSCDR1_UART_CLK_PRED_OFFSET		(3)
+#define MX51_CCM_CSCDR1_UART_CLK_PRED_MASK			(0x7 << 3)
+#define MX51_CCM_CSCDR1_UART_CLK_PODF_OFFSET		(0)
+#define MX51_CCM_CSCDR1_UART_CLK_PODF_MASK			(0x7)
+
+/* Define the bits in register CS1CDR and CS2CDR */
+#define MX51_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET	(22)
+#define MX51_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK	(0x7 << 22)
+#define MX51_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET	(16)
+#define MX51_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK	(0x3F << 16)
+#define MX51_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET		(6)
+#define MX51_CCM_CS1CDR_SSI1_CLK_PRED_MASK		(0x7 << 6)
+#define MX51_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET		(0)
+#define MX51_CCM_CS1CDR_SSI1_CLK_PODF_MASK		(0x3F)
+
+#define MX51_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET	(22)
+#define MX51_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK	(0x7 << 22)
+#define MX51_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET	(16)
+#define MX51_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK	(0x3F << 16)
+#define MX51_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET		(6)
+#define MX51_CCM_CS2CDR_SSI2_CLK_PRED_MASK		(0x7 << 6)
+#define MX51_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET		(0)
+#define MX51_CCM_CS2CDR_SSI2_CLK_PODF_MASK		(0x3F)
+
+/* Define the bits in register CDCDR */
+#define MX51_CCM_CDCDR_TVE_CLK_PRED_OFFSET		(28)
+#define MX51_CCM_CDCDR_TVE_CLK_PRED_MASK		(0x7 << 28)
+#define MX51_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET	(25)
+#define MX51_CCM_CDCDR_SPDIF0_CLK_PRED_MASK		(0x7 << 25)
+#define MX51_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET	(19)
+#define MX51_CCM_CDCDR_SPDIF0_CLK_PODF_MASK		(0x3F << 19)
+#define MX51_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET	(16)
+#define MX51_CCM_CDCDR_SPDIF1_CLK_PRED_MASK		(0x7 << 16)
+#define MX51_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET	(9)
+#define MX51_CCM_CDCDR_SPDIF1_CLK_PODF_MASK		(0x3F << 9)
+#define MX51_CCM_CDCDR_DI_CLK_PRED_OFFSET		(6)
+#define MX51_CCM_CDCDR_DI_CLK_PRED_MASK		(0x7 << 6)
+#define MX51_CCM_CDCDR_USB_PHY_PRED_OFFSET		(3)
+#define MX51_CCM_CDCDR_USB_PHY_PRED_MASK		(0x7 << 3)
+#define MX51_CCM_CDCDR_USB_PHY_PODF_OFFSET		(0)
+#define MX51_CCM_CDCDR_USB_PHY_PODF_MASK		(0x7)
+
+/* Define the bits in register CHSCCDR */
+#define MX51_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET		(12)
+#define MX51_CCM_CHSCCDR_ESC_CLK_PRED_MASK		(0x7 << 12)
+#define MX51_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET	(6)
+#define MX51_CCM_CHSCCDR_ESC_CLK_PODF_MASK		(0x3F << 6)
+#define MX51_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET	(3)
+#define MX51_CCM_CHSCCDR_HSC2_CLK_PODF_MASK		(0x7 << 3)
+#define MX51_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET	(0)
+#define MX51_CCM_CHSCCDR_HSC1_CLK_PODF_MASK		(0x7)
+
+/* Define the bits in register CSCDR2 */
+#define MX51_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET		(25)
+#define MX51_CCM_CSCDR2_CSPI_CLK_PRED_MASK		(0x7 << 25)
+#define MX51_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET		(19)
+#define MX51_CCM_CSCDR2_CSPI_CLK_PODF_MASK		(0x3F << 19)
+#define MX51_CCM_CSCDR2_SIM_CLK_PRED_OFFSET		(16)
+#define MX51_CCM_CSCDR2_SIM_CLK_PRED_MASK		(0x7 << 16)
+#define MX51_CCM_CSCDR2_SIM_CLK_PODF_OFFSET		(9)
+#define MX51_CCM_CSCDR2_SIM_CLK_PODF_MASK		(0x3F << 9)
+#define MX51_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET	(6)
+#define MX51_CCM_CSCDR2_SLIMBUS_PRED_MASK		(0x7 << 6)
+#define MX51_CCM_CSCDR2_SLIMBUS_PODF_OFFSET		(0)
+#define MX51_CCM_CSCDR2_SLIMBUS_PODF_MASK		(0x3F)
+
+/* Define the bits in register CSCDR3 */
+#define MX51_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET	(16)
+#define MX51_CCM_CSCDR3_HSI2C_CLK_PRED_MASK		(0x7 << 16)
+#define MX51_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET	(9)
+#define MX51_CCM_CSCDR3_HSI2C_CLK_PODF_MASK		(0x3F << 9)
+#define MX51_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET		(6)
+#define MX51_CCM_CSCDR3_FIRI_CLK_PRED_MASK		(0x7 << 6)
+#define MX51_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET		(0)
+#define MX51_CCM_CSCDR3_FIRI_CLK_PODF_MASK		(0x3F)
+
+/* Define the bits in register CSCDR4 */
+#define MX51_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET	(16)
+#define MX51_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK	(0x7 << 16)
+#define MX51_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET	(9)
+#define MX51_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK	(0x3F << 9)
+#define MX51_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET	(6)
+#define MX51_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK	(0x7 << 6)
+#define MX51_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET	(0)
+#define MX51_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK	(0x3F)
+
+/* Define the bits in register CDHIPR */
+#define MX51_CCM_CDHIPR_ARM_PODF_BUSY			(1 << 16)
+#define MX51_CCM_CDHIPR_DDR_HF_CLK_SEL_BUSY		(1 << 8)
+#define MX51_CCM_CDHIPR_DDR_PODF_BUSY			(1 << 7)
+#define MX51_CCM_CDHIPR_EMI_CLK_SEL_BUSY			(1 << 6)
+#define MX51_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY		(1 << 5)
+#define MX51_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY	(1 << 4)
+#define MX51_CCM_CDHIPR_AHB_PODF_BUSY			(1 << 3)
+#define MX51_CCM_CDHIPR_EMI_PODF_BUSY			(1 << 2)
+#define MX51_CCM_CDHIPR_AXI_B_PODF_BUSY			(1 << 1)
+#define MX51_CCM_CDHIPR_AXI_A_PODF_BUSY			(1 << 0)
+
+/* Define the bits in register CDCR */
+#define MX51_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER			(0x1 << 2)
+#define MX51_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET		(0)
+#define MX51_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK		(0x3)
+
+/* Define the bits in register CLPCR */
+#define MX51_CCM_CLPCR_BYPASS_HSC_LPM_HS		(0x1 << 23)
+#define MX51_CCM_CLPCR_BYPASS_SCC_LPM_HS		(0x1 << 22)
+#define MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS		(0x1 << 21)
+#define MX51_CCM_CLPCR_BYPASS_SDMA_LPM_HS		(0x1 << 20)
+#define MX51_CCM_CLPCR_BYPASS_EMI_LPM_HS		(0x1 << 19)
+#define MX51_CCM_CLPCR_BYPASS_IPU_LPM_HS		(0x1 << 18)
+#define MX51_CCM_CLPCR_BYPASS_RTIC_LPM_HS		(0x1 << 17)
+#define MX51_CCM_CLPCR_BYPASS_RNGC_LPM_HS		(0x1 << 16)
+#define MX51_CCM_CLPCR_COSC_PWRDOWN			(0x1 << 11)
+#define MX51_CCM_CLPCR_STBY_COUNT_OFFSET		(9)
+#define MX51_CCM_CLPCR_STBY_COUNT_MASK		(0x3 << 9)
+#define MX51_CCM_CLPCR_VSTBY				(0x1 << 8)
+#define MX51_CCM_CLPCR_DIS_REF_OSC			(0x1 << 7)
+#define MX51_CCM_CLPCR_SBYOS				(0x1 << 6)
+#define MX51_CCM_CLPCR_ARM_CLK_DIS_ON_LPM		(0x1 << 5)
+#define MX51_CCM_CLPCR_LPSR_CLK_SEL_OFFSET		(3)
+#define MX51_CCM_CLPCR_LPSR_CLK_SEL_MASK		(0x3 << 3)
+#define MX51_CCM_CLPCR_LPM_OFFSET			(0)
+#define MX51_CCM_CLPCR_LPM_MASK			(0x3)
+
+/* Define the bits in register CISR */
+#define MX51_CCM_CISR_ARM_PODF_LOADED			(0x1 << 25)
+#define MX51_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED		(0x1 << 21)
+#define MX51_CCM_CISR_AHB_PODF_LOADED			(0x1 << 20)
+#define MX51_CCM_CISR_EMI_PODF_LOADED				(0x1 << 19)
+#define MX51_CCM_CISR_AXI_B_PODF_LOADED			(0x1 << 18)
+#define MX51_CCM_CISR_AXI_A_PODF_LOADED			(0x1 << 17)
+#define MX51_CCM_CISR_DIVIDER_LOADED				(0x1 << 16)
+#define MX51_CCM_CISR_COSC_READY				(0x1 << 6)
+#define MX51_CCM_CISR_CKIH2_READY				(0x1 << 5)
+#define MX51_CCM_CISR_CKIH_READY				(0x1 << 4)
+#define MX51_CCM_CISR_FPM_READY				(0x1 << 3)
+#define MX51_CCM_CISR_LRF_PLL3					(0x1 << 2)
+#define MX51_CCM_CISR_LRF_PLL2					(0x1 << 1)
+#define MX51_CCM_CISR_LRF_PLL1					(0x1)
+
+/* Define the bits in register CIMR */
+#define MX51_CCM_CIMR_MASK_ARM_PODF_LOADED		(0x1 << 25)
+#define MX51_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED	(0x1 << 21)
+#define MX51_CCM_CIMR_MASK_EMI_PODF_LOADED		(0x1 << 20)
+#define MX51_CCM_CIMR_MASK_AXI_C_PODF_LOADED		(0x1 << 19)
+#define MX51_CCM_CIMR_MASK_AXI_B_PODF_LOADED		(0x1 << 18)
+#define MX51_CCM_CIMR_MASK_AXI_A_PODF_LOADED		(0x1 << 17)
+#define MX51_CCM_CIMR_MASK_DIVIDER_LOADED		(0x1 << 16)
+#define MX51_CCM_CIMR_MASK_COSC_READY			(0x1 << 5)
+#define MX51_CCM_CIMR_MASK_CKIH_READY			(0x1 << 4)
+#define MX51_CCM_CIMR_MASK_FPM_READY			(0x1 << 3)
+#define MX51_CCM_CIMR_MASK_LRF_PLL3			(0x1 << 2)
+#define MX51_CCM_CIMR_MASK_LRF_PLL2			(0x1 << 1)
+#define MX51_CCM_CIMR_MASK_LRF_PLL1			(0x1)
+
+/* Define the bits in register CCOSR */
+#define MX51_CCM_CCOSR_CKO2_EN_OFFSET			(0x1 << 24)
+#define MX51_CCM_CCOSR_CKO2_DIV_OFFSET			(21)
+#define MX51_CCM_CCOSR_CKO2_DIV_MASK			(0x7 << 21)
+#define MX51_CCM_CCOSR_CKO2_SEL_OFFSET			(16)
+#define MX51_CCM_CCOSR_CKO2_SEL_MASK			(0x1F << 16)
+#define MX51_CCM_CCOSR_CKOL_EN				(0x1 << 7)
+#define MX51_CCM_CCOSR_CKOL_DIV_OFFSET			(4)
+#define MX51_CCM_CCOSR_CKOL_DIV_MASK			(0x7 << 4)
+#define MX51_CCM_CCOSR_CKOL_SEL_OFFSET			(0)
+#define MX51_CCM_CCOSR_CKOL_SEL_MASK			(0xF)
+
+/* Define the bits in registers CGPR */
+#define MX51_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE		(0x1 << 4)
+#define MX51_CCM_CGPR_FPM_SEL				(0x1 << 3)
+#define MX51_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET		(0)
+#define MX51_CCM_CGPR_VL_L2BIST_CLKDIV_MASK		(0x7)
+
+/* Define the bits in registers CCGRx */
+#define MX51_CCM_CCGR_CG_MASK				0x3
+#define MX51_CCM_CCGR_MOD_OFF				0x0
+#define MX51_CCM_CCGR_MOD_ON				0x3
+#define MX51_CCM_CCGR_MOD_IDLE				0x1
+
+#define MX51_CCM_CCGR0_CG15_OFFSET			30
+#define MX51_CCM_CCGR0_CG15_MASK			(0x3 << 30)
+#define MX51_CCM_CCGR0_CG14_OFFSET			28
+#define MX51_CCM_CCGR0_CG14_MASK			(0x3 << 28)
+#define MX51_CCM_CCGR0_CG13_OFFSET			26
+#define MX51_CCM_CCGR0_CG13_MASK			(0x3 << 26)
+#define MX51_CCM_CCGR0_CG12_OFFSET			24
+#define MX51_CCM_CCGR0_CG12_MASK			(0x3 << 24)
+#define MX51_CCM_CCGR0_CG11_OFFSET			22
+#define MX51_CCM_CCGR0_CG11_MASK			(0x3 << 22)
+#define MX51_CCM_CCGR0_CG10_OFFSET			20
+#define MX51_CCM_CCGR0_CG10_MASK			(0x3 << 20)
+#define MX51_CCM_CCGR0_CG9_OFFSET			18
+#define MX51_CCM_CCGR0_CG9_MASK			(0x3 << 18)
+#define MX51_CCM_CCGR0_CG8_OFFSET			16
+#define MX51_CCM_CCGR0_CG8_MASK			(0x3 << 16)
+#define MX51_CCM_CCGR0_CG7_OFFSET			14
+#define MX51_CCM_CCGR0_CG6_OFFSET			12
+#define MX51_CCM_CCGR0_CG5_OFFSET			10
+#define MX51_CCM_CCGR0_CG5_MASK			(0x3 << 10)
+#define MX51_CCM_CCGR0_CG4_OFFSET			8
+#define MX51_CCM_CCGR0_CG4_MASK			(0x3 << 8)
+#define MX51_CCM_CCGR0_CG3_OFFSET			6
+#define MX51_CCM_CCGR0_CG3_MASK			(0x3 << 6)
+#define MX51_CCM_CCGR0_CG2_OFFSET			4
+#define MX51_CCM_CCGR0_CG2_MASK			(0x3 << 4)
+#define MX51_CCM_CCGR0_CG1_OFFSET			2
+#define MX51_CCM_CCGR0_CG1_MASK			(0x3 << 2)
+#define MX51_CCM_CCGR0_CG0_OFFSET			0
+#define MX51_CCM_CCGR0_CG0_MASK			0x3
+
+#define MX51_CCM_CCGR1_CG15_OFFSET			30
+#define MX51_CCM_CCGR1_CG14_OFFSET			28
+#define MX51_CCM_CCGR1_CG13_OFFSET			26
+#define MX51_CCM_CCGR1_CG12_OFFSET			24
+#define MX51_CCM_CCGR1_CG11_OFFSET			22
+#define MX51_CCM_CCGR1_CG10_OFFSET			20
+#define MX51_CCM_CCGR1_CG9_OFFSET			18
+#define MX51_CCM_CCGR1_CG8_OFFSET			16
+#define MX51_CCM_CCGR1_CG7_OFFSET			14
+#define MX51_CCM_CCGR1_CG6_OFFSET			12
+#define MX51_CCM_CCGR1_CG5_OFFSET			10
+#define MX51_CCM_CCGR1_CG4_OFFSET			8
+#define MX51_CCM_CCGR1_CG3_OFFSET			6
+#define MX51_CCM_CCGR1_CG2_OFFSET			4
+#define MX51_CCM_CCGR1_CG1_OFFSET			2
+#define MX51_CCM_CCGR1_CG0_OFFSET			0
+
+#define MX51_CCM_CCGR2_CG15_OFFSET			30
+#define MX51_CCM_CCGR2_CG14_OFFSET			28
+#define MX51_CCM_CCGR2_CG13_OFFSET			26
+#define MX51_CCM_CCGR2_CG12_OFFSET			24
+#define MX51_CCM_CCGR2_CG11_OFFSET			22
+#define MX51_CCM_CCGR2_CG10_OFFSET			20
+#define MX51_CCM_CCGR2_CG9_OFFSET			18
+#define MX51_CCM_CCGR2_CG8_OFFSET			16
+#define MX51_CCM_CCGR2_CG7_OFFSET			14
+#define MX51_CCM_CCGR2_CG6_OFFSET			12
+#define MX51_CCM_CCGR2_CG5_OFFSET			10
+#define MX51_CCM_CCGR2_CG4_OFFSET			8
+#define MX51_CCM_CCGR2_CG3_OFFSET			6
+#define MX51_CCM_CCGR2_CG2_OFFSET			4
+#define MX51_CCM_CCGR2_CG1_OFFSET			2
+#define MX51_CCM_CCGR2_CG0_OFFSET			0
+
+#define MX51_CCM_CCGR3_CG15_OFFSET			30
+#define MX51_CCM_CCGR3_CG14_OFFSET			28
+#define MX51_CCM_CCGR3_CG13_OFFSET			26
+#define MX51_CCM_CCGR3_CG12_OFFSET			24
+#define MX51_CCM_CCGR3_CG11_OFFSET			22
+#define MX51_CCM_CCGR3_CG10_OFFSET			20
+#define MX51_CCM_CCGR3_CG9_OFFSET			18
+#define MX51_CCM_CCGR3_CG8_OFFSET			16
+#define MX51_CCM_CCGR3_CG7_OFFSET			14
+#define MX51_CCM_CCGR3_CG6_OFFSET			12
+#define MX51_CCM_CCGR3_CG5_OFFSET			10
+#define MX51_CCM_CCGR3_CG4_OFFSET			8
+#define MX51_CCM_CCGR3_CG3_OFFSET			6
+#define MX51_CCM_CCGR3_CG2_OFFSET			4
+#define MX51_CCM_CCGR3_CG1_OFFSET			2
+#define MX51_CCM_CCGR3_CG0_OFFSET			0
+
+#define MX51_CCM_CCGR4_CG15_OFFSET			30
+#define MX51_CCM_CCGR4_CG14_OFFSET			28
+#define MX51_CCM_CCGR4_CG13_OFFSET			26
+#define MX51_CCM_CCGR4_CG12_OFFSET			24
+#define MX51_CCM_CCGR4_CG11_OFFSET			22
+#define MX51_CCM_CCGR4_CG10_OFFSET			20
+#define MX51_CCM_CCGR4_CG9_OFFSET			18
+#define MX51_CCM_CCGR4_CG8_OFFSET			16
+#define MX51_CCM_CCGR4_CG7_OFFSET			14
+#define MX51_CCM_CCGR4_CG6_OFFSET			12
+#define MX51_CCM_CCGR4_CG5_OFFSET			10
+#define MX51_CCM_CCGR4_CG4_OFFSET			8
+#define MX51_CCM_CCGR4_CG3_OFFSET			6
+#define MX51_CCM_CCGR4_CG2_OFFSET			4
+#define MX51_CCM_CCGR4_CG1_OFFSET			2
+#define MX51_CCM_CCGR4_CG0_OFFSET			0
+
+#define MX51_CCM_CCGR5_CG15_OFFSET			30
+#define MX51_CCM_CCGR5_CG14_OFFSET			28
+#define MX51_CCM_CCGR5_CG14_MASK			(0x3 << 28)
+#define MX51_CCM_CCGR5_CG13_OFFSET			26
+#define MX51_CCM_CCGR5_CG13_MASK			(0x3 << 26)
+#define MX51_CCM_CCGR5_CG12_OFFSET			24
+#define MX51_CCM_CCGR5_CG12_MASK			(0x3 << 24)
+#define MX51_CCM_CCGR5_CG11_OFFSET			22
+#define MX51_CCM_CCGR5_CG11_MASK			(0x3 << 22)
+#define MX51_CCM_CCGR5_CG10_OFFSET			20
+#define MX51_CCM_CCGR5_CG10_MASK			(0x3 << 20)
+#define MX51_CCM_CCGR5_CG9_OFFSET			18
+#define MX51_CCM_CCGR5_CG9_MASK			(0x3 << 18)
+#define MX51_CCM_CCGR5_CG8_OFFSET			16
+#define MX51_CCM_CCGR5_CG8_MASK			(0x3 << 16)
+#define MX51_CCM_CCGR5_CG7_OFFSET			14
+#define MX51_CCM_CCGR5_CG7_MASK			(0x3 << 14)
+#define MX51_CCM_CCGR5_CG6_OFFSET			12
+#define MX51_CCM_CCGR5_CG5_OFFSET			10
+#define MX51_CCM_CCGR5_CG4_OFFSET			8
+#define MX51_CCM_CCGR5_CG3_OFFSET			6
+#define MX51_CCM_CCGR5_CG2_OFFSET			4
+#define MX51_CCM_CCGR5_CG2_MASK			(0x3 << 4)
+#define MX51_CCM_CCGR5_CG1_OFFSET			2
+#define MX51_CCM_CCGR5_CG0_OFFSET			0
+#define MX51_CCM_CCGR6_CG7_OFFSET            14
+#define MX51_CCM_CCGR6_CG7_MASK          (0x3 << 14)
+#define MX51_CCM_CCGR6_CG6_OFFSET			12
+#define MX51_CCM_CCGR6_CG6_MASK			(0x3 << 12)
+#define MX51_CCM_CCGR6_CG5_OFFSET			10
+#define MX51_CCM_CCGR6_CG5_MASK			(0x3 << 10)
+#define MX51_CCM_CCGR6_CG4_OFFSET			8
+#define MX51_CCM_CCGR6_CG4_MASK			(0x3 << 8)
+#define MX51_CCM_CCGR6_CG3_OFFSET			6
+#define MX51_CCM_CCGR6_CG2_OFFSET			4
+#define MX51_CCM_CCGR6_CG1_OFFSET			2
+#define MX51_CCM_CCGR6_CG0_OFFSET			0
+
+/* CORTEXA8 platform */
+#define MX51_CORTEXA8_PLAT_PVID		(MX51_CORTEXA8_BASE + 0x0)
+#define MX51_CORTEXA8_PLAT_GPC		(MX51_CORTEXA8_BASE + 0x4)
+#define MX51_CORTEXA8_PLAT_PIC		(MX51_CORTEXA8_BASE + 0x8)
+#define MX51_CORTEXA8_PLAT_LPC		(MX51_CORTEXA8_BASE + 0xC)
+#define MX51_CORTEXA8_PLAT_NEON_LPC	(MX51_CORTEXA8_BASE + 0x10)
+#define MX51_CORTEXA8_PLAT_ICGC		(MX51_CORTEXA8_BASE + 0x14)
+#define MX51_CORTEXA8_PLAT_AMC		(MX51_CORTEXA8_BASE + 0x18)
+#define MX51_CORTEXA8_PLAT_NMC		(MX51_CORTEXA8_BASE + 0x20)
+#define MX51_CORTEXA8_PLAT_NMS		(MX51_CORTEXA8_BASE + 0x24)
+
+/* DVFS CORE */
+#define MX51_DVFSTHRS		(MX51_DVFS_CORE_BASE + 0x00)
+#define MX51_DVFSCOUN		(MX51_DVFS_CORE_BASE + 0x04)
+#define MX51_DVFSSIG1		(MX51_DVFS_CORE_BASE + 0x08)
+#define MX51_DVFSSIG0		(MX51_DVFS_CORE_BASE + 0x0C)
+#define MX51_DVFSGPC0		(MX51_DVFS_CORE_BASE + 0x10)
+#define MX51_DVFSGPC1		(MX51_DVFS_CORE_BASE + 0x14)
+#define MX51_DVFSGPBT		(MX51_DVFS_CORE_BASE + 0x18)
+#define MX51_DVFSEMAC		(MX51_DVFS_CORE_BASE + 0x1C)
+#define MX51_DVFSCNTR		(MX51_DVFS_CORE_BASE + 0x20)
+#define MX51_DVFSLTR0_0		(MX51_DVFS_CORE_BASE + 0x24)
+#define MX51_DVFSLTR0_1		(MX51_DVFS_CORE_BASE + 0x28)
+#define MX51_DVFSLTR1_0		(MX51_DVFS_CORE_BASE + 0x2C)
+#define MX51_DVFSLTR1_1		(MX51_DVFS_CORE_BASE + 0x30)
+#define MX51_DVFSPT0 		(MX51_DVFS_CORE_BASE + 0x34)
+#define MX51_DVFSPT1 		(MX51_DVFS_CORE_BASE + 0x38)
+#define MX51_DVFSPT2 		(MX51_DVFS_CORE_BASE + 0x3C)
+#define MX51_DVFSPT3 		(MX51_DVFS_CORE_BASE + 0x40)
+
+/* GPC */
+#define MX51_GPC_CNTR		(MX51_GPC_BASE + 0x0)
+#define MX51_GPC_PGR		(MX51_GPC_BASE + 0x4)
+#define MX51_GPC_VCR		(MX51_GPC_BASE + 0x8)
+#define MX51_GPC_ALL_PU		(MX51_GPC_BASE + 0xC)
+#define MX51_GPC_NEON		(MX51_GPC_BASE + 0x10)
+#define MX51_GPC_PGR_ARMPG_OFFSET	8
+#define MX51_GPC_PGR_ARMPG_MASK		(3 << 8)
+
+/* PGC */
+#define MX51_PGC_IPU_PGCR	(MX51_PGC_IPU_BASE + 0x0)
+#define MX51_PGC_IPU_PGSR	(MX51_PGC_IPU_BASE + 0xC)
+#define MX51_PGC_VPU_PGCR	(MX51_PGC_VPU_BASE + 0x0)
+#define MX51_PGC_VPU_PGSR	(MX51_PGC_VPU_BASE + 0xC)
+#define MX51_PGC_GPU_PGCR	(MX51_PGC_GPU_BASE + 0x0)
+#define MX51_PGC_GPU_PGSR	(MX51_PGC_GPU_BASE + 0xC)
+
+#define MX51_PGCR_PCR		1
+#define MX51_SRPGCR_PCR		1
+#define MX51_EMPGCR_PCR		1
+#define MX51_PGSR_PSR		1
+
+
+#define MX51_CORTEXA8_PLAT_LPC_DSM	(1 << 0)
+#define MX51_CORTEXA8_PLAT_LPC_DBG_DSM	(1 << 1)
+
+/* SRPG */
+#define MX51_SRPG_NEON_SRPGCR	(MX51_SRPG_NEON_BASE + 0x0)
+#define MX51_SRPG_NEON_PUPSCR	(MX51_SRPG_NEON_BASE + 0x4)
+#define MX51_SRPG_NEON_PDNSCR	(MX51_SRPG_NEON_BASE + 0x8)
+
+#define MX51_SRPG_ARM_SRPGCR	(MX51_SRPG_ARM_BASE + 0x0)
+#define MX51_SRPG_ARM_PUPSCR	(MX51_SRPG_ARM_BASE + 0x4)
+#define MX51_SRPG_ARM_PDNSCR	(MX51_SRPG_ARM_BASE + 0x8)
+
+#define MX51_SRPG_EMPGC0_SRPGCR	(MX51_SRPG_EMPGC0_BASE + 0x0)
+#define MX51_SRPG_EMPGC0_PUPSCR	(MX51_SRPG_EMPGC0_BASE + 0x4)
+#define MX51_SRPG_EMPGC0_PDNSCR	(MX51_SRPG_EMPGC0_BASE + 0x8)
+
+#define MX51_SRPG_EMPGC1_SRPGCR	(MX51_SRPG_EMPGC1_BASE + 0x0)
+#define MX51_SRPG_EMPGC1_PUPSCR	(MX51_SRPG_EMPGC1_BASE + 0x4)
+#define MX51_SRPG_EMPGC1_PDNSCR	(MX51_SRPG_EMPGC1_BASE + 0x8)
+
+#define MX51_SRPG_MEGAMIX_SRPGCR		(MX51_SRPG_MEGAMIX_BASE + 0x0)
+#define MX51_SRPG_MEGAMIX_PUPSCR		(MX51_SRPG_MEGAMIX_BASE + 0x4)
+#define MX51_SRPG_MEGAMIX_PDNSCR		(MX51_SRPG_MEGAMIX_BASE + 0x8)
+
+#define MX51_SRPGC_EMI_SRPGCR	(MX51_SRPGC_EMI_BASE + 0x0)
+#define MX51_SRPGC_EMI_PUPSCR	(MX51_SRPGC_EMI_BASE + 0x4)
+#define MX51_SRPGC_EMI_PDNSCR	(MX51_SRPGC_EMI_BASE + 0x8)
+
+#endif				/* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
+
+
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 4b89838..9ca838b 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -45,3 +45,9 @@ u64 imx_uid(void);
 #define cpu_is_mx35()	(0)
 #endif
 
+#ifdef CONFIG_ARCH_IMX51
+#define cpu_is_mx51()	(1)
+#else
+#define cpu_is_mx51()	(0)
+#endif
+
diff --git a/arch/arm/mach-imx/include/mach/imx-regs.h b/arch/arm/mach-imx/include/mach/imx-regs.h
index 2cc49dd..605d320 100644
--- a/arch/arm/mach-imx/include/mach/imx-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx-regs.h
@@ -51,6 +51,8 @@
 # include <mach/imx35-regs.h>
 #elif defined CONFIG_ARCH_IMX25
 # include <mach/imx25-regs.h>
+#elif defined CONFIG_ARCH_IMX51
+#include <mach/imx51-regs.h>
 #else
 # error "unknown i.MX soc type"
 #endif
diff --git a/arch/arm/mach-imx/include/mach/imx51-regs.h b/arch/arm/mach-imx/include/mach/imx51-regs.h
new file mode 100644
index 0000000..f99285c
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/imx51-regs.h
@@ -0,0 +1,131 @@
+#ifndef __MACH_IMX51_REGS_H
+#define __MACH_IMX51_REGS_H
+
+#define IMX_TIM1_BASE			0x73fa0000
+#define IMX_WDT_BASE			0x73f98000
+#define IMX_IOMUXC_BASE			0x73fa8000
+
+#define GPT_TCTL	0x00
+#define GPT_TPRER	0x04
+#define GPT_TCMP	0x10
+#define GPT_TCR		0x1c
+#define GPT_TCN		0x24
+#define GPT_TSTAT	0x08
+
+/* Part 2: Bitfields */
+#define TCTL_SWR	(1<<15)	/* Software reset */
+#define TCTL_FRR	(1<<9)	/* Freerun / restart */
+#define TCTL_CAP	(3<<6)	/* Capture Edge */
+#define TCTL_OM		(1<<5)	/* output mode */
+#define TCTL_IRQEN	(1<<4)	/* interrupt enable */
+#define TCTL_CLKSOURCE	(6)	/* Clock source bit position */
+#define TCTL_TEN	(1)	/* Timer enable */
+#define TPRER_PRES	(0xff)	/* Prescale */
+#define TSTAT_CAPT	(1<<1)	/* Capture event */
+#define TSTAT_COMP	(1)	/* Compare event */
+
+#define WCR	__REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
+#define WSR	__REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */
+#define WSTR	__REG16(IMX_WDT_BASE + 0x04) /* Watchdog Status Register  */
+
+/* important definition of some bits of WCR */
+#define WCR_WDE 0x04
+
+#define MX51_IROM_BASE_ADDR	0x0
+
+/*
+ * AIPS 1
+ */
+#define MX51_AIPS1_BASE_ADDR 	0x73F00000
+
+#define MX51_OTG_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00080000)
+#define MX51_GPIO1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00084000)
+#define MX51_GPIO2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00088000)
+#define MX51_GPIO3_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x0008C000)
+#define MX51_GPIO4_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00090000)
+#define MX51_KPP_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00094000)
+#define MX51_WDOG_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00098000)
+#define MX51_WDOG2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x0009C000)
+#define MX51_GPT1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A0000)
+#define MX51_SRTC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A4000)
+#define MX51_IOMUXC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A8000)
+#define MX51_EPIT1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000AC000)
+#define MX51_EPIT2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B0000)
+#define MX51_PWM1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B4000)
+#define MX51_PWM2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B8000)
+#define MX51_UART1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000BC000)
+#define MX51_UART2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000C0000)
+#define MX51_SRC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D0000)
+#define MX51_CCM_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D4000)
+#define MX51_GPC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D8000)
+
+/*
+ * AIPS 2
+ */
+#define MX51_AIPS2_BASE_ADDR		0x83F00000
+
+#define MX51_PLL1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00080000)
+#define MX51_PLL2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00084000)
+#define MX51_PLL3_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00088000)
+#define MX51_AHBMAX_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00094000)
+#define MX51_IIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00098000)
+#define MX51_CSU_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x0009C000)
+#define MX51_ARM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000A0000)
+#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A4000)
+#define MX51_FIRI_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000A8000)
+#define MX51_CSPI2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000AC000)
+#define MX51_SDMA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B0000)
+#define MX51_SCC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B4000)
+#define MX51_ROMCP_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B8000)
+#define MX51_RTIC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000BC000)
+#define MX51_CSPI3_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C0000)
+#define MX51_I2C2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C4000)
+#define MX51_I2C1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C8000)
+#define MX51_SSI1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000CC000)
+#define MX51_AUDMUX_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D0000)
+#define MX51_M4IF_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D8000)
+#define MX51_ESDCTL_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D9000)
+#define MX51_WEIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DA000)
+#define MX51_NFC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DB000)
+#define MX51_EMI_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DBF00)
+#define MX51_MIPI_HSC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DC000)
+#define MX51_ATA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E0000)
+#define MX51_SIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E4000)
+#define MX51_SSI3BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E8000)
+#define MX51_MXC_FEC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000EC000)
+#define MX51_TVE_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F0000)
+#define MX51_VPU_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F4000)
+#define MX51_SAHARA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F8000)
+
+#define MX51_SPBA0_BASE_ADDR    0x70000000
+#define MX51_CSPI1_BASE_ADDR    (MX51_SPBA0_BASE_ADDR + 0x00010000)
+
+/*
+ * Memory regions and CS
+ */
+#define MX51_GPU_CTRL_BASE_ADDR	0x30000000
+#define MX51_IPU_CTRL_BASE_ADDR	0x40000000
+#define MX51_CSD0_BASE_ADDR		0x90000000
+#define MX51_CSD1_BASE_ADDR		0xA0000000
+#define MX51_CS0_BASE_ADDR		0xB0000000
+#define MX51_CS1_BASE_ADDR		0xB8000000
+#define MX51_CS2_BASE_ADDR		0xC0000000
+#define MX51_CS3_BASE_ADDR		0xC8000000
+#define MX51_CS4_BASE_ADDR		0xCC000000
+#define MX51_CS5_BASE_ADDR		0xCE000000
+
+/* silicon revisions specific to i.MX51 */
+#define MX51_CHIP_REV_1_0	0x10
+#define MX51_CHIP_REV_1_1	0x11
+#define MX51_CHIP_REV_1_2	0x12
+#define MX51_CHIP_REV_1_3	0x13
+#define MX51_CHIP_REV_2_0	0x20
+#define MX51_CHIP_REV_2_1	0x21
+#define MX51_CHIP_REV_2_2	0x22
+#define MX51_CHIP_REV_2_3	0x23
+#define MX51_CHIP_REV_3_0	0x30
+#define MX51_CHIP_REV_3_1	0x31
+#define MX51_CHIP_REV_3_2	0x32
+
+#endif /* __MACH_IMX51_REGS_H */
+
diff --git a/arch/arm/mach-imx/include/mach/iomux-mx51.h b/arch/arm/mach-imx/include/mach/iomux-mx51.h
new file mode 100644
index 0000000..2901ee6
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/iomux-mx51.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer <s.hauer at pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option, NO_PAD_CTRL) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IOMUX_MX51_H__
+#define __MACH_IOMUX_MX51_H__
+
+#include <mach/iomux-v3.h>
+
+#define MX51_FEC_PAD_CTRL      (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DRIVE_STRENGTH_HIGH)
+
+/*
+ * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named
+ * GPIO_<unit>_<num> see also iomux-v3.h
+ */
+
+/*								  PAD    MUX   ALT INPSE PATH */
+#define MX51_PAD_EIM_DA0__EIM_DA0			IOMUX_PAD(0x7A8, 0x1C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA1__EIM_DA1			IOMUX_PAD(0x7A8, 0x20, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA2__EIM_DA2			IOMUX_PAD(0x7A8, 0x24, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA3__EIM_DA3			IOMUX_PAD(0x7A8, 0x28, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA4__EIM_DA4			IOMUX_PAD(0x7AC, 0x2C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA5__EIM_DA5			IOMUX_PAD(0x7AC, 0x30, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA6__EIM_DA6			IOMUX_PAD(0x7AC, 0x34, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA7__EIM_DA7			IOMUX_PAD(0x7AC, 0x38, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA8__EIM_DA8			IOMUX_PAD(0x7B0, 0x3C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA9__EIM_DA9			IOMUX_PAD(0x7B0, 0x40, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA10__EIM_DA10			IOMUX_PAD(0x7B0, 0x44, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA11__EIM_DA11			IOMUX_PAD(0x7B0, 0x48, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA12__EIM_DA12			IOMUX_PAD(0x7BC, 0x4C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA13__EIM_DA13			IOMUX_PAD(0x7BC, 0x50, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA14__EIM_DA14			IOMUX_PAD(0x7BC, 0x54, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA15__EIM_DA15			IOMUX_PAD(0x7BC, 0x58, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D16__EIM_D16			IOMUX_PAD(0x3F0, 0x5C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D17__EIM_D17			IOMUX_PAD(0x3F4, 0x60, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D18__EIM_D18			IOMUX_PAD(0x3F8, 0x64, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D19__EIM_D19			IOMUX_PAD(0x3FC, 0x68, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D20__EIM_D20			IOMUX_PAD(0x400, 0x6C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D21__EIM_D21			IOMUX_PAD(0x404, 0x70, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D22__EIM_D22			IOMUX_PAD(0x408, 0x74, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D23__EIM_D23			IOMUX_PAD(0x40C, 0x78, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D24__EIM_D24			IOMUX_PAD(0x410, 0x7C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D25__EIM_D25			IOMUX_PAD(0x414, 0x80, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D26__EIM_D26			IOMUX_PAD(0x418, 0x84, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D27__EIM_D27			IOMUX_PAD(0x41C, 0x88, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D28__EIM_D28			IOMUX_PAD(0x420, 0x8C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D29__EIM_D29			IOMUX_PAD(0x424, 0x90, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D30__EIM_D30			IOMUX_PAD(0x428, 0x94, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D31__EIM_D31			IOMUX_PAD(0x42C, 0x98, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A16__EIM_A16			IOMUX_PAD(0x430, 0x9C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A17__EIM_A17			IOMUX_PAD(0x434, 0xA0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A18__EIM_A18			IOMUX_PAD(0x438, 0xA4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A19__EIM_A19			IOMUX_PAD(0x43C, 0xA8, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_EIM_A20__EIM_A20			IOMUX_PAD(0x440, 0xAC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A20__GPIO2_14			IOMUX_PAD(0x440, 0xAC, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_EIM_A21__EIM_A21			IOMUX_PAD(0x444, 0xB0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A22__EIM_A22			IOMUX_PAD(0x448, 0xB4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A23__EIM_A23			IOMUX_PAD(0x44C, 0xB8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A24__EIM_A24			IOMUX_PAD(0x450, 0xBC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A25__EIM_A25			IOMUX_PAD(0x454, 0xC0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A26__EIM_A26			IOMUX_PAD(0x458, 0xC4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A27__EIM_A27			IOMUX_PAD(0x45C, 0xC8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB0__EIM_EB0			IOMUX_PAD(0x460, 0xCC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB1__EIM_EB1			IOMUX_PAD(0x464, 0xD0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_EIM_EB2__EIM_EB2			IOMUX_PAD(0x468, 0xD4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB2__FEC_MDIO			IOMUX_PAD(0x468, 0x0d4, 3, 0x954,   0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_EIM_EB3__EIM_EB3			IOMUX_PAD(0x46C, 0xD8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB3__FEC_RDATA1			IOMUX_PAD(0x46c, 0x0d8, 3, 0x95c,   0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_EIM_OE__EIM_OE				IOMUX_PAD(0x470, 0xDC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS0__EIM_CS0			IOMUX_PAD(0x474, 0xE0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS1__EIM_CS1			IOMUX_PAD(0x478, 0xE4, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_EIM_CS2__EIM_CS2			IOMUX_PAD(0x47C, 0xE8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS2__FEC_RDATA2			IOMUX_PAD(0x47c, 0x0e8, 3, 0x960,   0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_EIM_CS3__EIM_CS3			IOMUX_PAD(0x480, 0xEC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS3__FEC_RDATA3			IOMUX_PAD(0x480, 0x0ec, 3, 0x964,   0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_EIM_CS4__EIM_CS4			IOMUX_PAD(0x484, 0xF0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS4__FEC_RX_ER			IOMUX_PAD(0x484, 0x0f0, 3, 0x970,   0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_EIM_CS5__EIM_CS5			IOMUX_PAD(0x488, 0xF4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS5__FEC_CRS			IOMUX_PAD(0x52C, 0xF4, 3, 0x950, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_EIM_DTACK__EIM_DTACK			IOMUX_PAD(0x48C, 0xF8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_LBA__EIM_LBA			IOMUX_PAD(0x494, 0xFC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CRE__EIM_CRE			IOMUX_PAD(0x4A0, 0x100, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DRAM_CS1__DRAM_CS1			IOMUX_PAD(0x4D0, 0x104, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_WE_B__NANDF_WE_B			IOMUX_PAD(0x4E4, 0x108, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RE_B__NANDF_RE_B			IOMUX_PAD(0x4E8, 0x10C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_ALE__NANDF_ALE			IOMUX_PAD(0x4EC, 0x110, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CLE__NANDF_CLE			IOMUX_PAD(0x4F0, 0x114, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_WP_B__NANDF_WP_B			IOMUX_PAD(0x4F4, 0x118, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB0__NANDF_RB0			IOMUX_PAD(0x4F8, 0x11C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB1__NANDF_RB1			IOMUX_PAD(0x4FC, 0x120, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_NANDF_RB2__NANDF_RB2			IOMUX_PAD(0x500, 0x124, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB2__FEC_COL			IOMUX_PAD(0x500, 0x124, 1, 0x94c, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_RB3__NANDF_RB3			IOMUX_PAD(0x504, 0x128, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB3__FEC_RX_CLK			IOMUX_PAD(0x504, 0x128, 1, 0x968, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_RB4__NANDF_RB4			IOMUX_PAD(0x514, 0x12C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB5__NANDF_RB5			IOMUX_PAD(0x5D8, 0x130, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB6__FEC_RDATA0			IOMUX_PAD(0x5DC, 0x16C, 2, 0x958, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_RB7__NANDF_RB7			IOMUX_PAD(0x5E0, 0x138, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB7__FEC_TX_ER			IOMUX_PAD(0x5E0, 0x138, 2, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_NANDF_CS0__NANDF_CS0			IOMUX_PAD(0x518, 0x130, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS1__NANDF_CS1			IOMUX_PAD(0x51C, 0x134, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS2__NANDF_CS2			IOMUX_PAD(0x520, 0x138, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_NANDF_CS3__NANDF_CS3			IOMUX_PAD(0x524, 0x13C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS3__FEC_MDC			IOMUX_PAD(0x524, 0x13C, 2, 0x0, 0,MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_CS4__NANDF_CS4			IOMUX_PAD(0x528, 0x140, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS4__FEC_TDATA1			IOMUX_PAD(0x528, 0x140, 2, 0x0, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_CS5__NANDF_CS5			IOMUX_PAD(0x52C, 0x144, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS5__FEC_TDATA2			IOMUX_PAD(0x52C, 0x144, 2, 0x0, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_CS6__NANDF_CS6			IOMUX_PAD(0x530, 0x148, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS6__FEC_TDATA3			IOMUX_PAD(0x530, 0x148, 2, 0x0, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_CS7__NANDF_CS7			IOMUX_PAD(0x534, 0x14C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS7__FEC_TX_EN			IOMUX_PAD(0x534, 0x14C, 1, 0x0, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT		IOMUX_PAD(0x538, 0x150, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK		IOMUX_PAD(0x538, 0x150, 1, 0x974, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_D15__NANDF_D15			IOMUX_PAD(0x53C, 0x154, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D14__NANDF_D14			IOMUX_PAD(0x540, 0x158, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D13__NANDF_D13			IOMUX_PAD(0x544, 0x15C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D12__NANDF_D12			IOMUX_PAD(0x548, 0x160, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_NANDF_D11__NANDF_D11			IOMUX_PAD(0x54C, 0x164, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D11__FEC_RX_DV			IOMUX_PAD(0x54C, 0x164, 2, 0x96c, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_D10__NANDF_D10			IOMUX_PAD(0x550, 0x168, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_NANDF_D9__NANDF_D9			IOMUX_PAD(0x554, 0x16C, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX51_PAD_NANDF_D8__NANDF_D8			IOMUX_PAD(0x558, 0x170, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D8__FEC_TDATA0			IOMUX_PAD(0x558, 0x170, 2, 0x0, 0, MX51_FEC_PAD_CTRL)
+
+#define MX51_PAD_NANDF_D7__NANDF_D7			IOMUX_PAD(0x55C, 0x174, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D6__NANDF_D6			IOMUX_PAD(0x560, 0x178, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D5__NANDF_D5			IOMUX_PAD(0x564, 0x17C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D4__NANDF_D4			IOMUX_PAD(0x568, 0x180, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D3__NANDF_D3			IOMUX_PAD(0x56C, 0x184, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D2__NANDF_D2			IOMUX_PAD(0x570, 0x188, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D1__NANDF_D1			IOMUX_PAD(0x574, 0x18C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D0__NANDF_D0			IOMUX_PAD(0x578, 0x190, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D8__CSI1_D8			IOMUX_PAD(0x57C, 0x194, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D9__CSI1_D9			IOMUX_PAD(0x580, 0x198, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D10__CSI1_D10			IOMUX_PAD(0x584, 0x19C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D11__CSI1_D11			IOMUX_PAD(0x588, 0x1A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D12__CSI1_D12			IOMUX_PAD(0x58C, 0x1A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D13__CSI1_D13			IOMUX_PAD(0x590, 0x1A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D14__CSI1_D14			IOMUX_PAD(0x594, 0x1AC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D15__CSI1_D15			IOMUX_PAD(0x598, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D16__CSI1_D16			IOMUX_PAD(0x59C, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D17__CSI1_D17			IOMUX_PAD(0x5A0, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D18__CSI1_D18			IOMUX_PAD(0x5A4, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D19__CSI1_D19			IOMUX_PAD(0x5A8, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC			IOMUX_PAD(0x5AC, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC			IOMUX_PAD(0x5B0, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK		IOMUX_PAD(0x5B4, NON_MUX_I, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_MCLK__CSI1_MCLK			IOMUX_PAD(0x5B8, NON_MUX_I, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_PKE0__CSI1_PKE0			IOMUX_PAD(0x860, NON_MUX_I, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D12__CSI2_D12			IOMUX_PAD(0x5BC, 0x1CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D13__CSI2_D13			IOMUX_PAD(0x5C0, 0x1D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D14__CSI2_D14			IOMUX_PAD(0x5C4, 0x1D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D15__CSI2_D15			IOMUX_PAD(0x5C8, 0x1D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D16__CSI2_D16			IOMUX_PAD(0x5CC, 0x1DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D17__CSI2_D17			IOMUX_PAD(0x5D0, 0x1E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D18__CSI2_D18			IOMUX_PAD(0x5D4, 0x1E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D19__CSI2_D19			IOMUX_PAD(0x5D8, 0x1E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_VSYNC__CSI2_VSYNC			IOMUX_PAD(0x5DC, 0x1EC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_HSYNC__CSI2_HSYNC			IOMUX_PAD(0x5E0, 0x1F0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK		IOMUX_PAD(0x5E4, 0x1F4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_PKE0__CSI2_PKE0			IOMUX_PAD(0x81C, NON_MUX_I, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_I2C1_CLK__I2C1_CLK			IOMUX_PAD(0x5E8, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_I2C1_DAT__I2C1_DAT			IOMUX_PAD(0x5EC, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_TXD__AUD3_BB_TXD		IOMUX_PAD(0x5F0, 0x200, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_RXD__AUD3_BB_RXD		IOMUX_PAD(0x5F4, 0x204, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_CK__AUD3_BB_CK			IOMUX_PAD(0x5F8, 0x208, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_FS__AUD3_BB_FS			IOMUX_PAD(0x5FC, 0x20C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_MOSI__CSPI1_MOSI			IOMUX_PAD(0x600, 0x210, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_MISO__CSPI1_MISO			IOMUX_PAD(0x604, 0x214, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SS0__CSPI1_SS0			IOMUX_PAD(0x608, 0x218, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SS1__CSPI1_SS1			IOMUX_PAD(0x60C, 0x21C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_RDY__CSPI1_RDY			IOMUX_PAD(0x610, 0x220, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SCLK__CSPI1_SCLK			IOMUX_PAD(0x614, 0x224, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART1_RXD__UART1_RXD			IOMUX_PAD(0x618, 0x228, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART1_TXD__UART1_TXD			IOMUX_PAD(0x61C, 0x22C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART1_RTS__UART1_RTS			IOMUX_PAD(0x620, 0x230, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART1_CTS__UART1_CTS			IOMUX_PAD(0x624, 0x234, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART2_RXD__UART2_RXD			IOMUX_PAD(0x628, 0x238, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART2_TXD__UART2_TXD			IOMUX_PAD(0x62C, 0x23C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART3_RXD__UART3_RXD			IOMUX_PAD(0x630, 0x240, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART3_TXD__UART3_TXD			IOMUX_PAD(0x634, 0x244, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_OWIRE_LINE__OWIRE_LINE			IOMUX_PAD(0x638, 0x248, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW0__KEY_ROW0			IOMUX_PAD(0x63C, 0x24C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW1__KEY_ROW1			IOMUX_PAD(0x640, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW2__KEY_ROW2			IOMUX_PAD(0x644, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW3__KEY_ROW3			IOMUX_PAD(0x648, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL0__KEY_COL0			IOMUX_PAD(0x64C, 0x25C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL1__KEY_COL1			IOMUX_PAD(0x650, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL2__KEY_COL2			IOMUX_PAD(0x654, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL3__KEY_COL3			IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL4__KEY_COL4			IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL5__KEY_COL5			IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_CLK__USBH1_CLK			IOMUX_PAD(0x678, 0x278, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DIR__USBH1_DIR			IOMUX_PAD(0x67C, 0x27C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_STP__USBH1_STP			IOMUX_PAD(0x680, 0x280, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_NXT__USBH1_NXT			IOMUX_PAD(0x684, 0x284, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA0__USBH1_DATA0		IOMUX_PAD(0x688, 0x288, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA1__USBH1_DATA1		IOMUX_PAD(0x68C, 0x28C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA2__USBH1_DATA2		IOMUX_PAD(0x690, 0x290, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA3__USBH1_DATA3		IOMUX_PAD(0x694, 0x294, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA4__USBH1_DATA4		IOMUX_PAD(0x698, 0x298, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA5__USBH1_DATA5		IOMUX_PAD(0x69C, 0x29C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA6__USBH1_DATA6		IOMUX_PAD(0x6A0, 0x2A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA7__USBH1_DATA7		IOMUX_PAD(0x6A4, 0x2A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN11__DI1_PIN11			IOMUX_PAD(0x6A8, 0x2A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN12__DI1_PIN12			IOMUX_PAD(0x6AC, 0x2AC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN13__DI1_PIN13			IOMUX_PAD(0x6B0, 0x2B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_D0_CS__DI1_D0_CS			IOMUX_PAD(0x6B4, 0x2B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_D1_CS__DI1_D1_CS			IOMUX_PAD(0x6B8, 0x2B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN		IOMUX_PAD(0x6BC, 0x2BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO		IOMUX_PAD(0x6C0, 0x2C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK		IOMUX_PAD(0x6C4, 0x2C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS		IOMUX_PAD(0x6C8, 0x2C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT0__DISP1_DAT0			IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT1__DISP1_DAT1			IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT2__DISP1_DAT2			IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT3__DISP1_DAT3			IOMUX_PAD(0x6D8, 0x2D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT4__DISP1_DAT4			IOMUX_PAD(0x6DC, 0x2DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT5__DISP1_DAT5			IOMUX_PAD(0x6E0, 0x2E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT6__DISP1_DAT6			IOMUX_PAD(0x6E4, 0x2E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT7__DISP1_DAT7			IOMUX_PAD(0x6E8, 0x2E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT8__DISP1_DAT8			IOMUX_PAD(0x6EC, 0x2EC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT9__DISP1_DAT9			IOMUX_PAD(0x6F0, 0x2F0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT10__DISP1_DAT10		IOMUX_PAD(0x6F4, 0x2F4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT11__DISP1_DAT11		IOMUX_PAD(0x6F8, 0x2F8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT12__DISP1_DAT12		IOMUX_PAD(0x6FC, 0x2FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT13__DISP1_DAT13		IOMUX_PAD(0x700, 0x300, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT14__DISP1_DAT14		IOMUX_PAD(0x704, 0x304, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT15__DISP1_DAT15		IOMUX_PAD(0x708, 0x308, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT16__DISP1_DAT16		IOMUX_PAD(0x70C, 0x30C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT17__DISP1_DAT17		IOMUX_PAD(0x710, 0x310, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT18__DISP1_DAT18		IOMUX_PAD(0x714, 0x314, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT19__DISP1_DAT19		IOMUX_PAD(0x718, 0x318, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT20__DISP1_DAT20		IOMUX_PAD(0x71C, 0x31C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT21__DISP1_DAT21		IOMUX_PAD(0x720, 0x320, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT22__DISP1_DAT22		IOMUX_PAD(0x724, 0x324, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT23__DISP1_DAT23		IOMUX_PAD(0x728, 0x328, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN3__DI1_PIN3			IOMUX_PAD(0x72C, 0x32C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN2__DI1_PIN2			IOMUX_PAD(0x734, 0x330, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP1__DI_GP1				IOMUX_PAD(0x73C, 0x334, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP2__DI_GP2				IOMUX_PAD(0x740, 0x338, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP3__DI_GP3				IOMUX_PAD(0x744, 0x33C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN4__DI2_PIN4			IOMUX_PAD(0x748, 0x340, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN2__DI2_PIN2			IOMUX_PAD(0x74C, 0x344, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN3__DI2_PIN3			IOMUX_PAD(0x750, 0x348, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK		IOMUX_PAD(0x754, 0x34C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP4__DI_GP4				IOMUX_PAD(0x758, 0x350, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT0__DISP2_DAT0			IOMUX_PAD(0x75C, 0x354, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT1__DISP2_DAT1			IOMUX_PAD(0x760, 0x358, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT2__DISP2_DAT2			IOMUX_PAD(0x764, 0x35C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT3__DISP2_DAT3			IOMUX_PAD(0x768, 0x360, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT4__DISP2_DAT4			IOMUX_PAD(0x76C, 0x364, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT5__DISP2_DAT5			IOMUX_PAD(0x770, 0x368, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT6__DISP2_DAT6			IOMUX_PAD(0x774, 0x36C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT7__DISP2_DAT7			IOMUX_PAD(0x778, 0x370, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT8__DISP2_DAT8			IOMUX_PAD(0x77C, 0x374, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT9__DISP2_DAT9			IOMUX_PAD(0x780, 0x378, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT10__DISP2_DAT10		IOMUX_PAD(0x784, 0x37C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT11__DISP2_DAT11		IOMUX_PAD(0x788, 0x380, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT12__DISP2_DAT12		IOMUX_PAD(0x78C, 0x384, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT13__DISP2_DAT13		IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT14__DISP2_DAT14		IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT15__DISP2_DAT15		IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CMD__SD1_CMD			IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CLK__SD1_CLK			IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA0__SD1_DATA0			IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA1__SD1_DATA1			IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA2__SD1_DATA2			IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA3__SD1_DATA3			IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_0__GPIO1_0			IOMUX_PAD(0x7B4, 0x3AC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_1__GPIO1_1			IOMUX_PAD(0x7B8, 0x3B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CMD__SD2_CMD			IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CLK__SD2_CLK			IOMUX_PAD(0x7C0, 0x3B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA0__SD2_DATA0			IOMUX_PAD(0x7C4, 0x3BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA1__SD2_DATA1			IOMUX_PAD(0x7C8, 0x3C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA2__SD2_DATA2			IOMUX_PAD(0x7CC, 0x3C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA3__SD2_DATA3			IOMUX_PAD(0x7D0, 0x3C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_2__GPIO1_2			IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_3__GPIO1_3			IOMUX_PAD(0x7D8, 0x3D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ		IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_4__GPIO1_4			IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_5__GPIO1_5			IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_6__GPIO1_6			IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_7__GPIO1_7			IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_8__GPIO1_8			IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO1_9__GPIO1_9			IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
+#endif /* __MACH_IOMUX_MX51_H__ */
+
diff --git a/arch/arm/mach-imx/include/mach/iomux-v3.h b/arch/arm/mach-imx/include/mach/iomux-v3.h
index 1d660a0..198286a 100644
--- a/arch/arm/mach-imx/include/mach/iomux-v3.h
+++ b/arch/arm/mach-imx/include/mach/iomux-v3.h
@@ -84,13 +84,17 @@ struct pad_desc {
 #define PAD_CTL_OUTPUT_CMOS		(0)
 #define PAD_CTL_OUTPUT_OPEN_DRAIN	(1 << 3)
 
-#define PAD_CTL_DRIVE_STRENGTH_NORM	(0)
-#define PAD_CTL_DRIVE_STRENGTH_HIGH	(1 << 1)
-#define PAD_CTL_DRIVE_STRENGTH_MAX	(2 << 1)
+#define PAD_CTL_DRIVE_STRENGTH_LOW	(0 << 1)
+#define PAD_CTL_DRIVE_STRENGTH_MED	(1 << 1)
+#define PAD_CTL_DRIVE_STRENGTH_HIGH	(2 << 1)
+#define PAD_CTL_DRIVE_STRENGTH_MAX	(3 << 1)
 
 #define PAD_CTL_SLEW_RATE_SLOW		0
 #define PAD_CTL_SLEW_RATE_FAST		1
 
+#define PAD_CTL_DRV_VOT_LOW            (0 << 13)
+#define PAD_CTL_DRV_VOT_HIGH           (1 << 13)
+
 /*
  * setups a single pad:
  * 	- reserves the pad so that it is not claimed by another driver
diff --git a/arch/arm/mach-imx/speed-imx51.c b/arch/arm/mach-imx/speed-imx51.c
new file mode 100644
index 0000000..dcfc874
--- /dev/null
+++ b/arch/arm/mach-imx/speed-imx51.c
@@ -0,0 +1,163 @@
+#include <common.h>
+#include <asm/io.h>
+#include <asm-generic/div64.h>
+#include <mach/imx51-regs.h>
+#include "mach/clock-imx51.h"
+
+static u32 ccm_readl(u32 ofs)
+{
+	return readl(MX51_CCM_BASE_ADDR + ofs);
+}
+
+static unsigned long ckil_get_rate(void)
+{
+	return 32768;
+}
+
+static unsigned long osc_get_rate(void)
+{
+	return 24000000;
+}
+
+static unsigned long fpm_get_rate(void)
+{
+	return ckil_get_rate() * 512;
+}
+
+static unsigned long pll_get_rate(void __iomem *pllbase)
+{
+	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+	unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+	u64 temp;
+	unsigned long parent_rate;
+
+	dp_ctl = readl(pllbase + MX51_PLL_DP_CTL);
+
+	if ((dp_ctl & MX51_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+		parent_rate = fpm_get_rate();
+	else
+		parent_rate = osc_get_rate();
+
+	pll_hfsm = dp_ctl & MX51_PLL_DP_CTL_HFSM;
+	dbl = dp_ctl & MX51_PLL_DP_CTL_DPDCK0_2_EN;
+
+	if (pll_hfsm == 0) {
+		dp_op = readl(pllbase + MX51_PLL_DP_OP);
+		dp_mfd = readl(pllbase + MX51_PLL_DP_MFD);
+		dp_mfn = readl(pllbase + MX51_PLL_DP_MFN);
+	} else {
+		dp_op = readl(pllbase + MX51_PLL_DP_HFS_OP);
+		dp_mfd = readl(pllbase + MX51_PLL_DP_HFS_MFD);
+		dp_mfn = readl(pllbase + MX51_PLL_DP_HFS_MFN);
+	}
+	pdf = dp_op & MX51_PLL_DP_OP_PDF_MASK;
+	mfi = (dp_op & MX51_PLL_DP_OP_MFI_MASK) >> MX51_PLL_DP_OP_MFI_OFFSET;
+	mfi = (mfi <= 5) ? 5 : mfi;
+	mfd = dp_mfd & MX51_PLL_DP_MFD_MASK;
+	mfn = mfn_abs = dp_mfn & MX51_PLL_DP_MFN_MASK;
+	/* Sign extend to 32-bits */
+	if (mfn >= 0x04000000) {
+		mfn |= 0xFC000000;
+		mfn_abs = -mfn;
+	}
+
+	ref_clk = 2 * parent_rate;
+	if (dbl != 0)
+		ref_clk *= 2;
+
+	ref_clk /= (pdf + 1);
+	temp = (u64)ref_clk * mfn_abs;
+	do_div(temp, mfd + 1);
+	if (mfn < 0)
+		temp = -temp;
+	temp = (ref_clk * mfi) + temp;
+
+	return temp;
+}
+
+static unsigned long pll1_main_get_rate(void)
+{
+	return pll_get_rate((void __iomem *)MX51_PLL1_BASE_ADDR);
+}
+
+static unsigned long pll2_sw_get_rate(void)
+{
+	return pll_get_rate((void __iomem *)MX51_PLL2_BASE_ADDR);
+}
+
+static unsigned long pll3_sw_get_rate(void)
+{
+	return pll_get_rate((void __iomem *)MX51_PLL3_BASE_ADDR);
+}
+
+unsigned long imx_get_uartclk(void)
+{
+	u32 reg, prediv, podf;
+	unsigned long parent_rate;
+
+	parent_rate = pll2_sw_get_rate();
+
+	reg = ccm_readl(MX51_CCM_CSCDR1);
+	prediv = ((reg & MX51_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
+		  MX51_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
+	podf = ((reg & MX51_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+		MX51_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+
+	return parent_rate / (prediv * podf);
+}
+
+static unsigned long imx_get_ahbclk(void)
+{
+	u32 reg, div;
+
+	reg = ccm_readl(MX51_CCM_CBCDR);
+	div = ((reg >> 10) & 0x7) + 1;
+
+	return pll2_sw_get_rate() / div;
+}
+
+unsigned long imx_get_ipgclk(void)
+{
+	u32 reg, div;
+
+	reg = ccm_readl(MX51_CCM_CBCDR);
+	div = ((reg >> 8) & 0x3) + 1;
+
+	return imx_get_ahbclk() / div;
+}
+
+unsigned long imx_get_gptclk(void)
+{
+	return imx_get_ipgclk();
+}
+
+unsigned long imx_get_fecclk(void)
+{
+	return imx_get_ipgclk();
+}
+
+unsigned long imx_get_mmcclk(void)
+{
+	u32 reg, prediv, podf, rate;
+
+	reg = ccm_readl(MX51_CCM_CSCDR1);
+	prediv = ((reg & MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) >>
+			MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET) + 1;
+	podf = ((reg & MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) >>
+			MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET) + 1;
+
+	rate = pll2_sw_get_rate() / (prediv * podf);
+
+	return rate;
+}
+
+void imx_dump_clocks(void)
+{
+	printf("pll1: %ld\n", pll1_main_get_rate());
+	printf("pll2: %ld\n", pll2_sw_get_rate());
+	printf("pll3: %ld\n", pll3_sw_get_rate());
+	printf("uart: %ld\n", imx_get_uartclk());
+	printf("ipg:  %ld\n", imx_get_ipgclk());
+	printf("fec:  %ld\n", imx_get_fecclk());
+	printf("gpt:  %ld\n", imx_get_gptclk());
+}
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index 1d3f4f7..fc141a4 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -1,5 +1,5 @@
 
-#if defined CONFIG_ARCH_IMX25 || defined CONFIG_ARCH_IMX35
+#if defined CONFIG_ARCH_IMX25 || defined CONFIG_ARCH_IMX35 || defined CONFIG_ARCH_IMX51
 #include <mach/barebox.lds.h>
 #endif
 
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Oct 11 08:26:12 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 14:26:12 +0200
Subject: [PATCH 13/17] defaultenv: handle disk partitions
In-Reply-To: <1286796505-16049-14-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<1286796505-16049-14-git-send-email-s.hauer@pengutronix.de>
Message-ID: <201010111426.13066.jbe@pengutronix.de>

Sascha Hauer wrote:
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  defaultenv/bin/init |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/defaultenv/bin/init b/defaultenv/bin/init
> index a55e8e6..526e3db 100644
> --- a/defaultenv/bin/init
> +++ b/defaultenv/bin/init
> @@ -8,6 +8,10 @@ if [ -e /dev/nor0 ]; then
>  	addpart /dev/nor0 $nor_parts
>  fi
>
> +if [ -e /dev/disk0 ]; then
> +	addpart /dev/disk0 $disk_parts
> +fi
> +

Are you sure you want/need additional partitions on a disk without a 
persistant partition table?

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Mon Oct 11 08:50:18 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 14:50:18 +0200
Subject: [PATCH 13/17] defaultenv: handle disk partitions
In-Reply-To: <201010111426.13066.jbe@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<1286796505-16049-14-git-send-email-s.hauer@pengutronix.de>
	<201010111426.13066.jbe@pengutronix.de>
Message-ID: <20101011125018.GV28242@pengutronix.de>

On Mon, Oct 11, 2010 at 02:26:12PM +0200, Juergen Beisert wrote:
> Sascha Hauer wrote:
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  defaultenv/bin/init |    4 ++++
> >  1 files changed, 4 insertions(+), 0 deletions(-)
> >
> > diff --git a/defaultenv/bin/init b/defaultenv/bin/init
> > index a55e8e6..526e3db 100644
> > --- a/defaultenv/bin/init
> > +++ b/defaultenv/bin/init
> > @@ -8,6 +8,10 @@ if [ -e /dev/nor0 ]; then
> >  	addpart /dev/nor0 $nor_parts
> >  fi
> >
> > +if [ -e /dev/disk0 ]; then
> > +	addpart /dev/disk0 $disk_parts
> > +fi
> > +
> 
> Are you sure you want/need additional partitions on a disk without a 
> persistant partition table?

No ;)

It is not completely clear to me how we handle this best. On i.MX51 I
have some problems with the partition table. When booting from SD card
we just dump barebox.bin to the raw card. The partition table is then
part of barebox.bin. Unfortunately we do not know (or at least we don't
want to specifiy) the size of the card during compile time.

How should a bootable SD card should be partitioned anyway? We could add
partitions for barebox/env/kernel/root like usual, but this does not
look very standard for SD cards (and we even need extended partitions
if we want to add a data partition). We could also add just a single
partition for root and maintain the rest outside of any partition.

I haven't really thought this to an end.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Mon Oct 11 08:48:43 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 14:48:43 +0200
Subject: [PATCH 11/17] mci: handle SD cards < 2.0 correctly
In-Reply-To: <1286796505-16049-12-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<1286796505-16049-12-git-send-email-s.hauer@pengutronix.de>
Message-ID: <201010111448.43598.jbe@pengutronix.de>

Sascha Hauer wrote:
> With SD cards older than 2.0 the sd_send_if_cond() fails. Do
> not assume it's an MMC card in this case. Instead, assume
> it's a MMC card if sd_send_op_cond() fails.
>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/mci/mci-core.c |   24 +++++++-----------------
>  1 files changed, 7 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
> index a6c81b8..57b82bf 100644
> --- a/drivers/mci/mci-core.c
> +++ b/drivers/mci/mci-core.c
> @@ -1148,26 +1148,16 @@ static int mci_card_probe(struct device_d *mci_dev)
>
>  	/* Check if this card can handle the "SD Card Physical Layer
> Specification 2.0" */ rc = sd_send_if_cond(mci_dev);
> -	if (rc) {
> +	rc = sd_send_op_cond(mci_dev);
> +	if (rc && rc == -ETIMEDOUT) {
>  		/* If the command timed out, we check for an MMC card */
> -		if (rc == -ETIMEDOUT) {
> -			pr_debug("Card seems to be a MultiMediaCard\n");
> -			rc = mmc_send_op_cond(mci_dev);
> -			if (rc) {
> -				pr_err("MultiMediaCard voltage select failed with %d\n", rc);
> -				goto on_error;
> -			}
> -		} else
> -			goto on_error;
> -	} else {
> -		/* Its a 2.xx card. Setup operation conditions */
> -		rc = sd_send_op_cond(mci_dev);
> -		if (rc) {
> -			pr_debug("Cannot setup SD card's operation condition\n");
> -			goto on_error;
> -		}
> +		pr_debug("Card seems to be a MultiMediaCard\n");
> +		rc = mmc_send_op_cond(mci_dev);
>  	}
>
> +	if (rc)
> +		goto on_error;
> +
>  	rc = mci_startup(mci_dev);
>  	if (rc) {
>  		printf("Card's startup fails with %d\n", rc);

Tested-by: Juergen Beisert <jbe at pengutronix.de>

@Marek: You need this patch to make your SD card work on the mini2440.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From plagnioj at jcrosoft.com  Mon Oct 11 08:48:45 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 14:48:45 +0200
Subject: [PATCH] barebox-next: Avoid a Kconfig warning
In-Reply-To: <201010111050.28141.jbe@pengutronix.de>
References: <201010111050.28141.jbe@pengutronix.de>
Message-ID: <20101011124845.GG30252@game.jcrosoft.org>

On 10:50 Mon 11 Oct     , Juergen Beisert wrote:
> This patch removes the following warning in the current next-tree:
> 
> "arch/arm/mach-imx/Kconfig:53:warning: defaults for choice values not supported"
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
already fix in master

Best Regards,
J.


From jbe at pengutronix.de  Mon Oct 11 08:53:22 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 14:53:22 +0200
Subject: [PATCH 11/17] mci: handle SD cards < 2.0 correctly
In-Reply-To: <1286796505-16049-12-git-send-email-s.hauer@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<1286796505-16049-12-git-send-email-s.hauer@pengutronix.de>
Message-ID: <201010111453.22164.jbe@pengutronix.de>

Hi Sascha,

Sascha Hauer wrote:
> With SD cards older than 2.0 the sd_send_if_cond() fails. Do
> not assume it's an MMC card in this case. Instead, assume
> it's a MMC card if sd_send_op_cond() fails.

With your patch you can add this one also:

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index f961e46..bf060b5 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -45,7 +45,7 @@
  * @brief Memory Card framework
  *
  * Checked with the following cards:
- * - old Canon SD 16 MiB, does not like the 0x08 command (SD_CMD_SEND_IF_COND) -> failed
+ * - Canon MMC 16 MiB
  * - Kingston 512 MiB
  * - SanDisk 512 MiB
  * - Transcend SD Ultra, 1 GiB (Industrial)

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Mon Oct 11 08:59:35 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 14:59:35 +0200
Subject: [PATCH 13/17] defaultenv: handle disk partitions
In-Reply-To: <20101011125018.GV28242@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<201010111426.13066.jbe@pengutronix.de>
	<20101011125018.GV28242@pengutronix.de>
Message-ID: <201010111459.35914.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Mon, Oct 11, 2010 at 02:26:12PM +0200, Juergen Beisert wrote:
> > Sascha Hauer wrote:
> > > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > > ---
> > >  defaultenv/bin/init |    4 ++++
> > >  1 files changed, 4 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/defaultenv/bin/init b/defaultenv/bin/init
> > > index a55e8e6..526e3db 100644
> > > --- a/defaultenv/bin/init
> > > +++ b/defaultenv/bin/init
> > > @@ -8,6 +8,10 @@ if [ -e /dev/nor0 ]; then
> > >  	addpart /dev/nor0 $nor_parts
> > >  fi
> > >
> > > +if [ -e /dev/disk0 ]; then
> > > +	addpart /dev/disk0 $disk_parts
> > > +fi
> > > +
> >
> > Are you sure you want/need additional partitions on a disk without a
> > persistant partition table?
>
> No ;)
>
> It is not completely clear to me how we handle this best. On i.MX51 I
> have some problems with the partition table. When booting from SD card
> we just dump barebox.bin to the raw card. The partition table is then
> part of barebox.bin. Unfortunately we do not know (or at least we don't
> want to specifiy) the size of the card during compile time.
>
> How should a bootable SD card should be partitioned anyway? We could add
> partitions for barebox/env/kernel/root like usual, but this does not
> look very standard for SD cards (and we even need extended partitions
> if we want to add a data partition). We could also add just a single
> partition for root and maintain the rest outside of any partition.

If you want your kernel to work with this card you will need a partition 
table. Its more like a hard disk, not like a flash memory of NAND or NOR 
type. So, IMHO you will need a full blown partition table when you want use 
the SD card outside barebox.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Mon Oct 11 09:00:08 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 15:00:08 +0200
Subject: [PATCH] barebox-next: Avoid a Kconfig warning
In-Reply-To: <20101011124845.GG30252@game.jcrosoft.org>
References: <201010111050.28141.jbe@pengutronix.de>
	<20101011124845.GG30252@game.jcrosoft.org>
Message-ID: <201010111500.08251.jbe@pengutronix.de>

Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 10:50 Mon 11 Oct     , Juergen Beisert wrote:
> > This patch removes the following warning in the current next-tree:
> >
> > "arch/arm/mach-imx/Kconfig:53:warning: defaults for choice values not
> > supported"
> >
> > Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
>
> already fix in master

Ups, but not in next.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From marek.belisko at gmail.com  Mon Oct 11 09:07:44 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Mon, 11 Oct 2010 15:07:44 +0200
Subject: [PATCH 11/17] mci: handle SD cards < 2.0 correctly
In-Reply-To: <201010111448.43598.jbe@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<1286796505-16049-12-git-send-email-s.hauer@pengutronix.de>
	<201010111448.43598.jbe@pengutronix.de>
Message-ID: <AANLkTi=hs=GY895Ab1COooFJFbmujrGSHjXKwT5aQo0_@mail.gmail.com>

Hi Juergen,

On Mon, Oct 11, 2010 at 2:48 PM, Juergen Beisert <jbe at pengutronix.de> wrote:
> Sascha Hauer wrote:
>> With SD cards older than 2.0 the sd_send_if_cond() fails. Do
>> not assume it's an MMC card in this case. Instead, assume
>> it's a MMC card if sd_send_op_cond() fails.
>>
>> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
>> ---
>> ?drivers/mci/mci-core.c | ? 24 +++++++-----------------
>> ?1 files changed, 7 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
>> index a6c81b8..57b82bf 100644
>> --- a/drivers/mci/mci-core.c
>> +++ b/drivers/mci/mci-core.c
>> @@ -1148,26 +1148,16 @@ static int mci_card_probe(struct device_d *mci_dev)
>>
>> ? ? ? /* Check if this card can handle the "SD Card Physical Layer
>> Specification 2.0" */ rc = sd_send_if_cond(mci_dev);
>> - ? ? if (rc) {
>> + ? ? rc = sd_send_op_cond(mci_dev);
>> + ? ? if (rc && rc == -ETIMEDOUT) {
>> ? ? ? ? ? ? ? /* If the command timed out, we check for an MMC card */
>> - ? ? ? ? ? ? if (rc == -ETIMEDOUT) {
>> - ? ? ? ? ? ? ? ? ? ? pr_debug("Card seems to be a MultiMediaCard\n");
>> - ? ? ? ? ? ? ? ? ? ? rc = mmc_send_op_cond(mci_dev);
>> - ? ? ? ? ? ? ? ? ? ? if (rc) {
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? pr_err("MultiMediaCard voltage select failed with %d\n", rc);
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? goto on_error;
>> - ? ? ? ? ? ? ? ? ? ? }
>> - ? ? ? ? ? ? } else
>> - ? ? ? ? ? ? ? ? ? ? goto on_error;
>> - ? ? } else {
>> - ? ? ? ? ? ? /* Its a 2.xx card. Setup operation conditions */
>> - ? ? ? ? ? ? rc = sd_send_op_cond(mci_dev);
>> - ? ? ? ? ? ? if (rc) {
>> - ? ? ? ? ? ? ? ? ? ? pr_debug("Cannot setup SD card's operation condition\n");
>> - ? ? ? ? ? ? ? ? ? ? goto on_error;
>> - ? ? ? ? ? ? }
>> + ? ? ? ? ? ? pr_debug("Card seems to be a MultiMediaCard\n");
>> + ? ? ? ? ? ? rc = mmc_send_op_cond(mci_dev);
>> ? ? ? }
>>
>> + ? ? if (rc)
>> + ? ? ? ? ? ? goto on_error;
>> +
>> ? ? ? rc = mci_startup(mci_dev);
>> ? ? ? if (rc) {
>> ? ? ? ? ? ? ? printf("Card's startup fails with %d\n", rc);
>
> Tested-by: Juergen Beisert <jbe at pengutronix.de>
>
> @Marek: You need this patch to make your SD card work on the mini2440.
After applying a patch it 's better but it hangs:
IO settings: bus width=1, frequency=0 Hz
IO settings: bus width=1, frequency=200098 Hz
Command with response
Command with response
Command with response
Command with response
Put the Card in Identify Mode
Command with response
Command with long response
Card's identification data is: 1B534D53-44202020-10C811B9-74008197
Get/Set relative address
Command with response
Get card's specific data
Command with response
Command with long response
Card's specific data is: 002F0032-5F5983CA-6DB7FF9F-96400063
Transfer speed: 25000000
Max. block length are: Write=512, Read=512 Bytes
Capacity: 970 MiB
Read block length: 512, Write block length: 512
Select the card, and put it into Transfer Mode
Command with response
Changing transfer frequency
Command with response
Trying to read the SCR (try 1 of 3)
Command with response
Command with response
Command with response
IO settings: bus width=1, frequency=50625000 Hz
Command with response
Card is up and running now, registering as a disk
mci_sd_read called: Read 1 block(s), starting at 0 to 31BBFBB9
Command with response

Than it hangs maybe in while(1) in s3c_send_command?

>
> jbe
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Beisert ? ? ? ? ? ? |
> Linux Solutions for Science and Industry ? ? ?| Phone: +49-8766-939 228 ? ? |
> Vertretung Sued/Muenchen, Germany ? ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? ? ?| http://www.pengutronix.de/ ?|
>

BR,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From jbe at pengutronix.de  Mon Oct 11 09:47:35 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 15:47:35 +0200
Subject: [PATCH 11/17] mci: handle SD cards < 2.0 correctly
In-Reply-To: <AANLkTi=hs=GY895Ab1COooFJFbmujrGSHjXKwT5aQo0_@mail.gmail.com>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<201010111448.43598.jbe@pengutronix.de>
	<AANLkTi=hs=GY895Ab1COooFJFbmujrGSHjXKwT5aQo0_@mail.gmail.com>
Message-ID: <201010111547.36511.jbe@pengutronix.de>

Hi Marek,

Belisko Marek wrote:
> On Mon, Oct 11, 2010 at 2:48 PM, Juergen Beisert <jbe at pengutronix.de> wrote:
> > Sascha Hauer wrote:
> >> With SD cards older than 2.0 the sd_send_if_cond() fails. Do
> >> not assume it's an MMC card in this case. Instead, assume
> >> it's a MMC card if sd_send_op_cond() fails.
> >>
> >> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> >> ---
> >> ?drivers/mci/mci-core.c | ? 24 +++++++-----------------
> >> ?1 files changed, 7 insertions(+), 17 deletions(-)
> >>
> >> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
> >> index a6c81b8..57b82bf 100644
> >> --- a/drivers/mci/mci-core.c
> >> +++ b/drivers/mci/mci-core.c
> >> @@ -1148,26 +1148,16 @@ static int mci_card_probe(struct device_d
> >> *mci_dev)
> >>
> >> ? ? ? /* Check if this card can handle the "SD Card Physical Layer
> >> Specification 2.0" */ rc = sd_send_if_cond(mci_dev);
> >> - ? ? if (rc) {
> >> + ? ? rc = sd_send_op_cond(mci_dev);
> >> + ? ? if (rc && rc == -ETIMEDOUT) {
> >> ? ? ? ? ? ? ? /* If the command timed out, we check for an MMC card */
> >> - ? ? ? ? ? ? if (rc == -ETIMEDOUT) {
> >> - ? ? ? ? ? ? ? ? ? ? pr_debug("Card seems to be a MultiMediaCard\n");
> >> - ? ? ? ? ? ? ? ? ? ? rc = mmc_send_op_cond(mci_dev);
> >> - ? ? ? ? ? ? ? ? ? ? if (rc) {
> >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? pr_err("MultiMediaCard voltage select
> >> failed with %d\n", rc); - ? ? ? ? ? ? ? ? ? ? ? ? ? ? goto on_error;
> >> - ? ? ? ? ? ? ? ? ? ? }
> >> - ? ? ? ? ? ? } else
> >> - ? ? ? ? ? ? ? ? ? ? goto on_error;
> >> - ? ? } else {
> >> - ? ? ? ? ? ? /* Its a 2.xx card. Setup operation conditions */
> >> - ? ? ? ? ? ? rc = sd_send_op_cond(mci_dev);
> >> - ? ? ? ? ? ? if (rc) {
> >> - ? ? ? ? ? ? ? ? ? ? pr_debug("Cannot setup SD card's operation
> >> condition\n"); - ? ? ? ? ? ? ? ? ? ? goto on_error;
> >> - ? ? ? ? ? ? }
> >> + ? ? ? ? ? ? pr_debug("Card seems to be a MultiMediaCard\n");
> >> + ? ? ? ? ? ? rc = mmc_send_op_cond(mci_dev);
> >> ? ? ? }
> >>
> >> + ? ? if (rc)
> >> + ? ? ? ? ? ? goto on_error;
> >> +
> >> ? ? ? rc = mci_startup(mci_dev);
> >> ? ? ? if (rc) {
> >> ? ? ? ? ? ? ? printf("Card's startup fails with %d\n", rc);
> >
> > Tested-by: Juergen Beisert <jbe at pengutronix.de>
> >
> > @Marek: You need this patch to make your SD card work on the mini2440.
>
> After applying a patch it 's better but it hangs:
> IO settings: bus width=1, frequency=0 Hz
> IO settings: bus width=1, frequency=200098 Hz
> Command with response
> Command with response
> Command with response
> Command with response
> Put the Card in Identify Mode
> Command with response
> Command with long response
> Card's identification data is: 1B534D53-44202020-10C811B9-74008197
> Get/Set relative address
> Command with response
> Get card's specific data
> Command with response
> Command with long response
> Card's specific data is: 002F0032-5F5983CA-6DB7FF9F-96400063
> Transfer speed: 25000000
> Max. block length are: Write=512, Read=512 Bytes
> Capacity: 970 MiB
> Read block length: 512, Write block length: 512
> Select the card, and put it into Transfer Mode
> Command with response
> Changing transfer frequency
> Command with response
> Trying to read the SCR (try 1 of 3)
> Command with response
> Command with response
> Command with response
> IO settings: bus width=1, frequency=50625000 Hz
> Command with response
> Card is up and running now, registering as a disk
> mci_sd_read called: Read 1 block(s), starting at 0 to 31BBFBB9
> Command with response
>
> Than it hangs maybe in while(1) in s3c_send_command?

Your card is already probed and now the disk layer tries to read the partition 
table.

There seems a bug in one of the routines. The cards states:

> Transfer speed: 25000000

but the mci-core wants more:

> IO settings: bus width=1, frequency=50625000 Hz
                                      ^^^^^^^^^^^
I will check for it.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Mon Oct 11 09:54:54 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 15:54:54 +0200
Subject: [PATCH 13/17] defaultenv: handle disk partitions
In-Reply-To: <201010111459.35914.jbe@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<201010111426.13066.jbe@pengutronix.de>
	<20101011125018.GV28242@pengutronix.de>
	<201010111459.35914.jbe@pengutronix.de>
Message-ID: <20101011135454.GZ28242@pengutronix.de>

On Mon, Oct 11, 2010 at 02:59:35PM +0200, Juergen Beisert wrote:
> Sascha Hauer wrote:
> > On Mon, Oct 11, 2010 at 02:26:12PM +0200, Juergen Beisert wrote:
> > > Sascha Hauer wrote:
> > > > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > > > ---
> > > >  defaultenv/bin/init |    4 ++++
> > > >  1 files changed, 4 insertions(+), 0 deletions(-)
> > > >
> > > > diff --git a/defaultenv/bin/init b/defaultenv/bin/init
> > > > index a55e8e6..526e3db 100644
> > > > --- a/defaultenv/bin/init
> > > > +++ b/defaultenv/bin/init
> > > > @@ -8,6 +8,10 @@ if [ -e /dev/nor0 ]; then
> > > >  	addpart /dev/nor0 $nor_parts
> > > >  fi
> > > >
> > > > +if [ -e /dev/disk0 ]; then
> > > > +	addpart /dev/disk0 $disk_parts
> > > > +fi
> > > > +
> > >
> > > Are you sure you want/need additional partitions on a disk without a
> > > persistant partition table?
> >
> > No ;)
> >
> > It is not completely clear to me how we handle this best. On i.MX51 I
> > have some problems with the partition table. When booting from SD card
> > we just dump barebox.bin to the raw card. The partition table is then
> > part of barebox.bin. Unfortunately we do not know (or at least we don't
> > want to specifiy) the size of the card during compile time.
> >
> > How should a bootable SD card should be partitioned anyway? We could add
> > partitions for barebox/env/kernel/root like usual, but this does not
> > look very standard for SD cards (and we even need extended partitions
> > if we want to add a data partition). We could also add just a single
> > partition for root and maintain the rest outside of any partition.
> 
> If you want your kernel to work with this card you will need a partition 
> table. Its more like a hard disk, not like a flash memory of NAND or NOR 
> type. So, IMHO you will need a full blown partition table when you want use 
> the SD card outside barebox.

Yes I know. Do we need a fdisk command for barebox?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From plagnioj at jcrosoft.com  Mon Oct 11 09:53:29 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 15:53:29 +0200
Subject: defaultv env update v2
Message-ID: <20101011135329.GA7412@game.jcrosoft.org>

Hi,

	the following patch series update the update default env support by
	using getopts and allow us to specify via Kconfig the dependecy of the
	defaultenv

	a secondi step could be to use the preprocessir to generate some part
	of it

Best Regards,
J.


From jbe at pengutronix.de  Mon Oct 11 10:22:14 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 16:22:14 +0200
Subject: [PATCH 13/17] defaultenv: handle disk partitions
In-Reply-To: <20101011135454.GZ28242@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<201010111459.35914.jbe@pengutronix.de>
	<20101011135454.GZ28242@pengutronix.de>
Message-ID: <201010111622.15352.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Mon, Oct 11, 2010 at 02:59:35PM +0200, Juergen Beisert wrote:
> > Sascha Hauer wrote:
> > > On Mon, Oct 11, 2010 at 02:26:12PM +0200, Juergen Beisert wrote:
> > > > Sascha Hauer wrote:
> > > > > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > > > > ---
> > > > >  defaultenv/bin/init |    4 ++++
> > > > >  1 files changed, 4 insertions(+), 0 deletions(-)
> > > > >
> > > > > diff --git a/defaultenv/bin/init b/defaultenv/bin/init
> > > > > index a55e8e6..526e3db 100644
> > > > > --- a/defaultenv/bin/init
> > > > > +++ b/defaultenv/bin/init
> > > > > @@ -8,6 +8,10 @@ if [ -e /dev/nor0 ]; then
> > > > >  	addpart /dev/nor0 $nor_parts
> > > > >  fi
> > > > >
> > > > > +if [ -e /dev/disk0 ]; then
> > > > > +	addpart /dev/disk0 $disk_parts
> > > > > +fi
> > > > > +
> > > >
> > > > Are you sure you want/need additional partitions on a disk without a
> > > > persistant partition table?
> > >
> > > No ;)
> > >
> > > It is not completely clear to me how we handle this best. On i.MX51 I
> > > have some problems with the partition table. When booting from SD card
> > > we just dump barebox.bin to the raw card. The partition table is then
> > > part of barebox.bin. Unfortunately we do not know (or at least we don't
> > > want to specifiy) the size of the card during compile time.
> > >
> > > How should a bootable SD card should be partitioned anyway? We could
> > > add partitions for barebox/env/kernel/root like usual, but this does
> > > not look very standard for SD cards (and we even need extended
> > > partitions if we want to add a data partition). We could also add just
> > > a single partition for root and maintain the rest outside of any
> > > partition.
> >
> > If you want your kernel to work with this card you will need a partition
> > table. Its more like a hard disk, not like a flash memory of NAND or NOR
> > type. So, IMHO you will need a full blown partition table when you want
> > use the SD card outside barebox.
>
> Yes I know. Do we need a fdisk command for barebox?

IMHO not for barebox. Because to setup a full system on an SD card you would 
also need tools to create a filesystem on these partitions. That's not the 
job of a bootloader. We just have to handle partition tables in a correct 
manner.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From plagnioj at jcrosoft.com  Mon Oct 11 10:34:42 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 16:34:42 +0200
Subject: [PATCH 4/6] defaultenv/update: add check crc32 options
In-Reply-To: <20101011135329.GA7412@game.jcrosoft.org>
References: <20101011135329.GA7412@game.jcrosoft.org>
Message-ID: <1286807684-17355-4-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 common/Kconfig              |    2 ++
 defaultenv/bin/_update_help |    8 +++++---
 defaultenv/bin/update       |    8 +++++++-
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index e8d467e..617f640 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -394,6 +394,8 @@ config DEFAULT_ENVIRONMENT_GENERIC
 	depends on DEFAULT_ENVIRONMENT
 	select SHELL_HUSH
 	select HUSH_GETOPT
+	select CMD_CRC
+	select CMD_CRC_CMP
 	prompt "Default environment generic"
 	help
 	  With this option barebox will use the generic default
diff --git a/defaultenv/bin/_update_help b/defaultenv/bin/_update_help
index e6ea64c..a23f00f 100644
--- a/defaultenv/bin/_update_help
+++ b/defaultenv/bin/_update_help
@@ -1,8 +1,10 @@
 #!/bin/sh
 
-echo "usage: $0 -t <kernel|rootfs> -d <nor|nand> [-f imagename]"
+echo "usage: $0 -t <kernel|rootfs> -d <nor|nand> [-f imagename] -c"
 echo "update tools."
-echo""
+echo ""
+echo "options"
+echo " -c     to check the crc32 for the image and flashed one"
+echo ""
 echo "type update -t kernel -d <nor|nand> [-f imagename] to update kernel into flash"
 echo "type update -t rootfs -d <nor|nand> [-f imagename] to update rootfs into flash"
-
diff --git a/defaultenv/bin/update b/defaultenv/bin/update
index bdac11f..504bff6 100644
--- a/defaultenv/bin/update
+++ b/defaultenv/bin/update
@@ -4,8 +4,9 @@
 
 type=""
 device_type=""
+check=n
 
-while getopt "ht:d:f:" Option
+while getopt "ht:d:f:c" Option
 do
 if [ ${Option} = t ]; then
 	type=${OPTARG}
@@ -13,6 +14,8 @@ elif [ ${Option} = d ]; then
 	device_type=${OPTARG}
 elif [ ${Option} = f ]; then
 	imagename=${OPTARG}
+elif [ ${Option} = c ]; then
+	check=y
 else
 	. /env/bin/_update_help
 	exit 0
@@ -43,3 +46,6 @@ else
 fi
 
 . /env/bin/_update
+if [ x${check} = xy ]; then
+	crc32 -f $image -F $part
+fi
-- 
1.7.1



From plagnioj at jcrosoft.com  Mon Oct 11 10:34:41 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 16:34:41 +0200
Subject: [PATCH 3/6] defaultenv/update: merge update_rootfs and update_kernel
In-Reply-To: <20101011135329.GA7412@game.jcrosoft.org>
References: <20101011135329.GA7412@game.jcrosoft.org>
Message-ID: <1286807684-17355-3-git-send-email-plagnioj@jcrosoft.com>

use getopt to simplify it and prepare for xmodem support

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 common/Kconfig               |    1 +
 defaultenv/bin/_update       |    4 ---
 defaultenv/bin/_update_help  |    8 +++++++
 defaultenv/bin/init          |    3 +-
 defaultenv/bin/update        |   45 ++++++++++++++++++++++++++++++++++++++++++
 defaultenv/bin/update_kernel |   15 --------------
 defaultenv/bin/update_rootfs |   16 --------------
 7 files changed, 55 insertions(+), 37 deletions(-)
 create mode 100644 defaultenv/bin/_update_help
 create mode 100644 defaultenv/bin/update
 delete mode 100644 defaultenv/bin/update_kernel
 delete mode 100644 defaultenv/bin/update_rootfs

diff --git a/common/Kconfig b/common/Kconfig
index fb47397..e8d467e 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -393,6 +393,7 @@ config DEFAULT_ENVIRONMENT_GENERIC
 	bool
 	depends on DEFAULT_ENVIRONMENT
 	select SHELL_HUSH
+	select HUSH_GETOPT
 	prompt "Default environment generic"
 	help
 	  With this option barebox will use the generic default
diff --git a/defaultenv/bin/_update b/defaultenv/bin/_update
index ddd6b84..6f2ebd3 100644
--- a/defaultenv/bin/_update
+++ b/defaultenv/bin/_update
@@ -10,10 +10,6 @@ if [ ! -e "$part" ]; then
 	exit 1
 fi
 
-if [ $# = 1 ]; then
-	image=$1
-fi
-
 if [ x$ip = xdhcp ]; then
 	dhcp
 fi
diff --git a/defaultenv/bin/_update_help b/defaultenv/bin/_update_help
new file mode 100644
index 0000000..e6ea64c
--- /dev/null
+++ b/defaultenv/bin/_update_help
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+echo "usage: $0 -t <kernel|rootfs> -d <nor|nand> [-f imagename]"
+echo "update tools."
+echo""
+echo "type update -t kernel -d <nor|nand> [-f imagename] to update kernel into flash"
+echo "type update -t rootfs -d <nor|nand> [-f imagename] to update rootfs into flash"
+
diff --git a/defaultenv/bin/init b/defaultenv/bin/init
index a55e8e6..a39e5bd 100644
--- a/defaultenv/bin/init
+++ b/defaultenv/bin/init
@@ -25,8 +25,7 @@ echo -n "Hit any key to stop autoboot: "
 timeout -a $autoboot_timeout
 if [ $? != 0 ]; then
 	echo
-	echo "type update_kernel nand|nor [<imagename>] to update kernel into flash"
-	echo "type update_rootfs nand|nor [<imagename>] to update rootfs into flash"
+	update -h
 	echo
 	exit
 fi
diff --git a/defaultenv/bin/update b/defaultenv/bin/update
new file mode 100644
index 0000000..bdac11f
--- /dev/null
+++ b/defaultenv/bin/update
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+. /env/config
+
+type=""
+device_type=""
+
+while getopt "ht:d:f:" Option
+do
+if [ ${Option} = t ]; then
+	type=${OPTARG}
+elif [ ${Option} = d ]; then
+	device_type=${OPTARG}
+elif [ ${Option} = f ]; then
+	imagename=${OPTARG}
+else
+	. /env/bin/_update_help
+	exit 0
+fi
+done
+
+if [ x${type} = xkernel ]; then
+	image=$kernelimage
+elif [ x${type} = xrootfs ]; then
+	image=$rootfsimage
+	type=root
+else
+	. /env/bin/_update_help
+	exit 1
+fi
+
+if [ x${imagename} != x ]; then
+	image=${imagename}
+fi
+
+if [ x${device_type} = xnand ]; then
+	part=/dev/nand0.${type}.bb
+elif [ x${device_type} = xnor ]; then
+	part=/dev/nor0.${type}
+else
+	. /env/bin/_update_help
+	exit 1
+fi
+
+. /env/bin/_update
diff --git a/defaultenv/bin/update_kernel b/defaultenv/bin/update_kernel
deleted file mode 100644
index 1d35ed9..0000000
--- a/defaultenv/bin/update_kernel
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-. /env/config
-image=$kernelimage
-
-if [ x$1 = xnand ]; then
-	part=/dev/nand0.kernel.bb
-elif [ x$1 = xnor ]; then
-	part=/dev/nor0.kernel
-else
-	echo "usage: $0 nor|nand [imagename]"
-	exit 1
-fi
-
-. /env/bin/_update $2
diff --git a/defaultenv/bin/update_rootfs b/defaultenv/bin/update_rootfs
deleted file mode 100644
index 6366315..0000000
--- a/defaultenv/bin/update_rootfs
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-image=$rootfsimage
-
-if [ x$1 = xnand ]; then
-	part=/dev/nand0.root.bb
-elif [ x$1 = xnor ]; then
-	part=/dev/nor0.root
-else
-	echo "usage: $0 nor|nand [imagename]"
-	exit 1
-fi
-
-. /env/bin/_update $2
-- 
1.7.1



From plagnioj at jcrosoft.com  Mon Oct 11 10:34:44 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 16:34:44 +0200
Subject: [PATCH 6/6] defaultenv: add update_barebox to update barebox easly
	via tftp or xmodem
In-Reply-To: <20101011135329.GA7412@game.jcrosoft.org>
References: <20101011135329.GA7412@game.jcrosoft.org>
Message-ID: <1286807684-17355-6-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 defaultenv/bin/_update_help |    3 ++-
 defaultenv/bin/update       |    5 +++++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/defaultenv/bin/_update_help b/defaultenv/bin/_update_help
index 1d9b28e..22d940e 100644
--- a/defaultenv/bin/_update_help
+++ b/defaultenv/bin/_update_help
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-echo "usage: $0 -t <kernel|rootfs> -d <nor|nand> [-m tftp|xmodem] [-f imagename] -c"
+echo "usage: $0 -t <kernel|rootfs|barebox> -d <nor|nand> [-m tftp|xmodem] [-f imagename] -c"
 echo "update tools."
 echo ""
 echo "options"
@@ -9,3 +9,4 @@ echo ""
 echo "default mode is tftp"
 echo "type update -t kernel -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update kernel into flash"
 echo "type update -t rootfs -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update rootfs into flash"
+echo "type update -t barebox -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update barebox into flash"
diff --git a/defaultenv/bin/update b/defaultenv/bin/update
index 032f340..3601177 100644
--- a/defaultenv/bin/update
+++ b/defaultenv/bin/update
@@ -30,6 +30,11 @@ if [ x${type} = xkernel ]; then
 elif [ x${type} = xrootfs ]; then
 	image=$rootfsimage
 	type=root
+elif [ x${type} = xbarebox ]; then
+	image=$bareboximage
+	if [ x${image} = x ]; then
+		imamge=barebox.bin
+	fi
 else
 	. /env/bin/_update_help
 	exit 1
-- 
1.7.1



From plagnioj at jcrosoft.com  Mon Oct 11 10:34:43 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 16:34:43 +0200
Subject: [PATCH 5/6] defaultenv: add xmodem support for update
In-Reply-To: <20101011135329.GA7412@game.jcrosoft.org>
References: <20101011135329.GA7412@game.jcrosoft.org>
Message-ID: <1286807684-17355-5-git-send-email-plagnioj@jcrosoft.com>

the default mode is tftp to do not change the default behavior

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 defaultenv/bin/_update      |   26 +++++++++++++++++---------
 defaultenv/bin/_update_help |   21 +++++++++++----------
 defaultenv/bin/update       |   11 ++++++++++-
 3 files changed, 38 insertions(+), 20 deletions(-)
 rewrite defaultenv/bin/_update_help (65%)

diff --git a/defaultenv/bin/_update b/defaultenv/bin/_update
index 6f2ebd3..87e6922 100644
--- a/defaultenv/bin/_update
+++ b/defaultenv/bin/_update
@@ -10,14 +10,16 @@ if [ ! -e "$part" ]; then
 	exit 1
 fi
 
-if [ x$ip = xdhcp ]; then
-	dhcp
-fi
-
-ping $eth0.serverip
-if [ $? -ne 0 ] ; then
-	echo "Server did not reply! Update aborted."
-	exit 1
+if [ x$mode = xtftp ]; then
+	if [ x$ip = xdhcp ]; then
+		dhcp
+	fi
+
+	ping $eth0.serverip
+	if [ $? -ne 0 ] ; then
+		echo "Server did not reply! Update aborted."
+		exit 1
+	fi
 fi
 
 unprotect $part
@@ -30,6 +32,12 @@ erase $part
 echo
 echo "flashing $image to $part"
 echo
-tftp $image $part
+
+if [ x$mode = xtftp ]; then
+	tftp $image $part
+else
+	loadb -f $image -c
+	cp $image $part
+fi
 
 protect $part
diff --git a/defaultenv/bin/_update_help b/defaultenv/bin/_update_help
dissimilarity index 65%
index a23f00f..1d9b28e 100644
--- a/defaultenv/bin/_update_help
+++ b/defaultenv/bin/_update_help
@@ -1,10 +1,11 @@
-#!/bin/sh
-
-echo "usage: $0 -t <kernel|rootfs> -d <nor|nand> [-f imagename] -c"
-echo "update tools."
-echo ""
-echo "options"
-echo " -c     to check the crc32 for the image and flashed one"
-echo ""
-echo "type update -t kernel -d <nor|nand> [-f imagename] to update kernel into flash"
-echo "type update -t rootfs -d <nor|nand> [-f imagename] to update rootfs into flash"
+#!/bin/sh
+
+echo "usage: $0 -t <kernel|rootfs> -d <nor|nand> [-m tftp|xmodem] [-f imagename] -c"
+echo "update tools."
+echo ""
+echo "options"
+echo " -c     to check the crc32 for the image and flashed one"
+echo ""
+echo "default mode is tftp"
+echo "type update -t kernel -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update kernel into flash"
+echo "type update -t rootfs -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update rootfs into flash"
diff --git a/defaultenv/bin/update b/defaultenv/bin/update
index 504bff6..032f340 100644
--- a/defaultenv/bin/update
+++ b/defaultenv/bin/update
@@ -5,8 +5,9 @@
 type=""
 device_type=""
 check=n
+mode=tftp
 
-while getopt "ht:d:f:c" Option
+while getopt "ht:d:f:m:c" Option
 do
 if [ ${Option} = t ]; then
 	type=${OPTARG}
@@ -16,6 +17,8 @@ elif [ ${Option} = f ]; then
 	imagename=${OPTARG}
 elif [ ${Option} = c ]; then
 	check=y
+elif [ ${Option} = m ]; then
+	mode=${OPTARG}
 else
 	. /env/bin/_update_help
 	exit 0
@@ -45,6 +48,12 @@ else
 	exit 1
 fi
 
+if [ x${mode} != xtftp ] && [ x${mode} != xxmodem ] ; then
+	echo "unsupported mode ${mode}."
+	. /env/bin/_update_help
+	exit 1
+fi
+
 . /env/bin/_update
 if [ x${check} = xy ]; then
 	crc32 -f $image -F $part
-- 
1.7.1



From plagnioj at jcrosoft.com  Mon Oct 11 10:34:39 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 16:34:39 +0200
Subject: [PATCH 1/6] defaultenv: introduce CONFIG_DEFAULT_ENVIRONMENT_GENERIC
	to enable it
In-Reply-To: <20101011135329.GA7412@game.jcrosoft.org>
References: <20101011135329.GA7412@game.jcrosoft.org>
Message-ID: <1286807684-17355-1-git-send-email-plagnioj@jcrosoft.com>

this will we usefull to enable functionnality if used

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 arch/arm/configs/neso_defconfig   |    3 ++-
 arch/arm/configs/pca100_defconfig |    3 ++-
 arch/arm/configs/pcm037_defconfig |    3 ++-
 arch/arm/configs/pcm038_defconfig |    3 ++-
 arch/arm/configs/pcm043_defconfig |    3 ++-
 common/Kconfig                    |   13 +++++++++++++
 common/Makefile                   |   10 ++++++++--
 7 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/arch/arm/configs/neso_defconfig b/arch/arm/configs/neso_defconfig
index 9f6e3f4..24125f9 100644
--- a/arch/arm/configs/neso_defconfig
+++ b/arch/arm/configs/neso_defconfig
@@ -12,7 +12,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/guf-neso/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/guf-neso/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/arch/arm/configs/pca100_defconfig b/arch/arm/configs/pca100_defconfig
index d1708a6..8c72bdf 100644
--- a/arch/arm/configs/pca100_defconfig
+++ b/arch/arm/configs/pca100_defconfig
@@ -12,7 +12,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/phycard-i.MX27/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/phycard-i.MX27/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig
index 8e60b0a..e12f690 100644
--- a/arch/arm/configs/pcm037_defconfig
+++ b/arch/arm/configs/pcm037_defconfig
@@ -10,7 +10,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/pcm037/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm037/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/arch/arm/configs/pcm038_defconfig b/arch/arm/configs/pcm038_defconfig
index eacbbc6..2038f14 100644
--- a/arch/arm/configs/pcm038_defconfig
+++ b/arch/arm/configs/pcm038_defconfig
@@ -13,7 +13,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/pcm038/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm038/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/arch/arm/configs/pcm043_defconfig b/arch/arm/configs/pcm043_defconfig
index 51ca833..2dd711b 100644
--- a/arch/arm/configs/pcm043_defconfig
+++ b/arch/arm/configs/pcm043_defconfig
@@ -13,7 +13,8 @@ CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/pcm043/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm043/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
diff --git a/common/Kconfig b/common/Kconfig
index 123d070..fb47397 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -389,6 +389,19 @@ config DEFAULT_ENVIRONMENT
 	  Enabling this option will give you a default environment when
 	  the environment found in the environment sector is invalid
 
+config DEFAULT_ENVIRONMENT_GENERIC
+	bool
+	depends on DEFAULT_ENVIRONMENT
+	select SHELL_HUSH
+	prompt "Default environment generic"
+	help
+	  With this option barebox will use the generic default
+	  environment found under defaultenv/ in the src tree.
+	  The Directory given with DEFAULT_ENVIRONMENT_PATH
+	  will be added to the default environment. This should
+	  at least contain a /env/config file.
+	  This will be able to overwrite the files from defaultenv.
+
 config DEFAULT_ENVIRONMENT_PATH
 	string
 	depends on DEFAULT_ENVIRONMENT
diff --git a/common/Makefile b/common/Makefile
index e56dbc2..753455b 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -26,12 +26,18 @@ ifdef CONFIG_DEFAULT_ENVIRONMENT
 $(obj)/startup.o: include/generated/barebox_default_env.h
 $(obj)/env.o: include/generated/barebox_default_env.h
 
-ENV_FILES := $(shell cd $(srctree); for i in $(CONFIG_DEFAULT_ENVIRONMENT_PATH); do find $${i} -type f -exec readlink -f {} \;; done)
+ifeq ($(CONFIG_DEFAULT_ENVIRONMENT_GENERIC),y)
+DEFAULT_ENVIRONMENT_PATH = "defaultenv"
+endif
+
+DEFAULT_ENVIRONMENT_PATH += $(CONFIG_DEFAULT_ENVIRONMENT_PATH)
+
+ENV_FILES := $(shell cd $(srctree); for i in $(DEFAULT_ENVIRONMENT_PATH); do find $${i} -type f -exec readlink -f {} \;; done)
 
 endif # ifdef CONFIG_DEFAULT_ENVIRONMENT
 
 barebox_default_env: $(ENV_FILES)
-	$(Q)$(srctree)/scripts/genenv $(srctree) $(objtree) $(CONFIG_DEFAULT_ENVIRONMENT_PATH)
+	$(Q)$(srctree)/scripts/genenv $(srctree) $(objtree) $(DEFAULT_ENVIRONMENT_PATH)
 
 include/generated/barebox_default_env.h: barebox_default_env
 	$(Q)cat $< | $(objtree)/scripts/bin2c default_environment > $@
-- 
1.7.1



From plagnioj at jcrosoft.com  Mon Oct 11 10:34:40 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 16:34:40 +0200
Subject: [PATCH 2/6] commands/crc32: add compare 2 files crc
In-Reply-To: <20101011135329.GA7412@game.jcrosoft.org>
References: <20101011135329.GA7412@game.jcrosoft.org>
Message-ID: <1286807684-17355-2-git-send-email-plagnioj@jcrosoft.com>

add -F options to compare to file crc

it's usefull to compare what you flash in a partition

it's selectable by CONFIG_CMD_CRC_CMP

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 commands/Kconfig |    5 ++
 commands/crc.c   |  111 ++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 79 insertions(+), 37 deletions(-)

diff --git a/commands/Kconfig b/commands/Kconfig
index 0fc80aa..5416073 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -202,6 +202,11 @@ config CMD_CRC
 	select CRC32
 	prompt "crc"
 
+config CMD_CRC_CMP
+	tristate
+	depends on CMD_CRC
+	prompt "compare 2 files crc"
+
 config CMD_MTEST
 	tristate
 	prompt "mtest"
diff --git a/commands/crc.c b/commands/crc.c
index 4842cdc..d3e0865 100644
--- a/commands/crc.c
+++ b/commands/crc.c
@@ -30,20 +30,80 @@
 #include <malloc.h>
 #include <linux/ctype.h>
 
+static int file_crc(char* filename, ulong start, ulong size, ulong *crc,
+		    ulong *total)
+{
+	int fd, now;
+	int ret = 0;
+	char *buf;
+
+	*total = 0;
+	*crc = 0;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		printf("open %s: %s\n", filename, errno_str());
+		return fd;
+	}
+
+	if (start > 0) {
+		ret = lseek(fd, start, SEEK_SET);
+		if (ret == -1) {
+			perror("lseek");
+			goto out;
+		}
+	}
+
+	buf = xmalloc(4096);
+
+	while (size) {
+		now = min((ulong)4096, size);
+		now = read(fd, buf, now);
+		if (now < 0) {
+			ret = now;
+			perror("read");
+			goto out_free;
+		}
+		if (!now)
+			break;
+		*crc = crc32(*crc, buf, now);
+		size -= now;
+		*total += now;
+	}
+
+	printf ("CRC32 for %s 0x%08lx ... 0x%08lx ==> 0x%08lx",
+			filename, start, start + *total - 1, *crc);
+
+out_free:
+	free(buf);
+out:
+	close(fd);
+
+	return ret;
+}
+
 static int do_crc(struct command *cmdtp, int argc, char *argv[])
 {
 	ulong start = 0, size = ~0, total = 0;
 	ulong crc = 0, vcrc = 0;
 	char *filename = "/dev/mem";
-	char *buf;
-	int fd, opt, err = 0, filegiven = 0, verify = 0, now;
+#ifdef CONFIG_CMD_CRC_CMP
+	char *vfilename = NULL;
+#endif
+	int opt, err = 0, filegiven = 0, verify = 0;
 
-	while((opt = getopt(argc, argv, "f:v:")) > 0) {
+	while((opt = getopt(argc, argv, "f:F:v:")) > 0) {
 		switch(opt) {
 		case 'f':
 			filename = optarg;
 			filegiven = 1;
 			break;
+#ifdef CONFIG_CMD_CRC_CMP
+		case 'F':
+			verify = 1;
+			vfilename = optarg;
+			break;
+#endif
 		case 'v':
 			verify = 1;
 			vcrc = simple_strtoul(optarg, NULL, 0);
@@ -61,38 +121,17 @@ static int do_crc(struct command *cmdtp, int argc, char *argv[])
 		}
 	}
 
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		printf("open %s: %s\n", filename, errno_str());
+	if (file_crc(filename, start, size, &crc, &total) < 0)
 		return 1;
-	}
 
-	if (start > 0) {
-		if (lseek(fd, start, SEEK_SET) == -1) {
-			perror("lseek");
-			err = 1;
-			goto out;
-		}
-	}
-
-	buf = xmalloc(4096);
-
-	while (size) {
-		now = min((ulong)4096, size);
-		now = read(fd, buf, now);
-		if (now < 0) {
-			perror("read");
-			goto out_free;
-		}
-		if (!now)
-			break;
-		crc = crc32(crc, buf, now);
-		size -= now;
-		total += now;
+#ifdef CONFIG_CMD_CRC_CMP
+	if (vfilename) {
+		size = total;
+		puts("\n");
+		if (file_crc(vfilename, start, size, &vcrc, &total) < 0)
+			return 1;
 	}
-
-	printf ("CRC32 for %s 0x%08lx ... 0x%08lx ==> 0x%08lx",
-			filename, start, start + total - 1, crc);
+#endif
 
 	if (verify && crc != vcrc) {
 		printf(" != 0x%08x ** ERROR **", vcrc);
@@ -101,11 +140,6 @@ static int do_crc(struct command *cmdtp, int argc, char *argv[])
 
 	printf("\n");
 
-out_free:
-	free(buf);
-out:
-	close(fd);
-
 	return err;
 }
 
@@ -114,6 +148,9 @@ static const __maybe_unused char cmd_crc_help[] =
 "Calculate a crc32 checksum of a memory area\n"
 "Options:\n"
 "  -f <file>   Use file instead of memory\n"
+#ifdef CONFIG_CMD_CRC_CMP
+"  -F <file>   Use file to compare\n"
+#endif
 "  -v <crc>    Verfify\n";
 
 BAREBOX_CMD_START(crc32)
-- 
1.7.1



From plagnioj at jcrosoft.com  Mon Oct 11 10:41:29 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 16:41:29 +0200
Subject: [PATCH] Add basic support from ARM Versatile/PB
In-Reply-To: <20101010230505.17833.46593.stgit@zaytsev.su>
References: <20101010230505.17833.46593.stgit@zaytsev.su>
Message-ID: <20101011144129.GB7412@game.jcrosoft.org>

On 23:15 Sun 10 Oct     , Alexey Zaytsev wrote:
> Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
> ---
> 
> Hi.
> 
> It seems that barebox does not run on any ARM machines provided
> by QEMU. This patch adds basic Versatile/PB support. It is far from
> being complete and has not been tested on real hardware, but
> seems to work fine in QEMU.
> 
> Please notice, that you need to set CONFIG_VERSATILE_SMC91C111
> in order to have networking in QEMU, as it does not provide
> smc91x found on the real hardware.
> 
> For a queck test, run:
> 
> 	qemu-system-arm -kernel barebox.bin -M versatilepb -cpu arm926 -nographic -m 64 -net nic,model=smc91c111 -net user
this must be in a doc

please use defaultenv and enable more functionnability

as we can use it as ref board for emulation
> 
> 
>  arch/arm/Kconfig                                |    4 
>  arch/arm/Makefile                               |    2 
>  arch/arm/boards/versatile/Kconfig               |   21 +
>  arch/arm/boards/versatile/Makefile              |    2 
>  arch/arm/boards/versatile/config.h              |    5 
>  arch/arm/boards/versatile/env/bin/init          |    1 
>  arch/arm/boards/versatile/versatilepb.c         |   56 +++
>  arch/arm/configs/versatilepb_defconfig          |   12 +
>  arch/arm/include/asm/arm_timer.h                |   33 ++
>  arch/arm/mach-versatile/Kconfig                 |   16 +
>  arch/arm/mach-versatile/Makefile                |    2 
>  arch/arm/mach-versatile/core.c                  |  217 ++++++++++++
>  arch/arm/mach-versatile/include/mach/clkdev.h   |    7 
>  arch/arm/mach-versatile/include/mach/debug_ll.h |   37 ++
>  arch/arm/mach-versatile/include/mach/init.h     |    9 
>  arch/arm/mach-versatile/include/mach/platform.h |  417 +++++++++++++++++++++++
>  16 files changed, 841 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/boards/versatile/Kconfig
>  create mode 100644 arch/arm/boards/versatile/Makefile
>  create mode 100644 arch/arm/boards/versatile/config.h
>  create mode 100644 arch/arm/boards/versatile/env/bin/init
>  create mode 100644 arch/arm/boards/versatile/versatilepb.c
>  create mode 100644 arch/arm/configs/versatilepb_defconfig
>  create mode 100644 arch/arm/include/asm/arm_timer.h
>  create mode 100644 arch/arm/mach-versatile/Kconfig
>  create mode 100644 arch/arm/mach-versatile/Makefile
>  create mode 100644 arch/arm/mach-versatile/core.c
>  create mode 100644 arch/arm/mach-versatile/include/mach/clkdev.h
>  create mode 100644 arch/arm/mach-versatile/include/mach/debug_ll.h
>  create mode 100644 arch/arm/mach-versatile/include/mach/init.h
>  create mode 100644 arch/arm/mach-versatile/include/mach/platform.h
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index fa37036..d90246a 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -56,6 +56,9 @@ config ARCH_S3C24xx
>  	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
>  	select CPU_ARM920T
>  
> +config ARCH_VERSATILE
> +	bool "ARM Versatile boards (ARM926EJ-S)"
> +	select CPU_ARM926T
>  endchoice
>  
>  source arch/arm/cpu/Kconfig
> @@ -66,6 +69,7 @@ source arch/arm/mach-netx/Kconfig
>  source arch/arm/mach-nomadik/Kconfig
>  source arch/arm/mach-omap/Kconfig
>  source arch/arm/mach-s3c24xx/Kconfig
> +source arch/arm/mach-versatile/Kconfig
>  
>  config AEABI
>  	bool "Use the ARM EABI to compile barebox"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 77b6cf4..6ad14e7 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -45,6 +45,7 @@ machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
>  machine-$(CONFIG_ARCH_NETX)		:= netx
>  machine-$(CONFIG_ARCH_OMAP)		:= omap
>  machine-$(CONFIG_ARCH_S3C24xx)		:= s3c24xx
> +machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
>  
>  # Board directory name.  This list is sorted alphanumerically
>  # by CONFIG_* macro name.
> @@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
>  board-$(CONFIG_MACH_PM9263)			:= pm9263
>  board-$(CONFIG_MACH_SCB9328)			:= scb9328
>  board-$(CONFIG_MACH_NESO)			:= guf-neso
> +board-$(CONFIG_MACH_VERSATILEPB)		:= versatile
>  
>  machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
>  
> diff --git a/arch/arm/boards/versatile/Kconfig b/arch/arm/boards/versatile/Kconfig
> new file mode 100644
> index 0000000..d5da87d
> --- /dev/null
> +++ b/arch/arm/boards/versatile/Kconfig
> @@ -0,0 +1,21 @@
> +
> +
> +if MACH_VERSATILEPB
> +
> +config ARCH_TEXT_BASE
> +	hex
> +	default 0
> +
> +config BOARDINFO
> +	default "ARM Versatile/PB (ARM926EJ-S)"
> +endif
> +
> +config VERSATILE_SMC91C111
> +	bool "Use smc91c111 instead of smc91x (for QEMU)"
> +	default 0
??
> +	help
> +	 Enable this option to run barebox inside qemu.
> +	 Real versatile boards are equipped with smc911x,
> +	 but qemu only provides smc91111, which is a bit different.
it will be beter to modify the ressources depending on the drivers enabled

and nake it exclusive
> +
> +
> diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
> new file mode 100644
> index 0000000..a17aed3
> --- /dev/null
> +++ b/arch/arm/boards/versatile/Makefile
> @@ -0,0 +1,2 @@
> +
> +obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
> diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
> new file mode 100644
> index 0000000..25bb18f
> --- /dev/null
> +++ b/arch/arm/boards/versatile/config.h
> @@ -0,0 +1,5 @@
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#endif	/* __CONFIG_H */
> diff --git a/arch/arm/boards/versatile/env/bin/init b/arch/arm/boards/versatile/env/bin/init
> new file mode 100644
> index 0000000..224a6b4
> --- /dev/null
 +	sdram_dev.size = size;
> +	register_device(&sdram_dev);
> +	armlinux_add_dram(&sdram_dev);
> +}
> +
> +/* 4 uarts, yay! */
> +static struct device_d uart0_serial_device = {
> +	.id = 1,
why not start at 0?

btw there is a lots of whitespace could you fix them

Best Regards,
J.



From s.hauer at pengutronix.de  Mon Oct 11 10:48:36 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 16:48:36 +0200
Subject: [PATCH] Add basic support from ARM Versatile/PB
In-Reply-To: <20101011144129.GB7412@game.jcrosoft.org>
References: <20101010230505.17833.46593.stgit@zaytsev.su>
	<20101011144129.GB7412@game.jcrosoft.org>
Message-ID: <20101011144836.GB28242@pengutronix.de>

On Mon, Oct 11, 2010 at 04:41:29PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 23:15 Sun 10 Oct     , Alexey Zaytsev wrote:
> > Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
> > ---
> > 
> > Hi.
> > 
> > It seems that barebox does not run on any ARM machines provided
> > by QEMU. This patch adds basic Versatile/PB support. It is far from
> > being complete and has not been tested on real hardware, but
> > seems to work fine in QEMU.
> > 
> > Please notice, that you need to set CONFIG_VERSATILE_SMC91C111
> > in order to have networking in QEMU, as it does not provide
> > smc91x found on the real hardware.
> > 
> > For a queck test, run:
> > 
> > 	qemu-system-arm -kernel barebox.bin -M versatilepb -cpu arm926 -nographic -m 64 -net nic,model=smc91c111 -net user
> this must be in a doc
> 
> please use defaultenv and enable more functionnability
> 
> as we can use it as ref board for emulation
> > 
> > 
> > +
> > +config BOARDINFO
> > +	default "ARM Versatile/PB (ARM926EJ-S)"
> > +endif
> > +
> > +config VERSATILE_SMC91C111
> > +	bool "Use smc91c111 instead of smc91x (for QEMU)"
> > +	default 0
> ??
> > +	help
> > +	 Enable this option to run barebox inside qemu.
> > +	 Real versatile boards are equipped with smc911x,
> > +	 but qemu only provides smc91111, which is a bit different.
> it will be beter to modify the ressources depending on the drivers enabled

I think it's ok the way Alexey did this. It's a good place to document
that we need two different ethernet drivers depending on native/qemu
compilation.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From alexey.zaytsev at gmail.com  Mon Oct 11 10:49:53 2010
From: alexey.zaytsev at gmail.com (Alexey Zaytsev)
Date: Mon, 11 Oct 2010 18:49:53 +0400
Subject: [PATCH] Add basic support from ARM Versatile/PB
In-Reply-To: <20101011144129.GB7412@game.jcrosoft.org>
References: <20101010230505.17833.46593.stgit@zaytsev.su>
	<20101011144129.GB7412@game.jcrosoft.org>
Message-ID: <AANLkTimyPkqmd4sPp=WQS2t3jOHBqaHua0=XumVVkoe4@mail.gmail.com>

On Mon, Oct 11, 2010 at 18:41, Jean-Christophe PLAGNIOL-VILLARD
<plagnioj at jcrosoft.com> wrote:
> On 23:15 Sun 10 Oct ? ? , Alexey Zaytsev wrote:
>> Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
>> ---
>>
>> Hi.
>>
>> It seems that barebox does not run on any ARM machines provided
>> by QEMU. This patch adds basic Versatile/PB support. It is far from
>> being complete and has not been tested on real hardware, but
>> seems to work fine in QEMU.
>>
>> Please notice, that you need to set CONFIG_VERSATILE_SMC91C111
>> in order to have networking in QEMU, as it does not provide
>> smc91x found on the real hardware.
>>
>> For a queck test, run:
>>
>> ? ? ? qemu-system-arm -kernel barebox.bin -M versatilepb -cpu arm926 -nographic -m 64 -net nic,model=smc91c111 -net user
> this must be in a doc
>
> please use defaultenv and enable more functionnability
>
> as we can use it as ref board for emulation
>>
>>
>> ?arch/arm/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?4
>> ?arch/arm/Makefile ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?2
>> ?arch/arm/boards/versatile/Kconfig ? ? ? ? ? ? ? | ? 21 +
>> ?arch/arm/boards/versatile/Makefile ? ? ? ? ? ? ?| ? ?2
>> ?arch/arm/boards/versatile/config.h ? ? ? ? ? ? ?| ? ?5
>> ?arch/arm/boards/versatile/env/bin/init ? ? ? ? ?| ? ?1
>> ?arch/arm/boards/versatile/versatilepb.c ? ? ? ? | ? 56 +++
>> ?arch/arm/configs/versatilepb_defconfig ? ? ? ? ?| ? 12 +
>> ?arch/arm/include/asm/arm_timer.h ? ? ? ? ? ? ? ?| ? 33 ++
>> ?arch/arm/mach-versatile/Kconfig ? ? ? ? ? ? ? ? | ? 16 +
>> ?arch/arm/mach-versatile/Makefile ? ? ? ? ? ? ? ?| ? ?2
>> ?arch/arm/mach-versatile/core.c ? ? ? ? ? ? ? ? ?| ?217 ++++++++++++
>> ?arch/arm/mach-versatile/include/mach/clkdev.h ? | ? ?7
>> ?arch/arm/mach-versatile/include/mach/debug_ll.h | ? 37 ++
>> ?arch/arm/mach-versatile/include/mach/init.h ? ? | ? ?9
>> ?arch/arm/mach-versatile/include/mach/platform.h | ?417 +++++++++++++++++++++++
>> ?16 files changed, 841 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/boards/versatile/Kconfig
>> ?create mode 100644 arch/arm/boards/versatile/Makefile
>> ?create mode 100644 arch/arm/boards/versatile/config.h
>> ?create mode 100644 arch/arm/boards/versatile/env/bin/init
>> ?create mode 100644 arch/arm/boards/versatile/versatilepb.c
>> ?create mode 100644 arch/arm/configs/versatilepb_defconfig
>> ?create mode 100644 arch/arm/include/asm/arm_timer.h
>> ?create mode 100644 arch/arm/mach-versatile/Kconfig
>> ?create mode 100644 arch/arm/mach-versatile/Makefile
>> ?create mode 100644 arch/arm/mach-versatile/core.c
>> ?create mode 100644 arch/arm/mach-versatile/include/mach/clkdev.h
>> ?create mode 100644 arch/arm/mach-versatile/include/mach/debug_ll.h
>> ?create mode 100644 arch/arm/mach-versatile/include/mach/init.h
>> ?create mode 100644 arch/arm/mach-versatile/include/mach/platform.h
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index fa37036..d90246a 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -56,6 +56,9 @@ config ARCH_S3C24xx
>> ? ? ? bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
>> ? ? ? select CPU_ARM920T
>>
>> +config ARCH_VERSATILE
>> + ? ? bool "ARM Versatile boards (ARM926EJ-S)"
>> + ? ? select CPU_ARM926T
>> ?endchoice
>>
>> ?source arch/arm/cpu/Kconfig
>> @@ -66,6 +69,7 @@ source arch/arm/mach-netx/Kconfig
>> ?source arch/arm/mach-nomadik/Kconfig
>> ?source arch/arm/mach-omap/Kconfig
>> ?source arch/arm/mach-s3c24xx/Kconfig
>> +source arch/arm/mach-versatile/Kconfig
>>
>> ?config AEABI
>> ? ? ? bool "Use the ARM EABI to compile barebox"
>> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
>> index 77b6cf4..6ad14e7 100644
>> --- a/arch/arm/Makefile
>> +++ b/arch/arm/Makefile
>> @@ -45,6 +45,7 @@ machine-$(CONFIG_ARCH_NOMADIK) ? ? ? ? ? ? ?:= nomadik
>> ?machine-$(CONFIG_ARCH_NETX) ? ? ? ? ?:= netx
>> ?machine-$(CONFIG_ARCH_OMAP) ? ? ? ? ?:= omap
>> ?machine-$(CONFIG_ARCH_S3C24xx) ? ? ? ? ? ? ? := s3c24xx
>> +machine-$(CONFIG_ARCH_VERSATILE) ? ? := versatile
>>
>> ?# Board directory name. ?This list is sorted alphanumerically
>> ?# by CONFIG_* macro name.
>> @@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043) ? ? ? ? ? ? ? ? := pcm043
>> ?board-$(CONFIG_MACH_PM9263) ? ? ? ? ? ? ? ? ?:= pm9263
>> ?board-$(CONFIG_MACH_SCB9328) ? ? ? ? ? ? ? ? := scb9328
>> ?board-$(CONFIG_MACH_NESO) ? ? ? ? ? ? ? ? ? ?:= guf-neso
>> +board-$(CONFIG_MACH_VERSATILEPB) ? ? ? ? ? ? := versatile
>>
>> ?machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
>>
>> diff --git a/arch/arm/boards/versatile/Kconfig b/arch/arm/boards/versatile/Kconfig
>> new file mode 100644
>> index 0000000..d5da87d
>> --- /dev/null
>> +++ b/arch/arm/boards/versatile/Kconfig
>> @@ -0,0 +1,21 @@
>> +
>> +
>> +if MACH_VERSATILEPB
>> +
>> +config ARCH_TEXT_BASE
>> + ? ? hex
>> + ? ? default 0
>> +
>> +config BOARDINFO
>> + ? ? default "ARM Versatile/PB (ARM926EJ-S)"
>> +endif
>> +
>> +config VERSATILE_SMC91C111
>> + ? ? bool "Use smc91c111 instead of smc91x (for QEMU)"
>> + ? ? default 0
> ??

Will remove.

>> + ? ? help
>> + ? ? ?Enable this option to run barebox inside qemu.
>> + ? ? ?Real versatile boards are equipped with smc911x,
>> + ? ? ?but qemu only provides smc91111, which is a bit different.
> it will be beter to modify the ressources depending on the drivers enabled
>
> and nake it exclusive

Can't agree here, in my understanding, the board definition should not
depend on the drivers enabled. It might be a good idea to enable the
right driver depending on this option, but I'm not sure if this is
doable without forcing the ethernet driver always on.

>> +
>> +
>> diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
>> new file mode 100644
>> index 0000000..a17aed3
>> --- /dev/null
>> +++ b/arch/arm/boards/versatile/Makefile
>> @@ -0,0 +1,2 @@
>> +
>> +obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
>> diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
>> new file mode 100644
>> index 0000000..25bb18f
>> --- /dev/null
>> +++ b/arch/arm/boards/versatile/config.h
>> @@ -0,0 +1,5 @@
>> +
>> +#ifndef __CONFIG_H
>> +#define __CONFIG_H
>> +
>> +#endif ? ? ? /* __CONFIG_H */
>> diff --git a/arch/arm/boards/versatile/env/bin/init b/arch/arm/boards/versatile/env/bin/init
>> new file mode 100644
>> index 0000000..224a6b4
>> --- /dev/null
> ?+ ? ? ?sdram_dev.size = size;
>> + ? ? register_device(&sdram_dev);
>> + ? ? armlinux_add_dram(&sdram_dev);
>> +}
>> +
>> +/* 4 uarts, yay! */
>> +static struct device_d uart0_serial_device = {
>> + ? ? .id = 1,
> why not start at 0?

Will fix.
>
> btw there is a lots of whitespace could you fix them
>

Will fix.


From jbe at pengutronix.de  Mon Oct 11 10:52:22 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 16:52:22 +0200
Subject: Bring together i.MX23, its MCI driver and the ChumbyOne
Message-ID: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>

Now the i.MX23 architecture and the MCI support is in place, bring both
together and make the ChumbyOne use of it.

Regards,
jbe



From jbe at pengutronix.de  Mon Oct 11 10:52:23 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 16:52:23 +0200
Subject: [PATCH 1/4] Glue i.MX23 and MCI support
In-Reply-To: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286808746-19456-2-git-send-email-jbe@pengutronix.de>

The MCI framework and the i.MX23 architecture are present now. Bring both
together.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/include/mach/mci.h |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-stm/include/mach/mci.h

diff --git a/arch/arm/mach-stm/include/mach/mci.h b/arch/arm/mach-stm/include/mach/mci.h
new file mode 100644
index 0000000..b924908
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/mci.h
@@ -0,0 +1,32 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MACH_MMC_H
+#define __MACH_MMC_H
+
+struct stm_mci_platform_data {
+	unsigned caps;	/**< supported operating modes (MMC_MODE_*) */
+	unsigned voltages; /**< supported voltage range (MMC_VDD_*) */
+	unsigned f_min;	/**< min operating frequency in Hz (0 -> no limit) */
+	unsigned f_max;	/**< max operating frequency in Hz (0 -> no limit) */
+	/* TODO */
+	/* function to modify the voltage */
+	/* function to switch the voltage */
+	/* function to detect the presence of a SD card in the socket */
+};
+
+#endif /* __MACH_MMC_H */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Oct 11 10:52:24 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 16:52:24 +0200
Subject: [PATCH 2/4] Adapt the i.MX23 MCI driver to the v2 i.MX23 patch series
In-Reply-To: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286808746-19456-3-git-send-email-jbe@pengutronix.de>

The i.MX23 v2 architecture patch series was sligthly modified to easify
the i.MX28 architecture addition later on. So, we need now an index to
query the SSP clock frequency.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/stm378x.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index fbb9994..8865ee8 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -481,7 +481,7 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
 		return 0;
 	}
 
-	ssp = imx_get_sspclk() * 1000;
+	ssp = imx_get_sspclk(0) * 1000;
 
 	for (div1 = 2; div1 < 255; div1 += 2) {
 		div2 = ssp / nc / div1;
@@ -658,20 +658,20 @@ static int stm_mci_probe(struct device_d *hw_dev)
 	host->host_caps = pd->caps;
 
 	if (pd->f_min == 0) {
-		host->f_min = imx_get_sspclk() / 254U / 256U * 1000U;
+		host->f_min = imx_get_sspclk(0) / 254U / 256U * 1000U;
 		pr_debug("Min. frequency is %u Hz\n", host->f_min);
 	} else {
 		host->f_min = pd->f_min;
 		pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
-			host->f_min, imx_get_sspclk() / 254U / 256U * 1000U);
+			host->f_min, imx_get_sspclk(0) / 254U / 256U * 1000U);
 	}
 	if (pd->f_max == 0) {
-		host->f_max = imx_get_sspclk() / 2U / 1U * 1000U;
+		host->f_max = imx_get_sspclk(0) / 2U / 1U * 1000U;
 		pr_debug("Max. frequency is %u Hz\n", host->f_max);
 	} else {
 		host->f_max =  pd->f_max;
 		pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
-			host->f_max, imx_get_sspclk() / 2U / 1U * 1000U);
+			host->f_max, imx_get_sspclk(0) / 2U / 1U * 1000U);
 	}
 
 #ifdef CONFIG_MCI_INFO
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Oct 11 10:52:25 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 16:52:25 +0200
Subject: [PATCH 3/4] Spend the ChumbyOne a persistant environment memory on
	MCI card
In-Reply-To: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286808746-19456-4-git-send-email-jbe@pengutronix.de>

The ChumbyOne boot from MCI card only. As ist more fun to run barebox with
a persistant environment, provide one in the second partition on the MCI card.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/chumby_falconwing/env/bin/boot |   38 +++++++++++
 arch/arm/boards/chumby_falconwing/env/bin/init |   15 +++++
 arch/arm/boards/chumby_falconwing/env/config   |   36 +++++++++++
 arch/arm/boards/chumby_falconwing/falconwing.c |   81 +++++++++++++++++++++++-
 4 files changed, 169 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/boards/chumby_falconwing/env/bin/boot
 create mode 100644 arch/arm/boards/chumby_falconwing/env/bin/init
 create mode 100644 arch/arm/boards/chumby_falconwing/env/config

diff --git a/arch/arm/boards/chumby_falconwing/env/bin/boot b/arch/arm/boards/chumby_falconwing/env/bin/boot
new file mode 100644
index 0000000..981a387
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/env/bin/boot
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+. /env/config
+
+if [ x$1 = xdisk ]; then
+	rootfs_loc=disk
+	kernel_loc=disk
+elif [ x$1 = xnet ]; then
+	rootfs_loc=net
+	kernel_loc=net
+fi
+
+if [ x$ip = xdhcp ]; then
+	bootargs="$bootargs ip=dhcp"
+elif [ x$ip = xnone ]; then
+	bootargs="$bootargs ip=none"
+else
+	bootargs="$bootargs ip=$eth0.ipaddr::$eth0.gateway:$eth0.netmask:::"
+fi
+
+if [ x$rootfs_loc = xdisk ]; then
+	bootargs="$bootargs noinitrd rootfstype=$rootfs_type root=/dev/$rootfs_part"
+elif [ x$rootfs_loc = xnet ]; then
+	bootargs="$bootargs root=/dev/nfs nfsroot=$nfsroot,v3,tcp noinitrd"
+elif [ x$rootfs_loc = xinitrd ]; then
+	bootargs="$bootargs root=/dev/ram0 rdinit=/sbin/init"
+fi
+
+if [ x$kernelimage_type = xuimage ]; then
+	bootm /dev/$kernel_part
+elif [ x$kernelimage_type = xzimage ]; then
+	bootz /dev/$kernel_part
+else
+	echo "Booting failed. Correct setup of 'kernelimage_type'?"
+	exit
+fi
+
+echo "Booting failed. Correct setup of 'kernel_part'?"
diff --git a/arch/arm/boards/chumby_falconwing/env/bin/init b/arch/arm/boards/chumby_falconwing/env/bin/init
new file mode 100644
index 0000000..3ed68f7
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/env/bin/init
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+PATH=/env/bin
+export PATH
+
+. /env/config
+
+echo
+echo -n "Hit any key to stop autoboot: "
+timeout -a $autoboot_timeout
+if [ $? != 0 ]; then
+	exit
+fi
+
+boot
diff --git a/arch/arm/boards/chumby_falconwing/env/config b/arch/arm/boards/chumby_falconwing/env/config
new file mode 100644
index 0000000..1e61dce
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/env/config
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+machine=falconwing
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=none
+
+# or set your networking parameters here (if a USB network adapter is attached)
+#eth0.ipaddr=a.b.c.d
+#eth0.netmask=a.b.c.d
+#eth0.gateway=a.b.c.d
+#eth0.serverip=a.b.c.d
+
+# can be either 'net' or 'disk'
+kernel_loc=disk
+# can be either 'net', or 'disk' or 'initrd'
+rootfs_loc=disk
+
+# can be any regular filesystem like ext2, ext3, reiserfs in case of 'rootfs_loc=disk'
+rootfs_type=ext2
+# Where is the rootfs in case of 'rootfs_loc=disk'
+rootfs_part=mmcblk0p4
+
+# Where is the rootfs in case of 'rootfs_loc=net'
+nfsroot=FIXME
+
+# The image type of the kernel. Can be uimage, zimage
+kernelimage_type=uimage
+# Where to get the kernel image in case of 'kernel_loc=disk'
+kernel_part=disk0.2
+
+# base kernel parameter
+bootargs="console=ttyAM0,115200 debug ro lcd_panel=lms350 ssp1=mmc line=1 sysrq_always_enabled rotary=1"
+
+autoboot_timeout=2
diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index d209dd5..952a384 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -20,10 +20,14 @@
 #include <init.h>
 #include <gpio.h>
 #include <environment.h>
+#include <errno.h>
+#include <mci.h>
 #include <asm/armlinux.h>
 #include <asm/io.h>
 #include <generated/mach-types.h>
 #include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <mach/mci.h>
 
 static struct memory_platform_data ram_pdata = {
 	.name = "ram0",
@@ -37,6 +41,17 @@ static struct device_d sdram_dev = {
 	.platform_data = &ram_pdata,
 };
 
+static struct stm_mci_platform_data mci_pdata = {
+	.caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz,
+	.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,	/* fixed to 3.3 V */
+};
+
+static struct device_d mci_dev = {
+	.name     = "stm_mci",
+	.map_base = IMX_SSP1_BASE,
+	.platform_data = &mci_pdata,
+};
+
 static const uint32_t pad_setup[] = {
 	/* may be not required as already done by the bootlet code */
 #if 0
@@ -205,20 +220,64 @@ static const uint32_t pad_setup[] = {
 	GPMI_RDY3_GPIO | GPIO_IN | PULLUP(1),
 };
 
+/**
+ * Try to register an environment storage on the attached MCI card
+ * @return 0 on success
+ *
+ * We relay on the existance of a useable SD card, already attached to
+ * our system, to get someting like a persistant memory for our environment.
+ * If this SD card is also the boot media, we can use the second partition
+ * for our environment purpose (if present!).
+ */
+static int register_persistant_environment(void)
+{
+	struct cdev *cdev;
+
+	/*
+	 * The chumby one only has one MCI card socket.
+	 * So, we expect its name as "disk0".
+	 */
+	cdev = cdev_by_name("disk0");
+	if (cdev == NULL) {
+		pr_err("No MCI card preset\n");
+		return -ENODEV;
+	}
+
+	/* MCI card is present, also a useable partition on it? */
+	cdev = cdev_by_name("disk0.1");
+	if (cdev == NULL) {
+		pr_err("No second partition available\n");
+		pr_info("Please create at least a second partition with"
+			" 256 kiB...512 kiB in size (your choice)\n");
+		return -ENODEV;
+	}
+
+	/* use the full partition as our persistant environment storage */
+	return devfs_add_partition("disk0.1", 0, cdev->size, DEVFS_PARTITION_FIXED, "env0");
+}
+
 static int falconwing_devices_init(void)
 {
-	int i;
+	int i, rc;
 
 	/* initizalize gpios */
 	for (i = 0; i < ARRAY_SIZE(pad_setup); i++)
 		imx_gpio_mode(pad_setup[i]);
 
 	register_device(&sdram_dev);
+	imx_set_ioclk(480U * 1000U);	/* enable IOCLK to run at the PLL frequency */
+	/* run the SSP unit clock at 100,000 kHz */
+	imx_set_sspclk(0, 100U * 1000U, 1);
+	register_device(&mci_dev);
 
 	armlinux_add_dram(&sdram_dev);
 	armlinux_set_bootparams((void*)(sdram_dev.map_base + 0x100));
 	armlinux_set_architecture(MACH_TYPE_CHUMBY);
 
+	rc = register_persistant_environment();
+	if (rc != 0)
+		printf("Cannot create the 'env0' persistant environment storage (%d)\n", rc);
+
 	return 0;
 }
 
@@ -268,4 +327,24 @@ make ARCH=arm CROSS_COMPILE=armv5compiler
 @endverbatim
 
 @note replace the armv5compiler with your ARM v5 cross compiler.
+
+ at section setup_falconwing How to prepare an MCI card to boot the "chumby one" with barebox
+
+- Create four primary partitions on the MCI card
+ - the first one for the bootlets (about 256 kiB)
+ - the second one for the persistant environment (size is up to you, at least 256k)
+ - the third one for the kernel (2 MiB ... 4 MiB in size)
+ - the 4th one for the root filesystem which can fill the rest of the available space
+
+- Mark the first partition with the partition ID "53" and copy the bootlets
+  into this partition (currently not part of @b barebox!).
+
+- Copy the default @b barebox environment into the second partition (no filesystem required).
+
+- Copy the kernel into the third partition (no filesystem required).
+
+- Create the root filesystem in the 4th partition. You may copy an image into this
+  partition or you can do it in the classic way: mkfs on it, mount it and copy
+  all required data and programs into it.
+
 */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Oct 11 10:52:26 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 16:52:26 +0200
Subject: [PATCH 4/4] Adapt the defconfig for a full blown ChumbyOne support
In-Reply-To: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1286808746-19456-5-git-send-email-jbe@pengutronix.de>

Make the ChumbyOne use of the MCI framework.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/configs/chumbyone_defconfig |  224 +++++++++++++++++++++++++++++++++-
 1 files changed, 223 insertions(+), 1 deletions(-)

diff --git a/arch/arm/configs/chumbyone_defconfig b/arch/arm/configs/chumbyone_defconfig
index c21c7cd..277dbda 100644
--- a/arch/arm/configs/chumbyone_defconfig
+++ b/arch/arm/configs/chumbyone_defconfig
@@ -1,14 +1,122 @@
+#
+# Automatically generated make config: don't edit
+# Linux barebox version: 2010.10.0
+# Mon Oct 11 16:26:31 2010
+#
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_ARM=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_IMX is not set
 CONFIG_ARCH_STM=y
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_S3C24xx is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+
+#
+# processor features
+#
+CONFIG_ARCH_TEXT_BASE=0x42000000
+CONFIG_BOARDINFO="Chumby Falconwing"
+
+#
+# SigmaTel/Freescale i.MX System-on-Chip
+#
+CONFIG_ARCH_IMX23=y
+# CONFIG_MACH_MX23EVK is not set
 CONFIG_MACH_CHUMBY=y
+
+#
+# Board specific settings       
+#
 CONFIG_AEABI=y
+
+#
+# Arm specific settings         
+#
+CONFIG_CMD_ARM_CPUINFO=y
 CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
+CONFIG_GREGORIAN_CALENDER=y
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+CONFIG_GENERIC_GPIO=y
+
+#
+# General Settings              
+#
+CONFIG_LOCALVERSION_AUTO=y
+
+#
+# memory layout                 
+#
+CONFIG_HAVE_MMU=y
+# CONFIG_MMU is not set
+CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
+CONFIG_TEXT_BASE=0x42000000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+# CONFIG_MEMORY_LAYOUT_FIXED is not set
+CONFIG_STACK_SIZE=0x8000
+CONFIG_MALLOC_SIZE=0x400000
 CONFIG_BROKEN=y
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_PROMPT="chumby:"
+CONFIG_BAUDRATE=115200
 CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+# CONFIG_GLOB is not set
+CONFIG_PROMPT_HUSH_PS2="> "
+# CONFIG_HUSH_FANCY_PROMPT is not set
+# CONFIG_HUSH_GETOPT is not set
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
+# CONFIG_MENU is not set
+# CONFIG_PASSWORD is not set
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+CONFIG_TIMESTAMP=y
+CONFIG_CONSOLE_FULL=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+# CONFIG_OF_FLAT_TREE is not set
 CONFIG_PARTITION=y
-# CONFIG_DEFAULT_ENVIRONMENT is not set
+CONFIG_DEFAULT_ENVIRONMENT=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/chumby_falconwing/env"
+
+#
+# Debugging                     
+#
 CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+# CONFIG_ENABLE_DEVICE_NOISE is not set
+
+#
+# Commands                      
+#
+
+#
+# scripting                     
+#
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
@@ -16,10 +124,124 @@ CONFIG_CMD_LOADENV=y
 CONFIG_CMD_EXPORT=y
 CONFIG_CMD_PRINTENV=y
 CONFIG_CMD_READLINE=y
+CONFIG_CMD_TRUE=y
+CONFIG_CMD_FALSE=y
+# CONFIG_CMD_LOGIN is not set
+# CONFIG_CMD_PASSWD is not set
+
+#
+# file commands                 
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+
+#
+# console                       
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
 CONFIG_CMD_ECHO_E=y
+
+#
+# memory                        
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_MEMINFO is not set
+# CONFIG_CMD_CRC is not set
 CONFIG_CMD_MTEST=y
 CONFIG_CMD_MTEST_ALTERNATIVE=y
+
+#
+# flash                         
+#
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_UBI is not set
+
+#
+# booting                       
+#
+CONFIG_CMD_BOOTM=y
+# CONFIG_CMD_BOOTM_ZLIB is not set
+# CONFIG_CMD_BOOTM_BZLIB is not set
+# CONFIG_CMD_BOOTM_SHOW_TYPE is not set
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTU=y
 CONFIG_CMD_RESET=y
+# CONFIG_CMD_GO is not set
 CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_CMD_VERSION=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_DEVINFO=y
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_UNLZO is not set
+# CONFIG_NET is not set
+
+#
+# Drivers                       
+#
+
+#
+# serial drivers                
+#
+# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
+CONFIG_DRIVER_SERIAL_STM378X=y
+# CONFIG_DRIVER_SERIAL_NS16550 is not set
+
+#
+# SPI drivers                   
+#
 # CONFIG_SPI is not set
+# CONFIG_I2C is not set
+
+#
+# flash drivers                 
+#
+# CONFIG_DRIVER_CFI is not set
+# CONFIG_MTD is not set
+CONFIG_ATA=y
+
+#
+# drive types
+#
+CONFIG_ATA_DISK=y
+
+#
+# interface types
+#
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_VIDEO is not set
+CONFIG_MCI=y
+
+#
+# --- Feature list ---
+#
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_INFO=y
+
+#
+# --- MCI host drivers ---
+#
+CONFIG_MCI_STM378X=y
+
+#
+# Filesystem support            
+#
+# CONFIG_FS_CRAMFS is not set
+CONFIG_FS_RAMFS=y
+CONFIG_FS_DEVFS=y
+CONFIG_CRC32=y
+# CONFIG_DIGEST is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_PROCESS_ESCAPE_SEQUENCE=y
-- 
1.7.2.3



From alexey.zaytsev at gmail.com  Mon Oct 11 11:15:49 2010
From: alexey.zaytsev at gmail.com (Alexey Zaytsev)
Date: Mon, 11 Oct 2010 15:15:49 +0000
Subject: [PATCH v2] Add basic support from ARM Versatile/PB
Message-ID: <20101011150644.32683.47820.stgit@zaytsev.su>

To test in qemu:

qemu-system-arm -kernel barebox.bin -M versatilepb -cpu arm926 -nographic -m 64 -net nic,model=smc91c111 -net user

And don't forget to set CONFIG_VERSATILE_SMC91C111.

Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
---

Fixed a few minor problems.

Where should I add the instructions on running qemu? 
Anyway, it seems to be quite straght-forward, and I've documented it
in the commit message. I'll send an additional patch, if there is a
better place.

I have not added a default env yet. I'm new to barebox, and ran it for the first time only after porting it. Not sure I fully understand how works yet. ;)

 arch/arm/Kconfig                                |    5 
 arch/arm/Makefile                               |    2 
 arch/arm/boards/versatile/Kconfig               |   18 +
 arch/arm/boards/versatile/Makefile              |    2 
 arch/arm/boards/versatile/config.h              |    5 
 arch/arm/boards/versatile/env/bin/init          |    1 
 arch/arm/boards/versatile/versatilepb.c         |   56 +++
 arch/arm/configs/versatilepb_defconfig          |   12 +
 arch/arm/include/asm/arm_timer.h                |   33 ++
 arch/arm/mach-versatile/Kconfig                 |   16 +
 arch/arm/mach-versatile/Makefile                |    2 
 arch/arm/mach-versatile/core.c                  |  212 ++++++++++++
 arch/arm/mach-versatile/include/mach/clkdev.h   |    7 
 arch/arm/mach-versatile/include/mach/debug_ll.h |   37 ++
 arch/arm/mach-versatile/include/mach/init.h     |    8 
 arch/arm/mach-versatile/include/mach/platform.h |  417 +++++++++++++++++++++++
 16 files changed, 833 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/versatile/Kconfig
 create mode 100644 arch/arm/boards/versatile/Makefile
 create mode 100644 arch/arm/boards/versatile/config.h
 create mode 100644 arch/arm/boards/versatile/env/bin/init
 create mode 100644 arch/arm/boards/versatile/versatilepb.c
 create mode 100644 arch/arm/configs/versatilepb_defconfig
 create mode 100644 arch/arm/include/asm/arm_timer.h
 create mode 100644 arch/arm/mach-versatile/Kconfig
 create mode 100644 arch/arm/mach-versatile/Makefile
 create mode 100644 arch/arm/mach-versatile/core.c
 create mode 100644 arch/arm/mach-versatile/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-versatile/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-versatile/include/mach/init.h
 create mode 100644 arch/arm/mach-versatile/include/mach/platform.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fa37036..1730ce8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -56,6 +56,10 @@ config ARCH_S3C24xx
 	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
 	select CPU_ARM920T
 
+config ARCH_VERSATILE
+	bool "ARM Versatile boards (ARM926EJ-S)"
+	select CPU_ARM926T
+
 endchoice
 
 source arch/arm/cpu/Kconfig
@@ -66,6 +70,7 @@ source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
 source arch/arm/mach-omap/Kconfig
 source arch/arm/mach-s3c24xx/Kconfig
+source arch/arm/mach-versatile/Kconfig
 
 config AEABI
 	bool "Use the ARM EABI to compile barebox"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77b6cf4..6ad14e7 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -45,6 +45,7 @@ machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_OMAP)		:= omap
 machine-$(CONFIG_ARCH_S3C24xx)		:= s3c24xx
+machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 
 # Board directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
 board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
+board-$(CONFIG_MACH_VERSATILEPB)		:= versatile
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/versatile/Kconfig b/arch/arm/boards/versatile/Kconfig
new file mode 100644
index 0000000..9156d9c
--- /dev/null
+++ b/arch/arm/boards/versatile/Kconfig
@@ -0,0 +1,18 @@
+
+if MACH_VERSATILEPB
+
+config ARCH_TEXT_BASE
+	hex
+	default 0
+
+config BOARDINFO
+	default "ARM Versatile/PB (ARM926EJ-S)"
+endif
+
+config VERSATILE_SMC91C111
+	bool "Use smc91c111 instead of smc91x (for QEMU)"
+	help
+	 Enable this option to run barebox inside qemu.
+	 Real versatile boards are equipped with smc911x,
+	 but qemu only provides smc91c111, which is a bit different.
+
diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
new file mode 100644
index 0000000..a17aed3
--- /dev/null
+++ b/arch/arm/boards/versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
new file mode 100644
index 0000000..25bb18f
--- /dev/null
+++ b/arch/arm/boards/versatile/config.h
@@ -0,0 +1,5 @@
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/versatile/env/bin/init b/arch/arm/boards/versatile/env/bin/init
new file mode 100644
index 0000000..224a6b4
--- /dev/null
+++ b/arch/arm/boards/versatile/env/bin/init
@@ -0,0 +1 @@
+# Dummy Init environment script
diff --git a/arch/arm/boards/versatile/versatilepb.c b/arch/arm/boards/versatile/versatilepb.c
new file mode 100644
index 0000000..57e4991
--- /dev/null
+++ b/arch/arm/boards/versatile/versatilepb.c
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <mach/init.h>
+#include <mach/platform.h>
+
+static int vpb_console_init(void)
+{
+	versatile_register_uart(0);
+	return 0;
+}
+
+console_initcall(vpb_console_init);
+
+static struct device_d smc911x_dev = {
+	.id		= -1,
+#ifdef CONFIG_VERSATILE_SMC91C111
+	.name		= "smc91c111",
+#else
+	.name		= "smc911x",
+#endif
+	.map_base	= VERSATILE_ETH_BASE,
+	.size		= 64 * 1024
+};
+
+static int vpb_devices_init(void)
+{
+	versatile_add_sdram(64 * 1024 *1024);
+
+	register_device(&smc911x_dev);
+
+	armlinux_set_architecture(MACH_TYPE_VERSATILE_PB);
+	armlinux_set_bootparams((void *)(0x00000100));
+
+	return 0;
+}
+device_initcall(vpb_devices_init);
diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig
new file mode 100644
index 0000000..f505ac6
--- /dev/null
+++ b/arch/arm/configs/versatilepb_defconfig
@@ -0,0 +1,12 @@
+
+CONFIG_ARCH_VERSATILE=y
+CONFIG_MACH_VERSATILEPB=y
+
+CONFIG_TEXT_BASE=0x500000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+CONFIG_PROMPT="versatilepb> "
+CONFIG_DEFAULT_ENVIRONMENT=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/versatile/env"
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_DRIVER_NET_SMC911X=y
diff --git a/arch/arm/include/asm/arm_timer.h b/arch/arm/include/asm/arm_timer.h
new file mode 100644
index 0000000..0433279
--- /dev/null
+++ b/arch/arm/include/asm/arm_timer.h
@@ -0,0 +1,33 @@
+#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
+#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+
+/*
+ * From Linux v2.6.35
+ * arch/arm/include/asm/hardware/arm_timer.h
+ *
+ * ARM timer implementation, found in Integrator, Versatile and Realview
+ * platforms.  Not all platforms support all registers and bits in these
+ * registers, so we mark them with A for Integrator AP, C for Integrator
+ * CP, V for Versatile and R for Realview.
+ *
+ * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
+ * can have 16-bit or 32-bit selectable via a bit in the control register.
+ */
+#define TIMER_LOAD	0x00			/* ACVR rw */
+#define TIMER_VALUE	0x04			/* ACVR ro */
+#define TIMER_CTRL	0x08			/* ACVR rw */
+#define TIMER_CTRL_ONESHOT	(1 << 0)	/*  CVR */
+#define TIMER_CTRL_32BIT	(1 << 1)	/*  CVR */
+#define TIMER_CTRL_DIV1		(0 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV16	(1 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV256	(2 << 2)	/* ACVR */
+#define TIMER_CTRL_IE		(1 << 5)	/*   VR */
+#define TIMER_CTRL_PERIODIC	(1 << 6)	/* ACVR */
+#define TIMER_CTRL_ENABLE	(1 << 7)	/* ACVR */
+
+#define TIMER_INTCLR	0x0c			/* ACVR wo */
+#define TIMER_RIS	0x10			/*  CVR ro */
+#define TIMER_MIS	0x14			/*  CVR ro */
+#define TIMER_BGLOAD	0x18			/*  CVR rw */
+
+#endif
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
new file mode 100644
index 0000000..9a1bf95
--- /dev/null
+++ b/arch/arm/mach-versatile/Kconfig
@@ -0,0 +1,16 @@
+
+if ARCH_VERSATILE
+
+choice
+	prompt "ARM Board type"
+
+config MACH_VERSATILEPB
+	bool "ARM Versatile/PB (ARM926EJ-S)"
+	select ARM_AMBA
+	select CLKDEV_LOOKUP
+
+endchoice
+
+source arch/arm/boards/versatile/Kconfig
+
+endif
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
new file mode 100644
index 0000000..a8da54c
--- /dev/null
+++ b/arch/arm/mach-versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-y += core.o
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
new file mode 100644
index 0000000..94543c6
--- /dev/null
+++ b/arch/arm/mach-versatile/core.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd,
+ * http://l4dev.org
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * Based on mach-nomadik
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <debug_ll.h>
+
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/arm_timer.h>
+#include <asm/armlinux.h>
+
+#include <mach/platform.h>
+#include <mach/init.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.id = -1,
+	.name = "mem",
+	.map_base = 0x00000000,
+	.platform_data = &ram_pdata,
+};
+
+void versatile_add_sdram(u32 size)
+{
+	sdram_dev.size = size;
+	register_device(&sdram_dev);
+	armlinux_add_dram(&sdram_dev);
+}
+
+static struct device_d uart0_serial_device = {
+	.id = 0,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART0_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart1_serial_device = {
+	.id = 1,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART1_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart2_serial_device = {
+	.id = 2,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART2_BASE,
+	.size = 4096,
+};
+static struct device_d uart3_serial_device = {
+	.id = 3,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART3_BASE,
+	.size = 4096,
+};
+
+struct clk {
+	unsigned long rate;
+};
+
+static struct clk ref_clk_24 = {
+	.rate = 24000000,
+};
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* enable and disable do nothing */
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Create a clock structure with the given name */
+int vpb_clk_create(struct clk *clk, const char *dev_id)
+{
+	struct clk_lookup *clkdev;
+
+	clkdev = clkdev_alloc(clk, NULL, dev_id);
+	if (!clkdev)
+		return -ENOMEM;
+
+	clkdev_add(clkdev);
+	return 0;
+}
+
+/* 1Mhz / 256 */
+#define TIMER_FREQ (1000000/256)
+
+#define TIMER0_BASE (VERSATILE_TIMER0_1_BASE)
+#define TIMER1_BASE ((VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_BASE (VERSATILE_TIMER2_3_BASE)
+#define TIMER3_BASE ((VERSATILE_TIMER2_3_BASE) + 0x20)
+
+static uint64_t vpb_clocksource_read(void)
+{
+	return ~readl(TIMER0_BASE + TIMER_VALUE);
+}
+
+static struct clocksource vpb_cs = {
+	.read = vpb_clocksource_read,
+	.mask = 0xffffffff,
+	.shift = 10,
+};
+
+/* From Linux v2.6.35
+ * arch/arm/mach-versatile/core.c */
+static void versatile_timer_init (void)
+{
+	u32 val;
+
+	/*
+	 * set clock frequency:
+	 *      VERSATILE_REFCLK is 32KHz
+	 *      VERSATILE_TIMCLK is 1MHz
+	 */
+
+	val = readl(VERSATILE_SCTL_BASE);
+	val |= (VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel);
+	writel(val, VERSATILE_SCTL_BASE);
+
+	/*
+	 * Disable all timers, just to be sure.
+	 */
+
+	writel(0, TIMER0_BASE + TIMER_CTRL);
+	writel(0, TIMER1_BASE + TIMER_CTRL);
+	writel(0, TIMER2_BASE + TIMER_CTRL);
+	writel(0, TIMER3_BASE + TIMER_CTRL);
+
+        writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_DIV256,
+			                TIMER0_BASE + TIMER_CTRL);
+}
+
+static int vpb_clocksource_init(void)
+{
+	versatile_timer_init();
+	vpb_cs.mult = clocksource_hz2mult(TIMER_FREQ, vpb_cs.shift);
+
+	return init_clock(&vpb_cs);
+}
+
+core_initcall(vpb_clocksource_init);
+
+void versatile_register_uart(unsigned id)
+{
+	switch (id) {
+	case 0:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart0_serial_device));
+		register_device(&uart0_serial_device);
+		break;
+	case 1:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart1_serial_device));
+		register_device(&uart1_serial_device);
+		break;
+	case 2:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart2_serial_device));
+		register_device(&uart2_serial_device);
+		break;
+	case 3:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart3_serial_device));
+		register_device(&uart3_serial_device);
+		break;
+	}
+}
+
+void __noreturn reset_cpu (unsigned long ignored)
+{
+	while (1);
+}
+EXPORT_SYMBOL(reset_cpu);
+
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
new file mode 100644
index 0000000..04b37a8
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/debug_ll.h b/arch/arm/mach-versatile/include/mach/debug_ll.h
new file mode 100644
index 0000000..514fcfb
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/debug_ll.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * barebox is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * barebox is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with barebox.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define   __MACH_DEBUG_LL_H__
+
+#include <linux/amba/serial.h>
+#include <asm/io.h>
+
+static inline void putc(char c)
+{
+	/* Wait until there is space in the FIFO */
+	while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+
+	/* Send the character */
+	writel(c, 0x101F1000 + UART01x_DR);
+
+	/* Wait to make sure it hits the line, in case we die too soon. */
+	while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+}
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/init.h b/arch/arm/mach-versatile/include/mach/init.h
new file mode 100644
index 0000000..878cde0
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/init.h
@@ -0,0 +1,8 @@
+
+#ifndef __VERSATILE_INIT_H__
+#define __VERSATILE_INIT_H__
+
+void versatile_add_sdram(u32 size);
+void versatile_register_uart(unsigned id);
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
new file mode 100644
index 0000000..88b8032
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/platform.h
@@ -0,0 +1,417 @@
+/*
+ * ach-arm926ejs/include/mach/platform.h
+ *
+ * Borrowed from Linux v2.6.35
+ * arch/arm/mach-versatile/include/mach/platform.h
+ *
+ * Copyright (c) ARM Limited 2003.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __address_h
+#define __address_h                     1
+
+/*
+ * Memory definitions
+ */
+#define VERSATILE_BOOT_ROM_LO          0x30000000		/* DoC Base (64Mb)...*/
+#define VERSATILE_BOOT_ROM_HI          0x30000000
+#define VERSATILE_BOOT_ROM_BASE        VERSATILE_BOOT_ROM_HI	 /*  Normal position */
+#define VERSATILE_BOOT_ROM_SIZE        SZ_64M
+
+#define VERSATILE_SSRAM_BASE           /* VERSATILE_SSMC_BASE ? */
+#define VERSATILE_SSRAM_SIZE           SZ_2M
+
+#define VERSATILE_FLASH_BASE           0x34000000
+#define VERSATILE_FLASH_SIZE           SZ_64M
+
+/* 
+ *  SDRAM
+ */
+#define VERSATILE_SDRAM_BASE           0x00000000
+
+/* 
+ *  Logic expansion modules
+ * 
+ */
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile Registers
+ * ------------------------------------------------------------------------
+ * 
+ */
+#define VERSATILE_SYS_ID_OFFSET               0x00
+#define VERSATILE_SYS_SW_OFFSET               0x04
+#define VERSATILE_SYS_LED_OFFSET              0x08
+#define VERSATILE_SYS_OSC0_OFFSET             0x0C
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC1_OFFSET             0x10
+#define VERSATILE_SYS_OSC2_OFFSET             0x14
+#define VERSATILE_SYS_OSC3_OFFSET             0x18
+#define VERSATILE_SYS_OSC4_OFFSET             0x1C
+#elif defined(CONFIG_MACH_VERSATILE_AB)
+#define VERSATILE_SYS_OSC1_OFFSET             0x1C
+#endif
+
+#define VERSATILE_SYS_OSCCLCD_OFFSET          0x1c
+
+#define VERSATILE_SYS_LOCK_OFFSET             0x20
+#define VERSATILE_SYS_100HZ_OFFSET            0x24
+#define VERSATILE_SYS_CFGDATA1_OFFSET         0x28
+#define VERSATILE_SYS_CFGDATA2_OFFSET         0x2C
+#define VERSATILE_SYS_FLAGS_OFFSET            0x30
+#define VERSATILE_SYS_FLAGSSET_OFFSET         0x30
+#define VERSATILE_SYS_FLAGSCLR_OFFSET         0x34
+#define VERSATILE_SYS_NVFLAGS_OFFSET          0x38
+#define VERSATILE_SYS_NVFLAGSSET_OFFSET       0x38
+#define VERSATILE_SYS_NVFLAGSCLR_OFFSET       0x3C
+#define VERSATILE_SYS_RESETCTL_OFFSET         0x40
+#define VERSATILE_SYS_PCICTL_OFFSET           0x44
+#define VERSATILE_SYS_MCI_OFFSET              0x48
+#define VERSATILE_SYS_FLASH_OFFSET            0x4C
+#define VERSATILE_SYS_CLCD_OFFSET             0x50
+#define VERSATILE_SYS_CLCDSER_OFFSET          0x54
+#define VERSATILE_SYS_BOOTCS_OFFSET           0x58
+#define VERSATILE_SYS_24MHz_OFFSET            0x5C
+#define VERSATILE_SYS_MISC_OFFSET             0x60
+#define VERSATILE_SYS_TEST_OSC0_OFFSET        0x80
+#define VERSATILE_SYS_TEST_OSC1_OFFSET        0x84
+#define VERSATILE_SYS_TEST_OSC2_OFFSET        0x88
+#define VERSATILE_SYS_TEST_OSC3_OFFSET        0x8C
+#define VERSATILE_SYS_TEST_OSC4_OFFSET        0x90
+
+#define VERSATILE_SYS_BASE                    0x10000000
+#define VERSATILE_SYS_ID                      (VERSATILE_SYS_BASE + VERSATILE_SYS_ID_OFFSET)
+#define VERSATILE_SYS_SW                      (VERSATILE_SYS_BASE + VERSATILE_SYS_SW_OFFSET)
+#define VERSATILE_SYS_LED                     (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET)
+#define VERSATILE_SYS_OSC0                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET)
+#define VERSATILE_SYS_OSC1                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET)
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC2                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET)
+#define VERSATILE_SYS_OSC3                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET)
+#define VERSATILE_SYS_OSC4                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET)
+#endif
+
+#define VERSATILE_SYS_LOCK                    (VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET)
+#define VERSATILE_SYS_100HZ                   (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET)
+#define VERSATILE_SYS_CFGDATA1                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET)
+#define VERSATILE_SYS_CFGDATA2                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA2_OFFSET)
+#define VERSATILE_SYS_FLAGS                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGS_OFFSET)
+#define VERSATILE_SYS_FLAGSSET                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSSET_OFFSET)
+#define VERSATILE_SYS_FLAGSCLR                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSCLR_OFFSET)
+#define VERSATILE_SYS_NVFLAGS                 (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGS_OFFSET)
+#define VERSATILE_SYS_NVFLAGSSET              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
+#define VERSATILE_SYS_NVFLAGSCLR              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
+#define VERSATILE_SYS_RESETCTL                (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
+#define VERSATILE_SYS_PCICTL                  (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
+#define VERSATILE_SYS_MCI                     (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYS_FLASH                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_SYS_CLCD                    (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
+#define VERSATILE_SYS_CLCDSER                 (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCDSER_OFFSET)
+#define VERSATILE_SYS_BOOTCS                  (VERSATILE_SYS_BASE + VERSATILE_SYS_BOOTCS_OFFSET)
+#define VERSATILE_SYS_24MHz                   (VERSATILE_SYS_BASE + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_SYS_MISC                    (VERSATILE_SYS_BASE + VERSATILE_SYS_MISC_OFFSET)
+#define VERSATILE_SYS_TEST_OSC0               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC0_OFFSET)
+#define VERSATILE_SYS_TEST_OSC1               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC1_OFFSET)
+#define VERSATILE_SYS_TEST_OSC2               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC2_OFFSET)
+#define VERSATILE_SYS_TEST_OSC3               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC3_OFFSET)
+#define VERSATILE_SYS_TEST_OSC4               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC4_OFFSET)
+
+/* 
+ * Values for VERSATILE_SYS_RESET_CTRL
+ */
+#define VERSATILE_SYS_CTRL_RESET_CONFIGCLR    0x01
+#define VERSATILE_SYS_CTRL_RESET_CONFIGINIT   0x02
+#define VERSATILE_SYS_CTRL_RESET_DLLRESET     0x03
+#define VERSATILE_SYS_CTRL_RESET_PLLRESET     0x04
+#define VERSATILE_SYS_CTRL_RESET_POR          0x05
+#define VERSATILE_SYS_CTRL_RESET_DoC          0x06
+
+#define VERSATILE_SYS_CTRL_LED         (1 << 0)
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile control registers
+ * ------------------------------------------------------------------------
+ */
+
+/* 
+ * VERSATILE_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4  = build value
+ * 3:0   = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * VERSATILE_SYS_LOCK
+ *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, 
+ *     SYS_CLD, SYS_BOOTCS
+ */
+#define VERSATILE_SYS_LOCK_LOCKED    (1 << 16)
+#define VERSATILE_SYS_LOCKVAL_MASK	0xFFFF		/* write 0xA05F to enable write access */
+
+/*
+ * VERSATILE_SYS_FLASH
+ */
+#define VERSATILE_FLASHPROG_FLVPPEN	(1 << 0)	/* Enable writing to flash */
+
+/*
+ * VERSATILE_INTREG
+ *     - used to acknowledge and control MMCI and UART interrupts 
+ */
+#define VERSATILE_INTREG_WPROT        0x00    /* MMC protection status (no interrupt generated) */
+#define VERSATILE_INTREG_RI0          0x01    /* Ring indicator UART0 is asserted,              */
+#define VERSATILE_INTREG_CARDIN       0x08    /* MMCI card in detect                            */
+                                                /* write 1 to acknowledge and clear               */
+#define VERSATILE_INTREG_RI1          0x02    /* Ring indicator UART1 is asserted,              */
+#define VERSATILE_INTREG_CARDINSERT   0x03    /* Signal insertion of MMC card                   */
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_PCI_CORE_BASE        0x10001000	/* PCI core control */
+#define VERSATILE_I2C_BASE             0x10002000	/* I2C control */
+#define VERSATILE_SIC_BASE             0x10003000	/* Secondary interrupt controller */
+#define VERSATILE_AACI_BASE            0x10004000	/* Audio */
+#define VERSATILE_MMCI0_BASE           0x10005000	/* MMC interface */
+#define VERSATILE_KMI0_BASE            0x10006000	/* KMI interface */
+#define VERSATILE_KMI1_BASE            0x10007000	/* KMI 2nd interface */
+#define VERSATILE_CHAR_LCD_BASE        0x10008000	/* Character LCD */
+#define VERSATILE_UART3_BASE           0x10009000	/* UART 3 */
+#define VERSATILE_SCI1_BASE            0x1000A000
+#define VERSATILE_MMCI1_BASE           0x1000B000    /* MMC Interface */
+	/* 0x1000C000 - 0x1000CFFF = reserved */
+#define VERSATILE_ETH_BASE             0x10010000	/* Ethernet */
+#define VERSATILE_USB_BASE             0x10020000	/* USB */
+	/* 0x10030000 - 0x100FFFFF = reserved */
+#define VERSATILE_SMC_BASE             0x10100000	/* SMC */
+#define VERSATILE_MPMC_BASE            0x10110000	/* MPMC */
+#define VERSATILE_CLCD_BASE            0x10120000	/* CLCD */
+#define VERSATILE_DMAC_BASE            0x10130000	/* DMA controller */
+#define VERSATILE_VIC_BASE             0x10140000	/* Vectored interrupt controller */
+#define VERSATILE_PERIPH_BASE          0x10150000	/* off-chip peripherals alias from */
+                                                /* 0x10000000 - 0x100FFFFF */
+#define VERSATILE_AHBM_BASE            0x101D0000	/* AHB monitor */
+#define VERSATILE_SCTL_BASE            0x101E0000	/* System controller */
+#define VERSATILE_WATCHDOG_BASE        0x101E1000	/* Watchdog */
+#define VERSATILE_TIMER0_1_BASE        0x101E2000	/* Timer 0 and 1 */
+#define VERSATILE_TIMER2_3_BASE        0x101E3000	/* Timer 2 and 3 */
+#define VERSATILE_GPIO0_BASE           0x101E4000	/* GPIO port 0 */
+#define VERSATILE_GPIO1_BASE           0x101E5000	/* GPIO port 1 */
+#define VERSATILE_GPIO2_BASE           0x101E6000	/* GPIO port 2 */
+#define VERSATILE_GPIO3_BASE           0x101E7000	/* GPIO port 3 */
+#define VERSATILE_RTC_BASE             0x101E8000	/* Real Time Clock */
+	/* 0x101E9000 - reserved */
+#define VERSATILE_SCI_BASE             0x101F0000	/* Smart card controller */
+#define VERSATILE_UART0_BASE           0x101F1000	/* Uart 0 */
+#define VERSATILE_UART1_BASE           0x101F2000	/* Uart 1 */
+#define VERSATILE_UART2_BASE           0x101F3000	/* Uart 2 */
+#define VERSATILE_SSP_BASE             0x101F4000	/* Synchronous Serial Port */
+
+#define VERSATILE_SSMC_BASE            0x20000000	/* SSMC */
+#define VERSATILE_IB2_BASE             0x24000000	/* IB2 module */
+#define VERSATILE_MBX_BASE             0x40000000	/* MBX */
+
+/* PCI space */
+#define VERSATILE_PCI_BASE             0x41000000	/* PCI Interface */
+#define VERSATILE_PCI_CFG_BASE	       0x42000000
+#define VERSATILE_PCI_MEM_BASE0        0x44000000
+#define VERSATILE_PCI_MEM_BASE1        0x50000000
+#define VERSATILE_PCI_MEM_BASE2        0x60000000
+/* Sizes of above maps */
+#define VERSATILE_PCI_BASE_SIZE	       0x01000000
+#define VERSATILE_PCI_CFG_BASE_SIZE    0x02000000
+#define VERSATILE_PCI_MEM_BASE0_SIZE   0x0c000000	/* 32Mb */
+#define VERSATILE_PCI_MEM_BASE1_SIZE   0x10000000	/* 256Mb */
+#define VERSATILE_PCI_MEM_BASE2_SIZE   0x10000000	/* 256Mb */
+
+#define VERSATILE_SDRAM67_BASE         0x70000000	/* SDRAM banks 6 and 7 */
+#define VERSATILE_LT_BASE              0x80000000	/* Logic Tile expansion */
+
+/*
+ * Disk on Chip
+ */
+#define VERSATILE_DOC_BASE             0x2C000000
+#define VERSATILE_DOC_SIZE             (16 << 20)
+#define VERSATILE_DOC_PAGE_SIZE        512
+#define VERSATILE_DOC_TOTAL_PAGES     (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES    32
+#define START_PAGE          0x80
+
+/* 
+ *  LED settings, bits [7:0]
+ */
+#define VERSATILE_SYS_LED0             (1 << 0)
+#define VERSATILE_SYS_LED1             (1 << 1)
+#define VERSATILE_SYS_LED2             (1 << 2)
+#define VERSATILE_SYS_LED3             (1 << 3)
+#define VERSATILE_SYS_LED4             (1 << 4)
+#define VERSATILE_SYS_LED5             (1 << 5)
+#define VERSATILE_SYS_LED6             (1 << 6)
+#define VERSATILE_SYS_LED7             (1 << 7)
+
+#define ALL_LEDS                  0xFF
+
+#define LED_BANK                  VERSATILE_SYS_LED
+
+/* 
+ * Control registers
+ */
+#define VERSATILE_IDFIELD_OFFSET	0x0	/* Versatile build information */
+#define VERSATILE_FLASHPROG_OFFSET	0x4	/* Flash devices */
+#define VERSATILE_INTREG_OFFSET		0x8	/* Interrupt control */
+#define VERSATILE_DECODE_OFFSET		0xC	/* Fitted logic modules */
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile Interrupt Controller - control registers
+ * ------------------------------------------------------------------------
+ * 
+ *  Offsets from interrupt controller base 
+ * 
+ *  System Controller interrupt controller base is
+ * 
+ * 	VERSATILE_IC_BASE
+ * 
+ *  Core Module interrupt controller base is
+ * 
+ * 	VERSATILE_SYS_IC 
+ * 
+ */
+/* VIC definitions in include/asm-arm/hardware/vic.h */
+
+#define SIC_IRQ_STATUS                  0
+#define SIC_IRQ_RAW_STATUS              0x04
+#define SIC_IRQ_ENABLE                  0x08
+#define SIC_IRQ_ENABLE_SET              0x08
+#define SIC_IRQ_ENABLE_CLEAR            0x0C
+#define SIC_INT_SOFT_SET                0x10
+#define SIC_INT_SOFT_CLEAR              0x14
+#define SIC_INT_PIC_ENABLE              0x20	/* read status of pass through mask */
+#define SIC_INT_PIC_ENABLES             0x20	/* set interrupt pass through bits */
+#define SIC_INT_PIC_ENABLEC             0x24	/* Clear interrupt pass through bits */
+
+/* ------------------------------------------------------------------------
+ *  Interrupts - bit assignment (primary)
+ * ------------------------------------------------------------------------
+ */
+
+#define INT_WDOGINT                     0	/* Watchdog timer */
+#define INT_SOFTINT                     1	/* Software interrupt */
+#define INT_COMMRx                      2	/* Debug Comm Rx interrupt */
+#define INT_COMMTx                      3	/* Debug Comm Tx interrupt */
+#define INT_TIMERINT0_1                 4	/* Timer 0 and 1 */
+#define INT_TIMERINT2_3                 5	/* Timer 2 and 3 */
+#define INT_GPIOINT0                    6	/* GPIO 0 */
+#define INT_GPIOINT1                    7	/* GPIO 1 */
+#define INT_GPIOINT2                    8	/* GPIO 2 */
+#define INT_GPIOINT3                    9	/* GPIO 3 */
+#define INT_RTCINT                      10	/* Real Time Clock */
+#define INT_SSPINT                      11	/* Synchronous Serial Port */
+#define INT_UARTINT0                    12	/* UART 0 on development chip */
+#define INT_UARTINT1                    13	/* UART 1 on development chip */
+#define INT_UARTINT2                    14	/* UART 2 on development chip */
+#define INT_SCIINT                      15	/* Smart Card Interface */
+#define INT_CLCDINT                     16	/* CLCD controller */
+#define INT_DMAINT                      17	/* DMA controller */
+#define INT_PWRFAILINT                  18	/* Power failure */
+#define INT_MBXINT                      19	/* Graphics processor */
+#define INT_GNDINT                      20	/* Reserved */
+	/* External interrupt signals from logic tiles or secondary controller */
+#define INT_VICSOURCE21                 21	/* Disk on Chip */
+#define INT_VICSOURCE22                 22	/* MCI0A */
+#define INT_VICSOURCE23                 23	/* MCI1A */
+#define INT_VICSOURCE24                 24	/* AACI */
+#define INT_VICSOURCE25                 25	/* Ethernet */
+#define INT_VICSOURCE26                 26	/* USB */
+#define INT_VICSOURCE27                 27	/* PCI 0 */
+#define INT_VICSOURCE28                 28	/* PCI 1 */
+#define INT_VICSOURCE29                 29	/* PCI 2 */
+#define INT_VICSOURCE30                 30	/* PCI 3 */
+#define INT_VICSOURCE31                 31	/* SIC source */
+
+#define VERSATILE_SC_VALID_INT               0x003FFFFF
+
+#define MAXIRQNUM                       31
+#define MAXFIQNUM                       31
+#define MAXSWINUM                       31
+
+/* ------------------------------------------------------------------------
+ *  Interrupts - bit assignment (secondary)
+ * ------------------------------------------------------------------------
+ */
+#define SIC_INT_MMCI0B                  1	/* Multimedia Card 0B */
+#define SIC_INT_MMCI1B                  2	/* Multimedia Card 1B */
+#define SIC_INT_KMI0                    3	/* Keyboard/Mouse port 0 */
+#define SIC_INT_KMI1                    4	/* Keyboard/Mouse port 1 */
+#define SIC_INT_SCI3                    5	/* Smart Card interface */
+#define SIC_INT_UART3                   6	/* UART 3 empty or data available */
+#define SIC_INT_CLCD                    7	/* Character LCD */
+#define SIC_INT_TOUCH                   8	/* Touchscreen */
+#define SIC_INT_KEYPAD                  9	/* Key pressed on display keypad */
+	/* 10:20 - reserved */
+#define SIC_INT_DoC                     21	/* Disk on Chip memory controller */
+#define SIC_INT_MMCI0A                  22	/* MMC 0A */
+#define SIC_INT_MMCI1A                  23	/* MMC 1A */
+#define SIC_INT_AACI                    24	/* Audio Codec */
+#define SIC_INT_ETH                     25	/* Ethernet controller */
+#define SIC_INT_USB                     26	/* USB controller */
+#define SIC_INT_PCI0                    27
+#define SIC_INT_PCI1                    28
+#define SIC_INT_PCI2                    29
+#define SIC_INT_PCI3                    30
+
+
+/*
+ * System controller bit assignment
+ */
+#define VERSATILE_REFCLK	0
+#define VERSATILE_TIMCLK	1
+
+#define VERSATILE_TIMER1_EnSel	15
+#define VERSATILE_TIMER2_EnSel	17
+#define VERSATILE_TIMER3_EnSel	19
+#define VERSATILE_TIMER4_EnSel	21
+
+
+#define VERSATILE_CSR_BASE             0x10000000
+#define VERSATILE_CSR_SIZE             0x10000000
+
+#ifdef CONFIG_MACH_VERSATILE_AB
+/*
+ * IB2 Versatile/AB expansion board definitions
+ */
+#define VERSATILE_IB2_CAMERA_BANK	VERSATILE_IB2_BASE
+#define VERSATILE_IB2_KBD_DATAREG	(VERSATILE_IB2_BASE + 0x01000000)
+
+/* VICINTSOURCE27 */
+#define VERSATILE_IB2_INT_BASE		(VERSATILE_IB2_BASE + 0x02000000)
+#define VERSATILE_IB2_IER		(VERSATILE_IB2_INT_BASE + 0)
+#define VERSATILE_IB2_ISR		(VERSATILE_IB2_INT_BASE + 4)
+
+#define VERSATILE_IB2_CTL_BASE		(VERSATILE_IB2_BASE + 0x03000000)
+#define VERSATILE_IB2_CTRL		(VERSATILE_IB2_CTL_BASE + 0)
+#define VERSATILE_IB2_STAT		(VERSATILE_IB2_CTL_BASE + 4)
+#endif
+
+#endif



From plagnioj at jcrosoft.com  Mon Oct 11 11:20:58 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 17:20:58 +0200
Subject: [PATCH 4/4] Adapt the defconfig for a full blown ChumbyOne support
In-Reply-To: <1286808746-19456-5-git-send-email-jbe@pengutronix.de>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
	<1286808746-19456-5-git-send-email-jbe@pengutronix.de>
Message-ID: <20101011152058.GC7412@game.jcrosoft.org>

On 16:52 Mon 11 Oct     , Juergen Beisert wrote:
> Make the ChumbyOne use of the MCI framework.
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  arch/arm/configs/chumbyone_defconfig |  224 +++++++++++++++++++++++++++++++++-

please use savedefconfig

Best Regards,
J.


From plagnioj at jcrosoft.com  Mon Oct 11 11:23:04 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 11 Oct 2010 17:23:04 +0200
Subject: [PATCH] Add basic support from ARM Versatile/PB
In-Reply-To: <20101011144836.GB28242@pengutronix.de>
References: <20101010230505.17833.46593.stgit@zaytsev.su>
	<20101011144129.GB7412@game.jcrosoft.org>
	<20101011144836.GB28242@pengutronix.de>
Message-ID: <20101011152304.GD7412@game.jcrosoft.org>

On 16:48 Mon 11 Oct     , Sascha Hauer wrote:
> On Mon, Oct 11, 2010 at 04:41:29PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 23:15 Sun 10 Oct     , Alexey Zaytsev wrote:
> > > Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
> > > ---
> > > 
> > > Hi.
> > > 
> > > It seems that barebox does not run on any ARM machines provided
> > > by QEMU. This patch adds basic Versatile/PB support. It is far from
> > > being complete and has not been tested on real hardware, but
> > > seems to work fine in QEMU.
> > > 
> > > Please notice, that you need to set CONFIG_VERSATILE_SMC91C111
> > > in order to have networking in QEMU, as it does not provide
> > > smc91x found on the real hardware.
> > > 
> > > For a queck test, run:
> > > 
> > > 	qemu-system-arm -kernel barebox.bin -M versatilepb -cpu arm926 -nographic -m 64 -net nic,model=smc91c111 -net user
> > this must be in a doc
> > 
> > please use defaultenv and enable more functionnability
> > 
> > as we can use it as ref board for emulation
> > > 
> > > 
> > > +
> > > +config BOARDINFO
> > > +	default "ARM Versatile/PB (ARM926EJ-S)"
> > > +endif
> > > +
> > > +config VERSATILE_SMC91C111
> > > +	bool "Use smc91c111 instead of smc91x (for QEMU)"
> > > +	default 0
> > ??
> > > +	help
> > > +	 Enable this option to run barebox inside qemu.
> > > +	 Real versatile boards are equipped with smc911x,
> > > +	 but qemu only provides smc91111, which is a bit different.
> > it will be beter to modify the ressources depending on the drivers enabled
> 
> I think it's ok the way Alexey did this. It's a good place to document
> that we need two different ethernet drivers depending on native/qemu
> compilation.
yeah but just enable the drivers is enough but we need to make it exclusive
via Kconfig otherwise it will be confusing

Best Regards,
J.


From jbe at pengutronix.de  Mon Oct 11 11:42:01 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 17:42:01 +0200
Subject: [PATCH 4/4] Adapt the defconfig for a full blown ChumbyOne support
In-Reply-To: <20101011152058.GC7412@game.jcrosoft.org>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
	<1286808746-19456-5-git-send-email-jbe@pengutronix.de>
	<20101011152058.GC7412@game.jcrosoft.org>
Message-ID: <201010111742.02731.jbe@pengutronix.de>

Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:52 Mon 11 Oct     , Juergen Beisert wrote:
> > Make the ChumbyOne use of the MCI framework.
> >
> > Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> > ---
> >  arch/arm/configs/chumbyone_defconfig |  224
> > +++++++++++++++++++++++++++++++++-
>
> please use savedefconfig

Sorry, didn't notice the difference yet. I will resend this patch.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Mon Oct 11 11:47:44 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 11 Oct 2010 17:47:44 +0200
Subject: [PATCH 4/4] Adapt the defconfig for a full blown ChumbyOne support
In-Reply-To: <1286808746-19456-5-git-send-email-jbe@pengutronix.de>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
	<1286808746-19456-5-git-send-email-jbe@pengutronix.de>
Message-ID: <201010111747.44641.jbe@pengutronix.de>

commit 69f4b4f403b1dbe17a95be340688dc77d166bb4e
Author: Juergen Beisert <jbe at pengutronix.de>
Date:   Mon Oct 11 16:42:59 2010 +0200

    Adapt the defconfig for a full blown ChumbyOne support
    
    Make the ChumbyOne use of the MCI framework.
    
    Signed-off-by: Juergen Beisert <jbe at pengutronix.de>

diff --git a/arch/arm/configs/chumbyone_defconfig b/arch/arm/configs/chumbyone_defconfig
index c21c7cd..595b6a9 100644
--- a/arch/arm/configs/chumbyone_defconfig
+++ b/arch/arm/configs/chumbyone_defconfig
@@ -3,11 +3,12 @@ CONFIG_MACH_CHUMBY=y
 CONFIG_AEABI=y
 CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
 CONFIG_BROKEN=y
+CONFIG_PROMPT="chumby:"
 CONFIG_LONGHELP=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
-# CONFIG_DEFAULT_ENVIRONMENT is not set
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/chumby_falconwing/env"
 CONFIG_DEBUG_INFO=y
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
@@ -23,3 +24,6 @@ CONFIG_CMD_RESET=y
 CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_PARTITION=y
 # CONFIG_SPI is not set
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_STM378X=y


-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From alexey.zaytsev at gmail.com  Mon Oct 11 12:20:46 2010
From: alexey.zaytsev at gmail.com (Alexey Zaytsev)
Date: Mon, 11 Oct 2010 20:20:46 +0400
Subject: [PATCH v2] Add basic support from ARM Versatile/PB
In-Reply-To: <20101011150644.32683.47820.stgit@zaytsev.su>
References: <20101011150644.32683.47820.stgit@zaytsev.su>
Message-ID: <AANLkTi=yZZQ=cCoAfs0n2YwgZJtZfSOXc7xB-SBToph5@mail.gmail.com>

It seems that I've been wrong, and the real versatile/pb board also
provides smc91c111. I've been confused my the naming diffirences
between barebox and Linux. I'll send an updated patch soon.

On Mon, Oct 11, 2010 at 19:15, Alexey Zaytsev <alexey.zaytsev at gmail.com> wrote:
> To test in qemu:
>
> qemu-system-arm -kernel barebox.bin -M versatilepb -cpu arm926 -nographic -m 64 -net nic,model=smc91c111 -net user
>
> And don't forget to set CONFIG_VERSATILE_SMC91C111.
>
> Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
> ---
>
> Fixed a few minor problems.
>
> Where should I add the instructions on running qemu?
> Anyway, it seems to be quite straght-forward, and I've documented it
> in the commit message. I'll send an additional patch, if there is a
> better place.
>
> I have not added a default env yet. I'm new to barebox, and ran it for the first time only after porting it. Not sure I fully understand how works yet. ;)
>
> ?arch/arm/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?5
> ?arch/arm/Makefile ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?2
> ?arch/arm/boards/versatile/Kconfig ? ? ? ? ? ? ? | ? 18 +
> ?arch/arm/boards/versatile/Makefile ? ? ? ? ? ? ?| ? ?2
> ?arch/arm/boards/versatile/config.h ? ? ? ? ? ? ?| ? ?5
> ?arch/arm/boards/versatile/env/bin/init ? ? ? ? ?| ? ?1
> ?arch/arm/boards/versatile/versatilepb.c ? ? ? ? | ? 56 +++
> ?arch/arm/configs/versatilepb_defconfig ? ? ? ? ?| ? 12 +
> ?arch/arm/include/asm/arm_timer.h ? ? ? ? ? ? ? ?| ? 33 ++
> ?arch/arm/mach-versatile/Kconfig ? ? ? ? ? ? ? ? | ? 16 +
> ?arch/arm/mach-versatile/Makefile ? ? ? ? ? ? ? ?| ? ?2
> ?arch/arm/mach-versatile/core.c ? ? ? ? ? ? ? ? ?| ?212 ++++++++++++
> ?arch/arm/mach-versatile/include/mach/clkdev.h ? | ? ?7
> ?arch/arm/mach-versatile/include/mach/debug_ll.h | ? 37 ++
> ?arch/arm/mach-versatile/include/mach/init.h ? ? | ? ?8
> ?arch/arm/mach-versatile/include/mach/platform.h | ?417 +++++++++++++++++++++++
> ?16 files changed, 833 insertions(+), 0 deletions(-)
> ?create mode 100644 arch/arm/boards/versatile/Kconfig
> ?create mode 100644 arch/arm/boards/versatile/Makefile
> ?create mode 100644 arch/arm/boards/versatile/config.h
> ?create mode 100644 arch/arm/boards/versatile/env/bin/init
> ?create mode 100644 arch/arm/boards/versatile/versatilepb.c
> ?create mode 100644 arch/arm/configs/versatilepb_defconfig
> ?create mode 100644 arch/arm/include/asm/arm_timer.h
> ?create mode 100644 arch/arm/mach-versatile/Kconfig
> ?create mode 100644 arch/arm/mach-versatile/Makefile
> ?create mode 100644 arch/arm/mach-versatile/core.c
> ?create mode 100644 arch/arm/mach-versatile/include/mach/clkdev.h
> ?create mode 100644 arch/arm/mach-versatile/include/mach/debug_ll.h
> ?create mode 100644 arch/arm/mach-versatile/include/mach/init.h
> ?create mode 100644 arch/arm/mach-versatile/include/mach/platform.h
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index fa37036..1730ce8 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -56,6 +56,10 @@ config ARCH_S3C24xx
> ? ? ? ?bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
> ? ? ? ?select CPU_ARM920T
>
> +config ARCH_VERSATILE
> + ? ? ? bool "ARM Versatile boards (ARM926EJ-S)"
> + ? ? ? select CPU_ARM926T
> +
> ?endchoice
>
> ?source arch/arm/cpu/Kconfig
> @@ -66,6 +70,7 @@ source arch/arm/mach-netx/Kconfig
> ?source arch/arm/mach-nomadik/Kconfig
> ?source arch/arm/mach-omap/Kconfig
> ?source arch/arm/mach-s3c24xx/Kconfig
> +source arch/arm/mach-versatile/Kconfig
>
> ?config AEABI
> ? ? ? ?bool "Use the ARM EABI to compile barebox"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 77b6cf4..6ad14e7 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -45,6 +45,7 @@ machine-$(CONFIG_ARCH_NOMADIK) ? ? ? ? ? ? ? ?:= nomadik
> ?machine-$(CONFIG_ARCH_NETX) ? ? ? ? ? ?:= netx
> ?machine-$(CONFIG_ARCH_OMAP) ? ? ? ? ? ?:= omap
> ?machine-$(CONFIG_ARCH_S3C24xx) ? ? ? ? := s3c24xx
> +machine-$(CONFIG_ARCH_VERSATILE) ? ? ? := versatile
>
> ?# Board directory name. ?This list is sorted alphanumerically
> ?# by CONFIG_* macro name.
> @@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043) ? ? ? ? ? ? ? ? ? := pcm043
> ?board-$(CONFIG_MACH_PM9263) ? ? ? ? ? ? ? ? ? ?:= pm9263
> ?board-$(CONFIG_MACH_SCB9328) ? ? ? ? ? ? ? ? ? := scb9328
> ?board-$(CONFIG_MACH_NESO) ? ? ? ? ? ? ? ? ? ? ?:= guf-neso
> +board-$(CONFIG_MACH_VERSATILEPB) ? ? ? ? ? ? ? := versatile
>
> ?machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
>
> diff --git a/arch/arm/boards/versatile/Kconfig b/arch/arm/boards/versatile/Kconfig
> new file mode 100644
> index 0000000..9156d9c
> --- /dev/null
> +++ b/arch/arm/boards/versatile/Kconfig
> @@ -0,0 +1,18 @@
> +
> +if MACH_VERSATILEPB
> +
> +config ARCH_TEXT_BASE
> + ? ? ? hex
> + ? ? ? default 0
> +
> +config BOARDINFO
> + ? ? ? default "ARM Versatile/PB (ARM926EJ-S)"
> +endif
> +
> +config VERSATILE_SMC91C111
> + ? ? ? bool "Use smc91c111 instead of smc91x (for QEMU)"
> + ? ? ? help
> + ? ? ? ?Enable this option to run barebox inside qemu.
> + ? ? ? ?Real versatile boards are equipped with smc911x,
> + ? ? ? ?but qemu only provides smc91c111, which is a bit different.
> +
> diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
> new file mode 100644
> index 0000000..a17aed3
> --- /dev/null
> +++ b/arch/arm/boards/versatile/Makefile
> @@ -0,0 +1,2 @@
> +
> +obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
> diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
> new file mode 100644
> index 0000000..25bb18f
> --- /dev/null
> +++ b/arch/arm/boards/versatile/config.h
> @@ -0,0 +1,5 @@
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#endif /* __CONFIG_H */
> diff --git a/arch/arm/boards/versatile/env/bin/init b/arch/arm/boards/versatile/env/bin/init
> new file mode 100644
> index 0000000..224a6b4
> --- /dev/null
> +++ b/arch/arm/boards/versatile/env/bin/init
> @@ -0,0 +1 @@
> +# Dummy Init environment script
> diff --git a/arch/arm/boards/versatile/versatilepb.c b/arch/arm/boards/versatile/versatilepb.c
> new file mode 100644
> index 0000000..57e4991
> --- /dev/null
> +++ b/arch/arm/boards/versatile/versatilepb.c
> @@ -0,0 +1,56 @@
> +/*
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <asm/armlinux.h>
> +#include <generated/mach-types.h>
> +#include <mach/init.h>
> +#include <mach/platform.h>
> +
> +static int vpb_console_init(void)
> +{
> + ? ? ? versatile_register_uart(0);
> + ? ? ? return 0;
> +}
> +
> +console_initcall(vpb_console_init);
> +
> +static struct device_d smc911x_dev = {
> + ? ? ? .id ? ? ? ? ? ? = -1,
> +#ifdef CONFIG_VERSATILE_SMC91C111
> + ? ? ? .name ? ? ? ? ? = "smc91c111",
> +#else
> + ? ? ? .name ? ? ? ? ? = "smc911x",
> +#endif
> + ? ? ? .map_base ? ? ? = VERSATILE_ETH_BASE,
> + ? ? ? .size ? ? ? ? ? = 64 * 1024
> +};
> +
> +static int vpb_devices_init(void)
> +{
> + ? ? ? versatile_add_sdram(64 * 1024 *1024);
> +
> + ? ? ? register_device(&smc911x_dev);
> +
> + ? ? ? armlinux_set_architecture(MACH_TYPE_VERSATILE_PB);
> + ? ? ? armlinux_set_bootparams((void *)(0x00000100));
> +
> + ? ? ? return 0;
> +}
> +device_initcall(vpb_devices_init);
> diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig
> new file mode 100644
> index 0000000..f505ac6
> --- /dev/null
> +++ b/arch/arm/configs/versatilepb_defconfig
> @@ -0,0 +1,12 @@
> +
> +CONFIG_ARCH_VERSATILE=y
> +CONFIG_MACH_VERSATILEPB=y
> +
> +CONFIG_TEXT_BASE=0x500000
> +CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
> +CONFIG_MEMORY_LAYOUT_DEFAULT=y
> +CONFIG_PROMPT="versatilepb> "
> +CONFIG_DEFAULT_ENVIRONMENT=y
> +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/versatile/env"
> +CONFIG_SERIAL_AMBA_PL011=y
> +CONFIG_DRIVER_NET_SMC911X=y
> diff --git a/arch/arm/include/asm/arm_timer.h b/arch/arm/include/asm/arm_timer.h
> new file mode 100644
> index 0000000..0433279
> --- /dev/null
> +++ b/arch/arm/include/asm/arm_timer.h
> @@ -0,0 +1,33 @@
> +#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
> +#define __ASM_ARM_HARDWARE_ARM_TIMER_H
> +
> +/*
> + * From Linux v2.6.35
> + * arch/arm/include/asm/hardware/arm_timer.h
> + *
> + * ARM timer implementation, found in Integrator, Versatile and Realview
> + * platforms. ?Not all platforms support all registers and bits in these
> + * registers, so we mark them with A for Integrator AP, C for Integrator
> + * CP, V for Versatile and R for Realview.
> + *
> + * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
> + * can have 16-bit or 32-bit selectable via a bit in the control register.
> + */
> +#define TIMER_LOAD ? ? 0x00 ? ? ? ? ? ? ? ? ? ?/* ACVR rw */
> +#define TIMER_VALUE ? ?0x04 ? ? ? ? ? ? ? ? ? ?/* ACVR ro */
> +#define TIMER_CTRL ? ? 0x08 ? ? ? ? ? ? ? ? ? ?/* ACVR rw */
> +#define TIMER_CTRL_ONESHOT ? ? (1 << 0) ? ? ? ?/* ?CVR */
> +#define TIMER_CTRL_32BIT ? ? ? (1 << 1) ? ? ? ?/* ?CVR */
> +#define TIMER_CTRL_DIV1 ? ? ? ? ? ? ? ?(0 << 2) ? ? ? ?/* ACVR */
> +#define TIMER_CTRL_DIV16 ? ? ? (1 << 2) ? ? ? ?/* ACVR */
> +#define TIMER_CTRL_DIV256 ? ? ?(2 << 2) ? ? ? ?/* ACVR */
> +#define TIMER_CTRL_IE ? ? ? ? ?(1 << 5) ? ? ? ?/* ? VR */
> +#define TIMER_CTRL_PERIODIC ? ?(1 << 6) ? ? ? ?/* ACVR */
> +#define TIMER_CTRL_ENABLE ? ? ?(1 << 7) ? ? ? ?/* ACVR */
> +
> +#define TIMER_INTCLR ? 0x0c ? ? ? ? ? ? ? ? ? ?/* ACVR wo */
> +#define TIMER_RIS ? ? ?0x10 ? ? ? ? ? ? ? ? ? ?/* ?CVR ro */
> +#define TIMER_MIS ? ? ?0x14 ? ? ? ? ? ? ? ? ? ?/* ?CVR ro */
> +#define TIMER_BGLOAD ? 0x18 ? ? ? ? ? ? ? ? ? ?/* ?CVR rw */
> +
> +#endif
> diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
> new file mode 100644
> index 0000000..9a1bf95
> --- /dev/null
> +++ b/arch/arm/mach-versatile/Kconfig
> @@ -0,0 +1,16 @@
> +
> +if ARCH_VERSATILE
> +
> +choice
> + ? ? ? prompt "ARM Board type"
> +
> +config MACH_VERSATILEPB
> + ? ? ? bool "ARM Versatile/PB (ARM926EJ-S)"
> + ? ? ? select ARM_AMBA
> + ? ? ? select CLKDEV_LOOKUP
> +
> +endchoice
> +
> +source arch/arm/boards/versatile/Kconfig
> +
> +endif
> diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
> new file mode 100644
> index 0000000..a8da54c
> --- /dev/null
> +++ b/arch/arm/mach-versatile/Makefile
> @@ -0,0 +1,2 @@
> +
> +obj-y += core.o
> diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
> new file mode 100644
> index 0000000..94543c6
> --- /dev/null
> +++ b/arch/arm/mach-versatile/core.c
> @@ -0,0 +1,212 @@
> +/*
> + * Copyright (C) 2010 B Labs Ltd,
> + * http://l4dev.org
> + * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
> + *
> + * Based on mach-nomadik
> + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; version 2 of
> + * the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <clock.h>
> +#include <debug_ll.h>
> +
> +#include <linux/clkdev.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +
> +#include <asm/io.h>
> +#include <asm/arm_timer.h>
> +#include <asm/armlinux.h>
> +
> +#include <mach/platform.h>
> +#include <mach/init.h>
> +
> +static struct memory_platform_data ram_pdata = {
> + ? ? ? .name = "ram0",
> + ? ? ? .flags = DEVFS_RDWR,
> +};
> +
> +static struct device_d sdram_dev = {
> + ? ? ? .id = -1,
> + ? ? ? .name = "mem",
> + ? ? ? .map_base = 0x00000000,
> + ? ? ? .platform_data = &ram_pdata,
> +};
> +
> +void versatile_add_sdram(u32 size)
> +{
> + ? ? ? sdram_dev.size = size;
> + ? ? ? register_device(&sdram_dev);
> + ? ? ? armlinux_add_dram(&sdram_dev);
> +}
> +
> +static struct device_d uart0_serial_device = {
> + ? ? ? .id = 0,
> + ? ? ? .name = "uart-pl011",
> + ? ? ? .map_base = VERSATILE_UART0_BASE,
> + ? ? ? .size = 4096,
> +};
> +
> +static struct device_d uart1_serial_device = {
> + ? ? ? .id = 1,
> + ? ? ? .name = "uart-pl011",
> + ? ? ? .map_base = VERSATILE_UART1_BASE,
> + ? ? ? .size = 4096,
> +};
> +
> +static struct device_d uart2_serial_device = {
> + ? ? ? .id = 2,
> + ? ? ? .name = "uart-pl011",
> + ? ? ? .map_base = VERSATILE_UART2_BASE,
> + ? ? ? .size = 4096,
> +};
> +static struct device_d uart3_serial_device = {
> + ? ? ? .id = 3,
> + ? ? ? .name = "uart-pl011",
> + ? ? ? .map_base = VERSATILE_UART3_BASE,
> + ? ? ? .size = 4096,
> +};
> +
> +struct clk {
> + ? ? ? unsigned long rate;
> +};
> +
> +static struct clk ref_clk_24 = {
> + ? ? ? .rate = 24000000,
> +};
> +
> +unsigned long clk_get_rate(struct clk *clk)
> +{
> + ? ? ? return clk->rate;
> +}
> +EXPORT_SYMBOL(clk_get_rate);
> +
> +/* enable and disable do nothing */
> +int clk_enable(struct clk *clk)
> +{
> + ? ? ? return 0;
> +}
> +EXPORT_SYMBOL(clk_enable);
> +
> +void clk_disable(struct clk *clk)
> +{
> +}
> +EXPORT_SYMBOL(clk_disable);
> +
> +/* Create a clock structure with the given name */
> +int vpb_clk_create(struct clk *clk, const char *dev_id)
> +{
> + ? ? ? struct clk_lookup *clkdev;
> +
> + ? ? ? clkdev = clkdev_alloc(clk, NULL, dev_id);
> + ? ? ? if (!clkdev)
> + ? ? ? ? ? ? ? return -ENOMEM;
> +
> + ? ? ? clkdev_add(clkdev);
> + ? ? ? return 0;
> +}
> +
> +/* 1Mhz / 256 */
> +#define TIMER_FREQ (1000000/256)
> +
> +#define TIMER0_BASE (VERSATILE_TIMER0_1_BASE)
> +#define TIMER1_BASE ((VERSATILE_TIMER0_1_BASE) + 0x20)
> +#define TIMER2_BASE (VERSATILE_TIMER2_3_BASE)
> +#define TIMER3_BASE ((VERSATILE_TIMER2_3_BASE) + 0x20)
> +
> +static uint64_t vpb_clocksource_read(void)
> +{
> + ? ? ? return ~readl(TIMER0_BASE + TIMER_VALUE);
> +}
> +
> +static struct clocksource vpb_cs = {
> + ? ? ? .read = vpb_clocksource_read,
> + ? ? ? .mask = 0xffffffff,
> + ? ? ? .shift = 10,
> +};
> +
> +/* From Linux v2.6.35
> + * arch/arm/mach-versatile/core.c */
> +static void versatile_timer_init (void)
> +{
> + ? ? ? u32 val;
> +
> + ? ? ? /*
> + ? ? ? ?* set clock frequency:
> + ? ? ? ?* ? ? ?VERSATILE_REFCLK is 32KHz
> + ? ? ? ?* ? ? ?VERSATILE_TIMCLK is 1MHz
> + ? ? ? ?*/
> +
> + ? ? ? val = readl(VERSATILE_SCTL_BASE);
> + ? ? ? val |= (VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel);
> + ? ? ? writel(val, VERSATILE_SCTL_BASE);
> +
> + ? ? ? /*
> + ? ? ? ?* Disable all timers, just to be sure.
> + ? ? ? ?*/
> +
> + ? ? ? writel(0, TIMER0_BASE + TIMER_CTRL);
> + ? ? ? writel(0, TIMER1_BASE + TIMER_CTRL);
> + ? ? ? writel(0, TIMER2_BASE + TIMER_CTRL);
> + ? ? ? writel(0, TIMER3_BASE + TIMER_CTRL);
> +
> + ? ? ? ?writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_DIV256,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TIMER0_BASE + TIMER_CTRL);
> +}
> +
> +static int vpb_clocksource_init(void)
> +{
> + ? ? ? versatile_timer_init();
> + ? ? ? vpb_cs.mult = clocksource_hz2mult(TIMER_FREQ, vpb_cs.shift);
> +
> + ? ? ? return init_clock(&vpb_cs);
> +}
> +
> +core_initcall(vpb_clocksource_init);
> +
> +void versatile_register_uart(unsigned id)
> +{
> + ? ? ? switch (id) {
> + ? ? ? case 0:
> + ? ? ? ? ? ? ? vpb_clk_create(&ref_clk_24, dev_name(&uart0_serial_device));
> + ? ? ? ? ? ? ? register_device(&uart0_serial_device);
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 1:
> + ? ? ? ? ? ? ? vpb_clk_create(&ref_clk_24, dev_name(&uart1_serial_device));
> + ? ? ? ? ? ? ? register_device(&uart1_serial_device);
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 2:
> + ? ? ? ? ? ? ? vpb_clk_create(&ref_clk_24, dev_name(&uart2_serial_device));
> + ? ? ? ? ? ? ? register_device(&uart2_serial_device);
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 3:
> + ? ? ? ? ? ? ? vpb_clk_create(&ref_clk_24, dev_name(&uart3_serial_device));
> + ? ? ? ? ? ? ? register_device(&uart3_serial_device);
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> +}
> +
> +void __noreturn reset_cpu (unsigned long ignored)
> +{
> + ? ? ? while (1);
> +}
> +EXPORT_SYMBOL(reset_cpu);
> +
> diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
> new file mode 100644
> index 0000000..04b37a8
> --- /dev/null
> +++ b/arch/arm/mach-versatile/include/mach/clkdev.h
> @@ -0,0 +1,7 @@
> +#ifndef __ASM_MACH_CLKDEV_H
> +#define __ASM_MACH_CLKDEV_H
> +
> +#define __clk_get(clk) ({ 1; })
> +#define __clk_put(clk) do { } while (0)
> +
> +#endif
> diff --git a/arch/arm/mach-versatile/include/mach/debug_ll.h b/arch/arm/mach-versatile/include/mach/debug_ll.h
> new file mode 100644
> index 0000000..514fcfb
> --- /dev/null
> +++ b/arch/arm/mach-versatile/include/mach/debug_ll.h
> @@ -0,0 +1,37 @@
> +/*
> + * Copyright (C) 2010 B Labs Ltd
> + * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
> + *
> + * barebox is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * barebox is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with barebox. ?If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __MACH_DEBUG_LL_H__
> +#define ? __MACH_DEBUG_LL_H__
> +
> +#include <linux/amba/serial.h>
> +#include <asm/io.h>
> +
> +static inline void putc(char c)
> +{
> + ? ? ? /* Wait until there is space in the FIFO */
> + ? ? ? while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
> +
> + ? ? ? /* Send the character */
> + ? ? ? writel(c, 0x101F1000 + UART01x_DR);
> +
> + ? ? ? /* Wait to make sure it hits the line, in case we die too soon. */
> + ? ? ? while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
> +}
> +
> +#endif
> diff --git a/arch/arm/mach-versatile/include/mach/init.h b/arch/arm/mach-versatile/include/mach/init.h
> new file mode 100644
> index 0000000..878cde0
> --- /dev/null
> +++ b/arch/arm/mach-versatile/include/mach/init.h
> @@ -0,0 +1,8 @@
> +
> +#ifndef __VERSATILE_INIT_H__
> +#define __VERSATILE_INIT_H__
> +
> +void versatile_add_sdram(u32 size);
> +void versatile_register_uart(unsigned id);
> +
> +#endif
> diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
> new file mode 100644
> index 0000000..88b8032
> --- /dev/null
> +++ b/arch/arm/mach-versatile/include/mach/platform.h
> @@ -0,0 +1,417 @@
> +/*
> + * ach-arm926ejs/include/mach/platform.h
> + *
> + * Borrowed from Linux v2.6.35
> + * arch/arm/mach-versatile/include/mach/platform.h
> + *
> + * Copyright (c) ARM Limited 2003. ?All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ?02111-1307 ?USA
> + */
> +
> +#ifndef __address_h
> +#define __address_h ? ? ? ? ? ? ? ? ? ? 1
> +
> +/*
> + * Memory definitions
> + */
> +#define VERSATILE_BOOT_ROM_LO ? ? ? ? ?0x30000000 ? ? ? ? ? ? ?/* DoC Base (64Mb)...*/
> +#define VERSATILE_BOOT_ROM_HI ? ? ? ? ?0x30000000
> +#define VERSATILE_BOOT_ROM_BASE ? ? ? ?VERSATILE_BOOT_ROM_HI ? ?/* ?Normal position */
> +#define VERSATILE_BOOT_ROM_SIZE ? ? ? ?SZ_64M
> +
> +#define VERSATILE_SSRAM_BASE ? ? ? ? ? /* VERSATILE_SSMC_BASE ? */
> +#define VERSATILE_SSRAM_SIZE ? ? ? ? ? SZ_2M
> +
> +#define VERSATILE_FLASH_BASE ? ? ? ? ? 0x34000000
> +#define VERSATILE_FLASH_SIZE ? ? ? ? ? SZ_64M
> +
> +/*
> + * ?SDRAM
> + */
> +#define VERSATILE_SDRAM_BASE ? ? ? ? ? 0x00000000
> +
> +/*
> + * ?Logic expansion modules
> + *
> + */
> +
> +
> +/* ------------------------------------------------------------------------
> + * ?Versatile Registers
> + * ------------------------------------------------------------------------
> + *
> + */
> +#define VERSATILE_SYS_ID_OFFSET ? ? ? ? ? ? ? 0x00
> +#define VERSATILE_SYS_SW_OFFSET ? ? ? ? ? ? ? 0x04
> +#define VERSATILE_SYS_LED_OFFSET ? ? ? ? ? ? ?0x08
> +#define VERSATILE_SYS_OSC0_OFFSET ? ? ? ? ? ? 0x0C
> +
> +#if defined(CONFIG_ARCH_VERSATILE_PB)
> +#define VERSATILE_SYS_OSC1_OFFSET ? ? ? ? ? ? 0x10
> +#define VERSATILE_SYS_OSC2_OFFSET ? ? ? ? ? ? 0x14
> +#define VERSATILE_SYS_OSC3_OFFSET ? ? ? ? ? ? 0x18
> +#define VERSATILE_SYS_OSC4_OFFSET ? ? ? ? ? ? 0x1C
> +#elif defined(CONFIG_MACH_VERSATILE_AB)
> +#define VERSATILE_SYS_OSC1_OFFSET ? ? ? ? ? ? 0x1C
> +#endif
> +
> +#define VERSATILE_SYS_OSCCLCD_OFFSET ? ? ? ? ?0x1c
> +
> +#define VERSATILE_SYS_LOCK_OFFSET ? ? ? ? ? ? 0x20
> +#define VERSATILE_SYS_100HZ_OFFSET ? ? ? ? ? ?0x24
> +#define VERSATILE_SYS_CFGDATA1_OFFSET ? ? ? ? 0x28
> +#define VERSATILE_SYS_CFGDATA2_OFFSET ? ? ? ? 0x2C
> +#define VERSATILE_SYS_FLAGS_OFFSET ? ? ? ? ? ?0x30
> +#define VERSATILE_SYS_FLAGSSET_OFFSET ? ? ? ? 0x30
> +#define VERSATILE_SYS_FLAGSCLR_OFFSET ? ? ? ? 0x34
> +#define VERSATILE_SYS_NVFLAGS_OFFSET ? ? ? ? ?0x38
> +#define VERSATILE_SYS_NVFLAGSSET_OFFSET ? ? ? 0x38
> +#define VERSATILE_SYS_NVFLAGSCLR_OFFSET ? ? ? 0x3C
> +#define VERSATILE_SYS_RESETCTL_OFFSET ? ? ? ? 0x40
> +#define VERSATILE_SYS_PCICTL_OFFSET ? ? ? ? ? 0x44
> +#define VERSATILE_SYS_MCI_OFFSET ? ? ? ? ? ? ?0x48
> +#define VERSATILE_SYS_FLASH_OFFSET ? ? ? ? ? ?0x4C
> +#define VERSATILE_SYS_CLCD_OFFSET ? ? ? ? ? ? 0x50
> +#define VERSATILE_SYS_CLCDSER_OFFSET ? ? ? ? ?0x54
> +#define VERSATILE_SYS_BOOTCS_OFFSET ? ? ? ? ? 0x58
> +#define VERSATILE_SYS_24MHz_OFFSET ? ? ? ? ? ?0x5C
> +#define VERSATILE_SYS_MISC_OFFSET ? ? ? ? ? ? 0x60
> +#define VERSATILE_SYS_TEST_OSC0_OFFSET ? ? ? ?0x80
> +#define VERSATILE_SYS_TEST_OSC1_OFFSET ? ? ? ?0x84
> +#define VERSATILE_SYS_TEST_OSC2_OFFSET ? ? ? ?0x88
> +#define VERSATILE_SYS_TEST_OSC3_OFFSET ? ? ? ?0x8C
> +#define VERSATILE_SYS_TEST_OSC4_OFFSET ? ? ? ?0x90
> +
> +#define VERSATILE_SYS_BASE ? ? ? ? ? ? ? ? ? ?0x10000000
> +#define VERSATILE_SYS_ID ? ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_ID_OFFSET)
> +#define VERSATILE_SYS_SW ? ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_SW_OFFSET)
> +#define VERSATILE_SYS_LED ? ? ? ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET)
> +#define VERSATILE_SYS_OSC0 ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET)
> +#define VERSATILE_SYS_OSC1 ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET)
> +
> +#if defined(CONFIG_ARCH_VERSATILE_PB)
> +#define VERSATILE_SYS_OSC2 ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET)
> +#define VERSATILE_SYS_OSC3 ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET)
> +#define VERSATILE_SYS_OSC4 ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET)
> +#endif
> +
> +#define VERSATILE_SYS_LOCK ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET)
> +#define VERSATILE_SYS_100HZ ? ? ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET)
> +#define VERSATILE_SYS_CFGDATA1 ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET)
> +#define VERSATILE_SYS_CFGDATA2 ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA2_OFFSET)
> +#define VERSATILE_SYS_FLAGS ? ? ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGS_OFFSET)
> +#define VERSATILE_SYS_FLAGSSET ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSSET_OFFSET)
> +#define VERSATILE_SYS_FLAGSCLR ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSCLR_OFFSET)
> +#define VERSATILE_SYS_NVFLAGS ? ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGS_OFFSET)
> +#define VERSATILE_SYS_NVFLAGSSET ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
> +#define VERSATILE_SYS_NVFLAGSCLR ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
> +#define VERSATILE_SYS_RESETCTL ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
> +#define VERSATILE_SYS_PCICTL ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
> +#define VERSATILE_SYS_MCI ? ? ? ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
> +#define VERSATILE_SYS_FLASH ? ? ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
> +#define VERSATILE_SYS_CLCD ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
> +#define VERSATILE_SYS_CLCDSER ? ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCDSER_OFFSET)
> +#define VERSATILE_SYS_BOOTCS ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_BOOTCS_OFFSET)
> +#define VERSATILE_SYS_24MHz ? ? ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_24MHz_OFFSET)
> +#define VERSATILE_SYS_MISC ? ? ? ? ? ? ? ? ? ?(VERSATILE_SYS_BASE + VERSATILE_SYS_MISC_OFFSET)
> +#define VERSATILE_SYS_TEST_OSC0 ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC0_OFFSET)
> +#define VERSATILE_SYS_TEST_OSC1 ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC1_OFFSET)
> +#define VERSATILE_SYS_TEST_OSC2 ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC2_OFFSET)
> +#define VERSATILE_SYS_TEST_OSC3 ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC3_OFFSET)
> +#define VERSATILE_SYS_TEST_OSC4 ? ? ? ? ? ? ? (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC4_OFFSET)
> +
> +/*
> + * Values for VERSATILE_SYS_RESET_CTRL
> + */
> +#define VERSATILE_SYS_CTRL_RESET_CONFIGCLR ? ?0x01
> +#define VERSATILE_SYS_CTRL_RESET_CONFIGINIT ? 0x02
> +#define VERSATILE_SYS_CTRL_RESET_DLLRESET ? ? 0x03
> +#define VERSATILE_SYS_CTRL_RESET_PLLRESET ? ? 0x04
> +#define VERSATILE_SYS_CTRL_RESET_POR ? ? ? ? ?0x05
> +#define VERSATILE_SYS_CTRL_RESET_DoC ? ? ? ? ?0x06
> +
> +#define VERSATILE_SYS_CTRL_LED ? ? ? ? (1 << 0)
> +
> +
> +/* ------------------------------------------------------------------------
> + * ?Versatile control registers
> + * ------------------------------------------------------------------------
> + */
> +
> +/*
> + * VERSATILE_IDFIELD
> + *
> + * 31:24 = manufacturer (0x41 = ARM)
> + * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
> + * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
> + * 11:4 ?= build value
> + * 3:0 ? = revision number (0x1 = rev B (AHB))
> + */
> +
> +/*
> + * VERSATILE_SYS_LOCK
> + * ? ? control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL,
> + * ? ? SYS_CLD, SYS_BOOTCS
> + */
> +#define VERSATILE_SYS_LOCK_LOCKED ? ?(1 << 16)
> +#define VERSATILE_SYS_LOCKVAL_MASK ? ? 0xFFFF ? ? ? ? ?/* write 0xA05F to enable write access */
> +
> +/*
> + * VERSATILE_SYS_FLASH
> + */
> +#define VERSATILE_FLASHPROG_FLVPPEN ? ?(1 << 0) ? ? ? ?/* Enable writing to flash */
> +
> +/*
> + * VERSATILE_INTREG
> + * ? ? - used to acknowledge and control MMCI and UART interrupts
> + */
> +#define VERSATILE_INTREG_WPROT ? ? ? ?0x00 ? ?/* MMC protection status (no interrupt generated) */
> +#define VERSATILE_INTREG_RI0 ? ? ? ? ?0x01 ? ?/* Ring indicator UART0 is asserted, ? ? ? ? ? ? ?*/
> +#define VERSATILE_INTREG_CARDIN ? ? ? 0x08 ? ?/* MMCI card in detect ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* write 1 to acknowledge and clear ? ? ? ? ? ? ? */
> +#define VERSATILE_INTREG_RI1 ? ? ? ? ?0x02 ? ?/* Ring indicator UART1 is asserted, ? ? ? ? ? ? ?*/
> +#define VERSATILE_INTREG_CARDINSERT ? 0x03 ? ?/* Signal insertion of MMC card ? ? ? ? ? ? ? ? ? */
> +
> +/*
> + * VERSATILE peripheral addresses
> + */
> +#define VERSATILE_PCI_CORE_BASE ? ? ? ?0x10001000 ? ? ?/* PCI core control */
> +#define VERSATILE_I2C_BASE ? ? ? ? ? ? 0x10002000 ? ? ?/* I2C control */
> +#define VERSATILE_SIC_BASE ? ? ? ? ? ? 0x10003000 ? ? ?/* Secondary interrupt controller */
> +#define VERSATILE_AACI_BASE ? ? ? ? ? ?0x10004000 ? ? ?/* Audio */
> +#define VERSATILE_MMCI0_BASE ? ? ? ? ? 0x10005000 ? ? ?/* MMC interface */
> +#define VERSATILE_KMI0_BASE ? ? ? ? ? ?0x10006000 ? ? ?/* KMI interface */
> +#define VERSATILE_KMI1_BASE ? ? ? ? ? ?0x10007000 ? ? ?/* KMI 2nd interface */
> +#define VERSATILE_CHAR_LCD_BASE ? ? ? ?0x10008000 ? ? ?/* Character LCD */
> +#define VERSATILE_UART3_BASE ? ? ? ? ? 0x10009000 ? ? ?/* UART 3 */
> +#define VERSATILE_SCI1_BASE ? ? ? ? ? ?0x1000A000
> +#define VERSATILE_MMCI1_BASE ? ? ? ? ? 0x1000B000 ? ?/* MMC Interface */
> + ? ? ? /* 0x1000C000 - 0x1000CFFF = reserved */
> +#define VERSATILE_ETH_BASE ? ? ? ? ? ? 0x10010000 ? ? ?/* Ethernet */
> +#define VERSATILE_USB_BASE ? ? ? ? ? ? 0x10020000 ? ? ?/* USB */
> + ? ? ? /* 0x10030000 - 0x100FFFFF = reserved */
> +#define VERSATILE_SMC_BASE ? ? ? ? ? ? 0x10100000 ? ? ?/* SMC */
> +#define VERSATILE_MPMC_BASE ? ? ? ? ? ?0x10110000 ? ? ?/* MPMC */
> +#define VERSATILE_CLCD_BASE ? ? ? ? ? ?0x10120000 ? ? ?/* CLCD */
> +#define VERSATILE_DMAC_BASE ? ? ? ? ? ?0x10130000 ? ? ?/* DMA controller */
> +#define VERSATILE_VIC_BASE ? ? ? ? ? ? 0x10140000 ? ? ?/* Vectored interrupt controller */
> +#define VERSATILE_PERIPH_BASE ? ? ? ? ?0x10150000 ? ? ?/* off-chip peripherals alias from */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 0x10000000 - 0x100FFFFF */
> +#define VERSATILE_AHBM_BASE ? ? ? ? ? ?0x101D0000 ? ? ?/* AHB monitor */
> +#define VERSATILE_SCTL_BASE ? ? ? ? ? ?0x101E0000 ? ? ?/* System controller */
> +#define VERSATILE_WATCHDOG_BASE ? ? ? ?0x101E1000 ? ? ?/* Watchdog */
> +#define VERSATILE_TIMER0_1_BASE ? ? ? ?0x101E2000 ? ? ?/* Timer 0 and 1 */
> +#define VERSATILE_TIMER2_3_BASE ? ? ? ?0x101E3000 ? ? ?/* Timer 2 and 3 */
> +#define VERSATILE_GPIO0_BASE ? ? ? ? ? 0x101E4000 ? ? ?/* GPIO port 0 */
> +#define VERSATILE_GPIO1_BASE ? ? ? ? ? 0x101E5000 ? ? ?/* GPIO port 1 */
> +#define VERSATILE_GPIO2_BASE ? ? ? ? ? 0x101E6000 ? ? ?/* GPIO port 2 */
> +#define VERSATILE_GPIO3_BASE ? ? ? ? ? 0x101E7000 ? ? ?/* GPIO port 3 */
> +#define VERSATILE_RTC_BASE ? ? ? ? ? ? 0x101E8000 ? ? ?/* Real Time Clock */
> + ? ? ? /* 0x101E9000 - reserved */
> +#define VERSATILE_SCI_BASE ? ? ? ? ? ? 0x101F0000 ? ? ?/* Smart card controller */
> +#define VERSATILE_UART0_BASE ? ? ? ? ? 0x101F1000 ? ? ?/* Uart 0 */
> +#define VERSATILE_UART1_BASE ? ? ? ? ? 0x101F2000 ? ? ?/* Uart 1 */
> +#define VERSATILE_UART2_BASE ? ? ? ? ? 0x101F3000 ? ? ?/* Uart 2 */
> +#define VERSATILE_SSP_BASE ? ? ? ? ? ? 0x101F4000 ? ? ?/* Synchronous Serial Port */
> +
> +#define VERSATILE_SSMC_BASE ? ? ? ? ? ?0x20000000 ? ? ?/* SSMC */
> +#define VERSATILE_IB2_BASE ? ? ? ? ? ? 0x24000000 ? ? ?/* IB2 module */
> +#define VERSATILE_MBX_BASE ? ? ? ? ? ? 0x40000000 ? ? ?/* MBX */
> +
> +/* PCI space */
> +#define VERSATILE_PCI_BASE ? ? ? ? ? ? 0x41000000 ? ? ?/* PCI Interface */
> +#define VERSATILE_PCI_CFG_BASE ? ? ? ?0x42000000
> +#define VERSATILE_PCI_MEM_BASE0 ? ? ? ?0x44000000
> +#define VERSATILE_PCI_MEM_BASE1 ? ? ? ?0x50000000
> +#define VERSATILE_PCI_MEM_BASE2 ? ? ? ?0x60000000
> +/* Sizes of above maps */
> +#define VERSATILE_PCI_BASE_SIZE ? ? ? ? ? ? ? 0x01000000
> +#define VERSATILE_PCI_CFG_BASE_SIZE ? ?0x02000000
> +#define VERSATILE_PCI_MEM_BASE0_SIZE ? 0x0c000000 ? ? ?/* 32Mb */
> +#define VERSATILE_PCI_MEM_BASE1_SIZE ? 0x10000000 ? ? ?/* 256Mb */
> +#define VERSATILE_PCI_MEM_BASE2_SIZE ? 0x10000000 ? ? ?/* 256Mb */
> +
> +#define VERSATILE_SDRAM67_BASE ? ? ? ? 0x70000000 ? ? ?/* SDRAM banks 6 and 7 */
> +#define VERSATILE_LT_BASE ? ? ? ? ? ? ?0x80000000 ? ? ?/* Logic Tile expansion */
> +
> +/*
> + * Disk on Chip
> + */
> +#define VERSATILE_DOC_BASE ? ? ? ? ? ? 0x2C000000
> +#define VERSATILE_DOC_SIZE ? ? ? ? ? ? (16 << 20)
> +#define VERSATILE_DOC_PAGE_SIZE ? ? ? ?512
> +#define VERSATILE_DOC_TOTAL_PAGES ? ? (DOC_SIZE / PAGE_SIZE)
> +
> +#define ERASE_UNIT_PAGES ? ?32
> +#define START_PAGE ? ? ? ? ?0x80
> +
> +/*
> + * ?LED settings, bits [7:0]
> + */
> +#define VERSATILE_SYS_LED0 ? ? ? ? ? ? (1 << 0)
> +#define VERSATILE_SYS_LED1 ? ? ? ? ? ? (1 << 1)
> +#define VERSATILE_SYS_LED2 ? ? ? ? ? ? (1 << 2)
> +#define VERSATILE_SYS_LED3 ? ? ? ? ? ? (1 << 3)
> +#define VERSATILE_SYS_LED4 ? ? ? ? ? ? (1 << 4)
> +#define VERSATILE_SYS_LED5 ? ? ? ? ? ? (1 << 5)
> +#define VERSATILE_SYS_LED6 ? ? ? ? ? ? (1 << 6)
> +#define VERSATILE_SYS_LED7 ? ? ? ? ? ? (1 << 7)
> +
> +#define ALL_LEDS ? ? ? ? ? ? ? ? ?0xFF
> +
> +#define LED_BANK ? ? ? ? ? ? ? ? ?VERSATILE_SYS_LED
> +
> +/*
> + * Control registers
> + */
> +#define VERSATILE_IDFIELD_OFFSET ? ? ? 0x0 ? ? /* Versatile build information */
> +#define VERSATILE_FLASHPROG_OFFSET ? ? 0x4 ? ? /* Flash devices */
> +#define VERSATILE_INTREG_OFFSET ? ? ? ? ? ? ? ?0x8 ? ? /* Interrupt control */
> +#define VERSATILE_DECODE_OFFSET ? ? ? ? ? ? ? ?0xC ? ? /* Fitted logic modules */
> +
> +
> +/* ------------------------------------------------------------------------
> + * ?Versatile Interrupt Controller - control registers
> + * ------------------------------------------------------------------------
> + *
> + * ?Offsets from interrupt controller base
> + *
> + * ?System Controller interrupt controller base is
> + *
> + * ? ? VERSATILE_IC_BASE
> + *
> + * ?Core Module interrupt controller base is
> + *
> + * ? ? VERSATILE_SYS_IC
> + *
> + */
> +/* VIC definitions in include/asm-arm/hardware/vic.h */
> +
> +#define SIC_IRQ_STATUS ? ? ? ? ? ? ? ? ?0
> +#define SIC_IRQ_RAW_STATUS ? ? ? ? ? ? ?0x04
> +#define SIC_IRQ_ENABLE ? ? ? ? ? ? ? ? ?0x08
> +#define SIC_IRQ_ENABLE_SET ? ? ? ? ? ? ?0x08
> +#define SIC_IRQ_ENABLE_CLEAR ? ? ? ? ? ?0x0C
> +#define SIC_INT_SOFT_SET ? ? ? ? ? ? ? ?0x10
> +#define SIC_INT_SOFT_CLEAR ? ? ? ? ? ? ?0x14
> +#define SIC_INT_PIC_ENABLE ? ? ? ? ? ? ?0x20 ? /* read status of pass through mask */
> +#define SIC_INT_PIC_ENABLES ? ? ? ? ? ? 0x20 ? /* set interrupt pass through bits */
> +#define SIC_INT_PIC_ENABLEC ? ? ? ? ? ? 0x24 ? /* Clear interrupt pass through bits */
> +
> +/* ------------------------------------------------------------------------
> + * ?Interrupts - bit assignment (primary)
> + * ------------------------------------------------------------------------
> + */
> +
> +#define INT_WDOGINT ? ? ? ? ? ? ? ? ? ? 0 ? ? ?/* Watchdog timer */
> +#define INT_SOFTINT ? ? ? ? ? ? ? ? ? ? 1 ? ? ?/* Software interrupt */
> +#define INT_COMMRx ? ? ? ? ? ? ? ? ? ? ?2 ? ? ?/* Debug Comm Rx interrupt */
> +#define INT_COMMTx ? ? ? ? ? ? ? ? ? ? ?3 ? ? ?/* Debug Comm Tx interrupt */
> +#define INT_TIMERINT0_1 ? ? ? ? ? ? ? ? 4 ? ? ?/* Timer 0 and 1 */
> +#define INT_TIMERINT2_3 ? ? ? ? ? ? ? ? 5 ? ? ?/* Timer 2 and 3 */
> +#define INT_GPIOINT0 ? ? ? ? ? ? ? ? ? ?6 ? ? ?/* GPIO 0 */
> +#define INT_GPIOINT1 ? ? ? ? ? ? ? ? ? ?7 ? ? ?/* GPIO 1 */
> +#define INT_GPIOINT2 ? ? ? ? ? ? ? ? ? ?8 ? ? ?/* GPIO 2 */
> +#define INT_GPIOINT3 ? ? ? ? ? ? ? ? ? ?9 ? ? ?/* GPIO 3 */
> +#define INT_RTCINT ? ? ? ? ? ? ? ? ? ? ?10 ? ? /* Real Time Clock */
> +#define INT_SSPINT ? ? ? ? ? ? ? ? ? ? ?11 ? ? /* Synchronous Serial Port */
> +#define INT_UARTINT0 ? ? ? ? ? ? ? ? ? ?12 ? ? /* UART 0 on development chip */
> +#define INT_UARTINT1 ? ? ? ? ? ? ? ? ? ?13 ? ? /* UART 1 on development chip */
> +#define INT_UARTINT2 ? ? ? ? ? ? ? ? ? ?14 ? ? /* UART 2 on development chip */
> +#define INT_SCIINT ? ? ? ? ? ? ? ? ? ? ?15 ? ? /* Smart Card Interface */
> +#define INT_CLCDINT ? ? ? ? ? ? ? ? ? ? 16 ? ? /* CLCD controller */
> +#define INT_DMAINT ? ? ? ? ? ? ? ? ? ? ?17 ? ? /* DMA controller */
> +#define INT_PWRFAILINT ? ? ? ? ? ? ? ? ?18 ? ? /* Power failure */
> +#define INT_MBXINT ? ? ? ? ? ? ? ? ? ? ?19 ? ? /* Graphics processor */
> +#define INT_GNDINT ? ? ? ? ? ? ? ? ? ? ?20 ? ? /* Reserved */
> + ? ? ? /* External interrupt signals from logic tiles or secondary controller */
> +#define INT_VICSOURCE21 ? ? ? ? ? ? ? ? 21 ? ? /* Disk on Chip */
> +#define INT_VICSOURCE22 ? ? ? ? ? ? ? ? 22 ? ? /* MCI0A */
> +#define INT_VICSOURCE23 ? ? ? ? ? ? ? ? 23 ? ? /* MCI1A */
> +#define INT_VICSOURCE24 ? ? ? ? ? ? ? ? 24 ? ? /* AACI */
> +#define INT_VICSOURCE25 ? ? ? ? ? ? ? ? 25 ? ? /* Ethernet */
> +#define INT_VICSOURCE26 ? ? ? ? ? ? ? ? 26 ? ? /* USB */
> +#define INT_VICSOURCE27 ? ? ? ? ? ? ? ? 27 ? ? /* PCI 0 */
> +#define INT_VICSOURCE28 ? ? ? ? ? ? ? ? 28 ? ? /* PCI 1 */
> +#define INT_VICSOURCE29 ? ? ? ? ? ? ? ? 29 ? ? /* PCI 2 */
> +#define INT_VICSOURCE30 ? ? ? ? ? ? ? ? 30 ? ? /* PCI 3 */
> +#define INT_VICSOURCE31 ? ? ? ? ? ? ? ? 31 ? ? /* SIC source */
> +
> +#define VERSATILE_SC_VALID_INT ? ? ? ? ? ? ? 0x003FFFFF
> +
> +#define MAXIRQNUM ? ? ? ? ? ? ? ? ? ? ? 31
> +#define MAXFIQNUM ? ? ? ? ? ? ? ? ? ? ? 31
> +#define MAXSWINUM ? ? ? ? ? ? ? ? ? ? ? 31
> +
> +/* ------------------------------------------------------------------------
> + * ?Interrupts - bit assignment (secondary)
> + * ------------------------------------------------------------------------
> + */
> +#define SIC_INT_MMCI0B ? ? ? ? ? ? ? ? ?1 ? ? ?/* Multimedia Card 0B */
> +#define SIC_INT_MMCI1B ? ? ? ? ? ? ? ? ?2 ? ? ?/* Multimedia Card 1B */
> +#define SIC_INT_KMI0 ? ? ? ? ? ? ? ? ? ?3 ? ? ?/* Keyboard/Mouse port 0 */
> +#define SIC_INT_KMI1 ? ? ? ? ? ? ? ? ? ?4 ? ? ?/* Keyboard/Mouse port 1 */
> +#define SIC_INT_SCI3 ? ? ? ? ? ? ? ? ? ?5 ? ? ?/* Smart Card interface */
> +#define SIC_INT_UART3 ? ? ? ? ? ? ? ? ? 6 ? ? ?/* UART 3 empty or data available */
> +#define SIC_INT_CLCD ? ? ? ? ? ? ? ? ? ?7 ? ? ?/* Character LCD */
> +#define SIC_INT_TOUCH ? ? ? ? ? ? ? ? ? 8 ? ? ?/* Touchscreen */
> +#define SIC_INT_KEYPAD ? ? ? ? ? ? ? ? ?9 ? ? ?/* Key pressed on display keypad */
> + ? ? ? /* 10:20 - reserved */
> +#define SIC_INT_DoC ? ? ? ? ? ? ? ? ? ? 21 ? ? /* Disk on Chip memory controller */
> +#define SIC_INT_MMCI0A ? ? ? ? ? ? ? ? ?22 ? ? /* MMC 0A */
> +#define SIC_INT_MMCI1A ? ? ? ? ? ? ? ? ?23 ? ? /* MMC 1A */
> +#define SIC_INT_AACI ? ? ? ? ? ? ? ? ? ?24 ? ? /* Audio Codec */
> +#define SIC_INT_ETH ? ? ? ? ? ? ? ? ? ? 25 ? ? /* Ethernet controller */
> +#define SIC_INT_USB ? ? ? ? ? ? ? ? ? ? 26 ? ? /* USB controller */
> +#define SIC_INT_PCI0 ? ? ? ? ? ? ? ? ? ?27
> +#define SIC_INT_PCI1 ? ? ? ? ? ? ? ? ? ?28
> +#define SIC_INT_PCI2 ? ? ? ? ? ? ? ? ? ?29
> +#define SIC_INT_PCI3 ? ? ? ? ? ? ? ? ? ?30
> +
> +
> +/*
> + * System controller bit assignment
> + */
> +#define VERSATILE_REFCLK ? ? ? 0
> +#define VERSATILE_TIMCLK ? ? ? 1
> +
> +#define VERSATILE_TIMER1_EnSel 15
> +#define VERSATILE_TIMER2_EnSel 17
> +#define VERSATILE_TIMER3_EnSel 19
> +#define VERSATILE_TIMER4_EnSel 21
> +
> +
> +#define VERSATILE_CSR_BASE ? ? ? ? ? ? 0x10000000
> +#define VERSATILE_CSR_SIZE ? ? ? ? ? ? 0x10000000
> +
> +#ifdef CONFIG_MACH_VERSATILE_AB
> +/*
> + * IB2 Versatile/AB expansion board definitions
> + */
> +#define VERSATILE_IB2_CAMERA_BANK ? ? ?VERSATILE_IB2_BASE
> +#define VERSATILE_IB2_KBD_DATAREG ? ? ?(VERSATILE_IB2_BASE + 0x01000000)
> +
> +/* VICINTSOURCE27 */
> +#define VERSATILE_IB2_INT_BASE ? ? ? ? (VERSATILE_IB2_BASE + 0x02000000)
> +#define VERSATILE_IB2_IER ? ? ? ? ? ? ?(VERSATILE_IB2_INT_BASE + 0)
> +#define VERSATILE_IB2_ISR ? ? ? ? ? ? ?(VERSATILE_IB2_INT_BASE + 4)
> +
> +#define VERSATILE_IB2_CTL_BASE ? ? ? ? (VERSATILE_IB2_BASE + 0x03000000)
> +#define VERSATILE_IB2_CTRL ? ? ? ? ? ? (VERSATILE_IB2_CTL_BASE + 0)
> +#define VERSATILE_IB2_STAT ? ? ? ? ? ? (VERSATILE_IB2_CTL_BASE + 4)
> +#endif
> +
> +#endif
>
>


From alexey.zaytsev at gmail.com  Mon Oct 11 12:29:48 2010
From: alexey.zaytsev at gmail.com (Alexey Zaytsev)
Date: Mon, 11 Oct 2010 16:29:48 +0000
Subject: [PATCH v3] Add basic support from ARM Versatile/PB
Message-ID: <20101011162832.14102.69708.stgit@zaytsev.su>

Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
---

I hope this is the last iteration.

 arch/arm/Kconfig                                |    5 
 arch/arm/Makefile                               |    2 
 arch/arm/boards/versatile/Kconfig               |   10 +
 arch/arm/boards/versatile/Makefile              |    2 
 arch/arm/boards/versatile/config.h              |    5 
 arch/arm/boards/versatile/env/bin/init          |    1 
 arch/arm/boards/versatile/versatilepb.c         |   52 +++
 arch/arm/configs/versatilepb_defconfig          |   12 +
 arch/arm/include/asm/arm_timer.h                |   33 ++
 arch/arm/mach-versatile/Kconfig                 |   16 +
 arch/arm/mach-versatile/Makefile                |    2 
 arch/arm/mach-versatile/core.c                  |  212 ++++++++++++
 arch/arm/mach-versatile/include/mach/clkdev.h   |    7 
 arch/arm/mach-versatile/include/mach/debug_ll.h |   37 ++
 arch/arm/mach-versatile/include/mach/init.h     |    8 
 arch/arm/mach-versatile/include/mach/platform.h |  417 +++++++++++++++++++++++
 16 files changed, 821 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/versatile/Kconfig
 create mode 100644 arch/arm/boards/versatile/Makefile
 create mode 100644 arch/arm/boards/versatile/config.h
 create mode 100644 arch/arm/boards/versatile/env/bin/init
 create mode 100644 arch/arm/boards/versatile/versatilepb.c
 create mode 100644 arch/arm/configs/versatilepb_defconfig
 create mode 100644 arch/arm/include/asm/arm_timer.h
 create mode 100644 arch/arm/mach-versatile/Kconfig
 create mode 100644 arch/arm/mach-versatile/Makefile
 create mode 100644 arch/arm/mach-versatile/core.c
 create mode 100644 arch/arm/mach-versatile/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-versatile/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-versatile/include/mach/init.h
 create mode 100644 arch/arm/mach-versatile/include/mach/platform.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fa37036..1730ce8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -56,6 +56,10 @@ config ARCH_S3C24xx
 	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
 	select CPU_ARM920T
 
+config ARCH_VERSATILE
+	bool "ARM Versatile boards (ARM926EJ-S)"
+	select CPU_ARM926T
+
 endchoice
 
 source arch/arm/cpu/Kconfig
@@ -66,6 +70,7 @@ source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
 source arch/arm/mach-omap/Kconfig
 source arch/arm/mach-s3c24xx/Kconfig
+source arch/arm/mach-versatile/Kconfig
 
 config AEABI
 	bool "Use the ARM EABI to compile barebox"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77b6cf4..6ad14e7 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -45,6 +45,7 @@ machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_OMAP)		:= omap
 machine-$(CONFIG_ARCH_S3C24xx)		:= s3c24xx
+machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 
 # Board directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -80,6 +81,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
 board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
+board-$(CONFIG_MACH_VERSATILEPB)		:= versatile
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/versatile/Kconfig b/arch/arm/boards/versatile/Kconfig
new file mode 100644
index 0000000..b645f60
--- /dev/null
+++ b/arch/arm/boards/versatile/Kconfig
@@ -0,0 +1,10 @@
+
+if MACH_VERSATILEPB
+
+config ARCH_TEXT_BASE
+	hex
+	default 0
+
+config BOARDINFO
+	default "ARM Versatile/PB (ARM926EJ-S)"
+endif
diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
new file mode 100644
index 0000000..a17aed3
--- /dev/null
+++ b/arch/arm/boards/versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
new file mode 100644
index 0000000..25bb18f
--- /dev/null
+++ b/arch/arm/boards/versatile/config.h
@@ -0,0 +1,5 @@
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/versatile/env/bin/init b/arch/arm/boards/versatile/env/bin/init
new file mode 100644
index 0000000..224a6b4
--- /dev/null
+++ b/arch/arm/boards/versatile/env/bin/init
@@ -0,0 +1 @@
+# Dummy Init environment script
diff --git a/arch/arm/boards/versatile/versatilepb.c b/arch/arm/boards/versatile/versatilepb.c
new file mode 100644
index 0000000..126382c
--- /dev/null
+++ b/arch/arm/boards/versatile/versatilepb.c
@@ -0,0 +1,52 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <mach/init.h>
+#include <mach/platform.h>
+
+static int vpb_console_init(void)
+{
+	versatile_register_uart(0);
+	return 0;
+}
+
+console_initcall(vpb_console_init);
+
+static struct device_d smc911x_dev = {
+	.id		= -1,
+	.name		= "smc91c111",
+	.map_base	= VERSATILE_ETH_BASE,
+	.size		= 64 * 1024
+};
+
+static int vpb_devices_init(void)
+{
+	versatile_add_sdram(64 * 1024 *1024);
+
+	register_device(&smc911x_dev);
+
+	armlinux_set_architecture(MACH_TYPE_VERSATILE_PB);
+	armlinux_set_bootparams((void *)(0x00000100));
+
+	return 0;
+}
+device_initcall(vpb_devices_init);
diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig
new file mode 100644
index 0000000..f505ac6
--- /dev/null
+++ b/arch/arm/configs/versatilepb_defconfig
@@ -0,0 +1,12 @@
+
+CONFIG_ARCH_VERSATILE=y
+CONFIG_MACH_VERSATILEPB=y
+
+CONFIG_TEXT_BASE=0x500000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+CONFIG_PROMPT="versatilepb> "
+CONFIG_DEFAULT_ENVIRONMENT=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/versatile/env"
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_DRIVER_NET_SMC911X=y
diff --git a/arch/arm/include/asm/arm_timer.h b/arch/arm/include/asm/arm_timer.h
new file mode 100644
index 0000000..0433279
--- /dev/null
+++ b/arch/arm/include/asm/arm_timer.h
@@ -0,0 +1,33 @@
+#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
+#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+
+/*
+ * From Linux v2.6.35
+ * arch/arm/include/asm/hardware/arm_timer.h
+ *
+ * ARM timer implementation, found in Integrator, Versatile and Realview
+ * platforms.  Not all platforms support all registers and bits in these
+ * registers, so we mark them with A for Integrator AP, C for Integrator
+ * CP, V for Versatile and R for Realview.
+ *
+ * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
+ * can have 16-bit or 32-bit selectable via a bit in the control register.
+ */
+#define TIMER_LOAD	0x00			/* ACVR rw */
+#define TIMER_VALUE	0x04			/* ACVR ro */
+#define TIMER_CTRL	0x08			/* ACVR rw */
+#define TIMER_CTRL_ONESHOT	(1 << 0)	/*  CVR */
+#define TIMER_CTRL_32BIT	(1 << 1)	/*  CVR */
+#define TIMER_CTRL_DIV1		(0 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV16	(1 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV256	(2 << 2)	/* ACVR */
+#define TIMER_CTRL_IE		(1 << 5)	/*   VR */
+#define TIMER_CTRL_PERIODIC	(1 << 6)	/* ACVR */
+#define TIMER_CTRL_ENABLE	(1 << 7)	/* ACVR */
+
+#define TIMER_INTCLR	0x0c			/* ACVR wo */
+#define TIMER_RIS	0x10			/*  CVR ro */
+#define TIMER_MIS	0x14			/*  CVR ro */
+#define TIMER_BGLOAD	0x18			/*  CVR rw */
+
+#endif
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
new file mode 100644
index 0000000..9a1bf95
--- /dev/null
+++ b/arch/arm/mach-versatile/Kconfig
@@ -0,0 +1,16 @@
+
+if ARCH_VERSATILE
+
+choice
+	prompt "ARM Board type"
+
+config MACH_VERSATILEPB
+	bool "ARM Versatile/PB (ARM926EJ-S)"
+	select ARM_AMBA
+	select CLKDEV_LOOKUP
+
+endchoice
+
+source arch/arm/boards/versatile/Kconfig
+
+endif
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
new file mode 100644
index 0000000..a8da54c
--- /dev/null
+++ b/arch/arm/mach-versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-y += core.o
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
new file mode 100644
index 0000000..94543c6
--- /dev/null
+++ b/arch/arm/mach-versatile/core.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd,
+ * http://l4dev.org
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * Based on mach-nomadik
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <debug_ll.h>
+
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/arm_timer.h>
+#include <asm/armlinux.h>
+
+#include <mach/platform.h>
+#include <mach/init.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.id = -1,
+	.name = "mem",
+	.map_base = 0x00000000,
+	.platform_data = &ram_pdata,
+};
+
+void versatile_add_sdram(u32 size)
+{
+	sdram_dev.size = size;
+	register_device(&sdram_dev);
+	armlinux_add_dram(&sdram_dev);
+}
+
+static struct device_d uart0_serial_device = {
+	.id = 0,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART0_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart1_serial_device = {
+	.id = 1,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART1_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart2_serial_device = {
+	.id = 2,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART2_BASE,
+	.size = 4096,
+};
+static struct device_d uart3_serial_device = {
+	.id = 3,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART3_BASE,
+	.size = 4096,
+};
+
+struct clk {
+	unsigned long rate;
+};
+
+static struct clk ref_clk_24 = {
+	.rate = 24000000,
+};
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* enable and disable do nothing */
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Create a clock structure with the given name */
+int vpb_clk_create(struct clk *clk, const char *dev_id)
+{
+	struct clk_lookup *clkdev;
+
+	clkdev = clkdev_alloc(clk, NULL, dev_id);
+	if (!clkdev)
+		return -ENOMEM;
+
+	clkdev_add(clkdev);
+	return 0;
+}
+
+/* 1Mhz / 256 */
+#define TIMER_FREQ (1000000/256)
+
+#define TIMER0_BASE (VERSATILE_TIMER0_1_BASE)
+#define TIMER1_BASE ((VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_BASE (VERSATILE_TIMER2_3_BASE)
+#define TIMER3_BASE ((VERSATILE_TIMER2_3_BASE) + 0x20)
+
+static uint64_t vpb_clocksource_read(void)
+{
+	return ~readl(TIMER0_BASE + TIMER_VALUE);
+}
+
+static struct clocksource vpb_cs = {
+	.read = vpb_clocksource_read,
+	.mask = 0xffffffff,
+	.shift = 10,
+};
+
+/* From Linux v2.6.35
+ * arch/arm/mach-versatile/core.c */
+static void versatile_timer_init (void)
+{
+	u32 val;
+
+	/*
+	 * set clock frequency:
+	 *      VERSATILE_REFCLK is 32KHz
+	 *      VERSATILE_TIMCLK is 1MHz
+	 */
+
+	val = readl(VERSATILE_SCTL_BASE);
+	val |= (VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel);
+	writel(val, VERSATILE_SCTL_BASE);
+
+	/*
+	 * Disable all timers, just to be sure.
+	 */
+
+	writel(0, TIMER0_BASE + TIMER_CTRL);
+	writel(0, TIMER1_BASE + TIMER_CTRL);
+	writel(0, TIMER2_BASE + TIMER_CTRL);
+	writel(0, TIMER3_BASE + TIMER_CTRL);
+
+        writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_DIV256,
+			                TIMER0_BASE + TIMER_CTRL);
+}
+
+static int vpb_clocksource_init(void)
+{
+	versatile_timer_init();
+	vpb_cs.mult = clocksource_hz2mult(TIMER_FREQ, vpb_cs.shift);
+
+	return init_clock(&vpb_cs);
+}
+
+core_initcall(vpb_clocksource_init);
+
+void versatile_register_uart(unsigned id)
+{
+	switch (id) {
+	case 0:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart0_serial_device));
+		register_device(&uart0_serial_device);
+		break;
+	case 1:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart1_serial_device));
+		register_device(&uart1_serial_device);
+		break;
+	case 2:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart2_serial_device));
+		register_device(&uart2_serial_device);
+		break;
+	case 3:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart3_serial_device));
+		register_device(&uart3_serial_device);
+		break;
+	}
+}
+
+void __noreturn reset_cpu (unsigned long ignored)
+{
+	while (1);
+}
+EXPORT_SYMBOL(reset_cpu);
+
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
new file mode 100644
index 0000000..04b37a8
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/debug_ll.h b/arch/arm/mach-versatile/include/mach/debug_ll.h
new file mode 100644
index 0000000..514fcfb
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/debug_ll.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * barebox is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * barebox is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with barebox.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define   __MACH_DEBUG_LL_H__
+
+#include <linux/amba/serial.h>
+#include <asm/io.h>
+
+static inline void putc(char c)
+{
+	/* Wait until there is space in the FIFO */
+	while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+
+	/* Send the character */
+	writel(c, 0x101F1000 + UART01x_DR);
+
+	/* Wait to make sure it hits the line, in case we die too soon. */
+	while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+}
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/init.h b/arch/arm/mach-versatile/include/mach/init.h
new file mode 100644
index 0000000..878cde0
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/init.h
@@ -0,0 +1,8 @@
+
+#ifndef __VERSATILE_INIT_H__
+#define __VERSATILE_INIT_H__
+
+void versatile_add_sdram(u32 size);
+void versatile_register_uart(unsigned id);
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
new file mode 100644
index 0000000..88b8032
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/platform.h
@@ -0,0 +1,417 @@
+/*
+ * ach-arm926ejs/include/mach/platform.h
+ *
+ * Borrowed from Linux v2.6.35
+ * arch/arm/mach-versatile/include/mach/platform.h
+ *
+ * Copyright (c) ARM Limited 2003.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __address_h
+#define __address_h                     1
+
+/*
+ * Memory definitions
+ */
+#define VERSATILE_BOOT_ROM_LO          0x30000000		/* DoC Base (64Mb)...*/
+#define VERSATILE_BOOT_ROM_HI          0x30000000
+#define VERSATILE_BOOT_ROM_BASE        VERSATILE_BOOT_ROM_HI	 /*  Normal position */
+#define VERSATILE_BOOT_ROM_SIZE        SZ_64M
+
+#define VERSATILE_SSRAM_BASE           /* VERSATILE_SSMC_BASE ? */
+#define VERSATILE_SSRAM_SIZE           SZ_2M
+
+#define VERSATILE_FLASH_BASE           0x34000000
+#define VERSATILE_FLASH_SIZE           SZ_64M
+
+/* 
+ *  SDRAM
+ */
+#define VERSATILE_SDRAM_BASE           0x00000000
+
+/* 
+ *  Logic expansion modules
+ * 
+ */
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile Registers
+ * ------------------------------------------------------------------------
+ * 
+ */
+#define VERSATILE_SYS_ID_OFFSET               0x00
+#define VERSATILE_SYS_SW_OFFSET               0x04
+#define VERSATILE_SYS_LED_OFFSET              0x08
+#define VERSATILE_SYS_OSC0_OFFSET             0x0C
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC1_OFFSET             0x10
+#define VERSATILE_SYS_OSC2_OFFSET             0x14
+#define VERSATILE_SYS_OSC3_OFFSET             0x18
+#define VERSATILE_SYS_OSC4_OFFSET             0x1C
+#elif defined(CONFIG_MACH_VERSATILE_AB)
+#define VERSATILE_SYS_OSC1_OFFSET             0x1C
+#endif
+
+#define VERSATILE_SYS_OSCCLCD_OFFSET          0x1c
+
+#define VERSATILE_SYS_LOCK_OFFSET             0x20
+#define VERSATILE_SYS_100HZ_OFFSET            0x24
+#define VERSATILE_SYS_CFGDATA1_OFFSET         0x28
+#define VERSATILE_SYS_CFGDATA2_OFFSET         0x2C
+#define VERSATILE_SYS_FLAGS_OFFSET            0x30
+#define VERSATILE_SYS_FLAGSSET_OFFSET         0x30
+#define VERSATILE_SYS_FLAGSCLR_OFFSET         0x34
+#define VERSATILE_SYS_NVFLAGS_OFFSET          0x38
+#define VERSATILE_SYS_NVFLAGSSET_OFFSET       0x38
+#define VERSATILE_SYS_NVFLAGSCLR_OFFSET       0x3C
+#define VERSATILE_SYS_RESETCTL_OFFSET         0x40
+#define VERSATILE_SYS_PCICTL_OFFSET           0x44
+#define VERSATILE_SYS_MCI_OFFSET              0x48
+#define VERSATILE_SYS_FLASH_OFFSET            0x4C
+#define VERSATILE_SYS_CLCD_OFFSET             0x50
+#define VERSATILE_SYS_CLCDSER_OFFSET          0x54
+#define VERSATILE_SYS_BOOTCS_OFFSET           0x58
+#define VERSATILE_SYS_24MHz_OFFSET            0x5C
+#define VERSATILE_SYS_MISC_OFFSET             0x60
+#define VERSATILE_SYS_TEST_OSC0_OFFSET        0x80
+#define VERSATILE_SYS_TEST_OSC1_OFFSET        0x84
+#define VERSATILE_SYS_TEST_OSC2_OFFSET        0x88
+#define VERSATILE_SYS_TEST_OSC3_OFFSET        0x8C
+#define VERSATILE_SYS_TEST_OSC4_OFFSET        0x90
+
+#define VERSATILE_SYS_BASE                    0x10000000
+#define VERSATILE_SYS_ID                      (VERSATILE_SYS_BASE + VERSATILE_SYS_ID_OFFSET)
+#define VERSATILE_SYS_SW                      (VERSATILE_SYS_BASE + VERSATILE_SYS_SW_OFFSET)
+#define VERSATILE_SYS_LED                     (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET)
+#define VERSATILE_SYS_OSC0                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET)
+#define VERSATILE_SYS_OSC1                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET)
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC2                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET)
+#define VERSATILE_SYS_OSC3                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET)
+#define VERSATILE_SYS_OSC4                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET)
+#endif
+
+#define VERSATILE_SYS_LOCK                    (VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET)
+#define VERSATILE_SYS_100HZ                   (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET)
+#define VERSATILE_SYS_CFGDATA1                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET)
+#define VERSATILE_SYS_CFGDATA2                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA2_OFFSET)
+#define VERSATILE_SYS_FLAGS                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGS_OFFSET)
+#define VERSATILE_SYS_FLAGSSET                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSSET_OFFSET)
+#define VERSATILE_SYS_FLAGSCLR                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSCLR_OFFSET)
+#define VERSATILE_SYS_NVFLAGS                 (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGS_OFFSET)
+#define VERSATILE_SYS_NVFLAGSSET              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
+#define VERSATILE_SYS_NVFLAGSCLR              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
+#define VERSATILE_SYS_RESETCTL                (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
+#define VERSATILE_SYS_PCICTL                  (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
+#define VERSATILE_SYS_MCI                     (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYS_FLASH                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_SYS_CLCD                    (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
+#define VERSATILE_SYS_CLCDSER                 (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCDSER_OFFSET)
+#define VERSATILE_SYS_BOOTCS                  (VERSATILE_SYS_BASE + VERSATILE_SYS_BOOTCS_OFFSET)
+#define VERSATILE_SYS_24MHz                   (VERSATILE_SYS_BASE + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_SYS_MISC                    (VERSATILE_SYS_BASE + VERSATILE_SYS_MISC_OFFSET)
+#define VERSATILE_SYS_TEST_OSC0               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC0_OFFSET)
+#define VERSATILE_SYS_TEST_OSC1               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC1_OFFSET)
+#define VERSATILE_SYS_TEST_OSC2               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC2_OFFSET)
+#define VERSATILE_SYS_TEST_OSC3               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC3_OFFSET)
+#define VERSATILE_SYS_TEST_OSC4               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC4_OFFSET)
+
+/* 
+ * Values for VERSATILE_SYS_RESET_CTRL
+ */
+#define VERSATILE_SYS_CTRL_RESET_CONFIGCLR    0x01
+#define VERSATILE_SYS_CTRL_RESET_CONFIGINIT   0x02
+#define VERSATILE_SYS_CTRL_RESET_DLLRESET     0x03
+#define VERSATILE_SYS_CTRL_RESET_PLLRESET     0x04
+#define VERSATILE_SYS_CTRL_RESET_POR          0x05
+#define VERSATILE_SYS_CTRL_RESET_DoC          0x06
+
+#define VERSATILE_SYS_CTRL_LED         (1 << 0)
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile control registers
+ * ------------------------------------------------------------------------
+ */
+
+/* 
+ * VERSATILE_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4  = build value
+ * 3:0   = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * VERSATILE_SYS_LOCK
+ *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, 
+ *     SYS_CLD, SYS_BOOTCS
+ */
+#define VERSATILE_SYS_LOCK_LOCKED    (1 << 16)
+#define VERSATILE_SYS_LOCKVAL_MASK	0xFFFF		/* write 0xA05F to enable write access */
+
+/*
+ * VERSATILE_SYS_FLASH
+ */
+#define VERSATILE_FLASHPROG_FLVPPEN	(1 << 0)	/* Enable writing to flash */
+
+/*
+ * VERSATILE_INTREG
+ *     - used to acknowledge and control MMCI and UART interrupts 
+ */
+#define VERSATILE_INTREG_WPROT        0x00    /* MMC protection status (no interrupt generated) */
+#define VERSATILE_INTREG_RI0          0x01    /* Ring indicator UART0 is asserted,              */
+#define VERSATILE_INTREG_CARDIN       0x08    /* MMCI card in detect                            */
+                                                /* write 1 to acknowledge and clear               */
+#define VERSATILE_INTREG_RI1          0x02    /* Ring indicator UART1 is asserted,              */
+#define VERSATILE_INTREG_CARDINSERT   0x03    /* Signal insertion of MMC card                   */
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_PCI_CORE_BASE        0x10001000	/* PCI core control */
+#define VERSATILE_I2C_BASE             0x10002000	/* I2C control */
+#define VERSATILE_SIC_BASE             0x10003000	/* Secondary interrupt controller */
+#define VERSATILE_AACI_BASE            0x10004000	/* Audio */
+#define VERSATILE_MMCI0_BASE           0x10005000	/* MMC interface */
+#define VERSATILE_KMI0_BASE            0x10006000	/* KMI interface */
+#define VERSATILE_KMI1_BASE            0x10007000	/* KMI 2nd interface */
+#define VERSATILE_CHAR_LCD_BASE        0x10008000	/* Character LCD */
+#define VERSATILE_UART3_BASE           0x10009000	/* UART 3 */
+#define VERSATILE_SCI1_BASE            0x1000A000
+#define VERSATILE_MMCI1_BASE           0x1000B000    /* MMC Interface */
+	/* 0x1000C000 - 0x1000CFFF = reserved */
+#define VERSATILE_ETH_BASE             0x10010000	/* Ethernet */
+#define VERSATILE_USB_BASE             0x10020000	/* USB */
+	/* 0x10030000 - 0x100FFFFF = reserved */
+#define VERSATILE_SMC_BASE             0x10100000	/* SMC */
+#define VERSATILE_MPMC_BASE            0x10110000	/* MPMC */
+#define VERSATILE_CLCD_BASE            0x10120000	/* CLCD */
+#define VERSATILE_DMAC_BASE            0x10130000	/* DMA controller */
+#define VERSATILE_VIC_BASE             0x10140000	/* Vectored interrupt controller */
+#define VERSATILE_PERIPH_BASE          0x10150000	/* off-chip peripherals alias from */
+                                                /* 0x10000000 - 0x100FFFFF */
+#define VERSATILE_AHBM_BASE            0x101D0000	/* AHB monitor */
+#define VERSATILE_SCTL_BASE            0x101E0000	/* System controller */
+#define VERSATILE_WATCHDOG_BASE        0x101E1000	/* Watchdog */
+#define VERSATILE_TIMER0_1_BASE        0x101E2000	/* Timer 0 and 1 */
+#define VERSATILE_TIMER2_3_BASE        0x101E3000	/* Timer 2 and 3 */
+#define VERSATILE_GPIO0_BASE           0x101E4000	/* GPIO port 0 */
+#define VERSATILE_GPIO1_BASE           0x101E5000	/* GPIO port 1 */
+#define VERSATILE_GPIO2_BASE           0x101E6000	/* GPIO port 2 */
+#define VERSATILE_GPIO3_BASE           0x101E7000	/* GPIO port 3 */
+#define VERSATILE_RTC_BASE             0x101E8000	/* Real Time Clock */
+	/* 0x101E9000 - reserved */
+#define VERSATILE_SCI_BASE             0x101F0000	/* Smart card controller */
+#define VERSATILE_UART0_BASE           0x101F1000	/* Uart 0 */
+#define VERSATILE_UART1_BASE           0x101F2000	/* Uart 1 */
+#define VERSATILE_UART2_BASE           0x101F3000	/* Uart 2 */
+#define VERSATILE_SSP_BASE             0x101F4000	/* Synchronous Serial Port */
+
+#define VERSATILE_SSMC_BASE            0x20000000	/* SSMC */
+#define VERSATILE_IB2_BASE             0x24000000	/* IB2 module */
+#define VERSATILE_MBX_BASE             0x40000000	/* MBX */
+
+/* PCI space */
+#define VERSATILE_PCI_BASE             0x41000000	/* PCI Interface */
+#define VERSATILE_PCI_CFG_BASE	       0x42000000
+#define VERSATILE_PCI_MEM_BASE0        0x44000000
+#define VERSATILE_PCI_MEM_BASE1        0x50000000
+#define VERSATILE_PCI_MEM_BASE2        0x60000000
+/* Sizes of above maps */
+#define VERSATILE_PCI_BASE_SIZE	       0x01000000
+#define VERSATILE_PCI_CFG_BASE_SIZE    0x02000000
+#define VERSATILE_PCI_MEM_BASE0_SIZE   0x0c000000	/* 32Mb */
+#define VERSATILE_PCI_MEM_BASE1_SIZE   0x10000000	/* 256Mb */
+#define VERSATILE_PCI_MEM_BASE2_SIZE   0x10000000	/* 256Mb */
+
+#define VERSATILE_SDRAM67_BASE         0x70000000	/* SDRAM banks 6 and 7 */
+#define VERSATILE_LT_BASE              0x80000000	/* Logic Tile expansion */
+
+/*
+ * Disk on Chip
+ */
+#define VERSATILE_DOC_BASE             0x2C000000
+#define VERSATILE_DOC_SIZE             (16 << 20)
+#define VERSATILE_DOC_PAGE_SIZE        512
+#define VERSATILE_DOC_TOTAL_PAGES     (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES    32
+#define START_PAGE          0x80
+
+/* 
+ *  LED settings, bits [7:0]
+ */
+#define VERSATILE_SYS_LED0             (1 << 0)
+#define VERSATILE_SYS_LED1             (1 << 1)
+#define VERSATILE_SYS_LED2             (1 << 2)
+#define VERSATILE_SYS_LED3             (1 << 3)
+#define VERSATILE_SYS_LED4             (1 << 4)
+#define VERSATILE_SYS_LED5             (1 << 5)
+#define VERSATILE_SYS_LED6             (1 << 6)
+#define VERSATILE_SYS_LED7             (1 << 7)
+
+#define ALL_LEDS                  0xFF
+
+#define LED_BANK                  VERSATILE_SYS_LED
+
+/* 
+ * Control registers
+ */
+#define VERSATILE_IDFIELD_OFFSET	0x0	/* Versatile build information */
+#define VERSATILE_FLASHPROG_OFFSET	0x4	/* Flash devices */
+#define VERSATILE_INTREG_OFFSET		0x8	/* Interrupt control */
+#define VERSATILE_DECODE_OFFSET		0xC	/* Fitted logic modules */
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile Interrupt Controller - control registers
+ * ------------------------------------------------------------------------
+ * 
+ *  Offsets from interrupt controller base 
+ * 
+ *  System Controller interrupt controller base is
+ * 
+ * 	VERSATILE_IC_BASE
+ * 
+ *  Core Module interrupt controller base is
+ * 
+ * 	VERSATILE_SYS_IC 
+ * 
+ */
+/* VIC definitions in include/asm-arm/hardware/vic.h */
+
+#define SIC_IRQ_STATUS                  0
+#define SIC_IRQ_RAW_STATUS              0x04
+#define SIC_IRQ_ENABLE                  0x08
+#define SIC_IRQ_ENABLE_SET              0x08
+#define SIC_IRQ_ENABLE_CLEAR            0x0C
+#define SIC_INT_SOFT_SET                0x10
+#define SIC_INT_SOFT_CLEAR              0x14
+#define SIC_INT_PIC_ENABLE              0x20	/* read status of pass through mask */
+#define SIC_INT_PIC_ENABLES             0x20	/* set interrupt pass through bits */
+#define SIC_INT_PIC_ENABLEC             0x24	/* Clear interrupt pass through bits */
+
+/* ------------------------------------------------------------------------
+ *  Interrupts - bit assignment (primary)
+ * ------------------------------------------------------------------------
+ */
+
+#define INT_WDOGINT                     0	/* Watchdog timer */
+#define INT_SOFTINT                     1	/* Software interrupt */
+#define INT_COMMRx                      2	/* Debug Comm Rx interrupt */
+#define INT_COMMTx                      3	/* Debug Comm Tx interrupt */
+#define INT_TIMERINT0_1                 4	/* Timer 0 and 1 */
+#define INT_TIMERINT2_3                 5	/* Timer 2 and 3 */
+#define INT_GPIOINT0                    6	/* GPIO 0 */
+#define INT_GPIOINT1                    7	/* GPIO 1 */
+#define INT_GPIOINT2                    8	/* GPIO 2 */
+#define INT_GPIOINT3                    9	/* GPIO 3 */
+#define INT_RTCINT                      10	/* Real Time Clock */
+#define INT_SSPINT                      11	/* Synchronous Serial Port */
+#define INT_UARTINT0                    12	/* UART 0 on development chip */
+#define INT_UARTINT1                    13	/* UART 1 on development chip */
+#define INT_UARTINT2                    14	/* UART 2 on development chip */
+#define INT_SCIINT                      15	/* Smart Card Interface */
+#define INT_CLCDINT                     16	/* CLCD controller */
+#define INT_DMAINT                      17	/* DMA controller */
+#define INT_PWRFAILINT                  18	/* Power failure */
+#define INT_MBXINT                      19	/* Graphics processor */
+#define INT_GNDINT                      20	/* Reserved */
+	/* External interrupt signals from logic tiles or secondary controller */
+#define INT_VICSOURCE21                 21	/* Disk on Chip */
+#define INT_VICSOURCE22                 22	/* MCI0A */
+#define INT_VICSOURCE23                 23	/* MCI1A */
+#define INT_VICSOURCE24                 24	/* AACI */
+#define INT_VICSOURCE25                 25	/* Ethernet */
+#define INT_VICSOURCE26                 26	/* USB */
+#define INT_VICSOURCE27                 27	/* PCI 0 */
+#define INT_VICSOURCE28                 28	/* PCI 1 */
+#define INT_VICSOURCE29                 29	/* PCI 2 */
+#define INT_VICSOURCE30                 30	/* PCI 3 */
+#define INT_VICSOURCE31                 31	/* SIC source */
+
+#define VERSATILE_SC_VALID_INT               0x003FFFFF
+
+#define MAXIRQNUM                       31
+#define MAXFIQNUM                       31
+#define MAXSWINUM                       31
+
+/* ------------------------------------------------------------------------
+ *  Interrupts - bit assignment (secondary)
+ * ------------------------------------------------------------------------
+ */
+#define SIC_INT_MMCI0B                  1	/* Multimedia Card 0B */
+#define SIC_INT_MMCI1B                  2	/* Multimedia Card 1B */
+#define SIC_INT_KMI0                    3	/* Keyboard/Mouse port 0 */
+#define SIC_INT_KMI1                    4	/* Keyboard/Mouse port 1 */
+#define SIC_INT_SCI3                    5	/* Smart Card interface */
+#define SIC_INT_UART3                   6	/* UART 3 empty or data available */
+#define SIC_INT_CLCD                    7	/* Character LCD */
+#define SIC_INT_TOUCH                   8	/* Touchscreen */
+#define SIC_INT_KEYPAD                  9	/* Key pressed on display keypad */
+	/* 10:20 - reserved */
+#define SIC_INT_DoC                     21	/* Disk on Chip memory controller */
+#define SIC_INT_MMCI0A                  22	/* MMC 0A */
+#define SIC_INT_MMCI1A                  23	/* MMC 1A */
+#define SIC_INT_AACI                    24	/* Audio Codec */
+#define SIC_INT_ETH                     25	/* Ethernet controller */
+#define SIC_INT_USB                     26	/* USB controller */
+#define SIC_INT_PCI0                    27
+#define SIC_INT_PCI1                    28
+#define SIC_INT_PCI2                    29
+#define SIC_INT_PCI3                    30
+
+
+/*
+ * System controller bit assignment
+ */
+#define VERSATILE_REFCLK	0
+#define VERSATILE_TIMCLK	1
+
+#define VERSATILE_TIMER1_EnSel	15
+#define VERSATILE_TIMER2_EnSel	17
+#define VERSATILE_TIMER3_EnSel	19
+#define VERSATILE_TIMER4_EnSel	21
+
+
+#define VERSATILE_CSR_BASE             0x10000000
+#define VERSATILE_CSR_SIZE             0x10000000
+
+#ifdef CONFIG_MACH_VERSATILE_AB
+/*
+ * IB2 Versatile/AB expansion board definitions
+ */
+#define VERSATILE_IB2_CAMERA_BANK	VERSATILE_IB2_BASE
+#define VERSATILE_IB2_KBD_DATAREG	(VERSATILE_IB2_BASE + 0x01000000)
+
+/* VICINTSOURCE27 */
+#define VERSATILE_IB2_INT_BASE		(VERSATILE_IB2_BASE + 0x02000000)
+#define VERSATILE_IB2_IER		(VERSATILE_IB2_INT_BASE + 0)
+#define VERSATILE_IB2_ISR		(VERSATILE_IB2_INT_BASE + 4)
+
+#define VERSATILE_IB2_CTL_BASE		(VERSATILE_IB2_BASE + 0x03000000)
+#define VERSATILE_IB2_CTRL		(VERSATILE_IB2_CTL_BASE + 0)
+#define VERSATILE_IB2_STAT		(VERSATILE_IB2_CTL_BASE + 4)
+#endif
+
+#endif



From s.hauer at pengutronix.de  Mon Oct 11 13:05:59 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 Oct 2010 19:05:59 +0200
Subject: [PATCH 4/4] Adapt the defconfig for a full blown ChumbyOne support
In-Reply-To: <201010111742.02731.jbe@pengutronix.de>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
	<1286808746-19456-5-git-send-email-jbe@pengutronix.de>
	<20101011152058.GC7412@game.jcrosoft.org>
	<201010111742.02731.jbe@pengutronix.de>
Message-ID: <20101011170559.GC28242@pengutronix.de>

On Mon, Oct 11, 2010 at 05:42:01PM +0200, Juergen Beisert wrote:
> Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 16:52 Mon 11 Oct     , Juergen Beisert wrote:
> > > Make the ChumbyOne use of the MCI framework.
> > >
> > > Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> > > ---
> > >  arch/arm/configs/chumbyone_defconfig |  224
> > > +++++++++++++++++++++++++++++++++-
> >
> > please use savedefconfig
> 
> Sorry, didn't notice the difference yet. I will resend this patch.

I already put the patches into next and changed the defconfigs to
savedefconfig format on the way.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From plagnioj at jcrosoft.com  Tue Oct 12 02:00:00 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 12 Oct 2010 08:00:00 +0200
Subject: [PATCH v3] Add basic support from ARM Versatile/PB
In-Reply-To: <20101011162832.14102.69708.stgit@zaytsev.su>
References: <20101011162832.14102.69708.stgit@zaytsev.su>
Message-ID: <20101012060000.GH7412@game.jcrosoft.org>

> +if MACH_VERSATILEPB
> +
> +config ARCH_TEXT_BASE
> +	hex
> +	default 0
sure?
> +
> +config BOARDINFO
> +	default "ARM Versatile/PB (ARM926EJ-S)"
> +endif
> diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
> new file mode 100644
> index 0000000..a17aed3
> --- /dev/null
> +++ b/arch/arm/boards/versatile/Makefile
> @@ -0,0 +1,2 @@
> +
> +obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
> diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
> new file mode 100644
> index 0000000..25bb18f
> --- /dev/null
> +++ b/arch/arm/boards/versatile/config.h
> @@ -0,0 +1,5 @@
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#endif	/* __CONFIG_H */
> diff --git a/arch/arm/boards/versatile/env/bin/init b/arch/arm/boards/versatile/env/bin/init
> new file mode 100644
> index 0000000..224a6b4
> --- /dev/null
> +++ b/arch/arm/boards/versatile/env/bin/init
> @@ -0,0 +1 @@
> +# Dummy Init environment script
use defaultenv it will be better

> +static struct device_d smc911x_dev = {
> +	.id		= -1,
> +	.name		= "smc91c111",
> +	.map_base	= VERSATILE_ETH_BASE,
> +	.size		= 64 * 1024
it will be good to have a comma here
> +};
> +
> +static int vpb_devices_init(void)
> +{
> +	versatile_add_sdram(64 * 1024 *1024);
> +
> +	register_device(&smc911x_dev);
> +
> +	armlinux_set_architecture(MACH_TYPE_VERSATILE_PB);
> +	armlinux_set_bootparams((void *)(0x00000100));
> +
> +	return 0;
> +}
> +device_initcall(vpb_devices_init);
> +++ b/arch/arm/include/asm/arm_timer.h
> @@ -0,0 +1,33 @@
> +#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
> +#define __ASM_ARM_HARDWARE_ARM_TIMER_H
> +
> +/*
> + * From Linux v2.6.35
> + * arch/arm/include/asm/hardware/arm_timer.h
please keep the header at the same location
to simplify code sharing
> + *
> + * ARM timer implementation, found in Integrator, Versatile and Realview
> + * platforms.  Not all platforms support all registers and bits in these
> + * registers, so we mark them with A for Integrator AP, C for Integrator
> + * CP, V for Versatile and R for Realview.
> + *
> + * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
> + * can have 16-bit or 32-bit selectable via a bit in the control register.
> + */
> +#define TIMER_LOAD	0x00			/* ACVR rw */
> +#define TIMER_VALUE	0x04			/* ACVR ro */
> +#define TIMER_CTRL	0x08			/* ACVR rw */
> +#define TIMER_CTRL_ONESHOT	(1 << 0)	/*  CVR */
> +#define TIMER_CTRL_32BIT	(1 << 1)	/*  CVR */
> +#define TIMER_CTRL_DIV1		(0 << 2)	/* ACVR */
> +#define TIMER_CTRL_DIV16	(1 << 2)	/* ACVR */
> +#define TIMER_CTRL_DIV256	(2 << 2)	/* ACVR */
> +#define TIMER_CTRL_IE		(1 << 5)	/*   VR */
> +#define TIMER_CTRL_PERIODIC	(1 << 6)	/* ACVR */
> +#define TIMER_CTRL_ENABLE	(1 << 7)	/* ACVR */
> +
> +#define TIMER_INTCLR	0x0c			/* ACVR wo */
> +#define TIMER_RIS	0x10			/*  CVR ro */
> +#define TIMER_MIS	0x14			/*  CVR ro */
> +#define TIMER_BGLOAD	0x18			/*  CVR rw */
> +
> +#endif
...
> +obj-y += core.o
> diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
> new file mode 100644
> index 0000000..94543c6
> --- /dev/null
> +++ b/arch/arm/mach-versatile/core.c
> @@ -0,0 +1,212 @@
> +/*
> + * Copyright (C) 2010 B Labs Ltd,
> + * http://l4dev.org
> + * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
> + *
> + * Based on mach-nomadik
> + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; version 2 of
> + * the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <clock.h>
> +#include <debug_ll.h>
> +
> +#include <linux/clkdev.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +
> +#include <asm/io.h>
> +#include <asm/arm_timer.h>
> +#include <asm/armlinux.h>
> +
> +#include <mach/platform.h>
> +#include <mach/init.h>
> +
> +static struct memory_platform_data ram_pdata = {
> +	.name = "ram0",
> +	.flags = DEVFS_RDWR,
> +};
> +
> +static struct device_d sdram_dev = {
> +	.id = -1,
> +	.name = "mem",
> +	.map_base = 0x00000000,
> +	.platform_data = &ram_pdata,
> +};
> +
> +void versatile_add_sdram(u32 size)
> +{
> +	sdram_dev.size = size;
> +	register_device(&sdram_dev);
> +	armlinux_add_dram(&sdram_dev);
> +}
> +
> +static struct device_d uart0_serial_device = {
> +	.id = 0,
> +	.name = "uart-pl011",
> +	.map_base = VERSATILE_UART0_BASE,
> +	.size = 4096,
> +};
> +
> +static struct device_d uart1_serial_device = {
> +	.id = 1,
> +	.name = "uart-pl011",
> +	.map_base = VERSATILE_UART1_BASE,
> +	.size = 4096,
> +};
> +
> +static struct device_d uart2_serial_device = {
> +	.id = 2,
> +	.name = "uart-pl011",
> +	.map_base = VERSATILE_UART2_BASE,
> +	.size = 4096,
> +};
> +static struct device_d uart3_serial_device = {
> +	.id = 3,
> +	.name = "uart-pl011",
> +	.map_base = VERSATILE_UART3_BASE,
> +	.size = 4096,
> +};
> +
> +struct clk {
> +	unsigned long rate;
> +};
> +
> +static struct clk ref_clk_24 = {
> +	.rate = 24000000,
> +};
> +
> +unsigned long clk_get_rate(struct clk *clk)
> +{
> +	return clk->rate;
> +}
> +EXPORT_SYMBOL(clk_get_rate);
> +
> +/* enable and disable do nothing */
> +int clk_enable(struct clk *clk)
> +{
> +	return 0;
> +}
> +EXPORT_SYMBOL(clk_enable);
> +
> +void clk_disable(struct clk *clk)
> +{
> +}
> +EXPORT_SYMBOL(clk_disable);
> +
> +/* Create a clock structure with the given name */
> +int vpb_clk_create(struct clk *clk, const char *dev_id)
> +{
> +	struct clk_lookup *clkdev;
> +
> +	clkdev = clkdev_alloc(clk, NULL, dev_id);
> +	if (!clkdev)
> +		return -ENOMEM;
> +
> +	clkdev_add(clkdev);
> +	return 0;
> +}
> +
> +/* 1Mhz / 256 */
> +#define TIMER_FREQ (1000000/256)
> +
> +#define TIMER0_BASE (VERSATILE_TIMER0_1_BASE)
> +#define TIMER1_BASE ((VERSATILE_TIMER0_1_BASE) + 0x20)
> +#define TIMER2_BASE (VERSATILE_TIMER2_3_BASE)
> +#define TIMER3_BASE ((VERSATILE_TIMER2_3_BASE) + 0x20)
> +
> +static uint64_t vpb_clocksource_read(void)
> +{
> +	return ~readl(TIMER0_BASE + TIMER_VALUE);
> +}
> +
> +static struct clocksource vpb_cs = {
> +	.read = vpb_clocksource_read,
> +	.mask = 0xffffffff,
> +	.shift = 10,
> +};
> +
> +/* From Linux v2.6.35
> + * arch/arm/mach-versatile/core.c */
please add the copyright 

Copyright (C) 1999 - 2003 ARM Limited
Copyright (C) 2000 Deep Blue Solutions Ltd

too
> +static void versatile_timer_init (void)
> +{
> +	u32 val;
> +
> +	/*
> +	 * set clock frequency:
> +	 *      VERSATILE_REFCLK is 32KHz
> +	 *      VERSATILE_TIMCLK is 1MHz
> +	 */
> +
> +	val = readl(VERSATILE_SCTL_BASE);
> +	val |= (VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel);
> +	writel(val, VERSATILE_SCTL_BASE);
> +
> +	/*
> +	 * Disable all timers, just to be sure.
> +	 */
> +
> +	writel(0, TIMER0_BASE + TIMER_CTRL);
> +	writel(0, TIMER1_BASE + TIMER_CTRL);
> +	writel(0, TIMER2_BASE + TIMER_CTRL);
> +	writel(0, TIMER3_BASE + TIMER_CTRL);
> +
> +        writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_DIV256,
> +			                TIMER0_BASE + TIMER_CTRL);
> +}
> +
> 
there is still a lots of whitespace

please use checkpatch.pl

Best Regards,
J.


From plagnioj at jcrosoft.com  Tue Oct 12 02:51:50 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 12 Oct 2010 08:51:50 +0200
Subject: [PATCH 13/17] defaultenv: handle disk partitions
In-Reply-To: <201010111622.15352.jbe@pengutronix.de>
References: <1286796505-16049-1-git-send-email-s.hauer@pengutronix.de>
	<201010111459.35914.jbe@pengutronix.de>
	<20101011135454.GZ28242@pengutronix.de>
	<201010111622.15352.jbe@pengutronix.de>
Message-ID: <20101012065150.GI7412@game.jcrosoft.org>

> > > > >
> > > > > Are you sure you want/need additional partitions on a disk without a
> > > > > persistant partition table?
> > > >
> > > > No ;)
> > > >
> > > > It is not completely clear to me how we handle this best. On i.MX51 I
> > > > have some problems with the partition table. When booting from SD card
> > > > we just dump barebox.bin to the raw card. The partition table is then
> > > > part of barebox.bin. Unfortunately we do not know (or at least we don't
> > > > want to specifiy) the size of the card during compile time.
> > > >
> > > > How should a bootable SD card should be partitioned anyway? We could
> > > > add partitions for barebox/env/kernel/root like usual, but this does
> > > > not look very standard for SD cards (and we even need extended
> > > > partitions if we want to add a data partition). We could also add just
> > > > a single partition for root and maintain the rest outside of any
> > > > partition.
> > >
> > > If you want your kernel to work with this card you will need a partition
> > > table. Its more like a hard disk, not like a flash memory of NAND or NOR
> > > type. So, IMHO you will need a full blown partition table when you want
> > > use the SD card outside barebox.
> >
> > Yes I know. Do we need a fdisk command for barebox?
> 
> IMHO not for barebox. Because to setup a full system on an SD card you would 
> also need tools to create a filesystem on these partitions. That's not the 
> job of a bootloader. We just have to handle partition tables in a correct 
> manner.
I think we can support fdisk but we do not need to create fs we can just dump
it from tftp & co

and the env can be see as a fs

Best Regards,
J.


From plagnioj at jcrosoft.com  Tue Oct 12 04:13:44 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 12 Oct 2010 10:13:44 +0200
Subject: [PATCH] nhk8815: use defaultenv
In-Reply-To: <20101011135329.GA7412@game.jcrosoft.org>
References: <20101011135329.GA7412@game.jcrosoft.org>
Message-ID: <1286871224-19770-1-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 arch/arm/boards/nhk8815/env/bin/_update            |   36 ----------------
 arch/arm/boards/nhk8815/env/bin/boot               |   38 -----------------
 arch/arm/boards/nhk8815/env/bin/init               |   28 ------------
 .../boards/nhk8815/env/bin/update_barebox_xmodem   |   19 --------
 arch/arm/boards/nhk8815/env/bin/update_kernel      |    8 ----
 arch/arm/boards/nhk8815/env/bin/update_root        |    8 ----
 arch/arm/boards/nhk8815/env/config                 |   44 +++++++++++++------
 arch/arm/configs/nhk8815_defconfig                 |    5 +-
 8 files changed, 33 insertions(+), 153 deletions(-)
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/_update
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/boot
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/init
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_kernel
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_root

diff --git a/arch/arm/boards/nhk8815/env/bin/_update b/arch/arm/boards/nhk8815/env/bin/_update
deleted file mode 100644
index fb7cbe8..0000000
--- a/arch/arm/boards/nhk8815/env/bin/_update
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-
-if [ -z "$part" -o -z "$image" ]; then
-	echo "define \$part and \$image"
-	exit 1
-fi
-
-if [ \! -e "$part" ]; then
-	echo "Partition $part does not exist"
-	exit 1
-fi
-
-if [ $# = 1 ]; then
-	image=$1
-fi
-
-if [ x$ip = xdhcp ]; then
-	dhcp
-fi
-
-ping $eth0.serverip
-if [ $? -ne 0 ] ; then
-	echo "update aborted"
-	exit 1
-fi
-
-unprotect $part
-
-echo
-echo "erasing partition $part"
-erase $part
-
-echo
-echo "flashing $image to $part"
-echo
-tftp $image $part
diff --git a/arch/arm/boards/nhk8815/env/bin/boot b/arch/arm/boards/nhk8815/env/bin/boot
deleted file mode 100644
index fd8d957..0000000
--- a/arch/arm/boards/nhk8815/env/bin/boot
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-if [ x$1 = xflash ]; then
-	root=flash
-	kernel=flash
-fi
-
-if [ x$1 = xnet ]; then
-	root=net
-	kernel=net
-fi
-
-if [ x$ip = xdhcp ]; then
-	bootargs="$bootargs ip=dhcp"
-else
-	bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::"
-fi
-
-if [ x$root = xflash ]; then
-	bootargs="$bootargs root=$rootpart rootfstype=jffs2"
-else
-	bootargs="$bootargs root=/dev/nfs nfsroot=192.168.23.111:$nfsroot"
-fi
-
-bootargs="$bootargs"
-
-if [ $kernel = net ]; then
-	if [ x$ip = xdhcp ]; then
-		dhcp
-	fi
-	tftp $uimage uImage
-	bootm uImage
-else
-	bootm /dev/nor0.kernel
-fi
-
diff --git a/arch/arm/boards/nhk8815/env/bin/init b/arch/arm/boards/nhk8815/env/bin/init
deleted file mode 100644
index 5b45a70..0000000
--- a/arch/arm/boards/nhk8815/env/bin/init
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-PATH=/env/bin
-export PATH
-
-. /env/config
-
-if [ -e /dev/nand0 ]; then
-	addpart /dev/nand0 $nand_parts
-
-	# Uh, oh, hush first expands wildcards and then starts executing
-	# commands. What a bug!
-	source /env/bin/hush_hack
-fi
-
-echo
-echo -n "Hit any key to stop autoboot: "
-timeout -a $autoboot_timeout
-if [ $? != 0 ]; then
-	echo
-	echo "type update_kernel [<imagename>] to update kernel into flash"
-	echo "type udate_root [<imagename>] to update rootfs into flash"
-	echo "type update_barebox_xmodem nor to update barebox into flash"
-	echo
-	exit
-fi
-
-boot
diff --git a/arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem b/arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem
deleted file mode 100644
index 40f4ad3..0000000
--- a/arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-part=/dev/nand0.barebox
-
-loadb -f barebox.bin -c
-
-unprotect $part
-echo
-echo "erasing partition $part"
-erase $part
-
-echo
-echo "flashing barebox.bin to $part"
-echo
-cp barebox.bin $part
-crc32 -f barebox.bin
-crc32 -f $part
diff --git a/arch/arm/boards/nhk8815/env/bin/update_kernel b/arch/arm/boards/nhk8815/env/bin/update_kernel
deleted file mode 100644
index db0f4c2..0000000
--- a/arch/arm/boards/nhk8815/env/bin/update_kernel
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-image=$uimage
-part=/dev/nand0.kernel
-
-. /env/bin/_update $1
diff --git a/arch/arm/boards/nhk8815/env/bin/update_root b/arch/arm/boards/nhk8815/env/bin/update_root
deleted file mode 100644
index 9530e84..0000000
--- a/arch/arm/boards/nhk8815/env/bin/update_root
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-. /env/config
-
-image=$jffs2
-part=/dev/nand0.rootfs
-
-. /env/bin/_update $1
diff --git a/arch/arm/boards/nhk8815/env/config b/arch/arm/boards/nhk8815/env/config
index 7e7fc45..e657a76 100644
--- a/arch/arm/boards/nhk8815/env/config
+++ b/arch/arm/boards/nhk8815/env/config
@@ -1,16 +1,33 @@
 #!/bin/sh
 
-# can be either 'net' or 'flash'
-kernel=net
-root=net
-
-# use 'dhcp' todo dhcp in uboot and in kernel
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
 ip=dhcp
 
-#
-# setup default ethernet address
-#
-#eth0.serverip=192.168.23.108
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.netmask=a.b.c.d
+#eth0.gateway=a.b.c.d
+#eth0.serverip=a.b.c.d
+
+# can be either 'net' or 'nand'
+kernel_loc=net
+# can be either 'net', 'nand' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+#kernelimage_type=zimage
+#kernelimage=zImage
+kernelimage_type=uimage
+kernelimage=uImage
+#kernelimage_type=raw
+#kernelimage=Image
+#kernelimage_type=raw_lzo
+#kernelimage=Image.lzo
 
 # Partition			Size	Start
 # XloaderTOC + X-Loader		256KB	0x00000000
@@ -22,11 +39,10 @@ ip=dhcp
 
 nand_parts="256k(xloader)ro,256k(meminit),2M(barebox),3M(kernel),22M(rootfs),100M(userfs),384k(free),128k(bareboxenv)"
 
-uimage=uImage-nhk15
-
-# use 'dhcp' to do dhcp in uboot and in kernel
-ip=dhcp
-
 autoboot_timeout=3
 
 bootargs="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc"
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m "
+
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index e3f4102..b81afe2 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -10,7 +10,8 @@ CONFIG_AUTO_COMPLETE=y
 CONFIG_MENU=y
 CONFIG_PASSWD_SUM_SHA1=y
 CONFIG_PARTITION=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/nhk8815/env"
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/nhk8815/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
 CONFIG_CMD_SAVEENV=y
@@ -22,8 +23,8 @@ CONFIG_CMD_MENU=y
 CONFIG_CMD_MENU_MANAGEMENT=y
 CONFIG_CMD_PASSWD=y
 CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
 CONFIG_CMD_MEMINFO=y
-CONFIG_CMD_CRC=y
 CONFIG_CMD_MTEST=y
 CONFIG_CMD_FLASH=y
 CONFIG_CMD_BOOTM_ZLIB=y
-- 
1.7.1



From jbe at pengutronix.de  Tue Oct 12 04:28:04 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 12 Oct 2010 10:28:04 +0200
Subject: Where to store a header file
Message-ID: <201010121028.04871.jbe@pengutronix.de>

Hi,

currently I'm adding the i.MX28 architecture to barebox. This new CPU is the 
successor of the i.MX23. So, it shares the most parts with it. But it also 
shares the fact, its not a real i.MX like the i.MX27 is (STM378x-SigmaTel -> 
i.MX23-Freescale).

But new to the i.MX28 is the FEC known from the i.MX family. To be able to 
reuse the i.MX FEC driver (fec_imx.c) on the i.MX28 I need the "mach/iim.h" 
from the "mach-imx" tree. As the i.MX23/28 itself is "mach-stm" this files 
must be shared between these architectures. But where to store this 
headerfile? In "arch/arm/include/asm/"? In "include/" (perhaps 
as "include/imx_iim.h")? Or in "drivers/net/" as a local header file? Any 
ideas?

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From alexey.zaytsev at gmail.com  Tue Oct 12 05:07:50 2010
From: alexey.zaytsev at gmail.com (Alexey Zaytsev)
Date: Tue, 12 Oct 2010 13:07:50 +0400
Subject: [PATCH v3] Add basic support from ARM Versatile/PB
In-Reply-To: <20101012060000.GH7412@game.jcrosoft.org>
References: <20101011162832.14102.69708.stgit@zaytsev.su>
	<20101012060000.GH7412@game.jcrosoft.org>
Message-ID: <AANLkTimi49xXMg1giyMOyz1uA491++cfRy5s_1=zsPVQ@mail.gmail.com>

On Tue, Oct 12, 2010 at 10:00, Jean-Christophe PLAGNIOL-VILLARD
<plagnioj at jcrosoft.com> wrote:
>> +if MACH_VERSATILEPB
>> +
>> +config ARCH_TEXT_BASE
>> + ? ? hex
>> + ? ? default 0
> sure?

That's one thing I wanted to ask - where should I place the barebox?
Currently, I'm placing it at 5M, with 4M malloc and the stack below.
Do I get it right that the downloaded images are stored in the malloc
area? In this case, should I expand the malloc area close to the RAM
size in order to be able to handle large images?

>>
> there is still a lots of whitespace
>
> please use checkpatch.pl

Ok, I'll fix everything but platform.h, not to complicate code sharing.


From s.hauer at pengutronix.de  Tue Oct 12 13:38:19 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 12 Oct 2010 19:38:19 +0200
Subject: [PATCH v3] Add basic support from ARM Versatile/PB
In-Reply-To: <AANLkTimi49xXMg1giyMOyz1uA491++cfRy5s_1=zsPVQ@mail.gmail.com>
References: <20101011162832.14102.69708.stgit@zaytsev.su>
	<20101012060000.GH7412@game.jcrosoft.org>
	<AANLkTimi49xXMg1giyMOyz1uA491++cfRy5s_1=zsPVQ@mail.gmail.com>
Message-ID: <20101012173819.GG28242@pengutronix.de>

On Tue, Oct 12, 2010 at 01:07:50PM +0400, Alexey Zaytsev wrote:
> On Tue, Oct 12, 2010 at 10:00, Jean-Christophe PLAGNIOL-VILLARD
> <plagnioj at jcrosoft.com> wrote:
> >> +if MACH_VERSATILEPB
> >> +
> >> +config ARCH_TEXT_BASE
> >> + ? ? hex
> >> + ? ? default 0
> > sure?
> 
> That's one thing I wanted to ask - where should I place the barebox?
> Currently, I'm placing it at 5M, with 4M malloc and the stack below.
> Do I get it right that the downloaded images are stored in the malloc
> area?

It depends. If you download images to the filesystem they end up in the
malloc area, so this should at least be big enough to store a kernel
image. You also can tftp directly to flash, so the malloc space does not
have to be as big as your rootfs.
Normally I put barebox at the end of RAM and use 4-16MB of malloc area.
Please make sure that there is ~4MB of free space at the beginning of
the SDRAM since this is used during start of Linux images.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From eric at eukrea.com  Wed Oct 13 05:54:44 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 13 Oct 2010 11:54:44 +0200
Subject: [PATCH] unbreak bootm
Message-ID: <1286963684-16359-1-git-send-email-eric@eukrea.com>

commit a3c1e5d888d0ee317ffc7635694684bb71213c9c was
not tested as all the tests are wrong and it breaks bootm

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 commands/bootm.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/commands/bootm.c b/commands/bootm.c
index 83d36d3..666deeb 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -167,7 +167,7 @@ struct image_handle *map_image(const char *filename, int verify)
 		goto err_out;
 	}
 
-	if (image_check_magic(header)) {
+	if (! image_check_magic(header)) {
 		puts ("Bad Magic Number\n");
 		goto err_out;
 	}
@@ -332,7 +332,7 @@ static int do_bootm(struct command *cmdtp, int argc, char *argv[])
 
 	os_header = &os_handle->header;
 
-	if (image_check_arch(os_header, IH_ARCH)) {
+	if (! image_check_arch(os_header, IH_ARCH)) {
 		printf("Unsupported Architecture 0x%x\n",
 		       image_get_arch(os_header));
 		goto err_out;
@@ -409,7 +409,7 @@ static int image_info (ulong addr)
 	/* Copy header so we can blank CRC field for re-calculation */
 	memmove (&header, (char *)addr, image_get_header_size());
 
-	if (image_check_magic(hdr)) {
+	if (! image_check_magic(hdr)) {
 		puts ("   Bad Magic Number\n");
 		return 1;
 	}
-- 
1.7.0.4



From eric at eukrea.com  Wed Oct 13 06:14:27 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 13 Oct 2010 12:14:27 +0200
Subject: [PATCH] eukrea_cpuimx27: update board support
Message-ID: <1286964867-16922-1-git-send-email-eric@eukrea.com>

- fix for LCD support
- environment update (last one before trying to use the generic env)

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/boards/eukrea_cpuimx27/env/bin/boot      |   12 +++++++-----
 arch/arm/boards/eukrea_cpuimx27/env/bin/init      |   10 ++++++++++
 arch/arm/boards/eukrea_cpuimx27/env/config        |    9 +++++++--
 arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c |    3 +++
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx27/env/bin/boot b/arch/arm/boards/eukrea_cpuimx27/env/bin/boot
index 7272e56..0e1c80a 100644
--- a/arch/arm/boards/eukrea_cpuimx27/env/bin/boot
+++ b/arch/arm/boards/eukrea_cpuimx27/env/bin/boot
@@ -27,12 +27,14 @@ else
 	bootargs="$bootargs ip=off"
 fi
 
-if [ x$root = xnand ]; then
-	bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2"
-elif [ x$root = xnor ]; then
-	bootargs="$bootargs root=$rootpart_nor rootfstype=jffs2"
+if [ x$rootfstype = xubifs ]; then
+	bootargs="$bootargs root=ubi0:$ubiroot ubi.mtd=$rootpartnum rootfstype=ubifs"
 else
-	bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp"
+	if [ x$root = xnand ]; then
+		bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2"
+	elif [ x$root = xnor ]; then
+		bootargs="$bootargs root=$rootpart_nor rootfstype=jffs2"
+	fi
 fi
 
 bootargs="$bootargs mtdparts=physmap-flash.0:$nor_parts;mxc_nand:$nand_parts"
diff --git a/arch/arm/boards/eukrea_cpuimx27/env/bin/init b/arch/arm/boards/eukrea_cpuimx27/env/bin/init
index 3bfd194..aefd67c 100644
--- a/arch/arm/boards/eukrea_cpuimx27/env/bin/init
+++ b/arch/arm/boards/eukrea_cpuimx27/env/bin/init
@@ -16,11 +16,21 @@ if [ -e /dev/nand0 ]; then
 	source /env/bin/hush_hack 
 fi
 
+if [ -f /env/logo.bmp ]; then
+	bmp /env/logo.bmp
+	fb0.enable=1
+elif [ -f /env/logo.bmp.lzo ]; then
+	unlzo /env/logo.bmp.lzo /logo.bmp
+	bmp /logo.bmp
+	fb0.enable=1
+fi
+
 if [ -z $eth0.ethaddr ]; then
 	while [ -z $eth0.ethaddr ]; do
 		readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr
 	done
 	echo -a /env/config "eth0.ethaddr=$eth0.ethaddr"
+	saveenv
 fi
 
 echo
diff --git a/arch/arm/boards/eukrea_cpuimx27/env/config b/arch/arm/boards/eukrea_cpuimx27/env/config
index 505ada3..6449cdf 100644
--- a/arch/arm/boards/eukrea_cpuimx27/env/config
+++ b/arch/arm/boards/eukrea_cpuimx27/env/config
@@ -3,9 +3,11 @@
 # can be either 'net', 'nor' or 'nand''
 kernel=nor
 root=nor
+rootfstype=ubifs
 
-uimage=mx27/uImage
-jffs2=mx27/rootfs.jffs2
+basedir=cpuimx27
+uimage=$basedir/uImage
+rootfs=$basedir/rootfs
 
 autoboot_timeout=1
 
@@ -19,6 +21,9 @@ rootpart_nor="/dev/mtdblock3"
 nand_parts="-(nand)"
 rootpart_nand=""
 
+rootpartnum=3
+ubiroot="eukrea-cpuimx27-rootfs"
+
 nfsroot=""
 
 # use 'dhcp' to do dhcp in barebox and in kernel
diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
index 4d1797b..c7570cf 100644
--- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
+++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
@@ -275,6 +275,7 @@ static int eukrea_cpuimx27_devices_init(void)
 		PA29_PF_VSYNC,
 		PA31_PF_OE_ACD,
 		GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT,
+		GPIO_PORTA | 25 | GPIO_GPIO | GPIO_OUT,
 #endif
 	};
 
@@ -311,6 +312,8 @@ static int eukrea_cpuimx27_devices_init(void)
 	register_device(&imxfb_dev);
 	gpio_direction_output(GPIO_PORTE | 5, 0);
 	gpio_set_value(GPIO_PORTE | 5, 1);
+	gpio_direction_output(GPIO_PORTA | 25, 0);
+	gpio_set_value(GPIO_PORTA | 25, 1);
 #endif
 
 	armlinux_add_dram(&sdram_dev);
-- 
1.7.0.4



From plagnioj at jcrosoft.com  Wed Oct 13 06:08:59 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 13 Oct 2010 12:08:59 +0200
Subject: [PATCH] unbreak bootm
In-Reply-To: <1286963684-16359-1-git-send-email-eric@eukrea.com>
References: <1286963684-16359-1-git-send-email-eric@eukrea.com>
Message-ID: <20101013100859.GN7412@game.jcrosoft.org>

On 11:54 Wed 13 Oct     , Eric B?nard wrote:
> commit a3c1e5d888d0ee317ffc7635694684bb71213c9c was
> not tested as all the tests are wrong and it breaks bootm
I test it but no see it
> 
> Signed-off-by: Eric B?nard <eric at eukrea.com>
> ---
>  commands/bootm.c |    6 +++---
>  1 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/commands/bootm.c b/commands/bootm.c
> index 83d36d3..666deeb 100644
> --- a/commands/bootm.c
> +++ b/commands/bootm.c
> @@ -167,7 +167,7 @@ struct image_handle *map_image(const char *filename, int verify)
>  		goto err_out;
>  	}
>  
> -	if (image_check_magic(header)) {
> +	if (! image_check_magic(header)) {
no space after !
>  		puts ("Bad Magic Number\n");
>  		goto err_out;
>  	}
Best Regards,
J.


From eric at eukrea.com  Wed Oct 13 06:19:25 2010
From: eric at eukrea.com (=?ISO-8859-1?Q?Eric_B=E9nard?=)
Date: Wed, 13 Oct 2010 12:19:25 +0200
Subject: [PATCH] unbreak bootm
In-Reply-To: <20101013100859.GN7412@game.jcrosoft.org>
References: <1286963684-16359-1-git-send-email-eric@eukrea.com>
	<20101013100859.GN7412@game.jcrosoft.org>
Message-ID: <4CB587AD.4010609@eukrea.com>

Hi Jean-Christophe,

Le 13/10/2010 12:08, Jean-Christophe PLAGNIOL-VILLARD a ?crit :
> On 11:54 Wed 13 Oct     , Eric B?nard wrote:
>> commit a3c1e5d888d0ee317ffc7635694684bb71213c9c was
>> not tested as all the tests are wrong and it breaks bootm

Sorry this was not meant to be offensive, just spent to much time
on this so my comment may be a little bit to agressive.

> I test it but no see it

How do you test this ? In the present case it prevents to boot a uImage.

I think some other tests may be concerned also but I didn't have time to 
check everywhere.

Will resend with the space fixed.

Eric



From c.schlote at konzeptpark.de  Wed Oct 13 06:40:08 2010
From: c.schlote at konzeptpark.de (Carsten Schlote)
Date: Wed, 13 Oct 2010 12:40:08 +0200
Subject: pull-request: kp-mcb2 board files and configuration, GCC 4.5.x
	optimizer workaround, powerpc mach changes
Message-ID: <1286966408.19212.1.camel@kplaws107lx>

The following changes since commit
a14c018d11ab8931eb0882dd9d7f6bdb04aa6d8b:

  MAKEALL: allow CROSS_COMPILE*="" (2010-10-08 15:43:09 +0200)

are available in the git repository at:
  git://git.vahanus.net/csc/barebox.git for-upstream

Carsten Schlote (5):
      [ppc/mpc5xxx] Fixed typo in cpu_init.c
      [ppc/mpc5xxx] Small text cleanups and ADDECR to output
      [kp-mcb2] Added board files and configs for konzeptpark mcb2
      [compiler] Added OPTIMIZE options to enable GCC optimizer
      [drivers/nor] Fixed mismatch in prototype

 Makefile                                |    2 +-
 arch/arm/Makefile                       |    8 +
 arch/blackfin/Makefile                  |    7 +
 arch/m68k/Makefile                      |    7 +
 arch/ppc/Kconfig                        |   11 +
 arch/ppc/Makefile                       |    8 +
 arch/ppc/boards/kp-mcb2/Makefile        |    2 +
 arch/ppc/boards/kp-mcb2/barebox.lds.S   |  139 ++++++++++++
 arch/ppc/boards/kp-mcb2/config.h        |  253 ++++++++++++++++++++++
 arch/ppc/boards/kp-mcb2/kp-mcb2.c       |  349
+++++++++++++++++++++++++++++++
 arch/ppc/boards/kp-mcb2/kp-mcb2.dox     |    8 +
 arch/ppc/boards/kp-mcb2/mt46v32m16-75.h |   46 ++++
 arch/ppc/mach-mpc5xxx/Kconfig           |    5 +-
 arch/ppc/mach-mpc5xxx/cpu_init.c        |    2 +-
 arch/ppc/mach-mpc5xxx/reginfo.c         |    3 +-
 arch/sandbox/Makefile                   |    8 +
 arch/x86/Makefile                       |    8 +
 common/Kconfig                          |   13 ++
 drivers/nor/cfi_flash.c                 |    2 +-
 19 files changed, 875 insertions(+), 6 deletions(-)
 create mode 100644 arch/ppc/boards/kp-mcb2/Makefile
 create mode 100644 arch/ppc/boards/kp-mcb2/barebox.lds.S
 create mode 100644 arch/ppc/boards/kp-mcb2/config.h
 create mode 100644 arch/ppc/boards/kp-mcb2/kp-mcb2.c
 create mode 100644 arch/ppc/boards/kp-mcb2/kp-mcb2.dox
 create mode 100644 arch/ppc/boards/kp-mcb2/mt46v32m16-75.h

-- 
Carsten Schlote <c.schlote at konzeptpark.de>
konzeptpark.de


From s.hauer at pengutronix.de  Wed Oct 13 07:14:39 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 13 Oct 2010 13:14:39 +0200
Subject: [PATCH] unbreak bootm
In-Reply-To: <1286963684-16359-1-git-send-email-eric@eukrea.com>
References: <1286963684-16359-1-git-send-email-eric@eukrea.com>
Message-ID: <20101013111439.GO28242@pengutronix.de>

On Wed, Oct 13, 2010 at 11:54:44AM +0200, Eric B?nard wrote:
> commit a3c1e5d888d0ee317ffc7635694684bb71213c9c was
> not tested as all the tests are wrong and it breaks bootm
> 

:-(

How about the following patch (currently untested)?


[PATCH] image: remove confusing image_check_* functions

The function names do not make it clear what return value
is expected and do not save a single line of code. Put
the code inline and unbreak the wrong checks introduced
with a3c1e5d888d0ee317ffc7635694684bb71213c9c.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/lib/armlinux.c        |    2 +-
 arch/m68k/lib/m68k-linuxboot.c |    2 +-
 arch/ppc/lib/ppclinux.c        |    2 +-
 commands/bootm.c               |    8 +++---
 common/image.c                 |    7 +++--
 include/image.h                |   55 ----------------------------------------
 6 files changed, 11 insertions(+), 65 deletions(-)

diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index 7c2cbf9..f690fef 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -212,7 +212,7 @@ int do_bootm_linux(struct image_data *data)
 	void (*theKernel)(int zero, int arch, void *params);
 	image_header_t *os_header = &data->os->header;
 
-	if (image_check_type(os_header, IH_TYPE_MULTI)) {
+	if (image_get_type(os_header) == IH_TYPE_MULTI) {
 		printf("Multifile images not handled at the moment\n");
 		return -1;
 	}
diff --git a/arch/m68k/lib/m68k-linuxboot.c b/arch/m68k/lib/m68k-linuxboot.c
index e5e90a8..144d5a3 100644
--- a/arch/m68k/lib/m68k-linuxboot.c
+++ b/arch/m68k/lib/m68k-linuxboot.c
@@ -109,7 +109,7 @@ static int do_bootm_linux(struct image_data *data)
 	const char *commandline = getenv ("bootargs");
 	uint32_t loadaddr,loadsize;
 
-	if (image_check_type(os_header, IH_TYPE_MULTI)) {
+	if (image_get_type(os_header) == IH_TYPE_MULTI) {
 		printf("Multifile images not handled at the moment\n");
 		return -1;
 	}
diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c
index 5ee908d..fc22a87 100644
--- a/arch/ppc/lib/ppclinux.c
+++ b/arch/ppc/lib/ppclinux.c
@@ -45,7 +45,7 @@ static int do_bootm_linux(struct image_data *idata)
 	printf("entering %s: os_header: %p initrd_header: %p oftree: %s\n",
 			__FUNCTION__, os_header, initrd_header, idata->oftree);
 
-	if (image_check_type(os_header, IH_TYPE_MULTI)) {
+	if (image_get_type(os_header) == IH_TYPE_MULTI) {
 		unsigned long *data = (unsigned long *)(idata->os->data);
 		unsigned long len1 = 0, len2 = 0;
 
diff --git a/commands/bootm.c b/commands/bootm.c
index 83d36d3..a7cbfb9 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -167,7 +167,7 @@ struct image_handle *map_image(const char *filename, int verify)
 		goto err_out;
 	}
 
-	if (image_check_magic(header)) {
+	if (image_get_magic(header) != IH_MAGIC) {
 		puts ("Bad Magic Number\n");
 		goto err_out;
 	}
@@ -332,7 +332,7 @@ static int do_bootm(struct command *cmdtp, int argc, char *argv[])
 
 	os_header = &os_handle->header;
 
-	if (image_check_arch(os_header, IH_ARCH)) {
+	if (image_get_arch(os_header) != IH_ARCH) {
 		printf("Unsupported Architecture 0x%x\n",
 		       image_get_arch(os_header));
 		goto err_out;
@@ -350,7 +350,7 @@ static int do_bootm(struct command *cmdtp, int argc, char *argv[])
 
 	/* loop through the registered handlers */
 	list_for_each_entry(handler, &handler_list, list) {
-		if (image_check_os(os_header, handler->image_type)) {
+		if (image_get_os(hdr) == handler->image_type) {
 			handler->bootm(&data);
 			printf("handler returned!\n");
 			goto err_out;
@@ -409,7 +409,7 @@ static int image_info (ulong addr)
 	/* Copy header so we can blank CRC field for re-calculation */
 	memmove (&header, (char *)addr, image_get_header_size());
 
-	if (image_check_magic(hdr)) {
+	if (image_get_magic(hdr) != IH_MAGIC) {
 		puts ("   Bad Magic Number\n");
 		return 1;
 	}
diff --git a/common/image.c b/common/image.c
index 104446a..2b2c410 100644
--- a/common/image.c
+++ b/common/image.c
@@ -266,6 +266,7 @@ void image_print_contents(const void *ptr)
 {
 	const image_header_t *hdr = (const image_header_t *)ptr;
 	const char *p;
+	int type;
 
 #ifdef __BAREBOX__
 	p = "   ";
@@ -285,8 +286,8 @@ void image_print_contents(const void *ptr)
 	printf ("%sLoad Address: %08x\n", p, image_get_load(hdr));
 	printf ("%sEntry Point:  %08x\n", p, image_get_ep(hdr));
 
-	if (image_check_type(hdr, IH_TYPE_MULTI) ||
-			image_check_type(hdr, IH_TYPE_SCRIPT)) {
+	type = image_get_type(hdr);
+	if (type != IH_TYPE_MULTI || type != IH_TYPE_SCRIPT) {
 		int i;
 		ulong data, len;
 		ulong count = image_multi_count(hdr);
@@ -298,7 +299,7 @@ void image_print_contents(const void *ptr)
 			printf("%s   Image %d: ", p, i);
 			image_print_size(len);
 
-			if (image_check_type(hdr, IH_TYPE_SCRIPT) && i > 0) {
+			if (image_get_type(hdr) != IH_TYPE_SCRIPT && i > 0) {
 				/*
 				 * the user may need to know offsets
 				 * if planning to do something with
diff --git a/include/image.h b/include/image.h
index 2c5956d..a42d06b 100644
--- a/include/image.h
+++ b/include/image.h
@@ -320,61 +320,6 @@ static inline void image_set_name(image_header_t *hdr, const char *name)
 	strncpy(image_get_name(hdr), name, IH_NMLEN);
 }
 
-static inline int image_check_magic(const image_header_t *hdr)
-{
-	return (image_get_magic(hdr) == IH_MAGIC);
-}
-static inline int image_check_type(const image_header_t *hdr, uint8_t type)
-{
-	return (image_get_type(hdr) == type);
-}
-static inline int image_check_arch(const image_header_t *hdr, uint8_t arch)
-{
-	return (image_get_arch(hdr) == arch);
-}
-static inline int image_check_os(const image_header_t *hdr, uint8_t os)
-{
-	return (image_get_os(hdr) == os);
-}
-
-#ifdef __BAREBOX__
-static inline int image_check_target_arch(const image_header_t *hdr)
-{
-#if defined(__ARM__)
-	if (!image_check_arch(hdr, IH_ARCH_ARM))
-#elif defined(__avr32__)
-	if (!image_check_arch(hdr, IH_ARCH_AVR32))
-#elif defined(__bfin__)
-	if (!image_check_arch(hdr, IH_ARCH_BLACKFIN))
-#elif defined(__I386__)
-	if (!image_check_arch(hdr, IH_ARCH_I386))
-#elif defined(__m68k__)
-	if (!image_check_arch(hdr, IH_ARCH_M68K))
-#elif defined(__microblaze__)
-	if (!image_check_arch(hdr, IH_ARCH_MICROBLAZE))
-#elif defined(__mips__)
-	if (!image_check_arch(hdr, IH_ARCH_MIPS))
-#elif defined(__nios__)
-	if (!image_check_arch(hdr, IH_ARCH_NIOS))
-#elif defined(__nios2__)
-	if (!image_check_arch(hdr, IH_ARCH_NIOS2))
-#elif defined(__PPC__)
-	if (!image_check_arch(hdr, IH_ARCH_PPC))
-#elif defined(__sh__)
-	if (!image_check_arch(hdr, IH_ARCH_SH))
-#elif defined(__sparc__)
-	if (!image_check_arch(hdr, IH_ARCH_SPARC))
-#elif defined(CONFIG_LINUX)
-	if (!image_check_arch(hdr, IH_ARCH_LINUX))
-#else
-# error Unknown CPU type
-#endif
-		return 0;
-
-	return 1;
-}
-#endif
-
 ulong image_multi_count(const image_header_t *hdr);
 void image_multi_getimg(const image_header_t *hdr, ulong idx,
 			ulong *data, ulong *len);
-- 
1.7.2.3


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From eric at eukrea.com  Wed Oct 13 08:28:38 2010
From: eric at eukrea.com (=?ISO-8859-15?Q?Eric_B=E9nard?=)
Date: Wed, 13 Oct 2010 14:28:38 +0200
Subject: [PATCH] unbreak bootm
In-Reply-To: <20101013111439.GO28242@pengutronix.de>
References: <1286963684-16359-1-git-send-email-eric@eukrea.com>
	<20101013111439.GO28242@pengutronix.de>
Message-ID: <4CB5A5F6.9040802@eukrea.com>

Hi Sascha,

Le 13/10/2010 13:14, Sascha Hauer a ?crit :
> On Wed, Oct 13, 2010 at 11:54:44AM +0200, Eric B?nard wrote:
>> commit a3c1e5d888d0ee317ffc7635694684bb71213c9c was
>> not tested as all the tests are wrong and it breaks bootm
>>
>
> :-(
>
> How about the following patch (currently untested)?
>
works with the attached fix.

Eric

From eric at eukrea.com  Wed Oct 13 08:27:19 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 13 Oct 2010 14:27:19 +0200
Subject: [PATCH] fix Sascha's patch
Message-ID: <mailman.3.1286972931.18522.barebox@lists.infradead.org>

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 commands/bootm.c  |    2 +-
 common/image.c    |    2 +-
 scripts/mkimage.c |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/commands/bootm.c b/commands/bootm.c
index a7cbfb9..14475c7 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -350,7 +350,7 @@ static int do_bootm(struct command *cmdtp, int argc, char *argv[])
 
 	/* loop through the registered handlers */
 	list_for_each_entry(handler, &handler_list, list) {
-		if (image_get_os(hdr) == handler->image_type) {
+		if (image_get_os(os_header) == handler->image_type) {
 			handler->bootm(&data);
 			printf("handler returned!\n");
 			goto err_out;
diff --git a/common/image.c b/common/image.c
index 2b2c410..a4c8b95 100644
--- a/common/image.c
+++ b/common/image.c
@@ -287,7 +287,7 @@ void image_print_contents(const void *ptr)
 	printf ("%sEntry Point:  %08x\n", p, image_get_ep(hdr));
 
 	type = image_get_type(hdr);
-	if (type != IH_TYPE_MULTI || type != IH_TYPE_SCRIPT) {
+	if (type == IH_TYPE_MULTI || type == IH_TYPE_SCRIPT) {
 		int i;
 		ulong data, len;
 		ulong count = image_multi_count(hdr);
diff --git a/scripts/mkimage.c b/scripts/mkimage.c
index f6cbb1c..40a3483 100644
--- a/scripts/mkimage.c
+++ b/scripts/mkimage.c
@@ -224,7 +224,7 @@ NXTARG:		;
 		 */
 		memcpy (hdr, ptr, sizeof(image_header_t));
 
-		if (image_check_magic(hdr)) {
+		if (image_get_magic(hdr) != IH_MAGIC) {
 			fprintf (stderr,
 				"%s: Bad Magic Number: \"%s\" is no valid image\n",
 				cmdname, imagefile);
-- 
1.7.0.4


--------------050808030402020707000403--


From plagnioj at jcrosoft.com  Wed Oct 13 09:07:37 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 13 Oct 2010 15:07:37 +0200
Subject: pull-request: kp-mcb2 board files and configuration, GCC 4.5.x
	optimizer workaround, powerpc mach changes
In-Reply-To: <1286966408.19212.1.camel@kplaws107lx>
References: <1286966408.19212.1.camel@kplaws107lx>
Message-ID: <20101013130737.GA11087@game.jcrosoft.org>

On 12:40 Wed 13 Oct     , Carsten Schlote wrote:
> The following changes since commit
> a14c018d11ab8931eb0882dd9d7f6bdb04aa6d8b:
> 
>   MAKEALL: allow CROSS_COMPILE*="" (2010-10-08 15:43:09 +0200)
> 
> are available in the git repository at:
>   git://git.vahanus.net/csc/barebox.git for-upstream
can you send the patch to the ml please

Best Regards,
J.


From plagnioj at jcrosoft.com  Wed Oct 13 09:08:50 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 13 Oct 2010 15:08:50 +0200
Subject: [PATCH] unbreak bootm
In-Reply-To: <4CB5A5F6.9040802@eukrea.com>
References: <1286963684-16359-1-git-send-email-eric@eukrea.com>
	<20101013111439.GO28242@pengutronix.de>
	<4CB5A5F6.9040802@eukrea.com>
Message-ID: <20101013130850.GB11087@game.jcrosoft.org>

On 14:28 Wed 13 Oct     , Eric B?nard wrote:
> Hi Sascha,
> 
> Le 13/10/2010 13:14, Sascha Hauer a ?crit :
> >On Wed, Oct 13, 2010 at 11:54:44AM +0200, Eric B?nard wrote:
> >>commit a3c1e5d888d0ee317ffc7635694684bb71213c9c was
> >>not tested as all the tests are wrong and it breaks bootm
> >>
> >
> >:-(
> >
> >How about the following patch (currently untested)?
> >
> works with the attached fix.
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>

Best Regards,
J.


From s.hauer at pengutronix.de  Wed Oct 13 11:40:45 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 13 Oct 2010 17:40:45 +0200
Subject: [PATCH] unbreak bootm
In-Reply-To: <4CB5A5F6.9040802@eukrea.com>
References: <1286963684-16359-1-git-send-email-eric@eukrea.com>
	<20101013111439.GO28242@pengutronix.de>
	<4CB5A5F6.9040802@eukrea.com>
Message-ID: <20101013154045.GR28242@pengutronix.de>

On Wed, Oct 13, 2010 at 02:28:38PM +0200, Eric B?nard wrote:
> Hi Sascha,
>
> Le 13/10/2010 13:14, Sascha Hauer a ?crit :
>> On Wed, Oct 13, 2010 at 11:54:44AM +0200, Eric B?nard wrote:
>>> commit a3c1e5d888d0ee317ffc7635694684bb71213c9c was
>>> not tested as all the tests are wrong and it breaks bootm
>>>
>>
>> :-(
>>
>> How about the following patch (currently untested)?
>>
> works with the attached fix.

Ok, thanks for testing and fixing. I squashed the fixes into my patch
and added it to next.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From eric at eukrea.com  Wed Oct 13 12:45:01 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 13 Oct 2010 18:45:01 +0200
Subject: [PATCH] eukrea_cpuimx35: update board support
Message-ID: <1286988301-28817-1-git-send-email-eric@eukrea.com>

- support NAND internal boot
- update external boot init sequence
- LCD enable

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/boards/eukrea_cpuimx35/env/bin/init      |    4 +-
 arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c |    2 +-
 arch/arm/boards/eukrea_cpuimx35/flash_header.c    |   23 ++++++++++-----------
 arch/arm/boards/eukrea_cpuimx35/lowlevel.c        |   20 +++++++++++-------
 4 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx35/env/bin/init b/arch/arm/boards/eukrea_cpuimx35/env/bin/init
index 90007cd..b56d7b5 100644
--- a/arch/arm/boards/eukrea_cpuimx35/env/bin/init
+++ b/arch/arm/boards/eukrea_cpuimx35/env/bin/init
@@ -15,12 +15,12 @@ fi
 if [ -f /env/logo.bmp ]; then
 	fb0.enable=1
 	bmp /env/logo.bmp
-	gpio_direction_out 1 1
+	gpio_set_value 1 1
 elif [ -f /env/logo.bmp.lzo ]; then
 	unlzo /env/logo.bmp.lzo /logo.bmp
 	fb0.enable=1
 	bmp /logo.bmp
-	gpio_direction_out 1 1
+	gpio_set_value 1 1
 fi
 
 if [ -z $eth0.ethaddr ]; then
diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
index 63d019a..39490cc 100644
--- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
+++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
@@ -219,7 +219,7 @@ static int eukrea_cpuimx35_console_init(void)
 		ARRAY_SIZE(eukrea_cpuimx35_pads));
 
 	/* screen default on to prevent flicker */
-	gpio_direction_output(4, 1);
+	gpio_direction_output(4, 0);
 	/* backlight default off */
 	gpio_direction_output(1, 0);
 	/* led default off */
diff --git a/arch/arm/boards/eukrea_cpuimx35/flash_header.c b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
index 285a2d4..0cb493d 100644
--- a/arch/arm/boards/eukrea_cpuimx35/flash_header.c
+++ b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
@@ -12,19 +12,18 @@ void __naked __flash_header_start go(void)
 struct imx_dcd_entry __dcd_entry_section dcd_entry[] = {
 	{ .ptr_type = 4, .addr = 0x53F80004, .val = 0x00821000, },
 	{ .ptr_type = 4, .addr = 0x53F80004, .val = 0x00821000, },
-	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x00000004, },
-	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x0000000C, },
-	{ .ptr_type = 4, .addr = 0xB8001004, .val = 0x0009572B, },
-	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0x92220000, },
-	{ .ptr_type = 1, .addr = 0x80000400, .val = 0xda, },
-	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0xA2220000, },
-	{ .ptr_type = 1, .addr = 0x80000000, .val = 0x87654321, },
-	{ .ptr_type = 1, .addr = 0x80000000, .val = 0x87654321, },
-	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0xB2220000, },
+	{ .ptr_type = 4, .addr = 0xb8001010, .val = 0x00000004, },
+	{ .ptr_type = 4, .addr = 0xb8001000, .val = 0x92100000, },
+	{ .ptr_type = 1, .addr = 0x80000400, .val = 0x12344321, },
+	{ .ptr_type = 4, .addr = 0xb8001000, .val = 0xa2100000, },
+	{ .ptr_type = 4, .addr = 0x80000000, .val = 0x12344321, },
+	{ .ptr_type = 4, .addr = 0x80000000, .val = 0x12344321, },
+	{ .ptr_type = 4, .addr = 0xb8001000, .val = 0xb2100000, },
 	{ .ptr_type = 1, .addr = 0x80000033, .val = 0xda, },
-	{ .ptr_type = 1, .addr = 0x82000000, .val = 0xda, },
-	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0x82224080, },
-	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x00000004, },
+	{ .ptr_type = 1, .addr = 0x81000000, .val = 0xff, },
+	{ .ptr_type = 4, .addr = 0xb8001000, .val = 0x82226080, },
+	{ .ptr_type = 4, .addr = 0xb8001004, .val = 0x0009572B, },
+	{ .ptr_type = 4, .addr = 0x53f80008, .val = 0x20034000, },
 };
 
 
diff --git a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
index aad334d..6c0e106 100644
--- a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
+++ b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
@@ -66,6 +66,7 @@ void __bare_init __naked board_init_lowlevel(void)
 	unsigned int *trg, *src;
 	int i;
 #endif
+	register uint32_t loops = 0x20000;
 
 	r = get_cr();
 	r |= CR_Z; /* Flow prediction (Z) */
@@ -118,7 +119,7 @@ void __bare_init __naked board_init_lowlevel(void)
 	writel(r, ccm_base + CCM_CGR0);
 
 	r = readl(ccm_base + CCM_CGR1);
-	r |= 0x00000C00;
+	r |= 0x00030C00;
 	r |= 0x00000003;
 	writel(r, ccm_base + CCM_CGR1);
 
@@ -132,31 +133,34 @@ void __bare_init __naked board_init_lowlevel(void)
 		board_init_lowlevel_return();
 
 	/* Init Mobile DDR */
+	writel(0x0000000E, ESDMISC);
 	writel(0x00000004, ESDMISC);
-	writel(0x0000000C, ESDMISC);
+	__asm__ volatile ("1:\n"
+			"subs %0, %1, #1\n"
+			"bne 1b":"=r" (loops):"0" (loops));
+
 	writel(0x0009572B, ESDCFG0);
 	writel(0x92220000, ESDCTL0);
 	writeb(0xda, IMX_SDRAM_CS0 + 0x400);
 	writel(0xA2220000, ESDCTL0);
-	writel(0x87654321, IMX_SDRAM_CS0);
-	writel(0x87654321, IMX_SDRAM_CS0);
+	writeb(0xda, IMX_SDRAM_CS0);
+	writeb(0xda, IMX_SDRAM_CS0);
 	writel(0xB2220000, ESDCTL0);
 	writeb(0xda, IMX_SDRAM_CS0 + 0x33);
 	writeb(0xda, IMX_SDRAM_CS0 + 0x2000000);
-	writel(0x82224080, ESDCTL0);
-	writel(0x00000004, ESDMISC);
+	writel(0x82228080, ESDCTL0);
 
 #ifdef CONFIG_NAND_IMX_BOOT
 	/* skip NAND boot if not running from NFC space */
 	r = get_pc();
-	if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x1000)
+	if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x800)
 		board_init_lowlevel_return();
 
 	src = (unsigned int *)IMX_NFC_BASE;
 	trg = (unsigned int *)TEXT_BASE;
 
 	/* Move ourselves out of NFC SRAM */
-	for (i = 0; i < 0x1000 / sizeof(int); i++)
+	for (i = 0; i < 0x800 / sizeof(int); i++)
 		*trg++ = *src++;
 
 	/* Jump to SDRAM */
-- 
1.7.0.4



From eric at eukrea.com  Wed Oct 13 12:46:34 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 13 Oct 2010 18:46:34 +0200
Subject: [PATCH] eukrea_cpuimx35: update defconfig
Message-ID: <1286988394-29049-1-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/configs/eukrea_cpuimx35_defconfig |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/arm/configs/eukrea_cpuimx35_defconfig b/arch/arm/configs/eukrea_cpuimx35_defconfig
index 975d095..1c0ad98 100644
--- a/arch/arm/configs/eukrea_cpuimx35_defconfig
+++ b/arch/arm/configs/eukrea_cpuimx35_defconfig
@@ -1,6 +1,5 @@
 CONFIG_ARCH_IMX=y
 CONFIG_CACHE_L2X0=y
-CONFIG_ARCH_IMX_INTERNAL_BOOT=y
 CONFIG_ARCH_IMX35=y
 CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
 CONFIG_MMU=y
@@ -8,8 +7,11 @@ CONFIG_MALLOC_SIZE=0x800000
 CONFIG_LONGHELP=y
 CONFIG_GLOB=y
 CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_HUSH_GETOPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
+# CONFIG_CONSOLE_ACTIVATE_FIRST is not set
+CONFIG_CONSOLE_ACTIVATE_ALL=y
 CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/eukrea_cpuimx35/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
@@ -22,6 +24,7 @@ CONFIG_CMD_ECHO_E=y
 CONFIG_CMD_LOADB=y
 CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
 CONFIG_CMD_MTEST=y
 CONFIG_CMD_FLASH=y
 CONFIG_CMD_RESET=y
-- 
1.7.0.4



From carsten.schlote at gmx.net  Thu Oct 14 07:06:42 2010
From: carsten.schlote at gmx.net (Carsten Schlote)
Date: Thu, 14 Oct 2010 13:06:42 +0200
Subject: [PATCH 1/5] [ppc/mpc5xxx] Fixed typo in cpu_init.c
Message-ID: <1287054406-31713-1-git-send-email-carsten.schlote@gmx.net>

From: Carsten Schlote <c.schlote at konzeptpark.de>

- Fixed typo, which assigns CS5 start address to CS7

Signed-off-by: Carsten Schlote <c.schlote at konzeptpark.de>
---
 arch/ppc/mach-mpc5xxx/cpu_init.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/ppc/mach-mpc5xxx/cpu_init.c b/arch/ppc/mach-mpc5xxx/cpu_init.c
index fc5db0e..4ec5cba 100644
--- a/arch/ppc/mach-mpc5xxx/cpu_init.c
+++ b/arch/ppc/mach-mpc5xxx/cpu_init.c
@@ -119,7 +119,7 @@ int cpu_init(void)
 #endif
 
 #if defined(CFG_CS7_START) && defined(CFG_CS7_SIZE)
-	*(vu_long *)MPC5XXX_CS7_START = START_REG(CFG_CS5_START);
+	*(vu_long *)MPC5XXX_CS7_START = START_REG(CFG_CS7_START);
 	*(vu_long *)MPC5XXX_CS7_STOP = STOP_REG(CFG_CS7_START, CFG_CS7_SIZE);
 	addecr |= (1 << 27);
 #endif
-- 
1.7.2.2.277.gb49c4



From carsten.schlote at gmx.net  Thu Oct 14 07:06:43 2010
From: carsten.schlote at gmx.net (Carsten Schlote)
Date: Thu, 14 Oct 2010 13:06:43 +0200
Subject: [PATCH 2/5] [ppc/mpc5xxx] Small text cleanups and ADDECR to output
In-Reply-To: <1287054406-31713-1-git-send-email-carsten.schlote@gmx.net>
References: <1287054406-31713-1-git-send-email-carsten.schlote@gmx.net>
Message-ID: <1287054406-31713-2-git-send-email-carsten.schlote@gmx.net>

From: Carsten Schlote <c.schlote at konzeptpark.de>

Trivial.

Signed-off-by: Carsten Schlote <c.schlote at konzeptpark.de>
---
 arch/ppc/mach-mpc5xxx/reginfo.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/ppc/mach-mpc5xxx/reginfo.c b/arch/ppc/mach-mpc5xxx/reginfo.c
index 92a1b59..7d1ef64 100644
--- a/arch/ppc/mach-mpc5xxx/reginfo.c
+++ b/arch/ppc/mach-mpc5xxx/reginfo.c
@@ -4,8 +4,9 @@
 
 void reginfo(void)
 {
-	puts ("\nMPC5200 registers\n");
+	puts ("\nMPC5xxx registers\n");
 	printf ("MBAR=%08x\n", CFG_MBAR);
+	printf ("ADDECR=%08x\n", *(volatile ulong*)MPC5XXX_ADDECR);
 	puts ("Memory map registers\n");
 	printf ("\tCS0: start %08X\tstop %08X\tconfig %08X\ten %d\n",
 		*(volatile ulong*)MPC5XXX_CS0_START,
-- 
1.7.2.2.277.gb49c4



From carsten.schlote at gmx.net  Thu Oct 14 07:06:45 2010
From: carsten.schlote at gmx.net (Carsten Schlote)
Date: Thu, 14 Oct 2010 13:06:45 +0200
Subject: [PATCH 4/5] [compiler] Added OPTIMIZE options to enable GCC optimizer
In-Reply-To: <1287054406-31713-3-git-send-email-carsten.schlote@gmx.net>
References: <1287054406-31713-1-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-2-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-3-git-send-email-carsten.schlote@gmx.net>
Message-ID: <1287054406-31713-4-git-send-email-carsten.schlote@gmx.net>

From: Carsten Schlote <c.schlote at konzeptpark.de>

With GCC 4.5.x the default option -Os causes problems on powerpc as it
tries to move common code to libgcc2, which isn't correctly linked later.

With optimizer turned off, code compiles fine.

So I added some options to turn on/off optimization for all architectures
and to choose between -Os and -O option.

In case your compiler produces broken code or refuses to link, just try
without optimization. As it's an option no hack in the Makefile is required
anymore.

Signed-off-by: Carsten Schlote <c.schlote at konzeptpark.de>
---
 Makefile               |    2 +-
 arch/arm/Makefile      |    8 ++++++++
 arch/blackfin/Makefile |    7 +++++++
 arch/m68k/Makefile     |    7 +++++++
 arch/ppc/Makefile      |    8 ++++++++
 arch/sandbox/Makefile  |    8 ++++++++
 arch/x86/Makefile      |    8 ++++++++
 common/Kconfig         |   13 +++++++++++++
 8 files changed, 60 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 2442b5d..527b0a4 100644
--- a/Makefile
+++ b/Makefile
@@ -295,7 +295,7 @@ LINUXINCLUDE    := -Iinclude \
 CPPFLAGS        := -D__KERNEL__ -D__BAREBOX__ $(LINUXINCLUDE) -fno-builtin -ffreestanding
 
 CFLAGS          := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-                   -fno-strict-aliasing -fno-common -Os -pipe
+                   -fno-strict-aliasing -fno-common -pipe
 AFLAGS          := -D__ASSEMBLY__
 
 LDFLAGS		:= -Map barebox.map
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index e542c03..f94418d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -3,6 +3,14 @@ CPPFLAGS	+= -D__ARM__ -fno-strict-aliasing
 # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
 CPPFLAGS	+=$(call cc-option,-marm,)
 
+ifdef CONFIG_OPTIMIZE
+ifdef CONFIG_OPTIMIZE_SIZE
+CPPFLAGS += -Os
+else
+CPPFLAGS += -O
+endif
+endif
+
 ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
 CPPFLAGS	+= -mbig-endian
 AS		+= -EB
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index 902268d..a4f4b7d 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -1,6 +1,13 @@
 
 CPPFLAGS += -fno-strict-aliasing
 
+ifdef CONFIG_OPTIMIZE
+ifdef CONFIG_OPTIMIZE_SIZE
+CPPFLAGS += -Os
+else
+CPPFLAGS += -O
+endif
+endif
 
 board-$(CONFIG_MACH_IPE337)	:= ipe337
 cpu-$(CONFIG_BF561)		:= bf561
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
index ec70028..1366b4c 100644
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -21,6 +21,13 @@
 CPPFLAGS += -isystem $(gccincdir) -D __M68K__ \
 	-fno-strict-aliasing
 
+ifdef CONFIG_OPTIMIZE
+ifdef CONFIG_OPTIMIZE_SIZE
+CPPFLAGS += -Os
+else
+CPPFLAGS += -O
+endif
+endif
 
 machine-$(CONFIG_ARCH_MCF54xx)	   := mcfv4e
 board-$(CONFIG_MACH_KPUKDR1)	   := kp_ukd_r1
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index e843ed5..f2f3e4f 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -7,6 +7,14 @@ ifdef CONFIG_RELOCATABLE
 CPPFLAGS += -fPIC -mrelocatable
 endif
 
+ifdef CONFIG_OPTIMIZE
+ifdef CONFIG_OPTIMIZE_SIZE
+CPPFLAGS += -Os
+else
+CPPFLAGS += -O
+endif
+endif
+
 machine-$(CONFIG_ARCH_MPC5200)			:= mpc5200
 board-$(CONFIG_MACH_PHYCORE_MPC5200B_TINY)	:= pcm030
 board-$(CONFIG_MACH_KONZEPTPARK_MCB2)		:= kp-mcb2
diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile
index 4ca17ed..a9dfb53 100644
--- a/arch/sandbox/Makefile
+++ b/arch/sandbox/Makefile
@@ -1,6 +1,14 @@
 
 CPPFLAGS += -fno-strict-aliasing
 
+ifdef CONFIG_OPTIMIZE
+ifdef CONFIG_OPTIMIZE_SIZE
+CPPFLAGS += -Os
+else
+CPPFLAGS += -O
+endif
+endif
+
 machine-y := sandbox
 
 board-y := arch/sandbox/board
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 57c5dbc..ec2237b 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -1,5 +1,13 @@
 CPPFLAGS += -D__X86__ -fno-strict-aliasing
 
+ifdef CONFIG_OPTIMIZE
+ifdef CONFIG_OPTIMIZE_SIZE
+CPPFLAGS += -Os
+else
+CPPFLAGS += -O
+endif
+endif
+
 board-y := x86_generic
 machine-y := i386
 
diff --git a/common/Kconfig b/common/Kconfig
index 6556c62..04f386d 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -167,6 +167,19 @@ config RELOCATABLE
 	  allowing it to relocate to the end of the available RAM. This
 	  way you have the whole memory in a single piece.
 
+config OPTIMIZE_CODE
+	bool "enable compiler optimizations"
+	help
+	  Enable GCC compiler optimizations.
+
+config OPTIMIZE_SIZE
+	bool "compile size-optimized barebox binary (-Os)"
+	depends on OPTIMIZE_CODE
+	help
+	  This option will enable the size optimizations of GCC. This will
+	  break the build process with GCC 4.5.x as it references libgcc2
+	  in this case.
+
 config MACH_HAS_LOWLEVEL_INIT
 	bool
 
-- 
1.7.2.2.277.gb49c4



From carsten.schlote at gmx.net  Thu Oct 14 07:06:46 2010
From: carsten.schlote at gmx.net (Carsten Schlote)
Date: Thu, 14 Oct 2010 13:06:46 +0200
Subject: [PATCH 5/5] [drivers/nor] Fixed mismatch in prototype
In-Reply-To: <1287054406-31713-4-git-send-email-carsten.schlote@gmx.net>
References: <1287054406-31713-1-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-2-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-3-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-4-git-send-email-carsten.schlote@gmx.net>
Message-ID: <1287054406-31713-5-git-send-email-carsten.schlote@gmx.net>

From: Carsten Schlote <c.schlote at konzeptpark.de>

Trivial mismatch between cfi_flash.h and function in cfi_flash.c

Signed-off-by: Carsten Schlote <c.schlote at konzeptpark.de>
---
 drivers/nor/cfi_flash.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index fa5e5ee..7b9f06c 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -634,7 +634,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
 	return flash_write_cfiword (info, wp, cword);
 }
 
-static int flash_real_protect (struct flash_info *info, long sector, int prot)
+int flash_real_protect (struct flash_info *info, long sector, int prot)
 {
 	int retcode = 0;
 
-- 
1.7.2.2.277.gb49c4



From carsten.schlote at gmx.net  Thu Oct 14 07:06:44 2010
From: carsten.schlote at gmx.net (Carsten Schlote)
Date: Thu, 14 Oct 2010 13:06:44 +0200
Subject: [PATCH 3/5] [kp-mcb2] Added board files and configs for konzeptpark
	mcb2
In-Reply-To: <1287054406-31713-2-git-send-email-carsten.schlote@gmx.net>
References: <1287054406-31713-1-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-2-git-send-email-carsten.schlote@gmx.net>
Message-ID: <1287054406-31713-3-git-send-email-carsten.schlote@gmx.net>

From: Carsten Schlote <c.schlote at konzeptpark.de>

Added board specific files and config changes for konzeptpark MCB2
hardware.

Derived from pcm030 hardware.

Signed-off-by: Carsten Schlote <c.schlote at konzeptpark.de>
---
 arch/ppc/Kconfig                        |   11 +
 arch/ppc/Makefile                       |    2 +-
 arch/ppc/boards/kp-mcb2/Makefile        |    2 +
 arch/ppc/boards/kp-mcb2/barebox.lds.S   |  139 ++++++++++++
 arch/ppc/boards/kp-mcb2/config.h        |  253 ++++++++++++++++++++++
 arch/ppc/boards/kp-mcb2/kp-mcb2.c       |  349 +++++++++++++++++++++++++++++++
 arch/ppc/boards/kp-mcb2/kp-mcb2.dox     |    8 +
 arch/ppc/boards/kp-mcb2/mt46v32m16-75.h |   46 ++++
 arch/ppc/mach-mpc5xxx/Kconfig           |    5 +-
 9 files changed, 812 insertions(+), 3 deletions(-)
 create mode 100644 arch/ppc/boards/kp-mcb2/Makefile
 create mode 100644 arch/ppc/boards/kp-mcb2/barebox.lds.S
 create mode 100644 arch/ppc/boards/kp-mcb2/config.h
 create mode 100644 arch/ppc/boards/kp-mcb2/kp-mcb2.c
 create mode 100644 arch/ppc/boards/kp-mcb2/kp-mcb2.dox
 create mode 100644 arch/ppc/boards/kp-mcb2/mt46v32m16-75.h

diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index cda14de..32aa3ea 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1,11 +1,13 @@
 
 config BOARDINFO
 	default "Phytec Phycore mpc5200b tiny" if MACH_PHYCORE_MPC5200B_TINY
+	default "konzeptpark MCB2" if MACH_KONZEPTPARK_MCB2
 	
 config ARCH_TEXT_BASE
 	hex
 	default 0x00000000 if RELOCATABLE
 	default 0x01000000 if MACH_PHYCORE_MPC5200B_TINY
+	default 0x01000000 if MACH_KONZEPTPARK_MCB2
 
 config MPC5XXX_EARLY_CONSOLE
 	bool
@@ -55,6 +57,15 @@ config MACH_PHYCORE_MPC5200B_TINY
 	help
 	  Say Y here if you are using the Phytec Phycore MPC5200B Tiny
 	  board aka pcm030
+
+config MACH_KONZEPTPARK_MCB2
+	bool "konzeptpark MCB2"
+	select ARCH_MPC5200
+	select MPC5200
+	select MPC5xxx
+	select HAS_CFI
+	help
+	  Say Y here if you are using the konzeptpark MCB2 board
 endchoice
 
 source arch/ppc/mach-mpc5xxx/Kconfig
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 46d64e5..e843ed5 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -7,9 +7,9 @@ ifdef CONFIG_RELOCATABLE
 CPPFLAGS += -fPIC -mrelocatable
 endif
 
-
 machine-$(CONFIG_ARCH_MPC5200)			:= mpc5200
 board-$(CONFIG_MACH_PHYCORE_MPC5200B_TINY)	:= pcm030
+board-$(CONFIG_MACH_KONZEPTPARK_MCB2)		:= kp-mcb2
 cpu-$(CONFIG_ARCH_MPC5200)			:= mpc5xxx
 
 TEXT_BASE = $(CONFIG_TEXT_BASE)
diff --git a/arch/ppc/boards/kp-mcb2/Makefile b/arch/ppc/boards/kp-mcb2/Makefile
new file mode 100644
index 0000000..78d1120
--- /dev/null
+++ b/arch/ppc/boards/kp-mcb2/Makefile
@@ -0,0 +1,2 @@
+obj-y += kp-mcb2.o
+extra-y += barebox.lds
diff --git a/arch/ppc/boards/kp-mcb2/barebox.lds.S b/arch/ppc/boards/kp-mcb2/barebox.lds.S
new file mode 100644
index 0000000..ab99335
--- /dev/null
+++ b/arch/ppc/boards/kp-mcb2/barebox.lds.S
@@ -0,0 +1,139 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm-generic/barebox.lds.h>
+
+OUTPUT_ARCH("powerpc")
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  . = TEXT_BASE;
+
+  /* Read-only sections, merged into text segment: */
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    arch/ppc/mach-mpc5xxx/start.o	(.text)
+    *(.text*)
+    *(.got1*)
+    . = ALIGN(16);
+    *(.rodata*)
+    *(.rodata1*)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _etext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+
+  .data    :
+  {
+    *(.data*)
+    *(.data1*)
+    *(.sdata*)
+    *(.sdata2*)
+    *(.dynamic*)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  . = .;
+  __barebox_cmd_start = .;
+  .barebox_cmd : { BAREBOX_CMDS }
+  __barebox_cmd_end = .;
+
+  __barebox_initcalls_start = .;
+  .barebox_initcalls : { INITCALLS }
+  __barebox_initcalls_end = .;
+  __initcall_entries = (__barebox_initcalls_end - __barebox_initcalls_start) >> 2;
+
+  __usymtab_start = .;
+  __usymtab : { BAREBOX_SYMS }
+  __usymtab_end = .;
+
+  __early_init_data_begin = .;
+  .early_init_data : { *(.early_init_data) }
+  __early_init_data_end = .;
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __init_size = __init_end - _start;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss*) *(.scommon*)
+   *(.dynbss*)
+   *(.bss*)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/arch/ppc/boards/kp-mcb2/config.h b/arch/ppc/boards/kp-mcb2/config.h
new file mode 100644
index 0000000..c3aa86c
--- /dev/null
+++ b/arch/ppc/boards/kp-mcb2/config.h
@@ -0,0 +1,253 @@
+/*
+ * (C) Copyright 2003-2005
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * (C) Copyright 2006
+ * Eric Schumann, Phytec Messatechnik GmbH
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <mach/mpc5xxx.h>
+
+/* #define DEBUG */
+
+/*------------------------------------------------------------------------------------------------------------------------------------------------------
+High Level Configuration Options
+(easy to change)
+ ------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CONFIG_MPC5200_DDR	1	/* (with DDR-SDRAM) */
+#define CFG_MPC5XXX_CLKIN	33333000 /* ... running at 33.333333MHz */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH  */
+#define BOOTFLAG_WARM		0x02	/* Software reboot	     */
+
+/*------------------------------------------------------------------------------------------------------------------------------------------------------
+Serial console configuration
+ ------------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+#if (TEXT_BASE == 0xFF000000)		/* Boot low */
+#define CFG_LOWBOOT		1
+#endif
+/* RAMBOOT will be defined automatically in memory section */
+
+/*------------------------------------------------------------------------------------------------------------------------------------------------------
+IPB Bus clocking configuration.
+ ------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define  CFG_IPBSPEED_133		/* define for 133MHz speed */
+#if defined(CFG_IPBSPEED_133)
+/*
+ * PCI Bus clocking configuration
+ *
+ * Actually a PCI Clock of 66 MHz is only set (in cpu_init.c) if
+ * CFG_IPBSPEED_133 is defined. This is because a PCI Clock of 66 MHz yet hasn't
+ * been tested with a IPB Bus Clock of 66 MHz.
+ */
+#define CFG_PCISPEED_66		/* define for 66MHz speed */
+#else
+#undef CFG_PCISPEED_66			/* for 33MHz speed */
+#endif
+
+/* we only use CS-Boot */
+#define CFG_BOOTCS_START	0xFE000000
+#define CFG_BOOTCS_SIZE		0x02000000
+
+//#define CFG_BOOTCS_CFG	0x0008FD00
+/* one additional waitstate for the 33MHz statemachine */
+#define CFG_BOOTCS_CFG	0x0001dd00
+
+#define CFG_CS0_START		CFG_BOOTCS_START
+#define CFG_CS0_SIZE		CFG_BOOTCS_SIZE
+//#define CFG_CS0_CFG		0x0001dd00
+
+/* Konzeptpark MCB2 Mainboard Additions */
+#define CFG_CS1_START           0xfd310000
+#define CFG_CS1_SIZE            0x00010000
+#define CFG_CS1_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
+
+#define CFG_CS2_START           0xfd320000
+#define CFG_CS2_SIZE            0x00010000
+#define CFG_CS2_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
+
+#define CFG_CS3_START           0xfd330000
+#define CFG_CS3_SIZE            0x00010000
+#define CFG_CS3_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
+
+
+/* Konzeptpark MCB2 Topboard Additions */
+#define CFG_CS4_START           0xfd400000
+#define CFG_CS4_SIZE            0x00010000
+#define CFG_CS4_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
+
+#define CFG_CS5_START           0xfd410000
+#define CFG_CS5_SIZE            0x00010000
+#define CFG_CS5_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
+
+#define CFG_CS6_START           0xfd420000
+#define CFG_CS6_SIZE            0x00010000
+#define CFG_CS6_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
+
+#define CFG_CS7_START           0xfd430000
+#define CFG_CS7_SIZE            0x00010000
+#define CFG_CS7_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
+
+/*
+ * Use also hardware protection. This seems required, as the BDI uses hardware protection
+ * Without this, U-Boot can't work with this sectors, as its protection is software only by default
+ */
+#define CFG_FLASH_PROTECTION	1
+#define CFG_FLASH_EMPTY_INFO
+
+/*------------------------------------------------------------------------------------------------------------------------------------------------------
+  Memory map
+ ------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CFG_MBAR		0xF0000000 /* MBAR hast to be switched by other bootloader or debugger config  */
+#define CFG_SDRAM_BASE		0x00000000
+
+/* Use SRAM until RAM will be available */
+#define CFG_INIT_RAM_ADDR	MPC5XXX_SRAM
+#define CFG_INIT_RAM_SIZE	MPC5XXX_SRAM_SIZE	/* End of used area in DPRAM */
+#define CONFIG_EARLY_INITDATA_SIZE 0x100
+
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+
+/*------------------------------------------------------------------------------------------------------------------------------------------------------
+ GPIO configuration
+ ------------------------------------------------------------------------------------------------------------------------------------------------------*/
+//#define CFG_GPS_PORT_CONFIG	0x00558c10 /* PSC6=UART, PSC3=UART ; Ether=100MBit with MD */
+/*
+ * GPIO configuration
+ *
+ * Pin mapping:
+ *
+ * [29:31] = 01x
+ * PSC1_0 -> AC97 SDATA out
+ * PSC1_1 -> AC97 SDTA in
+ * PSC1_2 -> AC97 SYNC out
+ * PSC1_3 -> AC97 bitclock out
+ * PSC1_4 -> AC97 reset out
+ *
+ * [25:27] = 001
+ * PSC2_0 -> CAN 1 Tx out
+ * PSC2_1 -> CAN 1 Rx in
+ * PSC2_2 -> CAN 2 Tx out
+ * PSC2_3 -> CAN 2 Rx in
+ * PSC2_4 -> GPIO (claimed for ATA reset, active low)
+ *
+ * [20:23] = 1100
+ * PSC3_0 -> UART Tx out
+ * PSC3_1 -> UART Rx in
+ * PSC3_2 -> UART RTS (in/out FIXME)
+ * PSC3_3 -> UART CTS (in/out FIXME)
+ * PSC3_4 -> LocalPlus Bus CS6 \
+ * PSC3_5 -> LocalPlus Bus CS7 / --> see [4] and [5]
+ * PSC3_6 -> dedicated SPI MOSI out (master case)
+ * PSC3_7 -> dedicated SPI MISO in (master case)
+ * PSC3_8 -> dedicated SPI SS out (master case)
+ * PSC3_9 -> dedicated SPI CLK out (master case)
+ *
+ * [18:19] = 01
+ * USB_0 -> USB OE out
+ * USB_1 -> USB Tx- out
+ * USB_2 -> USB Tx+ out
+ * USB_3 -> USB RxD (in/out FIXME)
+ * USB_4 -> USB Rx+ in
+ * USB_5 -> USB Rx- in
+ * USB_6 -> USB PortPower out
+ * USB_7 -> USB speed out
+ * USB_8 -> USB suspend (in/out FIXME)
+ * USB_9 -> USB overcurrent in
+ *
+ * [17] = 0
+ * USB differential mode
+ *
+ * [16] = 0
+ * PCI enabled
+ *
+ * [12:15] = 0101
+ * ETH_0 -> ETH Txen
+ * ETH_1 -> ETH TxD0
+ * ETH_2 -> ETH TxD1
+ * ETH_3 -> ETH TxD2
+ * ETH_4 -> ETH TxD3
+ * ETH_5 -> ETH Txerr
+ * ETH_6 -> ETH MDC
+ * ETH_7 -> ETH MDIO
+ * ETH_8 -> ETH RxDv
+ * ETH_9 -> ETH RxCLK
+ * ETH_10 -> ETH Collision
+ * ETH_11 -> ETH TxD
+ * ETH_12 -> ETH RxD0
+ * ETH_13 -> ETH RxD1
+ * ETH_14 -> ETH RxD2
+ * ETH_15 -> ETH RxD3
+ * ETH_16 -> ETH Rxerr
+ * ETH_17 -> ETH CRS
+ *
+ * [9:11] = 101
+ * PSC6_0 -> UART RxD in
+ * PSC6_1 -> UART CTS (in/out FIXME)
+ * PSC6_2 -> UART TxD out
+ * PSC6_3 -> UART RTS (in/out FIXME)
+ *
+ * [2:3/6:7] = 00/11
+ * TMR_0 -> ATA_CS0 out
+ * TMR_1 -> ATA_CS1 out
+ * TMR_2 -> GPIO
+ * TMR_3 -> GPIO
+ * TMR_4 -> GPIO
+ * TMR_5 -> GPIO
+ * TMR_6 -> GPIO
+ * TMR_7 -> GPIO
+ * I2C_0 -> I2C 1 Clock out
+ * I2C_1 -> I2C 1 IO in/out
+ * I2C_2 -> I2C 2 Clock out
+ * I2C_3 -> I2C 2 IO in/out
+ *
+ * [4] = 1
+ * PSC3_5 is used as CS7
+ *
+ * [5] = 1
+ * PSC3_4 is used as CS6
+ *
+ * [1] = 0
+ * gpio_wkup_7 is GPIO
+ *
+ * [0] = 0
+ * gpio_wkup_6 is GPIO
+ *
+ */
+#define CFG_GPS_PORT_CONFIG	0x0f551c12
+
+/*------------------------------------------------------------------------------------------------------------------------------------------------------
+ Various low-level settings
+ ------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CFG_HID0_INIT		HID0_ICE | HID0_ICFI
+#define CFG_HID0_FINAL		HID0_ICE
+
+#define CFG_CS_BURST		0x00000000
+#define CFG_CS_DEADCYCLE	0x33333333
+
+#define OF_CPU			"PowerPC,5200 at 0"
+#define OF_TBCLK		CFG_MPC5XXX_CLKIN
+#define OF_SOC                  "soc5200 at f0000000"
+
+#endif /* __CONFIG_H */
diff --git a/arch/ppc/boards/kp-mcb2/kp-mcb2.c b/arch/ppc/boards/kp-mcb2/kp-mcb2.c
new file mode 100644
index 0000000..f4574c1
--- /dev/null
+++ b/arch/ppc/boards/kp-mcb2/kp-mcb2.c
@@ -0,0 +1,349 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * (C) Copyright 2004
+ * Mark Jonas, Freescale Semiconductor, mark.jonas at motorola.com.
+ *
+ * (C) Copyright 2006
+ * Eric Schumann, Phytec Messtechnik GmbH
+ *
+ * (C) Copyright 2010
+ * Carsten Schlote, konzeptpark GmbH
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#define DEBUG
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <mach/mpc5xxx.h>
+#include <mach/fec.h>
+#include <types.h>
+#include <partition.h>
+#include <mem_malloc.h>
+#include <reloc.h>
+
+int cfi_flash_hwdetect (struct device_d *cfi_dev)
+{
+	int width, id=0;
+	ulong mb=0, dev_size;
+	ulong base = 0xfe000000;
+	ulong lpb;
+
+	debug("BootCS: cfg=%08x\n", *(vu_long *)MPC5XXX_BOOTCS_CFG );
+	debug("CS0: cfg=%08x\n", *(vu_long *)MPC5XXX_CS0_CFG );
+	debug("*%08x = %04x\n", (vu_short *)base+0x100, *(vu_short *)base );
+
+	lpb = *(vu_long *)MPC5XXX_CS0_CFG;
+
+	*(vu_long *)MPC5XXX_BOOTCS_START = START_REG(base);
+	*(vu_long *)MPC5XXX_BOOTCS_STOP = STOP_REG(base, 32 * 1024 * 1024);
+	/*
+	 * we run the PCI bus with 33 1/3 MHz. The flash requires 75ns accesstime.
+	 * 2 base waitstates plus one additional waitstate makes the access as fast
+	 * as possible (=90ns)
+	 */
+	lpb &=  0x0000dfc0; /* make it writable and mask out wait stages */
+	lpb |=  0x0001d000; /* adjust wait stages */
+	*(vu_long *)MPC5XXX_CS0_CFG = lpb;
+
+	/* get flash width */
+	width = (lpb >> 8) & 0x3;
+
+	switch (width) {
+	case 0: /* 8 bit */
+		*(vu_char *)base = 0x90;
+		id = *(vu_char *)(base + 3);
+		*(vu_char *)base = 0xff;
+		break;
+	case 1: /* 16 bit */
+		debug("*%08x = %04x\n", (vu_short *)base, *(vu_short *)base );
+		*(vu_short *)base = 0x90;
+		debug("*%08x = %04x\n", (vu_short *)base, *(vu_short *)base );
+		id = *(vu_short *)(base + 2) & 0xff;
+		debug("*%08x = %04x\n", (vu_short *)base, *(vu_short *)base );
+		*(vu_short *)base = 0xff;
+		debug("*%08x = %04x\n", (vu_short *)base, *(vu_short *)base );
+		break;
+	case 3: /* 32 bit */
+		*(vu_short *)base = 0x90;
+		id = *(vu_short *)(base + 4) & 0xff;
+		*(vu_short *)base = 0xff;
+		break;
+	}
+
+	switch (id) {
+	case 0x16:
+		mb = 4;
+		break;
+	case 0x17:
+		mb = 8;
+		break;
+	case 0x18:
+		mb = 16;
+		break;
+	case 0x20:
+		mb = 8;
+		break;
+	case 0x21:
+		mb = 16;
+		break;
+	case 0x22:
+		mb = 32;
+		break;
+	}
+
+	/* On these boards everything which is 32bit wide consists
+	 * of two 16bit Flashes
+	 */
+	if (width == 3)
+		mb <<= 1;
+
+	/*
+	 * On this platform one chip select can only handle up to 32MiB.
+	 * So we must limit boot cs's baseaddress to 0xfe000000 and above
+         */
+	if (mb > 32)
+		dev_size = 32;
+	else
+		dev_size = mb;
+
+	debug("Flash configurator: width=%x id=%x dev_size=%d\n", width, id, dev_size);
+	if (dev_size) {
+		*(vu_long *)MPC5XXX_BOOTCS_START = START_REG(0x0u - (dev_size << 20));
+		*(vu_long *)MPC5XXX_BOOTCS_STOP = STOP_REG(0x0u - (dev_size << 20), (dev_size << 20));
+
+		/*
+		 * the developer is responsible to setup other chip select lines to
+		 * reach other parts of the device if its larger than 32MiB
+		 */
+	}
+	cfi_dev->map_base = 0x0u - (dev_size << 20);
+	cfi_dev->size = (dev_size << 20);
+	
+	debug("BootCS: cfg=%08x\n", *(vu_long *)MPC5XXX_BOOTCS_CFG );
+	debug("CS0: cfg=%08x\n", *(vu_long *)MPC5XXX_CS0_CFG );
+
+	return 0;
+}
+
+struct device_d cfi_dev = {
+	.name     = "cfi_flash",
+	.map_base = 0xfe000000,
+	.size     = 32 * 1024 * 1024,
+};
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+struct device_d sdram_dev = {
+	.name     = "mem",
+	.map_base = 0x0,
+	.size     = 128 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+static struct mpc5xxx_fec_platform_data fec_info = {
+	.xcv_type = MII100,
+};
+
+struct device_d eth_dev = {
+	.name		= "fec_mpc5xxx",
+	.map_base	= MPC5XXX_FEC,
+	.platform_data	= &fec_info,
+};
+
+static int devices_init (void)
+{
+	cfi_flash_hwdetect(&cfi_dev);
+	if (cfi_dev.size)
+		register_device(&cfi_dev);
+	register_device(&sdram_dev);
+	register_device(&eth_dev);
+
+	devfs_add_partition("nor0", 0x00000000, 0x0040000, PARTITION_FIXED, "bb-low");
+	devfs_add_partition("nor0", 0x00040000, 0x1d00000, PARTITION_FIXED, "filesystem");
+	devfs_add_partition("nor0", 0x01d40000, 0x01c0000, PARTITION_FIXED, "kernel");
+	devfs_add_partition("nor0", 0x01f00000, 0x0080000, PARTITION_FIXED, "self0");
+	devfs_add_partition("nor0", 0x01f80000, 0x0020000, PARTITION_FIXED, "dev-tree");
+	devfs_add_partition("nor0", 0x01fa0000, 0x0040000, PARTITION_FIXED, "env0");
+
+	return 0;
+}
+
+device_initcall(devices_init);
+
+static struct device_d psc3 = {
+	.name     = "mpc5xxx_serial",
+	.map_base = MPC5XXX_PSC3,
+	.size     = 4096,
+};
+
+static struct device_d psc6 = {
+	.name     = "mpc5xxx_serial",
+	.map_base = MPC5XXX_PSC6,
+	.size     = 4096,
+};
+
+static int console_init(void)
+{
+	register_device(&psc3);
+	register_device(&psc6);
+	return 0;
+}
+
+console_initcall(console_init);
+
+void *get_early_console_base(const char *name)
+{
+	if (!strcmp(name, RELOC("psc3")))
+		return (void *)MPC5XXX_PSC3;
+	if (!strcmp(name, RELOC("psc6")))
+		return (void *)MPC5XXX_PSC6;
+	return NULL;
+}
+
+#include "mt46v32m16-75.h"
+
+static void sdram_start (int hi_addr)
+{
+	long hi_addr_bit = hi_addr ? 0x01000000 : 0;
+
+	/* unlock mode register */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
+	__asm__ volatile ("sync");
+
+	/* precharge all banks */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
+	__asm__ volatile ("sync");
+
+#if SDRAM_DDR
+	/* set mode register: extended mode */
+	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
+	__asm__ volatile ("sync");
+
+	/* set mode register: reset DLL */
+	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
+	__asm__ volatile ("sync");
+#endif
+
+	/* precharge all banks */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
+	__asm__ volatile ("sync");
+
+	/* auto refresh */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
+	__asm__ volatile ("sync");
+
+	/* set mode register */
+	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
+	__asm__ volatile ("sync");
+
+	/* normal operation */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
+	__asm__ volatile ("sync");
+}
+
+/*
+ * ATTENTION: Although partially referenced initdram does NOT make real use
+ *            use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
+ *            is something else than 0x00000000.
+ */
+
+long int initdram (int board_type)
+{
+	ulong dramsize = 0;
+	ulong dramsize2 = 0;
+
+	ulong test1, test2;
+
+	if ((ulong)RELOC(initdram) > (2 << 30)) {
+		/* setup SDRAM chip selects */
+		*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001b;/* 256MB at 0x0 */
+		*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x10000000;/* disabled */
+		__asm__ volatile ("sync");
+
+		/* setup config registers */
+		*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
+		*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
+		__asm__ volatile ("sync");
+
+#if SDRAM_DDR && SDRAM_TAPDELAY
+		/* set tap delay */
+		*(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
+		__asm__ volatile ("sync");
+#endif
+
+		/* find RAM size using SDRAM CS0 only */
+		sdram_start(0);
+		test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x10000000);
+		sdram_start(1);
+		test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x10000000);
+		if (test1 > test2) {
+			sdram_start(0);
+			dramsize = test1;
+		} else {
+			dramsize = test2;
+		}
+
+		/* memory smaller than 1MB is impossible */
+		if (dramsize < (1 << 20)) {
+			dramsize = 0;
+		}
+
+		/* set SDRAM CS0 size according to the amount of RAM found */
+		if (dramsize > 0) {
+			*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1;
+		} else {
+			*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
+		}
+	} else
+		puts(RELOC("skipping sdram initialization\n"));
+
+	/* retrieve size of memory connected to SDRAM CS0 */
+	dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
+	if (dramsize >= 0x13) {
+		dramsize = (1 << (dramsize - 0x13)) << 20;
+	} else {
+		dramsize = 0;
+	}
+
+	/* retrieve size of memory connected to SDRAM CS1 */
+	dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
+	if (dramsize2 >= 0x13) {
+		dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
+	} else {
+		dramsize2 = 0;
+	}
+
+	return dramsize + dramsize2;
+}
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+	ft_cpu_setup(blob, bd);
+}
+#endif
+
diff --git a/arch/ppc/boards/kp-mcb2/kp-mcb2.dox b/arch/ppc/boards/kp-mcb2/kp-mcb2.dox
new file mode 100644
index 0000000..db64ba9
--- /dev/null
+++ b/arch/ppc/boards/kp-mcb2/kp-mcb2.dox
@@ -0,0 +1,8 @@
+/** @page kp-mcb2 konzeptpark MCB2
+
+This CPU card is based on a Freescale MPC5200B CPU. The card is shipped with:
+
+- 32MiB NOR type Flash Memory
+- 128MiB synchronous dynamic RAM
+
+*/
diff --git a/arch/ppc/boards/kp-mcb2/mt46v32m16-75.h b/arch/ppc/boards/kp-mcb2/mt46v32m16-75.h
new file mode 100644
index 0000000..4d191f1
--- /dev/null
+++ b/arch/ppc/boards/kp-mcb2/mt46v32m16-75.h
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2004
+ * Mark Jonas, Freescale Semiconductor, mark.jonas at motorola.com.
+ *
+ * Eric Schumann, Phytec Messtechnik
+ * adapted for mt46v32m16-75 DDR-RAM
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#define SDRAM_DDR	1		/* is DDR */
+
+/* Settings for XLB = 132 MHz */
+#define SDRAM_MODE	0x018D0000
+#define SDRAM_EMODE	0x40090000
+#define SDRAM_CONTROL	0x715f0f00
+#define SDRAM_CONFIG1	0x73722930
+#define SDRAM_CONFIG2	0x47770000
+
+
+/* Settings for XLB = 99 MHz */
+/*
+#define SDRAM_MODE	0x008D0000
+#define SDRAM_EMODE	0x40090000
+#define SDRAM_CONTROL	0x714b0f00
+#define SDRAM_CONFIG1	0x63611730
+#define SDRAM_CONFIG2	0x47670000
+*/
+
+#define SDRAM_TAPDELAY	0x10000000 /* reserved Bit in MPC5200 B3-Step */
diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig
index 5da6a5b..ce8815d 100644
--- a/arch/ppc/mach-mpc5xxx/Kconfig
+++ b/arch/ppc/mach-mpc5xxx/Kconfig
@@ -3,7 +3,7 @@ menu "Board specific settings       "
 config MACH_PHYCORE_MPC5200B_TINY_REV
 	int "Board Revision"
 	default 1
-	depends on MACH_PHYCORE_MPC5200B_TINY
+	depends on MACH_PHYCORE_MPC5200B_TINY || MACH_KONZEPTPARK_MCB2
 	help
 	  Revision 0 and revision 1 of the tiny board have
 	  incompatible flash settings. Unless you have a very
@@ -12,4 +12,5 @@ config MACH_PHYCORE_MPC5200B_TINY_REV
 endmenu
 
 config EARLY_CONSOLE_PORT
-	default "psc3" if MACH_PHYCORE_MPC5200B_TINY
\ No newline at end of file
+	default "psc3" if MACH_PHYCORE_MPC5200B_TINY
+	default "psc3" if MACH_KONZEPTPARK_MCB2
-- 
1.7.2.2.277.gb49c4



From eric at eukrea.com  Thu Oct 14 10:05:23 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:23 +0200
Subject: [PATCH 01/10] imx/clocksource: enable GPT1 before using it on CPUIMX25
Message-ID: <1287065132-20372-1-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/mach-imx/clocksource.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index a166038..b3a74b3 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -76,6 +76,10 @@ static int clocksource_init (void)
 	PCCR0 |= PCCR0_GPT1_EN;
 	PCCR1 |= PCCR1_PERCLK1_EN;
 #endif
+#ifdef CONFIG_ARCH_IMX25
+	writel(readl(IMX_CCM_BASE + CCM_CGCR1) | (1 << 19),
+		IMX_CCM_BASE + CCM_CGCR1);
+#endif
 
 	for (i = 0; i < 100; i++)
 		writel(0, timer_base + GPT_TCTL); /* We have no udelay by now */
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:26 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:26 +0200
Subject: [PATCH 04/10] mci-core: add more tested SD Cards
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-4-git-send-email-eric@eukrea.com>

note :
- Transcend 16GiB fails (no log)
- Micron 8GiB eMMC fails (hangs after : Detecting a 4.0 revision card)

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 drivers/mci/mci-core.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index ea27062..c92d5a9 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -46,9 +46,12 @@
  *
  * Checked with the following cards:
  * - Canon MMC 16 MiB
+ * - Integral MicroSDHC, 8 GiB (Class 4)
  * - Kingston 512 MiB
  * - SanDisk 512 MiB
  * - Transcend SD Ultra, 1 GiB (Industrial)
+ * - Transcend SDHC, 4 GiB (Class 6)
+ * - Transcend SDHC, 8 GiB (Class 6)
  */
 
 /**
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:24 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:24 +0200
Subject: [PATCH 02/10] mx25: add MMC clock support
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-2-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/mach-imx/speed-imx25.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c
index 9605674..e8feb6b 100644
--- a/arch/arm/mach-imx/speed-imx25.c
+++ b/arch/arm/mach-imx/speed-imx25.c
@@ -82,6 +82,11 @@ unsigned long imx_get_i2cclk(void)
 	return imx_get_perclk(6);
 }
 
+unsigned long imx_get_mmcclk(void)
+{
+	return imx_get_perclk(3);
+}
+
 int imx_dump_clocks(void)
 {
 	printf("mpll:    %10d Hz\n", imx_get_mpllclk());
@@ -92,6 +97,8 @@ int imx_dump_clocks(void)
 	printf("gpt:     %10d Hz\n", imx_get_ipgclk());
 	printf("nand:    %10d Hz\n", imx_get_perclk(8));
 	printf("lcd:     %10d Hz\n", imx_get_perclk(7));
+	printf("i2c:     %10d Hz\n", imx_get_perclk(6));
+	printf("sdhc1:   %10d Hz\n", imx_get_perclk(3));
 	return 0;
 }
 
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:27 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:27 +0200
Subject: [PATCH 05/10] epautoconf: fix compile error
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-5-git-send-email-eric@eukrea.com>

this patch fix the following error :
  CC      drivers/usb/gadget/epautoconf.o
drivers/usb/gadget/epautoconf.c:33: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'unsigned'
drivers/usb/gadget/epautoconf.c: In function 'ep_matches':
drivers/usb/gadget/epautoconf.c:168: error: 'epnum' undeclared (first use in this function)
drivers/usb/gadget/epautoconf.c:168: error: (Each undeclared identifier is reported only once
drivers/usb/gadget/epautoconf.c:168: error: for each function it appears in.)
drivers/usb/gadget/epautoconf.c: In function 'usb_ep_autoconfig_reset':
drivers/usb/gadget/epautoconf.c:304: error: 'epnum' undeclared (first use in this function)

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 drivers/usb/gadget/epautoconf.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index e549792..fe7e7fd 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -19,6 +19,7 @@
  *
  */
 
+#include <init.h>
 #include <common.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:30 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:30 +0200
Subject: [PATCH 08/10] speed-imx35: add support for SDHC1
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-8-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/mach-imx/speed-imx35.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/speed-imx35.c b/arch/arm/mach-imx/speed-imx35.c
index c5a31c7..324cc29 100644
--- a/arch/arm/mach-imx/speed-imx35.c
+++ b/arch/arm/mach-imx/speed-imx35.c
@@ -163,6 +163,17 @@ unsigned long imx_get_uartclk(void)
 		return imx_get_ppllclk() / div;
 }
 
+unsigned long imx_get_mmcclk(void)
+{
+	unsigned long pdr3 = readl(IMX_CCM_BASE + CCM_PDR3);
+	unsigned long div = get_3_3_div(pdr3);
+
+	if (pdr3 & (1 << 6))
+		return imx_get_armclk() / div;
+	else
+		return imx_get_ppllclk() / div;
+}
+
 ulong imx_get_fecclk(void)
 {
 	return imx_get_ipgclk();
@@ -183,6 +194,7 @@ void imx_dump_clocks(void)
 	printf("ipg:     %10d Hz\n", imx_get_ipgclk());
 	printf("ipg_per: %10d Hz\n", imx_get_ipg_perclk());
 	printf("uart:	 %10d Hz\n", imx_get_uartclk());
+	printf("sdhc1:   %10d Hz\n", imx_get_mmcclk());
 }
 
 /*
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:25 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:25 +0200
Subject: [PATCH 03/10] MX25: fix IOMUX for ESDHC1 pins
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-3-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/mach-imx/include/mach/iomux-mx25.h |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/iomux-mx25.h b/arch/arm/mach-imx/include/mach/iomux-mx25.h
index a290a33..a8ca8f1 100644
--- a/arch/arm/mach-imx/include/mach/iomux-mx25.h
+++ b/arch/arm/mach-imx/include/mach/iomux-mx25.h
@@ -658,21 +658,21 @@
 #define MX25_PAD_RW__EIM_RW                                IOMUX_PAD(0x278,  0x6c, 0,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_RW__AUD4_TXFS                             IOMUX_PAD(0x278,  0x6c, 4, 0x474, 0, NO_PAD_CTRL)
 #define MX25_PAD_RW__GPIO25                                IOMUX_PAD(0x278,  0x6c, 5,     0, 0, NO_PAD_CTRL)
-#define MX25_PAD_SD1_CLK__CLK                              IOMUX_PAD(0x38c, 0x194, 0,     0, 0, NO_PAD_CTRL)
+#define MX25_PAD_SD1_CLK__CLK                              IOMUX_PAD(0x38c, 0x194, 0x10,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CLK__MISO                             IOMUX_PAD(0x38c, 0x194, 1, 0x49c, 1, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CLK__RDATA3                           IOMUX_PAD(0x38c, 0x194, 2, 0x510, 2, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CLK__SDMA_DBG_STAT_0                  IOMUX_PAD(0x38c, 0x194, 4,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CLK__GPIO24                           IOMUX_PAD(0x38c, 0x194, 5,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CLK__SLCDC_DATA1                      IOMUX_PAD(0x38c, 0x194, 6,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CLK__TRACE11                          IOMUX_PAD(0x38c, 0x194, 7,     0, 0, NO_PAD_CTRL)
-#define MX25_PAD_SD1_CMD__CMD                              IOMUX_PAD(0x388, 0x190, 0,     0, 0, NO_PAD_CTRL)
+#define MX25_PAD_SD1_CMD__CMD                              IOMUX_PAD(0x388, 0x190, 0x10,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CMD__MOSI                             IOMUX_PAD(0x388, 0x190, 1, 0x4a0, 1, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CMD__RDATA2                           IOMUX_PAD(0x388, 0x190, 2, 0x50c, 2, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CMD__SDMA_DBG_EVT_SEL                 IOMUX_PAD(0x388, 0x190, 4,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CMD__GPIO23                           IOMUX_PAD(0x388, 0x190, 5,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CMD__SLCDC_DATA0                      IOMUX_PAD(0x388, 0x190, 6,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CMD__TRACE10                          IOMUX_PAD(0x388, 0x190, 7,     0, 0, NO_PAD_CTRL)
-#define MX25_PAD_SD1_DATA0__DAT0                           IOMUX_PAD(0x390, 0x198, 0,     0, 0, NO_PAD_CTRL)
+#define MX25_PAD_SD1_DATA0__DAT0                           IOMUX_PAD(0x390, 0x198, 0x10,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA0__SCLK                           IOMUX_PAD(0x390, 0x198, 1, 0x494, 1, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA0__TDATA2                         IOMUX_PAD(0x390, 0x198, 2,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA0__AUD7_TXFS                      IOMUX_PAD(0x390, 0x198, 3, 0x47c, 0, NO_PAD_CTRL)
@@ -680,7 +680,7 @@
 #define MX25_PAD_SD1_DATA0__GPIO25                         IOMUX_PAD(0x390, 0x198, 5,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA0__SLCDC_DATA2                    IOMUX_PAD(0x390, 0x198, 6,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA0__TRACE12                        IOMUX_PAD(0x390, 0x198, 7,     0, 0, NO_PAD_CTRL)
-#define MX25_PAD_SD1_DATA1__DAT1                           IOMUX_PAD(0x394, 0x19c, 0,     0, 0, NO_PAD_CTRL)
+#define MX25_PAD_SD1_DATA1__DAT1                           IOMUX_PAD(0x394, 0x19c, 0x10,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA1__RDY                            IOMUX_PAD(0x394, 0x19c, 1, 0x498, 1, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA1__TDATA3                         IOMUX_PAD(0x394, 0x19c, 2,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA1__AUD7_RXD                       IOMUX_PAD(0x394, 0x19c, 3, 0x478, 0, NO_PAD_CTRL)
@@ -688,7 +688,7 @@
 #define MX25_PAD_SD1_DATA1__GPIO26                         IOMUX_PAD(0x394, 0x19c, 5,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA1__SLCDC_DATA3                    IOMUX_PAD(0x394, 0x19c, 6,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA1__TRACE13                        IOMUX_PAD(0x394, 0x19c, 7,     0, 0, NO_PAD_CTRL)
-#define MX25_PAD_SD1_DATA2__DAT2                           IOMUX_PAD(0x398, 0x1a0, 0,     0, 0, NO_PAD_CTRL)
+#define MX25_PAD_SD1_DATA2__DAT2                           IOMUX_PAD(0x398, 0x1a0, 0x10,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA2__SS0                            IOMUX_PAD(0x398, 0x1a0, 1, 0x4a4, 1, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA2__RX_CLK                         IOMUX_PAD(0x398, 0x1a0, 2, 0x514, 2, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA2__AUD7_RXC                       IOMUX_PAD(0x398, 0x1a0, 3,     0, 0, NO_PAD_CTRL)
@@ -696,7 +696,7 @@
 #define MX25_PAD_SD1_DATA2__GPIO27                         IOMUX_PAD(0x398, 0x1a0, 5,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA2__SLCDC_DATA4                    IOMUX_PAD(0x398, 0x1a0, 6,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA2__TRACE14                        IOMUX_PAD(0x398, 0x1a0, 7,     0, 0, NO_PAD_CTRL)
-#define MX25_PAD_SD1_DATA3__DAT3                           IOMUX_PAD(0x39c, 0x1a4, 0,     0, 0, NO_PAD_CTRL)
+#define MX25_PAD_SD1_DATA3__DAT3                           IOMUX_PAD(0x39c, 0x1a4, 0x10,     0, 0, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA3__SS1                            IOMUX_PAD(0x39c, 0x1a4, 1, 0x4a8, 1, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA3__CRS                            IOMUX_PAD(0x39c, 0x1a4, 2, 0x508, 2, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA3__AUD7_RXFS                      IOMUX_PAD(0x39c, 0x1a4, 3,     0, 0, NO_PAD_CTRL)
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:29 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:29 +0200
Subject: [PATCH 07/10] imx35-regs: add defines for USB and SD
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-7-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/mach-imx/include/mach/imx35-regs.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h
index 5cfb788..b2b360a 100644
--- a/arch/arm/mach-imx/include/mach/imx35-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
@@ -51,6 +51,7 @@
 #define IMX_SDHC1_BASE		0x53FB4000
 #define IMX_SDHC2_BASE		0x53FB8000
 #define IMX_SDHC3_BASE		0x53FBC000
+#define IMX_OTG_BASE		0x53FF4000
 
 /*
  * Clock Controller Module (CCM)
@@ -73,6 +74,8 @@
 
 #define CCM_CGR1_FEC_SHIFT	0
 #define CCM_CGR1_I2C1_SHIFT	10
+#define CCM_CGR1_SDHC1_SHIFT	26
+#define CCM_CGR2_USB_SHIFT	22
 
 #define PDR0_AUTO_MUX_DIV(x)	(((x) & 0x7) << 9)
 #define PDR0_CCM_PER_AHB(x)	(((x) & 0x7) << 12)
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:28 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:28 +0200
Subject: [PATCH 06/10] eukrea_cpuimx25: update board support
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-6-git-send-email-eric@eukrea.com>

- support NAND external boot
- enable only used clocks
- LCD fix in /env/bin/init
- I2C support
- SDCard support
- USB Host 1 support
- DFU support on OTG port
- update defconfig

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/boards/eukrea_cpuimx25/env/bin/init      |    2 +
 arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c |  104 +++++++++++++++++++-
 arch/arm/boards/eukrea_cpuimx25/lowlevel.c        |   64 ++++++++++---
 arch/arm/configs/eukrea_cpuimx25_defconfig        |   12 ++-
 4 files changed, 162 insertions(+), 20 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx25/env/bin/init b/arch/arm/boards/eukrea_cpuimx25/env/bin/init
index 335d7ae..4732875 100644
--- a/arch/arm/boards/eukrea_cpuimx25/env/bin/init
+++ b/arch/arm/boards/eukrea_cpuimx25/env/bin/init
@@ -14,9 +14,11 @@ fi
 
 if [ -f /env/logo.bmp ]; then
 	bmp /env/logo.bmp
+	fb0.enable=1
 elif [ -f /env/logo.bmp.lzo ]; then
 	unlzo /env/logo.bmp.lzo /logo.bmp
 	bmp /logo.bmp
+	fb0.enable=1
 fi
 
 if [ -z $eth0.ethaddr ]; then
diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index 7fd1031..c2eb398 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -40,6 +40,8 @@
 #include <nand.h>
 #include <mach/imx-flash-header.h>
 #include <mach/iomux-mx25.h>
+#include <i2c/i2c.h>
+#include <usb/fsl_usb2.h>
 
 extern unsigned long _stext;
 extern void exception_vectors(void);
@@ -151,6 +153,70 @@ static struct device_d imxfb_dev = {
 	.platform_data	= &eukrea_cpuimx25_fb_data,
 };
 
+static struct device_d i2c_dev = {
+	.id	  = -1,
+	.name     = "i2c-imx",
+	.map_base = IMX_I2C1_BASE,
+};
+
+static struct device_d esdhc_dev = {
+	.name		= "imx-esdhc",
+	.map_base	= 0x53fb4000,
+};
+
+#ifdef CONFIG_USB
+
+#define MX35_H1_SIC_SHIFT	21
+#define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
+#define MX35_H1_PM_BIT		(1 << 8)
+#define MX35_H1_IPPUE_UP_BIT	(1 << 7)
+#define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
+#define MX35_H1_TLL_BIT		(1 << 5)
+#define MX35_H1_USBTE_BIT	(1 << 4)
+#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
+
+static void imx25_usb_init(void)
+{
+	unsigned int tmp;
+
+	/* Host 1 */
+	tmp = readl(IMX_OTG_BASE + 0x600);
+	tmp &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
+		MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
+	tmp |= (MXC_EHCI_INTERFACE_SINGLE_UNI) << MX35_H1_SIC_SHIFT;
+	tmp |= MX35_H1_USBTE_BIT;
+	tmp |= MX35_H1_IPPUE_DOWN_BIT;
+	writel(tmp, IMX_OTG_BASE + 0x600);
+
+	tmp = readl(IMX_OTG_BASE + 0x584);
+	tmp |= 3 << 30;
+	writel(tmp, IMX_OTG_BASE + 0x584);
+
+	/* Set to Host mode */
+	tmp = readl(IMX_OTG_BASE + 0x5a8);
+	writel(tmp | 0x3, IMX_OTG_BASE + 0x5a8);
+}
+
+static struct device_d usbh2_dev = {
+	.id	  = -1,
+	.name     = "ehci",
+	.map_base = IMX_OTG_BASE + 0x400,
+	.size     = 0x200,
+};
+#endif
+
+static struct fsl_usb2_platform_data usb_pdata = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_UTMI,
+};
+
+static struct device_d usbotg_dev = {
+	.name     = "fsl-udc",
+	.map_base = IMX_OTG_BASE,
+	.size     = 0x200,
+	.platform_data = &usb_pdata,
+};
+
 #ifdef CONFIG_MMU
 static void eukrea_cpuimx25_mmu_init(void)
 {
@@ -209,6 +275,16 @@ static struct pad_desc eukrea_cpuimx25_pads[] = {
 	MX25_PAD_HSYNC__LCDC_HSYN,
 	/* BACKLIGHT CONTROL */
 	MX25_PAD_PWM__GPIO26,
+	/* I2C */
+	MX25_PAD_I2C1_CLK__SCL,
+	MX25_PAD_I2C1_DAT__SDA,
+	/* SDCard */
+	MX25_PAD_SD1_CLK__CLK,
+	MX25_PAD_SD1_CMD__CMD,
+	MX25_PAD_SD1_DATA0__DAT0,
+	MX25_PAD_SD1_DATA1__DAT1,
+	MX25_PAD_SD1_DATA2__DAT2,
+	MX25_PAD_SD1_DATA3__DAT3,
 };
 
 static int eukrea_cpuimx25_devices_init(void)
@@ -217,6 +293,7 @@ static int eukrea_cpuimx25_devices_init(void)
 
 	mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads,
 		ARRAY_SIZE(eukrea_cpuimx25_pads));
+
 	register_device(&fec_dev);
 
 	nand_info.width = 1;
@@ -238,6 +315,15 @@ static int eukrea_cpuimx25_devices_init(void)
 
 	register_device(&imxfb_dev);
 
+	register_device(&i2c_dev);
+	register_device(&esdhc_dev);
+
+#ifdef CONFIG_USB
+	imx25_usb_init();
+	register_device(&usbh2_dev);
+#endif
+	register_device(&usbotg_dev);
+
 	armlinux_add_dram(&sdram0_dev);
 	armlinux_set_bootparams((void *)0x80000100);
 	armlinux_set_architecture(MACH_TYPE_EUKREA_CPUIMX25);
@@ -256,7 +342,6 @@ static struct device_d eukrea_cpuimx25_serial_device = {
 
 static int eukrea_cpuimx25_console_init(void)
 {
-	writel(0x03010101, IMX_CCM_BASE + CCM_PCDR3);
 	register_device(&eukrea_cpuimx25_serial_device);
 	return 0;
 }
@@ -270,10 +355,17 @@ void __bare_init nand_boot(void)
 }
 #endif
 
-static int eukrea_cpuimx25_core_setup(void)
-{
-	writel(0x01010103, IMX_CCM_BASE + CCM_PCDR2);
-	return 0;
+static int eukrea_cpuimx25_core_init(void) {
+	/* enable UART1, FEC, SDHC, USB & I2C clock */
+	writel(readl(IMX_CCM_BASE + CCM_CGCR0) | (1 << 6) | (1 << 23)
+		| (1 << 15) | (1 << 21) | (1 << 3) | (1 << 28),
+		IMX_CCM_BASE + CCM_CGCR0);
+	writel(readl(IMX_CCM_BASE + CCM_CGCR1) | (1 << 23) | (1 << 15)
+		| (1 << 13), IMX_CCM_BASE + CCM_CGCR1);
+	writel(readl(IMX_CCM_BASE + CCM_CGCR2) | (1 << 14),
+		IMX_CCM_BASE + CCM_CGCR2);
 
+	return 0;
 }
-core_initcall(eukrea_cpuimx25_core_setup);
+
+core_initcall(eukrea_cpuimx25_core_init);
diff --git a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
index b9d3ce5..4ebf247 100644
--- a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
+++ b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
@@ -26,13 +26,13 @@
 #include <mach/imx-regs.h>
 #include <mach/imx-pll.h>
 #include <mach/esdctl.h>
-#include <asm/cache-l2x0.h>
 #include <asm/io.h>
 #include <mach/imx-nand.h>
 #include <asm/barebox-arm.h>
 #include <asm-generic/memory_layout.h>
 #include <asm/system.h>
 
+#ifdef CONFIG_NAND_IMX_BOOT
 static void __bare_init __naked insdram(void)
 {
 	uint32_t r;
@@ -45,17 +45,32 @@ static void __bare_init __naked insdram(void)
 
 	board_init_lowlevel_return();
 }
-
-#define MX25_CCM_MCR	0x64
-#define MX25_CCM_CGR0	0x0c
-#define MX25_CCM_CGR1	0x10
-#define MX25_CCM_CGR2	0x14
+#endif
 
 void __bare_init __naked board_init_lowlevel(void)
 {
 	uint32_t r;
+#ifdef CONFIG_NAND_IMX_BOOT
 	unsigned int *trg, *src;
 	int i;
+#endif
+	register uint32_t loops = 0x20000;
+
+	/* restart the MPLL and wait until it's stable */
+	writel(readl(IMX_CCM_BASE + CCM_CCTL) | (1 << 27),
+						IMX_CCM_BASE + CCM_CCTL);
+	while (readl(IMX_CCM_BASE + CCM_CCTL) & (1 << 27)) {};
+
+	/* Configure dividers and ARM clock source
+	 * 	ARM @ 400 MHz
+	 * 	AHB @ 133 MHz
+	 */
+	writel(0x20034000, IMX_CCM_BASE + CCM_CCTL);
+
+	/* Enable UART1 / FEC / */
+/*	writel(0x1FFFFFFF, IMX_CCM_BASE + CCM_CGCR0);
+	writel(0xFFFFFFFF, IMX_CCM_BASE + CCM_CGCR1);
+	writel(0x000FDFFF, IMX_CCM_BASE + CCM_CGCR2);*/
 
 	/* AIPS setup - Only setup MPROTx registers. The PACR default values are good.
 	 * Set all MPROTx to be non-bufferable, trusted for R/W,
@@ -102,23 +117,46 @@ void __bare_init __naked board_init_lowlevel(void)
 	 */
 	writel(0x1, 0xb8003000);
 
-	/* enable all the clocks */
-	writel(0x038A81A2, IMX_CCM_BASE + MX25_CCM_CGR0);
-	writel(0x24788F00, IMX_CCM_BASE + MX25_CCM_CGR1);
-	writel(0x00004438, IMX_CCM_BASE + MX25_CCM_CGR2);
-	writel(0x00, IMX_CCM_BASE + MX25_CCM_MCR);
+	/* Speed up NAND controller by adjusting the NFC divider */
+	r = readl(IMX_CCM_BASE + CCM_PCDR2);
+	r &= ~0xf;
+	r |= 0x1;
+	writel(r, IMX_CCM_BASE + CCM_PCDR2);
+
+	/* Skip SDRAM initialization if we run from RAM */
+	r = get_pc();
+	if (r > 0x80000000 && r < 0x90000000)
+		board_init_lowlevel_return();
+
+	/* Init Mobile DDR */
+	writel(0x0000000E, ESDMISC);
+	writel(0x00000004, ESDMISC);
+	__asm__ volatile ("1:\n"
+			"subs %0, %1, #1\n"
+			"bne 1b":"=r" (loops):"0" (loops));
+
+	writel(0x0029572B, ESDCFG0);
+	writel(0x92210000, ESDCTL0);
+	writeb(0xda, IMX_SDRAM_CS0 + 0x400);
+	writel(0xA2210000, ESDCTL0);
+	writeb(0xda, IMX_SDRAM_CS0);
+	writeb(0xda, IMX_SDRAM_CS0);
+	writel(0xB2210000, ESDCTL0);
+	writeb(0xda, IMX_SDRAM_CS0 + 0x33);
+	writeb(0xda, IMX_SDRAM_CS0 + 0x1000000);
+	writel(0x82216080, ESDCTL0);
 
 #ifdef CONFIG_NAND_IMX_BOOT
 	/* skip NAND boot if not running from NFC space */
 	r = get_pc();
-	if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x1000)
+	if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x800)
 		board_init_lowlevel_return();
 
 	src = (unsigned int *)IMX_NFC_BASE;
 	trg = (unsigned int *)TEXT_BASE;
 
 	/* Move ourselves out of NFC SRAM */
-	for (i = 0; i < 0x1000 / sizeof(int); i++)
+	for (i = 0; i < 0x800 / sizeof(int); i++)
 		*trg++ = *src++;
 
 	/* Jump to SDRAM */
diff --git a/arch/arm/configs/eukrea_cpuimx25_defconfig b/arch/arm/configs/eukrea_cpuimx25_defconfig
index feb758e..bc68804 100644
--- a/arch/arm/configs/eukrea_cpuimx25_defconfig
+++ b/arch/arm/configs/eukrea_cpuimx25_defconfig
@@ -9,6 +9,7 @@ CONFIG_LONGHELP=y
 CONFIG_GLOB=y
 CONFIG_PROMPT_HUSH_PS2="cpuimx25>"
 CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_HUSH_GETOPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
 CONFIG_PARTITION=y
@@ -23,6 +24,7 @@ CONFIG_CMD_READLINE=y
 CONFIG_CMD_ECHO_E=y
 CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
 CONFIG_CMD_MTEST=y
 CONFIG_CMD_FLASH=y
 CONFIG_CMD_BOOTM_ZLIB=y
@@ -35,15 +37,23 @@ CONFIG_CMD_PARTITION=y
 CONFIG_CMD_BMP=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_UNLZO=y
+CONFIG_CMD_I2C=y
 CONFIG_NET=y
 CONFIG_NET_DHCP=y
 CONFIG_NET_PING=y
 CONFIG_NET_TFTP=y
 CONFIG_DRIVER_NET_FEC_IMX=y
 # CONFIG_SPI is not set
+CONFIG_I2C=y
+CONFIG_I2C_IMX=y
 CONFIG_MTD=y
 CONFIG_NAND=y
 CONFIG_NAND_IMX=y
-CONFIG_NAND_IMX_BOOT=y
+CONFIG_USB=y
+CONFIG_USB_EHCI=y
+CONFIG_USB_GADGET=y
 CONFIG_VIDEO=y
 CONFIG_DRIVER_VIDEO_IMX=y
+CONFIG_MCI=y
+CONFIG_MCI_IMX_ESDHC=y
+CONFIG_MCI_IMX_ESDHC_PIO=y
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:31 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:31 +0200
Subject: [PATCH 09/10] iomux-mx35: fox IOMUX for SDHC1's pins
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-9-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/mach-imx/include/mach/iomux-mx35.h |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/iomux-mx35.h b/arch/arm/mach-imx/include/mach/iomux-mx35.h
index 8a56d86..ad7ff56 100644
--- a/arch/arm/mach-imx/include/mach/iomux-mx35.h
+++ b/arch/arm/mach-imx/include/mach/iomux-mx35.h
@@ -815,42 +815,42 @@
 #define MX35_PAD_D3_SPL__SDMA_DEBUG_BUS_DEVICE_1		IOMUX_PAD(0x690, 0x22c, 6, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_D3_SPL__ARM11P_TOP_TRACE_22			IOMUX_PAD(0x690, 0x22c, 7, 0x0,   0, NO_PAD_CTRL)
 
-#define MX35_PAD_SD1_CMD__ESDHC1_CMD				IOMUX_PAD(0x694, 0x230, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CMD__ESDHC1_CMD				IOMUX_PAD(0x694, 0x230, 0x10, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CMD__MSHC_SCLK				IOMUX_PAD(0x694, 0x230, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CMD__IPU_DISPB_D0_VSYNC			IOMUX_PAD(0x694, 0x230, 3, 0x924, 2, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CMD__USB_TOP_USBOTG_DATA_4			IOMUX_PAD(0x694, 0x230, 4, 0x9b4, 0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CMD__GPIO1_6				IOMUX_PAD(0x694, 0x230, 5, 0x858, 2, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CMD__ARM11P_TOP_TRCTL			IOMUX_PAD(0x694, 0x230, 7, 0x0,   0, NO_PAD_CTRL)
 
-#define MX35_PAD_SD1_CLK__ESDHC1_CLK				IOMUX_PAD(0x698, 0x234, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CLK__ESDHC1_CLK				IOMUX_PAD(0x698, 0x234, 0x10, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CLK__MSHC_BS				IOMUX_PAD(0x698, 0x234, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CLK__IPU_DISPB_BCLK			IOMUX_PAD(0x698, 0x234, 3, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CLK__USB_TOP_USBOTG_DATA_5			IOMUX_PAD(0x698, 0x234, 4, 0x9b8, 0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CLK__GPIO1_7				IOMUX_PAD(0x698, 0x234, 5, 0x85c, 2, NO_PAD_CTRL)
 #define MX35_PAD_SD1_CLK__ARM11P_TOP_TRCLK			IOMUX_PAD(0x698, 0x234, 7, 0x0,   0, NO_PAD_CTRL)
 
-#define MX35_PAD_SD1_DATA0__ESDHC1_DAT0				IOMUX_PAD(0x69c, 0x238, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA0__ESDHC1_DAT0				IOMUX_PAD(0x69c, 0x238, 0x10, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA0__MSHC_DATA_0				IOMUX_PAD(0x69c, 0x238, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA0__IPU_DISPB_CS0			IOMUX_PAD(0x69c, 0x238, 3, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA0__USB_TOP_USBOTG_DATA_6		IOMUX_PAD(0x69c, 0x238, 4, 0x9bc, 0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA0__GPIO1_8				IOMUX_PAD(0x69c, 0x238, 5, 0x860, 2, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA0__ARM11P_TOP_TRACE_23			IOMUX_PAD(0x69c, 0x238, 7, 0x0,   0, NO_PAD_CTRL)
 
-#define MX35_PAD_SD1_DATA1__ESDHC1_DAT1				IOMUX_PAD(0x6a0, 0x23c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA1__ESDHC1_DAT1				IOMUX_PAD(0x6a0, 0x23c, 0x10, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA1__MSHC_DATA_1				IOMUX_PAD(0x6a0, 0x23c, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA1__IPU_DISPB_PAR_RS			IOMUX_PAD(0x6a0, 0x23c, 3, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA1__USB_TOP_USBOTG_DATA_0		IOMUX_PAD(0x6a0, 0x23c, 4, 0x9a4, 0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA1__GPIO1_9				IOMUX_PAD(0x6a0, 0x23c, 5, 0x864, 1, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA1__ARM11P_TOP_TRACE_24			IOMUX_PAD(0x6a0, 0x23c, 7, 0x0,   0, NO_PAD_CTRL)
 
-#define MX35_PAD_SD1_DATA2__ESDHC1_DAT2				IOMUX_PAD(0x6a4, 0x240, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA2__ESDHC1_DAT2				IOMUX_PAD(0x6a4, 0x240, 0x10, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA2__MSHC_DATA_2				IOMUX_PAD(0x6a4, 0x240, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA2__IPU_DISPB_WR			IOMUX_PAD(0x6a4, 0x240, 3, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA2__USB_TOP_USBOTG_DATA_1		IOMUX_PAD(0x6a4, 0x240, 4, 0x9a8, 0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA2__GPIO1_10				IOMUX_PAD(0x6a4, 0x240, 5, 0x830, 1, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA2__ARM11P_TOP_TRACE_25			IOMUX_PAD(0x6a4, 0x240, 7, 0x0,   0, NO_PAD_CTRL)
 
-#define MX35_PAD_SD1_DATA3__ESDHC1_DAT3				IOMUX_PAD(0x6a8, 0x244, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA3__ESDHC1_DAT3				IOMUX_PAD(0x6a8, 0x244, 0x10, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA3__MSHC_DATA_3				IOMUX_PAD(0x6a8, 0x244, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA3__IPU_DISPB_RD			IOMUX_PAD(0x6a8, 0x244, 3, 0x0,   0, NO_PAD_CTRL)
 #define MX35_PAD_SD1_DATA3__USB_TOP_USBOTG_DATA_2		IOMUX_PAD(0x6a8, 0x244, 4, 0x9ac, 0, NO_PAD_CTRL)
-- 
1.7.0.4



From eric at eukrea.com  Thu Oct 14 10:05:32 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Thu, 14 Oct 2010 16:05:32 +0200
Subject: [PATCH 10/10] eukrea_cpuimx35: update board support
In-Reply-To: <1287065132-20372-1-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
Message-ID: <1287065132-20372-10-git-send-email-eric@eukrea.com>

- support NAND external boot
- update internal boot init sequence
- unbreak flash_header using magic values ...
- LCD enable
- add I2C
- add SDCard
- add USB Host
- add DFU on USB OTG

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/boards/eukrea_cpuimx35/env/bin/init      |    4 +-
 arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c |   99 ++++++++++++++++++++-
 arch/arm/boards/eukrea_cpuimx35/flash_header.c    |   22 +++---
 arch/arm/boards/eukrea_cpuimx35/lowlevel.c        |   20 +++--
 arch/arm/configs/eukrea_cpuimx35_defconfig        |   14 +++-
 5 files changed, 135 insertions(+), 24 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx35/env/bin/init b/arch/arm/boards/eukrea_cpuimx35/env/bin/init
index 90007cd..b56d7b5 100644
--- a/arch/arm/boards/eukrea_cpuimx35/env/bin/init
+++ b/arch/arm/boards/eukrea_cpuimx35/env/bin/init
@@ -15,12 +15,12 @@ fi
 if [ -f /env/logo.bmp ]; then
 	fb0.enable=1
 	bmp /env/logo.bmp
-	gpio_direction_out 1 1
+	gpio_set_value 1 1
 elif [ -f /env/logo.bmp.lzo ]; then
 	unlzo /env/logo.bmp.lzo /logo.bmp
 	fb0.enable=1
 	bmp /logo.bmp
-	gpio_direction_out 1 1
+	gpio_set_value 1 1
 fi
 
 if [ -z $eth0.ethaddr ]; then
diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
index 63d019a..7d85f97 100644
--- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
+++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
@@ -51,6 +51,8 @@
 #include <mach/pmic.h>
 #include <mach/imx-ipu-fb.h>
 #include <mach/imx-pll.h>
+#include <i2c/i2c.h>
+#include <usb/fsl_usb2.h>
 
 static struct fec_platform_data fec_info = {
 	.xcv_type	= MII100,
@@ -126,6 +128,70 @@ static struct device_d imxfb_dev = {
 	.platform_data	= &ipu_fb_data,
 };
 
+static struct device_d i2c_dev = {
+	.id	  = -1,
+	.name     = "i2c-imx",
+	.map_base = IMX_I2C1_BASE,
+};
+
+static struct device_d esdhc_dev = {
+	.name		= "imx-esdhc",
+	.map_base	= IMX_SDHC1_BASE,
+};
+
+#ifdef CONFIG_USB
+
+#define MX35_H1_SIC_SHIFT	21
+#define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
+#define MX35_H1_PM_BIT		(1 << 8)
+#define MX35_H1_IPPUE_UP_BIT	(1 << 7)
+#define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
+#define MX35_H1_TLL_BIT		(1 << 5)
+#define MX35_H1_USBTE_BIT	(1 << 4)
+#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
+
+static void imx35_usb_init(void)
+{
+	unsigned int tmp;
+
+	/* Host 1 */
+	tmp = readl(IMX_OTG_BASE + 0x600);
+	tmp &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
+		MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
+	tmp |= (MXC_EHCI_INTERFACE_SINGLE_UNI) << MX35_H1_SIC_SHIFT;
+	tmp |= MX35_H1_USBTE_BIT;
+	tmp |= MX35_H1_IPPUE_DOWN_BIT;
+	writel(tmp, IMX_OTG_BASE + 0x600);
+
+	tmp = readl(IMX_OTG_BASE + 0x584);
+	tmp |= 3 << 30;
+	writel(tmp, IMX_OTG_BASE + 0x584);
+
+	/* Set to Host mode */
+	tmp = readl(IMX_OTG_BASE + 0x5a8);
+	writel(tmp | 0x3, IMX_OTG_BASE + 0x5a8);
+}
+
+static struct device_d usbh2_dev = {
+	.id	  = -1,
+	.name     = "ehci",
+	.map_base = IMX_OTG_BASE + 0x400,
+	.size     = 0x200,
+};
+#endif
+
+static struct fsl_usb2_platform_data usb_pdata = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_UTMI,
+};
+
+static struct device_d usbotg_dev = {
+	.name     = "fsl-udc",
+	.map_base = IMX_OTG_BASE,
+	.size     = 0x200,
+	.platform_data = &usb_pdata,
+};
+
 #ifdef CONFIG_MMU
 static int eukrea_cpuimx35_mmu_init(void)
 {
@@ -153,6 +219,8 @@ postcore_initcall(eukrea_cpuimx35_mmu_init);
 
 static int eukrea_cpuimx35_devices_init(void)
 {
+	unsigned int tmp;
+
 	register_device(&nand_dev);
 
 	devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
@@ -165,6 +233,18 @@ static int eukrea_cpuimx35_devices_init(void)
 	register_device(&sdram_dev);
 	register_device(&imxfb_dev);
 
+	register_device(&i2c_dev);
+	register_device(&esdhc_dev);
+
+#ifdef CONFIG_USB
+	imx35_usb_init();
+	register_device(&usbh2_dev);
+#endif
+	/* Workaround ENGcm09152 */
+	tmp = readl(IMX_OTG_BASE + 0x608);
+	writel(tmp | (1 << 23), IMX_OTG_BASE + 0x608);
+	register_device(&usbotg_dev);
+
 	armlinux_add_dram(&sdram_dev);
 	armlinux_set_bootparams((void *)0x80000100);
 	armlinux_set_architecture(MACH_TYPE_EUKREA_CPUIMX35);
@@ -211,6 +291,16 @@ static struct pad_desc eukrea_cpuimx35_pads[] = {
 	MX35_PAD_LD23__GPIO3_29,
 	MX35_PAD_CONTRAST__GPIO1_1,
 	MX35_PAD_D3_CLS__GPIO1_4,
+
+	MX35_PAD_I2C1_CLK__I2C1_SCL,
+	MX35_PAD_I2C1_DAT__I2C1_SDA,
+
+	MX35_PAD_SD1_CMD__ESDHC1_CMD,
+	MX35_PAD_SD1_CLK__ESDHC1_CLK,
+	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
 };
 
 static int eukrea_cpuimx35_console_init(void)
@@ -219,7 +309,7 @@ static int eukrea_cpuimx35_console_init(void)
 		ARRAY_SIZE(eukrea_cpuimx35_pads));
 
 	/* screen default on to prevent flicker */
-	gpio_direction_output(4, 1);
+	gpio_direction_output(4, 0);
 	/* backlight default off */
 	gpio_direction_output(1, 0);
 	/* led default off */
@@ -235,10 +325,15 @@ static int eukrea_cpuimx35_core_init(void)
 {
 	u32 reg;
 
-	/* enable clock for I2C1 and FEC */
+	/* enable clock for I2C1, SDHC1, USB and FEC */
 	reg = readl(IMX_CCM_BASE + CCM_CGR1);
 	reg |= 0x3 << CCM_CGR1_FEC_SHIFT;
+	reg |= 0x3 << CCM_CGR1_SDHC1_SHIFT;
+	reg |= 0x3 << CCM_CGR1_I2C1_SHIFT,
 	reg = writel(reg, IMX_CCM_BASE + CCM_CGR1);
+	reg = readl(IMX_CCM_BASE + CCM_CGR2);
+	reg |= 0x3 << CCM_CGR2_USB_SHIFT;
+	reg = writel(reg, IMX_CCM_BASE + CCM_CGR2);
 
 	/* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/
 	/*
diff --git a/arch/arm/boards/eukrea_cpuimx35/flash_header.c b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
index 285a2d4..4163caf 100644
--- a/arch/arm/boards/eukrea_cpuimx35/flash_header.c
+++ b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
@@ -12,24 +12,24 @@ void __naked __flash_header_start go(void)
 struct imx_dcd_entry __dcd_entry_section dcd_entry[] = {
 	{ .ptr_type = 4, .addr = 0x53F80004, .val = 0x00821000, },
 	{ .ptr_type = 4, .addr = 0x53F80004, .val = 0x00821000, },
-	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x00000004, },
+	{ .ptr_type = 4, .addr = 0xb8001010, .val = 0x00000004, },
 	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x0000000C, },
-	{ .ptr_type = 4, .addr = 0xB8001004, .val = 0x0009572B, },
-	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0x92220000, },
+	{ .ptr_type = 4, .addr = 0xb8001004, .val = 0x0009572B, },
+	{ .ptr_type = 4, .addr = 0xb8001000, .val = 0x92220000, },
 	{ .ptr_type = 1, .addr = 0x80000400, .val = 0xda, },
-	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0xA2220000, },
-	{ .ptr_type = 1, .addr = 0x80000000, .val = 0x87654321, },
-	{ .ptr_type = 1, .addr = 0x80000000, .val = 0x87654321, },
-	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0xB2220000, },
+	{ .ptr_type = 4, .addr = 0xb8001000, .val = 0xa2220000, },
+	{ .ptr_type = 4, .addr = 0x80000000, .val = 0x12344321, },
+	{ .ptr_type = 4, .addr = 0x80000000, .val = 0x12344321, },
+	{ .ptr_type = 4, .addr = 0xb8001000, .val = 0xb2220000, },
 	{ .ptr_type = 1, .addr = 0x80000033, .val = 0xda, },
 	{ .ptr_type = 1, .addr = 0x82000000, .val = 0xda, },
-	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0x82224080, },
-	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x00000004, },
+	{ .ptr_type = 4, .addr = 0xb8001000, .val = 0x82224080, },
+	{ .ptr_type = 4, .addr = 0xb8001010, .val = 0x00000004, },
 };
 
-
+#define DEST_BASE 0x80000000
 struct imx_flash_header __flash_header_section flash_header = {
-	.app_code_jump_vector	= DEST_BASE + ((unsigned int)&exception_vectors - TEXT_BASE),
+	.app_code_jump_vector	= DEST_BASE + 0x1000,
 	.app_code_barker	= APP_CODE_BARKER,
 	.app_code_csf		= 0,
 	.dcd_ptr_ptr		= FLASH_HEADER_BASE + offsetof(struct imx_flash_header, dcd),
diff --git a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
index aad334d..6c0e106 100644
--- a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
+++ b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
@@ -66,6 +66,7 @@ void __bare_init __naked board_init_lowlevel(void)
 	unsigned int *trg, *src;
 	int i;
 #endif
+	register uint32_t loops = 0x20000;
 
 	r = get_cr();
 	r |= CR_Z; /* Flow prediction (Z) */
@@ -118,7 +119,7 @@ void __bare_init __naked board_init_lowlevel(void)
 	writel(r, ccm_base + CCM_CGR0);
 
 	r = readl(ccm_base + CCM_CGR1);
-	r |= 0x00000C00;
+	r |= 0x00030C00;
 	r |= 0x00000003;
 	writel(r, ccm_base + CCM_CGR1);
 
@@ -132,31 +133,34 @@ void __bare_init __naked board_init_lowlevel(void)
 		board_init_lowlevel_return();
 
 	/* Init Mobile DDR */
+	writel(0x0000000E, ESDMISC);
 	writel(0x00000004, ESDMISC);
-	writel(0x0000000C, ESDMISC);
+	__asm__ volatile ("1:\n"
+			"subs %0, %1, #1\n"
+			"bne 1b":"=r" (loops):"0" (loops));
+
 	writel(0x0009572B, ESDCFG0);
 	writel(0x92220000, ESDCTL0);
 	writeb(0xda, IMX_SDRAM_CS0 + 0x400);
 	writel(0xA2220000, ESDCTL0);
-	writel(0x87654321, IMX_SDRAM_CS0);
-	writel(0x87654321, IMX_SDRAM_CS0);
+	writeb(0xda, IMX_SDRAM_CS0);
+	writeb(0xda, IMX_SDRAM_CS0);
 	writel(0xB2220000, ESDCTL0);
 	writeb(0xda, IMX_SDRAM_CS0 + 0x33);
 	writeb(0xda, IMX_SDRAM_CS0 + 0x2000000);
-	writel(0x82224080, ESDCTL0);
-	writel(0x00000004, ESDMISC);
+	writel(0x82228080, ESDCTL0);
 
 #ifdef CONFIG_NAND_IMX_BOOT
 	/* skip NAND boot if not running from NFC space */
 	r = get_pc();
-	if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x1000)
+	if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x800)
 		board_init_lowlevel_return();
 
 	src = (unsigned int *)IMX_NFC_BASE;
 	trg = (unsigned int *)TEXT_BASE;
 
 	/* Move ourselves out of NFC SRAM */
-	for (i = 0; i < 0x1000 / sizeof(int); i++)
+	for (i = 0; i < 0x800 / sizeof(int); i++)
 		*trg++ = *src++;
 
 	/* Jump to SDRAM */
diff --git a/arch/arm/configs/eukrea_cpuimx35_defconfig b/arch/arm/configs/eukrea_cpuimx35_defconfig
index 975d095..af82827 100644
--- a/arch/arm/configs/eukrea_cpuimx35_defconfig
+++ b/arch/arm/configs/eukrea_cpuimx35_defconfig
@@ -8,8 +8,11 @@ CONFIG_MALLOC_SIZE=0x800000
 CONFIG_LONGHELP=y
 CONFIG_GLOB=y
 CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_HUSH_GETOPT=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
+# CONFIG_CONSOLE_ACTIVATE_FIRST is not set
+CONFIG_CONSOLE_ACTIVATE_ALL=y
 CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/eukrea_cpuimx35/env"
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_SLEEP=y
@@ -22,6 +25,7 @@ CONFIG_CMD_ECHO_E=y
 CONFIG_CMD_LOADB=y
 CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
 CONFIG_CMD_MTEST=y
 CONFIG_CMD_FLASH=y
 CONFIG_CMD_RESET=y
@@ -31,15 +35,23 @@ CONFIG_CMD_PARTITION=y
 CONFIG_CMD_BMP=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_UNLZO=y
+CONFIG_CMD_I2C=y
 CONFIG_NET=y
 CONFIG_NET_DHCP=y
 CONFIG_NET_PING=y
 CONFIG_NET_TFTP=y
 CONFIG_DRIVER_NET_FEC_IMX=y
 # CONFIG_SPI is not set
+CONFIG_I2C=y
+CONFIG_I2C_IMX=y
 CONFIG_MTD=y
 CONFIG_NAND=y
 CONFIG_NAND_IMX=y
-CONFIG_NAND_IMX_BOOT=y
+CONFIG_USB=y
+CONFIG_USB_EHCI=y
+CONFIG_USB_GADGET=y
 CONFIG_VIDEO=y
 CONFIG_DRIVER_VIDEO_IMX_IPU=y
+CONFIG_MCI=y
+CONFIG_MCI_IMX_ESDHC=y
+CONFIG_MCI_IMX_ESDHC_PIO=y
-- 
1.7.0.4



From jbe at pengutronix.de  Thu Oct 14 15:38:45 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu, 14 Oct 2010 21:38:45 +0200
Subject: [PATCH] i.MX23/MCI: Make the clock calculation easier to read and
	correct
Message-ID: <201010142138.45775.jbe@pengutronix.de>

From: Juergen Beisert <jbe at pengutronix.de>
Subject: Make the clock calculation easier to read and correct

Due to a wrong rounding while calculating the clock divider the requested clock
of 25 MHz resulted into a 48 MHz clock. With this patch a clock frequency
below or equal the requested one will be set.
By using 'div' and 'rate' as vars, its also easier to check against the data
sheet.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>

---
 drivers/mci/stm378x.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

Index: a/drivers/mci/stm378x.c
===================================================================
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -474,7 +474,7 @@ static int stm_mci_adtc(struct device_d 
  */
 static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
 {
-	unsigned ssp, div1, div2, reg;
+	unsigned ssp, div, rate, reg;
 
 	if (nc == 0U) {
 		/* TODO stop the clock */
@@ -483,21 +483,21 @@ static unsigned setup_clock_speed(struct
 
 	ssp = imx_get_sspclk(0) * 1000;
 
-	for (div1 = 2; div1 < 255; div1 += 2) {
-		div2 = ssp / nc / div1;
-		if (div2 <= 0x100)
+	for (div = 2; div < 255; div += 2) {
+		rate = (((ssp + (nc >> 1) ) / nc) + (div >> 1)) / div;
+		if (rate <= 0x100)
 			break;
 	}
-	if (div1 >= 255) {
+	if (div >= 255) {
 		pr_warning("Cannot set clock to %d Hz\n", nc);
 		return 0;
 	}
 
 	reg = readl(hw_dev->map_base + HW_SSP_TIMING) & SSP_TIMING_TIMEOUT_MASK;
-	reg |= SSP_TIMING_CLOCK_DIVIDE(div1) | SSP_TIMING_CLOCK_RATE(div2 - 1);
+	reg |= SSP_TIMING_CLOCK_DIVIDE(div) | SSP_TIMING_CLOCK_RATE(rate - 1);
 	writel(reg, hw_dev->map_base + HW_SSP_TIMING);
 
-	return ssp / div1 / div2;
+	return ssp / div / rate;
 }
 
 /**

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Fri Oct 15 06:22:45 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 15 Oct 2010 12:22:45 +0200
Subject: [PATCH 3/5] [kp-mcb2] Added board files and configs for
	konzeptpark mcb2
In-Reply-To: <1287054406-31713-3-git-send-email-carsten.schlote@gmx.net>
References: <1287054406-31713-1-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-2-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-3-git-send-email-carsten.schlote@gmx.net>
Message-ID: <20101015102245.GA28242@pengutronix.de>

Hi Carsten,

There are several trailing whitespaces in this patch. Can you fix these
please?

Several other comments inline.

Regards
 Sascha

On Thu, Oct 14, 2010 at 01:06:44PM +0200, Carsten Schlote wrote:
> From: Carsten Schlote <c.schlote at konzeptpark.de>
> 
> Added board specific files and config changes for konzeptpark MCB2
> hardware.
> 
> Derived from pcm030 hardware.
> 
> Signed-off-by: Carsten Schlote <c.schlote at konzeptpark.de>
> ---
>  arch/ppc/Kconfig                        |   11 +
>  arch/ppc/Makefile                       |    2 +-
>  arch/ppc/boards/kp-mcb2/Makefile        |    2 +
>  arch/ppc/boards/kp-mcb2/barebox.lds.S   |  139 ++++++++++++
>  arch/ppc/boards/kp-mcb2/config.h        |  253 ++++++++++++++++++++++
>  arch/ppc/boards/kp-mcb2/kp-mcb2.c       |  349 +++++++++++++++++++++++++++++++
>  arch/ppc/boards/kp-mcb2/kp-mcb2.dox     |    8 +
>  arch/ppc/boards/kp-mcb2/mt46v32m16-75.h |   46 ++++
>  arch/ppc/mach-mpc5xxx/Kconfig           |    5 +-
>  9 files changed, 812 insertions(+), 3 deletions(-)
>  create mode 100644 arch/ppc/boards/kp-mcb2/Makefile
>  create mode 100644 arch/ppc/boards/kp-mcb2/barebox.lds.S
>  create mode 100644 arch/ppc/boards/kp-mcb2/config.h
>  create mode 100644 arch/ppc/boards/kp-mcb2/kp-mcb2.c
>  create mode 100644 arch/ppc/boards/kp-mcb2/kp-mcb2.dox
>  create mode 100644 arch/ppc/boards/kp-mcb2/mt46v32m16-75.h
> 
> diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
> index cda14de..32aa3ea 100644
> --- a/arch/ppc/Kconfig
> +++ b/arch/ppc/Kconfig
> @@ -1,11 +1,13 @@
>  
>  config BOARDINFO
>  	default "Phytec Phycore mpc5200b tiny" if MACH_PHYCORE_MPC5200B_TINY
> +	default "konzeptpark MCB2" if MACH_KONZEPTPARK_MCB2
>  	
>  config ARCH_TEXT_BASE
>  	hex
>  	default 0x00000000 if RELOCATABLE
>  	default 0x01000000 if MACH_PHYCORE_MPC5200B_TINY
> +	default 0x01000000 if MACH_KONZEPTPARK_MCB2
>  
>  config MPC5XXX_EARLY_CONSOLE
>  	bool
> @@ -55,6 +57,15 @@ config MACH_PHYCORE_MPC5200B_TINY
>  	help
>  	  Say Y here if you are using the Phytec Phycore MPC5200B Tiny
>  	  board aka pcm030
> +
> +config MACH_KONZEPTPARK_MCB2
> +	bool "konzeptpark MCB2"
> +	select ARCH_MPC5200
> +	select MPC5200
> +	select MPC5xxx
> +	select HAS_CFI
> +	help
> +	  Say Y here if you are using the konzeptpark MCB2 board
>  endchoice
>  
>  source arch/ppc/mach-mpc5xxx/Kconfig
> diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
> index 46d64e5..e843ed5 100644
> --- a/arch/ppc/Makefile
> +++ b/arch/ppc/Makefile
> @@ -7,9 +7,9 @@ ifdef CONFIG_RELOCATABLE
>  CPPFLAGS += -fPIC -mrelocatable
>  endif
>  
> -
>  machine-$(CONFIG_ARCH_MPC5200)			:= mpc5200
>  board-$(CONFIG_MACH_PHYCORE_MPC5200B_TINY)	:= pcm030
> +board-$(CONFIG_MACH_KONZEPTPARK_MCB2)		:= kp-mcb2
>  cpu-$(CONFIG_ARCH_MPC5200)			:= mpc5xxx
>  
>  TEXT_BASE = $(CONFIG_TEXT_BASE)
> diff --git a/arch/ppc/boards/kp-mcb2/Makefile b/arch/ppc/boards/kp-mcb2/Makefile
> new file mode 100644
> index 0000000..78d1120
> --- /dev/null
> +++ b/arch/ppc/boards/kp-mcb2/Makefile
> @@ -0,0 +1,2 @@
> +obj-y += kp-mcb2.o
> +extra-y += barebox.lds
> diff --git a/arch/ppc/boards/kp-mcb2/barebox.lds.S b/arch/ppc/boards/kp-mcb2/barebox.lds.S

Care to move this file to arch/ppc/lib and use it as a generic linker
script? Otherwise we'll never find out if it's generic and everyone
continues copying it.


> new file mode 100644
> index 0000000..ab99335
> --- /dev/null
> +++ b/arch/ppc/boards/kp-mcb2/barebox.lds.S
> @@ -0,0 +1,139 @@
> +/*
> + * (C) Copyright 2003
> + * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <asm-generic/barebox.lds.h>
> +
> +OUTPUT_ARCH("powerpc")
> +/* Do we need any of these for elf?
> +   __DYNAMIC = 0;    */
> +SECTIONS
> +{
> +  . = TEXT_BASE;
> +
> +  /* Read-only sections, merged into text segment: */
> +  .interp : { *(.interp) }
> +  .hash          : { *(.hash)		}
> +  .dynsym        : { *(.dynsym)		}
> +  .dynstr        : { *(.dynstr)		}
> +  .rel.text      : { *(.rel.text)		}
> +  .rela.text     : { *(.rela.text) 	}
> +  .rel.data      : { *(.rel.data)		}
> +  .rela.data     : { *(.rela.data) 	}
> +  .rel.rodata    : { *(.rel.rodata) 	}
> +  .rela.rodata   : { *(.rela.rodata) 	}
> +  .rel.got       : { *(.rel.got)		}
> +  .rela.got      : { *(.rela.got)		}
> +  .rel.ctors     : { *(.rel.ctors)	}
> +  .rela.ctors    : { *(.rela.ctors)	}
> +  .rel.dtors     : { *(.rel.dtors)	}
> +  .rela.dtors    : { *(.rela.dtors)	}
> +  .rel.bss       : { *(.rel.bss)		}
> +  .rela.bss      : { *(.rela.bss)		}
> +  .rel.plt       : { *(.rel.plt)		}
> +  .rela.plt      : { *(.rela.plt)		}
> +  .init          : { *(.init)	}
> +  .plt : { *(.plt) }
> +  .text      :
> +  {
> +    arch/ppc/mach-mpc5xxx/start.o	(.text)

This should be changed to *(.text_entry*) and the code in start.S moved
to this section. Otherwise this file seems to be generic for powerpc.

> +    *(.text*)
> +    *(.got1*)
> +    . = ALIGN(16);
> +    *(.rodata*)
> +    *(.rodata1*)
> +    *(.rodata.str1.4)
> +  }
> +  .fini      : { *(.fini)    } =0
> +  .ctors     : { *(.ctors)   }
> +  .dtors     : { *(.dtors)   }
> +
> +  /* Read-write section, merged into data segment: */
> +  . = (. + 0x0FFF) & 0xFFFFF000;
> +  _etext = .;
> +  PROVIDE (erotext = .);
> +  .reloc   :
> +  {
> +    *(.got)
> +    _GOT2_TABLE_ = .;
> +    *(.got2)
> +    _FIXUP_TABLE_ = .;
> +    *(.fixup)
> +  }
> +  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
> +  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
> +
> +
> +  .data    :
> +  {
> +    *(.data*)
> +    *(.data1*)
> +    *(.sdata*)
> +    *(.sdata2*)
> +    *(.dynamic*)
> +    CONSTRUCTORS
> +  }
> +  _edata  =  .;
> +  PROVIDE (edata = .);
> +
> +  . = .;
> +  __barebox_cmd_start = .;
> +  .barebox_cmd : { BAREBOX_CMDS }
> +  __barebox_cmd_end = .;
> +
> +  __barebox_initcalls_start = .;
> +  .barebox_initcalls : { INITCALLS }
> +  __barebox_initcalls_end = .;
> +  __initcall_entries = (__barebox_initcalls_end - __barebox_initcalls_start) >> 2;
> +
> +  __usymtab_start = .;
> +  __usymtab : { BAREBOX_SYMS }
> +  __usymtab_end = .;
> +
> +  __early_init_data_begin = .;
> +  .early_init_data : { *(.early_init_data) }
> +  __early_init_data_end = .;
> +
> +  __start___ex_table = .;
> +  __ex_table : { *(__ex_table) }
> +  __stop___ex_table = .;
> +
> +  . = ALIGN(4096);
> +  __init_begin = .;
> +  .text.init : { *(.text.init) }
> +  .data.init : { *(.data.init) }
> +  . = ALIGN(4096);
> +  __init_end = .;
> +
> +  __init_size = __init_end - _start;
> +
> +  __bss_start = .;
> +  .bss       :
> +  {
> +   *(.sbss*) *(.scommon*)
> +   *(.dynbss*)
> +   *(.bss*)
> +   *(COMMON)
> +  }
> +  _end = . ;
> +  PROVIDE (end = .);
> +}
> diff --git a/arch/ppc/boards/kp-mcb2/config.h b/arch/ppc/boards/kp-mcb2/config.h
> new file mode 100644
> index 0000000..c3aa86c
> --- /dev/null
> +++ b/arch/ppc/boards/kp-mcb2/config.h
> @@ -0,0 +1,253 @@
> +/*
> + * (C) Copyright 2003-2005
> + * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> + *
> + * (C) Copyright 2006
> + * Eric Schumann, Phytec Messatechnik GmbH
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#include <mach/mpc5xxx.h>
> +
> +/* #define DEBUG */
> +
> +/*------------------------------------------------------------------------------------------------------------------------------------------------------
> +High Level Configuration Options
> +(easy to change)
> + ------------------------------------------------------------------------------------------------------------------------------------------------------*/

These are really long lines. Please change this to standard

/*
 * comment
 */

> +#define CONFIG_MPC5200_DDR	1	/* (with DDR-SDRAM) */
> +#define CFG_MPC5XXX_CLKIN	33333000 /* ... running at 33.333333MHz */
> +#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH  */
> +#define BOOTFLAG_WARM		0x02	/* Software reboot	     */
> +
> +/*------------------------------------------------------------------------------------------------------------------------------------------------------
> +Serial console configuration
> + ------------------------------------------------------------------------------------------------------------------------------------------------------*/
> +
> +#if (TEXT_BASE == 0xFF000000)		/* Boot low */
> +#define CFG_LOWBOOT		1
> +#endif
> +/* RAMBOOT will be defined automatically in memory section */
> +
> +/*------------------------------------------------------------------------------------------------------------------------------------------------------
> +IPB Bus clocking configuration.
> + ------------------------------------------------------------------------------------------------------------------------------------------------------*/
> +#define  CFG_IPBSPEED_133		/* define for 133MHz speed */
> +#if defined(CFG_IPBSPEED_133)
> +/*
> + * PCI Bus clocking configuration
> + *
> + * Actually a PCI Clock of 66 MHz is only set (in cpu_init.c) if
> + * CFG_IPBSPEED_133 is defined. This is because a PCI Clock of 66 MHz yet hasn't
> + * been tested with a IPB Bus Clock of 66 MHz.
> + */
> +#define CFG_PCISPEED_66		/* define for 66MHz speed */
> +#else
> +#undef CFG_PCISPEED_66			/* for 33MHz speed */
> +#endif
> +
> +/* we only use CS-Boot */
> +#define CFG_BOOTCS_START	0xFE000000
> +#define CFG_BOOTCS_SIZE		0x02000000
> +
> +//#define CFG_BOOTCS_CFG	0x0008FD00
> +/* one additional waitstate for the 33MHz statemachine */
> +#define CFG_BOOTCS_CFG	0x0001dd00
> +
> +#define CFG_CS0_START		CFG_BOOTCS_START
> +#define CFG_CS0_SIZE		CFG_BOOTCS_SIZE
> +//#define CFG_CS0_CFG		0x0001dd00
> +
> +/* Konzeptpark MCB2 Mainboard Additions */
> +#define CFG_CS1_START           0xfd310000
> +#define CFG_CS1_SIZE            0x00010000
> +#define CFG_CS1_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
> +
> +#define CFG_CS2_START           0xfd320000
> +#define CFG_CS2_SIZE            0x00010000
> +#define CFG_CS2_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
> +
> +#define CFG_CS3_START           0xfd330000
> +#define CFG_CS3_SIZE            0x00010000
> +#define CFG_CS3_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
> +
> +
> +/* Konzeptpark MCB2 Topboard Additions */
> +#define CFG_CS4_START           0xfd400000
> +#define CFG_CS4_SIZE            0x00010000
> +#define CFG_CS4_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
> +
> +#define CFG_CS5_START           0xfd410000
> +#define CFG_CS5_SIZE            0x00010000
> +#define CFG_CS5_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
> +
> +#define CFG_CS6_START           0xfd420000
> +#define CFG_CS6_SIZE            0x00010000
> +#define CFG_CS6_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
> +
> +#define CFG_CS7_START           0xfd430000
> +#define CFG_CS7_SIZE            0x00010000
> +#define CFG_CS7_CFG             0x000AD800      /* 10WS, MX, AL, CE, AS_24, DS_8 */
> +
> +/*
> + * Use also hardware protection. This seems required, as the BDI uses hardware protection
> + * Without this, U-Boot can't work with this sectors, as its protection is software only by default
> + */
> +#define CFG_FLASH_PROTECTION	1
> +#define CFG_FLASH_EMPTY_INFO
> +
> +/*------------------------------------------------------------------------------------------------------------------------------------------------------
> +  Memory map
> + ------------------------------------------------------------------------------------------------------------------------------------------------------*/
> +#define CFG_MBAR		0xF0000000 /* MBAR hast to be switched by other bootloader or debugger config  */
> +#define CFG_SDRAM_BASE		0x00000000
> +
> +/* Use SRAM until RAM will be available */
> +#define CFG_INIT_RAM_ADDR	MPC5XXX_SRAM
> +#define CFG_INIT_RAM_SIZE	MPC5XXX_SRAM_SIZE	/* End of used area in DPRAM */
> +#define CONFIG_EARLY_INITDATA_SIZE 0x100
> +
> +#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
> +
> +/*------------------------------------------------------------------------------------------------------------------------------------------------------
> + GPIO configuration
> + ------------------------------------------------------------------------------------------------------------------------------------------------------*/
> +//#define CFG_GPS_PORT_CONFIG	0x00558c10 /* PSC6=UART, PSC3=UART ; Ether=100MBit with MD */

Please remove this line.

> +/*
> + * GPIO configuration
> + *
> + * Pin mapping:
> + *
> + * [29:31] = 01x
> + * PSC1_0 -> AC97 SDATA out
> + * PSC1_1 -> AC97 SDTA in
> + * PSC1_2 -> AC97 SYNC out
> + * PSC1_3 -> AC97 bitclock out
> + * PSC1_4 -> AC97 reset out
> + *
> + * [25:27] = 001
> + * PSC2_0 -> CAN 1 Tx out
> + * PSC2_1 -> CAN 1 Rx in
> + * PSC2_2 -> CAN 2 Tx out
> + * PSC2_3 -> CAN 2 Rx in
> + * PSC2_4 -> GPIO (claimed for ATA reset, active low)
> + *
> + * [20:23] = 1100
> + * PSC3_0 -> UART Tx out
> + * PSC3_1 -> UART Rx in
> + * PSC3_2 -> UART RTS (in/out FIXME)
> + * PSC3_3 -> UART CTS (in/out FIXME)
> + * PSC3_4 -> LocalPlus Bus CS6 \
> + * PSC3_5 -> LocalPlus Bus CS7 / --> see [4] and [5]
> + * PSC3_6 -> dedicated SPI MOSI out (master case)
> + * PSC3_7 -> dedicated SPI MISO in (master case)
> + * PSC3_8 -> dedicated SPI SS out (master case)
> + * PSC3_9 -> dedicated SPI CLK out (master case)
> + *
> + * [18:19] = 01
> + * USB_0 -> USB OE out
> + * USB_1 -> USB Tx- out
> + * USB_2 -> USB Tx+ out
> + * USB_3 -> USB RxD (in/out FIXME)
> + * USB_4 -> USB Rx+ in
> + * USB_5 -> USB Rx- in
> + * USB_6 -> USB PortPower out
> + * USB_7 -> USB speed out
> + * USB_8 -> USB suspend (in/out FIXME)
> + * USB_9 -> USB overcurrent in
> + *
> + * [17] = 0
> + * USB differential mode
> + *
> + * [16] = 0
> + * PCI enabled
> + *
> + * [12:15] = 0101
> + * ETH_0 -> ETH Txen
> + * ETH_1 -> ETH TxD0
> + * ETH_2 -> ETH TxD1
> + * ETH_3 -> ETH TxD2
> + * ETH_4 -> ETH TxD3
> + * ETH_5 -> ETH Txerr
> + * ETH_6 -> ETH MDC
> + * ETH_7 -> ETH MDIO
> + * ETH_8 -> ETH RxDv
> + * ETH_9 -> ETH RxCLK
> + * ETH_10 -> ETH Collision
> + * ETH_11 -> ETH TxD
> + * ETH_12 -> ETH RxD0
> + * ETH_13 -> ETH RxD1
> + * ETH_14 -> ETH RxD2
> + * ETH_15 -> ETH RxD3
> + * ETH_16 -> ETH Rxerr
> + * ETH_17 -> ETH CRS
> + *
> + * [9:11] = 101
> + * PSC6_0 -> UART RxD in
> + * PSC6_1 -> UART CTS (in/out FIXME)
> + * PSC6_2 -> UART TxD out
> + * PSC6_3 -> UART RTS (in/out FIXME)
> + *
> + * [2:3/6:7] = 00/11
> + * TMR_0 -> ATA_CS0 out
> + * TMR_1 -> ATA_CS1 out
> + * TMR_2 -> GPIO
> + * TMR_3 -> GPIO
> + * TMR_4 -> GPIO
> + * TMR_5 -> GPIO
> + * TMR_6 -> GPIO
> + * TMR_7 -> GPIO
> + * I2C_0 -> I2C 1 Clock out
> + * I2C_1 -> I2C 1 IO in/out
> + * I2C_2 -> I2C 2 Clock out
> + * I2C_3 -> I2C 2 IO in/out
> + *
> + * [4] = 1
> + * PSC3_5 is used as CS7
> + *
> + * [5] = 1
> + * PSC3_4 is used as CS6
> + *
> + * [1] = 0
> + * gpio_wkup_7 is GPIO
> + *
> + * [0] = 0
> + * gpio_wkup_6 is GPIO
> + *
> + */
> +#define CFG_GPS_PORT_CONFIG	0x0f551c12
> +
> +/*------------------------------------------------------------------------------------------------------------------------------------------------------
> + Various low-level settings
> + ------------------------------------------------------------------------------------------------------------------------------------------------------*/
> +#define CFG_HID0_INIT		HID0_ICE | HID0_ICFI
> +#define CFG_HID0_FINAL		HID0_ICE
> +
> +#define CFG_CS_BURST		0x00000000
> +#define CFG_CS_DEADCYCLE	0x33333333
> +
> +#define OF_CPU			"PowerPC,5200 at 0"
> +#define OF_TBCLK		CFG_MPC5XXX_CLKIN
> +#define OF_SOC                  "soc5200 at f0000000"
> +
> +#endif /* __CONFIG_H */
> diff --git a/arch/ppc/boards/kp-mcb2/kp-mcb2.c b/arch/ppc/boards/kp-mcb2/kp-mcb2.c
> new file mode 100644
> index 0000000..f4574c1
> --- /dev/null
> +++ b/arch/ppc/boards/kp-mcb2/kp-mcb2.c
> @@ -0,0 +1,349 @@
> +/*
> + * (C) Copyright 2003
> + * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> + *
> + * (C) Copyright 2004
> + * Mark Jonas, Freescale Semiconductor, mark.jonas at motorola.com.
> + *
> + * (C) Copyright 2006
> + * Eric Schumann, Phytec Messtechnik GmbH
> + *
> + * (C) Copyright 2010
> + * Carsten Schlote, konzeptpark GmbH
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +#define DEBUG

This shouldn't be defined

> +
> +#include <common.h>
> +#include <driver.h>
> +#include <init.h>
> +#include <mach/mpc5xxx.h>
> +#include <mach/fec.h>
> +#include <types.h>
> +#include <partition.h>
> +#include <mem_malloc.h>
> +#include <reloc.h>
> +
> +int cfi_flash_hwdetect (struct device_d *cfi_dev)
> +{

static

> +	int width, id=0;
> +	ulong mb=0, dev_size;
> +	ulong base = 0xfe000000;

base is always casted to (vu_short *). Maybe it's better to make this
a vu_short * in the first place?

> +	ulong lpb;
> +
> +	debug("BootCS: cfg=%08x\n", *(vu_long *)MPC5XXX_BOOTCS_CFG );
> +	debug("CS0: cfg=%08x\n", *(vu_long *)MPC5XXX_CS0_CFG );
> +	debug("*%08x = %04x\n", (vu_short *)base+0x100, *(vu_short *)base );
> +
> +	lpb = *(vu_long *)MPC5XXX_CS0_CFG;
> +
> +	*(vu_long *)MPC5XXX_BOOTCS_START = START_REG(base);
> +	*(vu_long *)MPC5XXX_BOOTCS_STOP = STOP_REG(base, 32 * 1024 * 1024);
> +	/*
> +	 * we run the PCI bus with 33 1/3 MHz. The flash requires 75ns accesstime.
> +	 * 2 base waitstates plus one additional waitstate makes the access as fast
> +	 * as possible (=90ns)
> +	 */
> +	lpb &=  0x0000dfc0; /* make it writable and mask out wait stages */
> +	lpb |=  0x0001d000; /* adjust wait stages */
> +	*(vu_long *)MPC5XXX_CS0_CFG = lpb;
> +
> +	/* get flash width */
> +	width = (lpb >> 8) & 0x3;
> +
> +	switch (width) {
> +	case 0: /* 8 bit */
> +		*(vu_char *)base = 0x90;
> +		id = *(vu_char *)(base + 3);
> +		*(vu_char *)base = 0xff;
> +		break;
> +	case 1: /* 16 bit */
> +		debug("*%08x = %04x\n", (vu_short *)base, *(vu_short *)base );
> +		*(vu_short *)base = 0x90;
> +		debug("*%08x = %04x\n", (vu_short *)base, *(vu_short *)base );
> +		id = *(vu_short *)(base + 2) & 0xff;
> +		debug("*%08x = %04x\n", (vu_short *)base, *(vu_short *)base );
> +		*(vu_short *)base = 0xff;
> +		debug("*%08x = %04x\n", (vu_short *)base, *(vu_short *)base );
> +		break;
> +	case 3: /* 32 bit */
> +		*(vu_short *)base = 0x90;
> +		id = *(vu_short *)(base + 4) & 0xff;
> +		*(vu_short *)base = 0xff;
> +		break;
> +	}
> +
> +	switch (id) {
> +	case 0x16:
> +		mb = 4;
> +		break;
> +	case 0x17:
> +		mb = 8;
> +		break;
> +	case 0x18:
> +		mb = 16;
> +		break;
> +	case 0x20:
> +		mb = 8;
> +		break;
> +	case 0x21:
> +		mb = 16;
> +		break;
> +	case 0x22:
> +		mb = 32;
> +		break;
> +	}
> +
> +	/* On these boards everything which is 32bit wide consists
> +	 * of two 16bit Flashes
> +	 */
> +	if (width == 3)
> +		mb <<= 1;
> +
> +	/*
> +	 * On this platform one chip select can only handle up to 32MiB.
> +	 * So we must limit boot cs's baseaddress to 0xfe000000 and above
> +         */
> +	if (mb > 32)
> +		dev_size = 32;
> +	else
> +		dev_size = mb;
> +
> +	debug("Flash configurator: width=%x id=%x dev_size=%d\n", width, id, dev_size);
> +	if (dev_size) {
> +		*(vu_long *)MPC5XXX_BOOTCS_START = START_REG(0x0u - (dev_size << 20));
> +		*(vu_long *)MPC5XXX_BOOTCS_STOP = STOP_REG(0x0u - (dev_size << 20), (dev_size << 20));
> +
> +		/*
> +		 * the developer is responsible to setup other chip select lines to
> +		 * reach other parts of the device if its larger than 32MiB
> +		 */
> +	}
> +	cfi_dev->map_base = 0x0u - (dev_size << 20);
> +	cfi_dev->size = (dev_size << 20);
> +	
> +	debug("BootCS: cfg=%08x\n", *(vu_long *)MPC5XXX_BOOTCS_CFG );
> +	debug("CS0: cfg=%08x\n", *(vu_long *)MPC5XXX_CS0_CFG );
> +
> +	return 0;
> +}
> +
> +struct device_d cfi_dev = {
> +	.name     = "cfi_flash",
> +	.map_base = 0xfe000000,
> +	.size     = 32 * 1024 * 1024,
> +};

static

Also, map_base and size shouldn't be initialized here as they get
overwriiten anyway. Maybe you could add a 'initialized during runtime'
comment instead.

> +
> +static struct memory_platform_data ram_pdata = {
> +	.name = "ram0",
> +	.flags = DEVFS_RDWR,
> +};
> +
> +struct device_d sdram_dev = {
> +	.name     = "mem",
> +	.map_base = 0x0,
> +	.size     = 128 * 1024 * 1024,
> +	.platform_data = &ram_pdata,
> +};

static

> +
> +static struct mpc5xxx_fec_platform_data fec_info = {
> +	.xcv_type = MII100,
> +};
> +
> +struct device_d eth_dev = {
> +	.name		= "fec_mpc5xxx",
> +	.map_base	= MPC5XXX_FEC,
> +	.platform_data	= &fec_info,
> +};

static

> +
> +static int devices_init (void)
> +{
> +	cfi_flash_hwdetect(&cfi_dev);
> +	if (cfi_dev.size)
> +		register_device(&cfi_dev);
> +	register_device(&sdram_dev);
> +	register_device(&eth_dev);
> +
> +	devfs_add_partition("nor0", 0x00000000, 0x0040000, PARTITION_FIXED, "bb-low");
> +	devfs_add_partition("nor0", 0x00040000, 0x1d00000, PARTITION_FIXED, "filesystem");
> +	devfs_add_partition("nor0", 0x01d40000, 0x01c0000, PARTITION_FIXED, "kernel");
> +	devfs_add_partition("nor0", 0x01f00000, 0x0080000, PARTITION_FIXED, "self0");
> +	devfs_add_partition("nor0", 0x01f80000, 0x0020000, PARTITION_FIXED, "dev-tree");
> +	devfs_add_partition("nor0", 0x01fa0000, 0x0040000, PARTITION_FIXED, "env0");

You assume a fixed flash size here while the actual size is probed
above. Either you have a fixed flash size in which case you can remove
the probing code above or the flash size is dynamic in which case you
should take it into account here.

> +
> +	return 0;
> +}
> +
> +device_initcall(devices_init);
> +
> +static struct device_d psc3 = {
> +	.name     = "mpc5xxx_serial",
> +	.map_base = MPC5XXX_PSC3,
> +	.size     = 4096,
> +};
> +
> +static struct device_d psc6 = {
> +	.name     = "mpc5xxx_serial",
> +	.map_base = MPC5XXX_PSC6,
> +	.size     = 4096,
> +};
> +
> +static int console_init(void)
> +{
> +	register_device(&psc3);
> +	register_device(&psc6);
> +	return 0;
> +}
> +
> +console_initcall(console_init);
> +
> +void *get_early_console_base(const char *name)
> +{
> +	if (!strcmp(name, RELOC("psc3")))
> +		return (void *)MPC5XXX_PSC3;
> +	if (!strcmp(name, RELOC("psc6")))
> +		return (void *)MPC5XXX_PSC6;
> +	return NULL;
> +}
> +
> +#include "mt46v32m16-75.h"
> +
> +static void sdram_start (int hi_addr)
> +{
> +	long hi_addr_bit = hi_addr ? 0x01000000 : 0;
> +
> +	/* unlock mode register */
> +	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
> +	__asm__ volatile ("sync");
> +
> +	/* precharge all banks */
> +	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
> +	__asm__ volatile ("sync");
> +
> +#if SDRAM_DDR
> +	/* set mode register: extended mode */
> +	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
> +	__asm__ volatile ("sync");
> +
> +	/* set mode register: reset DLL */
> +	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
> +	__asm__ volatile ("sync");
> +#endif
> +
> +	/* precharge all banks */
> +	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
> +	__asm__ volatile ("sync");
> +
> +	/* auto refresh */
> +	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
> +	__asm__ volatile ("sync");
> +
> +	/* set mode register */
> +	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
> +	__asm__ volatile ("sync");
> +
> +	/* normal operation */
> +	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
> +	__asm__ volatile ("sync");
> +}
> +
> +/*
> + * ATTENTION: Although partially referenced initdram does NOT make real use
> + *            use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
> + *            is something else than 0x00000000.
> + */

Then we should better stop using CFG_SDRAM_BASE and remove the comment
here.

> +
> +long int initdram (int board_type)
> +{
> +	ulong dramsize = 0;
> +	ulong dramsize2 = 0;
> +
> +	ulong test1, test2;
> +
> +	if ((ulong)RELOC(initdram) > (2 << 30)) {
> +		/* setup SDRAM chip selects */
> +		*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001b;/* 256MB at 0x0 */
> +		*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x10000000;/* disabled */
> +		__asm__ volatile ("sync");
> +
> +		/* setup config registers */
> +		*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
> +		*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
> +		__asm__ volatile ("sync");
> +
> +#if SDRAM_DDR && SDRAM_TAPDELAY
> +		/* set tap delay */
> +		*(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
> +		__asm__ volatile ("sync");
> +#endif
> +
> +		/* find RAM size using SDRAM CS0 only */
> +		sdram_start(0);
> +		test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x10000000);
> +		sdram_start(1);
> +		test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x10000000);
> +		if (test1 > test2) {
> +			sdram_start(0);
> +			dramsize = test1;
> +		} else {
> +			dramsize = test2;
> +		}
> +
> +		/* memory smaller than 1MB is impossible */
> +		if (dramsize < (1 << 20)) {
> +			dramsize = 0;
> +		}
> +
> +		/* set SDRAM CS0 size according to the amount of RAM found */
> +		if (dramsize > 0) {
> +			*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1;
> +		} else {
> +			*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
> +		}
> +	} else
> +		puts(RELOC("skipping sdram initialization\n"));
> +
> +	/* retrieve size of memory connected to SDRAM CS0 */
> +	dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
> +	if (dramsize >= 0x13) {
> +		dramsize = (1 << (dramsize - 0x13)) << 20;
> +	} else {
> +		dramsize = 0;
> +	}
> +
> +	/* retrieve size of memory connected to SDRAM CS1 */
> +	dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
> +	if (dramsize2 >= 0x13) {
> +		dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
> +	} else {
> +		dramsize2 = 0;
> +	}
> +
> +	return dramsize + dramsize2;
> +}
> +
> +#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
> +void
> +ft_board_setup(void *blob, bd_t *bd)
> +{
> +	ft_cpu_setup(blob, bd);
> +}
> +#endif
> +
> diff --git a/arch/ppc/boards/kp-mcb2/kp-mcb2.dox b/arch/ppc/boards/kp-mcb2/kp-mcb2.dox
> new file mode 100644
> index 0000000..db64ba9
> --- /dev/null
> +++ b/arch/ppc/boards/kp-mcb2/kp-mcb2.dox
> @@ -0,0 +1,8 @@
> +/** @page kp-mcb2 konzeptpark MCB2
> +
> +This CPU card is based on a Freescale MPC5200B CPU. The card is shipped with:
> +
> +- 32MiB NOR type Flash Memory
> +- 128MiB synchronous dynamic RAM
> +
> +*/
> diff --git a/arch/ppc/boards/kp-mcb2/mt46v32m16-75.h b/arch/ppc/boards/kp-mcb2/mt46v32m16-75.h
> new file mode 100644
> index 0000000..4d191f1
> --- /dev/null
> +++ b/arch/ppc/boards/kp-mcb2/mt46v32m16-75.h
> @@ -0,0 +1,46 @@
> +/*
> + * (C) Copyright 2004
> + * Mark Jonas, Freescale Semiconductor, mark.jonas at motorola.com.
> + *
> + * Eric Schumann, Phytec Messtechnik
> + * adapted for mt46v32m16-75 DDR-RAM
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#define SDRAM_DDR	1		/* is DDR */
> +
> +/* Settings for XLB = 132 MHz */
> +#define SDRAM_MODE	0x018D0000
> +#define SDRAM_EMODE	0x40090000
> +#define SDRAM_CONTROL	0x715f0f00
> +#define SDRAM_CONFIG1	0x73722930
> +#define SDRAM_CONFIG2	0x47770000
> +
> +
> +/* Settings for XLB = 99 MHz */
> +/*
> +#define SDRAM_MODE	0x008D0000
> +#define SDRAM_EMODE	0x40090000
> +#define SDRAM_CONTROL	0x714b0f00
> +#define SDRAM_CONFIG1	0x63611730
> +#define SDRAM_CONFIG2	0x47670000
> +*/
> +
> +#define SDRAM_TAPDELAY	0x10000000 /* reserved Bit in MPC5200 B3-Step */
> diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig
> index 5da6a5b..ce8815d 100644
> --- a/arch/ppc/mach-mpc5xxx/Kconfig
> +++ b/arch/ppc/mach-mpc5xxx/Kconfig
> @@ -3,7 +3,7 @@ menu "Board specific settings       "
>  config MACH_PHYCORE_MPC5200B_TINY_REV
>  	int "Board Revision"
>  	default 1
> -	depends on MACH_PHYCORE_MPC5200B_TINY
> +	depends on MACH_PHYCORE_MPC5200B_TINY || MACH_KONZEPTPARK_MCB2

You don't use MACH_PHYCORE_MPC5200B_TINY_REV and it looks strange to set
it for your board.

>  	help
>  	  Revision 0 and revision 1 of the tiny board have
>  	  incompatible flash settings. Unless you have a very
> @@ -12,4 +12,5 @@ config MACH_PHYCORE_MPC5200B_TINY_REV
>  endmenu
>  
>  config EARLY_CONSOLE_PORT
> -	default "psc3" if MACH_PHYCORE_MPC5200B_TINY
> \ No newline at end of file
> +	default "psc3" if MACH_PHYCORE_MPC5200B_TINY
> +	default "psc3" if MACH_KONZEPTPARK_MCB2
> -- 
> 1.7.2.2.277.gb49c4
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct 15 06:34:58 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 15 Oct 2010 12:34:58 +0200
Subject: [PATCH 4/5] [compiler] Added OPTIMIZE options to enable GCC
	optimizer
In-Reply-To: <1287054406-31713-4-git-send-email-carsten.schlote@gmx.net>
References: <1287054406-31713-1-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-2-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-3-git-send-email-carsten.schlote@gmx.net>
	<1287054406-31713-4-git-send-email-carsten.schlote@gmx.net>
Message-ID: <20101015103458.GB28242@pengutronix.de>

On Thu, Oct 14, 2010 at 01:06:45PM +0200, Carsten Schlote wrote:
> From: Carsten Schlote <c.schlote at konzeptpark.de>
> 
> With GCC 4.5.x the default option -Os causes problems on powerpc as it
> tries to move common code to libgcc2, which isn't correctly linked later.
> 
> With optimizer turned off, code compiles fine.
> 
> So I added some options to turn on/off optimization for all architectures
> and to choose between -Os and -O option.
> 
> In case your compiler produces broken code or refuses to link, just try
> without optimization. As it's an option no hack in the Makefile is required
> anymore.
>

Working around weird compiler behaviours is not a good argument for
selling this patch. Anyway, this can still be useful in several
situations like for example getting assembler code which is easier
to debug.

How about making this a choice?

choice
	prompt "compiler optimization"
	default CC_OPTIMIZE_FOR_SIZE

config CC_OPTIMIZE_FOR_SIZE
	bool "optimize for size"

config CC_OPTIMIZE_NONE
	bool "no optimization"

config CC_OPTIMIZE_SPEED
	bool "optimize for speed"

endchoice

This would simplify the ifdefs in the Makefiles. Also, size
optimization should be kept default.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Sat Oct 16 09:46:52 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Sat, 16 Oct 2010 15:46:52 +0200
Subject: [PATCH] imx: Separate framebuffer platformdata and the videomode
Message-ID: <201010161546.52848.jbe@pengutronix.de>

commit 4ac682bf08b61708bc432c48e58a6d1cf9ea3832
Author: Juergen Beisert <jbe at pengutronix.de>
Date:   Sat Oct 16 15:32:06 2010 +0200

    imx: Separate framebuffer platformdata and the videomode
    
    This patch separates the imx platformdata and its videomode in two structures,
    in order to support more than one defined videomode in the boardfile. This
    is intended to support runtime videomode selection later on. It also uses
    now the same videomode setup style than the imx-fpu based systems (like the
    i.MX35).
    
    Signed-off-by: Juergen Beisert <jbe at pengutronix.de>

diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index c2eb398..b1b9852 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -119,20 +119,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode cmo_display = {
+	.name		= "CMO-QVGA",
+	.refresh	= 60,
+	.xres		= 320,
+	.yres		= 240,
+	.pixclock	= KHZ2PICOS(6500),
+	.hsync_len	= 30,
+	.left_margin	= 38,
+	.right_margin	= 20,
+	.vsync_len	= 3,
+	.upper_margin	= 15,
+	.lower_margin	= 4,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CMO-QVGA",
-		.refresh	= 60,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= KHZ2PICOS(6500),
-		.hsync_len	= 30,
-		.left_margin	= 38,
-		.right_margin	= 20,
-		.vsync_len	= 3,
-		.upper_margin	= 15,
-		.lower_margin	= 4,
-	},
+	.mode		= &cmo_display,
 	.pcr		= 0xCAD08B80,
 	.bpp		= 16,
 };
diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
index 62fc14e..3ea2466 100644
--- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
+++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
@@ -186,20 +186,22 @@ static void eukrea_cpuimx27_mmu_init(void)
 #endif
 
 #ifdef CONFIG_DRIVER_VIDEO_IMX
+static struct fb_videomode cmo_display = {
+	.name		= "CMO-QVGA",
+	.refresh	= 60,
+	.xres		= 320,
+	.yres		= 240,
+	.pixclock	= 156000,
+	.hsync_len	= 30,
+	.left_margin	= 38,
+	.right_margin	= 20,
+	.vsync_len	= 3,
+	.upper_margin	= 15,
+	.lower_margin	= 4,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CMO-QVGA",
-		.refresh	= 60,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= 156000,
-		.hsync_len	= 30,
-		.left_margin	= 38,
-		.right_margin	= 20,
-		.vsync_len	= 3,
-		.upper_margin	= 15,
-		.lower_margin	= 4,
-	},
+	.mode		= &cmo_display,
 	.pcr		= 0xFAD08B80,
 	.bpp		= 16,};
 
diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c
index 9c85c08..6949675 100644
--- a/arch/arm/boards/guf-neso/board.c
+++ b/arch/arm/boards/guf-neso/board.c
@@ -91,20 +91,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode cpt_display = {
+	.name		= "CPT CLAA070LC0JCT",
+	.refresh	= 60,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= KHZ2PICOS(27000),
+	.hsync_len	= 1,	/* DE only sync */
+	.left_margin	= 50,
+	.right_margin	= 50,
+	.vsync_len	= 1,	/* DE only sync */
+	.upper_margin	= 10,
+	.lower_margin	= 10,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CPT CLAA070LC0JCT",
-		.refresh	= 60,
-		.xres		= 800,
-		.yres		= 480,
-		.pixclock	= KHZ2PICOS(27000),
-		.hsync_len	= 1,	/* DE only sync */
-		.left_margin	= 50,
-		.right_margin	= 50,
-		.vsync_len	= 1,	/* DE only sync */
-		.upper_margin	= 10,
-		.lower_margin	= 10,
-	},
+	.mode = &cpt_display,
 	/*
 	 * - TFT style panel
 	 * - clk enabled while idle
diff --git a/arch/arm/boards/imx21ads/imx21ads.c b/arch/arm/boards/imx21ads/imx21ads.c
index 44d37aa..81006de 100644
--- a/arch/arm/boards/imx21ads/imx21ads.c
+++ b/arch/arm/boards/imx21ads/imx21ads.c
@@ -79,24 +79,26 @@ static struct device_d cs8900_dev = {
 	// IRQ is connected to UART3_RTS
 };
 
+static struct fb_videomode sharp_display = {
+	.name           = "Sharp-LQ035Q7",
+	.refresh        = 60,
+	.xres           = 240,
+	.yres           = 320,
+	.pixclock       = 188679,
+	.left_margin    = 6,
+	.right_margin   = 16,
+	.upper_margin   = 8,
+	.lower_margin   = 10,
+	.hsync_len      = 2,
+	.vsync_len      = 1,
+	.sync           = 0,
+	.vmode          = FB_VMODE_NONINTERLACED,
+	.flag           = 0,
+};
+
 /* Sharp LQ035Q7DB02 QVGA display */
 static struct imx_fb_videomode imx_fb_modedata = {
-        .mode = {
-		.name           = "Sharp-LQ035Q7",
-		.refresh        = 60,
-		.xres           = 240,
-		.yres           = 320,
-		.pixclock       = 188679,
-		.left_margin    = 6,
-		.right_margin   = 16,
-		.upper_margin   = 8,
-		.lower_margin   = 10,
-		.hsync_len      = 2,
-		.vsync_len      = 1,
-		.sync           = 0,
-		.vmode          = FB_VMODE_NONINTERLACED,
-		.flag           = 0,
-	},
+        .mode           = &sharp_display,
         .pcr            = 0xfb108bc7,
         .bpp            = 16,
 };
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index 3a9b413..026e9c0 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -127,20 +127,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode sharp_display = {
+	.name		= "Sharp-LQ035Q7",
+	.refresh	= 60,
+	.xres		= 240,
+	.yres		= 320,
+	.pixclock	= 188679, /* in ps (5.3MHz) */
+	.hsync_len	= 7,
+	.left_margin	= 5,
+	.right_margin	= 16,
+	.vsync_len	= 1,
+	.upper_margin	= 7,
+	.lower_margin	= 9,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "Sharp-LQ035Q7",
-		.refresh	= 60,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 188679, /* in ps (5.3MHz) */
-		.hsync_len	= 7,
-		.left_margin	= 5,
-		.right_margin	= 16,
-		.vsync_len	= 1,
-		.upper_margin	= 7,
-		.lower_margin	= 9,
-	},
+	.mode		= &sharp_display,
 	/*
 	 * - HSYNC active high
 	 * - VSYNC active high
diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h
index 16b43ea..7baa244 100644
--- a/arch/arm/mach-imx/include/mach/imxfb.h
+++ b/arch/arm/mach-imx/include/mach/imxfb.h
@@ -50,7 +50,7 @@
 #define DMACR_TM(x)	((x) & 0xf)
 
 struct imx_fb_videomode {
-	struct fb_videomode mode;
+	struct fb_videomode *mode;
 	u32 pcr;
 	unsigned char	bpp;
 };
diff --git a/drivers/video/imx.c b/drivers/video/imx.c
index ac51858..6ccd77e 100644
--- a/drivers/video/imx.c
+++ b/drivers/video/imx.c
@@ -555,9 +555,9 @@ static int imxfb_probe(struct device_d *dev)
 	fbi->enable = pdata->enable;
 	fbi->dev = dev;
 	info->priv = fbi;
-	info->mode = &pdata->mode->mode;
-	info->xres = pdata->mode->mode.xres;
-	info->yres = pdata->mode->mode.yres;
+	info->mode = pdata->mode->mode;
+	info->xres = pdata->mode->mode->xres;
+	info->yres = pdata->mode->mode->yres;
 	info->bits_per_pixel = pdata->mode->bpp;
 	info->fbops = &imxfb_ops;
 
-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From baruch at tkos.co.il  Sat Oct 16 15:01:03 2010
From: baruch at tkos.co.il (Baruch Siach)
Date: Sat, 16 Oct 2010 21:01:03 +0200
Subject: [PATCH 06/10] eukrea_cpuimx25: update board support
In-Reply-To: <1287065132-20372-6-git-send-email-eric@eukrea.com>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
	<1287065132-20372-6-git-send-email-eric@eukrea.com>
Message-ID: <20101016190102.GD6225@tarshish>

Hi Eric,

On Thu, Oct 14, 2010 at 04:05:28PM +0200, Eric B?nard wrote:
> - support NAND external boot
> - enable only used clocks
> - LCD fix in /env/bin/init
> - I2C support
> - SDCard support
> - USB Host 1 support
> - DFU support on OTG port
> - update defconfig
> 
> Signed-off-by: Eric B?nard <eric at eukrea.com>
> ---
>  arch/arm/boards/eukrea_cpuimx25/env/bin/init      |    2 +
>  arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c |  104 +++++++++++++++++++-
>  arch/arm/boards/eukrea_cpuimx25/lowlevel.c        |   64 ++++++++++---
>  arch/arm/configs/eukrea_cpuimx25_defconfig        |   12 ++-
>  4 files changed, 162 insertions(+), 20 deletions(-)

[snip]

> diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c 
> b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> index 7fd1031..c2eb398 100644
> --- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> +++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c

[snip]

> +#ifdef CONFIG_USB
> +
> +#define MX35_H1_SIC_SHIFT	21
> +#define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
> +#define MX35_H1_PM_BIT		(1 << 8)
> +#define MX35_H1_IPPUE_UP_BIT	(1 << 7)
> +#define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
> +#define MX35_H1_TLL_BIT		(1 << 5)
> +#define MX35_H1_USBTE_BIT	(1 << 4)
> +#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)

The exact same defines appear in patch no. 10 of this series. IMO these should 
go into a shared header file.

baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -


From jbe at pengutronix.de  Mon Oct 18 12:43:39 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 18 Oct 2010 18:43:39 +0200
Subject: [PATCH] Add GPIO support and GPIO setup features to the S3C processors
Message-ID: <201010181843.39263.jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>
Subject: Add GPIO support and GPIO setup features to the S3C processors

This patch adds genetic GPIO support to all S3C2440 processor based systems.
Also it adds definitions to setup the pin multiplexer in a way the other
architectures do.

Note: Tested on a S3C2440 based system only. But should work on an S3C2410, too.

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>

---
 arch/arm/Kconfig                                   |    1 
 arch/arm/mach-s3c24xx/Makefile                     |    2 
 arch/arm/mach-s3c24xx/gpio-s3c24x0.c               |  170 ++++++++
 arch/arm/mach-s3c24xx/include/mach/gpio.h          |   31 +
 arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h |  426 +++++++++++++++++++++
 5 files changed, 629 insertions(+), 1 deletion(-)

Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
===================================================================
--- /dev/null
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
@@ -0,0 +1,170 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <mach/s3c24x0-iomap.h>
+#include <mach/gpio.h>
+
+static const unsigned char group_offset[] =
+{
+	0x00,	/* GPA */
+	0x10,	/* GPB */
+	0x20,	/* GPC */
+	0x30,	/* GPD */
+	0x40,	/* GPE */
+	0x50,	/* GPF */
+	0x60,	/* GPG */
+	0x70,	/* GPH */
+#ifdef CONFIG_CPU_S3C2440
+	0xd0,	/* GPJ */
+#endif
+};
+
+void gpio_set_value(unsigned gpio, int value)
+{
+	unsigned group = gpio >> 5;
+	unsigned bit = gpio % 32;
+	unsigned offset;
+	uint32_t reg;
+
+	offset = group_offset[group];
+
+	reg = readl(GPADAT + offset);
+	reg &= ~(1 << bit);
+	reg |= (!!value) << bit;
+	writel(reg, GPADAT + offset);
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+	unsigned group = gpio >> 5;
+	unsigned bit = gpio % 32;
+	unsigned offset;
+	uint32_t reg;
+
+	offset = group_offset[group];
+
+	reg = readl(GPACON + offset);
+	reg &= ~(0x3 << (bit << 1));
+	writel(reg, GPACON + offset);
+
+	return 0;
+}
+
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+	unsigned group = gpio >> 5;
+	unsigned bit = gpio % 32;
+	unsigned offset;
+	uint32_t reg;
+
+	offset = group_offset[group];
+
+	/* value */
+	reg = readl(GPADAT + offset);
+	reg &= ~(1 << bit);
+	reg |= (!!value) << bit;
+	writel(reg, GPADAT + offset);
+
+	/* direction */
+	if (group == 0) {	/* GPA is special */
+		reg = readl(GPACON);
+		reg &= ~(1 << bit);
+		writel(reg, GPACON);
+	} else {
+		reg = readl(GPACON + offset);
+		reg &= ~(0x3 << (bit << 1));
+		reg |= 0x1 << (bit << 1);
+		writel(reg, GPACON + offset);
+	}
+
+	return 0;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+	unsigned group = gpio >> 5;
+	unsigned bit = gpio % 32;
+	unsigned offset;
+	uint32_t reg;
+
+	offset = group_offset[group];
+
+	/* value */
+	reg = readl(GPADAT + offset);
+
+	return !!(reg & (1 << bit));
+}
+
+void s3c_gpio_mode(unsigned gpio_mode)
+{
+	unsigned group, func, bit, offset, gpio;
+	uint32_t reg;
+
+	group = GET_GROUP(gpio_mode);
+	func = GET_FUNC(gpio_mode);
+	bit = GET_BIT(gpio_mode);
+	gpio = GET_GPIO_NO(gpio_mode);
+
+	if (group == 0) {
+		/* GPA is special */
+		switch (func) {
+		case 0:		/* GPIO input */
+			pr_debug("Cannot set GPA pin to GPIO input\n");
+			break;
+		case 1:		/* GPIO output */
+			gpio_direction_output(bit, GET_GPIOVAL(gpio_mode));
+			break;
+		default:
+			reg = readl(GPACON);
+			reg |= 1 << bit;
+			writel(reg, GPACON);
+			break;
+		}
+		return;
+	}
+
+	offset = group_offset[group];
+
+	if (PU_PRESENT(gpio_mode)) {
+		reg = readl(GPACON + offset + 8);
+		if (GET_PU(gpio_mode))
+			reg |= (1 << bit);	/* set means _disabled_ */
+		else
+			reg &= ~(1 << bit);
+		writel(reg, GPACON + offset + 8);
+	}
+
+	switch (func) {
+	case 0: /* input */
+		gpio_direction_input(gpio);
+		break;
+	case 1:	/* output */
+		gpio_direction_output(gpio, GET_GPIOVAL(gpio_mode));
+		break;
+	case 2: /* function one */
+	case 3: /* function two */
+		reg = readl(GPACON + offset);
+		reg &= ~(0x3 << (bit << 1));
+		reg |= func << (bit << 1);
+		writel(reg, GPACON + offset);
+		break;
+	}
+}
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/gpio.h
===================================================================
--- /dev/null
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/gpio.h
@@ -0,0 +1,31 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_MACH_GPIO_H
+#define __ASM_MACH_GPIO_H
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2410)
+# include <mach/iomux-s3c24x0.h>
+#endif
+
+void gpio_set_value(unsigned, int);
+int gpio_direction_input(unsigned);
+int gpio_direction_output(unsigned, int);
+int gpio_get_value(unsigned);
+void s3c_gpio_mode(unsigned);
+
+#endif /* __ASM_MACH_GPIO_H */
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h
===================================================================
--- /dev/null
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MACH_IOMUX_S3C24x0_H
+#define __MACH_IOMUX_S3C24x0_H
+
+/* 3322222222221111111111
+ * 10987654321098765432109876543210
+ *                            ^^^^^_ Bit offset
+ *                        ^^^^______ Group Number
+ *                    ^^____________ Function
+ *                   ^______________ initial GPIO out value
+ *                  ^_______________ Pull up feature present
+ *                 ^________________ initial pull up setting
+ */
+
+
+#define PIN(group,bit) (group * 32 + bit)
+#define FUNC(x) (((x) & 0x3) << 11)
+#define GET_FUNC(x) (((x) >> 11) & 0x3)
+#define GET_GROUP(x) (((x) >> 5) & 0xf)
+#define GET_BIT(x) (((x) & 0x1ff) % 32)
+#define GET_GPIOVAL(x) (((x) >> 13) & 0x1)
+#define GET_GPIO_NO(x) ((x & 0x1ff))
+#define GPIO_OUT FUNC(1)
+#define GPIO_IN FUNC(0)
+#define GPIO_VAL(x) ((!!(x)) << 13)
+#define PU (1 << 14)
+#define PU_PRESENT(x) (!!((x) & (1 << 14)))
+#define ENABLE_PU (0 << 15)
+#define DISABLE_PU (1 << 15)
+#define GET_PU(x) (!!((x) & DISABLE_PU))
+
+/*
+ * Group 0: GPIO 0...31
+ * Used GPIO: 0...22
+ * These pins can also act as GPIO outputs
+ */
+#define GPA0_ADDR0		(PIN(0,0) | FUNC(2))
+#define GPA0_ADDR0_GPIO		(PIN(0,0) | FUNC(0))
+#define GPA1_ADDR16		(PIN(0,1) | FUNC(2))
+#define GPA1_ADDR16_GPIO	(PIN(0,1) | FUNC(0))
+#define GPA2_ADDR17		(PIN(0,2) | FUNC(2))
+#define GPA2_ADDR17_GPIO	(PIN(0,2) | FUNC(0))
+#define GPA3_ADDR18		(PIN(0,3) | FUNC(2))
+#define GPA3_ADDR18_GPIO	(PIN(0,3) | FUNC(0))
+#define GPA4_ADDR19		(PIN(0,4) | FUNC(2))
+#define GPA4_ADDR19_GPIO	(PIN(0,4) | FUNC(0))
+#define GPA5_ADDR20		(PIN(0,5) | FUNC(2))
+#define GPA5_ADDR20_GPIO	(PIN(0,5) | FUNC(0))
+#define GPA6_ADDR21		(PIN(0,6) | FUNC(2))
+#define GPA6_ADDR21_GPIO	(PIN(0,6) | FUNC(0))
+#define GPA7_ADDR22		(PIN(0,7) | FUNC(2))
+#define GPA7_ADDR22_GPIO	(PIN(0,7) | FUNC(0))
+#define GPA8_ADDR23		(PIN(0,8) | FUNC(2))
+#define GPA8_ADDR23_GPIO	(PIN(0,8) | FUNC(0))
+#define GPA9_ADDR24		(PIN(0,9) | FUNC(2))
+#define GPA9_ADDR24_GPIO	(PIN(0,9) | FUNC(0))
+#define GPA10_ADDR25		(PIN(0,10) | FUNC(2))
+#define GPA10_ADDR25_GPIO	(PIN(0,10) | FUNC(0))
+#define GPA11_ADDR26		(PIN(0,11) | FUNC(2))
+#define GPA11_ADDR26_GPIO	(PIN(0,11) | FUNC(0))
+#define GPA12_NGCS1		(PIN(0,12) | FUNC(2))
+#define GPA12_NGCS1_GPIO	(PIN(0,12) | FUNC(0))
+#define GPA13_NGCS2		(PIN(0,13) | FUNC(2))
+#define GPA13_NGCS2_GPIO	(PIN(0,13) | FUNC(0))
+#define GPA14_NGCS3		(PIN(0,14) | FUNC(2))
+#define GPA14_NGCS3_GPIO	(PIN(0,14) | FUNC(0))
+#define GPA15_NGCS4		(PIN(0,15) | FUNC(2))
+#define GPA15_NGCS4_GPIO	(PIN(0,15) | FUNC(0))
+#define GPA16_NGCS5		(PIN(0,16) | FUNC(2))
+#define GPA16_NGCS5_GPIO	(PIN(0,16) | FUNC(0))
+#define GPA17_CLE		(PIN(0,17) | FUNC(2))
+#define GPA17_CLE_GPIO		(PIN(0,17) | FUNC(0))
+#define GPA18_ALE		(PIN(0,18) | FUNC(2))
+#define GPA18_ALE_GPIO		(PIN(0,18) | FUNC(0))
+#define GPA19_NFWE		(PIN(0,19) | FUNC(2))
+#define GPA19_NFWE_GPIO		(PIN(0,19) | FUNC(0))
+#define GPA20_NFRE		(PIN(0,20) | FUNC(2))
+#define GPA20_NFRE_GPIO		(PIN(0,20) | FUNC(0))
+#define GPA21_NRSTOUT		(PIN(0,21) | FUNC(2))
+#define GPA21_NRSTOUT_GPIO	(PIN(0,21) | FUNC(0))
+#define GPA22_NFCE		(PIN(0,22) | FUNC(2))
+#define GPA22_NFCE_GPIO		(PIN(0,22) | FUNC(0))
+
+/*
+ * Group 1: GPIO 32...63
+ * Used GPIO: 0...10
+ * these pins can also act as GPIO inputs/outputs
+ */
+#define GPB0_TOUT0	(PIN(1,0) | FUNC(2) | PU)
+#define GPB0_GPIO	(PIN(1,0) | FUNC(0) | PU)
+#define GPB1_TOUT1	(PIN(1,1) | FUNC(2) | PU)
+#define GPB1_GPIO	(PIN(1,1) | FUNC(0) | PU)
+#define GPB2_TOUT2	(PIN(1,2) | FUNC(2) | PU)
+#define GPB2_GPIO	(PIN(1,2) | FUNC(0) | PU)
+#define GPB3_TOUT3	(PIN(1,3) | FUNC(2) | PU)
+#define GPB3_GPIO	(PIN(1,3) | FUNC(0) | PU)
+#define GPB4_TCLK0	(PIN(1,4) | FUNC(2) | PU)
+#define GPB4_GPIO	(PIN(1,4) | FUNC(0) | PU)
+#define GPB5_NXBACK	(PIN(1,5) | FUNC(2) | PU)
+#define GPB5_GPIO	(PIN(1,5) | FUNC(0) | PU)
+#define GPB6_NXBREQ	(PIN(1,6) | FUNC(2) | PU)
+#define GPB6_GPIO	(PIN(1,6) | FUNC(0) | PU)
+#define GPB7_NXDACK1	(PIN(1,7) | FUNC(2) | PU)
+#define GPB7_GPIO	(PIN(1,7) | FUNC(0) | PU)
+#define GPB8_NXDREQ1	(PIN(1,8) | FUNC(2) | PU)
+#define GPB8_GPIO	(PIN(1,8) | FUNC(0) | PU)
+#define GPB9_NXDACK0	(PIN(1,9) | FUNC(2) | PU)
+#define GPB9_GPIO	(PIN(1,9) | FUNC(0) | PU)
+#define GPB10_NXDREQ0	(PIN(1,10) | FUNC(2) | PU)
+#define GPB10_GPIO	(PIN(1,10) | FUNC(0) | PU)
+
+/*
+ * Group 1: GPIO 64...95
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPC0_LEND	(PIN(2,0) | FUNC(2) | PU)
+#define GPC0_GPIO	(PIN(2,0) | FUNC(0) | PU)
+#define GPC1_VCLK	(PIN(2,1) | FUNC(2) | PU)
+#define GPC1_GPIO	(PIN(2,1) | FUNC(0) | PU)
+#define GPC2_VLINE	(PIN(2,2) | FUNC(2) | PU)
+#define GPC2_GPIO	(PIN(2,2) | FUNC(0) | PU)
+#define GPC3_VFRAME	(PIN(2,3) | FUNC(2) | PU)
+#define GPC3_GPIO	(PIN(2,3) | FUNC(0) | PU)
+#define GPC4_VM		(PIN(2,4) | FUNC(2) | PU)
+#define GPC4_GPIO	(PIN(2,4) | FUNC(0) | PU)
+#define GPC5_LPCOE	(PIN(2,5) | FUNC(2) | PU)
+#define GPC5_GPIO	(PIN(2,5) | FUNC(0) | PU)
+#define GPC6_LPCREV	(PIN(2,6) | FUNC(2) | PU)
+#define GPC6_GPIO	(PIN(2,6) | FUNC(0) | PU)
+#define GPC7_LPCREVB	(PIN(2,7) | FUNC(2) | PU)
+#define GPC7_GPIO	(PIN(2,7) | FUNC(0) | PU)
+#define GPC8_VD0	(PIN(2,8) | FUNC(2) | PU)
+#define GPC8_GPIO	(PIN(2,8) | FUNC(0) | PU)
+#define GPC9_VD1	(PIN(2,9) | FUNC(2) | PU)
+#define GPC9_GPIO	(PIN(2,9) | FUNC(0) | PU)
+#define GPC10_VD2	(PIN(2,10) | FUNC(2) | PU)
+#define GPC10_GPIO	(PIN(2,10) | FUNC(0) | PU)
+#define GPC11_VD3	(PIN(2,11) | FUNC(2) | PU)
+#define GPC11_GPIO	(PIN(2,11) | FUNC(0) | PU)
+#define GPC12_VD4	(PIN(2,12) | FUNC(2) | PU)
+#define GPC12_GPIO	(PIN(2,12) | FUNC(0) | PU)
+#define GPC13_VD5	(PIN(2,13) | FUNC(2) | PU)
+#define GPC13_GPIO	(PIN(2,13) | FUNC(0) | PU)
+#define GPC14_VD6	(PIN(2,14) | FUNC(2) | PU)
+#define GPC14_GPIO	(PIN(2,14) | FUNC(0) | PU)
+#define GPC15_VD7	(PIN(2,15) | FUNC(2) | PU)
+#define GPC15_GPIO	(PIN(2,15) | FUNC(0) | PU)
+
+/*
+ * Group 1: GPIO 96...127
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPD0_VD8	(PIN(3,0) | FUNC(2) | PU)
+#define GPD0_GPIO	(PIN(3,0) | FUNC(0) | PU)
+#define GPD1_VD9	(PIN(3,1) | FUNC(2) | PU)
+#define GPD1_GPIO	(PIN(3,1) | FUNC(0) | PU)
+#define GPD2_VD10	(PIN(3,2) | FUNC(2) | PU)
+#define GPD2_GPIO	(PIN(3,2) | FUNC(0) | PU)
+#define GPD3_VD11	(PIN(3,3) | FUNC(2) | PU)
+#define GPD3_GPIO	(PIN(3,3) | FUNC(0) | PU)
+#define GPD4_VD12	(PIN(3,4) | FUNC(2) | PU)
+#define GPD4_GPIO	(PIN(3,4) | FUNC(0) | PU)
+#define GPD5_VD13	(PIN(3,5) | FUNC(2) | PU)
+#define GPD5_GPIO	(PIN(3,5) | FUNC(0) | PU)
+#define GPD6_VD14	(PIN(3,6) | FUNC(2) | PU)
+#define GPD6_GPIO	(PIN(3,6) | FUNC(0) | PU)
+#define GPD7_VD15	(PIN(3,7) | FUNC(2) | PU)
+#define GPD7_GPIO	(PIN(3,7) | FUNC(0) | PU)
+#define GPD8_VD16	(PIN(3,8) | FUNC(2) | PU)
+#define GPD8_GPIO	(PIN(3,8) | FUNC(0) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPD8_SPIMISO1	(PIN(3,8) | FUNC(3) | PU)
+#endif
+#define GPD9_VD17	(PIN(3,9) | FUNC(2) | PU)
+#define GPD9_GPIO	(PIN(3,9) | FUNC(0) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPD9_SPIMOSI1	(PIN(3,9) | FUNC(3) | PU)
+#endif
+#define GPD10_VD18	(PIN(3,10) | FUNC(2) | PU)
+#define GPD10_GPIO	(PIN(3,10) | FUNC(0) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPD10_SPICLK	(PIN(3,10) | FUNC(3) | PU)
+#endif
+#define GPD11_VD19	(PIN(3,11) | FUNC(2) | PU)
+#define GPD11_GPIO	(PIN(3,11) | FUNC(0) | PU)
+#define GPD12_VD20	(PIN(3,12) | FUNC(2) | PU)
+#define GPD12_GPIO	(PIN(3,12) | FUNC(0) | PU)
+#define GPD13_VD21	(PIN(3,13) | FUNC(2) | PU)
+#define GPD13_GPIO	(PIN(3,13) | FUNC(0) | PU)
+#define GPD14_VD22	(PIN(3,14) | FUNC(2) | PU)
+#define GPD14_GPIO	(PIN(3,14) | FUNC(0) | PU)
+#define GPD14_NSS1	(PIN(3,14) | FUNC(3) | PU)
+#define GPD15_VD23	(PIN(3,15) | FUNC(2) | PU)
+#define GPD15_GPIO	(PIN(3,15) | FUNC(0) | PU)
+#define GPD15_NSS0	(PIN(3,15) | FUNC(3) | PU)
+
+/*
+ * Group 1: GPIO 128...159
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPE0_I2SLRCK	(PIN(4,0) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE0_AC_SYNC	(PIN(4,0) | FUNC(3) | PU)
+#endif
+#define GPE0_GPIO	(PIN(4,0) | FUNC(0) | PU)
+#define GPE1_I2SSCLK	(PIN(4,1) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE1_AC_BIT_CLK (PIN(4,1) | FUNC(3) | PU)
+#endif
+#define GPE1_GPIO	(PIN(4,1) | FUNC(0) | PU)
+#define GPE2_CDCLK	(PIN(4,2) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE2_AC_NRESET	(PIN(4,2) | FUNC(3) | PU)
+#endif
+#define GPE2_GPIO	(PIN(4,2) | FUNC(0) | PU)
+#define GPE3_I2SDI	(PIN(4,3) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE3_AC_SDATA_IN (PIN(4,3) | FUNC(3) | PU)
+#endif
+#ifdef CONFIG_CPU_S3C2410
+# define GPE_NSS0	(PIN(4,3) | FUNC(3) | PU)
+#endif
+#define GPE3_GPIO	(PIN(4,3) | FUNC(0) | PU)
+#define GPE4_I2SDO	(PIN(4,4) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE4_AC_SDATA_OUT (PIN(4,4) | FUNC(3) | PU)
+#endif
+#ifdef CONFIG_CPU_S3C2440
+# define GPE4_I2SSDI	(PIN(4,4) | FUNC(3) | PU)
+#endif
+#define GPE4_GPIO	(PIN(4,4) | FUNC(0) | PU)
+#define GPE5_SDCLK	(PIN(4,5) | FUNC(2) | PU)
+#define GPE5_GPIO	(PIN(4,5) | FUNC(0) | PU)
+#define GPE6_SDCMD	(PIN(4,6) | FUNC(2) | PU)
+#define GPE6_GPIO	(PIN(4,6) | FUNC(0) | PU)
+#define GPE7_SDDAT0	(PIN(4,7) | FUNC(2) | PU)
+#define GPE7_GPIO	(PIN(4,7) | FUNC(0) | PU)
+#define GPE8_SDDAT1	(PIN(4,8) | FUNC(2) | PU)
+#define GPE8_GPIO	(PIN(4,8) | FUNC(0) | PU)
+#define GPE9_SDDAT2	(PIN(4,9) | FUNC(2) | PU)
+#define GPE9_GPIO	(PIN(4,9) | FUNC(0) | PU)
+#define GPE10_SDDAT3	(PIN(4,10) | FUNC(2) | PU)
+#define GPE10_GPIO	(PIN(4,10) | FUNC(0) | PU)
+#define GPE11_SPIMISO0	(PIN(4,11) | FUNC(2) | PU)
+#define GPE11_GPIO	(PIN(4,11) | FUNC(0) | PU)
+#define GPE12_SPIMOSI0	(PIN(4,12) | FUNC(2) | PU)
+#define GPE12_GPIO	(PIN(4,12) | FUNC(0) | PU)
+#define GPE13_SPICLK0	(PIN(4,13) | FUNC(2) | PU)
+#define GPE13_GPIO	(PIN(4,13) | FUNC(0) | PU)
+#define GPE14_IICSCL	(PIN(4,14) | FUNC(2))	/* no pullup option */
+#define GPE14_GPIO	(PIN(4,14) | FUNC(0))	/* no pullup option */
+#define GPE15_IICSDA	(PIN(4,15) | FUNC(2))	/* no pullup option */
+#define GPE15_GPIO	(PIN(4,15) | FUNC(0))	/* no pullup option */
+
+/*
+ * Group 1: GPIO 160...191
+ * Used GPIO: 0...7
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPF0_EINT0	(PIN(5,0) | FUNC(2) | PU)
+#define GPF0_GPIO	(PIN(5,0) | FUNC(0) | PU)
+#define GPF1_EINT1	(PIN(5,1) | FUNC(2) | PU)
+#define GPF1_GPIO	(PIN(5,1) | FUNC(0) | PU)
+#define GPF2_EINT2	(PIN(5,2) | FUNC(2) | PU)
+#define GPF2_GPIO	(PIN(5,2) | FUNC(0) | PU)
+#define GPF3_EINT3	(PIN(5,3) | FUNC(2) | PU)
+#define GPF3_GPIO	(PIN(5,3) | FUNC(0) | PU)
+#define GPF4_EINT4	(PIN(5,4) | FUNC(2) | PU)
+#define GPF4_GPIO	(PIN(5,4) | FUNC(0) | PU)
+#define GPF5_EINT5	(PIN(5,5) | FUNC(2) | PU)
+#define GPF5_GPIO	(PIN(5,5) | FUNC(0) | PU)
+#define GPF6_EINT6	(PIN(5,6) | FUNC(2) | PU)
+#define GPF6_GPIO	(PIN(5,6) | FUNC(0) | PU)
+#define GPF7_EINT7	(PIN(5,7) | FUNC(2) | PU)
+#define GPF7_GPIO	(PIN(5,7) | FUNC(0) | PU)
+
+/*
+ * Group 1: GPIO 192..223
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPG0_EINT8	(PIN(6,0) | FUNC(2) | PU)
+#define GPG0_GPIO	(PIN(6,0) | FUNC(0) | PU)
+#define GPG1_EINT9	(PIN(6,1) | FUNC(2) | PU)
+#define GPG1_GPIO	(PIN(6,1) | FUNC(0) | PU)
+#define GPG2_EINT10	(PIN(6,2) | FUNC(2) | PU)
+#define GPG2_NSS0	(PIN(6,2) | FUNC(3) | PU)
+#define GPG2_GPIO	(PIN(6,2) | FUNC(0) | PU)
+#define GPG3_EINT11	(PIN(6,3) | FUNC(2) | PU)
+#define GPG3_NSS1	(PIN(6,3) | FUNC(3) | PU)
+#define GPG3_GPIO	(PIN(6,3) | FUNC(0) | PU)
+#define GPG4_EINT12	(PIN(6,4) | FUNC(2) | PU)
+#define GPG4_LCD_PWREN	(PIN(6,4) | FUNC(3) | PU)
+#define GPG4_GPIO	(PIN(6,4) | FUNC(0) | PU)
+#define GPG5_EINT13	(PIN(6,5) | FUNC(2) | PU)
+#define GPG5_SPIMISO1	(PIN(6,5) | FUNC(3) | PU)
+#define GPG5_GPIO	(PIN(6,5) | FUNC(0) | PU)
+#define GPG6_EINT14	(PIN(6,6) | FUNC(2) | PU)
+#define GPG6_SPIMOSI1	(PIN(6,6) | FUNC(3) | PU)
+#define GPG6_GPIO	(PIN(6,6) | FUNC(0) | PU)
+#define GPG7_EINT15	(PIN(6,7) | FUNC(2) | PU)
+#define GPG7_SPICLK1	(PIN(6,7) | FUNC(3) | PU)
+#define GPG7_GPIO	(PIN(6,7) | FUNC(0) | PU)
+#define GPG8_EINT16	(PIN(6,8) | FUNC(2) | PU)
+#define GPG8_GPIO	(PIN(6,8) | FUNC(0) | PU)
+#define GPG9_EINT17	(PIN(6,9) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPG9_NRTS1	(PIN(6,9) | FUNC(3) | PU)
+#endif
+#define GPG9_GPIO	(PIN(6,9) | FUNC(0) | PU)
+#define GPG10_EINT18	(PIN(6,10) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPG10_NCTS1	(PIN(6,10) | FUNC(3) | PU)
+#endif
+#define GPG10_GPIO	(PIN(6,10) | FUNC(0) | PU)
+#define GPG11_EINT19	(PIN(6,11) | FUNC(2) | PU)
+#define GPG11_TCLK	(PIN(6,11) | FUNC(3) | PU)
+#define GPG11_GPIO	(PIN(6,11) | FUNC(0) | PU)
+#define GPG12_EINT20	(PIN(6,12) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2410
+# define GPG12_XMON	(PIN(6,12) | FUNC(3) | PU)
+#endif
+#define GPG12_GPIO	(PIN(6,12) | FUNC(0) | PU)
+#define GPG13_EINT21	(PIN(6,13) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2410
+# define GPG13_NXPON	(PIN(6,13) | FUNC(3) | PU)
+#endif
+#define GPG13_GPIO	(PIN(6,13) | FUNC(0) | PU)	/* must be input in NAND boot mode */
+#define GPG14_EINT22	(PIN(6,14) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2410
+# define GPG14_YMON	(PIN(6,14) | FUNC(3) | PU)
+#endif
+#define GPG14_GPIO	(PIN(6,14) | FUNC(0) | PU)	/* must be input in NAND boot mode */
+#define GPG15_EINT23	(PIN(6,15) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2410
+# define GPG15_YPON	(PIN(6,15) | FUNC(3) | PU)
+#endif
+#define GPG15_GPIO	(PIN(6,15) | FUNC(0) | PU)	/* must be input in NAND boot mode */
+
+/*
+ * Group 1: GPIO 224..255
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPH0_NCTS0	(PIN(7,0) | FUNC(2) | PU)
+#define GPH0_GPIO	(PIN(7,0) | FUNC(0) | PU)
+#define GPH1_NRTS0	(PIN(7,1) | FUNC(2) | PU)
+#define GPH1_GPIO	(PIN(7,1) | FUNC(0) | PU)
+#define GPH2_TXD0	(PIN(7,2) | FUNC(2) | PU)
+#define GPH2_GPIO	(PIN(7,2) | FUNC(0) | PU)
+#define GPH3_RXD0	(PIN(7,3) | FUNC(2) | PU)
+#define GPH3_GPIO	(PIN(7,3) | FUNC(0) | PU)
+#define GPH4_TXD1	(PIN(7,4) | FUNC(2) | PU)
+#define GPH4_GPIO	(PIN(7,4) | FUNC(0) | PU)
+#define GPH5_RXD1	(PIN(7,5) | FUNC(2) | PU)
+#define GPH5_GPIO	(PIN(7,5) | FUNC(0) | PU)
+#define GPH6_TXD2	(PIN(7,6) | FUNC(2) | PU)
+#define GPH6_NRTS1	(PIN(7,6) | FUNC(3) | PU)
+#define GPH6_GPIO	(PIN(7,6) | FUNC(0) | PU)
+#define GPH7_RXD2	(PIN(7,7) | FUNC(2) | PU)
+#define GPH7_NCTS1	(PIN(7,7) | FUNC(3) | PU)
+#define GPH7_GPIO	(PIN(7,7) | FUNC(0) | PU)
+#define GPH8_UEXTCLK	(PIN(7,8) | FUNC(2) | PU)
+#define GPH8_GPIO	(PIN(7,8) | FUNC(0) | PU)
+#define GPH9_CLOCKOUT0	(PIN(7,9) | FUNC(2) | PU)
+#define GPH9_GPIO	(PIN(7,9) | FUNC(0) | PU)
+#define GPH10_CLKOUT1	(PIN(7,10) | FUNC(2) | PU)
+#define GPH10_GPIO	(PIN(7,10) | FUNC(0) | PU)
+
+#ifdef CONFIG_CPU_S3C2440
+/*
+ * Group 1: GPIO 256..287
+ * Used GPIO: 0...12
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPJ0_CAMDATA0	(PIN(8,0) | FUNC(2) | PU)
+#define GPJ0_GPIO	(PIN(8,0) | FUNC(0) | PU)
+#define GPJ1_CAMDATA1	(PIN(8,1) | FUNC(2) | PU)
+#define GPJ1_GPIO	(PIN(8,1) | FUNC(0) | PU)
+#define GPJ2_CAMDATA2	(PIN(8,2) | FUNC(2) | PU)
+#define GPJ2_GPIO	(PIN(8,2) | FUNC(0) | PU)
+#define GPJ3_CAMDATA3	(PIN(8,3) | FUNC(2) | PU)
+#define GPJ3_GPIO	(PIN(8,3) | FUNC(0) | PU)
+#define GPJ4_CAMDATA4	(PIN(8,4) | FUNC(2) | PU)
+#define GPJ4_GPIO	(PIN(8,4) | FUNC(0) | PU)
+#define GPJ5_CAMDATA5	(PIN(8,5) | FUNC(2) | PU)
+#define GPJ5_GPIO	(PIN(8,5) | FUNC(0) | PU)
+#define GPJ6_CAMDATA6	(PIN(8,6) | FUNC(2) | PU)
+#define GPJ6_GPIO	(PIN(8,6) | FUNC(0) | PU)
+#define GPJ7_CAMDATA7	(PIN(8,7) | FUNC(2) | PU)
+#define GPJ7_GPIO	(PIN(8,7) | FUNC(0) | PU)
+#define GPJ8_CAMPCLK	(PIN(8,8) | FUNC(2) | PU)
+#define GPJ8_GPIO	(PIN(8,8) | FUNC(0) | PU)
+#define GPJ9_CAMVSYNC	(PIN(8,9) | FUNC(2) | PU)
+#define GPJ9_GPIO	(PIN(8,9) | FUNC(0) | PU)
+#define GPJ10_CAMHREF	(PIN(8,10) | FUNC(2) | PU)
+#define GPJ10_GPIO	(PIN(8,10) | FUNC(0) | PU)
+#define GPJ11_CAMCLKOUT	(PIN(8,11) | FUNC(2) | PU)
+#define GPJ11_GPIO	(PIN(8,11) | FUNC(0) | PU)
+#define GPJ12_CAMRESET	(PIN(8,12) | FUNC(0) | PU)
+#define GPJ12_GPIO	(PIN(8,12) | FUNC(0) | PU)
+
+#endif
+
+#endif /* __MACH_IOMUX_S3C24x0_H */
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/Makefile
===================================================================
--- barebox-2010.10.0.orig/arch/arm/mach-s3c24xx/Makefile
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/Makefile
@@ -1,2 +1,2 @@
-obj-y += generic.o
+obj-y += generic.o gpio-s3c24x0.o
 obj-$(CONFIG_S3C24XX_LOW_LEVEL_INIT) += lowlevel-init.o
Index: barebox-2010.10.0/arch/arm/Kconfig
===================================================================
--- barebox-2010.10.0.orig/arch/arm/Kconfig
+++ barebox-2010.10.0/arch/arm/Kconfig
@@ -59,6 +59,7 @@ config ARCH_OMAP
 config ARCH_S3C24xx
 	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
 	select CPU_ARM920T
+	select GENERIC_GPIO
 
 endchoice
 



From jbe at pengutronix.de  Mon Oct 18 12:55:34 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 18 Oct 2010 18:55:34 +0200
Subject: [PATCH]  S3C24xx: Remove variable type size restrictions
Message-ID: <201010181855.34960.jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>
Subject: [PATCH] S3C24xx: Remove variable type size restrictions

There is no need to restrict the size of the variables for the clock calculation
routines. So, remove and replace them by generic types.

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>

---
 arch/arm/mach-s3c24xx/generic.c                      |   29 ++++++++++---------
 arch/arm/mach-s3c24xx/include/mach/s3c24xx-generic.h |   14 ++++-----
 2 files changed, 23 insertions(+), 20 deletions(-)

Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/generic.c
===================================================================
--- barebox-2010.10.0.orig/arch/arm/mach-s3c24xx/generic.c
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/generic.c
@@ -33,9 +33,10 @@
  * Calculate the current M-PLL clock.
  * @return Current frequency in Hz
  */
-uint32_t s3c24xx_get_mpllclk(void)
+unsigned s3c24xx_get_mpllclk(void)
 {
-	uint32_t m, p, s, reg_val;
+	uint32_t reg_val;
+	unsigned m, p, s;
 
 	reg_val = readl(MPLLCON);
 	m = ((reg_val & 0xFF000) >> 12) + 8;
@@ -53,9 +54,10 @@ uint32_t s3c24xx_get_mpllclk(void)
  * Calculate the current U-PLL clock
  * @return Current frequency in Hz
  */
-uint32_t s3c24xx_get_upllclk(void)
+unsigned s3c24xx_get_upllclk(void)
 {
-	uint32_t m, p, s, reg_val;
+	uint32_t reg_val;
+	unsigned m, p, s;
 
 	reg_val = readl(UPLLCON);
 	m = ((reg_val & 0xFF000) >> 12) + 8;
@@ -69,7 +71,7 @@ uint32_t s3c24xx_get_upllclk(void)
  * Calculate the FCLK frequency used for the ARM CPU core
  * @return Current frequency in Hz
  */
-uint32_t s3c24xx_get_fclk(void)
+unsigned s3c24xx_get_fclk(void)
 {
 	return s3c24xx_get_mpllclk();
 }
@@ -78,9 +80,9 @@ uint32_t s3c24xx_get_fclk(void)
  * Calculate the HCLK frequency used for the AHB bus (CPU to main peripheral)
  * @return Current frequency in Hz
  */
-uint32_t s3c24xx_get_hclk(void)
+unsigned s3c24xx_get_hclk(void)
 {
-	uint32_t f_clk;
+	unsigned f_clk;
 
 	f_clk = s3c24xx_get_fclk();
 #ifdef CONFIG_CPU_S3C2410
@@ -104,9 +106,9 @@ uint32_t s3c24xx_get_hclk(void)
  * Calculate the PCLK frequency used for the slower peripherals
  * @return Current frequency in Hz
  */
-uint32_t s3c24xx_get_pclk(void)
+unsigned s3c24xx_get_pclk(void)
 {
-	uint32_t p_clk;
+	unsigned p_clk;
 
 	p_clk = s3c24xx_get_hclk();
 	if (readl(CLKDIVN) & 0x01)
@@ -118,7 +120,7 @@ uint32_t s3c24xx_get_pclk(void)
  * Calculate the UCLK frequency used by the USB host device
  * @return Current frequency in Hz
  */
-uint32_t s3c24xx_get_uclk(void)
+unsigned s3c24xx_get_uclk(void)
 {
     return s3c24xx_get_upllclk();
 }
@@ -127,9 +129,10 @@ uint32_t s3c24xx_get_uclk(void)
  * Calculate the amount of connected and available memory
  * @return Memory size in bytes
  */
-uint32_t s3c24x0_get_memory_size(void)
+unsigned s3c24x0_get_memory_size(void)
 {
-	uint32_t reg, size;
+	uint32_t reg;
+	unsigned size;
 
 	/*
 	 * detect the current memory size
@@ -202,7 +205,7 @@ static struct clocksource cs = {
 
 static int clocksource_init (void)
 {
-	uint32_t p_clk = s3c24xx_get_pclk();
+	unsigned p_clk = s3c24xx_get_pclk();
 
 	writel(0x00000000, TCON);	/* stop all timers */
 	writel(0x00ffffff, TCFG0);	/* PCLK / (255 + 1) for timer 4 */
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/s3c24xx-generic.h
===================================================================
--- barebox-2010.10.0.orig/arch/arm/mach-s3c24xx/include/mach/s3c24xx-generic.h
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/s3c24xx-generic.h
@@ -24,10 +24,10 @@
  * MA 02111-1307 USA
  */
 
-uint32_t s3c24xx_get_mpllclk(void);
-uint32_t s3c24xx_get_upllclk(void);
-uint32_t s3c24xx_get_fclk(void);
-uint32_t s3c24xx_get_hclk(void);
-uint32_t s3c24xx_get_pclk(void);
-uint32_t s3c24xx_get_uclk(void);
-uint32_t s3c24x0_get_memory_size(void);
+unsigned s3c24xx_get_mpllclk(void);
+unsigned s3c24xx_get_upllclk(void);
+unsigned s3c24xx_get_fclk(void);
+unsigned s3c24xx_get_hclk(void);
+unsigned s3c24xx_get_pclk(void);
+unsigned s3c24xx_get_uclk(void);
+unsigned s3c24x0_get_memory_size(void);


From jbe at pengutronix.de  Mon Oct 18 12:57:00 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 18 Oct 2010 18:57:00 +0200
Subject: [PATCH] S3C24xx: Move register definitions into their user
Message-ID: <201010181857.00515.jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>
Subject: [PATCH] S3C24xx: Move register definitions into their user

Follow the other architectures and drivers defining their used registers only
locally.

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>

---
 arch/arm/mach-s3c24xx/generic.c                    |   29 ++++++++++++++++++
 arch/arm/mach-s3c24xx/include/mach/s3c24x0-iomap.h |   33 ---------------------
 2 files changed, 29 insertions(+), 33 deletions(-)

Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/generic.c
===================================================================
--- barebox-2010.10.0.orig/arch/arm/mach-s3c24xx/generic.c
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/generic.c
@@ -29,6 +29,35 @@
 #include <asm/io.h>
 #include <mach/s3c24x0-iomap.h>
 
+#define LOCKTIME (S3C24X0_CLOCK_POWER_BASE)
+#define MPLLCON (S3C24X0_CLOCK_POWER_BASE + 0x4)
+#define UPLLCON (S3C24X0_CLOCK_POWER_BASE + 0x8)
+#define CLKCON (S3C24X0_CLOCK_POWER_BASE + 0xc)
+#define CLKSLOW (S3C24X0_CLOCK_POWER_BASE + 0x10)
+#define CLKDIVN (S3C24X0_CLOCK_POWER_BASE + 0x14)
+
+#define TCFG0 (S3C24X0_TIMER_BASE + 0x00)
+#define TCFG1 (S3C24X0_TIMER_BASE + 0x04)
+#define TCON (S3C24X0_TIMER_BASE + 0x08)
+#define TCNTB0 (S3C24X0_TIMER_BASE + 0x0c)
+#define TCMPB0 (S3C24X0_TIMER_BASE + 0x10)
+#define TCNTO0 (S3C24X0_TIMER_BASE + 0x14)
+#define TCNTB1 (S3C24X0_TIMER_BASE + 0x18)
+#define TCMPB1 (S3C24X0_TIMER_BASE + 0x1c)
+#define TCNTO1 (S3C24X0_TIMER_BASE + 0x20)
+#define TCNTB2 (S3C24X0_TIMER_BASE + 0x24)
+#define TCMPB2 (S3C24X0_TIMER_BASE + 0x28)
+#define TCNTO2 (S3C24X0_TIMER_BASE + 0x2c)
+#define TCNTB3 (S3C24X0_TIMER_BASE + 0x30)
+#define TCMPB3 (S3C24X0_TIMER_BASE + 0x34)
+#define TCNTO3 (S3C24X0_TIMER_BASE + 0x38)
+#define TCNTB4 (S3C24X0_TIMER_BASE + 0x3c)
+#define TCNTO4 (S3C24X0_TIMER_BASE + 0x40)
+
+#define WTCON (S3C24X0_WATCHDOG_BASE)
+#define WTDAT (S3C24X0_WATCHDOG_BASE + 0x04)
+#define WTCNT (S3C24X0_WATCHDOG_BASE + 0x08)
+
 /**
  * Calculate the current M-PLL clock.
  * @return Current frequency in Hz
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/s3c24x0-iomap.h
===================================================================
--- barebox-2010.10.0.orig/arch/arm/mach-s3c24xx/include/mach/s3c24x0-iomap.h
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/s3c24x0-iomap.h
@@ -40,39 +40,6 @@
 #define S3C2410_SPI_BASE		0x59000000
 #define S3C2410_SDI_BASE		0x5A000000
 
-/* Clock control (direct access) */
-
-#define LOCKTIME (S3C24X0_CLOCK_POWER_BASE)
-#define MPLLCON (S3C24X0_CLOCK_POWER_BASE + 0x4)
-#define UPLLCON (S3C24X0_CLOCK_POWER_BASE + 0x8)
-#define CLKCON (S3C24X0_CLOCK_POWER_BASE + 0xc)
-#define CLKSLOW (S3C24X0_CLOCK_POWER_BASE + 0x10)
-#define CLKDIVN (S3C24X0_CLOCK_POWER_BASE + 0x14)
-
-/* Timer (direct access) */
-#define TCFG0 (S3C24X0_TIMER_BASE + 0x00)
-#define TCFG1 (S3C24X0_TIMER_BASE + 0x04)
-#define TCON (S3C24X0_TIMER_BASE + 0x08)
-#define TCNTB0 (S3C24X0_TIMER_BASE + 0x0c)
-#define TCMPB0 (S3C24X0_TIMER_BASE + 0x10)
-#define TCNTO0 (S3C24X0_TIMER_BASE + 0x14)
-#define TCNTB1 (S3C24X0_TIMER_BASE + 0x18)
-#define TCMPB1 (S3C24X0_TIMER_BASE + 0x1c)
-#define TCNTO1 (S3C24X0_TIMER_BASE + 0x20)
-#define TCNTB2 (S3C24X0_TIMER_BASE + 0x24)
-#define TCMPB2 (S3C24X0_TIMER_BASE + 0x28)
-#define TCNTO2 (S3C24X0_TIMER_BASE + 0x2c)
-#define TCNTB3 (S3C24X0_TIMER_BASE + 0x30)
-#define TCMPB3 (S3C24X0_TIMER_BASE + 0x34)
-#define TCNTO3 (S3C24X0_TIMER_BASE + 0x38)
-#define TCNTB4 (S3C24X0_TIMER_BASE + 0x3c)
-#define TCNTO4 (S3C24X0_TIMER_BASE + 0x40)
-
-/* Watchdog (direct access) */
-#define WTCON (S3C24X0_WATCHDOG_BASE)
-#define WTDAT (S3C24X0_WATCHDOG_BASE + 0x04)
-#define WTCNT (S3C24X0_WATCHDOG_BASE + 0x08)
-
 /*
  * if we are booting from NAND, its internal SRAM occures at
  * a different address than without this feature


From jbe at pengutronix.de  Mon Oct 18 12:59:51 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 18 Oct 2010 18:59:51 +0200
Subject: [RFC] S3C24xx: Enable only the clocks of used units
Message-ID: <201010181859.51317.jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>
Subject: [RFC] S3C24xx: Enable only the clocks of used units

This patch disables most of the processor's clocks and enable them on demand
only.

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>

---
 arch/arm/mach-s3c24xx/generic.c                     |   22 +++++++++
 arch/arm/mach-s3c24xx/include/mach/s3c24x0-clocks.h |   46 ++++++++++++++++++++
 arch/arm/mach-s3c24xx/lowlevel-init.S               |   12 ++++-
 drivers/mtd/nand/nand_s3c2410.c                     |    3 +
 drivers/serial/serial_s3c24x0.c                     |    3 +
 5 files changed, 84 insertions(+), 2 deletions(-)

Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/generic.c
===================================================================
--- barebox-2010.10.0.orig/arch/arm/mach-s3c24xx/generic.c
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/generic.c
@@ -28,6 +28,7 @@
 #include <clock.h>
 #include <asm/io.h>
 #include <mach/s3c24x0-iomap.h>
+#include <mach/s3c24x0-clocks.h>
 
 #define LOCKTIME (S3C24X0_CLOCK_POWER_BASE)
 #define MPLLCON (S3C24X0_CLOCK_POWER_BASE + 0x4)
@@ -202,6 +203,25 @@ unsigned s3c24x0_get_memory_size(void)
 }
 
 /**
+ * Enable or disable unit's clock
+ * @param unit Unit to manipulate (refer CLK_* macros)
+ * @param state 1 for enable, 0 for disable
+ */
+void s3c244x_mod_clock(unsigned unit, int state)
+{
+	uint32_t clkcon;
+
+	clkcon = readl(CLKCON);
+
+	if (state != 0)
+		clkcon |= unit;
+	else
+		clkcon &= ~unit;
+
+	writel(clkcon, CLKCON);
+}
+
+/**
  * Show the user the current clock settings
  */
 int s3c24xx_dump_clocks(void)
@@ -236,6 +256,8 @@ static int clocksource_init (void)
 {
 	unsigned p_clk = s3c24xx_get_pclk();
 
+	s3c244x_mod_clock(CLK_PWMTIMER, 1);
+
 	writel(0x00000000, TCON);	/* stop all timers */
 	writel(0x00ffffff, TCFG0);	/* PCLK / (255 + 1) for timer 4 */
 	writel(0x00030000, TCFG1);	/* /16 */
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/s3c24x0-clocks.h
===================================================================
--- /dev/null
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/s3c24x0-clocks.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MACH_CLOCKS_H_
+# define _MACH_CLOCKS_H_
+
+/* Bits in register CLKCON to control unit's clock */
+#define CLK_AC97 (1 << 20)
+#define CLK_CAMERA (1 << 19)
+#define CLK_SPI (1 << 18)
+#define CLK_IIS (1 << 17)
+#define CLK_IIC (1 << 16)
+#define CLK_ADC (1 << 15)
+#define CLK_RTC (1 << 14)
+#define CLK_GPIO (1 << 13)
+#define CLK_UART2 (1 << 12)
+#define CLK_UART1 (1 << 11)
+#define CLK_UART0 (1 << 10)
+#define CLK_SDI (1 << 9)
+#define CLK_PWMTIMER (1 << 8)
+#define CLK_USBDEV (1 << 7)
+#define CLK_USBHOST (1 << 6)
+#define CLK_LCDC (1 << 5)
+#define CLK_NAND (1 << 4)
+
+#ifndef __ASSEMBLY__
+void s3c244x_mod_clock(unsigned, int);
+#endif
+
+#endif /* _MACH_CLOCKS_H_ */
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/lowlevel-init.S
===================================================================
--- barebox-2010.10.0.orig/arch/arm/mach-s3c24xx/lowlevel-init.S
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/lowlevel-init.S
@@ -20,6 +20,7 @@
 
 #include <config.h>
 #include <mach/s3c24x0-iomap.h>
+#include <mach/s3c24x0-clocks.h>
 
 	.section ".text_bare_init.s3c24x0_disable_wd","ax"
 
@@ -83,8 +84,15 @@ s3c24x0_pll_init:
 	mov r1, #BOARD_SPECIFIC_CLKDIVN
 	str r1, [r0, #20]
 
-	/* enable all devices on this chip */
-	mov r1, #0xFFFFFFF0
+	/*
+	 * Disable the clocks for most devices on this chip.
+	 * They will be enabled again on demand
+	 */
+#ifdef CONFIG_S3C24XX_NAND_BOOT
+	ldr r1, =0x6010 /* (CLK_RTC | CLK_GPIO | CLK_NAND) */
+#else
+	mov r1, #0x6000 /* (CLK_RTC | CLK_GPIO) */
+#endif
 	str r1, [r0, #12]
 
 	/* ??????? */
Index: barebox-2010.10.0/drivers/mtd/nand/nand_s3c2410.c
===================================================================
--- barebox-2010.10.0.orig/drivers/mtd/nand/nand_s3c2410.c
+++ barebox-2010.10.0/drivers/mtd/nand/nand_s3c2410.c
@@ -32,6 +32,7 @@
 #include <linux/mtd/nand.h>
 #include <mach/s3c24xx-generic.h>
 #include <mach/s3c24x0-iomap.h>
+#include <mach/s3c24x0-clocks.h>
 #include <mach/s3c24x0-nand.h>
 #include <asm/io.h>
 #include <asm-generic/errno.h>
@@ -358,6 +359,8 @@ static int s3c24x0_nand_probe(struct dev
 	if (!host)
 		return -ENOMEM;
 
+	s3c244x_mod_clock(CLK_NAND, 1);
+
 	host->dev = dev;
 	host->base = dev->map_base;
 
Index: barebox-2010.10.0/drivers/serial/serial_s3c24x0.c
===================================================================
--- barebox-2010.10.0.orig/drivers/serial/serial_s3c24x0.c
+++ barebox-2010.10.0/drivers/serial/serial_s3c24x0.c
@@ -27,6 +27,7 @@
 #include <asm/io.h>
 #include <mach/s3c24xx-generic.h>
 #include <mach/s3c24x0-iomap.h>
+#include <mach/s3c24x0-clocks.h>
 
 /* Note: Offsets are for little endian access */
 #define ULCON 0x00		/* line control */
@@ -123,6 +124,8 @@ static int s3c24x0_serial_probe(struct d
 
 	cdev = malloc(sizeof(struct console_device));
 
+	s3c244x_mod_clock(CLK_UART0 | CLK_UART1 | CLK_UART2, 1);
+
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;


From plagnioj at jcrosoft.com  Mon Oct 18 21:42:46 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 19 Oct 2010 03:42:46 +0200
Subject: [RFC] S3C24xx: Enable only the clocks of used units
In-Reply-To: <201010181859.51317.jbe@pengutronix.de>
References: <201010181859.51317.jbe@pengutronix.de>
Message-ID: <20101019014246.GK11127@game.jcrosoft.org>

> -	mov r1, #0xFFFFFFF0
> +	/*
> +	 * Disable the clocks for most devices on this chip.
> +	 * They will be enabled again on demand
> +	 */
> +#ifdef CONFIG_S3C24XX_NAND_BOOT
> +	ldr r1, =0x6010 /* (CLK_RTC | CLK_GPIO | CLK_NAND) */
> +#else
> +	mov r1, #0x6000 /* (CLK_RTC | CLK_GPIO) */
how about use the macro and define a macro to avoid the ifdef

Best Regards,
J.


From s.hauer at pengutronix.de  Tue Oct 19 02:54:58 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 08:54:58 +0200
Subject: [PATCH] imx: Separate framebuffer platformdata and the videomode
In-Reply-To: <201010161546.52848.jbe@pengutronix.de>
References: <201010161546.52848.jbe@pengutronix.de>
Message-ID: <20101019065458.GQ28242@pengutronix.de>

Hi J?rgen,

On Sat, Oct 16, 2010 at 03:46:52PM +0200, Juergen Beisert wrote:
> commit 4ac682bf08b61708bc432c48e58a6d1cf9ea3832
> Author: Juergen Beisert <jbe at pengutronix.de>
> Date:   Sat Oct 16 15:32:06 2010 +0200
> 
>     imx: Separate framebuffer platformdata and the videomode
>     
>     This patch separates the imx platformdata and its videomode in two structures,
>     in order to support more than one defined videomode in the boardfile. This
>     is intended to support runtime videomode selection later on. It also uses
>     now the same videomode setup style than the imx-fpu based systems (like the
>     i.MX35).

Multiple displays can have different bpp/pcr values. Shouldn't we build
an array of imx_fb_videomode instead?

Sascha

>     
>     Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> 
> diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> index c2eb398..b1b9852 100644
> --- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> +++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> @@ -119,20 +119,22 @@ static struct device_d nand_dev = {
>  	.platform_data	= &nand_info,
>  };
>  
> +static struct fb_videomode cmo_display = {
> +	.name		= "CMO-QVGA",
> +	.refresh	= 60,
> +	.xres		= 320,
> +	.yres		= 240,
> +	.pixclock	= KHZ2PICOS(6500),
> +	.hsync_len	= 30,
> +	.left_margin	= 38,
> +	.right_margin	= 20,
> +	.vsync_len	= 3,
> +	.upper_margin	= 15,
> +	.lower_margin	= 4,
> +};
> +
>  static struct imx_fb_videomode imxfb_mode = {
> -	.mode = {
> -		.name		= "CMO-QVGA",
> -		.refresh	= 60,
> -		.xres		= 320,
> -		.yres		= 240,
> -		.pixclock	= KHZ2PICOS(6500),
> -		.hsync_len	= 30,
> -		.left_margin	= 38,
> -		.right_margin	= 20,
> -		.vsync_len	= 3,
> -		.upper_margin	= 15,
> -		.lower_margin	= 4,
> -	},
> +	.mode		= &cmo_display,
>  	.pcr		= 0xCAD08B80,
>  	.bpp		= 16,
>  };
> diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
> index 62fc14e..3ea2466 100644
> --- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
> +++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
> @@ -186,20 +186,22 @@ static void eukrea_cpuimx27_mmu_init(void)
>  #endif
>  
>  #ifdef CONFIG_DRIVER_VIDEO_IMX
> +static struct fb_videomode cmo_display = {
> +	.name		= "CMO-QVGA",
> +	.refresh	= 60,
> +	.xres		= 320,
> +	.yres		= 240,
> +	.pixclock	= 156000,
> +	.hsync_len	= 30,
> +	.left_margin	= 38,
> +	.right_margin	= 20,
> +	.vsync_len	= 3,
> +	.upper_margin	= 15,
> +	.lower_margin	= 4,
> +};
> +
>  static struct imx_fb_videomode imxfb_mode = {
> -	.mode = {
> -		.name		= "CMO-QVGA",
> -		.refresh	= 60,
> -		.xres		= 320,
> -		.yres		= 240,
> -		.pixclock	= 156000,
> -		.hsync_len	= 30,
> -		.left_margin	= 38,
> -		.right_margin	= 20,
> -		.vsync_len	= 3,
> -		.upper_margin	= 15,
> -		.lower_margin	= 4,
> -	},
> +	.mode		= &cmo_display,
>  	.pcr		= 0xFAD08B80,
>  	.bpp		= 16,};
>  
> diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c
> index 9c85c08..6949675 100644
> --- a/arch/arm/boards/guf-neso/board.c
> +++ b/arch/arm/boards/guf-neso/board.c
> @@ -91,20 +91,22 @@ static struct device_d nand_dev = {
>  	.platform_data	= &nand_info,
>  };
>  
> +static struct fb_videomode cpt_display = {
> +	.name		= "CPT CLAA070LC0JCT",
> +	.refresh	= 60,
> +	.xres		= 800,
> +	.yres		= 480,
> +	.pixclock	= KHZ2PICOS(27000),
> +	.hsync_len	= 1,	/* DE only sync */
> +	.left_margin	= 50,
> +	.right_margin	= 50,
> +	.vsync_len	= 1,	/* DE only sync */
> +	.upper_margin	= 10,
> +	.lower_margin	= 10,
> +};
> +
>  static struct imx_fb_videomode imxfb_mode = {
> -	.mode = {
> -		.name		= "CPT CLAA070LC0JCT",
> -		.refresh	= 60,
> -		.xres		= 800,
> -		.yres		= 480,
> -		.pixclock	= KHZ2PICOS(27000),
> -		.hsync_len	= 1,	/* DE only sync */
> -		.left_margin	= 50,
> -		.right_margin	= 50,
> -		.vsync_len	= 1,	/* DE only sync */
> -		.upper_margin	= 10,
> -		.lower_margin	= 10,
> -	},
> +	.mode = &cpt_display,
>  	/*
>  	 * - TFT style panel
>  	 * - clk enabled while idle
> diff --git a/arch/arm/boards/imx21ads/imx21ads.c b/arch/arm/boards/imx21ads/imx21ads.c
> index 44d37aa..81006de 100644
> --- a/arch/arm/boards/imx21ads/imx21ads.c
> +++ b/arch/arm/boards/imx21ads/imx21ads.c
> @@ -79,24 +79,26 @@ static struct device_d cs8900_dev = {
>  	// IRQ is connected to UART3_RTS
>  };
>  
> +static struct fb_videomode sharp_display = {
> +	.name           = "Sharp-LQ035Q7",
> +	.refresh        = 60,
> +	.xres           = 240,
> +	.yres           = 320,
> +	.pixclock       = 188679,
> +	.left_margin    = 6,
> +	.right_margin   = 16,
> +	.upper_margin   = 8,
> +	.lower_margin   = 10,
> +	.hsync_len      = 2,
> +	.vsync_len      = 1,
> +	.sync           = 0,
> +	.vmode          = FB_VMODE_NONINTERLACED,
> +	.flag           = 0,
> +};
> +
>  /* Sharp LQ035Q7DB02 QVGA display */
>  static struct imx_fb_videomode imx_fb_modedata = {
> -        .mode = {
> -		.name           = "Sharp-LQ035Q7",
> -		.refresh        = 60,
> -		.xres           = 240,
> -		.yres           = 320,
> -		.pixclock       = 188679,
> -		.left_margin    = 6,
> -		.right_margin   = 16,
> -		.upper_margin   = 8,
> -		.lower_margin   = 10,
> -		.hsync_len      = 2,
> -		.vsync_len      = 1,
> -		.sync           = 0,
> -		.vmode          = FB_VMODE_NONINTERLACED,
> -		.flag           = 0,
> -	},
> +        .mode           = &sharp_display,
>          .pcr            = 0xfb108bc7,
>          .bpp            = 16,
>  };
> diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
> index 3a9b413..026e9c0 100644
> --- a/arch/arm/boards/pcm038/pcm038.c
> +++ b/arch/arm/boards/pcm038/pcm038.c
> @@ -127,20 +127,22 @@ static struct device_d nand_dev = {
>  	.platform_data	= &nand_info,
>  };
>  
> +static struct fb_videomode sharp_display = {
> +	.name		= "Sharp-LQ035Q7",
> +	.refresh	= 60,
> +	.xres		= 240,
> +	.yres		= 320,
> +	.pixclock	= 188679, /* in ps (5.3MHz) */
> +	.hsync_len	= 7,
> +	.left_margin	= 5,
> +	.right_margin	= 16,
> +	.vsync_len	= 1,
> +	.upper_margin	= 7,
> +	.lower_margin	= 9,
> +};
> +
>  static struct imx_fb_videomode imxfb_mode = {
> -	.mode = {
> -		.name		= "Sharp-LQ035Q7",
> -		.refresh	= 60,
> -		.xres		= 240,
> -		.yres		= 320,
> -		.pixclock	= 188679, /* in ps (5.3MHz) */
> -		.hsync_len	= 7,
> -		.left_margin	= 5,
> -		.right_margin	= 16,
> -		.vsync_len	= 1,
> -		.upper_margin	= 7,
> -		.lower_margin	= 9,
> -	},
> +	.mode		= &sharp_display,
>  	/*
>  	 * - HSYNC active high
>  	 * - VSYNC active high
> diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h
> index 16b43ea..7baa244 100644
> --- a/arch/arm/mach-imx/include/mach/imxfb.h
> +++ b/arch/arm/mach-imx/include/mach/imxfb.h
> @@ -50,7 +50,7 @@
>  #define DMACR_TM(x)	((x) & 0xf)
>  
>  struct imx_fb_videomode {
> -	struct fb_videomode mode;
> +	struct fb_videomode *mode;
>  	u32 pcr;
>  	unsigned char	bpp;
>  };
> diff --git a/drivers/video/imx.c b/drivers/video/imx.c
> index ac51858..6ccd77e 100644
> --- a/drivers/video/imx.c
> +++ b/drivers/video/imx.c
> @@ -555,9 +555,9 @@ static int imxfb_probe(struct device_d *dev)
>  	fbi->enable = pdata->enable;
>  	fbi->dev = dev;
>  	info->priv = fbi;
> -	info->mode = &pdata->mode->mode;
> -	info->xres = pdata->mode->mode.xres;
> -	info->yres = pdata->mode->mode.yres;
> +	info->mode = pdata->mode->mode;
> +	info->xres = pdata->mode->mode->xres;
> +	info->yres = pdata->mode->mode->yres;
>  	info->bits_per_pixel = pdata->mode->bpp;
>  	info->fbops = &imxfb_ops;
>  
> -- 
> Pengutronix e.K.                              | Juergen Beisert             |
> Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
> Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Tue Oct 19 02:55:18 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 19 Oct 2010 08:55:18 +0200
Subject: [RFC] S3C24xx: Enable only the clocks of used units
In-Reply-To: <20101019014246.GK11127@game.jcrosoft.org>
References: <201010181859.51317.jbe@pengutronix.de>
	<20101019014246.GK11127@game.jcrosoft.org>
Message-ID: <201010190855.18736.jbe@pengutronix.de>

Jean-Christophe PLAGNIOL-VILLARD wrote:
> > -	mov r1, #0xFFFFFFF0
> > +	/*
> > +	 * Disable the clocks for most devices on this chip.
> > +	 * They will be enabled again on demand
> > +	 */
> > +#ifdef CONFIG_S3C24XX_NAND_BOOT
> > +	ldr r1, =0x6010 /* (CLK_RTC | CLK_GPIO | CLK_NAND) */
> > +#else
> > +	mov r1, #0x6000 /* (CLK_RTC | CLK_GPIO) */
>
> how about use the macro and define a macro to avoid the ifdef

I tried with macros, but the assembler failed. Can't remember why. But I tried 
again a few minutes ago .... and now it works (????).

Do you mean something like this instead?

[...]
#ifdef CONFIG_S3C24XX_NAND_BOOT
# define FORCED_CLOCKS (CLK_RTC | CLK_GPIO | CLK_NAND)
#else
# define FORCED_CLOCKS (CLK_RTC | CLK_GPIO)
#endif

	/*
	 * Disable the clocks for most devices on this chip.
	 * They will be enabled again on demand
	 */
	ldr r1, =FORCED_CLOCKS
[...]

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Tue Oct 19 03:12:04 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 19 Oct 2010 09:12:04 +0200
Subject: [PATCH] imx: Separate framebuffer platformdata and the videomode
In-Reply-To: <20101019065458.GQ28242@pengutronix.de>
References: <201010161546.52848.jbe@pengutronix.de>
	<20101019065458.GQ28242@pengutronix.de>
Message-ID: <201010190912.05056.jbe@pengutronix.de>

Hi Sascha,

Sascha Hauer wrote:
> On Sat, Oct 16, 2010 at 03:46:52PM +0200, Juergen Beisert wrote:
> > commit 4ac682bf08b61708bc432c48e58a6d1cf9ea3832
> > Author: Juergen Beisert <jbe at pengutronix.de>
> > Date:   Sat Oct 16 15:32:06 2010 +0200
> >
> >     imx: Separate framebuffer platformdata and the videomode
> >
> >     This patch separates the imx platformdata and its videomode in two
> > structures, in order to support more than one defined videomode in the
> > boardfile. This is intended to support runtime videomode selection later
> > on. It also uses now the same videomode setup style than the imx-fpu
> > based systems (like the i.MX35).
>
> Multiple displays can have different bpp/pcr values. Shouldn't we build
> an array of imx_fb_videomode instead?

At this point of time its not necessary, because still only one display is 
supported (BTW: The 'bpp' value seems not display related, it a feature of 
the framebuffer only).
But in future we need a solution for videomode and driver specific data. Maybe 
we could add a private void pointer into the "struct fb_videomode" for this 
purpose?

When I release my "runtime videomode initialization" patch stack, we could 
discuss where to store such special information.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From marek.belisko at gmail.com  Tue Oct 19 03:48:52 2010
From: marek.belisko at gmail.com (Marek Belisko)
Date: Tue, 19 Oct 2010 09:48:52 +0200
Subject: [PATCH] Add basic support for mini2440 dev board.
Message-ID: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>

This work is mainly based on a9m2440 board implementation
from Juergen Beisert <jbe at pengutronix.de>. Functionality
was tested only running barebox from ram. Loading to flash
and booting will not work because missing lowlevel_init
functionality (lack of jtag debugger on my side ;)).

Signed-off-by: Marek Belisko <marek.belisko at gmail.com>
---
 arch/arm/Makefile                              |    1 +
 arch/arm/boards/mini2440/Makefile              |    2 +
 arch/arm/boards/mini2440/config.h              |   50 +++++
 arch/arm/boards/mini2440/env/bin/_update       |   34 ++++
 arch/arm/boards/mini2440/env/bin/boot          |   40 ++++
 arch/arm/boards/mini2440/env/bin/hush_hack     |    1 +
 arch/arm/boards/mini2440/env/bin/init          |   34 ++++
 arch/arm/boards/mini2440/env/bin/update_kernel |   13 ++
 arch/arm/boards/mini2440/env/bin/update_root   |   13 ++
 arch/arm/boards/mini2440/env/config            |   27 +++
 arch/arm/boards/mini2440/mini2440.c            |  139 +++++++++++++
 arch/arm/configs/mini2440_defconfig            |  251 ++++++++++++++++++++++++
 arch/arm/mach-s3c24xx/Kconfig                  |    9 +
 13 files changed, 614 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/mini2440/Makefile
 create mode 100644 arch/arm/boards/mini2440/config.h
 create mode 100644 arch/arm/boards/mini2440/env/bin/_update
 create mode 100644 arch/arm/boards/mini2440/env/bin/boot
 create mode 100644 arch/arm/boards/mini2440/env/bin/hush_hack
 create mode 100644 arch/arm/boards/mini2440/env/bin/init
 create mode 100644 arch/arm/boards/mini2440/env/bin/update_kernel
 create mode 100644 arch/arm/boards/mini2440/env/bin/update_root
 create mode 100644 arch/arm/boards/mini2440/env/config
 create mode 100644 arch/arm/boards/mini2440/mini2440.c
 create mode 100644 arch/arm/configs/mini2440_defconfig

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77b6cf4..c1d1fb6 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -80,6 +80,7 @@ board-$(CONFIG_MACH_PCM043)			:= pcm043
 board-$(CONFIG_MACH_PM9263)			:= pm9263
 board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
+board-$(CONFIG_MACH_MINI2440)			:= mini2440
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/mini2440/Makefile b/arch/arm/boards/mini2440/Makefile
new file mode 100644
index 0000000..09f7e7d
--- /dev/null
+++ b/arch/arm/boards/mini2440/Makefile
@@ -0,0 +1,2 @@
+
+obj-y += mini2440.o
diff --git a/arch/arm/boards/mini2440/config.h b/arch/arm/boards/mini2440/config.h
new file mode 100644
index 0000000..a664017
--- /dev/null
+++ b/arch/arm/boards/mini2440/config.h
@@ -0,0 +1,50 @@
+/**
+ * @file
+ * @brief Global defintions for the ARM S3C2440 based mini2440 CPU card
+ */
+/* This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/**
+ * The external clock reference is a 12.00 MHz crystal
+ */
+#define S3C24XX_CLOCK_REFERENCE 12000000
+
+/*
+ * Flash access timings
+ * Tacls  = 0ns (but 20ns data setup time)
+ * Twrph0 = 25ns (write) 35ns (read)
+ * Twrph1 = 10ns (10ns data hold time)
+ * Read cycle time = 50ns
+ *
+ * Assumed HCLK is 100MHz
+ * Tacls = 1 (-> 20ns)
+ * Twrph0 = 3 (-> 40ns)
+ * Twrph1 = 1 (-> 20ns)
+ * Cycle time = 80ns
+ */
+#define A9M2440_TACLS 1
+#define A9M2440_TWRPH0 3
+#define A9M2440_TWRPH1 1
+
+/* needed in the generic NAND boot code only */
+#ifdef CONFIG_S3C24XX_NAND_BOOT
+# define BOARD_DEFAULT_NAND_TIMING CALC_NFCONF_TIMING(A9M2440_TACLS, A9M2440_TWRPH0, A9M2440_TWRPH1)
+#endif
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/mini2440/env/bin/_update b/arch/arm/boards/mini2440/env/bin/_update
new file mode 100644
index 0000000..b10682e
--- /dev/null
+++ b/arch/arm/boards/mini2440/env/bin/_update
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+if [ -z "$part" -o -z "$image" ]; then
+	echo "define \$part and \$image"
+	exit 1
+fi
+
+if [ ! -e "$part" ]; then
+	echo "Partition $part does not exist"
+	exit 1
+fi
+
+if [ $# = 1 ]; then
+	image=$1
+fi
+
+if [ x$ip = xdhcp ]; then
+	dhcp
+fi
+
+ping $eth0.serverip
+if [ $? -ne 0 ] ; then
+	echo "update aborted"
+	exit 1
+fi
+
+echo
+echo "erasing partition $part"
+erase $part
+
+echo
+echo "flashing $image to $part"
+echo
+tftp $image $part
diff --git a/arch/arm/boards/mini2440/env/bin/boot b/arch/arm/boards/mini2440/env/bin/boot
new file mode 100644
index 0000000..86e22cf
--- /dev/null
+++ b/arch/arm/boards/mini2440/env/bin/boot
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+. /env/config
+
+if [ x$1 = xnand ]; then
+	root=nand
+	kernel=nand
+fi
+
+if [ x$1 = xnet ]; then
+	root=net
+	kernel=net
+fi
+
+if [ x$root = xnand ]; then
+	bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2"
+fi
+if [ x$root = xnet ]; then
+	bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp"
+	if [ x$ip = xdhcp ]; then
+		bootargs="$bootargs ip=dhcp"
+	else
+		bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::"
+	fi
+fi
+
+bootargs="$bootargs mtdparts=\"NAND 32MiB 3,3V 8-bit:$nand_parts\""
+
+bootargs="$bootargs cs89x0_media=rj45 cs89x0_mac=$eth0.ethaddr"
+
+if [ x$kernel = xnet ]; then
+	if [ x$ip = xdhcp ]; then
+		dhcp
+	fi
+	tftp $uimage uImage || exit 1
+	bootm uImage
+else
+	bootm /dev/nand0.kernel.bb
+fi
+
diff --git a/arch/arm/boards/mini2440/env/bin/hush_hack b/arch/arm/boards/mini2440/env/bin/hush_hack
new file mode 100644
index 0000000..5fffa92
--- /dev/null
+++ b/arch/arm/boards/mini2440/env/bin/hush_hack
@@ -0,0 +1 @@
+nand -a /dev/nand0.*
diff --git a/arch/arm/boards/mini2440/env/bin/init b/arch/arm/boards/mini2440/env/bin/init
new file mode 100644
index 0000000..e98ab84
--- /dev/null
+++ b/arch/arm/boards/mini2440/env/bin/init
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+PATH=/env/bin
+export PATH
+
+. /env/config
+
+if [ -e /dev/nand0 ]; then
+#addpart /dev/nand0 $nand_parts
+
+	# Uh, oh, hush first expands wildcards and then starts executing
+	# commands. What a bug!
+	source /env/bin/hush_hack
+fi
+
+if [ -z $eth0.ethaddr ]; then
+	while [ -z $eth0.ethaddr ]; do
+		readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr
+	done
+	echo -a /env/config "eth0.ethaddr=$eth0.ethaddr"
+fi
+
+echo
+echo -n "Hit any key to stop autoboot: "
+timeout -a $autoboot_timeout
+if [ $? != 0 ]; then
+	echo
+	echo "type update_kernel [<imagename>] to update kernel into flash"
+	echo "type update_root [<imagename>] to update rootfs into flash"
+	echo
+	exit
+fi
+
+boot
diff --git a/arch/arm/boards/mini2440/env/bin/update_kernel b/arch/arm/boards/mini2440/env/bin/update_kernel
new file mode 100644
index 0000000..c43a557
--- /dev/null
+++ b/arch/arm/boards/mini2440/env/bin/update_kernel
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+. /env/config
+
+part=/dev/nand0.kernel.bb
+
+if [ x$1 = x ]; then
+	image=$uimage
+else
+	image=$1
+fi
+
+. /env/bin/_update $image
diff --git a/arch/arm/boards/mini2440/env/bin/update_root b/arch/arm/boards/mini2440/env/bin/update_root
new file mode 100644
index 0000000..46cbca5
--- /dev/null
+++ b/arch/arm/boards/mini2440/env/bin/update_root
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+. /env/config
+
+part=/dev/nand0.root.bb
+
+if [ x$1 = x ]; then
+	image=$jffs2
+else
+	image=$1
+fi
+
+. /env/bin/_update $image
diff --git a/arch/arm/boards/mini2440/env/config b/arch/arm/boards/mini2440/env/config
new file mode 100644
index 0000000..05a2d01
--- /dev/null
+++ b/arch/arm/boards/mini2440/env/config
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# can be either 'net' or 'nand''
+kernel=net
+root=net
+
+#uimage=uImage-a9m2440
+uimage=uImage
+jffs2=root-a9m2440.jffs2
+
+autoboot_timeout=3
+
+nfsroot="/home/open-nandra/rootfs"
+bootargs="console=ttySAC0,115200"
+
+nand_parts="256k(barebox),128k(bareboxenv),1536k(kernel),-(root)"
+rootpart_nand="/dev/mtdblock3"
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+#ip=dhcp
+
+# or set your networking parameters here
+eth0.ipaddr=192.168.42.32
+eth0.netmask=255.255.0.0
+eth0.gateway=192.168.23.1
+eth0.serverip=192.168.23.2
+eth0.ethaddr=00:04:f3:00:06:35
diff --git a/arch/arm/boards/mini2440/mini2440.c b/arch/arm/boards/mini2440/mini2440.c
new file mode 100644
index 0000000..e36c576
--- /dev/null
+++ b/arch/arm/boards/mini2440/mini2440.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 Marek Belisko <marek.belisko at open-nandra.com>
+ * 
+ * Based on a9m2440.c board init by Juergen Beisert, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/**
+ * @file
+ * @brief mini2440 Specific Board Initialization routines
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <asm/mach-types.h>
+#include <partition.h>
+#include <nand.h>
+#include <asm/io.h>
+#include <mach/s3c24x0-iomap.h>
+#include <mach/s3c24x0-nand.h>
+#include <mach/s3c24xx-generic.h>
+#include <dm9000.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name		= "ram0",
+	.flags		= DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.name		= "mem",
+	.map_base	= CS6_BASE,
+	.platform_data	= &ram_pdata,
+};
+
+static struct s3c24x0_nand_platform_data nand_info = {
+	.nand_timing = CALC_NFCONF_TIMING(A9M2440_TACLS, A9M2440_TWRPH0, A9M2440_TWRPH1)
+};
+
+static struct device_d nand_dev = {
+	.name     = "s3c24x0_nand",
+	.map_base = S3C24X0_NAND_BASE,
+	.platform_data	= &nand_info,
+};
+
+/*
+ * dm9000 network controller onboard
+ */
+static struct dm9000_platform_data dm9000_data = {
+	.iobase   = CS4_BASE + 0x300,
+	.iodata   = CS4_BASE + 0x304,
+	.buswidth = DM9000_WIDTH_16,
+	.srom     = 1,
+};
+
+static struct device_d dm9000_dev = {
+	.name     = "dm9000",
+	.map_base = CS4_BASE + 0x300,
+	.size     = 8,
+	.platform_data = &dm9000_data,
+};
+
+static int mini2440_devices_init(void)
+{
+	uint32_t reg;
+
+	reg = readl(BWSCON);
+
+	/* CS#4 to access the network controller */
+	reg &= ~0x000f0000;
+	reg |=  0x000d0000;	/* 16 bit */
+	writel(0x1f4c, BANKCON4);
+
+	writel(reg, BWSCON);
+
+	/* release the reset signal to external devices */
+	reg = readl(MISCCR);
+	reg |= 0x10000;
+	writel(reg, MISCCR);
+
+	register_device(&nand_dev);
+	register_device(&sdram_dev);
+	register_device(&dm9000_dev);
+#ifdef CONFIG_NAND
+	/* ----------- add some vital partitions -------- */
+	devfs_del_partition("self_raw");
+	devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
+	dev_add_bb_dev("self_raw", NULL);
+
+	devfs_del_partition("env_raw");
+	devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED, "env_raw");
+	dev_add_bb_dev("env_raw", NULL);
+#endif
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
+	armlinux_set_architecture(MACH_TYPE_MINI2440);
+
+	return 0;
+}
+
+device_initcall(mini2440_devices_init);
+
+#ifdef CONFIG_S3C24XX_NAND_BOOT
+void __bare_init nand_boot(void)
+{
+	s3c24x0_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0, 512);
+}
+#endif
+
+static struct device_d mini2440_serial_device = {
+	.name     = "s3c24x0_serial",
+	.map_base = UART1_BASE,
+	.size     = UART1_SIZE,
+};
+
+static int mini2440_console_init(void)
+{
+	register_device(&mini2440_serial_device);
+	return 0;
+}
+
+console_initcall(mini2440_console_init);
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
new file mode 100644
index 0000000..11a0120
--- /dev/null
+++ b/arch/arm/configs/mini2440_defconfig
@@ -0,0 +1,251 @@
+#
+# Automatically generated make config: don't edit
+# Linux barebox version: 2010.10.0
+# Tue Oct 19 09:01:55 2010
+#
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_ARM=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_ARCH_S3C24xx=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4T=y
+
+#
+# processor features
+#
+CONFIG_ARCH_TEXT_BASE=0x31fc0000
+CONFIG_BOARDINFO="Mini 2440"
+CONFIG_CPU_S3C2440=y
+# CONFIG_MACH_A9M2410 is not set
+# CONFIG_MACH_A9M2440 is not set
+CONFIG_MACH_MINI2440=y
+
+#
+# Board specific settings       
+#
+
+#
+# S3C24X0 Features              
+#
+# CONFIG_S3C24XX_PLL_INIT is not set
+# CONFIG_S3C24XX_SDRAM_INIT is not set
+CONFIG_S3C24XX_NAND_BOOT=y
+# CONFIG_AEABI is not set
+
+#
+# Arm specific settings         
+#
+CONFIG_CMD_ARM_CPUINFO=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
+CONFIG_GREGORIAN_CALENDER=y
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+
+#
+# General Settings              
+#
+CONFIG_LOCALVERSION_AUTO=y
+
+#
+# memory layout                 
+#
+CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
+CONFIG_TEXT_BASE=0x31fc0000
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+# CONFIG_MEMORY_LAYOUT_FIXED is not set
+CONFIG_STACK_SIZE=0x8000
+CONFIG_MALLOC_SIZE=0x400000
+CONFIG_BROKEN=y
+CONFIG_EXPERIMENTAL=y
+# CONFIG_MODULES is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_PROMPT="barebox:"
+CONFIG_BAUDRATE=38400
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="> "
+# CONFIG_HUSH_FANCY_PROMPT is not set
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+# CONFIG_MENU is not set
+# CONFIG_PASSWORD is not set
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+CONFIG_TIMESTAMP=y
+CONFIG_CONSOLE_FULL=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+# CONFIG_OF_FLAT_TREE is not set
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/mini2440/env"
+
+#
+# Debugging                     
+#
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+CONFIG_ENABLE_DEVICE_NOISE=y
+
+#
+# Commands                      
+#
+
+#
+# scripting                     
+#
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TRUE=y
+CONFIG_CMD_FALSE=y
+# CONFIG_CMD_LOGIN is not set
+# CONFIG_CMD_PASSWD is not set
+
+#
+# file commands                 
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+
+#
+# console                       
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
+# CONFIG_CMD_ECHO_E is not set
+
+#
+# memory                        
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADY is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_MTEST=y
+# CONFIG_CMD_MTEST_ALTERNATIVE is not set
+
+#
+# flash                         
+#
+CONFIG_CMD_FLASH=y
+# CONFIG_CMD_UBI is not set
+
+#
+# booting                       
+#
+CONFIG_CMD_BOOTM=y
+# CONFIG_CMD_BOOTM_ZLIB is not set
+# CONFIG_CMD_BOOTM_BZLIB is not set
+# CONFIG_CMD_BOOTM_LZO is not set
+# CONFIG_CMD_BOOTM_SHOW_TYPE is not set
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTU=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_CMD_VERSION=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_DEVINFO=y
+# CONFIG_CMD_UNLZO is not set
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+# CONFIG_NET_NFS is not set
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+# CONFIG_NET_TFTP_PUSH is not set
+# CONFIG_NET_NETCONSOLE is not set
+# CONFIG_NET_RESOLV is not set
+
+#
+# Drivers                       
+#
+
+#
+# serial drivers                
+#
+# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
+# CONFIG_DRIVER_SERIAL_NS16550 is not set
+CONFIG_DRIVER_SERIAL_S3C24X0=y
+# CONFIG_DRIVER_SERIAL_S3C24X0_AUTOSYNC is not set
+CONFIG_HAS_DM9000=y
+CONFIG_MIIDEV=y
+
+#
+# Network drivers               
+#
+# CONFIG_DRIVER_NET_SMC911X is not set
+# CONFIG_DRIVER_NET_SMC91111 is not set
+CONFIG_DRIVER_NET_DM9000=y
+
+#
+# SPI drivers                   
+#
+# CONFIG_SPI is not set
+# CONFIG_I2C is not set
+
+#
+# flash drivers                 
+#
+# CONFIG_DRIVER_CFI is not set
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_S3C24X0=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_UBI is not set
+# CONFIG_ATA is not set
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_VIDEO is not set
+
+#
+# Filesystem support            
+#
+# CONFIG_FS_CRAMFS is not set
+CONFIG_FS_RAMFS=y
+CONFIG_FS_DEVFS=y
+CONFIG_CRC32=y
+# CONFIG_DIGEST is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+# CONFIG_PROCESS_ESCAPE_SEQUENCE is not set
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 2f47907..0f4d6e7 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -5,6 +5,7 @@ config ARCH_TEXT_BASE
 	default 0x31fc0000
 
 config BOARDINFO
+	default "Mini 2440"    if MACH_MINI2440
 	default "Digi A9M2440" if MACH_A9M2440
 	default "Digi A9M2410" if MACH_A9M2410
 
@@ -37,6 +38,14 @@ config MACH_A9M2440
 	  Say Y here if you are using Digi's Connect Core 9M equipped
 	  with a Samsung S3C2440 Processor
 
+config MACH_MINI2440
+	bool "Mini 2440"
+	select CPU_S3C2440
+	select HAS_DM9000
+	help
+	  Say Y here if you are using Mini 2440 dev board equipped 
+	  with a Samsung S3C2440 Processor
+
 endchoice
 
 menu "Board specific settings       "
-- 
1.7.1



From jbe at pengutronix.de  Tue Oct 19 04:28:28 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 19 Oct 2010 10:28:28 +0200
Subject: [PATCH] Add basic support for mini2440 dev board.
In-Reply-To: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>
References: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>
Message-ID: <201010191028.28405.jbe@pengutronix.de>

Marek Belisko wrote:
> This work is mainly based on a9m2440 board implementation
> from Juergen Beisert <jbe at pengutronix.de>. Functionality
> was tested only running barebox from ram. Loading to flash
> and booting will not work because missing lowlevel_init
> functionality (lack of jtag debugger on my side ;)).

I have now access to a mini2440 at Pengutronix. I will add this feature soon.

> [...]
> +static int mini2440_devices_init(void)
> +{
> +	uint32_t reg;
> +
> +	reg = readl(BWSCON);
> +
> +	/* CS#4 to access the network controller */
> +	reg &= ~0x000f0000;
> +	reg |=  0x000d0000;	/* 16 bit */
> +	writel(0x1f4c, BANKCON4);
> +
> +	writel(reg, BWSCON);
> +
> +	/* release the reset signal to external devices */
> +	reg = readl(MISCCR);
> +	reg |= 0x10000;
> +	writel(reg, MISCCR);
> +
> +	register_device(&nand_dev);
> +	register_device(&sdram_dev);
> +	register_device(&dm9000_dev);
> +#ifdef CONFIG_NAND
> +	/* ----------- add some vital partitions -------- */
> +	devfs_del_partition("self_raw");
> +	devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED,
> "self_raw"); +	dev_add_bb_dev("self_raw", NULL);
> +
> +	devfs_del_partition("env_raw");
> +	devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,
> "env_raw"); +	dev_add_bb_dev("env_raw", NULL);
> +#endif
> +	armlinux_add_dram(&sdram_dev);
> +	armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
> +	armlinux_set_architecture(MACH_TYPE_MINI2440);
> +
> +	return 0;
> +}

We need some kind of management here, because the mini2440 comes with NOR and 
NAND flash. And both can be configured to boot the system from: We need a 
location to store the environment. Maybe in NOR, when booting from NOR, and 
in NAND, when booting form NAND? Or only one single location where to store 
the environment, independent from the boot source? Ideas?

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From plagnioj at jcrosoft.com  Tue Oct 19 04:27:28 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 19 Oct 2010 10:27:28 +0200
Subject: [RFC] S3C24xx: Enable only the clocks of used units
In-Reply-To: <201010190855.18736.jbe@pengutronix.de>
References: <201010181859.51317.jbe@pengutronix.de>
	<20101019014246.GK11127@game.jcrosoft.org>
	<201010190855.18736.jbe@pengutronix.de>
Message-ID: <20101019082728.GL11127@game.jcrosoft.org>

On 08:55 Tue 19 Oct     , Juergen Beisert wrote:
> Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > -	mov r1, #0xFFFFFFF0
> > > +	/*
> > > +	 * Disable the clocks for most devices on this chip.
> > > +	 * They will be enabled again on demand
> > > +	 */
> > > +#ifdef CONFIG_S3C24XX_NAND_BOOT
> > > +	ldr r1, =0x6010 /* (CLK_RTC | CLK_GPIO | CLK_NAND) */
> > > +#else
> > > +	mov r1, #0x6000 /* (CLK_RTC | CLK_GPIO) */
> >
> > how about use the macro and define a macro to avoid the ifdef
> 
> I tried with macros, but the assembler failed. Can't remember why. But I tried 
> again a few minutes ago .... and now it works (????).
make because you had c definition in the header?
> 
> Do you mean something like this instead?
> 
> [...]
> #ifdef CONFIG_S3C24XX_NAND_BOOT
> # define FORCED_CLOCKS (CLK_RTC | CLK_GPIO | CLK_NAND)
> #else
> # define FORCED_CLOCKS (CLK_RTC | CLK_GPIO)
> #endif
> 
> 	/*
> 	 * Disable the clocks for most devices on this chip.
> 	 * They will be enabled again on demand
> 	 */
> 	ldr r1, =FORCED_CLOCKS
yeah excalty

Best Regards,
J.


From plagnioj at jcrosoft.com  Tue Oct 19 04:29:21 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 19 Oct 2010 10:29:21 +0200
Subject: [PATCH] Add basic support for mini2440 dev board.
In-Reply-To: <201010191028.28405.jbe@pengutronix.de>
References: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>
	<201010191028.28405.jbe@pengutronix.de>
Message-ID: <20101019082921.GM11127@game.jcrosoft.org>

On 10:28 Tue 19 Oct     , Juergen Beisert wrote:
> Marek Belisko wrote:
> > This work is mainly based on a9m2440 board implementation
> > from Juergen Beisert <jbe at pengutronix.de>. Functionality
> > was tested only running barebox from ram. Loading to flash
> > and booting will not work because missing lowlevel_init
> > functionality (lack of jtag debugger on my side ;)).
> 
> I have now access to a mini2440 at Pengutronix. I will add this feature soon.
> 
> > [...]
> > +static int mini2440_devices_init(void)
> > +{
> > +	uint32_t reg;
> > +
> > +	reg = readl(BWSCON);
> > +
> > +	/* CS#4 to access the network controller */
> > +	reg &= ~0x000f0000;
> > +	reg |=  0x000d0000;	/* 16 bit */
> > +	writel(0x1f4c, BANKCON4);
> > +
> > +	writel(reg, BWSCON);
> > +
> > +	/* release the reset signal to external devices */
> > +	reg = readl(MISCCR);
> > +	reg |= 0x10000;
> > +	writel(reg, MISCCR);
> > +
> > +	register_device(&nand_dev);
> > +	register_device(&sdram_dev);
> > +	register_device(&dm9000_dev);
> > +#ifdef CONFIG_NAND
> > +	/* ----------- add some vital partitions -------- */
> > +	devfs_del_partition("self_raw");
> > +	devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED,
> > "self_raw"); +	dev_add_bb_dev("self_raw", NULL);
> > +
> > +	devfs_del_partition("env_raw");
> > +	devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,
> > "env_raw"); +	dev_add_bb_dev("env_raw", NULL);
> > +#endif
> > +	armlinux_add_dram(&sdram_dev);
> > +	armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
> > +	armlinux_set_architecture(MACH_TYPE_MINI2440);
> > +
> > +	return 0;
> > +}
> 
> We need some kind of management here, because the mini2440 comes with NOR and 
> NAND flash. And both can be configured to boot the system from: We need a 
> location to store the environment. Maybe in NOR, when booting from NOR, and 
> in NAND, when booting form NAND? Or only one single location where to store 
> the environment, independent from the boot source? Ideas?
I like the idea to store in the boot media

Best Regards,
J.


From marek.belisko at gmail.com  Tue Oct 19 04:49:09 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Tue, 19 Oct 2010 10:49:09 +0200
Subject: [PATCH] Add basic support for mini2440 dev board.
In-Reply-To: <201010191028.28405.jbe@pengutronix.de>
References: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>
	<201010191028.28405.jbe@pengutronix.de>
Message-ID: <AANLkTimaQW8B+BpVJn-U4XvAyyiV5BrFZRqYYvW-ZZ3i@mail.gmail.com>

On Tue, Oct 19, 2010 at 10:28 AM, Juergen Beisert <jbe at pengutronix.de> wrote:
> Marek Belisko wrote:
>> This work is mainly based on a9m2440 board implementation
>> from Juergen Beisert <jbe at pengutronix.de>. Functionality
>> was tested only running barebox from ram. Loading to flash
>> and booting will not work because missing lowlevel_init
>> functionality (lack of jtag debugger on my side ;)).
>
> I have now access to a mini2440 at Pengutronix. I will add this feature soon.
>
>> [...]
>> +static int mini2440_devices_init(void)
>> +{
>> + ? ? uint32_t reg;
>> +
>> + ? ? reg = readl(BWSCON);
>> +
>> + ? ? /* CS#4 to access the network controller */
>> + ? ? reg &= ~0x000f0000;
>> + ? ? reg |= ?0x000d0000; ? ? /* 16 bit */
>> + ? ? writel(0x1f4c, BANKCON4);
>> +
>> + ? ? writel(reg, BWSCON);
>> +
>> + ? ? /* release the reset signal to external devices */
>> + ? ? reg = readl(MISCCR);
>> + ? ? reg |= 0x10000;
>> + ? ? writel(reg, MISCCR);
>> +
>> + ? ? register_device(&nand_dev);
>> + ? ? register_device(&sdram_dev);
>> + ? ? register_device(&dm9000_dev);
>> +#ifdef CONFIG_NAND
>> + ? ? /* ----------- add some vital partitions -------- */
>> + ? ? devfs_del_partition("self_raw");
>> + ? ? devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED,
>> "self_raw"); + ? ? ? ?dev_add_bb_dev("self_raw", NULL);
>> +
>> + ? ? devfs_del_partition("env_raw");
>> + ? ? devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,
>> "env_raw"); + dev_add_bb_dev("env_raw", NULL);
>> +#endif
>> + ? ? armlinux_add_dram(&sdram_dev);
>> + ? ? armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
>> + ? ? armlinux_set_architecture(MACH_TYPE_MINI2440);
>> +
>> + ? ? return 0;
>> +}
>
> We need some kind of management here, because the mini2440 comes with NOR and
> NAND flash. And both can be configured to boot the system from: We need a
> location to store the environment. Maybe in NOR, when booting from NOR, and
> in NAND, when booting form NAND? Or only one single location where to store
> the environment, independent from the boot source? Ideas?
AFAIK NOR flash with supervivi bootloader is used just for repair content of
NAND flash when something goes wrong. Do we really need to store
barebox to NOR flash?
>
> jbe
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Beisert ? ? ? ? ? ? |
> Linux Solutions for Science and Industry ? ? ?| Phone: +49-8766-939 228 ? ? |
> Vertretung Sued/Muenchen, Germany ? ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? ? ?| http://www.pengutronix.de/ ?|
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From jbe at pengutronix.de  Tue Oct 19 05:08:35 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 19 Oct 2010 11:08:35 +0200
Subject: [PATCH] Add basic support for mini2440 dev board.
In-Reply-To: <AANLkTimaQW8B+BpVJn-U4XvAyyiV5BrFZRqYYvW-ZZ3i@mail.gmail.com>
References: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>
	<201010191028.28405.jbe@pengutronix.de>
	<AANLkTimaQW8B+BpVJn-U4XvAyyiV5BrFZRqYYvW-ZZ3i@mail.gmail.com>
Message-ID: <201010191108.35835.jbe@pengutronix.de>

Belisko Marek wrote:
> On Tue, Oct 19, 2010 at 10:28 AM, Juergen Beisert <jbe at pengutronix.de> 
wrote:
> > Marek Belisko wrote:
> >> This work is mainly based on a9m2440 board implementation
> >> from Juergen Beisert <jbe at pengutronix.de>. Functionality
> >> was tested only running barebox from ram. Loading to flash
> >> and booting will not work because missing lowlevel_init
> >> functionality (lack of jtag debugger on my side ;)).
> >
> > I have now access to a mini2440 at Pengutronix. I will add this feature
> > soon.
> >
> >> [...]
> >> +static int mini2440_devices_init(void)
> >> +{
> >> + ? ? uint32_t reg;
> >> +
> >> + ? ? reg = readl(BWSCON);
> >> +
> >> + ? ? /* CS#4 to access the network controller */
> >> + ? ? reg &= ~0x000f0000;
> >> + ? ? reg |= ?0x000d0000; ? ? /* 16 bit */
> >> + ? ? writel(0x1f4c, BANKCON4);
> >> +
> >> + ? ? writel(reg, BWSCON);
> >> +
> >> + ? ? /* release the reset signal to external devices */
> >> + ? ? reg = readl(MISCCR);
> >> + ? ? reg |= 0x10000;
> >> + ? ? writel(reg, MISCCR);
> >> +
> >> + ? ? register_device(&nand_dev);
> >> + ? ? register_device(&sdram_dev);
> >> + ? ? register_device(&dm9000_dev);
> >> +#ifdef CONFIG_NAND
> >> + ? ? /* ----------- add some vital partitions -------- */
> >> + ? ? devfs_del_partition("self_raw");
> >> + ? ? devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED,
> >> "self_raw"); + ? ? ? ?dev_add_bb_dev("self_raw", NULL);
> >> +
> >> + ? ? devfs_del_partition("env_raw");
> >> + ? ? devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,
> >> "env_raw"); + dev_add_bb_dev("env_raw", NULL);
> >> +#endif
> >> + ? ? armlinux_add_dram(&sdram_dev);
> >> + ? ? armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
> >> + ? ? armlinux_set_architecture(MACH_TYPE_MINI2440);
> >> +
> >> + ? ? return 0;
> >> +}
> >
> > We need some kind of management here, because the mini2440 comes with NOR
> > and NAND flash. And both can be configured to boot the system from: We
> > need a location to store the environment. Maybe in NOR, when booting from
> > NOR, and in NAND, when booting form NAND? Or only one single location
> > where to store the environment, independent from the boot source? Ideas?
>
> AFAIK NOR flash with supervivi bootloader is used just for repair content
> of NAND flash when something goes wrong. Do we really need to store
> barebox to NOR flash?

We do not need it. But maybe we want it ;-)

Why supervivi, when barebox supports the mini2440 completely? (okay, okay, 
needs more work....)

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From marek.belisko at gmail.com  Tue Oct 19 05:12:57 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Tue, 19 Oct 2010 11:12:57 +0200
Subject: [PATCH] Add basic support for mini2440 dev board.
In-Reply-To: <201010191108.35835.jbe@pengutronix.de>
References: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>
	<201010191028.28405.jbe@pengutronix.de>
	<AANLkTimaQW8B+BpVJn-U4XvAyyiV5BrFZRqYYvW-ZZ3i@mail.gmail.com>
	<201010191108.35835.jbe@pengutronix.de>
Message-ID: <AANLkTimO51uYiuv-D+yzDu8YugcZHzokhTy2U8NAyvKB@mail.gmail.com>

On Tue, Oct 19, 2010 at 11:08 AM, Juergen Beisert <jbe at pengutronix.de> wrote:
> Belisko Marek wrote:
>> On Tue, Oct 19, 2010 at 10:28 AM, Juergen Beisert <jbe at pengutronix.de>
> wrote:
>> > Marek Belisko wrote:
>> >> This work is mainly based on a9m2440 board implementation
>> >> from Juergen Beisert <jbe at pengutronix.de>. Functionality
>> >> was tested only running barebox from ram. Loading to flash
>> >> and booting will not work because missing lowlevel_init
>> >> functionality (lack of jtag debugger on my side ;)).
>> >
>> > I have now access to a mini2440 at Pengutronix. I will add this feature
>> > soon.
>> >
>> >> [...]
>> >> +static int mini2440_devices_init(void)
>> >> +{
>> >> + ? ? uint32_t reg;
>> >> +
>> >> + ? ? reg = readl(BWSCON);
>> >> +
>> >> + ? ? /* CS#4 to access the network controller */
>> >> + ? ? reg &= ~0x000f0000;
>> >> + ? ? reg |= ?0x000d0000; ? ? /* 16 bit */
>> >> + ? ? writel(0x1f4c, BANKCON4);
>> >> +
>> >> + ? ? writel(reg, BWSCON);
>> >> +
>> >> + ? ? /* release the reset signal to external devices */
>> >> + ? ? reg = readl(MISCCR);
>> >> + ? ? reg |= 0x10000;
>> >> + ? ? writel(reg, MISCCR);
>> >> +
>> >> + ? ? register_device(&nand_dev);
>> >> + ? ? register_device(&sdram_dev);
>> >> + ? ? register_device(&dm9000_dev);
>> >> +#ifdef CONFIG_NAND
>> >> + ? ? /* ----------- add some vital partitions -------- */
>> >> + ? ? devfs_del_partition("self_raw");
>> >> + ? ? devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED,
>> >> "self_raw"); + ? ? ? ?dev_add_bb_dev("self_raw", NULL);
>> >> +
>> >> + ? ? devfs_del_partition("env_raw");
>> >> + ? ? devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,
>> >> "env_raw"); + dev_add_bb_dev("env_raw", NULL);
>> >> +#endif
>> >> + ? ? armlinux_add_dram(&sdram_dev);
>> >> + ? ? armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
>> >> + ? ? armlinux_set_architecture(MACH_TYPE_MINI2440);
>> >> +
>> >> + ? ? return 0;
>> >> +}
>> >
>> > We need some kind of management here, because the mini2440 comes with NOR
>> > and NAND flash. And both can be configured to boot the system from: We
>> > need a location to store the environment. Maybe in NOR, when booting from
>> > NOR, and in NAND, when booting form NAND? Or only one single location
>> > where to store the environment, independent from the boot source? Ideas?
>>
>> AFAIK NOR flash with supervivi bootloader is used just for repair content
>> of NAND flash when something goes wrong. Do we really need to store
>> barebox to NOR flash?
>
> We do not need it. But maybe we want it ;-)
>
> Why supervivi, when barebox supports the mini2440 completely? (okay, okay,
> needs more work....)
Well yes something like for my free-runner open-moko (in NOR u-boot)
;). You're right.
I can add more support but without jtag debugger I think I can't or
just a matter of luck ;)
that it boot from FLASH. Hope this basic help somebody to add full support.
>
> jbe
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Beisert ? ? ? ? ? ? |
> Linux Solutions for Science and Industry ? ? ?| Phone: +49-8766-939 228 ? ? |
> Vertretung Sued/Muenchen, Germany ? ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? ? ?| http://www.pengutronix.de/ ?|
>

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From jbe at pengutronix.de  Tue Oct 19 08:38:34 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 19 Oct 2010 14:38:34 +0200
Subject: [PATCH] Add basic support for mini2440 dev board.
In-Reply-To: <20101019082921.GM11127@game.jcrosoft.org>
References: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>
	<201010191028.28405.jbe@pengutronix.de>
	<20101019082921.GM11127@game.jcrosoft.org>
Message-ID: <201010191438.34628.jbe@pengutronix.de>

Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 10:28 Tue 19 Oct     , Juergen Beisert wrote:
> > Marek Belisko wrote:
> > > This work is mainly based on a9m2440 board implementation
> > > from Juergen Beisert <jbe at pengutronix.de>. Functionality
> > > was tested only running barebox from ram. Loading to flash
> > > and booting will not work because missing lowlevel_init
> > > functionality (lack of jtag debugger on my side ;)).
> >
> > I have now access to a mini2440 at Pengutronix. I will add this feature
> > soon.
> >
> > > [...]
> > > +static int mini2440_devices_init(void)
> > > +{
> > > +	uint32_t reg;
> > > +
> > > +	reg = readl(BWSCON);
> > > +
> > > +	/* CS#4 to access the network controller */
> > > +	reg &= ~0x000f0000;
> > > +	reg |=  0x000d0000;	/* 16 bit */
> > > +	writel(0x1f4c, BANKCON4);
> > > +
> > > +	writel(reg, BWSCON);
> > > +
> > > +	/* release the reset signal to external devices */
> > > +	reg = readl(MISCCR);
> > > +	reg |= 0x10000;
> > > +	writel(reg, MISCCR);
> > > +
> > > +	register_device(&nand_dev);
> > > +	register_device(&sdram_dev);
> > > +	register_device(&dm9000_dev);
> > > +#ifdef CONFIG_NAND
> > > +	/* ----------- add some vital partitions -------- */
> > > +	devfs_del_partition("self_raw");
> > > +	devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED,
> > > "self_raw"); +	dev_add_bb_dev("self_raw", NULL);
> > > +
> > > +	devfs_del_partition("env_raw");
> > > +	devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,
> > > "env_raw"); +	dev_add_bb_dev("env_raw", NULL);
> > > +#endif
> > > +	armlinux_add_dram(&sdram_dev);
> > > +	armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
> > > +	armlinux_set_architecture(MACH_TYPE_MINI2440);
> > > +
> > > +	return 0;
> > > +}
> >
> > We need some kind of management here, because the mini2440 comes with NOR
> > and NAND flash. And both can be configured to boot the system from: We
> > need a location to store the environment. Maybe in NOR, when booting from
> > NOR, and in NAND, when booting form NAND? Or only one single location
> > where to store the environment, independent from the boot source? Ideas?
>
> I like the idea to store in the boot media

If you switch the boot media the environment moves, too? That may confuse 
users, as their settings are "moving away" in this case. Okay, its not a 
regular usecase. But with the mini2440 its simply a configuration switch on 
the board. My idea was to add some Kconfig menu entries to select one of the 
possible cases a) move the environment with the boot source or b) store and 
expect it always in NOR or NAND.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Tue Oct 19 08:54:48 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:48 +0200
Subject: sparse fixes
Message-ID: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>

Hi all,

I recently tried to run make C=1. Here are the results. There are
enough sparse warnings left to fix though.

Sascha


The following changes since commit e9ff34657a9aeb42bd76141e97b0fb047ebfde58:

  eukrea_cpuimx35: update board support (2010-10-14 16:03:03 +0200)

are available in the git repository at:
  none ..BRANCH.NOT.VERIFIED..

Sascha Hauer (42):
      glob: sparse fixes
      fnmatch:sparse fixes
      readline: sparse fixes
      edit: sparse fixes
      command.h: sparse fixes
      crc32: sparse fixes
      copy_file: sparse fixes
      commands/mem.c: sparse fixes
      dlmalloc: sparse fixes
      console: sparse fixes
      notifier: sparse fixes
      fec_imx: sparse fixes
      imx gpio: sparse fixes
      imx clocksource: sparse fixes
      armlinux: sparse fixes
      arch/arm/cpu/cpu.c: sparse fixes
      cache-l2x0: sparse fixes
      speed-imx35: sparse fixes
      imx_dump_clocks: sparse fixes
      i.MX serial: sparse fixes
      i.MX remove wdog registers from header files
      hush: sparse fixes
      ramfs: sparse fixes
      common/env.c: sparse fixes
      version_string: sparse fixes
      imx-nand: sparse fixes
      ping: make locally used functions static
      arm div0: sparse fixes
      edit: make locally used variable static
      common/environment.c: sparse fixes
      commands/mem.c: make locally used function static
      bootm: sparse fixes
      net: make locally used functions static
      lib/driver.c: sparse fixes
      remove dead ldiv code
      common/memsize.c: add missing include
      i.MX speed: add missing include
      libbb: sparse fixes
      remove strange flush_cache functions
      pcm043: ifx compiler warning
      arm interrupts.c: sparse fixes
      process_escape_sequence: Add missing include

 arch/arm/boards/pcm043/pcm043.c             |    4 +-
 arch/arm/cpu/cache-l2x0.c                   |    2 +-
 arch/arm/cpu/cpu.c                          |    1 +
 arch/arm/cpu/interrupts.c                   |   10 +++-
 arch/arm/lib/Makefile                       |    1 -
 arch/arm/lib/armlinux.c                     |    3 +-
 arch/arm/lib/cache.c                        |   36 -----------
 arch/arm/lib/div0.c                         |    5 +-
 arch/arm/mach-imx/clocksource.c             |   25 ++++++--
 arch/arm/mach-imx/gpio.c                    |   15 +++--
 arch/arm/mach-imx/include/mach/clock.h      |    2 +
 arch/arm/mach-imx/include/mach/imx-nand.h   |    4 +-
 arch/arm/mach-imx/include/mach/imx1-regs.h  |    8 ---
 arch/arm/mach-imx/include/mach/imx21-regs.h |    8 ---
 arch/arm/mach-imx/include/mach/imx27-regs.h |    8 ---
 arch/arm/mach-imx/include/mach/imx31-regs.h |   10 ---
 arch/arm/mach-imx/include/mach/imx35-regs.h |   10 ---
 arch/arm/mach-imx/include/mach/imx51-regs.h |    7 --
 arch/arm/mach-imx/speed-imx25.c             |    3 +-
 arch/arm/mach-imx/speed-imx35.c             |    9 ++-
 arch/arm/mach-imx/speed.c                   |    1 +
 arch/ppc/lib/Makefile                       |    1 -
 arch/ppc/lib/cache.c                        |   50 ---------------
 arch/sandbox/os/common.c                    |    5 --
 commands/bootm.c                            |    2 +-
 commands/edit.c                             |    4 +-
 commands/loadb.c                            |    1 -
 commands/loads.c                            |    1 -
 commands/mem.c                              |    2 +-
 commands/version.c                          |    1 -
 common/console.c                            |    8 +-
 common/dlmalloc.c                           |   41 ++++++------
 common/env.c                                |    2 +-
 common/environment.c                        |    2 +-
 common/hush.c                               |   10 ++--
 common/memsize.c                            |    1 +
 drivers/net/fec_imx.c                       |    8 +-
 drivers/net/fec_imx.h                       |    6 +-
 drivers/serial/serial_imx.c                 |   89 ++++++++++++++-------------
 fs/ramfs.c                                  |    2 +-
 include/cache.h                             |    1 -
 include/command.h                           |    7 +-
 include/common.h                            |    4 +
 include/image.h                             |    1 +
 include/notifier.h                          |    1 +
 lib/Makefile                                |    1 -
 lib/copy_file.c                             |    2 +
 lib/crc32.c                                 |    2 +-
 lib/driver.c                                |    4 +-
 lib/fnmatch.c                               |    5 +-
 lib/glob.c                                  |   36 ++++-------
 lib/ldiv.c                                  |   55 ----------------
 lib/libbb.c                                 |    2 +-
 lib/process_escape_sequence.c               |    1 +
 lib/readline.c                              |    6 +-
 net/net.c                                   |    4 +-
 net/ping.c                                  |    4 +-
 57 files changed, 186 insertions(+), 358 deletions(-)
 delete mode 100644 arch/arm/lib/cache.c
 delete mode 100644 arch/ppc/lib/cache.c
 delete mode 100644 lib/ldiv.c


From s.hauer at pengutronix.de  Tue Oct 19 08:54:50 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:50 +0200
Subject: [PATCH 02/42] fnmatch:sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-3-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/fnmatch.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/lib/fnmatch.c b/lib/fnmatch.c
index 223b9d3..1a5e8d0 100644
--- a/lib/fnmatch.c
+++ b/lib/fnmatch.c
@@ -48,10 +48,7 @@ extern int errno;
 
 /* Match STRING against the filename pattern PATTERN, returning zero if
    it matches, nonzero if not.  */
-int fnmatch(pattern, string, flags)
-const char *pattern;
-const char *string;
-int flags;
+int fnmatch(const char *pattern, const char *string, int flags)
 {
 	register const char *p = pattern, *n = string;
 	register char c;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:51 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:51 +0200
Subject: [PATCH 03/42] readline: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-4-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/readline.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/readline.c b/lib/readline.c
index b82150e..b90de77 100644
--- a/lib/readline.c
+++ b/lib/readline.c
@@ -120,10 +120,10 @@ static char* hist_next(void)
 
 #define ERASE_TO_EOL() {				\
 	if (num < eol_num) {				\
-		int tmp;				\
-		for (tmp = num; tmp < eol_num; tmp++)	\
+		int t;					\
+		for (t = num; t < eol_num; t++)		\
 			getcmd_putch(' ');		\
-		while (tmp-- > num)			\
+		while (t-- > num)			\
 			getcmd_putch(CTL_BACKSPACE);	\
 		eol_num = num;				\
 	}						\
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:52 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:52 +0200
Subject: [PATCH 04/42] edit: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-5-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/edit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/commands/edit.c b/commands/edit.c
index a65b08a..7da6816 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -231,7 +231,7 @@ static int edit_read_file(const char *path)
 			line->prev = lastline;
 			if (lastline)
 				lastline->next = line;
-			line->next = 0;
+			line->next = NULL;
 			lastline = line;
 
 			if (!lineend)
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:54 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:54 +0200
Subject: [PATCH 06/42] crc32: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-7-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/crc32.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/crc32.c b/lib/crc32.c
index 3481782..275edb4 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -42,7 +42,7 @@ static void make_crc_table(void);
   the information needed to generate CRC's on data a byte at a time for all
   combinations of CRC register values and incoming bytes.
 */
-static void make_crc_table()
+static void make_crc_table(void)
 {
   ulong c;
   int n, k;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:53 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:53 +0200
Subject: [PATCH 05/42] command.h: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-6-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/command.h |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/command.h b/include/command.h
index 4a4d9cf..e235f63 100644
--- a/include/command.h
+++ b/include/command.h
@@ -78,9 +78,10 @@ void barebox_cmd_usage(struct command *cmdtp);
 
 #define Struct_Section  __attribute__ ((unused,section (".barebox_cmd")))
 
-#define BAREBOX_CMD_START(_name)				\
-const struct command __barebox_cmd_##_name	\
-	__attribute__ ((unused,section (".barebox_cmd_" __stringify(_name)))) = {				\
+#define BAREBOX_CMD_START(_name)							\
+extern const struct command __barebox_cmd_##_name;					\
+const struct command __barebox_cmd_##_name						\
+	__attribute__ ((unused,section (".barebox_cmd_" __stringify(_name)))) = {	\
 	.name		= #_name,
 
 #define BAREBOX_CMD_END					\
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:49 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:49 +0200
Subject: [PATCH 01/42] glob: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/glob.c |   36 ++++++++++++------------------------
 1 files changed, 12 insertions(+), 24 deletions(-)

diff --git a/lib/glob.c b/lib/glob.c
index a5e3d1d..43d2f67 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -100,11 +100,8 @@ const __ptr_t b;
    `glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
    Otherwise, `glob' returns zero.  */
-int glob(pattern, flags, errfunc, pglob)
-const char *pattern;
-int flags;
-int (*errfunc) __P((const char *, int));
-glob_t *pglob;
+int glob(const char *pattern, int flags,
+		int (*errfunc) __P((const char *, int)), glob_t *pglob)
 {
 	const char *filename;
 	char *dirname = NULL;
@@ -171,7 +168,7 @@ glob_t *pglob;
 		   For each name we found, call glob_in_dir on it and FILENAME,
 		   appending the results to PGLOB.  */
 		for (i = 0; i < dirs.gl_pathc; ++i) {
-			int oldcount;
+			int oldcount1;
 
 #ifdef	SHELL
 			{
@@ -186,7 +183,7 @@ glob_t *pglob;
 			}
 #endif				/* SHELL.  */
 
-			oldcount = pglob->gl_pathc;
+			oldcount1 = pglob->gl_pathc;
 			status = glob_in_dir(filename, dirs.gl_pathv[i],
 					     (flags | GLOB_APPEND) &
 					     ~GLOB_NOCHECK, errfunc, pglob);
@@ -202,8 +199,8 @@ glob_t *pglob;
 
 			/* Stick the directory on the front of each name.  */
 			prefix_array(dirs.gl_pathv[i],
-					 &pglob->gl_pathv[oldcount],
-					 pglob->gl_pathc - oldcount,
+					 &pglob->gl_pathv[oldcount1],
+					 pglob->gl_pathc - oldcount1,
 					 flags & GLOB_MARK);
 		}
 
@@ -286,11 +283,8 @@ out:
    unless DIRNAME is just "/".  Each old element of ARRAY is freed.
    If ADD_SLASH is non-zero, allocate one character more than
    necessary, so that a slash can be appended later.  */
-static int prefix_array(dirname, array, n, add_slash)
-const char *dirname;
-char **array;
-size_t n;
-int add_slash;
+static int prefix_array(const char *dirname, char **array, size_t n,
+		int add_slash)
 {
 	register size_t i;
 	size_t dirlen = strlen(dirname);
@@ -319,12 +313,8 @@ int add_slash;
    and matches are searched for in DIRECTORY.
    The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.
    The GLOB_APPEND flag is assumed to be set (always appends).  */
-static int glob_in_dir(pattern, directory, flags, errfunc, pglob)
-const char *pattern;
-const char *directory;
-int flags;
-int (*errfunc) __P((const char *, int));
-glob_t *pglob;
+static int glob_in_dir(const char *pattern, const char *directory,
+		int flags, int (*errfunc) __P((const char *, int)), glob_t *pglob)
 {
 	__ptr_t stream;
 
@@ -457,12 +447,10 @@ glob_t *pglob;
 #endif /* CONFIG_FAKE_GLOB */
 
 /* Free storage allocated in PGLOB by a previous `glob' call.  */
-void globfree(pglob)
-register glob_t *pglob;
+void globfree(glob_t *pglob)
 {
 	if (pglob->gl_pathv != NULL) {
-		register int i =
-		    pglob->gl_flags & GLOB_DOOFFS ? pglob->gl_offs : 0;
+		int i = pglob->gl_flags & GLOB_DOOFFS ? pglob->gl_offs : 0;
 		for (; i < pglob->gl_pathc; ++i)
 			if (pglob->gl_pathv[i] != NULL)
 				free((__ptr_t) pglob->gl_pathv[i]);
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:55 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:55 +0200
Subject: [PATCH 07/42] copy_file: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-8-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/copy_file.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/lib/copy_file.c b/lib/copy_file.c
index 0ff0435..7083531 100644
--- a/lib/copy_file.c
+++ b/lib/copy_file.c
@@ -3,6 +3,8 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <malloc.h>
+#include <libbb.h>
+
 #define RW_BUF_SIZE	(ulong)4096
 
 /**
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:56 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:56 +0200
Subject: [PATCH 08/42] commands/mem.c: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-9-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/common.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/common.h b/include/common.h
index 64f49db..0cf51b3 100644
--- a/include/common.h
+++ b/include/common.h
@@ -216,4 +216,6 @@ int run_shell(void);
 
 #define PAGE_SIZE	4096
 
+int memory_display(char *addr, ulong offs, ulong nbytes, int size);
+
 #endif	/* __COMMON_H_ */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:59 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:59 +0200
Subject: [PATCH 11/42] notifier: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-12-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/notifier.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/include/notifier.h b/include/notifier.h
index 878b17e..cb2be5f 100644
--- a/include/notifier.h
+++ b/include/notifier.h
@@ -15,6 +15,7 @@ struct notifier_head {
 };
 
 int notifier_chain_register(struct notifier_head *nh, struct notifier_block *n);
+int notifier_chain_unregister(struct notifier_head *nh, struct notifier_block *n);
 
 int notifier_call_chain(struct notifier_head *nh, unsigned long val, void *v);
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:02 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:02 +0200
Subject: [PATCH 14/42] imx clocksource: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-15-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/clocksource.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index b3a74b3..e492890 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -40,7 +40,7 @@
 #define GPT(x) __REG(IMX_TIM1_BASE + (x))
 #define timer_base (IMX_TIM1_BASE)
 
-uint64_t imx_clocksource_read(void)
+static uint64_t imx_clocksource_read(void)
 {
 	return readl(timer_base + GPT_TCN);
 }
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:58 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:58 +0200
Subject: [PATCH 10/42] console: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-11-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/console.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/common/console.c b/common/console.c
index 204a08c..3a1b451 100644
--- a/common/console.c
+++ b/common/console.c
@@ -120,7 +120,7 @@ static int console_baudrate_set(struct device_d *dev, struct param_d *param,
 static struct kfifo *console_input_buffer;
 static struct kfifo *console_output_buffer;
 
-int getc_buffer_flush(void)
+static int getc_buffer_flush(void)
 {
 	console_input_buffer = kfifo_alloc(1024);
 	console_output_buffer = kfifo_alloc(1024);
@@ -247,7 +247,9 @@ int tstc(void)
 }
 EXPORT_SYMBOL(tstc);
 
-void __early_initdata *early_console_base;
+#ifdef CONFIG_HAS_EARLY_INIT
+static void __early_initdata *early_console_base;
+#endif
 
 void console_putc(unsigned int ch, char c)
 {
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:54:57 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:54:57 +0200
Subject: [PATCH 09/42] dlmalloc: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-10-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/dlmalloc.c |   41 +++++++++++++++++++++--------------------
 1 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 83b1e18..ff63fbe 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -792,7 +792,7 @@ typedef struct malloc_chunk *mbinptr;
 #define IAV(i)  bin_at(i), bin_at(i)
 
 static mbinptr av_[NAV * 2 + 2] = {
-	0, 0,
+	NULL, NULL,
 	IAV (0), IAV (1), IAV (2), IAV (3), IAV (4), IAV (5), IAV (6), IAV (7),
 	IAV (8), IAV (9), IAV (10), IAV (11), IAV (12), IAV (13), IAV (14),
 	IAV (15),
@@ -1209,7 +1209,7 @@ void *malloc(size_t bytes)
 	INTERNAL_SIZE_T nb;
 
 	if ((long) bytes < 0)
-		return 0;
+		return NULL;
 
 	nb = request2size(bytes); /* padded request size; */
 
@@ -1364,7 +1364,7 @@ void *malloc(size_t bytes)
 		/* Try to extend */
 		malloc_extend_top(nb);
 		if ((remainder_size = chunksize(top) - nb) < (long) MINSIZE)
-			return 0;	/* propagate failure */
+			return NULL;	/* propagate failure */
 	}
 
 	victim = top;
@@ -1405,7 +1405,7 @@ void free(void *mem)
 	mchunkptr fwd;		/* misc temp for linking */
 	int islr;		/* track whether merging with last_remainder */
 
-	if (mem == 0)		/* free(0) has no effect */
+	if (!mem)		/* free(0) has no effect */
 		return;
 
 	p = mem2chunk(mem);
@@ -1524,15 +1524,15 @@ void *realloc(void *oldmem, size_t bytes)
 #ifdef REALLOC_ZERO_BYTES_FREES
 	if (bytes == 0) {
 		free(oldmem);
-		return 0;
+		return NULL;
 	}
 #endif
 
 	if ((long)bytes < 0)
-		return 0;
+		return NULL;
 
 	/* realloc of null is supposed to be same as malloc */
-	if (oldmem == 0)
+	if (!oldmem)
 		return malloc(bytes);
 
 	newp = oldp = mem2chunk(oldmem);
@@ -1570,7 +1570,7 @@ void *realloc(void *oldmem, size_t bytes)
 				goto split;
 			}
 		} else {
-			next = 0;
+			next = NULL;
 			nextsize = 0;
 		}
 
@@ -1582,7 +1582,7 @@ void *realloc(void *oldmem, size_t bytes)
 
 			/* try forward + backward first to save a later consolidation */
 
-			if (next != 0) {
+			if (next) {
 				/* into top */
 				if (next == top) {
 					if ((long)
@@ -1618,8 +1618,7 @@ void *realloc(void *oldmem, size_t bytes)
 			}
 
 			/* backward only */
-			if (prev != 0
-			    && (long)(prevsize + newsize) >= (long)nb) {
+			if (prev && (long)(prevsize + newsize) >= (long)nb) {
 				unlink(prev, bck, fwd);
 				newp = prev;
 				newsize += prevsize;
@@ -1633,8 +1632,8 @@ void *realloc(void *oldmem, size_t bytes)
 
 		newmem = malloc(bytes);
 
-		if (newmem == 0)	/* propagate failure */
-			return 0;
+		if (!newmem)	/* propagate failure */
+			return NULL;
 
 		/* Avoid copy if newp is next chunk after oldp. */
 		/* (This can only happen when new chunk is sbrk'ed.) */
@@ -1697,7 +1696,7 @@ void *memalign(size_t alignment, size_t bytes)
 	long remainder_size;	/* its size */
 
 	if ((long) bytes < 0)
-		return 0;
+		return NULL;
 
 	/* If need less alignment than we give anyway, just relay to malloc */
 
@@ -1714,8 +1713,8 @@ void *memalign(size_t alignment, size_t bytes)
 	nb = request2size(bytes);
 	m = (char*)(malloc (nb + alignment + MINSIZE));
 
-	if (m == 0)
-		return 0;	/* propagate failure */
+	if (!m)
+		return NULL;	/* propagate failure */
 
 	p = mem2chunk(m);
 
@@ -1763,6 +1762,7 @@ void *memalign(size_t alignment, size_t bytes)
 	return chunk2mem(p);
 }
 
+#if 0
 /*
  * valloc just invokes memalign with alignment argument equal
  * to the page size of the system (or as near to this as can
@@ -1772,6 +1772,7 @@ void *valloc(size_t bytes)
 {
 	return memalign(malloc_getpagesize, bytes);
 }
+#endif
 
 /*
  * pvalloc just invokes valloc for the nearest pagesize
@@ -1802,10 +1803,10 @@ void *calloc(size_t n, size_t elem_size)
 	void *mem = malloc(sz);
 
 	if ((long)n < 0)
-		return 0;
+		return NULL;
 
-	if (mem == 0)
-		return 0;
+	if (!mem)
+		return NULL;
 	else {
 		p = mem2chunk(mem);
 
@@ -1915,7 +1916,7 @@ size_t malloc_usable_size(void *mem)
 {
 	mchunkptr p;
 
-	if (mem == 0)
+	if (!mem)
 		return 0;
 	else {
 		p = mem2chunk(mem);
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:04 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:04 +0200
Subject: [PATCH 16/42] arch/arm/cpu/cpu.c: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-17-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/cpu/cpu.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 133d144..346f8dc 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -27,6 +27,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <cache.h>
 #include <asm/mmu.h>
 #include <asm/system.h>
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:00 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:00 +0200
Subject: [PATCH 12/42] fec_imx: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-13-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/net/fec_imx.c |    8 ++++----
 drivers/net/fec_imx.h |    6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 73b7a54..9c8de77 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -216,7 +216,7 @@ static void fec_tbd_init(struct fec_priv *fec)
  * @param[in] last 1 if this is the last buffer descriptor in the chain, else 0
  * @param[in] pRbd buffer descriptor to mark free again
  */
-static void fec_rbd_clean(int last, struct buffer_descriptor *pRbd)
+static void fec_rbd_clean(int last, struct buffer_descriptor __iomem *pRbd)
 {
 	/*
 	 * Reset buffer descriptor as empty
@@ -464,7 +464,7 @@ static int fec_send(struct eth_device *dev, void *eth_data, int data_length)
 static int fec_recv(struct eth_device *dev)
 {
 	struct fec_priv *fec = (struct fec_priv *)dev->priv;
-	struct buffer_descriptor *rbd = &fec->rbd_base[fec->rbd_index];
+	struct buffer_descriptor __iomem *rbd = &fec->rbd_base[fec->rbd_index];
 	unsigned long ievent;
 	int frame_length, len = 0;
 	struct fec_frame *frame;
@@ -568,11 +568,11 @@ static int fec_probe(struct device_d *dev)
 			sizeof(struct buffer_descriptor) + 2 * DB_ALIGNMENT);
 	base += (DB_ALIGNMENT - 1);
 	base &= ~(DB_ALIGNMENT - 1);
-	fec->rbd_base = (struct buffer_descriptor *)base;
+	fec->rbd_base = (struct buffer_descriptor __force __iomem *)base;
 	base += FEC_RBD_NUM * sizeof (struct buffer_descriptor) +
 		(DB_ALIGNMENT - 1);
 	base &= ~(DB_ALIGNMENT - 1);
-	fec->tbd_base = (struct buffer_descriptor *)base;
+	fec->tbd_base = (struct buffer_descriptor __force __iomem *)base;
 
 	writel((uint32_t)virt_to_phys(fec->tbd_base), fec->regs + FEC_ETDSR);
 	writel((uint32_t)virt_to_phys(fec->rbd_base), fec->regs + FEC_ERDSR);
diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h
index e1473a4..ce0fd89 100644
--- a/drivers/net/fec_imx.h
+++ b/drivers/net/fec_imx.h
@@ -135,11 +135,11 @@ struct buffer_descriptor {
  * @brief i.MX27-FEC private structure
  */
 struct fec_priv {
-	void *regs;
+	void __iomem *regs;
 	xceiver_type xcv_type;			/* transceiver type          */
-	struct buffer_descriptor *rbd_base;	/* RBD ring                  */
+	struct buffer_descriptor __iomem *rbd_base;	/* RBD ring                  */
 	int rbd_index;				/* next receive BD to read   */
-	struct buffer_descriptor *tbd_base;	/* TBD ring                  */
+	struct buffer_descriptor __iomem *tbd_base;	/* TBD ring                  */
 	int tbd_index;				/* next transmit BD to write */
 	struct mii_device miidev;
 };
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:01 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:01 +0200
Subject: [PATCH 13/42] imx gpio: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-14-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/gpio.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c
index c6a59a6..0a3e046 100644
--- a/arch/arm/mach-imx/gpio.c
+++ b/arch/arm/mach-imx/gpio.c
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <asm/io.h>
 #include <mach/imx-regs.h>
+#include <mach/gpio.h>
 
 #if defined CONFIG_ARCH_IMX1 || defined CONFIG_ARCH_IMX21 || defined CONFIG_ARCH_IMX27
 #define GPIO_DR		0x1c
@@ -47,20 +48,20 @@
 #define GPIO_ISR	0x18
 #endif
 
-extern void *imx_gpio_base[];
+extern void __iomem *imx_gpio_base[];
 extern int imx_gpio_count;
 
-static void *gpio_get_base(unsigned gpio)
+static void __iomem *gpio_get_base(unsigned gpio)
 {
 	if (gpio >= imx_gpio_count)
-		return 0;
+		return NULL;
 
 	return imx_gpio_base[gpio / 32];
 }
 
 void gpio_set_value(unsigned gpio, int value)
 {
-	void *base = gpio_get_base(gpio);
+	void __iomem *base = gpio_get_base(gpio);
 	int shift = gpio % 32;
 	u32 val;
 
@@ -79,7 +80,7 @@ void gpio_set_value(unsigned gpio, int value)
 
 int gpio_direction_input(unsigned gpio)
 {
-	void *base = gpio_get_base(gpio);
+	void __iomem *base = gpio_get_base(gpio);
 	int shift = gpio % 32;
 	u32 val;
 
@@ -96,7 +97,7 @@ int gpio_direction_input(unsigned gpio)
 
 int gpio_direction_output(unsigned gpio, int value)
 {
-	void *base = gpio_get_base(gpio);
+	void __iomem *base = gpio_get_base(gpio);
 	int shift = gpio % 32;
 	u32 val;
 
@@ -114,7 +115,7 @@ int gpio_direction_output(unsigned gpio, int value)
 
 int gpio_get_value(unsigned gpio)
 {
-	void *base = gpio_get_base(gpio);
+	void __iomem *base = gpio_get_base(gpio);
 	int shift = gpio % 32;
 	u32 val;
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:05 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:05 +0200
Subject: [PATCH 17/42] cache-l2x0: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-18-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/cpu/cache-l2x0.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/cpu/cache-l2x0.c b/arch/arm/cpu/cache-l2x0.c
index 61569d2..1ea7bab 100644
--- a/arch/arm/cpu/cache-l2x0.c
+++ b/arch/arm/cpu/cache-l2x0.c
@@ -127,7 +127,7 @@ static void l2x0_clean_range(unsigned long start, unsigned long end)
 	cache_sync();
 }
 
-void l2x0_flush_range(unsigned long start, unsigned long end)
+static void l2x0_flush_range(unsigned long start, unsigned long end)
 {
 	start &= ~(CACHE_LINE_SIZE - 1);
 	while (start < end) {
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:03 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:03 +0200
Subject: [PATCH 15/42] armlinux: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-16-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/lib/armlinux.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index f690fef..a70625c 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -40,6 +40,7 @@
 #include <asm/global_data.h>
 #include <asm/setup.h>
 #include <asm/barebox-arm.h>
+#include <asm/armlinux.h>
 
 static struct tag *params;
 static int armlinux_architecture = 0;
@@ -207,7 +208,7 @@ void armlinux_set_serial(u64 serial)
 }
 
 #ifdef CONFIG_CMD_BOOTM
-int do_bootm_linux(struct image_data *data)
+static int do_bootm_linux(struct image_data *data)
 {
 	void (*theKernel)(int zero, int arch, void *params);
 	image_header_t *os_header = &data->os->header;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:06 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:06 +0200
Subject: [PATCH 18/42] speed-imx35: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-19-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/speed-imx35.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/speed-imx35.c b/arch/arm/mach-imx/speed-imx35.c
index 324cc29..8937ef1 100644
--- a/arch/arm/mach-imx/speed-imx35.c
+++ b/arch/arm/mach-imx/speed-imx35.c
@@ -19,6 +19,7 @@
 #include <mach/imx-regs.h>
 #include <asm/io.h>
 #include <mach/clock.h>
+#include <mach/generic.h>
 #include <init.h>
 
 unsigned long imx_get_mpllclk(void)
@@ -27,7 +28,7 @@ unsigned long imx_get_mpllclk(void)
 	return imx_decode_pll(mpctl, CONFIG_MX35_HCLK_FREQ);
 }
 
-unsigned long imx_get_ppllclk(void)
+static unsigned long imx_get_ppllclk(void)
 {
 	ulong ppctl = readl(IMX_CCM_BASE + CCM_PPCTL);
 	return imx_decode_pll(ppctl, CONFIG_MX35_HCLK_FREQ);
@@ -56,7 +57,7 @@ static struct arm_ahb_div clk_consumer[] = {
 	{ .arm = 0, .ahb = 0, .sel = 0},
 };
 
-unsigned long imx_get_armclk(void)
+static unsigned long imx_get_armclk(void)
 {
 	unsigned long pdr0 = readl(IMX_CCM_BASE + CCM_PDR0);
 	struct arm_ahb_div *aad;
@@ -83,7 +84,7 @@ unsigned long imx_get_ahbclk(void)
 	return fref / aad->ahb;
 }
 
-unsigned long imx_get_ipgclk(void)
+static unsigned long imx_get_ipgclk(void)
 {
 	ulong clk = imx_get_ahbclk();
 
@@ -95,7 +96,7 @@ static unsigned long get_3_3_div(unsigned long in)
 	return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1);
 }
 
-unsigned long imx_get_ipg_perclk(void)
+static unsigned long imx_get_ipg_perclk(void)
 {
 	ulong pdr0 = readl(IMX_CCM_BASE + CCM_PDR0);
 	ulong pdr4 = readl(IMX_CCM_BASE + CCM_PDR4);
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:22 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:22 +0200
Subject: [PATCH 34/42] lib/driver.c: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-35-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/driver.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/driver.c b/lib/driver.c
index 66d8fee..edde1dc 100644
--- a/lib/driver.c
+++ b/lib/driver.c
@@ -54,7 +54,7 @@ struct device_d *get_device_by_name(const char *name)
 	return NULL;
 }
 
-struct device_d *get_device_by_name_id(const char *name, int id)
+static struct device_d *get_device_by_name_id(const char *name, int id)
 {
 	struct device_d *dev;
 
@@ -315,7 +315,7 @@ static int do_devinfo(struct command *cmdtp, int argc, char *argv[])
 		for_each_driver(drv)
 			printf("%10s\n",drv->name);
 	} else {
-		struct device_d *dev = get_device_by_name(argv[1]);
+		dev = get_device_by_name(argv[1]);
 
 		if (!dev) {
 			printf("no such device: %s\n",argv[1]);
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:07 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:07 +0200
Subject: [PATCH 19/42] imx_dump_clocks: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-20-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/clock.h |    2 ++
 arch/arm/mach-imx/speed-imx25.c        |    3 +--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/clock.h b/arch/arm/mach-imx/include/mach/clock.h
index bbe7a60..5b590a2 100644
--- a/arch/arm/mach-imx/include/mach/clock.h
+++ b/arch/arm/mach-imx/include/mach/clock.h
@@ -33,4 +33,6 @@ ulong imx_get_mmcclk(void);
 int imx_clko_set_div(int div);
 void imx_clko_set_src(int src);
 
+void imx_dump_clocks(void);
+
 #endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c
index e8feb6b..cb28e9f 100644
--- a/arch/arm/mach-imx/speed-imx25.c
+++ b/arch/arm/mach-imx/speed-imx25.c
@@ -87,7 +87,7 @@ unsigned long imx_get_mmcclk(void)
 	return imx_get_perclk(3);
 }
 
-int imx_dump_clocks(void)
+void imx_dump_clocks(void)
 {
 	printf("mpll:    %10d Hz\n", imx_get_mpllclk());
 	printf("upll:    %10d Hz\n", imx_get_upllclk());
@@ -99,7 +99,6 @@ int imx_dump_clocks(void)
 	printf("lcd:     %10d Hz\n", imx_get_perclk(7));
 	printf("i2c:     %10d Hz\n", imx_get_perclk(6));
 	printf("sdhc1:   %10d Hz\n", imx_get_perclk(3));
-	return 0;
 }
 
 /*
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:19 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:19 +0200
Subject: [PATCH 31/42] commands/mem.c: make locally used function static
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-32-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/mem.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/commands/mem.c b/commands/mem.c
index bc84f6d..73bf915 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -110,7 +110,7 @@ int memory_display(char *addr, ulong offs, ulong nbytes, int size)
 	return 0;
 }
 
-int open_and_lseek(const char *filename, int mode, off_t pos)
+static int open_and_lseek(const char *filename, int mode, off_t pos)
 {
 	int fd, ret;
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:21 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:21 +0200
Subject: [PATCH 33/42] net: make locally used functions static
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-34-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 net/net.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/net.c b/net/net.c
index 8d99595..a613d1d 100644
--- a/net/net.c
+++ b/net/net.c
@@ -209,7 +209,7 @@ static void arp_handler(struct arprequest *arp)
 	}
 }
 
-int arp_request(IPaddr_t dest, unsigned char *ether)
+static int arp_request(IPaddr_t dest, unsigned char *ether)
 {
 	char *pkt;
 	struct arprequest *arp;
@@ -437,7 +437,7 @@ void net_unregister(struct net_connection *con)
 	free(con);
 }
 
-int net_ip_send(struct net_connection *con, int len)
+static int net_ip_send(struct net_connection *con, int len)
 {
 	con->ip->tot_len = htons(sizeof(struct iphdr) + len);
 	con->ip->id = htons(net_ip_id++);;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:24 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:24 +0200
Subject: [PATCH 36/42] common/memsize.c: add missing include
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-37-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/memsize.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/common/memsize.c b/common/memsize.c
index 505e43f..e3bc56c 100644
--- a/common/memsize.c
+++ b/common/memsize.c
@@ -21,6 +21,7 @@
  * MA 02111-1307 USA
  */
 
+#include <common.h>
 #include <config.h>
 #if defined (__PPC__) && !defined (__SANDBOX__)
 /*
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:25 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:25 +0200
Subject: [PATCH 37/42] i.MX speed: add missing include
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-38-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/speed.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/speed.c b/arch/arm/mach-imx/speed.c
index e024733..750ace0 100644
--- a/arch/arm/mach-imx/speed.c
+++ b/arch/arm/mach-imx/speed.c
@@ -24,6 +24,7 @@
 #include <asm-generic/div64.h>
 #include <common.h>
 #include <command.h>
+#include <mach/clock.h>
 
 /*
  *  get the system pll clock in Hz
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:23 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:23 +0200
Subject: [PATCH 35/42] remove dead ldiv code
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-36-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/Makefile |    1 -
 lib/ldiv.c   |   55 -------------------------------------------------------
 2 files changed, 0 insertions(+), 56 deletions(-)
 delete mode 100644 lib/ldiv.c

diff --git a/lib/Makefile b/lib/Makefile
index 0c62917..8b986d2 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,7 +1,6 @@
 obj-y			+= ctype.o
 obj-y			+= rbtree.o
 obj-y			+= display_options.o
-obj-y			+= ldiv.o
 obj-y			+= string.o
 obj-y			+= vsprintf.o
 obj-y			+= div64.o
diff --git a/lib/ldiv.c b/lib/ldiv.c
deleted file mode 100644
index 5d231a2..0000000
--- a/lib/ldiv.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-typedef struct {
-	long    quot;
-	long    rem;
-} ldiv_t;
-/* Return the `ldiv_t' representation of NUMER over DENOM.  */
-ldiv_t
-ldiv (long int numer, long int denom)
-{
-  ldiv_t result;
-
-  result.quot = numer / denom;
-  result.rem = numer % denom;
-
-  /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
-     NUMER / DENOM is to be computed in infinite precision.  In
-     other words, we should always truncate the quotient towards
-     zero, never -infinity.  Machine division and remainer may
-     work either way when one or both of NUMER or DENOM is
-     negative.  If only one is negative and QUOT has been
-     truncated towards -infinity, REM will have the same sign as
-     DENOM and the opposite sign of NUMER; if both are negative
-     and QUOT has been truncated towards -infinity, REM will be
-     positive (will have the opposite sign of NUMER).  These are
-     considered `wrong'.  If both are NUM and DENOM are positive,
-     RESULT will always be positive.  This all boils down to: if
-     NUMER >= 0, but REM < 0, we got the wrong answer.  In that
-     case, to get the right answer, add 1 to QUOT and subtract
-     DENOM from REM.  */
-
-  if (numer >= 0 && result.rem < 0)
-    {
-      ++result.quot;
-      result.rem -= denom;
-    }
-
-  return result;
-}
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:15 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:15 +0200
Subject: [PATCH 27/42] ping: make locally used functions static
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-28-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 net/ping.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ping.c b/net/ping.c
index 440e229..d414784 100644
--- a/net/ping.c
+++ b/net/ping.c
@@ -40,7 +40,7 @@ static int ping_send(void)
 	return net_icmp_send(ping_con, 9);
 }
 
-void ping_handler(char *pkt, unsigned len)
+static void ping_handler(char *pkt, unsigned len)
 {
 	IPaddr_t tmp;
 	struct iphdr *ip = net_eth_to_iphdr(pkt);
@@ -52,7 +52,7 @@ void ping_handler(char *pkt, unsigned len)
 	ping_state = PING_STATE_SUCCESS;
 }
 
-int do_ping(struct command *cmdtp, int argc, char *argv[])
+static int do_ping(struct command *cmdtp, int argc, char *argv[])
 {
 	int ret;
 	uint64_t ping_start = 0;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:12 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:12 +0200
Subject: [PATCH 24/42] common/env.c: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-25-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/env.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/common/env.c b/common/env.c
index edaf388..f81bd46 100644
--- a/common/env.c
+++ b/common/env.c
@@ -137,7 +137,7 @@ const char *getenv (const char *name)
 	const char *val;
 
 	if (strchr(name, '.')) {
-		const char *ret = 0;
+		const char *ret = NULL;
 		char *devstr = strdup(name);
 		char *par = strchr(devstr, '.');
 		struct device_d *dev;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:16 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:16 +0200
Subject: [PATCH 28/42] arm div0: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-29-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/lib/div0.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/lib/div0.c b/arch/arm/lib/div0.c
index 6267bf1..99d6b85 100644
--- a/arch/arm/lib/div0.c
+++ b/arch/arm/lib/div0.c
@@ -20,11 +20,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
+#include <common.h>
+
+extern void __div0(void);
 
 /* Replacement (=dummy) for GNU/Linux division-by zero handler */
 void __div0 (void)
 {
-	extern void hang (void);
-
 	hang();
 }
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:28 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:28 +0200
Subject: [PATCH 40/42] pcm043: ifx compiler warning
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-41-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/pcm043/pcm043.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
index 9f98795..5932f95 100644
--- a/arch/arm/boards/pcm043/pcm043.c
+++ b/arch/arm/boards/pcm043/pcm043.c
@@ -93,7 +93,7 @@ static struct device_d nand_dev = {
 };
 
 #ifdef CONFIG_PCM043_DISPLAY_SHARP
-static const struct fb_videomode pcm043_fb_mode = {
+static struct fb_videomode pcm043_fb_mode = {
 	/* 240x320 @ 60 Hz */
 	.name		= "Sharp-LQ035Q7",
 	.refresh	= 60,
@@ -111,7 +111,7 @@ static const struct fb_videomode pcm043_fb_mode = {
 	.flag		= 0,
 };
 #else
-static const struct fb_videomode pcm043_fb_mode = {
+static struct fb_videomode pcm043_fb_mode = {
 	/* 240x320 @ 60 Hz */
 	.name		= "TX090",
 	.refresh	= 60,
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:14 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:14 +0200
Subject: [PATCH 26/42] imx-nand: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-27-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/imx-nand.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx-nand.h b/arch/arm/mach-imx/include/mach/imx-nand.h
index 06acddb..eb583a2 100644
--- a/arch/arm/mach-imx/include/mach/imx-nand.h
+++ b/arch/arm/mach-imx/include/mach/imx-nand.h
@@ -8,8 +8,8 @@ void imx_nand_set_layout(int writesize, int datawidth);
 
 struct imx_nand_platform_data {
 	int width;
-	int hw_ecc:1;
-	int flash_bbt:1;
+	unsigned int hw_ecc:1;
+	unsigned int flash_bbt:1;
 };
 #endif /* __ASM_ARCH_NAND_H */
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:18 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:18 +0200
Subject: [PATCH 30/42] common/environment.c: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-31-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/environment.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/common/environment.c b/common/environment.c
index 0eb7e6b..e5f24ec 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -109,7 +109,7 @@ int envfs_save(char *filename, char *dirname)
 	struct action_data data;
 	void *buf = NULL;
 
-	data.writep = 0;
+	data.writep = NULL;
 	data.base = dirname;
 
 	/* first pass: calculate size */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:27 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:27 +0200
Subject: [PATCH 39/42] remove strange flush_cache functions
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-40-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/lib/Makefile    |    1 -
 arch/arm/lib/cache.c     |   36 ---------------------------------
 arch/ppc/lib/Makefile    |    1 -
 arch/ppc/lib/cache.c     |   50 ----------------------------------------------
 arch/sandbox/os/common.c |    5 ----
 commands/loadb.c         |    1 -
 commands/loads.c         |    1 -
 include/cache.h          |    1 -
 8 files changed, 0 insertions(+), 96 deletions(-)
 delete mode 100644 arch/arm/lib/cache.c
 delete mode 100644 arch/ppc/lib/cache.c

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index c1ac1aa..1d7f15a 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -1,7 +1,6 @@
 obj-y	+= armlinux.o
 obj-y	+= _ashldi3.o
 obj-y	+= _ashrdi3.o
-obj-y	+= cache.o
 obj-y	+= div0.o
 obj-y	+= _divsi3.o
 obj-y	+= _modsi3.o
diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
deleted file mode 100644
index 61ee9d3..0000000
--- a/arch/arm/lib/cache.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/* for now: just dummy functions to satisfy the linker */
-
-#include <common.h>
-
-void  flush_cache (unsigned long dummy1, unsigned long dummy2)
-{
-#ifdef CONFIG_OMAP2420
-	void arm1136_cache_flush(void);
-
-	arm1136_cache_flush();
-#endif
-	return;
-}
diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile
index 400b1e1..0844d56 100644
--- a/arch/ppc/lib/Makefile
+++ b/arch/ppc/lib/Makefile
@@ -1,6 +1,5 @@
 obj-y += bat_rw.o
 obj-y += board.o
-obj-y += cache.o
 obj-y += extable.o
 obj-$(CONFIG_USE_IRQ) += interrupts.o
 obj-y += kgdb.o
diff --git a/arch/ppc/lib/cache.c b/arch/ppc/lib/cache.c
deleted file mode 100644
index 3d863b3..0000000
--- a/arch/ppc/lib/cache.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-
-void flush_cache (ulong start_addr, ulong size)
-{
-#ifndef CONFIG_5xx
-	ulong addr, end_addr = start_addr + size;
-
-	if (CONFIG_CACHELINE_SIZE) {
-		addr = start_addr & (CONFIG_CACHELINE_SIZE - 1);
-		for (addr = start_addr;
-		     addr < end_addr;
-		     addr += CONFIG_CACHELINE_SIZE) {
-			asm ("dcbst 0,%0": :"r" (addr));
-		}
-		asm ("sync");	/* Wait for all dcbst to complete on bus */
-
-		for (addr = start_addr;
-		     addr < end_addr;
-		     addr += CONFIG_CACHELINE_SIZE) {
-			asm ("icbi 0,%0": :"r" (addr));
-		}
-	}
-	asm ("sync");		/* Always flush prefetch queue in any case */
-	asm ("isync");
-#endif
-}
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index c73aa79..89b2e5c 100644
--- a/arch/sandbox/os/common.c
+++ b/arch/sandbox/os/common.c
@@ -213,11 +213,6 @@ off_t linux_lseek(int fd, off_t offset)
 	return lseek(fd, offset, SEEK_SET);
 }
 
-void  flush_cache(unsigned long dummy1, unsigned long dummy2)
-{
-	/* why should we? */
-}
-
 extern void start_barebox(void);
 extern void mem_malloc_init(void *start, void *end);
 
diff --git a/commands/loadb.c b/commands/loadb.c
index acfb94f..faf4a97 100644
--- a/commands/loadb.c
+++ b/commands/loadb.c
@@ -636,7 +636,6 @@ static ulong load_serial_ymodem(void)
 				0) {
 			size += res;
 			addr += res;
-			flush_cache((ulong) yModemBuf, res);
 			wr = write(ofd, ymodemBuf, res);
 			if (res != wr) {
 				perror("ymodem");
diff --git a/commands/loads.c b/commands/loads.c
index 8269af1..6e0dc7f 100644
--- a/commands/loads.c
+++ b/commands/loads.c
@@ -175,7 +175,6 @@ load_serial (ulong offset)
 			    "## Total Size      = 0x%08lX = %ld Bytes\n",
 			    start_addr, end_addr, size, size
 		    );
-		    flush_cache (start_addr, size);
 		    sprintf(buf, "%lX", size);
 		    setenv("filesize", buf);
 		    return (addr);
diff --git a/include/cache.h b/include/cache.h
index 5968da9..23841dc 100644
--- a/include/cache.h
+++ b/include/cache.h
@@ -1,7 +1,6 @@
 #ifndef __CACHE_H
 #define __CACHE_H
 
-void	flush_cache   (unsigned long, unsigned long);
 int	icache_status (void);
 void	icache_enable (void);
 void	icache_disable(void);
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:17 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:17 +0200
Subject: [PATCH 29/42] edit: make locally used variable static
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-30-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/edit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/commands/edit.c b/commands/edit.c
index 7da6816..c2ab877 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -58,7 +58,7 @@ static int textx  = 0;		/* position in text */
 static struct line *curline;	/* line where the cursor is */
 
 static struct line *scrline;	/* the first line on screen */
-int scrcol = 0;			/* the first column on screen */
+static int scrcol = 0;		/* the first column on screen */
 
 static void pos(int x, int y)
 {
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:10 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:10 +0200
Subject: [PATCH 22/42] hush: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-23-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/hush.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/common/hush.c b/common/hush.c
index 3359f37..77610bb 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -362,7 +362,7 @@ static int b_addqchr(o_string *o, int ch, int quote)
 }
 
 /* belongs in utility.c */
-char *simple_itoa(unsigned int i)
+static char *simple_itoa(unsigned int i)
 {
 	/* 21 digits plus null terminator, good for 64-bit or smaller ints */
 	static char local[22];
@@ -636,10 +636,10 @@ static int run_pipe_real(struct p_context *ctx, struct pipe *pi)
 		}
 		if (child->sp) {
 			char * str = NULL;
-			struct p_context ctx;
+			struct p_context ctx1;
 			str = make_string((child->argv + i));
-			parse_string_outer(&ctx, str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
-			release_context(&ctx);
+			parse_string_outer(&ctx1, str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
+			release_context(&ctx1);
 			free(str);
 			return last_return_code;
 		}
@@ -948,7 +948,7 @@ static int set_local_var(const char *s, int flg_export)
 	 * NAME=VALUE format.  So the first order of business is to
 	 * split 's' on the '=' into 'name' and 'value' */
 	value = strchr(name, '=');
-	if (value==0 && ++value==0) {
+	if (!value) {
 		free(name);
 		return -1;
 	}
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:13 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:13 +0200
Subject: [PATCH 25/42] version_string: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-26-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/version.c |    1 -
 common/console.c   |    2 --
 include/common.h   |    2 ++
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/commands/version.c b/commands/version.c
index 6c683d9..2b3ac05 100644
--- a/commands/version.c
+++ b/commands/version.c
@@ -26,7 +26,6 @@
 
 static int do_version(struct command *cmdtp, int argc, char *argv[])
 {
-	extern char version_string[];
 	printf ("\n%s\n", version_string);
 	return 0;
 }
diff --git a/common/console.c b/common/console.c
index 3a1b451..82786f2 100644
--- a/common/console.c
+++ b/common/console.c
@@ -43,8 +43,6 @@ EXPORT_SYMBOL(console_list);
 #define CONSOLE_INIT_EARLY	1
 #define CONSOLE_INIT_FULL	2
 
-extern char version_string[];
-
 static void display_banner (void)
 {
 	printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string));
diff --git a/include/common.h b/include/common.h
index 0cf51b3..394542f 100644
--- a/include/common.h
+++ b/include/common.h
@@ -218,4 +218,6 @@ int run_shell(void);
 
 int memory_display(char *addr, ulong offs, ulong nbytes, int size);
 
+extern const char version_string[];
+
 #endif	/* __COMMON_H_ */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:26 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:26 +0200
Subject: [PATCH 38/42] libbb: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-39-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/libbb.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/libbb.c b/lib/libbb.c
index ee91fec..4d532f6 100644
--- a/lib/libbb.c
+++ b/lib/libbb.c
@@ -29,7 +29,7 @@ char *concat_path_file(const char *path, const char *filename)
 	while (*filename == '/')
 		filename++;
 
-	str = xmalloc(strlen(path) + (lc==0 ? 1 : 0) + strlen(filename) + 1);
+	str = xmalloc(strlen(path) + (lc==NULL ? 1 : 0) + strlen(filename) + 1);
 	sprintf(str, "%s%s%s", path, (lc==NULL ? "/" : ""), filename);
 
 	return str;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:30 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:30 +0200
Subject: [PATCH 42/42] process_escape_sequence: Add missing include
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-43-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/process_escape_sequence.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/lib/process_escape_sequence.c b/lib/process_escape_sequence.c
index 546edaa..e3431d4 100644
--- a/lib/process_escape_sequence.c
+++ b/lib/process_escape_sequence.c
@@ -21,6 +21,7 @@
  */
 #include <common.h>
 #include <fs.h>
+#include <libbb.h>
 
 int process_escape_sequence(const char *source, char *dest, int destlen)
 {
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:20 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:20 +0200
Subject: [PATCH 32/42] bootm: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-33-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/bootm.c |    2 +-
 include/image.h  |    1 +
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/commands/bootm.c b/commands/bootm.c
index 14475c7..0d3649f 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -225,7 +225,7 @@ void unmap_image(struct image_handle *handle)
 }
 EXPORT_SYMBOL(unmap_image);
 
-LIST_HEAD(handler_list);
+static LIST_HEAD(handler_list);
 
 int register_image_handler(struct image_handler *handler)
 {
diff --git a/include/image.h b/include/image.h
index a42d06b..8932947 100644
--- a/include/image.h
+++ b/include/image.h
@@ -336,6 +336,7 @@ void	print_image_hdr (image_header_t *hdr);
  * image.
  */
 struct image_handle *map_image(const char *filename, int verify);
+void unmap_image(struct image_handle *handle);
 
 /*
  * Relocate an image to load_address by uncompressing
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:11 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:11 +0200
Subject: [PATCH 23/42] ramfs: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-24-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 fs/ramfs.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/ramfs.c b/fs/ramfs.c
index 9ecb824..6222550 100644
--- a/fs/ramfs.c
+++ b/fs/ramfs.c
@@ -420,7 +420,7 @@ static int ramfs_truncate(struct device_d *dev, FILE *f, ulong size)
 
 	if (newchunks < oldchunks) {
 		if (!newchunks)
-			node->data = 0;
+			node->data = NULL;
 		while (newchunks--)
 			data = data->next;
 		while (data) {
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:09 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:09 +0200
Subject: [PATCH 21/42] i.MX remove wdog registers from header files
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-22-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/clocksource.c             |   23 +++++++++++++++++++----
 arch/arm/mach-imx/include/mach/imx1-regs.h  |    8 --------
 arch/arm/mach-imx/include/mach/imx21-regs.h |    8 --------
 arch/arm/mach-imx/include/mach/imx27-regs.h |    8 --------
 arch/arm/mach-imx/include/mach/imx31-regs.h |   10 ----------
 arch/arm/mach-imx/include/mach/imx35-regs.h |   10 ----------
 arch/arm/mach-imx/include/mach/imx51-regs.h |    7 -------
 7 files changed, 19 insertions(+), 55 deletions(-)

diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index e492890..4cb923f 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -101,19 +101,34 @@ static int clocksource_init (void)
 core_initcall(clocksource_init);
 
 /*
+ * Watchdog Registers
+ */
+#ifdef CONFIG_ARCH_IMX1
+#define WDOG_WCR	0x00 /* Watchdog Control Register */
+#define WDOG_WSR	0x02 /* Watchdog Service Register */
+#define WDOG_WSTR	0x04 /* Watchdog Status Register  */
+#define WDOG_WCR_WDE	(1 << 0)
+#else
+#define WDOG_WCR	0x00 /* Watchdog Control Register */
+#define WDOG_WSR	0x02 /* Watchdog Service Register */
+#define WDOG_WSTR	0x04 /* Watchdog Status Register  */
+#define WDOG_WCR_WDE	(1 << 2)
+#endif
+
+/*
  * Reset the cpu by setting up the watchdog timer and let it time out
  */
 void __noreturn reset_cpu (unsigned long ignored)
 {
 	/* Disable watchdog and set Time-Out field to 0 */
-	WCR = 0x0000;
+	writew(0x0, IMX_WDT_BASE + WDOG_WCR);
 
 	/* Write Service Sequence */
-	WSR = 0x5555;
-	WSR = 0xAAAA;
+	writew(0x5555, IMX_WDT_BASE + WDOG_WSR);
+	writew(0xaaaa, IMX_WDT_BASE + WDOG_WSR);
 
 	/* Enable watchdog */
-	WCR = WCR_WDE;
+	writew(WDOG_WCR_WDE, IMX_WDT_BASE + WDOG_WCR);
 
 	while (1);
 	/*NOTREACHED*/
diff --git a/arch/arm/mach-imx/include/mach/imx1-regs.h b/arch/arm/mach-imx/include/mach/imx1-regs.h
index 0d6fd92..f940cdb 100644
--- a/arch/arm/mach-imx/include/mach/imx1-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx1-regs.h
@@ -40,14 +40,6 @@
 #define IMX_AITC_BASE              (0x23000 + IMX_IO_BASE)
 #define IMX_CSI_BASE               (0x24000 + IMX_IO_BASE)
 
-/* Watchdog Registers*/
-#define WCR  __REG(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
-#define WSR  __REG(IMX_WDT_BASE + 0x04) /* Watchdog Service Register */
-#define WSTR __REG(IMX_WDT_BASE + 0x08) /* Watchdog Status Register  */
-
-/* important definition of some bits of WCR */
-#define WCR_WDE 0x01
-
 /* SYSCTRL Registers */
 #define SIDR   __REG(IMX_SYSCTRL_BASE + 0x4) /* Silicon ID Register		    */
 #define FMCR   __REG(IMX_SYSCTRL_BASE + 0x8) /* Function Multiplex Control Register */
diff --git a/arch/arm/mach-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h
index 6d64b81..a2c4d03 100644
--- a/arch/arm/mach-imx/include/mach/imx21-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx21-regs.h
@@ -72,14 +72,6 @@
 #define CS5L __REG(IMX_EIM_BASE + 0x2C) /* Chip Select 5 Lower Register    */
 #define EIM  __REG(IMX_EIM_BASE + 0x30) /* EIM Configuration Register      */
 
-/* Watchdog Registers*/
-#define WCR  __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
-#define WSR  __REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */
-#define WRSR __REG16(IMX_WDT_BASE + 0x04) /* Watchdog Reset Status Register  */
-
-/* important definition of some bits of WCR */
-#define WCR_WDE 0x04
-
 /* PLL registers */
 #define CSCR		__REG(IMX_PLL_BASE + 0x00) /* Clock Source Control Register       */
 #define MPCTL0		__REG(IMX_PLL_BASE + 0x04) /* MCU PLL Control Register 0          */
diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h
index f4354ba..0fa954d 100644
--- a/arch/arm/mach-imx/include/mach/imx27-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx27-regs.h
@@ -82,14 +82,6 @@
 
 #include "esdctl.h"
 
-/* Watchdog Registers*/
-#define WCR  __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
-#define WSR  __REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */
-#define WSTR __REG16(IMX_WDT_BASE + 0x04) /* Watchdog Status Register  */
-
-/* important definition of some bits of WCR */
-#define WCR_WDE 0x04
-
 /* PLL registers */
 #define CSCR		__REG(IMX_PLL_BASE + 0x00) /* Clock Source Control Register       */
 #define MPCTL0		__REG(IMX_PLL_BASE + 0x04) /* MCU PLL Control Register 0          */
diff --git a/arch/arm/mach-imx/include/mach/imx31-regs.h b/arch/arm/mach-imx/include/mach/imx31-regs.h
index d2304ec..536bf0d 100644
--- a/arch/arm/mach-imx/include/mach/imx31-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx31-regs.h
@@ -120,16 +120,6 @@
 #endif
 
 /*
- * Watchdog Registers
- */
-#define WCR  __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
-#define WSR  __REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */
-#define WSTR __REG16(IMX_WDT_BASE + 0x04) /* Watchdog Status Register  */
-
-/* important definition of some bits of WCR */
-#define WCR_WDE 0x04
-
-/*
  * Clock Controller Module (CCM)
  */
 #define IMX_CCM_BASE	0x53f80000
diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h
index b2b360a..b0f6b82 100644
--- a/arch/arm/mach-imx/include/mach/imx35-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
@@ -135,15 +135,5 @@
 #define TSTAT_CAPT     (1<<1)  /* Capture event */
 #define TSTAT_COMP     (1)     /* Compare event */
 
-/*
- * Watchdog Registers
- */
-#define WCR  __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
-#define WSR  __REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */
-#define WSTR __REG16(IMX_WDT_BASE + 0x04) /* Watchdog Status Register  */
-
-/* important definition of some bits of WCR */
-#define WCR_WDE 0x04
-
 #endif /* __ASM_ARCH_MX35_REGS_H */
 
diff --git a/arch/arm/mach-imx/include/mach/imx51-regs.h b/arch/arm/mach-imx/include/mach/imx51-regs.h
index f99285c..1719a78 100644
--- a/arch/arm/mach-imx/include/mach/imx51-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx51-regs.h
@@ -24,13 +24,6 @@
 #define TSTAT_CAPT	(1<<1)	/* Capture event */
 #define TSTAT_COMP	(1)	/* Compare event */
 
-#define WCR	__REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
-#define WSR	__REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */
-#define WSTR	__REG16(IMX_WDT_BASE + 0x04) /* Watchdog Status Register  */
-
-/* important definition of some bits of WCR */
-#define WCR_WDE 0x04
-
 #define MX51_IROM_BASE_ADDR	0x0
 
 /*
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:29 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:29 +0200
Subject: [PATCH 41/42] arm interrupts.c: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-42-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/cpu/interrupts.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c
index 0557172..4a0b3f8 100644
--- a/arch/arm/cpu/interrupts.c
+++ b/arch/arm/cpu/interrupts.c
@@ -28,6 +28,14 @@
 #include <common.h>
 #include <asm/ptrace.h>
 
+void do_undefined_instruction (struct pt_regs *pt_regs);
+void do_software_interrupt (struct pt_regs *pt_regs);
+void do_prefetch_abort (struct pt_regs *pt_regs);
+void do_data_abort (struct pt_regs *pt_regs);
+void do_not_used (struct pt_regs *pt_regs);
+void do_fiq (struct pt_regs *pt_regs);
+void do_irq (struct pt_regs *pt_regs);
+
 #ifdef CONFIG_USE_IRQ
 /* enable IRQ interrupts */
 void enable_interrupts (void)
@@ -62,7 +70,7 @@ int disable_interrupts (void)
 /**
  * FIXME
  */
-void bad_mode (void)
+static void bad_mode (void)
 {
 	panic ("Resetting CPU ...\n");
 	reset_cpu (0);
-- 
1.7.2.3



From s.hauer at pengutronix.de  Tue Oct 19 08:55:08 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 Oct 2010 14:55:08 +0200
Subject: [PATCH 20/42] i.MX serial: sparse fixes
In-Reply-To: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287492930-15716-21-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/serial/serial_imx.c |   89 ++++++++++++++++++++++--------------------
 1 files changed, 47 insertions(+), 42 deletions(-)

diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index 25e6a0c..a7562f9 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -171,13 +171,14 @@ struct imx_serial_priv {
 	struct console_device cdev;
 	int baudrate;
 	struct notifier_block notify;
+	void __iomem *regs;
 };
 
-static int imx_serial_reffreq(ulong base)
+static int imx_serial_reffreq(void __iomem *regs)
 {
 	ulong rfdiv;
 
-	rfdiv = (readl(base + UFCR) >> 7) & 7;
+	rfdiv = (readl(regs + UFCR) >> 7) & 7;
 	rfdiv = rfdiv < 6 ? 6 - rfdiv : 7;
 
 	return imx_get_uartclk() / rfdiv;
@@ -190,108 +191,111 @@ static int imx_serial_reffreq(ulong base)
  */
 static int imx_serial_init_port(struct console_device *cdev)
 {
-	struct device_d *dev = cdev->dev;
-	ulong base = dev->map_base;
+	struct imx_serial_priv *priv = container_of(cdev,
+					struct imx_serial_priv, cdev);
+	void __iomem *regs = priv->regs;
 	uint32_t val;
 
-	writel(UCR1_VAL, base + UCR1);
-	writel(UCR2_WS | UCR2_IRTS, base + UCR2);
-	writel(UCR3_VAL, base + UCR3);
-	writel(UCR4_VAL, base + UCR4);
-	writel(0x0000002B, base + UESC);
-	writel(0, base + UTIM);
-	writel(0, base + UBIR);
-	writel(0, base + UBMR);
-	writel(0, base + UTS);
+	writel(UCR1_VAL, regs + UCR1);
+	writel(UCR2_WS | UCR2_IRTS, regs + UCR2);
+	writel(UCR3_VAL, regs + UCR3);
+	writel(UCR4_VAL, regs + UCR4);
+	writel(0x0000002B, regs + UESC);
+	writel(0, regs + UTIM);
+	writel(0, regs + UBIR);
+	writel(0, regs + UBMR);
+	writel(0, regs + UTS);
 
 
 	/* Configure FIFOs */
-	writel(0xa81, base + UFCR);
+	writel(0xa81, regs + UFCR);
 
 #ifdef ONEMS
-	writel(imx_serial_reffreq(base) / 1000, base + ONEMS);
+	writel(imx_serial_reffreq(regs) / 1000, regs + ONEMS);
 #endif
 
 	/* Enable FIFOs */
-	val = readl(base + UCR2);
+	val = readl(regs + UCR2);
 	val |= UCR2_SRST | UCR2_RXEN | UCR2_TXEN;
-	writel(val, base + UCR2);
+	writel(val, regs + UCR2);
 
   	/* Clear status flags */
-	val = readl(base + USR2);
+	val = readl(regs + USR2);
 	val |= USR2_ADET | USR2_DTRF | USR2_IDLE | USR2_IRINT | USR2_WAKE |
 	       USR2_RTSF | USR2_BRCD | USR2_ORE | USR2_RDR;
-	writel(val, base + USR2);
+	writel(val, regs + USR2);
 
   	/* Clear status flags */
-	val = readl(base + USR2);
+	val = readl(regs + USR2);
 	val |= USR1_PARITYERR | USR1_RTSD | USR1_ESCF | USR1_FRAMERR | USR1_AIRINT |
 	       USR1_AWAKE;
-	writel(val, base + USR2);
+	writel(val, regs + USR2);
 
 	return 0;
 }
 
 static void imx_serial_putc(struct console_device *cdev, char c)
 {
-	struct device_d *dev = cdev->dev;
+	struct imx_serial_priv *priv = container_of(cdev,
+					struct imx_serial_priv, cdev);
 
 	/* Wait for Tx FIFO not full */
-	while (readl(dev->map_base + UTS) & UTS_TXFULL);
+	while (readl(priv->regs + UTS) & UTS_TXFULL);
 
-        writel(c, dev->map_base + URTX0);
+        writel(c, priv->regs + URTX0);
 }
 
 static int imx_serial_tstc(struct console_device *cdev)
 {
-	struct device_d *dev = cdev->dev;
+	struct imx_serial_priv *priv = container_of(cdev,
+					struct imx_serial_priv, cdev);
 
 	/* If receive fifo is empty, return false */
-	if (readl(dev->map_base + UTS) & UTS_RXEMPTY)
+	if (readl(priv->regs + UTS) & UTS_RXEMPTY)
 		return 0;
 	return 1;
 }
 
 static int imx_serial_getc(struct console_device *cdev)
 {
-	struct device_d *dev = cdev->dev;
+	struct imx_serial_priv *priv = container_of(cdev,
+					struct imx_serial_priv, cdev);
 	unsigned char ch;
 
-	while (readl(dev->map_base + UTS) & UTS_RXEMPTY);
+	while (readl(priv->regs + UTS) & UTS_RXEMPTY);
 
-	ch = readl(dev->map_base + URXD0);
+	ch = readl(priv->regs + URXD0);
 
 	return ch;
 }
 
 static void imx_serial_flush(struct console_device *cdev)
 {
-	struct device_d *dev = cdev->dev;
+	struct imx_serial_priv *priv = container_of(cdev,
+					struct imx_serial_priv, cdev);
 
-	while (!(readl(dev->map_base + USR2) & USR2_TXDC));
+	while (!(readl(priv->regs + USR2) & USR2_TXDC));
 }
 
 static int imx_serial_setbaudrate(struct console_device *cdev, int baudrate)
 {
-	struct device_d *dev = cdev->dev;
 	struct imx_serial_priv *priv = container_of(cdev,
 					struct imx_serial_priv, cdev);
+	void __iomem *regs = priv->regs;
 	uint32_t val;
-
-	ulong base = dev->map_base;
-	ulong ucr1 = readl(base + UCR1);
+	uint32_t ucr1 = readl(regs + UCR1);
 
 	/* disable UART */
-	val = readl(base + UCR1);
+	val = readl(regs + UCR1);
 	val &= ~UCR1_UARTEN;
-	writel(val, base + UCR1);
+	writel(val, regs + UCR1);
 
 	/* Set the numerator value minus one of the BRM ratio */
-	writel((baudrate / 100) - 1, base + UBIR);
+	writel((baudrate / 100) - 1, regs + UBIR);
 	/* Set the denominator value minus one of the BRM ratio    */
-	writel((imx_serial_reffreq(base) / 1600) - 1, base + UBMR);
+	writel((imx_serial_reffreq(regs) / 1600) - 1, regs + UBMR);
 
-	writel(ucr1, base + UCR1);
+	writel(ucr1, regs + UCR1);
 
 	priv->baudrate = baudrate;
 
@@ -318,6 +322,7 @@ static int imx_serial_probe(struct device_d *dev)
 	priv = malloc(sizeof(*priv));
 	cdev = &priv->cdev;
 
+	priv->regs = (void __force __iomem *)dev->map_base;
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
@@ -331,9 +336,9 @@ static int imx_serial_probe(struct device_d *dev)
 	imx_serial_setbaudrate(cdev, 115200);
 
 	/* Enable UART */
-	val = readl(cdev->dev->map_base + UCR1);
+	val = readl(priv->regs + UCR1);
 	val |= UCR1_UARTEN;
-	writel(val, cdev->dev->map_base + UCR1);
+	writel(val, priv->regs + UCR1);
 
 	console_register(cdev);
 	priv->notify.notifier_call = imx_clocksource_clock_change;
-- 
1.7.2.3



From plagnioj at jcrosoft.com  Tue Oct 19 21:48:20 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 20 Oct 2010 03:48:20 +0200
Subject: [PATCH 21/42] i.MX remove wdog registers from header files
In-Reply-To: <1287492930-15716-22-git-send-email-s.hauer@pengutronix.de>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
	<1287492930-15716-22-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20101020014820.GB20390@game.jcrosoft.org>

On 14:55 Tue 19 Oct     , Sascha Hauer wrote:
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  arch/arm/mach-imx/clocksource.c             |   23 +++++++++++++++++++----
>  arch/arm/mach-imx/include/mach/imx1-regs.h  |    8 --------
>  arch/arm/mach-imx/include/mach/imx21-regs.h |    8 --------
>  arch/arm/mach-imx/include/mach/imx27-regs.h |    8 --------
>  arch/arm/mach-imx/include/mach/imx31-regs.h |   10 ----------
>  arch/arm/mach-imx/include/mach/imx35-regs.h |   10 ----------
>  arch/arm/mach-imx/include/mach/imx51-regs.h |    7 -------
>  7 files changed, 19 insertions(+), 55 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
> index e492890..4cb923f 100644
> --- a/arch/arm/mach-imx/clocksource.c
> +++ b/arch/arm/mach-imx/clocksource.c
> @@ -101,19 +101,34 @@ static int clocksource_init (void)
>  core_initcall(clocksource_init);
>  
>  /*
> + * Watchdog Registers
> + */
> +#ifdef CONFIG_ARCH_IMX1
> +#define WDOG_WCR	0x00 /* Watchdog Control Register */
> +#define WDOG_WSR	0x02 /* Watchdog Service Register */
> +#define WDOG_WSTR	0x04 /* Watchdog Status Register  */
> +#define WDOG_WCR_WDE	(1 << 0)
> +#else
> +#define WDOG_WCR	0x00 /* Watchdog Control Register */
> +#define WDOG_WSR	0x02 /* Watchdog Service Register */
> +#define WDOG_WSTR	0x04 /* Watchdog Status Register  */
> +#define WDOG_WCR_WDE	(1 << 2)
only the WDE seems different

Best Regards,
J.


From s.hauer at pengutronix.de  Wed Oct 20 02:27:48 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 20 Oct 2010 08:27:48 +0200
Subject: [PATCH 21/42] i.MX remove wdog registers from header files
In-Reply-To: <20101020014820.GB20390@game.jcrosoft.org>
References: <1287492930-15716-1-git-send-email-s.hauer@pengutronix.de>
	<1287492930-15716-22-git-send-email-s.hauer@pengutronix.de>
	<20101020014820.GB20390@game.jcrosoft.org>
Message-ID: <20101020062748.GC28242@pengutronix.de>

On Wed, Oct 20, 2010 at 03:48:20AM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 14:55 Tue 19 Oct     , Sascha Hauer wrote:
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  arch/arm/mach-imx/clocksource.c             |   23 +++++++++++++++++++----
> >  arch/arm/mach-imx/include/mach/imx1-regs.h  |    8 --------
> >  arch/arm/mach-imx/include/mach/imx21-regs.h |    8 --------
> >  arch/arm/mach-imx/include/mach/imx27-regs.h |    8 --------
> >  arch/arm/mach-imx/include/mach/imx31-regs.h |   10 ----------
> >  arch/arm/mach-imx/include/mach/imx35-regs.h |   10 ----------
> >  arch/arm/mach-imx/include/mach/imx51-regs.h |    7 -------
> >  7 files changed, 19 insertions(+), 55 deletions(-)
> > 
> > diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
> > index e492890..4cb923f 100644
> > --- a/arch/arm/mach-imx/clocksource.c
> > +++ b/arch/arm/mach-imx/clocksource.c
> > @@ -101,19 +101,34 @@ static int clocksource_init (void)
> >  core_initcall(clocksource_init);
> >  
> >  /*
> > + * Watchdog Registers
> > + */
> > +#ifdef CONFIG_ARCH_IMX1
> > +#define WDOG_WCR	0x00 /* Watchdog Control Register */
> > +#define WDOG_WSR	0x02 /* Watchdog Service Register */
> > +#define WDOG_WSTR	0x04 /* Watchdog Status Register  */
> > +#define WDOG_WCR_WDE	(1 << 0)
> > +#else
> > +#define WDOG_WCR	0x00 /* Watchdog Control Register */
> > +#define WDOG_WSR	0x02 /* Watchdog Service Register */
> > +#define WDOG_WSTR	0x04 /* Watchdog Status Register  */
> > +#define WDOG_WCR_WDE	(1 << 2)
> only the WDE seems different

oops, bug. on i.MX1 WSR should be 0x4 and SWTR should be 0x8. Will fix
this.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From eric at eukrea.com  Wed Oct 20 06:42:09 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 20 Oct 2010 12:42:09 +0200
Subject: [PATCH 1/3] fsl_udc: fix warning
Message-ID: <1287571331-11842-1-git-send-email-eric@eukrea.com>

this patch fix the following warning :
drivers/usb/gadget/fsl_udc.c: In function 'done':
drivers/usb/gadget/fsl_udc.c:566: warning: passing argument 1 of 'dma_inv_range' makes integer from pointer without a cast
arch/arm/include/asm/mmu.h:24: note: expected 'long unsigned int' but argument is of type 'void *'
drivers/usb/gadget/fsl_udc.c:566: warning: passing argument 2 of 'dma_inv_range' makes integer from pointer without a cast
arch/arm/include/asm/mmu.h:24: note: expected 'long unsigned int' but argument is of type 'void *'

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 drivers/usb/gadget/fsl_udc.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 119afcb..48fd0b5 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -563,7 +563,8 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, int status)
 		dma_free_coherent(curr_td);
 	}
 
-	dma_inv_range(req->req.buf, req->req.buf + req->req.length);
+	dma_inv_range((unsigned long)req->req.buf,
+		(unsigned long)(req->req.buf + req->req.length));
 
 	if (status && (status != -ESHUTDOWN))
 		VDBG("complete %s req %p stat %d len %u/%u",
-- 
1.7.0.4



From eric at eukrea.com  Wed Oct 20 06:42:23 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 20 Oct 2010 12:42:23 +0200
Subject: [PATCH 1/3] fsl_udc: fix warning
Message-ID: <1287571345-11877-1-git-send-email-eric@eukrea.com>

this patch fix the following warning :
drivers/usb/gadget/fsl_udc.c: In function 'done':
drivers/usb/gadget/fsl_udc.c:566: warning: passing argument 1 of 'dma_inv_range' makes integer from pointer without a cast
arch/arm/include/asm/mmu.h:24: note: expected 'long unsigned int' but argument is of type 'void *'
drivers/usb/gadget/fsl_udc.c:566: warning: passing argument 2 of 'dma_inv_range' makes integer from pointer without a cast
arch/arm/include/asm/mmu.h:24: note: expected 'long unsigned int' but argument is of type 'void *'

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 drivers/usb/gadget/fsl_udc.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 119afcb..48fd0b5 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -563,7 +563,8 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, int status)
 		dma_free_coherent(curr_td);
 	}
 
-	dma_inv_range(req->req.buf, req->req.buf + req->req.length);
+	dma_inv_range((unsigned long)req->req.buf,
+		(unsigned long)(req->req.buf + req->req.length));
 
 	if (status && (status != -ESHUTDOWN))
 		VDBG("complete %s req %p stat %d len %u/%u",
-- 
1.7.0.4



From eric at eukrea.com  Wed Oct 20 06:43:19 2010
From: eric at eukrea.com (=?ISO-8859-1?Q?Eric_B=E9nard?=)
Date: Wed, 20 Oct 2010 12:43:19 +0200
Subject: [PATCH 06/10] eukrea_cpuimx25: update board support
In-Reply-To: <20101016190102.GD6225@tarshish>
References: <1287065132-20372-1-git-send-email-eric@eukrea.com>
	<1287065132-20372-6-git-send-email-eric@eukrea.com>
	<20101016190102.GD6225@tarshish>
Message-ID: <4CBEC7C7.1040301@eukrea.com>

Hi Baruch,

Le 16/10/2010 21:01, Baruch Siach a ?crit :
>> +#ifdef CONFIG_USB
>> +
>> +#define MX35_H1_SIC_SHIFT	21
>> +#define MX35_H1_SIC_MASK	(0x3<<  MX35_H1_SIC_SHIFT)
>> +#define MX35_H1_PM_BIT		(1<<  8)
>> +#define MX35_H1_IPPUE_UP_BIT	(1<<  7)
>> +#define MX35_H1_IPPUE_DOWN_BIT	(1<<  6)
>> +#define MX35_H1_TLL_BIT		(1<<  5)
>> +#define MX35_H1_USBTE_BIT	(1<<  4)
>> +#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2<<  0)
>
> The exact same defines appear in patch no. 10 of this series. IMO these should
> go into a shared header file.
>
done, thanks for the review.

Eric


From eric at eukrea.com  Wed Oct 20 09:40:15 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 20 Oct 2010 15:40:15 +0200
Subject: [PATCH 1/3] fsl_udc: fix warning
Message-ID: <1287582017-12999-1-git-send-email-eric@eukrea.com>

this patch fix the following warning :
drivers/usb/gadget/fsl_udc.c: In function 'done':
drivers/usb/gadget/fsl_udc.c:566: warning: passing argument 1 of 'dma_inv_range' makes integer from pointer without a cast
arch/arm/include/asm/mmu.h:24: note: expected 'long unsigned int' but argument is of type 'void *'
drivers/usb/gadget/fsl_udc.c:566: warning: passing argument 2 of 'dma_inv_range' makes integer from pointer without a cast
arch/arm/include/asm/mmu.h:24: note: expected 'long unsigned int' but argument is of type 'void *'

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 drivers/usb/gadget/fsl_udc.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 119afcb..48fd0b5 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -563,7 +563,8 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, int status)
 		dma_free_coherent(curr_td);
 	}
 
-	dma_inv_range(req->req.buf, req->req.buf + req->req.length);
+	dma_inv_range((unsigned long)req->req.buf,
+		(unsigned long)(req->req.buf + req->req.length));
 
 	if (status && (status != -ESHUTDOWN))
 		VDBG("complete %s req %p stat %d len %u/%u",
-- 
1.7.0.4



From eric at eukrea.com  Wed Oct 20 09:40:16 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 20 Oct 2010 15:40:16 +0200
Subject: [PATCH 2/3] cpuimx35: fix warning
In-Reply-To: <1287582017-12999-1-git-send-email-eric@eukrea.com>
References: <1287582017-12999-1-git-send-email-eric@eukrea.com>
Message-ID: <1287582017-12999-2-git-send-email-eric@eukrea.com>

this patch fix the following warning :
arch/arm/boards/eukrea_cpuimx35/flash_header.c:30: warning: "DEST_BASE" redefined
arch/arm/mach-imx/include/mach/imx-flash-header.h:29: note: this is the location of the previous definition

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/boards/eukrea_cpuimx35/flash_header.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx35/flash_header.c b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
index 4163caf..3133995 100644
--- a/arch/arm/boards/eukrea_cpuimx35/flash_header.c
+++ b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
@@ -27,6 +27,7 @@ struct imx_dcd_entry __dcd_entry_section dcd_entry[] = {
 	{ .ptr_type = 4, .addr = 0xb8001010, .val = 0x00000004, },
 };
 
+#undef DEST_BASE
 #define DEST_BASE 0x80000000
 struct imx_flash_header __flash_header_section flash_header = {
 	.app_code_jump_vector	= DEST_BASE + 0x1000,
-- 
1.7.0.4



From eric at eukrea.com  Wed Oct 20 09:40:17 2010
From: eric at eukrea.com (=?UTF-8?q?Eric=20B=C3=A9nard?=)
Date: Wed, 20 Oct 2010 15:40:17 +0200
Subject: [PATCH 3/3] i.MX25 & 35 usb config bits : create mach/usb.h
In-Reply-To: <1287582017-12999-1-git-send-email-eric@eukrea.com>
References: <1287582017-12999-1-git-send-email-eric@eukrea.com>
Message-ID: <1287582017-12999-3-git-send-email-eric@eukrea.com>

as suggested by Baruch Siach

Signed-off-by: Eric B?nard <eric at eukrea.com>
---
 arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c |   11 +----------
 arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c |   11 +----------
 arch/arm/mach-imx/include/mach/usb.h              |   14 ++++++++++++++
 3 files changed, 16 insertions(+), 20 deletions(-)
 create mode 100644 arch/arm/mach-imx/include/mach/usb.h

diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index c2eb398..805ffe2 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -42,6 +42,7 @@
 #include <mach/iomux-mx25.h>
 #include <i2c/i2c.h>
 #include <usb/fsl_usb2.h>
+#include <mach/usb.h>
 
 extern unsigned long _stext;
 extern void exception_vectors(void);
@@ -165,16 +166,6 @@ static struct device_d esdhc_dev = {
 };
 
 #ifdef CONFIG_USB
-
-#define MX35_H1_SIC_SHIFT	21
-#define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
-#define MX35_H1_PM_BIT		(1 << 8)
-#define MX35_H1_IPPUE_UP_BIT	(1 << 7)
-#define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
-#define MX35_H1_TLL_BIT		(1 << 5)
-#define MX35_H1_USBTE_BIT	(1 << 4)
-#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
-
 static void imx25_usb_init(void)
 {
 	unsigned int tmp;
diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
index 7d85f97..dfe64d0 100644
--- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
+++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
@@ -53,6 +53,7 @@
 #include <mach/imx-pll.h>
 #include <i2c/i2c.h>
 #include <usb/fsl_usb2.h>
+#include <mach/usb.h>
 
 static struct fec_platform_data fec_info = {
 	.xcv_type	= MII100,
@@ -140,16 +141,6 @@ static struct device_d esdhc_dev = {
 };
 
 #ifdef CONFIG_USB
-
-#define MX35_H1_SIC_SHIFT	21
-#define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
-#define MX35_H1_PM_BIT		(1 << 8)
-#define MX35_H1_IPPUE_UP_BIT	(1 << 7)
-#define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
-#define MX35_H1_TLL_BIT		(1 << 5)
-#define MX35_H1_USBTE_BIT	(1 << 4)
-#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
-
 static void imx35_usb_init(void)
 {
 	unsigned int tmp;
diff --git a/arch/arm/mach-imx/include/mach/usb.h b/arch/arm/mach-imx/include/mach/usb.h
new file mode 100644
index 0000000..5d6670d
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/usb.h
@@ -0,0 +1,14 @@
+#ifndef __MACH_USB_H_
+#define __MACH_USB_H_
+
+/* configuration bits for i.MX25 and i.MX35 */
+#define MX35_H1_SIC_SHIFT	21
+#define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
+#define MX35_H1_PM_BIT		(1 << 8)
+#define MX35_H1_IPPUE_UP_BIT	(1 << 7)
+#define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
+#define MX35_H1_TLL_BIT		(1 << 5)
+#define MX35_H1_USBTE_BIT	(1 << 4)
+#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
+
+#endif /* __MACH_USB_H_*/
-- 
1.7.0.4



From jbe at pengutronix.de  Thu Oct 21 08:06:00 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu, 21 Oct 2010 14:06:00 +0200
Subject: Bring together i.MX23, its MCI driver and the ChumbyOne
In-Reply-To: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
References: <1286808746-19456-1-git-send-email-jbe@pengutronix.de>
Message-ID: <201010211406.00729.jbe@pengutronix.de>

Juergen Beisert wrote:
> Now the i.MX23 architecture and the MCI support is in place, bring both
> together and make the ChumbyOne use of it.

Do these patches further re-work? Or why do they not occur in barebox-next?

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From vm.rod25 at gmail.com  Thu Oct 21 13:55:16 2010
From: vm.rod25 at gmail.com (Victor Rodriguez)
Date: Thu, 21 Oct 2010 12:55:16 -0500
Subject: Beagleboard and barebox problem
Message-ID: <AANLkTinosq5jY41=piCX3JaeFy6Z93gnG1Ym_VRqZ_sJ@mail.gmail.com>

Hey I am new on bare box I have download it from git repo and when I
make the barebox.bin with omap3530_beagle_defconfig this is the output

Texas Instruments X-Loader 1.4.2 (Feb 19 2009 - 12:01:24)
Reading boot sector
Loading u-boot.bin from mmc


barebox 2010.10.0-00086-ga14c018 (Oct 21 2010 - 12:19:10)

Board: Texas Instrument's Beagle
I2C probe
i2c-omap at i2c-omap0: bus 0 rev3.12 at 100 kHz
ehci at ehci0: USB EHCI 1.00
NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron NAND 256MiB
1,8V 16-bit)
Malloc space: 0x80c00000 -> 0x81000000 (size  4 MB)
Stack space : 0x80bf8000 -> 0x80c00000 (size 32 kB)
Open /dev/env0 No such file or directory
running /env/bin/init...
not found
barebox> ls
.      ..     dev
barebox> ls /dev/
zero         mem          ram0         twl4030      nand0
nand_oob0


And when I compile with omap3530_beagle_per_uart_defconfig

This is the output

Texas Instruments X-Loader 1.4.2 (Feb 19 2009 - 12:01:24)
Reading boot sector
Loading u-boot.bin from mmc


barebox 2010.10.0-00086-ga14c018 (Oct 21 2010 - 12:41:33)

Board: Texas Instrument's Beagle
Malloc space: 0x87bfff10 -> 0x87ffff10 (size  4 MB)
Stack space : 0x87bf7f10 -> 0x87bfff10 (size 32 kB)
running /env/bin/init...
not found
X-load Beagle>ls
Unknown command 'ls'
X-load Beagle>help
Unknown command 'help'

And the same to all the commands

What I am looking for is to use bare box with MMC, the kernel image
and the File System are on the MMC on different partitions, I have
tested them and work perfect with the traditioanl u-boot.

I really want to try this new boat loader

Thanks

Victor Rodriguez


From s.hauer at pengutronix.de  Thu Oct 21 15:06:23 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 21 Oct 2010 21:06:23 +0200
Subject: [PATCH 2/3] cpuimx35: fix warning
In-Reply-To: <1287582017-12999-2-git-send-email-eric@eukrea.com>
References: <1287582017-12999-1-git-send-email-eric@eukrea.com>
	<1287582017-12999-2-git-send-email-eric@eukrea.com>
Message-ID: <20101021190623.GG28242@pengutronix.de>

Hi Eric,

On Wed, Oct 20, 2010 at 03:40:16PM +0200, Eric B?nard wrote:
> this patch fix the following warning :
> arch/arm/boards/eukrea_cpuimx35/flash_header.c:30: warning: "DEST_BASE" redefined
> arch/arm/mach-imx/include/mach/imx-flash-header.h:29: note: this is the location of the previous definition
> 
> Signed-off-by: Eric B?nard <eric at eukrea.com>
> ---
>  arch/arm/boards/eukrea_cpuimx35/flash_header.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/boards/eukrea_cpuimx35/flash_header.c b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
> index 4163caf..3133995 100644
> --- a/arch/arm/boards/eukrea_cpuimx35/flash_header.c
> +++ b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
> @@ -27,6 +27,7 @@ struct imx_dcd_entry __dcd_entry_section dcd_entry[] = {
>  	{ .ptr_type = 4, .addr = 0xb8001010, .val = 0x00000004, },
>  };
>  
> +#undef DEST_BASE
>  #define DEST_BASE 0x80000000
>  struct imx_flash_header __flash_header_section flash_header = {
>  	.app_code_jump_vector	= DEST_BASE + 0x1000,

Why don't you just use another define instead of redefining DEST_BASE?

Grepping through the other boards there seems to be something wrong
here. The original idea was to let the rom code copy the image to the
address it is linked at to not have to relocate it later. This seems to
be not the case for most boards

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Thu Oct 21 16:09:02 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 21 Oct 2010 22:09:02 +0200
Subject: [PATCH] Add GPIO support and GPIO setup features to the S3C
	processors
In-Reply-To: <201010181843.39263.jbe@pengutronix.de>
References: <201010181843.39263.jbe@pengutronix.de>
Message-ID: <20101021200902.GB22139@pengutronix.de>

On Mon, Oct 18, 2010 at 06:43:39PM +0200, Juergen Beisert wrote:
> From: Juergen Beisert <juergen at kreuzholzen.de>
> Subject: Add GPIO support and GPIO setup features to the S3C processors
> 
> This patch adds genetic GPIO support to all S3C2440 processor based systems.
> Also it adds definitions to setup the pin multiplexer in a way the other
> architectures do.
> 
> Note: Tested on a S3C2440 based system only. But should work on an S3C2410, too.
> 
> Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
> 
> ---
>  arch/arm/Kconfig                                   |    1 
>  arch/arm/mach-s3c24xx/Makefile                     |    2 
>  arch/arm/mach-s3c24xx/gpio-s3c24x0.c               |  170 ++++++++
>  arch/arm/mach-s3c24xx/include/mach/gpio.h          |   31 +
>  arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h |  426 +++++++++++++++++++++
>  5 files changed, 629 insertions(+), 1 deletion(-)
> 
> Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
> ===================================================================
> --- /dev/null
> +++ barebox-2010.10.0/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
> @@ -0,0 +1,170 @@
> +/*
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <errno.h>
> +#include <asm/io.h>
> +#include <mach/s3c24x0-iomap.h>
> +#include <mach/gpio.h>
> +
> +static const unsigned char group_offset[] =
> +{
> +	0x00,	/* GPA */
> +	0x10,	/* GPB */
> +	0x20,	/* GPC */
> +	0x30,	/* GPD */
> +	0x40,	/* GPE */
> +	0x50,	/* GPF */
> +	0x60,	/* GPG */
> +	0x70,	/* GPH */
> +#ifdef CONFIG_CPU_S3C2440
> +	0xd0,	/* GPJ */
> +#endif
> +};
> +
> +void gpio_set_value(unsigned gpio, int value)
> +{
> +	unsigned group = gpio >> 5;
> +	unsigned bit = gpio % 32;
> +	unsigned offset;
> +	uint32_t reg;
> +
> +	offset = group_offset[group];
> +
> +	reg = readl(GPADAT + offset);
> +	reg &= ~(1 << bit);
> +	reg |= (!!value) << bit;
> +	writel(reg, GPADAT + offset);
> +}
> +
> +int gpio_direction_input(unsigned gpio)
> +{
> +	unsigned group = gpio >> 5;
> +	unsigned bit = gpio % 32;
> +	unsigned offset;
> +	uint32_t reg;
> +
> +	offset = group_offset[group];
> +
> +	reg = readl(GPACON + offset);
> +	reg &= ~(0x3 << (bit << 1));
> +	writel(reg, GPACON + offset);
> +
> +	return 0;
> +}
> +
> +
> +int gpio_direction_output(unsigned gpio, int value)
> +{
> +	unsigned group = gpio >> 5;
> +	unsigned bit = gpio % 32;
> +	unsigned offset;
> +	uint32_t reg;
> +
> +	offset = group_offset[group];
> +
> +	/* value */
> +	reg = readl(GPADAT + offset);
> +	reg &= ~(1 << bit);
> +	reg |= (!!value) << bit;
> +	writel(reg, GPADAT + offset);

You can call gpio_set_value here.

> +
> +	/* direction */
> +	if (group == 0) {	/* GPA is special */
> +		reg = readl(GPACON);
> +		reg &= ~(1 << bit);
> +		writel(reg, GPACON);
> +	} else {

gpio_direction_input does not have this special handling. Is this
correct?

> +		reg = readl(GPACON + offset);
> +		reg &= ~(0x3 << (bit << 1));
> +		reg |= 0x1 << (bit << 1);
> +		writel(reg, GPACON + offset);
> +	}
> +
> +	return 0;
> +}
> +
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From eric at eukrea.com  Thu Oct 21 16:40:44 2010
From: eric at eukrea.com (=?ISO-8859-15?Q?Eric_B=E9nard?=)
Date: Thu, 21 Oct 2010 22:40:44 +0200
Subject: [PATCH 2/3] cpuimx35: fix warning
In-Reply-To: <20101021190623.GG28242@pengutronix.de>
References: <1287582017-12999-1-git-send-email-eric@eukrea.com>
	<1287582017-12999-2-git-send-email-eric@eukrea.com>
	<20101021190623.GG28242@pengutronix.de>
Message-ID: <4CC0A54C.7020308@eukrea.com>

Hi Sascha,

Le 21/10/2010 21:06, Sascha Hauer a ?crit :
>> +#undef DEST_BASE
>>   #define DEST_BASE 0x80000000
>>   struct imx_flash_header __flash_header_section flash_header = {
>>   	.app_code_jump_vector	= DEST_BASE + 0x1000,
>
> Why don't you just use another define instead of redefining DEST_BASE?
>
because I fixed this with my fingers and not with my brain :-D

Eric


From s.hauer at pengutronix.de  Fri Oct 22 03:05:04 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 09:05:04 +0200
Subject: Beagleboard and barebox problem
In-Reply-To: <AANLkTinosq5jY41=piCX3JaeFy6Z93gnG1Ym_VRqZ_sJ@mail.gmail.com>
References: <AANLkTinosq5jY41=piCX3JaeFy6Z93gnG1Ym_VRqZ_sJ@mail.gmail.com>
Message-ID: <20101022070504.GD22139@pengutronix.de>

Hi Victor,

On Thu, Oct 21, 2010 at 12:55:16PM -0500, Victor Rodriguez wrote:
> Hey I am new on bare box I have download it from git repo and when I
> make the barebox.bin with omap3530_beagle_defconfig this is the output
> 
> Texas Instruments X-Loader 1.4.2 (Feb 19 2009 - 12:01:24)
> Reading boot sector
> Loading u-boot.bin from mmc
> 
> 
> barebox 2010.10.0-00086-ga14c018 (Oct 21 2010 - 12:19:10)
> 
> Board: Texas Instrument's Beagle
> I2C probe
> i2c-omap at i2c-omap0: bus 0 rev3.12 at 100 kHz
> ehci at ehci0: USB EHCI 1.00
> NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron NAND 256MiB
> 1,8V 16-bit)
> Malloc space: 0x80c00000 -> 0x81000000 (size  4 MB)
> Stack space : 0x80bf8000 -> 0x80c00000 (size 32 kB)
> Open /dev/env0 No such file or directory
> running /env/bin/init...
> not found
> barebox> ls
> .      ..     dev
> barebox> ls /dev/
> zero         mem          ram0         twl4030      nand0
> nand_oob0

Then it's up and running, congratulations ;)

What the beagle board is missing is currently a place to store the
environment. You could add an environment to nand by adding something
like this to the board setup function:

	devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,"env_raw");
	dev_add_bb_dev("env_raw", "env0");

(this adds a partition at offset 0x40000 and size 0x20000 to nand, you
probably have to adjust the offset to not overwrite the X-loader)

Another possibility would be to add mmc support for omap and put the
environment there. We recently gained mmc support for barebox, so all
that's missing is an omap driver. The mmc support is still close to
U-Boot, so the driver won't need many changes.

> 
> 
> And when I compile with omap3530_beagle_per_uart_defconfig

The per_uart_defconfig is more a X-loader replacement. You can use it to
bootstrap from the serial port. For your case the other config is the
correct one.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Fri Oct 22 03:11:41 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 09:11:41 +0200
Subject: [PATCH] Add GPIO support and GPIO setup features to the S3C
	processors
In-Reply-To: <20101021200902.GB22139@pengutronix.de>
References: <201010181843.39263.jbe@pengutronix.de>
	<20101021200902.GB22139@pengutronix.de>
Message-ID: <201010220911.41518.jbe@pengutronix.de>

Hi Sascha,

Sascha Hauer wrote:
> On Mon, Oct 18, 2010 at 06:43:39PM +0200, Juergen Beisert wrote:
> > From: Juergen Beisert <juergen at kreuzholzen.de>
> > Subject: Add GPIO support and GPIO setup features to the S3C processors
> >
> > This patch adds genetic GPIO support to all S3C2440 processor based
> > systems. Also it adds definitions to setup the pin multiplexer in a way
> > the other architectures do.
> >
> > Note: Tested on a S3C2440 based system only. But should work on an
> > S3C2410, too.
> >
> > Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
> >
> > ---
> >  arch/arm/Kconfig                                   |    1
> >  arch/arm/mach-s3c24xx/Makefile                     |    2
> >  arch/arm/mach-s3c24xx/gpio-s3c24x0.c               |  170 ++++++++
> >  arch/arm/mach-s3c24xx/include/mach/gpio.h          |   31 +
> >  arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h |  426
> > +++++++++++++++++++++ 5 files changed, 629 insertions(+), 1 deletion(-)
> >
> > Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
> > ===================================================================
> > --- /dev/null
> > +++ barebox-2010.10.0/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
> > @@ -0,0 +1,170 @@
> > +/*
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; either version 2 of
> > + * the License, or (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> > + * MA 02111-1307 USA
> > + */
> > +
> > +#include <common.h>
> > +#include <errno.h>
> > +#include <asm/io.h>
> > +#include <mach/s3c24x0-iomap.h>
> > +#include <mach/gpio.h>
> > +
> > +static const unsigned char group_offset[] =
> > +{
> > +	0x00,	/* GPA */
> > +	0x10,	/* GPB */
> > +	0x20,	/* GPC */
> > +	0x30,	/* GPD */
> > +	0x40,	/* GPE */
> > +	0x50,	/* GPF */
> > +	0x60,	/* GPG */
> > +	0x70,	/* GPH */
> > +#ifdef CONFIG_CPU_S3C2440
> > +	0xd0,	/* GPJ */
> > +#endif
> > +};
> > +
> > +void gpio_set_value(unsigned gpio, int value)
> > +{
> > +	unsigned group = gpio >> 5;
> > +	unsigned bit = gpio % 32;
> > +	unsigned offset;
> > +	uint32_t reg;
> > +
> > +	offset = group_offset[group];
> > +
> > +	reg = readl(GPADAT + offset);
> > +	reg &= ~(1 << bit);
> > +	reg |= (!!value) << bit;
> > +	writel(reg, GPADAT + offset);
> > +}
> > +
> > +int gpio_direction_input(unsigned gpio)
> > +{
> > +	unsigned group = gpio >> 5;
> > +	unsigned bit = gpio % 32;
> > +	unsigned offset;
> > +	uint32_t reg;
> > +
> > +	offset = group_offset[group];
> > +
> > +	reg = readl(GPACON + offset);
> > +	reg &= ~(0x3 << (bit << 1));
> > +	writel(reg, GPACON + offset);
> > +
> > +	return 0;
> > +}
> > +
> > +
> > +int gpio_direction_output(unsigned gpio, int value)
> > +{
> > +	unsigned group = gpio >> 5;
> > +	unsigned bit = gpio % 32;
> > +	unsigned offset;
> > +	uint32_t reg;
> > +
> > +	offset = group_offset[group];
> > +
> > +	/* value */
> > +	reg = readl(GPADAT + offset);
> > +	reg &= ~(1 << bit);
> > +	reg |= (!!value) << bit;
> > +	writel(reg, GPADAT + offset);
>
> You can call gpio_set_value here.

Hmm, right. Will change it.

> > +
> > +	/* direction */
> > +	if (group == 0) {	/* GPA is special */
> > +		reg = readl(GPACON);
> > +		reg &= ~(1 << bit);
> > +		writel(reg, GPACON);
> > +	} else {
>
> gpio_direction_input does not have this special handling. Is this
> correct?

The GPA pin group can only be GPIO outputs *or* their native feature enabled 
(addressbus lines for example). But you are right, I should catch this error 
if someone tries to read from a GPA group pin.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 22 04:54:28 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 10:54:28 +0200
Subject: [PATCH v2] Add GPIO support and GPIO setup features to the S3C
	processors
In-Reply-To: <201010220911.41518.jbe@pengutronix.de>
References: <201010181843.39263.jbe@pengutronix.de>
	<20101021200902.GB22139@pengutronix.de>
	<201010220911.41518.jbe@pengutronix.de>
Message-ID: <201010221054.28515.jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>
Subject: [PATCH v2] Add GPIO support and GPIO setup features to the S3C processors

This patch adds genetic GPIO support to all S3C2440 processor based systems.
Also it adds definitions to setup the pin multiplexer in a way the other
architectures do.

Note: Tested on a S3C2440 based system only. But should work on an S3C2410, too.

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>

---
 arch/arm/Kconfig                                   |    1 
 arch/arm/mach-s3c24xx/Makefile                     |    2 
 arch/arm/mach-s3c24xx/gpio-s3c24x0.c               |  169 ++++++++
 arch/arm/mach-s3c24xx/include/mach/gpio.h          |   31 +
 arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h |  426 +++++++++++++++++++++
 5 files changed, 628 insertions(+), 1 deletion(-)

Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
===================================================================
--- /dev/null
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
@@ -0,0 +1,169 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <mach/s3c24x0-iomap.h>
+#include <mach/gpio.h>
+
+static const unsigned char group_offset[] =
+{
+	0x00,	/* GPA */
+	0x10,	/* GPB */
+	0x20,	/* GPC */
+	0x30,	/* GPD */
+	0x40,	/* GPE */
+	0x50,	/* GPF */
+	0x60,	/* GPG */
+	0x70,	/* GPH */
+#ifdef CONFIG_CPU_S3C2440
+	0xd0,	/* GPJ */
+#endif
+};
+
+void gpio_set_value(unsigned gpio, int value)
+{
+	unsigned group = gpio >> 5;
+	unsigned bit = gpio % 32;
+	unsigned offset;
+	uint32_t reg;
+
+	offset = group_offset[group];
+
+	reg = readl(GPADAT + offset);
+	reg &= ~(1 << bit);
+	reg |= (!!value) << bit;
+	writel(reg, GPADAT + offset);
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+	unsigned group = gpio >> 5;
+	unsigned bit = gpio % 32;
+	unsigned offset;
+	uint32_t reg;
+
+	offset = group_offset[group];
+
+	reg = readl(GPACON + offset);
+	reg &= ~(0x3 << (bit << 1));
+	writel(reg, GPACON + offset);
+
+	return 0;
+}
+
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+	unsigned group = gpio >> 5;
+	unsigned bit = gpio % 32;
+	unsigned offset;
+	uint32_t reg;
+
+	offset = group_offset[group];
+
+	/* value */
+	gpio_set_value(gpio,value);
+	/* direction */
+	if (group == 0) {	/* GPA is special */
+		reg = readl(GPACON);
+		reg &= ~(1 << bit);
+		writel(reg, GPACON);
+	} else {
+		reg = readl(GPACON + offset);
+		reg &= ~(0x3 << (bit << 1));
+		reg |= 0x1 << (bit << 1);
+		writel(reg, GPACON + offset);
+	}
+
+	return 0;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+	unsigned group = gpio >> 5;
+	unsigned bit = gpio % 32;
+	unsigned offset;
+	uint32_t reg;
+
+	if (group == 0)	/* GPA is special: no input mode available */
+		return -ENODEV;
+
+	offset = group_offset[group];
+
+	/* value */
+	reg = readl(GPADAT + offset);
+
+	return !!(reg & (1 << bit));
+}
+
+void s3c_gpio_mode(unsigned gpio_mode)
+{
+	unsigned group, func, bit, offset, gpio;
+	uint32_t reg;
+
+	group = GET_GROUP(gpio_mode);
+	func = GET_FUNC(gpio_mode);
+	bit = GET_BIT(gpio_mode);
+	gpio = GET_GPIO_NO(gpio_mode);
+
+	if (group == 0) {
+		/* GPA is special */
+		switch (func) {
+		case 0:		/* GPIO input */
+			pr_debug("Cannot set GPA pin to GPIO input\n");
+			break;
+		case 1:		/* GPIO output */
+			gpio_direction_output(bit, GET_GPIOVAL(gpio_mode));
+			break;
+		default:
+			reg = readl(GPACON);
+			reg |= 1 << bit;
+			writel(reg, GPACON);
+			break;
+		}
+		return;
+	}
+
+	offset = group_offset[group];
+
+	if (PU_PRESENT(gpio_mode)) {
+		reg = readl(GPACON + offset + 8);
+		if (GET_PU(gpio_mode))
+			reg |= (1 << bit);	/* set means _disabled_ */
+		else
+			reg &= ~(1 << bit);
+		writel(reg, GPACON + offset + 8);
+	}
+
+	switch (func) {
+	case 0: /* input */
+		gpio_direction_input(gpio);
+		break;
+	case 1:	/* output */
+		gpio_direction_output(gpio, GET_GPIOVAL(gpio_mode));
+		break;
+	case 2: /* function one */
+	case 3: /* function two */
+		reg = readl(GPACON + offset);
+		reg &= ~(0x3 << (bit << 1));
+		reg |= func << (bit << 1);
+		writel(reg, GPACON + offset);
+		break;
+	}
+}
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/gpio.h
===================================================================
--- /dev/null
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/gpio.h
@@ -0,0 +1,31 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_MACH_GPIO_H
+#define __ASM_MACH_GPIO_H
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2410)
+# include <mach/iomux-s3c24x0.h>
+#endif
+
+void gpio_set_value(unsigned, int);
+int gpio_direction_input(unsigned);
+int gpio_direction_output(unsigned, int);
+int gpio_get_value(unsigned);
+void s3c_gpio_mode(unsigned);
+
+#endif /* __ASM_MACH_GPIO_H */
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h
===================================================================
--- /dev/null
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MACH_IOMUX_S3C24x0_H
+#define __MACH_IOMUX_S3C24x0_H
+
+/* 3322222222221111111111
+ * 10987654321098765432109876543210
+ *                            ^^^^^_ Bit offset
+ *                        ^^^^______ Group Number
+ *                    ^^____________ Function
+ *                   ^______________ initial GPIO out value
+ *                  ^_______________ Pull up feature present
+ *                 ^________________ initial pull up setting
+ */
+
+
+#define PIN(group,bit) (group * 32 + bit)
+#define FUNC(x) (((x) & 0x3) << 11)
+#define GET_FUNC(x) (((x) >> 11) & 0x3)
+#define GET_GROUP(x) (((x) >> 5) & 0xf)
+#define GET_BIT(x) (((x) & 0x1ff) % 32)
+#define GET_GPIOVAL(x) (((x) >> 13) & 0x1)
+#define GET_GPIO_NO(x) ((x & 0x1ff))
+#define GPIO_OUT FUNC(1)
+#define GPIO_IN FUNC(0)
+#define GPIO_VAL(x) ((!!(x)) << 13)
+#define PU (1 << 14)
+#define PU_PRESENT(x) (!!((x) & (1 << 14)))
+#define ENABLE_PU (0 << 15)
+#define DISABLE_PU (1 << 15)
+#define GET_PU(x) (!!((x) & DISABLE_PU))
+
+/*
+ * Group 0: GPIO 0...31
+ * Used GPIO: 0...22
+ * These pins can also act as GPIO outputs
+ */
+#define GPA0_ADDR0		(PIN(0,0) | FUNC(2))
+#define GPA0_ADDR0_GPIO		(PIN(0,0) | FUNC(0))
+#define GPA1_ADDR16		(PIN(0,1) | FUNC(2))
+#define GPA1_ADDR16_GPIO	(PIN(0,1) | FUNC(0))
+#define GPA2_ADDR17		(PIN(0,2) | FUNC(2))
+#define GPA2_ADDR17_GPIO	(PIN(0,2) | FUNC(0))
+#define GPA3_ADDR18		(PIN(0,3) | FUNC(2))
+#define GPA3_ADDR18_GPIO	(PIN(0,3) | FUNC(0))
+#define GPA4_ADDR19		(PIN(0,4) | FUNC(2))
+#define GPA4_ADDR19_GPIO	(PIN(0,4) | FUNC(0))
+#define GPA5_ADDR20		(PIN(0,5) | FUNC(2))
+#define GPA5_ADDR20_GPIO	(PIN(0,5) | FUNC(0))
+#define GPA6_ADDR21		(PIN(0,6) | FUNC(2))
+#define GPA6_ADDR21_GPIO	(PIN(0,6) | FUNC(0))
+#define GPA7_ADDR22		(PIN(0,7) | FUNC(2))
+#define GPA7_ADDR22_GPIO	(PIN(0,7) | FUNC(0))
+#define GPA8_ADDR23		(PIN(0,8) | FUNC(2))
+#define GPA8_ADDR23_GPIO	(PIN(0,8) | FUNC(0))
+#define GPA9_ADDR24		(PIN(0,9) | FUNC(2))
+#define GPA9_ADDR24_GPIO	(PIN(0,9) | FUNC(0))
+#define GPA10_ADDR25		(PIN(0,10) | FUNC(2))
+#define GPA10_ADDR25_GPIO	(PIN(0,10) | FUNC(0))
+#define GPA11_ADDR26		(PIN(0,11) | FUNC(2))
+#define GPA11_ADDR26_GPIO	(PIN(0,11) | FUNC(0))
+#define GPA12_NGCS1		(PIN(0,12) | FUNC(2))
+#define GPA12_NGCS1_GPIO	(PIN(0,12) | FUNC(0))
+#define GPA13_NGCS2		(PIN(0,13) | FUNC(2))
+#define GPA13_NGCS2_GPIO	(PIN(0,13) | FUNC(0))
+#define GPA14_NGCS3		(PIN(0,14) | FUNC(2))
+#define GPA14_NGCS3_GPIO	(PIN(0,14) | FUNC(0))
+#define GPA15_NGCS4		(PIN(0,15) | FUNC(2))
+#define GPA15_NGCS4_GPIO	(PIN(0,15) | FUNC(0))
+#define GPA16_NGCS5		(PIN(0,16) | FUNC(2))
+#define GPA16_NGCS5_GPIO	(PIN(0,16) | FUNC(0))
+#define GPA17_CLE		(PIN(0,17) | FUNC(2))
+#define GPA17_CLE_GPIO		(PIN(0,17) | FUNC(0))
+#define GPA18_ALE		(PIN(0,18) | FUNC(2))
+#define GPA18_ALE_GPIO		(PIN(0,18) | FUNC(0))
+#define GPA19_NFWE		(PIN(0,19) | FUNC(2))
+#define GPA19_NFWE_GPIO		(PIN(0,19) | FUNC(0))
+#define GPA20_NFRE		(PIN(0,20) | FUNC(2))
+#define GPA20_NFRE_GPIO		(PIN(0,20) | FUNC(0))
+#define GPA21_NRSTOUT		(PIN(0,21) | FUNC(2))
+#define GPA21_NRSTOUT_GPIO	(PIN(0,21) | FUNC(0))
+#define GPA22_NFCE		(PIN(0,22) | FUNC(2))
+#define GPA22_NFCE_GPIO		(PIN(0,22) | FUNC(0))
+
+/*
+ * Group 1: GPIO 32...63
+ * Used GPIO: 0...10
+ * these pins can also act as GPIO inputs/outputs
+ */
+#define GPB0_TOUT0	(PIN(1,0) | FUNC(2) | PU)
+#define GPB0_GPIO	(PIN(1,0) | FUNC(0) | PU)
+#define GPB1_TOUT1	(PIN(1,1) | FUNC(2) | PU)
+#define GPB1_GPIO	(PIN(1,1) | FUNC(0) | PU)
+#define GPB2_TOUT2	(PIN(1,2) | FUNC(2) | PU)
+#define GPB2_GPIO	(PIN(1,2) | FUNC(0) | PU)
+#define GPB3_TOUT3	(PIN(1,3) | FUNC(2) | PU)
+#define GPB3_GPIO	(PIN(1,3) | FUNC(0) | PU)
+#define GPB4_TCLK0	(PIN(1,4) | FUNC(2) | PU)
+#define GPB4_GPIO	(PIN(1,4) | FUNC(0) | PU)
+#define GPB5_NXBACK	(PIN(1,5) | FUNC(2) | PU)
+#define GPB5_GPIO	(PIN(1,5) | FUNC(0) | PU)
+#define GPB6_NXBREQ	(PIN(1,6) | FUNC(2) | PU)
+#define GPB6_GPIO	(PIN(1,6) | FUNC(0) | PU)
+#define GPB7_NXDACK1	(PIN(1,7) | FUNC(2) | PU)
+#define GPB7_GPIO	(PIN(1,7) | FUNC(0) | PU)
+#define GPB8_NXDREQ1	(PIN(1,8) | FUNC(2) | PU)
+#define GPB8_GPIO	(PIN(1,8) | FUNC(0) | PU)
+#define GPB9_NXDACK0	(PIN(1,9) | FUNC(2) | PU)
+#define GPB9_GPIO	(PIN(1,9) | FUNC(0) | PU)
+#define GPB10_NXDREQ0	(PIN(1,10) | FUNC(2) | PU)
+#define GPB10_GPIO	(PIN(1,10) | FUNC(0) | PU)
+
+/*
+ * Group 1: GPIO 64...95
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPC0_LEND	(PIN(2,0) | FUNC(2) | PU)
+#define GPC0_GPIO	(PIN(2,0) | FUNC(0) | PU)
+#define GPC1_VCLK	(PIN(2,1) | FUNC(2) | PU)
+#define GPC1_GPIO	(PIN(2,1) | FUNC(0) | PU)
+#define GPC2_VLINE	(PIN(2,2) | FUNC(2) | PU)
+#define GPC2_GPIO	(PIN(2,2) | FUNC(0) | PU)
+#define GPC3_VFRAME	(PIN(2,3) | FUNC(2) | PU)
+#define GPC3_GPIO	(PIN(2,3) | FUNC(0) | PU)
+#define GPC4_VM		(PIN(2,4) | FUNC(2) | PU)
+#define GPC4_GPIO	(PIN(2,4) | FUNC(0) | PU)
+#define GPC5_LPCOE	(PIN(2,5) | FUNC(2) | PU)
+#define GPC5_GPIO	(PIN(2,5) | FUNC(0) | PU)
+#define GPC6_LPCREV	(PIN(2,6) | FUNC(2) | PU)
+#define GPC6_GPIO	(PIN(2,6) | FUNC(0) | PU)
+#define GPC7_LPCREVB	(PIN(2,7) | FUNC(2) | PU)
+#define GPC7_GPIO	(PIN(2,7) | FUNC(0) | PU)
+#define GPC8_VD0	(PIN(2,8) | FUNC(2) | PU)
+#define GPC8_GPIO	(PIN(2,8) | FUNC(0) | PU)
+#define GPC9_VD1	(PIN(2,9) | FUNC(2) | PU)
+#define GPC9_GPIO	(PIN(2,9) | FUNC(0) | PU)
+#define GPC10_VD2	(PIN(2,10) | FUNC(2) | PU)
+#define GPC10_GPIO	(PIN(2,10) | FUNC(0) | PU)
+#define GPC11_VD3	(PIN(2,11) | FUNC(2) | PU)
+#define GPC11_GPIO	(PIN(2,11) | FUNC(0) | PU)
+#define GPC12_VD4	(PIN(2,12) | FUNC(2) | PU)
+#define GPC12_GPIO	(PIN(2,12) | FUNC(0) | PU)
+#define GPC13_VD5	(PIN(2,13) | FUNC(2) | PU)
+#define GPC13_GPIO	(PIN(2,13) | FUNC(0) | PU)
+#define GPC14_VD6	(PIN(2,14) | FUNC(2) | PU)
+#define GPC14_GPIO	(PIN(2,14) | FUNC(0) | PU)
+#define GPC15_VD7	(PIN(2,15) | FUNC(2) | PU)
+#define GPC15_GPIO	(PIN(2,15) | FUNC(0) | PU)
+
+/*
+ * Group 1: GPIO 96...127
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPD0_VD8	(PIN(3,0) | FUNC(2) | PU)
+#define GPD0_GPIO	(PIN(3,0) | FUNC(0) | PU)
+#define GPD1_VD9	(PIN(3,1) | FUNC(2) | PU)
+#define GPD1_GPIO	(PIN(3,1) | FUNC(0) | PU)
+#define GPD2_VD10	(PIN(3,2) | FUNC(2) | PU)
+#define GPD2_GPIO	(PIN(3,2) | FUNC(0) | PU)
+#define GPD3_VD11	(PIN(3,3) | FUNC(2) | PU)
+#define GPD3_GPIO	(PIN(3,3) | FUNC(0) | PU)
+#define GPD4_VD12	(PIN(3,4) | FUNC(2) | PU)
+#define GPD4_GPIO	(PIN(3,4) | FUNC(0) | PU)
+#define GPD5_VD13	(PIN(3,5) | FUNC(2) | PU)
+#define GPD5_GPIO	(PIN(3,5) | FUNC(0) | PU)
+#define GPD6_VD14	(PIN(3,6) | FUNC(2) | PU)
+#define GPD6_GPIO	(PIN(3,6) | FUNC(0) | PU)
+#define GPD7_VD15	(PIN(3,7) | FUNC(2) | PU)
+#define GPD7_GPIO	(PIN(3,7) | FUNC(0) | PU)
+#define GPD8_VD16	(PIN(3,8) | FUNC(2) | PU)
+#define GPD8_GPIO	(PIN(3,8) | FUNC(0) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPD8_SPIMISO1	(PIN(3,8) | FUNC(3) | PU)
+#endif
+#define GPD9_VD17	(PIN(3,9) | FUNC(2) | PU)
+#define GPD9_GPIO	(PIN(3,9) | FUNC(0) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPD9_SPIMOSI1	(PIN(3,9) | FUNC(3) | PU)
+#endif
+#define GPD10_VD18	(PIN(3,10) | FUNC(2) | PU)
+#define GPD10_GPIO	(PIN(3,10) | FUNC(0) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPD10_SPICLK	(PIN(3,10) | FUNC(3) | PU)
+#endif
+#define GPD11_VD19	(PIN(3,11) | FUNC(2) | PU)
+#define GPD11_GPIO	(PIN(3,11) | FUNC(0) | PU)
+#define GPD12_VD20	(PIN(3,12) | FUNC(2) | PU)
+#define GPD12_GPIO	(PIN(3,12) | FUNC(0) | PU)
+#define GPD13_VD21	(PIN(3,13) | FUNC(2) | PU)
+#define GPD13_GPIO	(PIN(3,13) | FUNC(0) | PU)
+#define GPD14_VD22	(PIN(3,14) | FUNC(2) | PU)
+#define GPD14_GPIO	(PIN(3,14) | FUNC(0) | PU)
+#define GPD14_NSS1	(PIN(3,14) | FUNC(3) | PU)
+#define GPD15_VD23	(PIN(3,15) | FUNC(2) | PU)
+#define GPD15_GPIO	(PIN(3,15) | FUNC(0) | PU)
+#define GPD15_NSS0	(PIN(3,15) | FUNC(3) | PU)
+
+/*
+ * Group 1: GPIO 128...159
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPE0_I2SLRCK	(PIN(4,0) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE0_AC_SYNC	(PIN(4,0) | FUNC(3) | PU)
+#endif
+#define GPE0_GPIO	(PIN(4,0) | FUNC(0) | PU)
+#define GPE1_I2SSCLK	(PIN(4,1) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE1_AC_BIT_CLK (PIN(4,1) | FUNC(3) | PU)
+#endif
+#define GPE1_GPIO	(PIN(4,1) | FUNC(0) | PU)
+#define GPE2_CDCLK	(PIN(4,2) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE2_AC_NRESET	(PIN(4,2) | FUNC(3) | PU)
+#endif
+#define GPE2_GPIO	(PIN(4,2) | FUNC(0) | PU)
+#define GPE3_I2SDI	(PIN(4,3) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE3_AC_SDATA_IN (PIN(4,3) | FUNC(3) | PU)
+#endif
+#ifdef CONFIG_CPU_S3C2410
+# define GPE_NSS0	(PIN(4,3) | FUNC(3) | PU)
+#endif
+#define GPE3_GPIO	(PIN(4,3) | FUNC(0) | PU)
+#define GPE4_I2SDO	(PIN(4,4) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPE4_AC_SDATA_OUT (PIN(4,4) | FUNC(3) | PU)
+#endif
+#ifdef CONFIG_CPU_S3C2440
+# define GPE4_I2SSDI	(PIN(4,4) | FUNC(3) | PU)
+#endif
+#define GPE4_GPIO	(PIN(4,4) | FUNC(0) | PU)
+#define GPE5_SDCLK	(PIN(4,5) | FUNC(2) | PU)
+#define GPE5_GPIO	(PIN(4,5) | FUNC(0) | PU)
+#define GPE6_SDCMD	(PIN(4,6) | FUNC(2) | PU)
+#define GPE6_GPIO	(PIN(4,6) | FUNC(0) | PU)
+#define GPE7_SDDAT0	(PIN(4,7) | FUNC(2) | PU)
+#define GPE7_GPIO	(PIN(4,7) | FUNC(0) | PU)
+#define GPE8_SDDAT1	(PIN(4,8) | FUNC(2) | PU)
+#define GPE8_GPIO	(PIN(4,8) | FUNC(0) | PU)
+#define GPE9_SDDAT2	(PIN(4,9) | FUNC(2) | PU)
+#define GPE9_GPIO	(PIN(4,9) | FUNC(0) | PU)
+#define GPE10_SDDAT3	(PIN(4,10) | FUNC(2) | PU)
+#define GPE10_GPIO	(PIN(4,10) | FUNC(0) | PU)
+#define GPE11_SPIMISO0	(PIN(4,11) | FUNC(2) | PU)
+#define GPE11_GPIO	(PIN(4,11) | FUNC(0) | PU)
+#define GPE12_SPIMOSI0	(PIN(4,12) | FUNC(2) | PU)
+#define GPE12_GPIO	(PIN(4,12) | FUNC(0) | PU)
+#define GPE13_SPICLK0	(PIN(4,13) | FUNC(2) | PU)
+#define GPE13_GPIO	(PIN(4,13) | FUNC(0) | PU)
+#define GPE14_IICSCL	(PIN(4,14) | FUNC(2))	/* no pullup option */
+#define GPE14_GPIO	(PIN(4,14) | FUNC(0))	/* no pullup option */
+#define GPE15_IICSDA	(PIN(4,15) | FUNC(2))	/* no pullup option */
+#define GPE15_GPIO	(PIN(4,15) | FUNC(0))	/* no pullup option */
+
+/*
+ * Group 1: GPIO 160...191
+ * Used GPIO: 0...7
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPF0_EINT0	(PIN(5,0) | FUNC(2) | PU)
+#define GPF0_GPIO	(PIN(5,0) | FUNC(0) | PU)
+#define GPF1_EINT1	(PIN(5,1) | FUNC(2) | PU)
+#define GPF1_GPIO	(PIN(5,1) | FUNC(0) | PU)
+#define GPF2_EINT2	(PIN(5,2) | FUNC(2) | PU)
+#define GPF2_GPIO	(PIN(5,2) | FUNC(0) | PU)
+#define GPF3_EINT3	(PIN(5,3) | FUNC(2) | PU)
+#define GPF3_GPIO	(PIN(5,3) | FUNC(0) | PU)
+#define GPF4_EINT4	(PIN(5,4) | FUNC(2) | PU)
+#define GPF4_GPIO	(PIN(5,4) | FUNC(0) | PU)
+#define GPF5_EINT5	(PIN(5,5) | FUNC(2) | PU)
+#define GPF5_GPIO	(PIN(5,5) | FUNC(0) | PU)
+#define GPF6_EINT6	(PIN(5,6) | FUNC(2) | PU)
+#define GPF6_GPIO	(PIN(5,6) | FUNC(0) | PU)
+#define GPF7_EINT7	(PIN(5,7) | FUNC(2) | PU)
+#define GPF7_GPIO	(PIN(5,7) | FUNC(0) | PU)
+
+/*
+ * Group 1: GPIO 192..223
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPG0_EINT8	(PIN(6,0) | FUNC(2) | PU)
+#define GPG0_GPIO	(PIN(6,0) | FUNC(0) | PU)
+#define GPG1_EINT9	(PIN(6,1) | FUNC(2) | PU)
+#define GPG1_GPIO	(PIN(6,1) | FUNC(0) | PU)
+#define GPG2_EINT10	(PIN(6,2) | FUNC(2) | PU)
+#define GPG2_NSS0	(PIN(6,2) | FUNC(3) | PU)
+#define GPG2_GPIO	(PIN(6,2) | FUNC(0) | PU)
+#define GPG3_EINT11	(PIN(6,3) | FUNC(2) | PU)
+#define GPG3_NSS1	(PIN(6,3) | FUNC(3) | PU)
+#define GPG3_GPIO	(PIN(6,3) | FUNC(0) | PU)
+#define GPG4_EINT12	(PIN(6,4) | FUNC(2) | PU)
+#define GPG4_LCD_PWREN	(PIN(6,4) | FUNC(3) | PU)
+#define GPG4_GPIO	(PIN(6,4) | FUNC(0) | PU)
+#define GPG5_EINT13	(PIN(6,5) | FUNC(2) | PU)
+#define GPG5_SPIMISO1	(PIN(6,5) | FUNC(3) | PU)
+#define GPG5_GPIO	(PIN(6,5) | FUNC(0) | PU)
+#define GPG6_EINT14	(PIN(6,6) | FUNC(2) | PU)
+#define GPG6_SPIMOSI1	(PIN(6,6) | FUNC(3) | PU)
+#define GPG6_GPIO	(PIN(6,6) | FUNC(0) | PU)
+#define GPG7_EINT15	(PIN(6,7) | FUNC(2) | PU)
+#define GPG7_SPICLK1	(PIN(6,7) | FUNC(3) | PU)
+#define GPG7_GPIO	(PIN(6,7) | FUNC(0) | PU)
+#define GPG8_EINT16	(PIN(6,8) | FUNC(2) | PU)
+#define GPG8_GPIO	(PIN(6,8) | FUNC(0) | PU)
+#define GPG9_EINT17	(PIN(6,9) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPG9_NRTS1	(PIN(6,9) | FUNC(3) | PU)
+#endif
+#define GPG9_GPIO	(PIN(6,9) | FUNC(0) | PU)
+#define GPG10_EINT18	(PIN(6,10) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2440
+# define GPG10_NCTS1	(PIN(6,10) | FUNC(3) | PU)
+#endif
+#define GPG10_GPIO	(PIN(6,10) | FUNC(0) | PU)
+#define GPG11_EINT19	(PIN(6,11) | FUNC(2) | PU)
+#define GPG11_TCLK	(PIN(6,11) | FUNC(3) | PU)
+#define GPG11_GPIO	(PIN(6,11) | FUNC(0) | PU)
+#define GPG12_EINT20	(PIN(6,12) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2410
+# define GPG12_XMON	(PIN(6,12) | FUNC(3) | PU)
+#endif
+#define GPG12_GPIO	(PIN(6,12) | FUNC(0) | PU)
+#define GPG13_EINT21	(PIN(6,13) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2410
+# define GPG13_NXPON	(PIN(6,13) | FUNC(3) | PU)
+#endif
+#define GPG13_GPIO	(PIN(6,13) | FUNC(0) | PU)	/* must be input in NAND boot mode */
+#define GPG14_EINT22	(PIN(6,14) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2410
+# define GPG14_YMON	(PIN(6,14) | FUNC(3) | PU)
+#endif
+#define GPG14_GPIO	(PIN(6,14) | FUNC(0) | PU)	/* must be input in NAND boot mode */
+#define GPG15_EINT23	(PIN(6,15) | FUNC(2) | PU)
+#ifdef CONFIG_CPU_S3C2410
+# define GPG15_YPON	(PIN(6,15) | FUNC(3) | PU)
+#endif
+#define GPG15_GPIO	(PIN(6,15) | FUNC(0) | PU)	/* must be input in NAND boot mode */
+
+/*
+ * Group 1: GPIO 224..255
+ * Used GPIO: 0...15
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPH0_NCTS0	(PIN(7,0) | FUNC(2) | PU)
+#define GPH0_GPIO	(PIN(7,0) | FUNC(0) | PU)
+#define GPH1_NRTS0	(PIN(7,1) | FUNC(2) | PU)
+#define GPH1_GPIO	(PIN(7,1) | FUNC(0) | PU)
+#define GPH2_TXD0	(PIN(7,2) | FUNC(2) | PU)
+#define GPH2_GPIO	(PIN(7,2) | FUNC(0) | PU)
+#define GPH3_RXD0	(PIN(7,3) | FUNC(2) | PU)
+#define GPH3_GPIO	(PIN(7,3) | FUNC(0) | PU)
+#define GPH4_TXD1	(PIN(7,4) | FUNC(2) | PU)
+#define GPH4_GPIO	(PIN(7,4) | FUNC(0) | PU)
+#define GPH5_RXD1	(PIN(7,5) | FUNC(2) | PU)
+#define GPH5_GPIO	(PIN(7,5) | FUNC(0) | PU)
+#define GPH6_TXD2	(PIN(7,6) | FUNC(2) | PU)
+#define GPH6_NRTS1	(PIN(7,6) | FUNC(3) | PU)
+#define GPH6_GPIO	(PIN(7,6) | FUNC(0) | PU)
+#define GPH7_RXD2	(PIN(7,7) | FUNC(2) | PU)
+#define GPH7_NCTS1	(PIN(7,7) | FUNC(3) | PU)
+#define GPH7_GPIO	(PIN(7,7) | FUNC(0) | PU)
+#define GPH8_UEXTCLK	(PIN(7,8) | FUNC(2) | PU)
+#define GPH8_GPIO	(PIN(7,8) | FUNC(0) | PU)
+#define GPH9_CLOCKOUT0	(PIN(7,9) | FUNC(2) | PU)
+#define GPH9_GPIO	(PIN(7,9) | FUNC(0) | PU)
+#define GPH10_CLKOUT1	(PIN(7,10) | FUNC(2) | PU)
+#define GPH10_GPIO	(PIN(7,10) | FUNC(0) | PU)
+
+#ifdef CONFIG_CPU_S3C2440
+/*
+ * Group 1: GPIO 256..287
+ * Used GPIO: 0...12
+ * These pins can also act as GPIO inputs/outputs
+ */
+#define GPJ0_CAMDATA0	(PIN(8,0) | FUNC(2) | PU)
+#define GPJ0_GPIO	(PIN(8,0) | FUNC(0) | PU)
+#define GPJ1_CAMDATA1	(PIN(8,1) | FUNC(2) | PU)
+#define GPJ1_GPIO	(PIN(8,1) | FUNC(0) | PU)
+#define GPJ2_CAMDATA2	(PIN(8,2) | FUNC(2) | PU)
+#define GPJ2_GPIO	(PIN(8,2) | FUNC(0) | PU)
+#define GPJ3_CAMDATA3	(PIN(8,3) | FUNC(2) | PU)
+#define GPJ3_GPIO	(PIN(8,3) | FUNC(0) | PU)
+#define GPJ4_CAMDATA4	(PIN(8,4) | FUNC(2) | PU)
+#define GPJ4_GPIO	(PIN(8,4) | FUNC(0) | PU)
+#define GPJ5_CAMDATA5	(PIN(8,5) | FUNC(2) | PU)
+#define GPJ5_GPIO	(PIN(8,5) | FUNC(0) | PU)
+#define GPJ6_CAMDATA6	(PIN(8,6) | FUNC(2) | PU)
+#define GPJ6_GPIO	(PIN(8,6) | FUNC(0) | PU)
+#define GPJ7_CAMDATA7	(PIN(8,7) | FUNC(2) | PU)
+#define GPJ7_GPIO	(PIN(8,7) | FUNC(0) | PU)
+#define GPJ8_CAMPCLK	(PIN(8,8) | FUNC(2) | PU)
+#define GPJ8_GPIO	(PIN(8,8) | FUNC(0) | PU)
+#define GPJ9_CAMVSYNC	(PIN(8,9) | FUNC(2) | PU)
+#define GPJ9_GPIO	(PIN(8,9) | FUNC(0) | PU)
+#define GPJ10_CAMHREF	(PIN(8,10) | FUNC(2) | PU)
+#define GPJ10_GPIO	(PIN(8,10) | FUNC(0) | PU)
+#define GPJ11_CAMCLKOUT	(PIN(8,11) | FUNC(2) | PU)
+#define GPJ11_GPIO	(PIN(8,11) | FUNC(0) | PU)
+#define GPJ12_CAMRESET	(PIN(8,12) | FUNC(0) | PU)
+#define GPJ12_GPIO	(PIN(8,12) | FUNC(0) | PU)
+
+#endif
+
+#endif /* __MACH_IOMUX_S3C24x0_H */
Index: barebox-2010.10.0/arch/arm/mach-s3c24xx/Makefile
===================================================================
--- barebox-2010.10.0.orig/arch/arm/mach-s3c24xx/Makefile
+++ barebox-2010.10.0/arch/arm/mach-s3c24xx/Makefile
@@ -1,2 +1,2 @@
-obj-y += generic.o
+obj-y += generic.o gpio-s3c24x0.o
 obj-$(CONFIG_S3C24XX_LOW_LEVEL_INIT) += lowlevel-init.o
Index: barebox-2010.10.0/arch/arm/Kconfig
===================================================================
--- barebox-2010.10.0.orig/arch/arm/Kconfig
+++ barebox-2010.10.0/arch/arm/Kconfig
@@ -59,6 +59,7 @@ config ARCH_OMAP
 config ARCH_S3C24xx
 	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
 	select CPU_ARM920T
+	select GENERIC_GPIO
 
 endchoice
 

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 22 04:58:01 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 10:58:01 +0200
Subject: [PATCH] Add some help using the gpio commands at runtime
Message-ID: <201010221058.01249.jbe@pengutronix.de>

From: Juergen Beisert <jbe at pengutronix.de>
Subject: [PATCH] Add some help using the gpio commands at runtime

Last time I used the gpio commands I was somehow confused about the behaviour
of the 'gpio_get_value' command. So, I decided to add some doc for it. Here's
the result.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>

---
 Documentation/commands.dox |    1 
 commands/gpio.c            |   61 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

Index: barebox-2010.10.0/Documentation/commands.dox
===================================================================
--- barebox-2010.10.0.orig/Documentation/commands.dox
+++ barebox-2010.10.0/Documentation/commands.dox
@@ -10,6 +10,7 @@
 @li @subpage edit_command
 @li @subpage erase_command
 @li @subpage export_command
+ at li @subpage gpio_for_users
 @li @subpage tftp_command
 @li @subpage loadenv_command
 @li @subpage mount_command
Index: barebox-2010.10.0/commands/gpio.c
===================================================================
--- barebox-2010.10.0.orig/commands/gpio.c
+++ barebox-2010.10.0/commands/gpio.c
@@ -120,3 +120,64 @@ BAREBOX_CMD_START(gpio_direction_output)
 	BAREBOX_CMD_HELP(cmd_gpio_direction_output_help)
 BAREBOX_CMD_END
 
+/**
+ at page gpio_for_users Runtime GPIO handling
+
+ at section regular_gpio General usage information
+
+These commands are available if the symbol @b CONFIG_GENERIC_GPIO and
+ at b CONFIG_CMD_GPIO are enabled in the Kconfig.
+
+ at note All gpio related commands take a number to identify the pad. This
+number is architecture dependend. There may be no intuitional correlation
+between available pads and the GPIO numbers to be used in the commands. Due
+to this its also possible the numbers change between @b barebox releases.
+
+ at section gpio_dir_out Switch a pad into an output GPIO
+ at verbatim
+gpio_direction_output <gpio_no> <initial_value>
+ at endverbatim
+- @b gpio_no Architecture dependend GPIO number
+- @b initial_value Output value the pad should emit
+
+ at note To avoid glitches on the pad's line, the routines will first setting up
+the pad's value and after that switching the pad itself to output (if the
+silicon is able to do so)
+
+ at note If the pad is already configured into a non GPIO mode (if available)
+this command may fail (silently)
+
+ at section gpio_dir_in Switch a pad into an input GPIO
+ at verbatim
+gpio_direction_input <gpio_no>
+ at endverbatim
+- @b gpio_no Architecture dependend GPIO number
+
+ at note If the pad is already configured into a non GPIO mode (if available)
+this command may fail (silently)
+
+ at section gpio_get_value Read in the value of an GPIO input pad
+ at verbatim
+gpio_get_value <gpio_no>
+ at endverbatim
+
+Reads in the current pad's line value from the given GPIO number. It returns
+the value as a shell return code. There is no visible output at stdout. You
+can check the return value by using "echo $?"
+
+ at note If the return code is not '0' or '1' it's meant as an error code.
+
+ at note If the pad is not configured for GPIO mode this command may fail
+(silently) and returns garbage
+
+ at section gpio_set_value Set a new value to a GPIO output pad
+ at verbatim
+gpio_set_value <gpio_no> <value>
+ at endverbatim
+- @b gpio_no Architecture dependend GPIO number
+- @b value Output value the pad should emit
+
+Sets a new output @b value to the pad with GPIO number @b gpio_no
+
+ at note If the pad is not configured for GPIO mode this command may fail (silently)
+*/

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 22 04:59:29 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 10:59:29 +0200
Subject: [PATCH] Fix a simple typo to less confusing the user
Message-ID: <201010221059.29399.jbe@pengutronix.de>

From: Juergen Beisert <jbe at pengutronix.de>
Subject: Fix a simple typo to less confusing the user

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 commands/gpio.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: barebox-2010.10.0/commands/gpio.c
===================================================================
--- barebox-2010.10.0.orig/commands/gpio.c
+++ barebox-2010.10.0/commands/gpio.c
@@ -37,7 +37,7 @@ static int do_gpio_get_value(struct comm
 }
 
 static const __maybe_unused char cmd_gpio_get_value_help[] =
-"Usage: gpio_set_value <gpio>\n";
+"Usage: gpio_get_value <gpio>\n";
 
 BAREBOX_CMD_START(gpio_get_value)
 	.cmd		= do_gpio_get_value,

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From marc at cpdesign.com.au  Fri Oct 22 08:58:27 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri, 22 Oct 2010 23:58:27 +1100
Subject: [PATCH] Add some help using the gpio commands at runtime
In-Reply-To: <201010221058.01249.jbe@pengutronix.de>
References: <201010221058.01249.jbe@pengutronix.de>
Message-ID: <034801cb71e8$d8d10740$8a7315c0$@cpdesign.com.au>

Hi,

This is a great step for documentation, and a few things I didn't know. 
Thanks for the effort!

Just FYI, some really minor corrections below. (Sorry for being pedantic..
I'm OK if they are ignored :) )

Cheers
Marc

> -----Original Message-----
> From: barebox-bounces at lists.infradead.org [mailto:barebox-
> bounces at lists.infradead.org] On Behalf Of Juergen Beisert
> Sent: Friday, 22 October 2010 7:58 PM
> To: barebox at lists.infradead.org
> Subject: [PATCH] Add some help using the gpio commands at runtime
> 
> From: Juergen Beisert <jbe at pengutronix.de>
> Subject: [PATCH] Add some help using the gpio commands at runtime
> 
> Last time I used the gpio commands I was somehow confused about the
> behaviour of the 'gpio_get_value' command. So, I decided to add some doc
> for it. Here's the result.
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> 
> ---
>  Documentation/commands.dox |    1
>  commands/gpio.c            |   61
> +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 62 insertions(+)
> 
> Index: barebox-2010.10.0/Documentation/commands.dox
> ==========================================================
> =========
> --- barebox-2010.10.0.orig/Documentation/commands.dox
> +++ barebox-2010.10.0/Documentation/commands.dox
> @@ -10,6 +10,7 @@
>  @li @subpage edit_command
>  @li @subpage erase_command
>  @li @subpage export_command
> + at li @subpage gpio_for_users
>  @li @subpage tftp_command
>  @li @subpage loadenv_command
>  @li @subpage mount_command
> Index: barebox-2010.10.0/commands/gpio.c
> ==========================================================
> =========
> --- barebox-2010.10.0.orig/commands/gpio.c
> +++ barebox-2010.10.0/commands/gpio.c
> @@ -120,3 +120,64 @@ BAREBOX_CMD_START(gpio_direction_output)
>  	BAREBOX_CMD_HELP(cmd_gpio_direction_output_help)
>  BAREBOX_CMD_END
> 
> +/**
> + at page gpio_for_users Runtime GPIO handling
> +
> + at section regular_gpio General usage information
> +
> +These commands are available if the symbol @b CONFIG_GENERIC_GPIO
> and
> + at b CONFIG_CMD_GPIO are enabled in the Kconfig.
> +
> + at note All gpio related commands take a number to identify the pad. This
> +number is architecture dependend. There may be no intuitional

s/dependend/dependent

> +correlation between available pads and the GPIO numbers to be used in
> +the commands. Due to this its also possible the numbers change between

s/its/it's

> @b barebox releases.
> +
> + at section gpio_dir_out Switch a pad into an output GPIO @verbatim
> +gpio_direction_output <gpio_no> <initial_value> @endverbatim
> +- @b gpio_no Architecture dependend GPIO number
> +- @b initial_value Output value the pad should emit
> +
> + at note To avoid glitches on the pad's line, the routines will first
> +setting up the pad's value and after that switching the pad itself to
> +output (if the silicon is able to do so)
> +
> + at note If the pad is already configured into a non GPIO mode (if
> +available) this command may fail (silently)
> +
> + at section gpio_dir_in Switch a pad into an input GPIO @verbatim
> +gpio_direction_input <gpio_no> @endverbatim
> +- @b gpio_no Architecture dependend GPIO number
> +
> + at note If the pad is already configured into a non GPIO mode (if
> +available) this command may fail (silently)
> +
> + at section gpio_get_value Read in the value of an GPIO input pad
> + at verbatim gpio_get_value <gpio_no> @endverbatim
> +
> +Reads in the current pad's line value from the given GPIO number. It
> +returns the value as a shell return code. There is no visible output at
> +stdout. You can check the return value by using "echo $?"
> +
> + at note If the return code is not '0' or '1' it's meant as an error code.
> +
> + at note If the pad is not configured for GPIO mode this command may fail
> +(silently) and returns garbage
> +
> + at section gpio_set_value Set a new value to a GPIO output pad @verbatim
> +gpio_set_value <gpio_no> <value> @endverbatim
> +- @b gpio_no Architecture dependend GPIO number

s/dependend/dependent


> +- @b value Output value the pad should emit
> +
> +Sets a new output @b value to the pad with GPIO number @b gpio_no
> +
> + at note If the pad is not configured for GPIO mode this command may fail
> +(silently) */
> 
> --
> Pengutronix e.K.                              | Juergen Beisert
|
> Linux Solutions for Science and Industry      | Phone: +49-8766-939 228
|
> Vertretung Sued/Muenchen, Germany             | Fax:
+49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/
|
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox



From s.hauer at pengutronix.de  Fri Oct 22 09:15:19 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:19 +0200
Subject: [PATCH 01/13] ARM pca100: Use a flash bbt
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/phycard-i.MX27/pca100.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/phycard-i.MX27/pca100.c b/arch/arm/boards/phycard-i.MX27/pca100.c
index 7460c00..3a96180 100644
--- a/arch/arm/boards/phycard-i.MX27/pca100.c
+++ b/arch/arm/boards/phycard-i.MX27/pca100.c
@@ -68,6 +68,7 @@ static struct device_d fec_dev = {
 struct imx_nand_platform_data nand_info = {
 	.width = 1,
 	.hw_ecc = 1,
+	.flash_bbt = 1,
 };
 
 static struct device_d nand_dev = {
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:18 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:18 +0200
Subject: more patches for next
Message-ID: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>


The following changes since commit 298252bdef6a97d988f83f5ea554a2262c529ae2:

  process_escape_sequence: Add missing include (2010-10-21 22:21:42 +0200)

are available in the git repository at:
  git://git.pengutronix.de/git/barebox.git pu

Sascha Hauer (13):
      ARM pca100: Use a flash bbt
      i.MX nand: optimize nand boot code for size
      mci-core: add multiple block support
      i.MX51: Fix mmcclk rate
      i.MX esdctl: Add register bits from redboot
      i.MX35 regs: Add watchdog base
      fb: i.MX IPU: remove unnecessary printf
      fb: i.MX IPU: move fb_info initialization to a single function
      fb: i.MX IPU: fold mx3fb_set_par into its only user
      mci: align data for commands
      ARM: Add Garz+Fricke Cupid board support
      defaultenv: fix mtdparts
      ARM: Add defconfig for Garz+Fricke cupid board

 arch/arm/Makefile                           |    1 +
 arch/arm/boards/guf-cupid/Makefile          |   24 ++
 arch/arm/boards/guf-cupid/board.c           |  426 +++++++++++++++++++++++++++
 arch/arm/boards/guf-cupid/config.h          |   31 ++
 arch/arm/boards/guf-cupid/cupid.dox         |    9 +
 arch/arm/boards/guf-cupid/env/config        |   56 ++++
 arch/arm/boards/guf-cupid/lowlevel.c        |  349 ++++++++++++++++++++++
 arch/arm/boards/phycard-i.MX27/pca100.c     |    1 +
 arch/arm/configs/cupid_defconfig            |   56 ++++
 arch/arm/mach-imx/Kconfig                   |   11 +
 arch/arm/mach-imx/include/mach/esdctl.h     |   88 ++++++
 arch/arm/mach-imx/include/mach/imx35-regs.h |    1 +
 arch/arm/mach-imx/speed-imx51.c             |   33 ++-
 defaultenv/bin/boot                         |    2 +-
 drivers/mci/mci-core.c                      |   47 ++-
 drivers/mtd/nand/Kconfig                    |   16 +
 drivers/mtd/nand/nand_imx.c                 |  196 +++++++++----
 drivers/video/imx-ipu-fb.c                  |   92 +++----
 18 files changed, 1307 insertions(+), 132 deletions(-)
 create mode 100644 arch/arm/boards/guf-cupid/Makefile
 create mode 100644 arch/arm/boards/guf-cupid/board.c
 create mode 100644 arch/arm/boards/guf-cupid/config.h
 create mode 100644 arch/arm/boards/guf-cupid/cupid.dox
 create mode 100644 arch/arm/boards/guf-cupid/env/config
 create mode 100644 arch/arm/boards/guf-cupid/lowlevel.c
 create mode 100644 arch/arm/configs/cupid_defconfig


From s.hauer at pengutronix.de  Fri Oct 22 09:15:24 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:24 +0200
Subject: [PATCH 06/13] i.MX35 regs: Add watchdog base
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-7-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/imx35-regs.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h
index b0f6b82..89ca7ea 100644
--- a/arch/arm/mach-imx/include/mach/imx35-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
@@ -52,6 +52,7 @@
 #define IMX_SDHC2_BASE		0x53FB8000
 #define IMX_SDHC3_BASE		0x53FBC000
 #define IMX_OTG_BASE		0x53FF4000
+#define IMX_WDOG_BASE		0x53fdc000
 
 /*
  * Clock Controller Module (CCM)
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:21 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:21 +0200
Subject: [PATCH 03/13] mci-core: add multiple block support
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-4-git-send-email-s.hauer@pengutronix.de>

So far only for reading blocks. This is based on the corresponding
U-Boot code.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/mci-core.c |   35 +++++++++++++++++++++++++++--------
 1 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index c92d5a9..34c4f8c 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -139,23 +139,41 @@ static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned b
  * @param dst Where to store the data read from the card
  * @param blocknum Block number to read
  */
-static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned blocknum)
+static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned blocknum, int blocks)
 {
 	struct mci *mci = GET_MCI_DATA(mci_dev);
 	struct mci_cmd cmd;
 	struct mci_data data;
+	int ret;
+	unsigned mmccmd;
+
+	if (blocks > 1)
+		mmccmd = MMC_CMD_READ_MULTIPLE_BLOCK;
+	else
+		mmccmd = MMC_CMD_READ_SINGLE_BLOCK;
 
 	mci_setup_cmd(&cmd,
-		MMC_CMD_READ_SINGLE_BLOCK,
+		mmccmd,
 		mci->high_capacity != 0 ? blocknum : blocknum * mci->read_bl_len,
 		MMC_RSP_R1);
 
 	data.dest = dst;
-	data.blocks = 1;
+	data.blocks = blocks;
 	data.blocksize = mci->read_bl_len;
 	data.flags = MMC_DATA_READ;
 
-	return mci_send_cmd(mci_dev, &cmd, &data);
+	ret = mci_send_cmd(mci_dev, &cmd, &data);
+	if (ret)
+		return ret;
+
+	if (blocks > 1) {
+		mci_setup_cmd(&cmd,
+			MMC_CMD_STOP_TRANSMISSION,
+			0,
+			MMC_RSP_R1b);
+			ret = mci_send_cmd(mci_dev, &cmd, NULL);
+	}
+	return ret;
 }
 
 /**
@@ -979,19 +997,20 @@ static int mci_sd_read(struct device_d *disk_dev, uint64_t sector_start,
 	}
 
 	while (sector_count) {
+		int now = min(sector_count, 32);
 		if (sector_start > MAX_BUFFER_NUMBER) {
 			pr_err("Cannot handle block number %lu. Too large!\n",
 				(unsigned)sector_start);
 			return -EINVAL;
 		}
-		rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start);
+		rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start, now);
 		if (rc != 0) {
 			pr_err("Reading block %lu failed with %d\n", (unsigned)sector_start, rc);
 			return rc;
 		}
-		sector_count--;
-		buffer += mci->read_bl_len;
-		sector_start++;
+		sector_count -= now;
+		buffer += mci->read_bl_len * now;
+		sector_start += now;
 	}
 
 	return 0;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:22 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:22 +0200
Subject: [PATCH 04/13] i.MX51: Fix mmcclk rate
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-5-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/speed-imx51.c |   33 ++++++++++++++++++++++++++++++---
 1 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-imx/speed-imx51.c b/arch/arm/mach-imx/speed-imx51.c
index dcfc874..9983297 100644
--- a/arch/arm/mach-imx/speed-imx51.c
+++ b/arch/arm/mach-imx/speed-imx51.c
@@ -90,6 +90,26 @@ static unsigned long pll3_sw_get_rate(void)
 	return pll_get_rate((void __iomem *)MX51_PLL3_BASE_ADDR);
 }
 
+static unsigned long get_rate_select(int select,
+	unsigned long (* get_rate1)(void),
+	unsigned long (* get_rate2)(void),
+	unsigned long (* get_rate3)(void),
+	unsigned long (* get_rate4)(void))
+{
+	switch (select) {
+	case 0:
+		return get_rate1() ? get_rate1() : 0;
+	case 1:
+		return get_rate2() ? get_rate2() : 0;
+	case 2:
+		return get_rate3 ? get_rate3() : 0;
+	case 3:
+		return get_rate4 ? get_rate4() : 0;
+	}
+
+	return 0;
+}
+
 unsigned long imx_get_uartclk(void)
 {
 	u32 reg, prediv, podf;
@@ -140,15 +160,22 @@ unsigned long imx_get_mmcclk(void)
 {
 	u32 reg, prediv, podf, rate;
 
+	reg = ccm_readl(MX51_CCM_CSCMR1);
+	reg &= MX51_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK;
+	reg >>= MX51_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET;
+	rate = get_rate_select(reg,
+			pll1_main_get_rate,
+			pll2_sw_get_rate,
+			pll3_sw_get_rate,
+			NULL);
+
 	reg = ccm_readl(MX51_CCM_CSCDR1);
 	prediv = ((reg & MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) >>
 			MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET) + 1;
 	podf = ((reg & MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) >>
 			MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET) + 1;
 
-	rate = pll2_sw_get_rate() / (prediv * podf);
-
-	return rate;
+	return rate / (prediv * podf);
 }
 
 void imx_dump_clocks(void)
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:25 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:25 +0200
Subject: [PATCH 07/13] fb: i.MX IPU: remove unnecessary printf
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-8-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/video/imx-ipu-fb.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
index 2c25b81..399af75 100644
--- a/drivers/video/imx-ipu-fb.c
+++ b/drivers/video/imx-ipu-fb.c
@@ -840,8 +840,6 @@ static void ipu_fb_disable(struct fb_info *info)
 	struct ipu_fb_info *fbi = info->priv;
 	u32 reg;
 
-	printf("%s\n", __func__);
-
 	if (fbi->enable)
 		fbi->enable(0);
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:30 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:30 +0200
Subject: [PATCH 12/13] defaultenv: fix mtdparts
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-13-git-send-email-s.hauer@pengutronix.de>

We had some \" in mtdparts to allow for spaces in the mtdparts
kernel option. Barebox does not handle these correctly, so remove
them and disallow spaces in mtdparts

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 defaultenv/bin/boot |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/defaultenv/bin/boot b/defaultenv/bin/boot
index 3fdc5c1..42c7ec2 100644
--- a/defaultenv/bin/boot
+++ b/defaultenv/bin/boot
@@ -51,7 +51,7 @@ if [ -n $nand_parts ]; then
 fi
 
 if [ -n $mtdparts ]; then
-	bootargs="${bootargs} mtdparts=\"${mtdparts}\""
+	bootargs="${bootargs} mtdparts=${mtdparts}"
 fi
 
 if [ ! -e /dev/ram0.kernelraw ]; then
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:28 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:28 +0200
Subject: [PATCH 10/13] mci: align data for commands
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-11-git-send-email-s.hauer@pengutronix.de>

Some mci controllers cannot transfer data with their DMA engines
if the data is not sufficiently aligned. Normally this is a driver
problem, but hey, we have no problem aligning the data and keep
the burden from the drivers.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/mci-core.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 34c4f8c..6f31cca 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -347,7 +347,7 @@ static int mci_switch(struct device_d *mci_dev, unsigned set, unsigned index,
 static int mmc_change_freq(struct device_d *mci_dev)
 {
 	struct mci *mci = GET_MCI_DATA(mci_dev);
-	char ext_csd[512];
+	char *ext_csd = sector_buf;
 	char cardtype;
 	int err;
 
@@ -439,8 +439,8 @@ static int sd_change_freq(struct device_d *mci_dev)
 	struct mci *mci = GET_MCI_DATA(mci_dev);
 	struct mci_cmd cmd;
 	struct mci_data data;
-	uint32_t switch_status[16];
-	uint scr[2];
+	uint32_t *switch_status = sector_buf;
+	uint32_t *scr = sector_buf;
 	int timeout;
 	int err;
 
@@ -461,7 +461,7 @@ static int sd_change_freq(struct device_d *mci_dev)
 
 retry_scr:
 	pr_debug("Trying to read the SCR (try %d of %d)\n", 4 - timeout, 3);
-	data.dest = (char *)&scr;
+	data.dest = (char *)scr;
 	data.blocksize = 8;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
@@ -502,7 +502,7 @@ retry_scr:
 	timeout = 4;
 	while (timeout--) {
 		err = sd_switch(mci_dev, SD_SWITCH_CHECK, 0, 1,
-				(uint8_t*)&switch_status);
+				(uint8_t*)switch_status);
 		if (err) {
 			pr_debug("Checking SD transfer switch frequency feature failed: %d\n", err);
 			return err;
@@ -520,7 +520,7 @@ retry_scr:
 	if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
 		return 0;
 
-	err = sd_switch(mci_dev, SD_SWITCH_SWITCH, 0, 1, (uint8_t*)&switch_status);
+	err = sd_switch(mci_dev, SD_SWITCH_SWITCH, 0, 1, (uint8_t*)switch_status);
 	if (err) {
 		pr_debug("Switching SD transfer frequency failed: %d\n", err);
 		return err;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:27 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:27 +0200
Subject: [PATCH 09/13] fb: i.MX IPU: fold mx3fb_set_par into its only user
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-10-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/video/imx-ipu-fb.c |   27 +++++----------------------
 1 files changed, 5 insertions(+), 22 deletions(-)

diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
index 08036aa..c38082d 100644
--- a/drivers/video/imx-ipu-fb.c
+++ b/drivers/video/imx-ipu-fb.c
@@ -722,31 +722,11 @@ static void sdc_enable_channel(struct ipu_fb_info *fbi, void *fbmem)
 	mdelay(2);
 }
 
-/*
- * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
- * @return:	0 on success or negative error code on failure.
- */
-static int mx3fb_set_par(struct fb_info *info)
-{
-	struct ipu_fb_info *fbi = info->priv;
-	struct fb_videomode *mode = info->mode;
-	int ret;
-
-	ret = sdc_init_panel(info, IPU_PIX_FMT_RGB666);
-	if (ret < 0)
-		return ret;
-
-	reg_write(fbi, (mode->left_margin << 16) | mode->upper_margin,
-			SDC_BG_POS);
-
-	return 0;
-}
-
 /* References in this function refer to respective Linux kernel sources */
 static void ipu_fb_enable(struct fb_info *info)
 {
 	struct ipu_fb_info *fbi = info->priv;
-
+	struct fb_videomode *mode = info->mode;
 	u32 reg;
 
 	/* pcm037.c::mxc_board_init() */
@@ -799,7 +779,10 @@ static void ipu_fb_enable(struct fb_info *info)
 		~(SDC_COM_GWSEL | SDC_COM_KEY_COLOR_G);
 	reg_write(fbi, reg, SDC_COM_CONF);
 
-	mx3fb_set_par(info);
+	sdc_init_panel(info, IPU_PIX_FMT_RGB666);
+
+	reg_write(fbi, (mode->left_margin << 16) | mode->upper_margin,
+			SDC_BG_POS);
 
 	sdc_enable_channel(fbi, info->screen_base);
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:20 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:20 +0200
Subject: [PATCH 02/13] i.MX nand: optimize nand boot code for size
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-3-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/Kconfig    |   16 ++++
 drivers/mtd/nand/nand_imx.c |  196 +++++++++++++++++++++++++++++--------------
 2 files changed, 150 insertions(+), 62 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 475499a..bc95195 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -18,6 +18,22 @@ config NAND_IMX_BOOT
 	prompt "Support Starting barebox from NAND"
 	depends on NAND_IMX || NAND_IMX_V2
 
+choice
+	depends on NAND_IMX_BOOT
+	default NAND_IMX_BOOT_512_2K
+	prompt "select nand pagesize you want to support booting from"
+
+config NAND_IMX_BOOT_512
+	bool "512 byte page size"
+
+config NAND_IMX_BOOT_2K
+	bool "2048 byte page size"
+
+config NAND_IMX_BOOT_512_2K
+	bool "512 byte and 2048 byte pagesize"
+
+endchoice
+
 config NAND_OMAP_GPMC
 	tristate "NAND Flash Support for GPMC based OMAP platforms"
 	depends on ((ARCH_OMAP2 || ARCH_OMAP3) && GPMC)
diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index 5454e32..63ba188 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -222,7 +222,7 @@ static void memcpy32(void *trg, const void *src, int size)
  * @param       max_retries     number of retry attempts (separated by 1 us)
  * @param       param           parameter for debug
  */
-static void __nand_boot_init wait_op_done(struct imx_nand_host *host)
+static void wait_op_done(struct imx_nand_host *host)
 {
 	u32 tmp;
 	int i;
@@ -247,7 +247,7 @@ static void __nand_boot_init wait_op_done(struct imx_nand_host *host)
  *
  * @param       cmd     command for NAND Flash
  */
-static void __nand_boot_init send_cmd(struct imx_nand_host *host, u16 cmd)
+static void send_cmd(struct imx_nand_host *host, u16 cmd)
 {
 	MTD_DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd);
 
@@ -276,7 +276,7 @@ static void __nand_boot_init send_cmd(struct imx_nand_host *host, u16 cmd)
  * @param       addr    address to be written to NFC.
  * @param       islast  True if this is the last address cycle for command
  */
-static void __nand_boot_init noinline send_addr(struct imx_nand_host *host, u16 addr)
+static void send_addr(struct imx_nand_host *host, u16 addr)
 {
 	MTD_DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
 
@@ -294,7 +294,7 @@ static void __nand_boot_init noinline send_addr(struct imx_nand_host *host, u16
  * @param	buf_id	      Specify Internal RAM Buffer number (0-3)
  * @param       spare_only    set true if only the spare area is transferred
  */
-static void __nand_boot_init send_page(struct imx_nand_host *host,
+static void send_page(struct imx_nand_host *host,
 		unsigned int ops)
 {
 	int bufs, i;
@@ -1013,20 +1013,87 @@ static struct driver_d imx_nand_driver = {
 };
 
 #ifdef CONFIG_NAND_IMX_BOOT
+static void __nand_boot_init noinline imx_nandboot_wait_op_done(void *regs)
+{
+	u32 r;
+
+	while (1) {
+		r = readw(regs + NFC_CONFIG2);
+		if (r & NFC_INT)
+			break;
+	};
+
+	r &= ~NFC_INT;
+
+	writew(r, regs + NFC_CONFIG2);
+}
+
+/*
+ * This function issues the specified command to the NAND device and
+ * waits for completion.
+ *
+ * @param       cmd     command for NAND Flash
+ */
+static void __nand_boot_init imx_nandboot_send_cmd(void *regs, u16 cmd)
+{
+	writew(cmd, regs + NFC_FLASH_CMD);
+	writew(NFC_CMD, regs + NFC_CONFIG2);
+
+	imx_nandboot_wait_op_done(regs);
+}
+
+/*
+ * This function sends an address (or partial address) to the
+ * NAND device.  The address is used to select the source/destination for
+ * a NAND command.
+ *
+ * @param       addr    address to be written to NFC.
+ * @param       islast  True if this is the last address cycle for command
+ */
+static void __nand_boot_init noinline imx_nandboot_send_addr(void *regs, u16 addr)
+{
+	writew(addr, regs + NFC_FLASH_ADDR);
+	writew(NFC_ADDR, regs + NFC_CONFIG2);
+
+	/* Wait for operation to complete */
+	imx_nandboot_wait_op_done(regs);
+}
 
-static void __nand_boot_init nfc_addr(struct imx_nand_host *host, u32 offs)
+static void __nand_boot_init imx_nandboot_nfc_addr(void *regs, u32 offs, int pagesize_2k)
 {
-	if (host->pagesize_2k) {
-		send_addr(host, offs & 0xff);
-		send_addr(host, offs & 0xff);
-		send_addr(host, (offs >> 11) & 0xff);
-		send_addr(host, (offs >> 19) & 0xff);
-		send_addr(host, (offs >> 27) & 0xff);
+	imx_nandboot_send_addr(regs, offs & 0xff);
+
+	if (pagesize_2k) {
+		imx_nandboot_send_addr(regs, offs & 0xff);
+		imx_nandboot_send_addr(regs, (offs >> 11) & 0xff);
+		imx_nandboot_send_addr(regs, (offs >> 19) & 0xff);
+		imx_nandboot_send_addr(regs, (offs >> 27) & 0xff);
+		imx_nandboot_send_cmd(regs, NAND_CMD_READSTART);
 	} else {
-		send_addr(host, offs & 0xff);
-		send_addr(host, (offs >> 9) & 0xff);
-		send_addr(host, (offs >> 17) & 0xff);
-		send_addr(host, (offs >> 25) & 0xff);
+		imx_nandboot_send_addr(regs, (offs >> 9) & 0xff);
+		imx_nandboot_send_addr(regs, (offs >> 17) & 0xff);
+		imx_nandboot_send_addr(regs, (offs >> 25) & 0xff);
+	}
+}
+
+static void __nand_boot_init imx_nandboot_send_page(void *regs,
+		unsigned int ops, int pagesize_2k)
+{
+	int bufs, i;
+
+	if (nfc_is_v1() && pagesize_2k)
+		bufs = 4;
+	else
+		bufs = 1;
+
+	for (i = 0; i < bufs; i++) {
+		/* NANDFC buffer 0 is used for page read/write */
+		writew(i, regs + NFC_BUF_ADDR);
+
+		writew(ops, regs + NFC_CONFIG2);
+
+		/* Wait for operation to complete */
+		imx_nandboot_wait_op_done(regs);
 	}
 }
 
@@ -1040,38 +1107,49 @@ static void __nand_boot_init __memcpy32(void *trg, const void *src, int size)
 		*t++ = *s++;
 }
 
-void __nand_boot_init imx_nand_load_image(void *dest, int size)
+static int __maybe_unused is_pagesize_2k(void)
 {
-	struct imx_nand_host host;
-	u32 tmp, page, block, blocksize, pagesize;
 #ifdef CONFIG_ARCH_IMX21
-	tmp = readl(IMX_SYSTEM_CTL_BASE + 0x14);
-	if (tmp & (1 << 5))
-		host.pagesize_2k = 1;
+	if (readl(IMX_SYSTEM_CTL_BASE + 0x14) & (1 << 5))
+		return 1;
 	else
-		host.pagesize_2k = 0;
+		return 0;
 #endif
 #ifdef CONFIG_ARCH_IMX27
-	tmp = readl(IMX_SYSTEM_CTL_BASE + 0x14);
-	if (tmp & (1 << 5))
-		host.pagesize_2k = 1;
+	if (readl(IMX_SYSTEM_CTL_BASE + 0x14) & (1 << 5))
+		return 1;
 	else
-		host.pagesize_2k = 0;
+		return 0;
 #endif
 #ifdef CONFIG_ARCH_IMX31
-	tmp = readl(IMX_CCM_BASE + CCM_RCSR);
-	if (tmp & RCSR_NFMS)
-		host.pagesize_2k = 1;
+	if (readl(IMX_CCM_BASE + CCM_RCSR) & RCSR_NFMS)
+		return 1;
 	else
-		host.pagesize_2k = 0;
+		return 0;
 #endif
 #if defined(CONFIG_ARCH_IMX35) || defined(CONFIG_ARCH_IMX25)
 	if (readl(IMX_CCM_BASE + CCM_RCSR) & (1 << 8))
-		host.pagesize_2k = 1;
+		return 1;
 	else
-		host.pagesize_2k = 0;
+		return 0;
+#endif
+}
+
+void __nand_boot_init imx_nand_load_image(void *dest, int size)
+{
+	u32 tmp, page, block, blocksize, pagesize;
+	int pagesize_2k = 1;
+	void *regs, *base, *spare0;
+
+#if defined(CONFIG_NAND_IMX_BOOT_512)
+	pagesize_2k = 0;
+#elif defined(CONFIG_NAND_IMX_BOOT_2K)
+	pagesize_2k = 1;
+#else
+	pagesize_2k = is_pagesize_2k();
 #endif
-	if (host.pagesize_2k) {
+
+	if (pagesize_2k) {
 		pagesize = 2048;
 		blocksize = 128 * 1024;
 	} else {
@@ -1079,45 +1157,43 @@ void __nand_boot_init imx_nand_load_image(void *dest, int size)
 		blocksize = 16 * 1024;
 	}
 
-	host.base = (void __iomem *)IMX_NFC_BASE;
+	base = (void __iomem *)IMX_NFC_BASE;
 	if (nfc_is_v21()) {
-		host.regs = host.base + 0x1000;
-		host.spare0 = host.base + 0x1000;
-		host.spare_len = 64;
+		regs = base + 0x1000;
+		spare0 = base + 0x1000;
 	} else if (nfc_is_v1()) {
-		host.regs = host.base;
-		host.spare0 = host.base + 0x800;
-		host.spare_len = 16;
+		regs = base;
+		spare0 = base + 0x800;
 	}
 
-	send_cmd(&host, NAND_CMD_RESET);
+	imx_nandboot_send_cmd(regs, NAND_CMD_RESET);
 
 	/* preset operation */
 	/* Unlock the internal RAM Buffer */
-	writew(0x2, host.regs + NFC_CONFIG);
+	writew(0x2, regs + NFC_CONFIG);
 
 	/* Unlock Block Command for given address range */
-	writew(0x4, host.regs + NFC_WRPROT);
+	writew(0x4, regs + NFC_WRPROT);
 
-	tmp = readw(host.regs + NFC_CONFIG1);
+	tmp = readw(regs + NFC_CONFIG1);
 	tmp |= NFC_ECC_EN;
 	if (nfc_is_v21())
 		/* currently no support for 218 byte OOB with stronger ECC */
 		tmp |= NFC_ECC_MODE;
 	tmp &= ~(NFC_SP_EN | NFC_INT_MSK);
-	writew(tmp, host.regs + NFC_CONFIG1);
+	writew(tmp, regs + NFC_CONFIG1);
 
 	if (nfc_is_v21()) {
-		if (host.pagesize_2k) {
-			tmp = readw(host.regs + NFC_SPAS);
+		if (pagesize_2k) {
+			tmp = readw(regs + NFC_SPAS);
 			tmp &= 0xff00;
 			tmp |= NFC_SPAS_64;
-			writew(tmp, host.regs + NFC_SPAS);
+			writew(tmp, regs + NFC_SPAS);
 		} else {
-			tmp = readw(host.regs + NFC_SPAS);
+			tmp = readw(regs + NFC_SPAS);
 			tmp &= 0xff00;
 			tmp |= NFC_SPAS_16;
-			writew(tmp, host.regs + NFC_SPAS);
+			writew(tmp, regs + NFC_SPAS);
 		}
 	}
 
@@ -1132,25 +1208,21 @@ void __nand_boot_init imx_nand_load_image(void *dest, int size)
 					block * blocksize +
 					page * pagesize);
 
-			send_cmd(&host, NAND_CMD_READ0);
-			nfc_addr(&host, block * blocksize +
-					page * pagesize);
-			if (host.pagesize_2k)
-				send_cmd(&host, NAND_CMD_READSTART);
-			send_page(&host, NFC_OUTPUT);
+			imx_nandboot_send_cmd(regs, NAND_CMD_READ0);
+			imx_nandboot_nfc_addr(regs, block * blocksize +
+					page * pagesize, pagesize_2k);
+			imx_nandboot_send_page(regs, NFC_OUTPUT, pagesize_2k);
 			page++;
 
-			if (host.pagesize_2k) {
-				if ((readw(host.spare0) & 0xff)
-						!= 0xff)
+			if (pagesize_2k) {
+				if ((readw(spare0) & 0xff) != 0xff)
 					continue;
 			} else {
-				if ((readw(host.spare0 + 4) & 0xff00)
-						!= 0xff00)
+				if ((readw(spare0 + 4) & 0xff00) != 0xff00)
 					continue;
 			}
 
-			__memcpy32(dest, host.base, pagesize);
+			__memcpy32(dest, base, pagesize);
 			dest += pagesize;
 			size -= pagesize;
 
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:31 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:31 +0200
Subject: [PATCH 13/13] ARM: Add defconfig for Garz+Fricke cupid board
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-14-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/configs/cupid_defconfig |   56 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/configs/cupid_defconfig

diff --git a/arch/arm/configs/cupid_defconfig b/arch/arm/configs/cupid_defconfig
new file mode 100644
index 0000000..e24afe1
--- /dev/null
+++ b/arch/arm/configs/cupid_defconfig
@@ -0,0 +1,56 @@
+CONFIG_ARCH_IMX=y
+CONFIG_CACHE_L2X0=y
+CONFIG_ARCH_IMX35=y
+CONFIG_MACH_GUF_CUPID=y
+CONFIG_IMX_CLKO=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_TEXT_BASE=0x87F00000
+CONFIG_MALLOC_SIZE=0x1000000
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/guf-cupid/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_UNLZO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_IMX=y
+CONFIG_NAND_IMX_BOOT=y
+CONFIG_NAND_IMX_BOOT_2K=y
+CONFIG_UBI=y
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_IMX_IPU=y
+CONFIG_MCI=y
+CONFIG_MCI_IMX_ESDHC=y
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:26 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:26 +0200
Subject: [PATCH 08/13] fb: i.MX IPU: move fb_info initialization to a single
	function
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-9-git-send-email-s.hauer@pengutronix.de>

The bitfield information was only added to fb_info when the
framebuffer actually was enabled. That made it impossible to
call 'bmp' before enabling the display.
So, move all fb_info init to a single place and make it a function
to better allow for multiple displays later.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/video/imx-ipu-fb.c |   63 ++++++++++++++++++++++++-------------------
 1 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
index 399af75..08036aa 100644
--- a/drivers/video/imx-ipu-fb.c
+++ b/drivers/video/imx-ipu-fb.c
@@ -729,7 +729,6 @@ static void sdc_enable_channel(struct ipu_fb_info *fbi, void *fbmem)
 static int mx3fb_set_par(struct fb_info *info)
 {
 	struct ipu_fb_info *fbi = info->priv;
-	struct imx_ipu_fb_rgb *rgb;
 	struct fb_videomode *mode = info->mode;
 	int ret;
 
@@ -740,29 +739,6 @@ static int mx3fb_set_par(struct fb_info *info)
 	reg_write(fbi, (mode->left_margin << 16) | mode->upper_margin,
 			SDC_BG_POS);
 
-	switch (info->bits_per_pixel) {
-	case 32:
-		rgb = &def_rgb_32;
-		break;
-	case 24:
-		rgb = &def_rgb_24;
-		break;
-	case 16:
-	default:
-		rgb = &def_rgb_16;
-		break;
-	}
-
-	/*
-	 * Copy the RGB parameters for this display
-	 * from the machine specific parameters.
-	 */
-	info->red    = rgb->red;
-	info->green  = rgb->green;
-	info->blue   = rgb->blue;
-	info->transp = rgb->transp;
-
-
 	return 0;
 }
 
@@ -853,6 +829,39 @@ static struct fb_ops imxfb_ops = {
 	.fb_disable = ipu_fb_disable,
 };
 
+static void imxfb_init_info(struct fb_info *info, struct fb_videomode *mode,
+		int bpp)
+{
+	struct imx_ipu_fb_rgb *rgb;
+
+	info->mode = mode;
+	info->xres = mode->xres;
+	info->yres = mode->yres;
+	info->bits_per_pixel = bpp;
+
+	switch (info->bits_per_pixel) {
+	case 32:
+		rgb = &def_rgb_32;
+		break;
+	case 24:
+		rgb = &def_rgb_24;
+		break;
+	case 16:
+	default:
+		rgb = &def_rgb_16;
+		break;
+	}
+
+	/*
+	 * Copy the RGB parameters for this display
+	 * from the machine specific parameters.
+	 */
+	info->red    = rgb->red;
+	info->green  = rgb->green;
+	info->blue   = rgb->blue;
+	info->transp = rgb->transp;
+}
+
 static int imxfb_probe(struct device_d *dev)
 {
 	struct ipu_fb_info *fbi;
@@ -869,13 +878,11 @@ static int imxfb_probe(struct device_d *dev)
 	fbi->regs = (void *)dev->map_base;
 	fbi->dev = dev;
 	info->priv = fbi;
-	info->mode = pdata->mode;
-	info->xres = pdata->mode->xres;
-	info->yres = pdata->mode->yres;
-	info->bits_per_pixel = pdata->bpp;
 	info->fbops = &imxfb_ops;
 	fbi->enable = pdata->enable;
 
+	imxfb_init_info(info, pdata->mode, pdata->bpp);
+
 	dev_info(dev, "i.MX Framebuffer driver\n");
 
 	/*
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:23 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:23 +0200
Subject: [PATCH 05/13] i.MX esdctl: Add register bits from redboot
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-6-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/esdctl.h |   88 +++++++++++++++++++++++++++++++
 1 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h
index d15f52b..fe74cb6 100644
--- a/arch/arm/mach-imx/include/mach/esdctl.h
+++ b/arch/arm/mach-imx/include/mach/esdctl.h
@@ -18,9 +18,11 @@
 #define ESDCTL0_ROW13				(2 << 24)
 #define ESDCTL0_ROW14				(3 << 24)
 #define ESDCTL0_ROW15				(4 << 24)
+#define ESDCTL0_ROW_MASK			(7 << 24)
 #define ESDCTL0_COL8				(0 << 20)
 #define ESDCTL0_COL9				(1 << 20)
 #define ESDCTL0_COL10				(2 << 20)
+#define ESDCTL0_COL_MASK			(3 << 20)
 #define ESDCTL0_DSIZ_31_16			(0 << 16)
 #define ESDCTL0_DSIZ_15_0			(1 << 16)
 #define ESDCTL0_DSIZ_31_0			(2 << 16)
@@ -32,3 +34,89 @@
 #define ESDCTL0_FP				(1 << 8)
 #define ESDCTL0_BL				(1 << 7)
 
+#define ESDMISC_RST			0x00000002
+#define ESDMISC_MDDR_EN			0x00000004
+#define ESDMISC_MDDR_DIS		0x00000000
+#define ESDMISC_MDDR_DL_RST		0x00000008
+#define ESDMISC_MDDR_MDIS		0x00000010
+#define ESDMISC_LHD			0x00000020
+#define ESDMISC_SDRAMRDY		0x80000000
+
+#define	ESDCFGx_tXP_MASK 		0x00600000
+#define ESDCFGx_tXP_1			0x00000000
+#define ESDCFGx_tXP_2			0x00200000
+#define ESDCFGx_tXP_3			0x00400000
+#define ESDCFGx_tXP_4			0x00600000
+
+#define ESDCFGx_tWTR_MASK		0x00100000
+#define ESDCFGx_tWTR_1			0x00000000
+#define ESDCFGx_tWTR_2			0x00100000
+
+#define ESDCFGx_tRP_MASK		0x000c0000
+#define ESDCFGx_tRP_1			0x00000000
+#define ESDCFGx_tRP_2			0x00040000
+#define ESDCFGx_tRP_3			0x00080000
+#define ESDCFGx_tRP_4			0x000c0000
+
+
+#define ESDCFGx_tMRD_MASK		0x00030000
+#define ESDCFGx_tMRD_1			0x00000000
+#define ESDCFGx_tMRD_2			0x00010000
+#define ESDCFGx_tMRD_3			0x00020000
+#define ESDCFGx_tMRD_4			0x00030000
+
+
+#define ESDCFGx_tWR_MASK		0x00008000
+#define ESDCFGx_tWR_1_2			0x00000000
+#define ESDCFGx_tWR_2_3			0x00008000
+
+#define ESDCFGx_tRAS_MASK		0x00007000
+#define ESDCFGx_tRAS_1			0x00000000
+#define ESDCFGx_tRAS_2			0x00001000
+#define ESDCFGx_tRAS_3			0x00002000
+#define ESDCFGx_tRAS_4			0x00003000
+#define ESDCFGx_tRAS_5			0x00004000
+#define ESDCFGx_tRAS_6			0x00005000
+#define ESDCFGx_tRAS_7			0x00006000
+#define ESDCFGx_tRAS_8			0x00007000
+
+
+#define ESDCFGx_tRRD_MASK		0x00000c00
+#define ESDCFGx_tRRD_1			0x00000000
+#define ESDCFGx_tRRD_2			0x00000400
+#define ESDCFGx_tRRD_3			0x00000800
+#define ESDCFGx_tRRD_4			0x00000c00
+
+
+#define ESDCFGx_tCAS_MASK		0x00000300
+#define ESDCFGx_tCAS_2			0x00000200
+#define ESDCFGx_tCAS_3			0x00000300
+
+#define ESDCFGx_tRCD_MASK		0x00000070
+#define ESDCFGx_tRCD_1			0x00000000
+#define ESDCFGx_tRCD_2			0x00000010
+#define ESDCFGx_tRCD_3			0x00000020
+#define ESDCFGx_tRCD_4			0x00000030
+#define ESDCFGx_tRCD_5			0x00000040
+#define ESDCFGx_tRCD_6			0x00000050
+#define ESDCFGx_tRCD_7			0x00000060
+#define ESDCFGx_tRCD_8			0x00000070
+
+#define ESDCFGx_tRC_MASK		0x0000000f
+#define ESDCFGx_tRC_20			0x00000000
+#define ESDCFGx_tRC_2			0x00000001
+#define ESDCFGx_tRC_3			0x00000002
+#define ESDCFGx_tRC_4			0x00000003
+#define ESDCFGx_tRC_5			0x00000004
+#define ESDCFGx_tRC_6			0x00000005
+#define ESDCFGx_tRC_7			0x00000006
+#define ESDCFGx_tRC_8			0x00000007
+#define ESDCFGx_tRC_9			0x00000008
+#define ESDCFGx_tRC_10			0x00000009
+#define ESDCFGx_tRC_11			0x0000000a
+#define ESDCFGx_tRC_12			0x0000000b
+#define ESDCFGx_tRC_13			0x0000000c
+#define ESDCFGx_tRC_14			0x0000000d
+//#define ESDCFGx_tRC_14		0x0000000e	// 15 seems to not exist
+#define ESDCFGx_tRC_16			0x0000000f
+
-- 
1.7.2.3



From s.hauer at pengutronix.de  Fri Oct 22 09:15:29 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 15:15:29 +0200
Subject: [PATCH 11/13] ARM: Add Garz+Fricke Cupid board support
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1287753331-7696-12-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/Makefile                    |    1 +
 arch/arm/boards/guf-cupid/Makefile   |   24 ++
 arch/arm/boards/guf-cupid/board.c    |  426 ++++++++++++++++++++++++++++++++++
 arch/arm/boards/guf-cupid/config.h   |   31 +++
 arch/arm/boards/guf-cupid/cupid.dox  |    9 +
 arch/arm/boards/guf-cupid/env/config |   56 +++++
 arch/arm/boards/guf-cupid/lowlevel.c |  349 ++++++++++++++++++++++++++++
 arch/arm/mach-imx/Kconfig            |   11 +
 8 files changed, 907 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/guf-cupid/Makefile
 create mode 100644 arch/arm/boards/guf-cupid/board.c
 create mode 100644 arch/arm/boards/guf-cupid/config.h
 create mode 100644 arch/arm/boards/guf-cupid/cupid.dox
 create mode 100644 arch/arm/boards/guf-cupid/env/config
 create mode 100644 arch/arm/boards/guf-cupid/lowlevel.c

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d9670c4..cdb0185 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -84,6 +84,7 @@ board-$(CONFIG_MACH_NESO)			:= guf-neso
 board-$(CONFIG_MACH_MX23EVK)			:= freescale-mx23-evk
 board-$(CONFIG_MACH_CHUMBY)			:= chumby_falconwing
 board-$(CONFIG_MACH_FREESCALE_MX51_PDK)		:= freescale-mx51-pdk
+board-$(CONFIG_MACH_GUF_CUPID)			:= guf-cupid
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/guf-cupid/Makefile b/arch/arm/boards/guf-cupid/Makefile
new file mode 100644
index 0000000..3a06cf4
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/Makefile
@@ -0,0 +1,24 @@
+#
+# (C) Copyright 2007 Juergen Beisert <jbe at pengutronix.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+obj-y += lowlevel.o
+obj-y += board.o
diff --git a/arch/arm/boards/guf-cupid/board.c b/arch/arm/boards/guf-cupid/board.c
new file mode 100644
index 0000000..6d7a99b
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/board.c
@@ -0,0 +1,426 @@
+/*
+ * (C) 2007 Pengutronix, Sascha Hauer <s.hauer at pengutronix.de>
+ * (C) 2009 Pengutronix, Juergen Beisert <kernel at pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Board support for the Garz+Fricke Cupid board
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <driver.h>
+#include <environment.h>
+#include <fs.h>
+#include <mach/imx-regs.h>
+#include <asm/armlinux.h>
+#include <mach/gpio.h>
+#include <asm/io.h>
+#include <partition.h>
+#include <nand.h>
+#include <generated/mach-types.h>
+#include <mach/imx-nand.h>
+#include <fec.h>
+#include <fb.h>
+#include <asm/mmu.h>
+#include <mach/imx-ipu-fb.h>
+#include <mach/imx-pll.h>
+#include <mach/iomux-mx35.h>
+
+static struct fec_platform_data fec_info = {
+	.xcv_type = MII100,
+};
+
+static struct device_d fec_dev = {
+	.id	  = -1,
+	.name     = "fec_imx",
+	.map_base = IMX_FEC_BASE,
+	.platform_data	= &fec_info,
+};
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram0_dev = {
+	.id	  = -1,
+	.name     = "mem",
+	.map_base = IMX_SDRAM_CS0,
+	.size     = 128 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+struct imx_nand_platform_data nand_info = {
+	.width	= 1,
+	.hw_ecc	= 1,
+	.flash_bbt = 1,
+};
+
+static struct device_d nand_dev = {
+	.id	  = -1,
+	.name     = "imx_nand",
+	.map_base = IMX_NFC_BASE,
+	.platform_data	= &nand_info,
+};
+
+static struct fb_videomode guf_cupid_fb_mode = {
+	/* 800x480 @ 70 Hz */
+	.name		= "CPT CLAA070LC0JCT",
+	.refresh	= 70,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= 30761,
+	.left_margin	= 24,
+	.right_margin	= 47,
+	.upper_margin	= 5,
+	.lower_margin	= 3,
+	.hsync_len	= 24,
+	.vsync_len	= 3,
+	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_CLK_INVERT |
+			  FB_SYNC_OE_ACT_HIGH,
+	.vmode		= FB_VMODE_NONINTERLACED,
+	.flag		= 0,
+};
+
+#define GPIO_LCD_ENABLE		(2 * 32 + 24)
+#define GPIO_LCD_BACKLIGHT	(0 * 32 + 19)
+
+static void cupid_fb_enable(int enable)
+{
+	if (enable) {
+		gpio_direction_output(GPIO_LCD_ENABLE, 1);
+		mdelay(100);
+		gpio_direction_output(GPIO_LCD_BACKLIGHT, 1);
+	} else {
+		gpio_direction_output(GPIO_LCD_BACKLIGHT, 0);
+		mdelay(100);
+		gpio_direction_output(GPIO_LCD_ENABLE, 0);
+	}
+}
+
+static struct imx_ipu_fb_platform_data ipu_fb_data = {
+	.mode		= &guf_cupid_fb_mode,
+	.bpp		= 16,
+	.enable		= cupid_fb_enable,
+};
+
+static struct device_d imx_ipu_fb_dev = {
+	.id		= -1,
+	.name		= "imx-ipu-fb",
+	.map_base	= 0x53fc0000,
+	.size		= 0x1000,
+	.platform_data	= &ipu_fb_data,
+};
+
+static struct device_d esdhc_dev = {
+	.name		= "imx-esdhc",
+	.map_base	= IMX_SDHC1_BASE,
+};
+
+#ifdef CONFIG_MMU
+static int cupid_mmu_init(void)
+{
+	mmu_init();
+
+	arm_create_section(0x80000000, 0x80000000, 128, PMD_SECT_DEF_CACHED);
+	arm_create_section(0x90000000, 0x80000000, 128, PMD_SECT_DEF_UNCACHED);
+
+	setup_dma_coherent(0x10000000);
+
+#if TEXT_BASE & (0x100000 - 1)
+#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
+#else
+	arm_create_section(0x0,        TEXT_BASE,   1, PMD_SECT_DEF_UNCACHED);
+#endif
+
+	mmu_enable();
+
+#ifdef CONFIG_CACHE_L2X0
+	l2x0_init((void __iomem *)0x30000000, 0x00030024, 0x00000000);
+#endif
+	return 0;
+}
+postcore_initcall(cupid_mmu_init);
+#endif
+
+static int cupid_devices_init(void)
+{
+	uint32_t reg;
+
+	gpio_direction_output(GPIO_LCD_ENABLE, 0);
+	gpio_direction_output(GPIO_LCD_BACKLIGHT, 0);
+
+	reg = readl(IMX_CCM_BASE + CCM_RCSR);
+	/* some fuses provide us vital information about connected hardware */
+	if (reg & 0x20000000)
+		nand_info.width = 2;    /* 16 bit */
+	else
+		nand_info.width = 1;    /* 8 bit */
+
+	register_device(&fec_dev);
+	register_device(&nand_dev);
+
+	devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
+	dev_add_bb_dev("self_raw", "self0");
+	devfs_add_partition("nand0", 0x40000, 0x80000, PARTITION_FIXED, "env_raw");
+	dev_add_bb_dev("env_raw", "env0");
+
+	register_device(&sdram0_dev);
+	register_device(&imx_ipu_fb_dev);
+	register_device(&esdhc_dev);
+
+	armlinux_add_dram(&sdram0_dev);
+	armlinux_set_bootparams((void *)0x80000100);
+	armlinux_set_architecture(MACH_TYPE_GUF_CUPID);
+
+	return 0;
+}
+
+device_initcall(cupid_devices_init);
+
+static struct device_d cupid_serial_device = {
+	.id	  = -1,
+	.name     = "imx_serial",
+	.map_base = IMX_UART1_BASE,
+	.size     = 16 * 1024,
+};
+
+static struct pad_desc cupid_pads[] = {
+	/* UART1 */
+	MX35_PAD_CTS1__UART1_CTS,
+	MX35_PAD_RTS1__UART1_RTS,
+	MX35_PAD_TXD1__UART1_TXD_MUX,
+	MX35_PAD_RXD1__UART1_RXD_MUX,
+	/* UART2 */
+	MX35_PAD_CTS2__UART2_CTS,
+	MX35_PAD_RTS2__UART2_RTS,
+	MX35_PAD_TXD2__UART2_TXD_MUX,
+	MX35_PAD_RXD2__UART2_RXD_MUX,
+	/* FEC */
+	MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+	MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+	MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+	MX35_PAD_FEC_COL__FEC_COL,
+	MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+	MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+	MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+	MX35_PAD_FEC_MDC__FEC_MDC,
+	MX35_PAD_FEC_MDIO__FEC_MDIO,
+	MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+	MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+	MX35_PAD_FEC_CRS__FEC_CRS,
+	MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+	MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+	MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+	/* I2C1 */
+	MX35_PAD_I2C1_CLK__I2C1_SCL,
+	MX35_PAD_I2C1_DAT__I2C1_SDA,
+	/* Display */
+	MX35_PAD_LD0__IPU_DISPB_DAT_0,
+	MX35_PAD_LD1__IPU_DISPB_DAT_1,
+	MX35_PAD_LD2__IPU_DISPB_DAT_2,
+	MX35_PAD_LD3__IPU_DISPB_DAT_3,
+	MX35_PAD_LD4__IPU_DISPB_DAT_4,
+	MX35_PAD_LD5__IPU_DISPB_DAT_5,
+	MX35_PAD_LD6__IPU_DISPB_DAT_6,
+	MX35_PAD_LD7__IPU_DISPB_DAT_7,
+	MX35_PAD_LD8__IPU_DISPB_DAT_8,
+	MX35_PAD_LD9__IPU_DISPB_DAT_9,
+	MX35_PAD_LD10__IPU_DISPB_DAT_10,
+	MX35_PAD_LD11__IPU_DISPB_DAT_11,
+	MX35_PAD_LD12__IPU_DISPB_DAT_12,
+	MX35_PAD_LD13__IPU_DISPB_DAT_13,
+	MX35_PAD_LD14__IPU_DISPB_DAT_14,
+	MX35_PAD_LD15__IPU_DISPB_DAT_15,
+	MX35_PAD_LD16__IPU_DISPB_DAT_16,
+	MX35_PAD_LD17__IPU_DISPB_DAT_17,
+	MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC,
+	MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+	MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+	MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
+	MX35_PAD_LD18__GPIO3_24,		/* LCD enable */
+	MX35_PAD_CSPI1_SS1__GPIO1_19,		/* LCD backligtht PWM */
+	/* USB Host*/
+	MX35_PAD_MLB_CLK__GPIO3_3,		/* USB Host PWR */
+	MX35_PAD_MLB_DAT__GPIO3_4,		/* USB Host Overcurrent */
+	/* USB OTG */
+	MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
+	MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+	/* SSI */
+	MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS,
+	MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
+	MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
+	MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
+	/* UCB1400 IRQ */
+	MX35_PAD_ATA_INTRQ__GPIO2_29,
+	/* Speaker On */
+	MX35_PAD_LD20__GPIO3_26,
+	/* LEDs */
+	MX35_PAD_TX1__GPIO1_14,
+	/* ESDHC1 */
+	MX35_PAD_SD1_CMD__ESDHC1_CMD,
+	MX35_PAD_SD1_CLK__ESDHC1_CLK,
+	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+	/* ESDHC1 CD */
+	MX35_PAD_ATA_DATA5__GPIO2_18,
+	/* ESDHC1 WP */
+	MX35_PAD_ATA_DATA6__GPIO2_19,
+};
+
+static int cupid_console_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(cupid_pads, ARRAY_SIZE(cupid_pads));
+
+	register_device(&cupid_serial_device);
+	return 0;
+}
+
+console_initcall(cupid_console_init);
+
+static int cupid_core_setup(void)
+{
+	u32 tmp;
+
+	/* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/
+	/*
+	 * Set all MPROTx to be non-bufferable, trusted for R/W,
+	 * not forced to user-mode.
+	 */
+	writel(0x77777777, IMX_AIPS1_BASE);
+	writel(0x77777777, IMX_AIPS1_BASE + 0x4);
+	writel(0x77777777, IMX_AIPS2_BASE);
+	writel(0x77777777, IMX_AIPS2_BASE + 0x4);
+
+	/*
+	 * Clear the on and off peripheral modules Supervisor Protect bit
+	 * for SDMA to access them. Did not change the AIPS control registers
+	 * (offset 0x20) access type
+	 */
+	writel(0x0, IMX_AIPS1_BASE + 0x40);
+	writel(0x0, IMX_AIPS1_BASE + 0x44);
+	writel(0x0, IMX_AIPS1_BASE + 0x48);
+	writel(0x0, IMX_AIPS1_BASE + 0x4C);
+	tmp = readl(IMX_AIPS1_BASE + 0x50);
+	tmp &= 0x00FFFFFF;
+	writel(tmp, IMX_AIPS1_BASE + 0x50);
+
+	writel(0x0, IMX_AIPS2_BASE + 0x40);
+	writel(0x0, IMX_AIPS2_BASE + 0x44);
+	writel(0x0, IMX_AIPS2_BASE + 0x48);
+	writel(0x0, IMX_AIPS2_BASE + 0x4C);
+	tmp = readl(IMX_AIPS2_BASE + 0x50);
+	tmp &= 0x00FFFFFF;
+	writel(tmp, IMX_AIPS2_BASE + 0x50);
+
+	/* MAX (Multi-Layer AHB Crossbar Switch) setup */
+
+	/* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */
+#define MAX_PARAM1 0x00302154
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x0);   /* for S0 */
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x100); /* for S1 */
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x200); /* for S2 */
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x300); /* for S3 */
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x400); /* for S4 */
+
+	/* SGPCR - always park on last master */
+	writel(0x10, IMX_MAX_BASE + 0x10);	/* for S0 */
+	writel(0x10, IMX_MAX_BASE + 0x110);	/* for S1 */
+	writel(0x10, IMX_MAX_BASE + 0x210);	/* for S2 */
+	writel(0x10, IMX_MAX_BASE + 0x310);	/* for S3 */
+	writel(0x10, IMX_MAX_BASE + 0x410);	/* for S4 */
+
+	/* MGPCR - restore default values */
+	writel(0x0, IMX_MAX_BASE + 0x800);	/* for M0 */
+	writel(0x0, IMX_MAX_BASE + 0x900);	/* for M1 */
+	writel(0x0, IMX_MAX_BASE + 0xa00);	/* for M2 */
+	writel(0x0, IMX_MAX_BASE + 0xb00);	/* for M3 */
+	writel(0x0, IMX_MAX_BASE + 0xc00);	/* for M4 */
+	writel(0x0, IMX_MAX_BASE + 0xd00);	/* for M5 */
+
+	writel(0x0000DCF6, CSCR_U(0)); /* CS0: NOR Flash */
+	writel(0x444A4541, CSCR_L(0));
+	writel(0x44443302, CSCR_A(0));
+
+	/*
+	 * M3IF Control Register (M3IFCTL)
+	 * MRRP[0] = L2CC0 not on priority list (0 << 0)	= 0x00000000
+	 * MRRP[1] = MAX1 not on priority list (0 << 0)		= 0x00000000
+	 * MRRP[2] = L2CC1 not on priority list (0 << 0)	= 0x00000000
+	 * MRRP[3] = USB  not on priority list (0 << 0)		= 0x00000000
+	 * MRRP[4] = SDMA not on priority list (0 << 0)		= 0x00000000
+	 * MRRP[5] = GPU not on priority list (0 << 0)		= 0x00000000
+	 * MRRP[6] = IPU1 on priority list (1 << 6)		= 0x00000040
+	 * MRRP[7] = IPU2 not on priority list (0 << 0)		= 0x00000000
+	 *                                                       ------------
+	 *                                                        0x00000040
+	 */
+	writel(0x40, IMX_M3IF_BASE);
+
+	return 0;
+}
+
+core_initcall(cupid_core_setup);
+
+#define MPCTL_PARAM_399     (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5))
+#define MPCTL_PARAM_532     ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1))
+
+static int do_cpufreq(struct command *cmdtp, int argc, char *argv[])
+{
+	unsigned long freq;
+
+	if (argc != 2)
+		return COMMAND_ERROR_USAGE;
+
+	freq = simple_strtoul(argv[1], NULL, 0);
+
+	switch (freq) {
+	case 399:
+		writel(MPCTL_PARAM_399, IMX_CCM_BASE + CCM_MPCTL);
+		break;
+	case 532:
+		writel(MPCTL_PARAM_532, IMX_CCM_BASE + CCM_MPCTL);
+		break;
+	default:
+		return COMMAND_ERROR_USAGE;
+	}
+
+	printf("Switched CPU frequency to %dMHz\n", freq);
+
+	return 0;
+}
+
+static const __maybe_unused char cmd_cpufreq_help[] =
+"Usage: cpufreq 399|532\n"
+"\n"
+"Set CPU frequency to <freq> MHz\n";
+
+BAREBOX_CMD_START(cpufreq)
+	.cmd            = do_cpufreq,
+	.usage          = "adjust CPU frequency",
+	BAREBOX_CMD_HELP(cmd_cpufreq_help)
+BAREBOX_CMD_END
+
diff --git a/arch/arm/boards/guf-cupid/config.h b/arch/arm/boards/guf-cupid/config.h
new file mode 100644
index 0000000..0e3b175
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/config.h
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2007 Juergen Beisert <jbe at pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * Definitions related to passing arguments to kernel.
+ */
+
+#define CONFIG_MX35_HCLK_FREQ	24000000
+
+#endif
+
+/* nothing to do here yet */
diff --git a/arch/arm/boards/guf-cupid/cupid.dox b/arch/arm/boards/guf-cupid/cupid.dox
new file mode 100644
index 0000000..2ff1b2c
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/cupid.dox
@@ -0,0 +1,9 @@
+/** @page Garz+Fricke Cupid
+
+This CPU card is based on a Freescale i.MX35 CPU. The card is shipped with:
+
+- 256MiB Nand flash
+- 128MiB synchronous dynamic RAM
+
+
+*/
diff --git a/arch/arm/boards/guf-cupid/env/config b/arch/arm/boards/guf-cupid/env/config
new file mode 100644
index 0000000..4db05b6
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/env/config
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+machine=cupid
+eth0.serverip=
+user=
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.netmask=a.b.c.d
+#eth0.gateway=a.b.c.d
+#eth0.serverip=a.b.c.d
+
+# can be either 'net', 'nor' or 'nand'
+kernel_loc=net
+# can be either 'net', 'nor', 'nand' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root-$machine.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+kernelimage_type=zimage
+kernelimage=zImage-$machine
+#kernelimage_type=uimage
+#kernelimage=uImage-$machine
+#kernelimage_type=raw
+#kernelimage=Image-$machine
+#kernelimage_type=raw_lzo
+#kernelimage=Image-$machine.lzo
+
+if [ -n $user ]; then
+	kernelimage="$user"-"$kernelimage"
+	nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine"
+	rootfsimage="$user"-"$rootfsimage"
+else
+	nfsroot="$eth0.serverip:/path/to/nfs/root"
+fi
+
+autoboot_timeout=3
+
+bootargs="console=ttymxc0,115200"
+
+bootargs="$bootargs video=mx3fb:CTP-CLAA070LC0ACW"
+
+nand_parts="256k(barebox)ro,512k(bareboxenv),2M(kernel),-(root)"
+nand_device=mxc_nand
+rootfs_mtdblock_nand=3
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m "
+
diff --git a/arch/arm/boards/guf-cupid/lowlevel.c b/arch/arm/boards/guf-cupid/lowlevel.c
new file mode 100644
index 0000000..8d403ee
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/lowlevel.c
@@ -0,0 +1,349 @@
+/*
+ *
+ * (c) 2007 Pengutronix, Sascha Hauer <s.hauer at pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <init.h>
+#include <mach/imx-regs.h>
+#include <mach/imx-pll.h>
+#include <mach/esdctl.h>
+#include <asm/cache-l2x0.h>
+#include <asm/io.h>
+#include <mach/imx-nand.h>
+#include <asm/barebox-arm.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/system.h>
+
+/* Assuming 24MHz input clock */
+#define MPCTL_PARAM_399     (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5))
+#define MPCTL_PARAM_532     ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1))
+#define PPCTL_PARAM_300     (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1))
+
+#define SDRAM_MODE_BL_8	0x0003
+#define SDRAM_MODE_BSEQ	0x0000
+#define SDRAM_MODE_CL_3	0x0030
+#define MDDR_DS_HALF	0x20
+#define SDRAM_COMPARE_CONST1	0x55555555
+#define SDRAM_COMPARE_CONST2	0xaaaaaaaa
+
+#ifdef CONFIG_NAND_IMX_BOOT
+static void __bare_init __naked insdram(void)
+{
+	uint32_t r;
+
+	/* Speed up NAND controller by adjusting the NFC divider */
+	r = readl(IMX_CCM_BASE + CCM_PDR4);
+	r &= ~(0xf << 28);
+	r |= 0x1 << 28;
+	writel(r, IMX_CCM_BASE + CCM_PDR4);
+
+	/* setup a stack to be able to call imx_nand_load_image() */
+	r = STACK_BASE + STACK_SIZE - 12;
+	__asm__ __volatile__("mov sp, %0" : : "r"(r));
+
+	imx_nand_load_image((void *)TEXT_BASE, 256 * 1024);
+
+	board_init_lowlevel_return();
+}
+#endif
+
+static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_addr)
+{
+	volatile int loop;
+	void *r9 = (void *)IMX_SDRAM_CS0;
+	u32 r11 = 0xda; /* dummy constant */
+	u32 r1, r0;
+
+	/* disable second SDRAM region to save power */
+	r1 = readl(ESDCTL1);
+	r1 &= ~ESDCTL0_SDE;
+	writel(r1, ESDCTL1);
+
+	mode |= ESDMISC_RST | ESDMISC_MDDR_DL_RST;
+	writel(mode, ESDMISC);
+
+	mode &= ~(ESDMISC_RST | ESDMISC_MDDR_DL_RST);
+	writel(mode, ESDMISC);
+
+	/* wait for esdctl reset */
+	for (loop = 0; loop < 0x20000; loop++);
+
+	r1 = ESDCFGx_tXP_4 | ESDCFGx_tWTR_1 |
+		ESDCFGx_tRP_3 | ESDCFGx_tMRD_2 |
+		ESDCFGx_tWR_1_2 | ESDCFGx_tRAS_6 |
+		ESDCFGx_tRRD_2 | ESDCFGx_tCAS_3 |
+		ESDCFGx_tRCD_3 | ESDCFGx_tRC_20;
+
+	writel(r1, ESDCFG0);
+
+	/* enable SDRAM controller */
+	writel(memsize | ESDCTL0_SMODE_NORMAL, ESDCTL0);
+
+	/* Micron Datasheet Initialization Step 3: Wait 200us before first command */
+	for (loop = 0; loop < 1000; loop++);
+
+	/* Micron Datasheet Initialization Step 4: PRE CHARGE ALL */
+	writel(memsize | ESDCTL0_SMODE_PRECHARGE, ESDCTL0);
+	writeb(r11, sdram_addr);
+
+	/* Micron Datasheet Initialization Step 5: NOP for tRP (at least 22.5ns)
+	 * The CPU is not fast enough to cause a problem here
+	 */
+
+	/* Micron Datasheet Initialization Step 6: 2 AUTO REFRESH and tRFC NOP
+	 * (at least 140ns)
+	 */
+	writel(memsize | ESDCTL0_SMODE_AUTO_REFRESH, ESDCTL0);
+	writeb(r11, r9); /* AUTO REFRESH #1 */
+
+	for (loop = 0; loop < 3; loop++); /* ~140ns delay at 532MHz */
+
+	writeb(r11, r9); /* AUTO REFRESH #2 */
+
+	for (loop = 0; loop < 3; loop++); /* ~140ns delay at 532MHz */
+
+	/* Micron Datasheet Initialization Step 7: LOAD MODE REGISTER */
+	writel(memsize | ESDCTL0_SMODE_LOAD_MODE, ESDCTL0);
+	writeb(r11, r9 + (SDRAM_MODE_BL_8 | SDRAM_MODE_BSEQ | SDRAM_MODE_CL_3));
+
+	/* Micron Datasheet Initialization Step 8: tMRD = 2 tCK NOP
+	 * (The memory controller will take care of this delay)
+	 */
+
+	/* Micron Datasheet Initialization Step 9: LOAD MODE REGISTER EXTENDED */
+	writeb(r11, 0x84000000 | MDDR_DS_HALF);  /*we assume 14 Rows / 10 Cols here */
+
+	/* Micron Datasheet Initialization Step 9: tMRD = 2 tCK NOP
+	 * (The memory controller will take care of this delay)
+	 */
+
+	/* Now configure SDRAM-Controller and check that it works */
+	writel(memsize | ESDCTL0_BL | ESDCTL0_REF4, ESDCTL0);
+
+	/* Freescale asks for first access to be a write to properly
+	 * initialize DQS pin-state and keepers
+	 */
+	writel(0xdeadbeef, r9);
+
+	/* test that the RAM is in fact working */
+	writel(SDRAM_COMPARE_CONST1, r9);
+	writel(SDRAM_COMPARE_CONST2, r9 + 0x4);
+
+	if (readl(r9) != SDRAM_COMPARE_CONST1)
+		while (1);
+
+	/* Verify that the correct row and coloumn is selected */
+
+	/* So far we asssumed that we have 14 rows, verify this */
+	writel(SDRAM_COMPARE_CONST1, r9);
+	writel(SDRAM_COMPARE_CONST2, r9 + (1 << 25));
+
+	/* if both value are identical, we don't have 14 rows. assume 13 instead */
+	if (readl(r9) == readl(r9 + (1 << 25))) {
+		r0 = readl(ESDCTL0);
+		r0 &= ~ESDCTL0_ROW_MASK;
+		r0 |= ESDCTL0_ROW13;
+		writel(r0, ESDCTL0);
+	}
+
+	/* So far we asssumed that we have 10 columns, verify this */
+	writel(SDRAM_COMPARE_CONST1, r9);
+	writel(SDRAM_COMPARE_CONST2, r9 + (1 << 11));
+
+	/* if both value are identical, we don't have 10 cols. assume 9 instead */
+	if (readl(r9) == readl(r9 + (1 << 11))) {
+		r0 = readl(ESDCTL0);
+		r0 &= ~ESDCTL0_COL_MASK;
+		r0 |= ESDCTL0_COL9;
+		writel(r0, ESDCTL0);
+	}
+}
+
+#define BRANCH_PREDICTION_ENABLE
+#define UNALIGNED_ACCESS_ENABLE
+#define LOW_INT_LATENCY_ENABLE
+
+void __bare_init __naked board_init_lowlevel(void)
+{
+	u32 r0, r1;
+	void *iomuxc_base = (void *)IMX_IOMUXC_BASE;
+	int i;
+#ifdef CONFIG_NAND_IMX_BOOT
+	unsigned int *trg, *src;
+#endif
+
+	r0 = 0x10000000 + 128 * 1024 - 16;
+        __asm__ __volatile__("mov sp, %0" : : "r"(r0));
+
+	/*
+	 *       ARM1136 init
+	 *       - invalidate I/D cache/TLB and drain write buffer;
+	 *       - invalidate L2 cache
+	 *       - unaligned access
+	 *       - branch predictions
+	 */
+#ifdef TURN_OFF_IMPRECISE_ABORT
+	__asm__ __volatile__("mrs %0, cpsr":"=r"(r0));
+	r0 &= ~0x100;
+	__asm__ __volatile__("msr cpsr, %0" : : "r"(r0));
+#endif
+	/* ensure L1 caches and MMU are turned-off for now */
+	r1 = get_cr();
+	r1 &= ~(CR_I | CR_M | CR_C);
+
+	/* setup core features */
+	__asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1":"=r"(r0));
+#ifdef BRANCH_PREDICTION_ENABLE
+	r0 |= 7;
+	r1 |= CR_Z;
+#else
+	r0 &= ~7;
+	r1 &= ~CR_Z;
+#endif
+	__asm__ __volatile__("mcr p15, 0, r0, c1, c0, 1" : : "r"(r0));
+
+#ifdef UNALIGNED_ACCESS_ENABLE
+	r1 |= CR_U;
+#else
+	r1 &= ~CR_U;
+#endif
+
+#ifdef LOW_INT_LATENCY_ENABLE
+	r1 |= CR_FI;
+#else
+	r1 &= ~CR_FI;
+#endif
+	set_cr(r1);
+
+	r0 = 0;
+	__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 6" : : "r"(r0));
+
+	/* invalidate I cache and D cache */
+	__asm__ __volatile__("mcr p15, 0, r0, c7, c7, 0" : : "r"(r0));
+	/* invalidate TLBs */
+	__asm__ __volatile__("mcr p15, 0, r0, c8, c7, 0" : : "r"(r0));
+	/* Drain the write buffer */
+	__asm__ __volatile__("mcr p15, 0, r0, c7, c10, 4" : : "r"(r0));
+
+	/* Also setup the Peripheral Port Remap register inside the core */
+	r0 = 0x40000015; /* start from AIPS 2GB region */
+	__asm__ __volatile__("mcr p15, 0, r0, c15, c2, 4" : : "r"(r0));
+
+#define	WDOG_WMCR 0x8
+	/* silence reset WDOG */
+	writew(0, IMX_WDOG_BASE + WDOG_WMCR);
+
+	/* Skip SDRAM initialization if we run from RAM */
+	r0 = get_pc();
+	if (r0 > 0x80000000 && r0 < 0x90000000)
+		board_init_lowlevel_return();
+
+	/* Configure drive strength */
+
+	/* Configure DDR-pins to correct mode */
+	r0 = 0x00001800;
+	writel(r0, iomuxc_base + 0x794);
+	writel(r0, iomuxc_base + 0x798);
+	writel(r0, iomuxc_base + 0x79c);
+	writel(r0, iomuxc_base + 0x7a0);
+	writel(r0, iomuxc_base + 0x7a4);
+
+	/* Set drive strength for DDR-pins */
+	for (i = 0x368; i <= 0x4c8; i += 4) {
+		r0 = readl(iomuxc_base + i);
+		r0 &= ~0x6;
+		r0 |= 0x2;
+		writel(r0, iomuxc_base + i);
+		if (i == 0x468)
+			i = 0x4a4;
+	}
+
+	r0 = readl(iomuxc_base + 0x480);
+	r0 &= ~0x6;
+	r0 |= 0x2;
+	writel(r0, iomuxc_base + 0x480);
+
+	r0 = readl(iomuxc_base + 0x4b8);
+	r0 &= ~0x6;
+	r0 |= 0x2;
+	writel(r0, iomuxc_base + 0x4b8);
+
+	/* Configure static chip-selects */
+	r0 = readl(iomuxc_base + 0x000);
+	r0 &= ~1; /* configure CS2/CSD0 for SDRAM */
+	writel(r0, iomuxc_base + 0x000);
+
+	/* start-up code doesn't need any static chip-select.
+	 * Leave their initialization to high-level code that
+	 * can initialize them depending on the baseboard.
+	 */
+
+	/* Configure clocks */
+
+	/* setup cpu/bus clocks */
+	writel(0x003f4208, IMX_CCM_BASE + CCM_CCMR);
+
+	/* configure MPLL */
+	writel(MPCTL_PARAM_532, IMX_CCM_BASE + CCM_MPCTL);
+
+	/* configure PPLL */
+	writel(PPCTL_PARAM_300, IMX_CCM_BASE + CCM_PPCTL);
+
+	/* configure core dividers */
+	r0 = PDR0_CCM_PER_AHB(1) | PDR0_HSP_PODF(2);
+
+	writel(r0, IMX_CCM_BASE + CCM_PDR0);
+
+	/* configure clock-gates */
+	r0 = readl(IMX_CCM_BASE + CCM_CGR0);
+	r0 |= 0x00300000;
+	writel(r0, IMX_CCM_BASE + CCM_CGR0);
+
+	r0 = readl(IMX_CCM_BASE + CCM_CGR1);
+	r0 |= 0x00000c03;
+	writel(r0, IMX_CCM_BASE + CCM_CGR1);
+
+	/* Configure SDRAM */
+	/* Try 32-Bit 256 MB DDR memory */
+	r0 = ESDCTL0_SDE | ESDCTL0_ROW14 | ESDCTL0_COL10 | ESDCTL0_DSIZ_31_0; /* 1024 MBit DDR-SDRAM */
+	setup_sdram(r0, ESDMISC_MDDR_EN, 0x80000f00);
+
+#ifdef CONFIG_NAND_IMX_BOOT
+	/* skip NAND boot if not running from NFC space */
+	r0 = get_pc();
+	if (r0 < IMX_NFC_BASE || r0 > IMX_NFC_BASE + 0x800)
+		board_init_lowlevel_return();
+
+	src = (unsigned int *)IMX_NFC_BASE;
+	trg = (unsigned int *)TEXT_BASE;
+
+	/* Move ourselves out of NFC SRAM */
+	for (i = 0; i < 0x800 / sizeof(int); i++)
+		*trg++ = *src++;
+
+	/* Jump to SDRAM */
+	r0 = (unsigned int)&insdram;
+	__asm__ __volatile__("mov pc, %0" : : "r"(r0));
+#else
+	board_init_lowlevel_return();
+#endif
+}
+
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index d451875..f3506af 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -18,6 +18,7 @@ config ARCH_TEXT_BASE
 	default 0x08f80000 if MACH_SCB9328
 	default 0xa7e00000 if MACH_NESO
 	default 0x97f00000 if MACH_MX51_PDK
+	default 0x87f00000 if MACH_GUF_CUPID
 
 config BOARDINFO
 	default "Eukrea CPUIMX25" if MACH_EUKREA_CPUIMX25
@@ -34,6 +35,7 @@ config BOARDINFO
 	default "Synertronixx scb9328" if MACH_SCB9328
 	default "Garz+Fricke Neso" if MACH_NESO
 	default "Freescale i.MX51 PDK" if MACH_FREESCALE_MX51_PDK
+	default "Garz+Fricke Cupid" if MACH_GUF_CUPID
 
 config ARCH_HAS_FEC_IMX
 	bool
@@ -299,6 +301,15 @@ config MACH_PCM043
           Say Y here if you are using Phytec's phyCORE-i.MX35 (pcm043) equipped
           with a Freescale i.MX35 Processor
 
+config MACH_GUF_CUPID
+        bool "Garz+Fricke Cupid"
+	select HAVE_MMU
+	select MACH_HAS_LOWLEVEL_INIT
+	select ARCH_HAS_L2X0
+        help
+	  Say Y here if you are using the Garz+Fricke Neso board equipped
+	  with a Freescale i.MX35 Processor
+
 endchoice
 
 endif
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 09:18:48 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 15:18:48 +0200
Subject: [PATCH] Add some help using the gpio commands at runtime
In-Reply-To: <034801cb71e8$d8d10740$8a7315c0$@cpdesign.com.au>
References: <201010221058.01249.jbe@pengutronix.de>
	<034801cb71e8$d8d10740$8a7315c0$@cpdesign.com.au>
Message-ID: <201010221518.48623.jbe@pengutronix.de>

Hi Marc,

Marc Reilly wrote:
> This is a great step for documentation, and a few things I didn't know.
> Thanks for the effort!
>
> Just FYI, some really minor corrections below. (Sorry for being pedantic..
> I'm OK if they are ignored :) )

Thank you for the corrections. I will re-send the patch.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 22 09:24:00 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 15:24:00 +0200
Subject: [PATCH v2] Add some help using the gpio commands at runtime
In-Reply-To: <034801cb71e8$d8d10740$8a7315c0$@cpdesign.com.au>
References: <201010221058.01249.jbe@pengutronix.de>
	<034801cb71e8$d8d10740$8a7315c0$@cpdesign.com.au>
Message-ID: <201010221524.00862.jbe@pengutronix.de>

From: Juergen Beisert <jbe at pengutronix.de>
Subject: [PATCH] Add some help using the gpio commands at runtime

Last time I used the gpio commands I was somehow confused about the behaviour
of the 'gpio_get_value' command. So, I decided to add some doc for it. Here's
the result.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>

---
 Documentation/commands.dox |    1 
 commands/gpio.c            |   61 
+++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

Index: barebox-2010.10.0/Documentation/commands.dox
===================================================================
--- barebox-2010.10.0.orig/Documentation/commands.dox
+++ barebox-2010.10.0/Documentation/commands.dox
@@ -10,6 +10,7 @@
 @li @subpage edit_command
 @li @subpage erase_command
 @li @subpage export_command
+ at li @subpage gpio_for_users
 @li @subpage tftp_command
 @li @subpage loadenv_command
 @li @subpage mount_command
Index: barebox-2010.10.0/commands/gpio.c
===================================================================
--- barebox-2010.10.0.orig/commands/gpio.c
+++ barebox-2010.10.0/commands/gpio.c
@@ -120,3 +120,64 @@ BAREBOX_CMD_START(gpio_direction_output)
 	BAREBOX_CMD_HELP(cmd_gpio_direction_output_help)
 BAREBOX_CMD_END
 
+/**
+ at page gpio_for_users Runtime GPIO handling
+
+ at section regular_gpio General usage information
+
+These commands are available if the symbol @b CONFIG_GENERIC_GPIO and
+ at b CONFIG_CMD_GPIO are enabled in the Kconfig.
+
+ at note All gpio related commands take a number to identify the pad. This
+number is architecture dependent. There may be no intuitional correlation
+between available pads and the GPIO numbers to be used in the commands. Due
+to this it's also possible the numbers change between @b barebox releases.
+
+ at section gpio_dir_out Switch a pad into an output GPIO
+ at verbatim
+gpio_direction_output <gpio_no> <initial_value>
+ at endverbatim
+- @b gpio_no Architecture dependent GPIO number
+- @b initial_value Output value the pad should emit
+
+ at note To avoid glitches on the pad's line, the routines will first setting up
+the pad's value and after that switching the pad itself to output (if the
+silicon is able to do so)
+
+ at note If the pad is already configured into a non GPIO mode (if available)
+this command may fail (silently)
+
+ at section gpio_dir_in Switch a pad into an input GPIO
+ at verbatim
+gpio_direction_input <gpio_no>
+ at endverbatim
+- @b gpio_no Architecture dependent GPIO number
+
+ at note If the pad is already configured into a non GPIO mode (if available)
+this command may fail (silently)
+
+ at section gpio_get_value Read in the value of an GPIO input pad
+ at verbatim
+gpio_get_value <gpio_no>
+ at endverbatim
+
+Reads in the current pad's line value from the given GPIO number. It returns
+the value as a shell return code. There is no visible output at stdout. You
+can check the return value by using "echo $?"
+
+ at note If the return code is not '0' or '1' it's meant as an error code.
+
+ at note If the pad is not configured for GPIO mode this command may fail
+(silently) and returns garbage
+
+ at section gpio_set_value Set a new value to a GPIO output pad
+ at verbatim
+gpio_set_value <gpio_no> <value>
+ at endverbatim
+- @b gpio_no Architecture dependent GPIO number
+- @b value Output value the pad should emit
+
+Sets a new output @b value to the pad with GPIO number @b gpio_no
+
+ at note If the pad is not configured for GPIO mode this command may fail 
(silently)
+*/



-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 22 09:40:52 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 15:40:52 +0200
Subject: [PATCH 03/13] mci-core: add multiple block support
In-Reply-To: <1287753331-7696-4-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
	<1287753331-7696-4-git-send-email-s.hauer@pengutronix.de>
Message-ID: <201010221540.52926.jbe@pengutronix.de>

Sascha Hauer wrote:
> So far only for reading blocks. This is based on the corresponding
> U-Boot code.
>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Juergen Beisert <jbe at pengutronix.de>

At least my S32440 target still works with this patch.

Acked-by: Juergen Beisert <jbe at pengurtronix.de>

> ---
>  drivers/mci/mci-core.c |   35 +++++++++++++++++++++++++++--------
>  1 files changed, 27 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
> index c92d5a9..34c4f8c 100644
> --- a/drivers/mci/mci-core.c
> +++ b/drivers/mci/mci-core.c
> @@ -139,23 +139,41 @@ static int mci_block_write(struct device_d *mci_dev,
> const void *src, unsigned b * @param dst Where to store the data read from
> the card
>   * @param blocknum Block number to read
>   */
> -static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned
> blocknum) +static int mci_read_block(struct device_d *mci_dev, void *dst,
> unsigned blocknum, int blocks) {
>  	struct mci *mci = GET_MCI_DATA(mci_dev);
>  	struct mci_cmd cmd;
>  	struct mci_data data;
> +	int ret;
> +	unsigned mmccmd;
> +
> +	if (blocks > 1)
> +		mmccmd = MMC_CMD_READ_MULTIPLE_BLOCK;
> +	else
> +		mmccmd = MMC_CMD_READ_SINGLE_BLOCK;
>
>  	mci_setup_cmd(&cmd,
> -		MMC_CMD_READ_SINGLE_BLOCK,
> +		mmccmd,
>  		mci->high_capacity != 0 ? blocknum : blocknum * mci->read_bl_len,
>  		MMC_RSP_R1);
>
>  	data.dest = dst;
> -	data.blocks = 1;
> +	data.blocks = blocks;
>  	data.blocksize = mci->read_bl_len;
>  	data.flags = MMC_DATA_READ;
>
> -	return mci_send_cmd(mci_dev, &cmd, &data);
> +	ret = mci_send_cmd(mci_dev, &cmd, &data);
> +	if (ret)
> +		return ret;
> +
> +	if (blocks > 1) {
> +		mci_setup_cmd(&cmd,
> +			MMC_CMD_STOP_TRANSMISSION,
> +			0,
> +			MMC_RSP_R1b);
> +			ret = mci_send_cmd(mci_dev, &cmd, NULL);
> +	}
> +	return ret;
>  }
>
>  /**
> @@ -979,19 +997,20 @@ static int mci_sd_read(struct device_d *disk_dev,
> uint64_t sector_start, }
>
>  	while (sector_count) {
> +		int now = min(sector_count, 32);
>  		if (sector_start > MAX_BUFFER_NUMBER) {
>  			pr_err("Cannot handle block number %lu. Too large!\n",
>  				(unsigned)sector_start);
>  			return -EINVAL;
>  		}
> -		rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start);
> +		rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start, now);
>  		if (rc != 0) {
>  			pr_err("Reading block %lu failed with %d\n", (unsigned)sector_start,
> rc); return rc;
>  		}
> -		sector_count--;
> -		buffer += mci->read_bl_len;
> -		sector_start++;
> +		sector_count -= now;
> +		buffer += mci->read_bl_len * now;
> +		sector_start += now;
>  	}
>
>  	return 0;



-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 22 09:41:49 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 15:41:49 +0200
Subject: [PATCH 10/13] mci: align data for commands
In-Reply-To: <1287753331-7696-11-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
	<1287753331-7696-11-git-send-email-s.hauer@pengutronix.de>
Message-ID: <201010221541.49699.jbe@pengutronix.de>

Sascha Hauer wrote:
> Some mci controllers cannot transfer data with their DMA engines
> if the data is not sufficiently aligned. Normally this is a driver
> problem, but hey, we have no problem aligning the data and keep
> the burden from the drivers.
>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Juergen Beisert <jbe at pengutronix.de>

Acked-by: Juergen Beisert <jbe at pengutronix.de>

> ---
>  drivers/mci/mci-core.c |   12 ++++++------
>  1 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
> index 34c4f8c..6f31cca 100644
> --- a/drivers/mci/mci-core.c
> +++ b/drivers/mci/mci-core.c
> @@ -347,7 +347,7 @@ static int mci_switch(struct device_d *mci_dev,
> unsigned set, unsigned index, static int mmc_change_freq(struct device_d
> *mci_dev)
>  {
>  	struct mci *mci = GET_MCI_DATA(mci_dev);
> -	char ext_csd[512];
> +	char *ext_csd = sector_buf;
>  	char cardtype;
>  	int err;
>
> @@ -439,8 +439,8 @@ static int sd_change_freq(struct device_d *mci_dev)
>  	struct mci *mci = GET_MCI_DATA(mci_dev);
>  	struct mci_cmd cmd;
>  	struct mci_data data;
> -	uint32_t switch_status[16];
> -	uint scr[2];
> +	uint32_t *switch_status = sector_buf;
> +	uint32_t *scr = sector_buf;
>  	int timeout;
>  	int err;
>
> @@ -461,7 +461,7 @@ static int sd_change_freq(struct device_d *mci_dev)
>
>  retry_scr:
>  	pr_debug("Trying to read the SCR (try %d of %d)\n", 4 - timeout, 3);
> -	data.dest = (char *)&scr;
> +	data.dest = (char *)scr;
>  	data.blocksize = 8;
>  	data.blocks = 1;
>  	data.flags = MMC_DATA_READ;
> @@ -502,7 +502,7 @@ retry_scr:
>  	timeout = 4;
>  	while (timeout--) {
>  		err = sd_switch(mci_dev, SD_SWITCH_CHECK, 0, 1,
> -				(uint8_t*)&switch_status);
> +				(uint8_t*)switch_status);
>  		if (err) {
>  			pr_debug("Checking SD transfer switch frequency feature failed: %d\n",
> err); return err;
> @@ -520,7 +520,7 @@ retry_scr:
>  	if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
>  		return 0;
>
> -	err = sd_switch(mci_dev, SD_SWITCH_SWITCH, 0, 1,
> (uint8_t*)&switch_status); +	err = sd_switch(mci_dev, SD_SWITCH_SWITCH, 0,
> 1, (uint8_t*)switch_status); if (err) {
>  		pr_debug("Switching SD transfer frequency failed: %d\n", err);
>  		return err;



-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 22 10:03:38 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 16:03:38 +0200
Subject: [PATCH 03/13] mci-core: add multiple block support
In-Reply-To: <1287753331-7696-4-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
	<1287753331-7696-4-git-send-email-s.hauer@pengutronix.de>
Message-ID: <201010221603.38865.jbe@pengutronix.de>

Sascha Hauer wrote:
> So far only for reading blocks. This is based on the corresponding
> U-Boot code.
>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Juergen Beisert <jbe at pengutronix.de>
> ---
>  drivers/mci/mci-core.c |   35 +++++++++++++++++++++++++++--------
>  1 files changed, 27 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
> index c92d5a9..34c4f8c 100644
> --- a/drivers/mci/mci-core.c
> +++ b/drivers/mci/mci-core.c
> @@ -139,23 +139,41 @@ static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned b
>   * @param dst Where to store the data read from the card
>   * @param blocknum Block number to read
>   */
> -static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned blocknum)
> +static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned blocknum, int blocks) { 

I know real programmers [TM] hate documentation. But if you add a parameter,
please spend the short time to also add a

   "@param blocks Block count to read at once"

(or similar) to the header of this function.

> [...]

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From r.schwebel at pengutronix.de  Fri Oct 22 12:44:54 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:44:54 +0200
Subject: [PATCH 02/32] Doxyfile: enable quiet output
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-3-git-send-email-r.schwebel@pengutronix.de>

We set the output to "quiet" in order to see the warnings.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Doxyfile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Doxyfile b/Doxyfile
index 40bcb2f..6c04afe 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -424,7 +424,7 @@ FILE_VERSION_FILTER    =
 # The QUIET tag can be used to turn on/off the messages that are generated
 # by doxygen. Possible values are YES and NO. If left blank NO is used.
 
-QUIET                  = NO
+QUIET                  = YES
 
 # The WARNINGS tag can be used to turn on/off the warning messages that are
 # generated by doxygen. Possible values are YES and NO. If left blank
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:05 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:05 +0200
Subject: [PATCH 13/32] doc: fix typo
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-14-git-send-email-r.schwebel@pengutronix.de>

Remove a # which leads to this warning:
arch/arm/mach-s3c24xx/lowlevel-init.S:307: Warning: explicit link request to 'CALC_NFCONF_TIMING' could not be resolved

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 arch/arm/mach-s3c24xx/lowlevel-init.S |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/lowlevel-init.S b/arch/arm/mach-s3c24xx/lowlevel-init.S
index e8004e5..27f3a32 100644
--- a/arch/arm/mach-s3c24xx/lowlevel-init.S
+++ b/arch/arm/mach-s3c24xx/lowlevel-init.S
@@ -304,7 +304,7 @@ minimalistic. Setup the NAND access timing is done in a safe manner, what
 means: Slowest possible values are used. If you want to increase the speed you
 should define the BOARD_DEFAULT_NAND_TIMING to a valid setting into the
 NFCONF register and add it to your board specific config.h. Refer S3C24x0's
-datasheet for further details. The macro #CALC_NFCONF_TIMING could help to
+datasheet for further details. The macro CALC_NFCONF_TIMING could help to
 calculate the register setting in a hardware independent manner.
 
 @note The regular NAND driver uses a platform data structure to define the
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:01 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:01 +0200
Subject: [PATCH 09/32] doc: remove nonexisting command
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-10-git-send-email-r.schwebel@pengutronix.de>

Silence this warning:

Documentation/commands.dox:24: Warning: unable to resolve reference to `rarp_command' for \ref command

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index a8850b1..5404483 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -15,7 +15,6 @@
 @li @subpage mount_command
 @li @subpage printenv_command
 @li @subpage protect_command
- at li @subpage rarp_command
 @li @subpage saveenv_command
 @li @subpage setenv_command
 @li @subpage sh_command
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:09 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:09 +0200
Subject: [PATCH 17/32] doc: fix parameter name in mci-core
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-18-git-send-email-r.schwebel@pengutronix.de>

Silence this warning:

drivers/mci/mci-core.c:1324: Warning: argument `pdata' of command @param is not found in the argument list of mci_register(struct mci_host *host)
drivers/mci/mci-core.c:1324: Warning: The following parameters of mci_register(struct mci_host *host) are not documented:
  parameter host

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 drivers/mci/mci-core.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index c92d5a9..097bfa5 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1323,7 +1323,7 @@ device_initcall(mci_init);
 
 /**
  * Create a new mci device (for convenience)
- * @param pdata MCI device's platform data for this MCI device
+ * @param host mci_host for this MCI device
  * @return 0 on success
  */
 int mci_register(struct mci_host *host)
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:12 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:12 +0200
Subject: [PATCH 20/32] doc: add documentation for 'bmp'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-21-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    1 +
 commands/bmp.c             |   16 ++++++++--------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 5404483..da95e85 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -2,6 +2,7 @@
  * @page command_reference Supported Shell Commands
 
 @li @subpage addpart_command
+ at li @subpage bmp_command
 @li @subpage cat_command
 @li @subpage cd_command
 @li @subpage cp_command
diff --git a/commands/bmp.c b/commands/bmp.c
index 6e17200..242965a 100644
--- a/commands/bmp.c
+++ b/commands/bmp.c
@@ -193,17 +193,17 @@ failed_memmap:
 	return 1;
 }
 
-static const __maybe_unused char cmd_bmp_help[] =
-"Usage: bmp [OPTION]... FILE\n"
-"show bmp image FILE.\n"
-"  -f <fb>   framebuffer device (/dev/fb0)\n"
-"  -x <xofs> x offset (default center)\n"
-"  -y <yofs> y offset (default center)\n"
-"  -o        render offscreen\n";
+BAREBOX_CMD_HELP_START(bmp)
+BAREBOX_CMD_HELP_USAGE("bmp [OPTIONS] FILE")
+BAREBOX_CMD_HELP_SHORT("Show the bitmap FILE on the framebuffer.")
+BAREBOX_CMD_HELP_OPT  ("-f <fb>",   "framebuffer device (/dev/fb0)")
+BAREBOX_CMD_HELP_OPT  ("-x <xofs>", "x offset (default center)")
+BAREBOX_CMD_HELP_OPT  ("-y <yofs>", "y offset (default center)")
+BAREBOX_CMD_HELP_OPT  ("-o",        "render offscreen")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(bmp)
 	.cmd		= do_bmp,
 	.usage		= "show a bmp image",
 	BAREBOX_CMD_HELP(cmd_bmp_help)
 BAREBOX_CMD_END
-
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:10 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:10 +0200
Subject: [PATCH 18/32] doc: silence doxygen warnings
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-19-git-send-email-r.schwebel@pengutronix.de>

Silence these warnings:

common/kallsyms.c:8: Warning: documented function `const u8 kallsyms_names' was not declared or defined.
common/kallsyms.c:10: Warning: documented function `const u8 kallsyms_token_table' was not declared or defined.
common/kallsyms.c:11: Warning: documented function `const u16 kallsyms_token_index' was not declared or defined.
common/kallsyms.c:13: Warning: documented function `const unsigned long kallsyms_markers' was not declared or defined.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 common/kallsyms.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/common/kallsyms.c b/common/kallsyms.c
index 4069f4b..490adb9 100644
--- a/common/kallsyms.c
+++ b/common/kallsyms.c
@@ -2,6 +2,8 @@
 #include <init.h>
 #include <kallsyms.h>
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
 /* These will be re-linked against their real values during the second link stage */
 extern const unsigned long kallsyms_addresses[] __attribute__((weak));
 extern const unsigned long kallsyms_num_syms __attribute__((weak));
@@ -12,6 +14,8 @@ extern const u16 kallsyms_token_index[] __attribute__((weak));
 
 extern const unsigned long kallsyms_markers[] __attribute__((weak));
 
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
 /* expand a compressed symbol data into the resulting uncompressed string,
    given the offset to where the symbol is in the compressed stream */
 static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:07 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:07 +0200
Subject: [PATCH 15/32] doc: avoid that doxygen parses magic in command.h
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-16-git-send-email-r.schwebel@pengutronix.de>

Don't let doxygen parse the command magic, which leads to these warnings:

command.h:93: Warning: explicit link request to 'define' could not be resolved
command.h:98: Warning: expected <tr> tag but found TK_LNKWORD token instead!
command.h:98: Warning: Found unknown command `\t'
command.h:101: Warning: explicit link request to 'define' could not be resolved
command.h:103: Warning: explicit link request to 'define' could not be resolved

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 include/command.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/command.h b/include/command.h
index e235f63..0be7a69 100644
--- a/include/command.h
+++ b/include/command.h
@@ -76,6 +76,8 @@ void barebox_cmd_usage(struct command *cmdtp);
 
 #endif	/* __ASSEMBLY__ */
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
 #define Struct_Section  __attribute__ ((unused,section (".barebox_cmd")))
 
 #define BAREBOX_CMD_START(_name)							\
@@ -93,6 +95,8 @@ const struct command __barebox_cmd_##_name						\
 #define BAREBOX_CMD_HELP(text)
 #endif
 
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
 int register_command(struct command *);
 
 #endif	/* __COMMAND_H */
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:16 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:16 +0200
Subject: [PATCH 24/32] doc: unify documentation for 'ls'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-25-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    1 +
 commands/ls.c              |    9 +++++----
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index f3b5028..63ed480 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -16,6 +16,7 @@
 @li @subpage export_command
 @li @subpage tftp_command
 @li @subpage loadenv_command
+ at li @subpage ls_command
 @li @subpage mount_command
 @li @subpage printenv_command
 @li @subpage protect_command
diff --git a/commands/ls.c b/commands/ls.c
index a02ccfe..2005178 100644
--- a/commands/ls.c
+++ b/commands/ls.c
@@ -194,10 +194,11 @@ static int do_ls(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_ls_help[] =
-"Usage: ls [OPTION]... [FILE]...\n"
-"List information about the FILEs (the current directory by default).\n"
-"  -R  list subdirectories recursively\n";
+BAREBOX_CMD_HELP_START(ls)
+BAREBOX_CMD_HELP_USAGE("ls [OPTION]... [FILE]...\n")
+BAREBOX_CMD_HELP_SHORT("List information about the FILEs (the current directory by default).\n")
+BAREBOX_CMD_HELP_OPT  ("-R",  "list subdirectories recursively\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(ls)
 	.cmd		= do_ls,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:21 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:21 +0200
Subject: [PATCH 29/32] doc: add documentation for 'bootm'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-30-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    1 +
 commands/bootm.c           |   18 ++++++------------
 2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 28ddff4..c1471fb 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -3,6 +3,7 @@
 
 @li @subpage addpart_command
 @li @subpage bmp_command
+ at li @subpage bootm_command
 @li @subpage cat_command
 @li @subpage cd_command
 @li @subpage clear_command
diff --git a/commands/bootm.c b/commands/bootm.c
index 0d3649f..5cf97e8 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -368,18 +368,12 @@ err_out:
 	return 1;
 }
 
-static const __maybe_unused char cmd_bootm_help[] =
-"Usage: bootm [OPTION] image\n"
-"Boot application image\n"
-" -n             do not verify the images (speeds up boot process)\n"
-" -h             show advanced options\n";
-
-
-BAREBOX_CMD_START(bootm)
-	.cmd		= do_bootm,
-	.usage		= "boot application image",
-	BAREBOX_CMD_HELP(cmd_bootm_help)
-BAREBOX_CMD_END
+BAREBOX_CMD_HELP_START(bootm)
+BAREBOX_CMD_HELP_USAGE("bootm [OPTION] image\n")
+BAREBOX_CMD_HELP_SHORT("Boot an application image.\n")
+BAREBOX_CMD_HELP_OPT  ("-n",  "do not verify the images (speeds up boot process)")
+BAREBOX_CMD_HELP_END
+
 
 #ifdef CONFIG_CMD_IMI
 static int do_iminfo(struct command *cmdtp, int argc, char *argv[])
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:22 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:22 +0200
Subject: [PATCH 30/32] doc: unify documentation for 'addpart'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-31-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 commands/partition.c |   45 ++++++++++++---------------------------------
 1 files changed, 12 insertions(+), 33 deletions(-)

diff --git a/commands/partition.c b/commands/partition.c
index a1edcf6..89fb519 100644
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -149,19 +149,18 @@ static int do_addpart(struct command * cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_addpart_help[] =
-"Usage: addpart <device> <partition description>\n"
-"\n"
-"addpart adds a partition description to a device. The partition description\n"
-"has the form\n"
-"size1[@offset1](name1)[ro],size2[@offset2](name2)[ro],...\n"
-"<device> is the device name under. Size and offset can be given in decimal\n"
-"or - if prefixed with 0x in hex. Both can have an optional suffix K,M,G.\n"
-"The size of the last partition can be specified as '-' for the remaining\n"
-"space of the device.\n"
-"This format is the same as used in the Linux kernel for cmdline mtd partitions.\n"
-"\n"
-"Note: That this command has to be reworked and will probably change it's API.";
+BAREBOX_CMD_HELP_START(addpart)
+BAREBOX_CMD_HELP_USAGE("addpart <device> <part_desc>\n")
+BAREBOX_CMD_HELP_SHORT("Add a partition description to a device.\n")
+BAREBOX_CMD_HELP_OPT  ("<device>",    "device being worked on\n")
+BAREBOX_CMD_HELP_OPT  ("<part_desc>", "size1[@offset1](name1)[ro],size2[@offset2](name2)[ro],...\n")
+BAREBOX_CMD_HELP_TEXT ("Size and offset can be given in decimal hex (prefixed with 0x).\n")
+BAREBOX_CMD_HELP_TEXT ("Both can have an optional suffix K, M or G. The size of the last partition\n")
+BAREBOX_CMD_HELP_TEXT ("can be specified as '-' for the remaining space on the device. This format\n")
+BAREBOX_CMD_HELP_TEXT ("is the same as used by the Linux kernel or cmdline mtd partitions.\n")
+BAREBOX_CMD_HELP_TEXT ("\n")
+BAREBOX_CMD_HELP_TEXT ("@note This command has to be reworked and will probably change it's API.\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(addpart)
 	.cmd = do_addpart,
@@ -169,26 +168,6 @@ BAREBOX_CMD_START(addpart)
 	BAREBOX_CMD_HELP(cmd_addpart_help)
 BAREBOX_CMD_END
 
-/** @page addpart_command addpart Add a partition to a device
- *
- * Usage is: addpart \<device> \<partition description>
- *
- * Adds a partition description to a device. The partition description has the
- * form
- *
- * size1[\@offset1](name1)[ro],size2[\@offset2](name2)[ro],...
- *
- * \<device> is the device name under. Size and offset can be given in decimal
- * or - if prefixed with 0x - in hex. Both can have an optional suffix K,M,G.
- * The size of the last partition can be specified as '-' for the remaining
- * space of the device.
- *
- * @note The format is the same as used in the Linux kernel for cmdline mtd
- * partitions.
- *
- * @note This command has to be reworked and will probably change it's API.
- */
-
 static int do_delpart(struct command * cmdtp, int argc, char *argv[])
 {
 	int i, err;
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:11 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:11 +0200
Subject: [PATCH 19/32] doc: add macros to unify command help with doxygen
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-20-git-send-email-r.schwebel@pengutronix.de>

Currently we have duplicated all the information that appears online in
'help <command>' and in the doxygen documentation. This patch adds some
infrastructure to specify help texts only once and re-use them for the
integrated help as well as for the manual.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Doxyfile                |    2 +-
 include/command.h       |    9 ++++
 scripts/doxy_filter.awk |  101 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+), 1 deletions(-)
 create mode 100644 scripts/doxy_filter.awk

diff --git a/Doxyfile b/Doxyfile
index 912abc1..23f3e43 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -575,7 +575,7 @@ IMAGE_PATH             =
 # to standard output.  If FILTER_PATTERNS is specified, this tag will be
 # ignored.
 
-INPUT_FILTER           =
+INPUT_FILTER           = "awk -f scripts/doxy_filter.awk"
 
 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
 # basis.  Doxygen will compare the file name with each pattern and apply the
diff --git a/include/command.h b/include/command.h
index 0be7a69..e221546 100644
--- a/include/command.h
+++ b/include/command.h
@@ -89,6 +89,15 @@ const struct command __barebox_cmd_##_name						\
 #define BAREBOX_CMD_END					\
 };
 
+#define BAREBOX_CMD_HELP_START(_name) \
+static const __maybe_unused char cmd_##_name##_help[] =
+
+#define BAREBOX_CMD_HELP_USAGE(_name) "Usage: " _name
+#define BAREBOX_CMD_HELP_SHORT(_text) _text
+#define BAREBOX_CMD_HELP_OPT(_opt, _desc) _opt "\t" _desc
+#define BAREBOX_CMD_HELP_TEXT(_text)
+#define BAREBOX_CMD_HELP_END ;
+
 #ifdef CONFIG_LONGHELP
 #define BAREBOX_CMD_HELP(text)	.help = text,
 #else
diff --git a/scripts/doxy_filter.awk b/scripts/doxy_filter.awk
new file mode 100644
index 0000000..0f6e891
--- /dev/null
+++ b/scripts/doxy_filter.awk
@@ -0,0 +1,101 @@
+#!/usr/bin/awk
+
+/BAREBOX_CMD_HELP_START[[:space:]]*\((.*)\)/ {
+
+	this_opt = 0;
+	my_usage = "";
+	my_short = "";
+	my_cmd = gensub("BAREBOX_CMD_HELP_START[[:space:]]*\\((.*)\\)", "\\1", "g");
+	this_text = 0;
+	delete(my_text);
+	delete(my_opts);
+	next;
+}
+
+/BAREBOX_CMD_HELP_USAGE[[:space:]]*\((.*)\)/ {
+
+	$0 = gensub("<", "\\&lt;", "g");
+	$0 = gensub(">", "\\&gt;", "g");
+	$0 = gensub("BAREBOX_CMD_HELP_USAGE[[:space:]]*\\((.*)\\)", "\\1", "g");
+	$0 = gensub("\\\\n", "", "g");
+	my_usage = gensub("\"", "", "g");
+	next;
+
+}
+
+/BAREBOX_CMD_HELP_SHORT[[:space:]]*\((.*)\)/ {
+
+	$0 = gensub("<", "\\&lt;", "g");
+	$0 = gensub(">", "\\&gt;", "g");
+	$0 = gensub("BAREBOX_CMD_HELP_SHORT[[:space:]]*\\((.*)\\)", "\\1", "g");
+	$0 = gensub("\\\\n", "", "g");
+	my_short = gensub("\"", "", "g");
+	next;
+
+}
+
+/BAREBOX_CMD_HELP_OPT[[:space:]]*\([[:space:]]*(.*)[[:space:]]*,[[:space:]]*(.*)[[:space:]]*\)/ {
+
+	$0 = gensub("<", "\\&lt;", "g");
+	$0 = gensub(">", "\\&gt;", "g");
+	$0 = gensub("BAREBOX_CMD_HELP_OPT[[:space:]]*\\([[:space:]]*\"*(.*)\"[[:space:]]*,[[:space:]]*\"(.*)\"[[:space:]]*\\)", \
+		"<tr><td><tt> \\1 </tt></td><td>\\&nbsp;\\&nbsp;\\&nbsp;</td><td> \\2 </td></tr>", "g");
+	$0 = gensub("\\\\n", "", "g");
+	my_opts[this_opt] = gensub("\"", "", "g");
+	this_opt ++;
+	next;
+}
+
+/BAREBOX_CMD_HELP_TEXT[[:space:]]*\((.*)\)/ {
+
+	$0 = gensub("<", "\\&lt;", "g");
+	$0 = gensub(">", "\\&gt;", "g");
+	$0 = gensub("BAREBOX_CMD_HELP_TEXT[[:space:]]*\\((.*)\\)", "\\1", "g");
+	$0 = gensub("\\\\n", "<br>", "g");
+	my_text[this_text] = gensub("\"", "", "g");
+	this_text ++;
+	next;
+}
+
+/BAREBOX_CMD_HELP_END/ {
+
+	printf "/**\n";
+	printf " * @page " my_cmd "_command " my_cmd "\n";
+	printf " *\n";
+	printf " * \\par Usage:\n";
+	printf " * " my_usage "\n";
+	printf " *\n";
+
+	if (this_opt != 0) {
+		printf " * \\par Options:\n";
+		printf " *\n";
+		printf " * <table border=\"0\" cellpadding=\"0\">\n";
+		n = asorti(my_opts, my_opts_sorted);
+		for (i=1; i<=n; i++) {
+			printf " * " my_opts[my_opts_sorted[i]] "\n";
+		}
+		printf " * </table>\n";
+		printf " *\n";
+	}
+
+	printf " * " my_short "\n";
+	printf " *\n";
+
+	n = asorti(my_text, my_text_sorted);
+	if (n > 0) {
+		for (i=1; i<=n; i++) {
+			printf " * " my_text[my_text_sorted[i]] "\n";
+		}
+		printf " *\n";
+	}
+
+	printf " */\n";
+	next;
+}
+
+/^.*$/ {
+
+	print $0;
+
+}
+
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:24 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:24 +0200
Subject: [PATCH 32/32] doc: unify documentation for 'delpart'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-33-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 commands/partition.c |   13 ++++---------
 1 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/commands/partition.c b/commands/partition.c
index 89fb519..7c7f5ae 100644
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -183,9 +183,10 @@ static int do_delpart(struct command * cmdtp, int argc, char *argv[])
 	return 1;
 }
 
-static const __maybe_unused char cmd_delpart_help[] =
-"Usage: delpart FILE...\n"
-"Delete partitions previously added to a device with addpart.\n";
+BAREBOX_CMD_HELP_START(delpart)
+BAREBOX_CMD_HELP_USAGE("delpart FILE...\n")
+BAREBOX_CMD_HELP_SHORT("Delete partitions previously added to a device with addpart.\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(delpart)
 	.cmd = do_delpart,
@@ -193,9 +194,3 @@ BAREBOX_CMD_START(delpart)
 	BAREBOX_CMD_HELP(cmd_delpart_help)
 BAREBOX_CMD_END
 
-/** @page delpart_command delpart Delete a partition
- *
- * Usage is: delpart \<partions>
- *
- * Delete a partition previously added to a device with addpart.
- */
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:15 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:15 +0200
Subject: [PATCH 23/32] doc: add documentation for 'dfu'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-24-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    1 +
 commands/dfu.c             |   21 +++++++++++----------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index cfff884..f3b5028 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -10,6 +10,7 @@
 @li @subpage crc_command
 @li @subpage delpart_command
 @li @subpage devinfo_command
+ at li @subpage dfu_command
 @li @subpage edit_command
 @li @subpage erase_command
 @li @subpage export_command
diff --git a/commands/dfu.c b/commands/dfu.c
index 66fd6ea..6750130 100644
--- a/commands/dfu.c
+++ b/commands/dfu.c
@@ -162,16 +162,17 @@ out:
 	return 1;
 }
 
-static const __maybe_unused char cmd_dfu_help[] =
-"Usage: dfu [OPTION]... description\n"
-"start dfu firmware update\n"
-" -m <str> Manufacturer string (barebox)\n"
-" -p <str> product string (" CONFIG_BOARDINFO ")\n"
-" -V <id>  vendor id\n"
-" -P <id>  product id\n"
-"description has the form\n"
-"device1(name1)[sr],device2(name2)[sr]\n"
-"where s is for save mode and r for read back of firmware\n";
+BAREBOX_CMD_HELP_START(dfu)
+BAREBOX_CMD_HELP_USAGE("dfu [OPTIONS] <description>\n")
+BAREBOX_CMD_HELP_SHORT("Start firmware update with the Device Firmware Update (DFU) protocol.")
+BAREBOX_CMD_HELP_OPT  ("-m <str>",  "Manufacturer string (barebox)\n")
+BAREBOX_CMD_HELP_OPT  ("-p <str>",  "product string (" CONFIG_BOARDINFO ")\n")
+BAREBOX_CMD_HELP_OPT  ("-V <id>",   "vendor id\n")
+BAREBOX_CMD_HELP_OPT  ("-P <id>",   "product id\n")
+BAREBOX_CMD_HELP_TEXT ("<description> has the form:")
+BAREBOX_CMD_HELP_TEXT ("device1(name1)[sr],device2(name2)[sr]")
+BAREBOX_CMD_HELP_TEXT ("where "s" means "safe mode" and "r" readback of firmware.")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(dfu)
 	.cmd		= do_dfu,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:23 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:23 +0200
Subject: [PATCH 31/32] doc: unify documentation for 'cp'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-32-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 commands/cp.c |   24 ++++++++----------------
 1 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/commands/cp.c b/commands/cp.c
index 2c35ba1..a99c9b5 100644
--- a/commands/cp.c
+++ b/commands/cp.c
@@ -51,7 +51,7 @@ static int do_cp(struct command *cmdtp, int argc, char *argv[])
 		if (S_ISDIR(statbuf.st_mode))
 			last_is_dir = 1;
 	}
-	
+
 	if (argc > 3 && !last_is_dir) {
 		printf("cp: target `%s' is not a directory\n", argv[argc - 1]);
 		return 1;
@@ -77,10 +77,13 @@ out:
 	return ret;
 }
 
-static const __maybe_unused char cmd_cp_help[] =
-"Usage: cp <source> <destination>\n"
-"cp copies file <source> to <destination>.\n"
-"This command is file based only. See memcpy for memory copy\n";
+BAREBOX_CMD_HELP_START(cp)
+BAREBOX_CMD_HELP_USAGE("cp <source> <destination>\n")
+BAREBOX_CMD_HELP_SHORT("cp copies file <source> to <destination>.\n")
+BAREBOX_CMD_HELP_TEXT ("This command is file based. If you want to copy between memory blocks,\n")
+BAREBOX_CMD_HELP_TEXT ("use 'memcpy'.\n")
+
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(cp)
 	.cmd		= do_cp,
@@ -88,14 +91,3 @@ BAREBOX_CMD_START(cp)
 	BAREBOX_CMD_HELP(cmd_cp_help)
 BAREBOX_CMD_END
 
-/**
- * @page cp_command cp: Copy file
- *
- * Usage: cp \<source> [\<source>] \<destination>
- *
- * \c cp copies file \<source> to \<destination>
- *
- * Currently only this form is supported and you have to specify the exact
- * target filename (not a target directory).\n
- * This command is file based only. See memcpy for generic memory copy
- */
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:13 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:13 +0200
Subject: [PATCH 21/32] doc: add documentation for 'clear'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-22-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    1 +
 commands/clear.c           |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index da95e85..f829a3c 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -5,6 +5,7 @@
 @li @subpage bmp_command
 @li @subpage cat_command
 @li @subpage cd_command
+ at li @subpage clear_command
 @li @subpage cp_command
 @li @subpage delpart_command
 @li @subpage devinfo_command
diff --git a/commands/clear.c b/commands/clear.c
index 7589a0c..6a6b6c5 100644
--- a/commands/clear.c
+++ b/commands/clear.c
@@ -31,6 +31,11 @@ static int do_clear(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(clear)
+BAREBOX_CMD_HELP_USAGE("clear\n")
+BAREBOX_CMD_HELP_SHORT("Clear the screen.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(clear)
 	.cmd		= do_clear,
 	.usage		= "clear screen",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:44:58 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:44:58 +0200
Subject: [PATCH 06/32] Doxyfile: remove unused features
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-7-git-send-email-r.schwebel@pengutronix.de>

Disable callgraph and friends, we don't use them anyway.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Doxyfile |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Doxyfile b/Doxyfile
index 21a6212..37597f6 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -1210,7 +1210,7 @@ INCLUDED_BY_GRAPH      = NO
 # So in most cases it will be better to enable call graphs for selected
 # functions only using the \callgraph command.
 
-CALL_GRAPH             = YES
+CALL_GRAPH             = NO
 
 # If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
 # generate a caller dependency graph for every global function or class method.
@@ -1218,19 +1218,19 @@ CALL_GRAPH             = YES
 # So in most cases it will be better to enable caller graphs for selected
 # functions only using the \callergraph command.
 
-CALLER_GRAPH           = YES
+CALLER_GRAPH           = NO
 
 # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
 # will graphical hierarchy of all classes instead of a textual one.
 
-GRAPHICAL_HIERARCHY    = YES
+GRAPHICAL_HIERARCHY    = NO
 
 # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
 # then doxygen will show the dependencies a directory has on other directories
 # in a graphical way. The dependency relations are determined by the #include
 # relations between the files in the directories.
 
-DIRECTORY_GRAPH        = YES
+DIRECTORY_GRAPH        = NO
 
 # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
 # generated by dot. Possible values are png, jpg, or gif
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:20 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:20 +0200
Subject: [PATCH 28/32] doc: unify documentation for 'edit'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-29-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 commands/edit.c |   36 +++++++++++-------------------------
 1 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/commands/edit.c b/commands/edit.c
index c2ab877..d35097e 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -550,35 +550,21 @@ out:
 
 static const char *edit_aliases[] = { "sedit", NULL};
 
-static const __maybe_unused char cmd_edit_help[] =
-"Usage: (s)edit <file>\n"
-"This is a very small editor. Its only features are moving the cursor with\n"
-"the usual keys and typing characters.\n"
-"<ctrl-c> quits the editor without saving,\n"
-"<ctrl-d> quits the editor with saving the current file.\n"
-"\n"
-"If called as sedit the editor uses ansi codes to scroll the screen.\n";
-
-static const __maybe_unused char cmd_edit_usage[] = "edit a file";
+BAREBOX_CMD_HELP_START(edit)
+BAREBOX_CMD_HELP_USAGE("(s)edit <file>\n")
+BAREBOX_CMD_HELP_SHORT("A small editor. <ctrl-c> is exit, <ctrl-d> exit-with-save.\n")
+BAREBOX_CMD_HELP_TEXT ("This is a very small text editor. You can move the cursor around\n")
+BAREBOX_CMD_HELP_TEXT ("with the usual keys and type characters.\n")
+BAREBOX_CMD_HELP_TEXT ("<ctrl-c> quits the editor without saving,\n")
+BAREBOX_CMD_HELP_TEXT ("<ctrl-d> quits the editor with saving the current file.\n")
+BAREBOX_CMD_HELP_TEXT (" \n")
+BAREBOX_CMD_HELP_TEXT ("If called as sedit, the editor uses ansi codes to scroll the screen.\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(edit)
 	.cmd		= do_edit,
 	.aliases	= edit_aliases,
-	.usage		= cmd_edit_usage,
+	.usage		= "Usage: (s)edit <file>",
 	BAREBOX_CMD_HELP(cmd_edit_help)
 BAREBOX_CMD_END
 
-
-/**
- * @page edit_command edit (editor)
- *
- * Usage is: [s]edit \<file\>
- *
- * This is a very small editor. It's only features are moving the cursor with
- * the usual keys and typing characters.
- *
- * \b \<ctrl-c\> quits the editor without saving,\n
- * \b \<ctrl-d\> quits the editor with saving the current file.
- *
- * If called as \c sedit the editor uses ansi codes to scroll the screen.
- */
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:14 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:14 +0200
Subject: [PATCH 22/32] doc: add documentation for 'crc32'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-23-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    1 +
 commands/crc.c             |   15 +++++++--------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index f829a3c..cfff884 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -7,6 +7,7 @@
 @li @subpage cd_command
 @li @subpage clear_command
 @li @subpage cp_command
+ at li @subpage crc_command
 @li @subpage delpart_command
 @li @subpage devinfo_command
 @li @subpage edit_command
diff --git a/commands/crc.c b/commands/crc.c
index d3e0865..0873a1c 100644
--- a/commands/crc.c
+++ b/commands/crc.c
@@ -143,19 +143,18 @@ static int do_crc(struct command *cmdtp, int argc, char *argv[])
 	return err;
 }
 
-static const __maybe_unused char cmd_crc_help[] =
-"Usage: crc32 [OPTION] [AREA]\n"
-"Calculate a crc32 checksum of a memory area\n"
-"Options:\n"
-"  -f <file>   Use file instead of memory\n"
+BAREBOX_CMD_HELP_START(crc)
+BAREBOX_CMD_HELP_USAGE("crc32 [OPTION] [AREA]\n")
+BAREBOX_CMD_HELP_SHORT("Calculate a crc32 checksum of a memory area.\n")
+BAREBOX_CMD_HELP_OPT  ("-f <file>", "Use file instead of memory.\n")
 #ifdef CONFIG_CMD_CRC_CMP
-"  -F <file>   Use file to compare\n"
+BAREBOX_CMD_HELP_OPT  ("-F <file>", "Use file to compare.\n")
 #endif
-"  -v <crc>    Verfify\n";
+BAREBOX_CMD_HELP_OPT  ("-v <crc>",  "Verfify\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(crc32)
 	.cmd		= do_crc,
 	.usage		= "crc32 checksum calculation",
 	BAREBOX_CMD_HELP(cmd_crc_help)
 BAREBOX_CMD_END
-
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:44:56 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:44:56 +0200
Subject: [PATCH 04/32] Doxyfile: add exclude rules
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-5-git-send-email-r.schwebel@pengutronix.de>

The mtd stuff copied from linux and elsewhere contains commands which
are not understood by a 'real' doxygen. For now, we add exclude rules.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Doxyfile |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/Doxyfile b/Doxyfile
index 4fc9834..46f086c 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -515,7 +515,9 @@ RECURSIVE              = YES
 # excluded from the INPUT source files. This way you can easily exclude a
 # subdirectory from a directory tree whose root is specified with the INPUT tag.
 
-EXCLUDE                =
+EXCLUDE                = drivers/mtd/ubi \
+                         include/mtd \
+                         include/linux/mtd
 
 # The EXCLUDE_SYMLINKS tag can be used select whether or not files or
 # directories that are symbolic links (a Unix filesystem feature) are excluded
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:44:59 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:44:59 +0200
Subject: [PATCH 07/32] Doxyfile: enable assembler files
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-8-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Doxyfile |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/Doxyfile b/Doxyfile
index 37597f6..912abc1 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -503,6 +503,7 @@ INPUT_ENCODING         = UTF-8
 
 FILE_PATTERNS          = *.c \
                          *.h \
+                         *.S \
                          *.dox
 
 # The RECURSIVE tag can be used to turn specify whether or not subdirectories
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:44:52 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:44:52 +0200
Subject: Documentation Updates
Message-ID: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>

This series:

- switches doxygen to quiet output, in order to actually see the
  warnings

- fixes most of the warnings I could address; some are left and have to
  be discussed with the involved developers

- introduces a new set of macros to unify the online and offline
  documentation

- starts switching commands to this new mechanics.

The following changes since commit 298252bdef6a97d988f83f5ea554a2262c529ae2:

  process_escape_sequence: Add missing include (2010-10-21 22:21:42 +0200)

are available in the git repository at:
  http://git.pengutronix.de/git/rsc/barebox for-mainline

Robert Schwebel (32):
      reset_cpu: unify declaration
      Doxyfile: enable quiet output
      Doxyfile: remove obsolete boards directory
      Doxyfile: add exclude rules
      Doxyfile: remove non-existing directories
      Doxyfile: remove unused features
      Doxyfile: enable assembler files
      doc: let doxygen find some assembler functions
      doc: remove nonexisting command
      doc: remove reference to non-existing documentation
      doc: eliminate nonexisting reference
      doc: add missing quoting
      doc: fix typo
      doc: mark code explicitely
      doc: avoid that doxygen parses magic in command.h
      doc: fix wrongly named parameter
      doc: fix parameter name in mci-core
      doc: silence doxygen warnings
      doc: add macros to unify command help with doxygen
      doc: add documentation for 'bmp'
      doc: add documentation for 'clear'
      doc: add documentation for 'crc32'
      doc: add documentation for 'dfu'
      doc: unify documentation for 'ls'
      doc: unify documentation for 'cat'
      doc: unify documentation for 'cd'
      doc: add documentation for 'echo'
      doc: unify documentation for 'edit'
      doc: add documentation for 'bootm'
      doc: unify documentation for 'addpart'
      doc: unify documentation for 'cp'
      doc: unify documentation for 'delpart'

 Documentation/commands.dox            |    8 ++-
 Documentation/developers_manual.dox   |    1 -
 Documentation/users_manual.dox        |    1 -
 Doxyfile                              |   22 ++++---
 arch/arm/mach-at91/at91sam926x_time.c |    2 +-
 arch/arm/mach-ep93xx/clocksource.c    |    2 +-
 arch/arm/mach-imx/clocksource.c       |    2 +-
 arch/arm/mach-omap/arch-omap.dox      |    6 ++-
 arch/arm/mach-omap/omap3_generic.c    |    4 +-
 arch/arm/mach-s3c24xx/lowlevel-init.S |    2 +-
 arch/arm/mach-stm/reset-imx23.c       |    2 +-
 arch/blackfin/lib/cpu.c               |    2 +-
 arch/m68k/mach-mcfv4e/mcf_reset_cpu.c |    2 +-
 arch/ppc/mach-mpc5xxx/cpu.c           |    2 +-
 arch/sandbox/os/common.c              |    2 +-
 arch/x86/boot/boot_hdisk.S            |    2 -
 arch/x86/boot/boot_main.S             |    2 -
 arch/x86/boot/pmjump.S                |    2 -
 arch/x86/lib/memory16.S               |    2 -
 arch/x86/lib/traveler.S               |    3 -
 arch/x86/mach-x86.dox                 |    2 +-
 commands/bmp.c                        |   16 +++---
 commands/bootm.c                      |   18 ++----
 commands/cat.c                        |   19 ++----
 commands/cd.c                         |   17 ++----
 commands/clear.c                      |    5 ++
 commands/cp.c                         |   24 +++-----
 commands/crc.c                        |   15 ++---
 commands/dfu.c                        |   21 ++++---
 commands/echo.c                       |   10 +++
 commands/edit.c                       |   36 ++++--------
 commands/ls.c                         |    9 ++-
 commands/partition.c                  |   58 +++++--------------
 common/kallsyms.c                     |    4 +
 drivers/mci/mci-core.c                |    2 +-
 include/command.h                     |   13 ++++
 lib/parameter.c                       |    2 +-
 scripts/doxy_filter.awk               |  101 +++++++++++++++++++++++++++++++++
 38 files changed, 254 insertions(+), 189 deletions(-)
 create mode 100644 scripts/doxy_filter.awk



From r.schwebel at pengutronix.de  Fri Oct 22 12:44:53 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:44:53 +0200
Subject: [PATCH 01/32] reset_cpu: unify declaration
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-2-git-send-email-r.schwebel@pengutronix.de>

include/common.h declares this as "unsigned long addr", so we unify it.
This also silences a doxygen warning.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 arch/arm/mach-at91/at91sam926x_time.c |    2 +-
 arch/arm/mach-ep93xx/clocksource.c    |    2 +-
 arch/arm/mach-imx/clocksource.c       |    2 +-
 arch/arm/mach-omap/omap3_generic.c    |    4 ++--
 arch/arm/mach-stm/reset-imx23.c       |    2 +-
 arch/blackfin/lib/cpu.c               |    2 +-
 arch/m68k/mach-mcfv4e/mcf_reset_cpu.c |    2 +-
 arch/ppc/mach-mpc5xxx/cpu.c           |    2 +-
 arch/sandbox/os/common.c              |    2 +-
 9 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 84df1a1..c1b42f9 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -73,7 +73,7 @@ core_initcall(clocksource_init);
 /*
  * Reset the cpu through the reset controller
  */
-void __noreturn reset_cpu (unsigned long ignored)
+void __noreturn reset_cpu (unsigned long addr)
 {
 	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY |
 				     AT91_RSTC_PROCRST |
diff --git a/arch/arm/mach-ep93xx/clocksource.c b/arch/arm/mach-ep93xx/clocksource.c
index 3aa8e14..a1e315d 100644
--- a/arch/arm/mach-ep93xx/clocksource.c
+++ b/arch/arm/mach-ep93xx/clocksource.c
@@ -72,7 +72,7 @@ core_initcall(clocksource_init);
 /*
  * Reset the cpu
  */
-void __noreturn reset_cpu(unsigned long ignored)
+void __noreturn reset_cpu(unsigned long addr)
 {
 	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
 	uint32_t value;
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index b8101e9..5b1bad5 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -118,7 +118,7 @@ core_initcall(clocksource_init);
 /*
  * Reset the cpu by setting up the watchdog timer and let it time out
  */
-void __noreturn reset_cpu (unsigned long ignored)
+void __noreturn reset_cpu (unsigned long addr)
 {
 	/* Disable watchdog and set Time-Out field to 0 */
 	writew(0x0, IMX_WDT_BASE + WDOG_WCR);
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index 9893145..f780794 100644
--- a/arch/arm/mach-omap/omap3_generic.c
+++ b/arch/arm/mach-omap/omap3_generic.c
@@ -52,11 +52,11 @@
  *
  * In case of crashes, reset the CPU
  *
- * @param[in] addr -Cause of crash
+ * @param addr Cause of crash
  *
  * @return void
  */
-void __noreturn reset_cpu(ulong addr)
+void __noreturn reset_cpu(unsigned long addr)
 {
 	/* FIXME: Enable WDT and cause reset */
 	hang();
diff --git a/arch/arm/mach-stm/reset-imx23.c b/arch/arm/mach-stm/reset-imx23.c
index db0b3f2..b35f796 100644
--- a/arch/arm/mach-stm/reset-imx23.c
+++ b/arch/arm/mach-stm/reset-imx23.c
@@ -48,7 +48,7 @@
  * TODO There is a much easier way to reset the CPU: Refer bit 2 in
  *       the HW_CLKCTRL_RESET register, data sheet page 106/4-30
  */
-void __noreturn reset_cpu (unsigned long ignored)
+void __noreturn reset_cpu (unsigned long addr)
 {
 	writel(WDOG_COUNTER_RATE, IMX_WDT_BASE + HW_RTC_WATCHDOG);
 	writel(BM_RTC_CTRL_WATCHDOGEN, IMX_WDT_BASE + HW_RTC_CTRL_SET);
diff --git a/arch/blackfin/lib/cpu.c b/arch/blackfin/lib/cpu.c
index f96d22d..aed0864 100644
--- a/arch/blackfin/lib/cpu.c
+++ b/arch/blackfin/lib/cpu.c
@@ -32,7 +32,7 @@
 #include <asm/cpu.h>
 #include <init.h>
 
-void __noreturn reset_cpu(ulong ignored)
+void __noreturn reset_cpu(unsigned long addr)
 {
 	icache_disable();
 
diff --git a/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
index 3b1a25b..d4659d2 100644
--- a/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
+++ b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
@@ -27,7 +27,7 @@
 /**
  * Reset the cpu by setting up the watchdog timer and let it time out
  */
-void __noreturn reset_cpu (unsigned long ignored)
+void __noreturn reset_cpu (unsigned long addr)
 {
         while ( ignored ) { ; };
 
diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu.c
index 7ee1954..4d08c55 100644
--- a/arch/ppc/mach-mpc5xxx/cpu.c
+++ b/arch/ppc/mach-mpc5xxx/cpu.c
@@ -71,7 +71,7 @@ int checkcpu (void)
 
 /* ------------------------------------------------------------------------- */
 
-void __noreturn reset_cpu (unsigned long unused)
+void __noreturn reset_cpu (unsigned long addr)
 {
 	ulong msr;
 	/* Interrupts and MMU off */
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index 89b2e5c..287be0d 100644
--- a/arch/sandbox/os/common.c
+++ b/arch/sandbox/os/common.c
@@ -138,7 +138,7 @@ uint64_t linux_get_time(void)
 	return now;
 }
 
-void __attribute__((noreturn)) reset_cpu(int unused)
+void __attribute__((noreturn)) reset_cpu(unsigned long addr)
 {
 	cookmode();
 	exit(0);
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:44:55 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:44:55 +0200
Subject: [PATCH 03/32] Doxyfile: remove obsolete boards directory
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-4-git-send-email-r.schwebel@pengutronix.de>

This directory does not exist any more, so we can remove it. Silences a
doxygen warning.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Doxyfile |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/Doxyfile b/Doxyfile
index 6c04afe..4fc9834 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -483,7 +483,6 @@ INPUT                  = Documentation \
                          drivers \
                          commands \
                          common \
-                         board \
                          lib \
                          scripts/setupmbr \
 			 net
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:06 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:06 +0200
Subject: [PATCH 14/32] doc: mark code explicitely
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-15-git-send-email-r.schwebel@pengutronix.de>

Silence this warning:
arch/arm/mach-omap/arch-omap.dox:51: Warning: explicit link request to 'define' could not be resolved

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 arch/arm/mach-omap/arch-omap.dox |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap/arch-omap.dox b/arch/arm/mach-omap/arch-omap.dox
index df16b7b..9c90b4f 100644
--- a/arch/arm/mach-omap/arch-omap.dox
+++ b/arch/arm/mach-omap/arch-omap.dox
@@ -50,7 +50,11 @@ All basic devices you'd like to register should be put here with postcore_initca
 All OMAP common headers are located here. Where we have to incorporate a OMAP variant specific header, add a omapX_function_name.h.
 @warning Do not add board specific header files/information here. Put them in mach-omap.
 
-include/asm-arm/arch-omap/silicon.h contains includes for omapX-silicon.h which defines the base addresses for the peripherals on that platform. the usual convention is to use #define OMAP_SOMETHING_BASE to allow re-use.
+include/asm-arm/arch-omap/silicon.h contains includes for omapX-silicon.h which defines the base addresses for the peripherals on that platform. the usual convention is to use
+ at code
+#define OMAP_SOMETHING_BASE
+ at endcode
+to allow re-use.
 
 @section board_omap arch/arm/boards/omap directory guidelines
 All Board specific files go here. In u-boot, we always had to use common config file which is shared by other drivers to get serial, ethernet baseaddress etc.. we can easily use the device_d structure to handle it with @a barebox. This is more like programming for Linux kernel - it is pretty easy.
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:44:57 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:44:57 +0200
Subject: [PATCH 05/32] Doxyfile: remove non-existing directories
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-6-git-send-email-r.schwebel@pengutronix.de>

The example and image directories are currently not used, so we remove
the references from the Doxyfile. Silences a doxygen warning.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Doxyfile |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Doxyfile b/Doxyfile
index 46f086c..21a6212 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -544,7 +544,7 @@ EXCLUDE_SYMBOLS        =
 # directories that contain example code fragments that are included (see
 # the \include command).
 
-EXAMPLE_PATH           = Documentation/examples/
+EXAMPLE_PATH           =
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@@ -564,7 +564,7 @@ EXAMPLE_RECURSIVE      = NO
 # directories that contain image that are included in the documentation (see
 # the \image command).
 
-IMAGE_PATH             = Documentation/images/
+IMAGE_PATH             =
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:03 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:03 +0200
Subject: [PATCH 11/32] doc: eliminate nonexisting reference
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-12-git-send-email-r.schwebel@pengutronix.de>

Silence this warning:
arch/architecture.dox:89: Warning: unable to resolve reference to `dev_x86_mach' for \ref command

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/developers_manual.dox |    1 -
 arch/x86/mach-x86.dox               |    2 +-
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/Documentation/developers_manual.dox b/Documentation/developers_manual.dox
index 620905e..2f7d360 100644
--- a/Documentation/developers_manual.dox
+++ b/Documentation/developers_manual.dox
@@ -20,6 +20,5 @@ This part of the documentation is intended for developers of @a barebox.
 @li @subpage barebox_simul
 @li @subpage io_access_functions
 @li @subpage mcfv4e_MCDlib
- at li @subpage x86_runtime
 
 */
diff --git a/arch/x86/mach-x86.dox b/arch/x86/mach-x86.dox
index fc5b85a..661e905 100644
--- a/arch/x86/mach-x86.dox
+++ b/arch/x86/mach-x86.dox
@@ -2,7 +2,7 @@
  * how to integrate a new CPU (MACH) into this part of the barebox tree
  */
 
-/** @page x86_runtime barebox on x86 at runtime
+/** @page dev_x86_mach barebox on x86 at runtime
 
 @section mach_x86_memory_layout barebox's memory layout (BIOS based)
 
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:08 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:08 +0200
Subject: [PATCH 16/32] doc: fix wrongly named parameter
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-17-git-send-email-r.schwebel@pengutronix.de>

Silence this warning:

lib/parameter.c:85: Warning: argument `value' of command @param is not found in the argument list of dev_set_param(struct device_d *dev, const char *name, const char *val)
lib/parameter.c:85: Warning: The following parameters of dev_set_param(struct device_d *dev, const char *name, const char *val) are not documented:
  parameter val

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 lib/parameter.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/parameter.c b/lib/parameter.c
index 0aa4193..379a057 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -86,7 +86,7 @@ int dev_set_param_ip(struct device_d *dev, char *name, IPaddr_t ip)
  * dev_set_param - set a parameter of a device to a new value
  * @param dev	The device
  * @param name	The name of the parameter
- * @param value	The new value of the parameter
+ * @param val	The new value of the parameter
  */
 int dev_set_param(struct device_d *dev, const char *name, const char *val)
 {
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:19 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:19 +0200
Subject: [PATCH 27/32] doc: add documentation for 'echo'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-28-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    1 +
 commands/echo.c            |   10 ++++++++++
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 63ed480..28ddff4 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -11,6 +11,7 @@
 @li @subpage delpart_command
 @li @subpage devinfo_command
 @li @subpage dfu_command
+ at li @subpage echo_command
 @li @subpage edit_command
 @li @subpage erase_command
 @li @subpage export_command
diff --git a/commands/echo.c b/commands/echo.c
index dfa14d6..5cc150d 100644
--- a/commands/echo.c
+++ b/commands/echo.c
@@ -111,8 +111,18 @@ no_optarg_out:
 	return 1;
 }
 
+BAREBOX_CMD_HELP_START(echo)
+BAREBOX_CMD_HELP_USAGE("echo [OPTION]... [STRING]\n")
+BAREBOX_CMD_HELP_SHORT("Display a line of text.\n")
+BAREBOX_CMD_HELP_OPT  ("-n",  "do not output the trailing newline\n")
+BAREBOX_CMD_HELP_OPT  ("-a",  "FIXME\n")
+BAREBOX_CMD_HELP_OPT  ("-o",  "FIXME\n")
+BAREBOX_CMD_HELP_OPT  ("-e",  "FIXME\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(echo)
 	.cmd		= do_echo,
 	.usage		= "echo args to console",
+	BAREBOX_CMD_HELP(cmd_echo_help)
 BAREBOX_CMD_END
 
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:02 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:02 +0200
Subject: [PATCH 10/32] doc: remove reference to non-existing documentation
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-11-git-send-email-r.schwebel@pengutronix.de>

Silence this warning:
Documentation/users_manual.dox:10: Warning: unable to resolve reference to `partitions' for \ref command

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/users_manual.dox |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/Documentation/users_manual.dox b/Documentation/users_manual.dox
index cd2b99c..0a0a13e 100644
--- a/Documentation/users_manual.dox
+++ b/Documentation/users_manual.dox
@@ -9,7 +9,6 @@ work easier.
 @li @subpage shell_notes
 @li @subpage readline_parser
 @li @subpage command_reference
- at li @subpage partitions
 @li @subpage x86_bootloader
 @li @subpage net_netconsole
 
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:04 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:04 +0200
Subject: [PATCH 12/32] doc: add missing quoting
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-13-git-send-email-r.schwebel@pengutronix.de>

Silence this warning:

/home/rsc/git/barebox/commands/partition.c:177: Warning: Found unknown command `\offset1'
/home/rsc/git/barebox/commands/partition.c:177: Warning: Found unknown command `\offset2'

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 commands/partition.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/commands/partition.c b/commands/partition.c
index 7794925..a1edcf6 100644
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -176,7 +176,7 @@ BAREBOX_CMD_END
  * Adds a partition description to a device. The partition description has the
  * form
  *
- * size1[@offset1](name1)[ro],size2[@offset2](name2)[ro],...
+ * size1[\@offset1](name1)[ro],size2[\@offset2](name2)[ro],...
  *
  * \<device> is the device name under. Size and offset can be given in decimal
  * or - if prefixed with 0x - in hex. Both can have an optional suffix K,M,G.
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:00 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:00 +0200
Subject: [PATCH 08/32] doc: let doxygen find some assembler functions
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-9-git-send-email-r.schwebel@pengutronix.de>

Silences these warnings:

arch/x86/boot/boot_hdisk.S:29: Warning: documented function `void real_start' was not declared or defined.
arch/x86/boot/boot_main.S:28: Warning: documented function `void _start' was not declared or defined.
arch/x86/boot/pmjump.S:20: Warning: documented function `void protected_mode_jump' was not declared or defined.
arch/x86/lib/memory16.S:32: Warning: documented function `unsigned short bios_get_memsize' was not declared or defined.
arch/x86/lib/traveler.S:31: Warning: documented function `void real_to_prot' was not declared or defined.
arch/x86/lib/traveler.S:38: Warning: documented function `void prot_to_real' was not declared or defined.

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 arch/x86/boot/boot_hdisk.S |    2 --
 arch/x86/boot/boot_main.S  |    2 --
 arch/x86/boot/pmjump.S     |    2 --
 arch/x86/lib/memory16.S    |    2 --
 arch/x86/lib/traveler.S    |    3 ---
 5 files changed, 0 insertions(+), 11 deletions(-)

diff --git a/arch/x86/boot/boot_hdisk.S b/arch/x86/boot/boot_hdisk.S
index 40388e9..fc4c4d5 100644
--- a/arch/x86/boot/boot_hdisk.S
+++ b/arch/x86/boot/boot_hdisk.S
@@ -31,7 +31,6 @@
  * from the boot media.
  */
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
 
 	.file "boot_hdisk.S"
 	.code16
@@ -173,4 +172,3 @@ notification_string:	.asciz "UBOOT2 "
 chs_string:	.asciz "CHS "
 jmp_string:	.asciz "JMP "
 
-#endif
diff --git a/arch/x86/boot/boot_main.S b/arch/x86/boot/boot_main.S
index f3d248a..94fe434 100644
--- a/arch/x86/boot/boot_main.S
+++ b/arch/x86/boot/boot_main.S
@@ -30,7 +30,6 @@
  * @brief Fix segment:offset settings of some buggy BIOSs
  */
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
 
 	.file "boot_main.S"
 	.code16
@@ -55,4 +54,3 @@ _start:
 
 	.size _start, .-_start
 
-#endif
diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S
index d48e198..0e4cd38 100644
--- a/arch/x86/boot/pmjump.S
+++ b/arch/x86/boot/pmjump.S
@@ -20,7 +20,6 @@
  * @fn void protected_mode_jump(void)
  * @brief Switches the first time from real mode to flat mode
  */
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
 
 #include <asm/modes.h>
 #include "boot.h"
@@ -86,4 +85,3 @@ in_pm32:
 
 	.size protected_mode_jump, .-protected_mode_jump
 
-#endif
diff --git a/arch/x86/lib/memory16.S b/arch/x86/lib/memory16.S
index 01450fa..cb2f833 100644
--- a/arch/x86/lib/memory16.S
+++ b/arch/x86/lib/memory16.S
@@ -38,7 +38,6 @@
  *
  */
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
 
 	.section .boot.text.bios_get_memsize, "ax"
 	.code32
@@ -70,4 +69,3 @@ bios_get_memsize:
 
 	.size bios_get_memsize, .-bios_get_memsize
 
-#endif
diff --git a/arch/x86/lib/traveler.S b/arch/x86/lib/traveler.S
index 2b6dc85..0614195 100644
--- a/arch/x86/lib/traveler.S
+++ b/arch/x86/lib/traveler.S
@@ -41,8 +41,6 @@
  * Called from a 16 bit real mode segment and returns into a 32 bit segment
  */
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
 #include <asm/modes.h>
 
 	.file "walkyrie.S"
@@ -180,4 +178,3 @@ enter_realmode:
 
 	.size prot_to_real, .-prot_to_real
 
-#endif
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:17 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:17 +0200
Subject: [PATCH 25/32] doc: unify documentation for 'cat'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-26-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 commands/cat.c |   19 ++++++-------------
 1 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/commands/cat.c b/commands/cat.c
index 41b3324..37e6505 100644
--- a/commands/cat.c
+++ b/commands/cat.c
@@ -85,22 +85,15 @@ out:
 	return err;
 }
 
-static const __maybe_unused char cmd_cat_help[] =
-"Usage: cat [FILES]\n"
-"Concatenate files on stdout. Currently only printable characters\n"
-"and \\n and \\t are printed, but this should be optional\n";
+BAREBOX_CMD_HELP_START(cat)
+BAREBOX_CMD_HELP_USAGE("cat [FILES]\n")
+BAREBOX_CMD_HELP_SHORT("Concatenate files on stdout.\n")
+BAREBOX_CMD_HELP_TEXT ("Currently only printable characters and \\ n and \\ t are printed,\n")
+BAREBOX_CMD_HELP_TEXT ("but this should be optional.\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(cat)
 	.cmd		= do_cat,
 	.usage		= "concatenate file(s)",
 	BAREBOX_CMD_HELP(cmd_cat_help)
 BAREBOX_CMD_END
-
-/**
- * @page cat_command cat (concatenate)
- *
- * Usage is: cat \<file\> [\<file\> ...]
- *
- * Concatenate files to stdout. Currently only printable characters
- * and \\n and \\t are printed, but this should be optional
- */
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Fri Oct 22 12:45:18 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Fri, 22 Oct 2010 18:45:18 +0200
Subject: [PATCH 26/32] doc: unify documentation for 'cd'
In-Reply-To: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1287765924-1856-27-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 commands/cd.c |   17 +++++------------
 1 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/commands/cd.c b/commands/cd.c
index a842f4d..d73be32 100644
--- a/commands/cd.c
+++ b/commands/cd.c
@@ -47,21 +47,14 @@ static int do_cd(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_cd_help[] =
-"Usage: cd [directory]\n"
-"change to directory. If called without argument, change to /\n";
+BAREBOX_CMD_HELP_START(cd)
+BAREBOX_CMD_HELP_USAGE("cd [directory]\n")
+BAREBOX_CMD_HELP_SHORT("Change to directory.\n")
+BAREBOX_CMD_HELP_TEXT ("If called without an argument, change to the root directory /.\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(cd)
 	.cmd		= do_cd,
 	.usage		= "change working directory",
 	BAREBOX_CMD_HELP(cmd_cd_help)
 BAREBOX_CMD_END
-
-/**
- * @page cd_command cd (change working directory)
- *
- * Usage is: cd [\<directory name>]
- *
- * Change to \<directory name>. If called without argument, change to \b /
- * (root)
- */
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:14 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:14 +0200
Subject: Add dynamic video initialization to barebox
Message-ID: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>

Currently barebox uses a fixed videomode setup. Everything is compiled in.
This change adds the possibility to select a videomode according to a
connected display at runtime. The current behaviour is still present if not
otherwise configured. If configured for runtime setup, initialization of the
video hardware will be delayed until the required videomode will be selected
from the shell code. If more than one videomode is supported by the platform,
running the 'devinfo' command on the framebuffer device shows the supported
videomode list. After selecting the videomode, the output can be enabled.

On my hardware I can connect a regular monitor, which supports more than one
videomode. The runtime setup sequence looks like that:

tx28:/ devinfo framebuffer0
base  : 0x00000000
size  : 0x00000000
driver: framebuffer

 Video/Mode info:
  Video output not enabled
 Current video mode:
   No video mode selected yet
 Supported video mode(s):
  'VGA'
  'SVGA'
  'XGA'
  'SXGA'
 Parameters:
           cdepth = 16
             mode = <NULL>
           enable = <NULL>

tx28:/ framebuffer0.mode=SVGA
tx28:/ bmp splash.bmp
tx28:/ framebuffer0.enable=1

After the last command the monitor shows the splash screen.

jbe



From jbe at pengutronix.de  Fri Oct 22 12:53:15 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:15 +0200
Subject: [PATCH 01/11] imx: Separate framebuffer platformdata and the videomode
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-2-git-send-email-jbe@pengutronix.de>

This patch separates the imx platformdata and its videomode in two structures,
in order to support more than one defined videomode in the boardfile. This
is intended to support runtime videomode selection later on. It also uses
now the same videomode setup style than the imx-fpu based systems (like the
i.MX35).

    Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c |   28 +++++++++--------
 arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c |   28 +++++++++--------
 arch/arm/boards/guf-neso/board.c                  |   28 +++++++++--------
 arch/arm/boards/imx21ads/imx21ads.c               |   34 +++++++++++----------
 arch/arm/boards/pcm038/pcm038.c                   |   28 +++++++++--------
 arch/arm/mach-imx/include/mach/imxfb.h            |    2 +-
 drivers/video/imx.c                               |    6 ++--
 7 files changed, 82 insertions(+), 72 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index 805ffe2..032897a 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -120,20 +120,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode cmo_display = {
+	.name		= "CMO-QVGA",
+	.refresh	= 60,
+	.xres		= 320,
+	.yres		= 240,
+	.pixclock	= KHZ2PICOS(6500),
+	.hsync_len	= 30,
+	.left_margin	= 38,
+	.right_margin	= 20,
+	.vsync_len	= 3,
+	.upper_margin	= 15,
+	.lower_margin	= 4,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CMO-QVGA",
-		.refresh	= 60,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= KHZ2PICOS(6500),
-		.hsync_len	= 30,
-		.left_margin	= 38,
-		.right_margin	= 20,
-		.vsync_len	= 3,
-		.upper_margin	= 15,
-		.lower_margin	= 4,
-	},
+	.mode		= &cmo_display,
 	.pcr		= 0xCAD08B80,
 	.bpp		= 16,
 };
diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
index 62fc14e..3ea2466 100644
--- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
+++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
@@ -186,20 +186,22 @@ static void eukrea_cpuimx27_mmu_init(void)
 #endif
 
 #ifdef CONFIG_DRIVER_VIDEO_IMX
+static struct fb_videomode cmo_display = {
+	.name		= "CMO-QVGA",
+	.refresh	= 60,
+	.xres		= 320,
+	.yres		= 240,
+	.pixclock	= 156000,
+	.hsync_len	= 30,
+	.left_margin	= 38,
+	.right_margin	= 20,
+	.vsync_len	= 3,
+	.upper_margin	= 15,
+	.lower_margin	= 4,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CMO-QVGA",
-		.refresh	= 60,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= 156000,
-		.hsync_len	= 30,
-		.left_margin	= 38,
-		.right_margin	= 20,
-		.vsync_len	= 3,
-		.upper_margin	= 15,
-		.lower_margin	= 4,
-	},
+	.mode		= &cmo_display,
 	.pcr		= 0xFAD08B80,
 	.bpp		= 16,};
 
diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c
index 9c85c08..6949675 100644
--- a/arch/arm/boards/guf-neso/board.c
+++ b/arch/arm/boards/guf-neso/board.c
@@ -91,20 +91,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode cpt_display = {
+	.name		= "CPT CLAA070LC0JCT",
+	.refresh	= 60,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= KHZ2PICOS(27000),
+	.hsync_len	= 1,	/* DE only sync */
+	.left_margin	= 50,
+	.right_margin	= 50,
+	.vsync_len	= 1,	/* DE only sync */
+	.upper_margin	= 10,
+	.lower_margin	= 10,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CPT CLAA070LC0JCT",
-		.refresh	= 60,
-		.xres		= 800,
-		.yres		= 480,
-		.pixclock	= KHZ2PICOS(27000),
-		.hsync_len	= 1,	/* DE only sync */
-		.left_margin	= 50,
-		.right_margin	= 50,
-		.vsync_len	= 1,	/* DE only sync */
-		.upper_margin	= 10,
-		.lower_margin	= 10,
-	},
+	.mode = &cpt_display,
 	/*
 	 * - TFT style panel
 	 * - clk enabled while idle
diff --git a/arch/arm/boards/imx21ads/imx21ads.c b/arch/arm/boards/imx21ads/imx21ads.c
index 44d37aa..81006de 100644
--- a/arch/arm/boards/imx21ads/imx21ads.c
+++ b/arch/arm/boards/imx21ads/imx21ads.c
@@ -79,24 +79,26 @@ static struct device_d cs8900_dev = {
 	// IRQ is connected to UART3_RTS
 };
 
+static struct fb_videomode sharp_display = {
+	.name           = "Sharp-LQ035Q7",
+	.refresh        = 60,
+	.xres           = 240,
+	.yres           = 320,
+	.pixclock       = 188679,
+	.left_margin    = 6,
+	.right_margin   = 16,
+	.upper_margin   = 8,
+	.lower_margin   = 10,
+	.hsync_len      = 2,
+	.vsync_len      = 1,
+	.sync           = 0,
+	.vmode          = FB_VMODE_NONINTERLACED,
+	.flag           = 0,
+};
+
 /* Sharp LQ035Q7DB02 QVGA display */
 static struct imx_fb_videomode imx_fb_modedata = {
-        .mode = {
-		.name           = "Sharp-LQ035Q7",
-		.refresh        = 60,
-		.xres           = 240,
-		.yres           = 320,
-		.pixclock       = 188679,
-		.left_margin    = 6,
-		.right_margin   = 16,
-		.upper_margin   = 8,
-		.lower_margin   = 10,
-		.hsync_len      = 2,
-		.vsync_len      = 1,
-		.sync           = 0,
-		.vmode          = FB_VMODE_NONINTERLACED,
-		.flag           = 0,
-	},
+        .mode           = &sharp_display,
         .pcr            = 0xfb108bc7,
         .bpp            = 16,
 };
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index 3a9b413..026e9c0 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -127,20 +127,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode sharp_display = {
+	.name		= "Sharp-LQ035Q7",
+	.refresh	= 60,
+	.xres		= 240,
+	.yres		= 320,
+	.pixclock	= 188679, /* in ps (5.3MHz) */
+	.hsync_len	= 7,
+	.left_margin	= 5,
+	.right_margin	= 16,
+	.vsync_len	= 1,
+	.upper_margin	= 7,
+	.lower_margin	= 9,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "Sharp-LQ035Q7",
-		.refresh	= 60,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 188679, /* in ps (5.3MHz) */
-		.hsync_len	= 7,
-		.left_margin	= 5,
-		.right_margin	= 16,
-		.vsync_len	= 1,
-		.upper_margin	= 7,
-		.lower_margin	= 9,
-	},
+	.mode		= &sharp_display,
 	/*
 	 * - HSYNC active high
 	 * - VSYNC active high
diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h
index 16b43ea..7baa244 100644
--- a/arch/arm/mach-imx/include/mach/imxfb.h
+++ b/arch/arm/mach-imx/include/mach/imxfb.h
@@ -50,7 +50,7 @@
 #define DMACR_TM(x)	((x) & 0xf)
 
 struct imx_fb_videomode {
-	struct fb_videomode mode;
+	struct fb_videomode *mode;
 	u32 pcr;
 	unsigned char	bpp;
 };
diff --git a/drivers/video/imx.c b/drivers/video/imx.c
index ac51858..6ccd77e 100644
--- a/drivers/video/imx.c
+++ b/drivers/video/imx.c
@@ -555,9 +555,9 @@ static int imxfb_probe(struct device_d *dev)
 	fbi->enable = pdata->enable;
 	fbi->dev = dev;
 	info->priv = fbi;
-	info->mode = &pdata->mode->mode;
-	info->xres = pdata->mode->mode.xres;
-	info->yres = pdata->mode->mode.yres;
+	info->mode = pdata->mode->mode;
+	info->xres = pdata->mode->mode->xres;
+	info->yres = pdata->mode->mode->yres;
 	info->bits_per_pixel = pdata->mode->bpp;
 	info->fbops = &imxfb_ops;
 
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:16 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:16 +0200
Subject: [PATCH 02/11] Add more flags for sync control
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-3-git-send-email-jbe@pengutronix.de>

In order to make video mode setup and initializing a runtime job (currently
it is a compile time job) this patch tries to make the 'fb_videomode' structure
more generic. It should also carry special settings required only for some LC
displays. So, I add some additional sync flags to control the DE and CLCK to
the display (something a regular CRT does not know). Also the possibility to
stop the clock when outside active display data (required for (C)STN display).

Further suggestions for flags?

What about the special settings for some kind of Sharp displays the i.MX
processor family supports?

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 include/fb.h |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/include/fb.h b/include/fb.h
index 379f931..218b244 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -17,11 +17,21 @@
 					/* vtotal = 144d/288n/576i => PAL  */
 					/* vtotal = 121d/242n/484i => NTSC */
 #define FB_SYNC_ON_GREEN	32	/* sync on green */
+/* LC display related settings */
+#define FB_SYNC_DE_HIGH_ACT	(1 << 6)
+#define FB_SYNC_CLK_INVERT	(1 << 7)
+#define FB_SYNC_DATA_INVERT	(1 << 8)
+#define FB_SYNC_CLK_IDLE_EN	(1 << 9)
+#define FB_SYNC_SWAP_RGB	(1 << 10)
+#define FB_SYNC_CLK_SEL_EN	(1 << 11)
+#define FB_SYNC_SHARP_MODE	(1 << 31)
 
 #define FB_VMODE_NONINTERLACED  0	/* non interlaced */
 #define FB_VMODE_INTERLACED	1	/* interlaced	*/
 #define FB_VMODE_DOUBLE		2	/* double scan */
 #define FB_VMODE_ODD_FLD_FIRST	4	/* interlaced: top line first */
+/* LC display related settings */
+#define FB_VMODE_DUAL_SCAN	8
 #define FB_VMODE_MASK		255
 
 #define FB_VMODE_YWRAP		256	/* ywrap instead of panning     */
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:17 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:17 +0200
Subject: [PATCH 03/11] Bring in dynamic videomode selection at runtime
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-4-git-send-email-jbe@pengutronix.de>

This patch mostly rewrites all parts of /drivers/video/fb.c. As it changes
the API to the drivers, it must be done in one step to keep the repository
bisectable. But to do it in one step makes the patches itself unreadable.

So, I decided to do it in a few steps, only for the review. All patches marked
with a "step n of m" should be merged, prior the final commit into the
repository.

This step brings in the required functions for dynamic videomode selection at
runtime, but keep the old functions untouched (the new ones are commented out).

This is patch 1 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/video/Kconfig |   23 +++++
 drivers/video/fb.c    |  251 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/fb.h          |   40 ++++++++
 3 files changed, 314 insertions(+), 0 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7a89a3f..e6ecfc8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -5,6 +5,29 @@ menuconfig VIDEO
 
 if VIDEO
 
+comment "runtime options"
+
+config VIDEO_DELAY_ENABLING
+	bool "Delayed enabling"
+	help
+	  Say 'y' here to delay enabling video output. This is useful to first
+	  fill the framebuffer (splash screen for example) prior enabling the
+	  video device.
+          This entry adds the "enable" parameter to the video device, to enable
+	  or disable video output at runtime.
+
+config VIDEO_DELAY_INIT
+	bool "Delayed initialization"
+	select VIDEO_DELAY_ENABLING
+	help
+	  If the platform supports more than one video mode say 'y' her to delay
+	  the initialization of the video device until any kind of barebox's
+          shell code sets up the correct mode at runtime.
+          This entry adds the "mode" parameter to the video device, to setup
+          the desired videomode prior enabling it at runtime.
+
+comment "drivers"
+
 config DRIVER_VIDEO_IMX
 	bool "i.MX framebuffer driver"
 	depends on ARCH_IMX1 || ARCH_IMX21 || ARCH_IMX25 || ARCH_IMX27
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index f9a425e..c2934f6 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -1,3 +1,4 @@
+#include <init.h>
 #include <common.h>
 #include <fb.h>
 #include <errno.h>
@@ -5,6 +6,8 @@
 #include <getopt.h>
 #include <fcntl.h>
 #include <fs.h>
+#include <malloc.h>
+#include <xfuncs.h>
 
 static int fb_ioctl(struct cdev* cdev, int req, void *data)
 {
@@ -57,6 +60,141 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param,
 	return 0;
 }
 
+#if 0
+#ifdef CONFIG_VIDEO_DELAY_INIT
+static int fb_check_if_already_initialized(struct device_d *fb_dev)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+
+	if (info->active_mode != NULL) {
+		pr_err("Video mode '%s' is already set. Cannot change colour depth anymore.\n", info->active_mode->name);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int fb_cdepth_set(struct device_d *fb_dev, struct param_d *param, const char *val)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+	unsigned cdepth;
+	int rc;
+
+	rc = fb_check_if_already_initialized(fb_dev);
+	if (rc != 0)
+		return rc;
+
+	cdepth = simple_strtoul(val, NULL, 0);
+	if (cdepth != 0)
+		info->bits_per_pixel = cdepth;
+	else
+		return -EINVAL;
+
+	return dev_param_set_generic(fb_dev, param, val);
+}
+#endif
+
+#ifdef CONFIG_VIDEO_DELAY_ENABLING
+static int fb_enable_set(struct device_d *fb_dev, struct param_d *param, const char *val)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+	struct fb_host *host = fb_dev->platform_data;
+	int enable;
+	char *new;
+
+	if (!val)
+		return dev_param_set_generic(fb_dev, param, NULL);
+
+	enable = simple_strtoul(val, NULL, 0);
+
+	if (info->enabled == !!enable)
+		return 0;
+
+	if (enable) {
+		(host->fb_enable)(info);
+		new = "1";
+	} else {
+		(host->fb_disable)(info);
+		new = "0";
+	}
+
+	info->enabled = !!enable;
+
+	return dev_param_set_generic(fb_dev, param, new);
+}
+#endif
+
+static void fb_list_modes(struct fb_host *host)
+{
+	unsigned u;
+
+	if (host->mode_cnt == 0)
+		return;
+
+	printf(" Supported video mode(s):\n");
+	for (u = 0; u < host->mode_cnt; u++)
+		printf("  '%s'\n", host->mode[u].name);
+}
+
+static int fb_activate_mode(struct device_d *fb_dev, const struct fb_videomode *mode)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+	struct fb_host *host = fb_dev->platform_data;
+	int rc;
+
+	rc = (host->fb_mode)(info, mode);
+	if (rc != 0)
+		return rc;
+
+	info->active_mode = mode;
+	/*
+	 * At this point of time we know the remaining information we need
+	 * for the cdev and fb_info structure.
+	 */
+	cdev->size = fb_dev->size;
+	info->xres = mode->xres;
+	info->yres = mode->yres;
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_DELAY_INIT
+static int fb_mode_set(struct device_d *fb_dev, struct param_d *param, const char *name)
+{
+	struct fb_host *host = fb_dev->platform_data;
+	unsigned u;
+	int rc;
+
+	pr_debug("%s called\n", __func__);
+
+	rc = fb_check_if_already_initialized(fb_dev);
+	if (rc != 0)
+		return rc;
+
+	/* Search for the requested video mode by name */
+	for (u = 0; u < host->mode_cnt; u++) {
+		if (!strcmp(host->mode[u].name, name))
+			break;
+	}
+	if (u >= host->mode_cnt) {
+		fb_list_modes(host);	/* no mode with 'name' found */
+		return -ENODEV;
+	} else {
+		rc = fb_activate_mode(fb_dev, &host->mode[u]);
+	}
+
+	if (rc == 0)
+		dev_param_set_generic(fb_dev, param, name);
+
+	return rc;
+}
+#endif
+#endif
+
 static struct file_operations fb_ops = {
 	.read	= mem_read,
 	.write	= mem_write,
@@ -65,6 +203,119 @@ static struct file_operations fb_ops = {
 	.ioctl	= fb_ioctl,
 };
 
+#if 0
+static int add_fb_parameter(struct device_d *fb_dev)
+{
+#ifdef CONFIG_VIDEO_DELAY_INIT
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+	char cd[10];
+
+	/** @todo provide base address parameter for the user */
+
+	dev_add_param(fb_dev, "cdepth", fb_cdepth_set, NULL, 0);
+	if (info->bits_per_pixel == 0) {
+		dev_set_param(fb_dev, "cdepth", "16");
+		info->bits_per_pixel = 16;
+	} else {
+		sprintf(cd, "%u", info->bits_per_pixel);
+		dev_set_param(fb_dev, "cdepth", cd);
+	}
+	dev_add_param(fb_dev, "mode", fb_mode_set, NULL, 0);
+	/* default is 'none' for delayed video mode setup */
+#endif
+#ifdef CONFIG_VIDEO_DELAY_ENABLING
+	dev_add_param(fb_dev, "enable", fb_enable_set, NULL, 0);
+	/* default is 'off' for delayed video output */
+#endif
+	return 0;
+}
+
+struct framebuffer_desc {
+	struct cdev cdev;
+	struct fb_info info;
+};
+
+static int fb_probe(struct device_d *fb_dev)
+{
+	int id = get_free_deviceid("fb");
+	struct cdev *cdev;
+	struct fb_info *info;
+	struct fb_host *host = fb_dev->platform_data;
+
+	cdev = xzalloc(sizeof(struct framebuffer_desc));
+	info = (struct fb_info*)&cdev[1];
+
+	fb_dev->priv = cdev;	/* pointer forward */
+	cdev->dev = fb_dev;	/* pointer backward */
+
+	cdev->ops = &fb_ops;
+	cdev->name = asprintf("fb%d", id);
+
+	cdev->size = fb_dev->size;	/* use the default if any */
+	cdev->priv = info;
+
+	info->host = host;
+	info->fb_dev = fb_dev;
+
+	/* setup defaults */
+	if (host->bits_per_pixel != 0)
+		info->bits_per_pixel = host->bits_per_pixel;
+	else
+		info->bits_per_pixel = 16;	/* means RGB565 */
+
+	/* add params on demand */
+	add_fb_parameter(fb_dev);
+
+	devfs_create(cdev);
+#ifndef CONFIG_VIDEO_DELAY_INIT
+	/* initialize video mode immediately (the first one) */
+	fb_activate_mode(fb_dev, &host->mode[0]);
+#endif
+#ifndef CONFIG_VIDEO_DELAY_ENABLING
+	/* enable video output immediately */
+	(host->fb_enable)(info);
+#endif
+	return 0;
+}
+
+static struct driver_d fb_driver = {
+	.name	= "framebuffer",
+	.probe	= fb_probe,
+};
+
+static int framebuffer_init(void)
+{
+	return register_driver(&fb_driver);
+}
+
+device_initcall(framebuffer_init);
+
+struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned size)
+{
+	struct device_d *fb_dev;
+	int rc;
+
+	fb_dev = xzalloc(sizeof(struct device_d));
+
+	strcpy(fb_dev->name, fb_driver.name);
+	fb_dev->platform_data = (void*)host;
+
+	/* setup the defaults for this framebuffer if given */
+	fb_dev->size = size;
+	fb_dev->map_base = (unsigned long)base;
+
+	rc = register_device(fb_dev);
+	if (rc != 0) {
+		pr_debug("Cannot register framebuffer device\n");
+		free(fb_dev);
+		return NULL;
+	}
+
+	return fb_dev;
+}
+#endif
+
 int register_framebuffer(struct fb_info *info)
 {
 	int id = get_free_deviceid("fb");
diff --git a/include/fb.h b/include/fb.h
index 218b244..96edc24 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -85,6 +85,46 @@ struct fb_ops {
 	void (*fb_disable)(struct fb_info *info);
 };
 
+#if 0
+struct fb_host {
+	const struct fb_videomode *mode;
+	unsigned mode_cnt;
+
+	struct device_d *hw_dev;
+
+	/* callbacks into the video hardware driver */
+	int (*fb_setcolreg)(struct fb_info*, unsigned, unsigned, unsigned, unsigned, unsigned);
+	int (*fb_mode)(struct fb_info*, const struct fb_videomode*);
+	void (*fb_enable)(struct fb_info*);
+	void (*fb_disable)(struct fb_info*);
+
+	unsigned bits_per_pixel;
+};
+
+struct fb_info {
+	struct fb_host *host;
+	struct device_d *fb_dev;
+	const struct fb_videomode *active_mode;
+
+	u32 xres;			/* visible resolution		*/
+	u32 yres;
+	u32 bits_per_pixel;		/* guess what			*/
+
+	u32 grayscale;			/* != 0 Graylevels instead of colors */
+
+	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
+	struct fb_bitfield green;	/* else only length is significant */
+	struct fb_bitfield blue;
+	struct fb_bitfield transp;	/* transparency			*/
+
+#ifdef CONFIG_VIDEO_DELAY_ENABLING
+	int enabled;
+#endif
+};
+
+struct device_d *register_framebuffer(struct fb_host*, void*, unsigned);
+#endif
+
 struct fb_info {
 	struct fb_videomode *mode;
 
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:19 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:19 +0200
Subject: [PATCH 05/11] Add verbose framebuffer device info
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-6-git-send-email-jbe@pengutronix.de>

This is patch 3 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/video/Kconfig |    6 ++++++
 drivers/video/fb.c    |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e6ecfc8..f96accc 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -26,6 +26,12 @@ config VIDEO_DELAY_INIT
           This entry adds the "mode" parameter to the video device, to setup
           the desired videomode prior enabling it at runtime.
 
+config VIDEO_INFO_VERBOSE
+	bool "verbose video info"
+	help
+	  Say 'y' here to be more verbose when running the 'devinfo' command
+	  on the framebuffer device.
+
 comment "drivers"
 
 config DRIVER_VIDEO_IMX
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index ca3a4cd..15d993d 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -172,6 +172,45 @@ static struct file_operations fb_ops = {
 	.ioctl	= fb_ioctl,
 };
 
+static void fb_info(struct device_d *fb_dev)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+
+	printf(" Video/Mode info:\n");
+#ifdef CONFIG_VIDEO_DELAY_ENABLING
+	printf("  Video output %senabled\n", info->enabled != 0 ? "" : "not ");
+#endif
+	printf(" Current video mode:\n");
+	if (info->active_mode != NULL) {
+		printf("  Name: %s\n", info->active_mode->name);
+#ifdef CONFIG_VIDEO_INFO_VERBOSE
+		if (info->active_mode->refresh == 0)
+			printf("  Refresh rate: undefined\n");
+		else
+			printf("  Refresh rate: %u Hz\n",  info->active_mode->refresh);
+		printf("  Horizontal active pixel: %u\n", info->active_mode->xres);
+		printf("  Vertical active lines: %u\n", info->active_mode->yres);
+		printf("  Pixel clock: %u kHz\n", PICOS2KHZ(info->active_mode->pixclock));
+		printf("  Left/Right margin (pixel): %u/%u\n", info->active_mode->left_margin,
+			info->active_mode->right_margin);
+		printf("  Upper/Lower margin (lines): %u/%u\n", info->active_mode->upper_margin,
+			info->active_mode->lower_margin);
+		printf("  HSYNC length in pixel: %u, polarity: %s\n", info->active_mode->hsync_len,
+			(info->active_mode->sync & FB_SYNC_HOR_HIGH_ACT) ? "high" : "low");
+		printf("  VSYNC length in lines: %u, polarity: %s\n", info->active_mode->vsync_len,
+			(info->active_mode->sync & FB_SYNC_VERT_HIGH_ACT) ? "high" : "low");
+		printf("  Colour depth: %u bpp\n", info->bits_per_pixel);
+		printf("  Framebuffer size is: %u bytes\n", cdev->size);
+		/* TODO add the remaining information from fb_videomode. How valuable are they? */
+#endif
+	} else {
+		printf ("  No video mode selected yet\n");
+	}
+
+	fb_list_modes(fb_dev->platform_data);
+}
+
 static int add_fb_parameter(struct device_d *fb_dev)
 {
 #ifdef CONFIG_VIDEO_DELAY_INIT
@@ -250,6 +289,7 @@ static int fb_probe(struct device_d *fb_dev)
 static struct driver_d fb_driver = {
 	.name	= "framebuffer",
 	.probe	= fb_probe,
+	.info	= fb_info,
 };
 
 static int framebuffer_init(void)
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:20 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:20 +0200
Subject: [PATCH 06/11] Adapt the existing imx fb driver to support runtime
	videomode selection
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-7-git-send-email-jbe@pengutronix.de>

Adapt the API to the new framebuffer videomode selection at runtime. If the new
feature is not used, there is no visible change at runtime for platforms using
this driver.

NOTE: Due to the lack of hardware, this is compile time tested only.

This is patch 4 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/imxfb.h |    1 +
 drivers/video/imx.c                    |  211 ++++++++++++++++++--------------
 2 files changed, 120 insertions(+), 92 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h
index 7baa244..c536119 100644
--- a/arch/arm/mach-imx/include/mach/imxfb.h
+++ b/arch/arm/mach-imx/include/mach/imxfb.h
@@ -60,6 +60,7 @@ struct imx_fb_videomode {
  */
 struct imx_fb_platform_data {
 	struct imx_fb_videomode *mode;
+	unsigned mode_cnt;	/**< number of entries in 'mode' */
 
 	u_int		cmap_greyscale:1,
 			cmap_inverse:1,
diff --git a/drivers/video/imx.c b/drivers/video/imx.c
index 6ccd77e..07438e5 100644
--- a/drivers/video/imx.c
+++ b/drivers/video/imx.c
@@ -137,6 +137,7 @@ struct imxfb_rgb {
 };
 
 struct imxfb_info {
+	struct fb_host		fb_host;	/**< myself */
 	void __iomem		*regs;
 
 	u_int			pcr;
@@ -147,16 +148,15 @@ struct imxfb_info {
 				cmap_static:1,
 				unused:30;
 
-	struct imx_fb_videomode *mode;
-
-	struct fb_info		info;
-	struct device_d		*dev;
-
 	void			(*enable)(int enable);
 
-	struct fb_info		overlay;
+	struct fb_host		fb_overlay;
 };
 
+#define fb_overlay_to_imxfb_info(x) (container_of((struct fb_host*)(x->host), struct imxfb_info, fb_overlay))
+#define fb_overlay_dev_to_imxfb_info(x) (container_of((struct fb_host*)(x->platform_data), struct imxfb_info, fb_overlay))
+#define fb_info_to_imxfb_info(x) ((struct imxfb_info*)((x)->host))
+
 #define IMX_NAME	"IMX"
 
 /*
@@ -204,11 +204,10 @@ static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
 	return chan << bf->offset;
 }
 
-
-static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-		   u_int trans, struct fb_info *info)
+static int imxfb_setcolreg(struct fb_info *info, u_int regno, u_int red,
+			u_int green, u_int blue, u_int trans)
 {
-	struct imxfb_info *fbi = info->priv;
+	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
 	int ret = 1;
 	u32 val;
 
@@ -247,7 +246,7 @@ static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
 static void imxfb_enable_controller(struct fb_info *info)
 {
-	struct imxfb_info *fbi = info->priv;
+	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
 
 	writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR);
 #ifdef CONFIG_ARCH_IMX21
@@ -269,7 +268,7 @@ static void imxfb_enable_controller(struct fb_info *info)
 
 static void imxfb_disable_controller(struct fb_info *info)
 {
-	struct imxfb_info *fbi = info->priv;
+	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
 
 	if (fbi->enable)
 		fbi->enable(0);
@@ -295,14 +294,35 @@ static void imxfb_disable_controller(struct fb_info *info)
  *	Configures LCD Controller based on entries in var parameter.  Settings are
  *	only written to the controller if changes were made.
  */
-static int imxfb_activate_var(struct fb_info *info)
+static int imxfb_initialize_mode(struct fb_info *info, const struct fb_videomode *mode)
 {
-	struct fb_videomode *mode = info->mode;
 	struct imxfb_rgb *rgb;
 	unsigned long lcd_clk;
 	unsigned long long tmp;
-	struct imxfb_info *fbi = info->priv;
+	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
 	u32 pcr;
+	unsigned size;
+
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = mode->xres * mode->yres * (info->bits_per_pixel >> 3);
+	if (info->fb_dev->size != 0) {
+		if (size > info->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, info->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		info->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (info->fb_dev->map_base == 0U /* FIXME should be 'NULL'*/)
+		info->fb_dev->map_base = (unsigned long)xzalloc(info->fb_dev->size);
 
 	/* physical screen start address	    */
 	writel(VPW_VPW(mode->xres * info->bits_per_pixel / 8 / 4),
@@ -318,13 +338,13 @@ static int imxfb_activate_var(struct fb_info *info)
 		VCR_V_WAIT_2(mode->upper_margin),
 		fbi->regs + LCDC_VCR);
 
-	writel(SIZE_XMAX(info->xres) | SIZE_YMAX(info->yres),
+	writel(SIZE_XMAX(mode->xres) | SIZE_YMAX(mode->yres),
 			fbi->regs + LCDC_SIZE);
 
 	writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
 	writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
-	writel((unsigned long)fbi->info.screen_base, fbi->regs + LCDC_SSA);
+	writel((uint32_t)info->fb_dev->map_base, fbi->regs + LCDC_SSA);
 
 	/* panning offset 0 (0 pixel offset)        */
 	writel(0x0, fbi->regs + LCDC_POS);
@@ -386,16 +406,10 @@ static int imxfb_activate_var(struct fb_info *info)
 	return 0;
 }
 
-static struct fb_ops imxfb_ops = {
-	.fb_setcolreg	= imxfb_setcolreg,
-	.fb_enable	= imxfb_enable_controller,
-	.fb_disable	= imxfb_disable_controller,
-};
-
 #ifdef CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY
 static void imxfb_overlay_enable_controller(struct fb_info *overlay)
 {
-	struct imxfb_info *fbi = overlay->priv;
+	struct imxfb_info *fbi = fb_overlay_to_imxfb_info(overlay);
 	unsigned int tmp;
 
 	tmp = readl(fbi->regs + LCDC_LGWCR);
@@ -405,7 +419,7 @@ static void imxfb_overlay_enable_controller(struct fb_info *overlay)
 
 static void imxfb_overlay_disable_controller(struct fb_info *overlay)
 {
-	struct imxfb_info *fbi = overlay->priv;
+	struct imxfb_info *fbi = fb_overlay_to_imxfb_info(overlay);
 	unsigned int tmp;
 
 	tmp = readl(fbi->regs + LCDC_LGWCR);
@@ -413,23 +427,16 @@ static void imxfb_overlay_disable_controller(struct fb_info *overlay)
 	writel(tmp , fbi->regs + LCDC_LGWCR);
 }
 
-static int imxfb_overlay_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-		   u_int trans, struct fb_info *info)
+static int imxfb_overlay_setcolreg(struct fb_info *overlay, u_int regno,
+		u_int red, u_int green, u_int blue, u_int trans)
 {
 	return 0;
 }
 
-static struct fb_ops imxfb_overlay_ops = {
-	.fb_setcolreg	= imxfb_overlay_setcolreg,
-	.fb_enable	= imxfb_overlay_enable_controller,
-	.fb_disable	= imxfb_overlay_disable_controller,
-};
-
 static int imxfb_alpha_set(struct device_d *dev, struct param_d *param,
 		const char *val)
 {
-	struct fb_info *overlay = dev->priv;
-	struct imxfb_info *fbi = overlay->priv;
+	struct imxfb_info *fbi = fb_overlay_dev_to_imxfb_info(dev);
 	int alpha;
 	char alphastr[16];
 	unsigned int tmp;
@@ -452,32 +459,35 @@ static int imxfb_alpha_set(struct device_d *dev, struct param_d *param,
 	return 0;
 }
 
-static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb)
+static int imxfb_overlay_mode(struct fb_info *overlay, const struct fb_videomode *mode)
 {
-	struct fb_info *overlay;
+	struct imxfb_info *fbi = fb_overlay_to_imxfb_info(overlay);
 	struct imxfb_rgb *rgb;
-	int ret;
-
-	overlay = &fbi->overlay;
-
-	overlay->priv = fbi;
-	overlay->mode = fbi->info.mode;
-	overlay->xres = fbi->info.xres;
-	overlay->yres = fbi->info.yres;
-	overlay->bits_per_pixel = fbi->info.bits_per_pixel;
-	overlay->fbops = &imxfb_overlay_ops;
-
-	if (fb)
-		overlay->screen_base = fb;
-	else
-		overlay->screen_base = xzalloc(overlay->xres * overlay->yres *
-			(overlay->bits_per_pixel >> 3));
-
-	writel((unsigned long)overlay->screen_base, fbi->regs + LCDC_LGWSAR);
-	writel(SIZE_XMAX(overlay->xres) | SIZE_YMAX(overlay->yres),
-			fbi->regs + LCDC_LGWSR);
-	writel(VPW_VPW(overlay->xres * overlay->bits_per_pixel / 8 / 4),
-		fbi->regs + LCDC_LGWVPWR);
+	unsigned size;
+
+	/* we need at least this amount of memory for the framebuffer */
+	size = mode->xres * mode->yres * (overlay->bits_per_pixel >> 3);
+
+	if (overlay->fb_dev->size != 0) {
+		if (size > overlay->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, overlay->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		overlay->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (overlay->fb_dev->map_base == 0U /* FIXME should be 'NULL'*/)
+		overlay->fb_dev->map_base = (unsigned long)xzalloc(overlay->fb_dev->size);
+
+	writel((uint32_t)overlay->fb_dev->map_base, fbi->regs + LCDC_LGWSAR);
+	writel(SIZE_XMAX(mode->xres) | SIZE_YMAX(mode->yres), fbi->regs + LCDC_LGWSR);
+	writel(VPW_VPW(mode->xres * overlay->bits_per_pixel / 8 / 4), fbi->regs + LCDC_LGWVPWR);
 	writel(0, fbi->regs + LCDC_LGWPR);
 	writel(LGWCR_GWAV(0x0), fbi->regs + LCDC_LGWCR);
 
@@ -506,14 +516,36 @@ static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb)
 	overlay->blue   = rgb->blue;
 	overlay->transp = rgb->transp;
 
-	ret = register_framebuffer(overlay);
-	if (ret < 0) {
-		dev_err(fbi->dev, "failed to register framebuffer\n");
-		return ret;
+	return 0;
+}
+
+static int imxfb_register_overlay(struct imxfb_info *fbi, struct device_d *hw_dev,
+				struct imx_fb_platform_data *pdata)
+{
+	struct fb_host *overlay;
+	struct device_d *overlay_dev;
+
+	overlay = &fbi->fb_overlay;
+
+	/* add runtime hardware info */
+	overlay->hw_dev = hw_dev;	/* same as the master device */
+	overlay->fb_mode = imxfb_overlay_mode;
+	overlay->fb_enable = imxfb_overlay_enable_controller;
+	overlay->fb_disable = imxfb_overlay_disable_controller;
+	overlay->fb_setcolreg = imxfb_overlay_setcolreg;
+
+	/* add runtime video info */
+	overlay->mode = pdata->mode->mode;
+	overlay->mode_cnt = 1;	/* no choice */
+
+	overlay_dev = register_framebuffer(overlay, pdata->framebuffer_ovl, 0);
+	if (overlay_dev == NULL) {
+		dev_err(hw_dev, "failed to register overlay framebuffer\n");
+		return -EINVAL;
 	}
 
-	dev_add_param(&overlay->dev, "alpha", imxfb_alpha_set, NULL, 0);
-	dev_set_param(&overlay->dev, "alpha", "0");
+	dev_add_param(overlay_dev, "alpha", imxfb_alpha_set, NULL, 0);
+	dev_set_param(overlay_dev, "alpha", "0");
 
 	return 0;
 }
@@ -522,13 +554,13 @@ static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb)
 static int imxfb_probe(struct device_d *dev)
 {
 	struct imxfb_info *fbi;
-	struct fb_info *info;
+	struct device_d *fb_dev;
 	struct imx_fb_platform_data *pdata = dev->platform_data;
-	int ret;
 
 	if (!pdata)
 		return -ENODEV;
 
+	/* TODO should be done when enabling the video output */
 #ifdef CONFIG_ARCH_IMX21
 	PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN);
 #endif
@@ -544,40 +576,35 @@ static int imxfb_probe(struct device_d *dev)
 #endif
 
 	fbi = xzalloc(sizeof(*fbi));
-	info = &fbi->info;
 
-	fbi->mode = pdata->mode;
-	fbi->regs = (void *)dev->map_base;
+	/* add runtime hardware info */
+	fbi->fb_host.hw_dev = dev;
+	fbi->fb_host.fb_mode = imxfb_initialize_mode;
+	fbi->fb_host.fb_enable = imxfb_enable_controller;
+	fbi->fb_host.fb_disable = imxfb_disable_controller;
+	fbi->fb_host.fb_setcolreg = imxfb_setcolreg;
+
+	fbi->regs = (void*)dev->map_base;
 	fbi->pcr = pdata->mode->pcr;
 	fbi->pwmr = pdata->pwmr;
 	fbi->lscr1 = pdata->lscr1;
 	fbi->dmacr = pdata->dmacr;
 	fbi->enable = pdata->enable;
-	fbi->dev = dev;
-	info->priv = fbi;
-	info->mode = pdata->mode->mode;
-	info->xres = pdata->mode->mode->xres;
-	info->yres = pdata->mode->mode->yres;
-	info->bits_per_pixel = pdata->mode->bpp;
-	info->fbops = &imxfb_ops;
-
-	dev_info(dev, "i.MX Framebuffer driver\n");
-
-	if (pdata->framebuffer)
-		fbi->info.screen_base = pdata->framebuffer;
-	else
-		fbi->info.screen_base = xzalloc(info->xres * info->yres *
-			(info->bits_per_pixel >> 3));
-
-	imxfb_activate_var(&fbi->info);
-
-	ret = register_framebuffer(&fbi->info);
-	if (ret < 0) {
+
+	/* add runtime video info */
+	fbi->fb_host.mode = pdata->mode->mode;
+	/* to be backward compatible */
+	fbi->fb_host.mode_cnt = pdata->mode_cnt == 0 ? 1 : pdata->mode_cnt;
+	fbi->fb_host.bits_per_pixel = 16;	/* RGB565, the default */
+
+	fb_dev = register_framebuffer(&fbi->fb_host, pdata->framebuffer, 0);
+	if (dev == NULL) {
 		dev_err(dev, "failed to register framebuffer\n");
-		return ret;
+		return -EINVAL;
 	}
+
 #ifdef CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY
-	imxfb_register_overlay(fbi, pdata->framebuffer_ovl);
+	imxfb_register_overlay(fbi, fb_dev, pdata);
 #endif
 	return 0;
 }
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:18 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:18 +0200
Subject: [PATCH 04/11] Remove the old videomode functions
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-5-git-send-email-jbe@pengutronix.de>

Remove the old functions from the framebuffer framework and change API for
existing functions.
This patch is kept separately for review only. Should be merged with the other
special marked patches.

This is patch 2 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/video/fb.c |   67 ++-------------------------------------------------
 include/fb.h       |   38 -----------------------------
 2 files changed, 3 insertions(+), 102 deletions(-)

diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index c2934f6..ca3a4cd 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -11,6 +11,7 @@
 
 static int fb_ioctl(struct cdev* cdev, int req, void *data)
 {
+	struct fb_host *host = cdev->dev->platform_data;
 	struct fb_info *info = cdev->priv;
 
 	switch (req) {
@@ -18,10 +19,10 @@ static int fb_ioctl(struct cdev* cdev, int req, void *data)
 		memcpy(data, info, sizeof(*info));
 		break;
 	case FBIO_ENABLE:
-		info->fbops->fb_enable(info);
+		(host->fb_enable)(cdev->priv);
 		break;
 	case FBIO_DISABLE:
-		info->fbops->fb_disable(info);
+		(host->fb_disable)(cdev->priv);
 		break;
 	default:
 		return -ENOSYS;
@@ -30,37 +31,6 @@ static int fb_ioctl(struct cdev* cdev, int req, void *data)
 	return 0;
 }
 
-static int fb_enable_set(struct device_d *dev, struct param_d *param,
-		const char *val)
-{
-	struct fb_info *info = dev->priv;
-	int enable;
-	char *new;
-
-	if (!val)
-		return dev_param_set_generic(dev, param, NULL);
-
-	enable = simple_strtoul(val, NULL, 0);
-
-	if (info->enabled == !!enable)
-		return 0;
-
-	if (enable) {
-		info->fbops->fb_enable(info);
-		new = "1";
-	} else {
-		info->fbops->fb_disable(info);
-		new = "0";
-	}
-
-	dev_param_set_generic(dev, param, new);
-
-	info->enabled = !!enable;
-
-	return 0;
-}
-
-#if 0
 #ifdef CONFIG_VIDEO_DELAY_INIT
 static int fb_check_if_already_initialized(struct device_d *fb_dev)
 {
@@ -193,7 +163,6 @@ static int fb_mode_set(struct device_d *fb_dev, struct param_d *param, const cha
 	return rc;
 }
 #endif
-#endif
 
 static struct file_operations fb_ops = {
 	.read	= mem_read,
@@ -203,7 +172,6 @@ static struct file_operations fb_ops = {
 	.ioctl	= fb_ioctl,
 };
 
-#if 0
 static int add_fb_parameter(struct device_d *fb_dev)
 {
 #ifdef CONFIG_VIDEO_DELAY_INIT
@@ -314,32 +282,3 @@ struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned
 
 	return fb_dev;
 }
-#endif
-
-int register_framebuffer(struct fb_info *info)
-{
-	int id = get_free_deviceid("fb");
-	struct device_d *dev;
-
-	info->cdev.ops = &fb_ops;
-	info->cdev.name = asprintf("fb%d", id);
-	info->cdev.size = info->xres * info->yres * (info->bits_per_pixel >> 3);
-	info->cdev.dev = &info->dev;
-	info->cdev.priv = info;
-	info->cdev.dev->map_base = (unsigned long)info->screen_base;
-	info->cdev.dev->size = info->cdev.size;
-
-	dev = &info->dev;
-	dev->priv = info;
-
-	sprintf(dev->name, "fb");
-
-	register_device(&info->dev);
-	dev_add_param(dev, "enable", fb_enable_set, NULL, 0);
-	dev_set_param(dev, "enable", "0");
-
-	devfs_create(&info->cdev);
-
-	return 0;
-}
-
diff --git a/include/fb.h b/include/fb.h
index 96edc24..c004a56 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -77,15 +77,6 @@ struct fb_bitfield {
 
 struct fb_info;
 
-struct fb_ops {
-	/* set color register */
-	int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
-			    unsigned blue, unsigned transp, struct fb_info *info);
-	void (*fb_enable)(struct fb_info *info);
-	void (*fb_disable)(struct fb_info *info);
-};
-
-#if 0
 struct fb_host {
 	const struct fb_videomode *mode;
 	unsigned mode_cnt;
@@ -123,35 +114,6 @@ struct fb_info {
 };
 
 struct device_d *register_framebuffer(struct fb_host*, void*, unsigned);
-#endif
-
-struct fb_info {
-	struct fb_videomode *mode;
-
-	struct fb_ops *fbops;
-	struct device_d dev;		/* This is this fb device */
-
-	void *screen_base;
-
-	void *priv;
-
-	struct cdev cdev;
-
-	u32 xres;			/* visible resolution		*/
-	u32 yres;
-	u32 bits_per_pixel;		/* guess what			*/
-
-	u32 grayscale;			/* != 0 Graylevels instead of colors */
-
-	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
-	struct fb_bitfield green;	/* else only length is significant */
-	struct fb_bitfield blue;
-	struct fb_bitfield transp;	/* transparency			*/
-
-	int enabled;
-};
-
-int register_framebuffer(struct fb_info *info);
 
 #define FBIOGET_SCREENINFO	_IOR('F', 1, loff_t)
 #define	FBIO_ENABLE		_IO('F', 2)
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:21 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:21 +0200
Subject: [PATCH 07/11] Adapt the existing imx-ipu fb driver to support runtime
	videomode selection
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-8-git-send-email-jbe@pengutronix.de>

Adapt the API to the new framebuffer videomode selection at runtime. If the new
feature is not used, there is no visible change at runtime for platforms using
this driver.

NOTE: Due to the lack of hardware, this is compile time tested only.

This is patch 5 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/freescale-mx35-3-stack/3stack.c |    2 +-
 arch/arm/boards/pcm043/pcm043.c                 |    2 +-
 arch/arm/mach-imx/include/mach/imx-ipu-fb.h     |   12 +--
 drivers/video/imx-ipu-fb.c                      |  156 +++++++++++++---------
 4 files changed, 96 insertions(+), 76 deletions(-)

diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
index d6699cd..fb40f50 100644
--- a/arch/arm/boards/freescale-mx35-3-stack/3stack.c
+++ b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
@@ -139,7 +139,7 @@ static struct fb_videomode CTP_CLAA070LC0ACW = {
 	.lower_margin	= 10,	/* whole frame should have 500 lines */
 	.hsync_len	= 1,	/* note: DE only display */
 	.vsync_len	= 1,	/* note: DE only display */
-	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_DE_HIGH_ACT,
 	.vmode		= FB_VMODE_NONINTERLACED,
 	.flag		= 0,
 };
diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
index 5932f95..7e63cc5 100644
--- a/arch/arm/boards/pcm043/pcm043.c
+++ b/arch/arm/boards/pcm043/pcm043.c
@@ -124,7 +124,7 @@ static struct fb_videomode pcm043_fb_mode = {
 	.lower_margin	= 40,
 	.hsync_len	= 96,
 	.vsync_len	= 1,
-	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_DE_HIGH_ACT,
 	.vmode		= FB_VMODE_NONINTERLACED,
 	.flag		= 0,
 };
diff --git a/arch/arm/mach-imx/include/mach/imx-ipu-fb.h b/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
index 8e1cc87..ce95243 100644
--- a/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
+++ b/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
@@ -12,20 +12,12 @@
 
 #include <fb.h>
 
-/* Proprietary FB_SYNC_ flags */
-#define FB_SYNC_OE_ACT_HIGH	0x80000000
-#define FB_SYNC_CLK_INVERT	0x40000000
-#define FB_SYNC_DATA_INVERT	0x20000000
-#define FB_SYNC_CLK_IDLE_EN	0x10000000
-#define FB_SYNC_SHARP_MODE	0x08000000
-#define FB_SYNC_SWAP_RGB	0x04000000
-#define FB_SYNC_CLK_SEL_EN	0x02000000
-
 /*
- * struct mx3fb_platform_data - mx3fb platform data
+ * struct imx_ipu_fb_platform_data - imx-ipu-fb's platform data
  */
 struct imx_ipu_fb_platform_data {
 	struct fb_videomode	*mode;
+	unsigned mode_cnt;	/**< number of entries in 'mode' */
 	unsigned char		bpp;
 	void __iomem		*framebuffer;
 	/** hook to enable backlight and stuff */
diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
index 2c25b81..426defc 100644
--- a/drivers/video/imx-ipu-fb.c
+++ b/drivers/video/imx-ipu-fb.c
@@ -34,12 +34,12 @@
 #include <mach/clock.h>
 
 struct ipu_fb_info {
+	struct  fb_host		fb_host;	/**< myself */
 	void __iomem		*regs;
 
 	void			(*enable)(int enable);
 
-	struct fb_info		info;
-	struct device_d		*dev;
+	const struct fb_videomode *mode;	/**< requested videomodue */
 };
 
 /* IPU DMA Controller channel definitions. */
@@ -413,29 +413,30 @@ static inline void reg_write(struct ipu_fb_info *fbi, u32 value,
 	writel(value, fbi->regs + reg);
 }
 
+#define fb_info_to_imxfb_info(x) ((struct ipu_fb_info*)((x)->host))
+
 /*
  * sdc_init_panel() - initialize a synchronous LCD panel.
- * @width:		width of panel in pixels.
- * @height:		height of panel in pixels.
- * @pixel_fmt:		pixel format of buffer as FOURCC ASCII code.
+ * @param info The framebuffer to work on
+ * @param pixel_fmt pixel format of buffer as FOURCC ASCII code.
  * @return:		0 on success or negative error code on failure.
  */
 static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
 {
-	struct ipu_fb_info *fbi = info->priv;
-	struct fb_videomode *mode = info->mode;
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
+	const struct fb_videomode *mode = fbi->mode;
 	u32 reg, old_conf, div;
 	enum ipu_panel panel = IPU_PANEL_TFT;
 	unsigned long pixel_clk;
 
 	/* Init panel size and blanking periods */
 	reg = ((mode->hsync_len - 1) << 26) |
-		((info->xres + mode->left_margin + mode->right_margin +
+		((mode->xres + mode->left_margin + mode->right_margin +
 		  mode->hsync_len - 1) << 16);
 	reg_write(fbi, reg, SDC_HOR_CONF);
 
 	reg = ((mode->vsync_len - 1) << 26) | SDC_V_SYNC_WIDTH_L |
-		((info->yres + mode->upper_margin + mode->lower_margin +
+		((mode->yres + mode->upper_margin + mode->lower_margin +
 		  mode->vsync_len - 1) << 16);
 	reg_write(fbi, reg, SDC_VER_CONF);
 
@@ -448,7 +449,7 @@ static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
 		old_conf |= DI_D3_CLK_POL;
 	if (mode->sync & FB_SYNC_DATA_INVERT)
 		old_conf |= DI_D3_DATA_POL;
-	if (mode->sync & FB_SYNC_OE_ACT_HIGH)
+	if (mode->sync & FB_SYNC_DE_HIGH_ACT)
 		old_conf |= DI_D3_DRDY_SHARP_POL;
 	reg_write(fbi, old_conf, DI_DISP_SIG_POL);
 
@@ -483,12 +484,12 @@ static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
 	div = imx_get_lcdclk() * 16 / pixel_clk;
 
 	if (div < 0x40) {	/* Divider less than 4 */
-		dev_dbg(&info->dev,
+		dev_dbg(fbi->fb_host.hw_dev,
 			"InitPanel() - Pixel clock divider less than 4\n");
 		div = 0x40;
 	}
 
-	dev_dbg(&info->dev, "pixel clk = %u, divider %u.%u\n",
+	dev_dbg(fbi->fb_host.hw_dev, "pixel clk = %u, divider %u.%u\n",
 		pixel_clk, div >> 4, (div & 7) * 125);
 
 	/*
@@ -588,19 +589,20 @@ static u32 dma_param_addr(enum ipu_channel channel)
 	return 0x10000 | (channel << 4);
 }
 
-static void ipu_init_channel_buffer(struct ipu_fb_info *fbi,
+static void ipu_init_channel_buffer(struct fb_info *info,
 		enum ipu_channel channel, void *fbmem)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 	union chan_param_mem params = {};
 	u32 reg;
 	u32 stride_bytes;
 
-	stride_bytes = fbi->info.xres * ((fbi->info.bits_per_pixel + 7) / 8);
+	stride_bytes = fbi->mode->xres * ((info->bits_per_pixel + 7) / 8);
 	stride_bytes = (stride_bytes + 3) & ~3;
 
 	/* Build parameter memory data for DMA channel */
-	ipu_ch_param_set_size(&params, bpp_to_pixfmt(fbi->info.bits_per_pixel),
-			      fbi->info.xres, fbi->info.yres, stride_bytes);
+	ipu_ch_param_set_size(&params, bpp_to_pixfmt(info->bits_per_pixel),
+			      fbi->mode->xres, fbi->mode->yres, stride_bytes);
 	ipu_ch_param_set_buffer(&params, fbmem, NULL);
 	params.pp.bam = 0;
 	/* Some channels (rotation) have restriction on burst length */
@@ -622,9 +624,10 @@ static void ipu_init_channel_buffer(struct ipu_fb_info *fbi,
 	reg_write(fbi, reg, IPU_CHA_DB_MODE_SEL);
 }
 
-static void ipu_channel_set_priority(struct ipu_fb_info *fbi,
+static void ipu_channel_set_priority(struct fb_info *fb_info,
 		enum ipu_channel channel, int prio)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
 	u32 reg;
 
 	reg = reg_read(fbi, IDMAC_CHA_PRI);
@@ -639,11 +642,13 @@ static void ipu_channel_set_priority(struct ipu_fb_info *fbi,
 
 /*
  * ipu_enable_channel() - enable an IPU channel.
+ * @param info The framebuffer to work on
  * @channel:	channel ID.
  * @return:	0 on success or negative error code on failure.
  */
-static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
+static int ipu_enable_channel(struct fb_info *info, enum ipu_channel channel)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 	u32 reg;
 
 	/* Reset to buffer 0 */
@@ -651,7 +656,7 @@ static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
 
 	switch (channel) {
 	case IDMAC_SDC_0:
-		ipu_channel_set_priority(fbi, channel, 1);
+		ipu_channel_set_priority(info, channel, 1);
 		break;
 	default:
 		break;
@@ -663,9 +668,10 @@ static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
 	return 0;
 }
 
-static int ipu_update_channel_buffer(struct ipu_fb_info *fbi,
+static int ipu_update_channel_buffer(struct fb_info *info,
 		enum ipu_channel channel, void *buf)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 	u32 reg;
 
 	reg = reg_read(fbi, IPU_CHA_BUF0_RDY);
@@ -679,16 +685,17 @@ static int ipu_update_channel_buffer(struct ipu_fb_info *fbi,
 	return 0;
 }
 
-static int idmac_tx_submit(struct ipu_fb_info *fbi, enum ipu_channel channel,
+static int idmac_tx_submit(struct fb_info *info, enum ipu_channel channel,
 		void *buf)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 	int ret;
 
-	ipu_init_channel_buffer(fbi, channel, buf);
+	ipu_init_channel_buffer(info, channel, buf);
 
 
 	/* ipu_idmac.c::ipu_submit_channel_buffers() */
-	ret = ipu_update_channel_buffer(fbi, channel, buf);
+	ret = ipu_update_channel_buffer(info, channel, buf);
 	if (ret < 0)
 		return ret;
 
@@ -697,16 +704,17 @@ static int idmac_tx_submit(struct ipu_fb_info *fbi, enum ipu_channel channel,
 	reg_write(fbi, 1UL << channel, IPU_CHA_BUF0_RDY);
 
 
-	ret = ipu_enable_channel(fbi, channel);
+	ret = ipu_enable_channel(info, channel);
 	return ret;
 }
 
-static void sdc_enable_channel(struct ipu_fb_info *fbi, void *fbmem)
+static void sdc_enable_channel(struct fb_info *info, void *fbmem)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 	int ret;
 	u32 reg;
 
-	ret = idmac_tx_submit(fbi, IDMAC_SDC_0, fbmem);
+	ret = idmac_tx_submit(info, IDMAC_SDC_0, fbmem);
 
 	/* mx3fb.c::sdc_fb_init() */
 	if (ret >= 0) {
@@ -724,13 +732,14 @@ static void sdc_enable_channel(struct ipu_fb_info *fbi, void *fbmem)
 
 /*
  * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
+ * @param info The framebuffer to work on
  * @return:	0 on success or negative error code on failure.
  */
 static int mx3fb_set_par(struct fb_info *info)
 {
-	struct ipu_fb_info *fbi = info->priv;
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 	struct imx_ipu_fb_rgb *rgb;
-	struct fb_videomode *mode = info->mode;
+	const struct fb_videomode *mode = fbi->mode;
 	int ret;
 
 	ret = sdc_init_panel(info, IPU_PIX_FMT_RGB666);
@@ -766,10 +775,45 @@ static int mx3fb_set_par(struct fb_info *info)
 	return 0;
 }
 
+static int ipu_fb_initialize_mode(struct fb_info *fb_info, const struct fb_videomode *mode)
+{
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
+	unsigned size;
+
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = mode->xres * mode->yres * (fb_info->bits_per_pixel >> 3);
+	if (fb_info->fb_dev->size != 0) {
+		if (size > fb_info->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, fb_info->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		fb_info->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (fb_info->fb_dev->map_base == 0U /* FIXME should be 'NULL'*/)
+		fb_info->fb_dev->map_base = (unsigned long)xzalloc(fb_info->fb_dev->size);
+
+#if 0
+	/* FIXME why here? Its also called in ipu_fb_enable() */
+	sdc_enable_channel(fbi, fb_info->fb_dev->map_base);
+#endif
+	fbi->mode = mode;
+
+	return 0;
+}
+
 /* References in this function refer to respective Linux kernel sources */
 static void ipu_fb_enable(struct fb_info *info)
 {
-	struct ipu_fb_info *fbi = info->priv;
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 
 	u32 reg;
 
@@ -825,7 +869,7 @@ static void ipu_fb_enable(struct fb_info *info)
 
 	mx3fb_set_par(info);
 
-	sdc_enable_channel(fbi, info->screen_base);
+	sdc_enable_channel(info, (void*)info->fb_dev->map_base);
 
 	/*
 	 * Linux driver calls sdc_set_brightness() here again,
@@ -837,7 +881,7 @@ static void ipu_fb_enable(struct fb_info *info)
 
 static void ipu_fb_disable(struct fb_info *info)
 {
-	struct ipu_fb_info *fbi = info->priv;
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 	u32 reg;
 
 	printf("%s\n", __func__);
@@ -850,54 +894,38 @@ static void ipu_fb_disable(struct fb_info *info)
 	reg_write(fbi, reg, SDC_COM_CONF);
 }
 
-static struct fb_ops imxfb_ops = {
-	.fb_enable = ipu_fb_enable,
-	.fb_disable = ipu_fb_disable,
-};
-
 static int imxfb_probe(struct device_d *dev)
 {
 	struct ipu_fb_info *fbi;
-	struct fb_info *info;
+	struct device_d *fb_dev;
 	const struct imx_ipu_fb_platform_data *pdata = dev->platform_data;
-	int ret;
 
 	if (!pdata)
 		return -ENODEV;
 
 	fbi = xzalloc(sizeof(*fbi));
-	info = &fbi->info;
+
+	/* add runtime hardware info */
+	fbi->fb_host.hw_dev = dev;
+	fbi->fb_host.fb_mode = ipu_fb_initialize_mode;
+	fbi->fb_host.fb_enable = ipu_fb_enable;
+	fbi->fb_host.fb_disable = ipu_fb_disable;
+	fbi->fb_host.fb_setcolreg = NULL;
 
 	fbi->regs = (void *)dev->map_base;
-	fbi->dev = dev;
-	info->priv = fbi;
-	info->mode = pdata->mode;
-	info->xres = pdata->mode->xres;
-	info->yres = pdata->mode->yres;
-	info->bits_per_pixel = pdata->bpp;
-	info->fbops = &imxfb_ops;
-	fbi->enable = pdata->enable;
 
-	dev_info(dev, "i.MX Framebuffer driver\n");
+	/* add runtime video info */
+	fbi->fb_host.mode = pdata->mode;
+	/* to be backward compatible */
+	fbi->fb_host.mode_cnt = pdata->mode_cnt == 0 ? 1 : pdata->mode_cnt;
+	fbi->fb_host.bits_per_pixel = pdata->bpp;
 
-	/*
-	 * Use a given frambuffer or reserve some
-	 * memory for screen usage
-	 */
-	fbi->info.screen_base = pdata->framebuffer;
-	if (fbi->info.screen_base == NULL) {
-		fbi->info.screen_base = malloc(info->xres * info->yres *
-					       (info->bits_per_pixel >> 3));
-		if (!fbi->info.screen_base)
-			return -ENOMEM;
-	}
-
-	sdc_enable_channel(fbi, info->screen_base);
+	dev_info(dev, "i.MX Framebuffer driver\n");
 
-	ret = register_framebuffer(&fbi->info);
-	if (ret < 0) {
+	fb_dev = register_framebuffer(&fbi->fb_host, pdata->framebuffer, 0);
+	if (fb_dev == NULL) {
 		dev_err(dev, "failed to register framebuffer\n");
-		return ret;
+		return -EINVAL;
 	}
 
 	return 0;
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:23 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:23 +0200
Subject: [PATCH 09/11] STM378x: Add video driver for this platform
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-10-git-send-email-jbe@pengutronix.de>

As there is currently no user of this driver (but coming soon) it is for
reference only.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/include/mach/fb.h |   38 +++
 drivers/video/Kconfig               |    7 +
 drivers/video/Makefile              |    1 +
 drivers/video/stm.c                 |  556 +++++++++++++++++++++++++++++++++++
 4 files changed, 602 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-stm/include/mach/fb.h
 create mode 100644 drivers/video/stm.c

diff --git a/arch/arm/mach-stm/include/mach/fb.h b/arch/arm/mach-stm/include/mach/fb.h
new file mode 100644
index 0000000..6596ef2
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/fb.h
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_FB_H
+# define __MACH_FB_H
+
+#include <fb.h>
+
+#define STMLCDIF_8BIT 1	/** pixel data bus to the display is of 8 bit width */
+#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
+#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
+#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
+
+struct imx_fb_videomode {
+	struct fb_videomode *mode_list;
+	unsigned mode_count;
+	void *framebuffer;	/**< force fixed framebuffer address if != NULL */
+	unsigned size;		/**< force fixed size if != NULL */
+
+	unsigned dotclk_delay;	/**< refer manual HW_LCDIF_VDCTRL4 register */
+	unsigned ld_intf_width;	/**< refer STMLCDIF_* macros */
+};
+
+#endif /* __MACH_FB_H */
+
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 64f68c4..63a80b0 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -55,4 +55,11 @@ config S3C_VIDEO
 	help
 	  Add support for the S3C244x LCD controller.
 
+config DRIVER_VIDEO_STM
+	bool "i.MX23/28 framebuffer driver"
+	depends on ARCH_STM
+	help
+	  Say 'Y' here to enable framebuffer and spash screen support for
+	  i.MX23 and i.MX28 based systems.
+
 endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 4287fc8..0ddb81e 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_VIDEO) += fb.o
 
+obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o
 obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
 obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
 obj-$(CONFIG_S3C_VIDEO) += s3c.o
diff --git a/drivers/video/stm.c b/drivers/video/stm.c
new file mode 100644
index 0000000..b18378a
--- /dev/null
+++ b/drivers/video/stm.c
@@ -0,0 +1,556 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is based on:
+ * Author: Vitaly Wool <vital at embeddedalley.com>
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/**
+ * @file
+ * @brief LCDIF driver for i.MX23 and i.MX28 (i.MX23 untested yet)
+ *
+ * The LCDIF support four modes of operation
+ * - MPU interface (to drive smart displays) -> not supported yet
+ * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
+ * - Dotclock interface (to drive LC displays with RGB data and sync signals)
+ * - DVI (to drive ITU-R BT656)  -> not supported yet
+ *
+ * This driver depends on a correct setup of the pins used for this purpose
+ * (platform specific).
+ *
+ * For the developer: Don't forget to set the data bus width to the display
+ * in the imx_fb_videomode structure. You will else end up with ugly colours.
+ * If you fighting against jitter you can vary the clock delay. This is a feature
+ * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
+ * the required value in the imx_fb_videomode structure.
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <xfuncs.h>
+#include <asm/io.h>
+#include <mach/clock.h>
+#include <mach/fb.h>
+
+#define HW_LCDIF_CTRL 0x00
+# define CTRL_SFTRST (1 << 31)
+# define CTRL_CLKGATE (1 << 30)
+# define CTRL_BYPASS_COUNT (1 << 19)
+# define CTRL_VSYNC_MODE (1 << 18)
+# define CTRL_DOTCLK_MODE (1 << 17)
+# define CTRL_DATA_SELECT (1 << 16)
+# define SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
+# define SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
+# define GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
+# define CTRL_MASTER (1 << 5)
+# define CTRL_DF16 (1 << 3)
+# define CTRL_DF18 (1 << 2)
+# define CTRL_DF24 (1 << 1)
+# define CTRL_RUN (1 << 0)
+
+#define HW_LCDIF_CTRL1 0x10
+# define SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
+# define GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
+
+#define HW_LCDIF_CTRL2 0x20
+
+#define HW_LCDIF_TRANSFER_COUNT 0x30
+# define SET_VCOUNT(x) (((x) & 0xffff) << 16)
+# define SET_HCOUNT(x) ((x) & 0xffff)
+
+#define HW_LCDIF_CUR_BUF 0x40
+
+#define HW_LCDIF_NEXT_BUF 0x50
+
+#define HW_LCDIF_TIMING 0x60
+# define SET_CMD_HOLD(x) (((x) & 0xff) << 24)
+# define SET_CMD_SETUP(x) (((x) & 0xff) << 16)
+# define SET_DATA_HOLD(x) (((x) & 0xff) << 8)
+# define SET_DATA_SETUP(x) ((x) & 0xff))
+
+#define HW_LCDIF_VDCTRL0 0x70
+# define VDCTRL0_ENABLE_PRESENT (1 << 28)
+# define VDCTRL0_VSYNC_POL (1 << 27) /* 0 = low active, 1 = high active */
+# define VDCTRL0_HSYNC_POL (1 << 26) /* 0 = low active, 1 = high active */
+# define VDCTRL0_DOTCLK_POL (1 << 25) /* 0 = output at falling edge, capturing at rising edge */
+# define VDCTRL0_ENABLE_POL (1 << 24) /* 0 = low active, 1 = high active */
+# define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
+# define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
+# define VDCTRL0_HALF_LINE (1 << 19)
+# define VDCTRL0_HALF_LINE_MODE (1 << 18)
+# define SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_VDCTRL1 0x80
+
+#define HW_LCDIF_VDCTRL2 0x90
+# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0x3fff) << 18)
+# define SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_VDCTRL3 0xa0
+# define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
+# define VDCTRL3_VSYNC_ONLY (1 << 28)
+# define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
+# define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
+
+#define HW_LCDIF_VDCTRL4 0xb0
+# define SET_DOTCLK_DLY(x) (((x) & 0x7) << 29)
+# define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
+# define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_DVICTRL0 0xc0
+#define HW_LCDIF_DVICTRL1 0xd0
+#define HW_LCDIF_DVICTRL2 0xe0
+#define HW_LCDIF_DVICTRL3 0xf0
+#define HW_LCDIF_DVICTRL4 0x100
+#define HW_LCDIF_DATA 0x180
+
+#define HW_LCDIF_DEBUG0 0x1d0
+# define DEBUG_HSYNC (1 < 26)
+# define DEBUG_VSYNC (1 < 25)
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+struct imxfb_host {
+	struct fb_host fb_data;
+	struct device_d *hw_dev;
+	void __iomem *base;
+};
+
+#define fb_info_to_imxfb_host(x) ((struct imxfb_host*)((x)->host))
+
+/* the RGB565 true colour mode */
+static const struct fb_bitfield def_rgb565[] = {
+	[RED] = {
+		.offset = 11,
+		.length = 5,
+	},
+	[GREEN] = {
+		.offset = 5,
+		.length = 6,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 5,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/* the RGB666 true colour mode */
+static const struct fb_bitfield def_rgb666[] = {
+	[RED] = {
+		.offset = 16,
+		.length = 6,
+	},
+	[GREEN] = {
+		.offset = 8,
+		.length = 6,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 6,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/* the RGB888 true colour mode */
+static const struct fb_bitfield def_rgb888[] = {
+	[RED] = {
+		.offset = 16,
+		.length = 8,
+	},
+	[GREEN] = {
+		.offset = 8,
+		.length = 8,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 8,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/**
+ * Just calculate the amount of required bytes per line
+ * @param ppl Used pixel per line
+ * @param bpp Bits per pixel
+ * @return Byte count
+ */
+static inline unsigned calc_line_length(unsigned ppl, unsigned bpp)
+{
+	return (ppl * bpp) >> 3;
+}
+
+/**
+ * Prepare the video hardware for a specified video mode
+ * @param fb_info Framebuffer information
+ * @param mode The video mode description to initialize
+ * @return 0 on success
+ *
+ * Dotclock mode:
+ * One line of pixels or one frame in the i.MX28 is defined to:
+ * @verbatim
+ * |<---------------------- one line period -------------------------------->|
+ * |<- HSync length ->|
+ * |<----- Start of line --->|
+ *                           |<-------- active line data ------>|
+ *
+ * |<------------------------ frame period --------------------------------->|
+ * |<- VSync length ->|
+ * |<--- Start of 1. line -->|
+ *                           |<---------- active lines -------->|
+ * @endverbatim
+ * Based on the values from struct fb_videomode:
+ * - "one line period" = left_margin + xres + right_margin + hsync_len
+ * - "HSync length" = hsync_len
+ * - "Start of line" = hsync_len + left_margin
+ * - "active line data" = xres
+ */
+static int stmfb_initialize_mode(struct fb_info *fb_info, const struct fb_videomode *mode)
+{
+	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
+	struct imx_fb_videomode *pdata = fbh->hw_dev->platform_data;
+	uint32_t reg;
+	unsigned size;
+
+	pr_debug("%s called\n", __func__);
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = calc_line_length(mode->xres, fb_info->bits_per_pixel) * mode->yres;
+	if (fb_info->fb_dev->size != 0) {
+		if (size > fb_info->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, fb_info->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		fb_info->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (fb_info->fb_dev->map_base == 0U)
+		fb_info->fb_dev->map_base = (resource_size_t)xzalloc(fb_info->fb_dev->size);
+
+	/* TODO HCLK must be active at this point of time! */
+
+	size = imx_set_lcdifclk(PICOS2KHZ(mode->pixclock));
+	if (size == 0) {
+		pr_debug("Unable to set a valid pixel clock\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * bring the controller out of reset and configure it into DOTCLOCK mode
+	 */
+	reg = CTRL_BYPASS_COUNT |	/* always in DOTCLOCK mode */
+		CTRL_DOTCLK_MODE;
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+
+	/* master mode only */
+	reg |= CTRL_MASTER;
+
+	/*
+	 * Configure videomode and interface mode
+	 */
+	reg |= SET_BUS_WIDTH(pdata->ld_intf_width);
+	switch (fb_info->bits_per_pixel) {
+	case 8:
+		reg |= SET_WORD_LENGTH(1);
+		/* TODO refer manual page 2046 */
+		pr_warning("8 bpp mode not supported yet\n");
+		break;
+	case 16:
+		pr_debug("Setting up an RGB565 mode\n");
+		reg |= SET_WORD_LENGTH(0) | CTRL_DF16; /* we assume RGB565 */
+		writel(SET_BYTE_PACKAGING(0xf), fbh->base + HW_LCDIF_CTRL1);
+		fb_info->red = def_rgb565[RED];
+		fb_info->green = def_rgb565[GREEN];
+		fb_info->blue = def_rgb565[BLUE];
+		fb_info->transp =  def_rgb565[TRANSP];
+		break;
+	case 24:
+	case 32:
+		pr_debug("Setting up an RGB888/666 mode\n");
+		reg |= SET_WORD_LENGTH(3);
+		switch (pdata->ld_intf_width) {
+		case STMLCDIF_8BIT:
+			pr_debug("Unsupported LCD bus width mapping\n");
+			break;
+		case STMLCDIF_16BIT:
+		case STMLCDIF_18BIT:
+			/* 24 bit to 18 bit mapping */
+			reg |= CTRL_DF24;	/* ignore the upper 2 bits in each colour component */
+			fb_info->red = def_rgb666[RED];
+			fb_info->green = def_rgb666[GREEN];
+			fb_info->blue = def_rgb666[BLUE];
+			fb_info->transp =  def_rgb666[TRANSP];
+			break;
+		case STMLCDIF_24BIT:
+			/* real 24 bit */
+			fb_info->red = def_rgb888[RED];
+			fb_info->green = def_rgb888[GREEN];
+			fb_info->blue = def_rgb888[BLUE];
+			fb_info->transp =  def_rgb888[TRANSP];
+			break;
+		}
+		/* do not use packed pixels = one pixel per word instead */
+		writel(SET_BYTE_PACKAGING(0x7), fbh->base + HW_LCDIF_CTRL1);
+		break;
+	default:
+		pr_debug("Unhandled colour depth of %u\n", fb_info->bits_per_pixel);
+		return -EINVAL;
+	}
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+	pr_debug("Setting up CTRL to %08X\n", reg);
+
+	writel(SET_VCOUNT(mode->yres) |
+		SET_HCOUNT(mode->xres), fbh->base + HW_LCDIF_TRANSFER_COUNT);
+
+	reg = VDCTRL0_ENABLE_PRESENT |	/* always in DOTCLOCK mode */
+		VDCTRL0_VSYNC_PERIOD_UNIT |
+		VDCTRL0_VSYNC_PULSE_WIDTH_UNIT;
+	if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
+		reg |= VDCTRL0_HSYNC_POL;
+	if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
+		reg |= VDCTRL0_VSYNC_POL;
+	if (mode->sync & FB_SYNC_DE_HIGH_ACT)
+		reg |= VDCTRL0_ENABLE_POL;
+	if (mode->sync & FB_SYNC_CLK_INVERT)
+		reg |= VDCTRL0_DOTCLK_POL;
+
+	reg |= SET_VSYNC_PULSE_WIDTH(mode->vsync_len);
+	writel(reg, fbh->base + HW_LCDIF_VDCTRL0);
+	pr_debug("Setting up VDCTRL0 to %08X\n", reg);
+
+	/* frame length in lines */
+	writel(mode->upper_margin + mode->vsync_len + mode->lower_margin + mode->yres,
+		fbh->base + HW_LCDIF_VDCTRL1);
+
+	/* line length in units of clocks or pixels */
+	writel(SET_HSYNC_PULSE_WIDTH(mode->hsync_len) |
+		SET_HSYNC_PERIOD(mode->left_margin + mode->hsync_len + mode->right_margin + mode->xres),
+		fbh->base + HW_LCDIF_VDCTRL2);
+
+	writel(SET_HOR_WAIT_CNT(mode->left_margin + mode->hsync_len) |
+		SET_VERT_WAIT_CNT(mode->upper_margin + mode->vsync_len),
+		fbh->base + HW_LCDIF_VDCTRL3);
+
+	writel(SET_DOTCLK_DLY(pdata->dotclk_delay) |
+		SET_DOTCLK_H_VALID_DATA_CNT(mode->xres),
+		fbh->base + HW_LCDIF_VDCTRL4);
+
+	writel(fb_info->fb_dev->map_base, fbh->base + HW_LCDIF_CUR_BUF);
+	/* always show one framebuffer only */
+	writel(fb_info->fb_dev->map_base, fbh->base + HW_LCDIF_NEXT_BUF);
+
+	return 0;
+}
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void stmfb_enable_controller(struct fb_info *fb_info)
+{
+	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
+	uint32_t reg, last_reg;
+	unsigned loop, edges;
+
+	pr_debug("%s called\n", __func__);
+
+	/* if it was disabled, re-enable the mode again */
+	reg = readl(fbh->base + HW_LCDIF_CTRL);
+	reg |= CTRL_DOTCLK_MODE;
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+
+	/* enable the SYNC signals first, then the DMA enginge */
+	reg = readl(fbh->base + HW_LCDIF_VDCTRL4);
+	reg |= VDCTRL4_SYNC_SIGNALS_ON;
+	writel(reg, fbh->base + HW_LCDIF_VDCTRL4);
+
+	/*
+	 * Give the attached LC display or monitor a chance to sync into
+	 * our signals.
+	 * Wait for at least 2 VSYNCs = four VSYNC edges
+	 */
+	edges = 4;
+
+	while (edges != 0) {
+		loop = 800;
+		last_reg = readl(fbh->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
+		do {
+			reg = readl(fbh->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
+			if (reg != last_reg);
+				break;
+			last_reg = reg;
+			loop--;
+		} while (loop != 0);
+		edges--;
+	}
+
+	reg = readl(fbh->base + HW_LCDIF_CTRL);
+	reg |= CTRL_RUN;
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+}
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void stmfb_disable_controller(struct fb_info *fb_info)
+{
+	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
+	unsigned loop;
+	uint32_t reg;
+
+	pr_debug("%s called\n", __func__);
+	/*
+	 * Even if we disable the controller here, it will still continue
+	 * until its FIFOs are running out of data
+	 */
+	reg = readl(fbh->base + HW_LCDIF_CTRL);
+	reg &= ~CTRL_DOTCLK_MODE;
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+
+	loop = 1000;
+	while (loop) {
+		reg = readl(fbh->base + HW_LCDIF_CTRL);
+		if (!(reg & CTRL_RUN))
+			break;
+		loop--;
+	}
+
+	reg = readl(fbh->base + HW_LCDIF_VDCTRL4);
+	reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
+	writel(reg, fbh->base + HW_LCDIF_VDCTRL4);
+}
+
+/**
+ * Print some information about the current hardware state
+ * @param hw_dev STM video device
+ */
+static void stmfb_info(struct device_d *hw_dev)
+{
+	uint32_t reg;
+
+	printf(" STM video hardware:\n");
+	printf("  Pixel clock: %u kHz\n", imx_get_lcdifclk());
+
+	reg = readl(hw_dev->map_base + HW_LCDIF_CTRL);
+	switch (GET_WORD_LENGTH(reg)) {
+	case 0:
+		printf("  16 bpp mode with %s colour scheme\n", reg & CTRL_DF16 ? "RGB565" : "ARGB1555");
+		switch (GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1))) {
+		case 0xf:
+			printf("  One pixel per halfword\n");
+			break;
+		case 0x3:
+			printf("  One pixel per word\n");
+			break;
+		default:
+			printf("Unknown pixel packaging: %u\n", GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1)));
+		}
+		break;
+	case 1:
+	case 2:
+		printf("Unsupported bpp mode yet!\n");
+		break;
+	case 3:
+		printf("  24 bpp mode with %s colour scheme\n", reg & CTRL_DF24 ? "RGB888" : "RGB666");
+		switch (GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1))) {
+		case 0x7:
+			printf("  One pixel per word (xRGB xRGB xRGB ...)\n");
+			break;
+		case 0xf:
+			printf("Packed pixel format per word (RGBR GBRG BRGB ...)\n");
+			break;
+		default:
+			printf("Unknown pixel packaging: %u\n", GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1)));
+		}
+		break;
+	}
+}
+
+/*
+ * There is only one video hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct imxfb_host host_data = {
+	.fb_data.fb_mode = stmfb_initialize_mode,
+	.fb_data.fb_enable = stmfb_enable_controller,
+	.fb_data.fb_disable = stmfb_disable_controller,
+	.fb_data.bits_per_pixel = 16,
+};
+
+static int stmfb_probe(struct device_d *hw_dev)
+{
+	struct imx_fb_videomode *pdata = hw_dev->platform_data;
+	struct device_d *fb_dev;
+
+	if (pdata == NULL) {
+		pr_debug("STMFB: No platformdata. Giving up\n");
+		return -ENODEV;
+	}
+
+	/* add runtime hardware info */
+	host_data.hw_dev = hw_dev;
+	host_data.base = (void*)hw_dev->map_base;
+
+	/* add runtime video info */
+	host_data.fb_data.mode = pdata->mode_list;
+	host_data.fb_data.mode_cnt = pdata->mode_count;
+
+	fb_dev = register_framebuffer(&host_data.fb_data, pdata->framebuffer, pdata->size);
+	if (fb_dev == NULL) {
+		pr_err("STMFB: Failed to register framebuffer\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct driver_d stmfb_driver = {
+	.name	= "stmfb",
+	.probe	= stmfb_probe,
+	.info	= stmfb_info,
+};
+
+static int stmfb_init(void)
+{
+	return register_driver(&stmfb_driver);
+}
+
+device_initcall(stmfb_init);
+
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:25 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:25 +0200
Subject: [PATCH 11/11] Add doxygen documentation to the framebfuffer code
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-12-git-send-email-jbe@pengutronix.de>

Add some (hopyfully) helpful documentation to the source code.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 Documentation/developers_manual.dox |    1 +
 Documentation/users_manual.dox      |    1 +
 drivers/video/fb.c                  |  221 +++++++++++++++++++++++++++++++++++
 include/fb.h                        |   98 ++++++++++-----
 4 files changed, 288 insertions(+), 33 deletions(-)

diff --git a/Documentation/developers_manual.dox b/Documentation/developers_manual.dox
index 620905e..609d0a0 100644
--- a/Documentation/developers_manual.dox
+++ b/Documentation/developers_manual.dox
@@ -21,5 +21,6 @@ This part of the documentation is intended for developers of @a barebox.
 @li @subpage io_access_functions
 @li @subpage mcfv4e_MCDlib
 @li @subpage x86_runtime
+ at li @subpage fb_for_developers
 
 */
diff --git a/Documentation/users_manual.dox b/Documentation/users_manual.dox
index cd2b99c..1f0e35b 100644
--- a/Documentation/users_manual.dox
+++ b/Documentation/users_manual.dox
@@ -12,5 +12,6 @@ work easier.
 @li @subpage partitions
 @li @subpage x86_bootloader
 @li @subpage net_netconsole
+ at li @subpage fb_for_users
 
 */
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index 15d993d..9381bd1 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -32,6 +32,13 @@ static int fb_ioctl(struct cdev* cdev, int req, void *data)
 }
 
 #ifdef CONFIG_VIDEO_DELAY_INIT
+/**
+ * Check if the framebuffer is already initialized
+ * @param fb_dev The framebuffer device to check
+ * @return 0 if the framebuffer is still uninitialized, -EPERM if already initialized
+ *
+ * @note Currently video mode initializing is a "one time only" task.
+ */
 static int fb_check_if_already_initialized(struct device_d *fb_dev)
 {
 	struct cdev *cdev = fb_dev->priv;
@@ -45,6 +52,9 @@ static int fb_check_if_already_initialized(struct device_d *fb_dev)
 	return 0;
 }
 
+/**
+ * Change colour depth via device parameter
+ */
 static int fb_cdepth_set(struct device_d *fb_dev, struct param_d *param, const char *val)
 {
 	struct cdev *cdev = fb_dev->priv;
@@ -67,6 +77,9 @@ static int fb_cdepth_set(struct device_d *fb_dev, struct param_d *param, const c
 #endif
 
 #ifdef CONFIG_VIDEO_DELAY_ENABLING
+/**
+ * Enable/disable video output via device parameter
+ */
 static int fb_enable_set(struct device_d *fb_dev, struct param_d *param, const char *val)
 {
 	struct cdev *cdev = fb_dev->priv;
@@ -97,6 +110,10 @@ static int fb_enable_set(struct device_d *fb_dev, struct param_d *param, const c
 }
 #endif
 
+/**
+ * Output the list of supported video modes in this framebuffer
+ * @param host Platformdata of the hardware video device
+ */
 static void fb_list_modes(struct fb_host *host)
 {
 	unsigned u;
@@ -109,6 +126,14 @@ static void fb_list_modes(struct fb_host *host)
 		printf("  '%s'\n", host->mode[u].name);
 }
 
+/**
+ * Call the video hardware driver to initialize the given video mode
+ * @param fb_dev Framebuffer device
+ * @param mode Mode description to initialize
+ * @return 0 on success
+ *
+ * @note This call does not imply enabling the video output device!
+ */
 static int fb_activate_mode(struct device_d *fb_dev, const struct fb_videomode *mode)
 {
 	struct cdev *cdev = fb_dev->priv;
@@ -133,6 +158,15 @@ static int fb_activate_mode(struct device_d *fb_dev, const struct fb_videomode *
 }
 
 #ifdef CONFIG_VIDEO_DELAY_INIT
+/**
+ * Setup the requested video mode via device parameter
+ * @param dev Device instance
+ * @param param FIXME
+ * @param name Video mode name to activate
+ * @return 0 on success
+ *
+ * @note One time setup only, changing video modes is currently not supported.
+ */
 static int fb_mode_set(struct device_d *fb_dev, struct param_d *param, const char *name)
 {
 	struct fb_host *host = fb_dev->platform_data;
@@ -211,6 +245,14 @@ static void fb_info(struct device_d *fb_dev)
 	fb_list_modes(fb_dev->platform_data);
 }
 
+/**
+ * Add parameter to the framebuffer device on demand
+ * @param dev Device instance
+ * @return 0 on success
+ *
+ * Some parameter are only available (or usefull) if the intialization or
+ * enabling the video hardware is delayed.
+ */
 static int add_fb_parameter(struct device_d *fb_dev)
 {
 #ifdef CONFIG_VIDEO_DELAY_INIT
@@ -299,6 +341,13 @@ static int framebuffer_init(void)
 
 device_initcall(framebuffer_init);
 
+/**
+ * Create a new framebuffer device (for convenience)
+ * @param pinfo Video device's platform data for this framebuffer device
+ * @param base force framebuffer's base address to given value, or NULL for dynamically allocation
+ * @param sze force framebuffer's size to this value, or 0 for dynamically allocation
+ * @return Pointer to the newly created device or NULL on failure
+ */
 struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned size)
 {
 	struct device_d *fb_dev;
@@ -322,3 +371,175 @@ struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned
 
 	return fb_dev;
 }
+
+/**
+ at page fb_for_users Framebuffer handling for users
+
+ at section regular_fb Static framebuffer setup
+
+After registering the video device the driver initializes the video hardware, clears the
+framebuffer (set all to zero) and enables the video output hardware. This will happen
+prior any shell code is running. In this case a user will see an activated video output device
+(an LC display for example or a connected CRT) showing a black screen.
+When the shell code starts, its possible to write some kind of image into the framebuffer memory
+to show a splash screen (refer 'bmp' command).
+
+ at section delayed_fb Dynamic framebuffer setup
+
+To avoid a black screen until the image can be written, enabling the video output device
+can be delayed. Say 'y' to the "Delayed enabling" menu entry to activate this feature. This
+will initialize the video hardware, but do not enable the video output device. Instead it adds
+the parameter 'enable' to the framebuffer device. The video output device kept disabled until the
+command
+ at verbatim
+barebox:/ fb0.enable=1
+ at endverbatim
+is given in a shell script.
+
+If the platform supports more than one video output device its possible to select one of
+the supported ones at runtime. Say 'y' to the "Delayed initialization" menu entry to activate
+this feature. This will add the parameter 'mode' to the framebuffer device and will delay the
+initialization of the video hardware until the video output device gets specified.
+It will also delay the enabling of the video output device.
+
+Running the @b devinfo command on this fb0 device will output:
+ at verbatim
+barebox:/ devinfo fb0
+base  : 0x00000000
+size  : 0x00000000
+driver: framebuffer
+
+ Video/Mode info:
+  Video output not enabled
+ Current video mode:
+  No video mode selected yet
+ Supported video mode(s):
+  'QVGA'
+  'VGA'
+Parameters:
+          cdepth = 16
+            mode = <NULL>
+          enable = <NULL>
+ at endverbatim
+
+ at note As long @b devinfo reports a @b base or @b size of zero there is
+ at b no framebuffer memory yet!
+
+This framebuffer device is not initialized yet. As shown in the list, it
+supports two video modes: QVGA and VGA.
+
+So, the user can first specifiy the video output device with (for example)
+ at verbatim
+barebox:/ fb0.mode="QVGA"
+ at endverbatim
+
+After this the @b devinfo output changes to:
+ at verbatim
+barebox:/ devinfo fb0
+base  : 0x31fc0000
+size  : 0x00040000
+driver: framebuffer
+
+ Video/Mode info:
+  Video output not enabled
+ Current video mode:
+  Name: QVGA
+  Refresh rate: 60 Hz
+  Horizontal active pixel: 320
+  Vertical active lines: 240
+  Pixel clock: 6500 kHz
+  Left/Right margin (pixel): 20/20
+  Upper/Lower margin (lines): 10/10
+  HSYNC length in pixel: 10, polarity: high
+  VSYNC length in lines: 5, polarity: high
+  Colour depth: 16 bpp
+ Supported video mode(s):
+  'QVGA'
+  'VGA'
+Parameters:
+          cdepth = 16
+            mode = QVGA
+          enable = <NULL>
+ at endverbatim
+As one can see, the framebuffer has a @b base, a @b size and a video mode
+configuration now.
+ at note Take care if setting a video mode fails. In this case @b base and @b size
+will kept at zero!
+
+With this setting its possible to write some kind of image into the framebuffer
+memory and enabling the video output as the final step at runtime
+ at verbatim
+barebox:/ fb0.enable=1
+ at endverbatim
+The video output is fully enabled now:
+ at verbatim
+barebox:/ devinfo fb0
+base  : 0x31fc0000
+size  : 0x00040000
+driver: framebuffer
+
+ Video/Mode info:
+  Video output enabled
+ Current video mode:
+  Name: QVGA
+  Refresh rate: 60 Hz
+  Horizontal active pixel: 320
+  Vertical active lines: 240
+  Pixel clock: 6500 kHz
+  Left/Right margin (pixel): 20/20
+  Upper/Lower margin (lines): 10/10
+  HSYNC length in pixel: 10, polarity: high
+  VSYNC length in lines: 5, polarity: high
+  Colour depth: 16 bpp
+ Supported video mode(s):
+  'QVGA'
+  'VGA'
+Parameters:
+          cdepth = 16
+            mode = QVGA
+          enable = 1
+ at endverbatim
+
+ at section other_fb_params Other framebuffer parameter
+ at verbatim
+fb0.cdepth=[1 | 4 | 8 | 16 | 24 | 32]
+ at endverbatim
+
+Only available if "Delayed initialization" is selected. Colour depth to be used with the
+framebuffer. Its unit is "bit per pixel" and the default value is 16 bits per pixel (means
+"RGB565" format). This value can only be changed prior specifying the video mode.
+
+ at note The possible values from the list above are hardware dependend.
+
+ at note The default colour depth value may also depend on the hardware
+*/
+
+/**
+ * @page fb_for_developers Framebuffer handling for developers
+ * For the platform developer:
+ *
+ * When filling the platform specific video output device description you can still provide only one entry and
+ * you should setup the 'mode_cnt' entry with 0: Initialisation of the video hardware and enabling the
+ * video output device will still happen immediately.
+ *
+ * If you provide more than one video output device description use an array of this type. In this case the
+ * 'mode_cnt' entry must contain the count of existing array entries (> 1). Give each video output
+ * device description entry an unique name, because a user will select the required output device by this name
+ * at runtime.
+ *
+ * For the video hardware driver developer:
+ *
+ * Don't initialize a special video mode in your probe function (e.g. don't allocate any framebuffer memory aso).
+ * The framework will call back your exported fb_mode() function to do so (immediately ore delayed).
+ *
+ * Don't enable video output in your probe or exported fb_mode() function. Also do not switch on any LCD or
+ * backlight if any. The framework will call your exported fb_enable() function to do so (immediately ore delayed).
+ *
+ * If your hardware cannot handle the default 16 bit colour depth, change the 'bits_per_pixel' field
+ * prior registering your framebuffer.
+ *
+ * When your exported fb_mode() function is called, calculate the amount of memory you need for the requested
+ * video mode and colour depth, save this value to framebuffer's info struct in field 'size' and allocate some
+ * memory with this size for the framebuffer.
+ *
+ */
diff --git a/include/fb.h b/include/fb.h
index e0cd6aa..b17cc7d 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -18,19 +18,27 @@
 					/* vtotal = 121d/242n/484i => NTSC */
 #define FB_SYNC_ON_GREEN	32	/* sync on green */
 /* LC display related settings */
+/** LC display uses active high data enable signal */
 #define FB_SYNC_DE_HIGH_ACT	(1 << 6)
+/** LC display will latch its data at clock's rising edge */
 #define FB_SYNC_CLK_INVERT	(1 << 7)
+/** output RGB data inverted */
 #define FB_SYNC_DATA_INVERT	(1 << 8)
+/** Stop clock if no data is sent (required for passive displays) */
 #define FB_SYNC_CLK_IDLE_EN	(1 << 9)
+/** swap RGB to BGR */
 #define FB_SYNC_SWAP_RGB	(1 << 10)
+/** FIXME */
 #define FB_SYNC_CLK_SEL_EN	(1 << 11)
+/** enable special signals for SHARP displays (_very_ hardware specific) */
 #define FB_SYNC_SHARP_MODE	(1 << 31)
 
-#define FB_VMODE_NONINTERLACED  0	/* non interlaced */
-#define FB_VMODE_INTERLACED	1	/* interlaced	*/
+#define FB_VMODE_NONINTERLACED  0	/** non interlaced */
+#define FB_VMODE_INTERLACED	1	/** interlaced	*/
 #define FB_VMODE_DOUBLE		2	/* double scan */
-#define FB_VMODE_ODD_FLD_FIRST	4	/* interlaced: top line first */
+#define FB_VMODE_ODD_FLD_FIRST	4	/** interlaced: top line first */
 /* LC display related settings */
+/** output two screen parts at once (required for passive displays) */
 #define FB_VMODE_DUAL_SCAN	8
 #define FB_VMODE_MASK		255
 
@@ -42,19 +50,24 @@
 #define KHZ2PICOS(a) (1000000000UL/(a))
 
 struct fb_videomode {
-	const char *name;	/* optional */
-	unsigned refresh;		/* optional */
-	unsigned xres;
-	unsigned yres;
-	unsigned pixclock;
-	unsigned left_margin;
-	unsigned right_margin;
-	unsigned upper_margin;
-	unsigned lower_margin;
-	unsigned hsync_len;
-	unsigned vsync_len;
-	unsigned sync;
-	unsigned vmode;
+	const char *name;	/**< always required and must be unique */
+	unsigned refresh;	/**< frame refresh rate in [Hz] (optional) */
+	unsigned xres;		/**< visible horizontal pixel */
+	unsigned yres;		/**< visible vertical pixel */
+	unsigned pixclock;	/**< pixel clock period in [ps]. Refer
+				     PICOS2KHZ/KHZ2PICOS macros */
+	unsigned left_margin;	/**< distance in pixels between ending active HSYNC
+				     and starting visible line content */
+	unsigned right_margin;	/**< distance in pixels between ending visible line
+				     content and starting active HSYNC */
+	unsigned upper_margin;	/**< distance in lines between ending active VSYNC
+				     and the first line with visible content */
+	unsigned lower_margin;	/**< distance in lines between last line with
+				     visible content and starting active VSYNC */
+	unsigned hsync_len;	/**< HSYNC's active length in pixels */
+	unsigned vsync_len;	/**< VSYNC's active lenght in lines */
+	unsigned sync;		/**< sync information, refer FB_SYNC_* macros */
+	unsigned vmode;		/**< video mode information, refer FB_VMODE_* macros */
 	unsigned flag;
 };
 
@@ -69,18 +82,33 @@ struct fb_videomode {
  * of available palette entries (i.e. # of entries = 1 << length).
  */
 struct fb_bitfield {
-	unsigned offset;		/* beginning of bitfield	*/
-	unsigned length;		/* length of bitfield		*/
-	int msb_right;			/* != 0 : Most significant bit is right */
+	unsigned offset;		/**< beginning of bitfield	*/
+	unsigned length;		/**< length of bitfield		*/
+	int msb_right;			/**< != 0 : Most significant bit is right */
 };
 
 struct fb_info;
 
+/**
+ * Framebuffer device's platform information
+ *
+ * The video hardware driver must set the following fields:
+ * - 'fb_mode' function to setup a specific video mode
+ * - 'fb_enable' function to activate the video output
+ * - 'fb_disable' function to deactivate the video output
+ * - 'fb_setcolreg' function to ???????? FIXME
+ *
+ * The video hardware driver can set default values for the following fields:
+ * - 'mode' if the driver supports only specific video modes.
+ * - 'mode_cnt' must be set, if 'mode_list' is given
+ * - 'bits_per_pixel' if the video hardware driver defaults to another bpp than 16
+ */
 struct fb_host {
-	const struct fb_videomode *mode;
-	unsigned mode_cnt;
+	/* information about possible video mode(s) */
+	const struct fb_videomode *mode;	/**< Array of modes */
+	unsigned mode_cnt;		/**< count of entries in 'mode'. */
 
-	struct device_d *hw_dev;
+	struct device_d *hw_dev;	/**< the host device */
 
 	/* callbacks into the video hardware driver */
 	int (*fb_setcolreg)(struct fb_info*, unsigned, unsigned, unsigned, unsigned, unsigned);
@@ -88,24 +116,28 @@ struct fb_host {
 	void (*fb_enable)(struct fb_info*);
 	void (*fb_disable)(struct fb_info*);
 
-	unsigned bits_per_pixel;
+	unsigned bits_per_pixel;	/**< default bpp, 0 = use framebuffer's default */
 };
 
+/**
+ * Framebuffer's runtime information
+ */
 struct fb_info {
-	struct fb_host *host;
-	struct device_d *fb_dev;
+	struct fb_host *host;		/**< host data this fb is based on */
+	struct device_d *fb_dev;	/**< the framebuffer device */
+	/* information about current video mode */
+	/** the currently active video mode if set. Can be NULL = no video mode set yet */
 	const struct fb_videomode *active_mode;
+	unsigned xres;			/**< visible horizontal pixel count */
+	unsigned yres;			/**< visible vertical line count */
+	unsigned bits_per_pixel;	/**< requested colour depth */
 
-	unsigned xres;			/* visible resolution		*/
-	unsigned yres;
-	unsigned bits_per_pixel;	/* guess what			*/
-
-	int grayscale;			/* != 0 Graylevels instead of colors */
+	int grayscale;			/**< != 0 Graylevels instead of colors */
 
-	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
-	struct fb_bitfield green;	/* else only length is significant */
+	struct fb_bitfield red;		/**< bitfield in fb mem if true color, */
+	struct fb_bitfield green;	/**< else only length is significant */
 	struct fb_bitfield blue;
-	struct fb_bitfield transp;	/* transparency			*/
+	struct fb_bitfield transp;	/**< transparency			*/
 
 #ifdef CONFIG_VIDEO_DELAY_ENABLING
 	int enabled;
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:22 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:22 +0200
Subject: =?UTF-8?q?=5BPATCH=2008/11=5D=20Add=20a=20video=20driver=20for=20S3C2440=20bases=20platforms?=
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-9-git-send-email-jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
---
 arch/arm/mach-s3c24xx/include/mach/fb.h |   40 +++
 drivers/video/Kconfig                   |    6 +
 drivers/video/Makefile                  |    1 +
 drivers/video/s3c.c                     |  454 +++++++++++++++++++++++++++++++
 4 files changed, 501 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h
 create mode 100644 drivers/video/s3c.c

diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h
new file mode 100644
index 0000000..eec6164
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/fb.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __MACH_FB_H_
+# define __MACH_FB_H_
+
+#include <fb.h>
+
+struct s3c_fb_platform_data {
+
+	const struct fb_videomode *mode_list;
+	unsigned mode_cnt;
+
+	int passive_display;	/**< enable support for STN or CSTN displays */
+
+	void *framebuffer;	/**< force framebuffer base address */
+	unsigned size;		/**< force framebuffer size */
+
+	/** hook to enable backlight and stuff */
+	void (*enable)(int);
+};
+
+#endif /* __MACH_FB_H_ */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index f96accc..64f68c4 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -49,4 +49,10 @@ config DRIVER_VIDEO_IMX_IPU
 	  Add support for the IPU framebuffer device found on
 	  i.MX31 and i.MX35 CPUs.
 
+config S3C_VIDEO
+	bool "S3C244x framebuffer driver"
+	depends on ARCH_S3C24xx
+	help
+	  Add support for the S3C244x LCD controller.
+
 endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 179f0c4..4287fc8 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_VIDEO) += fb.o
 
 obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
 obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
+obj-$(CONFIG_S3C_VIDEO) += s3c.o
diff --git a/drivers/video/s3c.c b/drivers/video/s3c.c
new file mode 100644
index 0000000..cd0f220
--- /dev/null
+++ b/drivers/video/s3c.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ *
+ * This driver is based on a patch found in the web:
+ * (C) Copyright 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge at openmoko.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <fb.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <mach/gpio.h>
+#include <mach/s3c24xx-generic.h>
+#include <mach/s3c24x0-clocks.h>
+#include <mach/fb.h>
+
+#define LCDCON1 0x00
+# define PNRMODE(x) (((x) & 3) << 5)
+# define BPPMODE(x) (((x) & 0xf) << 1)
+# define SET_CLKVAL(x) (((x) & 0x3ff) << 8)
+# define GET_CLKVAL(x) (((x) >> 8) & 0x3ff)
+# define ENVID (1 << 0)
+
+#define LCDCON2 0x04
+# define SET_VBPD(x) (((x) & 0xff) << 24)
+# define SET_LINEVAL(x) (((x) & 0x3ff) << 14)
+# define SET_VFPD(x) (((x) & 0xff) << 6)
+# define SET_VSPW(x) ((x) & 0x3f)
+
+#define LCDCON3 0x08
+# define SET_HBPD(x) (((x) & 0x7f) << 19)
+# define SET_HOZVAL(x) (((x) & 0x7ff) << 8)
+# define SET_HFPD(x) ((x) & 0xff)
+
+#define LCDCON4 0x0c
+# define SET_HSPW(x) ((x) & 0xff)
+
+#define LCDCON5 0x10
+# define BPP24BL (1 << 12)
+# define FRM565 (1 << 11)
+# define INV_CLK (1 << 10)
+# define INV_HS (1 << 9)
+# define INV_VS (1 << 8)
+# define INV_DTA (1 << 7)
+# define INV_DE (1 << 6)
+# define INV_PWREN (1 << 5)
+# define INV_LEND (1 << 4)	/* FIXME */
+# define ENA_PWREN (1 << 3)
+# define ENA_LEND (1 << 2)	/* FIXME */
+# define BSWP (1 << 1)
+# define HWSWP (1 << 0)
+
+#define LCDSADDR1 0x14
+# define SET_LCDBANK(x) (((x) & 0x1ff) << 21)
+# define GET_LCDBANK(x) (((x) >> 21) & 0x1ff)
+# define SET_LCDBASEU(x) ((x) & 0x1fffff)
+# define GET_LCDBASEU(x) ((x) & 0x1fffff)
+
+#define LCDSADDR2 0x18
+# define SET_LCDBASEL(x) ((x) & 0x1fffff)
+# define GET_LCDBASEL(x) ((x) & 0x1fffff)
+
+#define LCDSADDR3 0x1c
+# define SET_OFFSIZE(x) (((x) & 0x7ff) << 11)
+# define GET_OFFSIZE(x) (((x) >> 11) & 0x7ff)
+# define SET_PAGE_WIDTH(x) ((x) & 0x3ff)
+# define GET_PAGE_WIDTH(x) ((x) & 0x3ff)
+
+#define RED_LUT 0x20
+#define GREEN_LUT 0x24
+#define BLUE_LUT 0x28
+
+#define DITHMODE 0x4c
+
+#define TPAL 0x50
+
+#define LCDINTPND 0x54
+
+#define LCDSRCPND 0x58
+
+#define LCDINTMSK 0x5c
+# define FIWSEL (1 << 2)
+
+#define TCONSEL 0x60
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+struct s3cfb_host {
+	struct fb_host fb_data;
+	struct device_d *hw_dev;
+	void __iomem *base;
+};
+
+#define fb_info_to_s3cfb_host(x) ((struct s3cfb_host*)((x)->host))
+#define s3cfb_host_to_s3c_fb_platform_data(x) ((struct s3c_fb_platform_data*)((x)->hw_dev->platform_data))
+
+/* the RGB565 true colour mode */
+static const struct fb_bitfield def_rgb565[] = {
+	[RED] = {
+		.offset = 11,
+		.length = 5,
+	},
+	[GREEN] = {
+		.offset = 5,
+		.length = 6,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 5,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/* the RGB888 true colour mode */
+static const struct fb_bitfield def_rgb888[] = {
+	[RED] = {
+		.offset = 16,
+		.length = 8,
+	},
+	[GREEN] = {
+		.offset = 8,
+		.length = 8,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 8,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void s3cfb_enable_controller(struct fb_info *fb_info)
+{
+	struct s3cfb_host *fbh = fb_info_to_s3cfb_host(fb_info);
+	struct s3c_fb_platform_data *pdata = s3cfb_host_to_s3c_fb_platform_data(fbh);
+	uint32_t con1;
+
+	pr_debug("%s called\n", __func__);
+
+	con1 = readl(fbh->base + LCDCON1);
+
+	con1 |= ENVID;
+
+	writel(con1, fbh->base + LCDCON1);
+
+	if (pdata->enable)
+		(pdata->enable)(1);
+}
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void s3cfb_disable_controller(struct fb_info *fb_info)
+{
+	struct s3cfb_host *fbh = fb_info_to_s3cfb_host(fb_info);
+	struct s3c_fb_platform_data *pdata = s3cfb_host_to_s3c_fb_platform_data(fbh);
+	uint32_t con1;
+
+	pr_debug("%s called\n", __func__);
+
+	if (pdata->enable)
+		(pdata->enable)(0);
+
+	con1 = readl(fbh->base + LCDCON1);
+
+	con1 &= ~ENVID;
+
+	writel(con1, fbh->base + LCDCON1);
+}
+
+/**
+ * Prepare the video hardware for a specified video mode
+ * @param fb_info Framebuffer information
+ * @param mode The video mode description to initialize
+ * @return 0 on success
+ *
+ * FIXME Diese Routine darf die Pinx nach drau?en nicht aktivieren. Zur Zeit macht sie das!
+ */
+static int s3cfb_initialize_mode(struct fb_info *fb_info, const struct fb_videomode *mode)
+{
+	struct s3cfb_host *fbh = fb_info_to_s3cfb_host(fb_info);
+	struct s3c_fb_platform_data *pdata = s3cfb_host_to_s3c_fb_platform_data(fbh);
+	unsigned size, hclk, div;
+	uint32_t con1, con2, con3, con4, con5 = 0;
+
+	pr_debug("%s called\n", __func__);
+
+	if (pdata->passive_display != 0) {
+		pr_err("Passive displays are currently not supported\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = mode->xres * mode->yres * (fb_info->bits_per_pixel >> 3);
+	if (fb_info->fb_dev->size != 0) {
+		if (size > fb_info->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, fb_info->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		fb_info->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (fb_info->fb_dev->map_base == 0U)
+		fb_info->fb_dev->map_base = (resource_size_t)xzalloc(fb_info->fb_dev->size);
+
+	/* its useful to enable the unit's clock */
+	s3c244x_mod_clock(CLK_LCDC, 1);
+
+	/* ensure video output is _off_ */
+	writel(0x00000000, fbh->base + LCDCON1);
+
+	hclk = s3c24xx_get_hclk() / 1000U;	/* hclk in kHz */
+	div = hclk / PICOS2KHZ(mode->pixclock);
+	if (div < 3)
+		div  = 3;
+	/* pixel clock is: (hclk) / ((div + 1) * 2) */
+	div += 1;
+	div >>= 1;
+	div -= 1;
+
+	con1 = PNRMODE(3) | SET_CLKVAL(div);	/* PNRMODE=3 is TFT */
+
+	switch (fb_info->bits_per_pixel) {
+#if 0
+	/* TODO add CLUT based modes */
+	case 1:
+		con1 |= BPPMODE(8);
+		break;
+	case 2:
+		con1 |= BPPMODE(9);
+		break;
+	case 4:
+		con1 |= BPPMODE(10);
+		break;
+	case 8:
+		con1 |= BPPMODE(11);
+		break;
+#endif
+	case 16:
+		con1 |= BPPMODE(12);
+		con5 |= FRM565;
+		fb_info->red = def_rgb565[RED];
+		fb_info->green = def_rgb565[GREEN];
+		fb_info->blue = def_rgb565[BLUE];
+		fb_info->transp =  def_rgb565[TRANSP];
+		break;
+	case 24:
+		con1 |= BPPMODE(13);
+		con5 |= BPP24BL;	/* FIXME */
+		fb_info->red = def_rgb888[RED];
+		fb_info->green = def_rgb888[GREEN];
+		fb_info->blue = def_rgb888[BLUE];
+		fb_info->transp =  def_rgb888[TRANSP];
+		break;
+	default:
+		pr_err("Invalid bits per pixel value: %u\n", fb_info->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	/* 'normal' in register description means positive logic */
+	if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
+		con5 |= INV_HS;
+	if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
+		con5 |= INV_VS;
+	if (!(mode->sync & FB_SYNC_DE_HIGH_ACT))
+		con5 |= INV_DE;
+	if (mode->sync & FB_SYNC_CLK_INVERT)
+		con5 |= INV_CLK;	/* display should latch at the rising edge */
+	if (mode->sync & FB_SYNC_SWAP_RGB)
+		con5 |= HWSWP;
+
+	/* TODO power enable config via platform data */
+
+	/* vertical timing */
+	con2 = SET_VBPD(mode->upper_margin - 1) |
+		SET_LINEVAL(mode->yres - 1) |
+		SET_VFPD(mode->lower_margin - 1) |
+		SET_VSPW(mode->vsync_len - 1);
+
+	/* horizontal timing */
+	con3 = SET_HBPD(mode->left_margin - 1) |
+		SET_HOZVAL(mode->xres - 1) |
+		SET_HFPD(mode->right_margin - 1);
+	con4 = SET_HSPW(mode->hsync_len - 1);
+
+	/* basic timing setup */
+	writel(con1, fbh->base + LCDCON1);
+	pr_debug(" Writing %08X into %08X (con1)\n", con1, fbh->base + LCDCON1);
+	writel(con2, fbh->base + LCDCON2);
+	pr_debug(" Writing %08X into %08X (con2)\n", con2, fbh->base + LCDCON2);
+	writel(con3, fbh->base + LCDCON3);
+	pr_debug(" Writing %08X into %08X (con3)\n", con3, fbh->base + LCDCON3);
+	writel(con4, fbh->base + LCDCON4);
+	pr_debug(" Writing %08X into %08X (con4)\n", con4, fbh->base + LCDCON4);
+	writel(con5, fbh->base + LCDCON5);
+	pr_debug(" Writing %08X into %08X (con5)\n", con5, fbh->base + LCDCON5);
+
+	pr_debug("Setting up the fb baseadress to %08X\n", fb_info->fb_dev->map_base);
+
+	/* framebuffer memory setup */
+	writel(fb_info->fb_dev->map_base >> 1, fbh->base + LCDSADDR1);
+	size = mode->xres * (fb_info->bits_per_pixel >> 3) * (mode->yres);
+	writel(SET_LCDBASEL((fb_info->fb_dev->map_base + size) >> 1), fbh->base + LCDSADDR2);
+
+	writel(SET_OFFSIZE(0) |
+		SET_PAGE_WIDTH((mode->xres * fb_info->bits_per_pixel) >> 4),
+		fbh->base + LCDSADDR3);
+
+	writel(FIWSEL, fbh->base + LCDINTMSK);
+
+	return 0;
+}
+
+/**
+ * Print some information about the current hardware state
+ * @param hw_dev S3C video device
+ */
+#ifdef CONFIG_VIDEO_INFO_VERBOSE
+static void s3cfb_info(struct device_d *hw_dev)
+{
+	uint32_t con1, con2, con3, con4, con5, addr1, addr2, addr3;
+
+	con1 = readl(hw_dev->map_base + LCDCON1);
+	addr1 = readl(hw_dev->map_base + LCDSADDR1);
+	addr2 = readl(hw_dev->map_base + LCDSADDR2);
+	addr3 = readl(hw_dev->map_base + LCDSADDR3);
+
+	printf(" Video hardware info:\n");
+	printf("  Video clock is running at %u Hz\n", s3c24xx_get_hclk() / ((GET_CLKVAL(con1) + 1) * 2));
+	printf("  Video memory bank starts at 0x%08X\n", GET_LCDBANK(addr1) << 22);
+	printf("  Video memory bank offset: 0x%08X\n", GET_LCDBASEU(addr1));
+	printf("  Video memory end: 0x%08X\n", GET_LCDBASEU(addr2));
+	printf("  Virtual screen offset size: %u half words\n", GET_OFFSIZE(addr3));
+	printf("  Virtual screen page width: %u half words\n", GET_PAGE_WIDTH(addr3));
+}
+#endif
+
+/*
+ * There is only one video hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct s3cfb_host host_data = {
+	.fb_data.fb_mode = s3cfb_initialize_mode,
+	.fb_data.fb_enable = s3cfb_enable_controller,
+	.fb_data.fb_disable = s3cfb_disable_controller,
+};
+
+static int s3cfb_probe(struct device_d *hw_dev)
+{
+	struct s3c_fb_platform_data *pdata = hw_dev->platform_data;
+	struct device_d *fb_dev;
+
+	pr_debug("%s called\n", __func__);
+
+	if (pdata == NULL) {
+		pr_debug("Framebuffer driver missing platform data");
+		return -ENODEV;
+	}
+
+	/* enable unit's clock */
+	s3c244x_mod_clock(CLK_LCDC, 1);
+
+	writel(0, hw_dev->map_base + LCDCON1);
+	/* off may be means high level */
+	writel(0, hw_dev->map_base + LCDCON5);
+
+	/* disable it again until user request */
+	s3c244x_mod_clock(CLK_LCDC, 0);
+
+	/* add runtime hardware info */
+	host_data.hw_dev = hw_dev;
+	host_data.base = (void*)hw_dev->map_base;
+
+	/* add runtime video info */
+	host_data.fb_data.mode = pdata->mode_list;
+	host_data.fb_data.mode_cnt = pdata->mode_cnt;
+
+	fb_dev = register_framebuffer(&host_data.fb_data, pdata->framebuffer, pdata->size);
+	if (fb_dev == NULL) {
+		pr_err("Failed to register framebuffer\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct driver_d s3cfb_driver = {
+	.name	= "s3cfb",
+	.probe	= s3cfb_probe,
+#ifdef CONFIG_VIDEO_INFO_VERBOSE
+	.info	= s3cfb_info,
+#endif
+};
+
+static int s3cfb_init(void)
+{
+	return register_driver(&s3cfb_driver);
+}
+
+device_initcall(s3cfb_init);
+
+/**
+ * The S3C244x LCD controller supports passive (CSTN/STN) and active (TFT) LC displays
+ *
+ * The driver itself currently supports only active TFT LC displays in the follwing manner:
+ *
+ *  * Palletized colours
+ *    - 1 bpp
+ *    - 2 bpp
+ *    - 4 bpp
+ *    - 8 bpp
+ *  * True colours
+ *    - 16 bpp
+ *    - 24 bpp
+ */
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 12:53:24 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 18:53:24 +0200
Subject: [PATCH 10/11] Remove variable size restrictions
In-Reply-To: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1287766405-1646-11-git-send-email-jbe@pengutronix.de>

There is no really need for special variable types in these structures. Replace
them by standard C types with the same behaviour.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 include/fb.h |   41 ++++++++++++++++++++---------------------
 1 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/include/fb.h b/include/fb.h
index c004a56..e0cd6aa 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -43,19 +43,19 @@
 
 struct fb_videomode {
 	const char *name;	/* optional */
-	u32 refresh;		/* optional */
-	u32 xres;
-	u32 yres;
-	u32 pixclock;
-	u32 left_margin;
-	u32 right_margin;
-	u32 upper_margin;
-	u32 lower_margin;
-	u32 hsync_len;
-	u32 vsync_len;
-	u32 sync;
-	u32 vmode;
-	u32 flag;
+	unsigned refresh;		/* optional */
+	unsigned xres;
+	unsigned yres;
+	unsigned pixclock;
+	unsigned left_margin;
+	unsigned right_margin;
+	unsigned upper_margin;
+	unsigned lower_margin;
+	unsigned hsync_len;
+	unsigned vsync_len;
+	unsigned sync;
+	unsigned vmode;
+	unsigned flag;
 };
 
 /* Interpretation of offset for color fields: All offsets are from the right,
@@ -69,10 +69,9 @@ struct fb_videomode {
  * of available palette entries (i.e. # of entries = 1 << length).
  */
 struct fb_bitfield {
-	u32 offset;			/* beginning of bitfield	*/
-	u32 length;			/* length of bitfield		*/
-	u32 msb_right;			/* != 0 : Most significant bit is */ 
-					/* right */ 
+	unsigned offset;		/* beginning of bitfield	*/
+	unsigned length;		/* length of bitfield		*/
+	int msb_right;			/* != 0 : Most significant bit is right */
 };
 
 struct fb_info;
@@ -97,11 +96,11 @@ struct fb_info {
 	struct device_d *fb_dev;
 	const struct fb_videomode *active_mode;
 
-	u32 xres;			/* visible resolution		*/
-	u32 yres;
-	u32 bits_per_pixel;		/* guess what			*/
+	unsigned xres;			/* visible resolution		*/
+	unsigned yres;
+	unsigned bits_per_pixel;	/* guess what			*/
 
-	u32 grayscale;			/* != 0 Graylevels instead of colors */
+	int grayscale;			/* != 0 Graylevels instead of colors */
 
 	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
 	struct fb_bitfield green;	/* else only length is significant */
-- 
1.7.2.3



From jbe at pengutronix.de  Fri Oct 22 13:21:31 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 22 Oct 2010 19:21:31 +0200
Subject: [PATCH 13/32] doc: fix typo
In-Reply-To: <1287765924-1856-14-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
	<1287765924-1856-14-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <201010221921.31210.jbe@pengutronix.de>

Robert Schwebel wrote:
> Remove a # which leads to this warning:
> arch/arm/mach-s3c24xx/lowlevel-init.S:307: Warning: explicit link request
> to 'CALC_NFCONF_TIMING' could not be resolved
>
> Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
> ---
>  arch/arm/mach-s3c24xx/lowlevel-init.S |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-s3c24xx/lowlevel-init.S
> b/arch/arm/mach-s3c24xx/lowlevel-init.S index e8004e5..27f3a32 100644
> --- a/arch/arm/mach-s3c24xx/lowlevel-init.S
> +++ b/arch/arm/mach-s3c24xx/lowlevel-init.S
> @@ -304,7 +304,7 @@ minimalistic. Setup the NAND access timing is done in a
> safe manner, what means: Slowest possible values are used. If you want to
> increase the speed you should define the BOARD_DEFAULT_NAND_TIMING to a
> valid setting into the NFCONF register and add it to your board specific
> config.h. Refer S3C24x0's -datasheet for further details. The macro
> #CALC_NFCONF_TIMING could help to +datasheet for further details. The macro
> CALC_NFCONF_TIMING could help to calculate the register setting in a
> hardware independent manner.
>
>  @note The regular NAND driver uses a platform data structure to define the

Hmm, but this macro exists and doxygen should generate a reference to it. 
Don't know why it spits out a warning here.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Fri Oct 22 13:41:09 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 19:41:09 +0200
Subject: [PATCH 03/11] Bring in dynamic videomode selection at runtime
In-Reply-To: <1287766405-1646-4-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-4-git-send-email-jbe@pengutronix.de>
Message-ID: <20101022174109.GF22139@pengutronix.de>

On Fri, Oct 22, 2010 at 06:53:17PM +0200, Juergen Beisert wrote:
> This patch mostly rewrites all parts of /drivers/video/fb.c. As it changes
> the API to the drivers, it must be done in one step to keep the repository
> bisectable. But to do it in one step makes the patches itself unreadable.
> 
> So, I decided to do it in a few steps, only for the review. All patches marked
> with a "step n of m" should be merged, prior the final commit into the
> repository.
> 
> This step brings in the required functions for dynamic videomode selection at
> runtime, but keep the old functions untouched (the new ones are commented out).
> 
> This is patch 1 of 7 to keep the repository bisectable.
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  drivers/video/Kconfig |   23 +++++
>  drivers/video/fb.c    |  251 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/fb.h          |   40 ++++++++
>  3 files changed, 314 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 7a89a3f..e6ecfc8 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -5,6 +5,29 @@ menuconfig VIDEO
>  
>  if VIDEO
>  
> +comment "runtime options"
> +
> +config VIDEO_DELAY_ENABLING
> +	bool "Delayed enabling"
> +	help
> +	  Say 'y' here to delay enabling video output. This is useful to first
> +	  fill the framebuffer (splash screen for example) prior enabling the
> +	  video device.
> +          This entry adds the "enable" parameter to the video device, to enable
> +	  or disable video output at runtime.
> +
> +config VIDEO_DELAY_INIT
> +	bool "Delayed initialization"
> +	select VIDEO_DELAY_ENABLING
> +	help
> +	  If the platform supports more than one video mode say 'y' her to delay
> +	  the initialization of the video device until any kind of barebox's
> +          shell code sets up the correct mode at runtime.
> +          This entry adds the "mode" parameter to the video device, to setup
> +          the desired videomode prior enabling it at runtime.

I think the framebuffers should *never* be activated by the setup code
and should be explicitely initialized by doing a 'fb0.enable=1' on the
command line. This way we have the most flexibility. We can enable
the framebuffer when we actually need it, we can draw a splash screen
before enabling it so that we do not have a black screen before we draw
an image. Also, the environment can decide to leave the framebuffer
disabled because the kernel will draw another screen a second later. If
necessary, the environemt can do a fb0.display="sharp-whatever" before
activating it. And we do not need any kconfig options for this.

Sascha


> +
> +comment "drivers"
> +
>  config DRIVER_VIDEO_IMX
>  	bool "i.MX framebuffer driver"
>  	depends on ARCH_IMX1 || ARCH_IMX21 || ARCH_IMX25 || ARCH_IMX27
> diff --git a/drivers/video/fb.c b/drivers/video/fb.c
> index f9a425e..c2934f6 100644
> --- a/drivers/video/fb.c
> +++ b/drivers/video/fb.c
> @@ -1,3 +1,4 @@
> +#include <init.h>
>  #include <common.h>
>  #include <fb.h>
>  #include <errno.h>
> @@ -5,6 +6,8 @@
>  #include <getopt.h>
>  #include <fcntl.h>
>  #include <fs.h>
> +#include <malloc.h>
> +#include <xfuncs.h>
>  
>  static int fb_ioctl(struct cdev* cdev, int req, void *data)
>  {
> @@ -57,6 +60,141 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param,
>  	return 0;
>  }
>  
> +#if 0
> +#ifdef CONFIG_VIDEO_DELAY_INIT
> +static int fb_check_if_already_initialized(struct device_d *fb_dev)
> +{
> +	struct cdev *cdev = fb_dev->priv;
> +	struct fb_info *info = cdev->priv;
> +
> +	if (info->active_mode != NULL) {
> +		pr_err("Video mode '%s' is already set. Cannot change colour depth anymore.\n", info->active_mode->name);
> +		return -EPERM;
> +	}
> +
> +	return 0;
> +}
> +
> +static int fb_cdepth_set(struct device_d *fb_dev, struct param_d *param, const char *val)
> +{
> +	struct cdev *cdev = fb_dev->priv;
> +	struct fb_info *info = cdev->priv;
> +	unsigned cdepth;
> +	int rc;
> +
> +	rc = fb_check_if_already_initialized(fb_dev);
> +	if (rc != 0)
> +		return rc;
> +
> +	cdepth = simple_strtoul(val, NULL, 0);
> +	if (cdepth != 0)
> +		info->bits_per_pixel = cdepth;
> +	else
> +		return -EINVAL;
> +
> +	return dev_param_set_generic(fb_dev, param, val);
> +}
> +#endif
> +
> +#ifdef CONFIG_VIDEO_DELAY_ENABLING
> +static int fb_enable_set(struct device_d *fb_dev, struct param_d *param, const char *val)
> +{
> +	struct cdev *cdev = fb_dev->priv;
> +	struct fb_info *info = cdev->priv;
> +	struct fb_host *host = fb_dev->platform_data;
> +	int enable;
> +	char *new;
> +
> +	if (!val)
> +		return dev_param_set_generic(fb_dev, param, NULL);
> +
> +	enable = simple_strtoul(val, NULL, 0);
> +
> +	if (info->enabled == !!enable)
> +		return 0;
> +
> +	if (enable) {
> +		(host->fb_enable)(info);
> +		new = "1";
> +	} else {
> +		(host->fb_disable)(info);
> +		new = "0";
> +	}
> +
> +	info->enabled = !!enable;
> +
> +	return dev_param_set_generic(fb_dev, param, new);
> +}
> +#endif
> +
> +static void fb_list_modes(struct fb_host *host)
> +{
> +	unsigned u;
> +
> +	if (host->mode_cnt == 0)
> +		return;
> +
> +	printf(" Supported video mode(s):\n");
> +	for (u = 0; u < host->mode_cnt; u++)
> +		printf("  '%s'\n", host->mode[u].name);
> +}
> +
> +static int fb_activate_mode(struct device_d *fb_dev, const struct fb_videomode *mode)
> +{
> +	struct cdev *cdev = fb_dev->priv;
> +	struct fb_info *info = cdev->priv;
> +	struct fb_host *host = fb_dev->platform_data;
> +	int rc;
> +
> +	rc = (host->fb_mode)(info, mode);
> +	if (rc != 0)
> +		return rc;
> +
> +	info->active_mode = mode;
> +	/*
> +	 * At this point of time we know the remaining information we need
> +	 * for the cdev and fb_info structure.
> +	 */
> +	cdev->size = fb_dev->size;
> +	info->xres = mode->xres;
> +	info->yres = mode->yres;
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_VIDEO_DELAY_INIT
> +static int fb_mode_set(struct device_d *fb_dev, struct param_d *param, const char *name)
> +{
> +	struct fb_host *host = fb_dev->platform_data;
> +	unsigned u;
> +	int rc;
> +
> +	pr_debug("%s called\n", __func__);
> +
> +	rc = fb_check_if_already_initialized(fb_dev);
> +	if (rc != 0)
> +		return rc;
> +
> +	/* Search for the requested video mode by name */
> +	for (u = 0; u < host->mode_cnt; u++) {
> +		if (!strcmp(host->mode[u].name, name))
> +			break;
> +	}
> +	if (u >= host->mode_cnt) {
> +		fb_list_modes(host);	/* no mode with 'name' found */
> +		return -ENODEV;
> +	} else {
> +		rc = fb_activate_mode(fb_dev, &host->mode[u]);
> +	}
> +
> +	if (rc == 0)
> +		dev_param_set_generic(fb_dev, param, name);
> +
> +	return rc;
> +}
> +#endif
> +#endif
> +
>  static struct file_operations fb_ops = {
>  	.read	= mem_read,
>  	.write	= mem_write,
> @@ -65,6 +203,119 @@ static struct file_operations fb_ops = {
>  	.ioctl	= fb_ioctl,
>  };
>  
> +#if 0
> +static int add_fb_parameter(struct device_d *fb_dev)
> +{
> +#ifdef CONFIG_VIDEO_DELAY_INIT
> +	struct cdev *cdev = fb_dev->priv;
> +	struct fb_info *info = cdev->priv;
> +	char cd[10];
> +
> +	/** @todo provide base address parameter for the user */
> +
> +	dev_add_param(fb_dev, "cdepth", fb_cdepth_set, NULL, 0);
> +	if (info->bits_per_pixel == 0) {
> +		dev_set_param(fb_dev, "cdepth", "16");
> +		info->bits_per_pixel = 16;
> +	} else {
> +		sprintf(cd, "%u", info->bits_per_pixel);
> +		dev_set_param(fb_dev, "cdepth", cd);
> +	}
> +	dev_add_param(fb_dev, "mode", fb_mode_set, NULL, 0);
> +	/* default is 'none' for delayed video mode setup */
> +#endif
> +#ifdef CONFIG_VIDEO_DELAY_ENABLING
> +	dev_add_param(fb_dev, "enable", fb_enable_set, NULL, 0);
> +	/* default is 'off' for delayed video output */
> +#endif
> +	return 0;
> +}
> +
> +struct framebuffer_desc {
> +	struct cdev cdev;
> +	struct fb_info info;
> +};
> +
> +static int fb_probe(struct device_d *fb_dev)
> +{
> +	int id = get_free_deviceid("fb");
> +	struct cdev *cdev;
> +	struct fb_info *info;
> +	struct fb_host *host = fb_dev->platform_data;
> +
> +	cdev = xzalloc(sizeof(struct framebuffer_desc));
> +	info = (struct fb_info*)&cdev[1];
> +
> +	fb_dev->priv = cdev;	/* pointer forward */
> +	cdev->dev = fb_dev;	/* pointer backward */
> +
> +	cdev->ops = &fb_ops;
> +	cdev->name = asprintf("fb%d", id);
> +
> +	cdev->size = fb_dev->size;	/* use the default if any */
> +	cdev->priv = info;
> +
> +	info->host = host;
> +	info->fb_dev = fb_dev;
> +
> +	/* setup defaults */
> +	if (host->bits_per_pixel != 0)
> +		info->bits_per_pixel = host->bits_per_pixel;
> +	else
> +		info->bits_per_pixel = 16;	/* means RGB565 */
> +
> +	/* add params on demand */
> +	add_fb_parameter(fb_dev);
> +
> +	devfs_create(cdev);
> +#ifndef CONFIG_VIDEO_DELAY_INIT
> +	/* initialize video mode immediately (the first one) */
> +	fb_activate_mode(fb_dev, &host->mode[0]);
> +#endif
> +#ifndef CONFIG_VIDEO_DELAY_ENABLING
> +	/* enable video output immediately */
> +	(host->fb_enable)(info);
> +#endif
> +	return 0;
> +}
> +
> +static struct driver_d fb_driver = {
> +	.name	= "framebuffer",
> +	.probe	= fb_probe,
> +};
> +
> +static int framebuffer_init(void)
> +{
> +	return register_driver(&fb_driver);
> +}
> +
> +device_initcall(framebuffer_init);
> +
> +struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned size)
> +{
> +	struct device_d *fb_dev;
> +	int rc;
> +
> +	fb_dev = xzalloc(sizeof(struct device_d));
> +
> +	strcpy(fb_dev->name, fb_driver.name);
> +	fb_dev->platform_data = (void*)host;
> +
> +	/* setup the defaults for this framebuffer if given */
> +	fb_dev->size = size;
> +	fb_dev->map_base = (unsigned long)base;
> +
> +	rc = register_device(fb_dev);
> +	if (rc != 0) {
> +		pr_debug("Cannot register framebuffer device\n");
> +		free(fb_dev);
> +		return NULL;
> +	}
> +
> +	return fb_dev;
> +}
> +#endif
> +
>  int register_framebuffer(struct fb_info *info)
>  {
>  	int id = get_free_deviceid("fb");
> diff --git a/include/fb.h b/include/fb.h
> index 218b244..96edc24 100644
> --- a/include/fb.h
> +++ b/include/fb.h
> @@ -85,6 +85,46 @@ struct fb_ops {
>  	void (*fb_disable)(struct fb_info *info);
>  };
>  
> +#if 0
> +struct fb_host {
> +	const struct fb_videomode *mode;
> +	unsigned mode_cnt;
> +
> +	struct device_d *hw_dev;
> +
> +	/* callbacks into the video hardware driver */
> +	int (*fb_setcolreg)(struct fb_info*, unsigned, unsigned, unsigned, unsigned, unsigned);
> +	int (*fb_mode)(struct fb_info*, const struct fb_videomode*);
> +	void (*fb_enable)(struct fb_info*);
> +	void (*fb_disable)(struct fb_info*);
> +
> +	unsigned bits_per_pixel;
> +};
> +
> +struct fb_info {
> +	struct fb_host *host;
> +	struct device_d *fb_dev;
> +	const struct fb_videomode *active_mode;
> +
> +	u32 xres;			/* visible resolution		*/
> +	u32 yres;
> +	u32 bits_per_pixel;		/* guess what			*/
> +
> +	u32 grayscale;			/* != 0 Graylevels instead of colors */
> +
> +	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
> +	struct fb_bitfield green;	/* else only length is significant */
> +	struct fb_bitfield blue;
> +	struct fb_bitfield transp;	/* transparency			*/
> +
> +#ifdef CONFIG_VIDEO_DELAY_ENABLING
> +	int enabled;
> +#endif
> +};
> +
> +struct device_d *register_framebuffer(struct fb_host*, void*, unsigned);
> +#endif
> +
>  struct fb_info {
>  	struct fb_videomode *mode;
>  
> -- 
> 1.7.2.3
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct 22 13:43:04 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 19:43:04 +0200
Subject: [PATCH 07/11] Adapt the existing imx-ipu fb driver to support
	runtime videomode selection
In-Reply-To: <1287766405-1646-8-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-8-git-send-email-jbe@pengutronix.de>
Message-ID: <20101022174304.GG22139@pengutronix.de>

On Fri, Oct 22, 2010 at 06:53:21PM +0200, Juergen Beisert wrote:
> Adapt the API to the new framebuffer videomode selection at runtime. If the new
> feature is not used, there is no visible change at runtime for platforms using
> this driver.

This conflicts with the ipu fb patch I posted today.

Sascha

> 
> NOTE: Due to the lack of hardware, this is compile time tested only.
> 
> This is patch 5 of 7 to keep the repository bisectable.
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  arch/arm/boards/freescale-mx35-3-stack/3stack.c |    2 +-
>  arch/arm/boards/pcm043/pcm043.c                 |    2 +-
>  arch/arm/mach-imx/include/mach/imx-ipu-fb.h     |   12 +--
>  drivers/video/imx-ipu-fb.c                      |  156 +++++++++++++---------
>  4 files changed, 96 insertions(+), 76 deletions(-)
> 
> diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
> index d6699cd..fb40f50 100644
> --- a/arch/arm/boards/freescale-mx35-3-stack/3stack.c
> +++ b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
> @@ -139,7 +139,7 @@ static struct fb_videomode CTP_CLAA070LC0ACW = {
>  	.lower_margin	= 10,	/* whole frame should have 500 lines */
>  	.hsync_len	= 1,	/* note: DE only display */
>  	.vsync_len	= 1,	/* note: DE only display */
> -	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
> +	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_DE_HIGH_ACT,
>  	.vmode		= FB_VMODE_NONINTERLACED,
>  	.flag		= 0,
>  };
> diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
> index 5932f95..7e63cc5 100644
> --- a/arch/arm/boards/pcm043/pcm043.c
> +++ b/arch/arm/boards/pcm043/pcm043.c
> @@ -124,7 +124,7 @@ static struct fb_videomode pcm043_fb_mode = {
>  	.lower_margin	= 40,
>  	.hsync_len	= 96,
>  	.vsync_len	= 1,
> -	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
> +	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_DE_HIGH_ACT,
>  	.vmode		= FB_VMODE_NONINTERLACED,
>  	.flag		= 0,
>  };
> diff --git a/arch/arm/mach-imx/include/mach/imx-ipu-fb.h b/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
> index 8e1cc87..ce95243 100644
> --- a/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
> +++ b/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
> @@ -12,20 +12,12 @@
>  
>  #include <fb.h>
>  
> -/* Proprietary FB_SYNC_ flags */
> -#define FB_SYNC_OE_ACT_HIGH	0x80000000
> -#define FB_SYNC_CLK_INVERT	0x40000000
> -#define FB_SYNC_DATA_INVERT	0x20000000
> -#define FB_SYNC_CLK_IDLE_EN	0x10000000
> -#define FB_SYNC_SHARP_MODE	0x08000000
> -#define FB_SYNC_SWAP_RGB	0x04000000
> -#define FB_SYNC_CLK_SEL_EN	0x02000000
> -
>  /*
> - * struct mx3fb_platform_data - mx3fb platform data
> + * struct imx_ipu_fb_platform_data - imx-ipu-fb's platform data
>   */
>  struct imx_ipu_fb_platform_data {
>  	struct fb_videomode	*mode;
> +	unsigned mode_cnt;	/**< number of entries in 'mode' */
>  	unsigned char		bpp;
>  	void __iomem		*framebuffer;
>  	/** hook to enable backlight and stuff */
> diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
> index 2c25b81..426defc 100644
> --- a/drivers/video/imx-ipu-fb.c
> +++ b/drivers/video/imx-ipu-fb.c
> @@ -34,12 +34,12 @@
>  #include <mach/clock.h>
>  
>  struct ipu_fb_info {
> +	struct  fb_host		fb_host;	/**< myself */
>  	void __iomem		*regs;
>  
>  	void			(*enable)(int enable);
>  
> -	struct fb_info		info;
> -	struct device_d		*dev;
> +	const struct fb_videomode *mode;	/**< requested videomodue */
>  };
>  
>  /* IPU DMA Controller channel definitions. */
> @@ -413,29 +413,30 @@ static inline void reg_write(struct ipu_fb_info *fbi, u32 value,
>  	writel(value, fbi->regs + reg);
>  }
>  
> +#define fb_info_to_imxfb_info(x) ((struct ipu_fb_info*)((x)->host))
> +
>  /*
>   * sdc_init_panel() - initialize a synchronous LCD panel.
> - * @width:		width of panel in pixels.
> - * @height:		height of panel in pixels.
> - * @pixel_fmt:		pixel format of buffer as FOURCC ASCII code.
> + * @param info The framebuffer to work on
> + * @param pixel_fmt pixel format of buffer as FOURCC ASCII code.
>   * @return:		0 on success or negative error code on failure.
>   */
>  static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
>  {
> -	struct ipu_fb_info *fbi = info->priv;
> -	struct fb_videomode *mode = info->mode;
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
> +	const struct fb_videomode *mode = fbi->mode;
>  	u32 reg, old_conf, div;
>  	enum ipu_panel panel = IPU_PANEL_TFT;
>  	unsigned long pixel_clk;
>  
>  	/* Init panel size and blanking periods */
>  	reg = ((mode->hsync_len - 1) << 26) |
> -		((info->xres + mode->left_margin + mode->right_margin +
> +		((mode->xres + mode->left_margin + mode->right_margin +
>  		  mode->hsync_len - 1) << 16);
>  	reg_write(fbi, reg, SDC_HOR_CONF);
>  
>  	reg = ((mode->vsync_len - 1) << 26) | SDC_V_SYNC_WIDTH_L |
> -		((info->yres + mode->upper_margin + mode->lower_margin +
> +		((mode->yres + mode->upper_margin + mode->lower_margin +
>  		  mode->vsync_len - 1) << 16);
>  	reg_write(fbi, reg, SDC_VER_CONF);
>  
> @@ -448,7 +449,7 @@ static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
>  		old_conf |= DI_D3_CLK_POL;
>  	if (mode->sync & FB_SYNC_DATA_INVERT)
>  		old_conf |= DI_D3_DATA_POL;
> -	if (mode->sync & FB_SYNC_OE_ACT_HIGH)
> +	if (mode->sync & FB_SYNC_DE_HIGH_ACT)
>  		old_conf |= DI_D3_DRDY_SHARP_POL;
>  	reg_write(fbi, old_conf, DI_DISP_SIG_POL);
>  
> @@ -483,12 +484,12 @@ static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
>  	div = imx_get_lcdclk() * 16 / pixel_clk;
>  
>  	if (div < 0x40) {	/* Divider less than 4 */
> -		dev_dbg(&info->dev,
> +		dev_dbg(fbi->fb_host.hw_dev,
>  			"InitPanel() - Pixel clock divider less than 4\n");
>  		div = 0x40;
>  	}
>  
> -	dev_dbg(&info->dev, "pixel clk = %u, divider %u.%u\n",
> +	dev_dbg(fbi->fb_host.hw_dev, "pixel clk = %u, divider %u.%u\n",
>  		pixel_clk, div >> 4, (div & 7) * 125);
>  
>  	/*
> @@ -588,19 +589,20 @@ static u32 dma_param_addr(enum ipu_channel channel)
>  	return 0x10000 | (channel << 4);
>  }
>  
> -static void ipu_init_channel_buffer(struct ipu_fb_info *fbi,
> +static void ipu_init_channel_buffer(struct fb_info *info,
>  		enum ipu_channel channel, void *fbmem)
>  {
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
>  	union chan_param_mem params = {};
>  	u32 reg;
>  	u32 stride_bytes;
>  
> -	stride_bytes = fbi->info.xres * ((fbi->info.bits_per_pixel + 7) / 8);
> +	stride_bytes = fbi->mode->xres * ((info->bits_per_pixel + 7) / 8);
>  	stride_bytes = (stride_bytes + 3) & ~3;
>  
>  	/* Build parameter memory data for DMA channel */
> -	ipu_ch_param_set_size(&params, bpp_to_pixfmt(fbi->info.bits_per_pixel),
> -			      fbi->info.xres, fbi->info.yres, stride_bytes);
> +	ipu_ch_param_set_size(&params, bpp_to_pixfmt(info->bits_per_pixel),
> +			      fbi->mode->xres, fbi->mode->yres, stride_bytes);
>  	ipu_ch_param_set_buffer(&params, fbmem, NULL);
>  	params.pp.bam = 0;
>  	/* Some channels (rotation) have restriction on burst length */
> @@ -622,9 +624,10 @@ static void ipu_init_channel_buffer(struct ipu_fb_info *fbi,
>  	reg_write(fbi, reg, IPU_CHA_DB_MODE_SEL);
>  }
>  
> -static void ipu_channel_set_priority(struct ipu_fb_info *fbi,
> +static void ipu_channel_set_priority(struct fb_info *fb_info,
>  		enum ipu_channel channel, int prio)
>  {
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
>  	u32 reg;
>  
>  	reg = reg_read(fbi, IDMAC_CHA_PRI);
> @@ -639,11 +642,13 @@ static void ipu_channel_set_priority(struct ipu_fb_info *fbi,
>  
>  /*
>   * ipu_enable_channel() - enable an IPU channel.
> + * @param info The framebuffer to work on
>   * @channel:	channel ID.
>   * @return:	0 on success or negative error code on failure.
>   */
> -static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
> +static int ipu_enable_channel(struct fb_info *info, enum ipu_channel channel)
>  {
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
>  	u32 reg;
>  
>  	/* Reset to buffer 0 */
> @@ -651,7 +656,7 @@ static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
>  
>  	switch (channel) {
>  	case IDMAC_SDC_0:
> -		ipu_channel_set_priority(fbi, channel, 1);
> +		ipu_channel_set_priority(info, channel, 1);
>  		break;
>  	default:
>  		break;
> @@ -663,9 +668,10 @@ static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
>  	return 0;
>  }
>  
> -static int ipu_update_channel_buffer(struct ipu_fb_info *fbi,
> +static int ipu_update_channel_buffer(struct fb_info *info,
>  		enum ipu_channel channel, void *buf)
>  {
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
>  	u32 reg;
>  
>  	reg = reg_read(fbi, IPU_CHA_BUF0_RDY);
> @@ -679,16 +685,17 @@ static int ipu_update_channel_buffer(struct ipu_fb_info *fbi,
>  	return 0;
>  }
>  
> -static int idmac_tx_submit(struct ipu_fb_info *fbi, enum ipu_channel channel,
> +static int idmac_tx_submit(struct fb_info *info, enum ipu_channel channel,
>  		void *buf)
>  {
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
>  	int ret;
>  
> -	ipu_init_channel_buffer(fbi, channel, buf);
> +	ipu_init_channel_buffer(info, channel, buf);
>  
>  
>  	/* ipu_idmac.c::ipu_submit_channel_buffers() */
> -	ret = ipu_update_channel_buffer(fbi, channel, buf);
> +	ret = ipu_update_channel_buffer(info, channel, buf);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -697,16 +704,17 @@ static int idmac_tx_submit(struct ipu_fb_info *fbi, enum ipu_channel channel,
>  	reg_write(fbi, 1UL << channel, IPU_CHA_BUF0_RDY);
>  
>  
> -	ret = ipu_enable_channel(fbi, channel);
> +	ret = ipu_enable_channel(info, channel);
>  	return ret;
>  }
>  
> -static void sdc_enable_channel(struct ipu_fb_info *fbi, void *fbmem)
> +static void sdc_enable_channel(struct fb_info *info, void *fbmem)
>  {
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
>  	int ret;
>  	u32 reg;
>  
> -	ret = idmac_tx_submit(fbi, IDMAC_SDC_0, fbmem);
> +	ret = idmac_tx_submit(info, IDMAC_SDC_0, fbmem);
>  
>  	/* mx3fb.c::sdc_fb_init() */
>  	if (ret >= 0) {
> @@ -724,13 +732,14 @@ static void sdc_enable_channel(struct ipu_fb_info *fbi, void *fbmem)
>  
>  /*
>   * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
> + * @param info The framebuffer to work on
>   * @return:	0 on success or negative error code on failure.
>   */
>  static int mx3fb_set_par(struct fb_info *info)
>  {
> -	struct ipu_fb_info *fbi = info->priv;
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
>  	struct imx_ipu_fb_rgb *rgb;
> -	struct fb_videomode *mode = info->mode;
> +	const struct fb_videomode *mode = fbi->mode;
>  	int ret;
>  
>  	ret = sdc_init_panel(info, IPU_PIX_FMT_RGB666);
> @@ -766,10 +775,45 @@ static int mx3fb_set_par(struct fb_info *info)
>  	return 0;
>  }
>  
> +static int ipu_fb_initialize_mode(struct fb_info *fb_info, const struct fb_videomode *mode)
> +{
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
> +	unsigned size;
> +
> +	/*
> +	 * we need at least this amount of memory for the framebuffer
> +	 */
> +	size = mode->xres * mode->yres * (fb_info->bits_per_pixel >> 3);
> +	if (fb_info->fb_dev->size != 0) {
> +		if (size > fb_info->fb_dev->size) {
> +			pr_err("Cannot initialize video mode '%s': Its too large. "
> +				"Required bytes are %u, available only %u\n",
> +				mode->name, size, fb_info->fb_dev->size);
> +			return -EINVAL;
> +		}
> +	} else
> +		fb_info->fb_dev->size = size;
> +
> +	/*
> +	 * if no framebuffer memory was specified yet, allocate one,
> +	 * and allocate more memory, on user request
> +	 */
> +	if (fb_info->fb_dev->map_base == 0U /* FIXME should be 'NULL'*/)
> +		fb_info->fb_dev->map_base = (unsigned long)xzalloc(fb_info->fb_dev->size);
> +
> +#if 0
> +	/* FIXME why here? Its also called in ipu_fb_enable() */
> +	sdc_enable_channel(fbi, fb_info->fb_dev->map_base);
> +#endif
> +	fbi->mode = mode;
> +
> +	return 0;
> +}
> +
>  /* References in this function refer to respective Linux kernel sources */
>  static void ipu_fb_enable(struct fb_info *info)
>  {
> -	struct ipu_fb_info *fbi = info->priv;
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
>  
>  	u32 reg;
>  
> @@ -825,7 +869,7 @@ static void ipu_fb_enable(struct fb_info *info)
>  
>  	mx3fb_set_par(info);
>  
> -	sdc_enable_channel(fbi, info->screen_base);
> +	sdc_enable_channel(info, (void*)info->fb_dev->map_base);
>  
>  	/*
>  	 * Linux driver calls sdc_set_brightness() here again,
> @@ -837,7 +881,7 @@ static void ipu_fb_enable(struct fb_info *info)
>  
>  static void ipu_fb_disable(struct fb_info *info)
>  {
> -	struct ipu_fb_info *fbi = info->priv;
> +	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
>  	u32 reg;
>  
>  	printf("%s\n", __func__);
> @@ -850,54 +894,38 @@ static void ipu_fb_disable(struct fb_info *info)
>  	reg_write(fbi, reg, SDC_COM_CONF);
>  }
>  
> -static struct fb_ops imxfb_ops = {
> -	.fb_enable = ipu_fb_enable,
> -	.fb_disable = ipu_fb_disable,
> -};
> -
>  static int imxfb_probe(struct device_d *dev)
>  {
>  	struct ipu_fb_info *fbi;
> -	struct fb_info *info;
> +	struct device_d *fb_dev;
>  	const struct imx_ipu_fb_platform_data *pdata = dev->platform_data;
> -	int ret;
>  
>  	if (!pdata)
>  		return -ENODEV;
>  
>  	fbi = xzalloc(sizeof(*fbi));
> -	info = &fbi->info;
> +
> +	/* add runtime hardware info */
> +	fbi->fb_host.hw_dev = dev;
> +	fbi->fb_host.fb_mode = ipu_fb_initialize_mode;
> +	fbi->fb_host.fb_enable = ipu_fb_enable;
> +	fbi->fb_host.fb_disable = ipu_fb_disable;
> +	fbi->fb_host.fb_setcolreg = NULL;
>  
>  	fbi->regs = (void *)dev->map_base;
> -	fbi->dev = dev;
> -	info->priv = fbi;
> -	info->mode = pdata->mode;
> -	info->xres = pdata->mode->xres;
> -	info->yres = pdata->mode->yres;
> -	info->bits_per_pixel = pdata->bpp;
> -	info->fbops = &imxfb_ops;
> -	fbi->enable = pdata->enable;
>  
> -	dev_info(dev, "i.MX Framebuffer driver\n");
> +	/* add runtime video info */
> +	fbi->fb_host.mode = pdata->mode;
> +	/* to be backward compatible */
> +	fbi->fb_host.mode_cnt = pdata->mode_cnt == 0 ? 1 : pdata->mode_cnt;
> +	fbi->fb_host.bits_per_pixel = pdata->bpp;
>  
> -	/*
> -	 * Use a given frambuffer or reserve some
> -	 * memory for screen usage
> -	 */
> -	fbi->info.screen_base = pdata->framebuffer;
> -	if (fbi->info.screen_base == NULL) {
> -		fbi->info.screen_base = malloc(info->xres * info->yres *
> -					       (info->bits_per_pixel >> 3));
> -		if (!fbi->info.screen_base)
> -			return -ENOMEM;
> -	}
> -
> -	sdc_enable_channel(fbi, info->screen_base);
> +	dev_info(dev, "i.MX Framebuffer driver\n");
>  
> -	ret = register_framebuffer(&fbi->info);
> -	if (ret < 0) {
> +	fb_dev = register_framebuffer(&fbi->fb_host, pdata->framebuffer, 0);
> +	if (fb_dev == NULL) {
>  		dev_err(dev, "failed to register framebuffer\n");
> -		return ret;
> +		return -EINVAL;
>  	}
>  
>  	return 0;
> -- 
> 1.7.2.3
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct 22 13:46:21 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 19:46:21 +0200
Subject: [PATCH 01/11] imx: Separate framebuffer platformdata and the
	videomode
In-Reply-To: <1287766405-1646-2-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-2-git-send-email-jbe@pengutronix.de>
Message-ID: <20101022174621.GH22139@pengutronix.de>

On Fri, Oct 22, 2010 at 06:53:15PM +0200, Juergen Beisert wrote:
> This patch separates the imx platformdata and its videomode in two structures,
> in order to support more than one defined videomode in the boardfile. This
> is intended to support runtime videomode selection later on. It also uses
> now the same videomode setup style than the imx-fpu based systems (like the
> i.MX35).
> 
>     Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c |   28 +++++++++--------
>  arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c |   28 +++++++++--------
>  arch/arm/boards/guf-neso/board.c                  |   28 +++++++++--------
>  arch/arm/boards/imx21ads/imx21ads.c               |   34 +++++++++++----------
>  arch/arm/boards/pcm038/pcm038.c                   |   28 +++++++++--------
>  arch/arm/mach-imx/include/mach/imxfb.h            |    2 +-
>  drivers/video/imx.c                               |    6 ++--
>  7 files changed, 82 insertions(+), 72 deletions(-)
> 
> diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> index 805ffe2..032897a 100644
> --- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> +++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> @@ -120,20 +120,22 @@ static struct device_d nand_dev = {
>  	.platform_data	= &nand_info,
>  };
>  
> +static struct fb_videomode cmo_display = {
> +	.name		= "CMO-QVGA",
> +	.refresh	= 60,
> +	.xres		= 320,
> +	.yres		= 240,
> +	.pixclock	= KHZ2PICOS(6500),
> +	.hsync_len	= 30,
> +	.left_margin	= 38,
> +	.right_margin	= 20,
> +	.vsync_len	= 3,
> +	.upper_margin	= 15,
> +	.lower_margin	= 4,
> +};
> +
>  static struct imx_fb_videomode imxfb_mode = {
> -	.mode = {
> -		.name		= "CMO-QVGA",
> -		.refresh	= 60,
> -		.xres		= 320,
> -		.yres		= 240,
> -		.pixclock	= KHZ2PICOS(6500),
> -		.hsync_len	= 30,
> -		.left_margin	= 38,
> -		.right_margin	= 20,
> -		.vsync_len	= 3,
> -		.upper_margin	= 15,
> -		.lower_margin	= 4,
> -	},
> +	.mode		= &cmo_display,
>  	.pcr		= 0xCAD08B80,
>  	.bpp		= 16,
>  };

What are we going to do about the .pcr value? It is display specific.
Look for example in pcm970-baseboard.c in the kernel. It has two
different possible displays with two different pcr values.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct 22 13:56:45 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 19:56:45 +0200
Subject: [PATCH v2] Add some help using the gpio commands at runtime
In-Reply-To: <201010221524.00862.jbe@pengutronix.de>
References: <201010221058.01249.jbe@pengutronix.de>
	<034801cb71e8$d8d10740$8a7315c0$@cpdesign.com.au>
	<201010221524.00862.jbe@pengutronix.de>
Message-ID: <20101022175645.GI22139@pengutronix.de>

On Fri, Oct 22, 2010 at 03:24:00PM +0200, Juergen Beisert wrote:
> From: Juergen Beisert <jbe at pengutronix.de>
> Subject: [PATCH] Add some help using the gpio commands at runtime
> 
> Last time I used the gpio commands I was somehow confused about the behaviour
> of the 'gpio_get_value' command. So, I decided to add some doc for it. Here's
> the result.
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> 
> ---
>  Documentation/commands.dox |    1 
>  commands/gpio.c            |   61 
> +++++++++++++++++++++++++++++++++++++++++++++

Your mailer breaks lines. (Fixed while applying)

Sascha


>  2 files changed, 62 insertions(+)
> 
> Index: barebox-2010.10.0/Documentation/commands.dox
> ===================================================================
> --- barebox-2010.10.0.orig/Documentation/commands.dox
> +++ barebox-2010.10.0/Documentation/commands.dox
> @@ -10,6 +10,7 @@
>  @li @subpage edit_command
>  @li @subpage erase_command
>  @li @subpage export_command
> + at li @subpage gpio_for_users
>  @li @subpage tftp_command
>  @li @subpage loadenv_command
>  @li @subpage mount_command
> Index: barebox-2010.10.0/commands/gpio.c
> ===================================================================
> --- barebox-2010.10.0.orig/commands/gpio.c
> +++ barebox-2010.10.0/commands/gpio.c
> @@ -120,3 +120,64 @@ BAREBOX_CMD_START(gpio_direction_output)
>  	BAREBOX_CMD_HELP(cmd_gpio_direction_output_help)
>  BAREBOX_CMD_END
>  
> +/**
> + at page gpio_for_users Runtime GPIO handling
> +
> + at section regular_gpio General usage information
> +
> +These commands are available if the symbol @b CONFIG_GENERIC_GPIO and
> + at b CONFIG_CMD_GPIO are enabled in the Kconfig.
> +
> + at note All gpio related commands take a number to identify the pad. This
> +number is architecture dependent. There may be no intuitional correlation
> +between available pads and the GPIO numbers to be used in the commands. Due
> +to this it's also possible the numbers change between @b barebox releases.
> +
> + at section gpio_dir_out Switch a pad into an output GPIO
> + at verbatim
> +gpio_direction_output <gpio_no> <initial_value>
> + at endverbatim
> +- @b gpio_no Architecture dependent GPIO number
> +- @b initial_value Output value the pad should emit
> +
> + at note To avoid glitches on the pad's line, the routines will first setting up
> +the pad's value and after that switching the pad itself to output (if the
> +silicon is able to do so)
> +
> + at note If the pad is already configured into a non GPIO mode (if available)
> +this command may fail (silently)
> +
> + at section gpio_dir_in Switch a pad into an input GPIO
> + at verbatim
> +gpio_direction_input <gpio_no>
> + at endverbatim
> +- @b gpio_no Architecture dependent GPIO number
> +
> + at note If the pad is already configured into a non GPIO mode (if available)
> +this command may fail (silently)
> +
> + at section gpio_get_value Read in the value of an GPIO input pad
> + at verbatim
> +gpio_get_value <gpio_no>
> + at endverbatim
> +
> +Reads in the current pad's line value from the given GPIO number. It returns
> +the value as a shell return code. There is no visible output at stdout. You
> +can check the return value by using "echo $?"
> +
> + at note If the return code is not '0' or '1' it's meant as an error code.
> +
> + at note If the pad is not configured for GPIO mode this command may fail
> +(silently) and returns garbage
> +
> + at section gpio_set_value Set a new value to a GPIO output pad
> + at verbatim
> +gpio_set_value <gpio_no> <value>
> + at endverbatim
> +- @b gpio_no Architecture dependent GPIO number
> +- @b value Output value the pad should emit
> +
> +Sets a new output @b value to the pad with GPIO number @b gpio_no
> +
> + at note If the pad is not configured for GPIO mode this command may fail 
> (silently)
> +*/
> 
> 
> 
> -- 
> Pengutronix e.K.                              | Juergen Beisert             |
> Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
> Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct 22 14:50:45 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 20:50:45 +0200
Subject: [PATCH 18/32] doc: silence doxygen warnings
In-Reply-To: <1287765924-1856-19-git-send-email-r.schwebel@pengutronix.de>
References: <1287765924-1856-1-git-send-email-r.schwebel@pengutronix.de>
	<1287765924-1856-19-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <20101022185045.GM22139@pengutronix.de>

Hi Robert,

I applied the series up to this patch excluding the one Juergen
commented about. For the rest I want to have a closer look.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct 22 14:56:37 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 20:56:37 +0200
Subject: [PATCH 08/11] Add a video driver for S3C2440 bases platforms
In-Reply-To: <1287766405-1646-9-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-9-git-send-email-jbe@pengutronix.de>
Message-ID: <20101022185637.GN22139@pengutronix.de>

On Fri, Oct 22, 2010 at 06:53:22PM +0200, Juergen Beisert wrote:
> From: Juergen Beisert <juergen at kreuzholzen.de>
> 
> Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
> ---
>  arch/arm/mach-s3c24xx/include/mach/fb.h |   40 +++
>  drivers/video/Kconfig                   |    6 +
>  drivers/video/Makefile                  |    1 +
>  drivers/video/s3c.c                     |  454 +++++++++++++++++++++++++++++++
>  4 files changed, 501 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h
>  create mode 100644 drivers/video/s3c.c
> 
> diff --git a/drivers/video/s3c.c b/drivers/video/s3c.c
> new file mode 100644
> index 0000000..cd0f220
> --- /dev/null
> +++ b/drivers/video/s3c.c
> +
> +/**
> + * Prepare the video hardware for a specified video mode
> + * @param fb_info Framebuffer information
> + * @param mode The video mode description to initialize
> + * @return 0 on success
> + *
> + * FIXME Diese Routine darf die Pinx nach drau?en nicht aktivieren. Zur Zeit macht sie das!

You should at least translate this to english ;)


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Fri Oct 22 14:59:31 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 Oct 2010 20:59:31 +0200
Subject: [PATCH 09/11] STM378x: Add video driver for this platform
In-Reply-To: <1287766405-1646-10-git-send-email-jbe@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-10-git-send-email-jbe@pengutronix.de>
Message-ID: <20101022185931.GO22139@pengutronix.de>

On Fri, Oct 22, 2010 at 06:53:23PM +0200, Juergen Beisert wrote:
> As there is currently no user of this driver (but coming soon) it is for
> reference only.
> 
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  arch/arm/mach-stm/include/mach/fb.h |   38 +++
>  drivers/video/Kconfig               |    7 +
>  drivers/video/Makefile              |    1 +
>  drivers/video/stm.c                 |  556 +++++++++++++++++++++++++++++++++++
>  4 files changed, 602 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-stm/include/mach/fb.h
>  create mode 100644 drivers/video/stm.c
> 
> diff --git a/arch/arm/mach-stm/include/mach/fb.h b/arch/arm/mach-stm/include/mach/fb.h
> new file mode 100644
> index 0000000..6596ef2
> --- /dev/null
> +++ b/arch/arm/mach-stm/include/mach/fb.h
> @@ -0,0 +1,38 @@
> +/*
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +#ifndef __MACH_FB_H
> +# define __MACH_FB_H
> +
> +#include <fb.h>
> +
> +#define STMLCDIF_8BIT 1	/** pixel data bus to the display is of 8 bit width */
> +#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
> +#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
> +#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
> +
> +struct imx_fb_videomode {
> +	struct fb_videomode *mode_list;
> +	unsigned mode_count;
> +	void *framebuffer;	/**< force fixed framebuffer address if != NULL */
> +	unsigned size;		/**< force fixed size if != NULL */
> +
> +	unsigned dotclk_delay;	/**< refer manual HW_LCDIF_VDCTRL4 register */
> +	unsigned ld_intf_width;	/**< refer STMLCDIF_* macros */
> +};
> +
> +#endif /* __MACH_FB_H */
> +
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 64f68c4..63a80b0 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -55,4 +55,11 @@ config S3C_VIDEO
>  	help
>  	  Add support for the S3C244x LCD controller.
>  
> +config DRIVER_VIDEO_STM
> +	bool "i.MX23/28 framebuffer driver"
> +	depends on ARCH_STM
> +	help
> +	  Say 'Y' here to enable framebuffer and spash screen support for
> +	  i.MX23 and i.MX28 based systems.
> +
>  endif
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index 4287fc8..0ddb81e 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_VIDEO) += fb.o
>  
> +obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o
>  obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
>  obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
>  obj-$(CONFIG_S3C_VIDEO) += s3c.o
> diff --git a/drivers/video/stm.c b/drivers/video/stm.c
> new file mode 100644
> index 0000000..b18378a
> --- /dev/null
> +++ b/drivers/video/stm.c
> @@ -0,0 +1,556 @@
> +/*
> + * Copyright (C) 2010 Juergen Beisert, Pengutronix
> + *
> + * This code is based on:
> + * Author: Vitaly Wool <vital at embeddedalley.com>
> + *
> + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +/**
> + * @file
> + * @brief LCDIF driver for i.MX23 and i.MX28 (i.MX23 untested yet)
> + *
> + * The LCDIF support four modes of operation
> + * - MPU interface (to drive smart displays) -> not supported yet
> + * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
> + * - Dotclock interface (to drive LC displays with RGB data and sync signals)
> + * - DVI (to drive ITU-R BT656)  -> not supported yet
> + *
> + * This driver depends on a correct setup of the pins used for this purpose
> + * (platform specific).
> + *
> + * For the developer: Don't forget to set the data bus width to the display
> + * in the imx_fb_videomode structure. You will else end up with ugly colours.
> + * If you fighting against jitter you can vary the clock delay. This is a feature
> + * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
> + * the required value in the imx_fb_videomode structure.
> + */
> +
> +/* #define DEBUG */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <driver.h>
> +#include <malloc.h>
> +#include <errno.h>
> +#include <xfuncs.h>
> +#include <asm/io.h>
> +#include <mach/clock.h>
> +#include <mach/fb.h>
> +
> +#define HW_LCDIF_CTRL 0x00
> +# define CTRL_SFTRST (1 << 31)
> +# define CTRL_CLKGATE (1 << 30)
> +# define CTRL_BYPASS_COUNT (1 << 19)
> +# define CTRL_VSYNC_MODE (1 << 18)
> +# define CTRL_DOTCLK_MODE (1 << 17)
> +# define CTRL_DATA_SELECT (1 << 16)
> +# define SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
> +# define SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
> +# define GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
> +# define CTRL_MASTER (1 << 5)
> +# define CTRL_DF16 (1 << 3)
> +# define CTRL_DF18 (1 << 2)
> +# define CTRL_DF24 (1 << 1)
> +# define CTRL_RUN (1 << 0)
> +
> +#define HW_LCDIF_CTRL1 0x10
> +# define SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
> +# define GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
> +
> +#define HW_LCDIF_CTRL2 0x20
> +
> +#define HW_LCDIF_TRANSFER_COUNT 0x30
> +# define SET_VCOUNT(x) (((x) & 0xffff) << 16)
> +# define SET_HCOUNT(x) ((x) & 0xffff)
> +
> +#define HW_LCDIF_CUR_BUF 0x40
> +
> +#define HW_LCDIF_NEXT_BUF 0x50
> +
> +#define HW_LCDIF_TIMING 0x60
> +# define SET_CMD_HOLD(x) (((x) & 0xff) << 24)
> +# define SET_CMD_SETUP(x) (((x) & 0xff) << 16)
> +# define SET_DATA_HOLD(x) (((x) & 0xff) << 8)
> +# define SET_DATA_SETUP(x) ((x) & 0xff))
> +
> +#define HW_LCDIF_VDCTRL0 0x70
> +# define VDCTRL0_ENABLE_PRESENT (1 << 28)
> +# define VDCTRL0_VSYNC_POL (1 << 27) /* 0 = low active, 1 = high active */
> +# define VDCTRL0_HSYNC_POL (1 << 26) /* 0 = low active, 1 = high active */
> +# define VDCTRL0_DOTCLK_POL (1 << 25) /* 0 = output at falling edge, capturing at rising edge */
> +# define VDCTRL0_ENABLE_POL (1 << 24) /* 0 = low active, 1 = high active */
> +# define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
> +# define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
> +# define VDCTRL0_HALF_LINE (1 << 19)
> +# define VDCTRL0_HALF_LINE_MODE (1 << 18)
> +# define SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
> +
> +#define HW_LCDIF_VDCTRL1 0x80
> +
> +#define HW_LCDIF_VDCTRL2 0x90
> +# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0x3fff) << 18)
> +# define SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
> +
> +#define HW_LCDIF_VDCTRL3 0xa0
> +# define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
> +# define VDCTRL3_VSYNC_ONLY (1 << 28)
> +# define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
> +# define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
> +
> +#define HW_LCDIF_VDCTRL4 0xb0
> +# define SET_DOTCLK_DLY(x) (((x) & 0x7) << 29)
> +# define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
> +# define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
> +
> +#define HW_LCDIF_DVICTRL0 0xc0
> +#define HW_LCDIF_DVICTRL1 0xd0
> +#define HW_LCDIF_DVICTRL2 0xe0
> +#define HW_LCDIF_DVICTRL3 0xf0
> +#define HW_LCDIF_DVICTRL4 0x100
> +#define HW_LCDIF_DATA 0x180
> +
> +#define HW_LCDIF_DEBUG0 0x1d0
> +# define DEBUG_HSYNC (1 < 26)
> +# define DEBUG_VSYNC (1 < 25)
> +
> +#define RED 0
> +#define GREEN 1
> +#define BLUE 2
> +#define TRANSP 3
> +
> +struct imxfb_host {
> +	struct fb_host fb_data;
> +	struct device_d *hw_dev;
> +	void __iomem *base;
> +};
> +
> +#define fb_info_to_imxfb_host(x) ((struct imxfb_host*)((x)->host))
> +
> +/* the RGB565 true colour mode */
> +static const struct fb_bitfield def_rgb565[] = {
> +	[RED] = {
> +		.offset = 11,
> +		.length = 5,
> +	},
> +	[GREEN] = {
> +		.offset = 5,
> +		.length = 6,
> +	},
> +	[BLUE] = {
> +		.offset = 0,
> +		.length = 5,
> +	},
> +	[TRANSP] = {	/* no support for transparency */
> +		.length = 0,
> +	}
> +};
> +
> +/* the RGB666 true colour mode */
> +static const struct fb_bitfield def_rgb666[] = {
> +	[RED] = {
> +		.offset = 16,
> +		.length = 6,
> +	},
> +	[GREEN] = {
> +		.offset = 8,
> +		.length = 6,
> +	},
> +	[BLUE] = {
> +		.offset = 0,
> +		.length = 6,
> +	},
> +	[TRANSP] = {	/* no support for transparency */
> +		.length = 0,
> +	}
> +};
> +
> +/* the RGB888 true colour mode */
> +static const struct fb_bitfield def_rgb888[] = {
> +	[RED] = {
> +		.offset = 16,
> +		.length = 8,
> +	},
> +	[GREEN] = {
> +		.offset = 8,
> +		.length = 8,
> +	},
> +	[BLUE] = {
> +		.offset = 0,
> +		.length = 8,
> +	},
> +	[TRANSP] = {	/* no support for transparency */
> +		.length = 0,
> +	}
> +};
> +
> +/**
> + * Just calculate the amount of required bytes per line
> + * @param ppl Used pixel per line
> + * @param bpp Bits per pixel
> + * @return Byte count
> + */
> +static inline unsigned calc_line_length(unsigned ppl, unsigned bpp)
> +{
> +	return (ppl * bpp) >> 3;
> +}
> +
> +/**
> + * Prepare the video hardware for a specified video mode
> + * @param fb_info Framebuffer information
> + * @param mode The video mode description to initialize
> + * @return 0 on success
> + *
> + * Dotclock mode:
> + * One line of pixels or one frame in the i.MX28 is defined to:
> + * @verbatim
> + * |<---------------------- one line period -------------------------------->|
> + * |<- HSync length ->|
> + * |<----- Start of line --->|
> + *                           |<-------- active line data ------>|
> + *
> + * |<------------------------ frame period --------------------------------->|
> + * |<- VSync length ->|
> + * |<--- Start of 1. line -->|
> + *                           |<---------- active lines -------->|
> + * @endverbatim
> + * Based on the values from struct fb_videomode:
> + * - "one line period" = left_margin + xres + right_margin + hsync_len
> + * - "HSync length" = hsync_len
> + * - "Start of line" = hsync_len + left_margin
> + * - "active line data" = xres
> + */
> +static int stmfb_initialize_mode(struct fb_info *fb_info, const struct fb_videomode *mode)
> +{
> +	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
> +	struct imx_fb_videomode *pdata = fbh->hw_dev->platform_data;
> +	uint32_t reg;
> +	unsigned size;
> +
> +	pr_debug("%s called\n", __func__);
> +	/*
> +	 * we need at least this amount of memory for the framebuffer
> +	 */
> +	size = calc_line_length(mode->xres, fb_info->bits_per_pixel) * mode->yres;
> +	if (fb_info->fb_dev->size != 0) {
> +		if (size > fb_info->fb_dev->size) {
> +			pr_err("Cannot initialize video mode '%s': Its too large. "
> +				"Required bytes are %u, available only %u\n",
> +				mode->name, size, fb_info->fb_dev->size);
> +			return -EINVAL;
> +		}
> +	} else
> +		fb_info->fb_dev->size = size;
> +
> +	/*
> +	 * if no framebuffer memory was specified yet, allocate one,
> +	 * and allocate more memory, on user request
> +	 */
> +	if (fb_info->fb_dev->map_base == 0U)
> +		fb_info->fb_dev->map_base = (resource_size_t)xzalloc(fb_info->fb_dev->size);
> +
> +	/* TODO HCLK must be active at this point of time! */
> +
> +	size = imx_set_lcdifclk(PICOS2KHZ(mode->pixclock));
> +	if (size == 0) {
> +		pr_debug("Unable to set a valid pixel clock\n");
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * bring the controller out of reset and configure it into DOTCLOCK mode
> +	 */
> +	reg = CTRL_BYPASS_COUNT |	/* always in DOTCLOCK mode */
> +		CTRL_DOTCLK_MODE;
> +	writel(reg, fbh->base + HW_LCDIF_CTRL);
> +
> +	/* master mode only */
> +	reg |= CTRL_MASTER;
> +
> +	/*
> +	 * Configure videomode and interface mode
> +	 */
> +	reg |= SET_BUS_WIDTH(pdata->ld_intf_width);
> +	switch (fb_info->bits_per_pixel) {
> +	case 8:
> +		reg |= SET_WORD_LENGTH(1);
> +		/* TODO refer manual page 2046 */
> +		pr_warning("8 bpp mode not supported yet\n");
> +		break;
> +	case 16:
> +		pr_debug("Setting up an RGB565 mode\n");
> +		reg |= SET_WORD_LENGTH(0) | CTRL_DF16; /* we assume RGB565 */
> +		writel(SET_BYTE_PACKAGING(0xf), fbh->base + HW_LCDIF_CTRL1);
> +		fb_info->red = def_rgb565[RED];
> +		fb_info->green = def_rgb565[GREEN];
> +		fb_info->blue = def_rgb565[BLUE];
> +		fb_info->transp =  def_rgb565[TRANSP];
> +		break;
> +	case 24:
> +	case 32:
> +		pr_debug("Setting up an RGB888/666 mode\n");
> +		reg |= SET_WORD_LENGTH(3);
> +		switch (pdata->ld_intf_width) {
> +		case STMLCDIF_8BIT:
> +			pr_debug("Unsupported LCD bus width mapping\n");
> +			break;
> +		case STMLCDIF_16BIT:
> +		case STMLCDIF_18BIT:
> +			/* 24 bit to 18 bit mapping */
> +			reg |= CTRL_DF24;	/* ignore the upper 2 bits in each colour component */
> +			fb_info->red = def_rgb666[RED];
> +			fb_info->green = def_rgb666[GREEN];
> +			fb_info->blue = def_rgb666[BLUE];
> +			fb_info->transp =  def_rgb666[TRANSP];
> +			break;
> +		case STMLCDIF_24BIT:
> +			/* real 24 bit */
> +			fb_info->red = def_rgb888[RED];
> +			fb_info->green = def_rgb888[GREEN];
> +			fb_info->blue = def_rgb888[BLUE];
> +			fb_info->transp =  def_rgb888[TRANSP];
> +			break;
> +		}
> +		/* do not use packed pixels = one pixel per word instead */
> +		writel(SET_BYTE_PACKAGING(0x7), fbh->base + HW_LCDIF_CTRL1);
> +		break;
> +	default:
> +		pr_debug("Unhandled colour depth of %u\n", fb_info->bits_per_pixel);
> +		return -EINVAL;
> +	}
> +	writel(reg, fbh->base + HW_LCDIF_CTRL);
> +	pr_debug("Setting up CTRL to %08X\n", reg);
> +
> +	writel(SET_VCOUNT(mode->yres) |
> +		SET_HCOUNT(mode->xres), fbh->base + HW_LCDIF_TRANSFER_COUNT);
> +
> +	reg = VDCTRL0_ENABLE_PRESENT |	/* always in DOTCLOCK mode */
> +		VDCTRL0_VSYNC_PERIOD_UNIT |
> +		VDCTRL0_VSYNC_PULSE_WIDTH_UNIT;
> +	if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
> +		reg |= VDCTRL0_HSYNC_POL;
> +	if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
> +		reg |= VDCTRL0_VSYNC_POL;
> +	if (mode->sync & FB_SYNC_DE_HIGH_ACT)
> +		reg |= VDCTRL0_ENABLE_POL;
> +	if (mode->sync & FB_SYNC_CLK_INVERT)
> +		reg |= VDCTRL0_DOTCLK_POL;
> +
> +	reg |= SET_VSYNC_PULSE_WIDTH(mode->vsync_len);
> +	writel(reg, fbh->base + HW_LCDIF_VDCTRL0);
> +	pr_debug("Setting up VDCTRL0 to %08X\n", reg);
> +
> +	/* frame length in lines */
> +	writel(mode->upper_margin + mode->vsync_len + mode->lower_margin + mode->yres,
> +		fbh->base + HW_LCDIF_VDCTRL1);
> +
> +	/* line length in units of clocks or pixels */
> +	writel(SET_HSYNC_PULSE_WIDTH(mode->hsync_len) |
> +		SET_HSYNC_PERIOD(mode->left_margin + mode->hsync_len + mode->right_margin + mode->xres),
> +		fbh->base + HW_LCDIF_VDCTRL2);
> +
> +	writel(SET_HOR_WAIT_CNT(mode->left_margin + mode->hsync_len) |
> +		SET_VERT_WAIT_CNT(mode->upper_margin + mode->vsync_len),
> +		fbh->base + HW_LCDIF_VDCTRL3);
> +
> +	writel(SET_DOTCLK_DLY(pdata->dotclk_delay) |
> +		SET_DOTCLK_H_VALID_DATA_CNT(mode->xres),
> +		fbh->base + HW_LCDIF_VDCTRL4);
> +
> +	writel(fb_info->fb_dev->map_base, fbh->base + HW_LCDIF_CUR_BUF);
> +	/* always show one framebuffer only */
> +	writel(fb_info->fb_dev->map_base, fbh->base + HW_LCDIF_NEXT_BUF);
> +
> +	return 0;
> +}
> +
> +/**
> + * @param fb_info Framebuffer information
> + */
> +static void stmfb_enable_controller(struct fb_info *fb_info)
> +{
> +	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
> +	uint32_t reg, last_reg;
> +	unsigned loop, edges;
> +
> +	pr_debug("%s called\n", __func__);
> +
> +	/* if it was disabled, re-enable the mode again */
> +	reg = readl(fbh->base + HW_LCDIF_CTRL);
> +	reg |= CTRL_DOTCLK_MODE;
> +	writel(reg, fbh->base + HW_LCDIF_CTRL);
> +
> +	/* enable the SYNC signals first, then the DMA enginge */
> +	reg = readl(fbh->base + HW_LCDIF_VDCTRL4);
> +	reg |= VDCTRL4_SYNC_SIGNALS_ON;
> +	writel(reg, fbh->base + HW_LCDIF_VDCTRL4);
> +
> +	/*
> +	 * Give the attached LC display or monitor a chance to sync into
> +	 * our signals.
> +	 * Wait for at least 2 VSYNCs = four VSYNC edges
> +	 */
> +	edges = 4;
> +
> +	while (edges != 0) {
> +		loop = 800;
> +		last_reg = readl(fbh->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
> +		do {
> +			reg = readl(fbh->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
> +			if (reg != last_reg);
> +				break;
> +			last_reg = reg;
> +			loop--;
> +		} while (loop != 0);
> +		edges--;
> +	}
> +
> +	reg = readl(fbh->base + HW_LCDIF_CTRL);
> +	reg |= CTRL_RUN;
> +	writel(reg, fbh->base + HW_LCDIF_CTRL);
> +}
> +
> +/**
> + * @param fb_info Framebuffer information
> + */
> +static void stmfb_disable_controller(struct fb_info *fb_info)
> +{
> +	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
> +	unsigned loop;
> +	uint32_t reg;
> +
> +	pr_debug("%s called\n", __func__);
> +	/*
> +	 * Even if we disable the controller here, it will still continue
> +	 * until its FIFOs are running out of data
> +	 */
> +	reg = readl(fbh->base + HW_LCDIF_CTRL);
> +	reg &= ~CTRL_DOTCLK_MODE;
> +	writel(reg, fbh->base + HW_LCDIF_CTRL);
> +
> +	loop = 1000;
> +	while (loop) {
> +		reg = readl(fbh->base + HW_LCDIF_CTRL);
> +		if (!(reg & CTRL_RUN))
> +			break;
> +		loop--;
> +	}
> +
> +	reg = readl(fbh->base + HW_LCDIF_VDCTRL4);
> +	reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
> +	writel(reg, fbh->base + HW_LCDIF_VDCTRL4);
> +}
> +
> +/**
> + * Print some information about the current hardware state
> + * @param hw_dev STM video device
> + */
> +static void stmfb_info(struct device_d *hw_dev)
> +{
> +	uint32_t reg;
> +
> +	printf(" STM video hardware:\n");
> +	printf("  Pixel clock: %u kHz\n", imx_get_lcdifclk());
> +
> +	reg = readl(hw_dev->map_base + HW_LCDIF_CTRL);
> +	switch (GET_WORD_LENGTH(reg)) {
> +	case 0:
> +		printf("  16 bpp mode with %s colour scheme\n", reg & CTRL_DF16 ? "RGB565" : "ARGB1555");
> +		switch (GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1))) {
> +		case 0xf:
> +			printf("  One pixel per halfword\n");
> +			break;
> +		case 0x3:
> +			printf("  One pixel per word\n");
> +			break;
> +		default:
> +			printf("Unknown pixel packaging: %u\n", GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1)));

Care to spend a line break?

> +		}
> +		break;
> +	case 1:
> +	case 2:
> +		printf("Unsupported bpp mode yet!\n");
> +		break;
> +	case 3:
> +		printf("  24 bpp mode with %s colour scheme\n", reg & CTRL_DF24 ? "RGB888" : "RGB666");
> +		switch (GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1))) {
> +		case 0x7:
> +			printf("  One pixel per word (xRGB xRGB xRGB ...)\n");
> +			break;
> +		case 0xf:
> +			printf("Packed pixel format per word (RGBR GBRG BRGB ...)\n");
> +			break;
> +		default:
> +			printf("Unknown pixel packaging: %u\n", GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1)));

ditto

> +		}
> +		break;
> +	}
> +}
> +
> +/*
> + * There is only one video hardware instance available.
> + * It makes no sense to dynamically allocate this data
> + */
> +static struct imxfb_host host_data = {
> +	.fb_data.fb_mode = stmfb_initialize_mode,
> +	.fb_data.fb_enable = stmfb_enable_controller,
> +	.fb_data.fb_disable = stmfb_disable_controller,
> +	.fb_data.bits_per_pixel = 16,
> +};
> +
> +static int stmfb_probe(struct device_d *hw_dev)
> +{
> +	struct imx_fb_videomode *pdata = hw_dev->platform_data;
> +	struct device_d *fb_dev;
> +
> +	if (pdata == NULL) {
> +		pr_debug("STMFB: No platformdata. Giving up\n");

We also have dev_dbg and friends for this.

> +		return -ENODEV;
> +	}
> +
> +	/* add runtime hardware info */
> +	host_data.hw_dev = hw_dev;
> +	host_data.base = (void*)hw_dev->map_base;
> +
> +	/* add runtime video info */
> +	host_data.fb_data.mode = pdata->mode_list;
> +	host_data.fb_data.mode_cnt = pdata->mode_count;
> +
> +	fb_dev = register_framebuffer(&host_data.fb_data, pdata->framebuffer, pdata->size);
> +	if (fb_dev == NULL) {
> +		pr_err("STMFB: Failed to register framebuffer\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct driver_d stmfb_driver = {
> +	.name	= "stmfb",
> +	.probe	= stmfb_probe,
> +	.info	= stmfb_info,
> +};
> +
> +static int stmfb_init(void)
> +{
> +	return register_driver(&stmfb_driver);
> +}
> +
> +device_initcall(stmfb_init);
> +
> -- 
> 1.7.2.3
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Sat Oct 23 06:35:07 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Sat, 23 Oct 2010 12:35:07 +0200
Subject: [PATCH 03/11] Bring in dynamic videomode selection at runtime
In-Reply-To: <20101022174109.GF22139@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-4-git-send-email-jbe@pengutronix.de>
	<20101022174109.GF22139@pengutronix.de>
Message-ID: <201010231235.07819.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Fri, Oct 22, 2010 at 06:53:17PM +0200, Juergen Beisert wrote:
> > This patch mostly rewrites all parts of /drivers/video/fb.c. As it
> > changes the API to the drivers, it must be done in one step to keep the
> > repository bisectable. But to do it in one step makes the patches itself
> > unreadable.
> >
> > So, I decided to do it in a few steps, only for the review. All patches
> > marked with a "step n of m" should be merged, prior the final commit into
> > the repository.
> >
> > This step brings in the required functions for dynamic videomode
> > selection at runtime, but keep the old functions untouched (the new ones
> > are commented out).
> >
> > This is patch 1 of 7 to keep the repository bisectable.
> >
> > Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> > ---
> >  drivers/video/Kconfig |   23 +++++
> >  drivers/video/fb.c    |  251
> > +++++++++++++++++++++++++++++++++++++++++++++++++ include/fb.h          |
> >   40 ++++++++
> >  3 files changed, 314 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> > index 7a89a3f..e6ecfc8 100644
> > --- a/drivers/video/Kconfig
> > +++ b/drivers/video/Kconfig
> > @@ -5,6 +5,29 @@ menuconfig VIDEO
> >
> >  if VIDEO
> >
> > +comment "runtime options"
> > +
> > +config VIDEO_DELAY_ENABLING
> > +	bool "Delayed enabling"
> > +	help
> > +	  Say 'y' here to delay enabling video output. This is useful to first
> > +	  fill the framebuffer (splash screen for example) prior enabling the
> > +	  video device.
> > +          This entry adds the "enable" parameter to the video device, to
> > enable +	  or disable video output at runtime.
> > +
> > +config VIDEO_DELAY_INIT
> > +	bool "Delayed initialization"
> > +	select VIDEO_DELAY_ENABLING
> > +	help
> > +	  If the platform supports more than one video mode say 'y' her to
> > delay +	  the initialization of the video device until any kind of
> > barebox's +          shell code sets up the correct mode at runtime.
> > +          This entry adds the "mode" parameter to the video device, to
> > setup +          the desired videomode prior enabling it at runtime.
>
> I think the framebuffers should *never* be activated by the setup code
> and should be explicitely initialized by doing a 'fb0.enable=1' on the
> command line.

Okay. It "should not" is a new policy to barebox. Currently the framebuffer is 
activated immediately (except the platforms you changed already). I just 
wanted to keep this behaviour.

> This way we have the most flexibility. We can enable 
> the framebuffer when we actually need it, we can draw a splash screen
> before enabling it so that we do not have a black screen before we draw
> an image. Also, the environment can decide to leave the framebuffer
> disabled because the kernel will draw another screen a second later. If
> necessary, the environemt can do a fb0.display="sharp-whatever" before
> activating it. And we do not need any kconfig options for this.

Okay. We can change the default behaviour for all platforms using graphic in 
this way. I will try to include it in the next series.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Sat Oct 23 06:31:40 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Sat, 23 Oct 2010 12:31:40 +0200
Subject: [PATCH 01/11] imx: Separate framebuffer platformdata and the
	videomode
In-Reply-To: <20101022174621.GH22139@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-2-git-send-email-jbe@pengutronix.de>
	<20101022174621.GH22139@pengutronix.de>
Message-ID: <201010231231.40697.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Fri, Oct 22, 2010 at 06:53:15PM +0200, Juergen Beisert wrote:
> > This patch separates the imx platformdata and its videomode in two
> > structures, in order to support more than one defined videomode in the
> > boardfile. This is intended to support runtime videomode selection later
> > on. It also uses now the same videomode setup style than the imx-fpu
> > based systems (like the i.MX35).
> >
> >     Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> > ---
> >  arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c |   28
> > +++++++++-------- arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c |  
> > 28 +++++++++-------- arch/arm/boards/guf-neso/board.c                  | 
> >  28 +++++++++-------- arch/arm/boards/imx21ads/imx21ads.c               |
> >   34 +++++++++++---------- arch/arm/boards/pcm038/pcm038.c               
> >    |   28 +++++++++-------- arch/arm/mach-imx/include/mach/imxfb.h       
> >     |    2 +-
> >  drivers/video/imx.c                               |    6 ++--
> >  7 files changed, 82 insertions(+), 72 deletions(-)
> >
> > diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> > b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c index
> > 805ffe2..032897a 100644
> > --- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> > +++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
> > @@ -120,20 +120,22 @@ static struct device_d nand_dev = {
> >  	.platform_data	= &nand_info,
> >  };
> >
> > +static struct fb_videomode cmo_display = {
> > +	.name		= "CMO-QVGA",
> > +	.refresh	= 60,
> > +	.xres		= 320,
> > +	.yres		= 240,
> > +	.pixclock	= KHZ2PICOS(6500),
> > +	.hsync_len	= 30,
> > +	.left_margin	= 38,
> > +	.right_margin	= 20,
> > +	.vsync_len	= 3,
> > +	.upper_margin	= 15,
> > +	.lower_margin	= 4,
> > +};
> > +
> >  static struct imx_fb_videomode imxfb_mode = {
> > -	.mode = {
> > -		.name		= "CMO-QVGA",
> > -		.refresh	= 60,
> > -		.xres		= 320,
> > -		.yres		= 240,
> > -		.pixclock	= KHZ2PICOS(6500),
> > -		.hsync_len	= 30,
> > -		.left_margin	= 38,
> > -		.right_margin	= 20,
> > -		.vsync_len	= 3,
> > -		.upper_margin	= 15,
> > -		.lower_margin	= 4,
> > -	},
> > +	.mode		= &cmo_display,
> >  	.pcr		= 0xCAD08B80,
> >  	.bpp		= 16,
> >  };
>
> What are we going to do about the .pcr value? It is display specific.
> Look for example in pcm970-baseboard.c in the kernel. It has two
> different possible displays with two different pcr values.

I will take a closer look what the meaning of this pcr value is. Maybe we can 
create it at runtime from other flags given in the imx_fb_videomode.

Otherwise we could add a private pointer to the imx_fb_videomode structure, 
which can point to platform and videomode specific data in a generic way.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Sat Oct 23 06:36:50 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Sat, 23 Oct 2010 12:36:50 +0200
Subject: [PATCH 07/11] Adapt the existing imx-ipu fb driver to support
	runtime videomode selection
In-Reply-To: <20101022174304.GG22139@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-8-git-send-email-jbe@pengutronix.de>
	<20101022174304.GG22139@pengutronix.de>
Message-ID: <201010231236.50704.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Fri, Oct 22, 2010 at 06:53:21PM +0200, Juergen Beisert wrote:
> > Adapt the API to the new framebuffer videomode selection at runtime. If
> > the new feature is not used, there is no visible change at runtime for
> > platforms using this driver.
>
> This conflicts with the ipu fb patch I posted today.

I see. I generated this list on to of barebox-next. Next try...

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Sat Oct 23 06:40:35 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Sat, 23 Oct 2010 12:40:35 +0200
Subject: [PATCH 09/11] STM378x: Add video driver for this platform
In-Reply-To: <20101022185931.GO22139@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-10-git-send-email-jbe@pengutronix.de>
	<20101022185931.GO22139@pengutronix.de>
Message-ID: <201010231240.36009.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Fri, Oct 22, 2010 at 06:53:23PM +0200, Juergen Beisert wrote:
> > As there is currently no user of this driver (but coming soon) it is for
> > reference only.
> >
> > [...]
> > +		default:
> > +			printf("Unknown pixel packaging: %u\n", GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1)));
>
> Care to spend a line break?

I like long lines... ;-)

Yes, I will add a line break the next time.

> > [...]
> > +static int stmfb_probe(struct device_d *hw_dev)
> > +{
> > +	struct imx_fb_videomode *pdata = hw_dev->platform_data;
> > +	struct device_d *fb_dev;
> > +
> > +	if (pdata == NULL) {
> > +		pr_debug("STMFB: No platformdata. Giving up\n");
>
> We also have dev_dbg and friends for this.

Yes.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Sat Oct 23 06:37:47 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Sat, 23 Oct 2010 12:37:47 +0200
Subject: [PATCH 08/11] Add a video driver for S3C2440 bases platforms
In-Reply-To: <20101022185637.GN22139@pengutronix.de>
References: <1287766405-1646-1-git-send-email-jbe@pengutronix.de>
	<1287766405-1646-9-git-send-email-jbe@pengutronix.de>
	<20101022185637.GN22139@pengutronix.de>
Message-ID: <201010231237.47956.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Fri, Oct 22, 2010 at 06:53:22PM +0200, Juergen Beisert wrote:
> > From: Juergen Beisert <juergen at kreuzholzen.de>
> >
> > Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
> > ---
> >  arch/arm/mach-s3c24xx/include/mach/fb.h |   40 +++
> >  drivers/video/Kconfig                   |    6 +
> >  drivers/video/Makefile                  |    1 +
> >  drivers/video/s3c.c                     |  454
> > +++++++++++++++++++++++++++++++ 4 files changed, 501 insertions(+), 0
> > deletions(-)
> >  create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h
> >  create mode 100644 drivers/video/s3c.c
> >
> > diff --git a/drivers/video/s3c.c b/drivers/video/s3c.c
> > new file mode 100644
> > index 0000000..cd0f220
> > --- /dev/null
> > +++ b/drivers/video/s3c.c
> > +
> > +/**
> > + * Prepare the video hardware for a specified video mode
> > + * @param fb_info Framebuffer information
> > + * @param mode The video mode description to initialize
> > + * @return 0 on success
> > + *
> > + * FIXME Diese Routine darf die Pinx nach drau?en nicht aktivieren. Zur
> > Zeit macht sie das!
>
> You should at least translate this to english ;)

Sure, I already removed this sentence in my local patch stack... :-)

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From marek.belisko at gmail.com  Mon Oct 25 08:39:53 2010
From: marek.belisko at gmail.com (Marek Belisko)
Date: Mon, 25 Oct 2010 14:39:53 +0200
Subject: [PATCH] barebox:usb_gadget:Remove compilation error.
Message-ID: <1288010393-3644-1-git-send-email-marek.belisko@gmail.com>

Missing include <init.h> caused that __initdata was
undeclared what lead to compilation error.

Signed-off-by: Marek Belisko <marek.belisko at gmail.com>
---
 drivers/usb/gadget/epautoconf.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index e549792..78f3099 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
-
+#include <init.h>
 #include <common.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
-- 
1.7.1



From s.hauer at pengutronix.de  Mon Oct 25 12:34:57 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 25 Oct 2010 18:34:57 +0200
Subject: [PATCH] barebox:usb_gadget:Remove compilation error.
In-Reply-To: <1288010393-3644-1-git-send-email-marek.belisko@gmail.com>
References: <1288010393-3644-1-git-send-email-marek.belisko@gmail.com>
Message-ID: <20101025163457.GA6017@pengutronix.de>

Hi Marek,

On Mon, Oct 25, 2010 at 02:39:53PM +0200, Marek Belisko wrote:
> Missing include <init.h> caused that __initdata was
> undeclared what lead to compilation error.

You probably mean the master branch, because next already has a fix for
this from Eric. I cherry-picked his patch to the master branch.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From marek.belisko at gmail.com  Mon Oct 25 13:07:04 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Mon, 25 Oct 2010 19:07:04 +0200
Subject: [PATCH] barebox:usb_gadget:Remove compilation error.
In-Reply-To: <20101025163457.GA6017@pengutronix.de>
References: <1288010393-3644-1-git-send-email-marek.belisko@gmail.com>
	<20101025163457.GA6017@pengutronix.de>
Message-ID: <AANLkTimr_PZaNnHhURxkxOuuRippEpeqWA_c8Hex4FXs@mail.gmail.com>

Hi Sascha,

On Mon, Oct 25, 2010 at 6:34 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> Hi Marek,
>
> On Mon, Oct 25, 2010 at 02:39:53PM +0200, Marek Belisko wrote:
>> Missing include <init.h> caused that __initdata was
>> undeclared what lead to compilation error.
>
> You probably mean the master branch, because next already has a fix for
> this from Eric. I cherry-picked his patch to the master branch.
Yes I found it in master branch. Suppose I have to use next branch when develop
some new functionality.
>
> Sascha
>
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 ? ?|
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From s.hauer at pengutronix.de  Mon Oct 25 13:50:21 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 25 Oct 2010 19:50:21 +0200
Subject: [PATCH] barebox:usb_gadget:Remove compilation error.
In-Reply-To: <AANLkTimr_PZaNnHhURxkxOuuRippEpeqWA_c8Hex4FXs@mail.gmail.com>
References: <1288010393-3644-1-git-send-email-marek.belisko@gmail.com>
	<20101025163457.GA6017@pengutronix.de>
	<AANLkTimr_PZaNnHhURxkxOuuRippEpeqWA_c8Hex4FXs@mail.gmail.com>
Message-ID: <20101025175021.GB6017@pengutronix.de>

On Mon, Oct 25, 2010 at 07:07:04PM +0200, Belisko Marek wrote:
> Hi Sascha,
> 
> On Mon, Oct 25, 2010 at 6:34 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> > Hi Marek,
> >
> > On Mon, Oct 25, 2010 at 02:39:53PM +0200, Marek Belisko wrote:
> >> Missing include <init.h> caused that __initdata was
> >> undeclared what lead to compilation error.
> >
> > You probably mean the master branch, because next already has a fix for
> > this from Eric. I cherry-picked his patch to the master branch.
> Yes I found it in master branch. Suppose I have to use next branch when develop
> some new functionality.

In this case I'm glad you found this is relevant for the master branch
;)

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From vm.rod25 at gmail.com  Mon Oct 25 18:29:41 2010
From: vm.rod25 at gmail.com (Victor Rodriguez)
Date: Mon, 25 Oct 2010 17:29:41 -0500
Subject: Beagleboard and barebox problem
In-Reply-To: <20101022070504.GD22139@pengutronix.de>
References: <AANLkTinosq5jY41=piCX3JaeFy6Z93gnG1Ym_VRqZ_sJ@mail.gmail.com>
	<20101022070504.GD22139@pengutronix.de>
Message-ID: <AANLkTimNiUjRq3GLNNa0gYRGGZjLaTrWbsNRKPU9=1mw@mail.gmail.com>

On Fri, Oct 22, 2010 at 2:05 AM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> Hi Victor,
>
> On Thu, Oct 21, 2010 at 12:55:16PM -0500, Victor Rodriguez wrote:
>> Hey I am new on bare box I have download it from git repo and when I
>> make the barebox.bin with omap3530_beagle_defconfig this is the output
>>
>> Texas Instruments X-Loader 1.4.2 (Feb 19 2009 - 12:01:24)
>> Reading boot sector
>> Loading u-boot.bin from mmc
>>
>>
>> barebox 2010.10.0-00086-ga14c018 (Oct 21 2010 - 12:19:10)
>>
>> Board: Texas Instrument's Beagle
>> I2C probe
>> i2c-omap at i2c-omap0: bus 0 rev3.12 at 100 kHz
>> ehci at ehci0: USB EHCI 1.00
>> NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron NAND 256MiB
>> 1,8V 16-bit)
>> Malloc space: 0x80c00000 -> 0x81000000 (size ?4 MB)
>> Stack space : 0x80bf8000 -> 0x80c00000 (size 32 kB)
>> Open /dev/env0 No such file or directory
>> running /env/bin/init...
>> not found
>> barebox> ls
>> . ? ? ?.. ? ? dev
>> barebox> ls /dev/
>> zero ? ? ? ? mem ? ? ? ? ?ram0 ? ? ? ? twl4030 ? ? ?nand0
>> nand_oob0
>
> Then it's up and running, congratulations ;)
>
> What the beagle board is missing is currently a place to store the
> environment. You could add an environment to nand by adding something
> like this to the board setup function:
>
> ? ? ? ?devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,"env_raw");
> ? ? ? ?dev_add_bb_dev("env_raw", "env0");
>
> (this adds a partition at offset 0x40000 and size 0x20000 to nand, you
> probably have to adjust the offset to not overwrite the X-loader)


HI Sascha thanks a lot for the help

Well after adding the environment for nand by adding this code :

 arch/arm/boards/omap/board-beagle.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/omap/board-beagle.c
b/arch/arm/boards/omap/board-beagle.c
index 6de2cce..21b31c2 100644
--- a/arch/arm/boards/omap/board-beagle.c
+++ b/arch/arm/boards/omap/board-beagle.c
@@ -73,6 +73,8 @@
 #include <linux/err.h>
 #include <usb/ehci.h>
 #include "board.h"
+#include <partition.h>
+#include <nand.h>

 /******************** Board Boot Time *******************/

@@ -334,6 +336,16 @@ static int beagle_devices_init(void)
 #endif
 	gpmc_generic_nand_devices_init(0, 16, 1);

+	/* ----------- add some vital partitions -------- */
+#ifdef CONFIG_NAND
+
+	devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED, "env_raw");
+	dev_add_bb_dev("env_raw", "env0");
+#endif
+
+
+
+
 	armlinux_add_dram(&sdram_dev);
 	armlinux_set_bootparams((void *)0x80000100);
 	armlinux_set_architecture(MACH_TYPE_OMAP3_BEAGLE);
-- 
1.7.0.4

barebox compiles fine

(Hope it could be a patch if you consider I could send this tiny patch
to the mailing list :)  )

And the output for the new boat loader is

Texas Instruments X-Loader 1.4.2 (Feb 19 2009 - 12:01:24)
Reading boot sector
Loading u-boot.bin from mmc


bare box 2010.10.0-00088-gd3ddbec (Oct 25 2010 - 16:36:06)

Board: Texas Instrument's Beagle
I2C probe
i2c-omap at i2c-omap0: bus 0 rev3.12 at 100 kHz
ehci at ehci0: USB EHCI 1.00
NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron NAND 256MiB
1,8V 16-bit)
Malloc space: 0x80c00000 -> 0x81000000 (size  4 MB)
Stack space : 0x80bf8000 -> 0x80c00000 (size 32 kB)
envfs: wrong magic on /dev/env0
running /env/bin/init...
not found
barebox> /

I fix the problem of envfs: wrong magic on /dev/env0 with your thread

http://www.mail-archive.com/u-boot-users at lists.sourceforge.net/msg10197.html

And every thing works fine

uboot> addpart /dev/nand0 256k(uboot),128k(env),2048k(kernel),-(rootfs)
uboot> nand -a /dev/nand0.*
uboot> erase /dev/nand0.kernel.bb


and in the end I have

barebox> /dev ls -la
ls: invalid option -- a
cr-------- 4294967295 zero
crw------- 4294967295 mem
crw-------  134217728 ram0
crw-------       1024 twl4030
crw-------  268435456 nand0
cr--------    8388608 nand_oob0
crw-------     131072 env_raw
crw-------     131072 env0
crw-------     262144 nand0.uboot
crw-------     131072 nand0.env
crw-------    2097152 nand0.kernel
crw-------  265945088 nand0.rootfs
crw-------  265945088 nand0.rootfs.bb
crw-------    2097152 nand0.kernel.bb
crw-------     131072 nand0.env.bb
crw-------     262144 nand0.uboot.bb


So every thing works fine :)

But I have a question how do I save the bootargs

My boot args used to be

setenv bootargs console=ttyS2,115200n8 noinitrd root=/dev/mmcblk0p2
rootfstype=ext2 rw rootdelay=1 nohz=off

But is not working for bare box

How do you save the boot args ?

The next step will be

uboot> tftp uImage-mx27ads /dev/nand0.kernel.bb

And the same for a ram disk File System in the nand0.rootfs.bb right ?

And

uboot> bootm /dev/nand0.kernel.bb

But my second question is  How the kernel know were is the File
System, where should I set something similar to boot args ?

Thanks for the help it really helps me a lot



> Another possibility would be to add mmc support for omap and put the
> environment there. We recently gained mmc support for barebox, so all
> that's missing is an omap driver. The mmc support is still close to
> U-Boot, so the driver won't need many changes.

I will try to do this hope it could help some one else.


Sincerely yours

Victor Rodriguez



>>
>>
>> And when I compile with omap3530_beagle_per_uart_defconfig
>
> The per_uart_defconfig is more a X-loader replacement. You can use it to
> bootstrap from the serial port. For your case the other config is the
> correct one.
>
> Sascha
>
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 ? ?|
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>


From s.hauer at pengutronix.de  Mon Oct 25 23:39:58 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 Oct 2010 05:39:58 +0200
Subject: Beagleboard and barebox problem
In-Reply-To: <AANLkTimNiUjRq3GLNNa0gYRGGZjLaTrWbsNRKPU9=1mw@mail.gmail.com>
References: <AANLkTinosq5jY41=piCX3JaeFy6Z93gnG1Ym_VRqZ_sJ@mail.gmail.com>
	<20101022070504.GD22139@pengutronix.de>
	<AANLkTimNiUjRq3GLNNa0gYRGGZjLaTrWbsNRKPU9=1mw@mail.gmail.com>
Message-ID: <20101026033958.GD6017@pengutronix.de>

Hi Victor,

> I fix the problem of envfs: wrong magic on /dev/env0 with your thread
> 
> http://www.mail-archive.com/u-boot-users at lists.sourceforge.net/msg10197.html
> 
> And every thing works fine
> 
> uboot> addpart /dev/nand0 256k(uboot),128k(env),2048k(kernel),-(rootfs)

I think on the beagle board the first space in Nand is occupied by the
xloader and xloader itself expects the second stage loader at offset
512k, but I don't know the exact situation off my head. Michael, maybe
you can comment on this?

> 
> setenv bootargs console=ttyS2,115200n8 noinitrd root=/dev/mmcblk0p2
> rootfstype=ext2 rw rootdelay=1 nohz=off
> 
> But is not working for bare box
> 
> How do you save the boot args ?

have a look at /env/config (using the edit command). Every file there is
saved into the environment using saveenv.

> 
> The next step will be
> 
> uboot> tftp uImage-mx27ads /dev/nand0.kernel.bb
> 
> And the same for a ram disk File System in the nand0.rootfs.bb right ?

Right, dont forget to erase the partitions with 'erase
/dev/nand0.kernel.bb' beforehand, otherwise you'll have garbage in your
nand.

> 
> And
> 
> uboot> bootm /dev/nand0.kernel.bb

In principle, yes. The normal process is to simply run 'boot' which is a
script under /env/bin. This will setup things like the commandline
correctly.

> 
> But my second question is  How the kernel know were is the File
> System, where should I set something similar to boot args ?

Have a look at the files under /env, I think this will answer your
questions (we have ls, cat and edit for this).

I'm sorry the situation on the beagle board is still a bit rough and
unclear. I hope we find time working on this.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From vm.rod25 at gmail.com  Tue Oct 26 00:07:21 2010
From: vm.rod25 at gmail.com (Victor Rodriguez)
Date: Mon, 25 Oct 2010 23:07:21 -0500
Subject: Beagleboard and barebox problem
In-Reply-To: <20101026033958.GD6017@pengutronix.de>
References: <AANLkTinosq5jY41=piCX3JaeFy6Z93gnG1Ym_VRqZ_sJ@mail.gmail.com>
	<20101022070504.GD22139@pengutronix.de>
	<AANLkTimNiUjRq3GLNNa0gYRGGZjLaTrWbsNRKPU9=1mw@mail.gmail.com>
	<20101026033958.GD6017@pengutronix.de>
Message-ID: <AANLkTi==hZCG9TbR1udevZPJp=wbji-JTTZaMTYYcW6f@mail.gmail.com>

On Mon, Oct 25, 2010 at 10:39 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> Hi Victor,
>
>> I fix the problem of envfs: wrong magic on /dev/env0 with your thread
>>
>> http://www.mail-archive.com/u-boot-users at lists.sourceforge.net/msg10197.html
>>
>> And every thing works fine
>>
>> uboot> addpart /dev/nand0 256k(uboot),128k(env),2048k(kernel),-(rootfs)
>
> I think on the beagle board the first space in Nand is occupied by the
> xloader and xloader itself expects the second stage loader at offset
> 512k, but I don't know the exact situation off my head. Michael, maybe
> you can comment on this?
>
>>
>> setenv bootargs console=ttyS2,115200n8 noinitrd root=/dev/mmcblk0p2
>> rootfstype=ext2 rw rootdelay=1 nohz=off
>>
>> But is not working for bare box
>>
>> How do you save the boot args ?
>
> have a look at /env/config (using the edit command). Every file there is
> saved into the environment using saveenv.
>
>>
>> The next step will be
>>
>> uboot> tftp uImage-mx27ads /dev/nand0.kernel.bb
>>
>> And the same for a ram disk File System in the nand0.rootfs.bb right ?
>
> Right, dont forget to erase the partitions with 'erase
> /dev/nand0.kernel.bb' beforehand, otherwise you'll have garbage in your
> nand.

You mean to erase the part of the nand where the kernel is saved
before copy the ramdisk to its partition? or before i run the 'boot'
comand ?



>>
>> And
>>
>> uboot> bootm /dev/nand0.kernel.bb
>
> In principle, yes. The normal process is to simply run 'boot' which is a
> script under /env/bin. This will setup things like the commandline
> correctly.
>
>>
>> But my second question is ?How the kernel know were is the File
>> System, where should I set something similar to boot args ?
>
> Have a look at the files under /env, I think this will answer your
> questions (we have ls, cat and edit for this).
>
> I'm sorry the situation on the beagle board is still a bit rough and
> unclear. I hope we find time working on this.


Yes I could give some free time to work on this :) but could you
please give me more information about the mmc dirver I am new on
barebox but I would like to help to improve it  :)

Which other board is using this MMC driver ? I can check the code.

The problem is that beagle board is much more familiar with booting by
mmc because it does not have any RJ45 connector in order to transfer
by TFTP or NFS the uImage.

By the way about the small piece of code for the beagle board nand. Do
you consider that is good enough for an small patch ?


Thanks a lot

Sincerely yours

Victor Rodriguez


> Sascha
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 ? ?|
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>


From jbe at pengutronix.de  Tue Oct 26 05:20:30 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 11:20:30 +0200
Subject: more patches for next
In-Reply-To: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <201010261120.30875.jbe@pengutronix.de>

Some of these changes lead into:

[...]
  CC      drivers/serial/serial_imx.o
In file included from arch/arm/mach-imx/include/mach/imx-regs.h:47,
                 from drivers/serial/serial_imx.c:21:
arch/arm/mach-imx/include/mach/imx27-regs.h:222:1: warning: "ESDMISC_RST" redefined
In file included from arch/arm/mach-imx/include/mach/imx27-regs.h:83,
                 from arch/arm/mach-imx/include/mach/imx-regs.h:47,
                 from drivers/serial/serial_imx.c:21:
arch/arm/mach-imx/include/mach/esdctl.h:37:1: warning: this is the location of the previous definition
In file included from arch/arm/mach-imx/include/mach/imx-regs.h:47,
                 from drivers/serial/serial_imx.c:21:
arch/arm/mach-imx/include/mach/imx27-regs.h:224:1: warning: "ESDMISC_MDDR_DL_RST" redefined
In file included from arch/arm/mach-imx/include/mach/imx27-regs.h:83,
                 from arch/arm/mach-imx/include/mach/imx-regs.h:47,
                 from drivers/serial/serial_imx.c:21:
arch/arm/mach-imx/include/mach/esdctl.h:40:1: warning: this is the location of the previous definition
In file included from arch/arm/mach-imx/include/mach/imx-regs.h:47,
                 from drivers/serial/serial_imx.c:21:
arch/arm/mach-imx/include/mach/imx27-regs.h:225:1: warning: "ESDMISC_MDDR_MDIS" redefined
In file included from arch/arm/mach-imx/include/mach/imx27-regs.h:83,
                 from arch/arm/mach-imx/include/mach/imx-regs.h:47,
                 from drivers/serial/serial_imx.c:21:
arch/arm/mach-imx/include/mach/esdctl.h:41:1: warning: this is the location of the previous definition
In file included from arch/arm/mach-imx/include/mach/imx-regs.h:47,
                 from drivers/serial/serial_imx.c:21:
arch/arm/mach-imx/include/mach/imx27-regs.h:226:1: warning: "ESDMISC_LHD" redefined
In file included from arch/arm/mach-imx/include/mach/imx27-regs.h:83,
                 from arch/arm/mach-imx/include/mach/imx-regs.h:47,
                 from drivers/serial/serial_imx.c:21:
arch/arm/mach-imx/include/mach/esdctl.h:42:1: warning: this is the location of the previous definition
[...]

Tested with the "pcm038_defconfig".

BTW: When building the "pcm043_defconfig" I get the following warnings
multiple times:

[...]
 CC      commands/mem.o
{standard input}: Assembler messages:
{standard input}:908: rdhi, rdlo and rm must all be different
{standard input}:934: rdhi, rdlo and rm must all be different
{standard input}:976: rdhi, rdlo and rm must all be different
[...]


-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From mkl at pengutronix.de  Tue Oct 26 05:48:01 2010
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 Oct 2010 11:48:01 +0200
Subject: more patches for next
In-Reply-To: <201010261120.30875.jbe@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
	<201010261120.30875.jbe@pengutronix.de>
Message-ID: <4CC6A3D1.5050708@pengutronix.de>

On 10/26/2010 11:20 AM, Juergen Beisert wrote:

[...]

> BTW: When building the "pcm043_defconfig" I get the following warnings
> multiple times:
> 
> [...]
>  CC      commands/mem.o
> {standard input}: Assembler messages:
> {standard input}:908: rdhi, rdlo and rm must all be different
> {standard input}:934: rdhi, rdlo and rm must all be different
> {standard input}:976: rdhi, rdlo and rm must all be different
> [...]

use a newer toolchain with newer binutils, e.g.

/opt/OSELAS.Toolchain-1.99.3/arm-1136jfs-linux-gnueabi/gcc-4.3.2-glibc-2.8-binutils-2.19-kernel-2.6.27-sanitized/bin/
Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20101026/ad603ae4/attachment.sig>

From jbe at pengutronix.de  Tue Oct 26 07:31:36 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:36 +0200
Subject: [PATCHv2] Add dynamic video initialization to barebox
Message-ID: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>

Currently barebox uses a fixed videomode setup. Everything is compiled in.
This change adds the possibility to select a videomode according to a
connected display at runtime. The current behaviour is still present if not
otherwise configured. If configured for runtime setup, initialization of the
video hardware will be delayed until the required videomode will be selected
from the shell code. If more than one videomode is supported by the platform,
running the 'devinfo' command on the framebuffer device shows the supported
videomode list. After selecting the videomode, the output can be enabled.

On my hardware I can connect a regular monitor, which supports more than one
videomode. The runtime setup sequence looks like that:

tx28:/ devinfo framebuffer0
base  : 0x00000000
size  : 0x00000000
driver: framebuffer

 Video/Mode info:
   Video output not enabled
 Current video mode:
   No video mode selected yet
 Supported video mode(s):
   'VGA'
   'SVGA'
   'XGA'
   'SXGA'
 Parameters:
           cdepth = 16
             mode = <NULL>
           enable = <NULL>

tx28:/ framebuffer0.mode=SVGA
tx28:/ bmp splash.bmp
tx28:/ framebuffer0.enable=1

After the last command the monitor shows the splash screen.

This is revision 2 of this patch stack.
 - enabling the video output is now always required to get a picture
 - driver specific data can now be added on a per videomode base
 - documentation is adapted to the new behaviour

jbe



From jbe at pengutronix.de  Tue Oct 26 07:31:37 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:37 +0200
Subject: [PATCH 01/12] Separate framebuffer platformdata and the videomode
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-2-git-send-email-jbe@pengutronix.de>

This patch separates the imx platformdata and its videomode in two structures,
in order to support more than one defined videomode in the boardfile. This
is intended to support runtime videomode selection later on. It also uses
now the same videomode setup style than the imx-fpu based systems (like the
i.MX35).

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c |   28 +++++++++--------
 arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c |   28 +++++++++--------
 arch/arm/boards/guf-neso/board.c                  |   28 +++++++++--------
 arch/arm/boards/imx21ads/imx21ads.c               |   34 +++++++++++----------
 arch/arm/boards/pcm038/pcm038.c                   |   28 +++++++++--------
 arch/arm/mach-imx/include/mach/imxfb.h            |    2 +-
 drivers/video/imx.c                               |    6 ++--
 7 files changed, 82 insertions(+), 72 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index 805ffe2..032897a 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -120,20 +120,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode cmo_display = {
+	.name		= "CMO-QVGA",
+	.refresh	= 60,
+	.xres		= 320,
+	.yres		= 240,
+	.pixclock	= KHZ2PICOS(6500),
+	.hsync_len	= 30,
+	.left_margin	= 38,
+	.right_margin	= 20,
+	.vsync_len	= 3,
+	.upper_margin	= 15,
+	.lower_margin	= 4,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CMO-QVGA",
-		.refresh	= 60,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= KHZ2PICOS(6500),
-		.hsync_len	= 30,
-		.left_margin	= 38,
-		.right_margin	= 20,
-		.vsync_len	= 3,
-		.upper_margin	= 15,
-		.lower_margin	= 4,
-	},
+	.mode		= &cmo_display,
 	.pcr		= 0xCAD08B80,
 	.bpp		= 16,
 };
diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
index 62fc14e..3ea2466 100644
--- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
+++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
@@ -186,20 +186,22 @@ static void eukrea_cpuimx27_mmu_init(void)
 #endif
 
 #ifdef CONFIG_DRIVER_VIDEO_IMX
+static struct fb_videomode cmo_display = {
+	.name		= "CMO-QVGA",
+	.refresh	= 60,
+	.xres		= 320,
+	.yres		= 240,
+	.pixclock	= 156000,
+	.hsync_len	= 30,
+	.left_margin	= 38,
+	.right_margin	= 20,
+	.vsync_len	= 3,
+	.upper_margin	= 15,
+	.lower_margin	= 4,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CMO-QVGA",
-		.refresh	= 60,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= 156000,
-		.hsync_len	= 30,
-		.left_margin	= 38,
-		.right_margin	= 20,
-		.vsync_len	= 3,
-		.upper_margin	= 15,
-		.lower_margin	= 4,
-	},
+	.mode		= &cmo_display,
 	.pcr		= 0xFAD08B80,
 	.bpp		= 16,};
 
diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c
index 9c85c08..6949675 100644
--- a/arch/arm/boards/guf-neso/board.c
+++ b/arch/arm/boards/guf-neso/board.c
@@ -91,20 +91,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode cpt_display = {
+	.name		= "CPT CLAA070LC0JCT",
+	.refresh	= 60,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= KHZ2PICOS(27000),
+	.hsync_len	= 1,	/* DE only sync */
+	.left_margin	= 50,
+	.right_margin	= 50,
+	.vsync_len	= 1,	/* DE only sync */
+	.upper_margin	= 10,
+	.lower_margin	= 10,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "CPT CLAA070LC0JCT",
-		.refresh	= 60,
-		.xres		= 800,
-		.yres		= 480,
-		.pixclock	= KHZ2PICOS(27000),
-		.hsync_len	= 1,	/* DE only sync */
-		.left_margin	= 50,
-		.right_margin	= 50,
-		.vsync_len	= 1,	/* DE only sync */
-		.upper_margin	= 10,
-		.lower_margin	= 10,
-	},
+	.mode = &cpt_display,
 	/*
 	 * - TFT style panel
 	 * - clk enabled while idle
diff --git a/arch/arm/boards/imx21ads/imx21ads.c b/arch/arm/boards/imx21ads/imx21ads.c
index 44d37aa..81006de 100644
--- a/arch/arm/boards/imx21ads/imx21ads.c
+++ b/arch/arm/boards/imx21ads/imx21ads.c
@@ -79,24 +79,26 @@ static struct device_d cs8900_dev = {
 	// IRQ is connected to UART3_RTS
 };
 
+static struct fb_videomode sharp_display = {
+	.name           = "Sharp-LQ035Q7",
+	.refresh        = 60,
+	.xres           = 240,
+	.yres           = 320,
+	.pixclock       = 188679,
+	.left_margin    = 6,
+	.right_margin   = 16,
+	.upper_margin   = 8,
+	.lower_margin   = 10,
+	.hsync_len      = 2,
+	.vsync_len      = 1,
+	.sync           = 0,
+	.vmode          = FB_VMODE_NONINTERLACED,
+	.flag           = 0,
+};
+
 /* Sharp LQ035Q7DB02 QVGA display */
 static struct imx_fb_videomode imx_fb_modedata = {
-        .mode = {
-		.name           = "Sharp-LQ035Q7",
-		.refresh        = 60,
-		.xres           = 240,
-		.yres           = 320,
-		.pixclock       = 188679,
-		.left_margin    = 6,
-		.right_margin   = 16,
-		.upper_margin   = 8,
-		.lower_margin   = 10,
-		.hsync_len      = 2,
-		.vsync_len      = 1,
-		.sync           = 0,
-		.vmode          = FB_VMODE_NONINTERLACED,
-		.flag           = 0,
-	},
+        .mode           = &sharp_display,
         .pcr            = 0xfb108bc7,
         .bpp            = 16,
 };
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index 3a9b413..026e9c0 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -127,20 +127,22 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
+static struct fb_videomode sharp_display = {
+	.name		= "Sharp-LQ035Q7",
+	.refresh	= 60,
+	.xres		= 240,
+	.yres		= 320,
+	.pixclock	= 188679, /* in ps (5.3MHz) */
+	.hsync_len	= 7,
+	.left_margin	= 5,
+	.right_margin	= 16,
+	.vsync_len	= 1,
+	.upper_margin	= 7,
+	.lower_margin	= 9,
+};
+
 static struct imx_fb_videomode imxfb_mode = {
-	.mode = {
-		.name		= "Sharp-LQ035Q7",
-		.refresh	= 60,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 188679, /* in ps (5.3MHz) */
-		.hsync_len	= 7,
-		.left_margin	= 5,
-		.right_margin	= 16,
-		.vsync_len	= 1,
-		.upper_margin	= 7,
-		.lower_margin	= 9,
-	},
+	.mode		= &sharp_display,
 	/*
 	 * - HSYNC active high
 	 * - VSYNC active high
diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h
index 16b43ea..7baa244 100644
--- a/arch/arm/mach-imx/include/mach/imxfb.h
+++ b/arch/arm/mach-imx/include/mach/imxfb.h
@@ -50,7 +50,7 @@
 #define DMACR_TM(x)	((x) & 0xf)
 
 struct imx_fb_videomode {
-	struct fb_videomode mode;
+	struct fb_videomode *mode;
 	u32 pcr;
 	unsigned char	bpp;
 };
diff --git a/drivers/video/imx.c b/drivers/video/imx.c
index ac51858..6ccd77e 100644
--- a/drivers/video/imx.c
+++ b/drivers/video/imx.c
@@ -555,9 +555,9 @@ static int imxfb_probe(struct device_d *dev)
 	fbi->enable = pdata->enable;
 	fbi->dev = dev;
 	info->priv = fbi;
-	info->mode = &pdata->mode->mode;
-	info->xres = pdata->mode->mode.xres;
-	info->yres = pdata->mode->mode.yres;
+	info->mode = pdata->mode->mode;
+	info->xres = pdata->mode->mode->xres;
+	info->yres = pdata->mode->mode->yres;
 	info->bits_per_pixel = pdata->mode->bpp;
 	info->fbops = &imxfb_ops;
 
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:38 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:38 +0200
Subject: [PATCH 02/12] Add more flags for sync control
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-3-git-send-email-jbe@pengutronix.de>

In order to make video mode setup and initializing a runtime job (currently
it is a compile time job) this patch tries to make the 'fb_videomode' structure
more generic. It should also carry special settings required only for some LC
displays. So, I add some additional sync flags to control the DE and CLCK to
the display (something a regular CRT do not know). Also the possibility to
stop the clock when outside active display data (required for (C)STN).

Further suggestions for flags?

What about the special settings for some kind of Sharp displays the i.MX
processor family supports?

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 include/fb.h |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/include/fb.h b/include/fb.h
index 379f931..218b244 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -17,11 +17,21 @@
 					/* vtotal = 144d/288n/576i => PAL  */
 					/* vtotal = 121d/242n/484i => NTSC */
 #define FB_SYNC_ON_GREEN	32	/* sync on green */
+/* LC display related settings */
+#define FB_SYNC_DE_HIGH_ACT	(1 << 6)
+#define FB_SYNC_CLK_INVERT	(1 << 7)
+#define FB_SYNC_DATA_INVERT	(1 << 8)
+#define FB_SYNC_CLK_IDLE_EN	(1 << 9)
+#define FB_SYNC_SWAP_RGB	(1 << 10)
+#define FB_SYNC_CLK_SEL_EN	(1 << 11)
+#define FB_SYNC_SHARP_MODE	(1 << 31)
 
 #define FB_VMODE_NONINTERLACED  0	/* non interlaced */
 #define FB_VMODE_INTERLACED	1	/* interlaced	*/
 #define FB_VMODE_DOUBLE		2	/* double scan */
 #define FB_VMODE_ODD_FLD_FIRST	4	/* interlaced: top line first */
+/* LC display related settings */
+#define FB_VMODE_DUAL_SCAN	8
 #define FB_VMODE_MASK		255
 
 #define FB_VMODE_YWRAP		256	/* ywrap instead of panning     */
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:39 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:39 +0200
Subject: [PATCH 03/12] Bring in dynamic videomode selection at runtime
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-4-git-send-email-jbe@pengutronix.de>

This patch mostly rewrites all parts of /drivers/video/fb.c. As it changes
the API to the drivers, it must be done in one step to keep the repository
bisectable. But to do it in one step makes the patches itself unreadable.

So, I decided to do it in a few steps, only for the review. All patches marked
with a "step n" should be merged, prior the final commit onto the repository.

This step brings in the required function for dynamic videomode selection at
runtime but keep the old functions untouched (the new one are commented out).

This is patch 1 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/video/Kconfig |   13 +++
 drivers/video/fb.c    |  243 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/fb.h          |   40 ++++++++
 3 files changed, 296 insertions(+), 0 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7a89a3f..8138226 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -5,6 +5,19 @@ menuconfig VIDEO
 
 if VIDEO
 
+comment "runtime options"
+
+config VIDEO_DELAY_INIT
+	bool "Delayed initialization"
+	help
+	  If the platform supports more than one video mode say 'y' her to delay
+	  the initialization of the video device until any kind of barebox's
+          shell code sets up the correct mode at runtime.
+          This entry adds the "mode" parameter to the video device, to setup
+          the desired videomode prior enabling it at runtime.
+
+comment "drivers"
+
 config DRIVER_VIDEO_IMX
 	bool "i.MX framebuffer driver"
 	depends on ARCH_IMX1 || ARCH_IMX21 || ARCH_IMX25 || ARCH_IMX27
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index f9a425e..c3c4761 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -1,3 +1,4 @@
+#include <init.h>
 #include <common.h>
 #include <fb.h>
 #include <errno.h>
@@ -5,6 +6,8 @@
 #include <getopt.h>
 #include <fcntl.h>
 #include <fs.h>
+#include <malloc.h>
+#include <xfuncs.h>
 
 static int fb_ioctl(struct cdev* cdev, int req, void *data)
 {
@@ -57,6 +60,139 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param,
 	return 0;
 }
 
+#if 0
+#ifdef CONFIG_VIDEO_DELAY_INIT
+static int fb_check_if_already_initialized(struct device_d *fb_dev)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+
+	if (info->active_mode != NULL) {
+		pr_err("Video mode '%s' is already set. Cannot change colour depth anymore.\n", info->active_mode->name);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int fb_cdepth_set(struct device_d *fb_dev, struct param_d *param, const char *val)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+	unsigned cdepth;
+	int rc;
+
+	rc = fb_check_if_already_initialized(fb_dev);
+	if (rc != 0)
+		return rc;
+
+	cdepth = simple_strtoul(val, NULL, 0);
+	if (cdepth != 0)
+		info->bits_per_pixel = cdepth;
+	else
+		return -EINVAL;
+
+	return dev_param_set_generic(fb_dev, param, val);
+}
+#endif
+
+static int fb_enable_set(struct device_d *fb_dev, struct param_d *param, const char *val)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+	struct fb_host *host = fb_dev->platform_data;
+	int enable;
+	char *new;
+
+	if (!val)
+		return dev_param_set_generic(fb_dev, param, NULL);
+
+	enable = simple_strtoul(val, NULL, 0);
+
+	if (info->enabled == !!enable)
+		return 0;
+
+	if (enable) {
+		(host->fb_enable)(info);
+		new = "1";
+	} else {
+		(host->fb_disable)(info);
+		new = "0";
+	}
+
+	info->enabled = !!enable;
+
+	return dev_param_set_generic(fb_dev, param, new);
+}
+
+static void fb_list_modes(struct fb_host *host)
+{
+	unsigned u;
+
+	if (host->mode_cnt == 0)
+		return;
+
+	printf(" Supported video mode(s):\n");
+	for (u = 0; u < host->mode_cnt; u++)
+		printf("  '%s'\n", host->mode[u].name);
+}
+
+static int fb_activate_mode(struct device_d *fb_dev, const struct fb_videomode *mode)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+	struct fb_host *host = fb_dev->platform_data;
+	int rc;
+
+	rc = (host->fb_mode)(info, mode);
+	if (rc != 0)
+		return rc;
+
+	info->active_mode = mode;
+	/*
+	 * At this point of time we know the remaining information we need
+	 * for the cdev and fb_info structure.
+	 */
+	cdev->size = fb_dev->size;
+	info->xres = mode->xres;
+	info->yres = mode->yres;
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_DELAY_INIT
+static int fb_mode_set(struct device_d *fb_dev, struct param_d *param, const char *name)
+{
+	struct fb_host *host = fb_dev->platform_data;
+	unsigned u;
+	int rc;
+
+	pr_debug("%s called\n", __func__);
+
+	rc = fb_check_if_already_initialized(fb_dev);
+	if (rc != 0)
+		return rc;
+
+	/* Search for the requested video mode by name */
+	for (u = 0; u < host->mode_cnt; u++) {
+		if (!strcmp(host->mode[u].name, name))
+			break;
+	}
+	if (u >= host->mode_cnt) {
+		fb_list_modes(host);	/* no mode with 'name' found */
+		return -ENODEV;
+	} else {
+		rc = fb_activate_mode(fb_dev, &host->mode[u]);
+	}
+
+	if (rc == 0)
+		dev_param_set_generic(fb_dev, param, name);
+
+	return rc;
+}
+#endif
+#endif
+
 static struct file_operations fb_ops = {
 	.read	= mem_read,
 	.write	= mem_write,
@@ -65,6 +201,113 @@ static struct file_operations fb_ops = {
 	.ioctl	= fb_ioctl,
 };
 
+#if 0
+static int add_fb_parameter(struct device_d *fb_dev)
+{
+#ifdef CONFIG_VIDEO_DELAY_INIT
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+	char cd[10];
+
+	/** @todo provide base address parameter for the user */
+
+	dev_add_param(fb_dev, "cdepth", fb_cdepth_set, NULL, 0);
+	if (info->bits_per_pixel == 0) {
+		dev_set_param(fb_dev, "cdepth", "16");
+		info->bits_per_pixel = 16;
+	} else {
+		sprintf(cd, "%u", info->bits_per_pixel);
+		dev_set_param(fb_dev, "cdepth", cd);
+	}
+	dev_add_param(fb_dev, "mode", fb_mode_set, NULL, 0);
+	/* default is 'none' for delayed video mode setup */
+#endif
+	dev_add_param(fb_dev, "enable", fb_enable_set, NULL, 0);
+	/* default is 'off' for delayed video output */
+	return 0;
+}
+
+struct framebuffer_desc {
+	struct cdev cdev;
+	struct fb_info info;
+};
+
+static int fb_probe(struct device_d *fb_dev)
+{
+	int id = get_free_deviceid("fb");
+	struct cdev *cdev;
+	struct fb_info *info;
+	struct fb_host *host = fb_dev->platform_data;
+
+	cdev = xzalloc(sizeof(struct framebuffer_desc));
+	info = (struct fb_info*)&cdev[1];
+
+	fb_dev->priv = cdev;	/* pointer forward */
+	cdev->dev = fb_dev;	/* pointer backward */
+
+	cdev->ops = &fb_ops;
+	cdev->name = asprintf("fb%d", id);
+
+	cdev->size = fb_dev->size;	/* use the default if any */
+	cdev->priv = info;
+
+	info->host = host;
+	info->fb_dev = fb_dev;
+
+	/* setup defaults */
+	if (host->bits_per_pixel != 0)
+		info->bits_per_pixel = host->bits_per_pixel;
+	else
+		info->bits_per_pixel = 16;	/* means RGB565 */
+
+	/* add params on demand */
+	add_fb_parameter(fb_dev);
+
+	devfs_create(cdev);
+#ifndef CONFIG_VIDEO_DELAY_INIT
+	/* initialize video mode immediately (the first one) */
+	fb_activate_mode(fb_dev, &host->mode[0]);
+#endif
+	return 0;
+}
+
+static struct driver_d fb_driver = {
+	.name	= "framebuffer",
+	.probe	= fb_probe,
+};
+
+static int framebuffer_init(void)
+{
+	return register_driver(&fb_driver);
+}
+
+device_initcall(framebuffer_init);
+
+struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned size)
+{
+	struct device_d *fb_dev;
+	int rc;
+
+	fb_dev = xzalloc(sizeof(struct device_d));
+
+	strcpy(fb_dev->name, fb_driver.name);
+	fb_dev->platform_data = (void*)host;
+
+	/* setup the defaults for this framebuffer if given */
+	fb_dev->size = size;
+	fb_dev->map_base = (unsigned long)base;
+
+	rc = register_device(fb_dev);
+	if (rc != 0) {
+		pr_debug("Cannot register framebuffer device\n");
+		free(fb_dev);
+		return NULL;
+	}
+
+	return fb_dev;
+}
+#endif
+
 int register_framebuffer(struct fb_info *info)
 {
 	int id = get_free_deviceid("fb");
diff --git a/include/fb.h b/include/fb.h
index 218b244..96edc24 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -85,6 +85,46 @@ struct fb_ops {
 	void (*fb_disable)(struct fb_info *info);
 };
 
+#if 0
+struct fb_host {
+	const struct fb_videomode *mode;
+	unsigned mode_cnt;
+
+	struct device_d *hw_dev;
+
+	/* callbacks into the video hardware driver */
+	int (*fb_setcolreg)(struct fb_info*, unsigned, unsigned, unsigned, unsigned, unsigned);
+	int (*fb_mode)(struct fb_info*, const struct fb_videomode*);
+	void (*fb_enable)(struct fb_info*);
+	void (*fb_disable)(struct fb_info*);
+
+	unsigned bits_per_pixel;
+};
+
+struct fb_info {
+	struct fb_host *host;
+	struct device_d *fb_dev;
+	const struct fb_videomode *active_mode;
+
+	u32 xres;			/* visible resolution		*/
+	u32 yres;
+	u32 bits_per_pixel;		/* guess what			*/
+
+	u32 grayscale;			/* != 0 Graylevels instead of colors */
+
+	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
+	struct fb_bitfield green;	/* else only length is significant */
+	struct fb_bitfield blue;
+	struct fb_bitfield transp;	/* transparency			*/
+
+#ifdef CONFIG_VIDEO_DELAY_ENABLING
+	int enabled;
+#endif
+};
+
+struct device_d *register_framebuffer(struct fb_host*, void*, unsigned);
+#endif
+
 struct fb_info {
 	struct fb_videomode *mode;
 
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:40 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:40 +0200
Subject: [PATCH 04/12] Remove the old videomode functions
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-5-git-send-email-jbe@pengutronix.de>

Remove the old functions from the framebuffer framework. This patch is kept
separate for review only. Should be merged with the previous one patch
prior commit.

This is patch 2 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/video/fb.c |   67 ++-------------------------------------------------
 include/fb.h       |   40 -------------------------------
 2 files changed, 3 insertions(+), 104 deletions(-)

diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index c3c4761..428ad34 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -11,6 +11,7 @@
 
 static int fb_ioctl(struct cdev* cdev, int req, void *data)
 {
+	struct fb_host *host = cdev->dev->platform_data;
 	struct fb_info *info = cdev->priv;
 
 	switch (req) {
@@ -18,10 +19,10 @@ static int fb_ioctl(struct cdev* cdev, int req, void *data)
 		memcpy(data, info, sizeof(*info));
 		break;
 	case FBIO_ENABLE:
-		info->fbops->fb_enable(info);
+		(host->fb_enable)(cdev->priv);
 		break;
 	case FBIO_DISABLE:
-		info->fbops->fb_disable(info);
+		(host->fb_disable)(cdev->priv);
 		break;
 	default:
 		return -ENOSYS;
@@ -30,37 +31,6 @@ static int fb_ioctl(struct cdev* cdev, int req, void *data)
 	return 0;
 }
 
-static int fb_enable_set(struct device_d *dev, struct param_d *param,
-		const char *val)
-{
-	struct fb_info *info = dev->priv;
-	int enable;
-	char *new;
-
-	if (!val)
-		return dev_param_set_generic(dev, param, NULL);
-
-	enable = simple_strtoul(val, NULL, 0);
-
-	if (info->enabled == !!enable)
-		return 0;
-
-	if (enable) {
-		info->fbops->fb_enable(info);
-		new = "1";
-	} else {
-		info->fbops->fb_disable(info);
-		new = "0";
-	}
-
-	dev_param_set_generic(dev, param, new);
-
-	info->enabled = !!enable;
-
-	return 0;
-}
-
-#if 0
 #ifdef CONFIG_VIDEO_DELAY_INIT
 static int fb_check_if_already_initialized(struct device_d *fb_dev)
 {
@@ -191,7 +161,6 @@ static int fb_mode_set(struct device_d *fb_dev, struct param_d *param, const cha
 	return rc;
 }
 #endif
-#endif
 
 static struct file_operations fb_ops = {
 	.read	= mem_read,
@@ -201,7 +170,6 @@ static struct file_operations fb_ops = {
 	.ioctl	= fb_ioctl,
 };
 
-#if 0
 static int add_fb_parameter(struct device_d *fb_dev)
 {
 #ifdef CONFIG_VIDEO_DELAY_INIT
@@ -306,32 +274,3 @@ struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned
 
 	return fb_dev;
 }
-#endif
-
-int register_framebuffer(struct fb_info *info)
-{
-	int id = get_free_deviceid("fb");
-	struct device_d *dev;
-
-	info->cdev.ops = &fb_ops;
-	info->cdev.name = asprintf("fb%d", id);
-	info->cdev.size = info->xres * info->yres * (info->bits_per_pixel >> 3);
-	info->cdev.dev = &info->dev;
-	info->cdev.priv = info;
-	info->cdev.dev->map_base = (unsigned long)info->screen_base;
-	info->cdev.dev->size = info->cdev.size;
-
-	dev = &info->dev;
-	dev->priv = info;
-
-	sprintf(dev->name, "fb");
-
-	register_device(&info->dev);
-	dev_add_param(dev, "enable", fb_enable_set, NULL, 0);
-	dev_set_param(dev, "enable", "0");
-
-	devfs_create(&info->cdev);
-
-	return 0;
-}
-
diff --git a/include/fb.h b/include/fb.h
index 96edc24..c94c1d0 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -77,15 +77,6 @@ struct fb_bitfield {
 
 struct fb_info;
 
-struct fb_ops {
-	/* set color register */
-	int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
-			    unsigned blue, unsigned transp, struct fb_info *info);
-	void (*fb_enable)(struct fb_info *info);
-	void (*fb_disable)(struct fb_info *info);
-};
-
-#if 0
 struct fb_host {
 	const struct fb_videomode *mode;
 	unsigned mode_cnt;
@@ -117,41 +108,10 @@ struct fb_info {
 	struct fb_bitfield blue;
 	struct fb_bitfield transp;	/* transparency			*/
 
-#ifdef CONFIG_VIDEO_DELAY_ENABLING
 	int enabled;
-#endif
 };
 
 struct device_d *register_framebuffer(struct fb_host*, void*, unsigned);
-#endif
-
-struct fb_info {
-	struct fb_videomode *mode;
-
-	struct fb_ops *fbops;
-	struct device_d dev;		/* This is this fb device */
-
-	void *screen_base;
-
-	void *priv;
-
-	struct cdev cdev;
-
-	u32 xres;			/* visible resolution		*/
-	u32 yres;
-	u32 bits_per_pixel;		/* guess what			*/
-
-	u32 grayscale;			/* != 0 Graylevels instead of colors */
-
-	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
-	struct fb_bitfield green;	/* else only length is significant */
-	struct fb_bitfield blue;
-	struct fb_bitfield transp;	/* transparency			*/
-
-	int enabled;
-};
-
-int register_framebuffer(struct fb_info *info);
 
 #define FBIOGET_SCREENINFO	_IOR('F', 1, loff_t)
 #define	FBIO_ENABLE		_IO('F', 2)
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:41 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:41 +0200
Subject: [PATCH 05/12] Add verbose framebuffer device info
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-6-git-send-email-jbe@pengutronix.de>

This is patch 3 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/video/Kconfig |    6 ++++++
 drivers/video/fb.c    |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 8138226..d7f3d01 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -16,6 +16,12 @@ config VIDEO_DELAY_INIT
           This entry adds the "mode" parameter to the video device, to setup
           the desired videomode prior enabling it at runtime.
 
+config VIDEO_INFO_VERBOSE
+	bool "Verbose video info"
+	help
+	  Say 'y' here to be more verbose when running the 'devinfo' command
+	  on the framebuffer device.
+
 comment "drivers"
 
 config DRIVER_VIDEO_IMX
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index 428ad34..cb66744 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -170,6 +170,43 @@ static struct file_operations fb_ops = {
 	.ioctl	= fb_ioctl,
 };
 
+static void fb_info(struct device_d *fb_dev)
+{
+	struct cdev *cdev = fb_dev->priv;
+	struct fb_info *info = cdev->priv;
+
+	printf(" Video/Mode info:\n");
+	printf("  Video output %senabled\n", info->enabled != 0 ? "" : "not ");
+	printf(" Current video mode:\n");
+	if (info->active_mode != NULL) {
+		printf("  Name: %s\n", info->active_mode->name);
+#ifdef CONFIG_VIDEO_INFO_VERBOSE
+		if (info->active_mode->refresh == 0)
+			printf("  Refresh rate: undefined\n");
+		else
+			printf("  Refresh rate: %u Hz\n",  info->active_mode->refresh);
+		printf("  Horizontal active pixel: %u\n", info->active_mode->xres);
+		printf("  Vertical active lines: %u\n", info->active_mode->yres);
+		printf("  Pixel clock: %u kHz\n", PICOS2KHZ(info->active_mode->pixclock));
+		printf("  Left/Right margin (pixel): %u/%u\n", info->active_mode->left_margin,
+			info->active_mode->right_margin);
+		printf("  Upper/Lower margin (lines): %u/%u\n", info->active_mode->upper_margin,
+			info->active_mode->lower_margin);
+		printf("  HSYNC length in pixel: %u, polarity: %s\n", info->active_mode->hsync_len,
+			(info->active_mode->sync & FB_SYNC_HOR_HIGH_ACT) ? "high" : "low");
+		printf("  VSYNC length in lines: %u, polarity: %s\n", info->active_mode->vsync_len,
+			(info->active_mode->sync & FB_SYNC_VERT_HIGH_ACT) ? "high" : "low");
+		printf("  Colour depth: %u bpp\n", info->bits_per_pixel);
+		printf("  Framebuffer size is: %u bytes\n", cdev->size);
+		/* TODO add the remaining information from fb_videomode. How valuable are they? */
+#endif
+	} else {
+		printf ("  No video mode selected yet\n");
+	}
+
+	fb_list_modes(fb_dev->platform_data);
+}
+
 static int add_fb_parameter(struct device_d *fb_dev)
 {
 #ifdef CONFIG_VIDEO_DELAY_INIT
@@ -242,6 +279,7 @@ static int fb_probe(struct device_d *fb_dev)
 static struct driver_d fb_driver = {
 	.name	= "framebuffer",
 	.probe	= fb_probe,
+	.info	= fb_info,
 };
 
 static int framebuffer_init(void)
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:46 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:46 +0200
Subject: [PATCH 10/12] Remove variable size restrictions
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-11-git-send-email-jbe@pengutronix.de>

There is no really need for special variable types in these structures. Replace
them by standard C types with the same behaviour.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 include/fb.h |   41 ++++++++++++++++++++---------------------
 1 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/include/fb.h b/include/fb.h
index c94c1d0..b42532e 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -43,19 +43,19 @@
 
 struct fb_videomode {
 	const char *name;	/* optional */
-	u32 refresh;		/* optional */
-	u32 xres;
-	u32 yres;
-	u32 pixclock;
-	u32 left_margin;
-	u32 right_margin;
-	u32 upper_margin;
-	u32 lower_margin;
-	u32 hsync_len;
-	u32 vsync_len;
-	u32 sync;
-	u32 vmode;
-	u32 flag;
+	unsigned refresh;		/* optional */
+	unsigned xres;
+	unsigned yres;
+	unsigned pixclock;
+	unsigned left_margin;
+	unsigned right_margin;
+	unsigned upper_margin;
+	unsigned lower_margin;
+	unsigned hsync_len;
+	unsigned vsync_len;
+	unsigned sync;
+	unsigned vmode;
+	unsigned flag;
 };
 
 /* Interpretation of offset for color fields: All offsets are from the right,
@@ -69,10 +69,9 @@ struct fb_videomode {
  * of available palette entries (i.e. # of entries = 1 << length).
  */
 struct fb_bitfield {
-	u32 offset;			/* beginning of bitfield	*/
-	u32 length;			/* length of bitfield		*/
-	u32 msb_right;			/* != 0 : Most significant bit is */ 
-					/* right */ 
+	unsigned offset;		/* beginning of bitfield	*/
+	unsigned length;		/* length of bitfield		*/
+	int msb_right;			/* != 0 : Most significant bit is right */
 };
 
 struct fb_info;
@@ -97,11 +96,11 @@ struct fb_info {
 	struct device_d *fb_dev;
 	const struct fb_videomode *active_mode;
 
-	u32 xres;			/* visible resolution		*/
-	u32 yres;
-	u32 bits_per_pixel;		/* guess what			*/
+	unsigned xres;			/* visible resolution		*/
+	unsigned yres;
+	unsigned bits_per_pixel;	/* guess what			*/
 
-	u32 grayscale;			/* != 0 Graylevels instead of colors */
+	int grayscale;			/* != 0 Graylevels instead of colors */
 
 	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
 	struct fb_bitfield green;	/* else only length is significant */
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:42 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:42 +0200
Subject: [PATCH 06/12] Adapt the existing imx fb driver to support runtime
	videomode selection
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-7-git-send-email-jbe@pengutronix.de>

Adapt the API to the new framebuffer videomode selection at runtime. If the new
feature is not used, there is no visible change at runtime for platforms using
this driver.

NOTE: Due to the lack of hardware, this is compile time tested only.

This is patch 4 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/imxfb.h |    1 +
 drivers/video/imx.c                    |  211 ++++++++++++++++++--------------
 2 files changed, 120 insertions(+), 92 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h
index 7baa244..c536119 100644
--- a/arch/arm/mach-imx/include/mach/imxfb.h
+++ b/arch/arm/mach-imx/include/mach/imxfb.h
@@ -60,6 +60,7 @@ struct imx_fb_videomode {
  */
 struct imx_fb_platform_data {
 	struct imx_fb_videomode *mode;
+	unsigned mode_cnt;	/**< number of entries in 'mode' */
 
 	u_int		cmap_greyscale:1,
 			cmap_inverse:1,
diff --git a/drivers/video/imx.c b/drivers/video/imx.c
index 6ccd77e..07438e5 100644
--- a/drivers/video/imx.c
+++ b/drivers/video/imx.c
@@ -137,6 +137,7 @@ struct imxfb_rgb {
 };
 
 struct imxfb_info {
+	struct fb_host		fb_host;	/**< myself */
 	void __iomem		*regs;
 
 	u_int			pcr;
@@ -147,16 +148,15 @@ struct imxfb_info {
 				cmap_static:1,
 				unused:30;
 
-	struct imx_fb_videomode *mode;
-
-	struct fb_info		info;
-	struct device_d		*dev;
-
 	void			(*enable)(int enable);
 
-	struct fb_info		overlay;
+	struct fb_host		fb_overlay;
 };
 
+#define fb_overlay_to_imxfb_info(x) (container_of((struct fb_host*)(x->host), struct imxfb_info, fb_overlay))
+#define fb_overlay_dev_to_imxfb_info(x) (container_of((struct fb_host*)(x->platform_data), struct imxfb_info, fb_overlay))
+#define fb_info_to_imxfb_info(x) ((struct imxfb_info*)((x)->host))
+
 #define IMX_NAME	"IMX"
 
 /*
@@ -204,11 +204,10 @@ static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
 	return chan << bf->offset;
 }
 
-
-static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-		   u_int trans, struct fb_info *info)
+static int imxfb_setcolreg(struct fb_info *info, u_int regno, u_int red,
+			u_int green, u_int blue, u_int trans)
 {
-	struct imxfb_info *fbi = info->priv;
+	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
 	int ret = 1;
 	u32 val;
 
@@ -247,7 +246,7 @@ static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
 static void imxfb_enable_controller(struct fb_info *info)
 {
-	struct imxfb_info *fbi = info->priv;
+	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
 
 	writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR);
 #ifdef CONFIG_ARCH_IMX21
@@ -269,7 +268,7 @@ static void imxfb_enable_controller(struct fb_info *info)
 
 static void imxfb_disable_controller(struct fb_info *info)
 {
-	struct imxfb_info *fbi = info->priv;
+	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
 
 	if (fbi->enable)
 		fbi->enable(0);
@@ -295,14 +294,35 @@ static void imxfb_disable_controller(struct fb_info *info)
  *	Configures LCD Controller based on entries in var parameter.  Settings are
  *	only written to the controller if changes were made.
  */
-static int imxfb_activate_var(struct fb_info *info)
+static int imxfb_initialize_mode(struct fb_info *info, const struct fb_videomode *mode)
 {
-	struct fb_videomode *mode = info->mode;
 	struct imxfb_rgb *rgb;
 	unsigned long lcd_clk;
 	unsigned long long tmp;
-	struct imxfb_info *fbi = info->priv;
+	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
 	u32 pcr;
+	unsigned size;
+
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = mode->xres * mode->yres * (info->bits_per_pixel >> 3);
+	if (info->fb_dev->size != 0) {
+		if (size > info->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, info->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		info->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (info->fb_dev->map_base == 0U /* FIXME should be 'NULL'*/)
+		info->fb_dev->map_base = (unsigned long)xzalloc(info->fb_dev->size);
 
 	/* physical screen start address	    */
 	writel(VPW_VPW(mode->xres * info->bits_per_pixel / 8 / 4),
@@ -318,13 +338,13 @@ static int imxfb_activate_var(struct fb_info *info)
 		VCR_V_WAIT_2(mode->upper_margin),
 		fbi->regs + LCDC_VCR);
 
-	writel(SIZE_XMAX(info->xres) | SIZE_YMAX(info->yres),
+	writel(SIZE_XMAX(mode->xres) | SIZE_YMAX(mode->yres),
 			fbi->regs + LCDC_SIZE);
 
 	writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
 	writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
-	writel((unsigned long)fbi->info.screen_base, fbi->regs + LCDC_SSA);
+	writel((uint32_t)info->fb_dev->map_base, fbi->regs + LCDC_SSA);
 
 	/* panning offset 0 (0 pixel offset)        */
 	writel(0x0, fbi->regs + LCDC_POS);
@@ -386,16 +406,10 @@ static int imxfb_activate_var(struct fb_info *info)
 	return 0;
 }
 
-static struct fb_ops imxfb_ops = {
-	.fb_setcolreg	= imxfb_setcolreg,
-	.fb_enable	= imxfb_enable_controller,
-	.fb_disable	= imxfb_disable_controller,
-};
-
 #ifdef CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY
 static void imxfb_overlay_enable_controller(struct fb_info *overlay)
 {
-	struct imxfb_info *fbi = overlay->priv;
+	struct imxfb_info *fbi = fb_overlay_to_imxfb_info(overlay);
 	unsigned int tmp;
 
 	tmp = readl(fbi->regs + LCDC_LGWCR);
@@ -405,7 +419,7 @@ static void imxfb_overlay_enable_controller(struct fb_info *overlay)
 
 static void imxfb_overlay_disable_controller(struct fb_info *overlay)
 {
-	struct imxfb_info *fbi = overlay->priv;
+	struct imxfb_info *fbi = fb_overlay_to_imxfb_info(overlay);
 	unsigned int tmp;
 
 	tmp = readl(fbi->regs + LCDC_LGWCR);
@@ -413,23 +427,16 @@ static void imxfb_overlay_disable_controller(struct fb_info *overlay)
 	writel(tmp , fbi->regs + LCDC_LGWCR);
 }
 
-static int imxfb_overlay_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-		   u_int trans, struct fb_info *info)
+static int imxfb_overlay_setcolreg(struct fb_info *overlay, u_int regno,
+		u_int red, u_int green, u_int blue, u_int trans)
 {
 	return 0;
 }
 
-static struct fb_ops imxfb_overlay_ops = {
-	.fb_setcolreg	= imxfb_overlay_setcolreg,
-	.fb_enable	= imxfb_overlay_enable_controller,
-	.fb_disable	= imxfb_overlay_disable_controller,
-};
-
 static int imxfb_alpha_set(struct device_d *dev, struct param_d *param,
 		const char *val)
 {
-	struct fb_info *overlay = dev->priv;
-	struct imxfb_info *fbi = overlay->priv;
+	struct imxfb_info *fbi = fb_overlay_dev_to_imxfb_info(dev);
 	int alpha;
 	char alphastr[16];
 	unsigned int tmp;
@@ -452,32 +459,35 @@ static int imxfb_alpha_set(struct device_d *dev, struct param_d *param,
 	return 0;
 }
 
-static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb)
+static int imxfb_overlay_mode(struct fb_info *overlay, const struct fb_videomode *mode)
 {
-	struct fb_info *overlay;
+	struct imxfb_info *fbi = fb_overlay_to_imxfb_info(overlay);
 	struct imxfb_rgb *rgb;
-	int ret;
-
-	overlay = &fbi->overlay;
-
-	overlay->priv = fbi;
-	overlay->mode = fbi->info.mode;
-	overlay->xres = fbi->info.xres;
-	overlay->yres = fbi->info.yres;
-	overlay->bits_per_pixel = fbi->info.bits_per_pixel;
-	overlay->fbops = &imxfb_overlay_ops;
-
-	if (fb)
-		overlay->screen_base = fb;
-	else
-		overlay->screen_base = xzalloc(overlay->xres * overlay->yres *
-			(overlay->bits_per_pixel >> 3));
-
-	writel((unsigned long)overlay->screen_base, fbi->regs + LCDC_LGWSAR);
-	writel(SIZE_XMAX(overlay->xres) | SIZE_YMAX(overlay->yres),
-			fbi->regs + LCDC_LGWSR);
-	writel(VPW_VPW(overlay->xres * overlay->bits_per_pixel / 8 / 4),
-		fbi->regs + LCDC_LGWVPWR);
+	unsigned size;
+
+	/* we need at least this amount of memory for the framebuffer */
+	size = mode->xres * mode->yres * (overlay->bits_per_pixel >> 3);
+
+	if (overlay->fb_dev->size != 0) {
+		if (size > overlay->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, overlay->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		overlay->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (overlay->fb_dev->map_base == 0U /* FIXME should be 'NULL'*/)
+		overlay->fb_dev->map_base = (unsigned long)xzalloc(overlay->fb_dev->size);
+
+	writel((uint32_t)overlay->fb_dev->map_base, fbi->regs + LCDC_LGWSAR);
+	writel(SIZE_XMAX(mode->xres) | SIZE_YMAX(mode->yres), fbi->regs + LCDC_LGWSR);
+	writel(VPW_VPW(mode->xres * overlay->bits_per_pixel / 8 / 4), fbi->regs + LCDC_LGWVPWR);
 	writel(0, fbi->regs + LCDC_LGWPR);
 	writel(LGWCR_GWAV(0x0), fbi->regs + LCDC_LGWCR);
 
@@ -506,14 +516,36 @@ static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb)
 	overlay->blue   = rgb->blue;
 	overlay->transp = rgb->transp;
 
-	ret = register_framebuffer(overlay);
-	if (ret < 0) {
-		dev_err(fbi->dev, "failed to register framebuffer\n");
-		return ret;
+	return 0;
+}
+
+static int imxfb_register_overlay(struct imxfb_info *fbi, struct device_d *hw_dev,
+				struct imx_fb_platform_data *pdata)
+{
+	struct fb_host *overlay;
+	struct device_d *overlay_dev;
+
+	overlay = &fbi->fb_overlay;
+
+	/* add runtime hardware info */
+	overlay->hw_dev = hw_dev;	/* same as the master device */
+	overlay->fb_mode = imxfb_overlay_mode;
+	overlay->fb_enable = imxfb_overlay_enable_controller;
+	overlay->fb_disable = imxfb_overlay_disable_controller;
+	overlay->fb_setcolreg = imxfb_overlay_setcolreg;
+
+	/* add runtime video info */
+	overlay->mode = pdata->mode->mode;
+	overlay->mode_cnt = 1;	/* no choice */
+
+	overlay_dev = register_framebuffer(overlay, pdata->framebuffer_ovl, 0);
+	if (overlay_dev == NULL) {
+		dev_err(hw_dev, "failed to register overlay framebuffer\n");
+		return -EINVAL;
 	}
 
-	dev_add_param(&overlay->dev, "alpha", imxfb_alpha_set, NULL, 0);
-	dev_set_param(&overlay->dev, "alpha", "0");
+	dev_add_param(overlay_dev, "alpha", imxfb_alpha_set, NULL, 0);
+	dev_set_param(overlay_dev, "alpha", "0");
 
 	return 0;
 }
@@ -522,13 +554,13 @@ static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb)
 static int imxfb_probe(struct device_d *dev)
 {
 	struct imxfb_info *fbi;
-	struct fb_info *info;
+	struct device_d *fb_dev;
 	struct imx_fb_platform_data *pdata = dev->platform_data;
-	int ret;
 
 	if (!pdata)
 		return -ENODEV;
 
+	/* TODO should be done when enabling the video output */
 #ifdef CONFIG_ARCH_IMX21
 	PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN);
 #endif
@@ -544,40 +576,35 @@ static int imxfb_probe(struct device_d *dev)
 #endif
 
 	fbi = xzalloc(sizeof(*fbi));
-	info = &fbi->info;
 
-	fbi->mode = pdata->mode;
-	fbi->regs = (void *)dev->map_base;
+	/* add runtime hardware info */
+	fbi->fb_host.hw_dev = dev;
+	fbi->fb_host.fb_mode = imxfb_initialize_mode;
+	fbi->fb_host.fb_enable = imxfb_enable_controller;
+	fbi->fb_host.fb_disable = imxfb_disable_controller;
+	fbi->fb_host.fb_setcolreg = imxfb_setcolreg;
+
+	fbi->regs = (void*)dev->map_base;
 	fbi->pcr = pdata->mode->pcr;
 	fbi->pwmr = pdata->pwmr;
 	fbi->lscr1 = pdata->lscr1;
 	fbi->dmacr = pdata->dmacr;
 	fbi->enable = pdata->enable;
-	fbi->dev = dev;
-	info->priv = fbi;
-	info->mode = pdata->mode->mode;
-	info->xres = pdata->mode->mode->xres;
-	info->yres = pdata->mode->mode->yres;
-	info->bits_per_pixel = pdata->mode->bpp;
-	info->fbops = &imxfb_ops;
-
-	dev_info(dev, "i.MX Framebuffer driver\n");
-
-	if (pdata->framebuffer)
-		fbi->info.screen_base = pdata->framebuffer;
-	else
-		fbi->info.screen_base = xzalloc(info->xres * info->yres *
-			(info->bits_per_pixel >> 3));
-
-	imxfb_activate_var(&fbi->info);
-
-	ret = register_framebuffer(&fbi->info);
-	if (ret < 0) {
+
+	/* add runtime video info */
+	fbi->fb_host.mode = pdata->mode->mode;
+	/* to be backward compatible */
+	fbi->fb_host.mode_cnt = pdata->mode_cnt == 0 ? 1 : pdata->mode_cnt;
+	fbi->fb_host.bits_per_pixel = 16;	/* RGB565, the default */
+
+	fb_dev = register_framebuffer(&fbi->fb_host, pdata->framebuffer, 0);
+	if (dev == NULL) {
 		dev_err(dev, "failed to register framebuffer\n");
-		return ret;
+		return -EINVAL;
 	}
+
 #ifdef CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY
-	imxfb_register_overlay(fbi, pdata->framebuffer_ovl);
+	imxfb_register_overlay(fbi, fb_dev, pdata);
 #endif
 	return 0;
 }
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:43 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:43 +0200
Subject: [PATCH 07/12] Adapt the existing imx-ipu fb driver to support runtime
	videomode selection
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-8-git-send-email-jbe@pengutronix.de>

Adapt the API to the new framebuffer videomode selection at runtime. If the new
feature is not used, there is no visible change at runtime for platforms using
this driver.

NOTE: Due to the lack of hardware, this is compile time tested only.

This is patch 5 of 7 to keep the repository bisectable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/freescale-mx35-3-stack/3stack.c |    2 +-
 arch/arm/boards/pcm043/pcm043.c                 |    2 +-
 arch/arm/mach-imx/include/mach/imx-ipu-fb.h     |   12 +-
 drivers/video/imx-ipu-fb.c                      |  216 +++++++++++++----------
 4 files changed, 124 insertions(+), 108 deletions(-)

diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
index d6699cd..fb40f50 100644
--- a/arch/arm/boards/freescale-mx35-3-stack/3stack.c
+++ b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
@@ -139,7 +139,7 @@ static struct fb_videomode CTP_CLAA070LC0ACW = {
 	.lower_margin	= 10,	/* whole frame should have 500 lines */
 	.hsync_len	= 1,	/* note: DE only display */
 	.vsync_len	= 1,	/* note: DE only display */
-	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_DE_HIGH_ACT,
 	.vmode		= FB_VMODE_NONINTERLACED,
 	.flag		= 0,
 };
diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
index 5932f95..7e63cc5 100644
--- a/arch/arm/boards/pcm043/pcm043.c
+++ b/arch/arm/boards/pcm043/pcm043.c
@@ -124,7 +124,7 @@ static struct fb_videomode pcm043_fb_mode = {
 	.lower_margin	= 40,
 	.hsync_len	= 96,
 	.vsync_len	= 1,
-	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_DE_HIGH_ACT,
 	.vmode		= FB_VMODE_NONINTERLACED,
 	.flag		= 0,
 };
diff --git a/arch/arm/mach-imx/include/mach/imx-ipu-fb.h b/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
index 8e1cc87..ce95243 100644
--- a/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
+++ b/arch/arm/mach-imx/include/mach/imx-ipu-fb.h
@@ -12,20 +12,12 @@
 
 #include <fb.h>
 
-/* Proprietary FB_SYNC_ flags */
-#define FB_SYNC_OE_ACT_HIGH	0x80000000
-#define FB_SYNC_CLK_INVERT	0x40000000
-#define FB_SYNC_DATA_INVERT	0x20000000
-#define FB_SYNC_CLK_IDLE_EN	0x10000000
-#define FB_SYNC_SHARP_MODE	0x08000000
-#define FB_SYNC_SWAP_RGB	0x04000000
-#define FB_SYNC_CLK_SEL_EN	0x02000000
-
 /*
- * struct mx3fb_platform_data - mx3fb platform data
+ * struct imx_ipu_fb_platform_data - imx-ipu-fb's platform data
  */
 struct imx_ipu_fb_platform_data {
 	struct fb_videomode	*mode;
+	unsigned mode_cnt;	/**< number of entries in 'mode' */
 	unsigned char		bpp;
 	void __iomem		*framebuffer;
 	/** hook to enable backlight and stuff */
diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
index c38082d..45399cb 100644
--- a/drivers/video/imx-ipu-fb.c
+++ b/drivers/video/imx-ipu-fb.c
@@ -34,12 +34,12 @@
 #include <mach/clock.h>
 
 struct ipu_fb_info {
+	struct  fb_host		fb_host;	/**< myself */
 	void __iomem		*regs;
 
 	void			(*enable)(int enable);
 
-	struct fb_info		info;
-	struct device_d		*dev;
+	const struct fb_videomode *mode;	/**< requested videomodue */
 };
 
 /* IPU DMA Controller channel definitions. */
@@ -413,29 +413,30 @@ static inline void reg_write(struct ipu_fb_info *fbi, u32 value,
 	writel(value, fbi->regs + reg);
 }
 
+#define fb_info_to_imxfb_info(x) ((struct ipu_fb_info*)((x)->host))
+
 /*
  * sdc_init_panel() - initialize a synchronous LCD panel.
- * @width:		width of panel in pixels.
- * @height:		height of panel in pixels.
- * @pixel_fmt:		pixel format of buffer as FOURCC ASCII code.
+ * @param info The framebuffer to work on
+ * @param pixel_fmt pixel format of buffer as FOURCC ASCII code.
  * @return:		0 on success or negative error code on failure.
  */
-static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
+static int sdc_init_panel(struct fb_info *fb_info, enum pixel_fmt pixel_fmt)
 {
-	struct ipu_fb_info *fbi = info->priv;
-	struct fb_videomode *mode = info->mode;
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
+	const struct fb_videomode *mode = fbi->mode;
 	u32 reg, old_conf, div;
 	enum ipu_panel panel = IPU_PANEL_TFT;
 	unsigned long pixel_clk;
 
 	/* Init panel size and blanking periods */
 	reg = ((mode->hsync_len - 1) << 26) |
-		((info->xres + mode->left_margin + mode->right_margin +
+		((mode->xres + mode->left_margin + mode->right_margin +
 		  mode->hsync_len - 1) << 16);
 	reg_write(fbi, reg, SDC_HOR_CONF);
 
 	reg = ((mode->vsync_len - 1) << 26) | SDC_V_SYNC_WIDTH_L |
-		((info->yres + mode->upper_margin + mode->lower_margin +
+		((mode->yres + mode->upper_margin + mode->lower_margin +
 		  mode->vsync_len - 1) << 16);
 	reg_write(fbi, reg, SDC_VER_CONF);
 
@@ -448,7 +449,7 @@ static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
 		old_conf |= DI_D3_CLK_POL;
 	if (mode->sync & FB_SYNC_DATA_INVERT)
 		old_conf |= DI_D3_DATA_POL;
-	if (mode->sync & FB_SYNC_OE_ACT_HIGH)
+	if (mode->sync & FB_SYNC_DE_HIGH_ACT)
 		old_conf |= DI_D3_DRDY_SHARP_POL;
 	reg_write(fbi, old_conf, DI_DISP_SIG_POL);
 
@@ -483,12 +484,12 @@ static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt)
 	div = imx_get_lcdclk() * 16 / pixel_clk;
 
 	if (div < 0x40) {	/* Divider less than 4 */
-		dev_dbg(&info->dev,
+		dev_dbg(fbi->fb_host.hw_dev,
 			"InitPanel() - Pixel clock divider less than 4\n");
 		div = 0x40;
 	}
 
-	dev_dbg(&info->dev, "pixel clk = %u, divider %u.%u\n",
+	dev_dbg(fbi->fb_host.hw_dev, "pixel clk = %u, divider %u.%u\n",
 		pixel_clk, div >> 4, (div & 7) * 125);
 
 	/*
@@ -588,19 +589,20 @@ static u32 dma_param_addr(enum ipu_channel channel)
 	return 0x10000 | (channel << 4);
 }
 
-static void ipu_init_channel_buffer(struct ipu_fb_info *fbi,
+static void ipu_init_channel_buffer(struct fb_info *fb_info,
 		enum ipu_channel channel, void *fbmem)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
 	union chan_param_mem params = {};
 	u32 reg;
 	u32 stride_bytes;
 
-	stride_bytes = fbi->info.xres * ((fbi->info.bits_per_pixel + 7) / 8);
+	stride_bytes = fbi->mode->xres * ((fb_info->bits_per_pixel + 7) / 8);
 	stride_bytes = (stride_bytes + 3) & ~3;
 
 	/* Build parameter memory data for DMA channel */
-	ipu_ch_param_set_size(&params, bpp_to_pixfmt(fbi->info.bits_per_pixel),
-			      fbi->info.xres, fbi->info.yres, stride_bytes);
+	ipu_ch_param_set_size(&params, bpp_to_pixfmt(fb_info->bits_per_pixel),
+			      fbi->mode->xres, fbi->mode->yres, stride_bytes);
 	ipu_ch_param_set_buffer(&params, fbmem, NULL);
 	params.pp.bam = 0;
 	/* Some channels (rotation) have restriction on burst length */
@@ -622,9 +624,10 @@ static void ipu_init_channel_buffer(struct ipu_fb_info *fbi,
 	reg_write(fbi, reg, IPU_CHA_DB_MODE_SEL);
 }
 
-static void ipu_channel_set_priority(struct ipu_fb_info *fbi,
+static void ipu_channel_set_priority(struct fb_info *fb_info,
 		enum ipu_channel channel, int prio)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
 	u32 reg;
 
 	reg = reg_read(fbi, IDMAC_CHA_PRI);
@@ -639,11 +642,13 @@ static void ipu_channel_set_priority(struct ipu_fb_info *fbi,
 
 /*
  * ipu_enable_channel() - enable an IPU channel.
+ * @param fb_info The framebuffer to work on
  * @channel:	channel ID.
  * @return:	0 on success or negative error code on failure.
  */
-static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
+static int ipu_enable_channel(struct fb_info *fb_info, enum ipu_channel channel)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
 	u32 reg;
 
 	/* Reset to buffer 0 */
@@ -651,7 +656,7 @@ static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
 
 	switch (channel) {
 	case IDMAC_SDC_0:
-		ipu_channel_set_priority(fbi, channel, 1);
+		ipu_channel_set_priority(fb_info, channel, 1);
 		break;
 	default:
 		break;
@@ -663,9 +668,10 @@ static int ipu_enable_channel(struct ipu_fb_info *fbi, enum ipu_channel channel)
 	return 0;
 }
 
-static int ipu_update_channel_buffer(struct ipu_fb_info *fbi,
+static int ipu_update_channel_buffer(struct fb_info *fb_info,
 		enum ipu_channel channel, void *buf)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
 	u32 reg;
 
 	reg = reg_read(fbi, IPU_CHA_BUF0_RDY);
@@ -679,16 +685,17 @@ static int ipu_update_channel_buffer(struct ipu_fb_info *fbi,
 	return 0;
 }
 
-static int idmac_tx_submit(struct ipu_fb_info *fbi, enum ipu_channel channel,
+static int idmac_tx_submit(struct fb_info *fb_info, enum ipu_channel channel,
 		void *buf)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
 	int ret;
 
-	ipu_init_channel_buffer(fbi, channel, buf);
+	ipu_init_channel_buffer(fb_info, channel, buf);
 
 
 	/* ipu_idmac.c::ipu_submit_channel_buffers() */
-	ret = ipu_update_channel_buffer(fbi, channel, buf);
+	ret = ipu_update_channel_buffer(fb_info, channel, buf);
 	if (ret < 0)
 		return ret;
 
@@ -697,16 +704,17 @@ static int idmac_tx_submit(struct ipu_fb_info *fbi, enum ipu_channel channel,
 	reg_write(fbi, 1UL << channel, IPU_CHA_BUF0_RDY);
 
 
-	ret = ipu_enable_channel(fbi, channel);
+	ret = ipu_enable_channel(fb_info, channel);
 	return ret;
 }
 
-static void sdc_enable_channel(struct ipu_fb_info *fbi, void *fbmem)
+static void sdc_enable_channel(struct fb_info *fb_info, void *fbmem)
 {
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
 	int ret;
 	u32 reg;
 
-	ret = idmac_tx_submit(fbi, IDMAC_SDC_0, fbmem);
+	ret = idmac_tx_submit(fb_info, IDMAC_SDC_0, fbmem);
 
 	/* mx3fb.c::sdc_fb_init() */
 	if (ret >= 0) {
@@ -722,11 +730,74 @@ static void sdc_enable_channel(struct ipu_fb_info *fbi, void *fbmem)
 	mdelay(2);
 }
 
+static void imxfb_init_info(struct fb_info *fb_info, const struct fb_videomode *mode)
+{
+	struct imx_ipu_fb_rgb *rgb;
+
+	fb_info->xres = mode->xres;
+	fb_info->yres = mode->yres;
+
+	switch (fb_info->bits_per_pixel) {
+	case 32:
+		rgb = &def_rgb_32;
+		break;
+	case 24:
+		rgb = &def_rgb_24;
+		break;
+	case 16:
+	default:
+		rgb = &def_rgb_16;
+		break;
+	}
+
+	/*
+	 * Copy the RGB parameters for this display
+	 * from the machine specific parameters.
+	 */
+	fb_info->red    = rgb->red;
+	fb_info->green  = rgb->green;
+	fb_info->blue   = rgb->blue;
+	fb_info->transp = rgb->transp;
+}
+
+static int ipu_fb_initialize_mode(struct fb_info *fb_info, const struct fb_videomode *mode)
+{
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
+	unsigned size;
+
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = mode->xres * mode->yres * (fb_info->bits_per_pixel >> 3);
+	if (fb_info->fb_dev->size != 0) {
+		if (size > fb_info->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, fb_info->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		fb_info->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (fb_info->fb_dev->map_base == 0U /* FIXME should be 'NULL'*/)
+		fb_info->fb_dev->map_base = (unsigned long)xzalloc(fb_info->fb_dev->size);
+
+	fbi->mode = mode;
+
+	imxfb_init_info(fb_info, mode);
+
+	return 0;
+}
+
 /* References in this function refer to respective Linux kernel sources */
-static void ipu_fb_enable(struct fb_info *info)
+static void ipu_fb_enable(struct fb_info *fb_info)
 {
-	struct ipu_fb_info *fbi = info->priv;
-	struct fb_videomode *mode = info->mode;
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(fb_info);
+	const struct fb_videomode *mode = fbi->mode;
 	u32 reg;
 
 	/* pcm037.c::mxc_board_init() */
@@ -779,12 +850,12 @@ static void ipu_fb_enable(struct fb_info *info)
 		~(SDC_COM_GWSEL | SDC_COM_KEY_COLOR_G);
 	reg_write(fbi, reg, SDC_COM_CONF);
 
-	sdc_init_panel(info, IPU_PIX_FMT_RGB666);
+	sdc_init_panel(fb_info, IPU_PIX_FMT_RGB666);
 
 	reg_write(fbi, (mode->left_margin << 16) | mode->upper_margin,
 			SDC_BG_POS);
 
-	sdc_enable_channel(fbi, info->screen_base);
+	sdc_enable_channel(fb_info, (void*)fb_info->fb_dev->map_base);
 
 	/*
 	 * Linux driver calls sdc_set_brightness() here again,
@@ -796,7 +867,7 @@ static void ipu_fb_enable(struct fb_info *info)
 
 static void ipu_fb_disable(struct fb_info *info)
 {
-	struct ipu_fb_info *fbi = info->priv;
+	struct ipu_fb_info *fbi = fb_info_to_imxfb_info(info);
 	u32 reg;
 
 	if (fbi->enable)
@@ -807,85 +878,38 @@ static void ipu_fb_disable(struct fb_info *info)
 	reg_write(fbi, reg, SDC_COM_CONF);
 }
 
-static struct fb_ops imxfb_ops = {
-	.fb_enable = ipu_fb_enable,
-	.fb_disable = ipu_fb_disable,
-};
-
-static void imxfb_init_info(struct fb_info *info, struct fb_videomode *mode,
-		int bpp)
-{
-	struct imx_ipu_fb_rgb *rgb;
-
-	info->mode = mode;
-	info->xres = mode->xres;
-	info->yres = mode->yres;
-	info->bits_per_pixel = bpp;
-
-	switch (info->bits_per_pixel) {
-	case 32:
-		rgb = &def_rgb_32;
-		break;
-	case 24:
-		rgb = &def_rgb_24;
-		break;
-	case 16:
-	default:
-		rgb = &def_rgb_16;
-		break;
-	}
-
-	/*
-	 * Copy the RGB parameters for this display
-	 * from the machine specific parameters.
-	 */
-	info->red    = rgb->red;
-	info->green  = rgb->green;
-	info->blue   = rgb->blue;
-	info->transp = rgb->transp;
-}
-
 static int imxfb_probe(struct device_d *dev)
 {
 	struct ipu_fb_info *fbi;
-	struct fb_info *info;
+	struct device_d *fb_dev;
 	const struct imx_ipu_fb_platform_data *pdata = dev->platform_data;
-	int ret;
 
 	if (!pdata)
 		return -ENODEV;
 
 	fbi = xzalloc(sizeof(*fbi));
-	info = &fbi->info;
+
+	/* add runtime hardware info */
+	fbi->fb_host.hw_dev = dev;
+	fbi->fb_host.fb_mode = ipu_fb_initialize_mode;
+	fbi->fb_host.fb_enable = ipu_fb_enable;
+	fbi->fb_host.fb_disable = ipu_fb_disable;
+	fbi->fb_host.fb_setcolreg = NULL;
 
 	fbi->regs = (void *)dev->map_base;
-	fbi->dev = dev;
-	info->priv = fbi;
-	info->fbops = &imxfb_ops;
-	fbi->enable = pdata->enable;
 
-	imxfb_init_info(info, pdata->mode, pdata->bpp);
+	/* add runtime video info */
+	fbi->fb_host.mode = pdata->mode;
+	/* to be backward compatible */
+	fbi->fb_host.mode_cnt = pdata->mode_cnt == 0 ? 1 : pdata->mode_cnt;
+	fbi->fb_host.bits_per_pixel = pdata->bpp;
 
 	dev_info(dev, "i.MX Framebuffer driver\n");
 
-	/*
-	 * Use a given frambuffer or reserve some
-	 * memory for screen usage
-	 */
-	fbi->info.screen_base = pdata->framebuffer;
-	if (fbi->info.screen_base == NULL) {
-		fbi->info.screen_base = malloc(info->xres * info->yres *
-					       (info->bits_per_pixel >> 3));
-		if (!fbi->info.screen_base)
-			return -ENOMEM;
-	}
-
-	sdc_enable_channel(fbi, info->screen_base);
-
-	ret = register_framebuffer(&fbi->info);
-	if (ret < 0) {
+	fb_dev = register_framebuffer(&fbi->fb_host, pdata->framebuffer, 0);
+	if (fb_dev == NULL) {
 		dev_err(dev, "failed to register framebuffer\n");
-		return ret;
+		return -EINVAL;
 	}
 
 	return 0;
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:48 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:48 +0200
Subject: [PATCH 12/12] Provide more driver specific data in a videomode
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-13-git-send-email-jbe@pengutronix.de>

In order to support more than one videomode in a binary barebox, some drivers
need more specific data to setup the requested video mode in a correct manner.
This patch adds the 'priv' field to the generic videomode description to give
any platform a chance to forward some video hardware specific information on
a per videomode base.

This is currently i.MX21/i.MX25/i.MX27 specific.

BTW: At least the 'pcr' value could be generated at runtime from the 'sync'
field in 'struct fb_videomode'.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c |   22 +++++------
 arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c |   21 +++++-----
 arch/arm/boards/guf-neso/board.c                  |   45 +++++++++++----------
 arch/arm/boards/imx21ads/imx21ads.c               |   24 ++++++------
 arch/arm/boards/pcm038/pcm038.c                   |   40 +++++++++---------
 arch/arm/mach-imx/include/mach/imxfb.h            |   20 +++++----
 drivers/video/imx.c                               |   19 +++++----
 include/fb.h                                      |    2 +
 8 files changed, 99 insertions(+), 94 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index 032897a..9a9021a 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -120,7 +120,14 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
-static struct fb_videomode cmo_display = {
+static const struct imx_fb_driver_data driver_data = {
+	.pwmr		= 0x00A903FF,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x80040060,
+	.pcr		= 0xCAD08B80,
+};
+
+static const struct fb_videomode cmo_display = {
 	.name		= "CMO-QVGA",
 	.refresh	= 60,
 	.xres		= 320,
@@ -134,20 +141,11 @@ static struct fb_videomode cmo_display = {
 	.lower_margin	= 4,
 };
 
-static struct imx_fb_videomode imxfb_mode = {
-	.mode		= &cmo_display,
-	.pcr		= 0xCAD08B80,
-	.bpp		= 16,
-};
-
 static struct imx_fb_platform_data eukrea_cpuimx25_fb_data = {
-	.mode		= &imxfb_mode,
-	.pwmr		= 0x00A903FF,
-	.lscr1		= 0x00120300,
-	.dmacr		= 0x80040060,
+	.mode		= &cmo_display,
+	.mode_cnt	= 1,
 };
 
-
 static struct device_d imxfb_dev = {
 	.id		= -1,
 	.name		= "imxfb",
diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
index 3ea2466..3696105 100644
--- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
+++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
@@ -186,7 +186,14 @@ static void eukrea_cpuimx27_mmu_init(void)
 #endif
 
 #ifdef CONFIG_DRIVER_VIDEO_IMX
-static struct fb_videomode cmo_display = {
+static const struct imx_fb_driver_data driver_data = {
+	.pwmr	= 0x00A903FF,
+	.lscr1	= 0x00120300,
+	.dmacr	= 0x00020010,
+	.pcr	= 0xFAD08B80,
+};
+
+static const struct fb_videomode cmo_display = {
 	.name		= "CMO-QVGA",
 	.refresh	= 60,
 	.xres		= 320,
@@ -198,18 +205,12 @@ static struct fb_videomode cmo_display = {
 	.vsync_len	= 3,
 	.upper_margin	= 15,
 	.lower_margin	= 4,
+	.priv		= &driver_data,
 };
 
-static struct imx_fb_videomode imxfb_mode = {
-	.mode		= &cmo_display,
-	.pcr		= 0xFAD08B80,
-	.bpp		= 16,};
-
 static struct imx_fb_platform_data eukrea_cpuimx27_fb_data = {
-	.mode	= &imxfb_mode,
-	.pwmr	= 0x00A903FF,
-	.lscr1	= 0x00120300,
-	.dmacr	= 0x00020010,
+	.mode	= &cmo_display,
+	.mode_cnt = 1,
 };
 
 static struct device_d imxfb_dev = {
diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c
index 6949675..a4d246f 100644
--- a/arch/arm/boards/guf-neso/board.c
+++ b/arch/arm/boards/guf-neso/board.c
@@ -91,22 +91,11 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
-static struct fb_videomode cpt_display = {
-	.name		= "CPT CLAA070LC0JCT",
-	.refresh	= 60,
-	.xres		= 800,
-	.yres		= 480,
-	.pixclock	= KHZ2PICOS(27000),
-	.hsync_len	= 1,	/* DE only sync */
-	.left_margin	= 50,
-	.right_margin	= 50,
-	.vsync_len	= 1,	/* DE only sync */
-	.upper_margin	= 10,
-	.lower_margin	= 10,
-};
-
-static struct imx_fb_videomode imxfb_mode = {
-	.mode = &cpt_display,
+static const struct imx_fb_driver_data driver_data = {
+	.pwmr	= 0x00000000,	/* doesn't matter */
+	.lscr1	= 0x00120300,	/* doesn't matter */
+	/* dynamic mode -> using the reset values (as recommended in the datasheet) */
+	.dmacr	= (0 << 31) | (4 << 16) | 96,
 	/*
 	 * - TFT style panel
 	 * - clk enabled while idle
@@ -122,7 +111,21 @@ static struct imx_fb_videomode imxfb_mode = {
 		PCR_SCLK_SEL |
 		PCR_LPPOL |
 		PCR_FLMPOL,
-	.bpp = 16,	/* TODO 32 bit does not work: The 'green' component is lacking in this mode */
+};
+
+static struct fb_videomode cpt_display = {
+	.name		= "CPT CLAA070LC0JCT",
+	.refresh	= 60,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= KHZ2PICOS(27000),
+	.hsync_len	= 1,	/* DE only sync */
+	.left_margin	= 50,
+	.right_margin	= 50,
+	.vsync_len	= 1,	/* DE only sync */
+	.upper_margin	= 10,
+	.lower_margin	= 10,
+	.priv		= &driver_data,
 };
 
 static void neso_fb_enable(int enable)
@@ -132,12 +135,10 @@ static void neso_fb_enable(int enable)
 }
 
 static struct imx_fb_platform_data neso_fb_data = {
-	.mode	= &imxfb_mode,
-	.pwmr	= 0x00000000,	/* doesn't matter */
-	.lscr1	= 0x00120300,	/* doesn't matter */
-	/* dynamic mode -> using the reset values (as recommended in the datasheet) */
-	.dmacr	= (0 << 31) | (4 << 16) | 96,
+	.mode	= &cpt_display,
+	.mode_cnt = 1,
 	.enable	= neso_fb_enable,
+	.bpp = 16,	/* TODO 32 bit does not work: The 'green' component is lacking in this mode */
 	.framebuffer_ovl = (void *)0xa7f00000,
 };
 
diff --git a/arch/arm/boards/imx21ads/imx21ads.c b/arch/arm/boards/imx21ads/imx21ads.c
index 81006de..3b654ec 100644
--- a/arch/arm/boards/imx21ads/imx21ads.c
+++ b/arch/arm/boards/imx21ads/imx21ads.c
@@ -79,7 +79,14 @@ static struct device_d cs8900_dev = {
 	// IRQ is connected to UART3_RTS
 };
 
-static struct fb_videomode sharp_display = {
+static const struct imx_fb_driver_data driver_data = {
+	.pwmr           = 0x00a903ff,
+	.lscr1          = 0x00120300,
+	.dmacr          = 0x00020008,
+        .pcr            = 0xfb108bc7,
+};
+
+static const struct fb_videomode sharp_display = {
 	.name           = "Sharp-LQ035Q7",
 	.refresh        = 60,
 	.xres           = 240,
@@ -94,23 +101,16 @@ static struct fb_videomode sharp_display = {
 	.sync           = 0,
 	.vmode          = FB_VMODE_NONINTERLACED,
 	.flag           = 0,
-};
-
-/* Sharp LQ035Q7DB02 QVGA display */
-static struct imx_fb_videomode imx_fb_modedata = {
-        .mode           = &sharp_display,
-        .pcr            = 0xfb108bc7,
-        .bpp            = 16,
+	.priv		= &driver_data,
 };
 
 static struct imx_fb_platform_data imx_fb_data = {
-	.mode           = &imx_fb_modedata,
+/* Sharp LQ035Q7DB02 QVGA display */
+	.mode           = &sharp_display,
+	.mode_cnt	= 1,
 	.cmap_greyscale = 0,
 	.cmap_inverse   = 0,
 	.cmap_static    = 0,
-	.pwmr           = 0x00a903ff,
-	.lscr1          = 0x00120300,
-	.dmacr          = 0x00020008,
 };
 
 static struct device_d imxfb_dev = {
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index 026e9c0..6a5d938 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -127,7 +127,23 @@ static struct device_d nand_dev = {
 	.platform_data	= &nand_info,
 };
 
-static struct fb_videomode sharp_display = {
+static const struct imx_fb_driver_data driver_data = {
+	/*
+	 * - HSYNC active high
+	 * - VSYNC active high
+	 * - clk notenabled while idle
+	 * - clock not inverted
+	 * - data not inverted
+	 * - data enable low active
+	 * - enable sharp mode
+	 */
+	.pwmr	= 0x00A903FF,
+	.lscr1	= 0x00120300,
+	.dmacr	= 0x00020010,
+	.pcr	= 0xF00080C0,
+};
+
+static const struct fb_videomode sharp_display = {
 	.name		= "Sharp-LQ035Q7",
 	.refresh	= 60,
 	.xres		= 240,
@@ -139,28 +155,12 @@ static struct fb_videomode sharp_display = {
 	.vsync_len	= 1,
 	.upper_margin	= 7,
 	.lower_margin	= 9,
-};
-
-static struct imx_fb_videomode imxfb_mode = {
-	.mode		= &sharp_display,
-	/*
-	 * - HSYNC active high
-	 * - VSYNC active high
-	 * - clk notenabled while idle
-	 * - clock not inverted
-	 * - data not inverted
-	 * - data enable low active
-	 * - enable sharp mode
-	 */
-	.pcr		= 0xF00080C0,
-	.bpp		= 16,
+	.priv		= &driver_data,
 };
 
 static struct imx_fb_platform_data pcm038_fb_data = {
-	.mode	= &imxfb_mode,
-	.pwmr	= 0x00A903FF,
-	.lscr1	= 0x00120300,
-	.dmacr	= 0x00020010,
+	.mode	= &sharp_display,
+	.mode_cnt = 1,
 };
 
 static struct device_d imxfb_dev = {
diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h
index c536119..dbd7c93 100644
--- a/arch/arm/mach-imx/include/mach/imxfb.h
+++ b/arch/arm/mach-imx/include/mach/imxfb.h
@@ -49,28 +49,30 @@
 #define DMACR_HM(x)	(((x) & 0xf) << 16)
 #define DMACR_TM(x)	((x) & 0xf)
 
-struct imx_fb_videomode {
-	struct fb_videomode *mode;
-	u32 pcr;
-	unsigned char	bpp;
+/**
+ * Videomode dependent, but driver specific data
+ */
+struct imx_fb_driver_data {
+	uint32_t	pwmr;	/**< refer datasheet: LPCCR register */
+	uint32_t	lscr1;	/**< refer datasheet: LSCR register */
+	uint32_t	dmacr;	/**< refer datasheet: LDCR register */
+	uint32_t	pcr;	/**< refer datasheet: LPCR register */
 };
 
 /**
  * Define relevant framebuffer information
  */
 struct imx_fb_platform_data {
-	struct imx_fb_videomode *mode;
+	const struct fb_videomode *mode;
 	unsigned mode_cnt;	/**< number of entries in 'mode' */
 
+	unsigned char	bpp;	/**< preferred colour depth for this device */
+
 	u_int		cmap_greyscale:1,
 			cmap_inverse:1,
 			cmap_static:1,
 			unused:29;
 
-	u_int		pwmr;
-	u_int		lscr1;
-	u_int		dmacr;
-
 	/** force a memory area to be used, else NULL for dynamic allocation */
 	void		*framebuffer;
 	/** force a memory area to be used, else NULL for dynamic allocation */
diff --git a/drivers/video/imx.c b/drivers/video/imx.c
index 07438e5..d935149 100644
--- a/drivers/video/imx.c
+++ b/drivers/video/imx.c
@@ -300,6 +300,7 @@ static int imxfb_initialize_mode(struct fb_info *info, const struct fb_videomode
 	unsigned long lcd_clk;
 	unsigned long long tmp;
 	struct imxfb_info *fbi = fb_info_to_imxfb_info(info);
+	const struct imx_fb_driver_data *drv_data = mode->priv;
 	u32 pcr;
 	unsigned size;
 
@@ -324,6 +325,11 @@ static int imxfb_initialize_mode(struct fb_info *info, const struct fb_videomode
 	if (info->fb_dev->map_base == 0U /* FIXME should be 'NULL'*/)
 		info->fb_dev->map_base = (unsigned long)xzalloc(info->fb_dev->size);
 
+	fbi->pcr = drv_data->pcr;
+	fbi->pwmr = drv_data->pwmr;
+	fbi->lscr1 = drv_data->lscr1;
+	fbi->dmacr = drv_data->dmacr;
+
 	/* physical screen start address	    */
 	writel(VPW_VPW(mode->xres * info->bits_per_pixel / 8 / 4),
 		fbi->regs + LCDC_VPW);
@@ -535,7 +541,7 @@ static int imxfb_register_overlay(struct imxfb_info *fbi, struct device_d *hw_de
 	overlay->fb_setcolreg = imxfb_overlay_setcolreg;
 
 	/* add runtime video info */
-	overlay->mode = pdata->mode->mode;
+	overlay->mode = pdata->mode;
 	overlay->mode_cnt = 1;	/* no choice */
 
 	overlay_dev = register_framebuffer(overlay, pdata->framebuffer_ovl, 0);
@@ -585,17 +591,12 @@ static int imxfb_probe(struct device_d *dev)
 	fbi->fb_host.fb_setcolreg = imxfb_setcolreg;
 
 	fbi->regs = (void*)dev->map_base;
-	fbi->pcr = pdata->mode->pcr;
-	fbi->pwmr = pdata->pwmr;
-	fbi->lscr1 = pdata->lscr1;
-	fbi->dmacr = pdata->dmacr;
 	fbi->enable = pdata->enable;
 
 	/* add runtime video info */
-	fbi->fb_host.mode = pdata->mode->mode;
-	/* to be backward compatible */
-	fbi->fb_host.mode_cnt = pdata->mode_cnt == 0 ? 1 : pdata->mode_cnt;
-	fbi->fb_host.bits_per_pixel = 16;	/* RGB565, the default */
+	fbi->fb_host.mode = pdata->mode;
+	fbi->fb_host.mode_cnt = pdata->mode_cnt;
+	fbi->fb_host.bits_per_pixel = pdata->bpp;
 
 	fb_dev = register_framebuffer(&fbi->fb_host, pdata->framebuffer, 0);
 	if (dev == NULL) {
diff --git a/include/fb.h b/include/fb.h
index 223b301..8ba4e5a 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -69,6 +69,8 @@ struct fb_videomode {
 	unsigned sync;		/**< sync information, refer FB_SYNC_* macros */
 	unsigned vmode;		/**< video mode information, refer FB_VMODE_* macros */
 	unsigned flag;
+
+	const void *priv;	/**< video driver related information */
 };
 
 /* Interpretation of offset for color fields: All offsets are from the right,
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:45 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:45 +0200
Subject: [PATCH 09/12] STM378x: Add video driver for this platform
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-10-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/include/mach/fb.h |   38 +++
 drivers/video/Kconfig               |    7 +
 drivers/video/Makefile              |    1 +
 drivers/video/stm.c                 |  561 +++++++++++++++++++++++++++++++++++
 4 files changed, 607 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-stm/include/mach/fb.h
 create mode 100644 drivers/video/stm.c

diff --git a/arch/arm/mach-stm/include/mach/fb.h b/arch/arm/mach-stm/include/mach/fb.h
new file mode 100644
index 0000000..6596ef2
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/fb.h
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_FB_H
+# define __MACH_FB_H
+
+#include <fb.h>
+
+#define STMLCDIF_8BIT 1	/** pixel data bus to the display is of 8 bit width */
+#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
+#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
+#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
+
+struct imx_fb_videomode {
+	struct fb_videomode *mode_list;
+	unsigned mode_count;
+	void *framebuffer;	/**< force fixed framebuffer address if != NULL */
+	unsigned size;		/**< force fixed size if != NULL */
+
+	unsigned dotclk_delay;	/**< refer manual HW_LCDIF_VDCTRL4 register */
+	unsigned ld_intf_width;	/**< refer STMLCDIF_* macros */
+};
+
+#endif /* __MACH_FB_H */
+
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5a5edd2..6cda478 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -45,4 +45,11 @@ config S3C_VIDEO
 	help
 	  Add support for the S3C244x LCD controller.
 
+config DRIVER_VIDEO_STM
+	bool "i.MX23/28 framebuffer driver"
+	depends on ARCH_STM
+	help
+	  Say 'Y' here to enable framebuffer and spash screen support for
+	  i.MX23 and i.MX28 based systems.
+
 endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 4287fc8..0ddb81e 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_VIDEO) += fb.o
 
+obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o
 obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
 obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
 obj-$(CONFIG_S3C_VIDEO) += s3c.o
diff --git a/drivers/video/stm.c b/drivers/video/stm.c
new file mode 100644
index 0000000..5f5d60a
--- /dev/null
+++ b/drivers/video/stm.c
@@ -0,0 +1,561 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix
+ *
+ * This code is based on:
+ * Author: Vitaly Wool <vital at embeddedalley.com>
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/**
+ * @file
+ * @brief LCDIF driver for i.MX23 and i.MX28 (i.MX23 untested yet)
+ *
+ * The LCDIF support four modes of operation
+ * - MPU interface (to drive smart displays) -> not supported yet
+ * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
+ * - Dotclock interface (to drive LC displays with RGB data and sync signals)
+ * - DVI (to drive ITU-R BT656)  -> not supported yet
+ *
+ * This driver depends on a correct setup of the pins used for this purpose
+ * (platform specific).
+ *
+ * For the developer: Don't forget to set the data bus width to the display
+ * in the imx_fb_videomode structure. You will else end up with ugly colours.
+ * If you fight against jitter you can vary the clock delay. This is a feature
+ * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
+ * the required value in the imx_fb_videomode structure.
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <xfuncs.h>
+#include <asm/io.h>
+#include <mach/clock.h>
+#include <mach/fb.h>
+
+#define HW_LCDIF_CTRL 0x00
+# define CTRL_SFTRST (1 << 31)
+# define CTRL_CLKGATE (1 << 30)
+# define CTRL_BYPASS_COUNT (1 << 19)
+# define CTRL_VSYNC_MODE (1 << 18)
+# define CTRL_DOTCLK_MODE (1 << 17)
+# define CTRL_DATA_SELECT (1 << 16)
+# define SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
+# define SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
+# define GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
+# define CTRL_MASTER (1 << 5)
+# define CTRL_DF16 (1 << 3)
+# define CTRL_DF18 (1 << 2)
+# define CTRL_DF24 (1 << 1)
+# define CTRL_RUN (1 << 0)
+
+#define HW_LCDIF_CTRL1 0x10
+# define SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
+# define GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
+
+#define HW_LCDIF_CTRL2 0x20
+
+#define HW_LCDIF_TRANSFER_COUNT 0x30
+# define SET_VCOUNT(x) (((x) & 0xffff) << 16)
+# define SET_HCOUNT(x) ((x) & 0xffff)
+
+#define HW_LCDIF_CUR_BUF 0x40
+
+#define HW_LCDIF_NEXT_BUF 0x50
+
+#define HW_LCDIF_TIMING 0x60
+# define SET_CMD_HOLD(x) (((x) & 0xff) << 24)
+# define SET_CMD_SETUP(x) (((x) & 0xff) << 16)
+# define SET_DATA_HOLD(x) (((x) & 0xff) << 8)
+# define SET_DATA_SETUP(x) ((x) & 0xff))
+
+#define HW_LCDIF_VDCTRL0 0x70
+# define VDCTRL0_ENABLE_PRESENT (1 << 28)
+# define VDCTRL0_VSYNC_POL (1 << 27) /* 0 = low active, 1 = high active */
+# define VDCTRL0_HSYNC_POL (1 << 26) /* 0 = low active, 1 = high active */
+# define VDCTRL0_DOTCLK_POL (1 << 25) /* 0 = output at falling edge, capturing at rising edge */
+# define VDCTRL0_ENABLE_POL (1 << 24) /* 0 = low active, 1 = high active */
+# define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
+# define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
+# define VDCTRL0_HALF_LINE (1 << 19)
+# define VDCTRL0_HALF_LINE_MODE (1 << 18)
+# define SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_VDCTRL1 0x80
+
+#define HW_LCDIF_VDCTRL2 0x90
+# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0x3fff) << 18)
+# define SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_VDCTRL3 0xa0
+# define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
+# define VDCTRL3_VSYNC_ONLY (1 << 28)
+# define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
+# define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
+
+#define HW_LCDIF_VDCTRL4 0xb0
+# define SET_DOTCLK_DLY(x) (((x) & 0x7) << 29)
+# define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
+# define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_DVICTRL0 0xc0
+#define HW_LCDIF_DVICTRL1 0xd0
+#define HW_LCDIF_DVICTRL2 0xe0
+#define HW_LCDIF_DVICTRL3 0xf0
+#define HW_LCDIF_DVICTRL4 0x100
+#define HW_LCDIF_DATA 0x180
+
+#define HW_LCDIF_DEBUG0 0x1d0
+# define DEBUG_HSYNC (1 < 26)
+# define DEBUG_VSYNC (1 < 25)
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+struct imxfb_host {
+	struct fb_host fb_data;
+	struct device_d *hw_dev;
+	void __iomem *base;
+};
+
+#define fb_info_to_imxfb_host(x) ((struct imxfb_host*)((x)->host))
+
+/* the RGB565 true colour mode */
+static const struct fb_bitfield def_rgb565[] = {
+	[RED] = {
+		.offset = 11,
+		.length = 5,
+	},
+	[GREEN] = {
+		.offset = 5,
+		.length = 6,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 5,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/* the RGB666 true colour mode */
+static const struct fb_bitfield def_rgb666[] = {
+	[RED] = {
+		.offset = 16,
+		.length = 6,
+	},
+	[GREEN] = {
+		.offset = 8,
+		.length = 6,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 6,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/* the RGB888 true colour mode */
+static const struct fb_bitfield def_rgb888[] = {
+	[RED] = {
+		.offset = 16,
+		.length = 8,
+	},
+	[GREEN] = {
+		.offset = 8,
+		.length = 8,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 8,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/**
+ * Just calculate the amount of required bytes per line
+ * @param ppl Used pixel per line
+ * @param bpp Bits per pixel
+ * @return Byte count
+ */
+static inline unsigned calc_line_length(unsigned ppl, unsigned bpp)
+{
+	return (ppl * bpp) >> 3;
+}
+
+/**
+ * Prepare the video hardware for a specified video mode
+ * @param fb_info Framebuffer information
+ * @param mode The video mode description to initialize
+ * @return 0 on success
+ *
+ * Dotclock mode:
+ * One line of pixels or one frame in the i.MX28 is defined to:
+ * @verbatim
+ * |<---------------------- one line period -------------------------------->|
+ * |<- HSync length ->|
+ * |<----- Start of line --->|
+ *                           |<-------- active line data ------>|
+ *
+ * |<------------------------ frame period --------------------------------->|
+ * |<- VSync length ->|
+ * |<--- Start of 1. line -->|
+ *                           |<---------- active lines -------->|
+ * @endverbatim
+ * Based on the values from struct fb_videomode:
+ * - "one line period" = left_margin + xres + right_margin + hsync_len
+ * - "HSync length" = hsync_len
+ * - "Start of line" = hsync_len + left_margin
+ * - "active line data" = xres
+ */
+static int stmfb_initialize_mode(struct fb_info *fb_info,
+		const struct fb_videomode *mode)
+{
+	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
+	struct imx_fb_videomode *pdata = fbh->hw_dev->platform_data;
+	uint32_t reg;
+	unsigned size;
+
+	pr_debug("%s called\n", __func__);
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = calc_line_length(mode->xres, fb_info->bits_per_pixel) * mode->yres;
+	if (fb_info->fb_dev->size != 0) {
+		if (size > fb_info->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, fb_info->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		fb_info->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (fb_info->fb_dev->map_base == 0U)
+		fb_info->fb_dev->map_base = (resource_size_t)xzalloc(fb_info->fb_dev->size);
+
+	/* TODO HCLK must be active at this point of time! */
+
+	size = imx_set_lcdifclk(PICOS2KHZ(mode->pixclock));
+	if (size == 0) {
+		pr_debug("Unable to set a valid pixel clock\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * bring the controller out of reset and configure it into DOTCLOCK mode
+	 */
+	reg = CTRL_BYPASS_COUNT |	/* always in DOTCLOCK mode */
+		CTRL_DOTCLK_MODE;
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+
+	/* master mode only */
+	reg |= CTRL_MASTER;
+
+	/*
+	 * Configure videomode and interface mode
+	 */
+	reg |= SET_BUS_WIDTH(pdata->ld_intf_width);
+	switch (fb_info->bits_per_pixel) {
+	case 8:
+		reg |= SET_WORD_LENGTH(1);
+		/* TODO refer manual page 2046 */
+		pr_warning("8 bpp mode not supported yet\n");
+		break;
+	case 16:
+		pr_debug("Setting up an RGB565 mode\n");
+		reg |= SET_WORD_LENGTH(0) | CTRL_DF16; /* we assume RGB565 */
+		writel(SET_BYTE_PACKAGING(0xf), fbh->base + HW_LCDIF_CTRL1);
+		fb_info->red = def_rgb565[RED];
+		fb_info->green = def_rgb565[GREEN];
+		fb_info->blue = def_rgb565[BLUE];
+		fb_info->transp =  def_rgb565[TRANSP];
+		break;
+	case 24:
+	case 32:
+		pr_debug("Setting up an RGB888/666 mode\n");
+		reg |= SET_WORD_LENGTH(3);
+		switch (pdata->ld_intf_width) {
+		case STMLCDIF_8BIT:
+			pr_debug("Unsupported LCD bus width mapping\n");
+			break;
+		case STMLCDIF_16BIT:
+		case STMLCDIF_18BIT:
+			/* 24 bit to 18 bit mapping */
+			reg |= CTRL_DF24; /* ignore the upper 2 bits in each colour component */
+			fb_info->red = def_rgb666[RED];
+			fb_info->green = def_rgb666[GREEN];
+			fb_info->blue = def_rgb666[BLUE];
+			fb_info->transp =  def_rgb666[TRANSP];
+			break;
+		case STMLCDIF_24BIT:
+			/* real 24 bit */
+			fb_info->red = def_rgb888[RED];
+			fb_info->green = def_rgb888[GREEN];
+			fb_info->blue = def_rgb888[BLUE];
+			fb_info->transp =  def_rgb888[TRANSP];
+			break;
+		}
+		/* do not use packed pixels = one pixel per word instead */
+		writel(SET_BYTE_PACKAGING(0x7), fbh->base + HW_LCDIF_CTRL1);
+		break;
+	default:
+		pr_debug("Unhandled colour depth of %u\n", fb_info->bits_per_pixel);
+		return -EINVAL;
+	}
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+	pr_debug("Setting up CTRL to %08X\n", reg);
+
+	writel(SET_VCOUNT(mode->yres) |
+		SET_HCOUNT(mode->xres), fbh->base + HW_LCDIF_TRANSFER_COUNT);
+
+	reg = VDCTRL0_ENABLE_PRESENT |	/* always in DOTCLOCK mode */
+		VDCTRL0_VSYNC_PERIOD_UNIT |
+		VDCTRL0_VSYNC_PULSE_WIDTH_UNIT;
+	if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
+		reg |= VDCTRL0_HSYNC_POL;
+	if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
+		reg |= VDCTRL0_VSYNC_POL;
+	if (mode->sync & FB_SYNC_DE_HIGH_ACT)
+		reg |= VDCTRL0_ENABLE_POL;
+	if (mode->sync & FB_SYNC_CLK_INVERT)
+		reg |= VDCTRL0_DOTCLK_POL;
+
+	reg |= SET_VSYNC_PULSE_WIDTH(mode->vsync_len);
+	writel(reg, fbh->base + HW_LCDIF_VDCTRL0);
+	pr_debug("Setting up VDCTRL0 to %08X\n", reg);
+
+	/* frame length in lines */
+	writel(mode->upper_margin + mode->vsync_len + mode->lower_margin + mode->yres,
+		fbh->base + HW_LCDIF_VDCTRL1);
+
+	/* line length in units of clocks or pixels */
+	writel(SET_HSYNC_PULSE_WIDTH(mode->hsync_len) |
+		SET_HSYNC_PERIOD(mode->left_margin + mode->hsync_len + mode->right_margin + mode->xres),
+		fbh->base + HW_LCDIF_VDCTRL2);
+
+	writel(SET_HOR_WAIT_CNT(mode->left_margin + mode->hsync_len) |
+		SET_VERT_WAIT_CNT(mode->upper_margin + mode->vsync_len),
+		fbh->base + HW_LCDIF_VDCTRL3);
+
+	writel(SET_DOTCLK_DLY(pdata->dotclk_delay) |
+		SET_DOTCLK_H_VALID_DATA_CNT(mode->xres),
+		fbh->base + HW_LCDIF_VDCTRL4);
+
+	writel(fb_info->fb_dev->map_base, fbh->base + HW_LCDIF_CUR_BUF);
+	/* always show one framebuffer only */
+	writel(fb_info->fb_dev->map_base, fbh->base + HW_LCDIF_NEXT_BUF);
+
+	return 0;
+}
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void stmfb_enable_controller(struct fb_info *fb_info)
+{
+	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
+	uint32_t reg, last_reg;
+	unsigned loop, edges;
+
+	pr_debug("%s called\n", __func__);
+
+	/* if it was disabled, re-enable the mode again */
+	reg = readl(fbh->base + HW_LCDIF_CTRL);
+	reg |= CTRL_DOTCLK_MODE;
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+
+	/* enable the SYNC signals first, then the DMA enginge */
+	reg = readl(fbh->base + HW_LCDIF_VDCTRL4);
+	reg |= VDCTRL4_SYNC_SIGNALS_ON;
+	writel(reg, fbh->base + HW_LCDIF_VDCTRL4);
+
+	/*
+	 * Give the attached LC display or monitor a chance to sync into
+	 * our signals.
+	 * Wait for at least 2 VSYNCs = four VSYNC edges
+	 */
+	edges = 4;
+
+	while (edges != 0) {
+		loop = 800;
+		last_reg = readl(fbh->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
+		do {
+			reg = readl(fbh->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
+			if (reg != last_reg);
+				break;
+			last_reg = reg;
+			loop--;
+		} while (loop != 0);
+		edges--;
+	}
+
+	reg = readl(fbh->base + HW_LCDIF_CTRL);
+	reg |= CTRL_RUN;
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+}
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void stmfb_disable_controller(struct fb_info *fb_info)
+{
+	struct imxfb_host *fbh = fb_info_to_imxfb_host(fb_info);
+	unsigned loop;
+	uint32_t reg;
+
+	pr_debug("%s called\n", __func__);
+	/*
+	 * Even if we disable the controller here, it will still continue
+	 * until its FIFOs are running out of data
+	 */
+	reg = readl(fbh->base + HW_LCDIF_CTRL);
+	reg &= ~CTRL_DOTCLK_MODE;
+	writel(reg, fbh->base + HW_LCDIF_CTRL);
+
+	loop = 1000;
+	while (loop) {
+		reg = readl(fbh->base + HW_LCDIF_CTRL);
+		if (!(reg & CTRL_RUN))
+			break;
+		loop--;
+	}
+
+	reg = readl(fbh->base + HW_LCDIF_VDCTRL4);
+	reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
+	writel(reg, fbh->base + HW_LCDIF_VDCTRL4);
+}
+
+/**
+ * Print some information about the current hardware state
+ * @param hw_dev STM video device
+ */
+static void stmfb_info(struct device_d *hw_dev)
+{
+	uint32_t reg;
+
+	printf(" STM video hardware:\n");
+	printf("  Pixel clock: %u kHz\n", imx_get_lcdifclk());
+
+	reg = readl(hw_dev->map_base + HW_LCDIF_CTRL);
+	switch (GET_WORD_LENGTH(reg)) {
+	case 0:
+		printf("  16 bpp mode with %s colour scheme\n",
+			reg & CTRL_DF16 ? "RGB565" : "ARGB1555");
+		switch (GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1))) {
+		case 0xf:
+			printf("  One pixel per halfword\n");
+			break;
+		case 0x3:
+			printf("  One pixel per word\n");
+			break;
+		default:
+			printf("Unknown pixel packaging: %u\n",
+				GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1)));
+		}
+		break;
+	case 1:
+	case 2:
+		printf("Unsupported bpp mode yet!\n");
+		break;
+	case 3:
+		printf("  24 bpp mode with %s colour scheme\n",
+			reg & CTRL_DF24 ? "RGB888" : "RGB666");
+		switch (GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1))) {
+		case 0x7:
+			printf("  One pixel per word (xRGB xRGB xRGB ...)\n");
+			break;
+		case 0xf:
+			printf("Packed pixel format per word (RGBR GBRG BRGB ...)\n");
+			break;
+		default:
+			printf("Unknown pixel packaging: %u\n",
+				GET_BYTE_PACKAGING(readl(hw_dev->map_base + HW_LCDIF_CTRL1)));
+		}
+		break;
+	}
+}
+
+/*
+ * There is only one video hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct imxfb_host host_data = {
+	.fb_data.fb_mode = stmfb_initialize_mode,
+	.fb_data.fb_enable = stmfb_enable_controller,
+	.fb_data.fb_disable = stmfb_disable_controller,
+	.fb_data.bits_per_pixel = 16,
+};
+
+static int stmfb_probe(struct device_d *hw_dev)
+{
+	struct imx_fb_videomode *pdata = hw_dev->platform_data;
+	struct device_d *fb_dev;
+
+	if (pdata == NULL) {
+		pr_debug("STMFB: No platformdata. Giving up\n");
+		return -ENODEV;
+	}
+
+	/* add runtime hardware info */
+	host_data.hw_dev = hw_dev;
+	host_data.base = (void*)hw_dev->map_base;
+
+	/* add runtime video info */
+	host_data.fb_data.mode = pdata->mode_list;
+	host_data.fb_data.mode_cnt = pdata->mode_count;
+
+	fb_dev = register_framebuffer(&host_data.fb_data, pdata->framebuffer,
+					pdata->size);
+	if (fb_dev == NULL) {
+		pr_err("STMFB: Failed to register framebuffer\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct driver_d stmfb_driver = {
+	.name	= "stmfb",
+	.probe	= stmfb_probe,
+	.info	= stmfb_info,
+};
+
+static int stmfb_init(void)
+{
+	return register_driver(&stmfb_driver);
+}
+
+device_initcall(stmfb_init);
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:47 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:47 +0200
Subject: [PATCH 11/12] Add doxygen documentation to the framebfuffer code
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-12-git-send-email-jbe@pengutronix.de>

Add some (hopefully) helpful documentation to the source code.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 Documentation/developers_manual.dox |    1 +
 Documentation/users_manual.dox      |    1 +
 drivers/video/fb.c                  |  234 +++++++++++++++++++++++++++++++++++
 include/fb.h                        |   98 ++++++++++-----
 4 files changed, 301 insertions(+), 33 deletions(-)

diff --git a/Documentation/developers_manual.dox b/Documentation/developers_manual.dox
index 2f7d360..69a0872 100644
--- a/Documentation/developers_manual.dox
+++ b/Documentation/developers_manual.dox
@@ -20,5 +20,6 @@ This part of the documentation is intended for developers of @a barebox.
 @li @subpage barebox_simul
 @li @subpage io_access_functions
 @li @subpage mcfv4e_MCDlib
+ at li @subpage fb_for_developers
 
 */
diff --git a/Documentation/users_manual.dox b/Documentation/users_manual.dox
index 0a0a13e..f434fc4 100644
--- a/Documentation/users_manual.dox
+++ b/Documentation/users_manual.dox
@@ -11,5 +11,6 @@ work easier.
 @li @subpage command_reference
 @li @subpage x86_bootloader
 @li @subpage net_netconsole
+ at li @subpage fb_for_users
 
 */
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index cb66744..fb95316 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -32,6 +32,13 @@ static int fb_ioctl(struct cdev* cdev, int req, void *data)
 }
 
 #ifdef CONFIG_VIDEO_DELAY_INIT
+/**
+ * Check if the framebuffer is already initialized
+ * @param fb_dev The framebuffer device to check
+ * @return 0 if the framebuffer is still uninitialized, -EPERM if already initialized
+ *
+ * @note Currently video mode initializing is a "one time only" task.
+ */
 static int fb_check_if_already_initialized(struct device_d *fb_dev)
 {
 	struct cdev *cdev = fb_dev->priv;
@@ -45,6 +52,9 @@ static int fb_check_if_already_initialized(struct device_d *fb_dev)
 	return 0;
 }
 
+/**
+ * Change colour depth via device parameter
+ */
 static int fb_cdepth_set(struct device_d *fb_dev, struct param_d *param, const char *val)
 {
 	struct cdev *cdev = fb_dev->priv;
@@ -66,6 +76,9 @@ static int fb_cdepth_set(struct device_d *fb_dev, struct param_d *param, const c
 }
 #endif
 
+/**
+ * Enable/disable video output via device parameter
+ */
 static int fb_enable_set(struct device_d *fb_dev, struct param_d *param, const char *val)
 {
 	struct cdev *cdev = fb_dev->priv;
@@ -95,6 +108,10 @@ static int fb_enable_set(struct device_d *fb_dev, struct param_d *param, const c
 	return dev_param_set_generic(fb_dev, param, new);
 }
 
+/**
+ * Output the list of supported video modes in this framebuffer
+ * @param host Platformdata of the hardware video device
+ */
 static void fb_list_modes(struct fb_host *host)
 {
 	unsigned u;
@@ -107,6 +124,14 @@ static void fb_list_modes(struct fb_host *host)
 		printf("  '%s'\n", host->mode[u].name);
 }
 
+/**
+ * Call the video hardware driver to initialize the given video mode
+ * @param fb_dev Framebuffer device
+ * @param mode Mode description to initialize
+ * @return 0 on success
+ *
+ * @note This call does not imply enabling the video output device!
+ */
 static int fb_activate_mode(struct device_d *fb_dev, const struct fb_videomode *mode)
 {
 	struct cdev *cdev = fb_dev->priv;
@@ -131,6 +156,15 @@ static int fb_activate_mode(struct device_d *fb_dev, const struct fb_videomode *
 }
 
 #ifdef CONFIG_VIDEO_DELAY_INIT
+/**
+ * Setup the requested video mode via device parameter
+ * @param dev Device instance
+ * @param param FIXME
+ * @param name Video mode name to activate
+ * @return 0 on success
+ *
+ * @note One time setup only, changing video modes is currently not supported.
+ */
 static int fb_mode_set(struct device_d *fb_dev, struct param_d *param, const char *name)
 {
 	struct fb_host *host = fb_dev->platform_data;
@@ -207,6 +241,14 @@ static void fb_info(struct device_d *fb_dev)
 	fb_list_modes(fb_dev->platform_data);
 }
 
+/**
+ * Add parameter to the framebuffer device on demand
+ * @param dev Device instance
+ * @return 0 on success
+ *
+ * Some parameter are only available (or usefull) if the intialization or
+ * enabling the video hardware is delayed.
+ */
 static int add_fb_parameter(struct device_d *fb_dev)
 {
 #ifdef CONFIG_VIDEO_DELAY_INIT
@@ -289,6 +331,13 @@ static int framebuffer_init(void)
 
 device_initcall(framebuffer_init);
 
+/**
+ * Create a new framebuffer device (for convenience)
+ * @param pinfo Video device's platform data for this framebuffer device
+ * @param base force framebuffer's base address to given value, or NULL for dynamically allocation
+ * @param sze force framebuffer's size to this value, or 0 for dynamically allocation
+ * @return Pointer to the newly created device or NULL on failure
+ */
 struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned size)
 {
 	struct device_d *fb_dev;
@@ -312,3 +361,188 @@ struct device_d *register_framebuffer(struct fb_host *host, void *base, unsigned
 
 	return fb_dev;
 }
+
+/**
+ at page fb_for_users Framebuffer handling for users
+
+ at section regular_fb Regular framebuffer setup
+
+After registering the video device the driver initializes the video hardware,
+allocates framebuffer memory, clears this memory (set all to zero) but does not
+enable the video output hardware. This will keep the visible display dark/off
+Any shell script can now paint a splash screen image into the framebuffer memory
+(refer the 'bmp' command) and after it's done it can enable the video output via
+setting a framebuffer's parameter. This feature ensures a flicker free visual
+startup of the system.
+
+To enable the video output after painting a splash screen just run a
+ at verbatim
+barebox:/ framebuffer0.enable=1
+ at endverbatim
+in your shell code.
+
+ at section delayed_fb Dynamic framebuffer setup
+
+If the platform supports more than one video output device, its possible to select
+one of the supported ones at runtime. Say 'y' to the "Delayed initialization" menu
+entry to activate this feature. This will add the parameter 'mode' to the framebuffer
+device and will delay the initialization of the video hardware until the video
+output device gets specified. But keep in mind that there will be also no
+framebuffer memory until the output video hardware and its videomode get
+specified. This is important to know, of you want to paint some nice splash
+screen.
+
+Running the @b devinfo command on this framebuffer0 device will output:
+ at verbatim
+barebox:/ devinfo framebuffer0
+base  : 0x00000000
+size  : 0x00000000
+driver: framebuffer
+
+ Video/Mode info:
+  Video output not enabled
+ Current video mode:
+  No video mode selected yet
+ Supported video mode(s):
+  'QVGA'
+  'VGA'
+Parameters:
+          cdepth = 16
+            mode = <NULL>
+          enable = <NULL>
+ at endverbatim
+
+ at note As long @b devinfo reports a @b base or @b size of zero there is
+ at b no framebuffer memory yet!
+
+This framebuffer device is not initialized yet. As shown in the list, it
+supports two video modes: QVGA and VGA.
+
+So, the user can first specifiy the video output device with (for example)
+ at verbatim
+barebox:/ framebuffer0.mode="QVGA"
+ at endverbatim
+
+After this the @b devinfo command's output changes to:
+ at verbatim
+barebox:/ devinfo framebuffer0
+base  : 0x31fc0000
+size  : 0x00040000
+driver: framebuffer
+
+ Video/Mode info:
+  Video output not enabled
+ Current video mode:
+  Name: QVGA
+  Refresh rate: 60 Hz
+  Horizontal active pixel: 320
+  Vertical active lines: 240
+  Pixel clock: 6500 kHz
+  Left/Right margin (pixel): 20/20
+  Upper/Lower margin (lines): 10/10
+  HSYNC length in pixel: 10, polarity: high
+  VSYNC length in lines: 5, polarity: high
+  Colour depth: 16 bpp
+ Supported video mode(s):
+  'QVGA'
+  'VGA'
+Parameters:
+          cdepth = 16
+            mode = QVGA
+          enable = <NULL>
+ at endverbatim
+As one can see, the framebuffer has a @b base, a @b size and a video mode
+configuration now.
+ at note Take care if setting a video mode fails. In this case @b base and @b size
+will kept at zero!
+
+With this setting its possible to paint some kind of image into the framebuffer
+memory and enabling the video output as the final step at runtime
+ at verbatim
+barebox:/ framebuffer0.enable=1
+ at endverbatim
+The video output is fully enabled now:
+ at verbatim
+barebox:/ devinfo framebuffer0
+base  : 0x31fc0000
+size  : 0x00040000
+driver: framebuffer
+
+ Video/Mode info:
+  Video output enabled
+ Current video mode:
+  Name: QVGA
+  Refresh rate: 60 Hz
+  Horizontal active pixel: 320
+  Vertical active lines: 240
+  Pixel clock: 6500 kHz
+  Left/Right margin (pixel): 20/20
+  Upper/Lower margin (lines): 10/10
+  HSYNC length in pixel: 10, polarity: high
+  VSYNC length in lines: 5, polarity: high
+  Colour depth: 16 bpp
+ Supported video mode(s):
+  'QVGA'
+  'VGA'
+Parameters:
+          cdepth = 16
+            mode = QVGA
+          enable = 1
+ at endverbatim
+
+ at section other_fb_params Other framebuffer parameter
+ at verbatim
+framebuffer0.cdepth=[1 | 4 | 8 | 16 | 24 | 32]
+ at endverbatim
+
+Only available if "Delayed initialization" is selected. Colour depth to be used with
+the framebuffer. Its unit is "bit per pixel" and the default value is 16 bits per
+pixel (means "RGB565" format). This value can only be changed prior specifying the
+video mode.
+
+ at note The possible values from the list above are hardware dependend.
+
+ at note The default colour depth value may also depend on the hardware
+*/
+
+/**
+ at page fb_for_developers Framebuffer handling for developers
+
+ at section fb_platform_dev For the platform developer
+
+When filling the platform specific video output device description you can still
+provide only one entry and you should setup the 'mode_cnt' entry with '0':
+Initialization of the video hardware will happen in accordance to the Kconfig
+menu settings.
+
+If you provide more than one video output device description use an array of
+this type. In this case the 'mode_cnt' entry must contain the count of existing
+array entries (> 1). Give each video output device description entry an unique
+name, because a user will select the required output device by this name
+at runtime.
+
+ at section fb_driver_dev For the video hardware driver developer:
+
+Don't initialize a special video mode in your probe function (e.g. don't
+allocate any framebuffer memory and so on). The framework will call back your
+exported fb_mode() function to do so (immediately or delayed).
+
+Don't enable video output in your probe or exported fb_mode() function. Also
+do not switch on any LCD or backlight if any. The framework will call your
+exported fb_enable() function to do so.
+
+If your hardware cannot handle the default 16 bit colour depth, change the
+'bits_per_pixel' field prior registering your framebuffer.
+
+When your exported fb_mode() function is called, calculate the amount of memory
+you need for the requested video mode and colour depth, save this value to
+framebuffer's info struct in field 'fb_dev->size' and allocate the memory with
+this size for the framebuffer. Store the basepointer to this area into
+framebuffer's info struct in field 'fb_dev->map_base'.
+
+ at note To support flickerless splash screen into the Linux kernel, your driver
+should support a fixed framebuffer memory. Fixed in location and size. The platform
+should hold the Linux kernel to not touch this memory in any way. Instead the
+kernel based video hardware driver should inherit the fixed settings.
+
+*/
diff --git a/include/fb.h b/include/fb.h
index b42532e..223b301 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -18,19 +18,27 @@
 					/* vtotal = 121d/242n/484i => NTSC */
 #define FB_SYNC_ON_GREEN	32	/* sync on green */
 /* LC display related settings */
+/** LC display uses active high data enable signal */
 #define FB_SYNC_DE_HIGH_ACT	(1 << 6)
+/** LC display will latch its data at clock's rising edge */
 #define FB_SYNC_CLK_INVERT	(1 << 7)
+/** output RGB data inverted */
 #define FB_SYNC_DATA_INVERT	(1 << 8)
+/** Stop clock if no data is sent (required for passive displays) */
 #define FB_SYNC_CLK_IDLE_EN	(1 << 9)
+/** swap RGB to BGR */
 #define FB_SYNC_SWAP_RGB	(1 << 10)
+/** FIXME */
 #define FB_SYNC_CLK_SEL_EN	(1 << 11)
+/** enable special signals for SHARP displays (_very_ hardware specific) */
 #define FB_SYNC_SHARP_MODE	(1 << 31)
 
-#define FB_VMODE_NONINTERLACED  0	/* non interlaced */
-#define FB_VMODE_INTERLACED	1	/* interlaced	*/
+#define FB_VMODE_NONINTERLACED  0	/** non interlaced */
+#define FB_VMODE_INTERLACED	1	/** interlaced	*/
 #define FB_VMODE_DOUBLE		2	/* double scan */
-#define FB_VMODE_ODD_FLD_FIRST	4	/* interlaced: top line first */
+#define FB_VMODE_ODD_FLD_FIRST	4	/** interlaced: top line first */
 /* LC display related settings */
+/** output two screen parts at once (required for passive displays) */
 #define FB_VMODE_DUAL_SCAN	8
 #define FB_VMODE_MASK		255
 
@@ -42,19 +50,24 @@
 #define KHZ2PICOS(a) (1000000000UL/(a))
 
 struct fb_videomode {
-	const char *name;	/* optional */
-	unsigned refresh;		/* optional */
-	unsigned xres;
-	unsigned yres;
-	unsigned pixclock;
-	unsigned left_margin;
-	unsigned right_margin;
-	unsigned upper_margin;
-	unsigned lower_margin;
-	unsigned hsync_len;
-	unsigned vsync_len;
-	unsigned sync;
-	unsigned vmode;
+	const char *name;	/**< always required and must be unique */
+	unsigned refresh;	/**< frame refresh rate in [Hz] (optional) */
+	unsigned xres;		/**< visible horizontal pixel */
+	unsigned yres;		/**< visible vertical pixel */
+	unsigned pixclock;	/**< pixel clock period in [ps]. Refer
+				     PICOS2KHZ/KHZ2PICOS macros */
+	unsigned left_margin;	/**< distance in pixels between ending active HSYNC
+				     and starting visible line content */
+	unsigned right_margin;	/**< distance in pixels between ending visible line
+				     content and starting active HSYNC */
+	unsigned upper_margin;	/**< distance in lines between ending active VSYNC
+				     and the first line with visible content */
+	unsigned lower_margin;	/**< distance in lines between last line with
+				     visible content and starting active VSYNC */
+	unsigned hsync_len;	/**< HSYNC's active length in pixels */
+	unsigned vsync_len;	/**< VSYNC's active lenght in lines */
+	unsigned sync;		/**< sync information, refer FB_SYNC_* macros */
+	unsigned vmode;		/**< video mode information, refer FB_VMODE_* macros */
 	unsigned flag;
 };
 
@@ -69,18 +82,33 @@ struct fb_videomode {
  * of available palette entries (i.e. # of entries = 1 << length).
  */
 struct fb_bitfield {
-	unsigned offset;		/* beginning of bitfield	*/
-	unsigned length;		/* length of bitfield		*/
-	int msb_right;			/* != 0 : Most significant bit is right */
+	unsigned offset;		/**< beginning of bitfield	*/
+	unsigned length;		/**< length of bitfield		*/
+	int msb_right;			/**< != 0 : Most significant bit is right */
 };
 
 struct fb_info;
 
+/**
+ * Framebuffer device's platform information
+ *
+ * The video hardware driver must set the following fields:
+ * - 'fb_mode' function to setup a specific video mode
+ * - 'fb_enable' function to activate the video output
+ * - 'fb_disable' function to deactivate the video output
+ * - 'fb_setcolreg' function to ???????? FIXME
+ *
+ * The video hardware driver can set default values for the following fields:
+ * - 'mode' if the driver supports only specific video modes.
+ * - 'mode_cnt' must be set, if 'mode_list' is given
+ * - 'bits_per_pixel' if the video hardware driver defaults to another bpp than 16
+ */
 struct fb_host {
-	const struct fb_videomode *mode;
-	unsigned mode_cnt;
+	/* information about possible video mode(s) */
+	const struct fb_videomode *mode;	/**< Array of modes */
+	unsigned mode_cnt;		/**< count of entries in 'mode'. */
 
-	struct device_d *hw_dev;
+	struct device_d *hw_dev;	/**< the host device */
 
 	/* callbacks into the video hardware driver */
 	int (*fb_setcolreg)(struct fb_info*, unsigned, unsigned, unsigned, unsigned, unsigned);
@@ -88,24 +116,28 @@ struct fb_host {
 	void (*fb_enable)(struct fb_info*);
 	void (*fb_disable)(struct fb_info*);
 
-	unsigned bits_per_pixel;
+	unsigned bits_per_pixel;	/**< default bpp, 0 = use framebuffer's default */
 };
 
+/**
+ * Framebuffer's runtime information
+ */
 struct fb_info {
-	struct fb_host *host;
-	struct device_d *fb_dev;
+	struct fb_host *host;		/**< host data this fb is based on */
+	struct device_d *fb_dev;	/**< the framebuffer device */
+	/* information about current video mode */
+	/** the currently active video mode if set. Can be NULL = no video mode set yet */
 	const struct fb_videomode *active_mode;
+	unsigned xres;			/**< visible horizontal pixel count */
+	unsigned yres;			/**< visible vertical line count */
+	unsigned bits_per_pixel;	/**< requested colour depth */
 
-	unsigned xres;			/* visible resolution		*/
-	unsigned yres;
-	unsigned bits_per_pixel;	/* guess what			*/
-
-	int grayscale;			/* != 0 Graylevels instead of colors */
+	int grayscale;			/**< != 0 Graylevels instead of colors */
 
-	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
-	struct fb_bitfield green;	/* else only length is significant */
+	struct fb_bitfield red;		/**< bitfield in fb mem if true color, */
+	struct fb_bitfield green;	/**< else only length is significant */
 	struct fb_bitfield blue;
-	struct fb_bitfield transp;	/* transparency			*/
+	struct fb_bitfield transp;	/**< transparency			*/
 
 	int enabled;
 };
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Oct 26 07:31:44 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 26 Oct 2010 13:31:44 +0200
Subject: [PATCH 08/12] Add a video driver for S3C2440 bases platforms
In-Reply-To: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
References: <1288092708-5187-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1288092708-5187-9-git-send-email-jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>
---
 arch/arm/mach-s3c24xx/include/mach/fb.h |   40 +++
 drivers/video/Kconfig                   |    6 +
 drivers/video/Makefile                  |    1 +
 drivers/video/s3c.c                     |  452 +++++++++++++++++++++++++++++++
 4 files changed, 499 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h
 create mode 100644 drivers/video/s3c.c

diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h
new file mode 100644
index 0000000..eec6164
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/fb.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __MACH_FB_H_
+# define __MACH_FB_H_
+
+#include <fb.h>
+
+struct s3c_fb_platform_data {
+
+	const struct fb_videomode *mode_list;
+	unsigned mode_cnt;
+
+	int passive_display;	/**< enable support for STN or CSTN displays */
+
+	void *framebuffer;	/**< force framebuffer base address */
+	unsigned size;		/**< force framebuffer size */
+
+	/** hook to enable backlight and stuff */
+	void (*enable)(int);
+};
+
+#endif /* __MACH_FB_H_ */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d7f3d01..5a5edd2 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -39,4 +39,10 @@ config DRIVER_VIDEO_IMX_IPU
 	  Add support for the IPU framebuffer device found on
 	  i.MX31 and i.MX35 CPUs.
 
+config S3C_VIDEO
+	bool "S3C244x framebuffer driver"
+	depends on ARCH_S3C24xx
+	help
+	  Add support for the S3C244x LCD controller.
+
 endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 179f0c4..4287fc8 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_VIDEO) += fb.o
 
 obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
 obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
+obj-$(CONFIG_S3C_VIDEO) += s3c.o
diff --git a/drivers/video/s3c.c b/drivers/video/s3c.c
new file mode 100644
index 0000000..8ae5785
--- /dev/null
+++ b/drivers/video/s3c.c
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ *
+ * This driver is based on a patch found in the web:
+ * (C) Copyright 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge at openmoko.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <fb.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <mach/gpio.h>
+#include <mach/s3c24xx-generic.h>
+#include <mach/s3c24x0-clocks.h>
+#include <mach/fb.h>
+
+#define LCDCON1 0x00
+# define PNRMODE(x) (((x) & 3) << 5)
+# define BPPMODE(x) (((x) & 0xf) << 1)
+# define SET_CLKVAL(x) (((x) & 0x3ff) << 8)
+# define GET_CLKVAL(x) (((x) >> 8) & 0x3ff)
+# define ENVID (1 << 0)
+
+#define LCDCON2 0x04
+# define SET_VBPD(x) (((x) & 0xff) << 24)
+# define SET_LINEVAL(x) (((x) & 0x3ff) << 14)
+# define SET_VFPD(x) (((x) & 0xff) << 6)
+# define SET_VSPW(x) ((x) & 0x3f)
+
+#define LCDCON3 0x08
+# define SET_HBPD(x) (((x) & 0x7f) << 19)
+# define SET_HOZVAL(x) (((x) & 0x7ff) << 8)
+# define SET_HFPD(x) ((x) & 0xff)
+
+#define LCDCON4 0x0c
+# define SET_HSPW(x) ((x) & 0xff)
+
+#define LCDCON5 0x10
+# define BPP24BL (1 << 12)
+# define FRM565 (1 << 11)
+# define INV_CLK (1 << 10)
+# define INV_HS (1 << 9)
+# define INV_VS (1 << 8)
+# define INV_DTA (1 << 7)
+# define INV_DE (1 << 6)
+# define INV_PWREN (1 << 5)
+# define INV_LEND (1 << 4)	/* FIXME */
+# define ENA_PWREN (1 << 3)
+# define ENA_LEND (1 << 2)	/* FIXME */
+# define BSWP (1 << 1)
+# define HWSWP (1 << 0)
+
+#define LCDSADDR1 0x14
+# define SET_LCDBANK(x) (((x) & 0x1ff) << 21)
+# define GET_LCDBANK(x) (((x) >> 21) & 0x1ff)
+# define SET_LCDBASEU(x) ((x) & 0x1fffff)
+# define GET_LCDBASEU(x) ((x) & 0x1fffff)
+
+#define LCDSADDR2 0x18
+# define SET_LCDBASEL(x) ((x) & 0x1fffff)
+# define GET_LCDBASEL(x) ((x) & 0x1fffff)
+
+#define LCDSADDR3 0x1c
+# define SET_OFFSIZE(x) (((x) & 0x7ff) << 11)
+# define GET_OFFSIZE(x) (((x) >> 11) & 0x7ff)
+# define SET_PAGE_WIDTH(x) ((x) & 0x3ff)
+# define GET_PAGE_WIDTH(x) ((x) & 0x3ff)
+
+#define RED_LUT 0x20
+#define GREEN_LUT 0x24
+#define BLUE_LUT 0x28
+
+#define DITHMODE 0x4c
+
+#define TPAL 0x50
+
+#define LCDINTPND 0x54
+
+#define LCDSRCPND 0x58
+
+#define LCDINTMSK 0x5c
+# define FIWSEL (1 << 2)
+
+#define TCONSEL 0x60
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+struct s3cfb_host {
+	struct fb_host fb_data;
+	struct device_d *hw_dev;
+	void __iomem *base;
+};
+
+#define fb_info_to_s3cfb_host(x) ((struct s3cfb_host*)((x)->host))
+#define s3cfb_host_to_s3c_fb_platform_data(x) ((struct s3c_fb_platform_data*)((x)->hw_dev->platform_data))
+
+/* the RGB565 true colour mode */
+static const struct fb_bitfield def_rgb565[] = {
+	[RED] = {
+		.offset = 11,
+		.length = 5,
+	},
+	[GREEN] = {
+		.offset = 5,
+		.length = 6,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 5,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/* the RGB888 true colour mode */
+static const struct fb_bitfield def_rgb888[] = {
+	[RED] = {
+		.offset = 16,
+		.length = 8,
+	},
+	[GREEN] = {
+		.offset = 8,
+		.length = 8,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 8,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void s3cfb_enable_controller(struct fb_info *fb_info)
+{
+	struct s3cfb_host *fbh = fb_info_to_s3cfb_host(fb_info);
+	struct s3c_fb_platform_data *pdata = s3cfb_host_to_s3c_fb_platform_data(fbh);
+	uint32_t con1;
+
+	pr_debug("%s called\n", __func__);
+
+	con1 = readl(fbh->base + LCDCON1);
+
+	con1 |= ENVID;
+
+	writel(con1, fbh->base + LCDCON1);
+
+	if (pdata->enable)
+		(pdata->enable)(1);
+}
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void s3cfb_disable_controller(struct fb_info *fb_info)
+{
+	struct s3cfb_host *fbh = fb_info_to_s3cfb_host(fb_info);
+	struct s3c_fb_platform_data *pdata = s3cfb_host_to_s3c_fb_platform_data(fbh);
+	uint32_t con1;
+
+	pr_debug("%s called\n", __func__);
+
+	if (pdata->enable)
+		(pdata->enable)(0);
+
+	con1 = readl(fbh->base + LCDCON1);
+
+	con1 &= ~ENVID;
+
+	writel(con1, fbh->base + LCDCON1);
+}
+
+/**
+ * Prepare the video hardware for a specified video mode
+ * @param fb_info Framebuffer information
+ * @param mode The video mode description to initialize
+ * @return 0 on success
+ */
+static int s3cfb_initialize_mode(struct fb_info *fb_info, const struct fb_videomode *mode)
+{
+	struct s3cfb_host *fbh = fb_info_to_s3cfb_host(fb_info);
+	struct s3c_fb_platform_data *pdata = s3cfb_host_to_s3c_fb_platform_data(fbh);
+	unsigned size, hclk, div;
+	uint32_t con1, con2, con3, con4, con5 = 0;
+
+	pr_debug("%s called\n", __func__);
+
+	if (pdata->passive_display != 0) {
+		pr_err("Passive displays are currently not supported\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = mode->xres * mode->yres * (fb_info->bits_per_pixel >> 3);
+	if (fb_info->fb_dev->size != 0) {
+		if (size > fb_info->fb_dev->size) {
+			pr_err("Cannot initialize video mode '%s': Its too large. "
+				"Required bytes are %u, available only %u\n",
+				mode->name, size, fb_info->fb_dev->size);
+			return -EINVAL;
+		}
+	} else
+		fb_info->fb_dev->size = size;
+
+	/*
+	 * if no framebuffer memory was specified yet, allocate one,
+	 * and allocate more memory, on user request
+	 */
+	if (fb_info->fb_dev->map_base == 0U)
+		fb_info->fb_dev->map_base = (resource_size_t)xzalloc(fb_info->fb_dev->size);
+
+	/* its useful to enable the unit's clock */
+	s3c244x_mod_clock(CLK_LCDC, 1);
+
+	/* ensure video output is _off_ */
+	writel(0x00000000, fbh->base + LCDCON1);
+
+	hclk = s3c24xx_get_hclk() / 1000U;	/* hclk in kHz */
+	div = hclk / PICOS2KHZ(mode->pixclock);
+	if (div < 3)
+		div  = 3;
+	/* pixel clock is: (hclk) / ((div + 1) * 2) */
+	div += 1;
+	div >>= 1;
+	div -= 1;
+
+	con1 = PNRMODE(3) | SET_CLKVAL(div);	/* PNRMODE=3 is TFT */
+
+	switch (fb_info->bits_per_pixel) {
+#if 0
+	/* TODO add CLUT based modes */
+	case 1:
+		con1 |= BPPMODE(8);
+		break;
+	case 2:
+		con1 |= BPPMODE(9);
+		break;
+	case 4:
+		con1 |= BPPMODE(10);
+		break;
+	case 8:
+		con1 |= BPPMODE(11);
+		break;
+#endif
+	case 16:
+		con1 |= BPPMODE(12);
+		con5 |= FRM565;
+		fb_info->red = def_rgb565[RED];
+		fb_info->green = def_rgb565[GREEN];
+		fb_info->blue = def_rgb565[BLUE];
+		fb_info->transp =  def_rgb565[TRANSP];
+		break;
+	case 24:
+		con1 |= BPPMODE(13);
+		con5 |= BPP24BL;	/* FIXME */
+		fb_info->red = def_rgb888[RED];
+		fb_info->green = def_rgb888[GREEN];
+		fb_info->blue = def_rgb888[BLUE];
+		fb_info->transp =  def_rgb888[TRANSP];
+		break;
+	default:
+		pr_err("Invalid bits per pixel value: %u\n", fb_info->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	/* 'normal' in register description means positive logic */
+	if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
+		con5 |= INV_HS;
+	if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
+		con5 |= INV_VS;
+	if (!(mode->sync & FB_SYNC_DE_HIGH_ACT))
+		con5 |= INV_DE;
+	if (mode->sync & FB_SYNC_CLK_INVERT)
+		con5 |= INV_CLK;	/* display should latch at the rising edge */
+	if (mode->sync & FB_SYNC_SWAP_RGB)
+		con5 |= HWSWP;
+
+	/* TODO power enable config via platform data */
+
+	/* vertical timing */
+	con2 = SET_VBPD(mode->upper_margin - 1) |
+		SET_LINEVAL(mode->yres - 1) |
+		SET_VFPD(mode->lower_margin - 1) |
+		SET_VSPW(mode->vsync_len - 1);
+
+	/* horizontal timing */
+	con3 = SET_HBPD(mode->left_margin - 1) |
+		SET_HOZVAL(mode->xres - 1) |
+		SET_HFPD(mode->right_margin - 1);
+	con4 = SET_HSPW(mode->hsync_len - 1);
+
+	/* basic timing setup */
+	writel(con1, fbh->base + LCDCON1);
+	pr_debug(" Writing %08X into %08X (con1)\n", con1, fbh->base + LCDCON1);
+	writel(con2, fbh->base + LCDCON2);
+	pr_debug(" Writing %08X into %08X (con2)\n", con2, fbh->base + LCDCON2);
+	writel(con3, fbh->base + LCDCON3);
+	pr_debug(" Writing %08X into %08X (con3)\n", con3, fbh->base + LCDCON3);
+	writel(con4, fbh->base + LCDCON4);
+	pr_debug(" Writing %08X into %08X (con4)\n", con4, fbh->base + LCDCON4);
+	writel(con5, fbh->base + LCDCON5);
+	pr_debug(" Writing %08X into %08X (con5)\n", con5, fbh->base + LCDCON5);
+
+	pr_debug("Setting up the fb baseadress to %08X\n", fb_info->fb_dev->map_base);
+
+	/* framebuffer memory setup */
+	writel(fb_info->fb_dev->map_base >> 1, fbh->base + LCDSADDR1);
+	size = mode->xres * (fb_info->bits_per_pixel >> 3) * (mode->yres);
+	writel(SET_LCDBASEL((fb_info->fb_dev->map_base + size) >> 1), fbh->base + LCDSADDR2);
+
+	writel(SET_OFFSIZE(0) |
+		SET_PAGE_WIDTH((mode->xres * fb_info->bits_per_pixel) >> 4),
+		fbh->base + LCDSADDR3);
+
+	writel(FIWSEL, fbh->base + LCDINTMSK);
+
+	return 0;
+}
+
+/**
+ * Print some information about the current hardware state
+ * @param hw_dev S3C video device
+ */
+#ifdef CONFIG_VIDEO_INFO_VERBOSE
+static void s3cfb_info(struct device_d *hw_dev)
+{
+	uint32_t con1, addr1, addr2, addr3;
+
+	con1 = readl(hw_dev->map_base + LCDCON1);
+	addr1 = readl(hw_dev->map_base + LCDSADDR1);
+	addr2 = readl(hw_dev->map_base + LCDSADDR2);
+	addr3 = readl(hw_dev->map_base + LCDSADDR3);
+
+	printf(" Video hardware info:\n");
+	printf("  Video clock is running at %u Hz\n", s3c24xx_get_hclk() / ((GET_CLKVAL(con1) + 1) * 2));
+	printf("  Video memory bank starts at 0x%08X\n", GET_LCDBANK(addr1) << 22);
+	printf("  Video memory bank offset: 0x%08X\n", GET_LCDBASEU(addr1));
+	printf("  Video memory end: 0x%08X\n", GET_LCDBASEU(addr2));
+	printf("  Virtual screen offset size: %u half words\n", GET_OFFSIZE(addr3));
+	printf("  Virtual screen page width: %u half words\n", GET_PAGE_WIDTH(addr3));
+}
+#endif
+
+/*
+ * There is only one video hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct s3cfb_host host_data = {
+	.fb_data.fb_mode = s3cfb_initialize_mode,
+	.fb_data.fb_enable = s3cfb_enable_controller,
+	.fb_data.fb_disable = s3cfb_disable_controller,
+};
+
+static int s3cfb_probe(struct device_d *hw_dev)
+{
+	struct s3c_fb_platform_data *pdata = hw_dev->platform_data;
+	struct device_d *fb_dev;
+
+	pr_debug("%s called\n", __func__);
+
+	if (pdata == NULL) {
+		pr_debug("Framebuffer driver missing platform data");
+		return -ENODEV;
+	}
+
+	/* enable unit's clock */
+	s3c244x_mod_clock(CLK_LCDC, 1);
+
+	writel(0, hw_dev->map_base + LCDCON1);
+	/* off may be means high level (FIXME itlp specific) */
+	writel(0, hw_dev->map_base + LCDCON5);
+
+	/* disable it again until user request */
+	s3c244x_mod_clock(CLK_LCDC, 0);
+
+	/* add runtime hardware info */
+	host_data.hw_dev = hw_dev;
+	host_data.base = (void*)hw_dev->map_base;
+
+	/* add runtime video info */
+	host_data.fb_data.mode = pdata->mode_list;
+	host_data.fb_data.mode_cnt = pdata->mode_cnt;
+
+	fb_dev = register_framebuffer(&host_data.fb_data, pdata->framebuffer, pdata->size);
+	if (fb_dev == NULL) {
+		pr_err("Failed to register framebuffer\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct driver_d s3cfb_driver = {
+	.name	= "s3cfb",
+	.probe	= s3cfb_probe,
+#ifdef CONFIG_VIDEO_INFO_VERBOSE
+	.info	= s3cfb_info,
+#endif
+};
+
+static int s3cfb_init(void)
+{
+	return register_driver(&s3cfb_driver);
+}
+
+device_initcall(s3cfb_init);
+
+/**
+ * The S3C244x LCD controller supports passive (CSTN/STN) and active (TFT) LC displays
+ *
+ * The driver itself currently supports only active TFT LC displays in the follwing manner:
+ *
+ *  * Palletized colours
+ *    - 1 bpp
+ *    - 2 bpp
+ *    - 4 bpp
+ *    - 8 bpp
+ *  * True colours
+ *    - 16 bpp
+ *    - 24 bpp
+ */
-- 
1.7.2.3



From marek.belisko at gmail.com  Tue Oct 26 07:33:05 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Tue, 26 Oct 2010 13:33:05 +0200
Subject: [PATCH] Add basic support for mini2440 dev board.
In-Reply-To: <201010191438.34628.jbe@pengutronix.de>
References: <1287474532-31528-1-git-send-email-marek.belisko@gmail.com>
	<201010191028.28405.jbe@pengutronix.de>
	<20101019082921.GM11127@game.jcrosoft.org>
	<201010191438.34628.jbe@pengutronix.de>
Message-ID: <AANLkTi=3PyjrHEgq5cCwL0XwCtNWiLTseeG8NHGkQgPJ@mail.gmail.com>

Will be this patch added to git repo? I have udc gadget patch available
but has dependency on this one.

On Tue, Oct 19, 2010 at 2:38 PM, Juergen Beisert <jbe at pengutronix.de> wrote:
> Jean-Christophe PLAGNIOL-VILLARD wrote:
>> On 10:28 Tue 19 Oct ? ? , Juergen Beisert wrote:
>> > Marek Belisko wrote:
>> > > This work is mainly based on a9m2440 board implementation
>> > > from Juergen Beisert <jbe at pengutronix.de>. Functionality
>> > > was tested only running barebox from ram. Loading to flash
>> > > and booting will not work because missing lowlevel_init
>> > > functionality (lack of jtag debugger on my side ;)).
>> >
>> > I have now access to a mini2440 at Pengutronix. I will add this feature
>> > soon.
>> >
>> > > [...]
>> > > +static int mini2440_devices_init(void)
>> > > +{
>> > > + uint32_t reg;
>> > > +
>> > > + reg = readl(BWSCON);
>> > > +
>> > > + /* CS#4 to access the network controller */
>> > > + reg &= ~0x000f0000;
>> > > + reg |= ?0x000d0000; ? ? /* 16 bit */
>> > > + writel(0x1f4c, BANKCON4);
>> > > +
>> > > + writel(reg, BWSCON);
>> > > +
>> > > + /* release the reset signal to external devices */
>> > > + reg = readl(MISCCR);
>> > > + reg |= 0x10000;
>> > > + writel(reg, MISCCR);
>> > > +
>> > > + register_device(&nand_dev);
>> > > + register_device(&sdram_dev);
>> > > + register_device(&dm9000_dev);
>> > > +#ifdef CONFIG_NAND
>> > > + /* ----------- add some vital partitions -------- */
>> > > + devfs_del_partition("self_raw");
>> > > + devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED,
>> > > "self_raw"); + ? ?dev_add_bb_dev("self_raw", NULL);
>> > > +
>> > > + devfs_del_partition("env_raw");
>> > > + devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED,
>> > > "env_raw"); + ? ? dev_add_bb_dev("env_raw", NULL);
>> > > +#endif
>> > > + armlinux_add_dram(&sdram_dev);
>> > > + armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
>> > > + armlinux_set_architecture(MACH_TYPE_MINI2440);
>> > > +
>> > > + return 0;
>> > > +}
>> >
>> > We need some kind of management here, because the mini2440 comes with NOR
>> > and NAND flash. And both can be configured to boot the system from: We
>> > need a location to store the environment. Maybe in NOR, when booting from
>> > NOR, and in NAND, when booting form NAND? Or only one single location
>> > where to store the environment, independent from the boot source? Ideas?
>>
>> I like the idea to store in the boot media
>
> If you switch the boot media the environment moves, too? That may confuse
> users, as their settings are "moving away" in this case. Okay, its not a
> regular usecase. But with the mini2440 its simply a configuration switch on
> the board. My idea was to add some Kconfig menu entries to select one of the
> possible cases a) move the environment with the boot source or b) store and
> expect it always in NOR or NAND.
>
> jbe
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Beisert ? ? ? ? ? ? |
> Linux Solutions for Science and Industry ? ? ?| Phone: +49-8766-939 228 ? ? |
> Vertretung Sued/Muenchen, Germany ? ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? ? ?| http://www.pengutronix.de/ ?|
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From s.hauer at pengutronix.de  Tue Oct 26 14:34:49 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 Oct 2010 20:34:49 +0200
Subject: Beagleboard and barebox problem
In-Reply-To: <AANLkTi==hZCG9TbR1udevZPJp=wbji-JTTZaMTYYcW6f@mail.gmail.com>
References: <AANLkTinosq5jY41=piCX3JaeFy6Z93gnG1Ym_VRqZ_sJ@mail.gmail.com>
	<20101022070504.GD22139@pengutronix.de>
	<AANLkTimNiUjRq3GLNNa0gYRGGZjLaTrWbsNRKPU9=1mw@mail.gmail.com>
	<20101026033958.GD6017@pengutronix.de>
	<AANLkTi==hZCG9TbR1udevZPJp=wbji-JTTZaMTYYcW6f@mail.gmail.com>
Message-ID: <20101026183449.GE6017@pengutronix.de>

On Mon, Oct 25, 2010 at 11:07:21PM -0500, Victor Rodriguez wrote:
> On Mon, Oct 25, 2010 at 10:39 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> > Hi Victor,
> >
> > Right, dont forget to erase the partitions with 'erase
> > /dev/nand0.kernel.bb' beforehand, otherwise you'll have garbage in your
> > nand.
> 
> You mean to erase the part of the nand where the kernel is saved
> before copy the ramdisk to its partition? or before i run the 'boot'
> comand ?

You have to erase the Nand before writing to it. (though I wonder if
that behaviour should be changed).

> >
> > I'm sorry the situation on the beagle board is still a bit rough and
> > unclear. I hope we find time working on this.
> 
> 
> Yes I could give some free time to work on this :) but could you
> please give me more information about the mmc dirver I am new on
> barebox but I would like to help to improve it  :)

Great ;)

> 
> Which other board is using this MMC driver ? I can check the code.

Currently there is no Omap MMC support in barebox. The path to go would
be to copy the Omap MMC driver from U-Boot and bash onto it until it
runs. For a clue what has to be changed in this driver you might want to
look at a diff between the i.MX esdhc driver inU-Boot and barebox.

> 
> The problem is that beagle board is much more familiar with booting by
> mmc because it does not have any RJ45 connector in order to transfer
> by TFTP or NFS the uImage.
> 
> By the way about the small piece of code for the beagle board nand. Do
> you consider that is good enough for an small patch ?

I think at least the offset of the environment has to be moved. AFAIK
the first 768k in Nand is used for the Xloader and the secoond stage
bootloader. It's probably not good for users overwriting this
accidently.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Tue Oct 26 14:58:28 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 Oct 2010 20:58:28 +0200
Subject: more patches for next
In-Reply-To: <201010261120.30875.jbe@pengutronix.de>
References: <1287753331-7696-1-git-send-email-s.hauer@pengutronix.de>
	<201010261120.30875.jbe@pengutronix.de>
Message-ID: <20101026185827.GF6017@pengutronix.de>

On Tue, Oct 26, 2010 at 11:20:30AM +0200, Juergen Beisert wrote:
> Some of these changes lead into:
> 
> [...]
>   CC      drivers/serial/serial_imx.o
> In file included from arch/arm/mach-imx/include/mach/imx-regs.h:47,
>                  from drivers/serial/serial_imx.c:21:
> arch/arm/mach-imx/include/mach/imx27-regs.h:222:1: warning: "ESDMISC_RST" redefined
> In file included from arch/arm/mach-imx/include/mach/imx27-regs.h:83,
>                  from arch/arm/mach-imx/include/mach/imx-regs.h:47,
>                  from drivers/serial/serial_imx.c:21:
> arch/arm/mach-imx/include/mach/esdctl.h:37:1: warning: this is the location of the previous definition
> In file included from arch/arm/mach-imx/include/mach/imx-regs.h:47,
>                  from drivers/serial/serial_imx.c:21:
> arch/arm/mach-imx/include/mach/imx27-regs.h:224:1: warning: "ESDMISC_MDDR_DL_RST" redefined
> In file included from arch/arm/mach-imx/include/mach/imx27-regs.h:83,
>                  from arch/arm/mach-imx/include/mach/imx-regs.h:47,
>                  from drivers/serial/serial_imx.c:21:
> arch/arm/mach-imx/include/mach/esdctl.h:40:1: warning: this is the location of the previous definition
> In file included from arch/arm/mach-imx/include/mach/imx-regs.h:47,
>                  from drivers/serial/serial_imx.c:21:
> arch/arm/mach-imx/include/mach/imx27-regs.h:225:1: warning: "ESDMISC_MDDR_MDIS" redefined
> In file included from arch/arm/mach-imx/include/mach/imx27-regs.h:83,
>                  from arch/arm/mach-imx/include/mach/imx-regs.h:47,
>                  from drivers/serial/serial_imx.c:21:
> arch/arm/mach-imx/include/mach/esdctl.h:41:1: warning: this is the location of the previous definition
> In file included from arch/arm/mach-imx/include/mach/imx-regs.h:47,
>                  from drivers/serial/serial_imx.c:21:
> arch/arm/mach-imx/include/mach/imx27-regs.h:226:1: warning: "ESDMISC_LHD" redefined
> In file included from arch/arm/mach-imx/include/mach/imx27-regs.h:83,
>                  from arch/arm/mach-imx/include/mach/imx-regs.h:47,
>                  from drivers/serial/serial_imx.c:21:
> arch/arm/mach-imx/include/mach/esdctl.h:42:1: warning: this is the location of the previous definition
> [...]
> 
> Tested with the "pcm038_defconfig".


The good thing is that all defines even if written differently are the
same. The following fixes this:



From s.hauer at pengutronix.de  Tue Oct 26 14:56:17 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 Oct 2010 20:56:17 +0200
Subject: [PATCH] ARM i.MX27: remove duplicated defines
Message-ID: <mailman.4.1288119512.1530.barebox@lists.infradead.org>

The esdctl regs are now in a seperate header file, so remove the
duplicates from imx27-regs.h

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/imx27-regs.h |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h
index 0fa954d..e87d5bf 100644
--- a/arch/arm/mach-imx/include/mach/imx27-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx27-regs.h
@@ -219,14 +219,6 @@
 #define ESDCFG_TWTR		(1 << 20)
 #define ESDCFG_TXP(x)		(((x) & 0x3) << 21)
 
-#define ESDMISC_RST		(1 << 1)
-#define ESDMISC_MDDREN		(1 << 2)
-#define ESDMISC_MDDR_DL_RST	(1 << 3)
-#define ESDMISC_MDDR_MDIS	(1 << 4)
-#define ESDMISC_LHD		(1 << 5)
-#define ESDMISC_MA10_SHARE	(1 << 6)
-#define ESDMISC_SDRAM_RDY	(1 << 6)
-
 /*
  * Definitions for the clocksource driver
  */
-- 
1.7.2.3

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From marek.belisko at gmail.com  Wed Oct 27 08:42:03 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Wed, 27 Oct 2010 14:42:03 +0200
Subject: command bootu to start kernel
Message-ID: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>

Hi,

I have mini2440 board with barebox running from RAM.
I try to start uImage kernel for that platform but I'm little bit
confused how to do it.

I do tftp uImage and the bootu uImage but it always hangs :

commandline: console=ttySAC0,115200
arch_number: 1999

I track down that theKernel pointer point to 0xffffffff (memmap return
(void*)-1) which is obviously wrong.
If I understand correctly bootu function take first parameter and try to
open a file and memmap. If file isn't opened successfully then convert
string address which is then taken for
theKernel pointer.

Is this correct procedure or do I something wrong?

Thanks for replies,

Marek


-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From jbe at pengutronix.de  Wed Oct 27 09:33:15 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Wed, 27 Oct 2010 15:33:15 +0200
Subject: command bootu to start kernel
In-Reply-To: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
Message-ID: <201010271533.15954.jbe@pengutronix.de>

Belisko Marek wrote:
> I have mini2440 board with barebox running from RAM.
> I try to start uImage kernel for that platform but I'm little bit
> confused how to do it.
>
> I do tftp uImage and the bootu uImage but it always hangs :
>
> commandline: console=ttySAC0,115200
> arch_number: 1999
>
> I track down that theKernel pointer point to 0xffffffff (memmap return
> (void*)-1) which is obviously wrong.
> If I understand correctly bootu function take first parameter and try to
> open a file and memmap. If file isn't opened successfully then convert
> string address which is then taken for
> theKernel pointer.
>
> Is this correct procedure or do I something wrong?

Try to start a zImage with "bootz". On my system 'bootm' and 'bootu' do not 
work.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Wed Oct 27 09:46:36 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 27 Oct 2010 15:46:36 +0200
Subject: command bootu to start kernel
In-Reply-To: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
Message-ID: <20101027134636.GK6017@pengutronix.de>

Hi Marek,

On Wed, Oct 27, 2010 at 02:42:03PM +0200, Belisko Marek wrote:
> Hi,
> 
> I have mini2440 board with barebox running from RAM.
> I try to start uImage kernel for that platform but I'm little bit
> confused how to do it.
> 
> I do tftp uImage and the bootu uImage but it always hangs :

Uh, I can't remember why I named the bootu command this way, but it was
an unlucky decision. Actually this command starts raw kernel images.
What you are looking for is the bootm command which starts uimages. I
don't know why it's bootm, the command name is derived from U-Boot.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Wed Oct 27 09:54:38 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 27 Oct 2010 15:54:38 +0200
Subject: command bootu to start kernel
In-Reply-To: <201010271533.15954.jbe@pengutronix.de>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<201010271533.15954.jbe@pengutronix.de>
Message-ID: <20101027135438.GL6017@pengutronix.de>

On Wed, Oct 27, 2010 at 03:33:15PM +0200, Juergen Beisert wrote:
> Belisko Marek wrote:
> > I have mini2440 board with barebox running from RAM.
> > I try to start uImage kernel for that platform but I'm little bit
> > confused how to do it.
> >
> > I do tftp uImage and the bootu uImage but it always hangs :
> >
> > commandline: console=ttySAC0,115200
> > arch_number: 1999
> >
> > I track down that theKernel pointer point to 0xffffffff (memmap return
> > (void*)-1) which is obviously wrong.
> > If I understand correctly bootu function take first parameter and try to
> > open a file and memmap. If file isn't opened successfully then convert
> > string address which is then taken for
> > theKernel pointer.
> >
> > Is this correct procedure or do I something wrong?
> 
> Try to start a zImage with "bootz". On my system 'bootm' and 'bootu' do not 
> work.

bootz is for starting zImages. At least this command has a convenient
name :)
bootz should work on your system aswell. If not, please complain loudly.
bootu is a bit tricky though. To start a raw linux image it has to be
copied to the exact address is is expected to run, for most boards this
is start of sdram + 0x8000, but this may differ on some boards (it's
basically PHYS_OFFSET + TEXT_OFFSET in the kernel)

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From marek.belisko at gmail.com  Wed Oct 27 10:03:31 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Wed, 27 Oct 2010 16:03:31 +0200
Subject: command bootu to start kernel
In-Reply-To: <20101027135438.GL6017@pengutronix.de>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<201010271533.15954.jbe@pengutronix.de>
	<20101027135438.GL6017@pengutronix.de>
Message-ID: <AANLkTinRKJCJK-3sgA5M0q6RjnKA-42vLf5wVYOCcGeE@mail.gmail.com>

On Wed, Oct 27, 2010 at 3:54 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> On Wed, Oct 27, 2010 at 03:33:15PM +0200, Juergen Beisert wrote:
>> Belisko Marek wrote:
>> > I have mini2440 board with barebox running from RAM.
>> > I try to start uImage kernel for that platform but I'm little bit
>> > confused how to do it.
>> >
>> > I do tftp uImage and the bootu uImage but it always hangs :
>> >
>> > commandline: console=ttySAC0,115200
>> > arch_number: 1999
>> >
>> > I track down that theKernel pointer point to 0xffffffff (memmap return
>> > (void*)-1) which is obviously wrong.
>> > If I understand correctly bootu function take first parameter and try to
>> > open a file and memmap. If file isn't opened successfully then convert
>> > string address which is then taken for
>> > theKernel pointer.
>> >
>> > Is this correct procedure or do I something wrong?
>>
>> Try to start a zImage with "bootz". On my system 'bootm' and 'bootu' do not
>> work.
>
> bootz is for starting zImages. At least this command has a convenient
> name :)
> bootz should work on your system aswell. If not, please complain loudly.
Well it's not working.
tftp zImage
bootz zImage laed to:

ERROR: out of memory and device restart :(.

> bootu is a bit tricky though. To start a raw linux image it has to be
> copied to the exact address is is expected to run, for most boards this
> is start of sdram + 0x8000, but this may differ on some boards (it's
> basically PHYS_OFFSET + TEXT_OFFSET in the kernel)
T
>
> Sascha
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 ? ?|
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From jbe at pengutronix.de  Wed Oct 27 10:38:42 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Wed, 27 Oct 2010 16:38:42 +0200
Subject: command bootu to start kernel
In-Reply-To: <20101027135438.GL6017@pengutronix.de>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<201010271533.15954.jbe@pengutronix.de>
	<20101027135438.GL6017@pengutronix.de>
Message-ID: <201010271638.42404.jbe@pengutronix.de>

Sascha Hauer wrote:
> On Wed, Oct 27, 2010 at 03:33:15PM +0200, Juergen Beisert wrote:
> > Belisko Marek wrote:
> > > I have mini2440 board with barebox running from RAM.
> > > I try to start uImage kernel for that platform but I'm little bit
> > > confused how to do it.
> > >
> > > I do tftp uImage and the bootu uImage but it always hangs :
> > >
> > > commandline: console=ttySAC0,115200
> > > arch_number: 1999
> > >
> > > I track down that theKernel pointer point to 0xffffffff (memmap return
> > > (void*)-1) which is obviously wrong.
> > > If I understand correctly bootu function take first parameter and try
> > > to open a file and memmap. If file isn't opened successfully then
> > > convert string address which is then taken for
> > > theKernel pointer.
> > >
> > > Is this correct procedure or do I something wrong?
> >
> > Try to start a zImage with "bootz". On my system 'bootm' and 'bootu' do
> > not work.
>
> bootz is for starting zImages. At least this command has a convenient
> name :)
> bootz should work on your system aswell. If not, please complain loudly.

bootz works here. bootm always complains with the scripts from the generic 
environment:

booting kernel of type uimage from /dev/ram0.kernel
Bad Magic Number

But:

me at host$ file arch/arm/boot/uImage
arch/arm/boot/uImage: u-boot legacy uImage, Linux-2.6.31-00770-g54c3fe6-dir, 
Linux/ARM, OS Kernel Image (Not compressed), 2350016 bytes, Mon Oct 25 
16:58:30 2010, Load Address: 0x40008000, Entry Point: 0x40008000, Header CRC: 
0x17A7330B, Data CRC: 0x888DAA63

Anything wrong with the uImage (built with "make uImage") or the 
command 'bootm'?

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From marek.belisko at gmail.com  Fri Oct 29 02:08:19 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 29 Oct 2010 08:08:19 +0200
Subject: command bootu to start kernel
In-Reply-To: <201010271638.42404.jbe@pengutronix.de>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<201010271533.15954.jbe@pengutronix.de>
	<20101027135438.GL6017@pengutronix.de>
	<201010271638.42404.jbe@pengutronix.de>
Message-ID: <AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>

On Wed, Oct 27, 2010 at 4:38 PM, Juergen Beisert <jbe at pengutronix.de> wrote:
> Sascha Hauer wrote:
>> On Wed, Oct 27, 2010 at 03:33:15PM +0200, Juergen Beisert wrote:
>> > Belisko Marek wrote:
>> > > I have mini2440 board with barebox running from RAM.
>> > > I try to start uImage kernel for that platform but I'm little bit
>> > > confused how to do it.
>> > >
>> > > I do tftp uImage and the bootu uImage but it always hangs :
>> > >
>> > > commandline: console=ttySAC0,115200
>> > > arch_number: 1999
>> > >
>> > > I track down that theKernel pointer point to 0xffffffff (memmap return
>> > > (void*)-1) which is obviously wrong.
>> > > If I understand correctly bootu function take first parameter and try
>> > > to open a file and memmap. If file isn't opened successfully then
>> > > convert string address which is then taken for
>> > > theKernel pointer.
>> > >
>> > > Is this correct procedure or do I something wrong?
>> >
>> > Try to start a zImage with "bootz". On my system 'bootm' and 'bootu' do
>> > not work.
>>
>> bootz is for starting zImages. At least this command has a convenient
>> name :)
>> bootz should work on your system aswell. If not, please complain loudly.
>
> bootz works here. bootm always complains with the scripts from the generic
> environment:
bootz also work here but need to increase malloc size. Use 8M instead 4M.
>
> booting kernel of type uimage from /dev/ram0.kernel
> Bad Magic Number
>
> But:
>
> me at host$ file arch/arm/boot/uImage
> arch/arm/boot/uImage: u-boot legacy uImage, Linux-2.6.31-00770-g54c3fe6-dir,
> Linux/ARM, OS Kernel Image (Not compressed), 2350016 bytes, Mon Oct 25
> 16:58:30 2010, Load Address: 0x40008000, Entry Point: 0x40008000, Header CRC:
> 0x17A7330B, Data CRC: 0x888DAA63
>
> Anything wrong with the uImage (built with "make uImage") or the
> command 'bootm'?
Instead bootm for my uImage works:
bootm uImage
   Verifying Checksum ... OK
   Image Name:   Linux-2.6.32-rc8
   Created:      2010-09-27   8:36:01 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2058404 Bytes =  2 MB
   Load Address: 30008000
   Entry Point:  30008000
OK
commandline: console=ttySAC0,115200
arch_number: 1999

Starting kernel ...

strange but true ;)
>
> jbe
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Beisert ? ? ? ? ? ? |
> Linux Solutions for Science and Industry ? ? ?| Phone: +49-8766-939 228 ? ? |
> Vertretung Sued/Muenchen, Germany ? ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? ? ?| http://www.pengutronix.de/ ?|
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From marek.belisko at gmail.com  Fri Oct 29 03:49:52 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 29 Oct 2010 09:49:52 +0200
Subject: command bootu to start kernel
In-Reply-To: <AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<201010271533.15954.jbe@pengutronix.de>
	<20101027135438.GL6017@pengutronix.de>
	<201010271638.42404.jbe@pengutronix.de>
	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
Message-ID: <AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>

On Fri, Oct 29, 2010 at 8:08 AM, Belisko Marek <marek.belisko at gmail.com> wrote:
> On Wed, Oct 27, 2010 at 4:38 PM, Juergen Beisert <jbe at pengutronix.de> wrote:
>> Sascha Hauer wrote:
>>> On Wed, Oct 27, 2010 at 03:33:15PM +0200, Juergen Beisert wrote:
>>> > Belisko Marek wrote:
>>> > > I have mini2440 board with barebox running from RAM.
>>> > > I try to start uImage kernel for that platform but I'm little bit
>>> > > confused how to do it.
>>> > >
>>> > > I do tftp uImage and the bootu uImage but it always hangs :
>>> > >
>>> > > commandline: console=ttySAC0,115200
>>> > > arch_number: 1999
>>> > >
>>> > > I track down that theKernel pointer point to 0xffffffff (memmap return
>>> > > (void*)-1) which is obviously wrong.
>>> > > If I understand correctly bootu function take first parameter and try
>>> > > to open a file and memmap. If file isn't opened successfully then
>>> > > convert string address which is then taken for
>>> > > theKernel pointer.
>>> > >
>>> > > Is this correct procedure or do I something wrong?
>>> >
>>> > Try to start a zImage with "bootz". On my system 'bootm' and 'bootu' do
>>> > not work.
>>>
>>> bootz is for starting zImages. At least this command has a convenient
>>> name :)
>>> bootz should work on your system aswell. If not, please complain loudly.
>>
>> bootz works here. bootm always complains with the scripts from the generic
>> environment:
> bootz also work here but need to increase malloc size. Use 8M instead 4M.
>>
>> booting kernel of type uimage from /dev/ram0.kernel
>> Bad Magic Number
>>
>> But:
>>
>> me at host$ file arch/arm/boot/uImage
>> arch/arm/boot/uImage: u-boot legacy uImage, Linux-2.6.31-00770-g54c3fe6-dir,
>> Linux/ARM, OS Kernel Image (Not compressed), 2350016 bytes, Mon Oct 25
>> 16:58:30 2010, Load Address: 0x40008000, Entry Point: 0x40008000, Header CRC:
>> 0x17A7330B, Data CRC: 0x888DAA63
>>
>> Anything wrong with the uImage (built with "make uImage") or the
>> command 'bootm'?
> Instead bootm for my uImage works:
> bootm uImage
> ? Verifying Checksum ... OK
> ? Image Name: ? Linux-2.6.32-rc8
> ? Created: ? ? ?2010-09-27 ? 8:36:01 UTC
> ? Image Type: ? ARM Linux Kernel Image (uncompressed)
> ? Data Size: ? ?2058404 Bytes = ?2 MB
> ? Load Address: 30008000
> ? Entry Point: ?30008000
> OK
> commandline: console=ttySAC0,115200
> arch_number: 1999
>
> Starting kernel ...
Despite of loading kernel is working kernel isn't started for
mini2440(from u-boot works fine). It hang at:
Uncompressing Linux..................................................................................................................................
done, booting the kernel.

Same boot zImage and uImage kernels.
>
> strange but true ;)
>>
>> jbe
>>
>> --
>> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Beisert ? ? ? ? ? ? |
>> Linux Solutions for Science and Industry ? ? ?| Phone: +49-8766-939 228 ? ? |
>> Vertretung Sued/Muenchen, Germany ? ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? ? ?| http://www.pengutronix.de/ ?|
>>
>> _______________________________________________
>> barebox mailing list
>> barebox at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/barebox
>>
>
> thanks,
>
> marek
>
> --
> as simple and primitive as possible
> -------------------------------------------------
> Marek Belisko - OPEN-NANDRA
> Freelance Developer
>
> Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
> Tel: +421 915 052 184
> skype: marekwhite
> icq: 290551086
> web: http://open-nandra.com
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From marc at cpdesign.com.au  Fri Oct 29 04:04:16 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri, 29 Oct 2010 19:04:16 +1100
Subject: command bootu to start kernel
In-Reply-To: <AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
Message-ID: <201010291904.16717.marc@cpdesign.com.au>

Hi,

I have no experience with the mini2440, but:

On Friday, October 29, 2010 06:49:52 pm Belisko Marek wrote:
> On Fri, Oct 29, 2010 at 8:08 AM, Belisko Marek <marek.belisko at gmail.com> 
> >> me at host$ file arch/arm/boot/uImage
> >> arch/arm/boot/uImage: u-boot legacy uImage,
> >> Linux-2.6.31-00770-g54c3fe6-dir, Linux/ARM, OS Kernel Image (Not
> >> compressed), 2350016 bytes, Mon Oct 25 16:58:30 2010, Load Address:
> >> 0x40008000, Entry Point: 0x40008000, Header CRC: 0x17A7330B, Data CRC:
> >> 0x888DAA63
> >> 
> >> Anything wrong with the uImage (built with "make uImage") or the
> >> command 'bootm'?

The load and entry point are 0x400...  here

> > 
> > Instead bootm for my uImage works:
> > bootm uImage
> >   Verifying Checksum ... OK
> >   Image Name:   Linux-2.6.32-rc8
> >   Created:      2010-09-27   8:36:01 UTC
> >   Image Type:   ARM Linux Kernel Image (uncompressed)
> >   Data Size:    2058404 Bytes =  2 MB
> >   Load Address: 30008000
> >   Entry Point:  30008000
> > OK

and 0x300.. here


I've no idea how your RAM is mapped, but verify that it is being loaded to the 
correct address. (also check that it's not overlapping your barebox, malloc or 
stack)

> > commandline: console=ttySAC0,115200
> > arch_number: 1999
> > 
> > Starting kernel ...
> 
> Despite of loading kernel is working kernel isn't started for
> mini2440(from u-boot works fine). It hang at:
> Uncompressing
> Linux.....................................................................
> ............................................................. done, booting
> the kernel.

Also enable low level debugging and the earlyprintk in your kernel - maybe the 
kernel is running but crashes before it gets ti initializing the console.


Cheers
Marc



From marek.belisko at gmail.com  Fri Oct 29 04:20:46 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 29 Oct 2010 10:20:46 +0200
Subject: command bootu to start kernel
In-Reply-To: <201010291904.16717.marc@cpdesign.com.au>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
	<201010291904.16717.marc@cpdesign.com.au>
Message-ID: <AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>

On Fri, Oct 29, 2010 at 10:04 AM, Marc Reilly <marc at cpdesign.com.au> wrote:
> Hi,
>
> I have no experience with the mini2440, but:
>
> On Friday, October 29, 2010 06:49:52 pm Belisko Marek wrote:
>> On Fri, Oct 29, 2010 at 8:08 AM, Belisko Marek <marek.belisko at gmail.com>
>> >> me at host$ file arch/arm/boot/uImage
>> >> arch/arm/boot/uImage: u-boot legacy uImage,
>> >> Linux-2.6.31-00770-g54c3fe6-dir, Linux/ARM, OS Kernel Image (Not
>> >> compressed), 2350016 bytes, Mon Oct 25 16:58:30 2010, Load Address:
>> >> 0x40008000, Entry Point: 0x40008000, Header CRC: 0x17A7330B, Data CRC:
>> >> 0x888DAA63
>> >>
>> >> Anything wrong with the uImage (built with "make uImage") or the
>> >> command 'bootm'?
>
> The load and entry point are 0x400... ?here
This post was from Juergen where bootm doesn't work. You're maybe
right wrong load address
is there. For s3c shoudl be 0x30008000 like for working example below.
>
>> >
>> > Instead bootm for my uImage works:
>> > bootm uImage
>> > ? Verifying Checksum ... OK
>> > ? Image Name: ? Linux-2.6.32-rc8
>> > ? Created: ? ? ?2010-09-27 ? 8:36:01 UTC
>> > ? Image Type: ? ARM Linux Kernel Image (uncompressed)
>> > ? Data Size: ? ?2058404 Bytes = ?2 MB
>> > ? Load Address: 30008000
>> > ? Entry Point: ?30008000
>> > OK
>
> and 0x300.. here
>
>
> I've no idea how your RAM is mapped, but verify that it is being loaded to the
> correct address. (also check that it's not overlapping your barebox, malloc or
> stack)
>
>> > commandline: console=ttySAC0,115200
>> > arch_number: 1999
>> >
>> > Starting kernel ...
>>
>> Despite of loading kernel is working kernel isn't started for
>> mini2440(from u-boot works fine). It hang at:
>> Uncompressing
>> Linux.....................................................................
>> ............................................................. done, booting
>> the kernel.
>
> Also enable low level debugging and the earlyprintk in your kernel - maybe the
> kernel is running but crashes before it gets ti initializing the console.
I have 2.6.32 kernel but early_printk isn't available and I enable
lowlevel debugging but
don't get nothing else on console. Anyway thanks.
>
>
> Cheers
> Marc
>
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From baruch at tkos.co.il  Fri Oct 29 04:34:51 2010
From: baruch at tkos.co.il (Baruch Siach)
Date: Fri, 29 Oct 2010 10:34:51 +0200
Subject: command bootu to start kernel
In-Reply-To: <AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
	<201010291904.16717.marc@cpdesign.com.au>
	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>
Message-ID: <20101029083451.GB21232@tarshish>

Hi Belisko,

On Fri, Oct 29, 2010 at 10:20:46AM +0200, Belisko Marek wrote:
> I have 2.6.32 kernel but early_printk isn't available and I enable
> lowlevel debugging but
> don't get nothing else on console. Anyway thanks.

Try this patch to see the low level console output:

commit 5c31454464ed655401c31c68c895b16eafd2bde5
Author: Baruch Siach <baruch at tkos.co.il>
Date:   Mon Jan 19 10:41:47 2009 +0200

    arm, printk: the famous printascii() hack

diff --git a/kernel/printk.c b/kernel/printk.c
index 5052b54..d685f8a 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -685,6 +685,10 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 	/* Emit the output into the temporary buffer */
 	printed_len += vscnprintf(printk_buf + printed_len,
 				  sizeof(printk_buf) - printed_len, fmt, args);
+	{
+		extern void printascii(const char *);
+		printascii(printk_buf);
+	}
 
 
 	/*

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -


From marek.belisko at gmail.com  Fri Oct 29 04:45:23 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 29 Oct 2010 10:45:23 +0200
Subject: command bootu to start kernel
In-Reply-To: <20101029083451.GB21232@tarshish>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
	<201010291904.16717.marc@cpdesign.com.au>
	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>
	<20101029083451.GB21232@tarshish>
Message-ID: <AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>

HI Baruch,

On Fri, Oct 29, 2010 at 10:34 AM, Baruch Siach <baruch at tkos.co.il> wrote:
> Hi Belisko,
>
> On Fri, Oct 29, 2010 at 10:20:46AM +0200, Belisko Marek wrote:
>> I have 2.6.32 kernel but early_printk isn't available and I enable
>> lowlevel debugging but
>> don't get nothing else on console. Anyway thanks.
>
> Try this patch to see the low level console output:
>
> commit 5c31454464ed655401c31c68c895b16eafd2bde5
> Author: Baruch Siach <baruch at tkos.co.il>
> Date: ? Mon Jan 19 10:41:47 2009 +0200
>
> ? ?arm, printk: the famous printascii() hack
>
> diff --git a/kernel/printk.c b/kernel/printk.c
> index 5052b54..d685f8a 100644
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -685,6 +685,10 @@ asmlinkage int vprintk(const char *fmt, va_list args)
> ? ? ? ?/* Emit the output into the temporary buffer */
> ? ? ? ?printed_len += vscnprintf(printk_buf + printed_len,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(printk_buf) - printed_len, fmt, args);
> + ? ? ? {
> + ? ? ? ? ? ? ? extern void printascii(const char *);
> + ? ? ? ? ? ? ? printascii(printk_buf);
> + ? ? ? }
>
>
> ? ? ? ?/*
>
> --
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~. .~ ? Tk Open Systems
> =}------------------------------------------------ooO--U--Ooo------------{=
> ? - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
>
Patch works like charm. Output from my kernel startup:

<5>Linux version 2.6.32-rc8 (open-nandra at linux) (gcc version 4.3.5
(Buildroot 2010.08-rc1) ) #14 Fri Oct 29 10:40:20 CEST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
Memory policy: ECC disabled, Data cache writeback
<7>On node 0 totalpages: 0
<1>bootmem alloc of 32768 bytes failed!
<0>Kernel panic - not syncing: Out of memory


thanks,

marek
-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From mkl at pengutronix.de  Fri Oct 29 04:50:39 2010
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 29 Oct 2010 10:50:39 +0200
Subject: command bootu to start kernel
In-Reply-To: <AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>	<201010291904.16717.marc@cpdesign.com.au>	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>	<20101029083451.GB21232@tarshish>
	<AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>
Message-ID: <4CCA8ADF.2020209@pengutronix.de>

On 10/29/2010 10:45 AM, Belisko Marek wrote:
> HI Baruch,
> 
> On Fri, Oct 29, 2010 at 10:34 AM, Baruch Siach <baruch at tkos.co.il> wrote:
>> Hi Belisko,
>>
>> On Fri, Oct 29, 2010 at 10:20:46AM +0200, Belisko Marek wrote:
>>> I have 2.6.32 kernel but early_printk isn't available and I enable
>>> lowlevel debugging but
>>> don't get nothing else on console. Anyway thanks.
>>
>> Try this patch to see the low level console output:
>>
>> commit 5c31454464ed655401c31c68c895b16eafd2bde5
>> Author: Baruch Siach <baruch at tkos.co.il>
>> Date:   Mon Jan 19 10:41:47 2009 +0200
>>
>>    arm, printk: the famous printascii() hack
>>
>> diff --git a/kernel/printk.c b/kernel/printk.c
>> index 5052b54..d685f8a 100644
>> --- a/kernel/printk.c
>> +++ b/kernel/printk.c
>> @@ -685,6 +685,10 @@ asmlinkage int vprintk(const char *fmt, va_list args)
>>        /* Emit the output into the temporary buffer */
>>        printed_len += vscnprintf(printk_buf + printed_len,
>>                                  sizeof(printk_buf) - printed_len, fmt, args);
>> +       {
>> +               extern void printascii(const char *);
>> +               printascii(printk_buf);
>> +       }
>>
>>
>>        /*
>>
>> --
>>                                                     ~. .~   Tk Open Systems
>> =}------------------------------------------------ooO--U--Ooo------------{=
>>   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
>>
> Patch works like charm. Output from my kernel startup:
> 
> <5>Linux version 2.6.32-rc8 (open-nandra at linux) (gcc version 4.3.5
> (Buildroot 2010.08-rc1) ) #14 Fri Oct 29 10:40:20 CEST 2010
> CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
> CPU: VIVT data cache, VIVT instruction cache
> Machine: MINI2440
> Memory policy: ECC disabled, Data cache writeback
> <7>On node 0 totalpages: 0
> <1>bootmem alloc of 32768 bytes failed!
> <0>Kernel panic - not syncing: Out of memory

do you have a "MEM=32" on your command line?

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20101029/da333637/attachment.sig>

From marek.belisko at gmail.com  Fri Oct 29 05:04:08 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 29 Oct 2010 11:04:08 +0200
Subject: command bootu to start kernel
In-Reply-To: <4CCA8ADF.2020209@pengutronix.de>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
	<201010291904.16717.marc@cpdesign.com.au>
	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>
	<20101029083451.GB21232@tarshish>
	<AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>
	<4CCA8ADF.2020209@pengutronix.de>
Message-ID: <AANLkTi==CwV+WZZ5Mb=1+usVAheaEi11F+=KDf=drXQp@mail.gmail.com>

On Fri, Oct 29, 2010 at 10:50 AM, Marc Kleine-Budde <mkl at pengutronix.de> wrote:
> On 10/29/2010 10:45 AM, Belisko Marek wrote:
>> HI Baruch,
>>
>> On Fri, Oct 29, 2010 at 10:34 AM, Baruch Siach <baruch at tkos.co.il> wrote:
>>> Hi Belisko,
>>>
>>> On Fri, Oct 29, 2010 at 10:20:46AM +0200, Belisko Marek wrote:
>>>> I have 2.6.32 kernel but early_printk isn't available and I enable
>>>> lowlevel debugging but
>>>> don't get nothing else on console. Anyway thanks.
>>>
>>> Try this patch to see the low level console output:
>>>
>>> commit 5c31454464ed655401c31c68c895b16eafd2bde5
>>> Author: Baruch Siach <baruch at tkos.co.il>
>>> Date: ? Mon Jan 19 10:41:47 2009 +0200
>>>
>>> ? ?arm, printk: the famous printascii() hack
>>>
>>> diff --git a/kernel/printk.c b/kernel/printk.c
>>> index 5052b54..d685f8a 100644
>>> --- a/kernel/printk.c
>>> +++ b/kernel/printk.c
>>> @@ -685,6 +685,10 @@ asmlinkage int vprintk(const char *fmt, va_list args)
>>> ? ? ? ?/* Emit the output into the temporary buffer */
>>> ? ? ? ?printed_len += vscnprintf(printk_buf + printed_len,
>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(printk_buf) - printed_len, fmt, args);
>>> + ? ? ? {
>>> + ? ? ? ? ? ? ? extern void printascii(const char *);
>>> + ? ? ? ? ? ? ? printascii(printk_buf);
>>> + ? ? ? }
>>>
>>>
>>> ? ? ? ?/*
>>>
>>> --
>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~. .~ ? Tk Open Systems
>>> =}------------------------------------------------ooO--U--Ooo------------{=
>>> ? - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
>>>
>> Patch works like charm. Output from my kernel startup:
>>
>> <5>Linux version 2.6.32-rc8 (open-nandra at linux) (gcc version 4.3.5
>> (Buildroot 2010.08-rc1) ) #14 Fri Oct 29 10:40:20 CEST 2010
>> CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
>> CPU: VIVT data cache, VIVT instruction cache
>> Machine: MINI2440
>> Memory policy: ECC disabled, Data cache writeback
>> <7>On node 0 totalpages: 0
>> <1>bootmem alloc of 32768 bytes failed!
>> <0>Kernel panic - not syncing: Out of memory
>
> do you have a "MEM=32" on your command line?
Well I add it but same result:
bootz zImage
loaded zImage from zImage with size 2059064
commandline: console=ttySAC0,115200 mem=32
arch_number: 1999
Uncompressing Linux..................................................................................................................................
done, booting the kernel.
<5>Linux version 2.6.32-rc8 (open-nandra at linux) (gcc version 4.3.5
(Buildroot 2010.08-rc1) ) #14 Fri Oct 29 10:40:20 CEST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
Memory policy: ECC disabled, Data cache writeback
<7>On node 0 totalpages: 0
<1>bootmem alloc of 32768 bytes failed!
<0>Kernel panic - not syncing: Out of memory
>
> Marc
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ?| Marc Kleine-Budde ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ?| Phone: +49-231-2826-924 ? ? |
> Vertretung West/Dortmund ? ? ? ? ?| Fax: ? +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 ?| http://www.pengutronix.de ? |
>
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From mkl at pengutronix.de  Fri Oct 29 05:12:00 2010
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 29 Oct 2010 11:12:00 +0200
Subject: command bootu to start kernel
In-Reply-To: <AANLkTi==CwV+WZZ5Mb=1+usVAheaEi11F+=KDf=drXQp@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>	<201010291904.16717.marc@cpdesign.com.au>	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>	<20101029083451.GB21232@tarshish>	<AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>	<4CCA8ADF.2020209@pengutronix.de>
	<AANLkTi==CwV+WZZ5Mb=1+usVAheaEi11F+=KDf=drXQp@mail.gmail.com>
Message-ID: <4CCA8FE0.3080006@pengutronix.de>

On 10/29/2010 11:04 AM, Belisko Marek wrote:
> On Fri, Oct 29, 2010 at 10:50 AM, Marc Kleine-Budde <mkl at pengutronix.de> wrote:
>> On 10/29/2010 10:45 AM, Belisko Marek wrote:
>>> HI Baruch,
>>>
>>> On Fri, Oct 29, 2010 at 10:34 AM, Baruch Siach <baruch at tkos.co.il> wrote:
>>>> Hi Belisko,
>>>>
>>>> On Fri, Oct 29, 2010 at 10:20:46AM +0200, Belisko Marek wrote:
>>>>> I have 2.6.32 kernel but early_printk isn't available and I enable
>>>>> lowlevel debugging but
>>>>> don't get nothing else on console. Anyway thanks.
>>>>
>>>> Try this patch to see the low level console output:
>>>>
>>>> commit 5c31454464ed655401c31c68c895b16eafd2bde5
>>>> Author: Baruch Siach <baruch at tkos.co.il>
>>>> Date:   Mon Jan 19 10:41:47 2009 +0200
>>>>
>>>>    arm, printk: the famous printascii() hack
>>>>
>>>> diff --git a/kernel/printk.c b/kernel/printk.c
>>>> index 5052b54..d685f8a 100644
>>>> --- a/kernel/printk.c
>>>> +++ b/kernel/printk.c
>>>> @@ -685,6 +685,10 @@ asmlinkage int vprintk(const char *fmt, va_list args)
>>>>        /* Emit the output into the temporary buffer */
>>>>        printed_len += vscnprintf(printk_buf + printed_len,
>>>>                                  sizeof(printk_buf) - printed_len, fmt, args);
>>>> +       {
>>>> +               extern void printascii(const char *);
>>>> +               printascii(printk_buf);
>>>> +       }
>>>>
>>>>
>>>>        /*
>>>>
>>>> --
>>>>                                                     ~. .~   Tk Open Systems
>>>> =}------------------------------------------------ooO--U--Ooo------------{=
>>>>   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
>>>>
>>> Patch works like charm. Output from my kernel startup:
>>>
>>> <5>Linux version 2.6.32-rc8 (open-nandra at linux) (gcc version 4.3.5
>>> (Buildroot 2010.08-rc1) ) #14 Fri Oct 29 10:40:20 CEST 2010
>>> CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
>>> CPU: VIVT data cache, VIVT instruction cache
>>> Machine: MINI2440
>>> Memory policy: ECC disabled, Data cache writeback
>>> <7>On node 0 totalpages: 0
>>> <1>bootmem alloc of 32768 bytes failed!
>>> <0>Kernel panic - not syncing: Out of memory
>>
>> do you have a "MEM=32" on your command line?
> Well I add it but same result:

BTW: It must be "mem=", in lowercase, but you did this.

What I was meant to ask was, if you forget to add the "M" to "32".
Because with mem=32 you tell Linux just to use 32 bytes of memory. Maybe
your ATAGs are broken, Linux might not see the whole RAM or any if it.

Cheers, Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20101029/388eb9aa/attachment.sig>

From marek.belisko at gmail.com  Fri Oct 29 05:21:16 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 29 Oct 2010 11:21:16 +0200
Subject: command bootu to start kernel
In-Reply-To: <4CCA8FE0.3080006@pengutronix.de>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
	<201010291904.16717.marc@cpdesign.com.au>
	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>
	<20101029083451.GB21232@tarshish>
	<AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>
	<4CCA8ADF.2020209@pengutronix.de>
	<AANLkTi==CwV+WZZ5Mb=1+usVAheaEi11F+=KDf=drXQp@mail.gmail.com>
	<4CCA8FE0.3080006@pengutronix.de>
Message-ID: <AANLkTi=69fM38iyvP3VbwvYYqif7FfvTHCnyuzHuwpho@mail.gmail.com>

On Fri, Oct 29, 2010 at 11:12 AM, Marc Kleine-Budde <mkl at pengutronix.de> wrote:
> On 10/29/2010 11:04 AM, Belisko Marek wrote:
>> On Fri, Oct 29, 2010 at 10:50 AM, Marc Kleine-Budde <mkl at pengutronix.de> wrote:
>>> On 10/29/2010 10:45 AM, Belisko Marek wrote:
>>>> HI Baruch,
>>>>
>>>> On Fri, Oct 29, 2010 at 10:34 AM, Baruch Siach <baruch at tkos.co.il> wrote:
>>>>> Hi Belisko,
>>>>>
>>>>> On Fri, Oct 29, 2010 at 10:20:46AM +0200, Belisko Marek wrote:
>>>>>> I have 2.6.32 kernel but early_printk isn't available and I enable
>>>>>> lowlevel debugging but
>>>>>> don't get nothing else on console. Anyway thanks.
>>>>>
>>>>> Try this patch to see the low level console output:
>>>>>
>>>>> commit 5c31454464ed655401c31c68c895b16eafd2bde5
>>>>> Author: Baruch Siach <baruch at tkos.co.il>
>>>>> Date: ? Mon Jan 19 10:41:47 2009 +0200
>>>>>
>>>>> ? ?arm, printk: the famous printascii() hack
>>>>>
>>>>> diff --git a/kernel/printk.c b/kernel/printk.c
>>>>> index 5052b54..d685f8a 100644
>>>>> --- a/kernel/printk.c
>>>>> +++ b/kernel/printk.c
>>>>> @@ -685,6 +685,10 @@ asmlinkage int vprintk(const char *fmt, va_list args)
>>>>> ? ? ? ?/* Emit the output into the temporary buffer */
>>>>> ? ? ? ?printed_len += vscnprintf(printk_buf + printed_len,
>>>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(printk_buf) - printed_len, fmt, args);
>>>>> + ? ? ? {
>>>>> + ? ? ? ? ? ? ? extern void printascii(const char *);
>>>>> + ? ? ? ? ? ? ? printascii(printk_buf);
>>>>> + ? ? ? }
>>>>>
>>>>>
>>>>> ? ? ? ?/*
>>>>>
>>>>> --
>>>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~. .~ ? Tk Open Systems
>>>>> =}------------------------------------------------ooO--U--Ooo------------{=
>>>>> ? - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
>>>>>
>>>> Patch works like charm. Output from my kernel startup:
>>>>
>>>> <5>Linux version 2.6.32-rc8 (open-nandra at linux) (gcc version 4.3.5
>>>> (Buildroot 2010.08-rc1) ) #14 Fri Oct 29 10:40:20 CEST 2010
>>>> CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
>>>> CPU: VIVT data cache, VIVT instruction cache
>>>> Machine: MINI2440
>>>> Memory policy: ECC disabled, Data cache writeback
>>>> <7>On node 0 totalpages: 0
>>>> <1>bootmem alloc of 32768 bytes failed!
>>>> <0>Kernel panic - not syncing: Out of memory
>>>
>>> do you have a "MEM=32" on your command line?
>> Well I add it but same result:
>
> BTW: It must be "mem=", in lowercase, but you did this.
>
> What I was meant to ask was, if you forget to add the "M" to "32".
> Because with mem=32 you tell Linux just to use 32 bytes of memory. Maybe
> your ATAGs are broken, Linux might not see the whole RAM or any if it.
yes it was typo I forgot put M after 32. Kernel now properly boot :).
U-boot somehow
add kernel this parameter? Because for u-boot I don't need to set this
parameter.
>
> Cheers, Marc
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ?| Marc Kleine-Budde ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ?| Phone: +49-231-2826-924 ? ? |
> Vertretung West/Dortmund ? ? ? ? ?| Fax: ? +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 ?| http://www.pengutronix.de ? |
>
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From mkl at pengutronix.de  Fri Oct 29 05:26:14 2010
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 29 Oct 2010 11:26:14 +0200
Subject: command bootu to start kernel
In-Reply-To: <AANLkTi=69fM38iyvP3VbwvYYqif7FfvTHCnyuzHuwpho@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>	<201010291904.16717.marc@cpdesign.com.au>	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>	<20101029083451.GB21232@tarshish>	<AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>	<4CCA8ADF.2020209@pengutronix.de>	<AANLkTi==CwV+WZZ5Mb=1+usVAheaEi11F+=KDf=drXQp@mail.gmail.com>	<4CCA8FE0.3080006@pengutronix.de>
	<AANLkTi=69fM38iyvP3VbwvYYqif7FfvTHCnyuzHuwpho@mail.gmail.com>
Message-ID: <4CCA9336.8030807@pengutronix.de>

On 10/29/2010 11:21 AM, Belisko Marek wrote:
>>>> do you have a "MEM=32" on your command line?
>>> Well I add it but same result:
>>
>> BTW: It must be "mem=", in lowercase, but you did this.
>>
>> What I was meant to ask was, if you forget to add the "M" to "32".
>> Because with mem=32 you tell Linux just to use 32 bytes of memory. Maybe
>> your ATAGs are broken, Linux might not see the whole RAM or any if it.

> yes it was typo I forgot put M after 32. Kernel now properly boot :).

How much RAM you you have? Adjust mem= accordingly.

> U-boot somehow
> add kernel this parameter? Because for u-boot I don't need to set this
> parameter.

Nope - u-boot and barebox set up this information in the ATAG list.
Seems something is broken with your ATAG list.

cheers, Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20101029/3d12abac/attachment-0001.sig>

From u.kleine-koenig at pengutronix.de  Fri Oct 29 05:30:32 2010
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Fri, 29 Oct 2010 11:30:32 +0200
Subject: command bootu to start kernel
In-Reply-To: <4CCA9336.8030807@pengutronix.de>
References: <AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
	<201010291904.16717.marc@cpdesign.com.au>
	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>
	<20101029083451.GB21232@tarshish>
	<AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>
	<4CCA8ADF.2020209@pengutronix.de>
	<AANLkTi==CwV+WZZ5Mb=1+usVAheaEi11F+=KDf=drXQp@mail.gmail.com>
	<4CCA8FE0.3080006@pengutronix.de>
	<AANLkTi=69fM38iyvP3VbwvYYqif7FfvTHCnyuzHuwpho@mail.gmail.com>
	<4CCA9336.8030807@pengutronix.de>
Message-ID: <20101029093032.GJ31158@pengutronix.de>

On Fri, Oct 29, 2010 at 11:26:14AM +0200, Marc Kleine-Budde wrote:
> On 10/29/2010 11:21 AM, Belisko Marek wrote:
> >>>> do you have a "MEM=32" on your command line?
> >>> Well I add it but same result:
> >>
> >> BTW: It must be "mem=", in lowercase, but you did this.
> >>
> >> What I was meant to ask was, if you forget to add the "M" to "32".
> >> Because with mem=32 you tell Linux just to use 32 bytes of memory. Maybe
> >> your ATAGs are broken, Linux might not see the whole RAM or any if it.
> 
> > yes it was typo I forgot put M after 32. Kernel now properly boot :).
> 
> How much RAM you you have? Adjust mem= accordingly.
> 
> > U-boot somehow
> > add kernel this parameter? Because for u-boot I don't need to set this
> > parameter.
> 
> Nope - u-boot and barebox set up this information in the ATAG list.
> Seems something is broken with your ATAG list.
It's setup in setup_memory_tags (arch/arm/lib/armlinux.c).  So you
probably need to call armlinux_add_dram.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From marek.belisko at gmail.com  Fri Oct 29 05:31:53 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 29 Oct 2010 11:31:53 +0200
Subject: command bootu to start kernel
In-Reply-To: <4CCA9336.8030807@pengutronix.de>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<AANLkTim9C1gxiGNj3gyso0aqcM_r1qxf0M3dDCWDmMMO@mail.gmail.com>
	<AANLkTikBmg33g-Uh=_fEtvkN6n6GZAi71Lc5tFm51yjJ@mail.gmail.com>
	<201010291904.16717.marc@cpdesign.com.au>
	<AANLkTikYV-vFVU-QF09yC-wzF5nSDmcy1rG0xz2WJLpj@mail.gmail.com>
	<20101029083451.GB21232@tarshish>
	<AANLkTim_NDWXcHj7oPuaTMymHKVtMZCnmCKwVkKuLFBJ@mail.gmail.com>
	<4CCA8ADF.2020209@pengutronix.de>
	<AANLkTi==CwV+WZZ5Mb=1+usVAheaEi11F+=KDf=drXQp@mail.gmail.com>
	<4CCA8FE0.3080006@pengutronix.de>
	<AANLkTi=69fM38iyvP3VbwvYYqif7FfvTHCnyuzHuwpho@mail.gmail.com>
	<4CCA9336.8030807@pengutronix.de>
Message-ID: <AANLkTinXMoAtEAS6hifvFhoxFUETSsqTBX+s01rJ9c3F@mail.gmail.com>

On Fri, Oct 29, 2010 at 11:26 AM, Marc Kleine-Budde <mkl at pengutronix.de> wrote:
> On 10/29/2010 11:21 AM, Belisko Marek wrote:
>>>>> do you have a "MEM=32" on your command line?
>>>> Well I add it but same result:
>>>
>>> BTW: It must be "mem=", in lowercase, but you did this.
>>>
>>> What I was meant to ask was, if you forget to add the "M" to "32".
>>> Because with mem=32 you tell Linux just to use 32 bytes of memory. Maybe
>>> your ATAGs are broken, Linux might not see the whole RAM or any if it.
>
>> yes it was typo I forgot put M after 32. Kernel now properly boot :).
>
> How much RAM you you have? Adjust mem= accordingly.
Have 64M I will adjust.
>
>> U-boot somehow
>> add kernel this parameter? Because for u-boot I don't need to set this
>> parameter.
>
> Nope - u-boot and barebox set up this information in the ATAG list.
> Seems something is broken with your ATAG list.
Could be a problem thats I load barebox directly to ram and run it and
then RAM size isn't probed
and correctly set in atags?
>
> cheers, Marc
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ?| Marc Kleine-Budde ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ?| Phone: +49-231-2826-924 ? ? |
> Vertretung West/Dortmund ? ? ? ? ?| Fax: ? +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 ?| http://www.pengutronix.de ? |
>
>

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From jbe at pengutronix.de  Fri Oct 29 08:36:18 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 29 Oct 2010 14:36:18 +0200
Subject: command bootu to start kernel
In-Reply-To: <AANLkTinXMoAtEAS6hifvFhoxFUETSsqTBX+s01rJ9c3F@mail.gmail.com>
References: <AANLkTimj3WiRQaeP+tQ7-AHy3WcVG0MKpwt5uNfo_cWf@mail.gmail.com>
	<4CCA9336.8030807@pengutronix.de>
	<AANLkTinXMoAtEAS6hifvFhoxFUETSsqTBX+s01rJ9c3F@mail.gmail.com>
Message-ID: <201010291436.18901.jbe@pengutronix.de>

Belisko Marek wrote:
> On Fri, Oct 29, 2010 at 11:26 AM, Marc Kleine-Budde <mkl at pengutronix.de> 
wrote:
> > On 10/29/2010 11:21 AM, Belisko Marek wrote:
> >>>>> do you have a "MEM=32" on your command line?
> >>>>
> >>>> Well I add it but same result:
> >>>
> >>> BTW: It must be "mem=", in lowercase, but you did this.
> >>>
> >>> What I was meant to ask was, if you forget to add the "M" to "32".
> >>> Because with mem=32 you tell Linux just to use 32 bytes of memory.
> >>> Maybe your ATAGs are broken, Linux might not see the whole RAM or any
> >>> if it.
> >>
> >> yes it was typo I forgot put M after 32. Kernel now properly boot :).
> >
> > How much RAM you you have? Adjust mem= accordingly.
>
> Have 64M I will adjust.
>
> >> U-boot somehow
> >> add kernel this parameter? Because for u-boot I don't need to set this
> >> parameter.
> >
> > Nope - u-boot and barebox set up this information in the ATAG list.
> > Seems something is broken with your ATAG list.
>
> Could be a problem thats I load barebox directly to ram and run it and
> then RAM size isn't probed
> and correctly set in atags?

No, you need something like that:

[...]
static struct memory_platform_data ram_pdata = {
	.name		= "ram0",
	.flags		= DEVFS_RDWR,
};

struct device_d mini_sdram_dev = {
	.id		= -1,
	.name		= "mem",
	.map_base	= CS6_BASE,
	.size		= 64 * 1024 * 1024,
	.platform_data	= &ram_pdata,
};

[...]

static int mini2440_devices_init(void)
{
[...]
	register_device(&mini2440_sdram_dev);
[...]
	armlinux_add_dram(&mini2440_sdram_dev);
[...]
}

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 29 15:36:26 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 29 Oct 2010 21:36:26 +0200
Subject: [PATCH] MCI: Add some doc how to handle MCI cards
Message-ID: <201010292136.26904.jbe@pengutronix.de>

From: Juergen Beisert <juergen at kreuzholzen.de>
Subject: [PATCH] MCI: Add some doc how to handle MCI cards

Signed-off-by: Juergen Beisert <juergen at kreuzholzen.de>

---
 Documentation/developers_manual.dox |    1 
 Documentation/users_manual.dox      |    1 
 drivers/mci/mci-core.c              |  117 ++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+)

Index: barebox-2010.10.0/Documentation/developers_manual.dox
===================================================================
--- barebox-2010.10.0.orig/Documentation/developers_manual.dox
+++ barebox-2010.10.0/Documentation/developers_manual.dox
@@ -18,6 +18,7 @@ This part of the documentation is intend
 @li @subpage how_mount_works
 @li @subpage boot_preparation
 @li @subpage barebox_simul
+ at li @subpage mci_for_developers
 @li @subpage io_access_functions
 @li @subpage mcfv4e_MCDlib
 
Index: barebox-2010.10.0/Documentation/users_manual.dox
===================================================================
--- barebox-2010.10.0.orig/Documentation/users_manual.dox
+++ barebox-2010.10.0/Documentation/users_manual.dox
@@ -9,6 +9,7 @@ work easier.
 @li @subpage shell_notes
 @li @subpage readline_parser
 @li @subpage command_reference
+ at li @subpage mci_for_users
 @li @subpage x86_bootloader
 @li @subpage net_netconsole
 
Index: barebox-2010.10.0/drivers/mci/mci-core.c
===================================================================
--- barebox-2010.10.0.orig/drivers/mci/mci-core.c
+++ barebox-2010.10.0/drivers/mci/mci-core.c
@@ -1358,3 +1358,120 @@ int mci_register(struct mci_host *host)
 
 	return register_device(mci_dev);
 }
+
+/**
+ * @page mci_for_developers MCI information for developers
+ *
+ * Pay attention
+ * - Provide a MCI clock to let the card do its reset
+ * - Provide power supply to the socket. There is no callback in the generic
+ *   driver to do so
+ *
+ * If your MCI host hardware is slow, you should avoid the card probing at system
+ * startup. Do it on demand only in this case. This can be achieved by disabling
+ * the MCI_STARTUP menu entry.
+ */
+
+/**
+ at page mci_for_users MCI cards for users
+
+MCI cards are handled like regular disks in @b barebox. When a card is detected,
+access gets added to the system as @b /dev/disk0. If @b barebox detects a partition
+table in the first sector, it also adds these partitions as @b /dev/disk0.0,
+ at b dev/disk0.1 and so on.
+
+All these disk devices can be used with the command @b md, @b mw, @b cp,
+ at b bootm in a regular manner.
+
+ at verbatim
+barebox:/ devinfo
+devices:
+|----s3c24x0_serial0
+|----cs0
+|----ramfs0
+|----devfs0
+|----mem0 (defaultenv)
+|----mem1 (mem)
+|----s3c_mci0
+|----disk0 (disk0, disk0.0)
+|----s3cfb0
+|----framebuffer0 (fb0)
+|----s3c24x0_nand0
+|----nand0 (nand0, nand_oob0, self_raw, env_raw, nand0.uboot, nand0.ubootenv, nand0.kernel, nand0.root)
+|----mem2 (ram0)
+|----cs89000
+|----eth0
+
+drivers:
+s3c24x0_serial
+     ramfs
+     devfs
+    cs8900
+s3c24x0_nand
+      disk
+framebuffer
+     s3cfb
+   s3c_mci
+       mem
+ at endverbatim
+
+The device in question is the @b mci0. Run the @b devinfo command again on this device.
+
+ at verbatim
+barebox:/ devinfo mci0
+base  : 0x00000000
+size  : 0x3d600000
+driver: mci
+
+ Card:
+  Attached is an SD Card (Version: 2.0)
+  Capacity: 982 MiB
+   CID: 1C535653-44432020-10000000-1800849F
+   CSD: 005E0032-5F5983D5-EDB7FF9F-964000C1
+  Max. transfer speed: 25000000 Hz
+  Manufacturer ID: 1C
+  OEM/Application ID: 5356
+  Product name: 'SDC  '
+  Product revision: 1.0
+  Serial no: 24
+  Manufacturing date: 4.2008
+no parameters available
+ at endverbatim
+
+In this case probing the MCI card has successfully happen at system startup. Probing
+at this early point of time can be necessary for systems that depends on data from
+this kind of storage (for example if the persistant environment is stored on the
+MCI card).
+
+As probing an MCI card may take some seconds, it could be useful to do this
+on demand only (if not otherwise required). In this case the @b devinfo
+shows different information about the MCI card prior probing:
+
+ at verbatim
+barebox:/ devinfo mci0
+base  : 0x00000000
+size  : 0x00000000
+driver: mci
+
+ Card:
+   Not probed yet.
+
+parameters
+     probe = 0
+ at endverbatim
+
+ at note The MCI card should already be inserted when powering the system, as
+ at b barebox does not support runtime power supply switching.
+
+To do the MCI card probing right now, just enter:
+ at verbatim
+barebox:/ mci0.probe=1
+ at endverbatim
+
+ at note @b barebox currently cannot really cope with hot plug (its a bootloader only,
+not an operating system...). So, unplugging the already probed card and replacing
+it by another one and also probing this new card may crash your system (and might
+also destroy the MCI card, as unplugging and plugging happens while the socket is
+"hot").
+
+*/

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From bogus@does.not.exist.com  Fri Oct 22 17:57:35 2010
From: bogus@does.not.exist.com ()
Date: Fri, 22 Oct 2010 21:57:35 -0000
Subject: No subject
Message-ID: <mailman.45.1292053196.1530.barebox@lists.infradead.org>

Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
---
 arch/arm/mach-imx/include/mach/imx-regs.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx-regs.h b/arch/arm/mach-imx/include/mach/imx-regs.h
index 605d320..a234621 100644
--- a/arch/arm/mach-imx/include/mach/imx-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx-regs.h
@@ -57,6 +57,10 @@
 # error "unknown i.MX soc type"
 #endif
 
+/* There's a off-by-one betweem the gpio bank number and the gpiochip */
+/* range e.g. GPIO_1_5 is gpio 5 under linux */
+#define IMX_GPIO_NR(bank, nr)		(((bank) - 1) * 32 + (nr))
+
 #define GPIO_PIN_MASK 0x1f
 
 #define GPIO_PORT_SHIFT 5
-- 
1.7.1



From bogus@does.not.exist.com  Fri Oct 22 17:57:35 2010
From: bogus@does.not.exist.com ()
Date: Fri, 22 Oct 2010 21:57:35 -0000
Subject: No subject
Message-ID: <mailman.176.1300720752.1530.barebox@lists.infradead.org>

i.MX27 boot from internal ROM. According to the document, the ROM code take=
s care about the initial reset before loading the first page of code from t=
he NAND flash.
I'm however a little concerned about this figure in the document :

[cid:image002.png at 01CBE7E3.B1A2CCA0]

If I understand well, this should be the structure of the 2K NFC buffer whe=
n booting from internal ROM. I don't think this will be the structure when =
loading the first page of Barebox code, correct ?
Anyone familiar with this Micron specific flash problem ? And the consequen=
ces for Barebox ? Do we have to make modifications in the Barebox code to t=
ackle this ?

(because the Freescale document is rather WinCE related, I'm not sure this =
also applies to Barebox/Linux based systems...)

I hope we didn't make a bad choice of NAND flash in combination with i.MX27=
... ? ;-)


Best Regards,

Filip


(Btw : anyone can tell me what CSF and DCD stand for... ? Did not find any =
explanations in the i.MX27 reference manual yet)

--_000_6EE7D1502C48E44E92DCADF9DD3E0DB9017FF3BF5211SRVVS06TELE_
Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
//www.w3.org/TR/REC-html40"><head><meta http-equiv=3DContent-Type content=
=3D"text/html; charset=3Dus-ascii"><meta name=3DGenerator content=3D"Micros=
oft Word 12 (filtered medium)"><!--[if !mso]><style>v\:* {behavior:url(#def=
ault#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
	{font-family:"Cambria Math";
	panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
	{font-family:Tahoma;
	panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0cm;
	margin-bottom:.0001pt;
	font-size:11.0pt;
	font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
	{mso-style-priority:99;
	color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{mso-style-priority:99;
	color:purple;
	text-decoration:underline;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
	{mso-style-priority:99;
	mso-style-link:"Balloon Text Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:8.0pt;
	font-family:"Tahoma","sans-serif";}
span.EmailStyle17
	{mso-style-type:personal-compose;
	font-family:"Arial","sans-serif";
	color:windowtext;}
span.BalloonTextChar
	{mso-style-name:"Balloon Text Char";
	mso-style-priority:99;
	mso-style-link:"Balloon Text";
	font-family:"Tahoma","sans-serif";}
.MsoChpDefault
	{mso-style-type:export-only;}
@page WordSection1
	{size:612.0pt 792.0pt;
	margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
	{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"2050" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]--></head><body lang=3DNL link=3Dblue vlink=
=3Dpurple><div class=3DWordSection1><p class=3DMsoNormal><span style=3D'fon=
t-size:10.0pt;font-family:"Arial","sans-serif"'>Hi,<o:p></o:p></span></p><p=
 class=3DMsoNormal><span style=3D'font-size:10.0pt;font-family:"Arial","san=
s-serif"'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span lang=3DEN-=
US style=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'>On our own i=
.MX27 based boards, we have Micron NAND flash memory (MT29F2G08ABBEAH4). Be=
sides the BI-swapping problem for 2K NAND flashes, I can see that this chip=
 needs an initial reset command before it becomes operational. This is some=
thing that has to be done in the early boot code, so before loading the fir=
st page of bootloader code (the reset should be sent before the first page =
of code can be read from flash).<o:p></o:p></span></p><p class=3DMsoNormal>=
<span lang=3DEN-US style=3D'font-size:10.0pt;font-family:"Arial","sans-seri=
f"'>From Freescale doc, I found that we have to blow certain fuses to make =
the i.MX27 boot from internal ROM. According to the document, the ROM code =
takes care about the initial reset before loading the first page of code fr=
om the NAND flash.<o:p></o:p></span></p><p class=3DMsoNormal><span lang=3DE=
N-US style=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'>I&#8217;m =
however a little concerned about this figure in the document :<o:p></o:p></=
span></p><p class=3DMsoNormal><span lang=3DEN-US style=3D'font-size:10.0pt;=
font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p><p class=3DMs=
oNormal><span style=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'><=
img width=3D494 height=3D458 id=3D"Picture_x0020_1" src=3D"cid:image002.png=
@01CBE7E3.B1A2CCA0"></span><span lang=3DEN-US style=3D'font-size:10.0pt;fon=
t-family:"Arial","sans-serif"'><o:p></o:p></span></p><p class=3DMsoNormal><=
span lang=3DEN-US style=3D'font-size:10.0pt;font-family:"Arial","sans-serif=
"'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span lang=3DEN-US styl=
e=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'>If I understand wel=
l, this should be the structure of the 2K NFC buffer when booting from inte=
rnal ROM. I don&#8217;t think this will be the structure when loading the f=
irst page of Barebox code, correct ?<o:p></o:p></span></p><p class=3DMsoNor=
mal><span lang=3DEN-US style=3D'font-size:10.0pt;font-family:"Arial","sans-=
serif"'>Anyone familiar with this Micron specific flash problem ? And the c=
onsequences for Barebox ? Do we have to make modifications in the Barebox c=
ode to tackle this ?<o:p></o:p></span></p><p class=3DMsoNormal><span lang=
=3DEN-US style=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&=
nbsp;</o:p></span></p><p class=3DMsoNormal><span lang=3DEN-US style=3D'font=
-size:10.0pt;font-family:"Arial","sans-serif"'>(because the Freescale docum=
ent is rather WinCE related, I&#8217;m not sure this also applies to Barebo=
x/Linux based systems&#8230;)<o:p></o:p></span></p><p class=3DMsoNormal><sp=
an lang=3DEN-US style=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'=
><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span lang=3DEN-US style=
=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'>I hope we didn&#8217=
;t make a bad choice of NAND flash in combination with i.MX27&#8230; ? ;-)<=
o:p></o:p></span></p><p class=3DMsoNormal><span lang=3DEN-US style=3D'font-=
size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p><=
p class=3DMsoNormal><span lang=3DEN-US style=3D'font-size:10.0pt;font-famil=
y:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><s=
pan lang=3DEN-US style=3D'font-size:10.0pt;font-family:"Arial","sans-serif"=
'>Best Regards,<o:p></o:p></span></p><p class=3DMsoNormal><span lang=3DEN-U=
S style=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</=
o:p></span></p><p class=3DMsoNormal><span lang=3DEN-US style=3D'font-size:1=
0.0pt;font-family:"Arial","sans-serif"'>Filip<o:p></o:p></span></p><p class=
=3DMsoNormal><span lang=3DEN-US style=3D'font-size:10.0pt;font-family:"Aria=
l","sans-serif"'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span lan=
g=3DEN-US style=3D'font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>=
&nbsp;</o:p></span></p><p class=3DMsoNormal><span lang=3DEN-US style=3D'fon=
t-size:10.0pt;font-family:"Arial","sans-serif"'>(Btw : anyone can tell me w=
hat CSF and DCD stand for&#8230; ? Did not find any explanations in the i.M=
X27 reference manual yet)<o:p></o:p></span></p></div></body></html>=

--_000_6EE7D1502C48E44E92DCADF9DD3E0DB9017FF3BF5211SRVVS06TELE_--

--_004_6EE7D1502C48E44E92DCADF9DD3E0DB9017FF3BF5211SRVVS06TELE_
Content-Type: image/png; name="image002.png"
Content-Description: image002.png
Content-Disposition: inline; filename="image002.png"; size=51367;
	creation-date="Mon, 21 Mar 2011 16:19:03 GMT";
	modification-date="Mon, 21 Mar 2011 16:19:03 GMT"
Content-ID: <image002.png at 01CBE7E3.B1A2CCA0>
Content-Transfer-Encoding: base64

[encoded data, 69377 characters]
AABJRU5ErkJggg==

--_004_6EE7D1502C48E44E92DCADF9DD3E0DB9017FF3BF5211SRVVS06TELE_--


