summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-11-02 18:05:32 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2010-11-02 18:05:32 +0100
commit3d4f24ef0bc1d00577b87ec216cec61bbf34a4ec (patch)
treefa52777dc46e18e70f798e3f130e3b43c5cea2c4
parentd1209136e304faab8616f75a347bf2d02d283468 (diff)
parent4bfc616111c836c3e33fdc759ed5224dfc68f06b (diff)
downloadbarebox-3d4f24ef0bc1d00577b87ec216cec61bbf34a4ec.tar.gz
barebox-3d4f24ef0bc1d00577b87ec216cec61bbf34a4ec.tar.xz
Merge branch 'next'
-rw-r--r--Documentation/barebox-main.dox232
-rw-r--r--Documentation/boards.dox6
-rw-r--r--Documentation/building.dox60
-rw-r--r--Documentation/commands.dox30
-rw-r--r--Documentation/developers_manual.dox1
-rw-r--r--Documentation/first_steps.dox61
-rw-r--r--Documentation/users_manual.dox14
-rw-r--r--Doxyfile27
-rw-r--r--arch/arm/Kconfig6
-rw-r--r--arch/arm/Makefile5
-rw-r--r--arch/arm/boards/chumby_falconwing/Makefile1
-rw-r--r--arch/arm/boards/chumby_falconwing/config.h21
-rw-r--r--arch/arm/boards/chumby_falconwing/env/bin/boot38
-rw-r--r--arch/arm/boards/chumby_falconwing/env/bin/init15
-rw-r--r--arch/arm/boards/chumby_falconwing/env/config36
-rw-r--r--arch/arm/boards/chumby_falconwing/falconwing.c350
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/env/bin/init2
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/env/config2
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c95
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/lowlevel.c64
-rw-r--r--arch/arm/boards/eukrea_cpuimx27/env/bin/boot12
-rw-r--r--arch/arm/boards/eukrea_cpuimx27/env/bin/init10
-rw-r--r--arch/arm/boards/eukrea_cpuimx27/env/config11
-rw-r--r--arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c5
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/env/bin/init4
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/env/config2
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c90
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/flash_header.c24
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/lowlevel.c20
-rw-r--r--arch/arm/boards/freescale-mx23-evk/Makefile2
-rw-r--r--arch/arm/boards/freescale-mx23-evk/config.h16
-rw-r--r--arch/arm/boards/freescale-mx23-evk/mx23-evk.c96
-rw-r--r--arch/arm/boards/freescale-mx25-3-stack/3stack.c2
-rw-r--r--arch/arm/boards/freescale-mx35-3-stack/3stack.c6
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/Makefile3
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/board.c318
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/config.h24
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/env/config52
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/flash_header.c85
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S216
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox4
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/spi.c340
-rw-r--r--arch/arm/boards/guf-cupid/Makefile24
-rw-r--r--arch/arm/boards/guf-cupid/board.c426
-rw-r--r--arch/arm/boards/guf-cupid/config.h31
-rw-r--r--arch/arm/boards/guf-cupid/cupid.dox9
-rw-r--r--arch/arm/boards/guf-cupid/env/config56
-rw-r--r--arch/arm/boards/guf-cupid/lowlevel.c349
-rw-r--r--arch/arm/boards/nhk8815/env/bin/_update36
-rw-r--r--arch/arm/boards/nhk8815/env/bin/boot38
-rw-r--r--arch/arm/boards/nhk8815/env/bin/init28
-rw-r--r--arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem19
-rw-r--r--arch/arm/boards/nhk8815/env/bin/update_kernel8
-rw-r--r--arch/arm/boards/nhk8815/env/bin/update_root8
-rw-r--r--arch/arm/boards/nhk8815/env/config44
-rw-r--r--arch/arm/boards/pcm038/Makefile2
-rw-r--r--arch/arm/boards/pcm038/lowlevel.c7
-rw-r--r--arch/arm/boards/pcm038/pcm038.c65
-rw-r--r--arch/arm/boards/pcm038/pll.h70
-rw-r--r--arch/arm/boards/pcm038/pll_init.S48
-rw-r--r--arch/arm/boards/pcm043/pcm043.c4
-rw-r--r--arch/arm/boards/phycard-i.MX27/pca100.c16
-rw-r--r--arch/arm/configs/chumbyone_defconfig29
-rw-r--r--arch/arm/configs/cupid_defconfig56
-rw-r--r--arch/arm/configs/eukrea_cpuimx25_defconfig12
-rw-r--r--arch/arm/configs/eukrea_cpuimx35_defconfig14
-rw-r--r--arch/arm/configs/freescale_mx51_babbage_defconfig43
-rw-r--r--arch/arm/configs/imx23evk_defconfig24
-rw-r--r--arch/arm/configs/neso_defconfig3
-rw-r--r--arch/arm/configs/nhk8815_defconfig5
-rw-r--r--arch/arm/configs/pca100_defconfig3
-rw-r--r--arch/arm/configs/pcm037_defconfig3
-rw-r--r--arch/arm/configs/pcm038_defconfig3
-rw-r--r--arch/arm/configs/pcm043_defconfig3
-rw-r--r--arch/arm/cpu/cache-l2x0.c2
-rw-r--r--arch/arm/cpu/cpu.c1
-rw-r--r--arch/arm/cpu/interrupts.c10
-rw-r--r--arch/arm/cpu/mmu.c6
-rw-r--r--arch/arm/lib/Makefile1
-rw-r--r--arch/arm/lib/armlinux.c35
-rw-r--r--arch/arm/lib/div0.c5
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c2
-rw-r--r--arch/arm/mach-ep93xx/clocksource.c2
-rw-r--r--arch/arm/mach-imx/Kconfig35
-rw-r--r--arch/arm/mach-imx/Makefile1
-rw-r--r--arch/arm/mach-imx/clocksource.c31
-rw-r--r--arch/arm/mach-imx/gpio.c15
-rw-r--r--arch/arm/mach-imx/imx51.c51
-rw-r--r--arch/arm/mach-imx/include/mach/clock-imx51.h696
-rw-r--r--arch/arm/mach-imx/include/mach/clock.h3
-rw-r--r--arch/arm/mach-imx/include/mach/esdctl.h88
-rw-r--r--arch/arm/mach-imx/include/mach/generic.h6
-rw-r--r--arch/arm/mach-imx/include/mach/imx-nand.h4
-rw-r--r--arch/arm/mach-imx/include/mach/imx-regs.h2
-rw-r--r--arch/arm/mach-imx/include/mach/imx1-regs.h8
-rw-r--r--arch/arm/mach-imx/include/mach/imx21-regs.h8
-rw-r--r--arch/arm/mach-imx/include/mach/imx27-regs.h16
-rw-r--r--arch/arm/mach-imx/include/mach/imx31-regs.h10
-rw-r--r--arch/arm/mach-imx/include/mach/imx35-regs.h14
-rw-r--r--arch/arm/mach-imx/include/mach/imx51-regs.h124
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-mx25.h12
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-mx27.h6
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-mx35.h12
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-mx51.h330
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-v3.h10
-rw-r--r--arch/arm/mach-imx/include/mach/usb.h14
-rw-r--r--arch/arm/mach-imx/speed-imx25.c10
-rw-r--r--arch/arm/mach-imx/speed-imx27.c5
-rw-r--r--arch/arm/mach-imx/speed-imx35.c21
-rw-r--r--arch/arm/mach-imx/speed-imx51.c190
-rw-r--r--arch/arm/mach-imx/speed.c1
-rw-r--r--arch/arm/mach-omap/arch-omap.dox6
-rw-r--r--arch/arm/mach-omap/omap3_generic.c4
-rw-r--r--arch/arm/mach-s3c24xx/Makefile2
-rw-r--r--arch/arm/mach-s3c24xx/gpio-s3c24x0.c169
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/gpio.h31
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h426
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/mci.h (renamed from arch/ppc/lib/cache.c)50
-rw-r--r--arch/arm/mach-stm/Kconfig48
-rw-r--r--arch/arm/mach-stm/Makefile2
-rw-r--r--arch/arm/mach-stm/clocksource-imx23.c82
-rw-r--r--arch/arm/mach-stm/imx23.c (renamed from arch/arm/lib/cache.c)25
-rw-r--r--arch/arm/mach-stm/include/mach/clock.h34
-rw-r--r--arch/arm/mach-stm/include/mach/generic.h24
-rw-r--r--arch/arm/mach-stm/include/mach/gpio.h29
-rw-r--r--arch/arm/mach-stm/include/mach/imx-regs.h27
-rw-r--r--arch/arm/mach-stm/include/mach/imx23-regs.h41
-rw-r--r--arch/arm/mach-stm/include/mach/iomux-imx23.h424
-rw-r--r--arch/arm/mach-stm/include/mach/mci.h32
-rw-r--r--arch/arm/mach-stm/iomux-imx23.c117
-rw-r--r--arch/arm/mach-stm/reset-imx23.c61
-rw-r--r--arch/arm/mach-stm/speed-imx23.c280
-rw-r--r--arch/blackfin/lib/cpu.c2
-rw-r--r--arch/m68k/lib/m68k-linuxboot.c2
-rw-r--r--arch/m68k/mach-mcfv4e/mcf_reset_cpu.c2
-rw-r--r--arch/ppc/lib/Makefile1
-rw-r--r--arch/ppc/lib/ppclinux.c2
-rw-r--r--arch/ppc/mach-mpc5xxx/cpu.c2
-rw-r--r--arch/sandbox/board/hostfile.c2
-rw-r--r--arch/sandbox/os/common.c7
-rw-r--r--arch/x86/boards/x86_generic/generic_pc.c2
-rw-r--r--arch/x86/boot/boot_hdisk.S2
-rw-r--r--arch/x86/boot/boot_main.S2
-rw-r--r--arch/x86/boot/pmjump.S2
-rw-r--r--arch/x86/lib/memory16.S2
-rw-r--r--arch/x86/lib/traveler.S3
-rw-r--r--arch/x86/mach-x86.dox2
-rw-r--r--commands/Kconfig5
-rw-r--r--commands/bmp.c27
-rw-r--r--commands/bootm.c48
-rw-r--r--commands/cat.c19
-rw-r--r--commands/cd.c17
-rw-r--r--commands/clear.c5
-rw-r--r--commands/cp.c30
-rw-r--r--commands/crc.c124
-rw-r--r--commands/dfu.c28
-rw-r--r--commands/echo.c17
-rw-r--r--commands/edit.c42
-rw-r--r--commands/export.c14
-rw-r--r--commands/flash.c100
-rw-r--r--commands/gpio.c93
-rw-r--r--commands/linux16.c25
-rw-r--r--commands/loadb.c1
-rw-r--r--commands/loadenv.c34
-rw-r--r--commands/loads.c1
-rw-r--r--commands/ls.c9
-rw-r--r--commands/mem.c2
-rw-r--r--commands/mount.c78
-rw-r--r--commands/partition.c75
-rw-r--r--commands/printenv.c30
-rw-r--r--commands/saveenv.c31
-rw-r--r--commands/setenv.c30
-rw-r--r--commands/version.c1
-rw-r--r--common/Kconfig23
-rw-r--r--common/Makefile10
-rw-r--r--common/console.c8
-rw-r--r--common/dlmalloc.c41
-rw-r--r--common/env.c2
-rw-r--r--common/environment.c2
-rw-r--r--common/hush.c137
-rw-r--r--common/image.c7
-rw-r--r--common/kallsyms.c4
-rw-r--r--common/memsize.c1
-rw-r--r--common/parser.c51
-rw-r--r--defaultenv/bin/_update30
-rw-r--r--defaultenv/bin/_update_help12
-rw-r--r--defaultenv/bin/boot4
-rw-r--r--defaultenv/bin/init7
-rw-r--r--defaultenv/bin/update65
-rw-r--r--defaultenv/bin/update_kernel15
-rw-r--r--defaultenv/bin/update_rootfs16
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/ata/disk_drive.c51
-rw-r--r--drivers/i2c/Kconfig16
-rw-r--r--drivers/i2c/Makefile6
-rw-r--r--drivers/i2c/mc13892.c164
-rw-r--r--drivers/mci/Kconfig64
-rw-r--r--drivers/mci/Makefile5
-rw-r--r--drivers/mci/imx-esdhc.c512
-rw-r--r--drivers/mci/imx-esdhc.h164
-rw-r--r--drivers/mci/imx.c520
-rw-r--r--drivers/mci/mci-core.c1360
-rw-r--r--drivers/mci/s3c.c817
-rw-r--r--drivers/mci/stm378x.c699
-rw-r--r--drivers/mfd/Kconfig28
-rw-r--r--drivers/mfd/Makefile6
-rw-r--r--drivers/mfd/lp3972.c (renamed from drivers/i2c/lp3972.c)0
-rw-r--r--drivers/mfd/mc13783.c (renamed from drivers/spi/mc13783.c)0
-rw-r--r--drivers/mfd/mc13892.c327
-rw-r--r--drivers/mfd/mc34704.c (renamed from drivers/i2c/mc34704.c)2
-rw-r--r--drivers/mfd/mc9sdz60.c (renamed from drivers/i2c/mc9sdz60.c)2
-rw-r--r--drivers/mfd/twl4030.c (renamed from drivers/i2c/twl4030.c)2
-rw-r--r--drivers/mtd/nand/Kconfig16
-rw-r--r--drivers/mtd/nand/nand_imx.c196
-rw-r--r--drivers/net/fec_imx.c8
-rw-r--r--drivers/net/fec_imx.h6
-rw-r--r--drivers/serial/Kconfig5
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/serial_imx.c92
-rw-r--r--drivers/serial/stm-serial.c202
-rw-r--r--drivers/spi/Kconfig12
-rw-r--r--drivers/spi/Makefile2
-rw-r--r--drivers/spi/imx_spi.c347
-rw-r--r--drivers/usb/gadget/fsl_udc.c3
-rw-r--r--drivers/usb/host/ehci-omap.c2
-rw-r--r--drivers/usb/otg/twl4030.c2
-rw-r--r--drivers/video/imx-ipu-fb.c92
-rw-r--r--fs/ramfs.c2
-rw-r--r--include/asm-generic/barebox.lds.h2
-rw-r--r--include/cache.h1
-rw-r--r--include/command.h20
-rw-r--r--include/common.h4
-rw-r--r--include/image.h56
-rw-r--r--include/mci.h239
-rw-r--r--include/mfd/lp3972.h (renamed from include/i2c/lp3972.h)0
-rw-r--r--include/mfd/mc13892.h (renamed from include/i2c/mc13892.h)28
-rw-r--r--include/mfd/mc34704.h (renamed from include/i2c/mc34704.h)0
-rw-r--r--include/mfd/mc9sdz60.h (renamed from include/i2c/mc9sdz60.h)0
-rw-r--r--include/mfd/twl4030.h (renamed from include/i2c/twl4030.h)0
-rw-r--r--include/notifier.h1
-rw-r--r--lib/Kconfig2
-rw-r--r--lib/Makefile1
-rw-r--r--lib/copy_file.c2
-rw-r--r--lib/crc32.c2
-rw-r--r--lib/driver.c88
-rw-r--r--lib/fnmatch.c5
-rw-r--r--lib/glob.c36
-rw-r--r--lib/ldiv.c55
-rw-r--r--lib/libbb.c2
-rw-r--r--lib/parameter.c2
-rw-r--r--lib/process_escape_sequence.c1
-rw-r--r--lib/readline.c6
-rw-r--r--net/net.c4
-rw-r--r--net/ping.c4
-rw-r--r--net/tftp.c49
-rw-r--r--scripts/doxy_filter.awk103
-rw-r--r--scripts/mkimage.c2
258 files changed, 13546 insertions, 1857 deletions
diff --git a/Documentation/barebox-main.dox b/Documentation/barebox-main.dox
index fb780e6364..90fce8ec8a 100644
--- a/Documentation/barebox-main.dox
+++ b/Documentation/barebox-main.dox
@@ -1,166 +1,74 @@
-/** @mainpage Universal Bootloader
-
-@section barebox_intro Introduction
-
-@a Barebox is a bootloader which follows the tradition of U-Boot. U-Boot
-offers an excellent choice as a bootloader for today's embedded systems,
-seen from a user's point of view. Nevertheless, there are quite some
-design flaws which turned out over the last years and we think that they
-cannot be solved in a production tree. So this tree tries to do several
-things right - without caring about losing support for old boards.
-
-@par General features include:
-
-- A posix based file API
- - inside @a barebox the usual open/close/read/write/lseek functions are used.
- This makes it familiar to everyone who has programmed under unix systems.
-
-- usual shell commands like ls/cd/mkdir/echo/cat,...
-
-- The environment is not a variable store anymore, but a file store. It has
- currently some limitations, of course. The environment is not a real
- read/write filesystem, it is more like a tar archive, or even more like
- an ar archive, because it cannot handle directories. The saveenv command
- saves the files under a certain directory (by default /env) in persistent
- storage (by default /dev/env0). There is a counterpart called loadenv, too.
+/** @mainpage Barebox
+
+Barebox is a bootloader that initializes a hardware and boots Linux and
+maybe other operating systems or bare metal code on a variety of
+processors. It was initialy derived from U-Boot and captures up with
+several of it's ideas, so users being familiar with U-Boot should come
+into production quickly with Barebox.
+
+However, as the Barebox developers are highly addicted to the Linux
+kernel, it's coding style and code quality, we try to stick as closely
+as possible to the methodologies and techniques developed in Linux. In
+addition we have a strong background in POSIX, so you'll find several
+good old Unix traditions realized in Barebox as well.
+
+@par Highlights:
+
+- <b>POSIX File API:</b><br>
+ @a Barebox uses the the well known open/close/read/write/lseek access
+ functions, together with a model of representing devices by files. This
+ makes the APIs familiar to everyone who has experience with Unix
+ systems.
+
+- <b>Shell:</b><br>
+ We have the standard shell commands like ls/cd/mkdir/echo/cat,...
+
+- <b>Environment Filesystem:</b><br>
+ In contrast to U-Boot, Barebox doesn't misuse the environment for
+ scripting. If you start the bootloader, it gives you a shell and
+ something that looks like a filesystem. In fact it isn't: it is a very
+ simple ar archive being extracted from flash into a ramdisk with 'loadenv'
+ and stored back with 'saveenv'.
+
+- <b>Filesystem Support:</b><br>
+ When starting up, the environment is mounted to /, followed by a
+ device filesytem being mounted to /dev in order to make it possible to
+ access devices. Other filesystems can be mounted on demand.
+
+- <b>Driver Model (borrowed from Linux):</b><br>
+ Barebox follows the Linux driver model: devices can be specified in a
+ hardware specific file, and drivers feel responsible for these devices
+ if they have the same name.
+
+- <b>Clocksource:</b><br>
+ We use the clocksource API knwon from Linux.
+
+- <b>Kconfig/Kbuild:</b><br>
+ This gives us parallel builds and removes the need for lots of ifdefs.
+
+- <b>Sandbox:</b><br>
+ If you develop features for @a Barebox, you can use the 'sandbox'
+ target which compiles @a Barebox as a POSIX application in the Linux
+ userspace: it can be started like a normal command and even has
+ network access (tun/tap). Files from the local filesytem can be used
+ to simulate devices.
+
+- <b>Device Parameters:</b><br>
+ There is a parameter model in @a Barebox: each device can specify it's
+ own parameters, which do exist for every instance. Parameters can be
+ changed on the command line with \<devid\>.\<param\>="...". For
+ example, if you want to access the IPv4 address for eth0, this is done
+ with 'eth0.ip=192.168.0.7' and 'echo $eth0.ip'.
+
+- <b>Getopt:</b><br>
+ @a Barebox has a lightweight getopt() implementation. This makes it
+ unnecessary to use positional parameters, which can be hard to read.
+
+- <b>Integrated Editor:</b><br>
+ Scripts can be edited with a small integrated fullscreen editor.
+ This editor has no features except the ones really needed: moving
+ the cursor around, typing characters, exiting and saving.
-- Real filesystem support
- - The loader starts up with mounting a ramdisk on /. Then a devfs is mounted
- on /dev allowing the user (or shell commands) to access devices. Apart from
- these two filesystems there is currently one filesystem ported: cramfs. One
- can mount it with the usual mount command.
-
-- device/driver model
- - Devices are no longer described by defines in the config file. Instead
- there are devices which can be registered in the board .c file or
- dynamically allocated. Drivers will match upon the devices automatically.
-
-- clocksource support
- - Timekeeping has been simplified by the use of the Linux clocksource API.
- Only one function is needed for a new board, no [gs]et_timer[masked]() or
- reset_timer[masked]() functions.
-
-- Kconfig and Kernel build system
- - Only targets which are really needed get recompiled. Parallel builds are
- no problem anymore. This also removes the need for many many ifdefs in
- the code.
-
-- simulation target
- - @a barebox can be compiled to run under Linux. While this is rather useless
- in real world this is a great debugging and development aid. New features
- can be easily developed and tested on long train journeys and started
- under gdb. There is a console driver for linux which emulates a serial
- device and a tap based ethernet driver. Linux files can be mapped to
- devices under @a barebox to emulate storage devices.
-
-- device parameter support
- - Each device can have a unlimited number of parameters. They can be accessed
- on the command line with \<devid\>.\<param\>="...", for example
- 'eth0.ip=192.168.0.7' or 'echo $eth0.ip'
-
-- initcalls
- - hooks in the startup process can be achieved with *_initcall() directives
- in each file.
-
-- getopt
- - There is a small getopt implementation. Some commands got really
- complicated (both in code and in usage) due to the fact that @a U-Boot only
- allowed positional parameters.
-
-- editor
- - Scripts can be edited with a small editor. This editor has no features
- except the ones really needed: moving the cursor and typing characters.
-
-@par Building barebox
-
-@a Barebox uses the Linux kernel's build system. It consists of two parts:
-the makefile infrastructure (kbuild), plus a configuration system
-(kconfig). So building @a barebox is very similar to building the Linux
-kernel.
-
-For the examples below, we use the User Mode @a barebox implementation, which
-is a port of @a barebox to the Linux userspace. This makes it possible to
-test drive the code without having real hardware. So for this test
-scenario, @p ARCH=sandbox is the valid architecture selection. This currently
-only works on ia32 hosts and partly on x86-64.
-
-Selection of the architecture and the cross compiler can be done in two
-ways. You can either specify it using the environment variables @p ARCH
-and @p CROSS_COMPILE, or you can create the soft links cross_arch and
-cross_compile pointing to your architecture and compiler. For @p ARCH=sandbox
-we do not need a cross compiler so it is sufficient to specify the
-architecture:
-
-@code # ln -s arch/sandbox cross_arch @endcode
-
-In order to configure the various aspects of @a barebox, start the @a barebox
-configuration system:
-
-@code # make menuconfig @endcode
-
-This command starts a menu box and lets you select all the different
-options available for your architecture. Once the configuration was
-finished (you can simulate this by using the standard demo config file
-with 'make sandbox_defconfig'), there is a .config file in the toplevel
-directory of the sourcecode.
-
-Once @a barebox is configured, we can start the compilation
-
-@code # make @endcode
-
-If everything goes well, the result is a file called @p barebox:
-
-@code
- # ls -l barebox
- -rwxr-xr-x 1 rsc ptx 114073 Jun 26 22:34 barebox
-@endcode
-
-@a barebox usually needs an environment for storing the configuration data.
-You can generate an environment using the example environment contained
-in arch/sanbox/board/env:
-
-@code # ./scripts/bareboxenv -s -p 0x10000 arch/sanbox/board/env/ env.bin @endcode
-
-To get some files to play with you can generate a cramfs image:
-
-@code # mkcramfs somedir/ cramfs.bin @endcode
-
-The @a barebox image is a normal Linux executable, so it can be started
-just like every other program:
-
-@code
- # ./barebox -e env.bin -i cramfs.bin
-
- barebox 2.0.0-trunk (Jun 26 2007 - 22:34:38)
-
- loading environment from /dev/env0
- barebox\> /
-@endcode
-
-Specifying -[ie] \<file\> tells @a barebox to map the file as a device
-under @p /dev. Files given with '-e' will appear as @p /dev/env[n]. Files
-given with '-i' will appear as @p /dev/fd[n].
-If @a barebox finds a valid configuration sector on @p /dev/env0 it will
-load it to @p /env. It then executes @p /env/init if it exists. If you have
-loaded the example environment @a barebox will show you a menu asking for
-your settings.
-
-If you have started @a barebox as root you will find a new tap device on your
-host which you can configure using ifconfig. Once you configured the
-network settings accordingly you can do a ping or tftpboot.
-
-If you have mapped a cramfs image try mounting it with
-
-@code
- # mkdir /cram
- # mount /dev/fd0 cramfs /cram
-@endcode
-
-Memory can be examined as usual using @p md/mw commands. They both understand
-the -f \<file\> option to tell the commands that they should work on the
-specified files instead of @p /dev/mem which holds the complete address space.
-Note that if you call 'md /dev/fd0' (without -f) @a barebox will segfault on
-the host, because it will interpret @p /dev/fd0 as a number.
@par Directory layout
diff --git a/Documentation/boards.dox b/Documentation/boards.dox
index 3eb79b27b7..fa0f284a3b 100644
--- a/Documentation/boards.dox
+++ b/Documentation/boards.dox
@@ -8,18 +8,23 @@ PowerPC type:
ARM type:
+
@li @subpage pcm037
@li @subpage pcm038
@li @subpage pcm043
@li @subpage imx21ads
@li @subpage imx27ads
@li @subpage the3stack
+@li @subpage mx23_evk
+@li @subpage board_babage
+@li @subpage chumbyone
@li @subpage scb9328
@li @subpage netx
@li @subpage dev_omap_arch
@li @subpage a9m2440
@li @subpage a9m2410
@li @subpage eukrea_cpuimx27
+@li @subpage eukrea_cpuimx35
@li @subpage edb9301
@li @subpage edb9302
@li @subpage edb9302a
@@ -28,6 +33,7 @@ ARM type:
@li @subpage edb9312
@li @subpage edb9315
@li @subpage edb9315a
+@li @subpage board_cupid
Blackfin type:
diff --git a/Documentation/building.dox b/Documentation/building.dox
new file mode 100644
index 0000000000..527ca45d05
--- /dev/null
+++ b/Documentation/building.dox
@@ -0,0 +1,60 @@
+/** @page building Building
+
+<i>This section describes how to build the Barebox bootloader.</i>
+
+@a Barebox uses Kconfig/Kbuild from the Linux kernel to build it's
+sources. It consists of two parts: the makefile infrastructure (kbuild)
+and a configuration system (kconfig). So building @a barebox is very
+similar to building the Linux kernel.
+
+In the examples below we use the "sandbox" configuration, which is a
+port of @a Barebox to the Linux userspace. This makes it possible to
+test the code without having real hardware or even qemu. Note that the
+sandbox architecture does only work well on x86 and has some issues on
+x86_64.
+
+\todo Find out about issues on x86_64.
+
+Selecting the architecture and the corresponding cross compiler is done
+by setting the following environment variables:
+
+- ARCH=\<architecture>
+- CROSS_COMPILE=\<compiler-prefix>
+
+For @p ARCH=sandbox we do not need a cross compiler, so it is sufficient
+to specify the architecture:
+
+@code
+# export ARCH=sandbox
+@endcode
+
+In order to configure the various aspects of @a barebox, start the
+@a barebox configuration system:
+
+@code
+# make menuconfig
+@endcode
+
+This command starts a menu box and lets you select all the different
+options available for the selected architecture. Once the configuration
+is finished (you can simulate this by using the default config file with
+'make sandbox_defconfig'), there is a .config file in the toplevel
+directory of the sourcecode.
+
+After @a barebox is configured, we can start the compilation:
+
+@code
+# make
+@endcode
+
+You can use '-j \<n\>' in order to do a parallel build if you have more
+than one cpus.
+
+If everything goes well, the result is a file called @p barebox:
+
+@code
+# ls -l barebox
+-rwxr-xr-x 1 rsc ptx 114073 Jun 26 22:34 barebox
+@endcode
+
+*/
diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index a8850b1bb4..27eb511679 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -1,24 +1,48 @@
/**
- * @page command_reference Supported Shell Commands
+ * @page command_reference Shell Commands
+
+<i>This section describes the commands which are available on the @a
+Barebox shell. </i>
+
+@a Barebox, as a bootloader, usually shall start the Linux kernel right
+away. However, there are several use cases around which make it
+necessary to have some (customizable) logic and interactive scripting
+possibilities. In order to achieve this, @a Barebox offers several
+commands on it's integrated commandline shell.
+
+The following alphabetically sorted list documents all commands
+available in @a Barebox:
+
+\todo Sort this by functionality?
@li @subpage addpart_command
+@li @subpage bmp_command
+@li @subpage bootm_command
@li @subpage cat_command
@li @subpage cd_command
+@li @subpage clear_command
@li @subpage cp_command
+@li @subpage crc_command
@li @subpage delpart_command
@li @subpage devinfo_command
+@li @subpage dfu_command
+@li @subpage echo_command
@li @subpage edit_command
@li @subpage erase_command
@li @subpage export_command
+@li @subpage gpio_get_value_command
+@li @subpage gpio_set_value_command
+@li @subpage gpio_direction_input_command
+@li @subpage gpio_direction_output_command
@li @subpage tftp_command
@li @subpage loadenv_command
+@li @subpage ls_command
@li @subpage mount_command
@li @subpage printenv_command
@li @subpage protect_command
-@li @subpage rarp_command
@li @subpage saveenv_command
@li @subpage setenv_command
-@li @subpage sh_command
@li @subpage unprotect_command
@li @subpage linux16_command
+
*/
diff --git a/Documentation/developers_manual.dox b/Documentation/developers_manual.dox
index 620905eaa7..2f7d3605ef 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
-@li @subpage x86_runtime
*/
diff --git a/Documentation/first_steps.dox b/Documentation/first_steps.dox
new file mode 100644
index 0000000000..edc612fb89
--- /dev/null
+++ b/Documentation/first_steps.dox
@@ -0,0 +1,61 @@
+/** @page first_steps First Steps
+
+<i>This section demonstrates the first steps with the 'sandbox'
+platform. </i>
+
+@a barebox usually needs an environment for storing it's configuration.
+You can generate an environment using the example-environment contained
+in arch/sanbox/board/env:
+
+@code
+# ./scripts/bareboxenv -s -p 0x10000 arch/sanbox/board/env/ env.bin
+@endcode
+
+To get some files to play with you can generate a cramfs image:
+
+@code
+# mkcramfs somedir/ cramfs.bin
+@endcode
+
+The @a barebox image is a normal Linux executable, so it can be started
+just like every other program:
+
+@code
+# ./barebox -e env.bin -i cramfs.bin
+
+barebox 2010.10.0 (Oct 29 2010 - 13:47:17)
+
+loading environment from /dev/env0
+barebox\> /
+@endcode
+
+Specifying -[ie] \<file\> tells @a barebox to map the file as a device
+under @p /dev. Files given with '-e' will appear as @p /dev/env[n]. Files
+given with '-i' will appear as @p /dev/fd[n].
+
+If @a barebox finds a valid configuration sector on @p /dev/env0, it
+will be loaded into @p /env and executes @p /env/init if existing.
+The default environment from the example above will show up a menu
+asking for the relevant settings.
+
+If you have started @a barebox as root you will find a new tap device on
+your host which you can configure using ifconfig. Once configured with
+valid network addresses, barebox can be used to ping the host machine or
+to fetch files with tftp.
+
+\todo Add more about tun/tap configuration
+
+If you have mapped a cramfs image, try mounting it with
+
+@code
+# mkdir /cram
+# mount /dev/fd0 cramfs /cram
+@endcode
+
+Memory can be examined using @p md/mw commands. They both understand the
+-f \<file\> option to tell the commands that they should work on the
+specified files instead of @p /dev/mem (which holds the complete address
+space). Note that if you call 'md /dev/fd0' (without -f), @a barebox will
+segfault on the host, because it will interpret @p /dev/fd0 as a number.
+
+*/
diff --git a/Documentation/users_manual.dox b/Documentation/users_manual.dox
index cd2b99cd41..ea47b18724 100644
--- a/Documentation/users_manual.dox
+++ b/Documentation/users_manual.dox
@@ -1,15 +1,17 @@
/** @page users_manual User's Manual
-Who should read this part?
+This manual provides help for working with @a Barebox from the user's
+point of view. So if you want to use @a Barebox for booting your target,
+you find a lot of nice tricks on these pages to make your life easier.
-Mostly everyone. The user needs it to find help for his daily work to manage
-his targets. The developer to find out all the new features that make his
-work easier.
+@li @subpage building
+@li @subpage first_steps
+@li @subpage command_reference
+@li @subpage gpio_for_users
+\todo Rework the following sections
@li @subpage shell_notes
@li @subpage readline_parser
-@li @subpage command_reference
-@li @subpage partitions
@li @subpage x86_bootloader
@li @subpage net_netconsole
diff --git a/Doxyfile b/Doxyfile
index 40bcb2f97c..d9ce22c0e3 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
@@ -483,7 +483,6 @@ INPUT = Documentation \
drivers \
commands \
common \
- board \
lib \
scripts/setupmbr \
net
@@ -504,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
@@ -516,7 +516,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
@@ -543,7 +545,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
@@ -563,7 +565,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
@@ -573,7 +575,7 @@ IMAGE_PATH = Documentation/images/
# 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
@@ -1065,7 +1067,10 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
+PREDEFINED = \
+ DOXYGEN_SHOULD_SKIP_THIS \
+ CONFIG_CMD_DEVINFO \
+ CONFIG_NET_TFTP_PUSH
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
@@ -1209,7 +1214,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.
@@ -1217,19 +1222,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
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fa3703627c..8cb86cb449 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
@@ -55,6 +59,7 @@ config ARCH_OMAP
config ARCH_S3C24xx
bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
select CPU_ARM920T
+ select GENERIC_GPIO
endchoice
@@ -62,6 +67,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/Makefile b/arch/arm/Makefile
index 77b6cf4551..cdb0185d6f 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,10 @@ 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
+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/chumby_falconwing/Makefile b/arch/arm/boards/chumby_falconwing/Makefile
new file mode 100644
index 0000000000..0bc79d9f9f
--- /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 0000000000..87d9e2f476
--- /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/env/bin/boot b/arch/arm/boards/chumby_falconwing/env/bin/boot
new file mode 100644
index 0000000000..981a387a1d
--- /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 0000000000..3ed68f76c5
--- /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 0000000000..1e61dce976
--- /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
new file mode 100644
index 0000000000..952a384061
--- /dev/null
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -0,0 +1,350 @@
+/*
+ * (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 <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",
+ .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 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
+ /* 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),
+};
+
+/**
+ * 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, 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;
+}
+
+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
+
+@section get_falconwing_binary How to get the bootloader binary image:
+
+Using the default configuration:
+
+@verbatim
+make ARCH=arm chumbyone_defconfig
+@endverbatim
+
+Build the bootloader binary image:
+
+@verbatim
+make ARCH=arm CROSS_COMPILE=armv5compiler
+@endverbatim
+
+@note replace the armv5compiler with your ARM v5 cross compiler.
+
+@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.
+
+*/
diff --git a/arch/arm/boards/eukrea_cpuimx25/env/bin/init b/arch/arm/boards/eukrea_cpuimx25/env/bin/init
index 335d7ae579..47328759bc 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/env/config b/arch/arm/boards/eukrea_cpuimx25/env/config
index 9217ca17be..3e41ec8b98 100644
--- a/arch/arm/boards/eukrea_cpuimx25/env/config
+++ b/arch/arm/boards/eukrea_cpuimx25/env/config
@@ -13,7 +13,7 @@ autoboot_timeout=1
nfsroot=""
bootargs="console=ttymxc0,115200"
-nand_parts="256k(barebox)ro,128k(bareboxenv),2176k(kernel),-(root)"
+nand_parts="256k(barebox)ro,128k(bareboxenv),2432k(kernel),-(root)"
rootpartnum_nand=3
ubiroot="eukrea-cpuimx25-rootfs"
diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index 7fd1031171..805ffe2d10 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -40,6 +40,9 @@
#include <nand.h>
#include <mach/imx-flash-header.h>
#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);
@@ -151,6 +154,60 @@ 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
+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 +266,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 +284,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 +306,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 +333,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 +346,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 b9d3ce57bb..4ebf247776 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/boards/eukrea_cpuimx27/env/bin/boot b/arch/arm/boards/eukrea_cpuimx27/env/bin/boot
index 7272e56763..0e1c80a932 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 3bfd194913..aefd67cc34 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 505ada39c7..7f5600339f 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
@@ -13,12 +15,15 @@ autoboot_timeout=1
video="CMO-QVGA"
bootargs="console=ttymxc0,115200 fec_mac=$eth0.ethaddr video=mxcfb:$video"
-nor_parts="256k(barebox)ro,128k(bareboxenv),2176k(kernel),-(root)"
+nor_parts="256k(barebox)ro,128k(bareboxenv),2432k(kernel),-(root)"
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 4d1797bca7..62fc14e4ec 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 = {
@@ -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);
diff --git a/arch/arm/boards/eukrea_cpuimx35/env/bin/init b/arch/arm/boards/eukrea_cpuimx35/env/bin/init
index 90007cd65d..b56d7b5c24 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/env/config b/arch/arm/boards/eukrea_cpuimx35/env/config
index df2079fa58..fc99e51d30 100644
--- a/arch/arm/boards/eukrea_cpuimx35/env/config
+++ b/arch/arm/boards/eukrea_cpuimx35/env/config
@@ -13,7 +13,7 @@ autoboot_timeout=1
nfsroot=""
bootargs="console=ttymxc0,115200"
-nand_parts="256k(barebox)ro,128k(bareboxenv),2176k(kernel),-(root)"
+nand_parts="256k(barebox)ro,128k(bareboxenv),2432k(kernel),-(root)"
rootpartnum_nand=3
ubiroot="eukrea-cpuimx35-rootfs"
diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
index 63d019a045..dfe64d0174 100644
--- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
+++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
@@ -51,6 +51,9 @@
#include <mach/pmic.h>
#include <mach/imx-ipu-fb.h>
#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,
@@ -126,6 +129,60 @@ 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
+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 +210,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 +224,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 +282,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 +300,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 +316,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 285a2d4a96..5a77c3adcc 100644
--- a/arch/arm/boards/eukrea_cpuimx35/flash_header.c
+++ b/arch/arm/boards/eukrea_cpuimx35/flash_header.c
@@ -12,30 +12,30 @@ 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 CPUIMX35_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 = CPUIMX35_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),
.super_root_key = 0,
.dcd = FLASH_HEADER_BASE + offsetof(struct imx_flash_header, dcd_barker),
- .app_dest = DEST_BASE,
+ .app_dest = CPUIMX35_DEST_BASE,
.dcd_barker = DCD_BARKER,
.dcd_block_len = sizeof(dcd_entry),
};
diff --git a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
index aad334d2e8..6c0e106f67 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/boards/freescale-mx23-evk/Makefile b/arch/arm/boards/freescale-mx23-evk/Makefile
new file mode 100644
index 0000000000..cffb561cb6
--- /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 0000000000..4b3da8f2e5
--- /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 0000000000..1ce72be8d7
--- /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
+
+@section get_imx23evk_binary How to get the bootloader binary image:
+
+Using the default configuration:
+
+@verbatim
+make ARCH=arm imx23evk_defconfig
+@endverbatim
+
+Build the bootloader binary image:
+
+@verbatim
+make ARCH=arm CROSS_COMPILE=armv5compiler
+@endverbatim
+
+@note replace the armv5compiler with your ARM v5 cross compiler.
+*/
diff --git a/arch/arm/boards/freescale-mx25-3-stack/3stack.c b/arch/arm/boards/freescale-mx25-3-stack/3stack.c
index 70de7958eb..25945f13d8 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 71aaa92970..d6699cdc93 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 */
@@ -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/arch/arm/boards/freescale-mx51-pdk/Makefile b/arch/arm/boards/freescale-mx51-pdk/Makefile
new file mode 100644
index 0000000000..8e0c87c96f
--- /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 0000000000..5197c55007
--- /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 0000000000..b7effe5d28
--- /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 0000000000..d9b84078f8
--- /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 0000000000..5f94506b69
--- /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 0000000000..793104c7c2
--- /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 0000000000..d9ea823e5c
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox
@@ -0,0 +1,4 @@
+/** @page board_babage 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 0000000000..8eabe817d9
--- /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/boards/guf-cupid/Makefile b/arch/arm/boards/guf-cupid/Makefile
new file mode 100644
index 0000000000..3a06cf406b
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/Makefile
@@ -0,0 +1,24 @@
+#
+# (C) Copyright 2007 Juergen Beisert <jbe@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 0000000000..6d7a99bc84
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/board.c
@@ -0,0 +1,426 @@
+/*
+ * (C) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ * (C) 2009 Pengutronix, Juergen Beisert <kernel@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 0000000000..0e3b175a62
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/config.h
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2007 Juergen Beisert <jbe@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 0000000000..45f0e0cc22
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/cupid.dox
@@ -0,0 +1,9 @@
+/** @page board_cupid 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 0000000000..4db05b6c6d
--- /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 0000000000..8d403ee821
--- /dev/null
+++ b/arch/arm/boards/guf-cupid/lowlevel.c
@@ -0,0 +1,349 @@
+/*
+ *
+ * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@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/boards/nhk8815/env/bin/_update b/arch/arm/boards/nhk8815/env/bin/_update
deleted file mode 100644
index fb7cbe8619..0000000000
--- 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 fd8d957db1..0000000000
--- 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 5b45a70d47..0000000000
--- 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 40f4ad3dc0..0000000000
--- 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 db0f4c2678..0000000000
--- 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 9530e847ef..0000000000
--- 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 7e7fc456c3..e657a76f99 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/boards/pcm038/Makefile b/arch/arm/boards/pcm038/Makefile
index a681ddafb9..970804e280 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 eb85e8f27b..b50e1c8386 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 fda326240b..3a9b41352b 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 0000000000..13a7989cb5
--- /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 0c1ff13415..0000000000
--- 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)
-
diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
index 9f98795fd1..5932f954c3 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,
diff --git a/arch/arm/boards/phycard-i.MX27/pca100.c b/arch/arm/boards/phycard-i.MX27/pca100.c
index 7328a6c894..3a96180814 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 = {
@@ -109,6 +110,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 +186,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 +210,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;
diff --git a/arch/arm/configs/chumbyone_defconfig b/arch/arm/configs/chumbyone_defconfig
new file mode 100644
index 0000000000..595b6a9b4c
--- /dev/null
+++ b/arch/arm/configs/chumbyone_defconfig
@@ -0,0 +1,29 @@
+CONFIG_ARCH_STM=y
+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_PATH="arch/arm/boards/chumby_falconwing/env"
+CONFIG_DEBUG_INFO=y
+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_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+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
diff --git a/arch/arm/configs/cupid_defconfig b/arch/arm/configs/cupid_defconfig
new file mode 100644
index 0000000000..e24afe1d5a
--- /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
diff --git a/arch/arm/configs/eukrea_cpuimx25_defconfig b/arch/arm/configs/eukrea_cpuimx25_defconfig
index feb758e91d..bc68804d8c 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
diff --git a/arch/arm/configs/eukrea_cpuimx35_defconfig b/arch/arm/configs/eukrea_cpuimx35_defconfig
index 975d09519b..af82827dc4 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
diff --git a/arch/arm/configs/freescale_mx51_babbage_defconfig b/arch/arm/configs/freescale_mx51_babbage_defconfig
new file mode 100644
index 0000000000..d99d91a31e
--- /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/configs/imx23evk_defconfig b/arch/arm/configs/imx23evk_defconfig
new file mode 100644
index 0000000000..047a7e1586
--- /dev/null
+++ b/arch/arm/configs/imx23evk_defconfig
@@ -0,0 +1,24 @@
+CONFIG_ARCH_STM=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_BROKEN=y
+CONFIG_LONGHELP=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_PARTITION=y
+# CONFIG_DEFAULT_ENVIRONMENT is not set
+CONFIG_DEBUG_INFO=y
+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_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+# CONFIG_SPI is not set
diff --git a/arch/arm/configs/neso_defconfig b/arch/arm/configs/neso_defconfig
index 9f6e3f4b94..24125f914b 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/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index e3f41025ce..b81afe2a71 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
diff --git a/arch/arm/configs/pca100_defconfig b/arch/arm/configs/pca100_defconfig
index d1708a681e..8c72bdf237 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 8e60b0a6c3..e12f690f26 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 eacbbc6398..2038f1431f 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 51ca83320b..2dd711b39f 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/arch/arm/cpu/cache-l2x0.c b/arch/arm/cpu/cache-l2x0.c
index 61569d20b1..1ea7bab362 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) {
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 133d144e8c..346f8dce63 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>
diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c
index 0557172fe3..4a0b3f8db8 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);
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 5bf31c03bf..08a57ce815 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"
);
}
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index c1ac1aaf72..1d7f15a489 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/armlinux.c b/arch/arm/lib/armlinux.c
index 7c2cbf95ea..f826da64cb 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;
@@ -135,8 +136,7 @@ static void setup_serial_tag(void)
}
}
-#if 0
-static void setup_initrd_tag(ulong initrd_start, ulong initrd_end)
+static void setup_initrd_tag(image_header_t *header)
{
/* an ATAG_INITRD node tells the kernel where the compressed
* ramdisk can be found. ATAG_RDIMG is a better name, actually.
@@ -144,12 +144,11 @@ static void setup_initrd_tag(ulong initrd_start, ulong initrd_end)
params->hdr.tag = ATAG_INITRD2;
params->hdr.size = tag_size(tag_initrd);
- params->u.initrd.start = initrd_start;
- params->u.initrd.size = initrd_end - initrd_start;
+ params->u.initrd.start = image_get_load(header);
+ params->u.initrd.size = image_get_data_size(header);
params = tag_next(params);
}
-#endif
static void setup_end_tag (void)
{
@@ -157,17 +156,17 @@ static void setup_end_tag (void)
params->hdr.size = 0;
}
-static void setup_tags(void)
+static void setup_tags(struct image_data *data)
{
const char *commandline = getenv("bootargs");
setup_start_tag();
setup_memory_tags();
setup_commandline_tag(commandline);
-#if 0
- if (initrd_start && initrd_end)
- setup_initrd_tag (initrd_start, initrd_end);
-#endif
+
+ if (data && data->initrd)
+ setup_initrd_tag (&data->initrd->header);
+
setup_revision_tag();
setup_serial_tag();
setup_end_tag();
@@ -207,12 +206,12 @@ 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;
- 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;
}
@@ -232,13 +231,17 @@ int do_bootm_linux(struct image_data *data)
debug("## Transferring control to Linux (at address 0x%p) ...\n",
theKernel);
- setup_tags();
+ setup_tags(data);
if (relocate_image(data->os, (void *)image_get_load(os_header)))
return -1;
+ if (data->initrd)
+ if (relocate_image(data->initrd, (void *)image_get_load(&data->initrd->header)))
+ return -1;
+
/* we assume that the kernel is in place */
- printf("\nStarting kernel ...\n\n");
+ printf("\nStarting kernel %s...\n\n", data->initrd ? "with initrd " : "");
shutdown_barebox();
theKernel (0, armlinux_architecture, armlinux_bootparams);
@@ -335,7 +338,7 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[])
printf("loaded zImage from %s with size %d\n", argv[1], header.end);
- setup_tags();
+ setup_tags(NULL);
shutdown_barebox();
theKernel(0, armlinux_architecture, armlinux_bootparams);
@@ -379,7 +382,7 @@ static int do_bootu(struct command *cmdtp, int argc, char *argv[])
if (!theKernel)
theKernel = (void *)simple_strtoul(argv[1], NULL, 0);
- setup_tags();
+ setup_tags(NULL);
shutdown_barebox();
theKernel(0, armlinux_architecture, armlinux_bootparams);
diff --git a/arch/arm/lib/div0.c b/arch/arm/lib/div0.c
index 6267bf16a5..99d6b85ea2 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();
}
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 84df1a13ad..c1b42f92c9 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 3aa8e14a7a..a1e315dca6 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/Kconfig b/arch/arm/mach-imx/Kconfig
index 4f95393e00..f3506af5d9 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -17,6 +17,8 @@ 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
+ default 0x87f00000 if MACH_GUF_CUPID
config BOARDINFO
default "Eukrea CPUIMX25" if MACH_EUKREA_CPUIMX25
@@ -32,13 +34,15 @@ 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
+ default "Garz+Fricke Cupid" if MACH_GUF_CUPID
config ARCH_HAS_FEC_IMX
bool
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 +98,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
# ----------------------------------------------------------
@@ -292,12 +301,36 @@ 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
# ----------------------------------------------------------
+if ARCH_IMX51
+
+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
+
menu "Board specific settings "
if MACH_PCM043
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index de62f7eaab..ce38566502 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/clocksource.c b/arch/arm/mach-imx/clocksource.c
index a16603854d..5b1bad52f8 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);
}
@@ -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 */
@@ -97,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 0x04 /* Watchdog Service Register */
+#define WDOG_WSTR 0x08 /* 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)
+void __noreturn reset_cpu (unsigned long addr)
{
/* 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/gpio.c b/arch/arm/mach-imx/gpio.c
index c6a59a66cf..0a3e0461eb 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;
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index 8c4fc11a0c..075ed22f20 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 0000000000..0dee7c310c
--- /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/clock.h b/arch/arm/mach-imx/include/mach/clock.h
index 76ab4a53c1..5b590a251e 100644
--- a/arch/arm/mach-imx/include/mach/clock.h
+++ b/arch/arm/mach-imx/include/mach/clock.h
@@ -28,8 +28,11 @@ 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);
+void imx_dump_clocks(void);
+
#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h
index d15f52bc7f..fe74cb63c3 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
+
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 4b89838685..9ca838b71d 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-nand.h b/arch/arm/mach-imx/include/mach/imx-nand.h
index 06acddb2f7..eb583a22b7 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 */
diff --git a/arch/arm/mach-imx/include/mach/imx-regs.h b/arch/arm/mach-imx/include/mach/imx-regs.h
index 2cc49dd6ad..605d320d9a 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/imx1-regs.h b/arch/arm/mach-imx/include/mach/imx1-regs.h
index 0d6fd9200e..f940cdb4b2 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 6d64b811e1..a2c4d03643 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 f4354ba9b7..e87d5bf241 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 */
@@ -227,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
*/
diff --git a/arch/arm/mach-imx/include/mach/imx31-regs.h b/arch/arm/mach-imx/include/mach/imx31-regs.h
index d2304ec6c0..536bf0dad4 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 5cfb788c5b..89ca7eafcd 100644
--- a/arch/arm/mach-imx/include/mach/imx35-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
@@ -51,6 +51,8 @@
#define IMX_SDHC1_BASE 0x53FB4000
#define IMX_SDHC2_BASE 0x53FB8000
#define IMX_SDHC3_BASE 0x53FBC000
+#define IMX_OTG_BASE 0x53FF4000
+#define IMX_WDOG_BASE 0x53fdc000
/*
* Clock Controller Module (CCM)
@@ -73,6 +75,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)
@@ -132,15 +136,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
new file mode 100644
index 0000000000..1719a787c5
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/imx51-regs.h
@@ -0,0 +1,124 @@
+#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 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-mx25.h b/arch/arm/mach-imx/include/mach/iomux-mx25.h
index a290a338d8..a8ca8f1b60 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)
diff --git a/arch/arm/mach-imx/include/mach/iomux-mx27.h b/arch/arm/mach-imx/include/mach/iomux-mx27.h
index 993b141040..23e448b213 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)
diff --git a/arch/arm/mach-imx/include/mach/iomux-mx35.h b/arch/arm/mach-imx/include/mach/iomux-mx35.h
index 8a56d86791..ad7ff565af 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)
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 0000000000..2901ee609e
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/iomux-mx51.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer <s.hauer@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 1d660a0af3..198286a1f6 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/include/mach/usb.h b/arch/arm/mach-imx/include/mach/usb.h
new file mode 100644
index 0000000000..5d6670d067
--- /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_*/
diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c
index 96056741e6..cb28e9f77d 100644
--- a/arch/arm/mach-imx/speed-imx25.c
+++ b/arch/arm/mach-imx/speed-imx25.c
@@ -82,7 +82,12 @@ unsigned long imx_get_i2cclk(void)
return imx_get_perclk(6);
}
-int imx_dump_clocks(void)
+unsigned long imx_get_mmcclk(void)
+{
+ return imx_get_perclk(3);
+}
+
+void imx_dump_clocks(void)
{
printf("mpll: %10d Hz\n", imx_get_mpllclk());
printf("upll: %10d Hz\n", imx_get_upllclk());
@@ -92,7 +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));
- return 0;
+ printf("i2c: %10d Hz\n", imx_get_perclk(6));
+ printf("sdhc1: %10d Hz\n", imx_get_perclk(3));
}
/*
diff --git a/arch/arm/mach-imx/speed-imx27.c b/arch/arm/mach-imx/speed-imx27.c
index cdcd4191fe..0a92d29f1c 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;
diff --git a/arch/arm/mach-imx/speed-imx35.c b/arch/arm/mach-imx/speed-imx35.c
index c5a31c7996..8937ef1bbf 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);
@@ -163,6 +164,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 +195,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());
}
/*
diff --git a/arch/arm/mach-imx/speed-imx51.c b/arch/arm/mach-imx/speed-imx51.c
new file mode 100644
index 0000000000..99832971dc
--- /dev/null
+++ b/arch/arm/mach-imx/speed-imx51.c
@@ -0,0 +1,190 @@
+#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);
+}
+
+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;
+ 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_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;
+
+ return rate / (prediv * podf);
+}
+
+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/arch/arm/mach-imx/speed.c b/arch/arm/mach-imx/speed.c
index e024733246..750ace0545 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
diff --git a/arch/arm/mach-omap/arch-omap.dox b/arch/arm/mach-omap/arch-omap.dox
index df16b7be96..9c90b4fb16 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
+@code
+#define OMAP_SOMETHING_BASE
+@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.
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index 9893145780..f780794282 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-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 1cc8a23751..88d45fe370 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/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
diff --git a/arch/arm/mach-s3c24xx/gpio-s3c24x0.c b/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
new file mode 100644
index 0000000000..3d5e5e5c96
--- /dev/null
+++ b/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;
+ }
+}
diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio.h b/arch/arm/mach-s3c24xx/include/mach/gpio.h
new file mode 100644
index 0000000000..37db4f55fc
--- /dev/null
+++ b/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 */
diff --git a/arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h b/arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h
new file mode 100644
index 0000000000..2c64a979df
--- /dev/null
+++ b/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 */
diff --git a/arch/ppc/lib/cache.c b/arch/arm/mach-s3c24xx/include/mach/mci.h
index 3d863b327b..6ba8961693 100644
--- a/arch/ppc/lib/cache.c
+++ b/arch/arm/mach-s3c24xx/include/mach/mci.h
@@ -1,6 +1,12 @@
/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * (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.
@@ -21,30 +27,20 @@
* 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;
+#ifndef __MACH_MMC_H_
+#define __MACH_MMC_H_
- 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 */
+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;
+};
- 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
-}
+#endif /* __MACH_MMC_H_ */
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
new file mode 100644
index 0000000000..021919a8a8
--- /dev/null
+++ b/arch/arm/mach-stm/Kconfig
@@ -0,0 +1,48 @@
+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"
+
+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"
+
+config MACH_MX23EVK
+ bool "mx23-evk"
+ 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
+
+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 0000000000..59d70b6b55
--- /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 0000000000..7c0268c1fb
--- /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/lib/cache.c b/arch/arm/mach-stm/imx23.c
index 61ee9d3b13..14a4249893 100644
--- a/arch/arm/lib/cache.c
+++ b/arch/arm/mach-stm/imx23.c
@@ -1,9 +1,5 @@
/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
+ * (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
@@ -21,16 +17,19 @@
* MA 02111-1307 USA
*/
-/* for now: just dummy functions to satisfy the linker */
-
#include <common.h>
+#include <command.h>
-void flush_cache (unsigned long dummy1, unsigned long dummy2)
+extern void imx_dump_clocks(void);
+
+static int do_clocks(struct command *cmdtp, int argc, char *argv[])
{
-#ifdef CONFIG_OMAP2420
- void arm1136_cache_flush(void);
+ imx_dump_clocks();
- arm1136_cache_flush();
-#endif
- return;
+ 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 0000000000..0e1a6d6f42
--- /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 0000000000..3a552a8979
--- /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 0000000000..fa8263cc95
--- /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 0000000000..40dc74262e
--- /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 0000000000..89ca45374d
--- /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 0000000000..bebaf56571
--- /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/include/mach/mci.h b/arch/arm/mach-stm/include/mach/mci.h
new file mode 100644
index 0000000000..b9249085ae
--- /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 */
diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx23.c
new file mode 100644
index 0000000000..b0f4046e30
--- /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 0000000000..b35f796b40
--- /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 addr)
+{
+ 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 0000000000..7418ad57dd
--- /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));
+}
diff --git a/arch/blackfin/lib/cpu.c b/arch/blackfin/lib/cpu.c
index f96d22da13..aed0864a9c 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/lib/m68k-linuxboot.c b/arch/m68k/lib/m68k-linuxboot.c
index e5e90a8722..144d5a30b1 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/m68k/mach-mcfv4e/mcf_reset_cpu.c b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
index 3b1a25b269..d4659d22aa 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/lib/Makefile b/arch/ppc/lib/Makefile
index 400b1e128d..0844d5608c 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/ppclinux.c b/arch/ppc/lib/ppclinux.c
index 5ee908d132..fc22a87170 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/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu.c
index 7ee1954be4..4d08c55714 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/board/hostfile.c b/arch/sandbox/board/hostfile.c
index ad625d7a6e..38a52a886c 100644
--- a/arch/sandbox/board/hostfile.c
+++ b/arch/sandbox/board/hostfile.c
@@ -79,7 +79,9 @@ static int hf_probe(struct device_d *dev)
priv->cdev.size = hf->size;
priv->cdev.ops = &hf_fops;
priv->cdev.priv = hf;
+#ifdef CONFIG_FS_DEVFS
devfs_create(&priv->cdev);
+#endif
return 0;
}
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index c73aa79f2e..287be0d13b 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);
@@ -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/arch/x86/boards/x86_generic/generic_pc.c b/arch/x86/boards/x86_generic/generic_pc.c
index a6cd7e0de3..b9c31aa61f 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/arch/x86/boot/boot_hdisk.S b/arch/x86/boot/boot_hdisk.S
index 40388e993d..fc4c4d5c80 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 f3d248ae5b..94fe434b0a 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 d48e1983f1..0e4cd38536 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 01450fa596..cb2f833178 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 2b6dc85ed2..06141955fd 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
diff --git a/arch/x86/mach-x86.dox b/arch/x86/mach-x86.dox
index fc5b85a081..661e905bac 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)
diff --git a/commands/Kconfig b/commands/Kconfig
index 0fc80aad1a..54160737b8 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/bmp.c b/commands/bmp.c
index 6e17200a1a..5bac031004 100644
--- a/commands/bmp.c
+++ b/commands/bmp.c
@@ -193,17 +193,28 @@ 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\n")
+BAREBOX_CMD_HELP_SHORT("Show the bitmap FILE on the framebuffer.\n")
+BAREBOX_CMD_HELP_OPT ("-f <fb>", "framebuffer device (/dev/fb0)\n")
+BAREBOX_CMD_HELP_OPT ("-x <xofs>", "x offset (default center)\n")
+BAREBOX_CMD_HELP_OPT ("-y <yofs>", "y offset (default center)\n")
+BAREBOX_CMD_HELP_OPT ("-o", "render offscreen\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page bmp_command
+
+This command displays a graphics in the bitmap (.bmp) format on the
+framebuffer. Currently the bmp command supports images with 8 and 24 bit
+color depth.
+
+\todo What does the -o (offscreen) option do?
+
+ */
BAREBOX_CMD_START(bmp)
.cmd = do_bmp,
.usage = "show a bmp image",
BAREBOX_CMD_HELP(cmd_bmp_help)
BAREBOX_CMD_END
-
diff --git a/commands/bootm.c b/commands/bootm.c
index 83d36d3e2e..991431bf77 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;
}
@@ -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)
{
@@ -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(os_header) == handler->image_type) {
handler->bootm(&data);
printf("handler returned!\n");
goto err_out;
@@ -368,19 +368,25 @@ 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_HELP_START(bootm)
+BAREBOX_CMD_HELP_USAGE("bootm [-n] image\n")
+BAREBOX_CMD_HELP_SHORT("Boot an application image.\n")
+BAREBOX_CMD_HELP_OPT ("-n", "Do not verify the image (speeds up boot process)\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(bootm)
.cmd = do_bootm,
- .usage = "boot application image",
+ .usage = "boot an application image",
BAREBOX_CMD_HELP(cmd_bootm_help)
BAREBOX_CMD_END
+/**
+ * @page bootm_command
+
+\todo What does bootm do, what kind of image does it boot?
+
+ */
+
#ifdef CONFIG_CMD_IMI
static int do_iminfo(struct command *cmdtp, int argc, char *argv[])
{
@@ -409,7 +415,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;
}
@@ -440,14 +446,16 @@ static int image_info (ulong addr)
return 0;
}
-BAREBOX_CMD(
- iminfo, 1, do_iminfo,
- "iminfo - print header information for application image\n",
- "addr [addr ...]\n"
- " - print header information for application image starting at\n"
- " address 'addr' in memory; this includes verification of the\n"
- " image contents (magic number, header and payload checksums)\n"
-);
+BAREBOX_CMD_HELP_START(iminfo)
+BAREBOX_CMD_HELP_USAGE("iminfo\n")
+BAREBOX_CMD_HELP_SHORT("Print header information for an application image.\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(iminfo)
+ .cmd = do_iminfo,
+ .usage = "print header information for an application image",
+ BAREBOX_CMD_HELP(cmd_iminfo_help)
+BAREBOX_CMD_END
#endif /* CONFIG_CMD_IMI */
diff --git a/commands/cat.c b/commands/cat.c
index 41b3324300..37e65050c3 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
- */
diff --git a/commands/cd.c b/commands/cd.c
index a842f4dc20..d73be32ab9 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)
- */
diff --git a/commands/clear.c b/commands/clear.c
index 7589a0c380..6a6b6c5a2d 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",
diff --git a/commands/cp.c b/commands/cp.c
index 2c35ba131c..ae8719b24b 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,19 @@ 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("copy file from <source> to <destination>.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page cp_command
+This command operates on files.
+
+If you want to copy between memory blocks, use 'memcpy'.
+
+\todo What does this mean? Add examples.
+ */
BAREBOX_CMD_START(cp)
.cmd = do_cp,
@@ -88,14 +97,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
- */
diff --git a/commands/crc.c b/commands/crc.c
index 4842cdc82f..0873a1c07e 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,24 +140,21 @@ static int do_crc(struct command *cmdtp, int argc, char *argv[])
printf("\n");
-out_free:
- free(buf);
-out:
- close(fd);
-
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"
-" -v <crc> Verfify\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
+BAREBOX_CMD_HELP_OPT ("-F <file>", "Use file to compare.\n")
+#endif
+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
-
diff --git a/commands/dfu.c b/commands/dfu.c
index 66fd6eaa62..385fd89d41 100644
--- a/commands/dfu.c
+++ b/commands/dfu.c
@@ -162,16 +162,24 @@ 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.\n")
+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_END
+
+/**
+ * @page dfu_command
+\<description> has the following form:
+device1(name1)[sr],device2(name2)[sr]
+'s' means 'safe mode' (download the complete image before flashing) and
+'r' that readback of the firmware is allowed.
+
+\todo Add example, how to use dfu from a Linux or Windows host.
+ */
BAREBOX_CMD_START(dfu)
.cmd = do_dfu,
diff --git a/commands/echo.c b/commands/echo.c
index dfa14d67b9..3e098df1d0 100644
--- a/commands/echo.c
+++ b/commands/echo.c
@@ -111,8 +111,25 @@ no_optarg_out:
return 1;
}
+BAREBOX_CMD_HELP_START(echo)
+BAREBOX_CMD_HELP_USAGE("echo [OPTIONS] [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
+
+/**
+ * @page echo_command
+
+\todo Add documentation for -a, -o and -e.
+
+ */
+
BAREBOX_CMD_START(echo)
.cmd = do_echo,
.usage = "echo args to console",
+ BAREBOX_CMD_HELP(cmd_echo_help)
BAREBOX_CMD_END
diff --git a/commands/edit.c b/commands/edit.c
index a65b08acd2..ca40d5921b 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)
{
@@ -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)
@@ -550,35 +550,25 @@ 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";
+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_END
-static const __maybe_unused char cmd_edit_usage[] = "edit a file";
+/**
+ * @page edit_command
+
+<p> Barebox contains a small text editor which can be used to edit
+config files in /env. You can move the cursor around with the arrow keys
+and type characters. </p>
+
+If called as sedit, the editor uses ansi codes to scroll the screen.
+ */
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.
- */
diff --git a/commands/export.c b/commands/export.c
index 31259cc9b4..98b1e1a8fc 100644
--- a/commands/export.c
+++ b/commands/export.c
@@ -51,9 +51,10 @@ static int do_export(struct command *cmdtp, int argc, char *argv[])
return 0;
}
-static const __maybe_unused char cmd_export_help[] =
-"Usage: export <var>[=value]...\n"
-"export an environment variable to subsequently executed scripts\n";
+BAREBOX_CMD_HELP_START(export)
+BAREBOX_CMD_HELP_USAGE("export <var>[=value]\n")
+BAREBOX_CMD_HELP_SHORT("export an environment variable to subsequently executed scripts\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(export)
.cmd = do_export,
@@ -61,10 +62,3 @@ BAREBOX_CMD_START(export)
BAREBOX_CMD_HELP(cmd_export_help)
BAREBOX_CMD_END
-/**
- * @page export_command export: Export an environment variable
- *
- * Usage: export \<var>[=value]...
- *
- * Export an environment variable to subsequently executed scripts.
- */
diff --git a/commands/flash.c b/commands/flash.c
index 20f5cfc33a..9a0eb50371 100644
--- a/commands/flash.c
+++ b/commands/flash.c
@@ -83,10 +83,10 @@ out:
return ret;
}
-static const __maybe_unused char cmd_erase_help[] =
-"Usage: erase <device> [area]\n"
-"Erase a flash device or parts of a device if an area specification\n"
-"is given\n";
+BAREBOX_CMD_HELP_START(erase)
+BAREBOX_CMD_HELP_USAGE("erase <device> [area]\n")
+BAREBOX_CMD_HELP_SHORT("Erase a flash device or parts of a device if an area specification is given.\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(erase)
.cmd = do_flerase,
@@ -94,16 +94,18 @@ BAREBOX_CMD_START(erase)
BAREBOX_CMD_HELP(cmd_erase_help)
BAREBOX_CMD_END
-/** @page erase_command erase Erase flash memory
- *
- * Usage is: erase \<devicee>
- *
- * Erase the flash memory behind the device. It depends on the device given,
- * what area will be erased. If the device represents the whole flash memory
- * the whole memory will be erased. If the device represents a partition on
- * a main flash memory, only this partition part will be erased.
- *
- * Refer \b addpart, \b delpart and \b devinfo for partition handling.
+/**
+ * @page erase_command
+
+<p> Erase the flash memory handled by this device. Which area will be
+erased depends on the device: If the device represents the whole flash
+memory, the whole memory will be erased. If the device represents a
+partition on a main flash memory, only this partition part will be
+erased. </p>
+
+Refer to \ref addpart_command, \ref delpart_command and \ref
+devinfo_command for partition handling.
+
*/
static int do_protect(struct command *cmdtp, int argc, char *argv[])
@@ -160,43 +162,57 @@ out:
return ret;
}
-static const __maybe_unused char cmd_protect_help[] =
-"Usage: (un)protect <device> [area]\n"
-"(un)protect a flash device or parts of a device if an area specification\n"
-"is given\n";
+BAREBOX_CMD_HELP_START(protect)
+BAREBOX_CMD_HELP_USAGE("protect <device> [area]\n")
+BAREBOX_CMD_HELP_SHORT("protect a flash device (or parts of a device, if an area is specified)\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(protect)
.cmd = do_protect,
- .usage = "enable FLASH write protection",
+ .usage = "enable flash write protection",
BAREBOX_CMD_HELP(cmd_protect_help)
BAREBOX_CMD_END
+/**
+ * @page protect_command
+
+Protect the flash memory behind the device. It depends on the device
+given, what area will be protected. If the device represents the whole
+flash memory the whole memory will be protected. If the device
+represents a partition on a main flash memory, only this partition part
+will be protected.
+
+Refer addpart_command, delpart_command and devinfo_command for partition
+handling.
+
+\todo Rework this documentation, what is an 'area'? Explain more about
+flashes here.
+
+ */
+
+BAREBOX_CMD_HELP_START(unprotect)
+BAREBOX_CMD_HELP_USAGE("unprotect <device> [area]\n")
+BAREBOX_CMD_HELP_SHORT("unprotect a flash device (or parts of a device, if an area is specified)\n")
+BAREBOX_CMD_HELP_END
+
BAREBOX_CMD_START(unprotect)
.cmd = do_protect,
- .usage = "disable FLASH write protection",
- BAREBOX_CMD_HELP(cmd_protect_help)
+ .usage = "disable flash write protection",
+ BAREBOX_CMD_HELP(cmd_unprotect_help)
BAREBOX_CMD_END
-/** @page protect_command protect Protect a flash memory
- *
- * Usage is: protect \<devicee>
- *
- * Protect the flash memory behind the device. It depends on the device given,
- * what area will be protected. If the device represents the whole flash memory
- * the whole memory will be protected. If the device represents a partition on
- * a main flash memory, only this partition part will be protected.
- *
- * Refer \b addpart, \b delpart and \b devinfo for partition handling.
- */
+/**
+ * @page unprotect_command
+
+Unprotect the flash memory behind the device. It depends on the device given,
+what area will be unprotected. If the device represents the whole flash memory
+the whole memory will be unprotected. If the device represents a partition
+on a main flash memory, only this partition part will be unprotected.
+
+Refer addpart_command, delpart_command and devinfo_command for partition
+handling.
+
+\todo Rework this documentation, what does it mean?
-/** @page unprotect_command unprotect Unprotect a flash memory
- *
- * Usage is: unprotect \<devicee>
- *
- * Unprotect the flash memory behind the device. It depends on the device given,
- * what area will be unprotected. If the device represents the whole flash memory
- * the whole memory will be unprotected. If the device represents a partition
- * on a main flash memory, only this partition part will be unprotected.
- *
- * Refer \b addpart, \b delpart and \b devinfo for partition handling.
*/
+
diff --git a/commands/gpio.c b/commands/gpio.c
index 2575c1e50e..0cf19fefc9 100644
--- a/commands/gpio.c
+++ b/commands/gpio.c
@@ -36,12 +36,14 @@ static int do_gpio_get_value(struct command *cmdtp, int argc, char *argv[])
return value;
}
-static const __maybe_unused char cmd_gpio_get_value_help[] =
-"Usage: gpio_set_value <gpio>\n";
+BAREBOX_CMD_HELP_START(gpio_get_value)
+BAREBOX_CMD_HELP_USAGE("gpio_get_value <gpio>\n")
+BAREBOX_CMD_HELP_SHORT("get the value of an gpio input pin\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(gpio_get_value)
.cmd = do_gpio_get_value,
- .usage = "return a gpio's value",
+ .usage = "return value of a gpio pin",
BAREBOX_CMD_HELP(cmd_gpio_get_value_help)
BAREBOX_CMD_END
@@ -60,8 +62,10 @@ static int do_gpio_set_value(struct command *cmdtp, int argc, char *argv[])
return 0;
}
-static const __maybe_unused char cmd_gpio_set_value_help[] =
-"Usage: gpio_set_value <gpio> <value>\n";
+BAREBOX_CMD_HELP_START(gpio_set_value)
+BAREBOX_CMD_HELP_USAGE("gpio_set_value <gpio> <value>\n")
+BAREBOX_CMD_HELP_SHORT("set the value of an gpio output pin\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(gpio_set_value)
.cmd = do_gpio_set_value,
@@ -85,13 +89,15 @@ static int do_gpio_direction_input(struct command *cmdtp, int argc, char *argv[]
return 0;
}
-static const __maybe_unused char cmd_do_gpio_direction_input_help[] =
-"Usage: gpio_direction_input <gpio>\n";
+BAREBOX_CMD_HELP_START(gpio_direction_input)
+BAREBOX_CMD_HELP_USAGE("gpio_direction_input <gpio>\n")
+BAREBOX_CMD_HELP_SHORT("set direction of a gpio pin to input\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(gpio_direction_input)
.cmd = do_gpio_direction_input,
- .usage = "set a gpio as output",
- BAREBOX_CMD_HELP(cmd_do_gpio_direction_input_help)
+ .usage = "set direction of a gpio pin to input",
+ BAREBOX_CMD_HELP(cmd_gpio_direction_input_help)
BAREBOX_CMD_END
static int do_gpio_direction_output(struct command *cmdtp, int argc, char *argv[])
@@ -111,12 +117,75 @@ static int do_gpio_direction_output(struct command *cmdtp, int argc, char *argv[
return 0;
}
-static const __maybe_unused char cmd_gpio_direction_output_help[] =
-"Usage: gpio_direction_output <gpio> <value>\n";
+BAREBOX_CMD_HELP_START(gpio_direction_output)
+BAREBOX_CMD_HELP_USAGE("gpio_direction_output <gpio> <value>\n")
+BAREBOX_CMD_HELP_SHORT("set direction of a gpio pin to output\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(gpio_direction_output)
.cmd = do_gpio_direction_output,
- .usage = "set a gpio as output",
+ .usage = "set direction of a gpio pin to output",
BAREBOX_CMD_HELP(cmd_gpio_direction_output_help)
BAREBOX_CMD_END
+/**
+ * @page gpio_for_users GPIO Handling
+
+@section regular_gpio General usage information
+
+These commands are available if the symbol @b CONFIG_GENERIC_GPIO and @b
+CONFIG_CMD_GPIO are enabled in Kconfig.
+
+@note All gpio related commands take a number to identify the pad. This
+number is architecture dependent and may not directly correlate with the
+pad numbers. Due to this, it is also possible that the numbers changes
+between @b barebox releases.
+
+@section gpio_dir_out Use Pad as GPIO Output
+@verbatim
+# gpio_direction_output <gpio_no> <initial_value>
+@endverbatim
+- gpio_no: Architecture dependend GPIO number
+- initial_value: Output value
+
+<p> To avoid glitches on the pad the routines will first sett up the
+pad's value and afterwards switch the pad to output (if the silicon is
+able to do so). If the pad is already configured in non-GPIO mode (if
+available), this command may silently fail. </p>
+
+@section gpio_dir_in Use Pad as GPIO Input
+@verbatim
+# gpio_direction_input <gpio_no>
+@endverbatim
+- gpio_no: Architecture dependent GPIO number
+
+<p> If the pad is already configured in non-GPIO mode (if available),
+this command may silently fail. </p>
+
+@section gpio_get_value Read Input Value from GPIO Pin
+@verbatim
+# gpio_get_value <gpio_no>
+@endverbatim
+
+<p> Reads the current value of a GPIO pin and return the value as a
+shell return code. There is no visible output on stdout. You can check
+the return value by using "echo $?". </p>
+
+<p> A return code other than '0' or '1' specifies an error code. </p>
+
+<p> If the pad is not configured in GPIO mode, this command may silently
+fail and return garbage. </p>
+
+@section gpio_set_value Set Output Value on GPIO Pin
+@verbatim
+# gpio_set_value <gpio_no> <value>
+@endverbatim
+- gpio_no: Architecture dependent GPIO number
+- value: Output value
+
+<p> Set a new output value on pad with GPIO number \<gpio_no>. </p>
+
+<p> If the pad is not configured in GPIO-mode, this command may silently
+fail. </p>
+
+*/
diff --git a/commands/linux16.c b/commands/linux16.c
index b15812f1d9..ec859a73ab 100644
--- a/commands/linux16.c
+++ b/commands/linux16.c
@@ -288,14 +288,22 @@ on_error:
return rc;
}
-static const __maybe_unused char cmd_linux16_help[] =
-"Usage: linux16 <file>\n"
-"Boot a linux kernel via real mode code\n";
+BAREBOX_CMD_HELP_START(linux16)
+BAREBOX_CMD_HELP_USAGE("linux16 <file>\n")
+BAREBOX_CMD_HELP_SHORT("Boot a kernel on x86 via real mode code.\n")
+BAREBOX_CMD_HELP_END
+/**
+ * @page linux16_command
+
+<p> Only kernel images in bzImage format are supported by now. See \ref
+x86_boot_preparation for more info about how to use this command.</p>
+
+ */
BAREBOX_CMD_START(linux16)
.cmd = do_linux16,
- .usage = "boot linux kernel",
+ .usage = "boot a linux kernel",
BAREBOX_CMD_HELP(cmd_linux16_help)
BAREBOX_CMD_END
@@ -305,15 +313,6 @@ BAREBOX_CMD_END
*/
/**
- * @page linux16_command linux16: Boot a bzImage kernel on x86
- *
- * Usage is: linux16 \<file\>
- *
- * Boot a linux kernel via real mode code. Only kernel images in the
- * @p bzImage format are supported.
- */
-
-/**
* @page x86_boot_preparation Linux Preparation on x86
*
* Due to some real mode constraints, starting Linux is somehow tricky.
diff --git a/commands/loadb.c b/commands/loadb.c
index acfb94fe08..faf4a97f6b 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/loadenv.c b/commands/loadenv.c
index 14fbf1e336..c33c34fcee 100644
--- a/commands/loadenv.c
+++ b/commands/loadenv.c
@@ -43,28 +43,22 @@ static int do_loadenv(struct command *cmdtp, int argc, char *argv[])
return envfs_load(filename, dirname);
}
-static const __maybe_unused char cmd_loadenv_help[] =
-"Usage: loadenv [ENVFS] [DIRECTORY]\n"
-"Load the persistent storage contained in <envfs> to the directory\n"
-"<directory>.\n"
-"If ommitted <directory> defaults to /env and <envfs> defaults to /dev/env0.\n"
-"Note that envfs can only handle files. Directories are skipped silently.\n";
+BAREBOX_CMD_HELP_START(loadenv)
+BAREBOX_CMD_HELP_USAGE("loadenv [ENVFS] [DIRECTORY]\n")
+BAREBOX_CMD_HELP_SHORT("Load environment from ENVFS into DIRECTORY (default: /dev/env0 -> /env).\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page loadenv_command
+
+ENVFS can only handle files, directories are skipped silently.
+
+\todo This needs proper documentation. What is ENVFS, why is it FS etc. Explain the concepts.
+
+ */
BAREBOX_CMD_START(loadenv)
.cmd = do_loadenv,
- .usage = "load environment from persistent storage",
+ .usage = "Load environment from ENVFS into DIRECTORY (default: /dev/env0 -> /env).",
BAREBOX_CMD_HELP(cmd_loadenv_help)
BAREBOX_CMD_END
-
-/**
- * @page loadenv_command loadenv
- *
- * Usage: loadenv [\<directory>] [\<envfs>]
- *
- * Load the persistent storage contained in \<envfs> to the directory \<directory>.
- *
- * If ommitted \<directory> defaults to \c /env and \<envfs> defaults to
- * \c /dev/env0.
- *
- * @note envfs can only handle files. Directories are skipped silently.
- */
diff --git a/commands/loads.c b/commands/loads.c
index 8269af1955..6e0dc7fabc 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/commands/ls.c b/commands/ls.c
index a02ccfe772..4f9c408b1d 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 [OPTIONS] [FILES]\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,
diff --git a/commands/mem.c b/commands/mem.c
index bc84f6d56e..73bf9158da 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;
diff --git a/commands/mount.c b/commands/mount.c
index 8e4388ecd8..52d1700a78 100644
--- a/commands/mount.c
+++ b/commands/mount.c
@@ -58,49 +58,45 @@ static int do_mount(struct command *cmdtp, int argc, char *argv[])
return 0;
}
-static const __maybe_unused char cmd_mount_help[] =
-"Usage: mount: list mounted filesystems\n"
-"or: mount <device> <fstype> <mountpoint>\n"
-"\n"
-"Mount a filesystem of a given type to a mountpoint.\n"
-"<device> can be one of /dev/* or some arbitrary string if no\n"
-"device is needed for this driver (for example ramfs).\n"
-"<fstype> is the filesystem driver to use. Try the 'devinfo' command\n"
-"for a list of available drivers.\n"
-"<mountpoint> must be an empty directory descending directly from the\n"
-"root directory.\n";
+BAREBOX_CMD_HELP_START(mount)
+BAREBOX_CMD_HELP_USAGE("mount [<device> <fstype> <mountpoint>]\n")
+BAREBOX_CMD_HELP_SHORT("Mount a filesystem of a given type to a mountpoint.\n")
+BAREBOX_CMD_HELP_SHORT("If no argument is given, list mounted filesystems.\n")
+BAREBOX_CMD_HELP_END
-BAREBOX_CMD_START(mount)
- .cmd = do_mount,
- .usage = "mount a filesystem to a device",
- BAREBOX_CMD_HELP(cmd_mount_help)
-BAREBOX_CMD_END
+/**
+ * @page mount_command
+
+<ul>
+<li>\<device> can be a device in /dev or some arbitrary string if no
+ device is needed for this driver, i.e. on ramfs. </li>
+<li>\<fstype> is the filesystem driver. A list of available drivers can
+ be shown with the \ref devinfo_command command.</li>
+<li>\<mountpoint> must be an empty directory, one level below the /
+ directory.</li>
+</ul>
-/** @page mount_command mount
- * Usage: mount [\<device> \<fstype> \<mountpoint>]
- *
- * Mounts a filesystem of a given \<fstype> on a \<device> to a \<mountpoint>.
- * \<device> can be one of /dev/ * or some arbitrary string if no
- * device is needed for this driver (for example ramfs).
- *
- * \<fstype> is the filesystem driver to use. Try the 'devinfo' command
- * for a list of available drivers.
- *
- * \<mountpoint> must be an empty directory descending directly from the
- * root directory.
*/
-/** @page how_mount_works How mount works in barebox
- *
- * Mounting a filesystem ontop of a device is working like devices and drivers
- * are finding together.
- *
- * The mount command creates a new device with the filesystem name as the
- * driver for this "device". So the framework is able to merge both parts
- * together.
- *
- * By the way: With this feature its impossible to accidentely remove
- * partitions in use. A partition is internally also a device. If its mounted
- * it will be marked as busy, so an delpart command fails, until the filesystem
- * has been unmounted.
+/**
+ * @page how_mount_works How mount works in barebox
+
+Mounting a filesystem ontop of a device is working like devices and
+drivers are finding together.
+
+The mount command creates a new device with the filesystem name as the
+driver for this "device". So the framework is able to merge both parts
+together.
+
+By the way: With this feature its impossible to accidentely remove
+partitions in use. A partition is internally also a device. If its
+mounted it will be marked as busy, so an delpart command fails, until
+the filesystem has been unmounted.
+
*/
+
+BAREBOX_CMD_START(mount)
+ .cmd = do_mount,
+ .usage = "Mount a filesystem of a given type to a mountpoint or list mounted filesystems.",
+ BAREBOX_CMD_HELP(cmd_mount_help)
+BAREBOX_CMD_END
diff --git a/commands/partition.c b/commands/partition.c
index 7794925943..db9b9fb0df 100644
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -149,19 +149,24 @@ 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_END
+
+/**
+ * @page addpart_command
+
+The size and the offset can be given in decimal (without any prefix) and
+in hex (prefixed with 0x). Both can have an optional suffix K, M or G.
+The size of the last partition can be specified as '-' for the remaining
+space on the device. This format is the same as used by the Linux
+kernel or cmdline mtd partitions.
+
+\todo This command has to be reworked and will probably change it's API.
+*/
BAREBOX_CMD_START(addpart)
.cmd = do_addpart,
@@ -169,26 +174,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;
@@ -204,9 +189,21 @@ 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 <part 1> [<part n>] \n")
+BAREBOX_CMD_HELP_SHORT("Delete partitions previously added to a device with addpart.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page delpart_command
+
+Partitions are created by adding their description with the addpart
+command. If you want to get rid of a partition again, use delpart. The
+argument list is taken as a list of partitions to be deleted.
+
+\todo Add an example
+
+ */
BAREBOX_CMD_START(delpart)
.cmd = do_delpart,
@@ -214,9 +211,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.
- */
diff --git a/commands/printenv.c b/commands/printenv.c
index e6fc0e4e55..4078bbcc34 100644
--- a/commands/printenv.c
+++ b/commands/printenv.c
@@ -65,26 +65,22 @@ static int do_printenv(struct command *cmdtp, int argc, char *argv[])
return 0;
}
-static const __maybe_unused char cmd_printenv_help[] =
-"\n - print values of all environment variables\n"
-"printenv name ...\n"
-" - print value of environment variable 'name'\n";
+BAREBOX_CMD_HELP_START(printenv)
+BAREBOX_CMD_HELP_USAGE("printenv [variable]\n")
+BAREBOX_CMD_HELP_SHORT("Print value of one or all environment variables.\n")
+BAREBOX_CMD_HELP_END
+/**
+ * @page printenv_command
+
+<p>If an argument is given, printenv prints the content of an environment
+variable to the terminal. If no argument is specified, all variables are
+printed.</p>
+
+ */
BAREBOX_CMD_START(printenv)
.cmd = do_printenv,
- .usage = "print environment variables",
+ .usage = "Print value of one or all environment variables.",
BAREBOX_CMD_HELP(cmd_printenv_help)
BAREBOX_CMD_END
-
-/**
- * @page printenv_command printenv
- *
- * Usage: printenv [\<name>]
- *
- * Print environment variables.
- * If \<name> was given, it prints out its content if the environment variable
- * \<name> exists.
- *
- * Without the \<name> argument all current environment variables are printed.
- */
diff --git a/commands/saveenv.c b/commands/saveenv.c
index 42ea58f4da..2f969fe7b9 100644
--- a/commands/saveenv.c
+++ b/commands/saveenv.c
@@ -94,12 +94,10 @@ out:
return ret;
}
-static const __maybe_unused char cmd_saveenv_help[] =
-"Usage: saveenv [<envfs>] [<directory>]\n"
-"Save the files in <directory> to the persistent storage device <envfs>.\n"
-"<envfs> is normally a block in flash, but could be any other file.\n"
-"If ommitted <directory> defaults to /env and <envfs> defaults to /dev/env0.\n"
-"Note that envfs can only handle files. Directories are skipped silently.\n";
+BAREBOX_CMD_HELP_START(saveenv)
+BAREBOX_CMD_HELP_USAGE("saveenv [envfs] [directory]\n")
+BAREBOX_CMD_HELP_SHORT("Save the files in <directory> to the persistent storage device <envfs>.\n")
+BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(saveenv)
.cmd = do_saveenv,
@@ -108,15 +106,14 @@ BAREBOX_CMD_START(saveenv)
BAREBOX_CMD_END
/**
- * @page saveenv_command saveenv
- *
- * Usage: saveenv [\<envfs>] [\<directory>]
- *
- * Save the files in \<directory> to the persistent storage device \<envfs>.
- * \<envfs> is normally a block in flash, but could be any other file.
- *
- * If ommitted \<directory> defaults to \c /env and \<envfs> defaults to
- * \c /dev/env0.
- *
- * @note envfs can only handle files. Directories are skipped silently.
+ * @page saveenv_command
+
+<p>\<envfs> is usually a block in flash but can be any other file. If
+ommitted, \<directory> defaults to /env and \<envfs> defaults to
+/dev/env0. Note that envfs can only handle files, directories are being
+skipped silently.</p>
+
+\todo What does 'block in flash' mean? Add example.
+
*/
+
diff --git a/commands/setenv.c b/commands/setenv.c
index 257348f80a..e39db20937 100644
--- a/commands/setenv.c
+++ b/commands/setenv.c
@@ -38,27 +38,23 @@ static int do_setenv(struct command *cmdtp, int argc, char *argv[])
return 0;
}
-static const __maybe_unused char cmd_setenv_help[] =
-"name value ...\n"
-" - set environment variable 'name' to 'value ...'\n"
-"setenv name\n"
-" - delete environment variable 'name'\n";
+BAREBOX_CMD_HELP_START(setenv)
+BAREBOX_CMD_HELP_USAGE("setenv <name> [<value>]\n")
+BAREBOX_CMD_HELP_SHORT("Set environment variable to a value or delete if value is avoided.\n")
+BAREBOX_CMD_HELP_END
+/**
+ * @page setenv_command
+
+<p> This command is only available if the simple command line parser is
+in use. Within the hush shell, \c setenv is not required.</p>
+
+\todo Check if kconfig does this correctly.
+
+ */
BAREBOX_CMD_START(setenv)
.cmd = do_setenv,
.usage = "set environment variables",
BAREBOX_CMD_HELP(cmd_setenv_help)
BAREBOX_CMD_END
-
-/**
- * @page setenv_command setenv: set an environment variable
- *
- * Usage: setenv \<name> [\<value>]
- *
- * Set environment variable \<name> to \<value>. Without a given value, the
- * environment variable will be deleted.
- *
- * @note This command is only available if the simple command line parser is
- * in use. Within the hush shell \c setenv is not required.
- */
diff --git a/commands/version.c b/commands/version.c
index 6c683d9bff..2b3ac05c0c 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/Kconfig b/common/Kconfig
index ad70cde4f3..617f640a57 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"
@@ -382,6 +389,22 @@ 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
+ select HUSH_GETOPT
+ select CMD_CRC
+ select CMD_CRC_CMP
+ 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 e56dbc21a8..753455b64f 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 > $@
diff --git a/common/console.c b/common/console.c
index 204a08c593..82786f2b03 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));
@@ -120,7 +118,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 +245,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)
{
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 83b1e187f8..ff63fbec49 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);
diff --git a/common/env.c b/common/env.c
index edaf388956..f81bd468ff 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;
diff --git a/common/environment.c b/common/environment.c
index 0eb7e6b6fc..e5f24ec201 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 */
diff --git a/common/hush.c b/common/hush.c
index 19e35f5fa1..77610bba7d 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;
};
@@ -267,13 +278,14 @@ 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);
/* 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);
@@ -350,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];
@@ -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().
@@ -515,7 +571,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 +597,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 */ }
@@ -580,13 +636,17 @@ static int run_pipe_real(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);
+ parse_string_outer(&ctx1, str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
+ release_context(&ctx1);
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]);
}
@@ -601,7 +661,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 +759,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;
@@ -790,6 +850,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;
@@ -853,11 +914,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,
@@ -887,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;
}
@@ -928,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.
@@ -1371,7 +1446,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;
@@ -1533,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[])
@@ -1564,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;
@@ -1577,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;
}
@@ -1627,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
diff --git a/common/image.c b/common/image.c
index 104446a785..a4c8b95210 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/common/kallsyms.c b/common/kallsyms.c
index 4069f4b701..490adb9223 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)
diff --git a/common/memsize.c b/common/memsize.c
index 505e43f0cb..e3bc56ce8a 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__)
/*
diff --git a/common/parser.c b/common/parser.c
index 97e354bae9..fd578c728b 100644
--- a/common/parser.c
+++ b/common/parser.c
@@ -6,9 +6,8 @@ static int parse_line (char *line, char *argv[])
{
int nargs = 0;
-#ifdef DEBUG_PARSER
- printf ("parse_line: \"%s\"\n", line);
-#endif
+ pr_debug("parse_line: \"%s\"\n", line);
+
while (nargs < CONFIG_MAXARGS) {
/* skip any white space */
@@ -18,9 +17,9 @@ static int parse_line (char *line, char *argv[])
if (*line == '\0') { /* end of line, no more args */
argv[nargs] = NULL;
-#ifdef DEBUG_PARSER
- printf ("parse_line: nargs=%d\n", nargs);
-#endif
+
+ pr_debug("parse_line: nargs=%d\n", nargs);
+
return (nargs);
}
@@ -33,9 +32,9 @@ static int parse_line (char *line, char *argv[])
if (*line == '\0') { /* end of line, no more args */
argv[nargs] = NULL;
-#ifdef DEBUG_PARSER
- printf ("parse_line: nargs=%d\n", nargs);
-#endif
+
+ pr_debug("parse_line: nargs=%d\n", nargs);
+
return (nargs);
}
@@ -43,10 +42,8 @@ static int parse_line (char *line, char *argv[])
}
printf ("** Too many args (max. %d) **\n", CONFIG_MAXARGS);
+ pr_debug("parse_line: nargs=%d\n", nargs);
-#ifdef DEBUG_PARSER
- printf ("parse_line: nargs=%d\n", nargs);
-#endif
return (nargs);
}
@@ -61,12 +58,12 @@ static void process_macros (const char *input, char *output)
/* 1 = waiting for '(' or '{' */
/* 2 = waiting for ')' or '}' */
/* 3 = waiting for ''' */
-#ifdef DEBUG_PARSER
+#ifdef DEBUG
char *output_start = output;
+#endif
- printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input),
+ pr_debug("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input),
input);
-#endif
prev = '\0'; /* previous character */
@@ -153,10 +150,8 @@ static void process_macros (const char *input, char *output)
if (outputcnt)
*output = 0;
-#ifdef DEBUG_PARSER
- printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
+ pr_debug("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
strlen (output_start), output_start);
-#endif
}
/****************************************************************************
@@ -185,8 +180,8 @@ int run_command (const char *cmd, int flag)
int argc, inquotes;
int rc = 0;
-#ifdef DEBUG_PARSER
- printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
+#ifdef DEBUG
+ pr_debug("[RUN_COMMAND] cmd[%p]=\"", cmd);
puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */
puts ("\"\n");
#endif
@@ -202,13 +197,13 @@ int run_command (const char *cmd, int flag)
strcpy (cmdbuf, cmd);
- /* Process separators and check for invalid
+ /*
+ * Process separators and check for invalid
* repeatable commands
*/
-#ifdef DEBUG_PARSER
- printf ("[PROCESS_SEPARATORS] %s\n", cmd);
-#endif
+ pr_debug("[PROCESS_SEPARATORS] %s\n", cmd);
+
while (*str) {
/*
@@ -235,11 +230,11 @@ int run_command (const char *cmd, int flag)
str = sep + 1; /* start of command for next pass */
*sep = '\0';
}
- else
+ else {
str = sep; /* no more commands for next pass */
-#ifdef DEBUG_PARSER
- printf ("token: \"%s\"\n", token);
-#endif
+ }
+
+ pr_debug("token: \"%s\"\n", token);
/* find macros in this token and replace them */
process_macros (token, finaltoken);
diff --git a/defaultenv/bin/_update b/defaultenv/bin/_update
index ddd6b84f72..87e6922326 100644
--- a/defaultenv/bin/_update
+++ b/defaultenv/bin/_update
@@ -10,18 +10,16 @@ if [ ! -e "$part" ]; then
exit 1
fi
-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 = 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
@@ -34,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
new file mode 100644
index 0000000000..22d940e142
--- /dev/null
+++ b/defaultenv/bin/_update_help
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+echo "usage: $0 -t <kernel|rootfs|barebox> -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"
+echo "type update -t barebox -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update barebox into flash"
diff --git a/defaultenv/bin/boot b/defaultenv/bin/boot
index 6476bdb4d4..42c7ec2965 100644
--- a/defaultenv/bin/boot
+++ b/defaultenv/bin/boot
@@ -16,7 +16,7 @@ fi
if [ x$ip = xdhcp ]; then
bootargs="$bootargs ip=dhcp"
elif [ x$ip = xnone ]; then
- bootargs="ip=none"
+ bootargs="$bootargs ip=none"
else
bootargs="$bootargs ip=$eth0.ipaddr::$eth0.gateway:$eth0.netmask:::"
fi
@@ -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
diff --git a/defaultenv/bin/init b/defaultenv/bin/init
index a55e8e60a3..96a5716628 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
@@ -25,8 +29,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 0000000000..3601177308
--- /dev/null
+++ b/defaultenv/bin/update
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+. /env/config
+
+type=""
+device_type=""
+check=n
+mode=tftp
+
+while getopt "ht:d:f:m:c" Option
+do
+if [ ${Option} = t ]; then
+ type=${OPTARG}
+elif [ ${Option} = d ]; then
+ device_type=${OPTARG}
+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
+fi
+done
+
+if [ x${type} = xkernel ]; then
+ image=$kernelimage
+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
+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
+
+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
+fi
diff --git a/defaultenv/bin/update_kernel b/defaultenv/bin/update_kernel
deleted file mode 100644
index 1d35ed9727..0000000000
--- 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 63663150c2..0000000000
--- 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
diff --git a/drivers/Kconfig b/drivers/Kconfig
index f7154c62dc..d94017bfc1 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -9,6 +9,8 @@ source "drivers/mtd/Kconfig"
source "drivers/ata/Kconfig"
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 706e1c8ac2..242a564dd7 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -6,5 +6,7 @@ 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/
+obj-y += mfd/
diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index 250dadaa2a..a54429a5f1 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>
@@ -34,6 +35,7 @@
#include <errno.h>
#include <string.h>
#include <linux/kernel.h>
+#include <malloc.h>
/**
* Description of one partition table entry (D*S type)
@@ -105,7 +107,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,
@@ -268,23 +271,22 @@ 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 */
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
@@ -298,28 +300,39 @@ 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);
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 */
- 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;
+ }
- 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
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 9ce16558c4..c2af818393 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 0584b5589d..42e22c01b0 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/i2c/mc13892.c b/drivers/i2c/mc13892.c
deleted file mode 100644
index 67d4232a23..0000000000
--- a/drivers/i2c/mc13892.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2007 Sascha Hauer, Pengutronix
- * 2009 Marc Kleine-Budde <mkl@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
- *
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <xfuncs.h>
-#include <errno.h>
-
-#include <i2c/i2c.h>
-#include <i2c/mc13892.h>
-
-#define DRIVERNAME "mc13892"
-
-#define to_mc13892(a) container_of(a, struct mc13892, cdev)
-
-static struct mc13892 *mc_dev;
-
-struct mc13892 *mc13892_get(void)
-{
- if (!mc_dev)
- return NULL;
-
- return mc_dev;
-}
-EXPORT_SYMBOL(mc13892_get);
-
-int mc13892_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val)
-{
- u8 buf[3];
- int ret;
-
- ret = i2c_read_reg(mc13892->client, reg, buf, 3);
- *val = buf[0] << 16 | buf[1] << 8 | buf[2] << 0;
-
- return ret == 3 ? 0 : ret;
-}
-EXPORT_SYMBOL(mc13892_reg_read)
-
-int mc13892_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val)
-{
- u8 buf[] = {
- val >> 16,
- val >> 8,
- val >> 0,
- };
- int ret;
-
- ret = i2c_write_reg(mc13892->client, reg, buf, 3);
-
- return ret == 3 ? 0 : ret;
-}
-EXPORT_SYMBOL(mc13892_reg_write)
-
-int mc13892_set_bits(struct mc13892 *mc13892, enum mc13892_reg reg, u32 mask, u32 val)
-{
- u32 tmp;
- int err;
-
- err = mc13892_reg_read(mc13892, reg, &tmp);
- tmp = (tmp & ~mask) | val;
-
- if (!err)
- err = mc13892_reg_write(mc13892, reg, tmp);
-
- return err;
-}
-EXPORT_SYMBOL(mc13892_set_bits);
-
-static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
-{
- struct mc13892 *priv = to_mc13892(cdev);
- u32 *buf = _buf;
- size_t i = count >> 2;
- int err;
-
- offset >>= 2;
-
- while (i) {
- err = mc13892_reg_read(priv, offset, buf);
- if (err)
- return (ssize_t)err;
- buf++;
- i--;
- offset++;
- }
-
- return count;
-}
-
-static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
-{
- struct mc13892 *mc13892 = to_mc13892(cdev);
- const u32 *buf = _buf;
- size_t i = count >> 2;
- int err;
-
- offset >>= 2;
-
- while (i) {
- err = mc13892_reg_write(mc13892, offset, *buf);
- if (err)
- return (ssize_t)err;
- buf++;
- i--;
- offset++;
- }
-
- return count;
-}
-
-static struct file_operations mc_fops = {
- .lseek = dev_lseek_default,
- .read = mc_read,
- .write = mc_write,
-};
-
-static int mc_probe(struct device_d *dev)
-{
- if (mc_dev)
- return -EBUSY;
-
- mc_dev = xzalloc(sizeof(struct mc13892));
- mc_dev->cdev.name = DRIVERNAME;
- mc_dev->client = to_i2c_client(dev);
- mc_dev->cdev.size = 256;
- mc_dev->cdev.dev = dev;
- mc_dev->cdev.ops = &mc_fops;
-
- devfs_create(&mc_dev->cdev);
-
- return 0;
-}
-
-static struct driver_d mc_driver = {
- .name = DRIVERNAME,
- .probe = mc_probe,
-};
-
-static int mc_init(void)
-{
- register_driver(&mc_driver);
- return 0;
-}
-
-device_initcall(mc_init);
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
new file mode 100644
index 0000000000..b1f2773354
--- /dev/null
+++ b/drivers/mci/Kconfig
@@ -0,0 +1,64 @@
+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 ---"
+
+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.
+
+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.
+
+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.
+
+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
new file mode 100644
index 0000000000..a10cb47960
--- /dev/null
+++ b/drivers/mci/Makefile
@@ -0,0 +1,5 @@
+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 0000000000..63cd059f6d
--- /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@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 0000000000..19fed5aebf
--- /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__ */
diff --git a/drivers/mci/imx.c b/drivers/mci/imx.c
new file mode 100644
index 0000000000..852569275b
--- /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@emcraft.com>
+ * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@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);
+
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
new file mode 100644
index 0000000000..a8aa486d4c
--- /dev/null
+++ b/drivers/mci/mci-core.c
@@ -0,0 +1,1360 @@
+/*
+ * (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:
+ * - 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)
+ */
+
+/**
+ * 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);
+}
+
+static void *sector_buf;
+
+/**
+ * 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;
+ 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 = buf;
+ 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
+ * @param blocks number of blocks to read
+ */
+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,
+ mmccmd,
+ mci->high_capacity != 0 ? blocknum : blocknum * mci->read_bl_len,
+ MMC_RSP_R1);
+
+ data.dest = dst;
+ data.blocks = blocks;
+ data.blocksize = mci->read_bl_len;
+ data.flags = MMC_DATA_READ;
+
+ 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;
+}
+
+/**
+ * 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 = sector_buf;
+ 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 = sector_buf;
+ uint32_t *scr = sector_buf;
+ 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 with %d\n", (unsigned)sector_start, rc);
+ 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) {
+ 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, now);
+ if (rc != 0) {
+ pr_err("Reading block %lu failed with %d\n", (unsigned)sector_start, rc);
+ return rc;
+ }
+ sector_count -= now;
+ buffer += mci->read_bl_len * now;
+ sector_start += now;
+ }
+
+ 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);
+ rc = sd_send_op_cond(mci_dev);
+ if (rc && rc == -ETIMEDOUT) {
+ /* If the command timed out, we check for an MMC card */
+ 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);
+ 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)
+{
+ sector_buf = memalign(32, 512);
+ if (!sector_buf)
+ return -ENOMEM;
+
+ return register_driver(&mci_driver);
+}
+
+device_initcall(mci_init);
+
+/**
+ * Create a new mci device (for convenience)
+ * @param host mci_host 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/drivers/mci/s3c.c b/drivers/mci/s3c.c
new file mode 100644
index 0000000000..9810683f4b
--- /dev/null
+++ b/drivers/mci/s3c.c
@@ -0,0 +1,817 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert <juergen@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@maintech.de>
+ * Copyright (C) 2008 Simtec Electronics <ben-linux@fluff.org>
+ * (C) Copyright 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@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);
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
new file mode 100644
index 0000000000..420c2ea92b
--- /dev/null
+++ b/drivers/mci/stm378x.c
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe@pengutronix.de>
+ *
+ * This code is based on:
+ *
+ * Copyright (C) 2007 SigmaTel, Inc., Ioannis Kappas <ikappas@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, div, rate, reg;
+
+ if (nc == 0U) {
+ /* TODO stop the clock */
+ return 0;
+ }
+
+ ssp = imx_get_sspclk(0) * 1000;
+
+ for (div = 2; div < 255; div += 2) {
+ rate = (((ssp + (nc >> 1) ) / nc) + (div >> 1)) / div;
+ if (rate <= 0x100)
+ break;
+ }
+ 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(div) | SSP_TIMING_CLOCK_RATE(rate - 1);
+ writel(reg, hw_dev->map_base + HW_SSP_TIMING);
+
+ return ssp / div / rate;
+}
+
+/**
+ * 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(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(0) / 254U / 256U * 1000U);
+ }
+ if (pd->f_max == 0) {
+ 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(0) / 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);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
new file mode 100644
index 0000000000..96440d852f
--- /dev/null
+++ b/drivers/mfd/Kconfig
@@ -0,0 +1,28 @@
+menu MFD
+
+config I2C_MC13892
+ depends on I2C || SPI
+ 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 0000000000..d411f23b69
--- /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
index 98266990dc..98266990dc 100644
--- a/drivers/i2c/lp3972.c
+++ b/drivers/mfd/lp3972.c
diff --git a/drivers/spi/mc13783.c b/drivers/mfd/mc13783.c
index 19e2780920..19e2780920 100644
--- a/drivers/spi/mc13783.c
+++ b/drivers/mfd/mc13783.c
diff --git a/drivers/mfd/mc13892.c b/drivers/mfd/mc13892.c
new file mode 100644
index 0000000000..08a439b4c7
--- /dev/null
+++ b/drivers/mfd/mc13892.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2007 Sascha Hauer, Pengutronix
+ * 2009 Marc Kleine-Budde <mkl@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
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <xfuncs.h>
+#include <errno.h>
+#include <spi/spi.h>
+#include <malloc.h>
+
+#include <i2c/i2c.h>
+#include <mfd/mc13892.h>
+
+#define DRIVERNAME "mc13892"
+
+#define to_mc13892(a) container_of(a, struct mc13892, cdev)
+
+static struct mc13892 *mc_dev;
+
+struct mc13892 *mc13892_get(void)
+{
+ if (!mc_dev)
+ return NULL;
+
+ return mc_dev;
+}
+EXPORT_SYMBOL(mc13892_get);
+
+#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;
+
+ ret = i2c_read_reg(mc13892->client, reg, buf, 3);
+ *val = buf[0] << 16 | buf[1] << 8 | buf[2] << 0;
+
+ return ret == 3 ? 0 : ret;
+}
+
+static int mc13892_i2c_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val)
+{
+ u8 buf[] = {
+ val >> 16,
+ val >> 8,
+ val >> 0,
+ };
+ int ret;
+
+ ret = i2c_write_reg(mc13892->client, reg, buf, 3);
+
+ 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;
+ int err;
+
+ err = mc13892_reg_read(mc13892, reg, &tmp);
+ tmp = (tmp & ~mask) | val;
+
+ if (!err)
+ err = mc13892_reg_write(mc13892, reg, tmp);
+
+ return err;
+}
+EXPORT_SYMBOL(mc13892_set_bits);
+
+static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
+{
+ struct mc13892 *priv = to_mc13892(cdev);
+ u32 *buf = _buf;
+ size_t i = count >> 2;
+ int err;
+
+ offset >>= 2;
+
+ while (i) {
+ err = mc13892_reg_read(priv, offset, buf);
+ if (err)
+ return (ssize_t)err;
+ buf++;
+ i--;
+ offset++;
+ }
+
+ return count;
+}
+
+static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
+{
+ struct mc13892 *mc13892 = to_mc13892(cdev);
+ const u32 *buf = _buf;
+ size_t i = count >> 2;
+ int err;
+
+ offset >>= 2;
+
+ while (i) {
+ err = mc13892_reg_write(mc13892, offset, *buf);
+ if (err)
+ return (ssize_t)err;
+ buf++;
+ i--;
+ offset++;
+ }
+
+ return count;
+}
+
+static struct file_operations mc_fops = {
+ .lseek = dev_lseek_default,
+ .read = mc_read,
+ .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;
+
+ mc_dev = xzalloc(sizeof(struct mc13892));
+ mc_dev->mode = mode;
+ mc_dev->cdev.name = DRIVERNAME;
+ 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;
+
+ rev = mc13893_query_revision(mc_dev);
+ if (rev < 0) {
+ free(mc_dev);
+ return -EINVAL;
+ }
+
+ devfs_create(&mc_dev->cdev);
+
+ return 0;
+}
+
+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_i2c_driver);
+ register_driver(&mc_spi_driver);
+ return 0;
+}
+
+device_initcall(mc_init);
diff --git a/drivers/i2c/mc34704.c b/drivers/mfd/mc34704.c
index 51a8737209..a2171b35d1 100644
--- a/drivers/i2c/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/i2c/mc9sdz60.c b/drivers/mfd/mc9sdz60.c
index 3580af8852..db208ec2db 100644
--- a/drivers/i2c/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/i2c/twl4030.c b/drivers/mfd/twl4030.c
index 5305ec67e3..81bf48bbb7 100644
--- a/drivers/i2c/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/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 475499a600..bc95195116 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 5454e32083..63ba188789 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;
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 73b7a5476b..9c8de77dab 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 e1473a4271..ce0fd89ec4 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;
};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index c7ea2d974d..3a8882fd1d 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 959290e642..9f0e12b01d 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/serial_imx.c b/drivers/serial/serial_imx.c
index 801004e186..a7562f9db1 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
@@ -170,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;
@@ -189,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;
@@ -317,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;
@@ -330,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;
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
new file mode 100644
index 0000000000..90563f599e
--- /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@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);
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 3eebd08983..a88e179e5a 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -9,8 +9,14 @@ config DRIVER_SPI_IMX
depends on ARCH_IMX
depends on SPI
-config DRIVER_SPI_MC13783
- bool "MC13783 a.k.a. PMIC driver"
- 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
endmenu
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 81f2c6bc62..b2b2f6788f 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
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 5c9791978a..2ad1bfa499 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -26,47 +26,104 @@
#include <asm/io.h>
#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)
+#include <mach/generic.h>
+
+#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)
+
+#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,
+#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);
+ 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)
@@ -77,29 +134,31 @@ 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 + 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)
+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->chipselect[spi->chip_select];
+ int gpio = imx->cs_array[spi->chip_select];
u32 ctrl_reg;
if (spi->mode & SPI_CS_HIGH)
@@ -111,35 +170,156 @@ 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);
}
+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)
{
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 +327,39 @@ 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,
+ .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
+};
+
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,15 +369,22 @@ 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;
-
- 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);
+ imx->cs_array = pdata->chipselect;
+
+#ifdef CONFIG_DRIVER_SPI_IMX_0_0
+ 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;
+
+ imx->init(imx);
spi_register_master(master);
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 119afcb6c5..48fd0b5fb9 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",
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 0c30c52fc9..05f1628fab 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 72edf25843..40771699ea 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/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
index 2c25b81f41..c38082d6c6 100644
--- a/drivers/video/imx-ipu-fb.c
+++ b/drivers/video/imx-ipu-fb.c
@@ -722,55 +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 imx_ipu_fb_rgb *rgb;
- 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);
-
- 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;
-}
-
/* 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() */
@@ -823,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);
@@ -840,8 +799,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);
@@ -855,6 +812,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;
@@ -871,13 +861,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");
/*
diff --git a/fs/ramfs.c b/fs/ramfs.c
index 9ecb824d0b..62225504b5 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) {
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index 1d3f4f7ac8..fc141a474e 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
diff --git a/include/cache.h b/include/cache.h
index 5968da907f..23841dcd06 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);
diff --git a/include/command.h b/include/command.h
index 4a4d9cf925..e221546091 100644
--- a/include/command.h
+++ b/include/command.h
@@ -76,22 +76,36 @@ 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) \
-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 \
};
+#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
#define BAREBOX_CMD_HELP(text)
#endif
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
int register_command(struct command *);
#endif /* __COMMAND_H */
diff --git a/include/common.h b/include/common.h
index 64f49db387..394542f762 100644
--- a/include/common.h
+++ b/include/common.h
@@ -216,4 +216,8 @@ int run_shell(void);
#define PAGE_SIZE 4096
+int memory_display(char *addr, ulong offs, ulong nbytes, int size);
+
+extern const char version_string[];
+
#endif /* __COMMON_H_ */
diff --git a/include/image.h b/include/image.h
index 2c5956d600..8932947b7e 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);
@@ -391,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
diff --git a/include/mci.h b/include/mci.h
new file mode 100644
index 0000000000..8c669ca0af
--- /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_ */
diff --git a/include/i2c/lp3972.h b/include/mfd/lp3972.h
index edb5801118..edb5801118 100644
--- a/include/i2c/lp3972.h
+++ b/include/mfd/lp3972.h
diff --git a/include/i2c/mc13892.h b/include/mfd/mc13892.h
index 112d05ba69..78a42e99a4 100644
--- a/include/i2c/mc13892.h
+++ b/include/mfd/mc13892.h
@@ -79,9 +79,32 @@ 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,
+};
+
struct mc13892 {
struct cdev cdev;
struct i2c_client *client;
+ struct spi_device *spi;
+ enum mc13892_mode mode;
+ enum mc13892_revision revision;
};
extern struct mc13892 *mc13892_get(void);
@@ -90,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 */
diff --git a/include/i2c/mc34704.h b/include/mfd/mc34704.h
index a3723d72a9..a3723d72a9 100644
--- a/include/i2c/mc34704.h
+++ b/include/mfd/mc34704.h
diff --git a/include/i2c/mc9sdz60.h b/include/mfd/mc9sdz60.h
index 3882cea1a0..3882cea1a0 100644
--- a/include/i2c/mc9sdz60.h
+++ b/include/mfd/mc9sdz60.h
diff --git a/include/i2c/twl4030.h b/include/mfd/twl4030.h
index 3fef4d9ad6..3fef4d9ad6 100644
--- a/include/i2c/twl4030.h
+++ b/include/mfd/twl4030.h
diff --git a/include/notifier.h b/include/notifier.h
index 878b17e078..cb2be5f548 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);
diff --git a/lib/Kconfig b/lib/Kconfig
index 9eca161bef..ad2b3cf0c8 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -11,7 +11,7 @@ config CRC16
bool
menuconfig DIGEST
- bool "Digest"
+ bool "Digest "
if DIGEST
diff --git a/lib/Makefile b/lib/Makefile
index 0c62917b43..8b986d2a70 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/copy_file.c b/lib/copy_file.c
index 0ff0435f11..70835319b6 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
/**
diff --git a/lib/crc32.c b/lib/crc32.c
index 34817824f1..275edb4c52 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;
diff --git a/lib/driver.c b/lib/driver.c
index 66d8fee38f..ff92e44d21 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;
@@ -244,6 +244,26 @@ int dummy_probe(struct device_d *dev)
}
EXPORT_SYMBOL(dummy_probe);
+const char *dev_id(const struct device_d *dev)
+{
+ static char buf[sizeof(unsigned long) * 2];
+
+ sprintf(buf, FORMAT_DRIVER_MANE_ID, dev->name, dev->id);
+
+ return buf;
+}
+
+void devices_shutdown(void)
+{
+ struct device_d *dev;
+
+ list_for_each_entry(dev, &active, active) {
+ if (dev->driver->remove)
+ dev->driver->remove(dev);
+ }
+}
+
+#ifdef CONFIG_CMD_DEVINFO
static int do_devinfo_subtree(struct device_d *dev, int depth, char edge)
{
struct device_d *child;
@@ -276,27 +296,6 @@ static int do_devinfo_subtree(struct device_d *dev, int depth, char edge)
return 0;
}
-const char *dev_id(const struct device_d *dev)
-{
- static char buf[sizeof(unsigned long) * 2];
-
- sprintf(buf, FORMAT_DRIVER_MANE_ID, dev->name, dev->id);
-
- return buf;
-}
-
-void devices_shutdown(void)
-{
- struct device_d *dev;
-
- list_for_each_entry(dev, &active, active) {
- if (dev->driver->remove)
- dev->driver->remove(dev);
- }
-}
-
-#ifdef CONFIG_CMD_DEVINFO
-
static int do_devinfo(struct command *cmdtp, int argc, char *argv[])
{
struct device_d *dev;
@@ -315,7 +314,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]);
@@ -340,30 +339,22 @@ static int do_devinfo(struct command *cmdtp, int argc, char *argv[])
return 0;
}
-static const __maybe_unused char cmd_devinfo_help[] =
-"Usage: devinfo [DEVICE]\n"
-"If called without arguments devinfo shows a summary about known devices and\n"
-"drivers. If called with a device path as argument devinfo shows more detailed\n"
-"information about this device and its parameters.\n";
+BAREBOX_CMD_HELP_START(devinfo)
+BAREBOX_CMD_HELP_USAGE("devinfo [DEVICE]\n")
+BAREBOX_CMD_HELP_SHORT("Output device information.\n")
+BAREBOX_CMD_HELP_END
-BAREBOX_CMD_START(devinfo)
- .cmd = do_devinfo,
- .usage = "display info about devices and drivers",
- BAREBOX_CMD_HELP(cmd_devinfo_help)
-BAREBOX_CMD_END
+/**
+ * @page devinfo_command
-#endif
+If called without arguments, devinfo shows a summary of the known
+devices and drivers.
+
+If called with a device path being the argument, devinfo shows more
+default information about this device and its parameters.
+
+Example from an MPC5200 based system:
-/**
- * @page devinfo_command devinfo
- *
- * Usage is: devinfo /dev/\<device>
- *
- * If called without arguments devinfo shows a summary about known devices and
- * drivers. If called with a device path as argument devinfo shows more
- * detailed information about this device and its parameters.
- *
- * Example from an MPC5200 based system:
@verbatim
barebox:/ devinfo /dev/eth0
base : 0x1002b000
@@ -378,5 +369,12 @@ BAREBOX_CMD_END
netmask = 255.255.255.0
serverip = 192.168.23.2
@endverbatim
- *
*/
+
+BAREBOX_CMD_START(devinfo)
+ .cmd = do_devinfo,
+ .usage = "Show information about devices and drivers.",
+ BAREBOX_CMD_HELP(cmd_devinfo_help)
+BAREBOX_CMD_END
+#endif
+
diff --git a/lib/fnmatch.c b/lib/fnmatch.c
index 223b9d3cda..1a5e8d0d3d 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;
diff --git a/lib/glob.c b/lib/glob.c
index a5e3d1d67a..43d2f671b5 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]);
diff --git a/lib/ldiv.c b/lib/ldiv.c
deleted file mode 100644
index 5d231a2a65..0000000000
--- 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;
-}
diff --git a/lib/libbb.c b/lib/libbb.c
index ee91fec18b..4d532f6161 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;
diff --git a/lib/parameter.c b/lib/parameter.c
index 0aa4193431..379a0577ed 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)
{
diff --git a/lib/process_escape_sequence.c b/lib/process_escape_sequence.c
index 546edaa01f..e3431d4b9f 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)
{
diff --git a/lib/readline.c b/lib/readline.c
index b82150e355..b90de77fd7 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; \
} \
diff --git a/net/net.c b/net/net.c
index 8d9959520c..a613d1da74 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++);;
diff --git a/net/ping.c b/net/ping.c
index 440e229ba0..d414784e23 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;
diff --git a/net/tftp.c b/net/tftp.c
index 6345a7220d..6be8b8f623 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -364,15 +364,29 @@ out_close:
return tftp_err == 0 ? 0 : 1;
}
-static const __maybe_unused char cmd_tftp_help[] =
-"Usage: tftp <remotefile> [localfile]\n"
-"Load a file from a TFTP server.\n"
+BAREBOX_CMD_HELP_START(tftp)
#ifdef CONFIG_NET_TFTP_PUSH
-"or\n"
-" tftp -p <localfile> [remotefile]\n"
-"Upload a file to a TFTP server\n"
+BAREBOX_CMD_HELP_USAGE("tftp <remotefile> [localfile], tftp -p <localfile> [remotefile]\n")
+BAREBOX_CMD_HELP_SHORT("Load a file from or upload to TFTP server.\n")
+BAREBOX_CMD_HELP_END
+#else
+BAREBOX_CMD_HELP_USAGE("tftp <remotefile> [localfile]\n")
+BAREBOX_CMD_HELP_SHORT("Load a file from a TFTP server.\n")
+BAREBOX_CMD_HELP_END
#endif
-;
+
+/**
+ * @page tftp_command
+
+The second file argument can be skipped in which case the first filename
+is used (without the directory part).
+
+\<localfile> can be the local filename or a device file under /dev.
+This also works for flash memory. Refer to \ref erase_command and \ref
+unprotect_command for flash preparation.
+
+\note This command is available only if enabled in menuconfig.
+ */
BAREBOX_CMD_START(tftp)
.cmd = do_tftpb,
@@ -384,24 +398,3 @@ BAREBOX_CMD_START(tftp)
BAREBOX_CMD_HELP(cmd_tftp_help)
BAREBOX_CMD_END
-/**
- * @page tftp_command tftp
- *
- * Usage:
- * tftp \<remotefilename\> [\<localfilename\>]
- *
- * or
- *
- * tftp -p \<localfilename\> [\<remotefilename\>]
- *
- * Load a file from a tftp server or upload a file to a tftp server if
- * the -p option is given. The second file argument can be skipped in
- * which case the first filename is used (without the directory part).
- *
- * \<localfile> can be the local filename or a device file under /dev.
- * This also works for flash memory. Refer to \b erase, \b unprotect for
- * flash preparation.
- *
- * Note: This command is available only if enabled in menuconfig.
- */
-
diff --git a/scripts/doxy_filter.awk b/scripts/doxy_filter.awk
new file mode 100644
index 0000000000..5ec0406298
--- /dev/null
+++ b/scripts/doxy_filter.awk
@@ -0,0 +1,103 @@
+#!/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("@", "\\\\@", "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;
+
+}
+
diff --git a/scripts/mkimage.c b/scripts/mkimage.c
index f6cbb1c4c9..40a3483138 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);