diff --git a/Documentation/barebox-main.dox b/Documentation/barebox-main.dox index fb780e6..90fce8e 100644 --- a/Documentation/barebox-main.dox +++ b/Documentation/barebox-main.dox @@ -1,166 +1,74 @@ -/** @mainpage Universal Bootloader +/** @mainpage Barebox -@section barebox_intro Introduction +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. -@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. +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 General features include: +@par Highlights: -- 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. +- POSIX File API:
+ @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. -- usual shell commands like ls/cd/mkdir/echo/cat,... +- Shell:
+ We have the standard 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. +- Environment Filesystem:
+ 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'. -- 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. +- Filesystem Support:
+ 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. -- 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. +- Driver Model (borrowed from Linux):
+ 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. -- 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. +- Clocksource:
+ We use the clocksource API knwon from Linux. -- 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. +- Kconfig/Kbuild:
+ This gives us parallel builds and removes the need for lots of ifdefs. -- 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. +- Sandbox:
+ 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. -- device parameter support - - Each device can have a unlimited number of parameters. They can be accessed - on the command line with \.\="...", for example - 'eth0.ip=192.168.0.7' or 'echo $eth0.ip' +- Device Parameters:
+ 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 \.\="...". 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'. -- initcalls - - hooks in the startup process can be achieved with *_initcall() directives - in each file. +- Getopt:
+ @a Barebox has a lightweight getopt() implementation. This makes it + unnecessary to use positional parameters, which can be hard to read. -- 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. +- Integrated Editor:
+ 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. -- 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] \ 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 \ 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 3eb79b2..fa0f284 100644 --- a/Documentation/boards.dox +++ b/Documentation/boards.dox @@ -8,18 +8,23 @@ 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 @@ @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 0000000..527ca45 --- /dev/null +++ b/Documentation/building.dox @@ -0,0 +1,60 @@ +/** @page building Building + +This section describes how to build the Barebox bootloader. + +@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=\ +- CROSS_COMPILE=\ + +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 \' 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 a8850b1..27eb511 100644 --- a/Documentation/commands.dox +++ b/Documentation/commands.dox @@ -1,24 +1,48 @@ /** - * @page command_reference Supported Shell Commands + * @page command_reference Shell Commands + +This section describes the commands which are available on the @a +Barebox shell. + +@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 620905e..2f7d360 100644 --- a/Documentation/developers_manual.dox +++ b/Documentation/developers_manual.dox @@ -20,6 +20,5 @@ @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 0000000..edc612f --- /dev/null +++ b/Documentation/first_steps.dox @@ -0,0 +1,61 @@ +/** @page first_steps First Steps + +This section demonstrates the first steps with the 'sandbox' +platform. + +@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] \ 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 \ 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 cd2b99c..ea47b18 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 40bcb2f..d9ce22c 100644 --- a/Doxyfile +++ b/Doxyfile @@ -424,7 +424,7 @@ # 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 @@ drivers \ commands \ common \ - board \ lib \ scripts/setupmbr \ net @@ -504,6 +503,7 @@ FILE_PATTERNS = *.c \ *.h \ + *.S \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories @@ -516,7 +516,9 @@ # 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 @@ # 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 @@ # 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 @@ # 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 @@ # 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 @@ # 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 @@ # 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 fa37036..8cb86cb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -39,6 +39,10 @@ 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_S3C24xx bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443" select CPU_ARM920T + select GENERIC_GPIO endchoice @@ -62,6 +67,7 @@ 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 77b6cf4..cdb0185 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -41,6 +41,7 @@ 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_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 0000000..0bc79d9 --- /dev/null +++ b/arch/arm/boards/chumby_falconwing/Makefile @@ -0,0 +1 @@ +obj-y = falconwing.o diff --git a/arch/arm/boards/chumby_falconwing/config.h b/arch/arm/boards/chumby_falconwing/config.h new file mode 100644 index 0000000..87d9e2f --- /dev/null +++ b/arch/arm/boards/chumby_falconwing/config.h @@ -0,0 +1,21 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _CONFIG_H_ +# define _CONFIG_H_ + +#endif /* _CONFIG_H_ */ diff --git a/arch/arm/boards/chumby_falconwing/env/bin/boot b/arch/arm/boards/chumby_falconwing/env/bin/boot new file mode 100644 index 0000000..981a387 --- /dev/null +++ b/arch/arm/boards/chumby_falconwing/env/bin/boot @@ -0,0 +1,38 @@ +#!/bin/sh + +. /env/config + +if [ x$1 = xdisk ]; then + rootfs_loc=disk + kernel_loc=disk +elif [ x$1 = xnet ]; then + rootfs_loc=net + kernel_loc=net +fi + +if [ x$ip = xdhcp ]; then + bootargs="$bootargs ip=dhcp" +elif [ x$ip = xnone ]; then + bootargs="$bootargs ip=none" +else + bootargs="$bootargs ip=$eth0.ipaddr::$eth0.gateway:$eth0.netmask:::" +fi + +if [ x$rootfs_loc = xdisk ]; then + bootargs="$bootargs noinitrd rootfstype=$rootfs_type root=/dev/$rootfs_part" +elif [ x$rootfs_loc = xnet ]; then + bootargs="$bootargs root=/dev/nfs nfsroot=$nfsroot,v3,tcp noinitrd" +elif [ x$rootfs_loc = xinitrd ]; then + bootargs="$bootargs root=/dev/ram0 rdinit=/sbin/init" +fi + +if [ x$kernelimage_type = xuimage ]; then + bootm /dev/$kernel_part +elif [ x$kernelimage_type = xzimage ]; then + bootz /dev/$kernel_part +else + echo "Booting failed. Correct setup of 'kernelimage_type'?" + exit +fi + +echo "Booting failed. Correct setup of 'kernel_part'?" diff --git a/arch/arm/boards/chumby_falconwing/env/bin/init b/arch/arm/boards/chumby_falconwing/env/bin/init new file mode 100644 index 0000000..3ed68f7 --- /dev/null +++ b/arch/arm/boards/chumby_falconwing/env/bin/init @@ -0,0 +1,15 @@ +#!/bin/sh + +PATH=/env/bin +export PATH + +. /env/config + +echo +echo -n "Hit any key to stop autoboot: " +timeout -a $autoboot_timeout +if [ $? != 0 ]; then + exit +fi + +boot diff --git a/arch/arm/boards/chumby_falconwing/env/config b/arch/arm/boards/chumby_falconwing/env/config new file mode 100644 index 0000000..1e61dce --- /dev/null +++ b/arch/arm/boards/chumby_falconwing/env/config @@ -0,0 +1,36 @@ +#!/bin/sh + +machine=falconwing + +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration +ip=none + +# or set your networking parameters here (if a USB network adapter is attached) +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d +#eth0.gateway=a.b.c.d +#eth0.serverip=a.b.c.d + +# can be either 'net' or 'disk' +kernel_loc=disk +# can be either 'net', or 'disk' or 'initrd' +rootfs_loc=disk + +# can be any regular filesystem like ext2, ext3, reiserfs in case of 'rootfs_loc=disk' +rootfs_type=ext2 +# Where is the rootfs in case of 'rootfs_loc=disk' +rootfs_part=mmcblk0p4 + +# Where is the rootfs in case of 'rootfs_loc=net' +nfsroot=FIXME + +# The image type of the kernel. Can be uimage, zimage +kernelimage_type=uimage +# Where to get the kernel image in case of 'kernel_loc=disk' +kernel_part=disk0.2 + +# base kernel parameter +bootargs="console=ttyAM0,115200 debug ro lcd_panel=lms350 ssp1=mmc line=1 sysrq_always_enabled rotary=1" + +autoboot_timeout=2 diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c new file mode 100644 index 0000000..952a384 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 335d7ae..4732875 100644 --- a/arch/arm/boards/eukrea_cpuimx25/env/bin/init +++ b/arch/arm/boards/eukrea_cpuimx25/env/bin/init @@ -14,9 +14,11 @@ 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 9217ca1..3e41ec8 100644 --- a/arch/arm/boards/eukrea_cpuimx25/env/config +++ b/arch/arm/boards/eukrea_cpuimx25/env/config @@ -13,7 +13,7 @@ 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 7fd1031..805ffe2 100644 --- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c +++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c @@ -40,6 +40,9 @@ #include #include #include +#include +#include +#include extern unsigned long _stext; extern void exception_vectors(void); @@ -151,6 +154,60 @@ .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 @@ 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 @@ 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 @@ 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 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 @@ } #endif -static int eukrea_cpuimx25_core_setup(void) -{ - writel(0x01010103, IMX_CCM_BASE + CCM_PCDR2); - return 0; +static int eukrea_cpuimx25_core_init(void) { + /* enable UART1, FEC, SDHC, USB & I2C clock */ + writel(readl(IMX_CCM_BASE + CCM_CGCR0) | (1 << 6) | (1 << 23) + | (1 << 15) | (1 << 21) | (1 << 3) | (1 << 28), + IMX_CCM_BASE + CCM_CGCR0); + writel(readl(IMX_CCM_BASE + CCM_CGCR1) | (1 << 23) | (1 << 15) + | (1 << 13), IMX_CCM_BASE + CCM_CGCR1); + writel(readl(IMX_CCM_BASE + CCM_CGCR2) | (1 << 14), + IMX_CCM_BASE + CCM_CGCR2); + return 0; } -core_initcall(eukrea_cpuimx25_core_setup); + +core_initcall(eukrea_cpuimx25_core_init); diff --git a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c index b9d3ce5..4ebf247 100644 --- a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c +++ b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c @@ -26,13 +26,13 @@ #include #include #include -#include #include #include #include #include #include +#ifdef CONFIG_NAND_IMX_BOOT static void __bare_init __naked insdram(void) { uint32_t r; @@ -45,17 +45,32 @@ 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 @@ */ 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 7272e56..0e1c80a 100644 --- a/arch/arm/boards/eukrea_cpuimx27/env/bin/boot +++ b/arch/arm/boards/eukrea_cpuimx27/env/bin/boot @@ -27,12 +27,14 @@ bootargs="$bootargs ip=off" fi -if [ x$root = xnand ]; then - bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2" -elif [ x$root = xnor ]; then - bootargs="$bootargs root=$rootpart_nor rootfstype=jffs2" +if [ x$rootfstype = xubifs ]; then + bootargs="$bootargs root=ubi0:$ubiroot ubi.mtd=$rootpartnum rootfstype=ubifs" else - bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp" + if [ x$root = xnand ]; then + bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2" + elif [ x$root = xnor ]; then + bootargs="$bootargs root=$rootpart_nor rootfstype=jffs2" + fi fi bootargs="$bootargs mtdparts=physmap-flash.0:$nor_parts;mxc_nand:$nand_parts" diff --git a/arch/arm/boards/eukrea_cpuimx27/env/bin/init b/arch/arm/boards/eukrea_cpuimx27/env/bin/init index 3bfd194..aefd67c 100644 --- a/arch/arm/boards/eukrea_cpuimx27/env/bin/init +++ b/arch/arm/boards/eukrea_cpuimx27/env/bin/init @@ -16,11 +16,21 @@ source /env/bin/hush_hack fi +if [ -f /env/logo.bmp ]; then + bmp /env/logo.bmp + fb0.enable=1 +elif [ -f /env/logo.bmp.lzo ]; then + unlzo /env/logo.bmp.lzo /logo.bmp + bmp /logo.bmp + fb0.enable=1 +fi + if [ -z $eth0.ethaddr ]; then while [ -z $eth0.ethaddr ]; do readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr done echo -a /env/config "eth0.ethaddr=$eth0.ethaddr" + saveenv fi echo diff --git a/arch/arm/boards/eukrea_cpuimx27/env/config b/arch/arm/boards/eukrea_cpuimx27/env/config index 505ada3..7f56003 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 @@ 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 4d1797b..62fc14e 100644 --- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c +++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include static struct device_d cfi_dev = { @@ -275,6 +275,7 @@ 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 @@ 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 90007cd..b56d7b5 100644 --- a/arch/arm/boards/eukrea_cpuimx35/env/bin/init +++ b/arch/arm/boards/eukrea_cpuimx35/env/bin/init @@ -15,12 +15,12 @@ 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 df2079f..fc99e51 100644 --- a/arch/arm/boards/eukrea_cpuimx35/env/config +++ b/arch/arm/boards/eukrea_cpuimx35/env/config @@ -13,7 +13,7 @@ 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 63d019a..dfe64d0 100644 --- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c +++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c @@ -51,6 +51,9 @@ #include #include #include +#include +#include +#include static struct fec_platform_data fec_info = { .xcv_type = MII100, @@ -126,6 +129,60 @@ .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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { u32 reg; - /* enable clock for I2C1 and FEC */ + /* enable clock for I2C1, SDHC1, USB and FEC */ reg = readl(IMX_CCM_BASE + CCM_CGR1); reg |= 0x3 << CCM_CGR1_FEC_SHIFT; + reg |= 0x3 << CCM_CGR1_SDHC1_SHIFT; + reg |= 0x3 << CCM_CGR1_I2C1_SHIFT, reg = writel(reg, IMX_CCM_BASE + CCM_CGR1); + reg = readl(IMX_CCM_BASE + CCM_CGR2); + reg |= 0x3 << CCM_CGR2_USB_SHIFT; + reg = writel(reg, IMX_CCM_BASE + CCM_CGR2); /* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/ /* diff --git a/arch/arm/boards/eukrea_cpuimx35/flash_header.c b/arch/arm/boards/eukrea_cpuimx35/flash_header.c index 285a2d4..5a77c3a 100644 --- a/arch/arm/boards/eukrea_cpuimx35/flash_header.c +++ b/arch/arm/boards/eukrea_cpuimx35/flash_header.c @@ -12,30 +12,30 @@ 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 aad334d..6c0e106 100644 --- a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c +++ b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c @@ -66,6 +66,7 @@ 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 @@ 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 @@ 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 0000000..cffb561 --- /dev/null +++ b/arch/arm/boards/freescale-mx23-evk/Makefile @@ -0,0 +1,2 @@ +# +obj-y := mx23-evk.o diff --git a/arch/arm/boards/freescale-mx23-evk/config.h b/arch/arm/boards/freescale-mx23-evk/config.h new file mode 100644 index 0000000..4b3da8f --- /dev/null +++ b/arch/arm/boards/freescale-mx23-evk/config.h @@ -0,0 +1,16 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ diff --git a/arch/arm/boards/freescale-mx23-evk/mx23-evk.c b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c new file mode 100644 index 0000000..1ce72be --- /dev/null +++ b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +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 70de7958..25945f1 100644 --- a/arch/arm/boards/freescale-mx25-3-stack/3stack.c +++ b/arch/arm/boards/freescale-mx25-3-stack/3stack.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include extern unsigned long _stext; extern void exception_vectors(void); diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c index 71aaa92..d6699cd 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 #include -#include -#include +#include +#include /* Board rev for the PDK 3stack */ @@ -111,7 +111,7 @@ 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 0000000..8e0c87c --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/Makefile @@ -0,0 +1,3 @@ +obj-y += lowlevel_init.o +obj-y += board.o +obj-y += flash_header.o diff --git a/arch/arm/boards/freescale-mx51-pdk/board.c b/arch/arm/boards/freescale-mx51-pdk/board.c new file mode 100644 index 0000000..5197c55 --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/board.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct memory_platform_data ram_pdata = { + .name = "ram0", + .flags = DEVFS_RDWR, +}; + +static struct device_d sdram_dev = { + .id = -1, + .name = "mem", + .map_base = 0x90000000, + .size = 512 * 1024 * 1024, + .platform_data = &ram_pdata, +}; + +static struct fec_platform_data fec_info = { + .xcv_type = MII100, +}; + +static struct device_d fec_dev = { + .name = "fec_imx", + .map_base = 0x83fec000, + .platform_data = &fec_info, +}; + +static struct device_d esdhc_dev = { + .name = "imx-esdhc", + .map_base = 0x70004000, +}; + +static struct pad_desc f3s_pads[] = { + MX51_PAD_EIM_EB2__FEC_MDIO, + MX51_PAD_EIM_EB3__FEC_RDATA1, + MX51_PAD_EIM_CS2__FEC_RDATA2, + MX51_PAD_EIM_CS3__FEC_RDATA3, + MX51_PAD_EIM_CS4__FEC_RX_ER, + MX51_PAD_EIM_CS5__FEC_CRS, + MX51_PAD_NANDF_RB2__FEC_COL, + MX51_PAD_NANDF_RB3__FEC_RX_CLK, + MX51_PAD_NANDF_RB7__FEC_TX_ER, + MX51_PAD_NANDF_CS3__FEC_MDC, + MX51_PAD_NANDF_CS4__FEC_TDATA1, + MX51_PAD_NANDF_CS5__FEC_TDATA2, + MX51_PAD_NANDF_CS6__FEC_TDATA3, + MX51_PAD_NANDF_CS7__FEC_TX_EN, + MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK, + MX51_PAD_NANDF_D11__FEC_RX_DV, + MX51_PAD_NANDF_RB6__FEC_RDATA0, + MX51_PAD_NANDF_D8__FEC_TDATA0, + MX51_PAD_CSPI1_SS0__CSPI1_SS0, + MX51_PAD_CSPI1_MOSI__CSPI1_MOSI, + MX51_PAD_CSPI1_MISO__CSPI1_MISO, + MX51_PAD_CSPI1_RDY__CSPI1_RDY, + MX51_PAD_CSPI1_SCLK__CSPI1_SCLK, + MX51_PAD_EIM_A20__GPIO2_14, /* LAN8700 reset pin */ + IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, 0x85), /* FIXME: needed? */ +}; + +#ifdef CONFIG_MMU +static void babbage_mmu_init(void) +{ + mmu_init(); + + arm_create_section(0x90000000, 0x90000000, 512, PMD_SECT_DEF_CACHED); + arm_create_section(0xb0000000, 0x90000000, 512, PMD_SECT_DEF_UNCACHED); + + setup_dma_coherent(0x20000000); + +#if TEXT_BASE & (0x100000 - 1) +#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary +#else + arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED); +#endif + + mmu_enable(); +} +#else +static void babbage_mmu_init(void) +{ +} +#endif + +//extern int babbage_power_init(void); + +#define BABBAGE_ECSPI1_CS0 (3 * 32 + 24) +static int spi_0_cs[] = {BABBAGE_ECSPI1_CS0}; + +static struct spi_imx_master spi_0_data = { + .chipselect = spi_0_cs, + .num_chipselect = ARRAY_SIZE(spi_0_cs), +}; + +static struct device_d spi_dev = { + .id = -1, + .name = "imx_spi", + .map_base = MX51_CSPI1_BASE_ADDR, + .platform_data = &spi_0_data, +}; + +static const struct spi_board_info mx51_babbage_spi_board_info[] = { + { + .name = "mc13892-spi", + .max_speed_hz = 300000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +#define MX51_CCM_CACRR 0x10 + +static void babbage_power_init(void) +{ + struct mc13892 *mc13892; + u32 val; + + mc13892 = mc13892_get(); + if (!mc13892) { + printf("could not get mc13892\n"); + return; + } + + /* Write needed to Power Gate 2 register */ + mc13892_reg_read(mc13892, 34, &val); + val &= ~0x10000; + mc13892_reg_write(mc13892, 34, val); + + /* Write needed to update Charger 0 */ + mc13892_reg_write(mc13892, 48, 0x0023807F); + + /* power up the system first */ + mc13892_reg_write(mc13892, 34, 0x00200000); + + if (imx_silicon_revision() < MX51_CHIP_REV_3_0) { + /* Set core voltage to 1.1V */ + mc13892_reg_read(mc13892, 24, &val); + val &= ~0x1f; + val |= 0x14; + mc13892_reg_write(mc13892, 24, val); + + /* Setup VCC (SW2) to 1.25 */ + mc13892_reg_read(mc13892, 25, &val); + val &= ~0x1f; + val |= 0x1a; + mc13892_reg_write(mc13892, 25, val); + + /* Setup 1V2_DIG1 (SW3) to 1.25 */ + mc13892_reg_read(mc13892, 26, &val); + val &= ~0x1f; + val |= 0x1a; + mc13892_reg_write(mc13892, 26, val); + udelay(50); + /* Raise the core frequency to 800MHz */ + writel(0x0, MX51_CCM_BASE_ADDR + MX51_CCM_CACRR); + } else { + /* Setup VCC (SW2) to 1.225 */ + mc13892_reg_read(mc13892, 25, &val); + val &= ~0x1f; + val |= 0x19; + mc13892_reg_write(mc13892, 25, val); + + /* Setup 1V2_DIG1 (SW3) to 1.2 */ + mc13892_reg_read(mc13892, 26, &val); + val &= ~0x1f; + val |= 0x18; + mc13892_reg_write(mc13892, 26, val); + } + + if (mc13892_get_revision(mc13892) < MC13892_REVISION_2_0) { + /* Set switchers in PWM mode for Atlas 2.0 and lower */ + /* Setup the switcher mode for SW1 & SW2*/ + mc13892_reg_read(mc13892, 28, &val); + val &= ~0x3c0f; + val |= 0x1405; + mc13892_reg_write(mc13892, 28, val); + + /* Setup the switcher mode for SW3 & SW4 */ + mc13892_reg_read(mc13892, 29, &val); + val &= ~0xf0f; + val |= 0x505; + mc13892_reg_write(mc13892, 29, val); + } else { + /* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */ + /* Setup the switcher mode for SW1 & SW2*/ + mc13892_reg_read(mc13892, 28, &val); + val &= ~0x3c0f; + val |= 0x2008; + mc13892_reg_write(mc13892, 28, val); + + /* Setup the switcher mode for SW3 & SW4 */ + mc13892_reg_read(mc13892, 29, &val); + val &= ~0xf0f; + val |= 0x808; + mc13892_reg_write(mc13892, 29, val); + } + + /* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */ + mc13892_reg_read(mc13892, 30, &val); + val &= ~0x34030; + val |= 0x10020; + mc13892_reg_write(mc13892, 30, val); + + /* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */ + mc13892_reg_read(mc13892, 31, &val); + val &= ~0x1FC; + val |= 0x1F4; + mc13892_reg_write(mc13892, 31, val); + + /* Configure VGEN3 and VCAM regulators to use external PNP */ + val = 0x208; + mc13892_reg_write(mc13892, 33, val); + udelay(200); +#define GPIO_LAN8700_RESET (1 * 32 + 14) + + /* Reset the ethernet controller over GPIO */ + gpio_direction_output(GPIO_LAN8700_RESET, 0); + + /* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */ + val = 0x49249; + mc13892_reg_write(mc13892, 33, val); + + udelay(500); + + gpio_set_value(GPIO_LAN8700_RESET, 1); +} + +static int f3s_devices_init(void) +{ + babbage_mmu_init(); + + register_device(&sdram_dev); + register_device(&fec_dev); + register_device(&esdhc_dev); + + spi_register_board_info(mx51_babbage_spi_board_info, + ARRAY_SIZE(mx51_babbage_spi_board_info)); + register_device(&spi_dev); + + babbage_power_init(); + + armlinux_add_dram(&sdram_dev); + armlinux_set_bootparams((void *)0x90000100); + armlinux_set_architecture(MACH_TYPE_MX51_BABBAGE); + + return 0; +} + +device_initcall(f3s_devices_init); + +static int f3s_part_init(void) +{ + devfs_add_partition("disk0", 0x00000, 0x40000, PARTITION_FIXED, "self0"); + devfs_add_partition("disk0", 0x40000, 0x20000, PARTITION_FIXED, "env0"); + + return 0; +} +late_initcall(f3s_part_init); + +static struct device_d f3s_serial_device = { + .name = "imx_serial", + .map_base = 0x73fbc000, + .size = 4096, +}; + +static int f3s_console_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(f3s_pads, ARRAY_SIZE(f3s_pads)); + + writel(0, 0x73fa8228); + writel(0, 0x73fa822c); + writel(0, 0x73fa8230); + writel(0, 0x73fa8234); + + register_device(&f3s_serial_device); + return 0; +} + +console_initcall(f3s_console_init); + diff --git a/arch/arm/boards/freescale-mx51-pdk/config.h b/arch/arm/boards/freescale-mx51-pdk/config.h new file mode 100644 index 0000000..b7effe5 --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/config.h @@ -0,0 +1,24 @@ +/** + * @file + * @brief Global defintions for the ARM i.MX51 based babbage board + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/freescale-mx51-pdk/env/config b/arch/arm/boards/freescale-mx51-pdk/env/config new file mode 100644 index 0000000..d9b8407 --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/env/config @@ -0,0 +1,52 @@ +#!/bin/sh + +machine=babbage +eth0.serverip= +user= + +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration +ip=dhcp + +# or set your networking parameters here +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d +#eth0.gateway=a.b.c.d +#eth0.serverip=a.b.c.d + +# can be either 'net', 'nor' or 'nand' +kernel_loc=net +# can be either 'net', 'nor', 'nand' or 'initrd' +rootfs_loc=net + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root-$machine.$rootfs_type + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +kernelimage_type=zimage +kernelimage=zImage-$machine +#kernelimage_type=uimage +#kernelimage=uImage-$machine +#kernelimage_type=raw +#kernelimage=Image-$machine +#kernelimage_type=raw_lzo +#kernelimage=Image-$machine.lzo + +if [ -n $user ]; then + kernelimage="$user"-"$kernelimage" + nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine" + rootfsimage="$user"-"$rootfsimage" +else + nfsroot="$eth0.serverip:/path/to/nfs/root" +fi + +autoboot_timeout=3 + +bootargs="console=ttymxc0,115200" + +disk_parts="256k(barebox)ro,128k(bareboxenv),4M(kernel),-(root)" + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " + diff --git a/arch/arm/boards/freescale-mx51-pdk/flash_header.c b/arch/arm/boards/freescale-mx51-pdk/flash_header.c new file mode 100644 index 0000000..5f94506 --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/flash_header.c @@ -0,0 +1,85 @@ +#include +#include + +extern unsigned long _stext; + +void __naked __flash_header_start go(void) +{ + __asm__ __volatile__("b exception_vectors\n"); +} + +struct imx_dcd_entry __dcd_entry_section dcd_entry[] = { + { .ptr_type = 4, .addr = 0x73fa88a0, .val = 0x00000200, }, + { .ptr_type = 4, .addr = 0x73fa850c, .val = 0x000020c5, }, + { .ptr_type = 4, .addr = 0x73fa8510, .val = 0x000020c5, }, + { .ptr_type = 4, .addr = 0x73fa883c, .val = 0x00000002, }, + { .ptr_type = 4, .addr = 0x73fa8848, .val = 0x00000002, }, + { .ptr_type = 4, .addr = 0x73fa84b8, .val = 0x000000e7, }, + { .ptr_type = 4, .addr = 0x73fa84bc, .val = 0x00000045, }, + { .ptr_type = 4, .addr = 0x73fa84c0, .val = 0x00000045, }, + { .ptr_type = 4, .addr = 0x73fa84c4, .val = 0x00000045, }, + { .ptr_type = 4, .addr = 0x73fa84c8, .val = 0x00000045, }, + { .ptr_type = 4, .addr = 0x73fa8820, .val = 0x00000000, }, + { .ptr_type = 4, .addr = 0x73fa84a4, .val = 0x00000003, }, + { .ptr_type = 4, .addr = 0x73fa84a8, .val = 0x00000003, }, + { .ptr_type = 4, .addr = 0x73fa84ac, .val = 0x000000e3, }, + { .ptr_type = 4, .addr = 0x73fa84b0, .val = 0x000000e3, }, + { .ptr_type = 4, .addr = 0x73fa84b4, .val = 0x000000e3, }, + { .ptr_type = 4, .addr = 0x73fa84cc, .val = 0x000000e3, }, + { .ptr_type = 4, .addr = 0x73fa84d0, .val = 0x000000e2, }, + { .ptr_type = 4, .addr = 0x73fa882c, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0x73fa88a4, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0x73fa88ac, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0x73fa88b8, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0x83fd9000, .val = 0x82a20000, }, + { .ptr_type = 4, .addr = 0x83fd9008, .val = 0x82a20000, }, + { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad0d0, }, + { .ptr_type = 4, .addr = 0x83fd9004, .val = 0x3f3584ab, }, + { .ptr_type = 4, .addr = 0x83fd900c, .val = 0x3f3584ab, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801a, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801b, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00448019, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x07328018, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x06328018, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x03808019, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00408019, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008000, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801e, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801f, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801d, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0732801c, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0632801c, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0380801d, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0040801d, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008004, }, + { .ptr_type = 4, .addr = 0x83fd9000, .val = 0xb2a20000, }, + { .ptr_type = 4, .addr = 0x83fd9008, .val = 0xb2a20000, }, + { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad6d0, }, + { .ptr_type = 4, .addr = 0x83fd9034, .val = 0x90000000, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00000000, }, +}; + +#define APP_DEST 0x90000000 + +struct imx_flash_header __flash_header_section flash_header = { + .app_code_jump_vector = APP_DEST + 0x1000, + .app_code_barker = APP_CODE_BARKER, + .app_code_csf = 0, + .dcd_ptr_ptr = APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd), + .super_root_key = 0, + .dcd = APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd_barker), + .app_dest = APP_DEST, + .dcd_barker = DCD_BARKER, + .dcd_block_len = sizeof (dcd_entry), +}; + +unsigned long __image_len_section barebox_len = 0x40000; + diff --git a/arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S b/arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S new file mode 100644 index 0000000..793104c --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S @@ -0,0 +1,216 @@ +/* + * This code is based on the ecos babbage startup code + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#define ROM_SI_REV_OFFSET 0x48 + +.macro setup_pll pll, freq + ldr r2, =\pll + ldr r1, =0x00001232 + str r1, [r2, #MX51_PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */ + mov r1, #0x2 + str r1, [r2, #MX51_PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ + + str r3, [r2, #MX51_PLL_DP_OP] + str r3, [r2, #MX51_PLL_DP_HFS_OP] + + str r4, [r2, #MX51_PLL_DP_MFD] + str r4, [r2, #MX51_PLL_DP_HFS_MFD] + + str r5, [r2, #MX51_PLL_DP_MFN] + str r5, [r2, #MX51_PLL_DP_HFS_MFN] + + ldr r1, =0x00001232 + str r1, [r2, #MX51_PLL_DP_CTL] +1: ldr r1, [r2, #MX51_PLL_DP_CTL] + ands r1, r1, #0x1 + beq 1b +.endm + +#define writel(val, reg) \ + ldr r0, =reg; \ + ldr r1, =val; \ + str r1, [r0]; + +#define IMX51_TO_2 + +.globl board_init_lowlevel +board_init_lowlevel: + mov r10, lr + + /* explicitly disable L2 cache */ + mrc 15, 0, r0, c1, c0, 1 + bic r0, r0, #0x2 + mcr 15, 0, r0, c1, c0, 1 + + /* reconfigure L2 cache aux control reg */ + mov r0, #0xC0 /* tag RAM */ + add r0, r0, #0x4 /* data RAM */ + orr r0, r0, #(1 << 24) /* disable write allocate delay */ + orr r0, r0, #(1 << 23) /* disable write allocate combine */ + orr r0, r0, #(1 << 22) /* disable write allocate */ + + ldr r1, =MX51_IROM_BASE_ADDR + ldr r3, [r1, #ROM_SI_REV_OFFSET] + cmp r3, #0x10 + orrls r0, r0, #(1 << 25) /* disable write combine for TO 2 and lower revs */ + + mcr 15, 1, r0, c9, c0, 2 + + ldr r0, =MX51_CCM_BASE_ADDR + + /* Gate of clocks to the peripherals first */ + ldr r1, =0x3FFFFFFF + str r1, [r0, #MX51_CCM_CCGR0] + ldr r1, =0x0 + str r1, [r0, #MX51_CCM_CCGR1] + str r1, [r0, #MX51_CCM_CCGR2] + str r1, [r0, #MX51_CCM_CCGR3] + + ldr r1, =0x00030000 + str r1, [r0, #MX51_CCM_CCGR4] + ldr r1, =0x00FFF030 + str r1, [r0, #MX51_CCM_CCGR5] + ldr r1, =0x00000300 + str r1, [r0, #MX51_CCM_CCGR6] + + /* Disable IPU and HSC dividers */ + mov r1, #0x60000 + str r1, [r0, #MX51_CCM_CCDR] + +#ifdef IMX51_TO_2 + /* Make sure to switch the DDR away from PLL 1 */ + ldr r1, =0x19239145 + str r1, [r0, #MX51_CCM_CBCDR] + /* make sure divider effective */ +1: ldr r1, [r0, #MX51_CCM_CDHIPR] + cmp r1, #0x0 + bne 1b +#endif + + /* Switch ARM to step clock */ + mov r1, #0x4 + str r1, [r0, #MX51_CCM_CCSR] + + mov r3, #MX51_PLL_DP_OP_800 + mov r4, #MX51_PLL_DP_MFD_800 + mov r5, #MX51_PLL_DP_MFN_800 + setup_pll MX51_PLL1_BASE_ADDR + + mov r3, #MX51_PLL_DP_OP_665 + mov r4, #MX51_PLL_DP_MFD_665 + mov r5, #MX51_PLL_DP_MFN_665 + setup_pll MX51_PLL3_BASE_ADDR + + /* Switch peripheral to PLL 3 */ + ldr r1, =0x000010C0 + str r1, [r0, #MX51_CCM_CBCMR] + ldr r1, =0x13239145 + str r1, [r0, #MX51_CCM_CBCDR] + + mov r3, #MX51_PLL_DP_OP_665 + mov r4, #MX51_PLL_DP_MFD_665 + mov r5, #MX51_PLL_DP_MFN_665 + setup_pll MX51_PLL2_BASE_ADDR + + /* Switch peripheral to PLL2 */ + ldr r1, =0x19239145 + str r1, [r0, #MX51_CCM_CBCDR] + ldr r1, =0x000020C0 + str r1, [r0, #MX51_CCM_CBCMR] + + mov r3, #MX51_PLL_DP_OP_216 + mov r4, #MX51_PLL_DP_MFD_216 + mov r5, #MX51_PLL_DP_MFN_216 + setup_pll MX51_PLL3_BASE_ADDR + + /* Set the platform clock dividers */ + ldr r2, =MX51_ARM_BASE_ADDR + ldr r1, =0x00000124 + str r1, [r2, #0x14] + + /* Run TO 3.0 at Full speed, for other TO's wait till we increase VDDGP */ + ldr r1, =MX51_IROM_BASE_ADDR + ldr r3, [r1, #ROM_SI_REV_OFFSET] + cmp r3, #0x10 + movls r1, #0x1 + movhi r1, #0 + str r1, [r0, #MX51_CCM_CACRR] + + /* Switch ARM back to PLL 1 */ + mov r1, #0 + str r1, [r0, #MX51_CCM_CCSR] + + /* setup the rest */ + /* Use lp_apm (24MHz) source for perclk */ +#ifdef IMX51_TO_2 + ldr r1, =0x000020C2 + str r1, [r0, #MX51_CCM_CBCMR] + // ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz + ldr r1, =0x59239100 + str r1, [r0, #MX51_CCM_CBCDR] +#else + ldr r1, =0x0000E3C2 + str r1, [r0, #MX51_CCM_CBCMR] + // emi=ahb, all perclk dividers are 1 since using 24MHz + // DDR divider=6 to have 665/6=110MHz + ldr r1, =0x013B9100 + str r1, [r0, #MX51_CCM_CBCDR] +#endif + + /* Restore the default values in the Gate registers */ + ldr r1, =0xFFFFFFFF + str r1, [r0, #MX51_CCM_CCGR0] + str r1, [r0, #MX51_CCM_CCGR1] + str r1, [r0, #MX51_CCM_CCGR2] + str r1, [r0, #MX51_CCM_CCGR3] + str r1, [r0, #MX51_CCM_CCGR4] + str r1, [r0, #MX51_CCM_CCGR5] + str r1, [r0, #MX51_CCM_CCGR6] + + /* Use PLL 2 for UART's, get 66.5MHz from it */ + ldr r1, =0xA5A2A020 + str r1, [r0, #MX51_CCM_CSCMR1] + ldr r1, =0x00C30321 + str r1, [r0, #MX51_CCM_CSCDR1] + + /* make sure divider effective */ + 1: ldr r1, [r0, #MX51_CCM_CDHIPR] + cmp r1, #0x0 + bne 1b + + mov r1, #0x0 + str r1, [r0, #MX51_CCM_CCDR] + + writel(0x1, 0x73fa8074) + ldr r0, =0x73f88000 + ldr r1, [r0] + orr r1, #0x40 + str r1, [r0] + + ldr r0, =0x73f88004 + ldr r1, [r0] + orr r1, #0x40 + str r1, [r0] + + mov pc, r10 + diff --git a/arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox b/arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox new file mode 100644 index 0000000..d9ea823 --- /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 0000000..8eabe81 --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/spi.c @@ -0,0 +1,340 @@ +#include +#include +#include +#include +#include + +#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(" = %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 0000000..3a06cf4 --- /dev/null +++ b/arch/arm/boards/guf-cupid/Makefile @@ -0,0 +1,24 @@ +# +# (C) Copyright 2007 Juergen Beisert +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +obj-y += lowlevel.o +obj-y += board.o diff --git a/arch/arm/boards/guf-cupid/board.c b/arch/arm/boards/guf-cupid/board.c new file mode 100644 index 0000000..6d7a99b --- /dev/null +++ b/arch/arm/boards/guf-cupid/board.c @@ -0,0 +1,426 @@ +/* + * (C) 2007 Pengutronix, Sascha Hauer + * (C) 2009 Pengutronix, Juergen Beisert + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 MHz\n"; + +BAREBOX_CMD_START(cpufreq) + .cmd = do_cpufreq, + .usage = "adjust CPU frequency", + BAREBOX_CMD_HELP(cmd_cpufreq_help) +BAREBOX_CMD_END + diff --git a/arch/arm/boards/guf-cupid/config.h b/arch/arm/boards/guf-cupid/config.h new file mode 100644 index 0000000..0e3b175 --- /dev/null +++ b/arch/arm/boards/guf-cupid/config.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2007 Juergen Beisert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * Definitions related to passing arguments to kernel. + */ + +#define CONFIG_MX35_HCLK_FREQ 24000000 + +#endif + +/* nothing to do here yet */ diff --git a/arch/arm/boards/guf-cupid/cupid.dox b/arch/arm/boards/guf-cupid/cupid.dox new file mode 100644 index 0000000..45f0e0c --- /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 0000000..4db05b6 --- /dev/null +++ b/arch/arm/boards/guf-cupid/env/config @@ -0,0 +1,56 @@ +#!/bin/sh + +machine=cupid +eth0.serverip= +user= + +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration +ip=dhcp + +# or set your networking parameters here +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d +#eth0.gateway=a.b.c.d +#eth0.serverip=a.b.c.d + +# can be either 'net', 'nor' or 'nand' +kernel_loc=net +# can be either 'net', 'nor', 'nand' or 'initrd' +rootfs_loc=net + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root-$machine.$rootfs_type + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +kernelimage_type=zimage +kernelimage=zImage-$machine +#kernelimage_type=uimage +#kernelimage=uImage-$machine +#kernelimage_type=raw +#kernelimage=Image-$machine +#kernelimage_type=raw_lzo +#kernelimage=Image-$machine.lzo + +if [ -n $user ]; then + kernelimage="$user"-"$kernelimage" + nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine" + rootfsimage="$user"-"$rootfsimage" +else + nfsroot="$eth0.serverip:/path/to/nfs/root" +fi + +autoboot_timeout=3 + +bootargs="console=ttymxc0,115200" + +bootargs="$bootargs video=mx3fb:CTP-CLAA070LC0ACW" + +nand_parts="256k(barebox)ro,512k(bareboxenv),2M(kernel),-(root)" +nand_device=mxc_nand +rootfs_mtdblock_nand=3 + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " + diff --git a/arch/arm/boards/guf-cupid/lowlevel.c b/arch/arm/boards/guf-cupid/lowlevel.c new file mode 100644 index 0000000..8d403ee --- /dev/null +++ b/arch/arm/boards/guf-cupid/lowlevel.c @@ -0,0 +1,349 @@ +/* + * + * (c) 2007 Pengutronix, Sascha Hauer + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 fb7cbe8..0000000 --- a/arch/arm/boards/nhk8815/env/bin/_update +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -if [ -z "$part" -o -z "$image" ]; then - echo "define \$part and \$image" - exit 1 -fi - -if [ \! -e "$part" ]; then - echo "Partition $part does not exist" - exit 1 -fi - -if [ $# = 1 ]; then - image=$1 -fi - -if [ x$ip = xdhcp ]; then - dhcp -fi - -ping $eth0.serverip -if [ $? -ne 0 ] ; then - echo "update aborted" - exit 1 -fi - -unprotect $part - -echo -echo "erasing partition $part" -erase $part - -echo -echo "flashing $image to $part" -echo -tftp $image $part diff --git a/arch/arm/boards/nhk8815/env/bin/boot b/arch/arm/boards/nhk8815/env/bin/boot deleted file mode 100644 index fd8d957..0000000 --- a/arch/arm/boards/nhk8815/env/bin/boot +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -. /env/config - -if [ x$1 = xflash ]; then - root=flash - kernel=flash -fi - -if [ x$1 = xnet ]; then - root=net - kernel=net -fi - -if [ x$ip = xdhcp ]; then - bootargs="$bootargs ip=dhcp" -else - bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::" -fi - -if [ x$root = xflash ]; then - bootargs="$bootargs root=$rootpart rootfstype=jffs2" -else - bootargs="$bootargs root=/dev/nfs nfsroot=192.168.23.111:$nfsroot" -fi - -bootargs="$bootargs" - -if [ $kernel = net ]; then - if [ x$ip = xdhcp ]; then - dhcp - fi - tftp $uimage uImage - bootm uImage -else - bootm /dev/nor0.kernel -fi - diff --git a/arch/arm/boards/nhk8815/env/bin/init b/arch/arm/boards/nhk8815/env/bin/init deleted file mode 100644 index 5b45a70..0000000 --- a/arch/arm/boards/nhk8815/env/bin/init +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -PATH=/env/bin -export PATH - -. /env/config - -if [ -e /dev/nand0 ]; then - addpart /dev/nand0 $nand_parts - - # Uh, oh, hush first expands wildcards and then starts executing - # commands. What a bug! - source /env/bin/hush_hack -fi - -echo -echo -n "Hit any key to stop autoboot: " -timeout -a $autoboot_timeout -if [ $? != 0 ]; then - echo - echo "type update_kernel [] to update kernel into flash" - echo "type udate_root [] 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 40f4ad3d..0000000 --- a/arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -. /env/config - -part=/dev/nand0.barebox - -loadb -f barebox.bin -c - -unprotect $part -echo -echo "erasing partition $part" -erase $part - -echo -echo "flashing barebox.bin to $part" -echo -cp barebox.bin $part -crc32 -f barebox.bin -crc32 -f $part diff --git a/arch/arm/boards/nhk8815/env/bin/update_kernel b/arch/arm/boards/nhk8815/env/bin/update_kernel deleted file mode 100644 index db0f4c2..0000000 --- a/arch/arm/boards/nhk8815/env/bin/update_kernel +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -part=/dev/nand0.kernel - -. /env/bin/_update $1 diff --git a/arch/arm/boards/nhk8815/env/bin/update_root b/arch/arm/boards/nhk8815/env/bin/update_root deleted file mode 100644 index 9530e84..0000000 --- a/arch/arm/boards/nhk8815/env/bin/update_root +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$jffs2 -part=/dev/nand0.rootfs - -. /env/bin/_update $1 diff --git a/arch/arm/boards/nhk8815/env/config b/arch/arm/boards/nhk8815/env/config index 7e7fc45..e657a76 100644 --- a/arch/arm/boards/nhk8815/env/config +++ b/arch/arm/boards/nhk8815/env/config @@ -1,16 +1,33 @@ #!/bin/sh -# can be either 'net' or 'flash' -kernel=net -root=net - -# use 'dhcp' todo dhcp in uboot and in kernel +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration ip=dhcp -# -# setup default ethernet address -# -#eth0.serverip=192.168.23.108 +# or set your networking parameters here +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d +#eth0.gateway=a.b.c.d +#eth0.serverip=a.b.c.d + +# can be either 'net' or 'nand' +kernel_loc=net +# can be either 'net', 'nand' or 'initrd' +rootfs_loc=net + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root.$rootfs_type + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +#kernelimage_type=zimage +#kernelimage=zImage +kernelimage_type=uimage +kernelimage=uImage +#kernelimage_type=raw +#kernelimage=Image +#kernelimage_type=raw_lzo +#kernelimage=Image.lzo # Partition Size Start # XloaderTOC + X-Loader 256KB 0x00000000 @@ -22,11 +39,10 @@ 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 a681dda..970804e 100644 --- a/arch/arm/boards/pcm038/Makefile +++ b/arch/arm/boards/pcm038/Makefile @@ -1,3 +1,3 @@ -obj-y += lowlevel.o pll_init.o +obj-y += lowlevel.o obj-y += pcm038.o diff --git a/arch/arm/boards/pcm038/lowlevel.c b/arch/arm/boards/pcm038/lowlevel.c index eb85e8f..b50e1c8 100644 --- a/arch/arm/boards/pcm038/lowlevel.c +++ b/arch/arm/boards/pcm038/lowlevel.c @@ -31,6 +31,8 @@ #include #include +#include "pll.h" + #ifdef CONFIG_NAND_IMX_BOOT static void __bare_init __naked insdram(void) { @@ -68,6 +70,11 @@ if (r > 0xa0000000 && r < 0xb0000000) board_init_lowlevel_return(); + /* re-program the PLL prior(!) starting the SDRAM controller */ + MPCTL0 = MPCTL0_VAL; + SPCTL0 = SPCTL0_VAL; + CSCR = CSCR_VAL | CSCR_UPDATE_DIS | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART; + /* * DDR on CSD0 */ diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c index fda3262..3a9b413 100644 --- a/arch/arm/boards/pcm038/pcm038.c +++ b/arch/arm/boards/pcm038/pcm038.c @@ -44,6 +44,8 @@ #include #include +#include "pll.h" + static struct device_d cfi_dev = { .id = -1, .name = "cfi_flash", @@ -379,11 +381,6 @@ 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 @@ console_initcall(pcm038_console_init); -extern void *pcm038_pll_init, *pcm038_pll_init_end; +/** + * 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) +{ + uint32_t reg; + reg = SPCTL0; + SPCTL0 = reg; + + return reg; +} + +/** + * 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; - void *vram = (void*)0xffff4c00; - void (*pllfunc)(void) = vram; - printf("initialising PLLs: 0x%p 0x%p\n", &pcm038_pll_init); + spctl0 = get_pll_spctl10(); - memcpy(vram, &pcm038_pll_init, 0x100); - - console_flush(); - - ret = pmic_power(); - if (ret) { - printf("Failed to initialize PMIC. Will continue with low CPU speed\n"); - return 0; + /* PLL registers already set to their final values? */ + if (spctl0 == SPCTL0_VAL && MPCTL0 == MPCTL0_VAL) { + console_flush(); + ret = pmic_power(); + if (ret == 0) { + /* wait for required power level to run the CPU at 400 MHz */ + udelay(100000); + CSCR = CSCR_VAL_FINAL; + PCDR0 = 0x130410c3; + PCDR1 = 0x09030911; + /* Clocks have changed. Notify clients */ + clock_notifier_call_chain(); + } else { + printf("Failed to initialize PMIC. Will continue with low CPU speed\n"); + } } - /* wait for good power level */ - udelay(100000); - - pllfunc(); - /* clock gating enable */ GPCR = 0x00050f08; - PCDR0 = 0x130410c3; - PCDR1 = 0x09030911; - - /* Clocks have changed. Notify clients */ - clock_notifier_call_chain(); - return 0; } diff --git a/arch/arm/boards/pcm038/pll.h b/arch/arm/boards/pcm038/pll.h new file mode 100644 index 0000000..13a7989 --- /dev/null +++ b/arch/arm/boards/pcm038/pll.h @@ -0,0 +1,70 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/** + * @file + * @brief phyCORE-i.MX27 specific PLL setup + */ + +#ifndef __PCM038_PLL_H +#define __PCM038_PLL_H + +/* define the PLL setting we want to run the system */ + +/* main clock divider settings immediately after reset (at 1.25 V core supply) */ +#define CSCR_VAL (CSCR_USB_DIV(3) | \ + CSCR_SD_CNT(3) | \ + CSCR_MSHC_SEL | \ + CSCR_H264_SEL | \ + CSCR_SSI1_SEL | \ + CSCR_SSI2_SEL | \ + CSCR_SP_SEL | /* 26 MHz reference */ \ + CSCR_MCU_SEL | /* 26 MHz reference */ \ + CSCR_ARM_DIV(0) | /* CPU runs at MPLL/3 clock */ \ + CSCR_AHB_DIV(1) | /* AHB runs at MPLL/6 clock */ \ + CSCR_SPEN | \ + CSCR_MPEN) + +/* main clock divider settings after core voltage increases to 1.45 V */ +#define CSCR_VAL_FINAL (CSCR_USB_DIV(3) | \ + CSCR_SD_CNT(3) | \ + CSCR_MSHC_SEL | \ + CSCR_H264_SEL | \ + CSCR_SSI1_SEL | \ + CSCR_SSI2_SEL | \ + CSCR_SP_SEL | /* 26 MHz reference */ \ + CSCR_MCU_SEL | /* 26 MHz reference */ \ + CSCR_ARM_SRC_MPLL | /* use main MPLL clock */ \ + CSCR_ARM_DIV(0) | /* CPU run at full MPLL clock */ \ + CSCR_AHB_DIV(1) | /* AHB runs at MPLL/6 clock */ \ + CSCR_SPEN | \ + CSCR_MPEN) + +/* MPLL should provide a 399 MHz clock from the 26 MHz reference */ +#define MPCTL0_VAL (IMX_PLL_PD(0) | \ + IMX_PLL_MFD(51) | \ + IMX_PLL_MFI(7) | \ + IMX_PLL_MFN(35)) + +/* SPLL should provide a 240 MHz clock from the 26 MHz reference */ +#define SPCTL0_VAL (IMX_PLL_PD(1) | \ + IMX_PLL_MFD(12) | \ + IMX_PLL_MFI(9) | \ + IMX_PLL_MFN(3)) + + +#endif /* __PCM038_PLL_H */ diff --git a/arch/arm/boards/pcm038/pll_init.S b/arch/arm/boards/pcm038/pll_init.S deleted file mode 100644 index 0c1ff13..0000000 --- a/arch/arm/boards/pcm038/pll_init.S +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include - -#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 9f98795..5932f95 100644 --- a/arch/arm/boards/pcm043/pcm043.c +++ b/arch/arm/boards/pcm043/pcm043.c @@ -93,7 +93,7 @@ }; #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 @@ .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 7328a6c..3a96180 100644 --- a/arch/arm/boards/phycard-i.MX27/pca100.c +++ b/arch/arm/boards/phycard-i.MX27/pca100.c @@ -68,6 +68,7 @@ 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 @@ } #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 @@ 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 @@ 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 0000000..595b6a9 --- /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 0000000..e24afe1 --- /dev/null +++ b/arch/arm/configs/cupid_defconfig @@ -0,0 +1,56 @@ +CONFIG_ARCH_IMX=y +CONFIG_CACHE_L2X0=y +CONFIG_ARCH_IMX35=y +CONFIG_MACH_GUF_CUPID=y +CONFIG_IMX_CLKO=y +CONFIG_AEABI=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_MMU=y +CONFIG_TEXT_BASE=0x87F00000 +CONFIG_MALLOC_SIZE=0x1000000 +CONFIG_LONGHELP=y +CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/guf-cupid/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_BMP=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_UNLZO=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y +CONFIG_NET_PING=y +CONFIG_NET_TFTP=y +CONFIG_NET_TFTP_PUSH=y +CONFIG_NET_NETCONSOLE=y +CONFIG_NET_RESOLV=y +CONFIG_DRIVER_NET_FEC_IMX=y +# CONFIG_SPI is not set +CONFIG_MTD=y +CONFIG_NAND=y +CONFIG_NAND_IMX=y +CONFIG_NAND_IMX_BOOT=y +CONFIG_NAND_IMX_BOOT_2K=y +CONFIG_UBI=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_IMX_IPU=y +CONFIG_MCI=y +CONFIG_MCI_IMX_ESDHC=y diff --git a/arch/arm/configs/eukrea_cpuimx25_defconfig b/arch/arm/configs/eukrea_cpuimx25_defconfig index feb758e..bc68804 100644 --- a/arch/arm/configs/eukrea_cpuimx25_defconfig +++ b/arch/arm/configs/eukrea_cpuimx25_defconfig @@ -9,6 +9,7 @@ CONFIG_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_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_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 975d095..af82827 100644 --- a/arch/arm/configs/eukrea_cpuimx35_defconfig +++ b/arch/arm/configs/eukrea_cpuimx35_defconfig @@ -8,8 +8,11 @@ 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_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_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 0000000..d99d91a --- /dev/null +++ b/arch/arm/configs/freescale_mx51_babbage_defconfig @@ -0,0 +1,43 @@ +CONFIG_ARCH_IMX=y +CONFIG_ARCH_IMX_INTERNAL_BOOT=y +CONFIG_ARCH_IMX51=y +CONFIG_AEABI=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_MMU=y +CONFIG_TEXT_BASE=0x97f00000 +CONFIG_MALLOC_SIZE=0x2000000 +CONFIG_LONGHELP=y +CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/freescale-mx51-pdk/env/" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_CRC=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_GPIO=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_PING=y +CONFIG_NET_TFTP=y +CONFIG_DRIVER_NET_FEC_IMX=y +CONFIG_DRIVER_SPI_IMX=y +CONFIG_DRIVER_CFI=y +CONFIG_CFI_BUFFER_WRITE=y +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +CONFIG_MCI_IMX_ESDHC=y +CONFIG_I2C_MC13892=y diff --git a/arch/arm/configs/imx23evk_defconfig b/arch/arm/configs/imx23evk_defconfig new file mode 100644 index 0000000..047a7e1 --- /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 9f6e3f4..24125f9 100644 --- a/arch/arm/configs/neso_defconfig +++ b/arch/arm/configs/neso_defconfig @@ -12,7 +12,8 @@ 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 e3f4102..b81afe2 100644 --- a/arch/arm/configs/nhk8815_defconfig +++ b/arch/arm/configs/nhk8815_defconfig @@ -10,7 +10,8 @@ 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_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 d1708a6..8c72bdf 100644 --- a/arch/arm/configs/pca100_defconfig +++ b/arch/arm/configs/pca100_defconfig @@ -12,7 +12,8 @@ CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_PARTITION=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/phycard-i.MX27/env" +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/phycard-i.MX27/env" CONFIG_CMD_EDIT=y CONFIG_CMD_SLEEP=y CONFIG_CMD_SAVEENV=y diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig index 8e60b0a..e12f690 100644 --- a/arch/arm/configs/pcm037_defconfig +++ b/arch/arm/configs/pcm037_defconfig @@ -10,7 +10,8 @@ CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_PARTITION=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/pcm037/env" +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm037/env" CONFIG_CMD_EDIT=y CONFIG_CMD_SLEEP=y CONFIG_CMD_SAVEENV=y diff --git a/arch/arm/configs/pcm038_defconfig b/arch/arm/configs/pcm038_defconfig index eacbbc6..2038f14 100644 --- a/arch/arm/configs/pcm038_defconfig +++ b/arch/arm/configs/pcm038_defconfig @@ -13,7 +13,8 @@ CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_PARTITION=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/pcm038/env" +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm038/env" CONFIG_CMD_EDIT=y CONFIG_CMD_SLEEP=y CONFIG_CMD_SAVEENV=y diff --git a/arch/arm/configs/pcm043_defconfig b/arch/arm/configs/pcm043_defconfig index 51ca833..2dd711b 100644 --- a/arch/arm/configs/pcm043_defconfig +++ b/arch/arm/configs/pcm043_defconfig @@ -13,7 +13,8 @@ CONFIG_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 61569d2..1ea7bab 100644 --- a/arch/arm/cpu/cache-l2x0.c +++ b/arch/arm/cpu/cache-l2x0.c @@ -127,7 +127,7 @@ 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 133d144..346f8dc 100644 --- a/arch/arm/cpu/cpu.c +++ b/arch/arm/cpu/cpu.c @@ -27,6 +27,7 @@ #include #include +#include #include #include diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c index 0557172..4a0b3f8 100644 --- a/arch/arm/cpu/interrupts.c +++ b/arch/arm/cpu/interrupts.c @@ -28,6 +28,14 @@ #include #include +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 @@ /** * 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 5bf31c0..08a57ce 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -16,12 +16,10 @@ 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 c1ac1aa..1d7f15a 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -1,7 +1,6 @@ obj-y += armlinux.o obj-y += _ashldi3.o obj-y += _ashrdi3.o -obj-y += cache.o obj-y += div0.o obj-y += _divsi3.o obj-y += _modsi3.o diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c index 7c2cbf9..f826da6 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -40,6 +40,7 @@ #include #include #include +#include static struct tag *params; static int armlinux_architecture = 0; @@ -135,8 +136,7 @@ } } -#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 @@ 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 @@ 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 @@ } #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 @@ 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 @@ 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 @@ 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/cache.c b/arch/arm/lib/cache.c deleted file mode 100644 index 61ee9d3..0000000 --- a/arch/arm/lib/cache.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * (C) Copyright 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* for now: just dummy functions to satisfy the linker */ - -#include - -void flush_cache (unsigned long dummy1, unsigned long dummy2) -{ -#ifdef CONFIG_OMAP2420 - void arm1136_cache_flush(void); - - arm1136_cache_flush(); -#endif - return; -} diff --git a/arch/arm/lib/div0.c b/arch/arm/lib/div0.c index 6267bf1..99d6b85 100644 --- a/arch/arm/lib/div0.c +++ b/arch/arm/lib/div0.c @@ -20,11 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ +#include + +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 84df1a1..c1b42f9 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c @@ -73,7 +73,7 @@ /* * Reset the cpu through the reset controller */ -void __noreturn reset_cpu (unsigned long ignored) +void __noreturn reset_cpu (unsigned long addr) { at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | diff --git a/arch/arm/mach-ep93xx/clocksource.c b/arch/arm/mach-ep93xx/clocksource.c index 3aa8e14..a1e315d 100644 --- a/arch/arm/mach-ep93xx/clocksource.c +++ b/arch/arm/mach-ep93xx/clocksource.c @@ -72,7 +72,7 @@ /* * 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 4f95393..f3506af 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -17,6 +17,8 @@ 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 @@ 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 @@ 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 @@ 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 de62f7e..ce38566 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -5,6 +5,7 @@ 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 a166038..5b1bad5 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 @@ 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 @@ 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 c6a59a6..0a3e046 100644 --- a/arch/arm/mach-imx/gpio.c +++ b/arch/arm/mach-imx/gpio.c @@ -27,6 +27,7 @@ #include #include #include +#include #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 @@ 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_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_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 8c4fc11..075ed22 100644 --- a/arch/arm/mach-imx/imx51.c +++ b/arch/arm/mach-imx/imx51.c @@ -15,7 +15,10 @@ * MA 02111-1307 USA */ +#include #include +#include +#include #include "gpio.h" @@ -28,3 +31,51 @@ int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; +#define SI_REV 0x48 + +static u32 mx51_silicon_revision; +static char *mx51_rev_string = "unknown"; + +int imx_silicon_revision(void) +{ + return mx51_silicon_revision; +} + +static int query_silicon_revision(void) +{ + void __iomem *rom = MX51_IROM_BASE_ADDR; + u32 rev; + + rev = readl(rom + SI_REV); + switch (rev) { + case 0x1: + mx51_silicon_revision = MX51_CHIP_REV_1_0; + mx51_rev_string = "1.0"; + break; + case 0x2: + mx51_silicon_revision = MX51_CHIP_REV_1_1; + mx51_rev_string = "1.1"; + break; + case 0x10: + mx51_silicon_revision = MX51_CHIP_REV_2_0; + mx51_rev_string = "2.0"; + break; + case 0x20: + mx51_silicon_revision = MX51_CHIP_REV_3_0; + mx51_rev_string = "3.0"; + break; + default: + mx51_silicon_revision = 0; + } + + return 0; +} +core_initcall(query_silicon_revision); + +static int imx51_print_silicon_rev(void) +{ + printf("detected i.MX51 rev %s\n", mx51_rev_string); + + return 0; +} +device_initcall(imx51_print_silicon_rev); diff --git a/arch/arm/mach-imx/include/mach/clock-imx51.h b/arch/arm/mach-imx/include/mach/clock-imx51.h new file mode 100644 index 0000000..0dee7c3 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/clock-imx51.h @@ -0,0 +1,696 @@ +/* + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__ + +/* PLL Register Offsets */ +#define MX51_PLL_DP_CTL 0x00 +#define MX51_PLL_DP_CONFIG 0x04 +#define MX51_PLL_DP_OP 0x08 +#define MX51_PLL_DP_MFD 0x0C +#define MX51_PLL_DP_MFN 0x10 +#define MX51_PLL_DP_MFNMINUS 0x14 +#define MX51_PLL_DP_MFNPLUS 0x18 +#define MX51_PLL_DP_HFS_OP 0x1C +#define MX51_PLL_DP_HFS_MFD 0x20 +#define MX51_PLL_DP_HFS_MFN 0x24 +#define MX51_PLL_DP_MFN_TOGC 0x28 +#define MX51_PLL_DP_DESTAT 0x2c + +/* PLL Register Bit definitions */ +#define MX51_PLL_DP_CTL_MUL_CTRL 0x2000 +#define MX51_PLL_DP_CTL_DPDCK0_2_EN 0x1000 +#define MX51_PLL_DP_CTL_DPDCK0_2_OFFSET 12 +#define MX51_PLL_DP_CTL_ADE 0x800 +#define MX51_PLL_DP_CTL_REF_CLK_DIV 0x400 +#define MX51_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8) +#define MX51_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8 +#define MX51_PLL_DP_CTL_HFSM 0x80 +#define MX51_PLL_DP_CTL_PRE 0x40 +#define MX51_PLL_DP_CTL_UPEN 0x20 +#define MX51_PLL_DP_CTL_RST 0x10 +#define MX51_PLL_DP_CTL_RCP 0x8 +#define MX51_PLL_DP_CTL_PLM 0x4 +#define MX51_PLL_DP_CTL_BRM0 0x2 +#define MX51_PLL_DP_CTL_LRF 0x1 + +#define MX51_PLL_DP_CONFIG_BIST 0x8 +#define MX51_PLL_DP_CONFIG_SJC_CE 0x4 +#define MX51_PLL_DP_CONFIG_AREN 0x2 +#define MX51_PLL_DP_CONFIG_LDREQ 0x1 + +#define MX51_PLL_DP_OP_MFI_OFFSET 4 +#define MX51_PLL_DP_OP_MFI_MASK (0xF << 4) +#define MX51_PLL_DP_OP_PDF_OFFSET 0 +#define MX51_PLL_DP_OP_PDF_MASK 0xF + +#define MX51_PLL_DP_MFD_OFFSET 0 +#define MX51_PLL_DP_MFD_MASK 0x07FFFFFF + +#define MX51_PLL_DP_MFN_OFFSET 0x0 +#define MX51_PLL_DP_MFN_MASK 0x07FFFFFF + +#define MX51_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17) +#define MX51_PLL_DP_MFN_TOGC_TOG_EN (1 << 16) +#define MX51_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0 +#define MX51_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF + +#define MX51_PLL_DP_DESTAT_TOG_SEL (1 << 31) +#define MX51_PLL_DP_DESTAT_MFN 0x07FFFFFF + +/* Assuming 24MHz input clock with doubler ON */ +/* MFI PDF */ +#define MX51_PLL_DP_OP_850 ((8 << 4) + ((1 - 1) << 0)) +#define MX51_PLL_DP_MFD_850 (48 - 1) +#define MX51_PLL_DP_MFN_850 41 + +#define MX51_PLL_DP_OP_800 ((8 << 4) + ((1 - 1) << 0)) +#define MX51_PLL_DP_MFD_800 (3 - 1) +#define MX51_PLL_DP_MFN_800 1 + +#define MX51_PLL_DP_OP_700 ((7 << 4) + ((1 - 1) << 0)) +#define MX51_PLL_DP_MFD_700 (24 - 1) +#define MX51_PLL_DP_MFN_700 7 + +#define MX51_PLL_DP_OP_665 ((6 << 4) + ((1 - 1) << 0)) +#define MX51_PLL_DP_MFD_665 (96 - 1) +#define MX51_PLL_DP_MFN_665 89 + +#define MX51_PLL_DP_OP_532 ((5 << 4) + ((1 - 1) << 0)) +#define MX51_PLL_DP_MFD_532 (24 - 1) +#define MX51_PLL_DP_MFN_532 13 + +#define MX51_PLL_DP_OP_400 ((8 << 4) + ((2 - 1) << 0)) +#define MX51_PLL_DP_MFD_400 (3 - 1) +#define MX51_PLL_DP_MFN_400 1 + +#define MX51_PLL_DP_OP_216 ((6 << 4) + ((3 - 1) << 0)) +#define MX51_PLL_DP_MFD_216 (4 - 1) +#define MX51_PLL_DP_MFN_216 3 + +/* Register addresses of CCM*/ +#define MX51_CCM_CCR 0x00 +#define MX51_CCM_CCDR 0x04 +#define MX51_CCM_CSR 0x08 +#define MX51_CCM_CCSR 0x0C +#define MX51_CCM_CACRR 0x10 +#define MX51_CCM_CBCDR 0x14 +#define MX51_CCM_CBCMR 0x18 +#define MX51_CCM_CSCMR1 0x1C +#define MX51_CCM_CSCMR2 0x20 +#define MX51_CCM_CSCDR1 0x24 +#define MX51_CCM_CS1CDR 0x28 +#define MX51_CCM_CS2CDR 0x2C +#define MX51_CCM_CDCDR 0x30 +#define MX51_CCM_CHSCDR 0x34 +#define MX51_CCM_CSCDR2 0x38 +#define MX51_CCM_CSCDR3 0x3C +#define MX51_CCM_CSCDR4 0x40 +#define MX51_CCM_CWDR 0x44 +#define MX51_CCM_CDHIPR 0x48 +#define MX51_CCM_CDCR 0x4C +#define MX51_CCM_CTOR 0x50 +#define MX51_CCM_CLPCR 0x54 +#define MX51_CCM_CISR 0x58 +#define MX51_CCM_CIMR 0x5C +#define MX51_CCM_CCOSR 0x60 +#define MX51_CCM_CGPR 0x64 +#define MX51_CCM_CCGR0 0x68 +#define MX51_CCM_CCGR1 0x6C +#define MX51_CCM_CCGR2 0x70 +#define MX51_CCM_CCGR3 0x74 +#define MX51_CCM_CCGR4 0x78 +#define MX51_CCM_CCGR5 0x7C +#define MX51_CCM_CCGR6 0x80 +#define MX51_CCM_CMEOR 0x84 + +/* Define the bits in register CCR */ +#define MX51_CCM_CCR_COSC_EN (1 << 12) +#define MX51_CCM_CCR_FPM_MULT_MASK (1 << 11) +#define MX51_CCM_CCR_CAMP2_EN (1 << 10) +#define MX51_CCM_CCR_CAMP1_EN (1 << 9) +#define MX51_CCM_CCR_FPM_EN (1 << 8) +#define MX51_CCM_CCR_OSCNT_OFFSET (0) +#define MX51_CCM_CCR_OSCNT_MASK (0xFF) + +/* Define the bits in register CCDR */ +#define MX51_CCM_CCDR_HSC_HS_MASK (0x1 << 18) +#define MX51_CCM_CCDR_IPU_HS_MASK (0x1 << 17) +#define MX51_CCM_CCDR_EMI_HS_MASK (0x1 << 16) + +/* Define the bits in register CSR */ +#define MX51_CCM_CSR_COSR_READY (1 << 5) +#define MX51_CCM_CSR_LVS_VALUE (1 << 4) +#define MX51_CCM_CSR_CAMP2_READY (1 << 3) +#define MX51_CCM_CSR_CAMP1_READY (1 << 2) +#define MX51_CCM_CSR_FPM_READY (1 << 1) +#define MX51_CCM_CSR_REF_EN_B (1 << 0) + +/* Define the bits in register CCSR */ +#define MX51_CCM_CCSR_LP_APM_SEL (0x1 << 9) +#define MX51_CCM_CCSR_STEP_SEL_OFFSET (7) +#define MX51_CCM_CCSR_STEP_SEL_MASK (0x3 << 7) +#define MX51_CCM_CCSR_PLL2_PODF_OFFSET (5) +#define MX51_CCM_CCSR_PLL2_PODF_MASK (0x3 << 5) +#define MX51_CCM_CCSR_PLL3_PODF_OFFSET (3) +#define MX51_CCM_CCSR_PLL3_PODF_MASK (0x3 << 3) +#define MX51_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2) +#define MX51_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1) +#define MX51_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0) + +/* Define the bits in register CACRR */ +#define MX51_CCM_CACRR_ARM_PODF_OFFSET (0) +#define MX51_CCM_CACRR_ARM_PODF_MASK (0x7) + +/* Define the bits in register CBCDR */ +#define MX51_CCM_CBCDR_EMI_CLK_SEL (0x1 << 26) +#define MX51_CCM_CBCDR_PERIPH_CLK_SEL (0x1 << 25) +#define MX51_CCM_CBCDR_DDR_HF_SEL_OFFSET (30) +#define MX51_CCM_CBCDR_DDR_HF_SEL (0x1 << 30) +#define MX51_CCM_CBCDR_DDR_PODF_OFFSET (27) +#define MX51_CCM_CBCDR_DDR_PODF_MASK (0x7 << 27) +#define MX51_CCM_CBCDR_EMI_PODF_OFFSET (22) +#define MX51_CCM_CBCDR_EMI_PODF_MASK (0x7 << 22) +#define MX51_CCM_CBCDR_AXI_B_PODF_OFFSET (19) +#define MX51_CCM_CBCDR_AXI_B_PODF_MASK (0x7 << 19) +#define MX51_CCM_CBCDR_AXI_A_PODF_OFFSET (16) +#define MX51_CCM_CBCDR_AXI_A_PODF_MASK (0x7 << 16) +#define MX51_CCM_CBCDR_NFC_PODF_OFFSET (13) +#define MX51_CCM_CBCDR_NFC_PODF_MASK (0x7 << 13) +#define MX51_CCM_CBCDR_AHB_PODF_OFFSET (10) +#define MX51_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10) +#define MX51_CCM_CBCDR_IPG_PODF_OFFSET (8) +#define MX51_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8) +#define MX51_CCM_CBCDR_PERCLK_PRED1_OFFSET (6) +#define MX51_CCM_CBCDR_PERCLK_PRED1_MASK (0x3 << 6) +#define MX51_CCM_CBCDR_PERCLK_PRED2_OFFSET (3) +#define MX51_CCM_CBCDR_PERCLK_PRED2_MASK (0x7 << 3) +#define MX51_CCM_CBCDR_PERCLK_PODF_OFFSET (0) +#define MX51_CCM_CBCDR_PERCLK_PODF_MASK (0x7) + +/* Define the bits in register CBCMR */ +#define MX51_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET (14) +#define MX51_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (0x3 << 14) +#define MX51_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET (12) +#define MX51_CCM_CBCMR_PERIPH_CLK_SEL_MASK (0x3 << 12) +#define MX51_CCM_CBCMR_DDR_CLK_SEL_OFFSET (10) +#define MX51_CCM_CBCMR_DDR_CLK_SEL_MASK (0x3 << 10) +#define MX51_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET (8) +#define MX51_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK (0x3 << 8) +#define MX51_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET (6) +#define MX51_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK (0x3 << 6) +#define MX51_CCM_CBCMR_GPU_CLK_SEL_OFFSET (4) +#define MX51_CCM_CBCMR_GPU_CLK_SEL_MASK (0x3 << 4) +#define MX51_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET (14) +#define MX51_CCM_CBCMR_GPU2D_CLK_SEL_MASK (0x3 << 14) +#define MX51_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL (0x1 << 1) +#define MX51_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0) + +/* Define the bits in register CSCMR1 */ +#define MX51_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30) +#define MX51_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30) +#define MX51_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28) +#define MX51_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK (0x3 << 28) +#define MX51_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET (26) +#define MX51_CCM_CSCMR1_USB_PHY_CLK_SEL (0x1 << 26) +#define MX51_CCM_CSCMR1_UART_CLK_SEL_OFFSET (24) +#define MX51_CCM_CSCMR1_UART_CLK_SEL_MASK (0x3 << 24) +#define MX51_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET (22) +#define MX51_CCM_CSCMR1_USBOH3_CLK_SEL_MASK (0x3 << 22) +#define MX51_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET (20) +#define MX51_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK (0x3 << 20) +#define MX51_CCM_CSCMR1_ESDHC3_CLK_SEL (0x1 << 19) +#define MX51_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 18) +#define MX51_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET (16) +#define MX51_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK (0x3 << 16) +#define MX51_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14) +#define MX51_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14) +#define MX51_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12) +#define MX51_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12) +#define MX51_CCM_CSCMR1_SSI3_CLK_SEL (0x1 << 11) +#define MX51_CCM_CSCMR1_VPU_RCLK_SEL (0x1 << 10) +#define MX51_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET (8) +#define MX51_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK (0x3 << 8) +#define MX51_CCM_CSCMR1_TVE_CLK_SEL (0x1 << 7) +#define MX51_CCM_CSCMR1_TVE_EXT_CLK_SEL (0x1 << 6) +#define MX51_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET (4) +#define MX51_CCM_CSCMR1_CSPI_CLK_SEL_MASK (0x3 << 4) +#define MX51_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET (2) +#define MX51_CCM_CSCMR1_SPDIF_CLK_SEL_MASK (0x3 << 2) +#define MX51_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL (0x1 << 1) +#define MX51_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL (0x1) + +/* Define the bits in register CSCMR2 */ +#define MX51_CCM_CSCMR2_DI_CLK_SEL_OFFSET(n) (26+n*3) +#define MX51_CCM_CSCMR2_DI_CLK_SEL_MASK(n) (0x7 << (26+n*3)) +#define MX51_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET (24) +#define MX51_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK (0x3 << 24) +#define MX51_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET (22) +#define MX51_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK (0x3 << 22) +#define MX51_CCM_CSCMR2_ESC_CLK_SEL_OFFSET (20) +#define MX51_CCM_CSCMR2_ESC_CLK_SEL_MASK (0x3 << 20) +#define MX51_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET (18) +#define MX51_CCM_CSCMR2_HSC2_CLK_SEL_MASK (0x3 << 18) +#define MX51_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET (16) +#define MX51_CCM_CSCMR2_HSC1_CLK_SEL_MASK (0x3 << 16) +#define MX51_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET (14) +#define MX51_CCM_CSCMR2_HSI2C_CLK_SEL_MASK (0x3 << 14) +#define MX51_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET (12) +#define MX51_CCM_CSCMR2_FIRI_CLK_SEL_MASK (0x3 << 12) +#define MX51_CCM_CSCMR2_SIM_CLK_SEL_OFFSET (10) +#define MX51_CCM_CSCMR2_SIM_CLK_SEL_MASK (0x3 << 10) +#define MX51_CCM_CSCMR2_SLIMBUS_COM (0x1 << 9) +#define MX51_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET (6) +#define MX51_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK (0x7 << 6) +#define MX51_CCM_CSCMR2_SPDIF1_COM (1 << 5) +#define MX51_CCM_CSCMR2_SPDIF0_COM (1 << 4) +#define MX51_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET (2) +#define MX51_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK (0x3 << 2) +#define MX51_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET (0) +#define MX51_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK (0x3) + +/* Define the bits in register CSCDR1 */ +#define MX51_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET (22) +#define MX51_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22) +#define MX51_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19) +#define MX51_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK (0x7 << 19) +#define MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET (16) +#define MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK (0x7 << 16) +#define MX51_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14) +#define MX51_CCM_CSCDR1_PGC_CLK_PODF_MASK (0x3 << 14) +#define MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET (11) +#define MX51_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK (0x7 << 11) +#define MX51_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET (8) +#define MX51_CCM_CSCDR1_USBOH3_CLK_PRED_MASK (0x7 << 8) +#define MX51_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET (6) +#define MX51_CCM_CSCDR1_USBOH3_CLK_PODF_MASK (0x3 << 6) +#define MX51_CCM_CSCDR1_UART_CLK_PRED_OFFSET (3) +#define MX51_CCM_CSCDR1_UART_CLK_PRED_MASK (0x7 << 3) +#define MX51_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0) +#define MX51_CCM_CSCDR1_UART_CLK_PODF_MASK (0x7) + +/* Define the bits in register CS1CDR and CS2CDR */ +#define MX51_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET (22) +#define MX51_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK (0x7 << 22) +#define MX51_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET (16) +#define MX51_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK (0x3F << 16) +#define MX51_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6) +#define MX51_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6) +#define MX51_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0) +#define MX51_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F) + +#define MX51_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET (22) +#define MX51_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK (0x7 << 22) +#define MX51_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET (16) +#define MX51_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK (0x3F << 16) +#define MX51_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6) +#define MX51_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6) +#define MX51_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0) +#define MX51_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F) + +/* Define the bits in register CDCDR */ +#define MX51_CCM_CDCDR_TVE_CLK_PRED_OFFSET (28) +#define MX51_CCM_CDCDR_TVE_CLK_PRED_MASK (0x7 << 28) +#define MX51_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25) +#define MX51_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25) +#define MX51_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (19) +#define MX51_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x3F << 19) +#define MX51_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (16) +#define MX51_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 16) +#define MX51_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9) +#define MX51_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x3F << 9) +#define MX51_CCM_CDCDR_DI_CLK_PRED_OFFSET (6) +#define MX51_CCM_CDCDR_DI_CLK_PRED_MASK (0x7 << 6) +#define MX51_CCM_CDCDR_USB_PHY_PRED_OFFSET (3) +#define MX51_CCM_CDCDR_USB_PHY_PRED_MASK (0x7 << 3) +#define MX51_CCM_CDCDR_USB_PHY_PODF_OFFSET (0) +#define MX51_CCM_CDCDR_USB_PHY_PODF_MASK (0x7) + +/* Define the bits in register CHSCCDR */ +#define MX51_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET (12) +#define MX51_CCM_CHSCCDR_ESC_CLK_PRED_MASK (0x7 << 12) +#define MX51_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET (6) +#define MX51_CCM_CHSCCDR_ESC_CLK_PODF_MASK (0x3F << 6) +#define MX51_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET (3) +#define MX51_CCM_CHSCCDR_HSC2_CLK_PODF_MASK (0x7 << 3) +#define MX51_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET (0) +#define MX51_CCM_CHSCCDR_HSC1_CLK_PODF_MASK (0x7) + +/* Define the bits in register CSCDR2 */ +#define MX51_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET (25) +#define MX51_CCM_CSCDR2_CSPI_CLK_PRED_MASK (0x7 << 25) +#define MX51_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET (19) +#define MX51_CCM_CSCDR2_CSPI_CLK_PODF_MASK (0x3F << 19) +#define MX51_CCM_CSCDR2_SIM_CLK_PRED_OFFSET (16) +#define MX51_CCM_CSCDR2_SIM_CLK_PRED_MASK (0x7 << 16) +#define MX51_CCM_CSCDR2_SIM_CLK_PODF_OFFSET (9) +#define MX51_CCM_CSCDR2_SIM_CLK_PODF_MASK (0x3F << 9) +#define MX51_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET (6) +#define MX51_CCM_CSCDR2_SLIMBUS_PRED_MASK (0x7 << 6) +#define MX51_CCM_CSCDR2_SLIMBUS_PODF_OFFSET (0) +#define MX51_CCM_CSCDR2_SLIMBUS_PODF_MASK (0x3F) + +/* Define the bits in register CSCDR3 */ +#define MX51_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET (16) +#define MX51_CCM_CSCDR3_HSI2C_CLK_PRED_MASK (0x7 << 16) +#define MX51_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET (9) +#define MX51_CCM_CSCDR3_HSI2C_CLK_PODF_MASK (0x3F << 9) +#define MX51_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET (6) +#define MX51_CCM_CSCDR3_FIRI_CLK_PRED_MASK (0x7 << 6) +#define MX51_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET (0) +#define MX51_CCM_CSCDR3_FIRI_CLK_PODF_MASK (0x3F) + +/* Define the bits in register CSCDR4 */ +#define MX51_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET (16) +#define MX51_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK (0x7 << 16) +#define MX51_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET (9) +#define MX51_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK (0x3F << 9) +#define MX51_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET (6) +#define MX51_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK (0x7 << 6) +#define MX51_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET (0) +#define MX51_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK (0x3F) + +/* Define the bits in register CDHIPR */ +#define MX51_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16) +#define MX51_CCM_CDHIPR_DDR_HF_CLK_SEL_BUSY (1 << 8) +#define MX51_CCM_CDHIPR_DDR_PODF_BUSY (1 << 7) +#define MX51_CCM_CDHIPR_EMI_CLK_SEL_BUSY (1 << 6) +#define MX51_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5) +#define MX51_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY (1 << 4) +#define MX51_CCM_CDHIPR_AHB_PODF_BUSY (1 << 3) +#define MX51_CCM_CDHIPR_EMI_PODF_BUSY (1 << 2) +#define MX51_CCM_CDHIPR_AXI_B_PODF_BUSY (1 << 1) +#define MX51_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0) + +/* Define the bits in register CDCR */ +#define MX51_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2) +#define MX51_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0) +#define MX51_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3) + +/* Define the bits in register CLPCR */ +#define MX51_CCM_CLPCR_BYPASS_HSC_LPM_HS (0x1 << 23) +#define MX51_CCM_CLPCR_BYPASS_SCC_LPM_HS (0x1 << 22) +#define MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21) +#define MX51_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 20) +#define MX51_CCM_CLPCR_BYPASS_EMI_LPM_HS (0x1 << 19) +#define MX51_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18) +#define MX51_CCM_CLPCR_BYPASS_RTIC_LPM_HS (0x1 << 17) +#define MX51_CCM_CLPCR_BYPASS_RNGC_LPM_HS (0x1 << 16) +#define MX51_CCM_CLPCR_COSC_PWRDOWN (0x1 << 11) +#define MX51_CCM_CLPCR_STBY_COUNT_OFFSET (9) +#define MX51_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9) +#define MX51_CCM_CLPCR_VSTBY (0x1 << 8) +#define MX51_CCM_CLPCR_DIS_REF_OSC (0x1 << 7) +#define MX51_CCM_CLPCR_SBYOS (0x1 << 6) +#define MX51_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) +#define MX51_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3) +#define MX51_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3) +#define MX51_CCM_CLPCR_LPM_OFFSET (0) +#define MX51_CCM_CLPCR_LPM_MASK (0x3) + +/* Define the bits in register CISR */ +#define MX51_CCM_CISR_ARM_PODF_LOADED (0x1 << 25) +#define MX51_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21) +#define MX51_CCM_CISR_AHB_PODF_LOADED (0x1 << 20) +#define MX51_CCM_CISR_EMI_PODF_LOADED (0x1 << 19) +#define MX51_CCM_CISR_AXI_B_PODF_LOADED (0x1 << 18) +#define MX51_CCM_CISR_AXI_A_PODF_LOADED (0x1 << 17) +#define MX51_CCM_CISR_DIVIDER_LOADED (0x1 << 16) +#define MX51_CCM_CISR_COSC_READY (0x1 << 6) +#define MX51_CCM_CISR_CKIH2_READY (0x1 << 5) +#define MX51_CCM_CISR_CKIH_READY (0x1 << 4) +#define MX51_CCM_CISR_FPM_READY (0x1 << 3) +#define MX51_CCM_CISR_LRF_PLL3 (0x1 << 2) +#define MX51_CCM_CISR_LRF_PLL2 (0x1 << 1) +#define MX51_CCM_CISR_LRF_PLL1 (0x1) + +/* Define the bits in register CIMR */ +#define MX51_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 25) +#define MX51_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21) +#define MX51_CCM_CIMR_MASK_EMI_PODF_LOADED (0x1 << 20) +#define MX51_CCM_CIMR_MASK_AXI_C_PODF_LOADED (0x1 << 19) +#define MX51_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18) +#define MX51_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17) +#define MX51_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16) +#define MX51_CCM_CIMR_MASK_COSC_READY (0x1 << 5) +#define MX51_CCM_CIMR_MASK_CKIH_READY (0x1 << 4) +#define MX51_CCM_CIMR_MASK_FPM_READY (0x1 << 3) +#define MX51_CCM_CIMR_MASK_LRF_PLL3 (0x1 << 2) +#define MX51_CCM_CIMR_MASK_LRF_PLL2 (0x1 << 1) +#define MX51_CCM_CIMR_MASK_LRF_PLL1 (0x1) + +/* Define the bits in register CCOSR */ +#define MX51_CCM_CCOSR_CKO2_EN_OFFSET (0x1 << 24) +#define MX51_CCM_CCOSR_CKO2_DIV_OFFSET (21) +#define MX51_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21) +#define MX51_CCM_CCOSR_CKO2_SEL_OFFSET (16) +#define MX51_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16) +#define MX51_CCM_CCOSR_CKOL_EN (0x1 << 7) +#define MX51_CCM_CCOSR_CKOL_DIV_OFFSET (4) +#define MX51_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4) +#define MX51_CCM_CCOSR_CKOL_SEL_OFFSET (0) +#define MX51_CCM_CCOSR_CKOL_SEL_MASK (0xF) + +/* Define the bits in registers CGPR */ +#define MX51_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (0x1 << 4) +#define MX51_CCM_CGPR_FPM_SEL (0x1 << 3) +#define MX51_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET (0) +#define MX51_CCM_CGPR_VL_L2BIST_CLKDIV_MASK (0x7) + +/* Define the bits in registers CCGRx */ +#define MX51_CCM_CCGR_CG_MASK 0x3 +#define MX51_CCM_CCGR_MOD_OFF 0x0 +#define MX51_CCM_CCGR_MOD_ON 0x3 +#define MX51_CCM_CCGR_MOD_IDLE 0x1 + +#define MX51_CCM_CCGR0_CG15_OFFSET 30 +#define MX51_CCM_CCGR0_CG15_MASK (0x3 << 30) +#define MX51_CCM_CCGR0_CG14_OFFSET 28 +#define MX51_CCM_CCGR0_CG14_MASK (0x3 << 28) +#define MX51_CCM_CCGR0_CG13_OFFSET 26 +#define MX51_CCM_CCGR0_CG13_MASK (0x3 << 26) +#define MX51_CCM_CCGR0_CG12_OFFSET 24 +#define MX51_CCM_CCGR0_CG12_MASK (0x3 << 24) +#define MX51_CCM_CCGR0_CG11_OFFSET 22 +#define MX51_CCM_CCGR0_CG11_MASK (0x3 << 22) +#define MX51_CCM_CCGR0_CG10_OFFSET 20 +#define MX51_CCM_CCGR0_CG10_MASK (0x3 << 20) +#define MX51_CCM_CCGR0_CG9_OFFSET 18 +#define MX51_CCM_CCGR0_CG9_MASK (0x3 << 18) +#define MX51_CCM_CCGR0_CG8_OFFSET 16 +#define MX51_CCM_CCGR0_CG8_MASK (0x3 << 16) +#define MX51_CCM_CCGR0_CG7_OFFSET 14 +#define MX51_CCM_CCGR0_CG6_OFFSET 12 +#define MX51_CCM_CCGR0_CG5_OFFSET 10 +#define MX51_CCM_CCGR0_CG5_MASK (0x3 << 10) +#define MX51_CCM_CCGR0_CG4_OFFSET 8 +#define MX51_CCM_CCGR0_CG4_MASK (0x3 << 8) +#define MX51_CCM_CCGR0_CG3_OFFSET 6 +#define MX51_CCM_CCGR0_CG3_MASK (0x3 << 6) +#define MX51_CCM_CCGR0_CG2_OFFSET 4 +#define MX51_CCM_CCGR0_CG2_MASK (0x3 << 4) +#define MX51_CCM_CCGR0_CG1_OFFSET 2 +#define MX51_CCM_CCGR0_CG1_MASK (0x3 << 2) +#define MX51_CCM_CCGR0_CG0_OFFSET 0 +#define MX51_CCM_CCGR0_CG0_MASK 0x3 + +#define MX51_CCM_CCGR1_CG15_OFFSET 30 +#define MX51_CCM_CCGR1_CG14_OFFSET 28 +#define MX51_CCM_CCGR1_CG13_OFFSET 26 +#define MX51_CCM_CCGR1_CG12_OFFSET 24 +#define MX51_CCM_CCGR1_CG11_OFFSET 22 +#define MX51_CCM_CCGR1_CG10_OFFSET 20 +#define MX51_CCM_CCGR1_CG9_OFFSET 18 +#define MX51_CCM_CCGR1_CG8_OFFSET 16 +#define MX51_CCM_CCGR1_CG7_OFFSET 14 +#define MX51_CCM_CCGR1_CG6_OFFSET 12 +#define MX51_CCM_CCGR1_CG5_OFFSET 10 +#define MX51_CCM_CCGR1_CG4_OFFSET 8 +#define MX51_CCM_CCGR1_CG3_OFFSET 6 +#define MX51_CCM_CCGR1_CG2_OFFSET 4 +#define MX51_CCM_CCGR1_CG1_OFFSET 2 +#define MX51_CCM_CCGR1_CG0_OFFSET 0 + +#define MX51_CCM_CCGR2_CG15_OFFSET 30 +#define MX51_CCM_CCGR2_CG14_OFFSET 28 +#define MX51_CCM_CCGR2_CG13_OFFSET 26 +#define MX51_CCM_CCGR2_CG12_OFFSET 24 +#define MX51_CCM_CCGR2_CG11_OFFSET 22 +#define MX51_CCM_CCGR2_CG10_OFFSET 20 +#define MX51_CCM_CCGR2_CG9_OFFSET 18 +#define MX51_CCM_CCGR2_CG8_OFFSET 16 +#define MX51_CCM_CCGR2_CG7_OFFSET 14 +#define MX51_CCM_CCGR2_CG6_OFFSET 12 +#define MX51_CCM_CCGR2_CG5_OFFSET 10 +#define MX51_CCM_CCGR2_CG4_OFFSET 8 +#define MX51_CCM_CCGR2_CG3_OFFSET 6 +#define MX51_CCM_CCGR2_CG2_OFFSET 4 +#define MX51_CCM_CCGR2_CG1_OFFSET 2 +#define MX51_CCM_CCGR2_CG0_OFFSET 0 + +#define MX51_CCM_CCGR3_CG15_OFFSET 30 +#define MX51_CCM_CCGR3_CG14_OFFSET 28 +#define MX51_CCM_CCGR3_CG13_OFFSET 26 +#define MX51_CCM_CCGR3_CG12_OFFSET 24 +#define MX51_CCM_CCGR3_CG11_OFFSET 22 +#define MX51_CCM_CCGR3_CG10_OFFSET 20 +#define MX51_CCM_CCGR3_CG9_OFFSET 18 +#define MX51_CCM_CCGR3_CG8_OFFSET 16 +#define MX51_CCM_CCGR3_CG7_OFFSET 14 +#define MX51_CCM_CCGR3_CG6_OFFSET 12 +#define MX51_CCM_CCGR3_CG5_OFFSET 10 +#define MX51_CCM_CCGR3_CG4_OFFSET 8 +#define MX51_CCM_CCGR3_CG3_OFFSET 6 +#define MX51_CCM_CCGR3_CG2_OFFSET 4 +#define MX51_CCM_CCGR3_CG1_OFFSET 2 +#define MX51_CCM_CCGR3_CG0_OFFSET 0 + +#define MX51_CCM_CCGR4_CG15_OFFSET 30 +#define MX51_CCM_CCGR4_CG14_OFFSET 28 +#define MX51_CCM_CCGR4_CG13_OFFSET 26 +#define MX51_CCM_CCGR4_CG12_OFFSET 24 +#define MX51_CCM_CCGR4_CG11_OFFSET 22 +#define MX51_CCM_CCGR4_CG10_OFFSET 20 +#define MX51_CCM_CCGR4_CG9_OFFSET 18 +#define MX51_CCM_CCGR4_CG8_OFFSET 16 +#define MX51_CCM_CCGR4_CG7_OFFSET 14 +#define MX51_CCM_CCGR4_CG6_OFFSET 12 +#define MX51_CCM_CCGR4_CG5_OFFSET 10 +#define MX51_CCM_CCGR4_CG4_OFFSET 8 +#define MX51_CCM_CCGR4_CG3_OFFSET 6 +#define MX51_CCM_CCGR4_CG2_OFFSET 4 +#define MX51_CCM_CCGR4_CG1_OFFSET 2 +#define MX51_CCM_CCGR4_CG0_OFFSET 0 + +#define MX51_CCM_CCGR5_CG15_OFFSET 30 +#define MX51_CCM_CCGR5_CG14_OFFSET 28 +#define MX51_CCM_CCGR5_CG14_MASK (0x3 << 28) +#define MX51_CCM_CCGR5_CG13_OFFSET 26 +#define MX51_CCM_CCGR5_CG13_MASK (0x3 << 26) +#define MX51_CCM_CCGR5_CG12_OFFSET 24 +#define MX51_CCM_CCGR5_CG12_MASK (0x3 << 24) +#define MX51_CCM_CCGR5_CG11_OFFSET 22 +#define MX51_CCM_CCGR5_CG11_MASK (0x3 << 22) +#define MX51_CCM_CCGR5_CG10_OFFSET 20 +#define MX51_CCM_CCGR5_CG10_MASK (0x3 << 20) +#define MX51_CCM_CCGR5_CG9_OFFSET 18 +#define MX51_CCM_CCGR5_CG9_MASK (0x3 << 18) +#define MX51_CCM_CCGR5_CG8_OFFSET 16 +#define MX51_CCM_CCGR5_CG8_MASK (0x3 << 16) +#define MX51_CCM_CCGR5_CG7_OFFSET 14 +#define MX51_CCM_CCGR5_CG7_MASK (0x3 << 14) +#define MX51_CCM_CCGR5_CG6_OFFSET 12 +#define MX51_CCM_CCGR5_CG5_OFFSET 10 +#define MX51_CCM_CCGR5_CG4_OFFSET 8 +#define MX51_CCM_CCGR5_CG3_OFFSET 6 +#define MX51_CCM_CCGR5_CG2_OFFSET 4 +#define MX51_CCM_CCGR5_CG2_MASK (0x3 << 4) +#define MX51_CCM_CCGR5_CG1_OFFSET 2 +#define MX51_CCM_CCGR5_CG0_OFFSET 0 +#define MX51_CCM_CCGR6_CG7_OFFSET 14 +#define MX51_CCM_CCGR6_CG7_MASK (0x3 << 14) +#define MX51_CCM_CCGR6_CG6_OFFSET 12 +#define MX51_CCM_CCGR6_CG6_MASK (0x3 << 12) +#define MX51_CCM_CCGR6_CG5_OFFSET 10 +#define MX51_CCM_CCGR6_CG5_MASK (0x3 << 10) +#define MX51_CCM_CCGR6_CG4_OFFSET 8 +#define MX51_CCM_CCGR6_CG4_MASK (0x3 << 8) +#define MX51_CCM_CCGR6_CG3_OFFSET 6 +#define MX51_CCM_CCGR6_CG2_OFFSET 4 +#define MX51_CCM_CCGR6_CG1_OFFSET 2 +#define MX51_CCM_CCGR6_CG0_OFFSET 0 + +/* CORTEXA8 platform */ +#define MX51_CORTEXA8_PLAT_PVID (MX51_CORTEXA8_BASE + 0x0) +#define MX51_CORTEXA8_PLAT_GPC (MX51_CORTEXA8_BASE + 0x4) +#define MX51_CORTEXA8_PLAT_PIC (MX51_CORTEXA8_BASE + 0x8) +#define MX51_CORTEXA8_PLAT_LPC (MX51_CORTEXA8_BASE + 0xC) +#define MX51_CORTEXA8_PLAT_NEON_LPC (MX51_CORTEXA8_BASE + 0x10) +#define MX51_CORTEXA8_PLAT_ICGC (MX51_CORTEXA8_BASE + 0x14) +#define MX51_CORTEXA8_PLAT_AMC (MX51_CORTEXA8_BASE + 0x18) +#define MX51_CORTEXA8_PLAT_NMC (MX51_CORTEXA8_BASE + 0x20) +#define MX51_CORTEXA8_PLAT_NMS (MX51_CORTEXA8_BASE + 0x24) + +/* DVFS CORE */ +#define MX51_DVFSTHRS (MX51_DVFS_CORE_BASE + 0x00) +#define MX51_DVFSCOUN (MX51_DVFS_CORE_BASE + 0x04) +#define MX51_DVFSSIG1 (MX51_DVFS_CORE_BASE + 0x08) +#define MX51_DVFSSIG0 (MX51_DVFS_CORE_BASE + 0x0C) +#define MX51_DVFSGPC0 (MX51_DVFS_CORE_BASE + 0x10) +#define MX51_DVFSGPC1 (MX51_DVFS_CORE_BASE + 0x14) +#define MX51_DVFSGPBT (MX51_DVFS_CORE_BASE + 0x18) +#define MX51_DVFSEMAC (MX51_DVFS_CORE_BASE + 0x1C) +#define MX51_DVFSCNTR (MX51_DVFS_CORE_BASE + 0x20) +#define MX51_DVFSLTR0_0 (MX51_DVFS_CORE_BASE + 0x24) +#define MX51_DVFSLTR0_1 (MX51_DVFS_CORE_BASE + 0x28) +#define MX51_DVFSLTR1_0 (MX51_DVFS_CORE_BASE + 0x2C) +#define MX51_DVFSLTR1_1 (MX51_DVFS_CORE_BASE + 0x30) +#define MX51_DVFSPT0 (MX51_DVFS_CORE_BASE + 0x34) +#define MX51_DVFSPT1 (MX51_DVFS_CORE_BASE + 0x38) +#define MX51_DVFSPT2 (MX51_DVFS_CORE_BASE + 0x3C) +#define MX51_DVFSPT3 (MX51_DVFS_CORE_BASE + 0x40) + +/* GPC */ +#define MX51_GPC_CNTR (MX51_GPC_BASE + 0x0) +#define MX51_GPC_PGR (MX51_GPC_BASE + 0x4) +#define MX51_GPC_VCR (MX51_GPC_BASE + 0x8) +#define MX51_GPC_ALL_PU (MX51_GPC_BASE + 0xC) +#define MX51_GPC_NEON (MX51_GPC_BASE + 0x10) +#define MX51_GPC_PGR_ARMPG_OFFSET 8 +#define MX51_GPC_PGR_ARMPG_MASK (3 << 8) + +/* PGC */ +#define MX51_PGC_IPU_PGCR (MX51_PGC_IPU_BASE + 0x0) +#define MX51_PGC_IPU_PGSR (MX51_PGC_IPU_BASE + 0xC) +#define MX51_PGC_VPU_PGCR (MX51_PGC_VPU_BASE + 0x0) +#define MX51_PGC_VPU_PGSR (MX51_PGC_VPU_BASE + 0xC) +#define MX51_PGC_GPU_PGCR (MX51_PGC_GPU_BASE + 0x0) +#define MX51_PGC_GPU_PGSR (MX51_PGC_GPU_BASE + 0xC) + +#define MX51_PGCR_PCR 1 +#define MX51_SRPGCR_PCR 1 +#define MX51_EMPGCR_PCR 1 +#define MX51_PGSR_PSR 1 + + +#define MX51_CORTEXA8_PLAT_LPC_DSM (1 << 0) +#define MX51_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1) + +/* SRPG */ +#define MX51_SRPG_NEON_SRPGCR (MX51_SRPG_NEON_BASE + 0x0) +#define MX51_SRPG_NEON_PUPSCR (MX51_SRPG_NEON_BASE + 0x4) +#define MX51_SRPG_NEON_PDNSCR (MX51_SRPG_NEON_BASE + 0x8) + +#define MX51_SRPG_ARM_SRPGCR (MX51_SRPG_ARM_BASE + 0x0) +#define MX51_SRPG_ARM_PUPSCR (MX51_SRPG_ARM_BASE + 0x4) +#define MX51_SRPG_ARM_PDNSCR (MX51_SRPG_ARM_BASE + 0x8) + +#define MX51_SRPG_EMPGC0_SRPGCR (MX51_SRPG_EMPGC0_BASE + 0x0) +#define MX51_SRPG_EMPGC0_PUPSCR (MX51_SRPG_EMPGC0_BASE + 0x4) +#define MX51_SRPG_EMPGC0_PDNSCR (MX51_SRPG_EMPGC0_BASE + 0x8) + +#define MX51_SRPG_EMPGC1_SRPGCR (MX51_SRPG_EMPGC1_BASE + 0x0) +#define MX51_SRPG_EMPGC1_PUPSCR (MX51_SRPG_EMPGC1_BASE + 0x4) +#define MX51_SRPG_EMPGC1_PDNSCR (MX51_SRPG_EMPGC1_BASE + 0x8) + +#define MX51_SRPG_MEGAMIX_SRPGCR (MX51_SRPG_MEGAMIX_BASE + 0x0) +#define MX51_SRPG_MEGAMIX_PUPSCR (MX51_SRPG_MEGAMIX_BASE + 0x4) +#define MX51_SRPG_MEGAMIX_PDNSCR (MX51_SRPG_MEGAMIX_BASE + 0x8) + +#define MX51_SRPGC_EMI_SRPGCR (MX51_SRPGC_EMI_BASE + 0x0) +#define MX51_SRPGC_EMI_PUPSCR (MX51_SRPGC_EMI_BASE + 0x4) +#define MX51_SRPGC_EMI_PDNSCR (MX51_SRPGC_EMI_BASE + 0x8) + +#endif /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */ + + diff --git a/arch/arm/mach-imx/include/mach/clock.h b/arch/arm/mach-imx/include/mach/clock.h index 76ab4a5..5b590a2 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_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 d15f52b..fe74cb6 100644 --- a/arch/arm/mach-imx/include/mach/esdctl.h +++ b/arch/arm/mach-imx/include/mach/esdctl.h @@ -18,9 +18,11 @@ #define ESDCTL0_ROW13 (2 << 24) #define ESDCTL0_ROW14 (3 << 24) #define ESDCTL0_ROW15 (4 << 24) +#define ESDCTL0_ROW_MASK (7 << 24) #define ESDCTL0_COL8 (0 << 20) #define ESDCTL0_COL9 (1 << 20) #define ESDCTL0_COL10 (2 << 20) +#define ESDCTL0_COL_MASK (3 << 20) #define ESDCTL0_DSIZ_31_16 (0 << 16) #define ESDCTL0_DSIZ_15_0 (1 << 16) #define ESDCTL0_DSIZ_31_0 (2 << 16) @@ -32,3 +34,89 @@ #define ESDCTL0_FP (1 << 8) #define ESDCTL0_BL (1 << 7) +#define ESDMISC_RST 0x00000002 +#define ESDMISC_MDDR_EN 0x00000004 +#define ESDMISC_MDDR_DIS 0x00000000 +#define ESDMISC_MDDR_DL_RST 0x00000008 +#define ESDMISC_MDDR_MDIS 0x00000010 +#define ESDMISC_LHD 0x00000020 +#define ESDMISC_SDRAMRDY 0x80000000 + +#define ESDCFGx_tXP_MASK 0x00600000 +#define ESDCFGx_tXP_1 0x00000000 +#define ESDCFGx_tXP_2 0x00200000 +#define ESDCFGx_tXP_3 0x00400000 +#define ESDCFGx_tXP_4 0x00600000 + +#define ESDCFGx_tWTR_MASK 0x00100000 +#define ESDCFGx_tWTR_1 0x00000000 +#define ESDCFGx_tWTR_2 0x00100000 + +#define ESDCFGx_tRP_MASK 0x000c0000 +#define ESDCFGx_tRP_1 0x00000000 +#define ESDCFGx_tRP_2 0x00040000 +#define ESDCFGx_tRP_3 0x00080000 +#define ESDCFGx_tRP_4 0x000c0000 + + +#define ESDCFGx_tMRD_MASK 0x00030000 +#define ESDCFGx_tMRD_1 0x00000000 +#define ESDCFGx_tMRD_2 0x00010000 +#define ESDCFGx_tMRD_3 0x00020000 +#define ESDCFGx_tMRD_4 0x00030000 + + +#define ESDCFGx_tWR_MASK 0x00008000 +#define ESDCFGx_tWR_1_2 0x00000000 +#define ESDCFGx_tWR_2_3 0x00008000 + +#define ESDCFGx_tRAS_MASK 0x00007000 +#define ESDCFGx_tRAS_1 0x00000000 +#define ESDCFGx_tRAS_2 0x00001000 +#define ESDCFGx_tRAS_3 0x00002000 +#define ESDCFGx_tRAS_4 0x00003000 +#define ESDCFGx_tRAS_5 0x00004000 +#define ESDCFGx_tRAS_6 0x00005000 +#define ESDCFGx_tRAS_7 0x00006000 +#define ESDCFGx_tRAS_8 0x00007000 + + +#define ESDCFGx_tRRD_MASK 0x00000c00 +#define ESDCFGx_tRRD_1 0x00000000 +#define ESDCFGx_tRRD_2 0x00000400 +#define ESDCFGx_tRRD_3 0x00000800 +#define ESDCFGx_tRRD_4 0x00000c00 + + +#define ESDCFGx_tCAS_MASK 0x00000300 +#define ESDCFGx_tCAS_2 0x00000200 +#define ESDCFGx_tCAS_3 0x00000300 + +#define ESDCFGx_tRCD_MASK 0x00000070 +#define ESDCFGx_tRCD_1 0x00000000 +#define ESDCFGx_tRCD_2 0x00000010 +#define ESDCFGx_tRCD_3 0x00000020 +#define ESDCFGx_tRCD_4 0x00000030 +#define ESDCFGx_tRCD_5 0x00000040 +#define ESDCFGx_tRCD_6 0x00000050 +#define ESDCFGx_tRCD_7 0x00000060 +#define ESDCFGx_tRCD_8 0x00000070 + +#define ESDCFGx_tRC_MASK 0x0000000f +#define ESDCFGx_tRC_20 0x00000000 +#define ESDCFGx_tRC_2 0x00000001 +#define ESDCFGx_tRC_3 0x00000002 +#define ESDCFGx_tRC_4 0x00000003 +#define ESDCFGx_tRC_5 0x00000004 +#define ESDCFGx_tRC_6 0x00000005 +#define ESDCFGx_tRC_7 0x00000006 +#define ESDCFGx_tRC_8 0x00000007 +#define ESDCFGx_tRC_9 0x00000008 +#define ESDCFGx_tRC_10 0x00000009 +#define ESDCFGx_tRC_11 0x0000000a +#define ESDCFGx_tRC_12 0x0000000b +#define ESDCFGx_tRC_13 0x0000000c +#define ESDCFGx_tRC_14 0x0000000d +//#define ESDCFGx_tRC_14 0x0000000e // 15 seems to not exist +#define ESDCFGx_tRC_16 0x0000000f + diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h index 4b89838..9ca838b 100644 --- a/arch/arm/mach-imx/include/mach/generic.h +++ b/arch/arm/mach-imx/include/mach/generic.h @@ -45,3 +45,9 @@ #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 06acddb..eb583a2 100644 --- a/arch/arm/mach-imx/include/mach/imx-nand.h +++ b/arch/arm/mach-imx/include/mach/imx-nand.h @@ -8,8 +8,8 @@ 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 2cc49dd..605d320 100644 --- a/arch/arm/mach-imx/include/mach/imx-regs.h +++ b/arch/arm/mach-imx/include/mach/imx-regs.h @@ -51,6 +51,8 @@ # include #elif defined CONFIG_ARCH_IMX25 # include +#elif defined CONFIG_ARCH_IMX51 +#include #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 0d6fd92..f940cdb 100644 --- a/arch/arm/mach-imx/include/mach/imx1-regs.h +++ b/arch/arm/mach-imx/include/mach/imx1-regs.h @@ -40,14 +40,6 @@ #define IMX_AITC_BASE (0x23000 + IMX_IO_BASE) #define IMX_CSI_BASE (0x24000 + IMX_IO_BASE) -/* Watchdog Registers*/ -#define WCR __REG(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */ -#define WSR __REG(IMX_WDT_BASE + 0x04) /* Watchdog Service Register */ -#define WSTR __REG(IMX_WDT_BASE + 0x08) /* Watchdog Status Register */ - -/* important definition of some bits of WCR */ -#define WCR_WDE 0x01 - /* SYSCTRL Registers */ #define SIDR __REG(IMX_SYSCTRL_BASE + 0x4) /* Silicon ID Register */ #define FMCR __REG(IMX_SYSCTRL_BASE + 0x8) /* Function Multiplex Control Register */ diff --git a/arch/arm/mach-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h index 6d64b81..a2c4d03 100644 --- a/arch/arm/mach-imx/include/mach/imx21-regs.h +++ b/arch/arm/mach-imx/include/mach/imx21-regs.h @@ -72,14 +72,6 @@ #define CS5L __REG(IMX_EIM_BASE + 0x2C) /* Chip Select 5 Lower Register */ #define EIM __REG(IMX_EIM_BASE + 0x30) /* EIM Configuration Register */ -/* Watchdog Registers*/ -#define WCR __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */ -#define WSR __REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */ -#define WRSR __REG16(IMX_WDT_BASE + 0x04) /* Watchdog Reset Status Register */ - -/* important definition of some bits of WCR */ -#define WCR_WDE 0x04 - /* PLL registers */ #define CSCR __REG(IMX_PLL_BASE + 0x00) /* Clock Source Control Register */ #define MPCTL0 __REG(IMX_PLL_BASE + 0x04) /* MCU PLL Control Register 0 */ diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h index f4354ba..e87d5bf 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 d2304ec..536bf0d 100644 --- a/arch/arm/mach-imx/include/mach/imx31-regs.h +++ b/arch/arm/mach-imx/include/mach/imx31-regs.h @@ -120,16 +120,6 @@ #endif /* - * Watchdog Registers - */ -#define WCR __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */ -#define WSR __REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */ -#define WSTR __REG16(IMX_WDT_BASE + 0x04) /* Watchdog Status Register */ - -/* important definition of some bits of WCR */ -#define WCR_WDE 0x04 - -/* * Clock Controller Module (CCM) */ #define IMX_CCM_BASE 0x53f80000 diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h index 5cfb788..89ca7ea 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 0000000..1719a78 --- /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 a290a33..a8ca8f1 100644 --- a/arch/arm/mach-imx/include/mach/iomux-mx25.h +++ b/arch/arm/mach-imx/include/mach/iomux-mx25.h @@ -658,21 +658,21 @@ #define MX25_PAD_RW__EIM_RW IOMUX_PAD(0x278, 0x6c, 0, 0, 0, NO_PAD_CTRL) #define MX25_PAD_RW__AUD4_TXFS IOMUX_PAD(0x278, 0x6c, 4, 0x474, 0, NO_PAD_CTRL) #define MX25_PAD_RW__GPIO25 IOMUX_PAD(0x278, 0x6c, 5, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_SD1_CLK__CLK IOMUX_PAD(0x38c, 0x194, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_SD1_CLK__CLK IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__MISO IOMUX_PAD(0x38c, 0x194, 1, 0x49c, 1, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__RDATA3 IOMUX_PAD(0x38c, 0x194, 2, 0x510, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__SDMA_DBG_STAT_0 IOMUX_PAD(0x38c, 0x194, 4, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__GPIO24 IOMUX_PAD(0x38c, 0x194, 5, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__SLCDC_DATA1 IOMUX_PAD(0x38c, 0x194, 6, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__TRACE11 IOMUX_PAD(0x38c, 0x194, 7, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_SD1_CMD__CMD IOMUX_PAD(0x388, 0x190, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_SD1_CMD__CMD IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__MOSI IOMUX_PAD(0x388, 0x190, 1, 0x4a0, 1, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__RDATA2 IOMUX_PAD(0x388, 0x190, 2, 0x50c, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__SDMA_DBG_EVT_SEL IOMUX_PAD(0x388, 0x190, 4, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__GPIO23 IOMUX_PAD(0x388, 0x190, 5, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__SLCDC_DATA0 IOMUX_PAD(0x388, 0x190, 6, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__TRACE10 IOMUX_PAD(0x388, 0x190, 7, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_SD1_DATA0__DAT0 IOMUX_PAD(0x390, 0x198, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA0__DAT0 IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA0__SCLK IOMUX_PAD(0x390, 0x198, 1, 0x494, 1, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA0__TDATA2 IOMUX_PAD(0x390, 0x198, 2, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA0__AUD7_TXFS IOMUX_PAD(0x390, 0x198, 3, 0x47c, 0, NO_PAD_CTRL) @@ -680,7 +680,7 @@ #define MX25_PAD_SD1_DATA0__GPIO25 IOMUX_PAD(0x390, 0x198, 5, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA0__SLCDC_DATA2 IOMUX_PAD(0x390, 0x198, 6, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA0__TRACE12 IOMUX_PAD(0x390, 0x198, 7, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_SD1_DATA1__DAT1 IOMUX_PAD(0x394, 0x19c, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA1__DAT1 IOMUX_PAD(0x394, 0x19c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA1__RDY IOMUX_PAD(0x394, 0x19c, 1, 0x498, 1, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA1__TDATA3 IOMUX_PAD(0x394, 0x19c, 2, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA1__AUD7_RXD IOMUX_PAD(0x394, 0x19c, 3, 0x478, 0, NO_PAD_CTRL) @@ -688,7 +688,7 @@ #define MX25_PAD_SD1_DATA1__GPIO26 IOMUX_PAD(0x394, 0x19c, 5, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA1__SLCDC_DATA3 IOMUX_PAD(0x394, 0x19c, 6, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA1__TRACE13 IOMUX_PAD(0x394, 0x19c, 7, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_SD1_DATA2__DAT2 IOMUX_PAD(0x398, 0x1a0, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA2__DAT2 IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__SS0 IOMUX_PAD(0x398, 0x1a0, 1, 0x4a4, 1, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__RX_CLK IOMUX_PAD(0x398, 0x1a0, 2, 0x514, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__AUD7_RXC IOMUX_PAD(0x398, 0x1a0, 3, 0, 0, NO_PAD_CTRL) @@ -696,7 +696,7 @@ #define MX25_PAD_SD1_DATA2__GPIO27 IOMUX_PAD(0x398, 0x1a0, 5, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__SLCDC_DATA4 IOMUX_PAD(0x398, 0x1a0, 6, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__TRACE14 IOMUX_PAD(0x398, 0x1a0, 7, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_SD1_DATA3__DAT3 IOMUX_PAD(0x39c, 0x1a4, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA3__DAT3 IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA3__SS1 IOMUX_PAD(0x39c, 0x1a4, 1, 0x4a8, 1, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA3__CRS IOMUX_PAD(0x39c, 0x1a4, 2, 0x508, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA3__AUD7_RXFS IOMUX_PAD(0x39c, 0x1a4, 3, 0, 0, NO_PAD_CTRL) diff --git a/arch/arm/mach-imx/include/mach/iomux-mx27.h b/arch/arm/mach-imx/include/mach/iomux-mx27.h index 993b141..23e448b 100644 --- a/arch/arm/mach-imx/include/mach/iomux-mx27.h +++ b/arch/arm/mach-imx/include/mach/iomux-mx27.h @@ -28,6 +28,12 @@ #define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2) #define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3) #define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4) +#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4) +#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5) +#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6) +#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7) +#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8) +#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9) #define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22) #define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25) #define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_PF | GPIO_IN | 5) diff --git a/arch/arm/mach-imx/include/mach/iomux-mx35.h b/arch/arm/mach-imx/include/mach/iomux-mx35.h index 8a56d86..ad7ff56 100644 --- a/arch/arm/mach-imx/include/mach/iomux-mx35.h +++ b/arch/arm/mach-imx/include/mach/iomux-mx35.h @@ -815,42 +815,42 @@ #define MX35_PAD_D3_SPL__SDMA_DEBUG_BUS_DEVICE_1 IOMUX_PAD(0x690, 0x22c, 6, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_D3_SPL__ARM11P_TOP_TRACE_22 IOMUX_PAD(0x690, 0x22c, 7, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CMD__ESDHC1_CMD IOMUX_PAD(0x694, 0x230, 0, 0x0, 0, NO_PAD_CTRL) +#define MX35_PAD_SD1_CMD__ESDHC1_CMD IOMUX_PAD(0x694, 0x230, 0x10, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_CMD__MSHC_SCLK IOMUX_PAD(0x694, 0x230, 1, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_CMD__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x694, 0x230, 3, 0x924, 2, NO_PAD_CTRL) #define MX35_PAD_SD1_CMD__USB_TOP_USBOTG_DATA_4 IOMUX_PAD(0x694, 0x230, 4, 0x9b4, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_CMD__GPIO1_6 IOMUX_PAD(0x694, 0x230, 5, 0x858, 2, NO_PAD_CTRL) #define MX35_PAD_SD1_CMD__ARM11P_TOP_TRCTL IOMUX_PAD(0x694, 0x230, 7, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CLK__ESDHC1_CLK IOMUX_PAD(0x698, 0x234, 0, 0x0, 0, NO_PAD_CTRL) +#define MX35_PAD_SD1_CLK__ESDHC1_CLK IOMUX_PAD(0x698, 0x234, 0x10, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_CLK__MSHC_BS IOMUX_PAD(0x698, 0x234, 1, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_CLK__IPU_DISPB_BCLK IOMUX_PAD(0x698, 0x234, 3, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_CLK__USB_TOP_USBOTG_DATA_5 IOMUX_PAD(0x698, 0x234, 4, 0x9b8, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_CLK__GPIO1_7 IOMUX_PAD(0x698, 0x234, 5, 0x85c, 2, NO_PAD_CTRL) #define MX35_PAD_SD1_CLK__ARM11P_TOP_TRCLK IOMUX_PAD(0x698, 0x234, 7, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA0__ESDHC1_DAT0 IOMUX_PAD(0x69c, 0x238, 0, 0x0, 0, NO_PAD_CTRL) +#define MX35_PAD_SD1_DATA0__ESDHC1_DAT0 IOMUX_PAD(0x69c, 0x238, 0x10, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA0__MSHC_DATA_0 IOMUX_PAD(0x69c, 0x238, 1, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA0__IPU_DISPB_CS0 IOMUX_PAD(0x69c, 0x238, 3, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA0__USB_TOP_USBOTG_DATA_6 IOMUX_PAD(0x69c, 0x238, 4, 0x9bc, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA0__GPIO1_8 IOMUX_PAD(0x69c, 0x238, 5, 0x860, 2, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA0__ARM11P_TOP_TRACE_23 IOMUX_PAD(0x69c, 0x238, 7, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA1__ESDHC1_DAT1 IOMUX_PAD(0x6a0, 0x23c, 0, 0x0, 0, NO_PAD_CTRL) +#define MX35_PAD_SD1_DATA1__ESDHC1_DAT1 IOMUX_PAD(0x6a0, 0x23c, 0x10, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA1__MSHC_DATA_1 IOMUX_PAD(0x6a0, 0x23c, 1, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA1__IPU_DISPB_PAR_RS IOMUX_PAD(0x6a0, 0x23c, 3, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA1__USB_TOP_USBOTG_DATA_0 IOMUX_PAD(0x6a0, 0x23c, 4, 0x9a4, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA1__GPIO1_9 IOMUX_PAD(0x6a0, 0x23c, 5, 0x864, 1, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA1__ARM11P_TOP_TRACE_24 IOMUX_PAD(0x6a0, 0x23c, 7, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA2__ESDHC1_DAT2 IOMUX_PAD(0x6a4, 0x240, 0, 0x0, 0, NO_PAD_CTRL) +#define MX35_PAD_SD1_DATA2__ESDHC1_DAT2 IOMUX_PAD(0x6a4, 0x240, 0x10, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA2__MSHC_DATA_2 IOMUX_PAD(0x6a4, 0x240, 1, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA2__IPU_DISPB_WR IOMUX_PAD(0x6a4, 0x240, 3, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA2__USB_TOP_USBOTG_DATA_1 IOMUX_PAD(0x6a4, 0x240, 4, 0x9a8, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA2__GPIO1_10 IOMUX_PAD(0x6a4, 0x240, 5, 0x830, 1, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA2__ARM11P_TOP_TRACE_25 IOMUX_PAD(0x6a4, 0x240, 7, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA3__ESDHC1_DAT3 IOMUX_PAD(0x6a8, 0x244, 0, 0x0, 0, NO_PAD_CTRL) +#define MX35_PAD_SD1_DATA3__ESDHC1_DAT3 IOMUX_PAD(0x6a8, 0x244, 0x10, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA3__MSHC_DATA_3 IOMUX_PAD(0x6a8, 0x244, 1, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA3__IPU_DISPB_RD IOMUX_PAD(0x6a8, 0x244, 3, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_SD1_DATA3__USB_TOP_USBOTG_DATA_2 IOMUX_PAD(0x6a8, 0x244, 4, 0x9ac, 0, NO_PAD_CTRL) diff --git a/arch/arm/mach-imx/include/mach/iomux-mx51.h b/arch/arm/mach-imx/include/mach/iomux-mx51.h new file mode 100644 index 0000000..2901ee6 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/iomux-mx51.h @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2009 by Sascha Hauer + * + * 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 + +#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___ + * If or refers to a GPIO, it is named + * GPIO__ see also iomux-v3.h + */ + +/* PAD MUX ALT INPSE PATH */ +#define MX51_PAD_EIM_DA0__EIM_DA0 IOMUX_PAD(0x7A8, 0x1C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA1__EIM_DA1 IOMUX_PAD(0x7A8, 0x20, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA2__EIM_DA2 IOMUX_PAD(0x7A8, 0x24, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA3__EIM_DA3 IOMUX_PAD(0x7A8, 0x28, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA4__EIM_DA4 IOMUX_PAD(0x7AC, 0x2C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA5__EIM_DA5 IOMUX_PAD(0x7AC, 0x30, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA6__EIM_DA6 IOMUX_PAD(0x7AC, 0x34, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA7__EIM_DA7 IOMUX_PAD(0x7AC, 0x38, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA8__EIM_DA8 IOMUX_PAD(0x7B0, 0x3C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA9__EIM_DA9 IOMUX_PAD(0x7B0, 0x40, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA10__EIM_DA10 IOMUX_PAD(0x7B0, 0x44, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA11__EIM_DA11 IOMUX_PAD(0x7B0, 0x48, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA12__EIM_DA12 IOMUX_PAD(0x7BC, 0x4C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA13__EIM_DA13 IOMUX_PAD(0x7BC, 0x50, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA14__EIM_DA14 IOMUX_PAD(0x7BC, 0x54, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_DA15__EIM_DA15 IOMUX_PAD(0x7BC, 0x58, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D16__EIM_D16 IOMUX_PAD(0x3F0, 0x5C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D17__EIM_D17 IOMUX_PAD(0x3F4, 0x60, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D18__EIM_D18 IOMUX_PAD(0x3F8, 0x64, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D19__EIM_D19 IOMUX_PAD(0x3FC, 0x68, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D20__EIM_D20 IOMUX_PAD(0x400, 0x6C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D21__EIM_D21 IOMUX_PAD(0x404, 0x70, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D22__EIM_D22 IOMUX_PAD(0x408, 0x74, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D23__EIM_D23 IOMUX_PAD(0x40C, 0x78, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D24__EIM_D24 IOMUX_PAD(0x410, 0x7C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D25__EIM_D25 IOMUX_PAD(0x414, 0x80, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D26__EIM_D26 IOMUX_PAD(0x418, 0x84, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D27__EIM_D27 IOMUX_PAD(0x41C, 0x88, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D28__EIM_D28 IOMUX_PAD(0x420, 0x8C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D29__EIM_D29 IOMUX_PAD(0x424, 0x90, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D30__EIM_D30 IOMUX_PAD(0x428, 0x94, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D31__EIM_D31 IOMUX_PAD(0x42C, 0x98, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A16__EIM_A16 IOMUX_PAD(0x430, 0x9C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A17__EIM_A17 IOMUX_PAD(0x434, 0xA0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A18__EIM_A18 IOMUX_PAD(0x438, 0xA4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A19__EIM_A19 IOMUX_PAD(0x43C, 0xA8, 0, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_EIM_A20__EIM_A20 IOMUX_PAD(0x440, 0xAC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A20__GPIO2_14 IOMUX_PAD(0x440, 0xAC, 1, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_EIM_A21__EIM_A21 IOMUX_PAD(0x444, 0xB0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A22__EIM_A22 IOMUX_PAD(0x448, 0xB4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A23__EIM_A23 IOMUX_PAD(0x44C, 0xB8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A24__EIM_A24 IOMUX_PAD(0x450, 0xBC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A25__EIM_A25 IOMUX_PAD(0x454, 0xC0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A26__EIM_A26 IOMUX_PAD(0x458, 0xC4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_A27__EIM_A27 IOMUX_PAD(0x45C, 0xC8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0xCC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0xD0, 0, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_EIM_EB2__EIM_EB2 IOMUX_PAD(0x468, 0xD4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_EB2__FEC_MDIO IOMUX_PAD(0x468, 0x0d4, 3, 0x954, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_EIM_EB3__EIM_EB3 IOMUX_PAD(0x46C, 0xD8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_EB3__FEC_RDATA1 IOMUX_PAD(0x46c, 0x0d8, 3, 0x95c, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_EIM_OE__EIM_OE IOMUX_PAD(0x470, 0xDC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS0__EIM_CS0 IOMUX_PAD(0x474, 0xE0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS1__EIM_CS1 IOMUX_PAD(0x478, 0xE4, 0, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_EIM_CS2__EIM_CS2 IOMUX_PAD(0x47C, 0xE8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS2__FEC_RDATA2 IOMUX_PAD(0x47c, 0x0e8, 3, 0x960, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_EIM_CS3__EIM_CS3 IOMUX_PAD(0x480, 0xEC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS3__FEC_RDATA3 IOMUX_PAD(0x480, 0x0ec, 3, 0x964, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_EIM_CS4__EIM_CS4 IOMUX_PAD(0x484, 0xF0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS4__FEC_RX_ER IOMUX_PAD(0x484, 0x0f0, 3, 0x970, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_EIM_CS5__EIM_CS5 IOMUX_PAD(0x488, 0xF4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS5__FEC_CRS IOMUX_PAD(0x52C, 0xF4, 3, 0x950, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_EIM_DTACK__EIM_DTACK IOMUX_PAD(0x48C, 0xF8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_LBA__EIM_LBA IOMUX_PAD(0x494, 0xFC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CRE__EIM_CRE IOMUX_PAD(0x4A0, 0x100, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DRAM_CS1__DRAM_CS1 IOMUX_PAD(0x4D0, 0x104, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_WE_B__NANDF_WE_B IOMUX_PAD(0x4E4, 0x108, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RE_B__NANDF_RE_B IOMUX_PAD(0x4E8, 0x10C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_ALE__NANDF_ALE IOMUX_PAD(0x4EC, 0x110, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CLE__NANDF_CLE IOMUX_PAD(0x4F0, 0x114, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_WP_B__NANDF_WP_B IOMUX_PAD(0x4F4, 0x118, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB0__NANDF_RB0 IOMUX_PAD(0x4F8, 0x11C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB1__NANDF_RB1 IOMUX_PAD(0x4FC, 0x120, 0, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_NANDF_RB2__NANDF_RB2 IOMUX_PAD(0x500, 0x124, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x94c, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_RB3__NANDF_RB3 IOMUX_PAD(0x504, 0x128, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB3__FEC_RX_CLK IOMUX_PAD(0x504, 0x128, 1, 0x968, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_RB4__NANDF_RB4 IOMUX_PAD(0x514, 0x12C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB5__NANDF_RB5 IOMUX_PAD(0x5D8, 0x130, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB6__FEC_RDATA0 IOMUX_PAD(0x5DC, 0x16C, 2, 0x958, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_RB7__NANDF_RB7 IOMUX_PAD(0x5E0, 0x138, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB7__FEC_TX_ER IOMUX_PAD(0x5E0, 0x138, 2, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_NANDF_CS0__NANDF_CS0 IOMUX_PAD(0x518, 0x130, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS1__NANDF_CS1 IOMUX_PAD(0x51C, 0x134, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS2__NANDF_CS2 IOMUX_PAD(0x520, 0x138, 0, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_NANDF_CS3__NANDF_CS3 IOMUX_PAD(0x524, 0x13C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13C, 2, 0x0, 0,MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_CS4__NANDF_CS4 IOMUX_PAD(0x528, 0x140, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS4__FEC_TDATA1 IOMUX_PAD(0x528, 0x140, 2, 0x0, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_CS5__NANDF_CS5 IOMUX_PAD(0x52C, 0x144, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS5__FEC_TDATA2 IOMUX_PAD(0x52C, 0x144, 2, 0x0, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_CS6__NANDF_CS6 IOMUX_PAD(0x530, 0x148, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS6__FEC_TDATA3 IOMUX_PAD(0x530, 0x148, 2, 0x0, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_CS7__NANDF_CS7 IOMUX_PAD(0x534, 0x14C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS7__FEC_TX_EN IOMUX_PAD(0x534, 0x14C, 1, 0x0, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT IOMUX_PAD(0x538, 0x150, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x974, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_D15__NANDF_D15 IOMUX_PAD(0x53C, 0x154, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D14__NANDF_D14 IOMUX_PAD(0x540, 0x158, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D13__NANDF_D13 IOMUX_PAD(0x544, 0x15C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D12__NANDF_D12 IOMUX_PAD(0x548, 0x160, 0, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_NANDF_D11__NANDF_D11 IOMUX_PAD(0x54C, 0x164, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D11__FEC_RX_DV IOMUX_PAD(0x54C, 0x164, 2, 0x96c, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_D10__NANDF_D10 IOMUX_PAD(0x550, 0x168, 0, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_NANDF_D9__NANDF_D9 IOMUX_PAD(0x554, 0x16C, 0, 0x0, 0, NO_PAD_CTRL) + +#define MX51_PAD_NANDF_D8__NANDF_D8 IOMUX_PAD(0x558, 0x170, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D8__FEC_TDATA0 IOMUX_PAD(0x558, 0x170, 2, 0x0, 0, MX51_FEC_PAD_CTRL) + +#define MX51_PAD_NANDF_D7__NANDF_D7 IOMUX_PAD(0x55C, 0x174, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D6__NANDF_D6 IOMUX_PAD(0x560, 0x178, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D5__NANDF_D5 IOMUX_PAD(0x564, 0x17C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D4__NANDF_D4 IOMUX_PAD(0x568, 0x180, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D3__NANDF_D3 IOMUX_PAD(0x56C, 0x184, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D2__NANDF_D2 IOMUX_PAD(0x570, 0x188, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D1__NANDF_D1 IOMUX_PAD(0x574, 0x18C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D0__NANDF_D0 IOMUX_PAD(0x578, 0x190, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D8__CSI1_D8 IOMUX_PAD(0x57C, 0x194, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D9__CSI1_D9 IOMUX_PAD(0x580, 0x198, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D10__CSI1_D10 IOMUX_PAD(0x584, 0x19C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D11__CSI1_D11 IOMUX_PAD(0x588, 0x1A0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D12__CSI1_D12 IOMUX_PAD(0x58C, 0x1A4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D13__CSI1_D13 IOMUX_PAD(0x590, 0x1A8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D14__CSI1_D14 IOMUX_PAD(0x594, 0x1AC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D15__CSI1_D15 IOMUX_PAD(0x598, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D16__CSI1_D16 IOMUX_PAD(0x59C, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D17__CSI1_D17 IOMUX_PAD(0x5A0, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D18__CSI1_D18 IOMUX_PAD(0x5A4, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_D19__CSI1_D19 IOMUX_PAD(0x5A8, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC IOMUX_PAD(0x5AC, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC IOMUX_PAD(0x5B0, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK IOMUX_PAD(0x5B4, NON_MUX_I, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_MCLK__CSI1_MCLK IOMUX_PAD(0x5B8, NON_MUX_I, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI1_PKE0__CSI1_PKE0 IOMUX_PAD(0x860, NON_MUX_I, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_D12__CSI2_D12 IOMUX_PAD(0x5BC, 0x1CC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_D13__CSI2_D13 IOMUX_PAD(0x5C0, 0x1D0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_D14__CSI2_D14 IOMUX_PAD(0x5C4, 0x1D4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_D15__CSI2_D15 IOMUX_PAD(0x5C8, 0x1D8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_D16__CSI2_D16 IOMUX_PAD(0x5CC, 0x1DC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_D17__CSI2_D17 IOMUX_PAD(0x5D0, 0x1E0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_D18__CSI2_D18 IOMUX_PAD(0x5D4, 0x1E4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_D19__CSI2_D19 IOMUX_PAD(0x5D8, 0x1E8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_VSYNC__CSI2_VSYNC IOMUX_PAD(0x5DC, 0x1EC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_HSYNC__CSI2_HSYNC IOMUX_PAD(0x5E0, 0x1F0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK IOMUX_PAD(0x5E4, 0x1F4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSI2_PKE0__CSI2_PKE0 IOMUX_PAD(0x81C, NON_MUX_I, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(0x5E8, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(0x5EC, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_AUD3_BB_TXD__AUD3_BB_TXD IOMUX_PAD(0x5F0, 0x200, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_AUD3_BB_RXD__AUD3_BB_RXD IOMUX_PAD(0x5F4, 0x204, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_AUD3_BB_CK__AUD3_BB_CK IOMUX_PAD(0x5F8, 0x208, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_AUD3_BB_FS__AUD3_BB_FS IOMUX_PAD(0x5FC, 0x20C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(0x600, 0x210, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(0x604, 0x214, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(0x608, 0x218, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(0x60C, 0x21C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_RDY__CSPI1_RDY IOMUX_PAD(0x610, 0x220, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(0x614, 0x224, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61C, 0x22C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x620, 0x230, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x624, 0x234, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x628, 0x238, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x62C, 0x23C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_UART3_RXD__UART3_RXD IOMUX_PAD(0x630, 0x240, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_UART3_TXD__UART3_TXD IOMUX_PAD(0x634, 0x244, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_OWIRE_LINE__OWIRE_LINE IOMUX_PAD(0x638, 0x248, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x63C, 0x24C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x640, 0x250, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x644, 0x254, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x648, 0x258, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x64C, 0x25C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x650, 0x260, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x654, 0x264, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_COL4__KEY_COL4 IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_COL5__KEY_COL5 IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DIR__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_STP__USBH1_STP IOMUX_PAD(0x680, 0x280, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_NXT__USBH1_NXT IOMUX_PAD(0x684, 0x284, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 IOMUX_PAD(0x68C, 0x28C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 IOMUX_PAD(0x69C, 0x29C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI1_PIN11__DI1_PIN11 IOMUX_PAD(0x6A8, 0x2A8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI1_PIN12__DI1_PIN12 IOMUX_PAD(0x6AC, 0x2AC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI1_PIN13__DI1_PIN13 IOMUX_PAD(0x6B0, 0x2B0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI1_D0_CS__DI1_D0_CS IOMUX_PAD(0x6B4, 0x2B4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI1_D1_CS__DI1_D1_CS IOMUX_PAD(0x6B8, 0x2B8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN IOMUX_PAD(0x6BC, 0x2BC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO IOMUX_PAD(0x6C0, 0x2C0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK IOMUX_PAD(0x6C4, 0x2C4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS IOMUX_PAD(0x6C8, 0x2C8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT3__DISP1_DAT3 IOMUX_PAD(0x6D8, 0x2D8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT4__DISP1_DAT4 IOMUX_PAD(0x6DC, 0x2DC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT5__DISP1_DAT5 IOMUX_PAD(0x6E0, 0x2E0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT6__DISP1_DAT6 IOMUX_PAD(0x6E4, 0x2E4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT7__DISP1_DAT7 IOMUX_PAD(0x6E8, 0x2E8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT8__DISP1_DAT8 IOMUX_PAD(0x6EC, 0x2EC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT9__DISP1_DAT9 IOMUX_PAD(0x6F0, 0x2F0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT10__DISP1_DAT10 IOMUX_PAD(0x6F4, 0x2F4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT11__DISP1_DAT11 IOMUX_PAD(0x6F8, 0x2F8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT12__DISP1_DAT12 IOMUX_PAD(0x6FC, 0x2FC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT13__DISP1_DAT13 IOMUX_PAD(0x700, 0x300, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT14__DISP1_DAT14 IOMUX_PAD(0x704, 0x304, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT15__DISP1_DAT15 IOMUX_PAD(0x708, 0x308, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT16__DISP1_DAT16 IOMUX_PAD(0x70C, 0x30C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT17__DISP1_DAT17 IOMUX_PAD(0x710, 0x310, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT18__DISP1_DAT18 IOMUX_PAD(0x714, 0x314, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT19__DISP1_DAT19 IOMUX_PAD(0x718, 0x318, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT20__DISP1_DAT20 IOMUX_PAD(0x71C, 0x31C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT21__DISP1_DAT21 IOMUX_PAD(0x720, 0x320, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT22__DISP1_DAT22 IOMUX_PAD(0x724, 0x324, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP1_DAT23__DISP1_DAT23 IOMUX_PAD(0x728, 0x328, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI1_PIN3__DI1_PIN3 IOMUX_PAD(0x72C, 0x32C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI1_PIN2__DI1_PIN2 IOMUX_PAD(0x734, 0x330, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI_GP1__DI_GP1 IOMUX_PAD(0x73C, 0x334, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI_GP2__DI_GP2 IOMUX_PAD(0x740, 0x338, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI_GP3__DI_GP3 IOMUX_PAD(0x744, 0x33C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI2_PIN4__DI2_PIN4 IOMUX_PAD(0x748, 0x340, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI2_PIN2__DI2_PIN2 IOMUX_PAD(0x74C, 0x344, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI2_PIN3__DI2_PIN3 IOMUX_PAD(0x750, 0x348, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK IOMUX_PAD(0x754, 0x34C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI_GP4__DI_GP4 IOMUX_PAD(0x758, 0x350, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 IOMUX_PAD(0x75C, 0x354, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 IOMUX_PAD(0x760, 0x358, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT2__DISP2_DAT2 IOMUX_PAD(0x764, 0x35C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT3__DISP2_DAT3 IOMUX_PAD(0x768, 0x360, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT4__DISP2_DAT4 IOMUX_PAD(0x76C, 0x364, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT5__DISP2_DAT5 IOMUX_PAD(0x770, 0x368, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT6__DISP2_DAT6 IOMUX_PAD(0x774, 0x36C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT7__DISP2_DAT7 IOMUX_PAD(0x778, 0x370, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT8__DISP2_DAT8 IOMUX_PAD(0x77C, 0x374, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT9__DISP2_DAT9 IOMUX_PAD(0x780, 0x378, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78C, 0x384, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x7B4, 0x3AC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x7B8, 0x3B0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7C0, 0x3B8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7C4, 0x3BC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7C8, 0x3C0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7CC, 0x3C4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7D0, 0x3C8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_2__GPIO1_2 IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_3__GPIO1_3 IOMUX_PAD(0x7D8, 0x3D0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_6__GPIO1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL) +#endif /* __MACH_IOMUX_MX51_H__ */ + diff --git a/arch/arm/mach-imx/include/mach/iomux-v3.h b/arch/arm/mach-imx/include/mach/iomux-v3.h index 1d660a0..198286a 100644 --- a/arch/arm/mach-imx/include/mach/iomux-v3.h +++ b/arch/arm/mach-imx/include/mach/iomux-v3.h @@ -84,13 +84,17 @@ #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 0000000..5d6670d --- /dev/null +++ b/arch/arm/mach-imx/include/mach/usb.h @@ -0,0 +1,14 @@ +#ifndef __MACH_USB_H_ +#define __MACH_USB_H_ + +/* configuration bits for i.MX25 and i.MX35 */ +#define MX35_H1_SIC_SHIFT 21 +#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) +#define MX35_H1_PM_BIT (1 << 8) +#define MX35_H1_IPPUE_UP_BIT (1 << 7) +#define MX35_H1_IPPUE_DOWN_BIT (1 << 6) +#define MX35_H1_TLL_BIT (1 << 5) +#define MX35_H1_USBTE_BIT (1 << 4) +#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0) + +#endif /* __MACH_USB_H_*/ diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c index 9605674..cb28e9f 100644 --- a/arch/arm/mach-imx/speed-imx25.c +++ b/arch/arm/mach-imx/speed-imx25.c @@ -82,7 +82,12 @@ 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 @@ 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 cdcd419..0a92d29 100644 --- a/arch/arm/mach-imx/speed-imx27.c +++ b/arch/arm/mach-imx/speed-imx27.c @@ -159,6 +159,11 @@ 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 c5a31c7..8937ef1 100644 --- a/arch/arm/mach-imx/speed-imx35.c +++ b/arch/arm/mach-imx/speed-imx35.c @@ -19,6 +19,7 @@ #include #include #include +#include #include unsigned long imx_get_mpllclk(void) @@ -27,7 +28,7 @@ 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 @@ { .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 @@ 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 @@ 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 @@ 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 @@ 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 0000000..9983297 --- /dev/null +++ b/arch/arm/mach-imx/speed-imx51.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#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 e024733..750ace0 100644 --- a/arch/arm/mach-imx/speed.c +++ b/arch/arm/mach-imx/speed.c @@ -24,6 +24,7 @@ #include #include #include +#include /* * 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 df16b7b..9c90b4f 100644 --- a/arch/arm/mach-omap/arch-omap.dox +++ b/arch/arm/mach-omap/arch-omap.dox @@ -50,7 +50,11 @@ 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 9893145..f780794 100644 --- a/arch/arm/mach-omap/omap3_generic.c +++ b/arch/arm/mach-omap/omap3_generic.c @@ -52,11 +52,11 @@ * * In case of crashes, reset the CPU * - * @param[in] addr -Cause of crash + * @param addr Cause of crash * * @return void */ -void __noreturn reset_cpu(ulong addr) +void __noreturn reset_cpu(unsigned long addr) { /* FIXME: Enable WDT and cause reset */ hang(); diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile index 1cc8a23..88d45fe 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 0000000..3d5e5e5 --- /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 +#include +#include +#include +#include + +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 0000000..37db4f5 --- /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 +#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 0000000..2c64a97 --- /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/arm/mach-s3c24xx/include/mach/mci.h b/arch/arm/mach-s3c24xx/include/mach/mci.h new file mode 100644 index 0000000..6ba8961 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/mci.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2010 Juergen Beisert, Pengutronix + * + * This code is partially based on u-boot code: + * + * Copyright 2008, Freescale Semiconductor, Inc + * Andy Fleming + * + * Based (loosely) on the Linux code + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __MACH_MMC_H_ +#define __MACH_MMC_H_ + +struct s3c_mci_platform_data { + unsigned caps; /**< supported operating modes (MMC_MODE_*) */ + unsigned voltages; /**< supported voltage range (MMC_VDD_*) */ + unsigned f_min; /**< min operating frequency in Hz (0 -> no limit) */ + unsigned f_max; /**< max operating frequency in Hz (0 -> no limit) */ + /* TODO */ + /* function to modify the voltage */ + /* function to switch the voltage */ + /* function to detect the presence of a SD card in the socket */ + unsigned gpio_detect; + unsigned detect_invert; +}; + +#endif /* __MACH_MMC_H_ */ diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig new file mode 100644 index 0000000..021919a --- /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 0000000..59d70b6 --- /dev/null +++ b/arch/arm/mach-stm/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o imx23.o iomux-imx23.o clocksource-imx23.o reset-imx23.o + diff --git a/arch/arm/mach-stm/clocksource-imx23.c b/arch/arm/mach-stm/clocksource-imx23.c new file mode 100644 index 0000000..7c0268c --- /dev/null +++ b/arch/arm/mach-stm/clocksource-imx23.c @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#define TIMROTCTRL 0x00 +#define TIMCTRL1 0x40 +#define TIMCTRL1_SET 0x44 +#define TIMCTRL1_CLR 0x48 +#define TIMCTRL1_TOG 0x4c +# define TIMCTRL_RELOAD (1 << 6) +# define TIMCTRL_UPDATE (1 << 7) +# define TIMCTRL_PRESCALE(x) ((x & 0x3) << 4) +# define TIMCTRL_SELECT(x) (x & 0xf) +#define TIMCOUNT1 0x50 + +static const unsigned long timer_base = IMX_TIM1_BASE; + +#define CLOCK_TICK_RATE (32000) + +static uint64_t imx23_clocksource_read(void) +{ + /* only the upper bits are the valid */ + return ~(readl(timer_base + TIMCOUNT1) >> 16); +} + +static struct clocksource cs = { + .read = imx23_clocksource_read, + .mask = 0x0000ffff, + .shift = 10, +}; + +static int imx23_clocksource_clock_change(struct notifier_block *nb, unsigned long event, void *data) +{ + cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE/*imx_get_xclk()*/, cs.shift); + return 0; +} + +static struct notifier_block imx23_clock_notifier = { + .notifier_call = imx23_clocksource_clock_change, +}; + +static int clocksource_init(void) +{ + /* enable the whole timer block */ + writel(0x3e000000, timer_base + TIMROTCTRL); + /* setup general purpose timer 1 */ + writel(0x00000000, timer_base + TIMCTRL1); + writel(TIMCTRL_UPDATE, timer_base + TIMCTRL1); + writel(0x0000ffff, timer_base + TIMCOUNT1); + + writel(TIMCTRL_UPDATE | TIMCTRL_RELOAD | TIMCTRL_PRESCALE(0) | TIMCTRL_SELECT(8), timer_base + TIMCTRL1); + cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE/*imx_get_xclk()*/, cs.shift); + init_clock(&cs); + + clock_register_client(&imx23_clock_notifier); + return 0; +} + +core_initcall(clocksource_init); diff --git a/arch/arm/mach-stm/imx23.c b/arch/arm/mach-stm/imx23.c new file mode 100644 index 0000000..14a4249 --- /dev/null +++ b/arch/arm/mach-stm/imx23.c @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +extern void imx_dump_clocks(void); + +static int do_clocks(struct command *cmdtp, int argc, char *argv[]) +{ + imx_dump_clocks(); + + return 0; +} + +BAREBOX_CMD_START(dump_clocks) + .cmd = do_clocks, + .usage = "show clock frequencies", +BAREBOX_CMD_END diff --git a/arch/arm/mach-stm/include/mach/clock.h b/arch/arm/mach-stm/include/mach/clock.h new file mode 100644 index 0000000..0e1a6d6 --- /dev/null +++ b/arch/arm/mach-stm/include/mach/clock.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef ASM_ARCH_CLOCK_IMX23_H +#define ASM_ARCH_CLOCK_IMX23_H + +unsigned imx_get_mpllclk(void); +unsigned imx_get_emiclk(void); +unsigned imx_get_ioclk(void); +unsigned imx_get_armclk(void); +unsigned imx_get_hclk(void); +unsigned imx_get_xclk(void); +unsigned imx_get_sspclk(unsigned); +unsigned imx_set_sspclk(unsigned, unsigned, int); +unsigned imx_set_ioclk(unsigned); + +#endif /* ASM_ARCH_CLOCK_IMX23_H */ + diff --git a/arch/arm/mach-stm/include/mach/generic.h b/arch/arm/mach-stm/include/mach/generic.h new file mode 100644 index 0000000..3a552a8 --- /dev/null +++ b/arch/arm/mach-stm/include/mach/generic.h @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifdef CONFIG_ARCH_IMX23 +# define cpu_is_mx23() (1) +#else +# define cpu_is_mx23() (0) +#endif diff --git a/arch/arm/mach-stm/include/mach/gpio.h b/arch/arm/mach-stm/include/mach/gpio.h new file mode 100644 index 0000000..fa8263c --- /dev/null +++ b/arch/arm/mach-stm/include/mach/gpio.h @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_MACH_GPIO_H +#define __ASM_MACH_GPIO_H + +#if defined CONFIG_ARCH_IMX23 +# include +#endif + +void imx_gpio_mode(unsigned); + +#endif /* __ASM_MACH_GPIO_H */ diff --git a/arch/arm/mach-stm/include/mach/imx-regs.h b/arch/arm/mach-stm/include/mach/imx-regs.h new file mode 100644 index 0000000..40dc742 --- /dev/null +++ b/arch/arm/mach-stm/include/mach/imx-regs.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _IMX_REGS_H +# define _IMX_REGS_H + +#if defined CONFIG_ARCH_IMX23 +# include +#endif + +#endif /* _IMX_REGS_H */ diff --git a/arch/arm/mach-stm/include/mach/imx23-regs.h b/arch/arm/mach-stm/include/mach/imx23-regs.h new file mode 100644 index 0000000..89ca453 --- /dev/null +++ b/arch/arm/mach-stm/include/mach/imx23-regs.h @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MX23_REGS_H +#define __ASM_ARCH_MX23_REGS_H + +/* + * sanity check + */ +#ifndef _IMX_REGS_H +# error "Please do not include directly. Use imx-regs.h instead." +#endif + +#define IMX_MEMORY_BASE 0x40000000 +#define IMX_UART1_BASE 0x8006c000 +#define IMX_UART2_BASE 0x8006e000 +#define IMX_DBGUART_BASE 0x80070000 +#define IMX_TIM1_BASE 0x80068000 +#define IMX_IOMUXC_BASE 0x80018000 +#define IMX_WDT_BASE 0x8005c000 +#define IMX_CCM_BASE 0x80040000 +#define IMX_I2C1_BASE 0x80058000 +#define IMX_SSP1_BASE 0x80010000 +#define IMX_SSP2_BASE 0x80034000 + +#endif /* __ASM_ARCH_MX23_REGS_H */ diff --git a/arch/arm/mach-stm/include/mach/iomux-imx23.h b/arch/arm/mach-stm/include/mach/iomux-imx23.h new file mode 100644 index 0000000..bebaf56 --- /dev/null +++ b/arch/arm/mach-stm/include/mach/iomux-imx23.h @@ -0,0 +1,424 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* 3322222222221111111111 + * 10987654321098765432109876543210 + * ^^^_ Register Number + * ^^^^____ Bit offset + * ^^________ Function + * ^__________ Drive strength feature present + * ^___________ Pull up / bit keeper present + * ^^____________ Drive strength setting + * ^______________ Pull up / bit keeper setting + * ^_______________ Voltage select present + * ^________________ Voltage selection + * ^____________________ direction if enabled as GPIO (1 = output) + * ^_____________________ initial output value if enabled as GPIO and configured as output + */ +#ifndef __ASM_MACH_IOMUX_H +#define __ASM_MACH_IOMUX_H + +/* control pad's function */ +#define FBIT_SHIFT (3) +#define PORTF(bank,bit) (((bit) << FBIT_SHIFT) | (bank)) +#define GET_PORTF(x) ((x) & 0x7) +#define GET_FBITPOS(x) (((x) >> FBIT_SHIFT) & 0xf) +#define GET_GPIO_NO(x) ((GET_PORTF(x) << 4) + GET_FBITPOS(m)) +#define FUNC_SHIFT 7 +#define FUNC(x) ((x) << FUNC_SHIFT) +#define GET_FUNC(x) (((x) >> FUNC_SHIFT) & 3) +#define IS_GPIO (3) + +/* control pad's GPIO feature if enabled */ +#define GPIO_OUT (1 << 19) +#define GPIO_VALUE(x) ((x) << 20) +#define GPIO_IN (0 << 19) +#define GET_GPIODIR(x) (!!((x) & (1 << 19))) +#define GET_GPIOVAL(x) (!!((x) & (1 << 20))) + +/* control pad's drive strength */ +#define SE (1 << 9) +#define SE_PRESENT(x) (!!((x) & SE)) +#define STRENGTH(x) ((x) << 11) +#define S4MA 0 /* used to define a 4 mA drive strength */ +#define S8MA 1 /* used to define a 8 mA drive strength */ +#define S12MA 2 /* used to define a 12 mA drive strength */ +#define S16MA 3 /* used to define a 16 mA drive strength, not all pads can drive this current! */ +#define GET_STRENGTH(x) (((x) >> 11) & 0x3) + +/* control pad's pull up / bit keeper feature */ +#define PE (1 << 10) +#define PE_PRESENT(x) (!!((x) & PE)) +#define PULLUP(x) ((x) << 13) +#define GET_PULLUP(x) (!!((x) & (1 << 13))) + +/* control pad's voltage feature */ +#define VE (1 << 14) +#define VE_PRESENT(x) (!!((x) & VE)) +#define VE_1_8V (0 << 15) +#define VE_2_5V (0 << 15) /* don't ask my why, RTFM */ +#define GET_VOLTAGE(x) (!!((x) & (1 << 15))) + +/* Bank 0, pins 0 ... 15, GPIO pins 0 ... 15 */ +#define GPMI_D15 (FUNC(0) | PORTF(0, 15) | SE | PE) +#define GPMI_D15_AUART2_TX (FUNC(1) | PORTF(0, 15) | SE | PE) +#define GPMI_D15_GPMI_CE3N (FUNC(2) | PORTF(0, 15) | SE | PE) +#define GPMI_D15_GPIO (FUNC(3) | PORTF(0, 15) | SE | PE) +#define GPMI_D14 (FUNC(0) | PORTF(0, 14) | SE) +#define GPMI_D14_AUART2_RX (FUNC(1) | PORTF(0, 14) | SE) +#define GPMI_D14_GPIO (FUNC(3) | PORTF(0, 14) | SE) +#define GPMI_D13 (FUNC(0) | PORTF(0, 13) | SE) +#define GPMI_D13_LCD_D23 (FUNC(1) | PORTF(0, 13) | SE) +#define GPMI_D13_GPIO (FUNC(3) | PORTF(0, 13) | SE) +#define GPMI_D12 (FUNC(0) | PORTF(0, 12) | SE) +#define GPMI_D12_LCD_D22 (FUNC(1) | PORTF(0, 12) | SE) +#define GPMI_D12_GPIO (FUNC(3) | PORTF(0, 12) | SE) +#define GPMI_D11 (FUNC(0) | PORTF(0, 11) | SE | PE) +#define GPMI_D11_LCD_D21 (FUNC(1) | PORTF(0, 11) | SE | PE) +#define GPMI_D11_SSP1_D7 (FUNC(2) | PORTF(0, 11) | SE | PE) +#define GPMI_D11_GPIO (FUNC(3) | PORTF(0, 11) | SE | PE) +#define GPMI_D10 (FUNC(0) | PORTF(0, 10) | SE | PE) +#define GPMI_D10_LCD_D20 (FUNC(1) | PORTF(0, 10) | SE | PE) +#define GPMI_D10_SSP1_D6 (FUNC(2) | PORTF(0, 10) | SE | PE) +#define GPMI_D10_GPIO (FUNC(3) | PORTF(0, 10) | SE | PE) +#define GPMI_D09 (FUNC(0) | PORTF(0, 9) | SE | PE) +#define GPMI_D09_LCD_D19 (FUNC(1) | PORTF(0, 9) | SE | PE) +#define GPMI_D09_SSP1_D5 (FUNC(2) | PORTF(0, 9) | SE | PE) +#define GPMI_D09_GPIO (FUNC(3) | PORTF(0, 9) | SE | PE) +#define GPMI_D08 (FUNC(0) | PORTF(0, 8) | SE | PE) +#define GPMI_D08_LCD_D18 (FUNC(1) | PORTF(0, 8) | SE | PE) +#define GPMI_D08_SSP1_D4 (FUNC(2) | PORTF(0, 8) | SE | PE) +#define GPMI_D08_GPIO (FUNC(3) | PORTF(0, 8) | SE | PE) +#define GPMI_D07 (FUNC(0) | PORTF(0, 7) | SE | PE) +#define GPMI_D07_LCD_D15 (FUNC(1) | PORTF(0, 7) | SE | PE) +#define GPMI_D07_SSP2_D7 (FUNC(2) | PORTF(0, 7) | SE | PE) +#define GPMI_D07_GPIO (FUNC(3) | PORTF(0, 7) | SE | PE) +#define GPMI_D06 (FUNC(0) | PORTF(0, 6) | SE | PE) +#define GPMI_D06_LCD_D14 (FUNC(1) | PORTF(0, 6) | SE | PE) +#define GPMI_D06_SSP2_D6 (FUNC(2) | PORTF(0, 6) | SE | PE) +#define GPMI_D06_GPIO (FUNC(3) | PORTF(0, 6) | SE | PE) +#define GPMI_D05 (FUNC(0) | PORTF(0, 5) | SE | PE) +#define GPMI_D05_LCD_D13 (FUNC(1) | PORTF(0, 5) | SE | PE) +#define GPMI_D05_SSP2_D5 (FUNC(2) | PORTF(0, 5) | SE | PE) +#define GPMI_D05_GPIO (FUNC(3) | PORTF(0, 5) | SE | PE) +#define GPMI_D04 (FUNC(0) | PORTF(0, 4) | SE | PE) +#define GPMI_D04_LCD_D12 (FUNC(1) | PORTF(0, 4) | SE | PE) +#define GPMI_D04_SSP2_D4 (FUNC(2) | PORTF(0, 4) | SE | PE) +#define GPMI_D04_GPIO (FUNC(3) | PORTF(0, 4) | SE | PE) +#define GPMI_D03 (FUNC(0) | PORTF(0, 3) | SE | PE) +#define GPMI_D03_LCD_D11 (FUNC(1) | PORTF(0, 3) | SE | PE) +#define GPMI_D03_SSP2_D3 (FUNC(2) | PORTF(0, 3) | SE | PE) +#define GPMI_D03_GPIO (FUNC(3) | PORTF(0, 3) | SE | PE) +#define GPMI_D02 (FUNC(0) | PORTF(0, 2) | SE | PE) +#define GPMI_D02_LCD_D10 (FUNC(1) | PORTF(0, 2) | SE | PE) +#define GPMI_D02_SSP2_D2 (FUNC(2) | PORTF(0, 2) | SE | PE) +#define GPMI_D02_GPIO (FUNC(3) | PORTF(0, 2) | SE | PE) +#define GPMI_D01 (FUNC(0) | PORTF(0, 1) | SE | PE) +#define GPMI_D01_LCD_D9 (FUNC(1) | PORTF(0, 1) | SE | PE) +#define GPMI_D01_SSP2_D1 (FUNC(2) | PORTF(0, 1) | SE | PE) +#define GPMI_D01_GPIO (FUNC(3) | PORTF(0, 1) | SE | PE) +#define GPMI_D00 (FUNC(0) | PORTF(0, 0) | SE | PE) +#define GPMI_D00_LCD_D8 (FUNC(1) | PORTF(0, 0) | SE | PE) +#define GPMI_D00_SSP2_D0 (FUNC(2) | PORTF(0, 0) | SE | PE) +#define GPMI_D00_GPIO (FUNC(3) | PORTF(0, 0) | SE | PE) + +/* Bank 0, pins 16 ... 31 GPIO pins 16 ... 31 */ +#define I2C_SDA (FUNC(0) | PORTF(1, 15) | SE) +#define I2C_SDA_GPMI_CE2N (FUNC(1) | PORTF(1, 15) | SE) +#define I2C_SDA_AUART1_RX (FUNC(2) | PORTF(1, 15) | SE) +#define I2C_SDA_GPIO (FUNC(3) | PORTF(1, 15) | SE) +#define I2C_CLK (FUNC(0) | PORTF(1, 14) | SE | PE) +#define I2C_CLK_GPMI_RDY2 (FUNC(1) | PORTF(1, 14) | SE | PE) +#define I2C_CLK_AUART1_TX (FUNC(2) | PORTF(1, 14) | SE | PE) +#define I2C_CLK_GPIO (FUNC(3) | PORTF(1, 14) | SE | PE) +#define AUART1_TX (FUNC(0) | PORTF(1, 13) | SE | PE) +#define AUART1_TX_SSP1_D7 (FUNC(2) | PORTF(1, 13) | SE | PE) +#define AUART1_TX_GPIO (FUNC(3) | PORTF(1, 13) | SE | PE) +#define AUART1_RX (FUNC(0) | PORTF(1, 12) | SE | PE) +#define AUART1_RX_SSP1_D6 (FUNC(2) | PORTF(1, 12) | SE | PE) +#define AUART1_RX_GPIO (FUNC(3) | PORTF(1, 12) | SE | PE) +#define AUART1_RTS (FUNC(0) | PORTF(1, 11) | SE | PE) +#define AUART1_RTS_SSP1_D5 (FUNC(2) | PORTF(1, 11) | SE | PE) +#define AUART1_RTS_GPIO (FUNC(3) | PORTF(1, 11) | SE | PE) +#define AUART1_CTS (FUNC(0) | PORTF(1, 10) | SE | PE) +#define AUART1_CTS_SSP1_D4 (FUNC(2) | PORTF(1, 10) | SE | PE) +#define AUART1_CTS_GPIO (FUNC(3) | PORTF(1, 10) | SE | PE) +#define GPMI_RDN (FUNC(0) | PORTF(1, 9) | SE) +#define GPMI_RDN_GPIO (FUNC(3) | PORTF(1, 9) | SE) +#define GPMI_WRN (FUNC(0) | PORTF(1, 8) | SE) +#define GPMI_WRN_SSP2_SCK (FUNC(2) | PORTF(1, 8) | SE) +#define GPMI_WRN_GPIO (FUNC(3) | PORTF(1, 8) | SE) +#define GPMI_WPM (FUNC(0) | PORTF(1, 7) | SE) +#define GPMI_WPM_GPIO (FUNC(3) | PORTF(1, 7) | SE) +#define GPMI_RDY3 (FUNC(0) | PORTF(1, 6) | SE | PE) +#define GPMI_RDY3_GPIO (FUNC(3) | PORTF(1, 6) | SE | PE) +#define GPMI_RDY2 (FUNC(0) | PORTF(1, 5) | SE | PE) +#define GPMI_RDY2_GPIO (FUNC(3) | PORTF(1, 5) | SE | PE) +#define GPMI_RDY1 (FUNC(0) | PORTF(1, 4) | SE | PE) +#define GPMI_RDY1_SSP2_CMD (FUNC(2) | PORTF(1, 4) | SE | PE) +#define GPMI_RDY1_GPIO (FUNC(3) | PORTF(1, 4) | SE | PE) +#define GPMI_RDY0 (FUNC(0) | PORTF(1, 3) | SE | PE) +#define GPMI_RDY0_SSP2_DETECT (FUNC(2) | PORTF(1, 3) | SE | PE) +#define GPMI_RDY0_GPIO (FUNC(3) | PORTF(1, 3) | SE | PE) +#define GPMI_CE2N (FUNC(0) | PORTF(1, 2) | SE | PE) +#define GPMI_CE2N_GPIO (FUNC(3) | PORTF(1, 2) | SE | PE) +#define GPMI_ALE (FUNC(0) | PORTF(1, 1) | SE) +#define GPMI_ALE_LCD_D17 (FUNC(1) | PORTF(1, 1) | SE) +#define GPMI_ALE_GPIO (FUNC(3) | PORTF(1, 1) | SE) +#define GPMI_CLE (FUNC(0) | PORTF(1, 0) | SE) +#define GPMI_CLE_LCD_D16 (FUNC(1) | PORTF(1, 1) | SE) +#define GPMI_CLE_GPIO (FUNC(3) | PORTF(1, 0) | SE) + +/* Bank 1, pins 0 ... 15 GPIO pins 32 ... 47 */ +#define LCD_D15 (FUNC(0) | PORTF(2, 15) | SE) +#define LCD_D15_ETM_DA7 (FUNC(1) | PORTF(2, 15) | SE) +#define LCD_D15_SAIF1_SDATA1 (FUNC(2) | PORTF(2, 15) | SE) +#define LCD_D15_GPIO (FUNC(3) | PORTF(2, 15) | SE) +#define LCD_D14 (FUNC(0) | PORTF(2, 14) | SE) +#define LCD_D14_ETM_DA6 (FUNC(1) | PORTF(2, 14) | SE) +#define LCD_D14_SAIF1_SDATA2 (FUNC(2) | PORTF(2, 14) | SE) +#define LCD_D14_GPIO (FUNC(3) | PORTF(2, 14) | SE) +#define LCD_D13 (FUNC(0) | PORTF(2, 13) | SE) +#define LCD_D13_ETM_DA5 (FUNC(1) | PORTF(2, 13) | SE) +#define LCD_D13_SAIF2_SDATA2 (FUNC(2) | PORTF(2, 13) | SE) +#define LCD_D13_GPIO (FUNC(3) | PORTF(2, 13) | SE) +#define LCD_D12 (FUNC(0) | PORTF(2, 12) | SE) +#define LCD_D12_ETM_DA4 (FUNC(1) | PORTF(2, 12) | SE) +#define LCD_D12_SAIF2_SDATA1 (FUNC(2) | PORTF(2, 12) | SE) +#define LCD_D12_GPIO (FUNC(3) | PORTF(2, 12) | SE) +#define LCD_D11 (FUNC(0) | PORTF(2, 11) | SE) +#define LCD_D11_ETM_DA3 (FUNC(1) | PORTF(2, 11) | SE) +#define LCD_D11_SAIF_LRCLK (FUNC(2) | PORTF(2, 11) | SE) +#define LCD_D11_GPIO (FUNC(3) | PORTF(2, 11) | SE) +#define LCD_D10 (FUNC(0) | PORTF(2, 10) | SE) +#define LCD_D10_ETM_DA2 (FUNC(1) | PORTF(2, 10) | SE) +#define LCD_D10_SAIF_BITCLK (FUNC(2) | PORTF(2, 10) | SE) +#define LCD_D10_GPIO (FUNC(3) | PORTF(2, 10) | SE) +#define LCD_D9 (FUNC(0) | PORTF(2, 9) | SE) +#define LCD_D9_ETM_DA1 (FUNC(1) | PORTF(2, 9) | SE) +#define LCD_D9_SAIF1_SDATA0 (FUNC(2) | PORTF(2, 9) | SE) +#define LCD_D9_GPIO (FUNC(3) | PORTF(2, 9) | SE) +#define LCD_D8 (FUNC(0) | PORTF(2, 8) | SE) +#define LCD_D8_ETM_DA0 (FUNC(1) | PORTF(2, 8) | SE) +#define LCD_D8_SAIF2_SDATA0 (FUNC(2) | PORTF(2, 8) | SE) +#define LCD_D8_GPIO (FUNC(3) | PORTF(2, 8) | SE) +#define LCD_D7 (FUNC(0) | PORTF(2, 7) | SE) +#define LCD_D7_ETM_DA15 (FUNC(1) | PORTF(2, 7) | SE) +#define LCD_D7_GPIO (FUNC(3) | PORTF(2, 7) | SE) +#define LCD_D6 (FUNC(0) | PORTF(2, 6) | SE) +#define LCD_D6_ETM_DA14 (FUNC(1) | PORTF(2, 6) | SE) +#define LCD_D6_GPIO (FUNC(3) | PORTF(2, 6) | SE) +#define LCD_D5 (FUNC(0) | PORTF(2, 5) | SE) +#define LCD_D5_ETM_DA13 (FUNC(1) | PORTF(2, 5) | SE) +#define LCD_D5_GPIO (FUNC(3) | PORTF(2, 5) | SE) +#define LCD_D4 (FUNC(0) | PORTF(2, 4) | SE) +#define LCD_D4_ETM_DA12 (FUNC(1) | PORTF(2, 4) | SE) +#define LCD_D4_GPIO (FUNC(3) | PORTF(2, 4) | SE) +#define LCD_D3 (FUNC(0) | PORTF(2, 3) | SE) +#define LCD_D3_ETM_DA11 (FUNC(1) | PORTF(2, 3) | SE) +#define LCD_D3_GPIO (FUNC(3) | PORTF(2, 3) | SE) +#define LCD_D2 (FUNC(0) | PORTF(2, 2) | SE) +#define LCD_D2_ETM_DA10 (FUNC(1) | PORTF(2, 2) | SE) +#define LCD_D2_GPIO (FUNC(3) | PORTF(2, 2) | SE) +#define LCD_D1 (FUNC(0) | PORTF(2, 1) | SE) +#define LCD_D1_ETM_DA9 (FUNC(1) | PORTF(2, 1) | SE) +#define LCD_D1_GPIO (FUNC(3) | PORTF(2, 1) | SE) +#define LCD_D0 (FUNC(0) | PORTF(2, 0) | SE) +#define LCD_D0_ETM_DA8 (FUNC(1) | PORTF(2, 0) | SE) +#define LCD_D0_GPIO (FUNC(3) | PORTF(2, 0) | SE) + +/* Bank 1, pins 16 ... 30 GPIO pins 48 ... 63 */ +#define PWM4 (FUNC(0) | PORTF(3, 14) | SE) +#define PWM4_ETM_CLK (FUNC(1) | PORTF(3, 14) | SE) +#define PWM4_AUART1_RTS (FUNC(2) | PORTF(3, 14) | SE) +#define PWM4_GPIO (FUNC(3) | PORTF(3, 14) | SE) +#define PWM3 (FUNC(0) | PORTF(3, 13) | SE) +#define PWM3_ETM_TCTL (FUNC(1) | PORTF(3, 13) | SE) +#define PWM3_AUART1_CTS (FUNC(2) | PORTF(3, 13) | SE) +#define PWM3_GPIO (FUNC(3) | PORTF(3, 13) | SE) +#define PWM2 (FUNC(0) | PORTF(3, 12) | SE | PE) +#define PWM2_GPMI_READY3 (FUNC(1) | PORTF(3, 12) | SE | PE) +#define PWM2_GPIO (FUNC(3) | PORTF(3, 12) | SE | PE) +#define PWM1 (FUNC(0) | PORTF(3, 11) | SE) +#define PWM1_TIMROT2 (FUNC(1) | PORTF(3, 11) | SE) +#define PWM1_DUART_TX (FUNC(2) | PORTF(3, 11) | SE) +#define PWM1_GPIO (FUNC(3) | PORTF(3, 11) | SE) +#define PWM0 (FUNC(0) | PORTF(3, 10) | SE) +#define PWM0_TIMROT1 (FUNC(1) | PORTF(3, 10) | SE) +#define PWM0_DUART_RX (FUNC(2) | PORTF(3, 10) | SE) +#define PWM0_GPIO (FUNC(3) | PORTF(3, 10) | SE) +#define LCD_VSYNC (FUNC(0) | PORTF(3, 9) | SE) +#define LCD_VSYNC_LCD_BUSY (FUNC(1) | PORTF(3, 9) | SE) +#define LCD_VSYNC_GPIO (FUNC(3) | PORTF(3, 9) | SE) +#define LCD_HSYNC (FUNC(0) | PORTF(3, 8) | SE) +#define LCD_HSYNC_I2C_SD (FUNC(1) | PORTF(3, 8) | SE) +#define LCD_HSYNC_GPIO (FUNC(3) | PORTF(3, 8) | SE) +#define LCD_ENABE (FUNC(0) | PORTF(3, 7) | SE) +#define LCD_ENABE_I2C_CLK (FUNC(1) | PORTF(3, 7) | SE) +#define LCD_ENABE_GPIO (FUNC(3) | PORTF(3, 7) | SE) +#define LCD_DOTCLOCK (FUNC(0) | PORTF(3, 6) | SE | PE) +#define LCD_DOTCLOCK_GPMI_READY3 (FUNC(1) | PORTF(3, 6) | SE | PE) +#define LCD_DOTCLOCK_GPIO (FUNC(3) | PORTF(3, 6) | SE | PE) +#define LCD_CS (FUNC(0) | PORTF(3, 5) | SE) +#define LCD_CS_GPIO (FUNC(3) | PORTF(3, 5) | SE) +#define LCD_WR (FUNC(0) | PORTF(3, 4) | SE) +#define LCD_WR_GPIO (FUNC(3) | PORTF(3, 4) | SE) +#define LCD_RS (FUNC(0) | PORTF(3, 3) | SE) +#define LCD_RS_ETM_TCLK (FUNC(1) | PORTF(3, 3) | SE) +#define LCD_RS_GPIO (FUNC(3) | PORTF(3, 3) | SE) +#define LCD_RESET (FUNC(0) | PORTF(3, 2) | SE | PE) +#define LCD_RESET_ETM_TCTL (FUNC(1) | PORTF(3, 2) | SE | PE) +#define LCD_RESET_GPMI_CE3N (FUNC(2) | PORTF(3, 2) | SE | PE) +#define LCD_RESET_GPIO (FUNC(3) | PORTF(3, 2) | SE | PE) +#define LCD_D17 (FUNC(0) | PORTF(3, 1) | SE) +#define LCD_D17_GPIO (FUNC(3) | PORTF(3, 1) | SE) +#define LCD_D16 (FUNC(0) | PORTF(3, 0) | SE) +#define LCD_D16_SAIF_ALT_BITCLK (FUNC(2) | PORTF(3, 0) | SE) +#define LCD_D16_GPIO (FUNC(3) | PORTF(3, 0) | SE) + +/* Bank 2, pins 0 ... 15 GPIO pins 64 ... 79 */ +#define EMI_A6 (FUNC(0) | PORTF(4, 15) | SE | VE) +#define EMI_A6_GPIO (FUNC(3) | PORTF(4, 15) | SE | VE) +#define EMI_A5 (FUNC(0) | PORTF(4, 14) | SE | VE) +#define EMI_A5_GPIO (FUNC(3) | PORTF(4, 14) | SE | VE) +#define EMI_A4 (FUNC(0) | PORTF(4, 13) | SE | VE) +#define EMI_A4_GPIO (FUNC(3) | PORTF(4, 13) | SE | VE) +#define EMI_A3 (FUNC(0) | PORTF(4, 12) | SE | VE) +#define EMI_A3_GPIO (FUNC(3) | PORTF(4, 12) | SE | VE) +#define EMI_A2 (FUNC(0) | PORTF(4, 11) | SE | VE) +#define EMI_A2_GPIO (FUNC(3) | PORTF(4, 11) | SE | VE) +#define EMI_A1 (FUNC(0) | PORTF(4, 10) | SE | VE) +#define EMI_A1_GPIO (FUNC(3) | PORTF(4, 10) | SE | VE) +#define EMI_A0 (FUNC(0) | PORTF(4, 9) | SE | VE) +#define EMI_A0_GPIO (FUNC(3) | PORTF(4, 9) | SE | VE) +#define ROTARYB (FUNC(0) | PORTF(4, 8) | SE | PE) +#define ROTARYB_AUART2_CTS (FUNC(1) | PORTF(4, 8) | SE | PE) +#define ROTARYB_GPMI_CE3N (FUNC(2) | PORTF(4, 8) | SE | PE) +#define ROTARYB_GPIO (FUNC(3) | PORTF(4, 8) | SE | PE) +#define ROTARYA (FUNC(0) | PORTF(4, 7) | SE) +#define ROTARYA_AUART2_RTS (FUNC(1) | PORTF(4, 7) | SE) +#define ROTARYA_SPDIF (FUNC(2) | PORTF(4, 7) | SE) +#define ROTARYA_GPIO (FUNC(3) | PORTF(4, 7) | SE) +#define SSP1_SCK (FUNC(0) | PORTF(4, 6) | SE) +#define SSP1_SCK_ALT_JTAG_TRST (FUNC(2) | PORTF(4, 6) | SE) +#define SSP1_SCK_GPIO (FUNC(3) | PORTF(4, 6) | SE) +#define SSP1_DATA3 (FUNC(0) | PORTF(4, 5) | SE | PE) +#define SSP1_DATA3_ALT_JTAG_TMS (FUNC(2) | PORTF(4, 5) | SE | PE) +#define SSP1_DATA3_GPIO (FUNC(3) | PORTF(4, 5) | SE | PE) +#define SSP1_DATA2 (FUNC(0) | PORTF(4, 4) | SE | PE) +#define SSP1_DATA2_I2C_SD (FUNC(1) | PORTF(4, 4) | SE | PE) +#define SSP1_DATA2_ALT_JTAG_RTCK (FUNC(2) | PORTF(4, 4) | SE | PE) +#define SSP1_DATA2_GPIO (FUNC(3) | PORTF(4, 4) | SE | PE) +#define SSP1_DATA1 (FUNC(0) | PORTF(4, 3) | SE | PE) +#define SSP1_DATA1_I2C_CLK (FUNC(1) | PORTF(4, 3) | SE | PE) +#define SSP1_DATA1_ALT_JTAG_TCK (FUNC(2) | PORTF(4, 3) | SE | PE) +#define SSP1_DATA1_GPIO (FUNC(3) | PORTF(4, 3) | SE | PE) +#define SSP1_DATA0 (FUNC(0) | PORTF(4, 2) | SE | PE) +#define SSP1_DATA0_ALT_JTAG_TDI (FUNC(2) | PORTF(4, 2) | SE | PE) +#define SSP1_DATA0_GPIO (FUNC(3) | PORTF(4, 2) | SE | PE) +#define SSP1_DETECT (FUNC(0) | PORTF(4, 1) | SE | PE) +#define SSP1_DETECT_GPMI_CE3N (FUNC(1) | PORTF(4, 1) | SE | PE) +#define SSP1_DETECT_USB_ID (FUNC(2) | PORTF(4, 1) | SE | PE) +#define SSP1_DETECT_GPIO (FUNC(3) | PORTF(4, 1) | SE | PE) +#define SSP1_CMD (FUNC(0) | PORTF(4, 0) | SE | PE) +#define SSP1_CMD_JTAG_TDO (FUNC(2) | PORTF(4, 0) | SE | PE) +#define SSP1_CMD_GPIO (FUNC(3) | PORTF(4, 0) | SE | PE) + +/* Bank 2, pins 16 ... 31 GPIO pins 80 ... 95 */ +#define EMI_WEN (FUNC(0) | PORTF(5, 15) | SE | VE) +#define EMI_WEN_GPIO (FUNC(3) | PORTF(5, 15) | SE | VE) +#define EMI_RASN (FUNC(0) | PORTF(5, 14) | SE | VE) +#define EMI_RASN_GPIO (FUNC(3) | PORTF(5, 14) | SE | VE) +#define EMI_CKE (FUNC(0) | PORTF(5, 13) | SE | VE) +#define EMI_CKE_GPIO (FUNC(3) | PORTF(5, 13) | SE | VE) +#define GPMI_CE0N (FUNC(0) | PORTF(5, 12) | SE) +#define GPMI_CE0N_GPIO (FUNC(3) | PORTF(5, 12) | SE) +#define GPMI_CE1N (FUNC(0) | PORTF(5, 11) | SE | PE) +#define GPMI_CE1N_GPIO (FUNC(3) | PORTF(5, 11) | SE | PE) +#define EMI_CE1N (FUNC(0) | PORTF(5, 10) | SE | VE | PE) +#define EMI_CE1N_GPIO (FUNC(3) | PORTF(5, 10) | SE | VE | PE) +#define EMI_CE0N (FUNC(0) | PORTF(5, 9) | SE | VE) +#define EMI_CE0N_GPIO (FUNC(3) | PORTF(5, 9) | SE | VE) +#define EMI_CASN (FUNC(0) | PORTF(5, 8) | SE | VE) +#define EMI_CASN_GPIO (FUNC(3) | PORTF(5, 8) | SE | VE) +#define EMI_BA1 (FUNC(0) | PORTF(5, 7) | SE | VE) +#define EMI_BA1_GPIO (FUNC(3) | PORTF(5, 7) | SE | VE) +#define EMI_BA0 (FUNC(0) | PORTF(5, 6) | SE | VE) +#define EMI_BA0_GPIO (FUNC(3) | PORTF(5, 6) | SE | VE) +#define EMI_A12 (FUNC(0) | PORTF(5, 5) | SE | VE) +#define EMI_A12_GPIO (FUNC(3) | PORTF(5, 5) | SE | VE) +#define EMI_A11 (FUNC(0) | PORTF(5, 4) | SE | VE) +#define EMI_A11_GPIO (FUNC(3) | PORTF(5, 4) | SE | VE) +#define EMI_A10 (FUNC(0) | PORTF(5, 3) | SE | VE) +#define EMI_A10_GPIO (FUNC(3) | PORTF(5, 3) | SE | VE) +#define EMI_A9 (FUNC(0) | PORTF(5, 2) | SE | VE) +#define EMI_A9_GPIO (FUNC(3) | PORTF(5, 2) | SE | VE) +#define EMI_A8 (FUNC(0) | PORTF(5, 1) | SE | VE) +#define EMI_A8_GPIO (FUNC(3) | PORTF(5, 1) | SE | VE) +#define EMI_A7 (FUNC(0) | PORTF(5, 0) | SE | VE) +#define EMI_A7_GPIO (FUNC(3) | PORTF(5, 0) | SE | VE) + +/* Bank 3, pins 0 ... 15 GPIO pins 96 ... 111 */ +#define EMI_D15 (FUNC(0) | PORTF(6, 15) | SE | VE | PE) +#define EMI_D15_DISABLED (FUNC(3) | PORTF(6, 15) | SE | VE | PE) +#define EMI_D14 (FUNC(0) | PORTF(6, 14) | SE | VE | PE) +#define EMI_D14_DISABLED (FUNC(3) | PORTF(6, 14) | SE | VE | PE) +#define EMI_D13 (FUNC(0) | PORTF(6, 13) | SE | VE | PE) +#define EMI_D13_DISABLED (FUNC(3) | PORTF(6, 13) | SE | VE | PE) +#define EMI_D12 (FUNC(0) | PORTF(6, 12) | SE | VE | PE) +#define EMI_D12_DISABLED (FUNC(3) | PORTF(6, 12) | SE | VE | PE) +#define EMI_D11 (FUNC(0) | PORTF(6, 11) | SE | VE | PE) +#define EMI_D11_DISABLED (FUNC(3) | PORTF(6, 11) | SE | VE | PE) +#define EMI_D10 (FUNC(0) | PORTF(6, 10) | SE | VE | PE) +#define EMI_D10_DISABLED (FUNC(3) | PORTF(6, 10) | SE | VE | PE) +#define EMI_D9 (FUNC(0) | PORTF(6, 9) | SE | VE | PE) +#define EMI_D9_DISABLED (FUNC(3) | PORTF(6, 9) | SE | VE | PE) +#define EMI_D8 (FUNC(0) | PORTF(6, 8) | SE | VE | PE) +#define EMI_D8_DISABLED (FUNC(3) | PORTF(6, 8) | SE | VE | PE) +#define EMI_D7 (FUNC(0) | PORTF(6, 7) | SE | VE | PE) +#define EMI_D7_DISABLED (FUNC(3) | PORTF(6, 7) | SE | VE | PE) +#define EMI_D6 (FUNC(0) | PORTF(6, 6) | SE | VE | PE) +#define EMI_D6_DISABLED (FUNC(3) | PORTF(6, 6) | SE | VE | PE) +#define EMI_D5 (FUNC(0) | PORTF(6, 5) | SE | VE | PE) +#define EMI_D5_DISABLED (FUNC(3) | PORTF(6, 5) | SE | VE | PE) +#define EMI_D4 (FUNC(0) | PORTF(6, 4) | SE | VE | PE) +#define EMI_D4_DISABLED (FUNC(3) | PORTF(6, 4) | SE | VE | PE) +#define EMI_D3 (FUNC(0) | PORTF(6, 3) | SE | VE | PE) +#define EMI_D3_DISABLED (FUNC(3) | PORTF(6, 3) | SE | VE | PE) +#define EMI_D2 (FUNC(0) | PORTF(6, 2) | SE | VE | PE) +#define EMI_D2_DISABLED (FUNC(3) | PORTF(6, 2) | SE | VE | PE) +#define EMI_D1 (FUNC(0) | PORTF(6, 1) | SE | VE | PE) +#define EMI_D1_DISABLED (FUNC(3) | PORTF(6, 1) | SE | VE | PE) +#define EMI_D0 (FUNC(0) | PORTF(6, 0) | SE | VE | PE) +#define EMI_D0_DISABLED (FUNC(3) | PORTF(6, 0) | SE | VE | PE) + +/* Bank 3, pins 16 ... 21 GPIO pins 112 ... 117 */ +#define EMI_CLKN (FUNC(0) | PORTF(7, 5) | SE | VE) +#define EMI_CLKN_DISABLED (FUNC(3) | PORTF(7, 5) | SE | VE) +#define EMI_CLK (FUNC(0) | PORTF(7, 4) | SE | VE) +#define EMI_CLK_DISABLED (FUNC(3) | PORTF(7, 4) | SE | VE) +#define EMI_DQS1 (FUNC(0) | PORTF(7, 3) | SE | VE) +#define EMI_DQS1_DISABLED (FUNC(3) | PORTF(7, 3) | SE | VE) +#define EMI_DQS0 (FUNC(0) | PORTF(7, 2) | SE | VE) +#define EMI_DQS0_DISABLED (FUNC(3) | PORTF(7, 2) | SE | VE) +#define EMI_DQM1 (FUNC(0) | PORTF(7, 1) | SE | VE | PE) +#define EMI_DQM1_DISABLED (FUNC(3) | PORTF(7, 1) | SE | VE | PE) +#define EMI_DQM0 (FUNC(0) | PORTF(7, 0) | SE | VE | PE) +#define EMI_DQM0_DISABLED (FUNC(3) | PORTF(7, 0) | SE | VE | PE) + +#endif /* __ASM_MACH_IOMUX_H */ diff --git a/arch/arm/mach-stm/include/mach/mci.h b/arch/arm/mach-stm/include/mach/mci.h new file mode 100644 index 0000000..b924908 --- /dev/null +++ b/arch/arm/mach-stm/include/mach/mci.h @@ -0,0 +1,32 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __MACH_MMC_H +#define __MACH_MMC_H + +struct stm_mci_platform_data { + unsigned caps; /**< supported operating modes (MMC_MODE_*) */ + unsigned voltages; /**< supported voltage range (MMC_VDD_*) */ + unsigned f_min; /**< min operating frequency in Hz (0 -> no limit) */ + unsigned f_max; /**< max operating frequency in Hz (0 -> no limit) */ + /* TODO */ + /* function to modify the voltage */ + /* function to switch the voltage */ + /* function to detect the presence of a SD card in the socket */ +}; + +#endif /* __MACH_MMC_H */ diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx23.c new file mode 100644 index 0000000..b0f4046 --- /dev/null +++ b/arch/arm/mach-stm/iomux-imx23.c @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#define HW_PINCTRL_CTRL 0x000 +#define HW_PINCTRL_MUXSEL0 0x100 +#define HW_PINCTRL_DRIVE0 0x200 +#define HW_PINCTRL_PULL0 0x400 +#define HW_PINCTRL_DOUT0 0x500 +#define HW_PINCTRL_DIN0 0x600 +#define HW_PINCTRL_DOE0 0x700 + +static uint32_t calc_mux_reg(uint32_t no) +{ + /* each register controls 16 pads */ + return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0; +} + +static uint32_t calc_strength_reg(uint32_t no) +{ + /* each register controls 8 pads */ + return ((no >> 3) << 4) + HW_PINCTRL_DRIVE0; +} + +static uint32_t calc_pullup_reg(uint32_t no) +{ + /* each register controls 32 pads */ + return ((no >> 5) << 4) + HW_PINCTRL_PULL0; +} + +static uint32_t calc_output_enable_reg(uint32_t no) +{ + /* each register controls 32 pads */ + return ((no >> 5) << 4) + HW_PINCTRL_DOE0; +} + +static uint32_t calc_output_reg(uint32_t no) +{ + /* each register controls 32 pads */ + return ((no >> 5) << 4) + HW_PINCTRL_DOUT0; +} + +/** + * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin + */ +void imx_gpio_mode(unsigned m) +{ + uint32_t reg_offset, gpio_pin, reg; + + gpio_pin = GET_GPIO_NO(m); + + /* configure the pad to its function (always) */ + reg_offset = calc_mux_reg(gpio_pin); + reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 16) << 1)); + reg |= GET_FUNC(m) << ((gpio_pin % 16) << 1); + writel(reg, IMX_IOMUXC_BASE + reg_offset); + + /* some pins are disabled when configured for GPIO */ + if ((gpio_pin > 95) && (GET_FUNC(m) == IS_GPIO)) { + printf("Cannot configure pad %d to GPIO\n", gpio_pin); + return; + } + + if (SE_PRESENT(m)) { + reg_offset = calc_strength_reg(gpio_pin); + reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 8) << 2)); + reg |= GET_STRENGTH(m) << ((gpio_pin % 8) << 2); + writel(reg, IMX_IOMUXC_BASE + reg_offset); + } + + if (VE_PRESENT(m)) { + reg_offset = calc_strength_reg(gpio_pin); + if (GET_VOLTAGE(m) == 1) + writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 4); + else + writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 8); + } + + if (PE_PRESENT(m)) { + reg_offset = calc_pullup_reg(gpio_pin); + writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8)); + } + + if (GET_FUNC(m) == IS_GPIO) { + if (GET_GPIODIR(m) == 1) { + /* first set the output value */ + reg_offset = calc_output_reg(gpio_pin); + writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8)); + /* then the direction */ + reg_offset = calc_output_enable_reg(gpio_pin); + writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 4); + } else { + writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 8); + } + } +} diff --git a/arch/arm/mach-stm/reset-imx23.c b/arch/arm/mach-stm/reset-imx23.c new file mode 100644 index 0000000..b35f796 --- /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 +#include +#include +#include +#include + +#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 0000000..7418ad5 --- /dev/null +++ b/arch/arm/mach-stm/speed-imx23.c @@ -0,0 +1,280 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This code is based partially on code of: + * + * (c) 2008 Embedded Alley Solutions, Inc. + * (C) Copyright 2009-2010 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +/* 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 f96d22d..aed0864 100644 --- a/arch/blackfin/lib/cpu.c +++ b/arch/blackfin/lib/cpu.c @@ -32,7 +32,7 @@ #include #include -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 e5e90a8..144d5a3 100644 --- a/arch/m68k/lib/m68k-linuxboot.c +++ b/arch/m68k/lib/m68k-linuxboot.c @@ -109,7 +109,7 @@ 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 3b1a25b..d4659d2 100644 --- a/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c +++ b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c @@ -27,7 +27,7 @@ /** * Reset the cpu by setting up the watchdog timer and let it time out */ -void __noreturn reset_cpu (unsigned long ignored) +void __noreturn reset_cpu (unsigned long addr) { while ( ignored ) { ; }; diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index 400b1e1..0844d56 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -1,6 +1,5 @@ obj-y += bat_rw.o obj-y += board.o -obj-y += cache.o obj-y += extable.o obj-$(CONFIG_USE_IRQ) += interrupts.o obj-y += kgdb.o diff --git a/arch/ppc/lib/cache.c b/arch/ppc/lib/cache.c deleted file mode 100644 index 3d863b3..0000000 --- a/arch/ppc/lib/cache.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * (C) Copyright 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - - -void flush_cache (ulong start_addr, ulong size) -{ -#ifndef CONFIG_5xx - ulong addr, end_addr = start_addr + size; - - if (CONFIG_CACHELINE_SIZE) { - addr = start_addr & (CONFIG_CACHELINE_SIZE - 1); - for (addr = start_addr; - addr < end_addr; - addr += CONFIG_CACHELINE_SIZE) { - asm ("dcbst 0,%0": :"r" (addr)); - } - asm ("sync"); /* Wait for all dcbst to complete on bus */ - - for (addr = start_addr; - addr < end_addr; - addr += CONFIG_CACHELINE_SIZE) { - asm ("icbi 0,%0": :"r" (addr)); - } - } - asm ("sync"); /* Always flush prefetch queue in any case */ - asm ("isync"); -#endif -} diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c index 5ee908d..fc22a87 100644 --- a/arch/ppc/lib/ppclinux.c +++ b/arch/ppc/lib/ppclinux.c @@ -45,7 +45,7 @@ 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 7ee1954..4d08c55 100644 --- a/arch/ppc/mach-mpc5xxx/cpu.c +++ b/arch/ppc/mach-mpc5xxx/cpu.c @@ -71,7 +71,7 @@ /* ------------------------------------------------------------------------- */ -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 ad625d7..38a52a8 100644 --- a/arch/sandbox/board/hostfile.c +++ b/arch/sandbox/board/hostfile.c @@ -79,7 +79,9 @@ 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 c73aa79..287be0d 100644 --- a/arch/sandbox/os/common.c +++ b/arch/sandbox/os/common.c @@ -138,7 +138,7 @@ return now; } -void __attribute__((noreturn)) reset_cpu(int unused) +void __attribute__((noreturn)) reset_cpu(unsigned long addr) { cookmode(); exit(0); @@ -213,11 +213,6 @@ 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 a6cd7e0..b9c31aa 100644 --- a/arch/x86/boards/x86_generic/generic_pc.c +++ b/arch/x86/boards/x86_generic/generic_pc.c @@ -46,7 +46,7 @@ static struct device_d 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 40388e9..fc4c4d5 100644 --- a/arch/x86/boot/boot_hdisk.S +++ b/arch/x86/boot/boot_hdisk.S @@ -31,7 +31,6 @@ * from the boot media. */ -#ifndef DOXYGEN_SHOULD_SKIP_THIS .file "boot_hdisk.S" .code16 @@ -173,4 +172,3 @@ chs_string: .asciz "CHS " jmp_string: .asciz "JMP " -#endif diff --git a/arch/x86/boot/boot_main.S b/arch/x86/boot/boot_main.S index f3d248a..94fe434 100644 --- a/arch/x86/boot/boot_main.S +++ b/arch/x86/boot/boot_main.S @@ -30,7 +30,6 @@ * @brief Fix segment:offset settings of some buggy BIOSs */ -#ifndef DOXYGEN_SHOULD_SKIP_THIS .file "boot_main.S" .code16 @@ -55,4 +54,3 @@ .size _start, .-_start -#endif diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S index d48e198..0e4cd38 100644 --- a/arch/x86/boot/pmjump.S +++ b/arch/x86/boot/pmjump.S @@ -20,7 +20,6 @@ * @fn void protected_mode_jump(void) * @brief Switches the first time from real mode to flat mode */ -#ifndef DOXYGEN_SHOULD_SKIP_THIS #include #include "boot.h" @@ -86,4 +85,3 @@ .size protected_mode_jump, .-protected_mode_jump -#endif diff --git a/arch/x86/lib/memory16.S b/arch/x86/lib/memory16.S index 01450fa..cb2f833 100644 --- a/arch/x86/lib/memory16.S +++ b/arch/x86/lib/memory16.S @@ -38,7 +38,6 @@ * */ -#ifndef DOXYGEN_SHOULD_SKIP_THIS .section .boot.text.bios_get_memsize, "ax" .code32 @@ -70,4 +69,3 @@ .size bios_get_memsize, .-bios_get_memsize -#endif diff --git a/arch/x86/lib/traveler.S b/arch/x86/lib/traveler.S index 2b6dc85..0614195 100644 --- a/arch/x86/lib/traveler.S +++ b/arch/x86/lib/traveler.S @@ -41,8 +41,6 @@ * Called from a 16 bit real mode segment and returns into a 32 bit segment */ -#ifndef DOXYGEN_SHOULD_SKIP_THIS - #include .file "walkyrie.S" @@ -180,4 +178,3 @@ .size prot_to_real, .-prot_to_real -#endif diff --git a/arch/x86/mach-x86.dox b/arch/x86/mach-x86.dox index fc5b85a..661e905 100644 --- a/arch/x86/mach-x86.dox +++ b/arch/x86/mach-x86.dox @@ -2,7 +2,7 @@ * how to integrate a new CPU (MACH) into this part of the barebox tree */ -/** @page x86_runtime barebox on x86 at runtime +/** @page dev_x86_mach barebox on x86 at runtime @section mach_x86_memory_layout barebox's memory layout (BIOS based) diff --git a/commands/Kconfig b/commands/Kconfig index 0fc80aa..5416073 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -202,6 +202,11 @@ 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 6e17200..5bac031 100644 --- a/commands/bmp.c +++ b/commands/bmp.c @@ -193,17 +193,28 @@ return 1; } -static const __maybe_unused char cmd_bmp_help[] = -"Usage: bmp [OPTION]... FILE\n" -"show bmp image FILE.\n" -" -f framebuffer device (/dev/fb0)\n" -" -x x offset (default center)\n" -" -y 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 ", "framebuffer device (/dev/fb0)\n") +BAREBOX_CMD_HELP_OPT ("-x ", "x offset (default center)\n") +BAREBOX_CMD_HELP_OPT ("-y ", "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 83d36d3..991431b 100644 --- a/commands/bootm.c +++ b/commands/bootm.c @@ -167,7 +167,7 @@ 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 @@ } 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 @@ 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 @@ /* 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 @@ 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 @@ /* 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 @@ 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 41b3324..37e6505 100644 --- a/commands/cat.c +++ b/commands/cat.c @@ -85,22 +85,15 @@ 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 \ [\ ...] - * - * 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 a842f4d..d73be32 100644 --- a/commands/cd.c +++ b/commands/cd.c @@ -47,21 +47,14 @@ 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 [\] - * - * Change to \. If called without argument, change to \b / - * (root) - */ diff --git a/commands/clear.c b/commands/clear.c index 7589a0c..6a6b6c5 100644 --- a/commands/clear.c +++ b/commands/clear.c @@ -31,6 +31,11 @@ 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 2c35ba1..ae8719b 100644 --- a/commands/cp.c +++ b/commands/cp.c @@ -51,7 +51,7 @@ 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 @@ return ret; } -static const __maybe_unused char cmd_cp_help[] = -"Usage: cp \n" -"cp copies file to .\n" -"This command is file based only. See memcpy for memory copy\n"; +BAREBOX_CMD_HELP_START(cp) +BAREBOX_CMD_HELP_USAGE("cp \n") +BAREBOX_CMD_HELP_SHORT("copy file from to .\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_HELP(cmd_cp_help) BAREBOX_CMD_END -/** - * @page cp_command cp: Copy file - * - * Usage: cp \ [\] \ - * - * \c cp copies file \ to \ - * - * 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 4842cdc..0873a1c 100644 --- a/commands/crc.c +++ b/commands/crc.c @@ -30,20 +30,80 @@ #include #include +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 @@ } } - 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; + +#ifdef CONFIG_CMD_CRC_CMP + if (vfilename) { + size = total; + puts("\n"); + if (file_crc(vfilename, start, size, &vcrc, &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; - } - - 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 @@ 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 Use file instead of memory\n" -" -v 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 ", "Use file instead of memory.\n") +#ifdef CONFIG_CMD_CRC_CMP +BAREBOX_CMD_HELP_OPT ("-F ", "Use file to compare.\n") +#endif +BAREBOX_CMD_HELP_OPT ("-v ", "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 66fd6ea..385fd89 100644 --- a/commands/dfu.c +++ b/commands/dfu.c @@ -162,16 +162,24 @@ return 1; } -static const __maybe_unused char cmd_dfu_help[] = -"Usage: dfu [OPTION]... description\n" -"start dfu firmware update\n" -" -m Manufacturer string (barebox)\n" -" -p product string (" CONFIG_BOARDINFO ")\n" -" -V vendor id\n" -" -P 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] \n") +BAREBOX_CMD_HELP_SHORT("Start firmware update with the Device Firmware Update (DFU) protocol.\n") +BAREBOX_CMD_HELP_OPT ("-m ", "Manufacturer string (barebox)\n") +BAREBOX_CMD_HELP_OPT ("-p ", "product string (" CONFIG_BOARDINFO ")\n") +BAREBOX_CMD_HELP_OPT ("-V ", "vendor id\n") +BAREBOX_CMD_HELP_OPT ("-P ", "product id\n") +BAREBOX_CMD_HELP_END + +/** + * @page dfu_command +\ 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 dfa14d6..3e098df 100644 --- a/commands/echo.c +++ b/commands/echo.c @@ -111,8 +111,25 @@ 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 a65b08a..ca40d59 100644 --- a/commands/edit.c +++ b/commands/edit.c @@ -58,7 +58,7 @@ 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 @@ line->prev = lastline; if (lastline) lastline->next = line; - line->next = 0; + line->next = NULL; lastline = line; if (!lineend) @@ -550,35 +550,25 @@ static const char *edit_aliases[] = { "sedit", NULL}; -static const __maybe_unused char cmd_edit_help[] = -"Usage: (s)edit \n" -"This is a very small editor. Its only features are moving the cursor with\n" -"the usual keys and typing characters.\n" -" quits the editor without saving,\n" -" 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 \n") +BAREBOX_CMD_HELP_SHORT("A small editor. is exit, exit-with-save.\n") +BAREBOX_CMD_HELP_END -static const __maybe_unused char cmd_edit_usage[] = "edit a file"; +/** + * @page edit_command + +

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.

+ +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 ", BAREBOX_CMD_HELP(cmd_edit_help) BAREBOX_CMD_END - -/** - * @page edit_command edit (editor) - * - * Usage is: [s]edit \ - * - * This is a very small editor. It's only features are moving the cursor with - * the usual keys and typing characters. - * - * \b \ quits the editor without saving,\n - * \b \ 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 31259cc..98b1e1a 100644 --- a/commands/export.c +++ b/commands/export.c @@ -51,9 +51,10 @@ return 0; } -static const __maybe_unused char cmd_export_help[] = -"Usage: export [=value]...\n" -"export an environment variable to subsequently executed scripts\n"; +BAREBOX_CMD_HELP_START(export) +BAREBOX_CMD_HELP_USAGE("export [=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_HELP(cmd_export_help) BAREBOX_CMD_END -/** - * @page export_command export: Export an environment variable - * - * Usage: export \[=value]... - * - * Export an environment variable to subsequently executed scripts. - */ diff --git a/commands/flash.c b/commands/flash.c index 20f5cfc..9a0eb50 100644 --- a/commands/flash.c +++ b/commands/flash.c @@ -83,10 +83,10 @@ return ret; } -static const __maybe_unused char cmd_erase_help[] = -"Usage: erase [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 [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_HELP(cmd_erase_help) BAREBOX_CMD_END -/** @page erase_command erase Erase flash memory - * - * Usage is: erase \ - * - * 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 + +

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.

+ +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 @@ return ret; } -static const __maybe_unused char cmd_protect_help[] = -"Usage: (un)protect [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 [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 [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 \ - * - * 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 \ - * - * 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 2575c1e..0cf19fe 100644 --- a/commands/gpio.c +++ b/commands/gpio.c @@ -36,12 +36,14 @@ return value; } -static const __maybe_unused char cmd_gpio_get_value_help[] = -"Usage: gpio_set_value \n"; +BAREBOX_CMD_HELP_START(gpio_get_value) +BAREBOX_CMD_HELP_USAGE("gpio_get_value \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 @@ return 0; } -static const __maybe_unused char cmd_gpio_set_value_help[] = -"Usage: gpio_set_value \n"; +BAREBOX_CMD_HELP_START(gpio_set_value) +BAREBOX_CMD_HELP_USAGE("gpio_set_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 @@ return 0; } -static const __maybe_unused char cmd_do_gpio_direction_input_help[] = -"Usage: gpio_direction_input \n"; +BAREBOX_CMD_HELP_START(gpio_direction_input) +BAREBOX_CMD_HELP_USAGE("gpio_direction_input \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 @@ return 0; } -static const __maybe_unused char cmd_gpio_direction_output_help[] = -"Usage: gpio_direction_output \n"; +BAREBOX_CMD_HELP_START(gpio_direction_output) +BAREBOX_CMD_HELP_USAGE("gpio_direction_output \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 +@endverbatim +- gpio_no: Architecture dependend GPIO number +- initial_value: Output value + +

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.

+ +@section gpio_dir_in Use Pad as GPIO Input +@verbatim +# gpio_direction_input +@endverbatim +- gpio_no: Architecture dependent GPIO number + +

If the pad is already configured in non-GPIO mode (if available), +this command may silently fail.

+ +@section gpio_get_value Read Input Value from GPIO Pin +@verbatim +# gpio_get_value +@endverbatim + +

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 $?".

+ +

A return code other than '0' or '1' specifies an error code.

+ +

If the pad is not configured in GPIO mode, this command may silently +fail and return garbage.

+ +@section gpio_set_value Set Output Value on GPIO Pin +@verbatim +# gpio_set_value +@endverbatim +- gpio_no: Architecture dependent GPIO number +- value: Output value + +

Set a new output value on pad with GPIO number \.

+ +

If the pad is not configured in GPIO-mode, this command may silently +fail.

+ +*/ diff --git a/commands/linux16.c b/commands/linux16.c index b15812f..ec859a7 100644 --- a/commands/linux16.c +++ b/commands/linux16.c @@ -288,14 +288,22 @@ return rc; } -static const __maybe_unused char cmd_linux16_help[] = -"Usage: linux16 \n" -"Boot a linux kernel via real mode code\n"; +BAREBOX_CMD_HELP_START(linux16) +BAREBOX_CMD_HELP_USAGE("linux16 \n") +BAREBOX_CMD_HELP_SHORT("Boot a kernel on x86 via real mode code.\n") +BAREBOX_CMD_HELP_END +/** + * @page linux16_command + +

Only kernel images in bzImage format are supported by now. See \ref +x86_boot_preparation for more info about how to use this command.

+ + */ 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 @@ */ /** - * @page linux16_command linux16: Boot a bzImage kernel on x86 - * - * Usage is: linux16 \ - * - * 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 acfb94f..faf4a97 100644 --- a/commands/loadb.c +++ b/commands/loadb.c @@ -636,7 +636,6 @@ 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 14fbf1e..c33c34f 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -43,28 +43,22 @@ return envfs_load(filename, dirname); } -static const __maybe_unused char cmd_loadenv_help[] = -"Usage: loadenv [ENVFS] [DIRECTORY]\n" -"Load the persistent storage contained in to the directory\n" -".\n" -"If ommitted defaults to /env and 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 [\] [\] - * - * Load the persistent storage contained in \ to the directory \. - * - * If ommitted \ defaults to \c /env and \ 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 8269af1..6e0dc7f 100644 --- a/commands/loads.c +++ b/commands/loads.c @@ -175,7 +175,6 @@ "## 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 a02ccfe..4f9c408 100644 --- a/commands/ls.c +++ b/commands/ls.c @@ -194,10 +194,11 @@ 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 bc84f6d..73bf915 100644 --- a/commands/mem.c +++ b/commands/mem.c @@ -110,7 +110,7 @@ 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 8e4388e..52d1700 100644 --- a/commands/mount.c +++ b/commands/mount.c @@ -58,49 +58,45 @@ return 0; } -static const __maybe_unused char cmd_mount_help[] = -"Usage: mount: list mounted filesystems\n" -"or: mount \n" -"\n" -"Mount a filesystem of a given type to a mountpoint.\n" -" can be one of /dev/* or some arbitrary string if no\n" -"device is needed for this driver (for example ramfs).\n" -" is the filesystem driver to use. Try the 'devinfo' command\n" -"for a list of available drivers.\n" -" must be an empty directory descending directly from the\n" -"root directory.\n"; +BAREBOX_CMD_HELP_START(mount) +BAREBOX_CMD_HELP_USAGE("mount [ ]\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 + +/** + * @page mount_command + +
    +
  • \ can be a device in /dev or some arbitrary string if no + device is needed for this driver, i.e. on ramfs.
  • +
  • \ is the filesystem driver. A list of available drivers can + be shown with the \ref devinfo_command command.
  • +
  • \ must be an empty directory, one level below the / + 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. + + */ BAREBOX_CMD_START(mount) .cmd = do_mount, - .usage = "mount a filesystem to a device", + .usage = "Mount a filesystem of a given type to a mountpoint or list mounted filesystems.", BAREBOX_CMD_HELP(cmd_mount_help) BAREBOX_CMD_END - -/** @page mount_command mount - * Usage: mount [\ \ \] - * - * Mounts a filesystem of a given \ on a \ to a \. - * \ can be one of /dev/ * or some arbitrary string if no - * device is needed for this driver (for example ramfs). - * - * \ is the filesystem driver to use. Try the 'devinfo' command - * for a list of available drivers. - * - * \ 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. - */ diff --git a/commands/partition.c b/commands/partition.c index 7794925..db9b9fb 100644 --- a/commands/partition.c +++ b/commands/partition.c @@ -149,19 +149,24 @@ return 0; } -static const __maybe_unused char cmd_addpart_help[] = -"Usage: addpart \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" -" 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 \n") +BAREBOX_CMD_HELP_SHORT("Add a partition description to a device.\n") +BAREBOX_CMD_HELP_OPT ("", "device being worked on\n") +BAREBOX_CMD_HELP_OPT ("", "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_HELP(cmd_addpart_help) BAREBOX_CMD_END -/** @page addpart_command addpart Add a partition to a device - * - * Usage is: addpart \ \ - * - * Adds a partition description to a device. The partition description has the - * form - * - * size1[@offset1](name1)[ro],size2[@offset2](name2)[ro],... - * - * \ 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 @@ 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 [] \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_HELP(cmd_delpart_help) BAREBOX_CMD_END -/** @page delpart_command delpart Delete a partition - * - * Usage is: delpart \ - * - * Delete a partition previously added to a device with addpart. - */ diff --git a/commands/printenv.c b/commands/printenv.c index e6fc0e4..4078bbc 100644 --- a/commands/printenv.c +++ b/commands/printenv.c @@ -65,26 +65,22 @@ 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 + +

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.

+ + */ 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 [\] - * - * Print environment variables. - * If \ was given, it prints out its content if the environment variable - * \ exists. - * - * Without the \ argument all current environment variables are printed. - */ diff --git a/commands/saveenv.c b/commands/saveenv.c index 42ea58f..2f969fe 100644 --- a/commands/saveenv.c +++ b/commands/saveenv.c @@ -94,12 +94,10 @@ return ret; } -static const __maybe_unused char cmd_saveenv_help[] = -"Usage: saveenv [] []\n" -"Save the files in to the persistent storage device .\n" -" is normally a block in flash, but could be any other file.\n" -"If ommitted defaults to /env and 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 to the persistent storage device .\n") +BAREBOX_CMD_HELP_END BAREBOX_CMD_START(saveenv) .cmd = do_saveenv, @@ -108,15 +106,14 @@ BAREBOX_CMD_END /** - * @page saveenv_command saveenv - * - * Usage: saveenv [\] [\] - * - * Save the files in \ to the persistent storage device \. - * \ is normally a block in flash, but could be any other file. - * - * If ommitted \ defaults to \c /env and \ defaults to - * \c /dev/env0. - * - * @note envfs can only handle files. Directories are skipped silently. + * @page saveenv_command + +

\ is usually a block in flash but can be any other file. If +ommitted, \ defaults to /env and \ defaults to +/dev/env0. Note that envfs can only handle files, directories are being +skipped silently.

+ +\todo What does 'block in flash' mean? Add example. + */ + diff --git a/commands/setenv.c b/commands/setenv.c index 257348f..e39db20 100644 --- a/commands/setenv.c +++ b/commands/setenv.c @@ -38,27 +38,23 @@ 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 []\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 + +

This command is only available if the simple command line parser is +in use. Within the hush shell, \c setenv is not required.

+ +\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 \ [\] - * - * Set environment variable \ to \. 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 6c683d9..2b3ac05 100644 --- a/commands/version.c +++ b/commands/version.c @@ -26,7 +26,6 @@ static int do_version(struct command *cmdtp, int argc, char *argv[]) { - extern char version_string[]; printf ("\n%s\n", version_string); return 0; } diff --git a/common/Kconfig b/common/Kconfig index ad70cde..617f640 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -248,6 +248,13 @@ 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 @@ 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 e56dbc2..753455b 100644 --- a/common/Makefile +++ b/common/Makefile @@ -26,12 +26,18 @@ $(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 204a08c..82786f2 100644 --- a/common/console.c +++ b/common/console.c @@ -43,8 +43,6 @@ #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 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 @@ } 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 83b1e18..ff63fbe 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -792,7 +792,7 @@ #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 @@ INTERNAL_SIZE_T nb; if ((long) bytes < 0) - return 0; + return NULL; nb = request2size(bytes); /* padded request size; */ @@ -1364,7 +1364,7 @@ /* 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 @@ 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 @@ #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 @@ goto split; } } else { - next = 0; + next = NULL; nextsize = 0; } @@ -1582,7 +1582,7 @@ /* 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 @@ } /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { return memalign(malloc_getpagesize, bytes); } +#endif /* * pvalloc just invokes valloc for the nearest pagesize @@ -1802,10 +1803,10 @@ 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 @@ { mchunkptr p; - if (mem == 0) + if (!mem) return 0; else { p = mem2chunk(mem); diff --git a/common/env.c b/common/env.c index edaf388..f81bd46 100644 --- a/common/env.c +++ b/common/env.c @@ -137,7 +137,7 @@ const char *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 0eb7e6b..e5f24ec 100644 --- a/common/environment.c +++ b/common/environment.c @@ -109,7 +109,7 @@ 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 19e35f5..77610bb 100644 --- a/common/hush.c +++ b/common/hush.c @@ -120,6 +120,8 @@ #include #include #include +#include +#include /*cmd_boot.c*/ extern int do_bootd(struct command *cmdtp, int flag, int argc, char *argv[]); /* do_bootd */ @@ -174,6 +176,12 @@ #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 @@ char **global_argv; unsigned int global_argc; + + int options_parsed; + struct list_head options; }; @@ -267,13 +278,14 @@ 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 @@ } /* 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 @@ 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 @@ * 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 @@ 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 @@ } 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 @@ 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 @@ } 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 @@ } 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 @@ } /* 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 @@ * 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 @@ 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 @@ 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 @@ 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 @@ ret = parse_string_outer(&ctx, script, FLAG_PARSE_SEMICOLON); + release_context(&ctx); free(script); return ret; @@ -1577,6 +1658,7 @@ 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_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 \n" +"\n" +"hush option parser. 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 ,\n" +"arguments are saved in OPTARG.\n"; + +BAREBOX_CMD_START(getopt) + .cmd = do_getopt, + .usage = "getopt ", + 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 104446a..a4c8b95 100644 --- a/common/image.c +++ b/common/image.c @@ -266,6 +266,7 @@ { const image_header_t *hdr = (const image_header_t *)ptr; const char *p; + int type; #ifdef __BAREBOX__ p = " "; @@ -285,8 +286,8 @@ 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 @@ 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 4069f4b..490adb9 100644 --- a/common/kallsyms.c +++ b/common/kallsyms.c @@ -2,6 +2,8 @@ #include #include +#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 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 505e43f..e3bc56c 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -21,6 +21,7 @@ * MA 02111-1307 USA */ +#include #include #if defined (__PPC__) && !defined (__SANDBOX__) /* diff --git a/common/parser.c b/common/parser.c index 97e354b..fd578c7 100644 --- a/common/parser.c +++ b/common/parser.c @@ -6,9 +6,8 @@ { 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 @@ 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 @@ 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 @@ } 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,13 +58,13 @@ /* 1 = waiting for '(' or '{' */ /* 2 = waiting for ')' or '}' */ /* 3 = waiting for ''' */ -#ifdef DEBUG_PARSER +#ifdef DEBUG char *output_start = output; - - printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input), - input); #endif + pr_debug("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input), + input); + prev = '\0'; /* previous character */ while (inputcnt && outputcnt) { @@ -153,10 +150,8 @@ 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 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 @@ 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 @@ 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 ddd6b84..87e6922 100644 --- a/defaultenv/bin/_update +++ b/defaultenv/bin/_update @@ -10,18 +10,16 @@ exit 1 fi -if [ $# = 1 ]; then - image=$1 -fi +if [ x$mode = xtftp ]; then + if [ x$ip = xdhcp ]; then + dhcp + fi -if [ x$ip = xdhcp ]; then - dhcp -fi - -ping $eth0.serverip -if [ $? -ne 0 ] ; then - echo "Server did not reply! Update aborted." - exit 1 + ping $eth0.serverip + if [ $? -ne 0 ] ; then + echo "Server did not reply! Update aborted." + exit 1 + fi fi unprotect $part @@ -34,6 +32,12 @@ 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 0000000..22d940e --- /dev/null +++ b/defaultenv/bin/_update_help @@ -0,0 +1,12 @@ +#!/bin/sh + +echo "usage: $0 -t -d [-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 [-m tftp|xmodem] [-f imagename] to update kernel into flash" +echo "type update -t rootfs -d [-m tftp|xmodem] [-f imagename] to update rootfs into flash" +echo "type update -t barebox -d [-m tftp|xmodem] [-f imagename] to update barebox into flash" diff --git a/defaultenv/bin/boot b/defaultenv/bin/boot index 6476bdb..42c7ec2 100644 --- a/defaultenv/bin/boot +++ b/defaultenv/bin/boot @@ -16,7 +16,7 @@ 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 @@ 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 a55e8e6..96a5716 100644 --- a/defaultenv/bin/init +++ b/defaultenv/bin/init @@ -8,6 +8,10 @@ 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 @@ timeout -a $autoboot_timeout if [ $? != 0 ]; then echo - echo "type update_kernel nand|nor [] to update kernel into flash" - echo "type update_rootfs nand|nor [] to update rootfs into flash" + update -h echo exit fi diff --git a/defaultenv/bin/update b/defaultenv/bin/update new file mode 100644 index 0000000..3601177 --- /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 1d35ed9..0000000 --- a/defaultenv/bin/update_kernel +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -. /env/config -image=$kernelimage - -if [ x$1 = xnand ]; then - part=/dev/nand0.kernel.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.kernel -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 diff --git a/defaultenv/bin/update_rootfs b/defaultenv/bin/update_rootfs deleted file mode 100644 index 6366315..0000000 --- a/defaultenv/bin/update_rootfs +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$rootfsimage - -if [ x$1 = xnand ]; then - part=/dev/nand0.root.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.root -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 diff --git a/drivers/Kconfig b/drivers/Kconfig index f7154c6..d94017b 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -9,6 +9,8 @@ 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 706e1c8..242a564 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -6,5 +6,7 @@ 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 250dada..a54429a 100644 --- a/drivers/ata/disk_drive.c +++ b/drivers/ata/disk_drive.c @@ -23,6 +23,7 @@ * @brief Generic disk drive support * * @todo Support for disks larger than 4 GiB + * @todo Reliable size detection for BIOS based disks (on x86 only) */ #include @@ -34,6 +35,7 @@ #include #include #include +#include /** * Description of one partition table entry (D*S type) @@ -105,7 +107,8 @@ 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 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 @@ 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*)§or[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*)§or[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*)§or[446]); + rc = disk_register_partitions(dev, (struct partition_entry*)§or[446]); - return 0; +on_error: + free(sector); + return rc; } #ifdef CONFIG_ATA_BIOS diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 9ce1655..c2af818 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -5,20 +5,4 @@ source drivers/i2c/busses/Kconfig -config I2C_MC13892 - bool "MC13892 a.k.a. PMIC driver" - -config I2C_MC34704 - bool "MC34704 PMIC driver" - -config I2C_MC9SDZ60 - bool "MC9SDZ60 driver" - -config I2C_LP3972 - bool "LP3972 driver" - -config I2C_TWL4030 - bool "TWL4030 driver" - select GPIO - endif diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 0584b55..42e22c0 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -1,7 +1 @@ obj-$(CONFIG_I2C) += i2c.o busses/ - -obj-$(CONFIG_I2C_MC13892) += mc13892.o -obj-$(CONFIG_I2C_MC34704) += mc34704.o -obj-$(CONFIG_I2C_MC9SDZ60) += mc9sdz60.o -obj-$(CONFIG_I2C_LP3972) += lp3972.o -obj-$(CONFIG_I2C_TWL4030) += twl4030.o diff --git a/drivers/i2c/lp3972.c b/drivers/i2c/lp3972.c deleted file mode 100644 index 9826699..0000000 --- a/drivers/i2c/lp3972.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2007 Sascha Hauer, Pengutronix - * 2009 Marc Kleine-Budde - * 2009 Eric Benard - * - * 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 -#include -#include -#include -#include - -#include - -#include - -#define DRIVERNAME "lp3972" - -struct lp_priv { - struct cdev cdev; - struct i2c_client *client; -}; - -#define to_lp_priv(a) container_of(a, struct lp_priv, cdev) - -static struct lp_priv *lp_dev; - -struct i2c_client *lp3972_get_client(void) -{ - if (!lp_dev) - return NULL; - - return lp_dev->client; -} - -static u32 lp_read_reg(struct lp_priv *lp, int reg) -{ - u8 buf; - - i2c_read_reg(lp->client, reg, &buf, sizeof(buf)); - - return buf; -} - -static ssize_t lp_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) -{ - struct lp_priv *priv = to_lp_priv(cdev); - int i = count; - u8 *buf = _buf; - - while (i) { - *buf = lp_read_reg(priv, offset); - buf++; - i--; - offset++; - } - - return count; -} - -static struct file_operations lp_fops = { - .lseek = dev_lseek_default, - .read = lp_read, -}; - -static int lp_probe(struct device_d *dev) -{ - if (lp_dev) - return -EBUSY; - - lp_dev = xzalloc(sizeof(struct lp_priv)); - lp_dev->cdev.name = DRIVERNAME; - lp_dev->client = to_i2c_client(dev); - lp_dev->cdev.size = 256; - lp_dev->cdev.dev = dev; - lp_dev->cdev.ops = &lp_fops; - - devfs_create(&lp_dev->cdev); - - return 0; -} - -static struct driver_d lp_driver = { - .name = DRIVERNAME, - .probe = lp_probe, -}; - -static int lp_init(void) -{ - register_driver(&lp_driver); - return 0; -} - -device_initcall(lp_init); diff --git a/drivers/i2c/mc13892.c b/drivers/i2c/mc13892.c deleted file mode 100644 index 67d4232..0000000 --- a/drivers/i2c/mc13892.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2007 Sascha Hauer, Pengutronix - * 2009 Marc Kleine-Budde - * - * 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 -#include -#include -#include -#include - -#include -#include - -#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/i2c/mc34704.c b/drivers/i2c/mc34704.c deleted file mode 100644 index 51a8737..0000000 --- a/drivers/i2c/mc34704.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2007 Sascha Hauer, Pengutronix - * 2009 Marc Kleine-Budde - * Copyright (C) 2010 Baruch Siach - * - * 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 -#include -#include -#include -#include - -#include -#include - -#define DRIVERNAME "mc34704" - -#define to_mc34704(a) container_of(a, struct mc34704, cdev) - -static struct mc34704 *mc34704_dev; - -struct mc34704 *mc34704_get(void) -{ - if (!mc34704_dev) - return NULL; - - return mc34704_dev; -} -EXPORT_SYMBOL(mc34704_get); - -int mc34704_reg_read(struct mc34704 *mc34704, u8 reg, u8 *val) -{ - int ret; - - ret = i2c_read_reg(mc34704->client, reg, val, 1); - - return ret == 1 ? 0 : ret; -} -EXPORT_SYMBOL(mc34704_reg_read) - -int mc34704_reg_write(struct mc34704 *mc34704, u8 reg, u8 val) -{ - int ret; - - ret = i2c_write_reg(mc34704->client, reg, &val, 1); - - return ret == 1 ? 0 : ret; -} -EXPORT_SYMBOL(mc34704_reg_write) - -static ssize_t mc34704_read(struct cdev *cdev, void *_buf, size_t count, - ulong offset, ulong flags) -{ - struct mc34704 *priv = to_mc34704(cdev); - u8 *buf = _buf; - size_t i = count; - int err; - - while (i) { - err = mc34704_reg_read(priv, offset, buf); - if (err) - return (ssize_t)err; - buf++; - i--; - offset++; - } - - return count; -} - -static ssize_t mc34704_write(struct cdev *cdev, const void *_buf, size_t count, - ulong offset, ulong flags) -{ - struct mc34704 *mc34704 = to_mc34704(cdev); - const u8 *buf = _buf; - size_t i = count; - int err; - - while (i) { - err = mc34704_reg_write(mc34704, offset, *buf); - if (err) - return (ssize_t)err; - buf++; - i--; - offset++; - } - - return count; -} - -static struct file_operations mc34704_fops = { - .lseek = dev_lseek_default, - .read = mc34704_read, - .write = mc34704_write, -}; - -static int mc34704_probe(struct device_d *dev) -{ - if (mc34704_dev) - return -EBUSY; - - mc34704_dev = xzalloc(sizeof(struct mc34704)); - mc34704_dev->cdev.name = DRIVERNAME; - mc34704_dev->client = to_i2c_client(dev); - mc34704_dev->cdev.size = 256; - mc34704_dev->cdev.dev = dev; - mc34704_dev->cdev.ops = &mc34704_fops; - - devfs_create(&mc34704_dev->cdev); - - return 0; -} - -static struct driver_d mc34704_driver = { - .name = DRIVERNAME, - .probe = mc34704_probe, -}; - -static int mc34704_init(void) -{ - register_driver(&mc34704_driver); - return 0; -} -device_initcall(mc34704_init); diff --git a/drivers/i2c/mc9sdz60.c b/drivers/i2c/mc9sdz60.c deleted file mode 100644 index 3580af8..0000000 --- a/drivers/i2c/mc9sdz60.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2007 Sascha Hauer, Pengutronix - * 2009 Marc Kleine-Budde - * - * 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 -#include -#include -#include -#include - -#include -#include - -#define DRIVERNAME "mc9sdz60" - -#define to_mc9sdz60(a) container_of(a, struct mc9sdz60, cdev) - -static struct mc9sdz60 *mc_dev; - -struct mc9sdz60 *mc9sdz60_get(void) -{ - if (!mc_dev) - return NULL; - - return mc_dev; -} -EXPORT_SYMBOL(mc9sdz60_get); - -int mc9sdz60_reg_read(struct mc9sdz60 *mc9sdz60, enum mc9sdz60_reg reg, u8 *val) -{ - int ret; - - ret = i2c_read_reg(mc9sdz60->client, reg, val, 1); - - return ret == 1 ? 0 : ret; -} -EXPORT_SYMBOL(mc9sdz60_reg_read) - -int mc9sdz60_reg_write(struct mc9sdz60 *mc9sdz60, enum mc9sdz60_reg reg, u8 val) -{ - int ret; - - ret = i2c_write_reg(mc9sdz60->client, reg, &val, 1); - - return ret == 1 ? 0 : ret; -} -EXPORT_SYMBOL(mc9sdz60_reg_write) - -int mc9sdz60_set_bits(struct mc9sdz60 *mc9sdz60, enum mc9sdz60_reg reg, u8 mask, u8 val) -{ - u8 tmp; - int err; - - err = mc9sdz60_reg_read(mc9sdz60, reg, &tmp); - tmp = (tmp & ~mask) | val; - - if (!err) - err = mc9sdz60_reg_write(mc9sdz60, reg, tmp); - - return err; -} -EXPORT_SYMBOL(mc9sdz60_set_bits); - -static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) -{ - struct mc9sdz60 *mc9sdz60 = to_mc9sdz60(cdev); - u8 *buf = _buf; - size_t i = count; - int err; - - while (i) { - err = mc9sdz60_reg_read(mc9sdz60, 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 mc9sdz60 *mc9sdz60 = to_mc9sdz60(cdev); - const u8 *buf = _buf; - size_t i = count; - int err; - - while (i) { - err = mc9sdz60_reg_write(mc9sdz60, 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 mc9sdz60)); - mc_dev->cdev.name = DRIVERNAME; - mc_dev->client = to_i2c_client(dev); - mc_dev->cdev.size = 64; /* 35 known registers */ - 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/i2c/twl4030.c b/drivers/i2c/twl4030.c deleted file mode 100644 index 5305ec6..0000000 --- a/drivers/i2c/twl4030.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2010 Michael Grzeschik - * - * This file is released under the GPLv2 - * - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define DRIVERNAME "twl4030" - -#define to_twl4030(a) container_of(a, struct twl4030, cdev) - -static struct twl4030 *twl_dev; - -struct twl4030 *twl4030_get(void) -{ - if (!twl_dev) - return NULL; - - return twl_dev; -} -EXPORT_SYMBOL(twl4030_get); - -int twl4030_reg_read(struct twl4030 *twl4030, u16 reg, u8 *val) -{ - int ret; - struct i2c_msg xfer_msg[2]; - struct i2c_msg *msg; - int i2c_addr; - unsigned char buf = reg & 0xff; - - i2c_addr = twl4030->client->addr + (reg / 0x100); - - /* [MSG1] fill the register address data */ - msg = &xfer_msg[0]; - msg->addr = i2c_addr; - msg->len = 1; - msg->flags = 0; /* Read the register value */ - msg->buf = &buf; - /* [MSG2] fill the data rx buffer */ - msg = &xfer_msg[1]; - msg->addr = i2c_addr; - msg->flags = I2C_M_RD; /* Read the register value */ - msg->len = 1; /* only n bytes */ - msg->buf = val; - ret = i2c_transfer(twl4030->client->adapter, xfer_msg, 2); - - /* i2c_transfer returns number of messages transferred */ - if (ret < 0) { - pr_err("%s: failed to transfer all messages: %s\n", __func__, strerror(-ret)); - return ret; - } - return 0; -} -EXPORT_SYMBOL(twl4030_reg_read) - -int twl4030_reg_write(struct twl4030 *twl4030, u16 reg, u8 val) -{ - int ret; - struct i2c_msg xfer_msg[1]; - struct i2c_msg *msg; - int i2c_addr; - u8 buf[2]; - - buf[0] = reg & 0xff; - buf[1] = val; - - i2c_addr = twl4030->client->addr + (reg / 0x100); - - /* - * [MSG1]: fill the register address data - * fill the data Tx buffer - */ - msg = xfer_msg; - msg->addr = i2c_addr; - msg->len = 2; - msg->flags = 0; - msg->buf = buf; - /* over write the first byte of buffer with the register address */ - ret = i2c_transfer(twl4030->client->adapter, xfer_msg, 1); - - /* i2c_transfer returns number of messages transferred */ - if (ret < 0) { - pr_err("%s: failed to transfer all messages: %s\n", __func__, strerror(-ret)); - return ret; - } - return 0; -} -EXPORT_SYMBOL(twl4030_reg_write) - -int twl4030_set_bits(struct twl4030 *twl4030, enum twl4030_reg reg, u8 mask, u8 val) -{ - u8 tmp; - int err; - - err = twl4030_reg_read(twl4030, reg, &tmp); - tmp = (tmp & ~mask) | val; - - if (!err) - err = twl4030_reg_write(twl4030, reg, tmp); - - return err; -} -EXPORT_SYMBOL(twl4030_set_bits); - -static ssize_t twl_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) -{ - struct twl4030 *priv = to_twl4030(cdev); - u8 *buf = _buf; - size_t i = count; - int err; - - while (i) { - err = twl4030_reg_read(priv, offset, buf); - if (err) - return (ssize_t)err; - buf++; - i--; - offset++; - } - - return count; -} - -static ssize_t twl_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags) -{ - struct twl4030 *twl4030 = to_twl4030(cdev); - const u8 *buf = _buf; - size_t i = count; - int err; - - while (i) { - err = twl4030_reg_write(twl4030, offset, *buf); - if (err) - return (ssize_t)err; - buf++; - i--; - offset++; - } - - return count; -} - -static struct file_operations twl_fops = { - .lseek = dev_lseek_default, - .read = twl_read, - .write = twl_write, -}; - -static int twl_probe(struct device_d *dev) -{ - if (twl_dev) - return -EBUSY; - - twl_dev = xzalloc(sizeof(struct twl4030)); - twl_dev->cdev.name = DRIVERNAME; - twl_dev->client = to_i2c_client(dev); - twl_dev->cdev.size = 1024; - twl_dev->cdev.dev = dev; - twl_dev->cdev.ops = &twl_fops; - - devfs_create(&twl_dev->cdev); - - return 0; -} - -static struct driver_d twl_driver = { - .name = DRIVERNAME, - .probe = twl_probe, -}; - -static int twl_init(void) -{ - register_driver(&twl_driver); - return 0; -} - -device_initcall(twl_init); diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig new file mode 100644 index 0000000..b1f2773 --- /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 0000000..a10cb47 --- /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 0000000..63cd059 --- /dev/null +++ b/drivers/mci/imx-esdhc.c @@ -0,0 +1,512 @@ +/* + * Copyright 2007,2010 Freescale Semiconductor, Inc + * Andy Fleming + * + * Based vaguely on the pxa mmc code: + * (C) Copyright 2003 + * Kyle Harris, Nexus Technologies, Inc. kharris@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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(®s->irqstat); + while (!(esdhc_read32(®s->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(®s->irqstat); + databuf = esdhc_read32(®s->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(®s->irqstat); + while (!(esdhc_read32(®s->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(®s->irqstat); + esdhc_write32(®s->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(®s->wml, WML_RD_WML_MASK, wml_value); + esdhc_write32(®s->dsaddr, (u32)data->dest); + } else { + if (wml_value > 0x80) + wml_value = 0x80; + if ((esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL) == 0) { + printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); + return -ETIMEDOUT; + } + + esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK, + wml_value << 16); + esdhc_write32(®s->dsaddr, (u32)data->src); + } +#else /* CONFIG_MCI_IMX_ESDHC_PIO */ + if (!(data->flags & MMC_DATA_READ)) { + if ((esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL) == 0) { + printf("\nThe SD card is locked. " + "Can not write to a locked card.\n\n"); + return -ETIMEDOUT; + } + esdhc_write32(®s->dsaddr, (u32)data->src); + } else + esdhc_write32(®s->dsaddr, (u32)data->dest); +#endif /* CONFIG_MCI_IMX_ESDHC_PIO */ + + esdhc_write32(®s->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(®s->irqstat, -1); + + /* Wait for the bus to be idle */ + while ((esdhc_read32(®s->prsstat) & PRSSTAT_CICHB) || + (esdhc_read32(®s->prsstat) & PRSSTAT_CIDHB)) + ; + + while (esdhc_read32(®s->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(®s->cmdarg, cmd->cmdarg); + esdhc_write32(®s->xfertyp, xfertyp); + + /* Wait for the command to complete */ + while (!(esdhc_read32(®s->irqstat) & IRQSTAT_CC)) + ; + + irqstat = esdhc_read32(®s->irqstat); + esdhc_write32(®s->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(®s->cmdrsp3); + cmdrsp2 = esdhc_read32(®s->cmdrsp2); + cmdrsp1 = esdhc_read32(®s->cmdrsp1); + cmdrsp0 = esdhc_read32(®s->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(®s->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(®s->irqstat); + + if (irqstat & DATA_ERR) + return -EIO; + + if (irqstat & IRQSTAT_DTOE) + return -ETIMEDOUT; + } while (!(irqstat & IRQSTAT_TC) && + (esdhc_read32(®s->prsstat) & PRSSTAT_DLA)); + + if (data->flags & MMC_DATA_READ) { + dma_inv_range((unsigned long)data->dest, + (unsigned long)(data->dest + 512)); + } +#endif + } + + esdhc_write32(®s->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(®s->sysctl, SYSCTL_CKEN); + + esdhc_clrsetbits32(®s->sysctl, SYSCTL_CLOCK_MASK, clk); + + udelay(10000); + + clk = SYSCTL_PEREN | SYSCTL_CKEN; + + esdhc_setbits32(®s->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(®s->proctl, PROCTL_DTW_4 | PROCTL_DTW_8); + + if (bus_width == 4) + esdhc_setbits32(®s->proctl, PROCTL_DTW_4); + else if (bus_width == 8) + esdhc_setbits32(®s->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(®s->scr, 0x00000040); + + /* Reset the entire host controller */ + esdhc_write32(®s->sysctl, SYSCTL_RSTA); + + /* Wait until the controller is available */ + while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout) + udelay(1000); + + esdhc_write32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN); + + /* Set the initial clock speed */ + set_sysctl(mci, 400000); + + /* Disable the BRR and BWR bits in IRQSTAT */ + esdhc_clrbits32(®s->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR); + + /* Put the PROCTL reg back to the default */ + esdhc_write32(®s->proctl, PROCTL_INIT); + + /* Set timout to the maximum value */ + esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16); + + return ret; +} + +static int esdhc_reset(struct fsl_esdhc *regs) +{ + uint64_t start; + + /* reset the controller */ + esdhc_write32(®s->sysctl, SYSCTL_RSTA); + + start = get_time_ns(); + /* hardware clears the bit when it is done */ + while (1) { + if (!(esdhc_read32(®s->sysctl) & SYSCTL_RSTA)) + break; + if (is_timeout(start, 100 * MSECOND)) { + printf("MMC/SD: Reset never completed.\n"); + return -EIO; + } + } + + return 0; +} + +static int fsl_esdhc_probe(struct device_d *dev) +{ + struct fsl_esdhc_host *host; + struct mci_host *mci; + u32 caps; + int ret; + + host = xzalloc(sizeof(*host)); + mci = &host->mci; + + host->dev = dev; + host->regs = (struct fsl_esdhc *)dev->map_base; + + /* First reset the eSDHC controller */ + ret = esdhc_reset(host->regs); + if (ret) { + free(host); + return ret; + } + + caps = esdhc_read32(&host->regs->hostcapblt); + + if (caps & ESDHC_HOSTCAPBLT_VS18) + mci->voltages |= MMC_VDD_165_195; + if (caps & ESDHC_HOSTCAPBLT_VS30) + mci->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; + if (caps & ESDHC_HOSTCAPBLT_VS33) + mci->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34; + + mci->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; + + if (caps & ESDHC_HOSTCAPBLT_HSS) + mci->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; + + host->mci.send_cmd = esdhc_send_cmd; + host->mci.set_ios = esdhc_set_ios; + host->mci.init = esdhc_init; + host->mci.host_caps = MMC_MODE_4BIT; + + host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + + host->mci.f_min = imx_get_mmcclk() >> 12; + if (host->mci.f_min < 200000) + host->mci.f_min = 200000; + host->mci.f_max = imx_get_mmcclk(); + + mci_register(&host->mci); + + return 0; +} + +static struct driver_d fsl_esdhc_driver = { + .name = "imx-esdhc", + .probe = fsl_esdhc_probe, +}; + +static int fsl_esdhc_init_driver(void) +{ + register_driver(&fsl_esdhc_driver); + return 0; +} + +device_initcall(fsl_esdhc_init_driver); + diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h new file mode 100644 index 0000000..19fed5a --- /dev/null +++ b/drivers/mci/imx-esdhc.h @@ -0,0 +1,164 @@ +/* + * FSL SD/MMC Defines + *------------------------------------------------------------------- + * + * Copyright 2007-2008,2010 Freescale Semiconductor, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *------------------------------------------------------------------- + * + */ + +#ifndef __FSL_ESDHC_H__ +#define __FSL_ESDHC_H__ + +#include +#include + +/* 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 0000000..8525692 --- /dev/null +++ b/drivers/mci/imx.c @@ -0,0 +1,520 @@ +/* + * This is a driver for the SDHC controller found in Freescale MX2/MX3 + * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). + * Unlike the hardware found on MX1, this hardware just works and does + * not need all the quirks found in imxmmc.c, hence the seperate driver. + * + * Copyright (C) 2009 Ilya Yanok, + * Copyright (C) 2008 Sascha Hauer, Pengutronix + * Copyright (C) 2006 Pavel Pisa, PiKRON + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 0000000..a8aa486 --- /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 +#include +#include +#include +#include +#include +#include +#include + +#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 0000000..9810683 --- /dev/null +++ b/drivers/mci/s3c.c @@ -0,0 +1,817 @@ +/* + * Copyright (C) 2010 Juergen Beisert + * + * 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 + * Copyright (C) 2008 Simtec Electronics + * (C) Copyright 2006 by OpenMoko, Inc. + * Author: Harald Welte + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 0000000..420c2ea --- /dev/null +++ b/drivers/mci/stm378x.c @@ -0,0 +1,699 @@ +/* + * Copyright (C) 2010 Juergen Beisert, Pengutronix + * + * This code is based on: + * + * Copyright (C) 2007 SigmaTel, Inc., Ioannis Kappas + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 0000000..96440d8 --- /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 0000000..d411f23 --- /dev/null +++ b/drivers/mfd/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_I2C_MC13892) += mc13892.o +obj-$(CONFIG_I2C_MC34704) += mc34704.o +obj-$(CONFIG_I2C_MC9SDZ60) += mc9sdz60.o +obj-$(CONFIG_I2C_LP3972) += lp3972.o +obj-$(CONFIG_I2C_TWL4030) += twl4030.o +obj-$(CONFIG_DRIVER_SPI_MC13783) += mc13783.o diff --git a/drivers/mfd/lp3972.c b/drivers/mfd/lp3972.c new file mode 100644 index 0000000..9826699 --- /dev/null +++ b/drivers/mfd/lp3972.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * 2009 Marc Kleine-Budde + * 2009 Eric Benard + * + * 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 +#include +#include +#include +#include + +#include + +#include + +#define DRIVERNAME "lp3972" + +struct lp_priv { + struct cdev cdev; + struct i2c_client *client; +}; + +#define to_lp_priv(a) container_of(a, struct lp_priv, cdev) + +static struct lp_priv *lp_dev; + +struct i2c_client *lp3972_get_client(void) +{ + if (!lp_dev) + return NULL; + + return lp_dev->client; +} + +static u32 lp_read_reg(struct lp_priv *lp, int reg) +{ + u8 buf; + + i2c_read_reg(lp->client, reg, &buf, sizeof(buf)); + + return buf; +} + +static ssize_t lp_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) +{ + struct lp_priv *priv = to_lp_priv(cdev); + int i = count; + u8 *buf = _buf; + + while (i) { + *buf = lp_read_reg(priv, offset); + buf++; + i--; + offset++; + } + + return count; +} + +static struct file_operations lp_fops = { + .lseek = dev_lseek_default, + .read = lp_read, +}; + +static int lp_probe(struct device_d *dev) +{ + if (lp_dev) + return -EBUSY; + + lp_dev = xzalloc(sizeof(struct lp_priv)); + lp_dev->cdev.name = DRIVERNAME; + lp_dev->client = to_i2c_client(dev); + lp_dev->cdev.size = 256; + lp_dev->cdev.dev = dev; + lp_dev->cdev.ops = &lp_fops; + + devfs_create(&lp_dev->cdev); + + return 0; +} + +static struct driver_d lp_driver = { + .name = DRIVERNAME, + .probe = lp_probe, +}; + +static int lp_init(void) +{ + register_driver(&lp_driver); + return 0; +} + +device_initcall(lp_init); diff --git a/drivers/mfd/mc13783.c b/drivers/mfd/mc13783.c new file mode 100644 index 0000000..19e2780 --- /dev/null +++ b/drivers/mfd/mc13783.c @@ -0,0 +1,237 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#define REG_INTERRUPT_STATUS_0 0x0 +#define REG_INTERRUPT_MASK 0x1 +#define REG_INTERRUPT_SENSE_0 0x2 +#define REG_INTERRUPT_STATUS_1 0x3 +#define REG_INTERRUPT_MASK_1 0x4 +#define REG_INTERRUPT_SENSE_1 0x5 +#define REG_POWER_UP_MODE_SENSE 0x6 +#define REG_REVISION 0x7 +#define REG_SEMAPHORE 0x8 +#define REG_ARBITRATION_PERIPHERAL_AUDIO 0x9 +#define REG_ARBITRATION_SWITCHERS 0xa +#define REG_ARBITRATION_REGULATORS(x) (0xb + (x)) /* 0 .. 1 */ +#define REG_POWER_CONTROL(x) (0xd + (x)) /* 0 .. 2 */ +#define REG_REGEN_ASSIGNMENT 0x10 +#define REG_CONTROL_SPARE 0x11 +#define REG_MEMORY_A 0x12 +#define REG_MEMORY_B 0x13 +#define REG_RTC_TIME 0x14 +#define REG_RTC_ALARM 0x15 +#define REG_RTC_DAY 0x16 +#define REG_RTC_DAY_ALARM 0x17 +#define REG_SWITCHERS(x) (0x18 + (x)) /* 0 .. 5 */ +#define REG_REGULATOR_SETTING(x) (0x1e + (x)) /* 0 .. 1 */ +#define REG_REGULATOR_MODE(x) (0x20 + (x)) /* 0 .. 1 */ +#define REG_POWER_MISCELLANEOUS 0x22 +#define REG_POWER_SPARE 0x23 +#define REG_AUDIO_RX_0 0x24 +#define REG_AUDIO_RX_1 0x25 +#define REG_AUDIO_TX 0x26 +#define REG_AUDIO_SSI_NETWORK 0x27 +#define REG_AUDIO_CODEC 0x28 +#define REG_AUDIO_STEREO_DAC 0x29 +#define REG_AUDIO_SPARE 0x2a +#define REG_ADC(x) (0x2b + (x)) /* 0 .. 4 */ +#define REG_CHARGER 0x30 +#define REG_USB 0x31 +#define REG_CHARGE_USB_SPARE 0x32 +#define REG_LED_CONTROL(x) (0x33 + (x)) /* 0 .. 5 */ +#define REG_SPARE 0x39 +#define REG_TRIM(x) (0x3a + (x)) /* 0 .. 1 */ +#define REG_TEST(x) (0x3c + (x)) /* 0 .. 3 */ + +#define MXC_PMIC_REG_NUM(reg) (((reg) & 0x3f) << 25) +#define MXC_PMIC_WRITE (1 << 31) + +#define SWX_VOLTAGE(x) ((x) & 0x3f) +#define SWX_VOLTAGE_DVS(x) (((x) & 0x3f) << 6) +#define SWX_VOLTAGE_STANDBY(x) (((x) & 0x3f) << 12) +#define SWX_VOLTAGE_1_450 0x16 + +#define SWX_MODE_OFF 0 +#define SWX_MODE_NO_PULSE_SKIP 1 +#define SWX_MODE_PULSE_SKIP 2 +#define SWX_MODE_LOW_POWER_PFM 3 + +#define SW1A_MODE(x) (((x) & 0x3) << 0) +#define SW1A_MODE_STANDBY(x) (((x) & 0x3) << 2) +#define SW1B_MODE(x) (((x) & 0x3) << 10) +#define SW1B_MODE_STANDBY(x) (((x) & 0x3) << 12) +#define SW1A_SOFTSTART (1 << 9) +#define SW1B_SOFTSTART (1 << 17) +#define SW_PLL_FACTOR(x) (((x) - 28) << 19) + +struct pmic_priv { + struct cdev cdev; + struct spi_device *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; +} + +static uint32_t pmic_read_reg(struct pmic_priv *pmic, int reg) +{ + uint32_t buf; + + buf = MXC_PMIC_REG_NUM(reg); + + spi_rw(pmic->spi, &buf, 4); + + return buf; +} + +static void pmic_write_reg(struct pmic_priv *pmic, int reg, uint32_t val) +{ + uint32_t buf = MXC_PMIC_REG_NUM(reg) | MXC_PMIC_WRITE | (val & 0xffffff); + + spi_rw(pmic->spi, &buf, 4); +} + +static struct pmic_priv *pmic_device; + +int pmic_power(void) +{ + if(!pmic_device) { + printf("%s: no pmic device available\n", __FUNCTION__); + return -ENODEV; + } + + pmic_write_reg(pmic_device, REG_SWITCHERS(0), + SWX_VOLTAGE(SWX_VOLTAGE_1_450) | + SWX_VOLTAGE_DVS(SWX_VOLTAGE_1_450) | + SWX_VOLTAGE_STANDBY(SWX_VOLTAGE_1_450)); + + pmic_write_reg(pmic_device, REG_SWITCHERS(4), + SW1A_MODE(SWX_MODE_NO_PULSE_SKIP) | + SW1A_MODE_STANDBY(SWX_MODE_NO_PULSE_SKIP)| + SW1A_SOFTSTART | + SW1B_MODE(SWX_MODE_NO_PULSE_SKIP) | + SW1B_MODE_STANDBY(SWX_MODE_NO_PULSE_SKIP) | + SW1B_SOFTSTART | + SW_PLL_FACTOR(32) + ); + + return 0; +} + +ssize_t pmic_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) +{ + int i = count >> 2; + uint32_t *buf = _buf; + + offset >>= 2; + + while (i) { + *buf = pmic_read_reg(pmic_device, offset); + buf++; + i--; + offset++; + } + + return count; +} + +ssize_t pmic_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags) +{ + int i = count >> 2; + const uint32_t *buf = _buf; + + offset >>= 2; + + while (i) { + pmic_write_reg(pmic_device, offset, *buf); + buf++; + i--; + offset++; + } + + return count; +} + +static struct file_operations pmic_fops = { + .lseek = dev_lseek_default, + .read = pmic_read, + .write = pmic_write, +}; + +static int pmic_probe(struct device_d *dev) +{ + struct spi_device *spi = (struct spi_device *)dev->type_data; + + if (pmic_device) + return -EBUSY; + + pmic_device = xzalloc(sizeof(*pmic_device)); + + pmic_device->cdev.name = "pmic"; + pmic_device->cdev.size = 256; + pmic_device->cdev.dev = dev; + pmic_device->cdev.ops = &pmic_fops; + + spi->mode = SPI_MODE_0 | SPI_CS_HIGH; + spi->bits_per_word = 32; + pmic_device->spi = spi; + + devfs_create(&pmic_device->cdev); + + return 0; +} + +static struct driver_d pmic_driver = { + .name = "mc13783", + .probe = pmic_probe, +}; + +static int pmic_init(void) +{ + register_driver(&pmic_driver); + return 0; +} + +device_initcall(pmic_init); + diff --git a/drivers/mfd/mc13892.c b/drivers/mfd/mc13892.c new file mode 100644 index 0000000..08a439b --- /dev/null +++ b/drivers/mfd/mc13892.c @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * 2009 Marc Kleine-Budde + * + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#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/mfd/mc34704.c b/drivers/mfd/mc34704.c new file mode 100644 index 0000000..a2171b3 --- /dev/null +++ b/drivers/mfd/mc34704.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * 2009 Marc Kleine-Budde + * Copyright (C) 2010 Baruch Siach + * + * 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 +#include +#include +#include +#include + +#include +#include + +#define DRIVERNAME "mc34704" + +#define to_mc34704(a) container_of(a, struct mc34704, cdev) + +static struct mc34704 *mc34704_dev; + +struct mc34704 *mc34704_get(void) +{ + if (!mc34704_dev) + return NULL; + + return mc34704_dev; +} +EXPORT_SYMBOL(mc34704_get); + +int mc34704_reg_read(struct mc34704 *mc34704, u8 reg, u8 *val) +{ + int ret; + + ret = i2c_read_reg(mc34704->client, reg, val, 1); + + return ret == 1 ? 0 : ret; +} +EXPORT_SYMBOL(mc34704_reg_read) + +int mc34704_reg_write(struct mc34704 *mc34704, u8 reg, u8 val) +{ + int ret; + + ret = i2c_write_reg(mc34704->client, reg, &val, 1); + + return ret == 1 ? 0 : ret; +} +EXPORT_SYMBOL(mc34704_reg_write) + +static ssize_t mc34704_read(struct cdev *cdev, void *_buf, size_t count, + ulong offset, ulong flags) +{ + struct mc34704 *priv = to_mc34704(cdev); + u8 *buf = _buf; + size_t i = count; + int err; + + while (i) { + err = mc34704_reg_read(priv, offset, buf); + if (err) + return (ssize_t)err; + buf++; + i--; + offset++; + } + + return count; +} + +static ssize_t mc34704_write(struct cdev *cdev, const void *_buf, size_t count, + ulong offset, ulong flags) +{ + struct mc34704 *mc34704 = to_mc34704(cdev); + const u8 *buf = _buf; + size_t i = count; + int err; + + while (i) { + err = mc34704_reg_write(mc34704, offset, *buf); + if (err) + return (ssize_t)err; + buf++; + i--; + offset++; + } + + return count; +} + +static struct file_operations mc34704_fops = { + .lseek = dev_lseek_default, + .read = mc34704_read, + .write = mc34704_write, +}; + +static int mc34704_probe(struct device_d *dev) +{ + if (mc34704_dev) + return -EBUSY; + + mc34704_dev = xzalloc(sizeof(struct mc34704)); + mc34704_dev->cdev.name = DRIVERNAME; + mc34704_dev->client = to_i2c_client(dev); + mc34704_dev->cdev.size = 256; + mc34704_dev->cdev.dev = dev; + mc34704_dev->cdev.ops = &mc34704_fops; + + devfs_create(&mc34704_dev->cdev); + + return 0; +} + +static struct driver_d mc34704_driver = { + .name = DRIVERNAME, + .probe = mc34704_probe, +}; + +static int mc34704_init(void) +{ + register_driver(&mc34704_driver); + return 0; +} +device_initcall(mc34704_init); diff --git a/drivers/mfd/mc9sdz60.c b/drivers/mfd/mc9sdz60.c new file mode 100644 index 0000000..db208ec --- /dev/null +++ b/drivers/mfd/mc9sdz60.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * 2009 Marc Kleine-Budde + * + * 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 +#include +#include +#include +#include + +#include +#include + +#define DRIVERNAME "mc9sdz60" + +#define to_mc9sdz60(a) container_of(a, struct mc9sdz60, cdev) + +static struct mc9sdz60 *mc_dev; + +struct mc9sdz60 *mc9sdz60_get(void) +{ + if (!mc_dev) + return NULL; + + return mc_dev; +} +EXPORT_SYMBOL(mc9sdz60_get); + +int mc9sdz60_reg_read(struct mc9sdz60 *mc9sdz60, enum mc9sdz60_reg reg, u8 *val) +{ + int ret; + + ret = i2c_read_reg(mc9sdz60->client, reg, val, 1); + + return ret == 1 ? 0 : ret; +} +EXPORT_SYMBOL(mc9sdz60_reg_read) + +int mc9sdz60_reg_write(struct mc9sdz60 *mc9sdz60, enum mc9sdz60_reg reg, u8 val) +{ + int ret; + + ret = i2c_write_reg(mc9sdz60->client, reg, &val, 1); + + return ret == 1 ? 0 : ret; +} +EXPORT_SYMBOL(mc9sdz60_reg_write) + +int mc9sdz60_set_bits(struct mc9sdz60 *mc9sdz60, enum mc9sdz60_reg reg, u8 mask, u8 val) +{ + u8 tmp; + int err; + + err = mc9sdz60_reg_read(mc9sdz60, reg, &tmp); + tmp = (tmp & ~mask) | val; + + if (!err) + err = mc9sdz60_reg_write(mc9sdz60, reg, tmp); + + return err; +} +EXPORT_SYMBOL(mc9sdz60_set_bits); + +static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) +{ + struct mc9sdz60 *mc9sdz60 = to_mc9sdz60(cdev); + u8 *buf = _buf; + size_t i = count; + int err; + + while (i) { + err = mc9sdz60_reg_read(mc9sdz60, 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 mc9sdz60 *mc9sdz60 = to_mc9sdz60(cdev); + const u8 *buf = _buf; + size_t i = count; + int err; + + while (i) { + err = mc9sdz60_reg_write(mc9sdz60, 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 mc9sdz60)); + mc_dev->cdev.name = DRIVERNAME; + mc_dev->client = to_i2c_client(dev); + mc_dev->cdev.size = 64; /* 35 known registers */ + 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/mfd/twl4030.c b/drivers/mfd/twl4030.c new file mode 100644 index 0000000..81bf48b --- /dev/null +++ b/drivers/mfd/twl4030.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2010 Michael Grzeschik + * + * This file is released under the GPLv2 + * + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define DRIVERNAME "twl4030" + +#define to_twl4030(a) container_of(a, struct twl4030, cdev) + +static struct twl4030 *twl_dev; + +struct twl4030 *twl4030_get(void) +{ + if (!twl_dev) + return NULL; + + return twl_dev; +} +EXPORT_SYMBOL(twl4030_get); + +int twl4030_reg_read(struct twl4030 *twl4030, u16 reg, u8 *val) +{ + int ret; + struct i2c_msg xfer_msg[2]; + struct i2c_msg *msg; + int i2c_addr; + unsigned char buf = reg & 0xff; + + i2c_addr = twl4030->client->addr + (reg / 0x100); + + /* [MSG1] fill the register address data */ + msg = &xfer_msg[0]; + msg->addr = i2c_addr; + msg->len = 1; + msg->flags = 0; /* Read the register value */ + msg->buf = &buf; + /* [MSG2] fill the data rx buffer */ + msg = &xfer_msg[1]; + msg->addr = i2c_addr; + msg->flags = I2C_M_RD; /* Read the register value */ + msg->len = 1; /* only n bytes */ + msg->buf = val; + ret = i2c_transfer(twl4030->client->adapter, xfer_msg, 2); + + /* i2c_transfer returns number of messages transferred */ + if (ret < 0) { + pr_err("%s: failed to transfer all messages: %s\n", __func__, strerror(-ret)); + return ret; + } + return 0; +} +EXPORT_SYMBOL(twl4030_reg_read) + +int twl4030_reg_write(struct twl4030 *twl4030, u16 reg, u8 val) +{ + int ret; + struct i2c_msg xfer_msg[1]; + struct i2c_msg *msg; + int i2c_addr; + u8 buf[2]; + + buf[0] = reg & 0xff; + buf[1] = val; + + i2c_addr = twl4030->client->addr + (reg / 0x100); + + /* + * [MSG1]: fill the register address data + * fill the data Tx buffer + */ + msg = xfer_msg; + msg->addr = i2c_addr; + msg->len = 2; + msg->flags = 0; + msg->buf = buf; + /* over write the first byte of buffer with the register address */ + ret = i2c_transfer(twl4030->client->adapter, xfer_msg, 1); + + /* i2c_transfer returns number of messages transferred */ + if (ret < 0) { + pr_err("%s: failed to transfer all messages: %s\n", __func__, strerror(-ret)); + return ret; + } + return 0; +} +EXPORT_SYMBOL(twl4030_reg_write) + +int twl4030_set_bits(struct twl4030 *twl4030, enum twl4030_reg reg, u8 mask, u8 val) +{ + u8 tmp; + int err; + + err = twl4030_reg_read(twl4030, reg, &tmp); + tmp = (tmp & ~mask) | val; + + if (!err) + err = twl4030_reg_write(twl4030, reg, tmp); + + return err; +} +EXPORT_SYMBOL(twl4030_set_bits); + +static ssize_t twl_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) +{ + struct twl4030 *priv = to_twl4030(cdev); + u8 *buf = _buf; + size_t i = count; + int err; + + while (i) { + err = twl4030_reg_read(priv, offset, buf); + if (err) + return (ssize_t)err; + buf++; + i--; + offset++; + } + + return count; +} + +static ssize_t twl_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags) +{ + struct twl4030 *twl4030 = to_twl4030(cdev); + const u8 *buf = _buf; + size_t i = count; + int err; + + while (i) { + err = twl4030_reg_write(twl4030, offset, *buf); + if (err) + return (ssize_t)err; + buf++; + i--; + offset++; + } + + return count; +} + +static struct file_operations twl_fops = { + .lseek = dev_lseek_default, + .read = twl_read, + .write = twl_write, +}; + +static int twl_probe(struct device_d *dev) +{ + if (twl_dev) + return -EBUSY; + + twl_dev = xzalloc(sizeof(struct twl4030)); + twl_dev->cdev.name = DRIVERNAME; + twl_dev->client = to_i2c_client(dev); + twl_dev->cdev.size = 1024; + twl_dev->cdev.dev = dev; + twl_dev->cdev.ops = &twl_fops; + + devfs_create(&twl_dev->cdev); + + return 0; +} + +static struct driver_d twl_driver = { + .name = DRIVERNAME, + .probe = twl_probe, +}; + +static int twl_init(void) +{ + register_driver(&twl_driver); + return 0; +} + +device_initcall(twl_init); diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 475499a..bc95195 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -18,6 +18,22 @@ prompt "Support Starting barebox from NAND" depends on NAND_IMX || NAND_IMX_V2 +choice + depends on NAND_IMX_BOOT + default NAND_IMX_BOOT_512_2K + prompt "select nand pagesize you want to support booting from" + +config NAND_IMX_BOOT_512 + bool "512 byte page size" + +config NAND_IMX_BOOT_2K + bool "2048 byte page size" + +config NAND_IMX_BOOT_512_2K + bool "512 byte and 2048 byte pagesize" + +endchoice + config NAND_OMAP_GPMC tristate "NAND Flash Support for GPMC based OMAP platforms" depends on ((ARCH_OMAP2 || ARCH_OMAP3) && GPMC) diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c index 5454e32..63ba188 100644 --- a/drivers/mtd/nand/nand_imx.c +++ b/drivers/mtd/nand/nand_imx.c @@ -222,7 +222,7 @@ * @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 @@ * * @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 @@ * @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 @@ * @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 @@ }; #ifdef CONFIG_NAND_IMX_BOOT - -static void __nand_boot_init nfc_addr(struct imx_nand_host *host, u32 offs) +static void __nand_boot_init noinline imx_nandboot_wait_op_done(void *regs) { - 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); + 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 imx_nandboot_nfc_addr(void *regs, u32 offs, int pagesize_2k) +{ + 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 @@ *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 - if (host.pagesize_2k) { +} + +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 (pagesize_2k) { pagesize = 2048; blocksize = 128 * 1024; } else { @@ -1079,45 +1157,43 @@ 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 @@ 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 73b7a54..9c8de77 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -216,7 +216,7 @@ * @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_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 @@ sizeof(struct buffer_descriptor) + 2 * DB_ALIGNMENT); base += (DB_ALIGNMENT - 1); base &= ~(DB_ALIGNMENT - 1); - fec->rbd_base = (struct buffer_descriptor *)base; + fec->rbd_base = (struct buffer_descriptor __force __iomem *)base; base += FEC_RBD_NUM * sizeof (struct buffer_descriptor) + (DB_ALIGNMENT - 1); base &= ~(DB_ALIGNMENT - 1); - fec->tbd_base = (struct buffer_descriptor *)base; + fec->tbd_base = (struct buffer_descriptor __force __iomem *)base; writel((uint32_t)virt_to_phys(fec->tbd_base), fec->regs + FEC_ETDSR); writel((uint32_t)virt_to_phys(fec->rbd_base), fec->regs + FEC_ERDSR); diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h index e1473a4..ce0fd89 100644 --- a/drivers/net/fec_imx.h +++ b/drivers/net/fec_imx.h @@ -135,11 +135,11 @@ * @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 c7ea2d9..3a8882f 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -18,6 +18,11 @@ default y bool "i.MX serial driver" +config DRIVER_SERIAL_STM378X + depends on ARCH_STM + default y + bool "i.MX23 serial driver" + config DRIVER_SERIAL_NETX depends on ARCH_NETX default y diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 959290e..9f0e12b 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC) += arm_dcc.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_DRIVER_SERIAL_IMX) += serial_imx.o +obj-$(CONFIG_DRIVER_SERIAL_STM378X) += stm-serial.o obj-$(CONFIG_DRIVER_SERIAL_ATMEL) += atmel.o obj-$(CONFIG_DRIVER_SERIAL_NETX) += serial_netx.o obj-$(CONFIG_DRIVER_SERIAL_LINUX_COMSOLE) += linux_console.o diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c index 801004e..a7562f9 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 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_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 @@ 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 @@ 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 0000000..90563f5 --- /dev/null +++ b/drivers/serial/stm-serial.c @@ -0,0 +1,202 @@ +/* + * (C) Copyright 2010 Juergen Beisert - Pengutronix + * + * This code was inspired by some patches made for u-boot covered by: + * (c) 2007 Sascha Hauer + * (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 +#include +#include +#include +#include +#include +#include + +#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 3eebd08..a88e179 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -9,8 +9,14 @@ 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 81f2c6b..b2b2f67 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -1,4 +1,2 @@ obj-$(CONFIG_SPI) += spi.o obj-$(CONFIG_DRIVER_SPI_IMX) += imx_spi.o - -obj-$(CONFIG_DRIVER_SPI_MC13783) += mc13783.o diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c index 5c97919..2ad1bfa 100644 --- a/drivers/spi/imx_spi.c +++ b/drivers/spi/imx_spi.c @@ -26,47 +26,104 @@ #include #include #include +#include -#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 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 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 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 MXC_CSPICTRL_MAXDATRATE 0x10 -#define MXC_CSPICTRL_DATAMASK 0x1F -#define MXC_CSPICTRL_DATASHIFT 14 +#define CSPI_0_0_CTRL_MAXDATRATE 0x10 +#define CSPI_0_0_CTRL_DATAMASK 0x1F +#define CSPI_0_0_CTRL_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 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 MXC_CSPIPERIOD_32KHZ (1 << 15) +#define CSPI_0_0_PERIOD_32KHZ (1 << 15) -#define MXC_CSPITEST_LBC (1 << 14) +#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 @@ 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 @@ 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 @@ 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 @@ master->setup = imx_spi_setup; master->transfer = imx_spi_transfer; master->num_chipselect = pdata->num_chipselect; - imx->chipselect = pdata->chipselect; + imx->cs_array = pdata->chipselect; - 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); +#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/spi/mc13783.c b/drivers/spi/mc13783.c deleted file mode 100644 index 19e2780..0000000 --- a/drivers/spi/mc13783.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include - -#define REG_INTERRUPT_STATUS_0 0x0 -#define REG_INTERRUPT_MASK 0x1 -#define REG_INTERRUPT_SENSE_0 0x2 -#define REG_INTERRUPT_STATUS_1 0x3 -#define REG_INTERRUPT_MASK_1 0x4 -#define REG_INTERRUPT_SENSE_1 0x5 -#define REG_POWER_UP_MODE_SENSE 0x6 -#define REG_REVISION 0x7 -#define REG_SEMAPHORE 0x8 -#define REG_ARBITRATION_PERIPHERAL_AUDIO 0x9 -#define REG_ARBITRATION_SWITCHERS 0xa -#define REG_ARBITRATION_REGULATORS(x) (0xb + (x)) /* 0 .. 1 */ -#define REG_POWER_CONTROL(x) (0xd + (x)) /* 0 .. 2 */ -#define REG_REGEN_ASSIGNMENT 0x10 -#define REG_CONTROL_SPARE 0x11 -#define REG_MEMORY_A 0x12 -#define REG_MEMORY_B 0x13 -#define REG_RTC_TIME 0x14 -#define REG_RTC_ALARM 0x15 -#define REG_RTC_DAY 0x16 -#define REG_RTC_DAY_ALARM 0x17 -#define REG_SWITCHERS(x) (0x18 + (x)) /* 0 .. 5 */ -#define REG_REGULATOR_SETTING(x) (0x1e + (x)) /* 0 .. 1 */ -#define REG_REGULATOR_MODE(x) (0x20 + (x)) /* 0 .. 1 */ -#define REG_POWER_MISCELLANEOUS 0x22 -#define REG_POWER_SPARE 0x23 -#define REG_AUDIO_RX_0 0x24 -#define REG_AUDIO_RX_1 0x25 -#define REG_AUDIO_TX 0x26 -#define REG_AUDIO_SSI_NETWORK 0x27 -#define REG_AUDIO_CODEC 0x28 -#define REG_AUDIO_STEREO_DAC 0x29 -#define REG_AUDIO_SPARE 0x2a -#define REG_ADC(x) (0x2b + (x)) /* 0 .. 4 */ -#define REG_CHARGER 0x30 -#define REG_USB 0x31 -#define REG_CHARGE_USB_SPARE 0x32 -#define REG_LED_CONTROL(x) (0x33 + (x)) /* 0 .. 5 */ -#define REG_SPARE 0x39 -#define REG_TRIM(x) (0x3a + (x)) /* 0 .. 1 */ -#define REG_TEST(x) (0x3c + (x)) /* 0 .. 3 */ - -#define MXC_PMIC_REG_NUM(reg) (((reg) & 0x3f) << 25) -#define MXC_PMIC_WRITE (1 << 31) - -#define SWX_VOLTAGE(x) ((x) & 0x3f) -#define SWX_VOLTAGE_DVS(x) (((x) & 0x3f) << 6) -#define SWX_VOLTAGE_STANDBY(x) (((x) & 0x3f) << 12) -#define SWX_VOLTAGE_1_450 0x16 - -#define SWX_MODE_OFF 0 -#define SWX_MODE_NO_PULSE_SKIP 1 -#define SWX_MODE_PULSE_SKIP 2 -#define SWX_MODE_LOW_POWER_PFM 3 - -#define SW1A_MODE(x) (((x) & 0x3) << 0) -#define SW1A_MODE_STANDBY(x) (((x) & 0x3) << 2) -#define SW1B_MODE(x) (((x) & 0x3) << 10) -#define SW1B_MODE_STANDBY(x) (((x) & 0x3) << 12) -#define SW1A_SOFTSTART (1 << 9) -#define SW1B_SOFTSTART (1 << 17) -#define SW_PLL_FACTOR(x) (((x) - 28) << 19) - -struct pmic_priv { - struct cdev cdev; - struct spi_device *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; -} - -static uint32_t pmic_read_reg(struct pmic_priv *pmic, int reg) -{ - uint32_t buf; - - buf = MXC_PMIC_REG_NUM(reg); - - spi_rw(pmic->spi, &buf, 4); - - return buf; -} - -static void pmic_write_reg(struct pmic_priv *pmic, int reg, uint32_t val) -{ - uint32_t buf = MXC_PMIC_REG_NUM(reg) | MXC_PMIC_WRITE | (val & 0xffffff); - - spi_rw(pmic->spi, &buf, 4); -} - -static struct pmic_priv *pmic_device; - -int pmic_power(void) -{ - if(!pmic_device) { - printf("%s: no pmic device available\n", __FUNCTION__); - return -ENODEV; - } - - pmic_write_reg(pmic_device, REG_SWITCHERS(0), - SWX_VOLTAGE(SWX_VOLTAGE_1_450) | - SWX_VOLTAGE_DVS(SWX_VOLTAGE_1_450) | - SWX_VOLTAGE_STANDBY(SWX_VOLTAGE_1_450)); - - pmic_write_reg(pmic_device, REG_SWITCHERS(4), - SW1A_MODE(SWX_MODE_NO_PULSE_SKIP) | - SW1A_MODE_STANDBY(SWX_MODE_NO_PULSE_SKIP)| - SW1A_SOFTSTART | - SW1B_MODE(SWX_MODE_NO_PULSE_SKIP) | - SW1B_MODE_STANDBY(SWX_MODE_NO_PULSE_SKIP) | - SW1B_SOFTSTART | - SW_PLL_FACTOR(32) - ); - - return 0; -} - -ssize_t pmic_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) -{ - int i = count >> 2; - uint32_t *buf = _buf; - - offset >>= 2; - - while (i) { - *buf = pmic_read_reg(pmic_device, offset); - buf++; - i--; - offset++; - } - - return count; -} - -ssize_t pmic_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags) -{ - int i = count >> 2; - const uint32_t *buf = _buf; - - offset >>= 2; - - while (i) { - pmic_write_reg(pmic_device, offset, *buf); - buf++; - i--; - offset++; - } - - return count; -} - -static struct file_operations pmic_fops = { - .lseek = dev_lseek_default, - .read = pmic_read, - .write = pmic_write, -}; - -static int pmic_probe(struct device_d *dev) -{ - struct spi_device *spi = (struct spi_device *)dev->type_data; - - if (pmic_device) - return -EBUSY; - - pmic_device = xzalloc(sizeof(*pmic_device)); - - pmic_device->cdev.name = "pmic"; - pmic_device->cdev.size = 256; - pmic_device->cdev.dev = dev; - pmic_device->cdev.ops = &pmic_fops; - - spi->mode = SPI_MODE_0 | SPI_CS_HIGH; - spi->bits_per_word = 32; - pmic_device->spi = spi; - - devfs_create(&pmic_device->cdev); - - return 0; -} - -static struct driver_d pmic_driver = { - .name = "mc13783", - .probe = pmic_probe, -}; - -static int pmic_init(void) -{ - register_driver(&pmic_driver); - return 0; -} - -device_initcall(pmic_init); - diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c index 119afcb..48fd0b5 100644 --- a/drivers/usb/gadget/fsl_udc.c +++ b/drivers/usb/gadget/fsl_udc.c @@ -563,7 +563,8 @@ 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 0c30c52..05f1628 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -11,7 +11,7 @@ /*-------------------------------------------------------------------------*/ -#include +#include #include #include #include diff --git a/drivers/usb/otg/twl4030.c b/drivers/usb/otg/twl4030.c index 72edf25..4077169 100644 --- a/drivers/usb/otg/twl4030.c +++ b/drivers/usb/otg/twl4030.c @@ -37,7 +37,7 @@ * MA 02111-1307 USA */ -#include +#include #include #include diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c index 2c25b81..c38082d 100644 --- a/drivers/video/imx-ipu-fb.c +++ b/drivers/video/imx-ipu-fb.c @@ -722,55 +722,11 @@ 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 @@ ~(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 @@ struct ipu_fb_info *fbi = info->priv; u32 reg; - printf("%s\n", __func__); - if (fbi->enable) fbi->enable(0); @@ -855,6 +812,39 @@ .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 @@ 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 9ecb824..6222550 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -420,7 +420,7 @@ 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 1d3f4f7..fc141a4 100644 --- a/include/asm-generic/barebox.lds.h +++ b/include/asm-generic/barebox.lds.h @@ -1,5 +1,5 @@ -#if defined CONFIG_ARCH_IMX25 || defined CONFIG_ARCH_IMX35 +#if defined CONFIG_ARCH_IMX25 || defined CONFIG_ARCH_IMX35 || defined CONFIG_ARCH_IMX51 #include #endif diff --git a/include/cache.h b/include/cache.h index 5968da9..23841dc 100644 --- a/include/cache.h +++ b/include/cache.h @@ -1,7 +1,6 @@ #ifndef __CACHE_H #define __CACHE_H -void flush_cache (unsigned long, unsigned long); int icache_status (void); void icache_enable (void); void icache_disable(void); diff --git a/include/command.h b/include/command.h index 4a4d9cf..e221546 100644 --- a/include/command.h +++ b/include/command.h @@ -76,22 +76,36 @@ #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 64f49db..394542f 100644 --- a/include/common.h +++ b/include/common.h @@ -216,4 +216,8 @@ #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/i2c/lp3972.h b/include/i2c/lp3972.h deleted file mode 100644 index edb5801..0000000 --- a/include/i2c/lp3972.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_ARCH_LP3972_H -#define __ASM_ARCH_LP3972_H - -extern struct i2c_client *lp3972_get_client(void); - -#endif /* __ASM_ARCH_LP3972_H */ - diff --git a/include/i2c/mc13892.h b/include/i2c/mc13892.h deleted file mode 100644 index 112d05b..0000000 --- a/include/i2c/mc13892.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2009 Marc Kleine-Budde - * - * This file is released under the GPLv2 - * - * Derived from: - * - arch-mxc/pmic_external.h -- contains interface of the PMIC protocol driver - * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. - * - */ - -#ifndef __ASM_ARCH_MC13892_H -#define __ASM_ARCH_MC13892_H - -enum mc13892_reg { - MC13892_REG_INT_STATUS0 = 0x00, - MC13892_REG_INT_MASK0 = 0x01, - MC13892_REG_INT_SENSE0 = 0x02, - MC13892_REG_INT_STATUS1 = 0x03, - MC13892_REG_INT_MASK1 = 0x04, - MC13892_REG_INT_SENSE1 = 0x05, - MC13892_REG_PU_MODE_S = 0x06, - MC13892_REG_IDENTIFICATION = 0x07, - MC13892_REG_UNUSED0 = 0x08, - MC13892_REG_ACC0 = 0x09, - MC13892_REG_ACC1 = 0x0a, - MC13892_REG_UNUSED1 = 0x0b, - MC13892_REG_UNUSED2 = 0x0c, - MC13892_REG_POWER_CTL0 = 0x0d, - MC13892_REG_POWER_CTL1 = 0x0e, - MC13892_REG_POWER_CTL2 = 0x0f, - MC13892_REG_REGEN_ASSIGN = 0x10, - MC13892_REG_UNUSED3 = 0x11, - MC13892_REG_MEM_A = 0x12, - MC13892_REG_MEM_B = 0x13, - MC13892_REG_RTC_TIME = 0x14, - MC13892_REG_RTC_ALARM = 0x15, - MC13892_REG_RTC_DAY = 0x16, - MC13892_REG_RTC_DAY_ALARM = 0x17, - MC13892_REG_SW_0 = 0x18, - MC13892_REG_SW_1 = 0x19, - MC13892_REG_SW_2 = 0x1a, - MC13892_REG_SW_3 = 0x1b, - MC13892_REG_SW_4 = 0x1c, - MC13892_REG_SW_5 = 0x1d, - MC13892_REG_SETTING_0 = 0x1e, - MC13892_REG_SETTING_1 = 0x1f, - MC13892_REG_MODE_0 = 0x20, - MC13892_REG_MODE_1 = 0x21, - MC13892_REG_POWER_MISC = 0x22, - MC13892_REG_UNUSED4 = 0x23, - MC13892_REG_UNUSED5 = 0x24, - MC13892_REG_UNUSED6 = 0x25, - MC13892_REG_UNUSED7 = 0x26, - MC13892_REG_UNUSED8 = 0x27, - MC13892_REG_UNUSED9 = 0x28, - MC13892_REG_UNUSED10 = 0x29, - MC13892_REG_UNUSED11 = 0x2a, - MC13892_REG_ADC0 = 0x2b, - MC13892_REG_ADC1 = 0x2c, - MC13892_REG_ADC2 = 0x2d, - MC13892_REG_ADC3 = 0x2e, - MC13892_REG_ADC4 = 0x2f, - MC13892_REG_CHARGE = 0x30, - MC13892_REG_USB0 = 0x31, - MC13892_REG_USB1 = 0x32, - MC13892_REG_LED_CTL0 = 0x33, - MC13892_REG_LED_CTL1 = 0x34, - MC13892_REG_LED_CTL2 = 0x35, - MC13892_REG_LED_CTL3 = 0x36, - MC13892_REG_UNUSED12 = 0x37, - MC13892_REG_UNUSED13 = 0x38, - MC13892_REG_TRIM0 = 0x39, - MC13892_REG_TRIM1 = 0x3a, - MC13892_REG_TEST0 = 0x3b, - MC13892_REG_TEST1 = 0x3c, - MC13892_REG_TEST2 = 0x3d, - MC13892_REG_TEST3 = 0x3e, - MC13892_REG_TEST4 = 0x3f, -}; - -struct mc13892 { - struct cdev cdev; - struct i2c_client *client; -}; - -extern struct mc13892 *mc13892_get(void); - -extern int mc13892_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val); -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); - -#endif /* __ASM_ARCH_MC13892_H */ diff --git a/include/i2c/mc34704.h b/include/i2c/mc34704.h deleted file mode 100644 index a3723d7..0000000 --- a/include/i2c/mc34704.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2009 Marc Kleine-Budde - * Copyright (C) 2010 Baruch Siach - * - * This file is released under the GPLv2 - * - * Derived from: - * - arch-mxc/pmic_external.h -- contains interface of the PMIC protocol driver - * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. - * - */ - -#ifndef __I2C_MC34704_H -#define __I2C_MC34704_H - -struct mc34704 { - struct cdev cdev; - struct i2c_client *client; -}; - -extern struct mc34704 *mc34704_get(void); - -extern int mc34704_reg_read(struct mc34704 *mc34704, u8 reg, u8 *val); -extern int mc34704_reg_write(struct mc34704 *mc34704, u8 reg, u8 val); - -#endif /* __I2C_MC34704_H */ diff --git a/include/i2c/mc9sdz60.h b/include/i2c/mc9sdz60.h deleted file mode 100644 index 3882cea..0000000 --- a/include/i2c/mc9sdz60.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2009 Marc Kleine-Budde - * - * This file is released under the GPLv2 - * - * Derived from: - * - mcu_max8660-bus.h -- contains interface of the mc9sdz60 and max8660 - * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. - * - */ - -#ifndef __ASM_ARCH_MC9SDZ60_H -#define __ASM_ARCH_MC9SDZ60_H - -/** - * Register addresses for the MC9SDZ60 - * - * @note: these match those in the kernel drivers/mxc/mcu_pmic/mc9s08dz60.h - * but not include/linux/mfd/mc9s08dz60/pmic.h - * - */ -enum mc9sdz60_reg { - MC9SDZ60_REG_VERSION = 0x00, - /* reserved 0x01 */ - MC9SDZ60_REG_SECS = 0x02, - MC9SDZ60_REG_MINS = 0x03, - MC9SDZ60_REG_HRS = 0x04, - MC9SDZ60_REG_DAY = 0x05, - MC9SDZ60_REG_DATE = 0x06, - MC9SDZ60_REG_MONTH = 0x07, - MC9SDZ60_REG_YEAR = 0x08, - MC9SDZ60_REG_ALARM_SECS = 0x09, - MC9SDZ60_REG_ALARM_MINS = 0x0a, - MC9SDZ60_REG_ALARM_HRS = 0x0b, - /* reserved 0x0c */ - /* reserved 0x0d */ - MC9SDZ60_REG_TS_CONTROL = 0x0e, - MC9SDZ60_REG_X_LOW = 0x0f, - MC9SDZ60_REG_Y_LOW = 0x10, - MC9SDZ60_REG_XY_HIGH = 0x11, - MC9SDZ60_REG_X_LEFT_LOW = 0x12, - MC9SDZ60_REG_X_LEFT_HIGH = 0x13, - MC9SDZ60_REG_X_RIGHT = 0x14, - MC9SDZ60_REG_Y_TOP_LOW = 0x15, - MC9SDZ60_REG_Y_TOP_HIGH = 0x16, - MC9SDZ60_REG_Y_BOTTOM = 0x17, - /* reserved 0x18 */ - /* reserved 0x19 */ - MC9SDZ60_REG_RESET_1 = 0x1a, - MC9SDZ60_REG_RESET_2 = 0x1b, - MC9SDZ60_REG_POWER_CTL = 0x1c, - MC9SDZ60_REG_DELAY_CONFIG = 0x1d, - /* reserved 0x1e */ - /* reserved 0x1f */ - MC9SDZ60_REG_GPIO_1 = 0x20, - MC9SDZ60_REG_GPIO_2 = 0x21, - MC9SDZ60_REG_KPD_1 = 0x22, - MC9SDZ60_REG_KPD_2 = 0x23, - MC9SDZ60_REG_KPD_CONTROL = 0x24, - MC9SDZ60_REG_INT_ENABLE_1 = 0x25, - MC9SDZ60_REG_INT_ENABLE_2 = 0x26, - MC9SDZ60_REG_INT_FLAG_1 = 0x27, - MC9SDZ60_REG_INT_FLAG_2 = 0x28, - MC9SDZ60_REG_DES_FLAG = 0x29, -}; - -struct mc9sdz60 { - struct cdev cdev; - struct i2c_client *client; -}; - -extern struct mc9sdz60 *mc9sdz60_get(void); - -extern int mc9sdz60_reg_read(struct mc9sdz60 *priv, enum mc9sdz60_reg reg, u8 *val); -extern int mc9sdz60_reg_write(struct mc9sdz60 *priv, enum mc9sdz60_reg reg, u8 val); -extern int mc9sdz60_set_bits(struct mc9sdz60 *priv, enum mc9sdz60_reg reg, u8 mask, u8 val); - -#endif /* __ASM_ARCH_MC9SDZ60_H */ diff --git a/include/i2c/twl4030.h b/include/i2c/twl4030.h deleted file mode 100644 index 3fef4d9..0000000 --- a/include/i2c/twl4030.h +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (C) 2010 Michael Grzeschik - * Copyright (C) 2010 Sascha Hauer - * - * This file is released under the GPLv2 - * - */ - -#ifndef __I2C_TWL4030_H -#define __I2C_TWL4030_H - -#include -#include -#include - -/* LED */ -#define TWL4030_LED_LEDEN_LEDAON (1 << 0) -#define TWL4030_LED_LEDEN_LEDBON (1 << 1) -#define TWL4030_LED_LEDEN_LEDAPWM (1 << 4) -#define TWL4030_LED_LEDEN_LEDBPWM (1 << 5) - -/* KEYPAD */ -#define TWL4030_KEYPAD_CTRL_KBD_ON (1 << 6) -#define TWL4030_KEYPAD_CTRL_RP_EN (1 << 5) -#define TWL4030_KEYPAD_CTRL_TOLE_EN (1 << 4) -#define TWL4030_KEYPAD_CTRL_TOE_EN (1 << 3) -#define TWL4030_KEYPAD_CTRL_LK_EN (1 << 2) -#define TWL4030_KEYPAD_CTRL_SOFTMODEN (1 << 1) -#define TWL4030_KEYPAD_CTRL_SOFT_NRST (1 << 0) - -/* P[1-3]_SW_EVENTS */ -#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_PWRON (1 << 6) -#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_SYSEN (1 << 5) -#define TWL4030_PM_MASTER_SW_EVENTS_ENABLE_WARMRESET (1 << 4) -#define TWL4030_PM_MASTER_SW_EVENTS_LVL_WAKEUP (1 << 3) -#define TWL4030_PM_MASTER_SW_EVENTS_DEVACT (1 << 2) -#define TWL4030_PM_MASTER_SW_EVENTS_DEVSLP (1 << 1) -#define TWL4030_PM_MASTER_SW_EVENTS_DEVOFF (1 << 0) - - -enum twl4030_reg { - /* Register base addresses */ - /* USB */ - TWL4030_BASEADD_USB = 0x0000, - /* AUD */ - TWL4030_BASEADD_AUDIO_VOICE = 0x0100, - TWL4030_BASEADD_GPIO = 0x0198, - TWL4030_BASEADD_INTBR = 0x0185, - TWL4030_BASEADD_PIH = 0x0180, - TWL4030_BASEADD_TEST = 0x014C, - /* AUX */ - TWL4030_BASEADD_INTERRUPTS = 0x02B9, - TWL4030_BASEADD_LED = 0x02EE, - TWL4030_BASEADD_MADC = 0x0200, - TWL4030_BASEADD_MAIN_CHARGE = 0x0274, - TWL4030_BASEADD_PRECHARGE = 0x02AA, - TWL4030_BASEADD_PWM0 = 0x02F8, - TWL4030_BASEADD_PWM1 = 0x02FB, - TWL4030_BASEADD_PWMA = 0x02EF, - TWL4030_BASEADD_PWMB = 0x02F1, - TWL4030_BASEADD_KEYPAD = 0x02D2, - /* POWER */ - TWL4030_BASEADD_BACKUP = 0x0314, - TWL4030_BASEADD_INT = 0x032E, - TWL4030_BASEADD_PM_MASTER = 0x0336, - TWL4030_BASEADD_PM_RECIEVER = 0x035B, - TWL4030_BASEADD_RTC = 0x031C, - TWL4030_BASEADD_SECURED_REG = 0x0300, - - /* LED */ - TWL4030_LED_LEDEN = 0x02EE, - - /* - * Voltage Selection in PM Receiver Module - */ - TWL4030_PM_RECEIVER_VAUX2_VSEL_18 = 0x05, - TWL4030_PM_RECEIVER_VAUX3_VSEL_28 = 0x03, - TWL4030_PM_RECEIVER_VPLL2_VSEL_18 = 0x05, - TWL4030_PM_RECEIVER_VDAC_VSEL_18 = 0x03, - TWL4030_PM_RECEIVER_VMMC1_VSEL_30 = 0x02, - - /* - * Device Selection in PM Receiver Module - */ - TWL4030_PM_RECEIVER_DEV_GRP_P1 = 0x20, - TWL4030_PM_RECEIVER_DEV_GRP_ALL = 0xE0, - - /* - * Power Management Master - */ - TWL4030_PM_MASTER_CFG_P1_TRANSITION = 0x0336, - TWL4030_PM_MASTER_CFG_P2_TRANSITION = 0x0337, - TWL4030_PM_MASTER_CFG_P3_TRANSITION = 0x0338, - TWL4030_PM_MASTER_CFG_P123_TRANSITION = 0x0339, - TWL4030_PM_MASTER_STS_BOOT = 0x033A, - TWL4030_PM_MASTER_CFG_BOOT = 0x033B, - TWL4030_PM_MASTER_SHUNDAN = 0x033C, - TWL4030_PM_MASTER_BOOT_BCI = 0x033D, - TWL4030_PM_MASTER_CFG_PWRANA1 = 0x033E, - TWL4030_PM_MASTER_CFG_PWRANA2 = 0x033F, - TWL4030_PM_MASTER_BGAP_TRIM = 0x0340, - TWL4030_PM_MASTER_BACKUP_MISC_STS = 0x0341, - TWL4030_PM_MASTER_BACKUP_MISC_CFG = 0x0342, - TWL4030_PM_MASTER_BACKUP_MISC_TST = 0x0343, - TWL4030_PM_MASTER_PROTECT_KEY = 0x0344, - TWL4030_PM_MASTER_STS_HW_CONDITIONS = 0x0345, - TWL4030_PM_MASTER_P1_SW_EVENTS = 0x0346, - TWL4030_PM_MASTER_P2_SW_EVENTS = 0x0347, - TWL4030_PM_MASTER_P3_SW_EVENTS = 0x0348, - TWL4030_PM_MASTER_STS_P123_STATE = 0x0349, - TWL4030_PM_MASTER_PB_CFG = 0x034A, - TWL4030_PM_MASTER_PB_WORD_MSB = 0x034B, - TWL4030_PM_MASTER_PB_WORD_LSB = 0x034C, - TWL4030_PM_MASTER_SEQ_ADD_W2P = 0x0352, - TWL4030_PM_MASTER_SEQ_ADD_P2A = 0x0353, - TWL4030_PM_MASTER_SEQ_ADD_A2W = 0x0354, - TWL4030_PM_MASTER_SEQ_ADD_A2S = 0x0355, - TWL4030_PM_MASTER_SEQ_ADD_S2A12 = 0x0356, - TWL4030_PM_MASTER_SEQ_ADD_S2A3 = 0x0357, - TWL4030_PM_MASTER_SEQ_ADD_WARM = 0x0358, - TWL4030_PM_MASTER_MEMORY_ADDRESS = 0x0359, - TWL4030_PM_MASTER_MEMORY_DATA = 0x035A, - TWL4030_PM_MASTER_SC_CONFIG = 0x035B, - TWL4030_PM_MASTER_SC_DETECT1 = 0x035C, - TWL4030_PM_MASTER_SC_DETECT2 = 0x035D, - TWL4030_PM_MASTER_WATCHDOG_CFG = 0x035E, - TWL4030_PM_MASTER_IT_CHECK_CFG = 0x035F, - TWL4030_PM_MASTER_VIBRATOR_CFG = 0x0360, - TWL4030_PM_MASTER_DCDC_GLOBAL_CFG = 0x0361, - TWL4030_PM_MASTER_VDD1_TRIM1 = 0x0362, - TWL4030_PM_MASTER_VDD1_TRIM2 = 0x0363, - TWL4030_PM_MASTER_VDD2_TRIM1 = 0x0364, - TWL4030_PM_MASTER_VDD2_TRIM2 = 0x0365, - TWL4030_PM_MASTER_VIO_TRIM1 = 0x0366, - TWL4030_PM_MASTER_VIO_TRIM2 = 0x0367, - TWL4030_PM_MASTER_MISC_CFG = 0x0368, - TWL4030_PM_MASTER_LS_TST_A = 0x0369, - TWL4030_PM_MASTER_LS_TST_B = 0x036A, - TWL4030_PM_MASTER_LS_TST_C = 0x036B, - TWL4030_PM_MASTER_LS_TST_D = 0x036C, - TWL4030_PM_MASTER_BB_CFG = 0x036D, - TWL4030_PM_MASTER_MISC_TST = 0x036E, - TWL4030_PM_MASTER_TRIM1 = 0x036F, - - /* Power Managment Receiver */ - TWL4030_PM_RECEIVER_SC_CONFIG = 0x035B, - TWL4030_PM_RECEIVER_SC_DETECT1 = 0x035C, - TWL4030_PM_RECEIVER_SC_DETECT2 = 0x035D, - TWL4030_PM_RECEIVER_WATCHDOG_CFG = 0x035E, - TWL4030_PM_RECEIVER_IT_CHECK_CFG = 0x035F, - TWL4030_PM_RECEIVER_VIBRATOR_CFG = 0x035F, - TWL4030_PM_RECEIVER_DC_TO_DC_CFG = 0x0361, - TWL4030_PM_RECEIVER_VDD1_TRIM1 = 0x0362, - TWL4030_PM_RECEIVER_VDD1_TRIM2 = 0x0363, - TWL4030_PM_RECEIVER_VDD2_TRIM1 = 0x0364, - TWL4030_PM_RECEIVER_VDD2_TRIM2 = 0x0365, - TWL4030_PM_RECEIVER_VIO_TRIM1 = 0x0366, - TWL4030_PM_RECEIVER_VIO_TRIM2 = 0x0367, - TWL4030_PM_RECEIVER_MISC_CFG = 0x0368, - TWL4030_PM_RECEIVER_LS_TST_A = 0x0369, - TWL4030_PM_RECEIVER_LS_TST_B = 0x036A, - TWL4030_PM_RECEIVER_LS_TST_C = 0x036B, - TWL4030_PM_RECEIVER_LS_TST_D = 0x036C, - TWL4030_PM_RECEIVER_BB_CFG = 0x036D, - TWL4030_PM_RECEIVER_MISC_TST = 0x036E, - TWL4030_PM_RECEIVER_TRIM1 = 0x036F, - TWL4030_PM_RECEIVER_TRIM2 = 0x0370, - TWL4030_PM_RECEIVER_DC_DC_TIMEOUT = 0x0371, - TWL4030_PM_RECEIVER_VAUX1_DEV_GRP = 0x0372, - TWL4030_PM_RECEIVER_VAUX1_TYPE = 0x0373, - TWL4030_PM_RECEIVER_VAUX1_REMAP = 0x0374, - TWL4030_PM_RECEIVER_VAUX1_DEDICATED = 0x0375, - TWL4030_PM_RECEIVER_VAUX2_DEV_GRP = 0x0376, - TWL4030_PM_RECEIVER_VAUX2_TYPE = 0x0377, - TWL4030_PM_RECEIVER_VAUX2_REMAP = 0x0378, - TWL4030_PM_RECEIVER_VAUX2_DEDICATED = 0x0379, - TWL4030_PM_RECEIVER_VAUX3_DEV_GRP = 0x037A, - TWL4030_PM_RECEIVER_VAUX3_TYPE = 0x037B, - TWL4030_PM_RECEIVER_VAUX3_REMAP = 0x037C, - TWL4030_PM_RECEIVER_VAUX3_DEDICATED = 0x037D, - TWL4030_PM_RECEIVER_VAUX4_DEV_GRP = 0x037E, - TWL4030_PM_RECEIVER_VAUX4_TYPE = 0x037F, - TWL4030_PM_RECEIVER_VAUX4_REMAP = 0x0380, - TWL4030_PM_RECEIVER_VAUX4_DEDICATED = 0x0381, - TWL4030_PM_RECEIVER_VMMC1_DEV_GRP = 0x0382, - TWL4030_PM_RECEIVER_VMMC1_TYPE = 0x0383, - TWL4030_PM_RECEIVER_VMMC1_REMAP = 0x0384, - TWL4030_PM_RECEIVER_VMMC1_DEDICATED = 0x0385, - TWL4030_PM_RECEIVER_VMMC2_DEV_GRP = 0x0386, - TWL4030_PM_RECEIVER_VMMC2_TYPE = 0x0387, - TWL4030_PM_RECEIVER_VMMC2_REMAP = 0x0388, - TWL4030_PM_RECEIVER_VMMC2_DEDICATED = 0x0389, - TWL4030_PM_RECEIVER_VPLL1_DEV_GRP = 0x038A, - TWL4030_PM_RECEIVER_VPLL1_TYPE = 0x038B, - TWL4030_PM_RECEIVER_VPLL1_REMAP = 0x038C, - TWL4030_PM_RECEIVER_VPLL1_DEDICATED = 0x038D, - TWL4030_PM_RECEIVER_VPLL2_DEV_GRP = 0x038E, - TWL4030_PM_RECEIVER_VPLL2_TYPE = 0x038F, - TWL4030_PM_RECEIVER_VPLL2_REMAP = 0x0390, - TWL4030_PM_RECEIVER_VPLL2_DEDICATED = 0x0391, - TWL4030_PM_RECEIVER_VSIM_DEV_GRP = 0x0392, - TWL4030_PM_RECEIVER_VSIM_TYPE = 0x0393, - TWL4030_PM_RECEIVER_VSIM_REMAP = 0x0394, - TWL4030_PM_RECEIVER_VSIM_DEDICATED = 0x0395, - TWL4030_PM_RECEIVER_VDAC_DEV_GRP = 0x0396, - TWL4030_PM_RECEIVER_VDAC_TYPE = 0x0397, - TWL4030_PM_RECEIVER_VDAC_REMAP = 0x0398, - TWL4030_PM_RECEIVER_VDAC_DEDICATED = 0x0399, - TWL4030_PM_RECEIVER_VINTANA1_DEV_GRP = 0x039A, - TWL4030_PM_RECEIVER_VINTANA1_TYP = 0x039B, - TWL4030_PM_RECEIVER_VINTANA1_REMAP = 0x039C, - TWL4030_PM_RECEIVER_VINTANA1_DEDICATED = 0x039D, - TWL4030_PM_RECEIVER_VINTANA2_DEV_GRP = 0x039E, - TWL4030_PM_RECEIVER_VINTANA2_TYPE = 0x039F, - TWL4030_PM_RECEIVER_VINTANA2_REMAP = 0x03A0, - TWL4030_PM_RECEIVER_VINTANA2_DEDICATED = 0x03A1, - TWL4030_PM_RECEIVER_VINTDIG_DEV_GRP = 0x03A2, - TWL4030_PM_RECEIVER_VINTDIG_TYPE = 0x03A3, - TWL4030_PM_RECEIVER_VINTDIG_REMAP = 0x03A4, - TWL4030_PM_RECEIVER_VINTDIG_DEDICATED = 0x03A5, - TWL4030_PM_RECEIVER_VIO_DEV_GRP = 0x03A6, - TWL4030_PM_RECEIVER_VIO_TYPE = 0x03A7, - TWL4030_PM_RECEIVER_VIO_REMAP = 0x03A8, - TWL4030_PM_RECEIVER_VIO_CFG = 0x03A9, - TWL4030_PM_RECEIVER_VIO_MISC_CFG = 0x03AA, - TWL4030_PM_RECEIVER_VIO_TEST1 = 0x03AB, - TWL4030_PM_RECEIVER_VIO_TEST2 = 0x03AC, - TWL4030_PM_RECEIVER_VIO_OSC = 0x03AD, - TWL4030_PM_RECEIVER_VIO_RESERVED = 0x03AE, - TWL4030_PM_RECEIVER_VIO_VSEL = 0x03AF, - TWL4030_PM_RECEIVER_VDD1_DEV_GRP = 0x03B0, - TWL4030_PM_RECEIVER_VDD1_TYPE = 0x03B1, - TWL4030_PM_RECEIVER_VDD1_REMAP = 0x03B2, - TWL4030_PM_RECEIVER_VDD1_CFG = 0x03B3, - TWL4030_PM_RECEIVER_VDD1_MISC_CFG = 0x03B4, - TWL4030_PM_RECEIVER_VDD1_TEST1 = 0x03B5, - TWL4030_PM_RECEIVER_VDD1_TEST2 = 0x03B6, - TWL4030_PM_RECEIVER_VDD1_OSC = 0x03B7, - TWL4030_PM_RECEIVER_VDD1_RESERVED = 0x03B8, - TWL4030_PM_RECEIVER_VDD1_VSEL = 0x03B9, - TWL4030_PM_RECEIVER_VDD1_VMODE_CFG = 0x03BA, - TWL4030_PM_RECEIVER_VDD1_VFLOOR = 0x03BB, - TWL4030_PM_RECEIVER_VDD1_VROOF = 0x03BC, - TWL4030_PM_RECEIVER_VDD1_STEP = 0x03BD, - TWL4030_PM_RECEIVER_VDD2_DEV_GRP = 0x03BE, - TWL4030_PM_RECEIVER_VDD2_TYPE = 0x03BF, - TWL4030_PM_RECEIVER_VDD2_REMAP = 0x03C0, - TWL4030_PM_RECEIVER_VDD2_CFG = 0x03C1, - TWL4030_PM_RECEIVER_VDD2_MISC_CFG = 0x03C2, - TWL4030_PM_RECEIVER_VDD2_TEST1 = 0x03C3, - TWL4030_PM_RECEIVER_VDD2_TEST2 = 0x03C4, - TWL4030_PM_RECEIVER_VDD2_OSC = 0x03C5, - TWL4030_PM_RECEIVER_VDD2_RESERVED = 0x03C6, - TWL4030_PM_RECEIVER_VDD2_VSEL = 0x03C7, - TWL4030_PM_RECEIVER_VDD2_VMODE_CFG = 0x03C8, - TWL4030_PM_RECEIVER_VDD2_VFLOOR = 0x03C9, - TWL4030_PM_RECEIVER_VDD2_VROOF = 0x03CA, - TWL4030_PM_RECEIVER_VDD2_STEP = 0x03CB, - TWL4030_PM_RECEIVER_VUSB1V5_DEV_GRP = 0x03CC, - TWL4030_PM_RECEIVER_VUSB1V5_TYPE = 0x03CD, - TWL4030_PM_RECEIVER_VUSB1V5_REMAP = 0x03CE, - TWL4030_PM_RECEIVER_VUSB1V8_DEV_GRP = 0x03CF, - TWL4030_PM_RECEIVER_VUSB1V8_TYPE = 0x03D0, - TWL4030_PM_RECEIVER_VUSB1V8_REMAP = 0x03D1, - TWL4030_PM_RECEIVER_VUSB3V1_DEV_GRP = 0x03D2, - TWL4030_PM_RECEIVER_VUSB3V1_TYPE = 0x03D3, - TWL4030_PM_RECEIVER_VUSB3V1_REMAP = 0x03D4, - TWL4030_PM_RECEIVER_VUSBCP_DEV_GRP = 0x03D5, - TWL4030_PM_RECEIVER_VUSBCP_TYPE = 0x03D6, - TWL4030_PM_RECEIVER_VUSBCP_REMAP = 0x03D7, - TWL4030_PM_RECEIVER_VUSB_DEDICATED1 = 0x03D8, - TWL4030_PM_RECEIVER_VUSB_DEDICATED2 = 0x03D9, - TWL4030_PM_RECEIVER_REGEN_DEV_GRP = 0x03DA, - TWL4030_PM_RECEIVER_REGEN_TYPE = 0x03DB, - TWL4030_PM_RECEIVER_REGEN_REMAP = 0x03DC, - TWL4030_PM_RECEIVER_NRESPWRON_DEV_GRP = 0x03DD, - TWL4030_PM_RECEIVER_NRESPWRON_TYPE = 0x03DE, - TWL4030_PM_RECEIVER_NRESPWRON_REMAP = 0x03DF, - TWL4030_PM_RECEIVER_CLKEN_DEV_GRP = 0x03E0, - TWL4030_PM_RECEIVER_CLKEN_TYPE = 0x03E1, - TWL4030_PM_RECEIVER_CLKEN_REMAP = 0x03E2, - TWL4030_PM_RECEIVER_SYSEN_DEV_GRP = 0x03E3, - TWL4030_PM_RECEIVER_SYSEN_TYPE = 0x03E4, - TWL4030_PM_RECEIVER_SYSEN_REMAP = 0x03E5, - TWL4030_PM_RECEIVER_HFCLKOUT_DEV_GRP = 0x03E6, - TWL4030_PM_RECEIVER_HFCLKOUT_TYPE = 0x03E7, - TWL4030_PM_RECEIVER_HFCLKOUT_REMAP = 0x03E8, - TWL4030_PM_RECEIVER_32KCLKOUT_DEV_GRP = 0x03E9, - TWL4030_PM_RECEIVER_32KCLKOUT_TYPE = 0x03EA, - TWL4030_PM_RECEIVER_32KCLKOUT_REMAP = 0x03EB, - TWL4030_PM_RECEIVER_TRITON_RESET_DEV_GR = 0x03EC, - TWL4030_PM_RECEIVER_TRITON_RESET_TYPE = 0x03ED, - TWL4030_PM_RECEIVER_TRITON_RESET_REMAP = 0x03EE, - TWL4030_PM_RECEIVER_MAINREF_DEV_GRP = 0x03EF, - TWL4030_PM_RECEIVER_MAINREF_TYPE = 0x03F0, - TWL4030_PM_RECEIVER_MAINREF_REMAP = 0x03F1, - - /* Keypad */ - TWL4030_KEYPAD_KEYP_CTRL_REG = 0x02D2, - TWL4030_KEYPAD_KEY_DEB_REG = 0x02D3, - TWL4030_KEYPAD_LONG_KEY_REG1 = 0x02D4, - TWL4030_KEYPAD_LK_PTV_REG = 0x02D5, - TWL4030_KEYPAD_TIME_OUT_REG1 = 0x02D6, - TWL4030_KEYPAD_TIME_OUT_REG2 = 0x02D7, - TWL4030_KEYPAD_KBC_REG = 0x02D8, - TWL4030_KEYPAD_KBR_REG = 0x02D9, - TWL4030_KEYPAD_KEYP_SMS = 0x02DA, - TWL4030_KEYPAD_FULL_CODE_7_0 = 0x02DB, - TWL4030_KEYPAD_FULL_CODE_15_8 = 0x02DC, - TWL4030_KEYPAD_FULL_CODE_23_16 = 0x02DD, - TWL4030_KEYPAD_FULL_CODE_31_24 = 0x02DE, - TWL4030_KEYPAD_FULL_CODE_39_32 = 0x02DF, - TWL4030_KEYPAD_FULL_CODE_47_40 = 0x02E0, - TWL4030_KEYPAD_FULL_CODE_55_48 = 0x02E1, - TWL4030_KEYPAD_FULL_CODE_63_56 = 0x02E2, - TWL4030_KEYPAD_KEYP_ISR1 = 0x02E3, - TWL4030_KEYPAD_KEYP_IMR1 = 0x02E4, - TWL4030_KEYPAD_KEYP_ISR2 = 0x02E5, - TWL4030_KEYPAD_KEYP_IMR2 = 0x02E6, - TWL4030_KEYPAD_KEYP_SIR = 0x02E7, - TWL4030_KEYPAD_KEYP_EDR = 0x02E8, - TWL4030_KEYPAD_KEYP_SIH_CTRL = 0x02E9, - - /* USB */ - TWL4030_USB_VENDOR_ID_LO = 0x0000, - TWL4030_USB_VENDOR_ID_HI = 0x0001, - TWL4030_USB_PRODUCT_ID_LO = 0x0002, - TWL4030_USB_PRODUCT_ID_HI = 0x0003, - TWL4030_USB_FUNC_CTRL = 0x0004, - TWL4030_USB_FUNC_CTRL_SET = 0x0005, - TWL4030_USB_FUNC_CTRL_CLR = 0x0006, - TWL4030_USB_IFC_CTRL = 0x0007, - TWL4030_USB_IFC_CTRL_SET = 0x0008, - TWL4030_USB_IFC_CTRL_CLR = 0x0009, - TWL4030_USB_OTG_CTRL = 0x000A, - TWL4030_USB_OTG_CTRL_SET = 0x000B, - TWL4030_USB_OTG_CTRL_CLR = 0x000C, - TWL4030_USB_USB_INT_EN_RISE = 0x000D, - TWL4030_USB_USB_INT_EN_RISE_SET = 0x000E, - TWL4030_USB_USB_INT_EN_RISE_CLR = 0x000F, - TWL4030_USB_USB_INT_EN_FALL = 0x0010, - TWL4030_USB_USB_INT_EN_FALL_SET = 0x0011, - TWL4030_USB_USB_INT_EN_FALL_CLR = 0x0012, - TWL4030_USB_USB_INT_STS = 0x0013, - TWL4030_USB_USB_INT_LATCH = 0x0014, - TWL4030_USB_DEBUG = 0x0015, - TWL4030_USB_SCRATCH_REG = 0x0016, - TWL4030_USB_SCRATCH_REG_SET = 0x0017, - TWL4030_USB_SCRATCH_REG_CLR = 0x0018, - TWL4030_USB_CARKIT_CTRL = 0x0019, - TWL4030_USB_CARKIT_CTRL_SET = 0x001A, - TWL4030_USB_CARKIT_CTRL_CLR = 0x001B, - TWL4030_USB_CARKIT_INT_DELAY = 0x001C, - TWL4030_USB_CARKIT_INT_EN = 0x001D, - TWL4030_USB_CARKIT_INT_EN_SET = 0x001E, - TWL4030_USB_CARKIT_INT_EN_CLR = 0x001F, - TWL4030_USB_CARKIT_INT_STS = 0x0020, - TWL4030_USB_CARKIT_INT_LATCH = 0x0021, - TWL4030_USB_CARKIT_PLS_CTRL = 0x0022, - TWL4030_USB_CARKIT_PLS_CTRL_SET = 0x0023, - TWL4030_USB_CARKIT_PLS_CTRL_CLR = 0x0024, - TWL4030_USB_TRANS_POS_WIDTH = 0x0025, - TWL4030_USB_TRANS_NEG_WIDTH = 0x0026, - TWL4030_USB_RCV_PLTY_RECOVERY = 0x0027, - TWL4030_USB_MCPC_CTRL = 0x0030, - TWL4030_USB_MCPC_CTRL_SET = 0x0031, - TWL4030_USB_MCPC_CTRL_CLR = 0x0032, - TWL4030_USB_MCPC_IO_CTRL = 0x0033, - TWL4030_USB_MCPC_IO_CTRL_SET = 0x0034, - TWL4030_USB_MCPC_IO_CTRL_CLR = 0x0035, - TWL4030_USB_MCPC_CTRL2 = 0x0036, - TWL4030_USB_MCPC_CTRL2_SET = 0x0037, - TWL4030_USB_MCPC_CTRL2_CLR = 0x0038, - TWL4030_USB_OTHER_FUNC_CTRL = 0x0080, - TWL4030_USB_OTHER_FUNC_CTRL_SET = 0x0081, - TWL4030_USB_OTHER_FUNC_CTRL_CLR = 0x0082, - TWL4030_USB_OTHER_IFC_CTRL = 0x0083, - TWL4030_USB_OTHER_IFC_CTRL_SET = 0x0084, - TWL4030_USB_OTHER_IFC_CTRL_CLR = 0x0085, - TWL4030_USB_OTHER_INT_EN_RISE_SET = 0x0087, - TWL4030_USB_OTHER_INT_EN_RISE_CLR = 0x0088, - TWL4030_USB_OTHER_INT_EN_FALL = 0x0089, - TWL4030_USB_OTHER_INT_EN_FALL_SET = 0x008A, - TWL4030_USB_OTHER_INT_EN_FALL_CLR = 0x008B, - TWL4030_USB_OTHER_INT_STS = 0x008C, - TWL4030_USB_OTHER_INT_LATCH = 0x008D, - TWL4030_USB_ID_STATUS = 0x0096, - TWL4030_USB_CARKIT_SM_1_INT_EN = 0x0097, - TWL4030_USB_CARKIT_SM_1_INT_EN_SET = 0x0098, - TWL4030_USB_CARKIT_SM_1_INT_EN_CLR = 0x0099, - TWL4030_USB_CARKIT_SM_1_INT_STS = 0x009A, - TWL4030_USB_CARKIT_SM_1_INT_LATCH = 0x009B, - TWL4030_USB_CARKIT_SM_2_INT_EN = 0x009C, - TWL4030_USB_CARKIT_SM_2_INT_EN_SET = 0x009D, - TWL4030_USB_CARKIT_SM_2_INT_EN_CLR = 0x009E, - TWL4030_USB_CARKIT_SM_2_INT_STS = 0x009F, - TWL4030_USB_CARKIT_SM_2_INT_LATCH = 0x00A0, - TWL4030_USB_CARKIT_SM_CTRL = 0x00A1, - TWL4030_USB_CARKIT_SM_CTRL_SET = 0x00A2, - TWL4030_USB_CARKIT_SM_CTRL_CLR = 0x00A3, - TWL4030_USB_CARKIT_SM_CMD = 0x00A4, - TWL4030_USB_CARKIT_SM_CMD_SET = 0x00A5, - TWL4030_USB_CARKIT_SM_CMD_CLR = 0x00A6, - TWL4030_USB_CARKIT_SM_CMD_STS = 0x00A7, - TWL4030_USB_CARKIT_SM_STATUS = 0x00A8, - TWL4030_USB_CARKIT_SM_ERR_STATUS = 0x00AA, - TWL4030_USB_CARKIT_SM_CTRL_STATE = 0x00AB, - TWL4030_USB_POWER_CTRL = 0x00AC, - TWL4030_USB_POWER_CTRL_SET = 0x00AD, - TWL4030_USB_POWER_CTRL_CLR = 0x00AE, - TWL4030_USB_OTHER_IFC_CTRL2 = 0x00AF, - TWL4030_USB_OTHER_IFC_CTRL2_SET = 0x00B0, - TWL4030_USB_OTHER_IFC_CTRL2_CLR = 0x00B1, - TWL4030_USB_REG_CTRL_EN = 0x00B2, - TWL4030_USB_REG_CTRL_EN_SET = 0x00B3, - TWL4030_USB_REG_CTRL_EN_CLR = 0x00B4, - TWL4030_USB_REG_CTRL_ERROR = 0x00B5, - TWL4030_USB_OTHER_FUNC_CTRL2 = 0x00B8, - TWL4030_USB_OTHER_FUNC_CTRL2_SET = 0x00B9, - TWL4030_USB_OTHER_FUNC_CTRL2_CLR = 0x00BA, - TWL4030_USB_CARKIT_ANA_CTRL = 0x00BB, - TWL4030_USB_CARKIT_ANA_CTRL_SET = 0x00BC, - TWL4030_USB_CARKIT_ANA_CTRL_CLR = 0x00BD, - TWL4030_USB_VBUS_DEBOUNCE = 0x00C0, - TWL4030_USB_ID_DEBOUNCE = 0x00C1, - TWL4030_USB_TPH_DP_CON_MIN = 0x00C2, - TWL4030_USB_TPH_DP_CON_MAX = 0x00C3, - TWL4030_USB_TCR_DP_CON_MIN = 0x00C4, - TWL4030_USB_TCR_DP_CON_MAX = 0x00C5, - TWL4030_USB_TPH_DP_PD_SHORT = 0x00C6, - TWL4030_USB_TPH_CMD_DLY = 0x00C7, - TWL4030_USB_TPH_DET_RST = 0x00C8, - TWL4030_USB_TPH_AUD_BIAS = 0x00C9, - TWL4030_USB_TCR_UART_DET_MIN = 0x00CA, - TWL4030_USB_TCR_UART_DET_MAX = 0x00CB, - TWL4030_USB_TPH_ID_INT_PW = 0x00CD, - TWL4030_USB_TACC_ID_INT_WAIT = 0x00CE, - TWL4030_USB_TACC_ID_INT_PW = 0x00CF, - TWL4030_USB_TPH_CMD_WAIT = 0x00D0, - TWL4030_USB_TPH_ACK_WAIT = 0x00D1, - TWL4030_USB_TPH_DP_DISC_DET = 0x00D2, - TWL4030_USB_VBAT_TIMER = 0x00D3, - TWL4030_USB_CARKIT_4W_DEBUG = 0x00E0, - TWL4030_USB_CARKIT_5W_DEBUG = 0x00E1, - TWL4030_USB_PHY_PWR_CTRL = 0x00FD, - TWL4030_USB_PHY_CLK_CTRL = 0x00FE, - TWL4030_USB_PHY_CLK_CTRL_STS = 0x00FF, -}; - -struct twl4030 { - struct cdev cdev; - struct i2c_client *client; -}; - -extern struct twl4030 *twl4030_get(void); - -extern int twl4030_reg_read(struct twl4030 *twl4030, u16 reg, u8 *val); -extern int twl4030_reg_write(struct twl4030 *twl4030, u16 reg, u8 val); -extern int twl4030_set_bits(struct twl4030 *twl4030, enum twl4030_reg reg, u8 mask, u8 val); - -#endif /* __I2C_TWL4030_H */ diff --git a/include/image.h b/include/image.h index 2c5956d..8932947 100644 --- a/include/image.h +++ b/include/image.h @@ -320,61 +320,6 @@ 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 @@ * 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 0000000..8c669ca --- /dev/null +++ b/include/mci.h @@ -0,0 +1,239 @@ +/* + * (C) Copyright 2010 Juergen Beisert, Pengutronix + * + * This code is partially based on u-boot code: + * + * Copyright 2008, Freescale Semiconductor, Inc + * Andy Fleming + * + * Based (loosely) on the Linux code + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _MCI_H_ +#define _MCI_H_ + +#include + +/* 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/mfd/lp3972.h b/include/mfd/lp3972.h new file mode 100644 index 0000000..edb5801 --- /dev/null +++ b/include/mfd/lp3972.h @@ -0,0 +1,7 @@ +#ifndef __ASM_ARCH_LP3972_H +#define __ASM_ARCH_LP3972_H + +extern struct i2c_client *lp3972_get_client(void); + +#endif /* __ASM_ARCH_LP3972_H */ + diff --git a/include/mfd/mc13892.h b/include/mfd/mc13892.h new file mode 100644 index 0000000..78a42e9 --- /dev/null +++ b/include/mfd/mc13892.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2009 Marc Kleine-Budde + * + * This file is released under the GPLv2 + * + * Derived from: + * - arch-mxc/pmic_external.h -- contains interface of the PMIC protocol driver + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + */ + +#ifndef __ASM_ARCH_MC13892_H +#define __ASM_ARCH_MC13892_H + +enum mc13892_reg { + MC13892_REG_INT_STATUS0 = 0x00, + MC13892_REG_INT_MASK0 = 0x01, + MC13892_REG_INT_SENSE0 = 0x02, + MC13892_REG_INT_STATUS1 = 0x03, + MC13892_REG_INT_MASK1 = 0x04, + MC13892_REG_INT_SENSE1 = 0x05, + MC13892_REG_PU_MODE_S = 0x06, + MC13892_REG_IDENTIFICATION = 0x07, + MC13892_REG_UNUSED0 = 0x08, + MC13892_REG_ACC0 = 0x09, + MC13892_REG_ACC1 = 0x0a, + MC13892_REG_UNUSED1 = 0x0b, + MC13892_REG_UNUSED2 = 0x0c, + MC13892_REG_POWER_CTL0 = 0x0d, + MC13892_REG_POWER_CTL1 = 0x0e, + MC13892_REG_POWER_CTL2 = 0x0f, + MC13892_REG_REGEN_ASSIGN = 0x10, + MC13892_REG_UNUSED3 = 0x11, + MC13892_REG_MEM_A = 0x12, + MC13892_REG_MEM_B = 0x13, + MC13892_REG_RTC_TIME = 0x14, + MC13892_REG_RTC_ALARM = 0x15, + MC13892_REG_RTC_DAY = 0x16, + MC13892_REG_RTC_DAY_ALARM = 0x17, + MC13892_REG_SW_0 = 0x18, + MC13892_REG_SW_1 = 0x19, + MC13892_REG_SW_2 = 0x1a, + MC13892_REG_SW_3 = 0x1b, + MC13892_REG_SW_4 = 0x1c, + MC13892_REG_SW_5 = 0x1d, + MC13892_REG_SETTING_0 = 0x1e, + MC13892_REG_SETTING_1 = 0x1f, + MC13892_REG_MODE_0 = 0x20, + MC13892_REG_MODE_1 = 0x21, + MC13892_REG_POWER_MISC = 0x22, + MC13892_REG_UNUSED4 = 0x23, + MC13892_REG_UNUSED5 = 0x24, + MC13892_REG_UNUSED6 = 0x25, + MC13892_REG_UNUSED7 = 0x26, + MC13892_REG_UNUSED8 = 0x27, + MC13892_REG_UNUSED9 = 0x28, + MC13892_REG_UNUSED10 = 0x29, + MC13892_REG_UNUSED11 = 0x2a, + MC13892_REG_ADC0 = 0x2b, + MC13892_REG_ADC1 = 0x2c, + MC13892_REG_ADC2 = 0x2d, + MC13892_REG_ADC3 = 0x2e, + MC13892_REG_ADC4 = 0x2f, + MC13892_REG_CHARGE = 0x30, + MC13892_REG_USB0 = 0x31, + MC13892_REG_USB1 = 0x32, + MC13892_REG_LED_CTL0 = 0x33, + MC13892_REG_LED_CTL1 = 0x34, + MC13892_REG_LED_CTL2 = 0x35, + MC13892_REG_LED_CTL3 = 0x36, + MC13892_REG_UNUSED12 = 0x37, + MC13892_REG_UNUSED13 = 0x38, + MC13892_REG_TRIM0 = 0x39, + MC13892_REG_TRIM1 = 0x3a, + MC13892_REG_TEST0 = 0x3b, + MC13892_REG_TEST1 = 0x3c, + MC13892_REG_TEST2 = 0x3d, + MC13892_REG_TEST3 = 0x3e, + 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); + +extern int mc13892_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val); +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/mfd/mc34704.h b/include/mfd/mc34704.h new file mode 100644 index 0000000..a3723d7 --- /dev/null +++ b/include/mfd/mc34704.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009 Marc Kleine-Budde + * Copyright (C) 2010 Baruch Siach + * + * This file is released under the GPLv2 + * + * Derived from: + * - arch-mxc/pmic_external.h -- contains interface of the PMIC protocol driver + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + */ + +#ifndef __I2C_MC34704_H +#define __I2C_MC34704_H + +struct mc34704 { + struct cdev cdev; + struct i2c_client *client; +}; + +extern struct mc34704 *mc34704_get(void); + +extern int mc34704_reg_read(struct mc34704 *mc34704, u8 reg, u8 *val); +extern int mc34704_reg_write(struct mc34704 *mc34704, u8 reg, u8 val); + +#endif /* __I2C_MC34704_H */ diff --git a/include/mfd/mc9sdz60.h b/include/mfd/mc9sdz60.h new file mode 100644 index 0000000..3882cea --- /dev/null +++ b/include/mfd/mc9sdz60.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Marc Kleine-Budde + * + * This file is released under the GPLv2 + * + * Derived from: + * - mcu_max8660-bus.h -- contains interface of the mc9sdz60 and max8660 + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + */ + +#ifndef __ASM_ARCH_MC9SDZ60_H +#define __ASM_ARCH_MC9SDZ60_H + +/** + * Register addresses for the MC9SDZ60 + * + * @note: these match those in the kernel drivers/mxc/mcu_pmic/mc9s08dz60.h + * but not include/linux/mfd/mc9s08dz60/pmic.h + * + */ +enum mc9sdz60_reg { + MC9SDZ60_REG_VERSION = 0x00, + /* reserved 0x01 */ + MC9SDZ60_REG_SECS = 0x02, + MC9SDZ60_REG_MINS = 0x03, + MC9SDZ60_REG_HRS = 0x04, + MC9SDZ60_REG_DAY = 0x05, + MC9SDZ60_REG_DATE = 0x06, + MC9SDZ60_REG_MONTH = 0x07, + MC9SDZ60_REG_YEAR = 0x08, + MC9SDZ60_REG_ALARM_SECS = 0x09, + MC9SDZ60_REG_ALARM_MINS = 0x0a, + MC9SDZ60_REG_ALARM_HRS = 0x0b, + /* reserved 0x0c */ + /* reserved 0x0d */ + MC9SDZ60_REG_TS_CONTROL = 0x0e, + MC9SDZ60_REG_X_LOW = 0x0f, + MC9SDZ60_REG_Y_LOW = 0x10, + MC9SDZ60_REG_XY_HIGH = 0x11, + MC9SDZ60_REG_X_LEFT_LOW = 0x12, + MC9SDZ60_REG_X_LEFT_HIGH = 0x13, + MC9SDZ60_REG_X_RIGHT = 0x14, + MC9SDZ60_REG_Y_TOP_LOW = 0x15, + MC9SDZ60_REG_Y_TOP_HIGH = 0x16, + MC9SDZ60_REG_Y_BOTTOM = 0x17, + /* reserved 0x18 */ + /* reserved 0x19 */ + MC9SDZ60_REG_RESET_1 = 0x1a, + MC9SDZ60_REG_RESET_2 = 0x1b, + MC9SDZ60_REG_POWER_CTL = 0x1c, + MC9SDZ60_REG_DELAY_CONFIG = 0x1d, + /* reserved 0x1e */ + /* reserved 0x1f */ + MC9SDZ60_REG_GPIO_1 = 0x20, + MC9SDZ60_REG_GPIO_2 = 0x21, + MC9SDZ60_REG_KPD_1 = 0x22, + MC9SDZ60_REG_KPD_2 = 0x23, + MC9SDZ60_REG_KPD_CONTROL = 0x24, + MC9SDZ60_REG_INT_ENABLE_1 = 0x25, + MC9SDZ60_REG_INT_ENABLE_2 = 0x26, + MC9SDZ60_REG_INT_FLAG_1 = 0x27, + MC9SDZ60_REG_INT_FLAG_2 = 0x28, + MC9SDZ60_REG_DES_FLAG = 0x29, +}; + +struct mc9sdz60 { + struct cdev cdev; + struct i2c_client *client; +}; + +extern struct mc9sdz60 *mc9sdz60_get(void); + +extern int mc9sdz60_reg_read(struct mc9sdz60 *priv, enum mc9sdz60_reg reg, u8 *val); +extern int mc9sdz60_reg_write(struct mc9sdz60 *priv, enum mc9sdz60_reg reg, u8 val); +extern int mc9sdz60_set_bits(struct mc9sdz60 *priv, enum mc9sdz60_reg reg, u8 mask, u8 val); + +#endif /* __ASM_ARCH_MC9SDZ60_H */ diff --git a/include/mfd/twl4030.h b/include/mfd/twl4030.h new file mode 100644 index 0000000..3fef4d9 --- /dev/null +++ b/include/mfd/twl4030.h @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2010 Michael Grzeschik + * Copyright (C) 2010 Sascha Hauer + * + * This file is released under the GPLv2 + * + */ + +#ifndef __I2C_TWL4030_H +#define __I2C_TWL4030_H + +#include +#include +#include + +/* LED */ +#define TWL4030_LED_LEDEN_LEDAON (1 << 0) +#define TWL4030_LED_LEDEN_LEDBON (1 << 1) +#define TWL4030_LED_LEDEN_LEDAPWM (1 << 4) +#define TWL4030_LED_LEDEN_LEDBPWM (1 << 5) + +/* KEYPAD */ +#define TWL4030_KEYPAD_CTRL_KBD_ON (1 << 6) +#define TWL4030_KEYPAD_CTRL_RP_EN (1 << 5) +#define TWL4030_KEYPAD_CTRL_TOLE_EN (1 << 4) +#define TWL4030_KEYPAD_CTRL_TOE_EN (1 << 3) +#define TWL4030_KEYPAD_CTRL_LK_EN (1 << 2) +#define TWL4030_KEYPAD_CTRL_SOFTMODEN (1 << 1) +#define TWL4030_KEYPAD_CTRL_SOFT_NRST (1 << 0) + +/* P[1-3]_SW_EVENTS */ +#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_PWRON (1 << 6) +#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_SYSEN (1 << 5) +#define TWL4030_PM_MASTER_SW_EVENTS_ENABLE_WARMRESET (1 << 4) +#define TWL4030_PM_MASTER_SW_EVENTS_LVL_WAKEUP (1 << 3) +#define TWL4030_PM_MASTER_SW_EVENTS_DEVACT (1 << 2) +#define TWL4030_PM_MASTER_SW_EVENTS_DEVSLP (1 << 1) +#define TWL4030_PM_MASTER_SW_EVENTS_DEVOFF (1 << 0) + + +enum twl4030_reg { + /* Register base addresses */ + /* USB */ + TWL4030_BASEADD_USB = 0x0000, + /* AUD */ + TWL4030_BASEADD_AUDIO_VOICE = 0x0100, + TWL4030_BASEADD_GPIO = 0x0198, + TWL4030_BASEADD_INTBR = 0x0185, + TWL4030_BASEADD_PIH = 0x0180, + TWL4030_BASEADD_TEST = 0x014C, + /* AUX */ + TWL4030_BASEADD_INTERRUPTS = 0x02B9, + TWL4030_BASEADD_LED = 0x02EE, + TWL4030_BASEADD_MADC = 0x0200, + TWL4030_BASEADD_MAIN_CHARGE = 0x0274, + TWL4030_BASEADD_PRECHARGE = 0x02AA, + TWL4030_BASEADD_PWM0 = 0x02F8, + TWL4030_BASEADD_PWM1 = 0x02FB, + TWL4030_BASEADD_PWMA = 0x02EF, + TWL4030_BASEADD_PWMB = 0x02F1, + TWL4030_BASEADD_KEYPAD = 0x02D2, + /* POWER */ + TWL4030_BASEADD_BACKUP = 0x0314, + TWL4030_BASEADD_INT = 0x032E, + TWL4030_BASEADD_PM_MASTER = 0x0336, + TWL4030_BASEADD_PM_RECIEVER = 0x035B, + TWL4030_BASEADD_RTC = 0x031C, + TWL4030_BASEADD_SECURED_REG = 0x0300, + + /* LED */ + TWL4030_LED_LEDEN = 0x02EE, + + /* + * Voltage Selection in PM Receiver Module + */ + TWL4030_PM_RECEIVER_VAUX2_VSEL_18 = 0x05, + TWL4030_PM_RECEIVER_VAUX3_VSEL_28 = 0x03, + TWL4030_PM_RECEIVER_VPLL2_VSEL_18 = 0x05, + TWL4030_PM_RECEIVER_VDAC_VSEL_18 = 0x03, + TWL4030_PM_RECEIVER_VMMC1_VSEL_30 = 0x02, + + /* + * Device Selection in PM Receiver Module + */ + TWL4030_PM_RECEIVER_DEV_GRP_P1 = 0x20, + TWL4030_PM_RECEIVER_DEV_GRP_ALL = 0xE0, + + /* + * Power Management Master + */ + TWL4030_PM_MASTER_CFG_P1_TRANSITION = 0x0336, + TWL4030_PM_MASTER_CFG_P2_TRANSITION = 0x0337, + TWL4030_PM_MASTER_CFG_P3_TRANSITION = 0x0338, + TWL4030_PM_MASTER_CFG_P123_TRANSITION = 0x0339, + TWL4030_PM_MASTER_STS_BOOT = 0x033A, + TWL4030_PM_MASTER_CFG_BOOT = 0x033B, + TWL4030_PM_MASTER_SHUNDAN = 0x033C, + TWL4030_PM_MASTER_BOOT_BCI = 0x033D, + TWL4030_PM_MASTER_CFG_PWRANA1 = 0x033E, + TWL4030_PM_MASTER_CFG_PWRANA2 = 0x033F, + TWL4030_PM_MASTER_BGAP_TRIM = 0x0340, + TWL4030_PM_MASTER_BACKUP_MISC_STS = 0x0341, + TWL4030_PM_MASTER_BACKUP_MISC_CFG = 0x0342, + TWL4030_PM_MASTER_BACKUP_MISC_TST = 0x0343, + TWL4030_PM_MASTER_PROTECT_KEY = 0x0344, + TWL4030_PM_MASTER_STS_HW_CONDITIONS = 0x0345, + TWL4030_PM_MASTER_P1_SW_EVENTS = 0x0346, + TWL4030_PM_MASTER_P2_SW_EVENTS = 0x0347, + TWL4030_PM_MASTER_P3_SW_EVENTS = 0x0348, + TWL4030_PM_MASTER_STS_P123_STATE = 0x0349, + TWL4030_PM_MASTER_PB_CFG = 0x034A, + TWL4030_PM_MASTER_PB_WORD_MSB = 0x034B, + TWL4030_PM_MASTER_PB_WORD_LSB = 0x034C, + TWL4030_PM_MASTER_SEQ_ADD_W2P = 0x0352, + TWL4030_PM_MASTER_SEQ_ADD_P2A = 0x0353, + TWL4030_PM_MASTER_SEQ_ADD_A2W = 0x0354, + TWL4030_PM_MASTER_SEQ_ADD_A2S = 0x0355, + TWL4030_PM_MASTER_SEQ_ADD_S2A12 = 0x0356, + TWL4030_PM_MASTER_SEQ_ADD_S2A3 = 0x0357, + TWL4030_PM_MASTER_SEQ_ADD_WARM = 0x0358, + TWL4030_PM_MASTER_MEMORY_ADDRESS = 0x0359, + TWL4030_PM_MASTER_MEMORY_DATA = 0x035A, + TWL4030_PM_MASTER_SC_CONFIG = 0x035B, + TWL4030_PM_MASTER_SC_DETECT1 = 0x035C, + TWL4030_PM_MASTER_SC_DETECT2 = 0x035D, + TWL4030_PM_MASTER_WATCHDOG_CFG = 0x035E, + TWL4030_PM_MASTER_IT_CHECK_CFG = 0x035F, + TWL4030_PM_MASTER_VIBRATOR_CFG = 0x0360, + TWL4030_PM_MASTER_DCDC_GLOBAL_CFG = 0x0361, + TWL4030_PM_MASTER_VDD1_TRIM1 = 0x0362, + TWL4030_PM_MASTER_VDD1_TRIM2 = 0x0363, + TWL4030_PM_MASTER_VDD2_TRIM1 = 0x0364, + TWL4030_PM_MASTER_VDD2_TRIM2 = 0x0365, + TWL4030_PM_MASTER_VIO_TRIM1 = 0x0366, + TWL4030_PM_MASTER_VIO_TRIM2 = 0x0367, + TWL4030_PM_MASTER_MISC_CFG = 0x0368, + TWL4030_PM_MASTER_LS_TST_A = 0x0369, + TWL4030_PM_MASTER_LS_TST_B = 0x036A, + TWL4030_PM_MASTER_LS_TST_C = 0x036B, + TWL4030_PM_MASTER_LS_TST_D = 0x036C, + TWL4030_PM_MASTER_BB_CFG = 0x036D, + TWL4030_PM_MASTER_MISC_TST = 0x036E, + TWL4030_PM_MASTER_TRIM1 = 0x036F, + + /* Power Managment Receiver */ + TWL4030_PM_RECEIVER_SC_CONFIG = 0x035B, + TWL4030_PM_RECEIVER_SC_DETECT1 = 0x035C, + TWL4030_PM_RECEIVER_SC_DETECT2 = 0x035D, + TWL4030_PM_RECEIVER_WATCHDOG_CFG = 0x035E, + TWL4030_PM_RECEIVER_IT_CHECK_CFG = 0x035F, + TWL4030_PM_RECEIVER_VIBRATOR_CFG = 0x035F, + TWL4030_PM_RECEIVER_DC_TO_DC_CFG = 0x0361, + TWL4030_PM_RECEIVER_VDD1_TRIM1 = 0x0362, + TWL4030_PM_RECEIVER_VDD1_TRIM2 = 0x0363, + TWL4030_PM_RECEIVER_VDD2_TRIM1 = 0x0364, + TWL4030_PM_RECEIVER_VDD2_TRIM2 = 0x0365, + TWL4030_PM_RECEIVER_VIO_TRIM1 = 0x0366, + TWL4030_PM_RECEIVER_VIO_TRIM2 = 0x0367, + TWL4030_PM_RECEIVER_MISC_CFG = 0x0368, + TWL4030_PM_RECEIVER_LS_TST_A = 0x0369, + TWL4030_PM_RECEIVER_LS_TST_B = 0x036A, + TWL4030_PM_RECEIVER_LS_TST_C = 0x036B, + TWL4030_PM_RECEIVER_LS_TST_D = 0x036C, + TWL4030_PM_RECEIVER_BB_CFG = 0x036D, + TWL4030_PM_RECEIVER_MISC_TST = 0x036E, + TWL4030_PM_RECEIVER_TRIM1 = 0x036F, + TWL4030_PM_RECEIVER_TRIM2 = 0x0370, + TWL4030_PM_RECEIVER_DC_DC_TIMEOUT = 0x0371, + TWL4030_PM_RECEIVER_VAUX1_DEV_GRP = 0x0372, + TWL4030_PM_RECEIVER_VAUX1_TYPE = 0x0373, + TWL4030_PM_RECEIVER_VAUX1_REMAP = 0x0374, + TWL4030_PM_RECEIVER_VAUX1_DEDICATED = 0x0375, + TWL4030_PM_RECEIVER_VAUX2_DEV_GRP = 0x0376, + TWL4030_PM_RECEIVER_VAUX2_TYPE = 0x0377, + TWL4030_PM_RECEIVER_VAUX2_REMAP = 0x0378, + TWL4030_PM_RECEIVER_VAUX2_DEDICATED = 0x0379, + TWL4030_PM_RECEIVER_VAUX3_DEV_GRP = 0x037A, + TWL4030_PM_RECEIVER_VAUX3_TYPE = 0x037B, + TWL4030_PM_RECEIVER_VAUX3_REMAP = 0x037C, + TWL4030_PM_RECEIVER_VAUX3_DEDICATED = 0x037D, + TWL4030_PM_RECEIVER_VAUX4_DEV_GRP = 0x037E, + TWL4030_PM_RECEIVER_VAUX4_TYPE = 0x037F, + TWL4030_PM_RECEIVER_VAUX4_REMAP = 0x0380, + TWL4030_PM_RECEIVER_VAUX4_DEDICATED = 0x0381, + TWL4030_PM_RECEIVER_VMMC1_DEV_GRP = 0x0382, + TWL4030_PM_RECEIVER_VMMC1_TYPE = 0x0383, + TWL4030_PM_RECEIVER_VMMC1_REMAP = 0x0384, + TWL4030_PM_RECEIVER_VMMC1_DEDICATED = 0x0385, + TWL4030_PM_RECEIVER_VMMC2_DEV_GRP = 0x0386, + TWL4030_PM_RECEIVER_VMMC2_TYPE = 0x0387, + TWL4030_PM_RECEIVER_VMMC2_REMAP = 0x0388, + TWL4030_PM_RECEIVER_VMMC2_DEDICATED = 0x0389, + TWL4030_PM_RECEIVER_VPLL1_DEV_GRP = 0x038A, + TWL4030_PM_RECEIVER_VPLL1_TYPE = 0x038B, + TWL4030_PM_RECEIVER_VPLL1_REMAP = 0x038C, + TWL4030_PM_RECEIVER_VPLL1_DEDICATED = 0x038D, + TWL4030_PM_RECEIVER_VPLL2_DEV_GRP = 0x038E, + TWL4030_PM_RECEIVER_VPLL2_TYPE = 0x038F, + TWL4030_PM_RECEIVER_VPLL2_REMAP = 0x0390, + TWL4030_PM_RECEIVER_VPLL2_DEDICATED = 0x0391, + TWL4030_PM_RECEIVER_VSIM_DEV_GRP = 0x0392, + TWL4030_PM_RECEIVER_VSIM_TYPE = 0x0393, + TWL4030_PM_RECEIVER_VSIM_REMAP = 0x0394, + TWL4030_PM_RECEIVER_VSIM_DEDICATED = 0x0395, + TWL4030_PM_RECEIVER_VDAC_DEV_GRP = 0x0396, + TWL4030_PM_RECEIVER_VDAC_TYPE = 0x0397, + TWL4030_PM_RECEIVER_VDAC_REMAP = 0x0398, + TWL4030_PM_RECEIVER_VDAC_DEDICATED = 0x0399, + TWL4030_PM_RECEIVER_VINTANA1_DEV_GRP = 0x039A, + TWL4030_PM_RECEIVER_VINTANA1_TYP = 0x039B, + TWL4030_PM_RECEIVER_VINTANA1_REMAP = 0x039C, + TWL4030_PM_RECEIVER_VINTANA1_DEDICATED = 0x039D, + TWL4030_PM_RECEIVER_VINTANA2_DEV_GRP = 0x039E, + TWL4030_PM_RECEIVER_VINTANA2_TYPE = 0x039F, + TWL4030_PM_RECEIVER_VINTANA2_REMAP = 0x03A0, + TWL4030_PM_RECEIVER_VINTANA2_DEDICATED = 0x03A1, + TWL4030_PM_RECEIVER_VINTDIG_DEV_GRP = 0x03A2, + TWL4030_PM_RECEIVER_VINTDIG_TYPE = 0x03A3, + TWL4030_PM_RECEIVER_VINTDIG_REMAP = 0x03A4, + TWL4030_PM_RECEIVER_VINTDIG_DEDICATED = 0x03A5, + TWL4030_PM_RECEIVER_VIO_DEV_GRP = 0x03A6, + TWL4030_PM_RECEIVER_VIO_TYPE = 0x03A7, + TWL4030_PM_RECEIVER_VIO_REMAP = 0x03A8, + TWL4030_PM_RECEIVER_VIO_CFG = 0x03A9, + TWL4030_PM_RECEIVER_VIO_MISC_CFG = 0x03AA, + TWL4030_PM_RECEIVER_VIO_TEST1 = 0x03AB, + TWL4030_PM_RECEIVER_VIO_TEST2 = 0x03AC, + TWL4030_PM_RECEIVER_VIO_OSC = 0x03AD, + TWL4030_PM_RECEIVER_VIO_RESERVED = 0x03AE, + TWL4030_PM_RECEIVER_VIO_VSEL = 0x03AF, + TWL4030_PM_RECEIVER_VDD1_DEV_GRP = 0x03B0, + TWL4030_PM_RECEIVER_VDD1_TYPE = 0x03B1, + TWL4030_PM_RECEIVER_VDD1_REMAP = 0x03B2, + TWL4030_PM_RECEIVER_VDD1_CFG = 0x03B3, + TWL4030_PM_RECEIVER_VDD1_MISC_CFG = 0x03B4, + TWL4030_PM_RECEIVER_VDD1_TEST1 = 0x03B5, + TWL4030_PM_RECEIVER_VDD1_TEST2 = 0x03B6, + TWL4030_PM_RECEIVER_VDD1_OSC = 0x03B7, + TWL4030_PM_RECEIVER_VDD1_RESERVED = 0x03B8, + TWL4030_PM_RECEIVER_VDD1_VSEL = 0x03B9, + TWL4030_PM_RECEIVER_VDD1_VMODE_CFG = 0x03BA, + TWL4030_PM_RECEIVER_VDD1_VFLOOR = 0x03BB, + TWL4030_PM_RECEIVER_VDD1_VROOF = 0x03BC, + TWL4030_PM_RECEIVER_VDD1_STEP = 0x03BD, + TWL4030_PM_RECEIVER_VDD2_DEV_GRP = 0x03BE, + TWL4030_PM_RECEIVER_VDD2_TYPE = 0x03BF, + TWL4030_PM_RECEIVER_VDD2_REMAP = 0x03C0, + TWL4030_PM_RECEIVER_VDD2_CFG = 0x03C1, + TWL4030_PM_RECEIVER_VDD2_MISC_CFG = 0x03C2, + TWL4030_PM_RECEIVER_VDD2_TEST1 = 0x03C3, + TWL4030_PM_RECEIVER_VDD2_TEST2 = 0x03C4, + TWL4030_PM_RECEIVER_VDD2_OSC = 0x03C5, + TWL4030_PM_RECEIVER_VDD2_RESERVED = 0x03C6, + TWL4030_PM_RECEIVER_VDD2_VSEL = 0x03C7, + TWL4030_PM_RECEIVER_VDD2_VMODE_CFG = 0x03C8, + TWL4030_PM_RECEIVER_VDD2_VFLOOR = 0x03C9, + TWL4030_PM_RECEIVER_VDD2_VROOF = 0x03CA, + TWL4030_PM_RECEIVER_VDD2_STEP = 0x03CB, + TWL4030_PM_RECEIVER_VUSB1V5_DEV_GRP = 0x03CC, + TWL4030_PM_RECEIVER_VUSB1V5_TYPE = 0x03CD, + TWL4030_PM_RECEIVER_VUSB1V5_REMAP = 0x03CE, + TWL4030_PM_RECEIVER_VUSB1V8_DEV_GRP = 0x03CF, + TWL4030_PM_RECEIVER_VUSB1V8_TYPE = 0x03D0, + TWL4030_PM_RECEIVER_VUSB1V8_REMAP = 0x03D1, + TWL4030_PM_RECEIVER_VUSB3V1_DEV_GRP = 0x03D2, + TWL4030_PM_RECEIVER_VUSB3V1_TYPE = 0x03D3, + TWL4030_PM_RECEIVER_VUSB3V1_REMAP = 0x03D4, + TWL4030_PM_RECEIVER_VUSBCP_DEV_GRP = 0x03D5, + TWL4030_PM_RECEIVER_VUSBCP_TYPE = 0x03D6, + TWL4030_PM_RECEIVER_VUSBCP_REMAP = 0x03D7, + TWL4030_PM_RECEIVER_VUSB_DEDICATED1 = 0x03D8, + TWL4030_PM_RECEIVER_VUSB_DEDICATED2 = 0x03D9, + TWL4030_PM_RECEIVER_REGEN_DEV_GRP = 0x03DA, + TWL4030_PM_RECEIVER_REGEN_TYPE = 0x03DB, + TWL4030_PM_RECEIVER_REGEN_REMAP = 0x03DC, + TWL4030_PM_RECEIVER_NRESPWRON_DEV_GRP = 0x03DD, + TWL4030_PM_RECEIVER_NRESPWRON_TYPE = 0x03DE, + TWL4030_PM_RECEIVER_NRESPWRON_REMAP = 0x03DF, + TWL4030_PM_RECEIVER_CLKEN_DEV_GRP = 0x03E0, + TWL4030_PM_RECEIVER_CLKEN_TYPE = 0x03E1, + TWL4030_PM_RECEIVER_CLKEN_REMAP = 0x03E2, + TWL4030_PM_RECEIVER_SYSEN_DEV_GRP = 0x03E3, + TWL4030_PM_RECEIVER_SYSEN_TYPE = 0x03E4, + TWL4030_PM_RECEIVER_SYSEN_REMAP = 0x03E5, + TWL4030_PM_RECEIVER_HFCLKOUT_DEV_GRP = 0x03E6, + TWL4030_PM_RECEIVER_HFCLKOUT_TYPE = 0x03E7, + TWL4030_PM_RECEIVER_HFCLKOUT_REMAP = 0x03E8, + TWL4030_PM_RECEIVER_32KCLKOUT_DEV_GRP = 0x03E9, + TWL4030_PM_RECEIVER_32KCLKOUT_TYPE = 0x03EA, + TWL4030_PM_RECEIVER_32KCLKOUT_REMAP = 0x03EB, + TWL4030_PM_RECEIVER_TRITON_RESET_DEV_GR = 0x03EC, + TWL4030_PM_RECEIVER_TRITON_RESET_TYPE = 0x03ED, + TWL4030_PM_RECEIVER_TRITON_RESET_REMAP = 0x03EE, + TWL4030_PM_RECEIVER_MAINREF_DEV_GRP = 0x03EF, + TWL4030_PM_RECEIVER_MAINREF_TYPE = 0x03F0, + TWL4030_PM_RECEIVER_MAINREF_REMAP = 0x03F1, + + /* Keypad */ + TWL4030_KEYPAD_KEYP_CTRL_REG = 0x02D2, + TWL4030_KEYPAD_KEY_DEB_REG = 0x02D3, + TWL4030_KEYPAD_LONG_KEY_REG1 = 0x02D4, + TWL4030_KEYPAD_LK_PTV_REG = 0x02D5, + TWL4030_KEYPAD_TIME_OUT_REG1 = 0x02D6, + TWL4030_KEYPAD_TIME_OUT_REG2 = 0x02D7, + TWL4030_KEYPAD_KBC_REG = 0x02D8, + TWL4030_KEYPAD_KBR_REG = 0x02D9, + TWL4030_KEYPAD_KEYP_SMS = 0x02DA, + TWL4030_KEYPAD_FULL_CODE_7_0 = 0x02DB, + TWL4030_KEYPAD_FULL_CODE_15_8 = 0x02DC, + TWL4030_KEYPAD_FULL_CODE_23_16 = 0x02DD, + TWL4030_KEYPAD_FULL_CODE_31_24 = 0x02DE, + TWL4030_KEYPAD_FULL_CODE_39_32 = 0x02DF, + TWL4030_KEYPAD_FULL_CODE_47_40 = 0x02E0, + TWL4030_KEYPAD_FULL_CODE_55_48 = 0x02E1, + TWL4030_KEYPAD_FULL_CODE_63_56 = 0x02E2, + TWL4030_KEYPAD_KEYP_ISR1 = 0x02E3, + TWL4030_KEYPAD_KEYP_IMR1 = 0x02E4, + TWL4030_KEYPAD_KEYP_ISR2 = 0x02E5, + TWL4030_KEYPAD_KEYP_IMR2 = 0x02E6, + TWL4030_KEYPAD_KEYP_SIR = 0x02E7, + TWL4030_KEYPAD_KEYP_EDR = 0x02E8, + TWL4030_KEYPAD_KEYP_SIH_CTRL = 0x02E9, + + /* USB */ + TWL4030_USB_VENDOR_ID_LO = 0x0000, + TWL4030_USB_VENDOR_ID_HI = 0x0001, + TWL4030_USB_PRODUCT_ID_LO = 0x0002, + TWL4030_USB_PRODUCT_ID_HI = 0x0003, + TWL4030_USB_FUNC_CTRL = 0x0004, + TWL4030_USB_FUNC_CTRL_SET = 0x0005, + TWL4030_USB_FUNC_CTRL_CLR = 0x0006, + TWL4030_USB_IFC_CTRL = 0x0007, + TWL4030_USB_IFC_CTRL_SET = 0x0008, + TWL4030_USB_IFC_CTRL_CLR = 0x0009, + TWL4030_USB_OTG_CTRL = 0x000A, + TWL4030_USB_OTG_CTRL_SET = 0x000B, + TWL4030_USB_OTG_CTRL_CLR = 0x000C, + TWL4030_USB_USB_INT_EN_RISE = 0x000D, + TWL4030_USB_USB_INT_EN_RISE_SET = 0x000E, + TWL4030_USB_USB_INT_EN_RISE_CLR = 0x000F, + TWL4030_USB_USB_INT_EN_FALL = 0x0010, + TWL4030_USB_USB_INT_EN_FALL_SET = 0x0011, + TWL4030_USB_USB_INT_EN_FALL_CLR = 0x0012, + TWL4030_USB_USB_INT_STS = 0x0013, + TWL4030_USB_USB_INT_LATCH = 0x0014, + TWL4030_USB_DEBUG = 0x0015, + TWL4030_USB_SCRATCH_REG = 0x0016, + TWL4030_USB_SCRATCH_REG_SET = 0x0017, + TWL4030_USB_SCRATCH_REG_CLR = 0x0018, + TWL4030_USB_CARKIT_CTRL = 0x0019, + TWL4030_USB_CARKIT_CTRL_SET = 0x001A, + TWL4030_USB_CARKIT_CTRL_CLR = 0x001B, + TWL4030_USB_CARKIT_INT_DELAY = 0x001C, + TWL4030_USB_CARKIT_INT_EN = 0x001D, + TWL4030_USB_CARKIT_INT_EN_SET = 0x001E, + TWL4030_USB_CARKIT_INT_EN_CLR = 0x001F, + TWL4030_USB_CARKIT_INT_STS = 0x0020, + TWL4030_USB_CARKIT_INT_LATCH = 0x0021, + TWL4030_USB_CARKIT_PLS_CTRL = 0x0022, + TWL4030_USB_CARKIT_PLS_CTRL_SET = 0x0023, + TWL4030_USB_CARKIT_PLS_CTRL_CLR = 0x0024, + TWL4030_USB_TRANS_POS_WIDTH = 0x0025, + TWL4030_USB_TRANS_NEG_WIDTH = 0x0026, + TWL4030_USB_RCV_PLTY_RECOVERY = 0x0027, + TWL4030_USB_MCPC_CTRL = 0x0030, + TWL4030_USB_MCPC_CTRL_SET = 0x0031, + TWL4030_USB_MCPC_CTRL_CLR = 0x0032, + TWL4030_USB_MCPC_IO_CTRL = 0x0033, + TWL4030_USB_MCPC_IO_CTRL_SET = 0x0034, + TWL4030_USB_MCPC_IO_CTRL_CLR = 0x0035, + TWL4030_USB_MCPC_CTRL2 = 0x0036, + TWL4030_USB_MCPC_CTRL2_SET = 0x0037, + TWL4030_USB_MCPC_CTRL2_CLR = 0x0038, + TWL4030_USB_OTHER_FUNC_CTRL = 0x0080, + TWL4030_USB_OTHER_FUNC_CTRL_SET = 0x0081, + TWL4030_USB_OTHER_FUNC_CTRL_CLR = 0x0082, + TWL4030_USB_OTHER_IFC_CTRL = 0x0083, + TWL4030_USB_OTHER_IFC_CTRL_SET = 0x0084, + TWL4030_USB_OTHER_IFC_CTRL_CLR = 0x0085, + TWL4030_USB_OTHER_INT_EN_RISE_SET = 0x0087, + TWL4030_USB_OTHER_INT_EN_RISE_CLR = 0x0088, + TWL4030_USB_OTHER_INT_EN_FALL = 0x0089, + TWL4030_USB_OTHER_INT_EN_FALL_SET = 0x008A, + TWL4030_USB_OTHER_INT_EN_FALL_CLR = 0x008B, + TWL4030_USB_OTHER_INT_STS = 0x008C, + TWL4030_USB_OTHER_INT_LATCH = 0x008D, + TWL4030_USB_ID_STATUS = 0x0096, + TWL4030_USB_CARKIT_SM_1_INT_EN = 0x0097, + TWL4030_USB_CARKIT_SM_1_INT_EN_SET = 0x0098, + TWL4030_USB_CARKIT_SM_1_INT_EN_CLR = 0x0099, + TWL4030_USB_CARKIT_SM_1_INT_STS = 0x009A, + TWL4030_USB_CARKIT_SM_1_INT_LATCH = 0x009B, + TWL4030_USB_CARKIT_SM_2_INT_EN = 0x009C, + TWL4030_USB_CARKIT_SM_2_INT_EN_SET = 0x009D, + TWL4030_USB_CARKIT_SM_2_INT_EN_CLR = 0x009E, + TWL4030_USB_CARKIT_SM_2_INT_STS = 0x009F, + TWL4030_USB_CARKIT_SM_2_INT_LATCH = 0x00A0, + TWL4030_USB_CARKIT_SM_CTRL = 0x00A1, + TWL4030_USB_CARKIT_SM_CTRL_SET = 0x00A2, + TWL4030_USB_CARKIT_SM_CTRL_CLR = 0x00A3, + TWL4030_USB_CARKIT_SM_CMD = 0x00A4, + TWL4030_USB_CARKIT_SM_CMD_SET = 0x00A5, + TWL4030_USB_CARKIT_SM_CMD_CLR = 0x00A6, + TWL4030_USB_CARKIT_SM_CMD_STS = 0x00A7, + TWL4030_USB_CARKIT_SM_STATUS = 0x00A8, + TWL4030_USB_CARKIT_SM_ERR_STATUS = 0x00AA, + TWL4030_USB_CARKIT_SM_CTRL_STATE = 0x00AB, + TWL4030_USB_POWER_CTRL = 0x00AC, + TWL4030_USB_POWER_CTRL_SET = 0x00AD, + TWL4030_USB_POWER_CTRL_CLR = 0x00AE, + TWL4030_USB_OTHER_IFC_CTRL2 = 0x00AF, + TWL4030_USB_OTHER_IFC_CTRL2_SET = 0x00B0, + TWL4030_USB_OTHER_IFC_CTRL2_CLR = 0x00B1, + TWL4030_USB_REG_CTRL_EN = 0x00B2, + TWL4030_USB_REG_CTRL_EN_SET = 0x00B3, + TWL4030_USB_REG_CTRL_EN_CLR = 0x00B4, + TWL4030_USB_REG_CTRL_ERROR = 0x00B5, + TWL4030_USB_OTHER_FUNC_CTRL2 = 0x00B8, + TWL4030_USB_OTHER_FUNC_CTRL2_SET = 0x00B9, + TWL4030_USB_OTHER_FUNC_CTRL2_CLR = 0x00BA, + TWL4030_USB_CARKIT_ANA_CTRL = 0x00BB, + TWL4030_USB_CARKIT_ANA_CTRL_SET = 0x00BC, + TWL4030_USB_CARKIT_ANA_CTRL_CLR = 0x00BD, + TWL4030_USB_VBUS_DEBOUNCE = 0x00C0, + TWL4030_USB_ID_DEBOUNCE = 0x00C1, + TWL4030_USB_TPH_DP_CON_MIN = 0x00C2, + TWL4030_USB_TPH_DP_CON_MAX = 0x00C3, + TWL4030_USB_TCR_DP_CON_MIN = 0x00C4, + TWL4030_USB_TCR_DP_CON_MAX = 0x00C5, + TWL4030_USB_TPH_DP_PD_SHORT = 0x00C6, + TWL4030_USB_TPH_CMD_DLY = 0x00C7, + TWL4030_USB_TPH_DET_RST = 0x00C8, + TWL4030_USB_TPH_AUD_BIAS = 0x00C9, + TWL4030_USB_TCR_UART_DET_MIN = 0x00CA, + TWL4030_USB_TCR_UART_DET_MAX = 0x00CB, + TWL4030_USB_TPH_ID_INT_PW = 0x00CD, + TWL4030_USB_TACC_ID_INT_WAIT = 0x00CE, + TWL4030_USB_TACC_ID_INT_PW = 0x00CF, + TWL4030_USB_TPH_CMD_WAIT = 0x00D0, + TWL4030_USB_TPH_ACK_WAIT = 0x00D1, + TWL4030_USB_TPH_DP_DISC_DET = 0x00D2, + TWL4030_USB_VBAT_TIMER = 0x00D3, + TWL4030_USB_CARKIT_4W_DEBUG = 0x00E0, + TWL4030_USB_CARKIT_5W_DEBUG = 0x00E1, + TWL4030_USB_PHY_PWR_CTRL = 0x00FD, + TWL4030_USB_PHY_CLK_CTRL = 0x00FE, + TWL4030_USB_PHY_CLK_CTRL_STS = 0x00FF, +}; + +struct twl4030 { + struct cdev cdev; + struct i2c_client *client; +}; + +extern struct twl4030 *twl4030_get(void); + +extern int twl4030_reg_read(struct twl4030 *twl4030, u16 reg, u8 *val); +extern int twl4030_reg_write(struct twl4030 *twl4030, u16 reg, u8 val); +extern int twl4030_set_bits(struct twl4030 *twl4030, enum twl4030_reg reg, u8 mask, u8 val); + +#endif /* __I2C_TWL4030_H */ diff --git a/include/notifier.h b/include/notifier.h index 878b17e..cb2be5f 100644 --- a/include/notifier.h +++ b/include/notifier.h @@ -15,6 +15,7 @@ }; 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 9eca161..ad2b3cf 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -11,7 +11,7 @@ bool menuconfig DIGEST - bool "Digest" + bool "Digest " if DIGEST diff --git a/lib/Makefile b/lib/Makefile index 0c62917..8b986d2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,7 +1,6 @@ obj-y += ctype.o obj-y += rbtree.o obj-y += display_options.o -obj-y += ldiv.o obj-y += string.o obj-y += vsprintf.o obj-y += div64.o diff --git a/lib/copy_file.c b/lib/copy_file.c index 0ff0435..7083531 100644 --- a/lib/copy_file.c +++ b/lib/copy_file.c @@ -3,6 +3,8 @@ #include #include #include +#include + #define RW_BUF_SIZE (ulong)4096 /** diff --git a/lib/crc32.c b/lib/crc32.c index 3481782..275edb4 100644 --- a/lib/crc32.c +++ b/lib/crc32.c @@ -42,7 +42,7 @@ 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 66d8fee..ff92e44 100644 --- a/lib/driver.c +++ b/lib/driver.c @@ -54,7 +54,7 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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_START(devinfo) - .cmd = do_devinfo, - .usage = "display info about devices and drivers", - BAREBOX_CMD_HELP(cmd_devinfo_help) -BAREBOX_CMD_END - -#endif +BAREBOX_CMD_HELP_START(devinfo) +BAREBOX_CMD_HELP_USAGE("devinfo [DEVICE]\n") +BAREBOX_CMD_HELP_SHORT("Output device information.\n") +BAREBOX_CMD_HELP_END /** - * @page devinfo_command devinfo - * - * Usage is: devinfo /dev/\ - * - * 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: + * @page devinfo_command + +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: + @verbatim barebox:/ devinfo /dev/eth0 base : 0x1002b000 @@ -378,5 +369,12 @@ 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 223b9d3..1a5e8d0 100644 --- a/lib/fnmatch.c +++ b/lib/fnmatch.c @@ -48,10 +48,7 @@ /* 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 a5e3d1d..43d2f67 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -100,11 +100,8 @@ `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 @@ 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 @@ } #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 @@ /* 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 @@ 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 @@ 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 @@ #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 5d231a2..0000000 --- a/lib/ldiv.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 1992, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -typedef struct { - long quot; - long rem; -} ldiv_t; -/* Return the `ldiv_t' representation of NUMER over DENOM. */ -ldiv_t -ldiv (long int numer, long int denom) -{ - ldiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where - NUMER / DENOM is to be computed in infinite precision. In - other words, we should always truncate the quotient towards - zero, never -infinity. Machine division and remainer may - work either way when one or both of NUMER or DENOM is - negative. If only one is negative and QUOT has been - truncated towards -infinity, REM will have the same sign as - DENOM and the opposite sign of NUMER; if both are negative - and QUOT has been truncated towards -infinity, REM will be - positive (will have the opposite sign of NUMER). These are - considered `wrong'. If both are NUM and DENOM are positive, - RESULT will always be positive. This all boils down to: if - NUMER >= 0, but REM < 0, we got the wrong answer. In that - case, to get the right answer, add 1 to QUOT and subtract - DENOM from REM. */ - - if (numer >= 0 && result.rem < 0) - { - ++result.quot; - result.rem -= denom; - } - - return result; -} diff --git a/lib/libbb.c b/lib/libbb.c index ee91fec..4d532f6 100644 --- a/lib/libbb.c +++ b/lib/libbb.c @@ -29,7 +29,7 @@ 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 0aa4193..379a057 100644 --- a/lib/parameter.c +++ b/lib/parameter.c @@ -86,7 +86,7 @@ * 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 546edaa..e3431d4 100644 --- a/lib/process_escape_sequence.c +++ b/lib/process_escape_sequence.c @@ -21,6 +21,7 @@ */ #include #include +#include int process_escape_sequence(const char *source, char *dest, int destlen) { diff --git a/lib/readline.c b/lib/readline.c index b82150e..b90de77 100644 --- a/lib/readline.c +++ b/lib/readline.c @@ -120,10 +120,10 @@ #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 8d99595..a613d1d 100644 --- a/net/net.c +++ b/net/net.c @@ -209,7 +209,7 @@ } } -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 @@ 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 440e229..d414784 100644 --- a/net/ping.c +++ b/net/ping.c @@ -40,7 +40,7 @@ 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 @@ 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 6345a72..6be8b8f 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -364,15 +364,29 @@ return tftp_err == 0 ? 0 : 1; } -static const __maybe_unused char cmd_tftp_help[] = -"Usage: tftp [localfile]\n" -"Load a file from a TFTP server.\n" +BAREBOX_CMD_HELP_START(tftp) #ifdef CONFIG_NET_TFTP_PUSH -"or\n" -" tftp -p [remotefile]\n" -"Upload a file to a TFTP server\n" +BAREBOX_CMD_HELP_USAGE("tftp [localfile], tftp -p [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 [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). + +\ 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_HELP(cmd_tftp_help) BAREBOX_CMD_END -/** - * @page tftp_command tftp - * - * Usage: - * tftp \ [\] - * - * or - * - * tftp -p \ [\] - * - * 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). - * - * \ 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 0000000..5ec0406 --- /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("<", "\\<", "g"); + $0 = gensub(">", "\\>", "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("<", "\\<", "g"); + $0 = gensub(">", "\\>", "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("<", "\\<", "g"); + $0 = gensub(">", "\\>", "g"); + $0 = gensub("@", "\\\\@", "g"); + $0 = gensub("BAREBOX_CMD_HELP_OPT[[:space:]]*\\([[:space:]]*\"*(.*)\"[[:space:]]*,[[:space:]]*\"(.*)\"[[:space:]]*\\)", \ + " \\1 \\ \\ \\  \\2 ", "g"); + $0 = gensub("\\\\n", "", "g"); + my_opts[this_opt] = gensub("\"", "", "g"); + this_opt ++; + next; +} + +/BAREBOX_CMD_HELP_TEXT[[:space:]]*\((.*)\)/ { + + $0 = gensub("<", "\\<", "g"); + $0 = gensub(">", "\\>", "g"); + $0 = gensub("BAREBOX_CMD_HELP_TEXT[[:space:]]*\\((.*)\\)", "\\1", "g"); + $0 = gensub("\\\\n", "
", "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 " * \n"; + n = asorti(my_opts, my_opts_sorted); + for (i=1; i<=n; i++) { + printf " * " my_opts[my_opts_sorted[i]] "\n"; + } + printf " *
\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 f6cbb1c..40a3483 100644 --- a/scripts/mkimage.c +++ b/scripts/mkimage.c @@ -224,7 +224,7 @@ */ 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);