diff options
208 files changed, 9143 insertions, 962 deletions
diff --git a/Documentation/boards/aarch64-qemu-virt.rst b/Documentation/boards/aarch64-qemu-virt.rst index b6b446e4c7..e21791af16 100644 --- a/Documentation/boards/aarch64-qemu-virt.rst +++ b/Documentation/boards/aarch64-qemu-virt.rst @@ -1,10 +1,11 @@ -=========== +Aarch64 +======= Aarch64 Qemu virt ------------------------- +----------------- Running barebox on QEMU aarch64 virt machine -^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Usage:: $ qemu-system-aarch64 -m 2048M \ diff --git a/Documentation/boards/imx.rst b/Documentation/boards/imx.rst index 6912ed9a54..60cdcf072e 100644 --- a/Documentation/boards/imx.rst +++ b/Documentation/boards/imx.rst @@ -16,6 +16,7 @@ The Internal Boot Mode is supported on: * i.MX25 * i.MX35 +* i.MX50 * i.MX51 * i.MX53 * i.MX6 diff --git a/Documentation/boards/rk3288.rst b/Documentation/boards/rk3288.rst new file mode 100644 index 0000000000..3acca74302 --- /dev/null +++ b/Documentation/boards/rk3288.rst @@ -0,0 +1,57 @@ +Rockchip RK3288 +=============== + +The RK3288 SoC has a two stage boot process. The booting is completed in two +consecutive stages. The binary for the 1st stage is referred to as the +Secondary Program Loader (SPL). The binary for the 2nd stage is simply referred to +as barebox. +SPL is a non-interactive loader and is only used to boot the 2nd stage loader. + +At this moment barebox can only be used as a 2nd stage bootloader. +Starting barebox requires another bootloader which will do the very basic +SDRAM initialization for us. We can use the u-boot for that. + +Building barebox +---------------- + +The RK3288 boards in barebox are covered by the ``rk3288_defconfig``. +The resulting images will be placed under ``images/``: + +:: + barebox-rk3288-phycore-som.img + + +Starting and updating barebox +----------------------------- + +SD/MMC +^^^^^^ + +For the first stage bootloader we will need an u-boot image. A detailed +description on how to build and flash an RK3288 SPL image can be found in the +u-boot source ``u-boot/doc/README.rockchip``. + +U-boot requires an image with a special header. + + mkimage -A arm -T firmware -C none -O u-boot -a 0x02000000 -e 0 -n "barebox image" -d images/barebox-rk3288-phycore-som.img barebox.img + +To write an image that boots from an SD card (assumed to be /dev/sdc): + + sudo dd if=u-boot/u-boot-spl-dtb.bin of=/dev/sdc seek=64 bs=512 + sudo dd if=barebox.img of=/dev/sdc seek=256 bs=512 + +This puts the Rockchip header and SPL image first and then places the barebox +image at block 256 (i.e. 128KB from the start of the SD card). This +corresponds with this setting in U-Boot: + + #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 256 + +RK3288 Boards +------------- + +.. toctree:: + :glob: + :numbered: + :maxdepth: 1 + + rk3288/* diff --git a/Documentation/boards/rk3288/phytec-som.rst b/Documentation/boards/rk3288/phytec-som.rst new file mode 100644 index 0000000000..1f3c714717 --- /dev/null +++ b/Documentation/boards/rk3288/phytec-som.rst @@ -0,0 +1,24 @@ +Phytec RK3288 based SOMs +======================== + +The phycore-som-rk3288 is actually not a real board. It represents a RK3288 +based Phytec module and its boards in the barebox. +You can find out more about the Phytec SOM concept on the website: + + http://phytec.com/products/system-on-modules/ + + +Supported modules and boards +---------------------------- + +Currently, barebox supports the following SOMs and boards: + + - phyCORE + + - PCM-946 + - PCM-947 + +Building phycore-som-rk3288 +--------------------------- + +The phycore-som-rk3288 boards are covered by the ``rk3288_defconfig``. diff --git a/Documentation/user/bootchooser.rst b/Documentation/user/bootchooser.rst new file mode 100644 index 0000000000..5baa66d9b9 --- /dev/null +++ b/Documentation/user/bootchooser.rst @@ -0,0 +1,274 @@ +Barebox Bootchooser +=================== + +In many cases embedded systems are layed out redundantly with multiple +kernels and multiple root file systems. The bootchooser framework provides +the building blocks to model different use cases without the need to start +from scratch over and over again. + +The bootchooser works on abstract boot targets, each with a set of properties +and implements an algorithm which selects the highest priority target to boot. + +Bootchooser Targets +------------------- + +A bootchooser target represents one target that barebox can boot. It consists +of a set of variables in the ``global.bootchooser.<targetname>`` namespace. The +following configuration variables are needed to describe a bootchooser target: + +``global.bootchooser.<targetname>.boot`` + This controls what barebox actually boots for this target. This string can contain + anything that the :ref:`boot <command_boot>` command understands. + +``global.bootchooser.<targetname>.default_attempts`` + The default number of attempts that a target shall be tried starting. +``global.bootchooser.<targetname>.default_priority`` + The default priority of a target. + + +Additionally the following runtime variables are needed. Unlinke the configuration +variables these are automatically changed by the bootchooser algorithm: + +``global.bootchooser.<targetname>.priority`` + The current priority of the target. Higher numbers have higher priorities. A priority + of 0 means the target is disabled and won't be started. +``global.bootchooser.<targetname>.remaining_attempts`` + The remaining_attempts counter. Only targets with a remaining_attempts counter > 0 + are started. + +The bootchooser algorithm generally only starts targets that have a priority +> 0 and a remaining_attempts counter > 0. + +The Bootchooser Algorithm +------------------------- + +The bootchooser algorithm is very simple. It works with two variables per target +and some optional flags. The variables are the remaining_attempts counter that +tells how many times the target will be started. The other variable is the priority, +the target with the highest priority will be used first, a zero priority means +the target is disabled. + +When booting, bootchooser starts the target with the highest priority that has a +nonzero remaining_attempts counter. With every start of a target the remaining +attempts counter of this target is decremented by one. This means every targets +remaining_attempts counter reaches zero sooner or later and the target won't be +booted anymore. To prevent that, the remaining_attempts counter must be reset to +its default. There are different flags in the bootchooser which control resetting +the remaining_attempts counter, controlled by the ``global.bootchooser.reset_attempts`` +variable. It holds a list of space separated flags. Possible values are: + +- ``power-on``: The remaining_attempts counters of all enabled targets are reset + after a power-on reset (``$global.system.reset="POR"``). This means after a power + cycle all targets will be tried again for the configured number of retries +- ``all-zero``: The remaining_attempts counters of all enabled targets are reset + when none of them has any remaining_attempts left. + +Additionally the remaining_attempts counter can be reset manually using the +:ref:`command_bootchooser` command. This allows for custom conditions under which +a system is marked as good. +In case only the booted system itself knows when it is in a good state, the +barebox-state tool from the dt-utils_ package can used to reset the remaining_attempts +counter from the currently running system. + +.. _dt-utils: http://git.pengutronix.de/?p=tools/dt-utils.git;a=summary + +Bootchooser General Options +--------------------------- + +Additionally to the target options described above, bootchooser has some general +options not specific to any target. + +``global.bootchooser.disable_on_zero_attempts`` + Boolean flag. if 1, bootchooser disables a target (sets priority to 0) whenever the + remaining attempts counter reaches 0. +``global.bootchooser.default_attempts`` + The default number of attempts that a target shall be tried starting, used when not + overwritten with the target specific variable of the same name. +``global.bootchooser.default_priority`` + The default priority of a target when not overwritten with the target specific variable + of the same name. +``global.bootchooser.reset_attempts`` + A space separated list of events that cause bootchooser to reset the + remaining_attempts counters of each target that has a non zero priority. possible values: + * empty: counters will never be reset`` + * power-on: counters will be reset after power-on-reset + * all-zero: counters will be reset when all targets have zero remaining attempts +``global.bootchooser.reset_priorities`` + A space separated list of events that cause bootchooser to reset the priorities of + all targets. Possible values: + * empty: priorities will never be reset + * all-zero: priorities will be reset when all targets have zero priority +``global.bootchooser.retry`` + If 1, bootchooser retries booting until one succeeds or no more valid targets exist. +``global.bootchooser.state_prefix`` + Variable prefix when bootchooser used with state framework as backend for storing runtime + data, see below. +``global.bootchooser.targets`` + Space separated list of targets that are used. For each entry in the list a corresponding + set of ``global.bootchooser.<name>``. variables must exist. +``global.bootchooser.last_chosen`` + bootchooser sets this to the target that was chosen on last boot (index) + +Using the State Framework as Backend for Runtime Variable Data +-------------------------------------------------------------- + +Normally the data that is modified by the bootchooser during runtime is stored +in global variables (backed with NV). Alternatively the :ref:`state_framework` +can be used for this data, which allows to store this data redundantly +and in small EEPROM spaces. See :ref:`state_framework` to setup the state framework. +During barebox runtime each state instance will create a device +(usually named 'state' when only one is used) with a set of parameters. Set +``global.bootchooser.state_prefix`` to the name of the device and optionally the +namespace inside this device. For example when your state device is called 'state' +and inside that the 'bootchooser' namespace is used for describing the targets, +then set ``global.bootchooser.state_prefix`` to ``state.bootchooser``. + +Example +------- + +The following example shows how to initialize two targets, 'system0' and 'system1'. +Both boot from an UBIFS on nand0, the former has a priority of 21 and boots from +the volume 'system0' whereas the latter has a priority of 20 and boots from +the volume 'system1'. + +.. code-block:: sh + + # initialize target 'system0' + nv bootchooser.system0.boot=nand0.ubi.system0 + nv bootchooser.system0.default_attempts=3 + nv bootchooser.system0.default_priority=21 + + # initialize target 'system1' + nv bootchooser.system1.boot=nand0.ubi.system1 + nv bootchooser.system1.default_attempts=3 + nv bootchooser.system1.default_priority=20 + + # make targets known + nv bootchooser.targets="system0 system1" + + # retry until one target succeeds + nv bootchooser.retry="true" + + # First try bootchooser, when no targets remain boot from network + nv boot.default="bootchooser net" + +Note that this example is for testing, normally the NV variables would be +initialized directly by files in the default environment, not with a script. + +Scenarios +--------- + +This section describes some scenarios that can be solved with bootchooser. All +scenarios assume multiple slots that can be booted, where 'multiple' is anything +higher than one. + +Scenario 1 +########## + +A system that shall always boot without user interaction. Staying in the bootloader +is not an option. In this scenario a target is started for the configured number +of remaining attempts. If it cannot successfully be started, the next target is chosen. +This happens until no targets are left to start, then all remaining attempts are +reset to their defaults and the first target is tried again. + +Settings +^^^^^^^^ +- ``global.bootchooser.reset_attempts="all-zero"`` +- ``global.bootchooser.reset_priorities="all-zero"`` +- ``global.bootchooser.disable_on_zero_attempts=0`` +- ``global.bootchooser.retry=1`` +- ``global.boot.default="bootchooser recovery"`` +- Userspace marks as good + +Deployment +^^^^^^^^^^ + +#. barebox or flash robot fills all slots with valid systems. +#. The all-zero settings will lead to automatically enabling the slots, no + default settings are needed here. + +Recovery +^^^^^^^^ + +Recovery will only be called when all targets are not startable (That is, no valid +Kernel found or read failure). Once a target is startable (A valid kernel is found +and started) Bootchooser will never fall through to the recovery target. + +Scenario 2 +########## + +A system with multiple slots, a slot that was booted three times without success +shall never be booted again (except after update or user interaction). + +Settings +^^^^^^^^ + +- ``global.bootchooser.reset_attempts=""`` +- ``global.bootchooser.reset_priorities=""`` +- ``global.bootchooser.disable_on_zero_attempts=0`` +- ``global.bootchooser.retry=1`` +- ``global.boot.default="bootchooser recovery"`` +- Userspace marks as good + +Deployment +^^^^^^^^^^ + +#. barebox or flash robot fills all slots with valid systems +#. barebox or flash robot marks slots as good or state contains non zero + defaults for the remaining_attempts / priorities + +Recovery +^^^^^^^^ +done by 'recovery' boot target which is booted after the bootchooser falls through due to +the lack of bootable targets. This target can be: +- A system that will be booted as recovery +- A barebox script that will be started + +Scenario 3 +########## + +A system with multiple slots and one recovery system. Booting a slot three times +without success disables it. A power cycle shall not be counted as failed boot. + +Settings +^^^^^^^^ + +- ``global.bootchooser.reset_attempts="power-on"`` +- ``global.bootchooser.reset_priorities=""`` +- ``global.bootchooser.disable_on_zero_attempts=1`` +- ``global.bootchooser.retry=1`` +- ``global.boot.default="bootchooser recovery"`` +- Userspace marks as good + +Deployment +^^^^^^^^^^ + +- barebox or flash robot fills all slots with valid systems +- barebox or flash robot marks slots as good + +Recovery +^^^^^^^^ + +Done by 'recovery' boot target which is booted after the bootchooser falls through +due to the lack of bootable targets. This target can be: +- A system that will be booted as recovery +- A barebox script that will be started + +Updating systems +---------------- + +Updating a slot is the same among the different scenarios. It is assumed that the +update is done under a running Linux system which can be one of the regular bootchooser +slots or a dedicated recovery system. For the regular slots updating is done like: + +- Set the priority of the inactive slot to 0. +- Update the inactive slot +- Set priority of the inactive slot to a higher value than the active slot +- Set remaining_attempts of the inactive slot to nonzero +- Reboot +- If necessary update the now inactive, not yet updated slot the same way + +One way of updating systems is using RAUC_ which integrates well with the bootchooser +in barebox. + +.. _RAUC: https://rauc.readthedocs.io/en/latest/ RAUC ( diff --git a/Documentation/user/imd.rst b/Documentation/user/imd.rst index e0251d644e..ce1b90c936 100644 --- a/Documentation/user/imd.rst +++ b/Documentation/user/imd.rst @@ -22,7 +22,9 @@ The informations can be extracted with the ``bareboximd`` tool which lives under ``scripts/`` in the barebox sourcecode. If enabled it is compiled for the compile host and also for the target architecture. barebox itself has the :ref:`command_imd` command to extract the informations. Here is an example output of the tool called -without additional options:: +without additional options: + +.. code-block:: none # imd barebox-phytec-pbab01dl-1gib.img build: #890 Wed Jul 30 16:15:24 CEST 2014 @@ -31,7 +33,9 @@ without additional options:: of_compatible: phytec,imx6x-pbab01 phytec,imx6dl-pfla02 fsl,imx6dl model: Phytec phyFLEX-i.MX6 Duallite Carrier-Board -Single informations can be extracted with the ``-t <type>`` option:: +Single informations can be extracted with the ``-t <type>`` option: + +.. code-block:: none # imd barebox-phytec-pbab01dl-1gib.img -t release 2014.07.0-00167-ge6632a9-dirty diff --git a/Documentation/user/state.rst b/Documentation/user/state.rst index c401f105bd..5dd5c486e2 100644 --- a/Documentation/user/state.rst +++ b/Documentation/user/state.rst @@ -1,3 +1,5 @@ +.. _state_framework: + Barebox State Framework ======================= diff --git a/Documentation/user/usb.rst b/Documentation/user/usb.rst index 8602a8f7fe..bbcb045cee 100644 --- a/Documentation/user/usb.rst +++ b/Documentation/user/usb.rst @@ -56,7 +56,9 @@ shall be provided to the host. For the possible ``flags`` see On the host side, the tool `dfu-util <http://dfu-util.gnumonks.org/>`_ can be used to update the partitions. It is available for most distributions and typically -supports the following options:: +supports the following options: + +.. code-block:: none dfu-util -h Usage: dfu-util [options] ... diff --git a/Documentation/user/user-manual.rst b/Documentation/user/user-manual.rst index 5841ea625c..435649f353 100644 --- a/Documentation/user/user-manual.rst +++ b/Documentation/user/user-manual.rst @@ -27,6 +27,7 @@ Contents: usb ubi booting-linux + bootchooser remote-control system-setup reset-reason @@ -1,5 +1,5 @@ VERSION = 2016 -PATCHLEVEL = 08 +PATCHLEVEL = 10 SUBLEVEL = 0 EXTRAVERSION = NAME = None diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f13cc1d25e..632037f299 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1,8 +1,6 @@ config ARM bool select HAS_KALLSYMS - select HAS_MODULES - select HAS_DMA select HAS_CACHE select HAVE_CONFIGURABLE_TEXT_BASE select HAVE_PBL_IMAGE @@ -377,6 +375,7 @@ config ARM_UNWIND config ARM_SEMIHOSTING bool "enable ARM semihosting support" + depends on !CPU_V8 help This option enables ARM semihosting support in barebox. ARM semihosting is a communication discipline that allows code diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 55f72484c9..96ec588da0 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -314,9 +314,5 @@ endif common- += $(patsubst %,arch/arm/boards/%/,$(board-)) CLEAN_FILES += include/generated/mach-types.h barebox-flash-image - -ifeq ($(CONFIG_CPU_V8), y) CLEAN_FILES += arch/arm/lib64/barebox.lds -else CLEAN_FILES += arch/arm/lib32/barebox.lds -endif diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 35b636f0cf..da6ea0d1cc 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -96,6 +96,7 @@ obj-$(CONFIG_MACH_PM9G45) += pm9g45/ obj-$(CONFIG_MACH_QIL_A9260) += qil-a926x/ obj-$(CONFIG_MACH_QIL_A9G20) += qil-a926x/ obj-$(CONFIG_MACH_RADXA_ROCK) += radxa-rock/ +obj-$(CONFIG_MACH_PHYTEC_SOM_RK3288) += phytec-som-rk3288/ obj-$(CONFIG_MACH_REALQ7) += datamodul-edm-qmx6/ obj-$(CONFIG_MACH_RPI_COMMON) += raspberry-pi/ obj-$(CONFIG_MACH_SABRELITE) += freescale-mx6-sabrelite/ @@ -136,4 +137,5 @@ obj-$(CONFIG_MACH_VIRT2REAL) += virt2real/ obj-$(CONFIG_MACH_ZEDBOARD) += avnet-zedboard/ obj-$(CONFIG_MACH_ZYLONITE) += zylonite/ obj-$(CONFIG_MACH_VARISCITE_MX6) += variscite-mx6/ +obj-$(CONFIG_MACH_VSCOM_BALTOS) += vscom-baltos/ obj-$(CONFIG_MACH_QEMU_VIRT64) += qemu-virt64/ diff --git a/arch/arm/boards/afi-gf/defaultenv-gf/boot/sd b/arch/arm/boards/afi-gf/defaultenv-gf/boot/sd index dce060542a..aa94b2fa2e 100644 --- a/arch/arm/boards/afi-gf/defaultenv-gf/boot/sd +++ b/arch/arm/boards/afi-gf/defaultenv-gf/boot/sd @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - boot-menu-add-entry "$0" "kernel & rootfs on SD card" - exit -fi - global.bootm.image=/boot/uImage global.bootm.oftree=/boot/oftree #global.bootm.initrd=<path to initrd> diff --git a/arch/arm/boards/afi-gf/defaultenv-gf/init/automount b/arch/arm/boards/afi-gf/defaultenv-gf/init/automount index c67bd1ba50..560bdb7975 100644 --- a/arch/arm/boards/afi-gf/defaultenv-gf/init/automount +++ b/arch/arm/boards/afi-gf/defaultenv-gf/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth1.serverip mkdir -p /mnt/tftp diff --git a/arch/arm/boards/at91sam9m10ihd/env/boot/android b/arch/arm/boards/at91sam9m10ihd/env/boot/android index 8492e41f7f..ce5aa32353 100644 --- a/arch/arm/boards/at91sam9m10ihd/env/boot/android +++ b/arch/arm/boards/at91sam9m10ihd/env/boot/android @@ -3,4 +3,4 @@ global.bootm.image="/dev/nand0.kernel.bb" global.linux.bootargs.dyn.root="root=/dev/mtdblock1 rootfstype=jffs2 rw init=/init rootdelay=1" # clean the mtdparts otherwise android does not boot -global -r linux.mtdparts. +global -r "linux.mtdparts.*" diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/automount b/arch/arm/boards/at91sam9m10ihd/env/init/automount index 5bb63ccb9e..96ffa7059a 100644 --- a/arch/arm/boards/at91sam9m10ihd/env/init/automount +++ b/arch/arm/boards/at91sam9m10ihd/env/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth0.serverip mkdir -p /mnt/tftp diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-001-nand b/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-001-nand index ac516d82d7..433bc888da 100644 --- a/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-001-nand +++ b/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-001-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="128k(nand0.at91bootstrap),256k(nand0.barebox)ro,128k(nand0.bareboxenv),128k(nand0.bareboxenv2),128k(nand0.oftree),1280k(nand0.free),3M(nand0.kernel),195M(nand0.rootfs),300M(nand0.userdata),-(nand0.cache)" kernelname="atmel_nand" diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-002-m25p80 b/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-002-m25p80 index 44198c820e..5457e4e0d4 100644 --- a/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-002-m25p80 +++ b/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-002-m25p80 @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "SPI NOR partitions" - exit -fi - mtdparts="32k(m25p0.at91bootstrap)ro,256k(m25p0.barebox),128k(m25p0.bareboxenv),128k(m25p0.bareboxenv2),128k(m25p0.oftree),-(m25p0.kernel)" kernelname="m25p0" diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/ps1 b/arch/arm/boards/at91sam9m10ihd/env/init/ps1 deleted file mode 100644 index a94acc14f8..0000000000 --- a/arch/arm/boards/at91sam9m10ihd/env/init/ps1 +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -/env/config - -if [ ${global.allow_color} = "true" ]; then - export PS1="\e[1;32mbarebox@\e[1;36m\h:\w\e[0m\n# " -else - export PS1="barebox@\h:\w\n# " -fi diff --git a/arch/arm/boards/beagle/defaultenv-beagle/init/mtdparts-nand b/arch/arm/boards/beagle/defaultenv-beagle/init/mtdparts-nand index 9335bb17a3..48c1c5d9ee 100644 --- a/arch/arm/boards/beagle/defaultenv-beagle/init/mtdparts-nand +++ b/arch/arm/boards/beagle/defaultenv-beagle/init/mtdparts-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="128k(nand0.xload),256k(nand0.barebox)ro,128k(nand0.bareboxenv),128k(nand0.oftree),4M(nand0.kernel),120M(nand0.rootfs),-(nand0.data)" kernelname="omap2-nand" diff --git a/arch/arm/boards/ccxmx51/env/init/mtdparts-nand b/arch/arm/boards/ccxmx51/env/init/mtdparts-nand index 5ea35d2ef7..27ed38a888 100644 --- a/arch/arm/boards/ccxmx51/env/init/mtdparts-nand +++ b/arch/arm/boards/ccxmx51/env/init/mtdparts-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="512k(barebox)ro,256k(bareboxenv),3328k(kernel),-(root)" kernelname="mxc_nand" diff --git a/arch/arm/boards/clep7212/defaultenv-clep7212/init/mtdparts-nor b/arch/arm/boards/clep7212/defaultenv-clep7212/init/mtdparts-nor index 8702b4059c..39777f95f2 100644 --- a/arch/arm/boards/clep7212/defaultenv-clep7212/init/mtdparts-nor +++ b/arch/arm/boards/clep7212/defaultenv-clep7212/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="256k(boot),256k(env),3584k(kernel),-(root)" kernelname="physmap-flash.0" diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/init/automount b/arch/arm/boards/crystalfontz-cfa10036/env/init/automount index 8fdca7cd47..6f85c27289 100644 --- a/arch/arm/boards/crystalfontz-cfa10036/env/init/automount +++ b/arch/arm/boards/crystalfontz-cfa10036/env/init/automount @@ -1,9 +1,4 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - mkdir -p /mnt/disk0.2 automount -d /mnt/disk0.2 '[ -e /dev/disk0.2 ] && mount /dev/disk0.2 /mnt/disk0.2' diff --git a/arch/arm/boards/datamodul-edm-qmx6/env/init/automount b/arch/arm/boards/datamodul-edm-qmx6/env/init/automount index 2ce37c785a..e786b82bdb 100644 --- a/arch/arm/boards/datamodul-edm-qmx6/env/init/automount +++ b/arch/arm/boards/datamodul-edm-qmx6/env/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth0.serverip mkdir -p /mnt/tftp diff --git a/arch/arm/boards/ebv-socrates/board.c b/arch/arm/boards/ebv-socrates/board.c index 5d2d619914..f3207b88ef 100644 --- a/arch/arm/boards/ebv-socrates/board.c +++ b/arch/arm/boards/ebv-socrates/board.c @@ -2,6 +2,9 @@ #include <types.h> #include <driver.h> #include <init.h> +#include <bbu.h> +#include <bootsource.h> +#include <filetype.h> #include <asm/armlinux.h> #include <linux/micrel_phy.h> #include <linux/phy.h> @@ -26,12 +29,45 @@ static int phy_fixup(struct phy_device *dev) static int socrates_init(void) { + enum bootsource bootsource = bootsource_get(); + uint32_t flag_qspi = 0; + uint32_t flag_mmc = 0; + if (!of_machine_is_compatible("ebv,socrates")) return 0; if (IS_ENABLED(CONFIG_PHYLIB)) phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, phy_fixup); + switch (bootsource) { + case BOOTSOURCE_MMC: + flag_mmc |= BBU_HANDLER_FLAG_DEFAULT; + break; + case BOOTSOURCE_SPI: + flag_qspi |= BBU_HANDLER_FLAG_DEFAULT; + break; + default: + break; + } + + bbu_register_std_file_update("qspi-xload0", flag_qspi, + "/dev/mtd0.prebootloader0", + filetype_socfpga_xload); + bbu_register_std_file_update("qspi-xload1", 0, + "/dev/mtd0.prebootloader1", + filetype_socfpga_xload); + bbu_register_std_file_update("qspi-xload2", 0, + "/dev/mtd0.prebootloader2", + filetype_socfpga_xload); + bbu_register_std_file_update("qspi-xload3", 0, + "/dev/mtd0.prebootloader3", + filetype_socfpga_xload); + bbu_register_std_file_update("qspi", 0, "/dev/mtd0.barebox", + filetype_arm_barebox); + + bbu_register_std_file_update("mmc-xload", flag_mmc, "/dev/mmc0.0", + filetype_socfpga_xload); + return 0; } postcore_initcall(socrates_init); diff --git a/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/init/automount b/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/init/automount index 8cb5eaf792..71dfd95f2b 100644 --- a/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/init/automount +++ b/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth0.serverip mkdir -p /mnt/tftp diff --git a/arch/arm/boards/freescale-mx6-sabrelite/lowlevel.c b/arch/arm/boards/freescale-mx6-sabrelite/lowlevel.c index abfb77a157..3b51e016e6 100644 --- a/arch/arm/boards/freescale-mx6-sabrelite/lowlevel.c +++ b/arch/arm/boards/freescale-mx6-sabrelite/lowlevel.c @@ -3,29 +3,70 @@ #include <mach/generic.h> #include <asm/barebox-arm-head.h> #include <asm/barebox-arm.h> +#include <mach/imx6-regs.h> +#include <io.h> +#include <mach/debug_ll.h> +#include <mach/esdctl.h> +#include <asm/cache.h> extern char __dtb_imx6q_sabrelite_start[]; -ENTRY_FUNCTION(start_imx6q_sabrelite, r0, r1, r2) +static noinline void imx6q_sabrelite_start(void) { - void *fdt; + void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR); + void __iomem *uart = IOMEM(MX6_UART2_BASE_ADDR); + + writel(0x4, iomuxbase + 0x0bc); + + imx6_ungate_all_peripherals(); + imx6_uart_setup(uart); + pbl_set_putc(imx_uart_putc, uart); + pr_debug("Freescale i.MX6q SabreLite\n"); + + imx6q_barebox_entry(__dtb_imx6q_sabrelite_start); +} + +ENTRY_FUNCTION(start_imx6q_sabrelite, r0, r1, r2) +{ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_sabrelite_start - get_runtime_offset(); + arm_early_mmu_cache_invalidate(); + + relocate_to_current_adr(); + setup_c(); + barrier(); - barebox_arm_entry(0x10000000, SZ_1G, fdt); + imx6q_sabrelite_start(); } extern char __dtb_imx6dl_sabrelite_start[]; -ENTRY_FUNCTION(start_imx6dl_sabrelite, r0, r1, r2) +static noinline void imx6dl_sabrelite_start(void) { - void *fdt; + void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR); + void __iomem *uart = IOMEM(MX6_UART2_BASE_ADDR); + + writel(0x4, iomuxbase + 0x16c); + + imx6_ungate_all_peripherals(); + imx6_uart_setup(uart); + pbl_set_putc(imx_uart_putc, uart); + pr_debug("Freescale i.MX6q SabreLite\n"); + + imx6q_barebox_entry(__dtb_imx6q_sabrelite_start); +} + +ENTRY_FUNCTION(start_imx6dl_sabrelite, r0, r1, r2) +{ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6dl_sabrelite_start - get_runtime_offset(); + arm_early_mmu_cache_invalidate(); + + relocate_to_current_adr(); + setup_c(); + barrier(); - barebox_arm_entry(0x10000000, SZ_1G, fdt); + imx6dl_sabrelite_start(); } diff --git a/arch/arm/boards/friendlyarm-mini2440/env/init/mtdparts-nand b/arch/arm/boards/friendlyarm-mini2440/env/init/mtdparts-nand index 7271341565..b51104ad76 100644 --- a/arch/arm/boards/friendlyarm-mini2440/env/init/mtdparts-nand +++ b/arch/arm/boards/friendlyarm-mini2440/env/init/mtdparts-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="256k(nand0.barebox),128k(nand0.bareboxenv),1536k(nand0.kernel),-(nand0.root)" kernelname="nand" diff --git a/arch/arm/boards/guf-santaro/lowlevel.c b/arch/arm/boards/guf-santaro/lowlevel.c index e2b6df5839..1502bb3d38 100644 --- a/arch/arm/boards/guf-santaro/lowlevel.c +++ b/arch/arm/boards/guf-santaro/lowlevel.c @@ -3,36 +3,47 @@ #include <io.h> #include <asm/barebox-arm-head.h> #include <asm/barebox-arm.h> +#include <asm/cache.h> #include <mach/generic.h> #include <mach/imx6-regs.h> #include <debug_ll.h> +#include <console.h> +#include <mach/esdctl.h> static inline void setup_uart(void) { - void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; + void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR); writel(0x1, iomuxbase + 0x2b0); imx6_ungate_all_peripherals(); - imx6_uart_setup_ll(); - - putc_ll('>'); + imx6_uart_setup(IOMEM(MX6_UART2_BASE_ADDR)); } extern char __dtb_imx6q_guf_santaro_start[]; -ENTRY_FUNCTION(start_imx6q_guf_santaro, r0, r1, r2) +static noinline void santaro_start(void) { - void *fdt; + pbl_set_putc(imx_uart_putc, IOMEM(MX6_UART2_BASE_ADDR)); + + pr_debug("Garz+Fricke Santaro\n"); + + imx6q_barebox_entry(__dtb_imx6q_guf_santaro_start); +} +ENTRY_FUNCTION(start_imx6q_guf_santaro, r0, r1, r2) +{ imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); - if (IS_ENABLED(CONFIG_DEBUG_LL)) - setup_uart(); + arm_early_mmu_cache_invalidate(); + + setup_uart(); - fdt = __dtb_imx6q_guf_santaro_start - get_runtime_offset(); + relocate_to_current_adr(); + setup_c(); + barrier(); - barebox_arm_entry(0x10000000, SZ_1G, fdt); + santaro_start(); } diff --git a/arch/arm/boards/highbank/defaultenv-highbank/init/automount b/arch/arm/boards/highbank/defaultenv-highbank/init/automount index 2c283c6eed..eb5c07a739 100644 --- a/arch/arm/boards/highbank/defaultenv-highbank/init/automount +++ b/arch/arm/boards/highbank/defaultenv-highbank/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth0.serverip mkdir -p /mnt/tftp diff --git a/arch/arm/boards/highbank/env/init/ps1 b/arch/arm/boards/highbank/env/init/ps1 deleted file mode 100644 index a94acc14f8..0000000000 --- a/arch/arm/boards/highbank/env/init/ps1 +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -/env/config - -if [ ${global.allow_color} = "true" ]; then - export PS1="\e[1;32mbarebox@\e[1;36m\h:\w\e[0m\n# " -else - export PS1="barebox@\h:\w\n# " -fi diff --git a/arch/arm/boards/highbank/init.c b/arch/arm/boards/highbank/init.c index 128132ad48..577ccc0b74 100644 --- a/arch/arm/boards/highbank/init.c +++ b/arch/arm/boards/highbank/init.c @@ -78,7 +78,7 @@ static int highbank_mem_init(void) fdt = IOMEM(FIRMWARE_DTB_BASE); root = of_unflatten_dtb(fdt); - if (!root) { + if (IS_ERR(root)) { pr_warn("no dtb found at 0x1000 use default configuration\n"); fdt = NULL; goto not_found; diff --git a/arch/arm/boards/karo-tx25/env/init/mtdparts-nand b/arch/arm/boards/karo-tx25/env/init/mtdparts-nand index e2dcfab49a..0288163ad1 100644 --- a/arch/arm/boards/karo-tx25/env/init/mtdparts-nand +++ b/arch/arm/boards/karo-tx25/env/init/mtdparts-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="512k(nand0.barebox),512k(nand0.bareboxenv),4M(nand0.kernel),-(nand0.root)" kernelname="mxc_nand" diff --git a/arch/arm/boards/lubbock/env/init/mtdparts-nor b/arch/arm/boards/lubbock/env/init/mtdparts-nor index 3307596467..b5c4e32411 100644 --- a/arch/arm/boards/lubbock/env/init/mtdparts-nor +++ b/arch/arm/boards/lubbock/env/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="2048k@0(nor0.barebox)ro,256k(nor0.barebox-env),256k(nor0.barebox-logo),256k(nor0.barebox-logo2),5120k(nor0.kernel),-(nor0.root)" kernelname="application-flash" diff --git a/arch/arm/boards/mainstone/env/init/mtdparts-nor b/arch/arm/boards/mainstone/env/init/mtdparts-nor index 3307596467..b5c4e32411 100644 --- a/arch/arm/boards/mainstone/env/init/mtdparts-nor +++ b/arch/arm/boards/mainstone/env/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="2048k@0(nor0.barebox)ro,256k(nor0.barebox-env),256k(nor0.barebox-logo),256k(nor0.barebox-logo2),5120k(nor0.kernel),-(nor0.root)" kernelname="application-flash" diff --git a/arch/arm/boards/mx31moboard/env/init/mtdparts-nor b/arch/arm/boards/mx31moboard/env/init/mtdparts-nor index f09a9cc381..ab5b175c37 100644 --- a/arch/arm/boards/mx31moboard/env/init/mtdparts-nor +++ b/arch/arm/boards/mx31moboard/env/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="512k(nor0.barebox)ro,256k(nor0.bareboxenv),4M(nor0.kernel),-(nor0.root)" kernelname="physmap-flash.0" diff --git a/arch/arm/boards/phytec-phycore-imx27/defaultenv-pcm038/boot/nor b/arch/arm/boards/phytec-phycore-imx27/defaultenv-pcm038/boot/nor index 0d10584abc..f584307d7a 100644 --- a/arch/arm/boards/phytec-phycore-imx27/defaultenv-pcm038/boot/nor +++ b/arch/arm/boards/phytec-phycore-imx27/defaultenv-pcm038/boot/nor @@ -1,9 +1,4 @@ #!/bin/sh -if [ "$1" = menu ]; then - boot-menu-add-entry "$0" "nor" - exit -fi - global.bootm.image="/dev/nor0.kernel" global.linux.bootargs.dyn.root="root=/dev/mtdblock3 ro" diff --git a/arch/arm/boards/phytec-phycore-imx31/env/init/mtdparts-nand b/arch/arm/boards/phytec-phycore-imx31/env/init/mtdparts-nand index 84220b77b3..540277cdeb 100644 --- a/arch/arm/boards/phytec-phycore-imx31/env/init/mtdparts-nand +++ b/arch/arm/boards/phytec-phycore-imx31/env/init/mtdparts-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="512k(nand0.barebox)ro,128k(nand0.bareboxenv),4M(nand0.kernel),-(nand0.root)" kernelname="mxc_nand" diff --git a/arch/arm/boards/phytec-phycore-imx31/env/init/mtdparts-nor b/arch/arm/boards/phytec-phycore-imx31/env/init/mtdparts-nor index 2ef6ead71a..940eb86c95 100644 --- a/arch/arm/boards/phytec-phycore-imx31/env/init/mtdparts-nor +++ b/arch/arm/boards/phytec-phycore-imx31/env/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="256k(nor0.barebox)ro,128k(nor0.bareboxenv),4M(nor0.kernel),-(nor0.root)" kernelname="physmap-flash.0" diff --git a/arch/arm/boards/phytec-phycore-imx35/env/init/mtdparts-nand b/arch/arm/boards/phytec-phycore-imx35/env/init/mtdparts-nand index 8a41f62810..c7185db7f7 100644 --- a/arch/arm/boards/phytec-phycore-imx35/env/init/mtdparts-nand +++ b/arch/arm/boards/phytec-phycore-imx35/env/init/mtdparts-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="512k(nand0.barebox),256k(nand0.bareboxenv),4M(nand0.kernel),-(nand0.root)" kernelname="mxc_nand" diff --git a/arch/arm/boards/phytec-phycore-imx35/env/init/mtdparts-nor b/arch/arm/boards/phytec-phycore-imx35/env/init/mtdparts-nor index f787f28442..09c3ba9842 100644 --- a/arch/arm/boards/phytec-phycore-imx35/env/init/mtdparts-nor +++ b/arch/arm/boards/phytec-phycore-imx35/env/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="512k(nor0.barebox),128k(nor0.bareboxenv),4M(nor0.kernel),-(nor0.root)" kernelname="physmap-flash.0" diff --git a/arch/arm/boards/phytec-phycore-pxa270/env/init/mtdparts-nor b/arch/arm/boards/phytec-phycore-pxa270/env/init/mtdparts-nor index e617cbaaba..4423943211 100644 --- a/arch/arm/boards/phytec-phycore-pxa270/env/init/mtdparts-nor +++ b/arch/arm/boards/phytec-phycore-pxa270/env/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="512k(nor0.barebox),256k(nor0.bareboxenv),4M(nor0.kernel),-(nor0.root)" kernelname="physmap-flash.0" diff --git a/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/automount b/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/automount index a059e190e2..91ded44119 100644 --- a/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/automount +++ b/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6-phycore/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth0.serverip mkdir -p /mnt/tftp diff --git a/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/automount b/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/automount index 49d99bd78d..4b223d8037 100644 --- a/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/automount +++ b/arch/arm/boards/phytec-som-imx6/defaultenv-physom-imx6/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth0.serverip mkdir -p /mnt/tftp diff --git a/arch/arm/boards/phytec-som-rk3288/Makefile b/arch/arm/boards/phytec-som-rk3288/Makefile new file mode 100644 index 0000000000..6f34c9a2f2 --- /dev/null +++ b/arch/arm/boards/phytec-som-rk3288/Makefile @@ -0,0 +1,3 @@ +obj-y += board.o +lwl-y += lowlevel.o +bbenv-y += defaultenv-physom-rk3288 diff --git a/arch/arm/boards/phytec-som-rk3288/board.c b/arch/arm/boards/phytec-som-rk3288/board.c new file mode 100644 index 0000000000..8ea6c6c47c --- /dev/null +++ b/arch/arm/boards/phytec-som-rk3288/board.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 PHYTEC Messtechnik GmbH, + * Author: Wadim Egorov <w.egorov@phytec.de> + * + * Device initialization for the phyCORE-RK3288 SoM + * + * 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. + * + * 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. + */ + +#include <common.h> +#include <init.h> +#include <envfs.h> + +static int physom_devices_init(void) +{ + if (!of_machine_is_compatible("phytec,rk3288-phycore-som")) + return 0; + + barebox_set_hostname("pcm059"); + defaultenv_append_directory(defaultenv_physom_rk3288); + + return 0; +} +device_initcall(physom_devices_init); diff --git a/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/boot/emmc b/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/boot/emmc new file mode 100644 index 0000000000..731b07f604 --- /dev/null +++ b/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/boot/emmc @@ -0,0 +1,6 @@ +#!/bin/sh + +global.bootm.image=/mnt/emmc/linuximage +global.bootm.oftree=/mnt/emmc/oftree + +global.linux.bootargs.dyn.root="root=/dev/mmcblk0p2 rw rootwait" diff --git a/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/boot/mmc b/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/boot/mmc new file mode 100644 index 0000000000..5b19dbac02 --- /dev/null +++ b/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/boot/mmc @@ -0,0 +1,6 @@ +#!/bin/sh + +global.bootm.image=/mnt/sdmmc/linuximage +global.bootm.oftree=/mnt/sdmmc/oftree + +global.linux.bootargs.dyn.root="root=/dev/mmcblk1p2 rw rootwait" diff --git a/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/init/automount-mmc b/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/init/automount-mmc new file mode 100644 index 0000000000..8b3f043bba --- /dev/null +++ b/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/init/automount-mmc @@ -0,0 +1,7 @@ +#!/bin/sh + +mkdir -p /mnt/emmc +automount -d /mnt/emmc 'mshc0.probe=1 && [ -e /dev/mshc0.0 ] && mount /dev/mshc0.0 /mnt/emmc' + +mkdir -p /mnt/sdmmc +automount -d /mnt/sdmmc 'mshc1.probe=1 && [ -e /dev/mshc1.0 ] && mount /dev/mshc1.0 /mnt/sdmmc' diff --git a/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/nv/boot.default b/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/nv/boot.default new file mode 100644 index 0000000000..b4cedfc16b --- /dev/null +++ b/arch/arm/boards/phytec-som-rk3288/defaultenv-physom-rk3288/nv/boot.default @@ -0,0 +1 @@ +emmc mmc diff --git a/arch/arm/boards/phytec-som-rk3288/lowlevel.c b/arch/arm/boards/phytec-som-rk3288/lowlevel.c new file mode 100644 index 0000000000..7804a55bcd --- /dev/null +++ b/arch/arm/boards/phytec-som-rk3288/lowlevel.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 PHYTEC Messtechnik GmbH, + * Author: Wadim Egorov <w.egorov@phytec.de> + * + * 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. + * + * 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. + */ + +#include <common.h> +#include <linux/sizes.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <mach/rk3288-regs.h> +#include <mach/grf_rk3288.h> +#include <mach/hardware.h> +#include <debug_ll.h> + +extern char __dtb_rk3288_phycore_som_start[]; + +ENTRY_FUNCTION(start_rk3288_phycore_som, r0, r1, r2) +{ + void *fdt; + arm_cpu_lowlevel_init(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) { + struct rk3288_grf * const grf = (void *)RK3288_GRF_BASE; + rk_clrsetreg(&grf->gpio4c_iomux, + GPIO4C1_MASK << GPIO4C1_SHIFT | + GPIO4C0_MASK << GPIO4C0_SHIFT, + GPIO4C1_UART0BT_SOUT << GPIO4C1_SHIFT | + GPIO4C0_UART0BT_SIN << GPIO4C0_SHIFT); + INIT_LL(); + } + + fdt = __dtb_rk3288_phycore_som_start - get_runtime_offset(); + + barebox_arm_entry(0x0, SZ_1G, fdt); +} diff --git a/arch/arm/boards/radxa-rock/board.c b/arch/arm/boards/radxa-rock/board.c index ec053f9123..d45e8a9c52 100644 --- a/arch/arm/boards/radxa-rock/board.c +++ b/arch/arm/boards/radxa-rock/board.c @@ -16,7 +16,7 @@ #include <io.h> #include <i2c/i2c.h> #include <i2c/i2c-gpio.h> -#include <mach/rockchip-regs.h> +#include <mach/rk3188-regs.h> #include <mfd/act8846.h> #include <asm/armlinux.h> diff --git a/arch/arm/boards/raspberry-pi/env/init/bootargs-base b/arch/arm/boards/raspberry-pi/env/init/bootargs-base index 4dda5501e3..416dc8a6f4 100644 --- a/arch/arm/boards/raspberry-pi/env/init/bootargs-base +++ b/arch/arm/boards/raspberry-pi/env/init/bootargs-base @@ -1,8 +1,3 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Base bootargs" - exit -fi - global.linux.bootargs.base="console=ttyAMA0,115200" diff --git a/arch/arm/boards/raspberry-pi/env/init/ps1 b/arch/arm/boards/raspberry-pi/env/init/ps1 deleted file mode 100644 index f8948466d3..0000000000 --- a/arch/arm/boards/raspberry-pi/env/init/ps1 +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -if [ ${global.allow_color} = "true" ]; then - export PS1="\e[1;32mbarebox@\e[1;36m\h:\w\e[0m\n# " -else - export PS1="barebox@\h:\w\n# " -fi diff --git a/arch/arm/boards/telit-evk-pro3/env/init/mtdparts-nand b/arch/arm/boards/telit-evk-pro3/env/init/mtdparts-nand index 58e859bb96..42907ae3a7 100644 --- a/arch/arm/boards/telit-evk-pro3/env/init/mtdparts-nand +++ b/arch/arm/boards/telit-evk-pro3/env/init/mtdparts-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="0xC0000(nand0.bootstrap),256k(nand0.barebox)ro,128k(nand0.bareboxenv),3M(nand0.kernel),-(nand0.rootfs)" kernelname="atmel_nand" diff --git a/arch/arm/boards/versatile/env/boot/nor b/arch/arm/boards/versatile/env/boot/nor index 3f31605c4f..f90bcc3fca 100644 --- a/arch/arm/boards/versatile/env/boot/nor +++ b/arch/arm/boards/versatile/env/boot/nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - boot-menu-add-entry "$0" "nor" - exit -fi - global.bootm.image="/dev/nor0.kernel" global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=5 rootfstype=ubifs" diff --git a/arch/arm/boards/versatile/env/boot/nor-update b/arch/arm/boards/versatile/env/boot/nor-update index 728889d20f..5799ed68d1 100644 --- a/arch/arm/boards/versatile/env/boot/nor-update +++ b/arch/arm/boards/versatile/env/boot/nor-update @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - boot-menu-add-entry "$0" "nor update" - exit -fi - global.bootm.image="/dev/nor0.update" dtb=/dev/nor0.dtb diff --git a/arch/arm/boards/versatile/env/init/automount b/arch/arm/boards/versatile/env/init/automount index 53f9196a15..d08990b53c 100644 --- a/arch/arm/boards/versatile/env/init/automount +++ b/arch/arm/boards/versatile/env/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth0.serverip mkdir -p /mnt/tftp diff --git a/arch/arm/boards/versatile/env/init/mtdparts-nor b/arch/arm/boards/versatile/env/init/mtdparts-nor index 9079d482da..20c2b994cc 100644 --- a/arch/arm/boards/versatile/env/init/mtdparts-nor +++ b/arch/arm/boards/versatile/env/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="512k(nor0.barebox)ro,512k(nor0.bareboxenv),4864k(nor0.kernel),256k(nor0.dtb),3M(nor0.update),-(nor0.root)" kernelname="physmap-flash.0" diff --git a/arch/arm/boards/versatile/env/init/ps1 b/arch/arm/boards/versatile/env/init/ps1 deleted file mode 100644 index a1d075499f..0000000000 --- a/arch/arm/boards/versatile/env/init/ps1 +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -if [ ${global.allow_color} = "true" ]; then - export PS1="\e[1;32mbarebox@\e[1;36m\h:\w\e[0m\n# " -else - export PS1="barebox@\h:\w\n# " -fi diff --git a/arch/arm/boards/vscom-baltos/Makefile b/arch/arm/boards/vscom-baltos/Makefile new file mode 100644 index 0000000000..092c31d6b2 --- /dev/null +++ b/arch/arm/boards/vscom-baltos/Makefile @@ -0,0 +1,2 @@ +lwl-y += lowlevel.o +obj-y += board.o diff --git a/arch/arm/boards/vscom-baltos/board.c b/arch/arm/boards/vscom-baltos/board.c new file mode 100644 index 0000000000..dc08ed5a20 --- /dev/null +++ b/arch/arm/boards/vscom-baltos/board.c @@ -0,0 +1,132 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * Raghavendra KH <r-khandenahally@ti.com> + * + * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/** + * @file + * @brief OnRISC Baltos Specific Board Initialization routines + */ + +#include <common.h> +#include <init.h> +#include <driver.h> +#include <envfs.h> +#include <environment.h> +#include <globalvar.h> +#include <linux/sizes.h> +#include <net.h> +#include <envfs.h> +#include <bootsource.h> +#include <asm/armlinux.h> +#include <generated/mach-types.h> +#include <mach/am33xx-generic.h> +#include <mach/am33xx-silicon.h> +#include <mach/sys_info.h> +#include <mach/syslib.h> +#include <mach/gpmc.h> +#include <linux/err.h> +#include <mach/bbu.h> +#include <libfile.h> + +static struct omap_barebox_part baltos_barebox_part = { + .nand_offset = SZ_512K, + .nand_size = 0x1e0000, +}; + +struct bsp_vs_hwparam { + uint32_t Magic; + uint32_t HwRev; + uint32_t SerialNumber; + char PrdDate[11]; + uint16_t SystemId; + uint8_t MAC1[6]; + uint8_t MAC2[6]; + uint8_t MAC3[6]; +} __attribute__ ((packed)); + +static int baltos_read_eeprom(void) +{ + struct bsp_vs_hwparam hw_param; + size_t size; + char *buf, var_buf[32]; + int rc; + unsigned char mac_addr[6]; + + rc = read_file_2("/dev/eeprom0", + &size, + (void *)&buf, + sizeof(hw_param)); + if (rc && rc != -EFBIG) + return rc; + + memcpy(&hw_param, buf, sizeof(hw_param)); + + free(buf); + + if (hw_param.Magic == 0xDEADBEEF) { + /* setup MAC1 */ + mac_addr[0] = hw_param.MAC1[0]; + mac_addr[1] = hw_param.MAC1[1]; + mac_addr[2] = hw_param.MAC1[2]; + mac_addr[3] = hw_param.MAC1[3]; + mac_addr[4] = hw_param.MAC1[4]; + mac_addr[5] = hw_param.MAC1[5]; + + eth_register_ethaddr(0, mac_addr); + + /* setup MAC2 */ + mac_addr[0] = hw_param.MAC2[0]; + mac_addr[1] = hw_param.MAC2[1]; + mac_addr[2] = hw_param.MAC2[2]; + mac_addr[3] = hw_param.MAC2[3]; + mac_addr[4] = hw_param.MAC2[4]; + mac_addr[5] = hw_param.MAC2[5]; + + eth_register_ethaddr(1, mac_addr); + } else { + printf("Baltos: incorrect magic number (0x%x) " + "in EEPROM\n", + hw_param.Magic); + + hw_param.SystemId = 0; + } + + sprintf(var_buf, "%d", hw_param.SystemId); + globalvar_add_simple("board.id", var_buf); + + return 0; +} +environment_initcall(baltos_read_eeprom); + +static int baltos_devices_init(void) +{ + if (!of_machine_is_compatible("vscom,onrisc")) + return 0; + + globalvar_add_simple("board.variant", "baltos"); + + if (bootsource_get() == BOOTSOURCE_MMC) + omap_set_bootmmc_devname("mmc0"); + + omap_set_barebox_part(&baltos_barebox_part); + + if (IS_ENABLED(CONFIG_SHELL_NONE)) + return am33xx_of_register_bootdevice(); + + return 0; +} +coredevice_initcall(baltos_devices_init); diff --git a/arch/arm/boards/vscom-baltos/lowlevel.c b/arch/arm/boards/vscom-baltos/lowlevel.c new file mode 100644 index 0000000000..8bce91a938 --- /dev/null +++ b/arch/arm/boards/vscom-baltos/lowlevel.c @@ -0,0 +1,134 @@ +#include <common.h> +#include <init.h> +#include <linux/sizes.h> +#include <io.h> +#include <linux/string.h> +#include <debug_ll.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <mach/am33xx-silicon.h> +#include <mach/am33xx-clock.h> +#include <mach/generic.h> +#include <mach/sdrc.h> +#include <mach/sys_info.h> +#include <mach/syslib.h> +#include <mach/am33xx-mux.h> +#include <mach/am33xx-generic.h> +#include <mach/wdt.h> + +static const struct am33xx_ddr_data ddr3_data = { + .rd_slave_ratio0 = 0x38, + .wr_dqs_slave_ratio0 = 0x44, + .fifo_we_slave_ratio0 = 0x94, + .wr_slave_ratio0 = 0x7D, + .use_rank0_delay = 0x01, + .dll_lock_diff0 = 0x0, +}; + +static const struct am33xx_cmd_control ddr3_cmd_ctrl = { + .slave_ratio0 = 0x80, + .dll_lock_diff0 = 0x1, + .invert_clkout0 = 0x0, + .slave_ratio1 = 0x80, + .dll_lock_diff1 = 0x1, + .invert_clkout1 = 0x0, + .slave_ratio2 = 0x80, + .dll_lock_diff2 = 0x1, + .invert_clkout2 = 0x0, +}; + +static const struct am33xx_emif_regs ddr3_regs = { + .emif_read_latency = 0x100007, + .emif_tim1 = 0x0AAAD4DB, + .emif_tim2 = 0x266B7FDA, + .emif_tim3 = 0x501F867F, + .zq_config = 0x50074BE4, + .sdram_config = 0x61C05332, + .sdram_config2 = 0x0, + .sdram_ref_ctrl = 0xC30, +}; + +static const struct am33xx_ddr_data ddr3_data_256mb = { + .rd_slave_ratio0 = 0x36, + .wr_dqs_slave_ratio0 = 0x38, + .fifo_we_slave_ratio0 = 0x99, + .wr_slave_ratio0 = 0x73, +}; + +static const struct am33xx_emif_regs ddr3_regs_256mb = { + .emif_read_latency = 0x7, + .emif_tim1 = 0x0AAAD4DB, + .emif_tim2 = 0x26437FDA, + .emif_tim3 = 0x501F83FF, + .sdram_config = 0x61C052B2, + .zq_config = 0x50074BE4, + .sdram_ref_ctrl = 0x00000C30, + +}; + +extern char __dtb_am335x_baltos_minimal_start[]; + +/** + * @brief The basic entry point for board initialization. + * + * This is called as part of machine init (after arch init). + * This is again called with stack in SRAM, so not too many + * constructs possible here. + * + * @return void + */ +static noinline int baltos_sram_init(void) +{ + uint32_t sdram_size; + void *fdt; + + fdt = __dtb_am335x_baltos_minimal_start; + + /* WDT1 is already running when the bootloader gets control + * Disable it to avoid "random" resets + */ + __raw_writel(WDT_DISABLE_CODE1, AM33XX_WDT_REG(WSPR)); + while (__raw_readl(AM33XX_WDT_REG(WWPS)) != 0x0); + __raw_writel(WDT_DISABLE_CODE2, AM33XX_WDT_REG(WSPR)); + while (__raw_readl(AM33XX_WDT_REG(WWPS)) != 0x0); + + /* Setup the PLLs and the clocks for the peripherals */ + am33xx_pll_init(MPUPLL_M_500, DDRPLL_M_400); + am335x_sdram_init(0x18B, &ddr3_cmd_ctrl, &ddr3_regs, &ddr3_data); + sdram_size = get_ram_size((void *)0x80000000, (1024 << 20)); + if (sdram_size == SZ_256M) + am335x_sdram_init(0x18B, &ddr3_cmd_ctrl, &ddr3_regs_256mb, + &ddr3_data_256mb); + + am33xx_uart_soft_reset((void *)AM33XX_UART0_BASE); + am33xx_enable_uart0_pin_mux(); + omap_uart_lowlevel_init((void *)AM33XX_UART0_BASE); + putc_ll('>'); + + am335x_barebox_entry(fdt); +} + +ENTRY_FUNCTION(start_am33xx_baltos_sram, bootinfo, r1, r2) +{ + am33xx_save_bootinfo((void *)bootinfo); + + /* + * Setup C environment, the board init code uses global variables. + * Stackpointer has already been initialized by the ROM code. + */ + relocate_to_current_adr(); + setup_c(); + + baltos_sram_init(); +} + +ENTRY_FUNCTION(start_am33xx_baltos_sdram, r0, r1, r2) +{ + void *fdt; + + fdt = __dtb_am335x_baltos_minimal_start; + + fdt -= get_runtime_offset(); + + am335x_barebox_entry(fdt); +} diff --git a/arch/arm/boards/zylonite/env/init/mtdparts-nand b/arch/arm/boards/zylonite/env/init/mtdparts-nand index 9db4652c40..749318b59e 100644 --- a/arch/arm/boards/zylonite/env/init/mtdparts-nand +++ b/arch/arm/boards/zylonite/env/init/mtdparts-nand @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NAND partitions" - exit -fi - mtdparts="128k@0(TIMH)ro,128k@128k(OBMI)ro,768k@256k(barebox),256k@1024k(barebox-env),12M@1280k(kernel),38016k@13568k(root)" kernelname="pxa3xx_nand-0" diff --git a/arch/arm/configs/rockchip_defconfig b/arch/arm/configs/rk3188_defconfig index c9bf87491c..1b6d4ff22c 100644 --- a/arch/arm/configs/rockchip_defconfig +++ b/arch/arm/configs/rk3188_defconfig @@ -1,4 +1,5 @@ CONFIG_ARCH_ROCKCHIP=y +CONFIG_ARCH_RK3188=y CONFIG_CACHE_L2X0=y CONFIG_MACH_RADXA_ROCK=y CONFIG_THUMB2_BAREBOX=y diff --git a/arch/arm/configs/rk3288_defconfig b/arch/arm/configs/rk3288_defconfig new file mode 100644 index 0000000000..f54f4cc3c3 --- /dev/null +++ b/arch/arm/configs/rk3288_defconfig @@ -0,0 +1,104 @@ +CONFIG_ARCH_ROCKCHIP=y +CONFIG_ARCH_RK3288=y +CONFIG_MACH_PHYTEC_SOM_RK3288=y +CONFIG_THUMB2_BAREBOX=y +CONFIG_ARM_BOARD_APPEND_ATAG=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_ARM_UNWIND=y +CONFIG_MMU=y +CONFIG_MALLOC_SIZE=0x0 +CONFIG_MALLOC_TLSF=y +CONFIG_KALLSYMS=y +CONFIG_RELOCATABLE=y +CONFIG_PROMPT="barebox> " +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_BOOTM_SHOW_TYPE=y +CONFIG_BOOTM_VERBOSE=y +CONFIG_BOOTM_INITRD=y +CONFIG_BOOTM_OFTREE=y +CONFIG_BOOTM_OFTREE_UIMAGE=y +CONFIG_BOOTM_AIMAGE=y +CONFIG_CONSOLE_ACTIVATE_NONE=y +CONFIG_DEFAULT_COMPRESSION_LZO=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_RESET_SOURCE=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_ROCKCHIP_UART_PORT=0 +CONFIG_CMD_DMESG=y +CONFIG_LONGHELP=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_ARM_MMUINFO=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_GO=y +CONFIG_CMD_RESET=y +CONFIG_CMD_UIMAGE=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_DEFAULTENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_FILETYPE=y +CONFIG_CMD_LN=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_SHA1SUM=y +CONFIG_CMD_SHA224SUM=y +CONFIG_CMD_SHA256SUM=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_LET=y +CONFIG_CMD_MSLEEP=y +CONFIG_CMD_READF=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_HOST=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_PING=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_MM=y +CONFIG_CMD_CLK=y +CONFIG_CMD_DETECT=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_OF_NODE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OF_DISPLAY_TIMINGS=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_TIME=y +CONFIG_NET=y +CONFIG_NET_NFS=y +CONFIG_NET_NETCONSOLE=y +CONFIG_OFDEVICE=y +CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_DRIVER_SERIAL_NS16550=y +CONFIG_DRIVER_NET_ARC_EMAC=y +CONFIG_SMSC_PHY=y +CONFIG_I2C_GPIO=y +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +CONFIG_MCI_MMC_BOOT_PARTITIONS=y +CONFIG_MCI_DW=y +CONFIG_MCI_DW_PIO=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_LED_GPIO_OF=y +CONFIG_GENERIC_PHY=y +CONFIG_FS_CRAMFS=y +CONFIG_FS_EXT4=y +CONFIG_FS_TFTP=y +CONFIG_FS_NFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y +CONFIG_FS_FAT_LFN=y +CONFIG_FS_BPKFS=y +CONFIG_FS_UIMAGEFS=y +CONFIG_LZO_DECOMPRESS=y diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig index 450a6d593a..e45e05bdb1 100644 --- a/arch/arm/cpu/Kconfig +++ b/arch/arm/cpu/Kconfig @@ -5,6 +5,8 @@ config PHYS_ADDR_T_64BIT config CPU_32 bool + select HAS_MODULES + select HAS_DMA config CPU_64 bool @@ -80,6 +82,7 @@ config CPU_V8 bool select CPU_64v8 select CPU_SUPPORTS_64BIT_KERNEL + select ARM_EXCEPTIONS config CPU_XSC3 bool diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index 331c1cd8bc..d8cb1871a6 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -16,8 +16,10 @@ obj-y += start.o entry.o ifeq ($(CONFIG_CPU_64v8), y) obj-y += setupc_64.o +pbl-y += setupc_64.o else obj-y += setupc.o +pbl-y += setupc.o endif # @@ -48,7 +50,7 @@ obj-$(CONFIG_CPU_64v8) += cache-armv8.o AFLAGS_pbl-cache-armv8.o :=-Wa,-march=armv8-a pbl-$(CONFIG_CPU_64v8) += cache-armv8.o -pbl-y += setupc.o entry.o +pbl-y += entry.o pbl-$(CONFIG_PBL_SINGLE_IMAGE) += start-pbl.o pbl-$(CONFIG_PBL_MULTI_IMAGES) += uncompress.o diff --git a/arch/arm/cpu/dtb.c b/arch/arm/cpu/dtb.c index ae4ff2a9ad..b9390b46e6 100644 --- a/arch/arm/cpu/dtb.c +++ b/arch/arm/cpu/dtb.c @@ -48,7 +48,7 @@ static int of_arm_init(void) } root = of_unflatten_dtb(fdt); - if (root) { + if (!IS_ERR(root)) { of_set_root_node(root); of_fix_tree(root); if (IS_ENABLED(CONFIG_OFDEVICE)) diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c index f723edc613..5f1469bb3e 100644 --- a/arch/arm/cpu/start-pbl.c +++ b/arch/arm/cpu/start-pbl.c @@ -28,6 +28,7 @@ #include <asm/sections.h> #include <asm/pgtable.h> #include <asm/cache.h> +#include <asm/unaligned.h> #include "mmu-early.h" @@ -49,7 +50,7 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { uint32_t offset; - uint32_t pg_start, pg_end, pg_len; + uint32_t pg_start, pg_end, pg_len, uncompressed_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); uint32_t endmem = membase + memsize; unsigned long barebox_base; @@ -63,9 +64,10 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, pg_start = (uint32_t)&input_data - offset; pg_end = (uint32_t)&input_data_end - offset; pg_len = pg_end - pg_start; + uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4)); if (IS_ENABLED(CONFIG_RELOCATABLE)) - barebox_base = arm_mem_barebox_image(membase, endmem, pg_len); + barebox_base = arm_mem_barebox_image(membase, endmem, uncompressed_len + MAX_BSS_SIZE); else barebox_base = TEXT_BASE; diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c index f25e5928cb..0120117e01 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -143,8 +143,7 @@ __noreturn void barebox_non_pbl_start(unsigned long membase, { unsigned long endmem = membase + memsize; unsigned long malloc_start, malloc_end; - unsigned long barebox_size = barebox_image_size + - ((unsigned long)&__bss_stop - (unsigned long)&__bss_start); + unsigned long barebox_size = barebox_image_size + MAX_BSS_SIZE; if (IS_ENABLED(CONFIG_RELOCATABLE)) { unsigned long barebox_base = arm_mem_barebox_image(membase, diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c index b8e2e9ffd7..eeb5a65439 100644 --- a/arch/arm/cpu/uncompress.c +++ b/arch/arm/cpu/uncompress.c @@ -29,6 +29,7 @@ #include <asm/sections.h> #include <asm/pgtable.h> #include <asm/cache.h> +#include <asm/unaligned.h> #include <debug_ll.h> @@ -44,7 +45,7 @@ static int __attribute__((__used__)) void __noreturn barebox_multi_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { - uint32_t pg_len; + uint32_t pg_len, uncompressed_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); uint32_t endmem = membase + memsize; unsigned long barebox_base; @@ -72,10 +73,11 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, */ pg_start = image_end + 1; pg_len = *(image_end); + uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4)); if (IS_ENABLED(CONFIG_RELOCATABLE)) barebox_base = arm_mem_barebox_image(membase, endmem, - pg_len); + uncompressed_len + MAX_BSS_SIZE); else barebox_base = TEXT_BASE; @@ -92,8 +94,8 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, free_mem_ptr = arm_mem_early_malloc(membase, endmem); free_mem_end_ptr = arm_mem_early_malloc_end(membase, endmem); - pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx\n", - pg_start, pg_len, barebox_base); + pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx (uncompressed size: 0x%08x)\n", + pg_start, pg_len, barebox_base, uncompressed_len); pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 09bf68ea2b..765cd595c6 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -54,6 +54,7 @@ pbl-dtb-$(CONFIG_MACH_PHYTEC_SOM_IMX6) += imx6q-phytec-pbaa03.dtb.o \ pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += armada-xp-openblocks-ax3-4-bb.dtb.o pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += kirkwood-openblocks_a6-bb.dtb.o pbl-dtb-$(CONFIG_MACH_RADXA_ROCK) += rk3188-radxarock.dtb.o +pbl-dtb-$(CONFIG_MACH_PHYTEC_SOM_RK3288) += rk3288-phycore-som.dtb.o pbl-dtb-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o pbl-dtb-$(CONFIG_MACH_SABRELITE) += imx6q-sabrelite.dtb.o imx6dl-sabrelite.dtb.o pbl-dtb-$(CONFIG_MACH_SABRESD) += imx6q-sabresd.dtb.o @@ -75,5 +76,6 @@ pbl-dtb-$(CONFIG_MACH_TX6X) += imx6q-tx6q.dtb.o pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o +pbl-dtb-$(CONFIG_MACH_VSCOM_BALTOS) += am335x-baltos-minimal.dtb.o clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts *.dtb.lzo diff --git a/arch/arm/dts/am335x-baltos-minimal.dts b/arch/arm/dts/am335x-baltos-minimal.dts new file mode 100644 index 0000000000..13eb91c83e --- /dev/null +++ b/arch/arm/dts/am335x-baltos-minimal.dts @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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. + */ + +/* + * VScom OnRISC + * http://www.vscom.de + */ + +/dts-v1/; + +#include "am33xx.dtsi" +#include <dt-bindings/pwm/pwm.h> + +/ { + model = "OnRISC Baltos"; + compatible = "vscom,onrisc", "ti,am33xx"; + + chosen { + linux,stdout-path = &uart0; + }; + + cpus { + cpu@0 { + cpu0-supply = <&vdd1_reg>; + }; + }; + + vbat: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vbat"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; +}; + +&am33xx_pinmux { + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + 0xf0 (MUX_MODE0 | INPUT_EN | PULL_UP) /* mmc0_dat3.mmc0_dat3 */ + 0xf4 (MUX_MODE0 | INPUT_EN | PULL_UP) /* mmc0_dat2.mmc0_dat2 */ + 0xf8 (MUX_MODE0 | INPUT_EN | PULL_UP) /* mmc0_dat1.mmc0_dat1 */ + 0xfc (MUX_MODE0 | INPUT_EN | PULL_UP) /* mmc0_dat0.mmc0_dat0 */ + 0x100 (MUX_MODE0 | INPUT_EN | PULL_UP) /* mmc0_clk.mmc0_clk */ + 0x104 (MUX_MODE0 | INPUT_EN | PULL_UP) /* mmc0_cmd.mmc0_cmd */ + >; + }; + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + 0x158 0x2a /* spi0_d1.i2c1_sda_mux3, INPUT | MODE2 */ + 0x15c 0x2a /* spi0_cs0.i2c1_scl_mux3, INPUT | MODE2 */ + >; + }; + + tps65910_pins: pinmux_tps65910_pins { + pinctrl-single,pins = < + 0x078 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_ben1.gpio1[28] */ + >; + + }; + tca6416_pins: pinmux_tca6416_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE7) /* xdma_event_intr1.gpio0[20] tca6416 stuff */ + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; + + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1 */ + 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs_dv */ + 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_tx_en.rmii1_txen */ + 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */ + 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */ + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */ + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */ + 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_ref_clk.rmii1_refclk */ + + + /* Slave 2 */ + 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */ + 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a1.rgmii2_rctl */ + 0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */ + 0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */ + 0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */ + 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */ + 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */ + 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */ + 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */ + 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */ + 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */ + 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */ + >; + }; + + cpsw_sleep: cpsw_sleep { + pinctrl-single,pins = < + /* Slave 1 reset value */ + 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7) + + /* Slave 2 reset value*/ + 0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; + + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ + 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ + >; + }; + + davinci_mdio_sleep: davinci_mdio_sleep { + pinctrl-single,pins = < + /* MDIO reset value */ + 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; + + nandflash_pins_s0: nandflash_pins_s0 { + pinctrl-single,pins = < + 0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */ + 0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */ + 0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */ + 0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */ + 0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */ + 0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */ + 0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */ + 0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */ + 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */ + 0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */ + 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */ + 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */ + 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */ + 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */ + 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */ + >; + }; +}; + +&elm { + status = "okay"; +}; + +&gpmc { + pinctrl-names = "default"; + pinctrl-0 = <&nandflash_pins_s0>; + ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ + status = "okay"; + + nand@0,0 { + reg = <0 0 0>; /* CS0, offset 0 */ + nand-bus-width = <8>; + ti,nand-ecc-opt = "bch8"; + ti,nand-xfer-type = "polled"; + + gpmc,device-nand = "true"; + gpmc,device-width = <1>; + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <40>; + gpmc,oe-on-ns = <0>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,wait-on-read = "true"; + gpmc,wait-on-write = "true"; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,clk-activation-ns = <0>; + gpmc,wait-monitoring-ns = <0>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + + #address-cells = <1>; + #size-cells = <1>; + elm_id = <&elm>; + + boot@0 { + label = "SPL"; + reg = <0x0 0x20000>; + }; + boot@20000{ + label = "SPL.backup1"; + reg = <0x20000 0x20000>; + }; + boot@40000 { + label = "SPL.backup2"; + reg = <0x40000 0x20000>; + }; + boot@60000 { + label = "SPL.backup3"; + reg = <0x60000 0x20000>; + }; + boot@80000 { + label = "u-boot"; + reg = <0x80000 0x1e0000>; + }; + boot@260000 { + label = "UBI"; + reg = <0x260000 0xfda0000>; + }; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + + status = "okay"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + status = "okay"; + clock-frequency = <1000>; + + tps: tps@2d { + reg = <0x2d>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio1>; + interrupts = <28 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&tps65910_pins>; + }; + + at24@50 { + compatible = "at24,24c02"; + pagesize = <8>; + reg = <0x50>; + }; + + tca6416: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio0>; + interrupts = <20 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&tca6416_pins>; + }; +}; + +&usb { + status = "okay"; +}; + +&usb_ctrl_mod { + status = "okay"; +}; + +&usb0_phy { + status = "okay"; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; + +&cppi41dma { + status = "okay"; +}; + +/include/ "tps65910.dtsi" + +&tps { + vcc1-supply = <&vbat>; + vcc2-supply = <&vbat>; + vcc3-supply = <&vbat>; + vcc4-supply = <&vbat>; + vcc5-supply = <&vbat>; + vcc6-supply = <&vbat>; + vcc7-supply = <&vbat>; + vccio-supply = <&vbat>; + + ti,en-ck32k-xtal = <1>; + + regulators { + vrtc_reg: regulator@0 { + regulator-always-on; + }; + + vio_reg: regulator@1 { + regulator-always-on; + }; + + vdd1_reg: regulator@2 { + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <912500>; + regulator-max-microvolt = <1312500>; + regulator-boot-on; + regulator-always-on; + }; + + vdd2_reg: regulator@3 { + /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ + regulator-name = "vdd_core"; + regulator-min-microvolt = <912500>; + regulator-max-microvolt = <1150000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd3_reg: regulator@4 { + regulator-always-on; + }; + + vdig1_reg: regulator@5 { + regulator-always-on; + }; + + vdig2_reg: regulator@6 { + regulator-always-on; + }; + + vpll_reg: regulator@7 { + regulator-always-on; + }; + + vdac_reg: regulator@8 { + regulator-always-on; + }; + + vaux1_reg: regulator@9 { + regulator-always-on; + }; + + vaux2_reg: regulator@10 { + regulator-always-on; + }; + + vaux33_reg: regulator@11 { + regulator-always-on; + }; + + vmmc_reg: regulator@12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; +}; + +&mac { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&cpsw_default>; + pinctrl-1 = <&cpsw_sleep>; + dual_emac = <1>; + + status = "okay"; +}; + +&davinci_mdio { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&davinci_mdio_default>; + pinctrl-1 = <&davinci_mdio_sleep>; + + status = "okay"; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <0>; + phy-mode = "rmii"; + dual_emac_res_vlan = <1>; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <7>; + phy-mode = "rgmii-txid"; + dual_emac_res_vlan = <2>; +}; + +&phy_sel { + rmii-clock-ext = <1>; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <&vmmc_reg>; + status = "okay"; +}; + +&gpio0 { + ti,no-reset-on-init; +}; diff --git a/arch/arm/dts/imx6dl-tx6u.dts b/arch/arm/dts/imx6dl-tx6u.dts index 77fda6203f..6c26feb978 100644 --- a/arch/arm/dts/imx6dl-tx6u.dts +++ b/arch/arm/dts/imx6dl-tx6u.dts @@ -1,6 +1,6 @@ /dts-v1/; -#include <arm/imx6q.dtsi> +#include <arm/imx6dl.dtsi> #include <arm/imx6qdl-tx6.dtsi> #include "imx6qdl.dtsi" #include "imx6qdl-tx6x.dtsi" diff --git a/arch/arm/dts/imx6q-guf-santaro.dts b/arch/arm/dts/imx6q-guf-santaro.dts index 2bd1a26317..3217a5bf90 100644 --- a/arch/arm/dts/imx6q-guf-santaro.dts +++ b/arch/arm/dts/imx6q-guf-santaro.dts @@ -63,6 +63,7 @@ compatible = "simple-panel"; backlight = <&backlight>; enable-gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>; + enable-delay = <200>; port { panel_in: endpoint { @@ -576,6 +577,16 @@ status = "okay"; }; +&usbh1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + status = "okay"; +}; + +&usbotg { + status = "okay"; +}; + &usdhc2 { /* SD card socket */ pinctrl-names = "default"; diff --git a/arch/arm/dts/rk3288-phycore-som.dts b/arch/arm/dts/rk3288-phycore-som.dts new file mode 100644 index 0000000000..5410bd1f76 --- /dev/null +++ b/arch/arm/dts/rk3288-phycore-som.dts @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2016 PHYTEC Messtechnik GmbH, + * Author: Wadim Egorov <w.egorov@phytec.de> + * + * 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. + * + * 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. + */ + +/dts-v1/; + +#include <arm/rk3288.dtsi> + +/ { + model = "phycore-rk3288"; + compatible = "phytec,rk3288-phycore-som", "rockchip,rk3288"; + + memory { + reg = <0 0x40000000>; + }; + + vcc33: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vcc33"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + regulator-boot-on; + regulator-always-on; + }; + + vcc18: fixedregulator@1 { + compatible = "regulator-fixed"; + regulator-name = "vcc18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + chosen { + stdout-path = &uart0; + + environment-emmc { + compatible = "barebox,environment"; + device-path = &emmc, "partname:barebox-environment"; + status = "disabled"; + }; + + environment-sdmmc { + compatible = "barebox,environment"; + device-path = &sdmmc, "partname:barebox-environment"; + status = "disabled"; + }; + }; +}; + +&pinctrl { + sdmmc { + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&i2c0 { + clock-frequency = <400000>; + status = "okay"; +}; + +&emmc { + broken-cd; + bus-width = <8>; + cap-mmc-highspeed; + disable-wp; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; + vmmc-supply = <&vcc33>; + vqmmc-supply = <&vcc18>; + status = "okay"; + + #size-cells = <1>; + #address-cells = <1>; + + partition@8000 { + label = "spl"; + reg = <0x8000 0x8000>; + }; + + partition@20000 { + label = "barebox"; + reg = <0x20000 0x80000>; + }; + + partition@a0000 { + label = "barebox-environment"; + reg = <0xa0000 0x20000>; + }; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; + vmmc-supply = <&vcc33>; + status = "okay"; + + #address-cells = <1>; + #size-cells = <1>; + + partition@8000 { + label = "spl"; + reg = <0x8000 0x8000>; + }; + + partition@20000 { + label = "barebox"; + reg = <0x20000 0x80000>; + }; + + partition@a0000 { + label = "barebox-environment"; + reg = <0xa0000 0x20000>; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>; + reg-shift = <2>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; diff --git a/arch/arm/dts/socfpga_cyclone5_socrates.dts b/arch/arm/dts/socfpga_cyclone5_socrates.dts index 95cdf5d3d5..ea7e6cc102 100644 --- a/arch/arm/dts/socfpga_cyclone5_socrates.dts +++ b/arch/arm/dts/socfpga_cyclone5_socrates.dts @@ -19,42 +19,12 @@ #include "socfpga.dtsi" / { - model = "EBV SoCrates"; - compatible = "ebv,socrates", "altr,socfpga"; - chosen { stdout-path = &uart0; }; - leds: gpio-leds { - }; -}; - -&gpio0 { - status = "okay"; -}; - -&gpio1 { - status = "okay"; -}; - -&leds { - compatible = "gpio-leds"; - - led@0 { - label = "0"; - gpios = <&porta 28 1>; - linux,default-trigger = "heartbeat"; - }; - - led@1 { - label = "1"; - gpios = <&portb 19 1>; - }; - - led@2 { - label = "2"; - gpios = <&portb 25 1>; + aliases { + ethernet0 = &gmac1; }; }; @@ -75,5 +45,35 @@ cdns,tsd2d-ns = <50>; cdns,tchsh-ns = <4>; cdns,tslch-ns = <4>; + + partition@0 { + label = "prebootloader0"; + reg = <0x00000 0x10000>; + }; + + partition@1 { + label = "prebootloader1"; + reg = <0x10000 0x10000>; + }; + + partition@2 { + label = "prebootloader2"; + reg = <0x20000 0x10000>; + }; + + partition@3 { + label = "prebootloader3"; + reg = <0x30000 0x10000>; + }; + + partition@4 { + label = "barebox"; + reg = <0x40000 0x80000>; + }; + + partition@5 { + label = "data"; + reg = <0xc0000 0x1f40000>; + }; }; }; diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index 0acdfa3dbc..061296a476 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -164,6 +164,13 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase, static void __naked noinline __##name \ (uint32_t arg0, uint32_t arg1, uint32_t arg2) - +/* + * When using compressed images in conjunction with relocatable images + * the PBL code must pick a suitable place where to uncompress the barebox + * image. For doing this the PBL code must know the size of the final + * image including the BSS segment. The BSS size is unknown to the PBL + * code, so define a maximum BSS size here. + */ +#define MAX_BSS_SIZE SZ_1M #endif /* _BAREBOX_ARM_H_ */ diff --git a/arch/arm/include/asm/barebox.h b/arch/arm/include/asm/barebox.h index 31a8e15630..5a6622235b 100644 --- a/arch/arm/include/asm/barebox.h +++ b/arch/arm/include/asm/barebox.h @@ -2,8 +2,10 @@ #define _BAREBOX_H_ 1 #ifdef CONFIG_ARM_UNWIND +#ifndef CONFIG_CPU_V8 #define ARCH_HAS_STACK_DUMP #endif +#endif #ifdef CONFIG_ARM_EXCEPTIONS #define ARCH_HAS_DATA_ABORT_MASK diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 404a6ae6ad..56663feb89 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -267,7 +267,7 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data) if (IS_BUILTIN(CONFIG_OFTREE)) { data->of_root_node = of_unflatten_dtb(oftree); - if (!data->of_root_node) { + if (IS_ERR(data->of_root_node)) { pr_err("unable to unflatten devicetree\n"); ret = -EINVAL; goto err_free; diff --git a/arch/arm/lib64/Makefile b/arch/arm/lib64/Makefile index 87e26f6afa..4b7b7e3cc5 100644 --- a/arch/arm/lib64/Makefile +++ b/arch/arm/lib64/Makefile @@ -4,6 +4,4 @@ obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o extra-y += barebox.lds -pbl-y += lib1funcs.o -pbl-y += ashldi3.o pbl-y += div0.o diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index b017944a90..ae35aaa35e 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -115,6 +115,12 @@ config ARCH_IMX35 select ARCH_HAS_FEC_IMX select PINCTRL_IMX_IOMUX_V3 +config ARCH_IMX50 + bool + select CPU_V7 + select ARCH_HAS_FEC_IMX + select PINCTRL_IMX_IOMUX_V3 + config ARCH_IMX51 bool select CPU_V7 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index db1cf7df08..0763944895 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -5,6 +5,8 @@ obj-$(CONFIG_ARCH_IMX21) += imx21.o clk-imx21.o obj-$(CONFIG_ARCH_IMX27) += imx27.o clk-imx27.o obj-$(CONFIG_ARCH_IMX31) += imx31.o clk-imx31.o obj-$(CONFIG_ARCH_IMX35) += imx35.o clk-imx35.o +obj-$(CONFIG_ARCH_IMX50) += imx50.o imx5.o clk-imx5.o +pbl-$(CONFIG_ARCH_IMX50) += imx50.o imx5.o obj-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o clk-imx5.o pbl-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o clk-imx5.o esdctl-v4.o diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index 344c2fb1e6..faed6313fb 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -79,6 +79,8 @@ static int clk_gate2_is_enabled(struct clk *clk) } static struct clk_ops clk_gate2_ops = { + .set_rate = clk_parent_set_rate, + .round_rate = clk_parent_round_rate, .enable = clk_gate2_enable, .disable = clk_gate2_disable, .is_enabled = clk_gate2_is_enabled, @@ -96,6 +98,7 @@ struct clk *clk_gate2_alloc(const char *name, const char *parent, g->clk.name = name; g->clk.parent_names = &g->parent; g->clk.num_parents = 1; + g->clk.flags = CLK_SET_RATE_PARENT; return &g->clk; } diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index fccea7fafe..864d06e195 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -171,6 +171,7 @@ static int imx25_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[ipg], MX25_CSPI3_BASE_ADDR, NULL); clkdev_add_physbase(clks[per3], MX25_ESDHC1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per4], MX25_ESDHC2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per8], MX25_NFC_BASE_ADDR, NULL); clkdev_add_physbase(clks[lcdc_ipg_per], MX25_LCDC_BASE_ADDR, "per"); clkdev_add_physbase(clks[lcdc_ipg], MX25_LCDC_BASE_ADDR, "ipg"); clkdev_add_physbase(clks[lcdc_ahb], MX25_LCDC_BASE_ADDR, "ahb"); diff --git a/arch/arm/mach-imx/clk-imx5.c b/arch/arm/mach-imx/clk-imx5.c index 51a6460c9e..d3cde7e42f 100644 --- a/arch/arm/mach-imx/clk-imx5.c +++ b/arch/arm/mach-imx/clk-imx5.c @@ -14,6 +14,7 @@ #include <of.h> #include <linux/clkdev.h> #include <linux/err.h> +#include <mach/imx50-regs.h> #include <mach/imx51-regs.h> #include <mach/imx53-regs.h> #include <dt-bindings/clock/imx5-clock.h> @@ -68,6 +69,17 @@ static const char *standard_pll_sel[] = { "lp_apm", }; +static const char *mx50_3bit_clk_sel[] = { + "pll1_sw", + "pll2_sw", + "pll3_sw", + "lp_apm", + "pfd0", + "pfd1", + "pfd4", + "osc", +}; + static const char *lp_apm_sel[] = { "osc", }; @@ -83,6 +95,13 @@ static const char *main_bus_sel[] = { "periph_apm", }; +static const char *mx50_periph_clk_sel[] = { + "pll1_sw", + "pll2_sw", + "pll3_sw", + "lp_apm", +}; + static const char *per_lp_apm_sel[] = { "main_bus", "lp_apm", @@ -194,12 +213,6 @@ static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *ba clks[IMX5_CLK_OSC] = clk_fixed("osc", 24000000); } - clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", base + CCM_CCSR, 9, 1, - lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); - clks[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", base + CCM_CBCMR, 12, 2, - periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); - clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", base + CCM_CBCDR, 25, 1, - main_bus_sel, ARRAY_SIZE(main_bus_sel)); clks[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", base + CCM_CBCMR, 1, 1, per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); clks[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", base + CCM_CBCDR, 6, 2); @@ -215,26 +228,42 @@ static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *ba standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); clks[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", base + CCM_CSCDR1, 3, 3); clks[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", base + CCM_CSCDR1, 0, 3); + clks[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred", + "esdhc_a_sel", base + CCM_CSCDR1, 16, 3); + clks[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf", + "esdhc_a_pred", base + CCM_CSCDR1, 11, 3); + clks[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred", + "esdhc_b_sel", base + CCM_CSCDR1, 22, 3); + clks[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf", + "esdhc_b_pred", base + CCM_CSCDR1, 19, 3); + clks[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + CCM_CSCMR1, + 4, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clks[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred", + "ecspi_sel", base + CCM_CSCDR2, 25, 3); + clks[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", + "ecspi_pred", base + CCM_CSCDR2, 19, 6); + clks[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", + "pll1_sw", base + CCM_CACRR, 0, 3); +} +static void mx5_clocks_mx51_mx53_init(void __iomem *base) +{ + clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", base + CCM_CCSR, 9, 1, + lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); + clks[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", base + CCM_CBCMR, 12, 2, + periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); + clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", base + CCM_CBCDR, 25, 1, + main_bus_sel, ARRAY_SIZE(main_bus_sel)); clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", base + CCM_CSCMR1, 20, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", base + CCM_CSCMR1, 16, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clks[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", base + CCM_CSCDR1, 16, 3); - clks[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", base + CCM_CSCDR1, 11, 3); - clks[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", base + CCM_CSCDR1, 22, 3); - clks[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", base + CCM_CSCDR1, 19, 3); clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", base + CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel)); clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", base + CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel)); - clks[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", base + CCM_CBCDR, 26, 1, emi_slow_sel, ARRAY_SIZE(emi_slow_sel)); clks[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", base + CCM_CBCDR, 22, 3); clks[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", base + CCM_CBCDR, 13, 3); - clks[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + CCM_CSCMR1, 4, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clks[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred", "ecspi_sel", base + CCM_CSCDR2, 25, 3); - clks[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_pred", base + CCM_CSCDR2, 19, 6); clks[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", base + CCM_CSCMR1, 22, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); clks[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", base + CCM_CSCDR1, 8, 3); @@ -243,7 +272,6 @@ static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *ba clks[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", base + CCM_CDCDR, 0, 3); clks[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", base + CCM_CSCMR1, 26, 1, usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); - clks[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "pll1_sw", base + CCM_CACRR, 0, 3); } static void mx5_clocks_ipu_init(void __iomem *regs) @@ -251,6 +279,73 @@ static void mx5_clocks_ipu_init(void __iomem *regs) clks[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", regs + CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); } +int __init mx50_clocks_init(struct device_d *dev, void __iomem *regs) +{ + clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", + (void *)MX50_PLL1_BASE_ADDR); + clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", + (void *)MX50_PLL2_BASE_ADDR); + clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", + (void *)MX50_PLL3_BASE_ADDR); + + mx5_clocks_common_init(dev, regs); + + clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", regs + CCM_CCSR, 10, 1, lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); + clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", regs + CCM_CBCDR, 25, 2, mx50_periph_clk_sel, ARRAY_SIZE(mx50_periph_clk_sel)); + clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", regs + CCM_CSCMR1, 21, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", regs + CCM_CSCMR1, 16, 3, mx50_3bit_clk_sel, ARRAY_SIZE(mx50_3bit_clk_sel)); + clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", regs + CCM_CSCMR1, 20, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel)); + clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", regs + CCM_CSCMR1, 19, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel)); + clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART3_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C3_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_GPT1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_CSPI_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_FEC_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX50_ESDHC1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX50_ESDHC2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX50_ESDHC3_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX50_ESDHC4_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM1_BASE_ADDR, "per"); + clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM2_BASE_ADDR, "per"); + + return 0; +} + +static int imx50_ccm_probe(struct device_d *dev) +{ + struct resource *iores; + void __iomem *regs; + + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + regs = IOMEM(iores->start); + + mx50_clocks_init(dev, regs); + + return 0; +} + +static __maybe_unused struct of_device_id imx50_ccm_dt_ids[] = { + { + .compatible = "fsl,imx50-ccm", + }, { + /* sentinel */ + } +}; + +static struct driver_d imx50_ccm_driver = { + .probe = imx50_ccm_probe, + .name = "imx50-ccm", + .of_compatible = DRV_OF_COMPAT(imx50_ccm_dt_ids), +}; + static void mx51_clocks_ipu_init(void __iomem *regs) { clks[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3, @@ -277,6 +372,7 @@ int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs) clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX51_PLL3_BASE_ADDR); mx5_clocks_common_init(dev, regs); + mx5_clocks_mx51_mx53_init(regs); clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART1_BASE_ADDR, NULL); clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART2_BASE_ADDR, NULL); @@ -365,6 +461,7 @@ int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs) clks[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", (void *)MX53_PLL4_BASE_ADDR); mx5_clocks_common_init(dev, regs); + mx5_clocks_mx51_mx53_init(regs); clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART1_BASE_ADDR, NULL); clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART2_BASE_ADDR, NULL); @@ -423,6 +520,8 @@ static struct driver_d imx53_ccm_driver = { static int imx5_ccm_init(void) { + if (IS_ENABLED(CONFIG_ARCH_IMX50)) + platform_driver_register(&imx50_ccm_driver); if (IS_ENABLED(CONFIG_ARCH_IMX51)) platform_driver_register(&imx51_ccm_driver); if (IS_ENABLED(CONFIG_ARCH_IMX53)) diff --git a/arch/arm/mach-imx/imx.c b/arch/arm/mach-imx/imx.c index 2e33325c9f..5ab6afc9bf 100644 --- a/arch/arm/mach-imx/imx.c +++ b/arch/arm/mach-imx/imx.c @@ -49,6 +49,8 @@ static int imx_soc_from_dt(void) return IMX_CPU_IMX31; if (of_machine_is_compatible("fsl,imx35")) return IMX_CPU_IMX35; + if (of_machine_is_compatible("fsl,imx50")) + return IMX_CPU_IMX50; if (of_machine_is_compatible("fsl,imx51")) return IMX_CPU_IMX51; if (of_machine_is_compatible("fsl,imx53")) @@ -89,6 +91,8 @@ static int imx_init(void) ret = imx31_init(); else if (cpu_is_mx35()) ret = imx35_init(); + else if (cpu_is_mx50()) + ret = imx50_init(); else if (cpu_is_mx51()) ret = imx51_init(); else if (cpu_is_mx53()) @@ -113,6 +117,8 @@ static int imx_init(void) ret = imx31_devices_init(); else if (cpu_is_mx35()) ret = imx35_devices_init(); + else if (cpu_is_mx50()) + ret = imx50_devices_init(); else if (cpu_is_mx51()) ret = imx51_devices_init(); else if (cpu_is_mx53()) diff --git a/arch/arm/mach-imx/imx50.c b/arch/arm/mach-imx/imx50.c new file mode 100644 index 0000000000..fb278a5105 --- /dev/null +++ b/arch/arm/mach-imx/imx50.c @@ -0,0 +1,187 @@ +/* + * 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. + * + */ + +#include <init.h> +#include <common.h> +#include <io.h> +#include <notifier.h> +#include <linux/sizes.h> +#include <mach/imx5.h> +#include <mach/imx50-regs.h> +#include <mach/revision.h> +#include <mach/clock-imx51_53.h> +#include <mach/generic.h> + +#define SI_REV 0x48 + +static int imx50_silicon_revision(void) +{ + void __iomem *rom = MX50_IROM_BASE_ADDR; + u32 rev; + u32 mx50_silicon_revision; + + rev = readl(rom + SI_REV); + switch (rev) { + case 0x10: + mx50_silicon_revision = IMX_CHIP_REV_1_0; + break; + case 0x11: + mx50_silicon_revision = IMX_CHIP_REV_1_1; + break; + default: + mx50_silicon_revision = IMX_CHIP_REV_UNKNOWN; + } + + imx_set_silicon_revision("i.MX50", mx50_silicon_revision); + + return 0; +} + +int imx50_init(void) +{ + imx50_silicon_revision(); + imx53_boot_save_loc((void *)MX50_SRC_BASE_ADDR); + + return 0; +} + +int imx50_devices_init(void) +{ + add_generic_device("imx-iomuxv3", 0, NULL, MX50_IOMUXC_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx50-ccm", 0, NULL, MX50_CCM_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx31-gpt", 0, NULL, MX50_GPT1_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx31-gpio", 0, NULL, MX50_GPIO1_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx31-gpio", 1, NULL, MX50_GPIO2_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx31-gpio", 2, NULL, MX50_GPIO3_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx31-gpio", 3, NULL, MX50_GPIO4_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx31-gpio", 4, NULL, MX50_GPIO5_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx31-gpio", 5, NULL, MX50_GPIO6_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx21-wdt", 0, NULL, MX50_WDOG1_BASE_ADDR, + 0x1000, IORESOURCE_MEM, NULL); + + return 0; +} + +void imx50_init_lowlevel_early(unsigned int cpufreq_mhz) +{ + void __iomem *ccm = (void __iomem *)MX50_CCM_BASE_ADDR; + u32 r; + + imx5_init_lowlevel(); + + /* + * 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, MX50_AIPS1_BASE_ADDR + 0); + writel(0x77777777, MX50_AIPS1_BASE_ADDR + 4); + writel(0x77777777, MX50_AIPS2_BASE_ADDR + 0); + writel(0x77777777, MX50_AIPS2_BASE_ADDR + 4); + + /* Gate of clocks to the peripherals first */ + writel(0x3fffffff, ccm + MX5_CCM_CCGR0); + writel(0x00000000, ccm + MX5_CCM_CCGR1); + writel(0x00000000, ccm + MX5_CCM_CCGR2); + writel(0x00000000, ccm + MX5_CCM_CCGR3); + writel(0x00030000, ccm + MX5_CCM_CCGR4); + writel(0x00fff030, ccm + MX5_CCM_CCGR5); + writel(0x0f00030f, ccm + MX5_CCM_CCGR6); + writel(0x00000000, ccm + MX50_CCM_CCGR7); + + /* Switch ARM to step clock */ + writel(0x4, ccm + MX5_CCM_CCSR); + + if (cpufreq_mhz == 400) + imx5_setup_pll_400((void __iomem *)MX50_PLL1_BASE_ADDR); + else + imx5_setup_pll_800((void __iomem *)MX50_PLL1_BASE_ADDR); + + imx5_setup_pll_216((void __iomem *)MX50_PLL3_BASE_ADDR); + + /* Switch peripheral to PLL3 */ + writel(0x00015154, ccm + MX5_CCM_CBCMR); + writel(0x04880945 | (1<<16), ccm + MX5_CCM_CBCDR); + + /* make sure change is effective */ + while (readl(ccm + MX5_CCM_CDHIPR)); + + imx5_setup_pll_400((void __iomem *)MX50_PLL2_BASE_ADDR); + + /* Switch peripheral to PLL2 */ + r = 0x02800145 | + (2 << 10) | + (0 << 16) | + (1 << 19); + + writel(r, ccm + MX5_CCM_CBCDR); + + r = readl(ccm + MX5_CCM_CSCMR1); + + /* change uart clk parent to pll2 */ + r &= ~MX5_CCM_CSCMR1_UART_CLK_SEL_MASK; + r |= 1 << MX5_CCM_CSCMR1_UART_CLK_SEL_OFFSET; + + writel(r, ccm + MX5_CCM_CSCMR1); + + /* make sure change is effective */ + while (readl(ccm + MX5_CCM_CDHIPR)); + + /* Set the platform clock dividers */ + writel(0x00000124, MX50_ARM_BASE_ADDR + 0x14); + + writel(0, ccm + MX5_CCM_CACRR); + + /* Switch ARM back to PLL 1. */ + writel(0, ccm + MX5_CCM_CCSR); + + /* make uart div = 6*/ + r = readl(ccm + MX5_CCM_CSCDR1); + r &= ~0x3f; + r |= 0x0a; + + r &= ~MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK; + r &= ~MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK; + r |= 1 << MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET; + + writel(r, ccm + MX5_CCM_CSCDR1); + + /* Restore the default values in the Gate registers */ + writel(0xffffffff, ccm + MX5_CCM_CCGR0); + writel(0xffffffff, ccm + MX5_CCM_CCGR1); + writel(0xffffffff, ccm + MX5_CCM_CCGR2); + writel(0xffffffff, ccm + MX5_CCM_CCGR3); + writel(0xffffffff, ccm + MX5_CCM_CCGR4); + writel(0xffffffff, ccm + MX5_CCM_CCGR5); + writel(0xffffffff, ccm + MX5_CCM_CCGR6); + writel(0xffffffff, ccm + MX50_CCM_CCGR7); + + writel(0, ccm + MX5_CCM_CCDR); +} + +void imx50_init_lowlevel(unsigned int cpufreq_mhz) +{ + imx50_init_lowlevel_early(cpufreq_mhz); + + clock_notifier_call_chain(); +} diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c index ba8fb8964a..18509a7b51 100644 --- a/arch/arm/mach-imx/imx6.c +++ b/arch/arm/mach-imx/imx6.c @@ -65,10 +65,10 @@ void imx6_init_lowlevel(void) writel(0xffffffff, 0x020c407c); writel(0xffffffff, 0x020c4080); - /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs - * to make sure PFD is working right, otherwise, PFDs may - * not output clock after reset, MX6DL and MX6SL have added 396M pfd - * workaround in ROM code, as bus clock need it + /* + * Due to a hardware bug (related to errata ERR006282) on i.MX6DQ we + * need to gate/ungate all PFDs to make sure PFD is working right, + * otherwise PFDs may not output clock after reset. */ if (is_imx6q || is_imx6d) { writel(BM_ANADIG_PFD_480_PFD3_CLKGATE | @@ -77,7 +77,7 @@ void imx6_init_lowlevel(void) BM_ANADIG_PFD_480_PFD0_CLKGATE, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_SET); writel(BM_ANADIG_PFD_528_PFD3_CLKGATE | - (is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) | + BM_ANADIG_PFD_528_PFD2_CLKGATE | BM_ANADIG_PFD_528_PFD1_CLKGATE | BM_ANADIG_PFD_528_PFD0_CLKGATE, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_SET); @@ -88,7 +88,7 @@ void imx6_init_lowlevel(void) BM_ANADIG_PFD_480_PFD0_CLKGATE, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_CLR); writel(BM_ANADIG_PFD_528_PFD3_CLKGATE | - (is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) | + BM_ANADIG_PFD_528_PFD2_CLKGATE | BM_ANADIG_PFD_528_PFD1_CLKGATE | BM_ANADIG_PFD_528_PFD0_CLKGATE, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_CLR); diff --git a/arch/arm/mach-imx/include/mach/clock-imx51_53.h b/arch/arm/mach-imx/include/mach/clock-imx51_53.h index 0f25dfbf2f..06ea2e2a3c 100644 --- a/arch/arm/mach-imx/include/mach/clock-imx51_53.h +++ b/arch/arm/mach-imx/include/mach/clock-imx51_53.h @@ -102,6 +102,7 @@ #define MX5_CCM_CCGR4 0x78 #define MX5_CCM_CCGR5 0x7C #define MX5_CCM_CCGR6 0x80 +#define MX50_CCM_CCGR7 0x84 #define MX53_CCM_CCGR7 0x84 #define MX51_CCM_CMEOR 0x84 diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h index 4f2d923aa0..5c2db6cd51 100644 --- a/arch/arm/mach-imx/include/mach/debug_ll.h +++ b/arch/arm/mach-imx/include/mach/debug_ll.h @@ -10,6 +10,7 @@ #include <mach/imx27-regs.h> #include <mach/imx31-regs.h> #include <mach/imx35-regs.h> +#include <mach/imx50-regs.h> #include <mach/imx51-regs.h> #include <mach/imx53-regs.h> #include <mach/imx6-regs.h> @@ -33,6 +34,8 @@ #define IMX_DEBUG_SOC MX31 #elif defined CONFIG_DEBUG_IMX35_UART #define IMX_DEBUG_SOC MX35 +#elif defined CONFIG_DEBUG_IMX50_UART +#define IMX_DEBUG_SOC MX50 #elif defined CONFIG_DEBUG_IMX51_UART #define IMX_DEBUG_SOC MX51 #elif defined CONFIG_DEBUG_IMX53_UART @@ -43,6 +46,13 @@ #error "unknown i.MX debug uart soc type" #endif +static inline void imx50_uart_setup_ll(void) +{ + void *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, CONFIG_DEBUG_IMX_UART_PORT)); + + imx50_uart_setup(base); +} + static inline void imx51_uart_setup_ll(void) { void *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, CONFIG_DEBUG_IMX_UART_PORT)); @@ -76,6 +86,7 @@ static inline void PUTC_LL(int c) } #else +static inline void imx50_uart_setup_ll(void) {} static inline void imx51_uart_setup_ll(void) {} static inline void imx53_uart_setup_ll(void) {} static inline void imx6_uart_setup_ll(void) {} diff --git a/arch/arm/mach-imx/include/mach/devices-imx50.h b/arch/arm/mach-imx/include/mach/devices-imx50.h new file mode 100644 index 0000000000..9e0eaa8cbb --- /dev/null +++ b/arch/arm/mach-imx/include/mach/devices-imx50.h @@ -0,0 +1,83 @@ + +#include <mach/devices.h> +#include <mach/imx50-regs.h> + +static inline struct device_d *imx50_add_spi0(struct spi_imx_master *pdata) +{ + return imx_add_spi_imx51((void *)MX50_ECSPI1_BASE_ADDR, 0, pdata); +} + +static inline struct device_d *imx50_add_spi1(struct spi_imx_master *pdata) +{ + return imx_add_spi_imx51((void *)MX50_ECSPI2_BASE_ADDR, 1, pdata); +} + +static inline struct device_d *imx50_add_cspi(struct spi_imx_master *pdata) +{ + return imx_add_spi_imx35((void *)MX50_CSPI_BASE_ADDR, 2, pdata); +} + +static inline struct device_d *imx50_add_i2c0(struct i2c_platform_data *pdata) +{ + return imx_add_i2c((void *)MX50_I2C1_BASE_ADDR, 0, pdata); +} + +static inline struct device_d *imx50_add_i2c1(struct i2c_platform_data *pdata) +{ + return imx_add_i2c((void *)MX50_I2C2_BASE_ADDR, 1, pdata); +} + +static inline struct device_d *imx50_add_i2c2(struct i2c_platform_data *pdata) +{ + return imx_add_i2c((void *)MX50_I2C3_BASE_ADDR, 2, pdata); +} + +static inline struct device_d *imx50_add_uart0(void) +{ + return imx_add_uart_imx21((void *)MX50_UART1_BASE_ADDR, 0); +} + +static inline struct device_d *imx50_add_uart1(void) +{ + return imx_add_uart_imx21((void *)MX50_UART2_BASE_ADDR, 1); +} + +static inline struct device_d *imx50_add_uart2(void) +{ + return imx_add_uart_imx21((void *)MX50_UART3_BASE_ADDR, 2); +} + +static inline struct device_d *imx50_add_uart3(void) +{ + return imx_add_uart_imx21((void *)MX50_UART4_BASE_ADDR, 3); +} + +static inline struct device_d *imx50_add_fec(struct fec_platform_data *pdata) +{ + return imx_add_fec_imx27((void *)MX50_FEC_BASE_ADDR, pdata); +} + +static inline struct device_d *imx50_add_mmc0(struct esdhc_platform_data *pdata) +{ + return imx_add_esdhc((void *)MX50_ESDHC1_BASE_ADDR, 0, pdata); +} + +static inline struct device_d *imx50_add_mmc1(struct esdhc_platform_data *pdata) +{ + return imx_add_esdhc((void *)MX50_ESDHC2_BASE_ADDR, 1, pdata); +} + +static inline struct device_d *imx50_add_mmc2(struct esdhc_platform_data *pdata) +{ + return imx_add_esdhc((void *)MX50_ESDHC3_BASE_ADDR, 2, pdata); +} + +static inline struct device_d *imx50_add_mmc3(struct esdhc_platform_data *pdata) +{ + return imx_add_esdhc((void *)MX50_ESDHC4_BASE_ADDR, 3, pdata); +} + +static inline struct device_d *imx50_add_kpp(struct matrix_keymap_data *pdata) +{ + return imx_add_kpp((void *)MX50_KPP_BASE_ADDR, pdata); +} diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h index 0a4200b3f4..cadc501040 100644 --- a/arch/arm/mach-imx/include/mach/generic.h +++ b/arch/arm/mach-imx/include/mach/generic.h @@ -11,6 +11,7 @@ u64 imx_uid(void); void imx25_boot_save_loc(void __iomem *ccm_base); void imx35_boot_save_loc(void __iomem *ccm_base); void imx27_boot_save_loc(void __iomem *sysctrl_base); +void imx50_boot_save_loc(void __iomem *src_base); void imx51_boot_save_loc(void __iomem *src_base); void imx53_boot_save_loc(void __iomem *src_base); void imx6_boot_save_loc(void __iomem *src_base); @@ -22,6 +23,7 @@ int imx25_init(void); int imx27_init(void); int imx31_init(void); int imx35_init(void); +int imx50_init(void); int imx51_init(void); int imx53_init(void); int imx6_init(void); @@ -32,6 +34,7 @@ int imx25_devices_init(void); int imx27_devices_init(void); int imx31_devices_init(void); int imx35_devices_init(void); +int imx50_devices_init(void); int imx51_devices_init(void); int imx53_devices_init(void); int imx6_devices_init(void); @@ -117,6 +120,19 @@ extern unsigned int __imx_cpu_type; # define cpu_is_mx35() (0) #endif +#ifdef CONFIG_ARCH_IMX50 +# ifdef imx_cpu_type +# undef imx_cpu_type +# define imx_cpu_type __imx_cpu_type +# else +# define imx_cpu_type IMX_CPU_IMX50 +# endif +# define cpu_is_mx50() (imx_cpu_type == IMX_CPU_IMX50) +#else +# define cpu_is_mx50() (0) +#endif + + #ifdef CONFIG_ARCH_IMX51 # ifdef imx_cpu_type # undef imx_cpu_type diff --git a/arch/arm/mach-imx/include/mach/imx5.h b/arch/arm/mach-imx/include/mach/imx5.h index 5d1a7d7d40..5957141298 100644 --- a/arch/arm/mach-imx/include/mach/imx5.h +++ b/arch/arm/mach-imx/include/mach/imx5.h @@ -1,6 +1,7 @@ #ifndef __MACH_MX5_H #define __MACH_MX5_H +void imx50_init_lowlevel(unsigned int cpufreq_mhz); void imx51_init_lowlevel(unsigned int cpufreq_mhz); void imx53_init_lowlevel(unsigned int cpufreq_mhz); void imx53_init_lowlevel_early(unsigned int cpufreq_mhz); diff --git a/arch/arm/mach-imx/include/mach/imx50-regs.h b/arch/arm/mach-imx/include/mach/imx50-regs.h new file mode 100644 index 0000000000..97ac8e2dad --- /dev/null +++ b/arch/arm/mach-imx/include/mach/imx50-regs.h @@ -0,0 +1,92 @@ +#ifndef __MACH_IMX50_REGS_H +#define __MACH_IMX50_REGS_H + +#include <linux/sizes.h> + +#define MX50_IROM_BASE_ADDR 0x0 + +#define MX50_IRAM_BASE_ADDR 0xF8000000 +#define MX50_IRAM_SIZE SZ_128K + +/* + * SPBA global module enabled #0 + */ +#define MX50_SPBA0_BASE_ADDR 0x50000000 +#define MX50_SPBA0_SIZE SZ_1M + +#define MX50_ESDHC1_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00004000) +#define MX50_ESDHC2_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00008000) +#define MX50_UART3_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x0000C000) +#define MX50_ECSPI1_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00010000) +#define MX50_SSI2_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00014000) +#define MX50_ESDHC3_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00020000) +#define MX50_ESDHC4_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00024000) +#define MX50_SPBA_CTRL_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x0003C000) + +/* + * AIPS 1 + */ +#define MX50_AIPS1_BASE_ADDR 0x53F00000 +#define MX50_AIPS1_SIZE SZ_512K + +#define MX50_OTG_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00080000) +#define MX50_GPIO1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00084000) +#define MX50_GPIO2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00088000) +#define MX50_GPIO3_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x0008C000) +#define MX50_GPIO4_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00090000) +#define MX50_KPP_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00094000) +#define MX50_WDOG1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00098000) +#define MX50_GPT1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000A0000) +#define MX50_SRTC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000A4000) +#define MX50_IOMUXC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000A8000) +#define MX50_EPIT1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000AC000) +#define MX50_PWM1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000B4000) +#define MX50_PWM2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000B8000) +#define MX50_UART1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000BC000) +#define MX50_UART2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000C0000) + +#define MX50_SRC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000D0000) +#define MX50_CCM_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000D4000) +#define MX50_GPC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000D8000) +#define MX50_GPIO5_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000DC000) +#define MX50_GPIO6_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000E0000) +#define MX50_I2C3_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000EC000) +#define MX50_UART4_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000F0000) + +/* + * AIPS 2 + */ +#define MX50_AIPS2_BASE_ADDR 0x63F00000 +#define MX50_AIPS2_SIZE SZ_512K + +#define MX50_PLL1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00080000) +#define MX50_PLL2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00084000) +#define MX50_PLL3_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00088000) +#define MX50_UART5_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00090000) +#define MX50_AHBMAX_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00094000) +#define MX50_ARM_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000A0000) +#define MX50_OWIRE_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000A4000) +#define MX50_ECSPI2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000AC000) +#define MX50_SDMA_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000B0000) +#define MX50_ROMCP_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000B8000) +#define MX50_CSPI_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000C0000) +#define MX50_I2C2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000C4000) +#define MX50_I2C1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000C8000) +#define MX50_SSI1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000CC000) +#define MX50_AUDMUX_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000D0000) +#define MX50_WEIM_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000DA000) +#define MX50_FEC_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000EC000) + +/* + * Memory regions and CS + */ +#define MX50_CSD0_BASE_ADDR 0x70000000 +#define MX50_CSD1_BASE_ADDR 0xB0000000 +#define MX50_CS0_BASE_ADDR 0xF0000000 +#define MX50_CS1_32MB_BASE_ADDR 0xF2000000 +#define MX50_CS1_64MB_BASE_ADDR 0xF4000000 +#define MX50_CS2_64MB_BASE_ADDR 0xF4000000 +#define MX50_CS2_96MB_BASE_ADDR 0xF6000000 +#define MX50_CS3_BASE_ADDR 0xF6000000 + +#endif /* __MACH_IMX50_REGS_H */ diff --git a/arch/arm/mach-imx/include/mach/imx_cpu_types.h b/arch/arm/mach-imx/include/mach/imx_cpu_types.h index 781ab9fe74..84724883b5 100644 --- a/arch/arm/mach-imx/include/mach/imx_cpu_types.h +++ b/arch/arm/mach-imx/include/mach/imx_cpu_types.h @@ -7,6 +7,7 @@ #define IMX_CPU_IMX27 27 #define IMX_CPU_IMX31 31 #define IMX_CPU_IMX35 35 +#define IMX_CPU_IMX50 50 #define IMX_CPU_IMX51 51 #define IMX_CPU_IMX53 53 #define IMX_CPU_IMX6 6 diff --git a/arch/arm/mach-imx/include/mach/iomux-mx50.h b/arch/arm/mach-imx/include/mach/iomux-mx50.h new file mode 100644 index 0000000000..c21bb3ea9b --- /dev/null +++ b/arch/arm/mach-imx/include/mach/iomux-mx50.h @@ -0,0 +1,943 @@ +/* + * Copyright 2013 Greg Ungerer <gerg@uclinux.org> + * Copyright 2016 Alexander Kurz <akurz@blala.de> + * based on linux imx50-pinfunc.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc.. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __MACH_IOMUX_MX50_H__ +#define __MACH_IOMUX_MX50_H__ + +#include <mach/iomux-v3.h> + +/* These 2 defines are for pins that may not have a mux register, but could + * have a pad setting register, and vice-versa. */ +#define __NA_ 0x00 + +#define MX50_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_HIGH) +#define MX50_SDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH) +#define MX50_I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_ODE | \ + PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH) +#define MX50_SPI_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH) + +#define MX50_PAD_KEY_COL0__KPP_COL_0 IOMUX_PAD(0x2CC, 0x020, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL0__GPIO4_0 IOMUX_PAD(0x2CC, 0x020, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL0__EIM_NANDF_CLE IOMUX_PAD(0x2CC, 0x020, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL0__CTI_TRIGIN7 IOMUX_PAD(0x2CC, 0x020, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL0__USBPHY1_TXREADY IOMUX_PAD(0x2CC, 0x020, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW0__KPP_ROW_0 IOMUX_PAD(0x2D0, 0x024, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW0__GPIO4_1 IOMUX_PAD(0x2D0, 0x024, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW0__EIM_NANDF_ALE IOMUX_PAD(0x2D0, 0x024, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW0__CTI_TRIGIN_ACK7 IOMUX_PAD(0x2D0, 0x024, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW0__USBPHY1_RXVALID IOMUX_PAD(0x2D0, 0x024, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL1__KPP_COL_1 IOMUX_PAD(0x2D4, 0x028, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL1__GPIO4_2 IOMUX_PAD(0x2D4, 0x028, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL1__EIM_NANDF_CEN_0 IOMUX_PAD(0x2D4, 0x028, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL1__CTI_TRIGOUT_ACK6 IOMUX_PAD(0x2D4, 0x028, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL1__USBPHY1_RXACTIVE IOMUX_PAD(0x2D4, 0x028, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW1__KPP_ROW_1 IOMUX_PAD(0x2D8, 0x02C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW1__GPIO4_3 IOMUX_PAD(0x2D8, 0x02C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW1__EIM_NANDF_CEN_1 IOMUX_PAD(0x2D8, 0x02C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW1__CTI_TRIGOUT_ACK7 IOMUX_PAD(0x2D8, 0x02C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW1__USBPHY1_RXERROR IOMUX_PAD(0x2D8, 0x02C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL2__KPP_COL_1 IOMUX_PAD(0x2DC, 0x030, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL2__GPIO4_4 IOMUX_PAD(0x2DC, 0x030, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL2__EIM_NANDF_CEN_2 IOMUX_PAD(0x2DC, 0x030, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL2__CTI_TRIGOUT6 IOMUX_PAD(0x2DC, 0x030, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL2__USBPHY1_SIECLOCK IOMUX_PAD(0x2DC, 0x030, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW2__KPP_ROW_2 IOMUX_PAD(0x2E0, 0x034, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW2__GPIO4_5 IOMUX_PAD(0x2E0, 0x034, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW2__EIM_NANDF_CEN_3 IOMUX_PAD(0x2E0, 0x034, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW2__CTI_TRIGOUT7 IOMUX_PAD(0x2E0, 0x034, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW2__USBPHY1_LINESTATE_0 IOMUX_PAD(0x2E0, 0x034, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL3__KPP_COL_2 IOMUX_PAD(0x2E4, 0x038, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL3__GPIO4_6 IOMUX_PAD(0x2E4, 0x038, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL3__EIM_NANDF_READY0 IOMUX_PAD(0x2E4, 0x038, 2, 0x7B4, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL3__SDMA_EXT_EVENT_0 IOMUX_PAD(0x2E4, 0x038, 6, 0x7B8, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_COL3__USBPHY1_LINESTATE_1 IOMUX_PAD(0x2E4, 0x038, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW3__KPP_ROW_3 IOMUX_PAD(0x2E8, 0x03C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW3__GPIO4_7 IOMUX_PAD(0x2E8, 0x03C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW3__EIM_NANDF_DQS IOMUX_PAD(0x2E8, 0x03C, 2, 0x7B0, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW3__SDMA_EXT_EVENT_1 IOMUX_PAD(0x2E8, 0x03C, 6, 0x7BC, 0, NO_PAD_CTRL) +#define MX50_PAD_KEY_ROW3__USBPHY1_VBUSVALID IOMUX_PAD(0x2E8, 0x03C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C1_SCL__I2C1_SCL IOMUX_PAD(0x2EC, 0x040, 0 | IOMUX_CONFIG_SION, __NA_, 0, MX50_I2C_PAD_CTRL) +#define MX50_PAD_I2C1_SCL__GPIO6_18 IOMUX_PAD(0x2EC, 0x040, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C1_SCL__UART2_TXD_MUX IOMUX_PAD(0x2EC, 0x040, 2, 0x7CC, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_I2C1_SDA__I2C1_SDA IOMUX_PAD(0x2F0, 0x044, 0 | IOMUX_CONFIG_SION, __NA_, 0, MX50_I2C_PAD_CTRL) +#define MX50_PAD_I2C1_SDA__GPIO6_19 IOMUX_PAD(0x2F0, 0x044, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C1_SDA__UART2_RXD_MUX IOMUX_PAD(0x2F0, 0x044, 2, 0x7CC, 1, MX50_UART_PAD_CTRL) +#define MX50_PAD_I2C2_SCL__I2C2_SCL IOMUX_PAD(0x2F4, 0x048, 0 | IOMUX_CONFIG_SION, __NA_, 0, MX50_I2C_PAD_CTRL) +#define MX50_PAD_I2C2_SCL__GPIO6_20 IOMUX_PAD(0x2F4, 0x048, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C2_SCL__UART2_CTS IOMUX_PAD(0x2F4, 0x048, 2, __NA_, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_I2C2_SDA__I2C2_SDA IOMUX_PAD(0x2F8, 0x04C, 0 | IOMUX_CONFIG_SION, __NA_, 0, MX50_I2C_PAD_CTRL) +#define MX50_PAD_I2C2_SDA__GPIO6_21 IOMUX_PAD(0x2F8, 0x04C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C2_SDA__UART2_RTS IOMUX_PAD(0x2F8, 0x04C, 2, 0x7C8, 1, MX50_UART_PAD_CTRL) +#define MX50_PAD_I2C3_SCL__I2C3_SCL IOMUX_PAD(0x2FC, 0x050, 0 | IOMUX_CONFIG_SION, __NA_, 0, MX50_I2C_PAD_CTRL) +#define MX50_PAD_I2C3_SCL__GPIO6_22 IOMUX_PAD(0x2FC, 0x050, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SCL__FEC_MDC IOMUX_PAD(0x2FC, 0x050, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SCL__GPC_PMIC_RDY IOMUX_PAD(0x2FC, 0x050, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SCL__GPT_CAPIN1 IOMUX_PAD(0x2FC, 0x050, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SCL__OBSERVE_MUX_OBSRV_INT_OUT0 IOMUX_PAD(0x2FC, 0x050, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SCL__USBOH1_USBOTG_OC IOMUX_PAD(0x2FC, 0x050, 7, 0x7E8, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SDA__I2C3_SDA IOMUX_PAD(0x300, 0x054, 0 | IOMUX_CONFIG_SION, __NA_, 0, MX50_I2C_PAD_CTRL) +#define MX50_PAD_I2C3_SDA__GPIO6_23 IOMUX_PAD(0x300, 0x054, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SDA__FEC_MDIO IOMUX_PAD(0x300, 0x054, 2, 0x774, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SDA__TZIC_PWRFAIL_INT IOMUX_PAD(0x300, 0x054, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SDA__SRTC_ALARM_DEB IOMUX_PAD(0x300, 0x054, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SDA__GPT_CAPIN2 IOMUX_PAD(0x300, 0x054, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SDA__OBSERVE_MUX_OBSRV_INT_OUT1 IOMUX_PAD(0x300, 0x054, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_I2C3_SDA__USBOH1_USBOTG_PWR IOMUX_PAD(0x300, 0x054, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM1__PWM1_PWMO IOMUX_PAD(0x304, 0x058, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM1__GPIO6_24 IOMUX_PAD(0x304, 0x058, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM1__USBOH1_USBOTG_OC IOMUX_PAD(0x304, 0x058, 2, 0x7E8, 1, NO_PAD_CTRL) +#define MX50_PAD_PWM1__GPT_CMPOUT1 IOMUX_PAD(0x304, 0x058, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM1__OBSERVE_MUX_OBSRV_INT_OUT2 IOMUX_PAD(0x304, 0x058, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM1__SJC_FAIL IOMUX_PAD(0x304, 0x058, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM2__PWM2_PWMO IOMUX_PAD(0x308, 0x05C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM2__GPIO6_25 IOMUX_PAD(0x308, 0x05C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM2__USBOH1_USBOTG_PWR IOMUX_PAD(0x308, 0x05C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM2__GPT_CMPOUT2 IOMUX_PAD(0x308, 0x05C, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM2__OBSERVE_MUX_OBSRV_INT_OUT3 IOMUX_PAD(0x308, 0x05C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_PWM2__SRC_ANY_PU_RST IOMUX_PAD(0x308, 0x05C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_OWIRE__OWIRE_LINE IOMUX_PAD(0x30C, 0x060, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_OWIRE__GPIO6_26 IOMUX_PAD(0x30C, 0x060, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_OWIRE__USBOH1_USBH1_OC IOMUX_PAD(0x30C, 0x060, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_OWIRE__CCM_SSI_EXT1_CLK IOMUX_PAD(0x30C, 0x060, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_OWIRE__EPDC_PWRIRQ IOMUX_PAD(0x30C, 0x060, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_OWIRE__GPT_CMPOUT3 IOMUX_PAD(0x30C, 0x060, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_OWIRE__OBSERVE_MUX_OBSRV_INT_OUT4 IOMUX_PAD(0x30C, 0x060, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_OWIRE__SJC_JTAG_ACT IOMUX_PAD(0x30C, 0x060, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPITO__EPIT1_EPITO IOMUX_PAD(0x310, 0x064, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPITO__GPIO6_27 IOMUX_PAD(0x310, 0x064, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPITO__USBOH1_USBH1_PWR IOMUX_PAD(0x310, 0x064, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPITO__CCM_SSI_EXT2_CLK IOMUX_PAD(0x310, 0x064, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPITO__DPLLIP1_TOG_EN IOMUX_PAD(0x310, 0x064, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPITO__GPT_CLK_IN IOMUX_PAD(0x310, 0x064, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPITO__PMU_IRQ_B IOMUX_PAD(0x310, 0x064, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPITO__SJC_DE_B IOMUX_PAD(0x310, 0x064, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_WDOG__WDOG1_WDOG_B IOMUX_PAD(0x314, 0x068, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_WDOG__GPIO6_28 IOMUX_PAD(0x314, 0x068, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_WDOG__WDOG1_WDOG_RST_B_DEB IOMUX_PAD(0x314, 0x068, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_WDOG__CCM_XTAL32K IOMUX_PAD(0x314, 0x068, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_WDOG__SJC_DONE IOMUX_PAD(0x314, 0x068, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXFS__AUDMUX_AUD3_TXFS IOMUX_PAD(0x318, 0x06C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXFS__GPIO6_0 IOMUX_PAD(0x318, 0x06C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXFS__SRC_BT_FUSE_RSV_1 IOMUX_PAD(0x318, 0x06C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXFS__USBPHY1_DATAOUT_8 IOMUX_PAD(0x318, 0x06C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXC__AUDMUX_AUD3_TXC IOMUX_PAD(0x31C, 0x070, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXC__GPIO6_1 IOMUX_PAD(0x31C, 0x070, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXC__SRC_BT_FUSE_RSV_0 IOMUX_PAD(0x31C, 0x070, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXC__USBPHY1_DATAOUT_9 IOMUX_PAD(0x31C, 0x070, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXD__AUDMUX_AUD3_TXD IOMUX_PAD(0x320, 0x074, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXD__GPIO6_2 IOMUX_PAD(0x320, 0x074, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXD__CSPI_RDY IOMUX_PAD(0x320, 0x074, 4, 0x6E8, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_TXD__USBPHY1_DATAOUT_10 IOMUX_PAD(0x320, 0x074, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXD__AUDMUX_AUD3_RXD IOMUX_PAD(0x324, 0x078, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXD__GPIO6_3 IOMUX_PAD(0x324, 0x078, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXD__CSPI_SS3 IOMUX_PAD(0x324, 0x078, 4, 0x6F4, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXD__USBPHY1_DATAOUT_11 IOMUX_PAD(0x324, 0x078, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXFS__AUDMUX_AUD3_RXFS IOMUX_PAD(0x328, 0x07C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXFS__GPIO6_4 IOMUX_PAD(0x328, 0x07C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXFS__UART5_TXD_MUX IOMUX_PAD(0x328, 0x07C, 2, 0x7E4, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_SSI_RXFS__EIM_WEIM_D_6 IOMUX_PAD(0x328, 0x07C, 3, 0x804, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXFS__CSPI_SS2 IOMUX_PAD(0x328, 0x07C, 4, 0x6F0, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXFS__FEC_COL IOMUX_PAD(0x328, 0x07C, 5, 0x770, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXFS__FEC_MDC IOMUX_PAD(0x328, 0x07C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXFS__USBPHY1_DATAOUT_12 IOMUX_PAD(0x328, 0x07C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXC__AUDMUX_AUD3_RXC IOMUX_PAD(0x32C, 0x080, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXC__GPIO6_5 IOMUX_PAD(0x32C, 0x080, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXC__UART5_RXD_MUX IOMUX_PAD(0x32C, 0x080, 2, 0x7E4, 1, MX50_UART_PAD_CTRL) +#define MX50_PAD_SSI_RXC__EIM_WEIM_D_7 IOMUX_PAD(0x32C, 0x080, 3, 0x808, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXC__CSPI_SS1 IOMUX_PAD(0x32C, 0x080, 4, 0x6EC, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXC__FEC_RX_CLK IOMUX_PAD(0x32C, 0x080, 5, 0x780, 0, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXC__FEC_MDIO IOMUX_PAD(0x32C, 0x080, 6, 0x774, 1, NO_PAD_CTRL) +#define MX50_PAD_SSI_RXC__USBPHY1_DATAOUT_13 IOMUX_PAD(0x32C, 0x080, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART1_TXD__UART1_TXD_MUX IOMUX_PAD(0x330, 0x084, 0, 0x7C4, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART1_TXD__GPIO6_6 IOMUX_PAD(0x330, 0x084, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART1_TXD__USBPHY1_DATAOUT_14 IOMUX_PAD(0x330, 0x084, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART1_RXD__UART1_RXD_MUX IOMUX_PAD(0x334, 0x088, 0, 0x7C4, 1, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART1_RXD__GPIO6_7 IOMUX_PAD(0x334, 0x088, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART1_RXD__USBPHY1_DATAOUT_15 IOMUX_PAD(0x334, 0x088, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x338, 0x08C, 0, __NA_, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART1_CTS__GPIO6_8 IOMUX_PAD(0x338, 0x08C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART1_CTS__UART5_TXD_MUX IOMUX_PAD(0x338, 0x08C, 2, 0x7E4, 2, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART1_CTS__ESDHC4_DAT4 IOMUX_PAD(0x338, 0x08C, 4, 0x760, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART1_CTS__ESDHC4_CMD IOMUX_PAD(0x338, 0x08C, 5, 0x74C, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART1_CTS__USBPHY2_DATAOUT_8 IOMUX_PAD(0x338, 0x08C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x33C, 0x090, 0, 0x7C0, 3, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART1_RTS__GPIO6_9 IOMUX_PAD(0x33C, 0x090, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART1_RTS__UART5_RXD_MUX IOMUX_PAD(0x33C, 0x090, 2, 0x7E4, 3, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART1_RTS__ESDHC4_DAT5 IOMUX_PAD(0x33C, 0x090, 4, 0x764, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART1_RTS__ESDHC4_CLK IOMUX_PAD(0x33C, 0x090, 5, 0x748, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART1_RTS__USBPHY2_DATAOUT_9 IOMUX_PAD(0x33C, 0x090, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART2_TXD__UART2_TXD_MUX IOMUX_PAD(0x340, 0x094, 0, 0x7CC, 2, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART2_TXD__GPIO6_10 IOMUX_PAD(0x340, 0x094, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART2_TXD__ESDHC4_DAT6 IOMUX_PAD(0x340, 0x094, 4, 0x768, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART2_TXD__ESDHC4_DAT4 IOMUX_PAD(0x340, 0x094, 5, 0x760, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART2_TXD__USBPHY2_DATAOUT_10 IOMUX_PAD(0x340, 0x094, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART2_RXD__UART2_RXD_MUX IOMUX_PAD(0x344, 0x098, 0, 0x7CC, 3, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART2_RXD__GPIO6_11 IOMUX_PAD(0x344, 0x098, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART2_RXD__ESDHC4_DAT7 IOMUX_PAD(0x344, 0x098, 4, 0x76C, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART2_RXD__ESDHC4_DAT5 IOMUX_PAD(0x344, 0x098, 5, 0x764, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART2_RXD__USBPHY2_DATAOUT_11 IOMUX_PAD(0x344, 0x098, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x348, 0x09C, 0, __NA_, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART2_CTS__GPIO6_12 IOMUX_PAD(0x348, 0x09C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART2_CTS__ESDHC4_CMD IOMUX_PAD(0x348, 0x09C, 4, 0x74C, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART2_CTS__ESDHC4_DAT6 IOMUX_PAD(0x348, 0x09C, 5, 0x768, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART2_CTS__USBPHY2_DATAOUT_12 IOMUX_PAD(0x348, 0x09C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x34C, 0x0A0, 0, 0x7C8, 2, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART2_RTS__GPIO6_13 IOMUX_PAD(0x34C, 0x0A0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART2_RTS__ESDHC4_CLK IOMUX_PAD(0x34C, 0x0A0, 4, 0x748, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART2_RTS__ESDHC4_DAT7 IOMUX_PAD(0x34C, 0x0A0, 5, 0x76C, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART2_RTS__USBPHY2_DATAOUT_13 IOMUX_PAD(0x34C, 0x0A0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART3_TXD__UART3_TXD_MUX IOMUX_PAD(0x350, 0x0A4, 0, 0x7D4, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART3_TXD__GPIO6_14 IOMUX_PAD(0x350, 0x0A4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART3_TXD__ESDHC1_DAT4 IOMUX_PAD(0x350, 0x0A4, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART3_TXD__ESDHC4_DAT0 IOMUX_PAD(0x350, 0x0A4, 4, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART3_TXD__ESDHC2_WP IOMUX_PAD(0x350, 0x0A4, 5, 0x744, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART3_TXD__EIM_WEIM_D_12 IOMUX_PAD(0x350, 0x0A4, 6, 0x81C, 0, NO_PAD_CTRL) +#define MX50_PAD_UART3_TXD__USBPHY2_DATAOUT_14 IOMUX_PAD(0x350, 0x0A4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART3_RXD__UART3_RXD_MUX IOMUX_PAD(0x354, 0x0A8, 0, 0x7D4, 1, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART3_RXD__GPIO6_15 IOMUX_PAD(0x354, 0x0A8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART3_RXD__ESDHC1_DAT5 IOMUX_PAD(0x354, 0x0A8, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART3_RXD__ESDHC4_DAT1 IOMUX_PAD(0x354, 0x0A8, 4, 0x754, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART3_RXD__ESDHC2_CD IOMUX_PAD(0x354, 0x0A8, 5, 0x740, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART3_RXD__EIM_WEIM_D_13 IOMUX_PAD(0x354, 0x0A8, 6, 0x820, 0, NO_PAD_CTRL) +#define MX50_PAD_UART3_RXD__USBPHY2_DATAOUT_15 IOMUX_PAD(0x354, 0x0A8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART4_TXD__UART4_TXD_MUX IOMUX_PAD(0x358, 0x0AC, 0, 0x7DC, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART4_TXD__GPIO6_16 IOMUX_PAD(0x358, 0x0AC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART4_TXD__UART3_CTS IOMUX_PAD(0x358, 0x0AC, 2, 0x7D0, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART4_TXD__ESDHC1_DAT6 IOMUX_PAD(0x358, 0x0AC, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART4_TXD__ESDHC4_DAT2 IOMUX_PAD(0x358, 0x0AC, 4, 0x758, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART4_TXD__ESDHC2_LCTL IOMUX_PAD(0x358, 0x0AC, 5, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART4_TXD__EIM_WEIM_D_14 IOMUX_PAD(0x358, 0x0AC, 6, 0x824, 0, NO_PAD_CTRL) +#define MX50_PAD_UART4_RXD__UART4_RXD_MUX IOMUX_PAD(0x35C, 0x0B0, 0, 0x7DC, 1, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART4_RXD__GPIO6_17 IOMUX_PAD(0x35C, 0x0B0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_UART4_RXD__UART3_RTS IOMUX_PAD(0x35C, 0x0B0, 2, 0x7D0, 1, MX50_UART_PAD_CTRL) +#define MX50_PAD_UART4_RXD__ESDHC1_DAT7 IOMUX_PAD(0x35C, 0x0B0, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART4_RXD__ESDHC4_DAT3 IOMUX_PAD(0x35C, 0x0B0, 4, 0x75C, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART4_RXD__ESDHC1_LCTL IOMUX_PAD(0x35C, 0x0B0, 5, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_UART4_RXD__EIM_WEIM_D_15 IOMUX_PAD(0x35C, 0x0B0, 6, 0x828, 0, NO_PAD_CTRL) +#define MX50_PAD_CSPI_SCLK__CSPI_SCLK IOMUX_PAD(0x360, 0x0B4, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_CSPI_SCLK__GPIO4_8 IOMUX_PAD(0x360, 0x0B4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_CSPI_MOSI__CSPI_MOSI IOMUX_PAD(0x364, 0x0B8, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_CSPI_MOSI__GPIO4_9 IOMUX_PAD(0x364, 0x0B8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_CSPI_MISO__CSPI_MISO IOMUX_PAD(0x368, 0x0BC, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_CSPI_MISO__GPIO4_10 IOMUX_PAD(0x368, 0x0BC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_CSPI_SS0__CSPI_SS0 IOMUX_PAD(0x36C, 0x0C0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_CSPI_SS0__GPIO4_11 IOMUX_PAD(0x36C, 0x0C0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x370, 0x0C4, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_ECSPI1_SCLK__GPIO4_12 IOMUX_PAD(0x370, 0x0C4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SCLK__CSPI_RDY IOMUX_PAD(0x370, 0x0C4, 2, 0x6E8, 1, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SCLK__ECSPI2_RDY IOMUX_PAD(0x370, 0x0C4, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SCLK__UART3_RTS IOMUX_PAD(0x370, 0x0C4, 4, 0x7D0, 2, MX50_UART_PAD_CTRL) +#define MX50_PAD_ECSPI1_SCLK__EPDC_SDCE_6 IOMUX_PAD(0x370, 0x0C4, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SCLK__EIM_WEIM_D_8 IOMUX_PAD(0x370, 0x0C4, 7, 0x80C, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x374, 0x0C8, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_ECSPI1_MOSI__GPIO4_13 IOMUX_PAD(0x374, 0x0C8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MOSI__CSPI_SS1 IOMUX_PAD(0x374, 0x0C8, 2, 0x6EC, 1, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MOSI__ECSPI2_SS1 IOMUX_PAD(0x374, 0x0C8, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MOSI__UART3_CTS IOMUX_PAD(0x374, 0x0C8, 4, __NA_, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_ECSPI1_MOSI__EPDC_SDCE_7 IOMUX_PAD(0x374, 0x0C8, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MOSI__EIM_WEIM_D_9 IOMUX_PAD(0x374, 0x0C8, 7, 0x810, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x378, 0x0CC, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_ECSPI1_MISO__GPIO4_14 IOMUX_PAD(0x378, 0x0CC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MISO__CSPI_SS2 IOMUX_PAD(0x378, 0x0CC, 2, 0x6F0, 1, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MISO__ECSPI2_SS2 IOMUX_PAD(0x378, 0x0CC, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MISO__UART4_RTS IOMUX_PAD(0x378, 0x0CC, 4, 0x7D8, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_ECSPI1_MISO__EPDC_SDCE_8 IOMUX_PAD(0x378, 0x0CC, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_MISO__EIM_WEIM_D_10 IOMUX_PAD(0x378, 0x0CC, 7, 0x814, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x37C, 0x0D0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SS0__GPIO4_15 IOMUX_PAD(0x37C, 0x0D0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SS0__CSPI_SS3 IOMUX_PAD(0x37C, 0x0D0, 2, 0x6F4, 1, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SS0__ECSPI2_SS3 IOMUX_PAD(0x37C, 0x0D0, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SS0__UART4_CTS IOMUX_PAD(0x37C, 0x0D0, 4, __NA_, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_ECSPI1_SS0__EPDC_SDCE_9 IOMUX_PAD(0x37C, 0x0D0, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI1_SS0__EIM_WEIM_D_11 IOMUX_PAD(0x37C, 0x0D0, 7, 0x818, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SCLK__ECSPI2_SCLK IOMUX_PAD(0x380, 0x0D4, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_ECSPI2_SCLK__GPIO4_16 IOMUX_PAD(0x380, 0x0D4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SCLK__ELCDIF_WR_RWN IOMUX_PAD(0x380, 0x0D4, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SCLK__ECSPI1_RDY IOMUX_PAD(0x380, 0x0D4, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SCLK__UART5_RTS IOMUX_PAD(0x380, 0x0D4, 4, 0x7E0, 0, MX50_UART_PAD_CTRL) +#define MX50_PAD_ECSPI2_SCLK__ELCDIF_DOTCLK IOMUX_PAD(0x380, 0x0D4, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SCLK__EIM_NANDF_CEN_4 IOMUX_PAD(0x380, 0x0D4, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SCLK__EIM_WEIM_D_8 IOMUX_PAD(0x380, 0x0D4, 7, 0x80C, 1, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MOSI__ECSPI2_MOSI IOMUX_PAD(0x384, 0x0D8, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_ECSPI2_MOSI__GPIO4_17 IOMUX_PAD(0x384, 0x0D8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MOSI__ELCDIF_RE_E IOMUX_PAD(0x384, 0x0D8, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MOSI__ECSPI1_SS1 IOMUX_PAD(0x384, 0x0D8, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MOSI__UART5_CTS IOMUX_PAD(0x384, 0x0D8, 4, 0x7E0, 1, MX50_UART_PAD_CTRL) +#define MX50_PAD_ECSPI2_MOSI__ELCDIF_ENABLE IOMUX_PAD(0x384, 0x0D8, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MOSI__EIM_NANDF_CEN_5 IOMUX_PAD(0x384, 0x0D8, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MOSI__EIM_WEIM_D_9 IOMUX_PAD(0x384, 0x0D8, 7, 0x810, 1, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO IOMUX_PAD(0x388, 0x0DC, 0, __NA_, 0, MX50_SPI_PAD_CTRL) +#define MX50_PAD_ECSPI2_MISO__GPIO4_18 IOMUX_PAD(0x388, 0x0DC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MISO__ELCDIF_RS IOMUX_PAD(0x388, 0x0DC, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MISO__ECSPI1_SS2 IOMUX_PAD(0x388, 0x0DC, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MISO__UART5_TXD_MUX IOMUX_PAD(0x388, 0x0DC, 4, 0x7E4, 4, MX50_UART_PAD_CTRL) +#define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC IOMUX_PAD(0x388, 0x0DC, 5, 0x73C, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MISO__EIM_NANDF_CEN_6 IOMUX_PAD(0x388, 0x0DC, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_MISO__EIM_WEIM_D_10 IOMUX_PAD(0x388, 0x0DC, 7, 0x814, 1, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS0 IOMUX_PAD(0x38C, 0x0E0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SS0__GPIO4_19 IOMUX_PAD(0x38C, 0x0E0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SS0__ELCDIF_CS IOMUX_PAD(0x38C, 0x0E0, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS3 IOMUX_PAD(0x38C, 0x0E0, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SS0__UART5_RXD_MUX IOMUX_PAD(0x38C, 0x0E0, 4, 0x7E4, 5, MX50_UART_PAD_CTRL) +#define MX50_PAD_ECSPI2_SS0__ELCDIF_HSYNC IOMUX_PAD(0x38C, 0x0E0, 5, 0x6F8, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SS0__EIM_NANDF_CEN_7 IOMUX_PAD(0x38C, 0x0E0, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_ECSPI2_SS0__EIM_WEIM_D_11 IOMUX_PAD(0x38C, 0x0E0, 7, 0x818, 1, NO_PAD_CTRL) +#define MX50_PAD_SD1_CLK__ESDHC1_CLK IOMUX_PAD(0x390, 0x0E4, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD1_CLK__GPIO5_0 IOMUX_PAD(0x390, 0x0E4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_CLK__CCM_CLKO IOMUX_PAD(0x390, 0x0E4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_CMD__ESDHC1_CMD IOMUX_PAD(0x394, 0x0E8, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD1_CMD__GPIO5_1 IOMUX_PAD(0x394, 0x0E8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_CMD__CCM_CLKO2 IOMUX_PAD(0x394, 0x0E8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_D0__ESDHC1_DAT0 IOMUX_PAD(0x398, 0x0EC, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD1_D0__GPIO5_2 IOMUX_PAD(0x398, 0x0EC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_D0__CCM_PLL1_BYP IOMUX_PAD(0x398, 0x0EC, 7, 0x6DC, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_D1__ESDHC1_DAT1 IOMUX_PAD(0x39C, 0x0F0, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD1_D1__GPIO5_3 IOMUX_PAD(0x39C, 0x0F0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_D1__CCM_PLL2_BYP IOMUX_PAD(0x39C, 0x0F0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_D2__ESDHC1_DAT2 IOMUX_PAD(0x3A0, 0x0F4, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD1_D2__GPIO5_4 IOMUX_PAD(0x3A0, 0x0F4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_D2__CCM_PLL3_BYP IOMUX_PAD(0x3A0, 0x0F4, 7, 0x6E4, 0, NO_PAD_CTRL) +#define MX50_PAD_SD1_D3__ESDHC1_DAT3 IOMUX_PAD(0x3A4, 0x0F8, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD1_D3__GPIO5_5 IOMUX_PAD(0x3A4, 0x0F8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_CLK__ESDHC2_CLK IOMUX_PAD(0x3A8, 0x0FC, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_CLK__GPIO5_6 IOMUX_PAD(0x3A8, 0x0FC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_CLK__MSHC_SCLK IOMUX_PAD(0x3A8, 0x0FC, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_CMD__ESDHC2_CMD IOMUX_PAD(0x3AC, 0x100, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_CMD__GPIO5_7 IOMUX_PAD(0x3AC, 0x100, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_CMD__MSHC_BS IOMUX_PAD(0x3AC, 0x100, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D0__ESDHC2_DAT0 IOMUX_PAD(0x3B0, 0x104, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_D0__GPIO5_8 IOMUX_PAD(0x3B0, 0x104, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D0__MSHC_DATA_0 IOMUX_PAD(0x3B0, 0x104, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D0__KPP_COL_4 IOMUX_PAD(0x3B0, 0x104, 3, 0x790, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D1__ESDHC2_DAT1 IOMUX_PAD(0x3B4, 0x108, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_D1__GPIO5_9 IOMUX_PAD(0x3B4, 0x108, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D1__MSHC_DATA_1 IOMUX_PAD(0x3B4, 0x108, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D1__KPP_ROW_4 IOMUX_PAD(0x3B4, 0x108, 3, 0x7A0, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D2__ESDHC2_DAT2 IOMUX_PAD(0x3B8, 0x10C, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_D2__GPIO5_10 IOMUX_PAD(0x3B8, 0x10C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D2__MSHC_DATA_2 IOMUX_PAD(0x3B8, 0x10C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D2__KPP_COL_5 IOMUX_PAD(0x3B8, 0x10C, 3, 0x794, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D3__ESDHC2_DAT3 IOMUX_PAD(0x3BC, 0x110, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_D3__GPIO5_11 IOMUX_PAD(0x3BC, 0x110, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D3__MSHC_DATA_3 IOMUX_PAD(0x3BC, 0x110, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D3__KPP_ROW_5 IOMUX_PAD(0x3BC, 0x110, 3, 0x7A4, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D4__ESDHC2_DAT4 IOMUX_PAD(0x3C0, 0x114, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_D4__GPIO5_12 IOMUX_PAD(0x3C0, 0x114, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D4__AUDMUX_AUD4_RXFS IOMUX_PAD(0x3C0, 0x114, 2, 0x6D0, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D4__KPP_COL_6 IOMUX_PAD(0x3C0, 0x114, 3, 0x798, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D4__EIM_WEIM_D_0 IOMUX_PAD(0x3C0, 0x114, 4, 0x7EC, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D4__CCM_CCM_OUT_0 IOMUX_PAD(0x3C0, 0x114, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D5__ESDHC2_DAT5 IOMUX_PAD(0x3C4, 0x118, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_D5__GPIO5_13 IOMUX_PAD(0x3C4, 0x118, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D5__AUDMUX_AUD4_RXC IOMUX_PAD(0x3C4, 0x118, 2, 0x6CC, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D5__KPP_ROW_6 IOMUX_PAD(0x3C4, 0x118, 3, 0x7A8, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D5__EIM_WEIM_D_1 IOMUX_PAD(0x3C4, 0x118, 4, 0x7F0, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D5__CCM_CCM_OUT_1 IOMUX_PAD(0x3C4, 0x118, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D6__ESDHC2_DAT6 IOMUX_PAD(0x3C8, 0x11C, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_D6__GPIO5_14 IOMUX_PAD(0x3C8, 0x11C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D6__AUDMUX_AUD4_RXD IOMUX_PAD(0x3C8, 0x11C, 2, 0x6C4, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D6__KPP_COL_7 IOMUX_PAD(0x3C8, 0x11C, 3, 0x79C, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D6__EIM_WEIM_D_2 IOMUX_PAD(0x3C8, 0x11C, 4, 0x7F4, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D6__CCM_CCM_OUT_2 IOMUX_PAD(0x3C8, 0x11C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D7__ESDHC2_DAT7 IOMUX_PAD(0x3CC, 0x120, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_D7__GPIO5_15 IOMUX_PAD(0x3CC, 0x120, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D7__AUDMUX_AUD4_TXFS IOMUX_PAD(0x3CC, 0x120, 2, 0x6D8, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D7__KPP_ROW_7 IOMUX_PAD(0x3CC, 0x120, 3, 0x7AC, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D7__EIM_WEIM_D_3 IOMUX_PAD(0x3CC, 0x120, 4, 0x7F8, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_D7__CCM_STOP IOMUX_PAD(0x3CC, 0x120, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_WP__ESDHC2_WP IOMUX_PAD(0x3D0, 0x124, 0, 0x744, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_WP__GPIO5_16 IOMUX_PAD(0x3D0, 0x124, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_WP__AUDMUX_AUD4_TXD IOMUX_PAD(0x3D0, 0x124, 2, 0x6C8, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_WP__EIM_WEIM_D_4 IOMUX_PAD(0x3D0, 0x124, 4, 0x7FC, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_WP__CCM_WAIT IOMUX_PAD(0x3D0, 0x124, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_CD__ESDHC2_CD IOMUX_PAD(0x3D4, 0x128, 0, 0x740, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD2_CD__GPIO5_17 IOMUX_PAD(0x3D4, 0x128, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_CD__AUDMUX_AUD4_TXC IOMUX_PAD(0x3D4, 0x128, 2, 0x6D4, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_CD__EIM_WEIM_D_5 IOMUX_PAD(0x3D4, 0x128, 4, 0x800, 0, NO_PAD_CTRL) +#define MX50_PAD_SD2_CD__CCM_REF_EN_B IOMUX_PAD(0x3D4, 0x128, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D0__ELCDIF_DAT_0 IOMUX_PAD(0x40C, 0x12C, 0, 0x6FC, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D0__GPIO2_0 IOMUX_PAD(0x40C, 0x12C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D0__FEC_TX_CLK IOMUX_PAD(0x40C, 0x12C, 2, 0x78C, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D0__EIM_WEIM_A_16 IOMUX_PAD(0x40C, 0x12C, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D0__SDMA_DEBUG_PC_0 IOMUX_PAD(0x40C, 0x12C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D0__USBPHY1_VSTATUS_0 IOMUX_PAD(0x40C, 0x12C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D1__ELCDIF_DAT_1 IOMUX_PAD(0x410, 0x130, 0, 0x700, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D1__GPIO2_1 IOMUX_PAD(0x410, 0x130, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D1__FEC_RX_ERR IOMUX_PAD(0x410, 0x130, 2, 0x788, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D1__EIM_WEIM_A_17 IOMUX_PAD(0x410, 0x130, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D1__SDMA_DEBUG_PC_1 IOMUX_PAD(0x410, 0x130, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D1__USBPHY1_VSTATUS_1 IOMUX_PAD(0x410, 0x130, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D2__ELCDIF_DAT_2 IOMUX_PAD(0x414, 0x134, 0, 0x704, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D2__GPIO2_2 IOMUX_PAD(0x414, 0x134, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D2__FEC_RX_DV IOMUX_PAD(0x414, 0x134, 2, 0x784, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D2__EIM_WEIM_A_18 IOMUX_PAD(0x414, 0x134, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D2__SDMA_DEBUG_PC_2 IOMUX_PAD(0x414, 0x134, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D2__USBPHY1_VSTATUS_2 IOMUX_PAD(0x414, 0x134, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D3__ELCDIF_DAT_3 IOMUX_PAD(0x418, 0x138, 0, 0x708, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D3__GPIO2_3 IOMUX_PAD(0x418, 0x138, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D3__FEC_RDATA_1 IOMUX_PAD(0x418, 0x138, 2, 0x77C, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D3__EIM_WEIM_A_19 IOMUX_PAD(0x418, 0x138, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D3__FEC_COL IOMUX_PAD(0x418, 0x138, 4, 0x770, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D3__SDMA_DEBUG_PC_3 IOMUX_PAD(0x418, 0x138, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D3__USBPHY1_VSTATUS_3 IOMUX_PAD(0x418, 0x138, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D4__ELCDIF_DAT_4 IOMUX_PAD(0x41C, 0x13C, 0, 0x70C, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D4__GPIO2_4 IOMUX_PAD(0x41C, 0x13C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D4__FEC_RDATA_0 IOMUX_PAD(0x41C, 0x13C, 2, 0x778, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D4__EIM_WEIM_A_20 IOMUX_PAD(0x41C, 0x13C, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D4__SDMA_DEBUG_PC_4 IOMUX_PAD(0x41C, 0x13C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D4__USBPHY1_VSTATUS_4 IOMUX_PAD(0x41C, 0x13C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D5__ELCDIF_DAT_5 IOMUX_PAD(0x420, 0x140, 0, 0x710, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D5__GPIO2_5 IOMUX_PAD(0x420, 0x140, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D5__FEC_TX_EN IOMUX_PAD(0x420, 0x140, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D5__EIM_WEIM_A_21 IOMUX_PAD(0x420, 0x140, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D5__SDMA_DEBUG_PC_5 IOMUX_PAD(0x420, 0x140, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D5__USBPHY1_VSTATUS_5 IOMUX_PAD(0x420, 0x140, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D6__ELCDIF_DAT_6 IOMUX_PAD(0x424, 0x144, 0, 0x714, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D6__GPIO2_6 IOMUX_PAD(0x424, 0x144, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D6__FEC_TDATA_1 IOMUX_PAD(0x424, 0x144, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D6__EIM_WEIM_A_22 IOMUX_PAD(0x424, 0x144, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D6__FEC_RX_CLK IOMUX_PAD(0x424, 0x144, 4, 0x780, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D6__SDMA_DEBUG_PC_6 IOMUX_PAD(0x424, 0x144, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D6__USBPHY1_VSTATUS_6 IOMUX_PAD(0x424, 0x144, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D7__ELCDIF_DAT_7 IOMUX_PAD(0x428, 0x148, 0, 0x718, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D7__GPIO2_7 IOMUX_PAD(0x428, 0x148, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D7__FEC_TDATA_0 IOMUX_PAD(0x428, 0x148, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D7__EIM_WEIM_A_23 IOMUX_PAD(0x428, 0x148, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D7__SDMA_DEBUG_PC_7 IOMUX_PAD(0x428, 0x148, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D7__USBPHY1_VSTATUS_7 IOMUX_PAD(0x428, 0x148, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_WR__ELCDIF_WR_RWN IOMUX_PAD(0x42C, 0x14C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_WR__GPIO2_16 IOMUX_PAD(0x42C, 0x14C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_WR__ELCDIF_DOTCLK IOMUX_PAD(0x42C, 0x14C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_WR__EIM_WEIM_A_24 IOMUX_PAD(0x42C, 0x14C, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_WR__SDMA_DEBUG_PC_8 IOMUX_PAD(0x42C, 0x14C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_WR__USBPHY1_AVALID IOMUX_PAD(0x42C, 0x14C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RD__ELCDIF_RD_E IOMUX_PAD(0x430, 0x150, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RD__GPIO2_19 IOMUX_PAD(0x430, 0x150, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RD__ELCDIF_ENABLE IOMUX_PAD(0x430, 0x150, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RD__EIM_WEIM_A_25 IOMUX_PAD(0x430, 0x150, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RD__SDMA_DEBUG_PC_9 IOMUX_PAD(0x430, 0x150, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RD__USBPHY1_BVALID IOMUX_PAD(0x430, 0x150, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RS__ELCDIF_RS IOMUX_PAD(0x434, 0x154, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RS__GPIO2_17 IOMUX_PAD(0x434, 0x154, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RS__ELCDIF_VSYNC IOMUX_PAD(0x434, 0x154, 2, 0x73C, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_RS__EIM_WEIM_A_26 IOMUX_PAD(0x434, 0x154, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RS__SDMA_DEBUG_PC_10 IOMUX_PAD(0x434, 0x154, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RS__USBPHY1_ENDSESSION IOMUX_PAD(0x434, 0x154, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_CS__ELCDIF_CS IOMUX_PAD(0x438, 0x158, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_CS__GPIO2_21 IOMUX_PAD(0x438, 0x158, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_CS__ELCDIF_HSYNC IOMUX_PAD(0x438, 0x158, 2, 0x6F8, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_CS__EIM_WEIM_A_27 IOMUX_PAD(0x438, 0x158, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_CS__EIM_WEIM_CS_3 IOMUX_PAD(0x438, 0x158, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_CS__SDMA_DEBUG_PC_11 IOMUX_PAD(0x438, 0x158, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_CS__USBPHY1_IDDIG IOMUX_PAD(0x438, 0x158, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_BUSY__ELCDIF_BUSY IOMUX_PAD(0x43C, 0x15C, 0, 0x6F8, 2, NO_PAD_CTRL) +#define MX50_PAD_DISP_BUSY__GPIO2_18 IOMUX_PAD(0x43C, 0x15C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_BUSY__EIM_WEIM_CS_3 IOMUX_PAD(0x43C, 0x15C, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_BUSY__SDMA_DEBUG_PC_12 IOMUX_PAD(0x43C, 0x15C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_BUSY__USBPHY2_HOSTDISCONNECT IOMUX_PAD(0x43C, 0x15C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RESET__ELCDIF_RESET IOMUX_PAD(0x440, 0x160, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RESET__GPIO2_20 IOMUX_PAD(0x440, 0x160, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RESET__EIM_WEIM_CS_3 IOMUX_PAD(0x440, 0x160, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RESET__SDMA_DEBUG_PC_13 IOMUX_PAD(0x440, 0x160, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_RESET__USBPHY2_BISTOK IOMUX_PAD(0x440, 0x160, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_CMD__ESDHC3_CMD IOMUX_PAD(0x444, 0x164, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_CMD__GPIO5_18 IOMUX_PAD(0x444, 0x164, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_CMD__EIM_NANDF_WRN IOMUX_PAD(0x444, 0x164, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_CMD__SSP_CMD IOMUX_PAD(0x444, 0x164, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_CLK__ESDHC3_CLK IOMUX_PAD(0x448, 0x168, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_CLK__GPIO5_19 IOMUX_PAD(0x448, 0x168, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_CLK__EIM_NANDF_RDN IOMUX_PAD(0x448, 0x168, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_CLK__SSP_CLK IOMUX_PAD(0x448, 0x168, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D0__ESDHC3_DAT0 IOMUX_PAD(0x44C, 0x16C, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_D0__GPIO5_20 IOMUX_PAD(0x44C, 0x16C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D0__EIM_NANDF_D_4 IOMUX_PAD(0x44C, 0x16C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D0__SSP_D0 IOMUX_PAD(0x44C, 0x16C, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D0__CCM_PLL1_BYP IOMUX_PAD(0x44C, 0x16C, 7, 0x6DC, 1, NO_PAD_CTRL) +#define MX50_PAD_SD3_D1__ESDHC3_DAT1 IOMUX_PAD(0x450, 0x170, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_D1__GPIO5_21 IOMUX_PAD(0x450, 0x170, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D1__EIM_NANDF_D_5 IOMUX_PAD(0x450, 0x170, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D1__SSP_D1 IOMUX_PAD(0x450, 0x170, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D1__CCM_PLL2_BYP IOMUX_PAD(0x450, 0x170, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D2__ESDHC3_DAT2 IOMUX_PAD(0x454, 0x174, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_D2__GPIO5_22 IOMUX_PAD(0x454, 0x174, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D2__EIM_NANDF_D_6 IOMUX_PAD(0x454, 0x174, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D2__SSP_D2 IOMUX_PAD(0x454, 0x174, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D2__CCM_PLL3_BYP IOMUX_PAD(0x454, 0x174, 7, 0x6E4, 1, NO_PAD_CTRL) +#define MX50_PAD_SD3_D3__ESDHC3_DAT3 IOMUX_PAD(0x458, 0x178, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_D3__GPIO5_23 IOMUX_PAD(0x458, 0x178, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D3__EIM_NANDF_D_7 IOMUX_PAD(0x458, 0x178, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D3__SSP_D3 IOMUX_PAD(0x458, 0x178, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D4__ESDHC3_DAT4 IOMUX_PAD(0x45C, 0x17C, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_D4__GPIO5_24 IOMUX_PAD(0x45C, 0x17C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D4__EIM_NANDF_D_0 IOMUX_PAD(0x45C, 0x17C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D4__SSP_D4 IOMUX_PAD(0x45C, 0x17C, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D5__ESDHC3_DAT5 IOMUX_PAD(0x460, 0x180, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_D5__GPIO5_25 IOMUX_PAD(0x460, 0x180, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D5__EIM_NANDF_D_1 IOMUX_PAD(0x460, 0x180, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D5__SSP_D5 IOMUX_PAD(0x460, 0x180, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D6__ESDHC3_DAT6 IOMUX_PAD(0x464, 0x184, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_D6__GPIO5_26 IOMUX_PAD(0x464, 0x184, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D6__EIM_NANDF_D_2 IOMUX_PAD(0x464, 0x184, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D6__SSP_D6 IOMUX_PAD(0x464, 0x184, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D7__ESDHC3_DAT7 IOMUX_PAD(0x468, 0x188, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_D7__GPIO5_27 IOMUX_PAD(0x468, 0x188, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D7__EIM_NANDF_D_3 IOMUX_PAD(0x468, 0x188, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_D7__SSP_D7 IOMUX_PAD(0x468, 0x188, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_WP__ESDHC3_WP IOMUX_PAD(0x46C, 0x18C, 0, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_WP__GPIO5_28 IOMUX_PAD(0x46C, 0x18C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_WP__EIM_NANDF_RESETN IOMUX_PAD(0x46C, 0x18C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_WP__SSP_CD IOMUX_PAD(0x46C, 0x18C, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_SD3_WP__ESDHC4_LCTL IOMUX_PAD(0x46C, 0x18C, 4, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_SD3_WP__EIM_WEIM_CS_3 IOMUX_PAD(0x46C, 0x18C, 5, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D8__ELCDIF_DAT_8 IOMUX_PAD(0x470, 0x190, 0, 0x71C, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D8__GPIO2_8 IOMUX_PAD(0x470, 0x190, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D8__EIM_NANDF_CLE IOMUX_PAD(0x470, 0x190, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D8__ESDHC1_LCTL IOMUX_PAD(0x470, 0x190, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D8__ESDHC4_CMD IOMUX_PAD(0x470, 0x190, 4, 0x74C, 2, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D8__KPP_COL_4 IOMUX_PAD(0x470, 0x190, 5, 0x790, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D8__FEC_TX_CLK IOMUX_PAD(0x470, 0x190, 6, 0x78C, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D8__USBPHY1_DATAOUT_0 IOMUX_PAD(0x470, 0x190, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D9__ELCDIF_DAT_9 IOMUX_PAD(0x474, 0x194, 0, 0x720, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D9__GPIO2_9 IOMUX_PAD(0x474, 0x194, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D9__EIM_NANDF_ALE IOMUX_PAD(0x474, 0x194, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D9__ESDHC2_LCTL IOMUX_PAD(0x474, 0x194, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D9__ESDHC4_CLK IOMUX_PAD(0x474, 0x194, 4, 0x748, 2, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D9__KPP_ROW_4 IOMUX_PAD(0x474, 0x194, 5, 0x7A0, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D9__FEC_RX_ER IOMUX_PAD(0x474, 0x194, 6, 0x788, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D9__USBPHY1_DATAOUT_1 IOMUX_PAD(0x474, 0x194, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D10__ELCDIF_DAT_10 IOMUX_PAD(0x478, 0x198, 0, 0x724, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D10__GPIO2_10 IOMUX_PAD(0x478, 0x198, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D10__EIM_NANDF_CEN_0 IOMUX_PAD(0x478, 0x198, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D10__ESDHC3_LCTL IOMUX_PAD(0x478, 0x198, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D10__ESDHC4_DAT0 IOMUX_PAD(0x478, 0x198, 4, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D10__KPP_COL_5 IOMUX_PAD(0x478, 0x198, 5, 0x794, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D10__FEC_RX_DV IOMUX_PAD(0x478, 0x198, 6, 0x784, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D10__USBPHY1_DATAOUT_2 IOMUX_PAD(0x478, 0x198, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D11__ELCDIF_DAT_11 IOMUX_PAD(0x47C, 0x19C, 0, 0x728, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D11__GPIO2_11 IOMUX_PAD(0x47C, 0x19C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D11__EIM_NANDF_CEN_1 IOMUX_PAD(0x47C, 0x19C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D11__ESDHC4_DAT1 IOMUX_PAD(0x47C, 0x19C, 4, 0x754, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D11__KPP_ROW_5 IOMUX_PAD(0x47C, 0x19C, 5, 0x7A4, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D11__FEC_RDATA_1 IOMUX_PAD(0x47C, 0x19C, 6, 0x77C, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D11__USBPHY1_DATAOUT_3 IOMUX_PAD(0x47C, 0x19C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D12__ELCDIF_DAT_12 IOMUX_PAD(0x480, 0x1A0, 0, 0x72C, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D12__GPIO2_12 IOMUX_PAD(0x480, 0x1A0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D12__EIM_NANDF_CEN_2 IOMUX_PAD(0x480, 0x1A0, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D12__ESDHC1_CD IOMUX_PAD(0x480, 0x1A0, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D12__ESDHC4_DAT2 IOMUX_PAD(0x480, 0x1A0, 4, 0x758, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D12__KPP_COL_6 IOMUX_PAD(0x480, 0x1A0, 5, 0x798, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D12__FEC_RDATA_0 IOMUX_PAD(0x480, 0x1A0, 6, 0x778, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D12__USBPHY1_DATAOUT_4 IOMUX_PAD(0x480, 0x1A0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D13__ELCDIF_DAT_13 IOMUX_PAD(0x484, 0x1A4, 0, 0x730, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D13__GPIO2_13 IOMUX_PAD(0x484, 0x1A4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D13__EIM_NANDF_CEN_3 IOMUX_PAD(0x484, 0x1A4, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D13__ESDHC3_CD IOMUX_PAD(0x484, 0x1A4, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D13__ESDHC4_DAT3 IOMUX_PAD(0x484, 0x1A4, 4, 0x75C, 1, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D13__KPP_ROW_6 IOMUX_PAD(0x484, 0x1A4, 5, 0x7A8, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D13__FEC_TX_EN IOMUX_PAD(0x484, 0x1A4, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D13__USBPHY1_DATAOUT_5 IOMUX_PAD(0x484, 0x1A4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D14__ELCDIF_DAT_14 IOMUX_PAD(0x488, 0x1A8, 0, 0x734, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D14__GPIO2_14 IOMUX_PAD(0x488, 0x1A8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D14__EIM_NANDF_READY0 IOMUX_PAD(0x488, 0x1A8, 2, 0x7B4, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D14__ESDHC1_WP IOMUX_PAD(0x488, 0x1A8, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D14__ESDHC4_WP IOMUX_PAD(0x488, 0x1A8, 4, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D14__KPP_COL_7 IOMUX_PAD(0x488, 0x1A8, 5, 0x79C, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D14__FEC_TDATA_1 IOMUX_PAD(0x488, 0x1A8, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D14__USBPHY1_DATAOUT_6 IOMUX_PAD(0x488, 0x1A8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D15__ELCDIF_DAT_15 IOMUX_PAD(0x48C, 0x1AC, 0, 0x738, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D15__GPIO2_15 IOMUX_PAD(0x48C, 0x1AC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D15__EIM_NANDF_DQS IOMUX_PAD(0x48C, 0x1AC, 2, 0x7B0, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D15__ESDHC3_RST IOMUX_PAD(0x48C, 0x1AC, 3, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D15__ESDHC4_CD IOMUX_PAD(0x48C, 0x1AC, 4, __NA_, 0, MX50_SDHC_PAD_CTRL) +#define MX50_PAD_DISP_D15__KPP_ROW_7 IOMUX_PAD(0x48C, 0x1AC, 5, 0x7AC, 1, NO_PAD_CTRL) +#define MX50_PAD_DISP_D15__FEC_TDATA_0 IOMUX_PAD(0x48C, 0x1AC, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_DISP_D15__USBPHY1_DATAOUT_7 IOMUX_PAD(0x48C, 0x1AC, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D0__EPDC_SDDO_0 IOMUX_PAD(0x54C, 0x1B0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D0__GPIO3_0 IOMUX_PAD(0x54C, 0x1B0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D0__EIM_WEIM_D_0 IOMUX_PAD(0x54C, 0x1B0, 2, 0x7EC, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D0__ELCDIF_RS IOMUX_PAD(0x54C, 0x1B0, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D0__ELCDIF_DOTCLK IOMUX_PAD(0x54C, 0x1B0, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D0__SDMA_DEBUG_EVT_CHN_LINES_0 IOMUX_PAD(0x54C, 0x1B0, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D0__USBPHY2_DATAOUT_0 IOMUX_PAD(0x54C, 0x1B0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D1__EPDC_SDDO_1 IOMUX_PAD(0x550, 0x1B4, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D1__GPIO3_1 IOMUX_PAD(0x550, 0x1B4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D1__EIM_WEIM_D_1 IOMUX_PAD(0x550, 0x1B4, 2, 0x7F0, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D1__ELCDIF_CS IOMUX_PAD(0x550, 0x1B4, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D1__ELCDIF_ENABLE IOMUX_PAD(0x550, 0x1B4, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D1__SDMA_DEBUG_EVT_CHN_LINES_1 IOMUX_PAD(0x550, 0x1B4, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D1__USBPHY2_DATAOUT_1 IOMUX_PAD(0x550, 0x1B4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D2__EPDC_SDDO_2 IOMUX_PAD(0x554, 0x1B8, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D2__GPIO3_2 IOMUX_PAD(0x554, 0x1B8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D2__EIM_WEIM_D_2 IOMUX_PAD(0x554, 0x1B8, 2, 0x7F4, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D2__ELCDIF_WR_RWN IOMUX_PAD(0x554, 0x1B8, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D2__ELCDIF_VSYNC IOMUX_PAD(0x554, 0x1B8, 4, 0x73C, 2, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D2__SDMA_DEBUG_EVT_CHN_LINES_2 IOMUX_PAD(0x554, 0x1B8, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D2__USBPHY2_DATAOUT_2 IOMUX_PAD(0x554, 0x1B8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D3__EPDC_SDDO_3 IOMUX_PAD(0x558, 0x1BC, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D3__GPIO3_3 IOMUX_PAD(0x558, 0x1BC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D3__EIM_WEIM_D_3 IOMUX_PAD(0x558, 0x1BC, 2, 0x7F8, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D3__ELCDIF_RD_E IOMUX_PAD(0x558, 0x1BC, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D3__ELCDIF_HSYNC IOMUX_PAD(0x558, 0x1BC, 4, 0x6F8, 3, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D3__SDMA_DEBUG_EVT_CHN_LINES_3 IOMUX_PAD(0x558, 0x1BC, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D3__USBPHY2_DATAOUT_3 IOMUX_PAD(0x558, 0x1BC, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D4__EPDC_SDDO_4 IOMUX_PAD(0x55C, 0x1C0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D4__GPIO3_4 IOMUX_PAD(0x55C, 0x1C0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D4__EIM_WEIM_D_4 IOMUX_PAD(0x55C, 0x1C0, 2, 0x7FC, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D4__SDMA_DEBUG_EVT_CHN_LINES_4 IOMUX_PAD(0x55C, 0x1C0, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D4__USBPHY2_DATAOUT_4 IOMUX_PAD(0x55C, 0x1C0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D5__EPDC_SDDO_5 IOMUX_PAD(0x560, 0x1C4, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D5__GPIO3_5 IOMUX_PAD(0x560, 0x1C4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D5__EIM_WEIM_D_5 IOMUX_PAD(0x560, 0x1C4, 2, 0x800, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D5__SDMA_DEBUG_EVT_CHN_LINES_5 IOMUX_PAD(0x560, 0x1C4, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D5__USBPHY2_DATAOUT_5 IOMUX_PAD(0x560, 0x1C4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D6__EPDC_SDDO_6 IOMUX_PAD(0x564, 0x1C8, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D6__GPIO3_6 IOMUX_PAD(0x564, 0x1C8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D6__EIM_WEIM_D_6 IOMUX_PAD(0x564, 0x1C8, 2, 0x804, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D6__SDMA_DEBUG_EVT_CHN_LINES_6 IOMUX_PAD(0x564, 0x1C8, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D6__USBPHY2_DATAOUT_6 IOMUX_PAD(0x564, 0x1C8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D7__EPDC_SDDO_7 IOMUX_PAD(0x568, 0x1CC, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D7__GPIO3_7 IOMUX_PAD(0x568, 0x1CC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D7__EIM_WEIM_D_7 IOMUX_PAD(0x568, 0x1CC, 2, 0x808, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D7__SDMA_DEBUG_EVT_CHN_LINES_7 IOMUX_PAD(0x568, 0x1CC, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D7__USBPHY2_DATAOUT_7 IOMUX_PAD(0x568, 0x1CC, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D8__EPDC_SDDO_8 IOMUX_PAD(0x56C, 0x1D0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D8__GPIO3_8 IOMUX_PAD(0x56C, 0x1D0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D8__EIM_WEIM_D_8 IOMUX_PAD(0x56C, 0x1D0, 2, 0x80C, 2, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D8__ELCDIF_DAT_24 IOMUX_PAD(0x56C, 0x1D0, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D8__SDMA_DEBUG_MATCHED_DMBUS IOMUX_PAD(0x56C, 0x1D0, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D8__USBPHY2_VSTATUS_0 IOMUX_PAD(0x56C, 0x1D0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D9__EPDC_SDDO_9 IOMUX_PAD(0x570, 0x1D4, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D9__GPIO3_9 IOMUX_PAD(0x570, 0x1D4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D9__EIM_WEIM_D_9 IOMUX_PAD(0x570, 0x1D4, 2, 0x810, 2, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D9__ELCDIF_DAT_25 IOMUX_PAD(0x570, 0x1D4, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D9__SDMA_DEBUG_EVENT_CHANNEL_SEL IOMUX_PAD(0x570, 0x1D4, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D9__USBPHY2_VSTATUS_1 IOMUX_PAD(0x570, 0x1D4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D10__EPDC_SDDO_10 IOMUX_PAD(0x574, 0x1D8, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D10__GPIO3_10 IOMUX_PAD(0x574, 0x1D8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D10__EIM_WEIM_D_10 IOMUX_PAD(0x574, 0x1D8, 2, 0x814, 2, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D10__ELCDIF_DAT_26 IOMUX_PAD(0x574, 0x1D8, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D10__SDMA_DEBUG_EVENT_CHANNEL_0 IOMUX_PAD(0x574, 0x1D8, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D10__USBPHY2_VSTATUS_2 IOMUX_PAD(0x574, 0x1D8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D11__EPDC_SDDO_11 IOMUX_PAD(0x578, 0x1DC, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D11__GPIO3_11 IOMUX_PAD(0x578, 0x1DC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D11__EIM_WEIM_D_11 IOMUX_PAD(0x578, 0x1DC, 2, 0x818, 2, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D11__ELCDIF_DAT_27 IOMUX_PAD(0x578, 0x1DC, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D11__SDMA_DEBUG_EVENT_CHANNEL_1 IOMUX_PAD(0x578, 0x1DC, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D11__USBPHY2_VSTATUS_3 IOMUX_PAD(0x578, 0x1DC, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D12__EPDC_SDDO_12 IOMUX_PAD(0x57C, 0x1E0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D12__GPIO3_12 IOMUX_PAD(0x57C, 0x1E0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D12__EIM_WEIM_D_12 IOMUX_PAD(0x57C, 0x1E0, 2, 0x81C, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D12__ELCDIF_DAT_28 IOMUX_PAD(0x57C, 0x1E0, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D12__SDMA_DEBUG_EVENT_CHANNEL_2 IOMUX_PAD(0x57C, 0x1E0, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D12__USBPHY2_VSTATUS_4 IOMUX_PAD(0x57C, 0x1E0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D13__EPDC_SDDO_13 IOMUX_PAD(0x580, 0x1E4, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D13__GPIO3_13 IOMUX_PAD(0x580, 0x1E4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D13__EIM_WEIM_D_13 IOMUX_PAD(0x580, 0x1E4, 2, 0x820, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D13__ELCDIF_DAT_29 IOMUX_PAD(0x580, 0x1E4, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D13__SDMA_DEBUG_EVENT_CHANNEL_3 IOMUX_PAD(0x580, 0x1E4, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D13__USBPHY2_VSTATUS_5 IOMUX_PAD(0x580, 0x1E4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D14__EPDC_SDDO_14 IOMUX_PAD(0x584, 0x1E8, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D14__GPIO3_14 IOMUX_PAD(0x584, 0x1E8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D14__EIM_WEIM_D_14 IOMUX_PAD(0x584, 0x1E8, 2, 0x824, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D14__ELCDIF_DAT_30 IOMUX_PAD(0x584, 0x1E8, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D14__AUDMUX_AUD6_TXD IOMUX_PAD(0x584, 0x1E8, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D14__SDMA_DEBUG_EVENT_CHANNEL_4 IOMUX_PAD(0x584, 0x1E8, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D14__USBPHY2_VSTATUS_6 IOMUX_PAD(0x584, 0x1E8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D15__EPDC_SDDO_15 IOMUX_PAD(0x588, 0x1EC, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D15__GPIO3_15 IOMUX_PAD(0x588, 0x1EC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D15__EIM_WEIM_D_15 IOMUX_PAD(0x588, 0x1EC, 2, 0x828, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D15__ELCDIF_DAT_31 IOMUX_PAD(0x588, 0x1EC, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D15__AUDMUX_AUD6_TXC IOMUX_PAD(0x588, 0x1EC, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D15__SDMA_DEBUG_EVENT_CHANNEL_5 IOMUX_PAD(0x588, 0x1EC, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_D15__USBPHY2_VSTATUS_7 IOMUX_PAD(0x588, 0x1EC, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDCLK__EPDC_GDCLK IOMUX_PAD(0x58C, 0x1F0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDCLK__GPIO3_16 IOMUX_PAD(0x58C, 0x1F0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDCLK__EIM_WEIM_D_16 IOMUX_PAD(0x58C, 0x1F0, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDCLK__ELCDIF_DAT_16 IOMUX_PAD(0x58C, 0x1F0, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDCLK__AUDMUX_AUD6_TXFS IOMUX_PAD(0x58C, 0x1F0, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDCLK__SDMA_DEBUG_CORE_STATE_0 IOMUX_PAD(0x58C, 0x1F0, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDCLK__USBPHY2_BISTOK IOMUX_PAD(0x58C, 0x1F0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDSP__EPCD_GDSP IOMUX_PAD(0x590, 0x1F4, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDSP__GPIO3_17 IOMUX_PAD(0x590, 0x1F4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDSP__EIM_WEIM_D_17 IOMUX_PAD(0x590, 0x1F4, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDSP__ELCDIF_DAT_17 IOMUX_PAD(0x590, 0x1F4, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDSP__AUDMUX_AUD6_RXD IOMUX_PAD(0x590, 0x1F4, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDSP__SDMA_DEBUG_CORE_STATE_1 IOMUX_PAD(0x590, 0x1F4, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDSP__USBPHY2_BVALID IOMUX_PAD(0x590, 0x1F4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDOE__EPCD_GDOE IOMUX_PAD(0x594, 0x1F8, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDOE__GPIO3_18 IOMUX_PAD(0x594, 0x1F8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDOE__EIM_WEIM_D_18 IOMUX_PAD(0x594, 0x1F8, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDOE__ELCDIF_DAT_18 IOMUX_PAD(0x594, 0x1F8, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDOE__AUDMUX_AUD6_RXC IOMUX_PAD(0x594, 0x1F8, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDOE__SDMA_DEBUG_CORE_STATE_2 IOMUX_PAD(0x594, 0x1F8, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDOE__USBPHY2_ENDSESSION IOMUX_PAD(0x594, 0x1F8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDRL__EPCD_GDRL IOMUX_PAD(0x598, 0x1FC, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDRL__GPIO3_19 IOMUX_PAD(0x598, 0x1FC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDRL__EIM_WEIM_D_19 IOMUX_PAD(0x598, 0x1F8, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDRL__ELCDIF_DAT_19 IOMUX_PAD(0x598, 0x1FC, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDRL__AUDMUX_AUD6_RXFS IOMUX_PAD(0x598, 0x1FC, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDRL__SDMA_DEBUG_CORE_STATE_3 IOMUX_PAD(0x598, 0x1FC, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_GDRL__USBPHY2_IDDIG IOMUX_PAD(0x598, 0x1FC, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLK__EPCD_SDCLK IOMUX_PAD(0x59C, 0x200, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLK__GPIO3_20 IOMUX_PAD(0x59C, 0x200, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLK__EIM_WEIM_D_20 IOMUX_PAD(0x59C, 0x200, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLK__ELCDIF_DAT_20 IOMUX_PAD(0x59C, 0x200, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLK__AUDMUX_AUD5_TXD IOMUX_PAD(0x59C, 0x200, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLK__SDMA_DEBUG_BUS_DEVICE_0 IOMUX_PAD(0x59C, 0x200, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLK__USBPHY2_HOSTDISCONNECT IOMUX_PAD(0x59C, 0x200, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOEZ__EPCD_SDOEZ IOMUX_PAD(0x5A0, 0x204, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOEZ__GPIO3_21 IOMUX_PAD(0x5A0, 0x204, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOEZ__EIM_WEIM_D_21 IOMUX_PAD(0x5A0, 0x204, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOEZ__ELCDIF_DAT_21 IOMUX_PAD(0x5A0, 0x204, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOEZ__AUDMUX_AUD5_TXC IOMUX_PAD(0x5A0, 0x204, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOEZ__SDMA_DEBUG_BUS_DEVICE_1 IOMUX_PAD(0x5A0, 0x204, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOEZ__USBPHY2_TXREADY IOMUX_PAD(0x5A0, 0x204, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOED__EPCD_SDOED IOMUX_PAD(0x5A4, 0x208, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOED__GPIO3_22 IOMUX_PAD(0x5A4, 0x208, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOED__EIM_WEIM_D_22 IOMUX_PAD(0x5A4, 0x208, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOED__ELCDIF_DAT_22 IOMUX_PAD(0x5A4, 0x208, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOED__AUDMUX_AUD5_TXFS IOMUX_PAD(0x5A4, 0x208, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOED__SDMA_DEBUG_BUS_DEVICE_2 IOMUX_PAD(0x5A4, 0x208, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOED__USBPHY2_RXVALID IOMUX_PAD(0x5A4, 0x208, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOE__EPCD_SDOE IOMUX_PAD(0x5A8, 0x20C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOE__GPIO3_23 IOMUX_PAD(0x5A8, 0x20C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOE__EIM_WEIM_D_23 IOMUX_PAD(0x5A8, 0x20C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOE__ELCDIF_DAT_23 IOMUX_PAD(0x5A8, 0x20C, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOE__AUDMUX_AUD5_RXD IOMUX_PAD(0x5A8, 0x20C, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOE__SDMA_DEBUG_BUS_DEVICE_3 IOMUX_PAD(0x5A8, 0x20C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDOE__USBPHY2_RXACTIVE IOMUX_PAD(0x5A8, 0x20C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDLE__EPCD_SDLE IOMUX_PAD(0x5AC, 0x210, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDLE__GPIO3_24 IOMUX_PAD(0x5AC, 0x210, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDLE__EIM_WEIM_D_24 IOMUX_PAD(0x5AC, 0x210, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDLE__ELCDIF_DAT_8 IOMUX_PAD(0x5AC, 0x210, 3, 0x71C, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDLE__AUDMUX_AUD5_RXC IOMUX_PAD(0x5AC, 0x210, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDLE__SDMA_DEBUG_BUS_DEVICE_4 IOMUX_PAD(0x5AC, 0x210, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDLE__USBPHY2_RXERROR IOMUX_PAD(0x5AC, 0x210, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLKN__EPCD_SDCLKN IOMUX_PAD(0x5B0, 0x214, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLKN__GPIO3_25 IOMUX_PAD(0x5B0, 0x214, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLKN__EIM_WEIM_D_25 IOMUX_PAD(0x5B0, 0x214, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLKN__ELCDIF_DAT_9 IOMUX_PAD(0x5B0, 0x214, 3, 0x720, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLKN__AUDMUX_AUD5_RXFS IOMUX_PAD(0x5B0, 0x214, 4, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLKN__SDMA_DEBUG_BUS_ERROR IOMUX_PAD(0x5B0, 0x214, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCLKN__USBPHY2_SIECLOCK IOMUX_PAD(0x5B0, 0x214, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDSHR__EPCD_SDSHR IOMUX_PAD(0x5B4, 0x218, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDSHR__GPIO3_26 IOMUX_PAD(0x5B4, 0x218, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDSHR__EIM_WEIM_D_26 IOMUX_PAD(0x5B4, 0x218, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDSHR__ELCDIF_DAT_10 IOMUX_PAD(0x5B4, 0x218, 3, 0x724, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDSHR__AUDMUX_AUD4_TXD IOMUX_PAD(0x5B4, 0x218, 4, 0x6C8, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDSHR__SDMA_DEBUG_BUS_RWB IOMUX_PAD(0x5B4, 0x218, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDSHR__USBPHY2_LINESTATE_0 IOMUX_PAD(0x5B4, 0x218, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCOM__EPCD_PWRCOM IOMUX_PAD(0x5B8, 0x21C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCOM__GPIO3_27 IOMUX_PAD(0x5B8, 0x21C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCOM__EIM_WEIM_D_27 IOMUX_PAD(0x5B8, 0x21C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCOM__ELCDIF_DAT_11 IOMUX_PAD(0x5B8, 0x21C, 3, 0x728, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCOM__AUDMUX_AUD4_TXC IOMUX_PAD(0x5B8, 0x21C, 4, 0x6D4, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCOM__SDMA_DEBUG_CORE_RUN IOMUX_PAD(0x5B8, 0x21C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCOM__USBPHY2_LINESTATE_1 IOMUX_PAD(0x5B8, 0x21C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRSTAT__EPCD_PWRSTAT IOMUX_PAD(0x5BC, 0x220, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRSTAT__GPIO3_28 IOMUX_PAD(0x5BC, 0x220, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRSTAT__EIM_WEIM_D_28 IOMUX_PAD(0x5BC, 0x220, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRSTAT__ELCDIF_DAT_12 IOMUX_PAD(0x5BC, 0x220, 3, 0x72C, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRSTAT__AUDMUX_AUD4_TXFS IOMUX_PAD(0x5BC, 0x220, 4, 0x6D8, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRSTAT__SDMA_DEBUG_MODE IOMUX_PAD(0x5BC, 0x220, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRSTAT__USBPHY2_VBUSVALID IOMUX_PAD(0x5BC, 0x220, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL0__EPCD_PWRCTRL0 IOMUX_PAD(0x5C0, 0x224, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL0__GPIO3_29 IOMUX_PAD(0x5C0, 0x224, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL0__EIM_WEIM_D_29 IOMUX_PAD(0x5C0, 0x224, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL0__ELCDIF_DAT_13 IOMUX_PAD(0x5C0, 0x224, 3, 0x730, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL0__AUDMUX_AUD4_RXD IOMUX_PAD(0x5C0, 0x224, 4, 0x6C4, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL0__SDMA_DEBUG_RTBUFFER_WRITE IOMUX_PAD(0x5C0, 0x224, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL0__USBPHY2_AVALID IOMUX_PAD(0x5C0, 0x224, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL1__EPCD_PWRCTRL1 IOMUX_PAD(0x5C4, 0x228, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL1__GPIO3_30 IOMUX_PAD(0x5C4, 0x228, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL1__EIM_WEIM_D_30 IOMUX_PAD(0x5C4, 0x228, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL1__ELCDIF_DAT_14 IOMUX_PAD(0x5C4, 0x228, 3, 0x734, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL1__AUDMUX_AUD4_RXC IOMUX_PAD(0x5C4, 0x228, 4, 0x6CC, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL1__SDMA_DEBUG_YIELD IOMUX_PAD(0x5C4, 0x228, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL1__USBPHY1_ONBIST IOMUX_PAD(0x5C4, 0x228, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL2__EPCD_PWRCTRL2 IOMUX_PAD(0x5C8, 0x22C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL2__GPIO3_31 IOMUX_PAD(0x5C8, 0x22C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL2__EIM_WEIM_D_31 IOMUX_PAD(0x5C8, 0x22C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL2__ELCDIF_DAT_15 IOMUX_PAD(0x5C8, 0x22C, 3, 0x738, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL2__AUDMUX_AUD4_RXFS IOMUX_PAD(0x5C8, 0x22C, 4, 0x6D0, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL2__SDMA_EXT_EVENT_0 IOMUX_PAD(0x5C8, 0x22C, 6, 0x7B8, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL2__USBPHY2_ONBIST IOMUX_PAD(0x5C8, 0x22C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL3__EPCD_PWRCTRL3 IOMUX_PAD(0x5CC, 0x230, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL3__GPIO4_20 IOMUX_PAD(0x5CC, 0x230, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL3__EIM_WEIM_EB_2 IOMUX_PAD(0x5CC, 0x230, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL3__SDMA_EXT_EVENT_1 IOMUX_PAD(0x5CC, 0x230, 6, 0x7BC, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_PWRCTRL3__USBPHY1_BISTOK IOMUX_PAD(0x5CC, 0x230, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_VCOM0__EPCD_VCOM_0 IOMUX_PAD(0x5D0, 0x234, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_VCOM0__GPIO4_21 IOMUX_PAD(0x5D0, 0x234, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_VCOM0__EIM_WEIM_EB_3 IOMUX_PAD(0x5D0, 0x234, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_VCOM0__USBPHY2_BISTOK IOMUX_PAD(0x5D0, 0x234, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_VCOM1__EPCD_VCOM_1 IOMUX_PAD(0x5D4, 0x238, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_VCOM1__GPIO4_22 IOMUX_PAD(0x5D4, 0x238, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_VCOM1__EIM_WEIM_CS_3 IOMUX_PAD(0x5D4, 0x238, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_BDR0__EPCD_BDR_0 IOMUX_PAD(0x5D8, 0x23C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_BDR0__GPIO4_23 IOMUX_PAD(0x5D8, 0x23C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_BDR0__ELCDIF_DAT_7 IOMUX_PAD(0x5D8, 0x23C, 3, 0x718, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_BDR1__EPCD_BDR_1 IOMUX_PAD(0x5DC, 0x240, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_BDR1__GPIO4_24 IOMUX_PAD(0x5DC, 0x240, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_BDR1__ELCDIF_DAT_6 IOMUX_PAD(0x5DC, 0x240, 3, 0x714, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE0__EPCD_SDCE_0 IOMUX_PAD(0x5E0, 0x244, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE0__GPIO4_25 IOMUX_PAD(0x5E0, 0x244, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE0__ELCDIF_DAT_5 IOMUX_PAD(0x5E0, 0x244, 3, 0x710, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE1__EPCD_SDCE_1 IOMUX_PAD(0x5E4, 0x248, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE1__GPIO4_26 IOMUX_PAD(0x5E4, 0x248, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE1__ELCDIF_DAT_4 IOMUX_PAD(0x5E4, 0x248, 3, 0x70C, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE2__EPCD_SDCE_2 IOMUX_PAD(0x5E8, 0x24C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE2__GPIO4_27 IOMUX_PAD(0x5E8, 0x24C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE2__ELCDIF_DAT_3 IOMUX_PAD(0x5E8, 0x24C, 3, 0x708, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE3__EPCD_SDCE_3 IOMUX_PAD(0x5EC, 0x250, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE3__GPIO4_28 IOMUX_PAD(0x5EC, 0x250, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE3__ELCDIF_DAT_2 IOMUX_PAD(0x5EC, 0x250, 3, 0x704, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE4__EPCD_SDCE_4 IOMUX_PAD(0x5F0, 0x254, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE4__GPIO4_29 IOMUX_PAD(0x5F0, 0x254, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE4__ELCDIF_DAT_1 IOMUX_PAD(0x5F0, 0x254, 3, 0x700, 1, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE5__EPCD_SDCE_5 IOMUX_PAD(0x5F4, 0x258, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE5__GPIO4_30 IOMUX_PAD(0x5F4, 0x258, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EPDC_SDCE5__ELCDIF_DAT_0 IOMUX_PAD(0x5F4, 0x258, 3, 0x6FC, 1, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA0__EIM_WEIM_A_0 IOMUX_PAD(0x5F8, 0x25C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA0__GPIO1_0 IOMUX_PAD(0x5F8, 0x25C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA0__KPP_COL_4 IOMUX_PAD(0x5F8, 0x25C, 3, 0x790, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA0__TPIU_TRACE_0 IOMUX_PAD(0x5F8, 0x25C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA0__SRC_BT_CFG1_0 IOMUX_PAD(0x5F8, 0x25C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA1__EIM_WEIM_A_1 IOMUX_PAD(0x5FC, 0x260, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA1__GPIO1_1 IOMUX_PAD(0x5FC, 0x260, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA1__KPP_ROW_4 IOMUX_PAD(0x5FC, 0x260, 3, 0x7A0, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA1__TPIU_TRACE_1 IOMUX_PAD(0x5FC, 0x260, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA1__SRC_BT_CFG1_1 IOMUX_PAD(0x5FC, 0x260, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA2__EIM_WEIM_A_2 IOMUX_PAD(0x600, 0x264, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA2__GPIO1_2 IOMUX_PAD(0x600, 0x264, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA2__KPP_COL_5 IOMUX_PAD(0x600, 0x264, 3, 0x794, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA2__TPIU_TRACE_2 IOMUX_PAD(0x600, 0x264, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA2__SRC_BT_CFG1_2 IOMUX_PAD(0x600, 0x264, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA3__EIM_WEIM_A_3 IOMUX_PAD(0x604, 0x268, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA3__GPIO1_3 IOMUX_PAD(0x604, 0x268, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA3__KPP_ROW_5 IOMUX_PAD(0x604, 0x268, 3, 0x7A4, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA3__TPIU_TRACE_3 IOMUX_PAD(0x604, 0x268, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA3__SRC_BT_CFG1_3 IOMUX_PAD(0x604, 0x268, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA4__EIM_WEIM_A_4 IOMUX_PAD(0x608, 0x26C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA4__GPIO1_4 IOMUX_PAD(0x608, 0x26C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA4__KPP_COL_6 IOMUX_PAD(0x608, 0x26C, 3, 0x798, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA4__TPIU_TRACE_4 IOMUX_PAD(0x608, 0x26C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA4__SRC_BT_CFG1_4 IOMUX_PAD(0x608, 0x26C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA5__EIM_WEIM_A_5 IOMUX_PAD(0x60C, 0x270, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA5__GPIO1_5 IOMUX_PAD(0x60C, 0x270, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA5__KPP_ROW_6 IOMUX_PAD(0x60C, 0x270, 3, 0x7A8, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA5__TPIU_TRACE_5 IOMUX_PAD(0x60C, 0x270, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA5__SRC_BT_CFG1_5 IOMUX_PAD(0x60C, 0x270, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA6__EIM_WEIM_A_6 IOMUX_PAD(0x610, 0x274, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA6__GPIO1_6 IOMUX_PAD(0x610, 0x274, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA6__KPP_COL_7 IOMUX_PAD(0x610, 0x274, 3, 0x79C, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA6__TPIU_TRACE_6 IOMUX_PAD(0x610, 0x274, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA6__SRC_BT_CFG1_6 IOMUX_PAD(0x610, 0x274, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA7__EIM_WEIM_A_7 IOMUX_PAD(0x614, 0x278, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA7__GPIO1_7 IOMUX_PAD(0x614, 0x278, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA7__KPP_ROW_7 IOMUX_PAD(0x614, 0x278, 3, 0x7AC, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA7__TPIU_TRACE_7 IOMUX_PAD(0x614, 0x278, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA7__SRC_BT_CFG1_7 IOMUX_PAD(0x614, 0x278, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA8__EIM_WEIM_A_8 IOMUX_PAD(0x618, 0x27C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA8__GPIO1_8 IOMUX_PAD(0x618, 0x27C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA8__EIM_NANDF_CLE IOMUX_PAD(0x618, 0x27C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA8__TPIU_TRACE_8 IOMUX_PAD(0x618, 0x27C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA8__SRC_BT_CFG2_0 IOMUX_PAD(0x618, 0x27C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA9__EIM_WEIM_A_9 IOMUX_PAD(0x61C, 0x280, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA9__GPIO1_9 IOMUX_PAD(0x61C, 0x280, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA9__EIM_NANDF_ALE IOMUX_PAD(0x61C, 0x280, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA9__TPIU_TRACE_9 IOMUX_PAD(0x61C, 0x280, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA9__SRC_BT_CFG2_1 IOMUX_PAD(0x61C, 0x280, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA10__EIM_WEIM_A_10 IOMUX_PAD(0x620, 0x284, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA10__GPIO1_10 IOMUX_PAD(0x620, 0x284, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA10__EIM_NANDF_CEN_0 IOMUX_PAD(0x620, 0x284, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA10__TPIU_TRACE_10 IOMUX_PAD(0x620, 0x284, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA10__SRC_BT_CFG2_2 IOMUX_PAD(0x620, 0x284, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA11__EIM_WEIM_A_11 IOMUX_PAD(0x624, 0x288, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA11__GPIO1_11 IOMUX_PAD(0x624, 0x288, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA11__EIM_NANDF_CEN_1 IOMUX_PAD(0x624, 0x288, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA11__TPIU_TRACE_11 IOMUX_PAD(0x624, 0x288, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA11__SRC_BT_CFG2_3 IOMUX_PAD(0x624, 0x288, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA12__EIM_WEIM_A_12 IOMUX_PAD(0x628, 0x28C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA12__GPIO1_12 IOMUX_PAD(0x628, 0x28C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA12__EIM_NANDF_CEN_2 IOMUX_PAD(0x628, 0x28C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA12__EPDC_SDCE_6 IOMUX_PAD(0x628, 0x28C, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA12__TPIU_TRACE_12 IOMUX_PAD(0x628, 0x28C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA12__SRC_BT_CFG2_4 IOMUX_PAD(0x628, 0x28C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA13__EIM_WEIM_A_13 IOMUX_PAD(0x62C, 0x290, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA13__GPIO1_13 IOMUX_PAD(0x62C, 0x290, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA13__EIM_NANDF_CEN_3 IOMUX_PAD(0x62C, 0x290, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA13__EPDC_SDCE_7 IOMUX_PAD(0x62C, 0x290, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA13__TPIU_TRACE_13 IOMUX_PAD(0x62C, 0x290, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA13__SRC_BT_CFG2_5 IOMUX_PAD(0x62C, 0x290, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA14__EIM_WEIM_A_14 IOMUX_PAD(0x630, 0x294, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA14__GPIO1_14 IOMUX_PAD(0x630, 0x294, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA14__EIM_NANDF_READY0 IOMUX_PAD(0x630, 0x294, 2, 0x7B4, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA14__EPDC_SDCE_8 IOMUX_PAD(0x630, 0x294, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA14__TPIU_TRACE_14 IOMUX_PAD(0x630, 0x294, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA14__SRC_BT_CFG2_6 IOMUX_PAD(0x630, 0x294, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA15__EIM_WEIM_A_15 IOMUX_PAD(0x634, 0x298, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA15__GPIO1_15 IOMUX_PAD(0x634, 0x298, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA15__EIM_NANDF_DQS IOMUX_PAD(0x634, 0x298, 2, 0x7B0, 2, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA15__EPDC_SDCE_9 IOMUX_PAD(0x634, 0x298, 3, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA15__TPIU_TRACE_15 IOMUX_PAD(0x634, 0x298, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_DA15__SRC_BT_CFG2_7 IOMUX_PAD(0x634, 0x298, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS2__EIM_WEIM_CS_2 IOMUX_PAD(0x638, 0x29C, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS2__GPIO1_16 IOMUX_PAD(0x638, 0x29C, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS2__EIM_WEIM_A_27 IOMUX_PAD(0x638, 0x29C, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS2__TPIU_TRCLK IOMUX_PAD(0x638, 0x29C, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS2__SRC_BT_CFG3_0 IOMUX_PAD(0x638, 0x29C, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS1__EIM_WEIM_CS_1 IOMUX_PAD(0x63C, 0x2A0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS1__GPIO1_17 IOMUX_PAD(0x63C, 0x2A0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS1__TPIU_TRCTL IOMUX_PAD(0x63C, 0x2A0, 6, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS1__SRC_BT_CFG3_1 IOMUX_PAD(0x63C, 0x2A0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS0__EIM_WEIM_CS_0 IOMUX_PAD(0x640, 0x2A4, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS0__GPIO1_18 IOMUX_PAD(0x640, 0x2A4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CS0__SRC_BT_CFG3_2 IOMUX_PAD(0x640, 0x2A4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_EB0__EIM_WEIM_EB_0 IOMUX_PAD(0x644, 0x2A8, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_EB0__GPIO1_19 IOMUX_PAD(0x644, 0x2A8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_EB0__SRC_BT_CFG3_3 IOMUX_PAD(0x644, 0x2A8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_EB1__EIM_WEIM_EB_1 IOMUX_PAD(0x648, 0x2AC, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_EB1__GPIO1_20 IOMUX_PAD(0x648, 0x2AC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_EB1__SRC_BT_CFG3_4 IOMUX_PAD(0x648, 0x2AC, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_WAIT__EIM_WEIM_WAIT IOMUX_PAD(0x64C, 0x2B0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_WAIT__GPIO1_21 IOMUX_PAD(0x64C, 0x2B0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_WAIT__EIM_WEIM_DTACK_B IOMUX_PAD(0x64C, 0x2B0, 2, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_WAIT__SRC_BT_CFG3_5 IOMUX_PAD(0x64C, 0x2B0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_BCLK__EIM_WEIM_BCLK IOMUX_PAD(0x650, 0x2B4, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_BCLK__GPIO1_22 IOMUX_PAD(0x650, 0x2B4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_BCLK__SRC_BT_CFG3_6 IOMUX_PAD(0x650, 0x2B4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_RDY__EIM_WEIM_RDY IOMUX_PAD(0x654, 0x2B8, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_RDY__GPIO1_23 IOMUX_PAD(0x654, 0x2B8, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_RDY__SRC_BT_CFG3_7 IOMUX_PAD(0x654, 0x2B8, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_OE__EIM_WEIM_OE IOMUX_PAD(0x658, 0x2BC, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_OE__GPIO1_24 IOMUX_PAD(0x658, 0x2BC, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_OE__INT_BOOT IOMUX_PAD(0x658, 0x2BC, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_RW__EIM_WEIM_RW IOMUX_PAD(0x65C, 0x2C0, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_RW__GPIO1_25 IOMUX_PAD(0x65C, 0x2C0, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_RW__SYSTEM_RST IOMUX_PAD(0x65C, 0x2C0, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_LBA__EIM_WEIM_LBA IOMUX_PAD(0x660, 0x2C4, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_LBA__GPIO1_26 IOMUX_PAD(0x660, 0x2C4, 1, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_LBA__TESTER_ACK IOMUX_PAD(0x660, 0x2C4, 7, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CRE__EIM_WEIM_CRE IOMUX_PAD(0x664, 0x2C8, 0, __NA_, 0, NO_PAD_CTRL) +#define MX50_PAD_EIM_CRE__GPIO1_27 IOMUX_PAD(0x664, 0x2C8, 1, __NA_, 0, NO_PAD_CTRL) + +#endif /* __MACH_IOMUX_MX50_H__ */ diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index f8ec195742..93fa35a208 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -182,6 +182,13 @@ config MACH_PHYTEC_SOM_AM335X select ARCH_AM33XX help Say Y here if you are using a am335x based Phytecs SOM + +config MACH_VSCOM_BALTOS + bool "VScom Baltos Devices" + select ARCH_AM33XX + help + Say Y here if you are using a am335x based VScom Baltos devices + endif choice diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index ea4361d44e..f2fa3c6345 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -1,14 +1,40 @@ -if ARCH_ROCKCHIP + +menu "Rockchip Features" + depends on ARCH_ROCKCHIP config ARCH_TEXT_BASE hex - default 0x68000000 + default 0x68000000 if ARCH_RK3188 + default 0x0 if ARCH_RK3288 + +config RK_TIMER + hex + default 1 + +choice + prompt "Select Rockchip SoC" + +config ARCH_RK3188 + bool "Rockchip RK3188 SoCs" + +config ARCH_RK3288 + bool "Rockchip RK3288 SoCs" + select CLOCKSOURCE_ROCKCHIP +endchoice comment "select Rockchip boards:" config MACH_RADXA_ROCK + depends on ARCH_RK3188 select I2C select MFD_ACT8846 bool "Radxa rock board" -endif +config MACH_PHYTEC_SOM_RK3288 + depends on ARCH_RK3288 + select I2C + bool "RK3288 phyCORE SOM" + help + Say Y here if you are using a RK3288 based Phytecs SOM + +endmenu diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 820eb10ac2..4ca7f17d8c 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -1 +1,2 @@ -obj-y += core.o +obj-$(CONFIG_ARCH_RK3188) += rk3188.o +obj-$(CONFIG_ARCH_RK3288) += rk3288.o diff --git a/arch/arm/mach-rockchip/include/mach/cru_rk3288.h b/arch/arm/mach-rockchip/include/mach/cru_rk3288.h new file mode 100644 index 0000000000..c898514c6b --- /dev/null +++ b/arch/arm/mach-rockchip/include/mach/cru_rk3288.h @@ -0,0 +1,184 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * (C) Copyright 2008-2014 Rockchip Electronics + * Peter, Software Engineering, <superpeter.cai@gmail.com>. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _ASM_ARCH_CRU_RK3288_H +#define _ASM_ARCH_CRU_RK3288_H + +#define OSC_HZ (24 * 1000 * 1000) + +#define APLL_HZ (1800 * 1000000) +#define GPLL_HZ (594 * 1000000) +#define CPLL_HZ (384 * 1000000) +#define NPLL_HZ (384 * 1000000) + +/* The SRAM is clocked off aclk_bus, so we want to max it out for boot speed */ +#define PD_BUS_ACLK_HZ 297000000 +#define PD_BUS_HCLK_HZ 148500000 +#define PD_BUS_PCLK_HZ 74250000 + +#define PERI_ACLK_HZ 148500000 +#define PERI_HCLK_HZ 148500000 +#define PERI_PCLK_HZ 74250000 + +struct rk3288_cru { + struct rk3288_pll { + u32 con0; + u32 con1; + u32 con2; + u32 con3; + } pll[5]; + u32 cru_mode_con; + u32 reserved0[3]; + u32 cru_clksel_con[43]; + u32 reserved1[21]; + u32 cru_clkgate_con[19]; + u32 reserved2; + u32 cru_glb_srst_fst_value; + u32 cru_glb_srst_snd_value; + u32 cru_softrst_con[12]; + u32 cru_misc_con; + u32 cru_glb_cnt_th; + u32 cru_glb_rst_con; + u32 reserved3; + u32 cru_glb_rst_st; + u32 reserved4; + u32 cru_sdmmc_con[2]; + u32 cru_sdio0_con[2]; + u32 cru_sdio1_con[2]; + u32 cru_emmc_con[2]; +}; + +/* CRU_CLKSEL11_CON */ +enum { + HSICPHY_DIV_SHIFT = 8, + HSICPHY_DIV_MASK = 0x3f, + + MMC0_PLL_SHIFT = 6, + MMC0_PLL_MASK = 3, + MMC0_PLL_SELECT_CODEC = 0, + MMC0_PLL_SELECT_GENERAL, + MMC0_PLL_SELECT_24MHZ, + + MMC0_DIV_SHIFT = 0, + MMC0_DIV_MASK = 0x3f, +}; + +/* CRU_CLKSEL12_CON */ +enum { + EMMC_PLL_SHIFT = 0xe, + EMMC_PLL_MASK = 3, + EMMC_PLL_SELECT_CODEC = 0, + EMMC_PLL_SELECT_GENERAL, + EMMC_PLL_SELECT_24MHZ, + + EMMC_DIV_SHIFT = 8, + EMMC_DIV_MASK = 0x3f, + + SDIO0_PLL_SHIFT = 6, + SDIO0_PLL_MASK = 3, + SDIO0_PLL_SELECT_CODEC = 0, + SDIO0_PLL_SELECT_GENERAL, + SDIO0_PLL_SELECT_24MHZ, + + SDIO0_DIV_SHIFT = 0, + SDIO0_DIV_MASK = 0x3f, +}; + +/* CRU_CLKSEL25_CON */ +enum { + SPI1_PLL_SHIFT = 0xf, + SPI1_PLL_MASK = 1, + SPI1_PLL_SELECT_CODEC = 0, + SPI1_PLL_SELECT_GENERAL, + + SPI1_DIV_SHIFT = 8, + SPI1_DIV_MASK = 0x7f, + + SPI0_PLL_SHIFT = 7, + SPI0_PLL_MASK = 1, + SPI0_PLL_SELECT_CODEC = 0, + SPI0_PLL_SELECT_GENERAL, + + SPI0_DIV_SHIFT = 0, + SPI0_DIV_MASK = 0x7f, +}; + +/* CRU_CLKSEL39_CON */ +enum { + ACLK_HEVC_PLL_SHIFT = 0xe, + ACLK_HEVC_PLL_MASK = 3, + ACLK_HEVC_PLL_SELECT_CODEC = 0, + ACLK_HEVC_PLL_SELECT_GENERAL, + ACLK_HEVC_PLL_SELECT_NEW, + + ACLK_HEVC_DIV_SHIFT = 8, + ACLK_HEVC_DIV_MASK = 0x1f, + + SPI2_PLL_SHIFT = 7, + SPI2_PLL_MASK = 1, + SPI2_PLL_SELECT_CODEC = 0, + SPI2_PLL_SELECT_GENERAL, + + SPI2_DIV_SHIFT = 0, + SPI2_DIV_MASK = 0x7f, +}; + +/* CRU_MODE_CON */ +enum { + NPLL_WORK_SHIFT = 0xe, + NPLL_WORK_MASK = 3, + NPLL_WORK_SLOW = 0, + NPLL_WORK_NORMAL, + NPLL_WORK_DEEP, + + GPLL_WORK_SHIFT = 0xc, + GPLL_WORK_MASK = 3, + GPLL_WORK_SLOW = 0, + GPLL_WORK_NORMAL, + GPLL_WORK_DEEP, + + CPLL_WORK_SHIFT = 8, + CPLL_WORK_MASK = 3, + CPLL_WORK_SLOW = 0, + CPLL_WORK_NORMAL, + CPLL_WORK_DEEP, + + DPLL_WORK_SHIFT = 4, + DPLL_WORK_MASK = 3, + DPLL_WORK_SLOW = 0, + DPLL_WORK_NORMAL, + DPLL_WORK_DEEP, + + APLL_WORK_SHIFT = 0, + APLL_WORK_MASK = 3, + APLL_WORK_SLOW = 0, + APLL_WORK_NORMAL, + APLL_WORK_DEEP, +}; + +/* CRU_APLL_CON0 */ +enum { + CLKR_SHIFT = 8, + CLKR_MASK = 0x3f, + + CLKOD_SHIFT = 0, + CLKOD_MASK = 0xf, +}; + +/* CRU_APLL_CON1 */ +enum { + LOCK_SHIFT = 0x1f, + LOCK_MASK = 1, + LOCK_UNLOCK = 0, + LOCK_LOCK, + + CLKF_SHIFT = 0, + CLKF_MASK = 0x1fff, +}; + +#endif diff --git a/arch/arm/mach-rockchip/include/mach/debug_ll.h b/arch/arm/mach-rockchip/include/mach/debug_ll.h index c666b99e81..9fde2976f1 100644 --- a/arch/arm/mach-rockchip/include/mach/debug_ll.h +++ b/arch/arm/mach-rockchip/include/mach/debug_ll.h @@ -1,25 +1,31 @@ #ifndef __MACH_DEBUG_LL_H__ #define __MACH_DEBUG_LL_H__ +#include <common.h> #include <io.h> +#include <mach/rk3188-regs.h> +#include <mach/rk3288-regs.h> + +#ifdef CONFIG_ARCH_RK3188 + +#define UART_CLOCK 100000000 +#define RK_DEBUG_SOC RK3188 +#define serial_out(a, v) writeb(v, a) +#define serial_in(a) readb(a) + +#elif defined CONFIG_ARCH_RK3288 + +#define UART_CLOCK 24000000 +#define RK_DEBUG_SOC RK3288 +#define serial_out(a, v) writel(v, a) +#define serial_in(a) readl(a) -#if CONFIG_DEBUG_ROCKCHIP_UART_PORT == 0 -#define UART_BASE 0x10124000 -#endif -#if CONFIG_DEBUG_ROCKCHIP_UART_PORT == 1 -#define UART_BASE 0x10126000 -#endif -#if CONFIG_DEBUG_ROCKCHIP_UART_PORT == 2 -#define UART_BASE 0x20064000 -#endif -#if CONFIG_DEBUG_ROCKCHIP_UART_PORT == 3 -#define UART_BASE 0x20068000 #endif -#define LSR_THRE 0x20 /* Xmit holding register empty */ -#define LSR (5 << 2) -#define THR (0 << 2) +#define __RK_UART_BASE(soc, num) soc##_UART##num##_BASE +#define RK_UART_BASE(soc, num) __RK_UART_BASE(soc, num) +#define LSR_THRE 0x20 /* Xmit holding register empty */ #define LCR_BKSE 0x80 /* Bank select enable */ #define LSR (5 << 2) #define THR (0 << 2) @@ -33,28 +39,35 @@ static inline void INIT_LL(void) { - unsigned int clk = 100000000; - unsigned int divisor = clk / 16 / 115200; - - writeb(0x00, UART_BASE + LCR); - writeb(0x00, UART_BASE + IER); - writeb(0x07, UART_BASE + MDR); - writeb(LCR_BKSE, UART_BASE + LCR); - writeb(divisor & 0xff, UART_BASE + DLL); - writeb(divisor >> 8, UART_BASE + DLM); - writeb(0x03, UART_BASE + LCR); - writeb(0x03, UART_BASE + MCR); - writeb(0x07, UART_BASE + FCR); - writeb(0x00, UART_BASE + MDR); + void __iomem *base = IOMEM(RK_UART_BASE(RK_DEBUG_SOC, + CONFIG_DEBUG_ROCKCHIP_UART_PORT)); + unsigned int divisor = DIV_ROUND_CLOSEST(UART_CLOCK, + 16 * CONFIG_BAUDRATE); + + serial_out(base + LCR, 0x00); + serial_out(base + IER, 0x00); + serial_out(base + MDR, 0x07); + serial_out(base + LCR, LCR_BKSE); + serial_out(base + DLL, divisor & 0xff); + serial_out(base + DLM, divisor >> 8); + serial_out(base + LCR, 0x03); + serial_out(base + MCR, 0x03); + serial_out(base + FCR, 0x07); + serial_out(base + MDR, 0x00); } static inline void PUTC_LL(char c) { + void __iomem *base = IOMEM(RK_UART_BASE(RK_DEBUG_SOC, + CONFIG_DEBUG_ROCKCHIP_UART_PORT)); + /* Wait until there is space in the FIFO */ - while ((readb(UART_BASE + LSR) & LSR_THRE) == 0); + while ((serial_in(base + LSR) & LSR_THRE) == 0) + ; /* Send the character */ - writeb(c, UART_BASE + THR); + serial_out(base + THR, c); /* Wait to make sure it hits the line, in case we die too soon. */ - while ((readb(UART_BASE + LSR) & LSR_THRE) == 0); + while ((serial_in(base + LSR) & LSR_THRE) == 0) + ; } #endif diff --git a/arch/arm/mach-rockchip/include/mach/grf_rk3288.h b/arch/arm/mach-rockchip/include/mach/grf_rk3288.h new file mode 100644 index 0000000000..0117a179c9 --- /dev/null +++ b/arch/arm/mach-rockchip/include/mach/grf_rk3288.h @@ -0,0 +1,768 @@ +/* + * (C) Copyright 2015 Google, Inc + * Copyright 2014 Rockchip Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _ASM_ARCH_GRF_RK3288_H +#define _ASM_ARCH_GRF_RK3288_H + +struct rk3288_grf_gpio_lh { + u32 l; + u32 h; +}; + +struct rk3288_grf { + u32 reserved[3]; + u32 gpio1d_iomux; + u32 gpio2a_iomux; + u32 gpio2b_iomux; + + u32 gpio2c_iomux; + u32 reserved2; + u32 gpio3a_iomux; + u32 gpio3b_iomux; + + u32 gpio3c_iomux; + u32 gpio3dl_iomux; + u32 gpio3dh_iomux; + u32 gpio4al_iomux; + + u32 gpio4ah_iomux; + u32 gpio4bl_iomux; + u32 reserved3; + u32 gpio4c_iomux; + + u32 gpio4d_iomux; + u32 reserved4; + u32 gpio5b_iomux; + u32 gpio5c_iomux; + + u32 reserved5; + u32 gpio6a_iomux; + u32 gpio6b_iomux; + u32 gpio6c_iomux; + u32 reserved6; + u32 gpio7a_iomux; + u32 gpio7b_iomux; + u32 gpio7cl_iomux; + u32 gpio7ch_iomux; + u32 reserved7; + u32 gpio8a_iomux; + u32 gpio8b_iomux; + u32 reserved8[30]; + struct rk3288_grf_gpio_lh gpio_sr[8]; + u32 gpio1_p[8][4]; + u32 gpio1_e[8][4]; + u32 gpio_smt; + u32 soc_con0; + u32 soc_con1; + u32 soc_con2; + u32 soc_con3; + u32 soc_con4; + u32 soc_con5; + u32 soc_con6; + u32 soc_con7; + u32 soc_con8; + u32 soc_con9; + u32 soc_con10; + u32 soc_con11; + u32 soc_con12; + u32 soc_con13; + u32 soc_con14; + u32 soc_status[22]; + u32 reserved9[2]; + u32 peridmac_con[4]; + u32 ddrc0_con0; + u32 ddrc1_con0; + u32 cpu_con[5]; + u32 reserved10[3]; + u32 cpu_status0; + u32 reserved11; + u32 uoc0_con[5]; + u32 uoc1_con[5]; + u32 uoc2_con[4]; + u32 uoc3_con[2]; + u32 uoc4_con[2]; + u32 pvtm_con[3]; + u32 pvtm_status[3]; + u32 io_vsel; + u32 saradc_testbit; + u32 tsadc_testbit_l; + u32 tsadc_testbit_h; + u32 os_reg[4]; + u32 reserved12; + u32 soc_con15; + u32 soc_con16; +}; + +struct rk3288_sgrf { + u32 soc_con0; + u32 soc_con1; + u32 soc_con2; + u32 soc_con3; + u32 soc_con4; + u32 soc_con5; + u32 reserved1[(0x20-0x18)/4]; + u32 busdmac_con[2]; + u32 reserved2[(0x40-0x28)/4]; + u32 cpu_con[3]; + u32 reserved3[(0x50-0x4c)/4]; + u32 soc_con6; + u32 soc_con7; + u32 soc_con8; + u32 soc_con9; + u32 soc_con10; + u32 soc_con11; + u32 soc_con12; + u32 soc_con13; + u32 soc_con14; + u32 soc_con15; + u32 soc_con16; + u32 soc_con17; + u32 soc_con18; + u32 soc_con19; + u32 soc_con20; + u32 soc_con21; + u32 reserved4[(0x100-0x90)/4]; + u32 soc_status[2]; + u32 reserved5[(0x120-0x108)/4]; + u32 fast_boot_addr; +}; + +/* GRF_GPIO1D_IOMUX */ +enum { + GPIO1D3_SHIFT = 6, + GPIO1D3_MASK = 1, + GPIO1D3_GPIO = 0, + GPIO1D3_LCDC0_DCLK, + + GPIO1D2_SHIFT = 4, + GPIO1D2_MASK = 1, + GPIO1D2_GPIO = 0, + GPIO1D2_LCDC0_DEN, + + GPIO1D1_SHIFT = 2, + GPIO1D1_MASK = 1, + GPIO1D1_GPIO = 0, + GPIO1D1_LCDC0_VSYNC, + + GPIO1D0_SHIFT = 0, + GPIO1D0_MASK = 1, + GPIO1D0_GPIO = 0, + GPIO1D0_LCDC0_HSYNC, +}; + +/* GRF_GPIO2C_IOMUX */ +enum { + GPIO2C1_SHIFT = 2, + GPIO2C1_MASK = 1, + GPIO2C1_GPIO = 0, + GPIO2C1_I2C3CAM_SDA, + + GPIO2C0_SHIFT = 0, + GPIO2C0_MASK = 1, + GPIO2C0_GPIO = 0, + GPIO2C0_I2C3CAM_SCL, +}; + +/* GRF_GPIO3A_IOMUX */ +enum { + GPIO3A7_SHIFT = 14, + GPIO3A7_MASK = 3, + GPIO3A7_GPIO = 0, + GPIO3A7_FLASH0_DATA7, + GPIO3A7_EMMC_DATA7, + + GPIO3A6_SHIFT = 12, + GPIO3A6_MASK = 3, + GPIO3A6_GPIO = 0, + GPIO3A6_FLASH0_DATA6, + GPIO3A6_EMMC_DATA6, + + GPIO3A5_SHIFT = 10, + GPIO3A5_MASK = 3, + GPIO3A5_GPIO = 0, + GPIO3A5_FLASH0_DATA5, + GPIO3A5_EMMC_DATA5, + + GPIO3A4_SHIFT = 8, + GPIO3A4_MASK = 3, + GPIO3A4_GPIO = 0, + GPIO3A4_FLASH0_DATA4, + GPIO3A4_EMMC_DATA4, + + GPIO3A3_SHIFT = 6, + GPIO3A3_MASK = 3, + GPIO3A3_GPIO = 0, + GPIO3A3_FLASH0_DATA3, + GPIO3A3_EMMC_DATA3, + + GPIO3A2_SHIFT = 4, + GPIO3A2_MASK = 3, + GPIO3A2_GPIO = 0, + GPIO3A2_FLASH0_DATA2, + GPIO3A2_EMMC_DATA2, + + GPIO3A1_SHIFT = 2, + GPIO3A1_MASK = 3, + GPIO3A1_GPIO = 0, + GPIO3A1_FLASH0_DATA1, + GPIO3A1_EMMC_DATA1, + + GPIO3A0_SHIFT = 0, + GPIO3A0_MASK = 3, + GPIO3A0_GPIO = 0, + GPIO3A0_FLASH0_DATA0, + GPIO3A0_EMMC_DATA0, +}; + +/* GRF_GPIO3B_IOMUX */ +enum { + GPIO3B7_SHIFT = 14, + GPIO3B7_MASK = 1, + GPIO3B7_GPIO = 0, + GPIO3B7_FLASH0_CSN1, + + GPIO3B6_SHIFT = 12, + GPIO3B6_MASK = 1, + GPIO3B6_GPIO = 0, + GPIO3B6_FLASH0_CSN0, + + GPIO3B5_SHIFT = 10, + GPIO3B5_MASK = 1, + GPIO3B5_GPIO = 0, + GPIO3B5_FLASH0_WRN, + + GPIO3B4_SHIFT = 8, + GPIO3B4_MASK = 1, + GPIO3B4_GPIO = 0, + GPIO3B4_FLASH0_CLE, + + GPIO3B3_SHIFT = 6, + GPIO3B3_MASK = 1, + GPIO3B3_GPIO = 0, + GPIO3B3_FLASH0_ALE, + + GPIO3B2_SHIFT = 4, + GPIO3B2_MASK = 1, + GPIO3B2_GPIO = 0, + GPIO3B2_FLASH0_RDN, + + GPIO3B1_SHIFT = 2, + GPIO3B1_MASK = 3, + GPIO3B1_GPIO = 0, + GPIO3B1_FLASH0_WP, + GPIO3B1_EMMC_PWREN, + + GPIO3B0_SHIFT = 0, + GPIO3B0_MASK = 1, + GPIO3B0_GPIO = 0, + GPIO3B0_FLASH0_RDY, +}; + +/* GRF_GPIO3C_IOMUX */ +enum { + GPIO3C2_SHIFT = 4, + GPIO3C2_MASK = 3, + GPIO3C2_GPIO = 0, + GPIO3C2_FLASH0_DQS, + GPIO3C2_EMMC_CLKOUT, + + GPIO3C1_SHIFT = 2, + GPIO3C1_MASK = 3, + GPIO3C1_GPIO = 0, + GPIO3C1_FLASH0_CSN3, + GPIO3C1_EMMC_RSTNOUT, + + GPIO3C0_SHIFT = 0, + GPIO3C0_MASK = 3, + GPIO3C0_GPIO = 0, + GPIO3C0_FLASH0_CSN2, + GPIO3C0_EMMC_CMD, +}; + +/* GRF_GPIO4C_IOMUX */ +enum { + GPIO4C7_SHIFT = 14, + GPIO4C7_MASK = 1, + GPIO4C7_GPIO = 0, + GPIO4C7_SDIO0_DATA3, + + GPIO4C6_SHIFT = 12, + GPIO4C6_MASK = 1, + GPIO4C6_GPIO = 0, + GPIO4C6_SDIO0_DATA2, + + GPIO4C5_SHIFT = 10, + GPIO4C5_MASK = 1, + GPIO4C5_GPIO = 0, + GPIO4C5_SDIO0_DATA1, + + GPIO4C4_SHIFT = 8, + GPIO4C4_MASK = 1, + GPIO4C4_GPIO = 0, + GPIO4C4_SDIO0_DATA0, + + GPIO4C3_SHIFT = 6, + GPIO4C3_MASK = 1, + GPIO4C3_GPIO = 0, + GPIO4C3_UART0BT_RTSN, + + GPIO4C2_SHIFT = 4, + GPIO4C2_MASK = 1, + GPIO4C2_GPIO = 0, + GPIO4C2_UART0BT_CTSN, + + GPIO4C1_SHIFT = 2, + GPIO4C1_MASK = 1, + GPIO4C1_GPIO = 0, + GPIO4C1_UART0BT_SOUT, + + GPIO4C0_SHIFT = 0, + GPIO4C0_MASK = 1, + GPIO4C0_GPIO = 0, + GPIO4C0_UART0BT_SIN, +}; + +/* GRF_GPIO5B_IOMUX */ +enum { + GPIO5B7_SHIFT = 14, + GPIO5B7_MASK = 3, + GPIO5B7_GPIO = 0, + GPIO5B7_SPI0_RXD, + GPIO5B7_TS0_DATA7, + GPIO5B7_UART4EXP_SIN, + + GPIO5B6_SHIFT = 12, + GPIO5B6_MASK = 3, + GPIO5B6_GPIO = 0, + GPIO5B6_SPI0_TXD, + GPIO5B6_TS0_DATA6, + GPIO5B6_UART4EXP_SOUT, + + GPIO5B5_SHIFT = 10, + GPIO5B5_MASK = 3, + GPIO5B5_GPIO = 0, + GPIO5B5_SPI0_CSN0, + GPIO5B5_TS0_DATA5, + GPIO5B5_UART4EXP_RTSN, + + GPIO5B4_SHIFT = 8, + GPIO5B4_MASK = 3, + GPIO5B4_GPIO = 0, + GPIO5B4_SPI0_CLK, + GPIO5B4_TS0_DATA4, + GPIO5B4_UART4EXP_CTSN, + + GPIO5B3_SHIFT = 6, + GPIO5B3_MASK = 3, + GPIO5B3_GPIO = 0, + GPIO5B3_UART1BB_RTSN, + GPIO5B3_TS0_DATA3, + + GPIO5B2_SHIFT = 4, + GPIO5B2_MASK = 3, + GPIO5B2_GPIO = 0, + GPIO5B2_UART1BB_CTSN, + GPIO5B2_TS0_DATA2, + + GPIO5B1_SHIFT = 2, + GPIO5B1_MASK = 3, + GPIO5B1_GPIO = 0, + GPIO5B1_UART1BB_SOUT, + GPIO5B1_TS0_DATA1, + + GPIO5B0_SHIFT = 0, + GPIO5B0_MASK = 3, + GPIO5B0_GPIO = 0, + GPIO5B0_UART1BB_SIN, + GPIO5B0_TS0_DATA0, +}; + +/* GRF_GPIO5C_IOMUX */ +enum { + GPIO5C3_SHIFT = 6, + GPIO5C3_MASK = 1, + GPIO5C3_GPIO = 0, + GPIO5C3_TS0_ERR, + + GPIO5C2_SHIFT = 4, + GPIO5C2_MASK = 1, + GPIO5C2_GPIO = 0, + GPIO5C2_TS0_CLK, + + GPIO5C1_SHIFT = 2, + GPIO5C1_MASK = 1, + GPIO5C1_GPIO = 0, + GPIO5C1_TS0_VALID, + + GPIO5C0_SHIFT = 0, + GPIO5C0_MASK = 3, + GPIO5C0_GPIO = 0, + GPIO5C0_SPI0_CSN1, + GPIO5C0_TS0_SYNC, +}; + +/* GRF_GPIO6B_IOMUX */ +enum { + GPIO6B3_SHIFT = 6, + GPIO6B3_MASK = 1, + GPIO6B3_GPIO = 0, + GPIO6B3_SPDIF_TX, + + GPIO6B2_SHIFT = 4, + GPIO6B2_MASK = 1, + GPIO6B2_GPIO = 0, + GPIO6B2_I2C1AUDIO_SCL, + + GPIO6B1_SHIFT = 2, + GPIO6B1_MASK = 1, + GPIO6B1_GPIO = 0, + GPIO6B1_I2C1AUDIO_SDA, + + GPIO6B0_SHIFT = 0, + GPIO6B0_MASK = 1, + GPIO6B0_GPIO = 0, + GPIO6B0_I2S_CLK, +}; + +/* GRF_GPIO6C_IOMUX */ +enum { + GPIO6C6_SHIFT = 12, + GPIO6C6_MASK = 1, + GPIO6C6_GPIO = 0, + GPIO6C6_SDMMC0_DECTN, + + GPIO6C5_SHIFT = 10, + GPIO6C5_MASK = 1, + GPIO6C5_GPIO = 0, + GPIO6C5_SDMMC0_CMD, + + GPIO6C4_SHIFT = 8, + GPIO6C4_MASK = 3, + GPIO6C4_GPIO = 0, + GPIO6C4_SDMMC0_CLKOUT, + GPIO6C4_JTAG_TDO, + + GPIO6C3_SHIFT = 6, + GPIO6C3_MASK = 3, + GPIO6C3_GPIO = 0, + GPIO6C3_SDMMC0_DATA3, + GPIO6C3_JTAG_TCK, + + GPIO6C2_SHIFT = 4, + GPIO6C2_MASK = 3, + GPIO6C2_GPIO = 0, + GPIO6C2_SDMMC0_DATA2, + GPIO6C2_JTAG_TDI, + + GPIO6C1_SHIFT = 2, + GPIO6C1_MASK = 3, + GPIO6C1_GPIO = 0, + GPIO6C1_SDMMC0_DATA1, + GPIO6C1_JTAG_TRSTN, + + GPIO6C0_SHIFT = 0, + GPIO6C0_MASK = 3, + GPIO6C0_GPIO = 0, + GPIO6C0_SDMMC0_DATA0, + GPIO6C0_JTAG_TMS, +}; + +/* GRF_GPIO7A_IOMUX */ +enum { + GPIO7A7_SHIFT = 14, + GPIO7A7_MASK = 3, + GPIO7A7_GPIO = 0, + GPIO7A7_UART3GPS_SIN, + GPIO7A7_GPS_MAG, + GPIO7A7_HSADCT1_DATA0, + + GPIO7A1_SHIFT = 2, + GPIO7A1_MASK = 1, + GPIO7A1_GPIO = 0, + GPIO7A1_PWM_1, + + GPIO7A0_SHIFT = 0, + GPIO7A0_MASK = 3, + GPIO7A0_GPIO = 0, + GPIO7A0_PWM_0, + GPIO7A0_VOP0_PWM, + GPIO7A0_VOP1_PWM, +}; + +/* GRF_GPIO7B_IOMUX */ +enum { + GPIO7B7_SHIFT = 14, + GPIO7B7_MASK = 3, + GPIO7B7_GPIO = 0, + GPIO7B7_ISP_SHUTTERTRIG, + GPIO7B7_SPI1_TXD, + + GPIO7B6_SHIFT = 12, + GPIO7B6_MASK = 3, + GPIO7B6_GPIO = 0, + GPIO7B6_ISP_PRELIGHTTRIG, + GPIO7B6_SPI1_RXD, + + GPIO7B5_SHIFT = 10, + GPIO7B5_MASK = 3, + GPIO7B5_GPIO = 0, + GPIO7B5_ISP_FLASHTRIGOUT, + GPIO7B5_SPI1_CSN0, + + GPIO7B4_SHIFT = 8, + GPIO7B4_MASK = 3, + GPIO7B4_GPIO = 0, + GPIO7B4_ISP_SHUTTEREN, + GPIO7B4_SPI1_CLK, + + GPIO7B3_SHIFT = 6, + GPIO7B3_MASK = 3, + GPIO7B3_GPIO = 0, + GPIO7B3_USB_DRVVBUS1, + GPIO7B3_EDP_HOTPLUG, + + GPIO7B2_SHIFT = 4, + GPIO7B2_MASK = 3, + GPIO7B2_GPIO = 0, + GPIO7B2_UART3GPS_RTSN, + GPIO7B2_USB_DRVVBUS0, + + GPIO7B1_SHIFT = 2, + GPIO7B1_MASK = 3, + GPIO7B1_GPIO = 0, + GPIO7B1_UART3GPS_CTSN, + GPIO7B1_GPS_RFCLK, + GPIO7B1_GPST1_CLK, + + GPIO7B0_SHIFT = 0, + GPIO7B0_MASK = 3, + GPIO7B0_GPIO = 0, + GPIO7B0_UART3GPS_SOUT, + GPIO7B0_GPS_SIG, + GPIO7B0_HSADCT1_DATA1, +}; + +/* GRF_GPIO7CL_IOMUX */ +enum { + GPIO7C3_SHIFT = 12, + GPIO7C3_MASK = 3, + GPIO7C3_GPIO = 0, + GPIO7C3_I2C5HDMI_SDA, + GPIO7C3_EDPHDMII2C_SDA, + + GPIO7C2_SHIFT = 8, + GPIO7C2_MASK = 1, + GPIO7C2_GPIO = 0, + GPIO7C2_I2C4TP_SCL, + + GPIO7C1_SHIFT = 4, + GPIO7C1_MASK = 1, + GPIO7C1_GPIO = 0, + GPIO7C1_I2C4TP_SDA, + + GPIO7C0_SHIFT = 0, + GPIO7C0_MASK = 3, + GPIO7C0_GPIO = 0, + GPIO7C0_ISP_FLASHTRIGIN, + GPIO7C0_EDPHDMI_CECINOUTT1, +}; + +/* GRF_GPIO7CH_IOMUX */ +enum { + GPIO7C7_SHIFT = 12, + GPIO7C7_MASK = 7, + GPIO7C7_GPIO = 0, + GPIO7C7_UART2DBG_SOUT, + GPIO7C7_UART2DBG_SIROUT, + GPIO7C7_PWM_3, + GPIO7C7_EDPHDMI_CECINOUT, + + GPIO7C6_SHIFT = 8, + GPIO7C6_MASK = 3, + GPIO7C6_GPIO = 0, + GPIO7C6_UART2DBG_SIN, + GPIO7C6_UART2DBG_SIRIN, + GPIO7C6_PWM_2, + + GPIO7C4_SHIFT = 0, + GPIO7C4_MASK = 3, + GPIO7C4_GPIO = 0, + GPIO7C4_I2C5HDMI_SCL, + GPIO7C4_EDPHDMII2C_SCL, +}; + +/* GRF_GPIO8A_IOMUX */ +enum { + GPIO8A7_SHIFT = 14, + GPIO8A7_MASK = 3, + GPIO8A7_GPIO = 0, + GPIO8A7_SPI2_CSN0, + GPIO8A7_SC_DETECT, + GPIO8A7_RESERVE, + + GPIO8A6_SHIFT = 12, + GPIO8A6_MASK = 3, + GPIO8A6_GPIO = 0, + GPIO8A6_SPI2_CLK, + GPIO8A6_SC_IO, + GPIO8A6_RESERVE, + + GPIO8A5_SHIFT = 10, + GPIO8A5_MASK = 3, + GPIO8A5_GPIO = 0, + GPIO8A5_I2C2SENSOR_SCL, + GPIO8A5_SC_CLK, + + GPIO8A4_SHIFT = 8, + GPIO8A4_MASK = 3, + GPIO8A4_GPIO = 0, + GPIO8A4_I2C2SENSOR_SDA, + GPIO8A4_SC_RST, + + GPIO8A3_SHIFT = 6, + GPIO8A3_MASK = 3, + GPIO8A3_GPIO = 0, + GPIO8A3_SPI2_CSN1, + GPIO8A3_SC_IOT1, + + GPIO8A2_SHIFT = 4, + GPIO8A2_MASK = 1, + GPIO8A2_GPIO = 0, + GPIO8A2_SC_DETECTT1, + + GPIO8A1_SHIFT = 2, + GPIO8A1_MASK = 3, + GPIO8A1_GPIO = 0, + GPIO8A1_PS2_DATA, + GPIO8A1_SC_VCC33V, + + GPIO8A0_SHIFT = 0, + GPIO8A0_MASK = 3, + GPIO8A0_GPIO = 0, + GPIO8A0_PS2_CLK, + GPIO8A0_SC_VCC18V, +}; + +/* GRF_GPIO8B_IOMUX */ +enum { + GPIO8B1_SHIFT = 2, + GPIO8B1_MASK = 3, + GPIO8B1_GPIO = 0, + GPIO8B1_SPI2_TXD, + GPIO8B1_SC_CLK, + + GPIO8B0_SHIFT = 0, + GPIO8B0_MASK = 3, + GPIO8B0_GPIO = 0, + GPIO8B0_SPI2_RXD, + GPIO8B0_SC_RST, +}; + +/* GRF_SOC_CON0 */ +enum { + PAUSE_MMC_PERI_SHIFT = 0xf, + PAUSE_MMC_PERI_MASK = 1, + + PAUSE_EMEM_PERI_SHIFT = 0xe, + PAUSE_EMEM_PERI_MASK = 1, + + PAUSE_USB_PERI_SHIFT = 0xd, + PAUSE_USB_PERI_MASK = 1, + + GRF_FORCE_JTAG_SHIFT = 0xc, + GRF_FORCE_JTAG_MASK = 1, + + GRF_CORE_IDLE_REQ_MODE_SEL1_SHIFT = 0xb, + GRF_CORE_IDLE_REQ_MODE_SEL1_MASK = 1, + + GRF_CORE_IDLE_REQ_MODE_SEL0_SHIFT = 0xa, + GRF_CORE_IDLE_REQ_MODE_SEL0_MASK = 1, + + DDR1_16BIT_EN_SHIFT = 9, + DDR1_16BIT_EN_MASK = 1, + + DDR0_16BIT_EN_SHIFT = 8, + DDR0_16BIT_EN_MASK = 1, + + VCODEC_SHIFT = 7, + VCODEC_MASK = 1, + VCODEC_SELECT_VEPU_ACLK = 0, + VCODEC_SELECT_VDPU_ACLK, + + UPCTL1_C_ACTIVE_IN_SHIFT = 6, + UPCTL1_C_ACTIVE_IN_MASK = 1, + UPCTL1_C_ACTIVE_IN_MAY = 0, + UPCTL1_C_ACTIVE_IN_WILL, + + UPCTL0_C_ACTIVE_IN_SHIFT = 5, + UPCTL0_C_ACTIVE_IN_MASK = 1, + UPCTL0_C_ACTIVE_IN_MAY = 0, + UPCTL0_C_ACTIVE_IN_WILL, + + MSCH1_MAINDDR3_SHIFT = 4, + MSCH1_MAINDDR3_MASK = 1, + MSCH1_MAINDDR3_DDR3 = 1, + + MSCH0_MAINDDR3_SHIFT = 3, + MSCH0_MAINDDR3_MASK = 1, + MSCH0_MAINDDR3_DDR3 = 1, + + MSCH1_MAINPARTIALPOP_SHIFT = 2, + MSCH1_MAINPARTIALPOP_MASK = 1, + + MSCH0_MAINPARTIALPOP_SHIFT = 1, + MSCH0_MAINPARTIALPOP_MASK = 1, +}; + +/* GRF_SOC_CON2 */ +enum { + UPCTL1_LPDDR3_ODT_EN_SHIFT = 0xd, + UPCTL1_LPDDR3_ODT_EN_MASK = 1, + UPCTL1_LPDDR3_ODT_EN_ODT = 1, + + UPCTL1_BST_DIABLE_SHIFT = 0xc, + UPCTL1_BST_DIABLE_MASK = 1, + UPCTL1_BST_DIABLE_DISABLE = 1, + + LPDDR3_EN1_SHIFT = 0xb, + LPDDR3_EN1_MASK = 1, + LPDDR3_EN1_LPDDR3 = 1, + + UPCTL0_LPDDR3_ODT_EN_SHIFT = 0xa, + UPCTL0_LPDDR3_ODT_EN_MASK = 1, + UPCTL0_LPDDR3_ODT_EN_ODT_ENABLE = 1, + + UPCTL0_BST_DIABLE_SHIFT = 9, + UPCTL0_BST_DIABLE_MASK = 1, + UPCTL0_BST_DIABLE_DISABLE = 1, + + LPDDR3_EN0_SHIFT = 8, + LPDDR3_EN0_MASK = 1, + LPDDR3_EN0_LPDDR3 = 1, + + GRF_POC_FLASH0_CTRL_SHIFT = 7, + GRF_POC_FLASH0_CTRL_MASK = 1, + GRF_POC_FLASH0_CTRL_GPIO3C_3 = 0, + GRF_POC_FLASH0_CTRL_GRF_IO_VSEL, + + SIMCARD_MUX_SHIFT = 6, + SIMCARD_MUX_MASK = 1, + SIMCARD_MUX_USE_A = 1, + SIMCARD_MUX_USE_B = 0, + + GRF_SPDIF_2CH_EN_SHIFT = 1, + GRF_SPDIF_2CH_EN_MASK = 1, + GRF_SPDIF_2CH_EN_8CH = 0, + GRF_SPDIF_2CH_EN_2CH, + + PWM_SHIFT = 0, + PWM_MASK = 1, + PWM_RK = 1, + PWM_PWM = 0, +}; + +#endif diff --git a/arch/arm/mach-rockchip/include/mach/hardware.h b/arch/arm/mach-rockchip/include/mach/hardware.h new file mode 100644 index 0000000000..b0afd1f3d4 --- /dev/null +++ b/arch/arm/mach-rockchip/include/mach/hardware.h @@ -0,0 +1,18 @@ +/* + * Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_HARDWARE_H +#define _ASM_ARCH_HARDWARE_H + +#define RK_CLRSETBITS(clr, set) ((((clr) | (set)) << 16) | set) +#define RK_SETBITS(set) RK_CLRSETBITS(0, set) +#define RK_CLRBITS(clr) RK_CLRSETBITS(clr, 0) + +#define rk_clrsetreg(addr, clr, set) writel((clr) << 16 | (set), addr) +#define rk_clrreg(addr, clr) writel((clr) << 16, addr) +#define rk_setreg(addr, set) writel(set, addr) + +#endif diff --git a/arch/arm/mach-rockchip/include/mach/rockchip-regs.h b/arch/arm/mach-rockchip/include/mach/rk3188-regs.h index a6a1c640d6..f147fe27fe 100644 --- a/arch/arm/mach-rockchip/include/mach/rockchip-regs.h +++ b/arch/arm/mach-rockchip/include/mach/rk3188-regs.h @@ -11,8 +11,8 @@ * GNU General Public License for more details. */ -#ifndef __MACH_ROCKCHIP_REGS_H -#define __MACH_ROCKCHIP_REGS_H +#ifndef __MACH_RK3188_REGS_H +#define __MACH_RK3188_REGS_H #define RK_CRU_BASE 0x20000000 #define RK_GRF_BASE 0x20008000 @@ -22,4 +22,10 @@ #define RK_SOC_CON0_REMAP (1 << 12) -#endif /* __MACH_ROCKCHIP_REGS_H */ +/* UART */ +#define RK3188_UART0_BASE 0x10124000 +#define RK3188_UART1_BASE 0x10126000 +#define RK3188_UART2_BASE 0x20064000 +#define RK3188_UART3_BASE 0x20068000 + +#endif /* __MACH_RK3188_REGS_H */ diff --git a/arch/arm/mach-rockchip/include/mach/rk3288-regs.h b/arch/arm/mach-rockchip/include/mach/rk3288-regs.h new file mode 100644 index 0000000000..a83a3a818b --- /dev/null +++ b/arch/arm/mach-rockchip/include/mach/rk3288-regs.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 PHYTEC Messtechnik GmbH, + * Author: Wadim Egorov <w.egorov@phytec.de> + * + * 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. + * + * 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. + */ + +#ifndef __MACH_RK3288_REGS_H +#define __MACH_RK3288_REGS_H + +#define RK3288_CRU_BASE 0xff760000 +#define RK3288_GRF_BASE 0xff770000 + +/* UART */ +#define RK3288_UART0_BASE 0xff180000 +#define RK3288_UART1_BASE 0xff190000 +#define RK3288_UART2_BASE 0xff690000 +#define RK3288_UART3_BASE 0xff1b0000 +#define RK3288_UART4_BASE 0xff1c0000 + +#endif /* __MACH_RK3288_REGS_H */ diff --git a/arch/arm/mach-rockchip/include/mach/timer.h b/arch/arm/mach-rockchip/include/mach/timer.h new file mode 100644 index 0000000000..e6ed0e4e3e --- /dev/null +++ b/arch/arm/mach-rockchip/include/mach/timer.h @@ -0,0 +1,19 @@ +/* + * (C) Copyright 2015 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_TIMER_H +#define _ASM_ARCH_TIMER_H + +struct rk_timer { + unsigned int timer_load_count0; + unsigned int timer_load_count1; + unsigned int timer_curr_value0; + unsigned int timer_curr_value1; + unsigned int timer_ctrl_reg; + unsigned int timer_int_status; +}; + +#endif diff --git a/arch/arm/mach-rockchip/core.c b/arch/arm/mach-rockchip/rk3188.c index 2428fee349..e7cbf36457 100644 --- a/arch/arm/mach-rockchip/core.c +++ b/arch/arm/mach-rockchip/rk3188.c @@ -15,7 +15,7 @@ #include <common.h> #include <init.h> #include <restart.h> -#include <mach/rockchip-regs.h> +#include <mach/rk3188-regs.h> static void __noreturn rockchip_restart_soc(struct restart_handler *rst) { diff --git a/arch/arm/mach-rockchip/rk3288.c b/arch/arm/mach-rockchip/rk3288.c new file mode 100644 index 0000000000..4e8fb4a123 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3288.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2016 PHYTEC Messtechnik GmbH, + * Author: Wadim Egorov <w.egorov@phytec.de> + * + * 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. + * + * 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. + */ + +#include <asm/io.h> +#include <common.h> +#include <init.h> +#include <restart.h> +#include <reset_source.h> +#include <bootsource.h> +#include <mach/rk3288-regs.h> +#include <mach/cru_rk3288.h> +#include <mach/hardware.h> + +static void __noreturn rockchip_restart_soc(struct restart_handler *rst) +{ + struct rk3288_cru *cru = (struct rk3288_cru *)RK3288_CRU_BASE; + + /* cold reset */ + writel(RK_CLRBITS(0xffff), &cru->cru_mode_con); + writel(0xfdb9, &cru->cru_glb_srst_fst_value); + + hang(); +} + +static void rk3288_detect_reset_reason(void) +{ + struct rk3288_cru *cru = (struct rk3288_cru *)RK3288_CRU_BASE; + + switch (cru->cru_glb_rst_st) { + case (1 << 0): + reset_source_set(RESET_POR); + break; + case (1 << 1): + reset_source_set(RESET_RST); + break; + case (1 << 2): + case (1 << 3): + reset_source_set(RESET_THERM); + break; + case (1 << 4): + case (1 << 5): + reset_source_set(RESET_WDG); + break; + default: + reset_source_set(RESET_UKWN); + break; + } +} + +static int rk3288_init(void) +{ + restart_handler_register_fn(rockchip_restart_soc); + + if (IS_ENABLED(CONFIG_RESET_SOURCE)) + rk3288_detect_reset_reason(); + + return 0; +} +postcore_initcall(rk3288_init); + +/* + * ATM we are not able to determine the boot source. + * So let's handle the environment on eMMC, regardless which device + * we are booting from. + */ +static int rk3288_env_init(void) +{ + const char *envpath = "/chosen/environment-emmc"; + int ret; + + bootsource_set(BOOTSOURCE_MMC); + bootsource_set_instance(0); + + ret = of_device_enable_path(envpath); + if (ret < 0) + pr_warn("Failed to enable environment partition '%s' (%d)\n", + envpath, ret); + + return 0; +} +device_initcall(rk3288_env_init); diff --git a/arch/arm/mach-socfpga/xload.c b/arch/arm/mach-socfpga/xload.c index 7f8f0320ca..993626966e 100644 --- a/arch/arm/mach-socfpga/xload.c +++ b/arch/arm/mach-socfpga/xload.c @@ -20,13 +20,15 @@ #include <mach/system-manager.h> #include <mach/socfpga-regs.h> - -static struct socfpga_barebox_part default_part = { - .nor_offset = SZ_256K, - .nor_size = SZ_1M, - .mmc_disk = "disk0.1", +static struct socfpga_barebox_part default_parts[] = { + { + .nor_offset = SZ_256K, + .nor_size = SZ_1M, + .mmc_disk = "disk0.1", + }, + { /* sentinel */ } }; -const struct socfpga_barebox_part *barebox_part = &default_part; +const struct socfpga_barebox_part *barebox_parts = &default_parts; enum socfpga_clks { timer, mmc, qspi_clk, uart, clk_max @@ -109,28 +111,52 @@ static void socfpga_timer_init(void) static __noreturn int socfpga_xload(void) { enum bootsource bootsource = bootsource_get(); - void *buf; + struct socfpga_barebox_part *part; + void *buf = NULL; switch (bootsource) { case BOOTSOURCE_MMC: socfpga_mmc_init(); - buf = bootstrap_read_disk(barebox_part->mmc_disk, "fat"); + + for (part = barebox_parts; part->mmc_disk; part++) { + buf = bootstrap_read_disk(barebox_parts->mmc_disk, "fat"); + if (!buf) { + pr_info("failed to load barebox from MMC %s\n", + part->mmc_disk); + continue; + } + } + if (!buf) { + pr_err("failed to load barebox.bin from MMC\n"); + hang(); + } break; case BOOTSOURCE_SPI: socfpga_qspi_init(); - buf = bootstrap_read_devfs("mtd0", false, barebox_part->nor_offset, - barebox_part->nor_size, SZ_1M); + + for (part = barebox_parts; part->nor_size; part++) { + buf = bootstrap_read_devfs("mtd0", false, + part->nor_offset, part->nor_size, SZ_1M); + if (!buf) { + pr_info("failed to load barebox from QSPI NOR flash at offset %#x\n", + part->nor_offset); + continue; + } + + break; + } + + if (!buf) { + pr_err("failed to load barebox from QSPI NOR flash\n"); + hang(); + } + break; default: pr_err("unknown bootsource %d\n", bootsource); hang(); } - if (!buf) { - pr_err("failed to load barebox.bin\n"); - hang(); - } - pr_info("starting bootloader...\n"); bootstrap_boot(buf, 0); diff --git a/arch/arm/pbl/Makefile b/arch/arm/pbl/Makefile index 1ff39dbdfe..c45511261d 100644 --- a/arch/arm/pbl/Makefile +++ b/arch/arm/pbl/Makefile @@ -3,7 +3,7 @@ suffix_$(CONFIG_IMAGE_COMPRESSION_GZIP) = gzip suffix_$(CONFIG_IMAGE_COMPRESSION_LZO) = lzo suffix_$(CONFIG_IMAGE_COMPRESSION_LZ4) = lz4 suffix_$(CONFIG_IMAGE_COMPRESSION_XZKERN) = xzkern -suffix_$(CONFIG_IMAGE_COMPRESSION_NONE) = shipped +suffix_$(CONFIG_IMAGE_COMPRESSION_NONE) = comp_copy OBJCOPYFLAGS_zbarebox.bin = -O binary piggy_o := piggy.$(suffix_y).o diff --git a/arch/mips/boot/dtb.c b/arch/mips/boot/dtb.c index 977c837887..e7633a5aff 100644 --- a/arch/mips/boot/dtb.c +++ b/arch/mips/boot/dtb.c @@ -51,7 +51,7 @@ static int of_mips_init(void) return 0; root = of_unflatten_dtb(__dtb_start); - if (root) { + if (!IS_ERR(root)) { pr_debug("using internal DTB\n"); of_set_root_node(root); if (IS_ENABLED(CONFIG_OFDEVICE)) diff --git a/arch/mips/dts/tplink-mr3020.dts b/arch/mips/dts/tplink-mr3020.dts index 831fab8108..1e843ee003 100644 --- a/arch/mips/dts/tplink-mr3020.dts +++ b/arch/mips/dts/tplink-mr3020.dts @@ -1,73 +1,7 @@ -/dts-v1/; - -#include <dt-bindings/gpio/gpio.h> - -#include <mips/qca/ar9331.dtsi> +#include <mips/qca/ar9331_tl_mr3020.dts> / { - model = "TP-Link TL-MR3020"; - compatible = "tplink,tl-mr3020"; - aliases { spiflash = &spiflash; }; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x2000000>; - }; - - leds { - compatible = "gpio-leds"; - - wlan { - label = "tp-link:green:wlan"; - gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; - default-state = "off"; - }; - - lan { - label = "tp-link:green:lan"; - gpios = <&gpio 17 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - wps { - label = "tp-link:green:wps"; - gpios = <&gpio 26 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - led3g { - label = "tp-link:green:3g"; - gpios = <&gpio 27 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - }; -}; - -&ref { - clock-frequency = <25000000>; -}; - -&uart { - status = "okay"; -}; - -&gpio { - status = "okay"; -}; - -&spi { - num-chipselects = <1>; - status = "okay"; - - /* Spansion S25FL032PIF SPI flash */ - spiflash: s25sl032p@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "spansion,s25sl032p", "jedec,spi-nor"; - spi-max-frequency = <104000000>; - reg = <0>; - }; }; diff --git a/arch/openrisc/lib/dtb.c b/arch/openrisc/lib/dtb.c index 4f63a7760f..04bb6d25cc 100644 --- a/arch/openrisc/lib/dtb.c +++ b/arch/openrisc/lib/dtb.c @@ -32,7 +32,7 @@ static int of_openrisc_init(void) return 0; root = of_unflatten_dtb(__dtb_start); - if (root) { + if (!IS_ERR(root)) { pr_debug("using internal DTB\n"); of_set_root_node(root); if (IS_ENABLED(CONFIG_OFDEVICE)) diff --git a/arch/ppc/boards/pcm030/env/init/mtdparts-nor b/arch/ppc/boards/pcm030/env/init/mtdparts-nor index e900a3b223..44c07ead21 100644 --- a/arch/ppc/boards/pcm030/env/init/mtdparts-nor +++ b/arch/ppc/boards/pcm030/env/init/mtdparts-nor @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "NOR partitions" - exit -fi - mtdparts="512k(nor0.bareboxlow),4M(nor0.kernel),512k(nor0.oftree),26M(nor0.root),512k(nor0.barebox),512k(nor0.bareboxenv)" kernelname="physmap-flash.0" diff --git a/commands/Kconfig b/commands/Kconfig index decd45d761..21d921268f 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -2058,7 +2058,7 @@ config CMD_OF_FIXUP_STATUS help Register a fixup to enable or disable node - Usage: of_fixup_node [-d] path + Usage: of_fixup_status [-d] path Options: -d disable node @@ -2097,6 +2097,11 @@ config CMD_STATE depends on STATE prompt "state" +config CMD_BOOTCHOOSER + tristate + depends on BOOTCHOOSER + prompt "bootchooser" + config CMD_DHRYSTONE bool prompt "dhrystone" diff --git a/commands/Makefile b/commands/Makefile index 7abd6dd406..601f15fc38 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -115,6 +115,7 @@ obj-$(CONFIG_CMD_NV) += nv.o obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o obj-$(CONFIG_CMD_STATE) += state.o obj-$(CONFIG_CMD_DHCP) += dhcp.o +obj-$(CONFIG_CMD_BOOTCHOOSER) += bootchooser.o obj-$(CONFIG_CMD_DHRYSTONE) += dhrystone.o obj-$(CONFIG_CMD_SPD_DECODE) += spd_decode.o obj-$(CONFIG_CMD_MMC_EXTCSD) += mmc_extcsd.o diff --git a/commands/boot.c b/commands/boot.c index 8b3b407e12..102ca07980 100644 --- a/commands/boot.c +++ b/commands/boot.c @@ -53,6 +53,8 @@ static int do_boot(int argc, char *argv[]) case 'w': boot_set_watchdog_timeout(simple_strtoul(optarg, NULL, 0)); break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/bootchooser.c b/commands/bootchooser.c new file mode 100644 index 0000000000..91938fe551 --- /dev/null +++ b/commands/bootchooser.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de> + * Copyright (C) 2015 Marc Kleine-Budde <mkl@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <bootchooser.h> +#include <globalvar.h> +#include <command.h> +#include <common.h> +#include <getopt.h> +#include <malloc.h> +#include <stdio.h> + +#define DONTTOUCH -2 +#define DEFAULT -1 + +static void target_reset(struct bootchooser_target *target, int priority, int attempts) +{ + printf("Resetting target %s to ", bootchooser_target_name(target)); + + if (priority >= 0) + printf("priority %d", priority); + else if (priority == DEFAULT) + printf("default priority"); + + if (priority > DONTTOUCH && attempts > DONTTOUCH) + printf(", "); + + if (attempts >= 0) + printf("%d attempts", attempts); + else if (attempts == DEFAULT) + printf("default attempts"); + + printf("\n"); + + if (priority > DONTTOUCH) + bootchooser_target_set_priority(target, priority); + if (attempts > DONTTOUCH) + bootchooser_target_set_attempts(target, attempts); +} + +static int do_bootchooser(int argc, char *argv[]) +{ + int opt, ret = 0, i; + struct bootchooser *bootchooser; + struct bootchooser_target *target; + int attempts = DONTTOUCH; + int priority = DONTTOUCH; + int info = 0; + bool done_something = false; + bool last_boot_successful = false; + + while ((opt = getopt(argc, argv, "a:p:is")) > 0) { + switch (opt) { + case 'a': + if (!strcmp(optarg, "default")) + attempts = DEFAULT; + else + attempts = simple_strtoul(optarg, NULL, 0); + break; + case 'p': + if (!strcmp(optarg, "default")) + priority = DEFAULT; + else + priority = simple_strtoul(optarg, NULL, 0); + break; + case 'i': + info = 1; + break; + case 's': + last_boot_successful = true; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + bootchooser = bootchooser_get(); + if (IS_ERR(bootchooser)) { + printf("No bootchooser found\n"); + return COMMAND_ERROR; + } + + if (last_boot_successful) { + bootchooser_last_boot_successful(); + done_something = true; + } + + if (attempts != DONTTOUCH || priority != DONTTOUCH) { + if (optind < argc) { + for (i = optind; i < argc; i++) { + target = bootchooser_target_by_name(bootchooser, argv[i]); + if (!target) { + printf("No such target: %s\n", argv[i]); + ret = COMMAND_ERROR; + goto out; + } + + target_reset(target, priority, attempts); + } + } else { + bootchooser_for_each_target(bootchooser, target) + target_reset(target, priority, attempts); + } + done_something = true; + } + + if (info) { + bootchooser_info(bootchooser); + done_something = true; + } + + if (!done_something) { + printf("Nothing to do\n"); + ret = COMMAND_ERROR_USAGE; + } +out: + bootchooser_put(bootchooser); + + return ret; +} + +BAREBOX_CMD_HELP_START(bootchooser) +BAREBOX_CMD_HELP_TEXT("Control misc behaviour of the bootchooser") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-a <n|default> [TARGETS]", "set priority of given targets to 'n' or the default priority") +BAREBOX_CMD_HELP_OPT ("-p <n|default> [TARGETS]", "set remaining attempts of given targets to 'n' or the default attempts") +BAREBOX_CMD_HELP_OPT ("-i", "Show information about the bootchooser") +BAREBOX_CMD_HELP_OPT ("-s", "Mark the last boot successful") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(bootchooser) + .cmd = do_bootchooser, + BAREBOX_CMD_DESC("bootchooser control") + BAREBOX_CMD_GROUP(CMD_GRP_MISC) + BAREBOX_CMD_HELP(cmd_bootchooser_help) +BAREBOX_CMD_END diff --git a/commands/bootm.c b/commands/bootm.c index 61b9086a15..c7cbdbe0f4 100644 --- a/commands/bootm.c +++ b/commands/bootm.c @@ -97,7 +97,7 @@ static int do_bootm(int argc, char *argv[]) data.dryrun = 1; break; default: - break; + return COMMAND_ERROR_USAGE; } } diff --git a/commands/dhcp.c b/commands/dhcp.c index eb98bfc2a7..4f4f5490c5 100644 --- a/commands/dhcp.c +++ b/commands/dhcp.c @@ -45,6 +45,8 @@ static int do_dhcp(int argc, char *argv[]) case 'r': retries = simple_strtoul(optarg, NULL, 10); break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/fbtest.c b/commands/fbtest.c index d070d1f7ab..bd0e140d07 100644 --- a/commands/fbtest.c +++ b/commands/fbtest.c @@ -137,6 +137,8 @@ static int do_fbtest(int argc, char *argv[]) case 'c': color = simple_strtoul(optarg, NULL, 16); break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/global.c b/commands/global.c index 581913d289..d21b82951c 100644 --- a/commands/global.c +++ b/commands/global.c @@ -25,14 +25,14 @@ static int do_global(int argc, char *argv[]) { - int opt; - int do_set_match = 0; + int opt, i; + int do_remove = 0; char *value; while ((opt = getopt(argc, argv, "r")) > 0) { switch (opt) { case 'r': - do_set_match = 1; + do_remove = 1; break; } } @@ -45,37 +45,36 @@ static int do_global(int argc, char *argv[]) argc -= optind; argv += optind; - if (argc != 1) + if (argc < 1) return COMMAND_ERROR_USAGE; - value = strchr(argv[0], '='); - if (value) { - *value = 0; - value++; - } - - if (do_set_match) { - if (!value) - value = ""; + for (i = 0; i < argc; i++) { + value = strchr(argv[i], '='); + if (value) { + *value = 0; + value++; + } - globalvar_set_match(argv[0], value); - return 0; + if (do_remove) + globalvar_remove(argv[i]); + else + globalvar_add_simple(argv[i], value); } - return globalvar_add_simple(argv[0], value); + return 0; } BAREBOX_CMD_HELP_START(global) BAREBOX_CMD_HELP_TEXT("Add a new global variable named VAR, optionally set to VALUE.") BAREBOX_CMD_HELP_TEXT("") BAREBOX_CMD_HELP_TEXT("Options:") -BAREBOX_CMD_HELP_OPT("-r", "set value of all global variables beginning with 'match'") +BAREBOX_CMD_HELP_OPT("-r", "Remove globalvars") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(global) .cmd = do_global, BAREBOX_CMD_DESC("create or set global variables") - BAREBOX_CMD_OPTS("[-r] VAR[=VALUE]") + BAREBOX_CMD_OPTS("[-r] VAR[=VALUE] ...") BAREBOX_CMD_GROUP(CMD_GRP_ENV) BAREBOX_CMD_HELP(cmd_global_help) BAREBOX_CMD_END diff --git a/commands/hashsum.c b/commands/hashsum.c index d05e571fb9..70aab2c4bf 100644 --- a/commands/hashsum.c +++ b/commands/hashsum.c @@ -42,6 +42,8 @@ static int do_hash(char *algo, int argc, char *argv[]) key = optarg; keylen = strlen(key); break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/help.c b/commands/help.c index 3d36d9bf48..819c40653c 100644 --- a/commands/help.c +++ b/commands/help.c @@ -98,6 +98,8 @@ static int do_help(int argc, char *argv[]) case 'a': all = 1; break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/hwclock.c b/commands/hwclock.c index 6a0fe0342a..5073618675 100644 --- a/commands/hwclock.c +++ b/commands/hwclock.c @@ -123,6 +123,8 @@ static int do_hwclock(int argc, char *argv[]) ntp_to_hw = 1; ntpserver = optarg; break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/linux16.c b/commands/linux16.c index bb678bdb83..db8d08105f 100644 --- a/commands/linux16.c +++ b/commands/linux16.c @@ -176,6 +176,8 @@ static int do_linux16(int argc, char *argv[]) } } break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/loadb.c b/commands/loadb.c index 6180ce371a..8c3906ca42 100644 --- a/commands/loadb.c +++ b/commands/loadb.c @@ -634,8 +634,7 @@ static int do_load_serial_bin(int argc, char *argv[]) console_dev_name = optarg; break; default: - perror(argv[0]); - return 1; + return COMMAND_ERROR_USAGE; } } diff --git a/commands/loadxy.c b/commands/loadxy.c index a4b1bec94d..a2aab0fc85 100644 --- a/commands/loadxy.c +++ b/commands/loadxy.c @@ -67,8 +67,7 @@ static int do_loady(int argc, char *argv[]) cname = optarg; break; default: - perror(argv[0]); - return 1; + return COMMAND_ERROR_USAGE; } } diff --git a/commands/ls.c b/commands/ls.c index ce02f16c49..331a4d2015 100644 --- a/commands/ls.c +++ b/commands/ls.c @@ -143,6 +143,8 @@ static int do_ls(int argc, char *argv[]) case 'l': flags &= ~LS_COLUMN; break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/mem.c b/commands/mem.c index 907f1f76a8..29eaa80b23 100644 --- a/commands/mem.c +++ b/commands/mem.c @@ -74,7 +74,7 @@ int mem_parse_options(int argc, char *argv[], char *optstr, int *mode, *swab = 1; break; default: - return -1; + return COMMAND_ERROR_USAGE; } } diff --git a/commands/menu.c b/commands/menu.c index e1079fd51e..72db26e5d1 100644 --- a/commands/menu.c +++ b/commands/menu.c @@ -22,6 +22,7 @@ #include <menu.h> #include <getopt.h> #include <errno.h> +#include <libbb.h> #include <linux/err.h> typedef enum { @@ -146,9 +147,7 @@ static int do_menu_add(struct cmd_menu *cm) if (!m->name) goto free; - m->display = strdup(cm->description); - if (!m->display) - goto free; + menu_add_title(m, strdup(cm->description)); ret = menu_add(m); @@ -271,7 +270,23 @@ static int do_menu_list(struct cmd_menu *cm) } list_for_each_entry(m, &menus->list, list) { - printf("%s: %s\n", m->name, m->display? m->display : m->name); + printf("%s: ", m->name); + if (m->display_lines) { + static char outstr[256]; + int i; + + printf("\n"); + for (i = 0; i < m->display_lines; i++) + /* Conform to menu rendering logic */ + if (IS_ENABLED(CONFIG_SHELL_HUSH)) { + process_escape_sequence(m->display[i], outstr, 256); + printf("\t%s\n", outstr); + } else { + printf("\t%s\n", m->display[i]); + } + } else { + printf("%s\n", m->name); + } if (is_entry(cm)) print_entries(m); } diff --git a/commands/menutree.c b/commands/menutree.c index ea5f65f3a1..cf37b01601 100644 --- a/commands/menutree.c +++ b/commands/menutree.c @@ -26,6 +26,8 @@ static int do_menutree(int argc, char *argv[]) case 'm': path = optarg; break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/reset.c b/commands/reset.c index 830048049a..6eac532623 100644 --- a/commands/reset.c +++ b/commands/reset.c @@ -34,6 +34,8 @@ static int cmd_reset(int argc, char *argv[]) case 'f': shutdown_flag = 0; break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/saveenv.c b/commands/saveenv.c index 6f210b7ec1..bc1202f9a1 100644 --- a/commands/saveenv.c +++ b/commands/saveenv.c @@ -35,6 +35,8 @@ static int do_saveenv(int argc, char *argv[]) case 'z': envfs_flags |= ENVFS_FLAGS_FORCE_BUILT_IN; break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/splash.c b/commands/splash.c index 15b296b680..2b70b29683 100644 --- a/commands/splash.c +++ b/commands/splash.c @@ -41,6 +41,8 @@ static int do_splash(int argc, char *argv[]) case 'y': s.y = simple_strtoul(optarg, NULL, 0); break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/ubi.c b/commands/ubi.c index 65d2d256a8..26b521f374 100644 --- a/commands/ubi.c +++ b/commands/ubi.c @@ -14,10 +14,9 @@ static int do_ubiupdatevol(int argc, char *argv[]) { - int fd_img, fd_vol, ret = 0; + int count, fd_img, fd_vol, ret = 0; uint64_t size = 0; struct stat st; - unsigned int count; void *buf; if (argc - optind < 2) @@ -66,9 +65,10 @@ static int do_ubiupdatevol(int argc, char *argv[]) break; } - ret = write(fd_vol, buf, count); - if (ret < 0) { + count = write(fd_vol, buf, count); + if (count < 0) { perror("write"); + ret = 1; break; } diff --git a/commands/usb.c b/commands/usb.c index 48c6619fde..9a23aa229d 100644 --- a/commands/usb.c +++ b/commands/usb.c @@ -123,6 +123,8 @@ static int do_usb(int argc, char *argv[]) case 's': show = 1; break; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/commands/usbserial.c b/commands/usbserial.c index e80b315250..ad6bc63fcc 100644 --- a/commands/usbserial.c +++ b/commands/usbserial.c @@ -44,6 +44,8 @@ static int do_usbserial(int argc, char *argv[]) case 'd': usb_serial_unregister(); return 0; + default: + return COMMAND_ERROR_USAGE; } } diff --git a/common/Kconfig b/common/Kconfig index 3b86c79252..efd19494d6 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -342,7 +342,7 @@ config KALLSYMS This is useful to print a nice backtrace when an exception occurs. config RELOCATABLE - depends on PPC || ARM + depends on PPC || (ARM && !CPU_V8) bool "generate relocatable barebox binary" help A non relocatable barebox binary will run at it's compiled in @@ -471,7 +471,7 @@ config MENU select PROCESS_ESCAPE_SEQUENCE help a menu framework that allow us to create list menu to simplify - barebox and make it more user-frendly + barebox and make it more user-friendly config PASSWORD bool @@ -841,6 +841,7 @@ config DEFAULT_ENVIRONMENT_GENERIC_NEW select CMD_BASENAME select CMD_READLINK select CMD_DIRNAME + select CMD_TEST select NVVAR select CMD_NV select FLEXIBLE_BOOTARGS @@ -929,6 +930,12 @@ config STATE_CRYPTO See Documentation/devicetree/bindings/barebox/barebox,state.rst for more information. +config BOOTCHOOSER + bool "bootchooser infrastructure" + select ENVIRONMENT_VARIABLES + select OFTREE + select PARAMETER + config RESET_SOURCE bool "detect Reset cause" depends on GLOBALVAR @@ -1036,6 +1043,13 @@ config DEBUG_IMX35_UART Say Y here if you want kernel low-level debugging support on i.MX35. +config DEBUG_IMX50_UART + bool "i.MX50 Debug UART" + depends on ARCH_IMX50 + help + Say Y here if you want kernel low-level debugging support + on i.MX50. + config DEBUG_IMX51_UART bool "i.MX51 Debug UART" depends on ARCH_IMX51 @@ -1079,11 +1093,11 @@ config DEBUG_AM33XX_UART on AM33XX. config DEBUG_ROCKCHIP_UART - bool "RK31xx Debug UART" + bool "RK3xxx Debug UART" depends on ARCH_ROCKCHIP help Say Y here if you want kernel low-level debugging support - on RK31XX. + on RK3XXX. endchoice @@ -1118,7 +1132,7 @@ config DEBUG_OMAP_UART_PORT AM33XX: 0 - 2 config DEBUG_ROCKCHIP_UART_PORT - int "RK31xx UART debug port" if DEBUG_ROCKCHIP_UART + int "RK3xxx UART debug port" if DEBUG_ROCKCHIP_UART default 2 depends on ARCH_ROCKCHIP help diff --git a/common/Makefile b/common/Makefile index 00bc0e8834..a36ae5e91f 100644 --- a/common/Makefile +++ b/common/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SHELL_HUSH) += hush.o obj-$(CONFIG_SHELL_SIMPLE) += parser.o obj-$(CONFIG_STATE) += state/ obj-$(CONFIG_RATP) += ratp.o +obj-$(CONFIG_BOOTCHOOSER) += bootchooser.o obj-$(CONFIG_UIMAGE) += image.o uimage.o obj-$(CONFIG_FITIMAGE) += image-fit.o obj-$(CONFIG_MENUTREE) += menutree.o diff --git a/common/blspec.c b/common/blspec.c index f02f5e9ce3..82b61f8741 100644 --- a/common/blspec.c +++ b/common/blspec.c @@ -394,7 +394,8 @@ static bool entry_is_of_compatible(struct blspec_entry *entry) root = of_unflatten_dtb(fdt); if (IS_ERR(root)) { - ret = PTR_ERR(root); + ret = false; + root = NULL; goto out; } diff --git a/common/boot.c b/common/boot.c index df9cba5b22..123b874b3c 100644 --- a/common/boot.c +++ b/common/boot.c @@ -10,6 +10,7 @@ */ #include <environment.h> +#include <bootchooser.h> #include <globalvar.h> #include <magicvar.h> #include <watchdog.h> @@ -43,7 +44,7 @@ struct bootentries *bootentries_alloc(void) if (IS_ENABLED(CONFIG_MENU)) { bootentries->menu = menu_alloc(); - bootentries->menu->display = basprintf("boot"); + menu_add_title(bootentries->menu, basprintf("boot")); } return bootentries; @@ -61,8 +62,12 @@ void bootentries_free(struct bootentries *bootentries) be->release(be); } - if (bootentries->menu) + if (bootentries->menu) { + int i; + for (i = 0; i < bootentries->menu->display_lines; i++) + free(bootentries->menu->display[i]); free(bootentries->menu->display); + } free(bootentries->menu); free(bootentries); } @@ -165,7 +170,6 @@ static void bootscript_entry_release(struct bootentry *entry) struct bootentry_script *bs = container_of(entry, struct bootentry_script, entry); free(bs->scriptpath); - free(bs->entry.me.display); free(bs); } @@ -271,6 +275,12 @@ int bootentry_create_from_name(struct bootentries *bootentries, } } + if (IS_ENABLED(CONFIG_BOOTCHOOSER) && !strcmp(name, "bootchooser")) { + ret = bootchooser_create_bootentry(bootentries); + if (ret > 0) + found += ret; + } + if (!found) { char *path; @@ -320,6 +330,7 @@ void bootsources_menu(struct bootentries *bootentries, int timeout) menu_show(bootentries->menu); + menu_remove_entry(bootentries->menu, back_entry); free(back_entry); } diff --git a/common/bootchooser.c b/common/bootchooser.c new file mode 100644 index 0000000000..9c110f267e --- /dev/null +++ b/common/bootchooser.c @@ -0,0 +1,928 @@ +/* + * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de> + * Copyright (C) 2015 Marc Kleine-Budde <mkl@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#define pr_fmt(fmt) "bootchooser: " fmt + +#include <bootchooser.h> +#include <environment.h> +#include <globalvar.h> +#include <magicvar.h> +#include <command.h> +#include <libfile.h> +#include <common.h> +#include <malloc.h> +#include <printk.h> +#include <xfuncs.h> +#include <envfs.h> +#include <errno.h> +#include <fcntl.h> +#include <ioctl.h> +#include <libbb.h> +#include <state.h> +#include <stdio.h> +#include <init.h> +#include <crc.h> +#include <net.h> +#include <fs.h> +#include <reset_source.h> + +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/err.h> + +#define BOOTCHOOSER_PREFIX "global.bootchooser" + +static char *available_targets; +static char *state_prefix; +static int global_default_attempts = 3; +static int global_default_priority = 1; +static int disable_on_zero_attempts; +static int retry; +static int last_boot_successful; + +struct bootchooser { + struct bootentry entry; + struct list_head targets; + struct bootchooser_target *last_chosen; + + struct state *state; + char *state_prefix; + + int verbose; + int dryrun; +}; + +struct bootchooser_target { + struct bootchooser *bootchooser; + struct list_head list; + + /* state */ + unsigned int priority; + unsigned int remaining_attempts; + int id; + + /* spec */ + char *name; + unsigned int default_attempts; + unsigned int default_priority; + + char *boot; + + char *prefix; + char *state_prefix; +}; + +enum reset_attempts { + RESET_ATTEMPTS_POWER_ON, + RESET_ATTEMPTS_ALL_ZERO, +}; + +static unsigned long reset_attempts; + +enum reset_priorities { + RESET_PRIORITIES_ALL_ZERO, +}; + +static unsigned long reset_priorities; + +static int bootchooser_target_ok(struct bootchooser_target *target, const char **reason) +{ + if (!target->priority) { + if (reason) + *reason = "Target disabled (priority = 0)"; + return false; + } + + if (!target->remaining_attempts) { + if (reason) + *reason = "remaining attempts = 0"; + return false; + } + + if (reason) + *reason = "target OK"; + + return true; +} + +static void pr_target(struct bootchooser_target *target) +{ + const char *reason; + int ok; + + ok = bootchooser_target_ok(target, &reason); + + printf("%s\n" + " id: %u\n" + " priority: %u\n" + " default_priority: %u\n" + " remaining attempts: %u\n" + " default attempts: %u\n" + " boot: '%s'\n", + target->name, target->id, target->priority, target->default_priority, + target->remaining_attempts, target->default_attempts, + target->boot); + if (!ok) + printf(" disabled due to %s\n", reason); +} + +static int pr_setenv(struct bootchooser *bc, const char *fmt, ...) +{ + va_list ap; + int ret = 0; + char *str, *val; + const char *oldval; + + va_start(ap, fmt); + str = bvasprintf(fmt, ap); + va_end(ap); + + if (!str) + return -ENOMEM; + + val = strchr(str, '='); + if (!val) { + ret = -EINVAL; + goto err; + } + + *val++ = '\0'; + + oldval = getenv(str); + if (!oldval || strcmp(oldval, val)) { + if (bc->state) + ret = setenv(str, val); + else + ret = nvvar_add(str, val); + } + +err: + free(str); + + return ret; +} + +static const char *pr_getenv(const char *fmt, ...) +{ + va_list ap; + char *str; + const char *val; + + va_start(ap, fmt); + str = bvasprintf(fmt, ap); + va_end(ap); + + if (!str) + return NULL; + + val = getenv(str); + + free(str); + + return val; +} + +static int getenv_u32(const char *prefix, const char *name, uint32_t *retval) +{ + char *str; + const char *val; + + str = xasprintf("%s.%s", prefix, name); + + val = getenv(str); + + free(str); + + if (!val) + return -ENOENT; + + *retval = simple_strtoul(val, NULL, 0); + + return 0; +} + +static int bootchooser_target_compare(struct list_head *a, struct list_head *b) +{ + struct bootchooser_target *bootchooser_a = + list_entry(a, struct bootchooser_target, list); + struct bootchooser_target *bootchooser_b = + list_entry(b, struct bootchooser_target, list); + + /* order with descending priority */ + return bootchooser_a->priority >= bootchooser_b->priority ? -1 : 1; +} + +/** + * bootchooser_target_new - Create a new bootchooser target + * @bc: The bootchooser + * @name: The name of the new target + * + * Parses the variables associated with @name, creates a bootchooser + * target from it and returns it. + */ +static struct bootchooser_target *bootchooser_target_new(struct bootchooser *bc, + const char *name) +{ + struct bootchooser_target *target = xzalloc(sizeof(*target)); + const char *val; + int ret; + + target->name = xstrdup(name); + target->prefix = basprintf("%s.%s", BOOTCHOOSER_PREFIX, name); + target->state_prefix = basprintf("%s.%s", bc->state_prefix, name); + target->default_attempts = global_default_attempts; + target->default_priority = global_default_priority; + + getenv_u32(target->prefix, "default_priority", + &target->default_priority); + getenv_u32(target->prefix, "default_attempts", + &target->default_attempts); + + ret = getenv_u32(target->state_prefix, "priority", &target->priority); + if (ret) { + pr_warn("Cannot read priority for target %s, using default %d\n", + target->name, target->default_priority); + target->priority = target->default_priority; + } + + ret = getenv_u32(target->state_prefix, "remaining_attempts", &target->remaining_attempts); + if (ret) { + pr_warn("Cannot read remaining attempts for target %s, using default %d\n", + target->name, target->default_attempts); + target->remaining_attempts = target->default_attempts; + } + + if (target->remaining_attempts && !target->priority) { + pr_warn("Disabled target %s has remaining attempts %d, setting to 0\n", + target->name, target->remaining_attempts); + target->remaining_attempts = 0; + } + + val = pr_getenv("%s.boot", target->prefix); + if (!val) + val = target->name; + target->boot = xstrdup(val); + + return target; +} + +/** + * bootchooser_target_by_id - Return a target given its id + * + * Each target has an id, simply counted by the order they appear in + * global.bootchooser.targets. We start counting at one to leave 0 + * for detection of uninitialized variables. + */ +static struct bootchooser_target *bootchooser_target_by_id(struct bootchooser *bc, + uint32_t id) +{ + struct bootchooser_target *target; + + list_for_each_entry(target, &bc->targets, list) + if (target->id == id) + return target; + + return NULL; +} + +/** + * bootchooser_target_disable - Disable a bootchooser target + */ +static void bootchooser_target_disable(struct bootchooser_target *target) +{ + target->priority = 0; + target->remaining_attempts = 0; +} + +/** + * bootchooser_target_enabled - test if a target is enabled + * + * Returns true if a target is enabled, false if it's not. + */ +static bool bootchooser_target_enabled(struct bootchooser_target *target) +{ + return target->priority != 0; +} + +/** + * bootchooser_reset_attempts - reset remaining attempts of targets + * + * Reset the remaining_attempts counter of all enabled targets + * to their default values. + */ +static void bootchooser_reset_attempts(struct bootchooser *bc) +{ + struct bootchooser_target *target; + + bootchooser_for_each_target(bc, target) { + if (bootchooser_target_enabled(target)) + bootchooser_target_set_attempts(target, -1); + } +} + +/** + * bootchooser_reset_priorities - reset priorities of targets + * + * Reset the priorities counter of all targets to their default + * values. + */ +static void bootchooser_reset_priorities(struct bootchooser *bc) +{ + struct bootchooser_target *target; + + bootchooser_for_each_target(bc, target) + bootchooser_target_set_priority(target, -1); +} + +/** + * bootchooser_get - get a bootchooser instance + * + * This evaluates the different globalvars and eventually state variables, + * creates a bootchooser instance from it and returns it. + */ +struct bootchooser *bootchooser_get(void) +{ + struct bootchooser *bc; + struct bootchooser_target *target; + char *targets, *str, *freep = NULL, *delim; + int ret = -EINVAL, id = 1; + uint32_t last_chosen; + static int attempts_resetted; + + bc = xzalloc(sizeof(*bc)); + + if (*state_prefix) { + if (IS_ENABLED(CONFIG_STATE)) { + char *state_devname; + + delim = strchr(state_prefix, '.'); + if (!delim) { + pr_err("state_prefix '%s' has invalid format\n", + state_prefix); + goto err; + } + state_devname = xstrndup(state_prefix, delim - state_prefix); + bc->state_prefix = xstrdup(state_prefix); + bc->state = state_by_name(state_devname); + if (!bc->state) { + free(state_devname); + pr_err("Cannot get state '%s'\n", + state_devname); + ret = -ENODEV; + goto err; + } + free(state_devname); + } else { + pr_err("State disabled, cannot use nv.state_prefix=%s\n", + state_prefix); + ret = -ENODEV; + goto err; + } + } else { + bc->state_prefix = xstrdup("nv.bootchooser"); + } + + INIT_LIST_HEAD(&bc->targets); + + freep = targets = xstrdup(available_targets); + + while (1) { + str = strsep(&targets, " "); + if (!str || !*str) + break; + + target = bootchooser_target_new(bc, str); + if (!IS_ERR(target)) { + target->id = id; + list_add_sort(&target->list, &bc->targets, + bootchooser_target_compare); + } + + id++; + } + + if (id == 1) { + pr_err("Target list $global.bootchooser.targets is empty\n"); + goto err; + } + + if (list_empty(&bc->targets)) { + pr_err("No targets could be initialized\n"); + goto err; + } + + free(freep); + + if (test_bit(RESET_PRIORITIES_ALL_ZERO, &reset_priorities)) { + int priority = 0; + + bootchooser_for_each_target(bc, target) + priority += target->priority; + + if (!priority) { + pr_info("All targets disabled, re-enabling them\n"); + bootchooser_reset_priorities(bc); + } + } + + if (test_bit(RESET_ATTEMPTS_POWER_ON, &reset_attempts) && + reset_source_get() == RESET_POR && !attempts_resetted) { + pr_info("Power-on Reset, resetting remaining attempts\n"); + bootchooser_reset_attempts(bc); + attempts_resetted = 1; + } + + if (test_bit(RESET_ATTEMPTS_ALL_ZERO, &reset_attempts)) { + int attempts = 0; + + bootchooser_for_each_target(bc, target) + attempts += target->remaining_attempts; + + if (!attempts) { + pr_info("All enabled targets have 0 remaining attempts, resetting them\n"); + bootchooser_reset_attempts(bc); + } + } + + ret = getenv_u32(bc->state_prefix, "last_chosen", &last_chosen); + if (!ret && last_chosen > 0) { + bc->last_chosen = bootchooser_target_by_id(bc, last_chosen); + if (!bc->last_chosen) + pr_warn("Last booted target with id %d does not exist\n", last_chosen); + } + + if (bc->last_chosen && last_boot_successful) + bootchooser_target_set_attempts(bc->last_chosen, -1); + + if (disable_on_zero_attempts) { + bootchooser_for_each_target(bc, target) { + if (!target->remaining_attempts) { + pr_info("target %s has 0 remaining attempts, disabling\n", + target->name); + bootchooser_target_disable(target); + } + } + + } + + return bc; + +err: + free(freep); + free(bc); + + return ERR_PTR(ret); +} + +/** + * bootchooser_save - save a bootchooser to the backing store + * @bc: The bootchooser instance to save + * + * Return: 0 for success, negative error code otherwise + */ +int bootchooser_save(struct bootchooser *bc) +{ + struct bootchooser_target *target; + int ret; + + if (bc->last_chosen) + pr_setenv(bc, "%s.last_chosen=%d", bc->state_prefix, + bc->last_chosen->id); + + list_for_each_entry(target, &bc->targets, list) { + ret = pr_setenv(bc, "%s.remaining_attempts=%d", + target->state_prefix, + target->remaining_attempts); + if (ret) + return ret; + + ret = pr_setenv(bc, "%s.priority=%d", + target->state_prefix, target->priority); + if (ret) + return ret; + } + + if (IS_ENABLED(CONFIG_STATE) && bc->state) { + ret = state_save(bc->state); + if (ret) { + pr_err("Cannot save state: %s\n", strerror(-ret)); + return ret; + } + } else { + ret = nvvar_save(); + if (ret) { + pr_err("Cannot save nv variables: %s\n", strerror(-ret)); + return ret; + } + } + + return 0; +} + +/** + * bootchooser_put - release a bootchooser instance + * @bc: The bootchooser instance + * + * This releases a bootchooser instance and the memory associated with it. + */ +int bootchooser_put(struct bootchooser *bc) +{ + struct bootchooser_target *target, *tmp; + int ret; + + ret = bootchooser_save(bc); + if (ret) + pr_err("Failed to save bootchooser state: %s\n", strerror(-ret)); + + list_for_each_entry_safe(target, tmp, &bc->targets, list) { + free(target->boot); + free(target->prefix); + free(target->state_prefix); + free(target->name); + free(target); + } + + free(bc); + + return ret; +} + +/** + * bootchooser_info - Show information about a bootchooser instance + * @bc: The bootchooser + */ +void bootchooser_info(struct bootchooser *bc) +{ + struct bootchooser_target *target; + const char *reason; + int count = 0; + + printf("Good targets (first will be booted next):\n"); + list_for_each_entry(target, &bc->targets, list) { + if (bootchooser_target_ok(target, NULL)) { + count++; + pr_target(target); + } + } + + if (!count) + printf("none\n"); + + count = 0; + + printf("\nDisabled targets:\n"); + list_for_each_entry(target, &bc->targets, list) { + if (!bootchooser_target_ok(target, &reason)) { + count++; + pr_target(target); + } + } + + if (!count) + printf("none\n"); + + printf("\nlast booted target: %s\n", bc->last_chosen ? + bc->last_chosen->name : "unknown"); +} + +/** + * bootchooser_get_target - get the target that shall be booted next + * @bc: The bootchooser + * + * This is the heart of the bootchooser. This function selects the next + * target to boot and returns it. The remaining_attempts counter of the + * selected target is decreased and the bootchooser state is saved to the + * backend. + * + * Return: The next target + */ +struct bootchooser_target *bootchooser_get_target(struct bootchooser *bc) +{ + struct bootchooser_target *target; + + list_for_each_entry(target, &bc->targets, list) { + if (bootchooser_target_ok(target, NULL)) + goto found; + } + + pr_err("No valid targets found:\n"); + list_for_each_entry(target, &bc->targets, list) + pr_target(target); + + return ERR_PTR(-ENOENT); + +found: + target->remaining_attempts--; + + if (bc->verbose) + pr_info("name=%s decrementing remaining_attempts to %d\n", + target->name, target->remaining_attempts); + + if (bc->verbose) + pr_info("selected target '%s', boot '%s'\n", target->name, target->boot); + + bc->last_chosen = target; + + bootchooser_save(bc); + + return target; +} + +/** + * bootchooser_target_name - get the name of a target + * @target: The target + * + * Given a bootchooser target this function returns its name. + * + * Return: The name of the target + */ +const char *bootchooser_target_name(struct bootchooser_target *target) +{ + return target->name; +} + +/** + * bootchooser_target_by_name - get a target from name + * @bc: The bootchooser + * @name: The name of the target to retrieve + * + * Given a name this function returns the corresponding target. + * + * Return: The target if found, NULL otherwise + */ +struct bootchooser_target *bootchooser_target_by_name(struct bootchooser *bc, + const char *name) +{ + struct bootchooser_target *target; + + bootchooser_for_each_target(bc, target) + if (!strcmp(target->name, name)) + return target; + return NULL; +} + +/** + * bootchooser_target_set_attempts - set remaining attempts of a target + * @target: The target to change + * @attempts: The number of attempts + * + * This sets the number of remaining attempts for a bootchooser target. + * If @attempts is < 0 then the remaining attempts is reset to the default + * value. + * + * Return: 0 for success, negative error code otherwise + */ +int bootchooser_target_set_attempts(struct bootchooser_target *target, int attempts) +{ + if (attempts >= 0) + target->remaining_attempts = attempts; + else + target->remaining_attempts = target->default_attempts; + + return 0; +} + +/** + * bootchooser_target_set_priority - set priority of a target + * @target: The target to change + * @priority: The priority + * + * This sets the priority of a bootchooser target. If @priority is < 0 + * then the priority reset to the default value. + * + * Return: 0 for success, negative error code otherwise + */ +int bootchooser_target_set_priority(struct bootchooser_target *target, int priority) +{ + if (priority >= 0) + target->priority = priority; + else + target->priority = target->default_priority; + + return 0; +} + +/** + * bootchooser_target_first - get the first target from a bootchooser + * @bc: The bootchooser + * + * Gets the first target from a bootchooser, used for the bootchooser + * target iterator. + * + * Return: The first target or NULL if no target exists + */ +struct bootchooser_target *bootchooser_target_first(struct bootchooser *bc) +{ + return list_first_entry_or_null(&bc->targets, + struct bootchooser_target, list); +} + +/** + * bootchooser_target_next - get the next target from a bootchooser + * @bc: The bootchooser + * @target: The current target + * + * Gets the next target from a bootchooser, used for the bootchooser + * target iterator. + * + * Return: The first target or NULL if no more targets exist + */ +struct bootchooser_target *bootchooser_target_next(struct bootchooser *bc, + struct bootchooser_target *target) +{ + struct list_head *next = target->list.next; + + if (next == &bc->targets) + return NULL; + + return list_entry(next, struct bootchooser_target, list); +} + +/** + * bootchooser_last_boot_successful - tell that the last boot was successful + * + * This tells bootchooser that the last boot was successful. + */ +void bootchooser_last_boot_successful(void) +{ + last_boot_successful = true; +} + +/** + * bootchooser_get_last_chosen - get the target which was chosen last time + * @bc: The bootchooser + * + * Bootchooser stores the id of the target which was last booted in + * <state_prefix>.last_chosen. This function returns the target associated + * with this id. + * + * Return: The target which was booted last time + */ +struct bootchooser_target *bootchooser_get_last_chosen(struct bootchooser *bc) +{ + if (!bc->last_chosen) + return ERR_PTR(-ENODEV); + + return bc->last_chosen; +} + +static int bootchooser_boot_one(struct bootchooser *bc, int *tryagain) +{ + char *system; + struct bootentries *entries; + struct bootentry *entry; + struct bootchooser_target *target; + int ret = 0; + + entries = bootentries_alloc(); + + target = bootchooser_get_target(bc); + if (IS_ERR(target)) { + ret = PTR_ERR(target); + *tryagain = 0; + goto out; + } + + system = basprintf("bootchooser.active=%s", target->name); + globalvar_add_simple("linux.bootargs.bootchooser", system); + free(system); + + ret = bootentry_create_from_name(entries, target->boot); + if (ret <= 0) { + printf("Nothing bootable found on '%s'\n", target->boot); + *tryagain = 1; + ret = -ENODEV; + goto out; + } + + last_boot_successful = false; + + ret = -ENOENT; + + bootentries_for_each_entry(entries, entry) { + ret = boot_entry(entry, bc->verbose, bc->dryrun); + if (!ret) { + *tryagain = 0; + goto out; + } + } + + *tryagain = 1; +out: + globalvar_set_match("linux.bootargs.bootchooser", NULL); + + bootentries_free(entries); + + return ret; +} + +static int bootchooser_boot(struct bootentry *entry, int verbose, int dryrun) +{ + struct bootchooser *bc = container_of(entry, struct bootchooser, + entry); + int ret, tryagain; + + bc->verbose = verbose; + bc->dryrun = dryrun; + + do { + ret = bootchooser_boot_one(bc, &tryagain); + + if (!retry) + break; + } while (tryagain); + + return ret; +} + +static void bootchooser_release(struct bootentry *entry) +{ + struct bootchooser *bc = container_of(entry, struct bootchooser, + entry); + + bootchooser_put(bc); +} + +/** + * bootchooser_create_bootentry - create a boot entry + * @entries: The list of bootentries + * + * This adds a bootchooser to the list of boot entries. Called + * by the 'boot' code. + * + * Return: The number of entries added to the list + */ +int bootchooser_create_bootentry(struct bootentries *entries) +{ + struct bootchooser *bc = bootchooser_get(); + + if (IS_ERR(bc)) + return PTR_ERR(bc); + + bc->entry.boot = bootchooser_boot; + bc->entry.release = bootchooser_release; + bc->entry.title = xstrdup("bootchooser"); + bc->entry.description = xstrdup("bootchooser"); + + bootentries_add_entry(entries, &bc->entry); + + return 1; +} + +static const char * const reset_attempts_names[] = { + [RESET_ATTEMPTS_POWER_ON] = "power-on", + [RESET_ATTEMPTS_ALL_ZERO] = "all-zero", +}; + +static const char * const reset_priorities_names[] = { + [RESET_PRIORITIES_ALL_ZERO] = "all-zero", +}; + +static int bootchooser_init(void) +{ + state_prefix = xstrdup(""); + available_targets = xstrdup(""); + + globalvar_add_simple_bool("bootchooser.disable_on_zero_attempts", &disable_on_zero_attempts); + globalvar_add_simple_bool("bootchooser.retry", &retry); + globalvar_add_simple_string("bootchooser.targets", &available_targets); + globalvar_add_simple_string("bootchooser.state_prefix", &state_prefix); + globalvar_add_simple_int("bootchooser.default_attempts", &global_default_attempts, "%u"); + globalvar_add_simple_int("bootchooser.default_priority", &global_default_priority, "%u"); + globalvar_add_simple_bitmask("bootchooser.reset_attempts", &reset_attempts, + reset_attempts_names, ARRAY_SIZE(reset_attempts_names)); + globalvar_add_simple_bitmask("bootchooser.reset_priorities", &reset_priorities, + reset_priorities_names, ARRAY_SIZE(reset_priorities_names)); + return 0; +} +device_initcall(bootchooser_init); + +BAREBOX_MAGICVAR_NAMED(global_bootchooser_disable_on_zero_attempts, + global.bootchooser.disable_on_zero_attempts, + "bootchooser: Disable target when remaining attempts counter reaches 0"); +BAREBOX_MAGICVAR_NAMED(global_bootchooser_retry, + global.bootchooser.retry, + "bootchooser: Try again when booting a target fails"); +BAREBOX_MAGICVAR_NAMED(global_bootchooser_targets, + global.bootchooser.targets, + "bootchooser: Space separated list of target names"); +BAREBOX_MAGICVAR_NAMED(global_bootchooser_default_attempts, + global.bootchooser.default_attempts, + "bootchooser: Default number of attempts for a target"); +BAREBOX_MAGICVAR_NAMED(global_bootchooser_default_priority, + global.bootchooser.default_priority, + "bootchooser: Default priority for a target"); +BAREBOX_MAGICVAR_NAMED(global_bootchooser_state_prefix, + global.bootchooser.state_prefix, + "bootchooser: state name prefix, empty for nv backend"); diff --git a/common/bootm.c b/common/bootm.c index 78d04d5806..59843195cd 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -336,6 +336,9 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address) if (data->os_fit && data->os_fit->oftree) { data->of_root_node = of_unflatten_dtb(data->os_fit->oftree); + + if (IS_ERR(data->of_root_node)) + data->of_root_node = NULL; } else if (data->oftree_file) { size_t size; @@ -367,7 +370,8 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address) free(oftree); - if (!data->of_root_node) { + if (IS_ERR(data->of_root_node)) { + data->of_root_node = NULL; pr_err("unable to unflatten devicetree\n"); return -EINVAL; } diff --git a/common/filetype.c b/common/filetype.c index a8666a1439..4728f877c9 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -61,6 +61,7 @@ static const struct filetype_str filetype_str[] = { [filetype_xz_compressed] = { "XZ compressed", "xz" }, [filetype_exe] = { "MS-DOS executable", "exe" }, [filetype_mxs_bootstream] = { "Freescale MXS bootstream", "mxsbs" }, + [filetype_socfpga_xload] = { "SoCFPGA prebootloader image", "socfpga-xload" }, }; const char *file_type_to_string(enum filetype f) @@ -294,6 +295,9 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) if (le32_to_cpu(buf[5]) == 0x504d5453) return filetype_mxs_bootstream; + if (buf[16] == 0x31305341) + return filetype_socfpga_xload; + if (is_barebox_arm_head(_buf)) return filetype_arm_barebox; if (buf[9] == 0x016f2818 || buf[9] == 0x18286f01) diff --git a/common/globalvar.c b/common/globalvar.c index 44e6528f6c..fb69db973a 100644 --- a/common/globalvar.c +++ b/common/globalvar.c @@ -36,6 +36,9 @@ int globalvar_add(const char *name, { struct param_d *param; + if (!strncmp(name, "global.", 7)) + name += 7; + param = dev_add_param(&global_device, name, set, get, flags); if (IS_ERR(param)) return PTR_ERR(param); @@ -44,12 +47,14 @@ int globalvar_add(const char *name, void globalvar_remove(const char *name) { - struct param_d *param = get_param_by_name(&global_device, name); + struct param_d *p, *tmp; - if (!param) - return; + list_for_each_entry_safe(p, tmp, &global_device.parameters, list) { + if (fnmatch(name, p->name, 0)) + continue; - dev_remove_param(param); + dev_remove_param(p); + } } static int __nv_save(const char *prefix, const char *name, const char *val) @@ -177,34 +182,14 @@ static int nvvar_device_dispatch(const char *name, struct device_d **dev, static int nv_set(struct device_d *dev, struct param_d *p, const char *val) { int ret; - int devspace; - struct device_d *rdev; - const char *pname; if (!val) val = ""; - ret = nvvar_device_dispatch(p->name, &rdev, &pname); - if (ret < 0) + ret = dev_set_param(&global_device, p->name, val); + if (ret) return ret; - devspace = ret; - - if (devspace) { - if (rdev) { - ret = dev_set_param(rdev, pname, val); - if (ret) { - pr_err("Cannot init param from nv: %s.%s=%s: %s\n", - dev_name(rdev), pname, val, strerror(-ret)); - return ret; - } - } - } else { - ret = dev_set_param(&global_device, p->name, val); - if (ret) - return ret; - } - free(p->value); p->value = xstrdup(val); @@ -229,54 +214,27 @@ static int nv_param_set(struct device_d *dev, struct param_d *p, const char *val static int __nvvar_add(const char *name, const char *value) { - struct param_d *p, *gp; + struct param_d *p; int ret; - int devspace; - struct device_d *dev; - const char *pname; if (!IS_ENABLED(CONFIG_NVVAR)) return -ENOSYS; - ret = nvvar_device_dispatch(name, &dev, &pname); - if (ret < 0) - return ret; - - devspace = ret; - - gp = get_param_by_name(&nv_device, name); - if (gp) { - if (!devspace) { - ret = dev_set_param(&global_device, name, value); - if (ret) - return ret; - } - - ret = dev_set_param(&nv_device, name, value); - if (ret) - return ret; - - return 0; + /* Get param. If it doesn't exist yet, create it */ + p = get_param_by_name(&nv_device, name); + if (!p) { + p = dev_add_param(&nv_device, name, nv_param_set, nv_param_get, 0); + if (IS_ERR(p)) + return PTR_ERR(p); } - if (!devspace) { - ret = globalvar_add_simple(name, value); - if (ret && ret != -EEXIST) - return ret; - } - - p = dev_add_param(&nv_device, name, nv_param_set, nv_param_get, 0); - if (IS_ERR(p)) - return PTR_ERR(p); + /* Create corresponding globalvar if it doesn't exist yet */ + ret = globalvar_add_simple(name, value); + if (ret && ret != -EEXIST) + return ret; - if (!value) { - if (devspace) { - if (dev) - value = dev_get_param(dev, pname); - } else { - value = dev_get_param(&global_device, name); - } - } + if (!value) + value = dev_get_param(&global_device, name); return nv_set(&nv_device, p, value); } @@ -285,6 +243,9 @@ int nvvar_add(const char *name, const char *value) { int ret; + if (!strncmp(name, "nv.", 3)) + name += 3; + ret = __nvvar_add(name, value); if (ret) return ret; @@ -418,6 +379,27 @@ void globalvar_set_match(const char *match, const char *val) } } +int globalvar_simple_set(struct device_d *dev, struct param_d *p, const char *val) +{ + struct device_d *rdev; + const char *pname; + int ret; + + ret = nvvar_device_dispatch(p->name, &rdev, &pname); + if (ret < 0) + return ret; + + if (ret && rdev) { + ret = dev_set_param(rdev, pname, val); + if (ret) + pr_err("Cannot init param from global: %s.%s=%s: %s\n", + dev_name(rdev), pname, val, strerror(-ret)); + } + + /* Pass to the generic function we have overwritten */ + return dev_param_set_generic(dev, p, val); +} + /* * globalvar_add_simple * @@ -425,11 +407,14 @@ void globalvar_set_match(const char *match, const char *val) */ int globalvar_add_simple(const char *name, const char *value) { - int ret; + struct param_d *param; - ret = globalvar_add(name, NULL, NULL, 0); - if (ret && ret != -EEXIST) - return ret; + param = dev_add_param(&global_device, name, globalvar_simple_set, NULL, + PARAM_GLOBALVAR_UNQUALIFIED); + if (IS_ERR(param)) { + if (PTR_ERR(param) != -EEXIST) + return PTR_ERR(param); + } if (!value) return 0; @@ -437,6 +422,147 @@ int globalvar_add_simple(const char *name, const char *value) return dev_set_param(&global_device, name, value); } +static int globalvar_remove_unqualified(const char *name) +{ + struct param_d *p; + + p = get_param_by_name(&global_device, name); + if (!p) + return 0; + + if (!(p->flags & PARAM_GLOBALVAR_UNQUALIFIED)) + return -EEXIST; + + dev_remove_param(p); + + return 0; +} + +static void globalvar_nv_sync(const char *name) +{ + const char *val; + + val = dev_get_param(&nv_device, name); + if (val) + dev_set_param(&global_device, name, val); +} + +int globalvar_add_simple_string(const char *name, char **value) +{ + struct param_d *p; + int ret; + + ret = globalvar_remove_unqualified(name); + if (ret) + return ret; + + p = dev_add_param_string(&global_device, name, NULL, NULL, + value, NULL); + + if (IS_ERR(p)) + return PTR_ERR(p); + + globalvar_nv_sync(name); + + return 0; +} + +int globalvar_add_simple_int(const char *name, int *value, + const char *format) +{ + struct param_d *p; + int ret; + + ret = globalvar_remove_unqualified(name); + if (ret) + return ret; + + p = dev_add_param_int(&global_device, name, NULL, NULL, + value, format, NULL); + + if (IS_ERR(p)) + return PTR_ERR(p); + + globalvar_nv_sync(name); + + return 0; +} + +int globalvar_add_simple_bool(const char *name, int *value) +{ + struct param_d *p; + int ret; + + ret = globalvar_remove_unqualified(name); + if (ret) + return ret; + + p = dev_add_param_bool(&global_device, name, NULL, NULL, + value, NULL); + + if (IS_ERR(p)) + return PTR_ERR(p); + + globalvar_nv_sync(name); + + return 0; +} + +int globalvar_add_simple_enum(const char *name, int *value, + const char * const *names, int max) +{ + struct param_d *p; + int ret; + + ret = globalvar_remove_unqualified(name); + if (ret) + return ret; + + p = dev_add_param_enum(&global_device, name, NULL, NULL, + value, names, max, NULL); + + if (IS_ERR(p)) + return PTR_ERR(p); + + globalvar_nv_sync(name); + + return 0; +} + +int globalvar_add_simple_bitmask(const char *name, unsigned long *value, + const char * const *names, int max) +{ + struct param_d *p; + + p = dev_add_param_bitmask(&global_device, name, NULL, NULL, + value, names, max, NULL); + + if (IS_ERR(p)) + return PTR_ERR(p); + + return 0; +} + +int globalvar_add_simple_ip(const char *name, IPaddr_t *ip) +{ + struct param_d *p; + int ret; + + ret = globalvar_remove_unqualified(name); + if (ret) + return ret; + + p = dev_add_param_ip(&global_device, name, NULL, NULL, + ip, NULL); + + if (IS_ERR(p)) + return PTR_ERR(p); + + globalvar_nv_sync(name); + + return 0; +} + static int globalvar_init(void) { register_device(&global_device); @@ -471,6 +597,7 @@ int nvvar_save(void) defaultenv_load(TMPDIR, 0); envfs_load(env, TMPDIR, 0); + unlink_recursive(TMPDIR "/nv", NULL); list_for_each_entry(param, &nv_device.parameters, list) { ret = __nv_save(TMPDIR "/nv", param->name, diff --git a/common/menu.c b/common/menu.c index 9819569f6f..64df458e68 100644 --- a/common/menu.c +++ b/common/menu.c @@ -43,10 +43,13 @@ EXPORT_SYMBOL(menu_get_menus); void menu_free(struct menu *m) { struct menu_entry *me, *tmp; + int i; if (!m) return; free(m->name); + for (i = 0; i < m->display_lines; i++) + free(m->display[i]); free(m->display); free(m->auto_display); @@ -164,7 +167,7 @@ static void __print_entry(const char *str) static void print_menu_entry(struct menu *m, struct menu_entry *me, int selected) { - gotoXY(3, me->num + 1); + gotoXY(3, me->num + m->display_lines); if (me->type == MENU_ENTRY_BOX) { if (me->box_state) @@ -232,14 +235,12 @@ EXPORT_SYMBOL(menu_set_auto_select); static void print_menu(struct menu *m) { struct menu_entry *me; + int i; clear(); - gotoXY(2, 1); - if(m->display) { - __print_entry(m->display); - } else { - puts("Menu : "); - puts(m->name); + for (i = 0; i < m->display_lines; i++) { + gotoXY(2, 1 + i); + __print_entry(m->display[i]); } list_for_each_entry(me, &m->entries, list) { @@ -269,7 +270,7 @@ int menu_show(struct menu *m) countdown = m->auto_select; if (m->auto_select >= 0) { - gotoXY(3, m->nb_entries + 2); + gotoXY(3, m->nb_entries + m->display_lines + 1); if (!m->auto_display) { printf("Auto Select in"); } else { @@ -293,10 +294,10 @@ int menu_show(struct menu *m) } } - gotoXY(3, m->nb_entries + 2); + gotoXY(3, m->nb_entries + m->display_lines + 1); printf("%*c", auto_display_len + 4, ' '); - gotoXY(3, m->selected->num + 1); + gotoXY(3, m->selected->num + m->display_lines); do { struct menu_entry *old_selected = m->selected; @@ -517,3 +518,63 @@ err_free: return ERR_PTR(ret); } EXPORT_SYMBOL(menu_add_command_entry); + +/* + * Add title to menu. + * Lines are separated by explicit char '\n' or by string "\n". + * + * @display: NULL or pointer to the string which will be freed in this function. + * If NULL or zero length string is provided, default title will be added. + */ +void menu_add_title(struct menu *m, char *display) +{ + char *tmp, *src, *dst; + int lines = 1; + int i; + + if (!display || !strlen(display)) { + free(display); + display = xasprintf("Menu : %s", m->name ? m->name : ""); + } + + src = dst = tmp = xstrdup(display); + /* Count lines and separate single string into multiple strings */ + while (*src) { + if (*src == '\\') { + if (*(src + 1) == '\\') { + *dst++ = *src++; + *dst++ = *src++; + continue; + } + if (*(src + 1) == 'n') { + *dst = 0; + src += 2; + dst++; + lines++; + continue; + } + } + if (*src == '\n') { + *dst = 0; + src++; + dst++; + lines++; + continue; + } + *dst++ = *src++; + } + *dst = 0; + + m->display = xzalloc(sizeof(*m->display) * lines); + m->display_lines = lines; + + for (src = tmp, i = 0; i < lines; i++) { + m->display[i] = xstrdup(src); + /* Go to the next line */ + src += strlen(src) + 1; + } + + free(tmp); + free(display); +} +EXPORT_SYMBOL(menu_add_title); diff --git a/common/menutree.c b/common/menutree.c index eb14da0d01..400d1a6939 100644 --- a/common/menutree.c +++ b/common/menutree.c @@ -19,6 +19,7 @@ #include <shell.h> #include <libfile.h> +#include <linux/ctype.h> #include <linux/stat.h> struct menutree { @@ -95,6 +96,7 @@ int menutree(const char *path, int toplevel) glob_t g; int i; char *globpath, *display; + size_t size; menu = menu_alloc(); @@ -106,14 +108,17 @@ int menutree(const char *path, int toplevel) goto out; } - display = read_file_line("%s/title", path); + globpath = basprintf("%s/title", path); + display = read_file(globpath, &size); + free(globpath); if (!display) { eprintf("no title found in %s/title\n", path); ret = -EINVAL; goto out; } - menu->display = shell_expand(display); + strim(display); + menu_add_title(menu, shell_expand(display)); free(display); for (i = 0; i < g.gl_pathc; i++) { diff --git a/defaultenv/defaultenv-1/bin/boot b/defaultenv/defaultenv-1/bin/boot index c17ccdb8f5..a5d6596d2d 100644 --- a/defaultenv/defaultenv-1/bin/boot +++ b/defaultenv/defaultenv-1/bin/boot @@ -2,6 +2,10 @@ . /env/config +if [ -f /env/bin/boot_board ]; then + . /env/bin/boot_board +fi + if [ x$kernel_loc = xnet ]; then kernel_loc=tftp fi diff --git a/defaultenv/defaultenv-1/bin/init b/defaultenv/defaultenv-1/bin/init index a55d293f03..2dcddbef2c 100644 --- a/defaultenv/defaultenv-1/bin/init +++ b/defaultenv/defaultenv-1/bin/init @@ -23,9 +23,8 @@ if [ -f /env/bin/init_board ]; then fi echo -e "\e[?25h" -if [ -f /env/bin/boot_board ]; then - . /env/bin/boot_board -elif [ -n $autoboot_timeout ]; then + +if [ -n $autoboot_timeout ]; then echo -n "Hit any key to stop autoboot: " timeout -a $autoboot_timeout if [ $? != 0 ]; then diff --git a/defaultenv/defaultenv-2-base/init/automount b/defaultenv/defaultenv-2-base/init/automount index fd1f5a6f49..959b2c148e 100644 --- a/defaultenv/defaultenv-2-base/init/automount +++ b/defaultenv/defaultenv-2-base/init/automount @@ -1,10 +1,5 @@ #!/bin/sh -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Automountpoints" - exit -fi - # automount tftp server based on $eth0.serverip mkdir -p /mnt/tftp diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 865542a814..e43f57304c 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -1 +1,3 @@ -obj-y += clk-cpu.o clk-pll.o clk-rk3188.o clk.o +obj-y += clk-cpu.o clk-pll.o clk.o +obj-$(CONFIG_ARCH_RK3188) += clk-rk3188.o +obj-$(CONFIG_ARCH_RK3288) += clk-rk3288.o diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c new file mode 100644 index 0000000000..bb111e1e0b --- /dev/null +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -0,0 +1,836 @@ +/* + * Copyright (c) 2014 MundoReader S.L. + * Author: Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <linux/clk.h> +#include <of.h> +#include <of_address.h> +#include <dt-bindings/clock/rk3288-cru.h> +#include "clk.h" +#include <linux/barebox-wrapper.h> +#include <init.h> + +#define RK3288_GRF_SOC_CON(x) (0x244 + x * 4) +#define RK3288_GRF_SOC_STATUS1 0x284 + +#define CLK_SET_RATE_NO_REPARENT 0 +#define CLK_DIVIDER_READ_ONLY 0 + +enum rk3288_plls { + apll, dpll, cpll, gpll, npll, +}; + +static struct rockchip_pll_rate_table rk3288_pll_rates[] = { + RK3066_PLL_RATE(2208000000, 1, 92, 1), + RK3066_PLL_RATE(2184000000, 1, 91, 1), + RK3066_PLL_RATE(2160000000, 1, 90, 1), + RK3066_PLL_RATE(2136000000, 1, 89, 1), + RK3066_PLL_RATE(2112000000, 1, 88, 1), + RK3066_PLL_RATE(2088000000, 1, 87, 1), + RK3066_PLL_RATE(2064000000, 1, 86, 1), + RK3066_PLL_RATE(2040000000, 1, 85, 1), + RK3066_PLL_RATE(2016000000, 1, 84, 1), + RK3066_PLL_RATE(1992000000, 1, 83, 1), + RK3066_PLL_RATE(1968000000, 1, 82, 1), + RK3066_PLL_RATE(1944000000, 1, 81, 1), + RK3066_PLL_RATE(1920000000, 1, 80, 1), + RK3066_PLL_RATE(1896000000, 1, 79, 1), + RK3066_PLL_RATE(1872000000, 1, 78, 1), + RK3066_PLL_RATE(1848000000, 1, 77, 1), + RK3066_PLL_RATE(1824000000, 1, 76, 1), + RK3066_PLL_RATE(1800000000, 1, 75, 1), + RK3066_PLL_RATE(1776000000, 1, 74, 1), + RK3066_PLL_RATE(1752000000, 1, 73, 1), + RK3066_PLL_RATE(1728000000, 1, 72, 1), + RK3066_PLL_RATE(1704000000, 1, 71, 1), + RK3066_PLL_RATE(1680000000, 1, 70, 1), + RK3066_PLL_RATE(1656000000, 1, 69, 1), + RK3066_PLL_RATE(1632000000, 1, 68, 1), + RK3066_PLL_RATE(1608000000, 1, 67, 1), + RK3066_PLL_RATE(1560000000, 1, 65, 1), + RK3066_PLL_RATE(1512000000, 1, 63, 1), + RK3066_PLL_RATE(1488000000, 1, 62, 1), + RK3066_PLL_RATE(1464000000, 1, 61, 1), + RK3066_PLL_RATE(1440000000, 1, 60, 1), + RK3066_PLL_RATE(1416000000, 1, 59, 1), + RK3066_PLL_RATE(1392000000, 1, 58, 1), + RK3066_PLL_RATE(1368000000, 1, 57, 1), + RK3066_PLL_RATE(1344000000, 1, 56, 1), + RK3066_PLL_RATE(1320000000, 1, 55, 1), + RK3066_PLL_RATE(1296000000, 1, 54, 1), + RK3066_PLL_RATE(1272000000, 1, 53, 1), + RK3066_PLL_RATE(1248000000, 1, 52, 1), + RK3066_PLL_RATE(1224000000, 1, 51, 1), + RK3066_PLL_RATE(1200000000, 1, 50, 1), + RK3066_PLL_RATE(1188000000, 2, 99, 1), + RK3066_PLL_RATE(1176000000, 1, 49, 1), + RK3066_PLL_RATE(1128000000, 1, 47, 1), + RK3066_PLL_RATE(1104000000, 1, 46, 1), + RK3066_PLL_RATE(1008000000, 1, 84, 2), + RK3066_PLL_RATE( 912000000, 1, 76, 2), + RK3066_PLL_RATE( 891000000, 8, 594, 2), + RK3066_PLL_RATE( 888000000, 1, 74, 2), + RK3066_PLL_RATE( 816000000, 1, 68, 2), + RK3066_PLL_RATE( 798000000, 2, 133, 2), + RK3066_PLL_RATE( 792000000, 1, 66, 2), + RK3066_PLL_RATE( 768000000, 1, 64, 2), + RK3066_PLL_RATE( 742500000, 8, 495, 2), + RK3066_PLL_RATE( 696000000, 1, 58, 2), + RK3066_PLL_RATE( 600000000, 1, 50, 2), + RK3066_PLL_RATE_BWADJ(594000000, 1, 198, 8, 1), + RK3066_PLL_RATE( 552000000, 1, 46, 2), + RK3066_PLL_RATE( 504000000, 1, 84, 4), + RK3066_PLL_RATE( 500000000, 3, 125, 2), + RK3066_PLL_RATE( 456000000, 1, 76, 4), + RK3066_PLL_RATE( 408000000, 1, 68, 4), + RK3066_PLL_RATE( 400000000, 3, 100, 2), + RK3066_PLL_RATE( 384000000, 2, 128, 4), + RK3066_PLL_RATE( 360000000, 1, 60, 4), + RK3066_PLL_RATE( 312000000, 1, 52, 4), + RK3066_PLL_RATE( 300000000, 1, 50, 4), + RK3066_PLL_RATE( 297000000, 2, 198, 8), + RK3066_PLL_RATE( 252000000, 1, 84, 8), + RK3066_PLL_RATE( 216000000, 1, 72, 8), + RK3066_PLL_RATE( 148500000, 2, 99, 8), + RK3066_PLL_RATE( 126000000, 1, 84, 16), + RK3066_PLL_RATE( 48000000, 1, 64, 32), + { /* sentinel */ }, +}; + +#define RK3288_DIV_ACLK_CORE_M0_MASK 0xf +#define RK3288_DIV_ACLK_CORE_M0_SHIFT 0 +#define RK3288_DIV_ACLK_CORE_MP_MASK 0xf +#define RK3288_DIV_ACLK_CORE_MP_SHIFT 4 +#define RK3288_DIV_L2RAM_MASK 0x7 +#define RK3288_DIV_L2RAM_SHIFT 0 +#define RK3288_DIV_ATCLK_MASK 0x1f +#define RK3288_DIV_ATCLK_SHIFT 4 +#define RK3288_DIV_PCLK_DBGPRE_MASK 0x1f +#define RK3288_DIV_PCLK_DBGPRE_SHIFT 9 + +#define RK3288_CLKSEL0(_core_m0, _core_mp) \ + { \ + .reg = RK3288_CLKSEL_CON(0), \ + .val = HIWORD_UPDATE(_core_m0, RK3288_DIV_ACLK_CORE_M0_MASK, \ + RK3288_DIV_ACLK_CORE_M0_SHIFT) | \ + HIWORD_UPDATE(_core_mp, RK3288_DIV_ACLK_CORE_MP_MASK, \ + RK3288_DIV_ACLK_CORE_MP_SHIFT), \ + } +#define RK3288_CLKSEL37(_l2ram, _atclk, _pclk_dbg_pre) \ + { \ + .reg = RK3288_CLKSEL_CON(37), \ + .val = HIWORD_UPDATE(_l2ram, RK3288_DIV_L2RAM_MASK, \ + RK3288_DIV_L2RAM_SHIFT) | \ + HIWORD_UPDATE(_atclk, RK3288_DIV_ATCLK_MASK, \ + RK3288_DIV_ATCLK_SHIFT) | \ + HIWORD_UPDATE(_pclk_dbg_pre, \ + RK3288_DIV_PCLK_DBGPRE_MASK, \ + RK3288_DIV_PCLK_DBGPRE_SHIFT), \ + } + +#define RK3288_CPUCLK_RATE(_prate, _core_m0, _core_mp, _l2ram, _atclk, _pdbg) \ + { \ + .prate = _prate, \ + .divs = { \ + RK3288_CLKSEL0(_core_m0, _core_mp), \ + RK3288_CLKSEL37(_l2ram, _atclk, _pdbg), \ + }, \ + } + +static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = { + RK3288_CPUCLK_RATE(1800000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1704000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1608000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1512000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1416000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1200000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1008000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 816000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 696000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 600000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 408000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 312000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 216000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 126000000, 1, 3, 1, 3, 3), +}; + +static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { + .core_reg = RK3288_CLKSEL_CON(0), + .div_core_shift = 8, + .div_core_mask = 0x1f, + .mux_core_shift = 15, +}; + +PNAME(mux_pll_p) = { "xin24m", "xin32k" }; +PNAME(mux_armclk_p) = { "apll_core", "gpll_core" }; +PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; +PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" }; + +PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; +PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; +PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; +PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" }; +PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" }; + +PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; +PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; +PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" }; +PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" }; +PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" }; +PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; +PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; +PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; +PNAME(mux_uart3_p) = { "uart3_src", "uart3_frac", "xin24m" }; +PNAME(mux_uart4_p) = { "uart4_src", "uart4_frac", "xin24m" }; +PNAME(mux_vip_out_p) = { "vip_src", "xin24m" }; +PNAME(mux_mac_p) = { "mac_pll_src", "ext_gmac" }; +PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; +PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; +PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; + +PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2", + "sclk_otgphy0" }; +PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; +PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; + +static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { + [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK3288_PLL_CON(0), + RK3288_MODE_CON, 0, 6, 0, rk3288_pll_rates), + [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4), + RK3288_MODE_CON, 4, 5, 0, NULL), + [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8), + RK3288_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), + RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), + [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), + RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), +}; + +static struct clk_div_table div_hclk_cpu_t[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 3, .div = 4 }, + { /* sentinel */}, +}; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { + /* + * Clock-Architecture Diagram 1 + */ + + GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(0), 1, GFLAGS), + GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(0), 2, GFLAGS), + + COMPOSITE_NOMUX(0, "armcore0", "armclk", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(36), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 0, GFLAGS), + COMPOSITE_NOMUX(0, "armcore1", "armclk", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(36), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 1, GFLAGS), + COMPOSITE_NOMUX(0, "armcore2", "armclk", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(36), 8, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 2, GFLAGS), + COMPOSITE_NOMUX(0, "armcore3", "armclk", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(36), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 3, GFLAGS), + COMPOSITE_NOMUX(0, "l2ram", "armclk", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(37), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 4, GFLAGS), + COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(0), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 5, GFLAGS), + COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 6, GFLAGS), + COMPOSITE_NOMUX(0, "atclk", "armclk", 0, + RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 7, GFLAGS), + COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3288_CLKGATE_CON(12), 8, GFLAGS), + GATE(0, "pclk_dbg", "pclk_dbg_pre", 0, + RK3288_CLKGATE_CON(12), 9, GFLAGS), + GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(12), 10, GFLAGS), + GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0, + RK3288_CLKGATE_CON(12), 11, GFLAGS), + + GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(0), 8, GFLAGS), + GATE(0, "gpll_ddr", "gpll", 0, + RK3288_CLKGATE_CON(0), 9, GFLAGS), + COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2, + DFLAGS | CLK_DIVIDER_POWER_OF_TWO), + + GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(0), 10, GFLAGS), + GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(0), 11, GFLAGS), + COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), + DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(1), 0, 3, DFLAGS), + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(1), 12, 3, DFLAGS, + RK3288_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t, + RK3288_CLKGATE_CON(0), 4, GFLAGS), + GATE(0, "c2c_host", "aclk_cpu_src", 0, + RK3288_CLKGATE_CON(13), 8, GFLAGS), + COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, + RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, + RK3288_CLKGATE_CON(5), 4, GFLAGS), + GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(0), 7, GFLAGS), + + COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS, + RK3288_CLKGATE_CON(4), 1, GFLAGS), + COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(8), 0, + RK3288_CLKGATE_CON(4), 2, GFLAGS), + MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(4), 8, 2, MFLAGS), + COMPOSITE_NODIV(SCLK_I2S0_OUT, "i2s0_clkout", mux_i2s_clkout_p, 0, + RK3288_CLKSEL_CON(4), 12, 1, MFLAGS, + RK3288_CLKGATE_CON(4), 0, GFLAGS), + GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", CLK_SET_RATE_PARENT, + RK3288_CLKGATE_CON(4), 3, GFLAGS), + + MUX(0, "spdif_src", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(5), 15, 1, MFLAGS), + COMPOSITE_NOMUX(0, "spdif_pre", "spdif_src", 0, + RK3288_CLKSEL_CON(5), 0, 7, DFLAGS, + RK3288_CLKGATE_CON(4), 4, GFLAGS), + COMPOSITE_FRAC(0, "spdif_frac", "spdif_src", 0, + RK3288_CLKSEL_CON(9), 0, + RK3288_CLKGATE_CON(4), 5, GFLAGS), + COMPOSITE_NODIV(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0, + RK3288_CLKSEL_CON(5), 8, 2, MFLAGS, + RK3288_CLKGATE_CON(4), 6, GFLAGS), + COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0, + RK3288_CLKSEL_CON(40), 0, 7, DFLAGS, + RK3288_CLKGATE_CON(4), 7, GFLAGS), + COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_pre", 0, + RK3288_CLKSEL_CON(41), 0, + RK3288_CLKGATE_CON(4), 8, GFLAGS), + COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, + RK3288_CLKSEL_CON(40), 8, 2, MFLAGS, + RK3288_CLKGATE_CON(4), 9, GFLAGS), + + GATE(0, "sclk_acc_efuse", "xin24m", 0, + RK3288_CLKGATE_CON(0), 12, GFLAGS), + GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0, + RK3288_CLKGATE_CON(1), 0, GFLAGS), + GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0, + RK3288_CLKGATE_CON(1), 1, GFLAGS), + GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0, + RK3288_CLKGATE_CON(1), 2, GFLAGS), + GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0, + RK3288_CLKGATE_CON(1), 3, GFLAGS), + GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0, + RK3288_CLKGATE_CON(1), 4, GFLAGS), + GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, + RK3288_CLKGATE_CON(1), 5, GFLAGS), + /* + * Clock-Architecture Diagram 2 + */ + + COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_usb480m_p, 0, + RK3288_CLKSEL_CON(32), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3288_CLKGATE_CON(3), 9, GFLAGS), + COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0, + RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(3), 11, GFLAGS), + /* + * We use aclk_vdpu by default GRF_SOC_CON0[7] setting in system, + * so we ignore the mux and make clocks nodes as following, + */ + GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vdpu", 0, + RK3288_CLKGATE_CON(9), 0, GFLAGS), + /* + * We introduce a virtul node of hclk_vodec_pre_v to split one clock + * struct with a gate and a fix divider into two node in software. + */ + GATE(0, "hclk_vcodec_pre_v", "aclk_vdpu", 0, + RK3288_CLKGATE_CON(3), 10, GFLAGS), + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, + RK3288_CLKGATE_CON(9), 1, GFLAGS), + + COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3288_CLKGATE_CON(3), 0, GFLAGS), + DIV(0, "hclk_vio", "aclk_vio0", 0, + RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), + COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(3), 2, GFLAGS), + + COMPOSITE(0, "aclk_rga_pre", mux_pll_src_cpll_gpll_usb480m_p, 0, + RK3288_CLKSEL_CON(30), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3288_CLKGATE_CON(3), 5, GFLAGS), + COMPOSITE(SCLK_RGA, "sclk_rga", mux_pll_src_cpll_gpll_usb480m_p, 0, + RK3288_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(3), 4, GFLAGS), + + COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS, + RK3288_CLKGATE_CON(3), 1, GFLAGS), + COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(29), 6, 2, MFLAGS, 8, 8, DFLAGS, + RK3288_CLKGATE_CON(3), 3, GFLAGS), + + COMPOSITE_NODIV(SCLK_EDP_24M, "sclk_edp_24m", mux_edp_24m_p, 0, + RK3288_CLKSEL_CON(28), 15, 1, MFLAGS, + RK3288_CLKGATE_CON(3), 12, GFLAGS), + COMPOSITE(SCLK_EDP, "sclk_edp", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3288_CLKGATE_CON(3), 13, GFLAGS), + + COMPOSITE(SCLK_ISP, "sclk_isp", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(6), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3288_CLKGATE_CON(3), 14, GFLAGS), + COMPOSITE(SCLK_ISP_JPE, "sclk_isp_jpe", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(6), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3288_CLKGATE_CON(3), 15, GFLAGS), + + GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, + RK3288_CLKGATE_CON(5), 12, GFLAGS), + GATE(SCLK_HDMI_CEC, "sclk_hdmi_cec", "xin32k", 0, + RK3288_CLKGATE_CON(5), 11, GFLAGS), + + COMPOSITE(ACLK_HEVC, "aclk_hevc", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(39), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(13), 13, GFLAGS), + DIV(HCLK_HEVC, "hclk_hevc", "aclk_hevc", 0, + RK3288_CLKSEL_CON(40), 12, 2, DFLAGS), + + COMPOSITE(SCLK_HEVC_CABAC, "sclk_hevc_cabac", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3288_CLKGATE_CON(13), 14, GFLAGS), + COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(13), 15, GFLAGS), + + COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(26), 8, 1, MFLAGS, + RK3288_CLKGATE_CON(3), 7, GFLAGS), + COMPOSITE_NOGATE(0, "sclk_vip_out", mux_vip_out_p, 0, + RK3288_CLKSEL_CON(26), 15, 1, MFLAGS, 9, 5, DFLAGS), + + DIV(0, "pclk_pd_alive", "gpll", 0, + RK3288_CLKSEL_CON(33), 8, 5, DFLAGS), + COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(33), 0, 5, DFLAGS, + RK3288_CLKGATE_CON(5), 8, GFLAGS), + + COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gll_usb_npll_p, 0, + RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3288_CLKGATE_CON(5), 7, GFLAGS), + + COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, + RK3288_CLKGATE_CON(2), 0, GFLAGS), + COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, + RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, + RK3288_CLKGATE_CON(2), 3, GFLAGS), + COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, + RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, + RK3288_CLKGATE_CON(2), 2, GFLAGS), + GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(2), 1, GFLAGS), + + /* + * Clock-Architecture Diagram 3 + */ + + COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(25), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3288_CLKGATE_CON(2), 9, GFLAGS), + COMPOSITE(SCLK_SPI1, "sclk_spi1", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(25), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3288_CLKGATE_CON(2), 10, GFLAGS), + COMPOSITE(SCLK_SPI2, "sclk_spi2", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(39), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3288_CLKGATE_CON(2), 11, GFLAGS), + + COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, + RK3288_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3288_CLKGATE_CON(13), 0, GFLAGS), + COMPOSITE(SCLK_SDIO0, "sclk_sdio0", mux_mmc_src_p, 0, + RK3288_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3288_CLKGATE_CON(13), 1, GFLAGS), + COMPOSITE(SCLK_SDIO1, "sclk_sdio1", mux_mmc_src_p, 0, + RK3288_CLKSEL_CON(34), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3288_CLKGATE_CON(13), 2, GFLAGS), + COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0, + RK3288_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3288_CLKGATE_CON(13), 3, GFLAGS), + + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3288_SDMMC_CON0, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3288_SDMMC_CON1, 0), + + MMC(SCLK_SDIO0_DRV, "sdio0_drv", "sclk_sdio0", RK3288_SDIO0_CON0, 1), + MMC(SCLK_SDIO0_SAMPLE, "sdio0_sample", "sclk_sdio0", RK3288_SDIO0_CON1, 0), + + MMC(SCLK_SDIO1_DRV, "sdio1_drv", "sclk_sdio1", RK3288_SDIO1_CON0, 1), + MMC(SCLK_SDIO1_SAMPLE, "sdio1_sample", "sclk_sdio1", RK3288_SDIO1_CON1, 0), + + MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3288_EMMC_CON0, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3288_EMMC_CON1, 0), + + COMPOSITE(0, "sclk_tspout", mux_tspout_p, 0, + RK3288_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(4), 11, GFLAGS), + COMPOSITE(0, "sclk_tsp", mux_pll_src_cpll_gpll_npll_p, 0, + RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3288_CLKGATE_CON(4), 10, GFLAGS), + + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(13), 4, GFLAGS), + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(13), 5, GFLAGS), + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(13), 6, GFLAGS), + GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED, + RK3288_CLKGATE_CON(13), 7, GFLAGS), + + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0, + RK3288_CLKSEL_CON(2), 0, 6, DFLAGS, + RK3288_CLKGATE_CON(2), 7, GFLAGS), + + COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0, + RK3288_CLKSEL_CON(24), 8, 8, DFLAGS, + RK3288_CLKGATE_CON(2), 8, GFLAGS), + + GATE(SCLK_PS2C, "sclk_ps2c", "xin24m", 0, + RK3288_CLKGATE_CON(5), 13, GFLAGS), + + COMPOSITE(SCLK_NANDC0, "sclk_nandc0", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(38), 7, 1, MFLAGS, 0, 5, DFLAGS, + RK3288_CLKGATE_CON(5), 5, GFLAGS), + COMPOSITE(SCLK_NANDC1, "sclk_nandc1", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(5), 6, GFLAGS), + + COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0, + RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS, + RK3288_CLKGATE_CON(1), 8, GFLAGS), + COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(17), 0, + RK3288_CLKGATE_CON(1), 9, GFLAGS), + MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(13), 8, 2, MFLAGS), + MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(13), 15, 1, MFLAGS), + COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0, + RK3288_CLKSEL_CON(14), 0, 7, DFLAGS, + RK3288_CLKGATE_CON(1), 10, GFLAGS), + COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(18), 0, + RK3288_CLKGATE_CON(1), 11, GFLAGS), + MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(14), 8, 2, MFLAGS), + COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0, + RK3288_CLKSEL_CON(15), 0, 7, DFLAGS, + RK3288_CLKGATE_CON(1), 12, GFLAGS), + COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(19), 0, + RK3288_CLKGATE_CON(1), 13, GFLAGS), + MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(15), 8, 2, MFLAGS), + COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0, + RK3288_CLKSEL_CON(16), 0, 7, DFLAGS, + RK3288_CLKGATE_CON(1), 14, GFLAGS), + COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(20), 0, + RK3288_CLKGATE_CON(1), 15, GFLAGS), + MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(16), 8, 2, MFLAGS), + COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0, + RK3288_CLKSEL_CON(3), 0, 7, DFLAGS, + RK3288_CLKGATE_CON(2), 12, GFLAGS), + COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(7), 0, + RK3288_CLKGATE_CON(2), 13, GFLAGS), + MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(3), 8, 2, MFLAGS), + + COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(2), 5, GFLAGS), + MUX(SCLK_MAC, "mac_clk", mux_mac_p, CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(21), 4, 1, MFLAGS), + GATE(SCLK_MACREF_OUT, "sclk_macref_out", "mac_clk", 0, + RK3288_CLKGATE_CON(5), 3, GFLAGS), + GATE(SCLK_MACREF, "sclk_macref", "mac_clk", 0, + RK3288_CLKGATE_CON(5), 2, GFLAGS), + GATE(SCLK_MAC_RX, "sclk_mac_rx", "mac_clk", 0, + RK3288_CLKGATE_CON(5), 0, GFLAGS), + GATE(SCLK_MAC_TX, "sclk_mac_tx", "mac_clk", 0, + RK3288_CLKGATE_CON(5), 1, GFLAGS), + + COMPOSITE(0, "hsadc_src", mux_pll_src_cpll_gpll_p, 0, + RK3288_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS, + RK3288_CLKGATE_CON(2), 6, GFLAGS), + MUX(0, "sclk_hsadc_out", mux_hsadcout_p, 0, + RK3288_CLKSEL_CON(22), 4, 1, MFLAGS), + + GATE(0, "jtag", "ext_jtag", 0, + RK3288_CLKGATE_CON(4), 14, GFLAGS), + + COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0, + RK3288_CLKSEL_CON(13), 11, 2, MFLAGS, + RK3288_CLKGATE_CON(5), 14, GFLAGS), + COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, + RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, + RK3288_CLKGATE_CON(3), 6, GFLAGS), + GATE(0, "hsicphy12m_xin12m", "xin12m", 0, + RK3288_CLKGATE_CON(13), 9, GFLAGS), + DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0, + RK3288_CLKSEL_CON(11), 8, 6, DFLAGS), + MUX(SCLK_HSICPHY12M, "sclk_hsicphy12m", mux_hsicphy12m_p, 0, + RK3288_CLKSEL_CON(22), 4, 1, MFLAGS), + + /* + * Clock-Architecture Diagram 4 + */ + + /* aclk_cpu gates */ + GATE(0, "sclk_intmem0", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 5, GFLAGS), + GATE(0, "sclk_intmem1", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 6, GFLAGS), + GATE(0, "sclk_intmem2", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 7, GFLAGS), + GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS), + GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 13, GFLAGS), + GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 4, GFLAGS), + GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS), + GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS), + + /* hclk_cpu gates */ + GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS), + GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS), + GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 9, GFLAGS), + GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS), + GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS), + + /* pclk_cpu gates */ + GATE(PCLK_PWM, "pclk_pwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 0, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 1, GFLAGS), + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 2, GFLAGS), + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 3, GFLAGS), + GATE(PCLK_DDRUPCTL0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), + GATE(PCLK_PUBL0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), + GATE(PCLK_DDRUPCTL1, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), + GATE(PCLK_PUBL1, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), + GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS), + GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), + GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS), + GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS), + + /* ddrctrl [DDR Controller PHY clock] gates */ + GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS), + GATE(0, "nclk_ddrupctl1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 5, GFLAGS), + + /* ddrphy gates */ + GATE(0, "sclk_ddrphy0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "sclk_ddrphy1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 13, GFLAGS), + + /* aclk_peri gates */ + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS), + GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 11, GFLAGS), + GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS), + GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS), + GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS), + + /* hclk_peri gates */ + GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 0, GFLAGS), + GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 4, GFLAGS), + GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS), + GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 7, GFLAGS), + GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS), + GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 9, GFLAGS), + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 10, GFLAGS), + GATE(0, "hclk_emem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 12, GFLAGS), + GATE(0, "hclk_mem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 13, GFLAGS), + GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS), + GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS), + GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS), + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 3, GFLAGS), + GATE(HCLK_SDIO0, "hclk_sdio0", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 4, GFLAGS), + GATE(HCLK_SDIO1, "hclk_sdio1", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 5, GFLAGS), + GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 6, GFLAGS), + GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 7, GFLAGS), + GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS), + + /* pclk_peri gates */ + GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 1, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS), + GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS), + GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS), + GATE(PCLK_PS2C, "pclk_ps2c", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 7, GFLAGS), + GATE(PCLK_UART0, "pclk_uart0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 8, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 9, GFLAGS), + GATE(PCLK_I2C4, "pclk_i2c4", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 15, GFLAGS), + GATE(PCLK_UART3, "pclk_uart3", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 11, GFLAGS), + GATE(PCLK_UART4, "pclk_uart4", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 12, GFLAGS), + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 13, GFLAGS), + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 14, GFLAGS), + GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 1, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 2, GFLAGS), + GATE(PCLK_SIM, "pclk_sim", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 3, GFLAGS), + GATE(PCLK_I2C5, "pclk_i2c5", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 0, GFLAGS), + GATE(PCLK_GMAC, "pclk_gmac", "pclk_peri", 0, RK3288_CLKGATE_CON(8), 1, GFLAGS), + + GATE(SCLK_LCDC_PWM0, "sclk_lcdc_pwm0", "xin24m", 0, RK3288_CLKGATE_CON(13), 10, GFLAGS), + GATE(SCLK_LCDC_PWM1, "sclk_lcdc_pwm1", "xin24m", 0, RK3288_CLKGATE_CON(13), 11, GFLAGS), + GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS), + GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS), + GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS), + + /* sclk_gpu gates */ + GATE(ACLK_GPU, "aclk_gpu", "sclk_gpu", 0, RK3288_CLKGATE_CON(18), 0, GFLAGS), + + /* pclk_pd_alive gates */ + GATE(PCLK_GPIO8, "pclk_gpio8", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 8, GFLAGS), + GATE(PCLK_GPIO7, "pclk_gpio7", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 7, GFLAGS), + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 1, GFLAGS), + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 2, GFLAGS), + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 3, GFLAGS), + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS), + GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS), + GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS), + GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS), + GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 12, GFLAGS), + + /* pclk_pd_pmu gates */ + GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS), + GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS), + GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 2, GFLAGS), + GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS), + GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS), + + /* hclk_vio gates */ + GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS), + GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), + GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), + GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS), + GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 10, GFLAGS), + GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), + GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), + GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), + GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 10, GFLAGS), + GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS), + GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS), + GATE(PCLK_MIPI_CSI, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS), + GATE(PCLK_LVDS_PHY, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS), + GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 8, GFLAGS), + GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS), + GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 11, GFLAGS), + + /* aclk_vio0 gates */ + GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), + GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), + GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 11, GFLAGS), + GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), + + /* aclk_vio1 gates */ + GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), + GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), + GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 12, GFLAGS), + + /* aclk_rga_pre gates */ + GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS), + GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 13, GFLAGS), + + /* + * Other ungrouped clocks. + */ + + GATE(0, "pclk_vip_in", "ext_vip", 0, RK3288_CLKGATE_CON(16), 0, GFLAGS), + GATE(0, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS), +}; + +static const char *rk3288_critical_clocks[] __initconst = { + "aclk_cpu", + "aclk_peri", + "hclk_peri", + "pclk_pd_pmu", +}; + +static int __init rk3288_clk_init(struct device_node *np) +{ + void __iomem *reg_base; + struct clk *clk; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return -ENOMEM; + } + + rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + + /* xin12m is created by an cru-internal divider */ + clk = clk_fixed_factor("xin12m", "xin24m", 1, 2, 0); + if (IS_ERR(clk)) + pr_warn("%s: could not register clock xin12m: %ld\n", + __func__, PTR_ERR(clk)); + + clk = clk_fixed_factor("usb480m", "xin24m", 20, 1, 0); + if (IS_ERR(clk)) + pr_warn("%s: could not register clock usb480m: %ld\n", + __func__, PTR_ERR(clk)); + + clk = clk_fixed_factor("hclk_vcodec_pre", + "hclk_vcodec_pre_v", 1, 4, 0); + if (IS_ERR(clk)) + pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", + __func__, PTR_ERR(clk)); + + /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ + clk = clk_fixed_factor("pclk_wdt", "pclk_pd_alive", 1, 1, 0); + if (IS_ERR(clk)) + pr_warn("%s: could not register clock pclk_wdt: %ld\n", + __func__, PTR_ERR(clk)); + else + rockchip_clk_add_lookup(clk, PCLK_WDT); + + rockchip_clk_register_plls(rk3288_pll_clks, + ARRAY_SIZE(rk3288_pll_clks), + RK3288_GRF_SOC_STATUS1); + rockchip_clk_register_branches(rk3288_clk_branches, + ARRAY_SIZE(rk3288_clk_branches)); + rockchip_clk_protect_critical(rk3288_critical_clocks, + ARRAY_SIZE(rk3288_critical_clocks)); + + rockchip_clk_register_armclk(ARMCLK, "armclk", + mux_armclk_p, ARRAY_SIZE(mux_armclk_p), + &rk3288_cpuclk_data, rk3288_cpuclk_rates, + ARRAY_SIZE(rk3288_cpuclk_rates)); + return 0; +} +CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); diff --git a/drivers/clk/socfpga.c b/drivers/clk/socfpga.c index 37ed038be8..6af0632caf 100644 --- a/drivers/clk/socfpga.c +++ b/drivers/clk/socfpga.c @@ -116,18 +116,27 @@ struct clk_periph { const char *parent; unsigned regofs; unsigned int fixed_div; + void __iomem *div_reg; + unsigned int width; + unsigned int shift; }; static unsigned long clk_periph_recalc_rate(struct clk *clk, unsigned long parent_rate) { struct clk_periph *periph = container_of(clk, struct clk_periph, clk); - u32 div; + u32 div, val; - if (periph->fixed_div) + if (periph->fixed_div) { div = periph->fixed_div; - else + } else { + if (periph->div_reg) { + val = readl(periph->div_reg) >> periph->shift; + val &= div_mask(periph->width); + parent_rate /= (val + 1); + } div = ((readl(clk_mgr_base_addr + periph->regofs) & 0x1ff) + 1); + } return parent_rate / div; } @@ -140,6 +149,7 @@ static struct clk *socfpga_periph_clk(struct device_node *node) { struct clk_periph *periph; int ret; + u32 div_reg[3]; periph = xzalloc(sizeof(*periph)); @@ -152,6 +162,15 @@ static struct clk *socfpga_periph_clk(struct device_node *node) periph->clk.name = xstrdup(node->name); periph->clk.ops = &clk_periph_ops; + ret = of_property_read_u32_array(node, "div-reg", div_reg, 3); + if (!ret) { + periph->div_reg = clk_mgr_base_addr + div_reg[0]; + periph->shift = div_reg[1]; + periph->width = div_reg[2]; + } else { + periph->div_reg = 0; + } + of_property_read_u32(node, "reg", &periph->regofs); of_property_read_u32(node, "fixed-divider", &periph->fixed_div); diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 3fb09fbec4..f1ab554f96 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -49,3 +49,7 @@ config CLOCKSOURCE_ORION config CLOCKSOURCE_UEMD bool depends on ARCH_UEMD + +config CLOCKSOURCE_ROCKCHIP + bool + depends on ARCH_ROCKCHIP diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 4eb1656ee0..39982ffb28 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_CLOCKSOURCE_MVEBU) += mvebu.o obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o obj-$(CONFIG_CLOCKSOURCE_ORION) += orion.o obj-$(CONFIG_CLOCKSOURCE_UEMD) += uemd.o +obj-$(CONFIG_CLOCKSOURCE_ROCKCHIP)+= rk_timer.o diff --git a/drivers/clocksource/rk_timer.c b/drivers/clocksource/rk_timer.c new file mode 100644 index 0000000000..baa517c62f --- /dev/null +++ b/drivers/clocksource/rk_timer.c @@ -0,0 +1,73 @@ +/* + * (C) Copyright 2015 Rockchip Electronics Co., Ltd + * + * (C) Copyright 2016 PHYTEC Messtechnik GmbH + * Author: Wadim Egorov <w.egorov@phytec.de> + + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <clock.h> +#include <init.h> +#include <io.h> +#include <mach/timer.h> +#include <stdio.h> +#include <mach/hardware.h> +#include <mach/cru_rk3288.h> +#include <common.h> + +struct rk_timer *timer_ptr; + +static uint64_t rockchip_get_ticks(void) +{ + uint64_t timebase_h, timebase_l; + + timebase_l = readl(&timer_ptr->timer_curr_value0); + timebase_h = readl(&timer_ptr->timer_curr_value1); + + return timebase_h << 32 | timebase_l; +} + +static struct clocksource rkcs = { + .read = rockchip_get_ticks, + .mask = CLOCKSOURCE_MASK(32), + .shift = 10, +}; + +static int rockchip_timer_probe(struct device_d *dev) +{ + struct resource *iores; + + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + timer_ptr = IOMEM(iores->start) + 0x20 * CONFIG_RK_TIMER; + + rkcs.mult = clocksource_hz2mult(OSC_HZ, rkcs.shift); + + writel(0xffffffff, &timer_ptr->timer_load_count0); + writel(0xffffffff, &timer_ptr->timer_load_count1); + writel(1, &timer_ptr->timer_ctrl_reg); + + return init_clock(&rkcs); +} + +static __maybe_unused struct of_device_id rktimer_dt_ids[] = { + { + .compatible = "rockchip,rk3288-timer", + }, { + /* sentinel */ + } +}; + +static struct driver_d rktimer_driver = { + .name = "rockchip-timer", + .probe = rockchip_timer_probe, + .of_compatible = DRV_OF_COMPAT(rktimer_dt_ids), +}; + +static int rktimer_init(void) +{ + return platform_driver_register(&rktimer_driver); +} +core_initcall(rktimer_init); diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c index 0e004abe31..27c36a6377 100644 --- a/drivers/mci/dw_mmc.c +++ b/drivers/mci/dw_mmc.c @@ -753,6 +753,8 @@ static __maybe_unused struct of_device_id dw_mmc_compatible[] = { }, { .compatible = "rockchip,rk2928-dw-mshc", }, { + .compatible = "rockchip,rk3288-dw-mshc", + }, { /* sentinel */ } }; diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c index 66786ffec7..262a904ace 100644 --- a/drivers/mci/imx-esdhc.c +++ b/drivers/mci/imx-esdhc.c @@ -85,7 +85,7 @@ static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data) xfertyp |= COMMAND_RSPTYP_48_BUSY; else if (cmd->resp_type & MMC_RSP_PRESENT) xfertyp |= COMMAND_RSPTYP_48; - if ((cpu_is_mx51() || cpu_is_mx53()) && + if ((cpu_is_mx50() || cpu_is_mx51() || cpu_is_mx53()) && cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) xfertyp |= SDHCI_CMD_ABORTCMD; @@ -638,6 +638,8 @@ static __maybe_unused struct of_device_id fsl_esdhc_compatible[] = { { .compatible = "fsl,imx25-esdhc", }, { + .compatible = "fsl,imx50-esdhc", + }, { .compatible = "fsl,imx51-esdhc", }, { .compatible = "fsl,imx53-esdhc", diff --git a/drivers/mci/mmci.c b/drivers/mci/mmci.c index 9d1e858917..7489ee03a1 100644 --- a/drivers/mci/mmci.c +++ b/drivers/mci/mmci.c @@ -212,7 +212,7 @@ static u64 mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int host struct variant_data *variant = host->variant; do { - int count = readl(base + MMCIFIFOCNT) << 2; + int count = host_remain - (readl(base + MMCIFIFOCNT) << 2); if (count > host_remain) count = host_remain; @@ -264,7 +264,6 @@ static int read_bytes(struct mci_host *mci, char *dest, unsigned int blkcount, u dev_dbg(host->hw_dev, "read_bytes: blkcount=%u blksize=%u\n", blkcount, blksize); do { - mmci_writel(host, MMCIDATACTRL, mmci_readl(host, MMCIDATACTRL)); len = mmci_pio_read(host, dest, xfercount); xfercount -= len; dest += len; diff --git a/drivers/mfd/mc13xxx.c b/drivers/mfd/mc13xxx.c index b2fcd95516..f6aa922425 100644 --- a/drivers/mfd/mc13xxx.c +++ b/drivers/mfd/mc13xxx.c @@ -219,6 +219,7 @@ static struct __init { { 0x0a, MC13892_REVISION_1_2, "1.2" }, { 0x10, MC13892_REVISION_2_0, "2.0" }, { 0x11, MC13892_REVISION_2_1, "2.1" }, + { 0x14, MC13892_REVISION_2_4, "2.4" }, { 0x18, MC13892_REVISION_3_0, "3.0" }, { 0x19, MC13892_REVISION_3_1, "3.1" }, { 0x1a, MC13892_REVISION_3_2, "3.2" }, diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 295e210f6e..6ef30ce195 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -76,8 +76,6 @@ static void __iomem *syscon_node_to_base(struct device_node *np) return syscon->base; } -EXPORT_SYMBOL_GPL(syscon_node_to_regmap); - void __iomem *syscon_base_lookup_by_pdevname(const char *s) { diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 8809238e54..6088512745 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_NAND) += nand_ecc.o obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o -obj-$(CONFIG_NAND) += nand_base.o nand-bb.o +obj-$(CONFIG_NAND) += nand_base.o nand-bb.o nand_timings.o obj-$(CONFIG_NAND_BBT) += nand_bbt.o obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c index f54fe21f7d..6f31c28ec6 100644 --- a/drivers/mtd/nand/nand_imx.c +++ b/drivers/mtd/nand/nand_imx.c @@ -24,6 +24,7 @@ #include <init.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> +#include <linux/clk.h> #include <mach/generic.h> #include <mach/imx-nand.h> #include <io.h> @@ -784,16 +785,63 @@ static int get_eccsize(struct mtd_info *mtd) return 8; } -static void preset_v1_v2(struct mtd_info *mtd) +static void preset_v1(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd->priv; struct imx_nand_host *host = nand_chip->priv; uint16_t config1 = 0; - if (nfc_is_v21()) - config1 |= NFC_V2_CONFIG1_FP_INT; + host->eccsize = 1; + + writew(config1, host->regs + NFC_V1_V2_CONFIG1); + /* preset operation */ + + /* Unlock the internal RAM Buffer */ + writew(0x2, host->regs + NFC_V1_V2_CONFIG); + + /* Blocks to be unlocked */ + writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR); + writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR); + + /* Unlock Block Command for given address range */ + writew(0x4, host->regs + NFC_V1_V2_WRPROT); +} - if (nfc_is_v21() && mtd->writesize) { +static void preset_v2(struct mtd_info *mtd) +{ + struct nand_chip *nand_chip = mtd->priv; + struct imx_nand_host *host = nand_chip->priv; + uint16_t config1 = 0; + int mode; + + mode = onfi_get_async_timing_mode(nand_chip); + if (mode != ONFI_TIMING_MODE_UNKNOWN && !IS_ERR(host->clk)) { + const struct nand_sdr_timings *timings; + + mode = fls(mode) - 1; + if (mode < 0) + mode = 0; + + timings = onfi_async_timing_mode_to_sdr_timings(mode); + if (!IS_ERR(timings)) { + unsigned long rate; + int tRC_min_ns = timings->tRC_min / 1000; + + rate = 1000000000 / tRC_min_ns; + if (tRC_min_ns < 30) + /* If tRC is smaller than 30ns we have to use EDO timing */ + config1 |= NFC_V1_V2_CONFIG1_ONE_CYCLE; + else + /* Otherwise we have two clock cycles per access */ + rate *= 2; + + clk_set_rate(host->clk, rate); + } + } + + config1 |= NFC_V2_CONFIG1_FP_INT; + + if (mtd->writesize) { uint16_t pages_per_block = mtd->erasesize / mtd->writesize; host->eccsize = get_eccsize(mtd); @@ -812,14 +860,8 @@ static void preset_v1_v2(struct mtd_info *mtd) writew(0x2, host->regs + NFC_V1_V2_CONFIG); /* Blocks to be unlocked */ - if (nfc_is_v21()) { - writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR); - writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR); - } else if (nfc_is_v1()) { - writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR); - writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR); - } else - BUG(); + writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR); + writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR); /* Unlock Block Command for given address range */ writew(0x4, host->regs + NFC_V1_V2_WRPROT); @@ -1166,8 +1208,10 @@ static int __init imxnd_probe(struct device_d *dev) host->data_buf = (uint8_t *)(host + 1); + /* No error check, not all SoCs provide a clk yet */ + host->clk = clk_get(dev, NULL); + if (nfc_is_v1() || nfc_is_v21()) { - host->preset = preset_v1_v2; host->send_cmd = send_cmd_v1_v2; host->send_addr = send_addr_v1_v2; host->send_page = send_page_v1_v2; @@ -1189,6 +1233,7 @@ static int __init imxnd_probe(struct device_d *dev) oob_smallpage = &nandv2_hw_eccoob_smallpage; oob_largepage = &nandv2_hw_eccoob_largepage; oob_4kpage = &nandv2_hw_eccoob_4k; /* FIXME : to check */ + host->preset = preset_v2; } else if (nfc_is_v1()) { iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) @@ -1201,6 +1246,7 @@ static int __init imxnd_probe(struct device_d *dev) oob_smallpage = &nandv1_hw_eccoob_smallpage; oob_largepage = &nandv1_hw_eccoob_largepage; oob_4kpage = &nandv1_hw_eccoob_smallpage; /* FIXME : to check */ + host->preset = preset_v1; } else if (nfc_is_v3_2()) { iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/nand_timings.c new file mode 100644 index 0000000000..7a939510b7 --- /dev/null +++ b/drivers/mtd/nand/nand_timings.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2014 Free Electrons + * + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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 <linux/kernel.h> +#include <linux/err.h> +#include <linux/mtd/nand.h> + +static const struct nand_sdr_timings onfi_sdr_timings[] = { + /* Mode 0 */ + { + .tADL_min = 200000, + .tALH_min = 20000, + .tALS_min = 50000, + .tAR_min = 25000, + .tCEA_max = 100000, + .tCEH_min = 20000, + .tCH_min = 20000, + .tCHZ_max = 100000, + .tCLH_min = 20000, + .tCLR_min = 20000, + .tCLS_min = 50000, + .tCOH_min = 0, + .tCS_min = 70000, + .tDH_min = 20000, + .tDS_min = 40000, + .tFEAT_max = 1000000, + .tIR_min = 10000, + .tITC_max = 1000000, + .tRC_min = 100000, + .tREA_max = 40000, + .tREH_min = 30000, + .tRHOH_min = 0, + .tRHW_min = 200000, + .tRHZ_max = 200000, + .tRLOH_min = 0, + .tRP_min = 50000, + .tRST_max = 250000000000, + .tWB_max = 200000, + .tRR_min = 40000, + .tWC_min = 100000, + .tWH_min = 30000, + .tWHR_min = 120000, + .tWP_min = 50000, + .tWW_min = 100000, + }, + /* Mode 1 */ + { + .tADL_min = 100000, + .tALH_min = 10000, + .tALS_min = 25000, + .tAR_min = 10000, + .tCEA_max = 45000, + .tCEH_min = 20000, + .tCH_min = 10000, + .tCHZ_max = 50000, + .tCLH_min = 10000, + .tCLR_min = 10000, + .tCLS_min = 25000, + .tCOH_min = 15000, + .tCS_min = 35000, + .tDH_min = 10000, + .tDS_min = 20000, + .tFEAT_max = 1000000, + .tIR_min = 0, + .tITC_max = 1000000, + .tRC_min = 50000, + .tREA_max = 30000, + .tREH_min = 15000, + .tRHOH_min = 15000, + .tRHW_min = 100000, + .tRHZ_max = 100000, + .tRLOH_min = 0, + .tRP_min = 25000, + .tRR_min = 20000, + .tRST_max = 500000000, + .tWB_max = 100000, + .tWC_min = 45000, + .tWH_min = 15000, + .tWHR_min = 80000, + .tWP_min = 25000, + .tWW_min = 100000, + }, + /* Mode 2 */ + { + .tADL_min = 100000, + .tALH_min = 10000, + .tALS_min = 15000, + .tAR_min = 10000, + .tCEA_max = 30000, + .tCEH_min = 20000, + .tCH_min = 10000, + .tCHZ_max = 50000, + .tCLH_min = 10000, + .tCLR_min = 10000, + .tCLS_min = 15000, + .tCOH_min = 15000, + .tCS_min = 25000, + .tDH_min = 5000, + .tDS_min = 15000, + .tFEAT_max = 1000000, + .tIR_min = 0, + .tITC_max = 1000000, + .tRC_min = 35000, + .tREA_max = 25000, + .tREH_min = 15000, + .tRHOH_min = 15000, + .tRHW_min = 100000, + .tRHZ_max = 100000, + .tRLOH_min = 0, + .tRR_min = 20000, + .tRST_max = 500000000, + .tWB_max = 100000, + .tRP_min = 17000, + .tWC_min = 35000, + .tWH_min = 15000, + .tWHR_min = 80000, + .tWP_min = 17000, + .tWW_min = 100000, + }, + /* Mode 3 */ + { + .tADL_min = 100000, + .tALH_min = 5000, + .tALS_min = 10000, + .tAR_min = 10000, + .tCEA_max = 25000, + .tCEH_min = 20000, + .tCH_min = 5000, + .tCHZ_max = 50000, + .tCLH_min = 5000, + .tCLR_min = 10000, + .tCLS_min = 10000, + .tCOH_min = 15000, + .tCS_min = 25000, + .tDH_min = 5000, + .tDS_min = 10000, + .tFEAT_max = 1000000, + .tIR_min = 0, + .tITC_max = 1000000, + .tRC_min = 30000, + .tREA_max = 20000, + .tREH_min = 10000, + .tRHOH_min = 15000, + .tRHW_min = 100000, + .tRHZ_max = 100000, + .tRLOH_min = 0, + .tRP_min = 15000, + .tRR_min = 20000, + .tRST_max = 500000000, + .tWB_max = 100000, + .tWC_min = 30000, + .tWH_min = 10000, + .tWHR_min = 80000, + .tWP_min = 15000, + .tWW_min = 100000, + }, + /* Mode 4 */ + { + .tADL_min = 70000, + .tALH_min = 5000, + .tALS_min = 10000, + .tAR_min = 10000, + .tCEA_max = 25000, + .tCEH_min = 20000, + .tCH_min = 5000, + .tCHZ_max = 30000, + .tCLH_min = 5000, + .tCLR_min = 10000, + .tCLS_min = 10000, + .tCOH_min = 15000, + .tCS_min = 20000, + .tDH_min = 5000, + .tDS_min = 10000, + .tFEAT_max = 1000000, + .tIR_min = 0, + .tITC_max = 1000000, + .tRC_min = 25000, + .tREA_max = 20000, + .tREH_min = 10000, + .tRHOH_min = 15000, + .tRHW_min = 100000, + .tRHZ_max = 100000, + .tRLOH_min = 5000, + .tRP_min = 12000, + .tRR_min = 20000, + .tRST_max = 500000000, + .tWB_max = 100000, + .tWC_min = 25000, + .tWH_min = 10000, + .tWHR_min = 80000, + .tWP_min = 12000, + .tWW_min = 100000, + }, + /* Mode 5 */ + { + .tADL_min = 70000, + .tALH_min = 5000, + .tALS_min = 10000, + .tAR_min = 10000, + .tCEA_max = 25000, + .tCEH_min = 20000, + .tCH_min = 5000, + .tCHZ_max = 30000, + .tCLH_min = 5000, + .tCLR_min = 10000, + .tCLS_min = 10000, + .tCOH_min = 15000, + .tCS_min = 15000, + .tDH_min = 5000, + .tDS_min = 7000, + .tFEAT_max = 1000000, + .tIR_min = 0, + .tITC_max = 1000000, + .tRC_min = 20000, + .tREA_max = 16000, + .tREH_min = 7000, + .tRHOH_min = 15000, + .tRHW_min = 100000, + .tRHZ_max = 100000, + .tRLOH_min = 5000, + .tRP_min = 10000, + .tRR_min = 20000, + .tRST_max = 500000000, + .tWB_max = 100000, + .tWC_min = 20000, + .tWH_min = 7000, + .tWHR_min = 80000, + .tWP_min = 10000, + .tWW_min = 100000, + }, +}; + +/** + * onfi_async_timing_mode_to_sdr_timings - [NAND Interface] Retrieve NAND + * timings according to the given ONFI timing mode + * @mode: ONFI timing mode + */ +const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode) +{ + if (mode < 0 || mode >= ARRAY_SIZE(onfi_sdr_timings)) + return ERR_PTR(-EINVAL); + + return &onfi_sdr_timings[mode]; +} diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 6409f14ae2..9a963f6d5e 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -198,7 +198,8 @@ static int m88e1121_config_init(struct phy_device *phydev) if (ret < 0) return ret; - phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_PHY_DEFAULT_PAGE); + ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_MARVELL_PHY_DEFAULT_PAGE); if (ret < 0) return ret; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 13b8324709..7132516aa1 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -311,8 +311,6 @@ static struct phy_device *of_phy_register_fixed_link(struct device_node *np, phydev->registered = 1; phydev->speed = 1000; phydev->duplex = 1; - phydev->pause = phydev->asym_pause = 0; - phydev->link = 1; return phydev; } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 146bf1ec3c..b112d7ee04 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -2,7 +2,7 @@ menu "serial drivers" depends on !CONSOLE_NONE config DRIVER_SERIAL_ARM_DCC - depends on ARM + depends on ARM && !CPU_V8 bool "ARM Debug Communications Channel (DCC) serial driver" config SERIAL_AMBA_PL011 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9a71b3bc25..43ba8f49ec 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -33,12 +33,12 @@ config DRIVER_SPI_IMX_0_0 config DRIVER_SPI_IMX_0_7 bool - depends on ARCH_IMX25 || ARCH_IMX31 || ARCH_IMX35 || ARCH_IMX53 + depends on ARCH_IMX25 || ARCH_IMX31 || ARCH_IMX35 || ARCH_IMX50 || ARCH_IMX53 default y config DRIVER_SPI_IMX_2_3 bool - depends on ARCH_IMX51 || ARCH_IMX53 || ARCH_IMX6 + depends on ARCH_IMX50 || ARCH_IMX51 || ARCH_IMX53 || ARCH_IMX6 default y config DRIVER_SPI_MXS diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c index a799abe4ee..a6f59261c3 100644 --- a/drivers/usb/imx/chipidea-imx.c +++ b/drivers/usb/imx/chipidea-imx.c @@ -150,13 +150,23 @@ static int imx_chipidea_probe_dt(struct imx_chipidea *ci) static int ci_register_role(struct imx_chipidea *ci) { - if (ci->role_registered) + int ret; + + if (ci->role_registered != IMX_USB_MODE_OTG) return -EBUSY; if (ci->mode == IMX_USB_MODE_HOST) { if (IS_ENABLED(CONFIG_USB_EHCI)) { ci->role_registered = 1; - return ehci_register(ci->dev, &ci->data); + ret = regulator_enable(ci->vbus); + if (ret) + return ret; + + ret = ehci_register(ci->dev, &ci->data); + if (!ret) + return 0; + + regulator_disable(ci->vbus); } else { dev_err(ci->dev, "Host support not available\n"); return -ENODEV; @@ -180,8 +190,12 @@ static int ci_set_mode(struct param_d *param, void *priv) { struct imx_chipidea *ci = priv; - if (ci->role_registered) - return -EBUSY; + if (ci->role_registered != IMX_USB_MODE_OTG) { + if (ci->role_registered == ci->mode) + return 0; + else + return -EBUSY; + } return ci_register_role(ci); } @@ -225,6 +239,7 @@ static int imx_chipidea_probe(struct device_d *dev) ci = xzalloc(sizeof(*ci)); ci->dev = dev; + ci->role_registered = IMX_USB_MODE_OTG; if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node) { ret = imx_chipidea_probe_dt(ci); @@ -242,9 +257,8 @@ static int imx_chipidea_probe(struct device_d *dev) } ci->vbus = regulator_get(dev, "vbus"); - - if (!IS_ERR(ci->vbus)) - regulator_enable(ci->vbus); + if (IS_ERR(ci->vbus)) + ci->vbus = NULL; iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) diff --git a/drivers/usb/imx/imx-usb-misc.c b/drivers/usb/imx/imx-usb-misc.c index d938a2cd87..7c18ca2a18 100644 --- a/drivers/usb/imx/imx-usb-misc.c +++ b/drivers/usb/imx/imx-usb-misc.c @@ -447,6 +447,12 @@ static struct platform_device_id imx_usbmisc_ids[] = { .driver_data = (unsigned long)&mx35_data, }, #endif +#ifdef CONFIG_ARCH_IMX50 + { + .name = "imx50-usb-misc", + .driver_data = (unsigned long)&mx5_data, + }, +#endif #ifdef CONFIG_ARCH_IMX51 { .name = "imx51-usb-misc", diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 7ff67e525e..8f31f5af74 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -127,6 +127,15 @@ config DRIVER_VIDEO_MTL017 The MTL017 is a parallel to lvds video encoder chip found on the Efika MX Smartbook. +config DRIVER_VIDEO_TC358767 + bool "TC358767A Display Port encoder" + select VIDEO_VPL + depends on DRIVER_VIDEO_EDID + depends on I2C + depends on OFTREE + help + The TC358767A is a DSI/DPI to eDP video encoder chip + config DRIVER_VIDEO_SIMPLE_PANEL bool "Simple panel support" select VIDEO_VPL diff --git a/drivers/video/Makefile b/drivers/video/Makefile index a64fc5f24d..1bf2e1f3ca 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRIVER_VIDEO_BACKLIGHT_PWM) += backlight-pwm.o obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbconsole.o obj-$(CONFIG_VIDEO_VPL) += vpl.o obj-$(CONFIG_DRIVER_VIDEO_MTL017) += mtl017.o +obj-$(CONFIG_DRIVER_VIDEO_TC358767) += tc358767.o obj-$(CONFIG_DRIVER_VIDEO_SIMPLE_PANEL) += simple-panel.o obj-$(CONFIG_DRIVER_VIDEO_ATMEL) += atmel_lcdfb.o atmel_lcdfb_core.o diff --git a/drivers/video/edid.c b/drivers/video/edid.c index 92b59a5564..258526433e 100644 --- a/drivers/video/edid.c +++ b/drivers/video/edid.c @@ -792,7 +792,6 @@ int edid_to_display_timings(struct display_timings *timings, unsigned char *edid return 0; out: - free(timings); free(mode); return ret; } diff --git a/drivers/video/imx-ipu-v3/imx-hdmi.c b/drivers/video/imx-ipu-v3/imx-hdmi.c index 8b251a52ea..17b6e4cc25 100644 --- a/drivers/video/imx-ipu-v3/imx-hdmi.c +++ b/drivers/video/imx-ipu-v3/imx-hdmi.c @@ -22,6 +22,7 @@ #include <asm-generic/div64.h> #include <linux/clk.h> #include <i2c/i2c.h> +#include <video/media-bus-format.h> #include <video/vpl.h> #include <mach/imx6-regs.h> #include <mach/imx53-regs.h> @@ -1261,7 +1262,7 @@ static int dw_hdmi_ioctl(struct vpl *vpl, unsigned int port, mode = data; mode->di_clkflags = IPU_DI_CLKMODE_EXT | IPU_DI_CLKMODE_SYNC; - mode->interface_pix_fmt = V4L2_PIX_FMT_RGB24; + mode->bus_format = MEDIA_BUS_FMT_RGB888_1X24; return 0; } diff --git a/drivers/video/imx-ipu-v3/imx-ipu-v3.h b/drivers/video/imx-ipu-v3/imx-ipu-v3.h index fbfec22e4f..cdfff6992f 100644 --- a/drivers/video/imx-ipu-v3/imx-ipu-v3.h +++ b/drivers/video/imx-ipu-v3/imx-ipu-v3.h @@ -116,7 +116,7 @@ struct ipu_di; struct ipu_dc *ipu_dc_get(struct ipu_soc *ipu, int channel); void ipu_dc_put(struct ipu_dc *dc); int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced, - u32 pixel_fmt, u32 width); + u32 bus_format, u32 width); void ipu_dc_enable_channel(struct ipu_dc *dc); void ipu_dc_disable_channel(struct ipu_dc *dc); @@ -323,7 +323,7 @@ struct ipu_client_platformdata { struct ipu_di_mode { u32 di_clkflags; - u32 interface_pix_fmt; + u32 bus_format; }; #define IMX_IPU_VPL_DI_MODE 0x12660001 diff --git a/drivers/video/imx-ipu-v3/imx-ldb.c b/drivers/video/imx-ipu-v3/imx-ldb.c index 17ae894bf7..14a86a42c1 100644 --- a/drivers/video/imx-ipu-v3/imx-ldb.c +++ b/drivers/video/imx-ipu-v3/imx-ldb.c @@ -26,6 +26,7 @@ #include <malloc.h> #include <errno.h> #include <init.h> +#include <video/media-bus-format.h> #include <video/vpl.h> #include <mfd/imx6q-iomuxc-gpr.h> #include <linux/clk.h> @@ -75,7 +76,7 @@ struct imx_ldb_data { struct imx_ldb { struct device_d *dev; - u32 interface_pix_fmt; + u32 bus_format; int mode_valid; struct imx_ldb_channel channel[2]; u32 ldb_ctrl; @@ -273,8 +274,8 @@ static int imx_ldb_ioctl(struct vpl *vpl, unsigned int port, mode = data; mode->di_clkflags = IPU_DI_CLKMODE_EXT | IPU_DI_CLKMODE_SYNC; - mode->interface_pix_fmt = (imx_ldb_ch->datawidth == 24) ? - V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666; + mode->bus_format = (imx_ldb_ch->datawidth == 24) ? + MEDIA_BUS_FMT_RGB888_1X24 : MEDIA_BUS_FMT_RGB666_1X18; return 0; case VPL_GET_VIDEOMODES: diff --git a/drivers/video/imx-ipu-v3/ipu-dc.c b/drivers/video/imx-ipu-v3/ipu-dc.c index 2deb2ae048..7b343e8149 100644 --- a/drivers/video/imx-ipu-v3/ipu-dc.c +++ b/drivers/video/imx-ipu-v3/ipu-dc.c @@ -17,6 +17,7 @@ #include <linux/err.h> #include <linux/clk.h> #include <malloc.h> +#include <video/media-bus-format.h> #include "imx-ipu-v3.h" #include "ipu-prv.h" @@ -138,18 +139,18 @@ static void dc_write_tmpl(struct ipu_dc *dc, int word, u32 opcode, u32 operand, ipuwritel("dc", reg2, priv->dc_tmpl_reg + word * 8 + 4); } -static int ipu_pixfmt_to_map(u32 fmt) +static int ipu_bus_format_to_map(u32 bus_format) { - switch (fmt) { - case V4L2_PIX_FMT_RGB24: + switch (bus_format) { + case MEDIA_BUS_FMT_RGB888_1X24: return IPU_DC_MAP_RGB24; - case V4L2_PIX_FMT_RGB565: + case MEDIA_BUS_FMT_RGB565_1X16: return IPU_DC_MAP_RGB565; - case IPU_PIX_FMT_GBR24: + case MEDIA_BUS_FMT_GBR888_1X24: return IPU_DC_MAP_GBR24; - case V4L2_PIX_FMT_BGR666: + case MEDIA_BUS_FMT_RGB666_1X18: return IPU_DC_MAP_BGR666; - case V4L2_PIX_FMT_BGR24: + case MEDIA_BUS_FMT_BGR888_1X24: return IPU_DC_MAP_BGR24; default: return -EINVAL; @@ -157,7 +158,7 @@ static int ipu_pixfmt_to_map(u32 fmt) } int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced, - u32 pixel_fmt, u32 width) + u32 bus_format, u32 width) { struct ipu_dc_priv *priv = dc->priv; u32 reg = 0; @@ -165,7 +166,7 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced, dc->di = ipu_di_get_num(di); - map = ipu_pixfmt_to_map(pixel_fmt); + map = ipu_bus_format_to_map(bus_format); if (map < 0) { dev_dbg(priv->dev, "IPU_DISP: No MAP\n"); return map; diff --git a/drivers/video/imx-ipu-v3/ipu-prv.h b/drivers/video/imx-ipu-v3/ipu-prv.h index 44d7802521..4d1c0692de 100644 --- a/drivers/video/imx-ipu-v3/ipu-prv.h +++ b/drivers/video/imx-ipu-v3/ipu-prv.h @@ -19,8 +19,6 @@ struct ipu_soc; #include "imx-ipu-v3.h" -#define IPU_PIX_FMT_GBR24 v4l2_fourcc('G', 'B', 'R', '3') - #define IPUV3_CHANNEL_CSI0 0 #define IPUV3_CHANNEL_CSI1 1 #define IPUV3_CHANNEL_CSI2 2 diff --git a/drivers/video/imx-ipu-v3/ipufb.c b/drivers/video/imx-ipu-v3/ipufb.c index 67fec11d4a..63024b546d 100644 --- a/drivers/video/imx-ipu-v3/ipufb.c +++ b/drivers/video/imx-ipu-v3/ipufb.c @@ -23,6 +23,7 @@ #include <linux/clk.h> #include <linux/err.h> #include <asm-generic/div64.h> +#include <video/media-bus-format.h> #include "imx-ipu-v3.h" #include "ipuv3-plane.h" @@ -56,7 +57,7 @@ struct ipufb_info { void (*enable)(int enable); unsigned int di_clkflags; - u32 interface_pix_fmt; + u32 bus_format; struct ipu_dc *dc; struct ipu_di *di; @@ -108,7 +109,7 @@ int ipu_crtc_mode_set(struct ipufb_info *fbi, int ret; struct ipu_di_signal_cfg sig_cfg = {}; struct ipu_di_mode di_mode = {}; - u32 interface_pix_fmt; + u32 bus_format = 0; dev_info(fbi->dev, "%s: mode->xres: %d\n", __func__, mode->xres); @@ -116,8 +117,11 @@ int ipu_crtc_mode_set(struct ipufb_info *fbi, mode->yres); vpl_ioctl(&fbi->vpl, 2 + fbi->dino, IMX_IPU_VPL_DI_MODE, &di_mode); - interface_pix_fmt = di_mode.interface_pix_fmt ? - di_mode.interface_pix_fmt : fbi->interface_pix_fmt; + vpl_ioctl(&fbi->vpl, 2 + fbi->dino, VPL_GET_BUS_FORMAT, &bus_format); + if (bus_format) + di_mode.di_clkflags = IPU_DI_CLKMODE_NON_FRACTIONAL; + else + bus_format = di_mode.bus_format ?: fbi->bus_format; if (mode->sync & FB_SYNC_HOR_HIGH_ACT) sig_cfg.Hsync_pol = 1; @@ -148,8 +152,8 @@ int ipu_crtc_mode_set(struct ipufb_info *fbi, sig_cfg.hsync_pin = 2; sig_cfg.vsync_pin = 3; - ret = ipu_dc_init_sync(fbi->dc, fbi->di, sig_cfg.interlaced, - interface_pix_fmt, mode->xres); + ret = ipu_dc_init_sync(fbi->dc, fbi->di, sig_cfg.interlaced, bus_format, + mode->xres); if (ret) { dev_err(fbi->dev, "initializing display controller failed with %d\n", @@ -318,14 +322,13 @@ static int ipufb_probe(struct device_d *dev) ret = of_property_read_string(node, "interface-pix-fmt", &fmt); if (!ret) { if (!strcmp(fmt, "rgb24")) - fbi->interface_pix_fmt = V4L2_PIX_FMT_RGB24; + fbi->bus_format = MEDIA_BUS_FMT_RGB888_1X24; else if (!strcmp(fmt, "rgb565")) - fbi->interface_pix_fmt = V4L2_PIX_FMT_RGB565; + fbi->bus_format = MEDIA_BUS_FMT_RGB565_1X16; else if (!strcmp(fmt, "bgr666")) - fbi->interface_pix_fmt = V4L2_PIX_FMT_BGR666; + fbi->bus_format = MEDIA_BUS_FMT_RGB666_1X18; else if (!strcmp(fmt, "lvds666")) - fbi->interface_pix_fmt = - v4l2_fourcc('L', 'V', 'D', '6'); + fbi->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; } ret = vpl_ioctl(&fbi->vpl, 2 + fbi->dino, VPL_GET_VIDEOMODES, &info->modes); diff --git a/drivers/video/tc358767.c b/drivers/video/tc358767.c new file mode 100644 index 0000000000..72f55f4a44 --- /dev/null +++ b/drivers/video/tc358767.c @@ -0,0 +1,1313 @@ +/* + * tc358767 eDP encoder driver + * + * Copyright (C) 2016 CogentEmbedded Inc + * Author: Andrey Gusakov <andrey.gusakov@cogentembedded.com> + * + * Copyright (C) 2016 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <init.h> +#include <driver.h> +#include <malloc.h> +#include <errno.h> +#include <i2c/i2c.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <gpio.h> +#include <of_gpio.h> +#include <video/media-bus-format.h> +#include <video/vpl.h> +#include <asm-generic/div64.h> + +#define DP_LINK_BW_SET 0x100 +#define DP_TRAINING_PATTERN_SET 0x102 + +#define DP_DOWNSPREAD_CTRL 0x107 +#define DP_SPREAD_AMP_0_5 (1 << 4) + +#define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 +#define DP_SET_ANSI_8B10B (1 << 0) + +#define DP_LANE0_1_STATUS 0x202 +#define DP_LANE2_3_STATUS 0x202 +#define DP_LANE_CR_DONE (1 << 0) +#define DP_LANE_CHANNEL_EQ_DONE (1 << 1) +#define DP_LANE_SYMBOL_LOCKED (1 << 2) +#define DP_CHANNEL_EQ_BITS (DP_LANE_CR_DONE | \ + DP_LANE_CHANNEL_EQ_DONE | \ + DP_LANE_SYMBOL_LOCKED) + +#define DP_LAINE_ALIGN_STATUS_UPDATED 0x204 +#define DP_INTERLANE_ALIGN_DONE (1 << 0) + +#define DP_LINK_SCRAMBLING_DISABLE 0x20 +#define DP_TRAINING_PATTERN_1 1 +#define DP_TRAINING_PATTERN_2 2 + +#define DP_EDP_CONFIGURATION_SET 0x10a +#define DP_ALTERNATE_SCRAMBLER_RESET_ENABLE (1 << 0) + +/* Registers */ + +/* Display Parallel Interface */ +#define DPIPXLFMT 0x0440 +#define VS_POL_ACTIVE_LOW (1 << 10) +#define HS_POL_ACTIVE_LOW (1 << 9) +#define DE_POL_ACTIVE_HIGH (0 << 8) +#define SUB_CFG_TYPE_CONFIG1 (0 << 2) /* LSB aligned */ +#define SUB_CFG_TYPE_CONFIG2 (1 << 2) /* Loosely Packed */ +#define SUB_CFG_TYPE_CONFIG3 (2 << 2) /* LSB aligned 8-bit */ +#define DPI_BPP_RGB888 (0 << 0) +#define DPI_BPP_RGB666 (1 << 0) +#define DPI_BPP_RGB565 (2 << 0) + +/* Video Path */ +#define VPCTRL0 0x0450 +#define OPXLFMT_RGB666 (0 << 8) +#define OPXLFMT_RGB888 (1 << 8) +#define FRMSYNC_DISABLED (0 << 4) /* Video Timing Gen Disabled */ +#define FRMSYNC_ENABLED (1 << 4) /* Video Timing Gen Enabled */ +#define MSF_DISABLED (0 << 0) /* Magic Square FRC disabled */ +#define MSF_ENABLED (1 << 0) /* Magic Square FRC enabled */ +#define HTIM01 0x0454 +#define HTIM02 0x0458 +#define VTIM01 0x045c +#define VTIM02 0x0460 +#define VFUEN0 0x0464 +#define VFUEN BIT(0) /* Video Frame Timing Upload */ + +/* System */ +#define TC_IDREG 0x0500 +#define SYSCTRL 0x0510 +#define DP0_AUDSRC_NO_INPUT (0 << 3) +#define DP0_AUDSRC_I2S_RX (1 << 3) +#define DP0_VIDSRC_NO_INPUT (0 << 0) +#define DP0_VIDSRC_DSI_RX (1 << 0) +#define DP0_VIDSRC_DPI_RX (2 << 0) +#define DP0_VIDSRC_COLOR_BAR (3 << 0) + +/* Control */ +#define DP0CTL 0x0600 +#define VID_MN_GEN BIT(6) /* Auto-generate M/N values */ +#define EF_EN BIT(5) /* Enable Enhanced Framing */ +#define VID_EN BIT(1) /* Video transmission enable */ +#define DP_EN BIT(0) /* Enable DPTX function */ + +/* Clocks */ +#define DP0_VIDMNGEN0 0x0610 +#define DP0_VIDMNGEN1 0x0614 +#define DP0_VMNGENSTATUS 0x0618 + +/* Main Channel */ +#define DP0_SECSAMPLE 0x0640 +#define DP0_VIDSYNCDELAY 0x0644 +#define DP0_TOTALVAL 0x0648 +#define DP0_STARTVAL 0x064c +#define DP0_ACTIVEVAL 0x0650 +#define DP0_SYNCVAL 0x0654 +#define DP0_MISC 0x0658 +#define TU_SIZE_RECOMMENDED (0x3f << 16) /* LSCLK cycles per TU */ +#define BPC_6 (0 << 5) +#define BPC_8 (1 << 5) + +/* AUX channel */ +#define DP0_AUXCFG0 0x0660 +#define DP0_AUXCFG1 0x0664 +#define AUX_RX_FILTER_EN BIT(16) + +#define DP0_AUXADDR 0x0668 +#define DP0_AUXWDATA(i) (0x066c + (i) * 4) +#define DP0_AUXRDATA(i) (0x067c + (i) * 4) +#define DP0_AUXSTATUS 0x068c +#define AUX_STATUS_MASK 0xf0 +#define AUX_STATUS_SHIFT 4 +#define AUX_TIMEOUT BIT(1) +#define AUX_BUSY BIT(0) +#define DP0_AUXI2CADR 0x0698 + +/* Link Training */ +#define DP0_SRCCTRL 0x06a0 +#define DP0_SRCCTRL_SCRMBLDIS BIT(13) +#define DP0_SRCCTRL_EN810B BIT(12) +#define DP0_SRCCTRL_NOTP (0 << 8) +#define DP0_SRCCTRL_TP1 (1 << 8) +#define DP0_SRCCTRL_TP2 (2 << 8) +#define DP0_SRCCTRL_LANESKEW BIT(7) +#define DP0_SRCCTRL_SSCG BIT(3) +#define DP0_SRCCTRL_LANES_1 (0 << 2) +#define DP0_SRCCTRL_LANES_2 (1 << 2) +#define DP0_SRCCTRL_BW27 (1 << 1) +#define DP0_SRCCTRL_BW162 (0 << 1) +#define DP0_SRCCTRL_AUTOCORRECT BIT(0) +#define DP0_LTSTAT 0x06d0 +#define LT_LOOPDONE BIT(13) +#define LT_STATUS_MASK (0x1f << 8) +#define LT_CHANNEL1_EQ_BITS (DP_CHANNEL_EQ_BITS << 4) +#define LT_INTERLANE_ALIGN_DONE BIT(3) +#define LT_CHANNEL0_EQ_BITS (DP_CHANNEL_EQ_BITS) +#define DP0_SNKLTCHGREQ 0x06d4 +#define DP0_LTLOOPCTRL 0x06d8 +#define DP0_SNKLTCTRL 0x06e4 + +/* PHY */ +#define DP_PHY_CTRL 0x0800 +#define DP_PHY_RST BIT(28) /* DP PHY Global Soft Reset */ +#define BGREN BIT(25) /* AUX PHY BGR Enable */ +#define PWR_SW_EN BIT(24) /* PHY Power Switch Enable */ +#define PHY_M1_RST BIT(12) /* Reset PHY1 Main Channel */ +#define PHY_RDY BIT(16) /* PHY Main Channels Ready */ +#define PHY_M0_RST BIT(8) /* Reset PHY0 Main Channel */ +#define PHY_A0_EN BIT(1) /* PHY Aux Channel0 Enable */ +#define PHY_M0_EN BIT(0) /* PHY Main Channel0 Enable */ + +/* PLL */ +#define DP0_PLLCTRL 0x0900 +#define DP1_PLLCTRL 0x0904 /* not defined in DS */ +#define PXL_PLLCTRL 0x0908 +#define PLLUPDATE BIT(2) +#define PLLBYP BIT(1) +#define PLLEN BIT(0) +#define PXL_PLLPARAM 0x0914 +#define IN_SEL_REFCLK (0 << 14) +#define SYS_PLLPARAM 0x0918 +#define REF_FREQ_38M4 (0 << 8) /* 38.4 MHz */ +#define REF_FREQ_19M2 (1 << 8) /* 19.2 MHz */ +#define REF_FREQ_26M (2 << 8) /* 26 MHz */ +#define REF_FREQ_13M (3 << 8) /* 13 MHz */ +#define SYSCLK_SEL_LSCLK (0 << 4) +#define LSCLK_DIV_1 (0 << 0) +#define LSCLK_DIV_2 (1 << 0) + +/* Test & Debug */ +#define TSTCTL 0x0a00 +#define PLL_DBG 0x0a04 + +struct tc_edp_link { + u8 rate; + u8 rev; + u8 lanes; + u8 enhanced; + u8 assr; + int scrambler_dis; + int spread; + int coding8b10b; + u8 swing; + u8 preemp; +}; + +struct tc_data { + struct i2c_client *client; + struct device_d *dev; + /* DP AUX channel */ + struct i2c_adapter adapter; + struct vpl vpl; + + /* link settings */ + struct tc_edp_link link; + + /* mode */ + struct fb_videomode *mode; + + u32 rev; + u8 assr; + + char *edid; + + int sd_gpio; + int sd_active_high; + int reset_gpio; + int reset_active_high; + struct clk *refclk; +}; +#define to_tc_i2c_struct(a) container_of(a, struct tc_data, adapter) + +static int tc_write_reg(struct tc_data *data, u16 reg, u32 value) +{ + int ret; + u8 buf[4]; + + buf[0] = value & 0xff; + buf[1] = (value >> 8) & 0xff; + buf[2] = (value >> 16) & 0xff; + buf[3] = (value >> 24) & 0xff; + + ret = i2c_write_reg(data->client, reg | I2C_ADDR_16_BIT, buf, 4); + if (ret != 4) { + dev_err(data->dev, "error writing reg 0x%04x: %d\n", + reg, ret); + return ret; + } + + return 0; +} + + +static int tc_read_reg(struct tc_data *data, u16 reg, u32 *value) +{ + int ret; + u8 buf[4]; + + ret = i2c_read_reg(data->client, reg | I2C_ADDR_16_BIT, buf, 4); + if (ret != 4) { + dev_err(data->dev, "error reading reg 0x%04x: %d\n", + reg, ret); + return ret; + } + + *value = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + return 0; +} + +/* simple macros to avoid error checks */ +#define tc_write(reg, var) do { \ + ret = tc_write_reg(tc, reg, var); \ + if (ret) \ + goto err; \ + } while (0) +#define tc_read(reg, var) do { \ + ret = tc_read_reg(tc, reg, var); \ + if (ret) \ + goto err; \ + } while (0) + +static int tc_aux_get_status(struct tc_data *tc) +{ + int ret; + u32 value; + + tc_read(DP0_AUXSTATUS, &value); + if ((value & 0x01) == 0x00) { + switch (value & 0xf0) { + case 0x00: + /* Ack */ + return 0; + case 0x40: + /* Nack */ + return -EIO; + case 0x80: + dev_err(tc->dev, "i2c defer\n"); + return -EAGAIN; + } + return 0; + } + + if (value & 0x02) { + dev_err(tc->dev, "i2c access timeout!\n"); + return -ETIME; + } + return -EBUSY; +err: + return ret; +} + +static int tc_aux_wait_busy(struct tc_data *tc, unsigned int timeout_ms) +{ + int ret; + u32 value; + + do { + tc_read(DP0_AUXSTATUS, &value); + if ((value & AUX_BUSY) == 0x00) + return 0; + mdelay(1); + } while (timeout_ms--); + + return -EBUSY; +err: + return ret; +} + +static int tc_aux_read(struct tc_data *tc, int reg, char *data, int size) +{ + int i = 0; + int ret; + u32 tmp; + + ret = tc_aux_wait_busy(tc, 100); + if (ret) + goto err; + + /* store address */ + tc_write(DP0_AUXADDR, reg); + /* start transfer */ + tc_write(DP0_AUXCFG0, ((size - 1) << 8) | 0x09); + + ret = tc_aux_wait_busy(tc, 100); + if (ret) + goto err; + + ret = tc_aux_get_status(tc); + if (ret) + goto err; + + /* read data */ + while (i < size) { + if ((i % 4) == 0) + tc_read(DP0_AUXRDATA(i >> 2), &tmp); + data[i] = tmp & 0xFF; + tmp = tmp >> 8; + i++; + } + + return 0; +err: + dev_err(tc->dev, "tc_aux_read error: %d\n", ret); + return ret; +} + +static int tc_aux_write(struct tc_data *tc, int reg, char *data, int size) +{ + int i = 0; + int ret; + u32 tmp = 0; + + ret = tc_aux_wait_busy(tc, 100); + if (ret) + goto err; + + i = 0; + /* store data */ + while (i < size) { + tmp = tmp | (data[i] << (8 * (i & 0x03))); + i++; + if (((i % 4) == 0) || + (i == size)) { + tc_write(DP0_AUXWDATA(i >> 2), tmp); + tmp = 0; + } + } + /* store address */ + tc_write(DP0_AUXADDR, reg); + /* start transfer */ + tc_write(DP0_AUXCFG0, ((size - 1) << 8) | 0x08); + + ret = tc_aux_wait_busy(tc, 100); + if (ret) + goto err; + + ret = tc_aux_get_status(tc); + if (ret) + goto err; + + return 0; +err: + dev_err(tc->dev, "tc_aux_write error: %d\n", ret); + return ret; +} + +static int tc_aux_i2c_read(struct tc_data *tc, struct i2c_msg *msg) +{ + int i = 0; + int ret; + u32 tmp; + + if (msg->flags & I2C_M_DATA_ONLY) + return -EINVAL; + + ret = tc_aux_wait_busy(tc, 100); + if (ret) + goto err; + + /* store address */ + tc_write(DP0_AUXADDR, msg->addr); + + /* start transfer */ + tc_write(DP0_AUXCFG0, ((msg->len - 1) << 8) | 0x01); + + ret = tc_aux_wait_busy(tc, 100); + if (ret) + goto err; + + ret = tc_aux_get_status(tc); + if (ret) + goto err; + + /* read data */ + while (i < msg->len) { + if ((i % 4) == 0) + tc_read(DP0_AUXRDATA(i >> 2), &tmp); + msg->buf[i] = tmp & 0xFF; + tmp = tmp >> 8; + i++; + } + + return 0; +err: + return ret; +} + +static int tc_aux_i2c_write(struct tc_data *tc, struct i2c_msg *msg) +{ + int i = 0; + int ret; + u32 tmp = 0; + + if (msg->flags & I2C_M_DATA_ONLY) + return -EINVAL; + + if (msg->len > 16) { + dev_err(tc->dev, "this bus support max 16 bytes per transfer\n"); + return -EINVAL; + } + + ret = tc_aux_wait_busy(tc, 100); + if (ret) + goto err; + + /* store data */ + while (i < msg->len) { + tmp = (tmp << 8) | msg->buf[i]; + i++; + if (((i % 4) == 0) || + (i == msg->len)) { + tc_write(DP0_AUXWDATA(i >> 2), tmp); + tmp = 0; + } + } + /* store address */ + tc_write(DP0_AUXADDR, msg->addr); + /* start transfer */ + tc_write(DP0_AUXCFG0, ((msg->len - 1) << 8) | 0x00); + + ret = tc_aux_wait_busy(tc, 100); + if (ret) + goto err; + + ret = tc_aux_get_status(tc); + if (ret) + goto err; + + return 0; +err: + return ret; +} + +static int tc_aux_i2c_xfer(struct i2c_adapter *adapter, + struct i2c_msg *msgs, int num) +{ + struct tc_data *tc = to_tc_i2c_struct(adapter); + unsigned int i; + int ret; + + /* check */ + for (i = 0; i < num; i++) { + if (msgs[i].len > 16) { + dev_err(tc->dev, "this bus support max 16 bytes per transfer\n"); + return -EINVAL; + } + } + + /* read/write data */ + for (i = 0; i < num; i++) { + /* write/read data */ + if (msgs[i].flags & I2C_M_RD) + ret = tc_aux_i2c_read(tc, &msgs[i]); + else + ret = tc_aux_i2c_write(tc, &msgs[i]); + if (ret) + goto err; + } + +err: + return (ret < 0) ? ret : num; +} + +static const char * const training_pattern1_errors[] = { + "No errors", + "Aux write error", + "Aux read error", + "Max voltage reached error", + "Loop counter expired error", + "res", "res", "res" +}; + +static const char * const training_pattern2_errors[] = { + "No errors", + "Aux write error", + "Aux read error", + "Clock recovery failed error", + "Loop counter expired error", + "res", "res", "res" +}; + +static u32 tc_srcctrl(struct tc_data *tc) +{ + /* + * No training pattern, skew lane 1 data by two LSCLK cycles with + * respect to lane 0 data, AutoCorrect Mode = 0 + */ + u32 reg = DP0_SRCCTRL_NOTP | DP0_SRCCTRL_LANESKEW; + + if (tc->link.scrambler_dis) + reg |= DP0_SRCCTRL_SCRMBLDIS; /* Scrambler Disabled */ + if (tc->link.coding8b10b) + /* Enable 8/10B Encoder (TxData[19:16] not used) */ + reg |= DP0_SRCCTRL_EN810B; + if (tc->link.spread) + reg |= DP0_SRCCTRL_SSCG; /* Spread Spectrum Enable */ + if (tc->link.lanes == 2) + reg |= DP0_SRCCTRL_LANES_2; /* Two Main Channel Lanes */ + if (tc->link.rate != 0x06) + reg |= DP0_SRCCTRL_BW27; /* 2.7 Gbps link */ + return reg; +} + +static void tc_wait_pll_lock(struct tc_data *tc) +{ + /* Wait for PLL to lock: up to 2.09 ms, depending on refclk */ + mdelay(100); +} + +static int tc_stream_clock_calc(struct tc_data *tc) +{ + int ret; + /* + * If the Stream clock and Link Symbol clock are + * asynchronous with each other, the value of M changes over + * time. This way of generating link clock and stream + * clock is called Asynchronous Clock mode. The value M + * must change while the value N stays constant. The + * value of N in this Asynchronous Clock mode must be set + * to 2^15 or 32,768. + * + * LSCLK = 1/10 of high speed link clock + * + * f_STRMCLK = M/N * f_LSCLK + * M/N = f_STRMCLK / f_LSCLK + * + */ + tc_write(DP0_VIDMNGEN1, 32768); + + return 0; +err: + return ret; +} + +static int tc_aux_link_setup(struct tc_data *tc) +{ + unsigned long rate; + u32 value; + int ret; + int timeout; + + rate = clk_get_rate(tc->refclk); + switch (rate) { + case 38400000: + value = REF_FREQ_38M4; + break; + case 26000000: + value = REF_FREQ_26M; + break; + case 19200000: + value = REF_FREQ_19M2; + break; + case 13000000: + value = REF_FREQ_13M; + break; + default: + dev_err(tc->dev, "Invalid refclk rate: %lu Hz\n", rate); + return -EINVAL; + } + + /* Setup DP-PHY / PLL */ + value |= SYSCLK_SEL_LSCLK | LSCLK_DIV_2; + tc_write(SYS_PLLPARAM, value); + + tc_write(DP_PHY_CTRL, BGREN | PWR_SW_EN | BIT(2) | PHY_A0_EN); + + /* + * Initially PLLs are in bypass. Force PLL parameter update, + * disable PLL bypass, enable PLL + */ + tc_write(DP0_PLLCTRL, PLLUPDATE | PLLEN); + tc_wait_pll_lock(tc); + + tc_write(DP1_PLLCTRL, PLLUPDATE | PLLEN); + tc_wait_pll_lock(tc); + + timeout = 1000; + do { + tc_read(DP_PHY_CTRL, &value); + udelay(1); + } while ((!(value & (1 << 16))) && (--timeout)); + + if (timeout == 0) { + dev_err(tc->dev, "Timeout waiting for PHY to become ready"); + return -ETIMEDOUT; + } + + /* Setup AUX link */ + tc_write(DP0_AUXCFG1, AUX_RX_FILTER_EN | + (0x06 << 8) | /* Aux Bit Period Calculator Threshold */ + (0x3f << 0)); /* Aux Response Timeout Timer */ + + return 0; +err: + dev_err(tc->dev, "tc_aux_link_setup failed: %d\n", ret); + return ret; +} + +static int tc_get_display_props(struct tc_data *tc) +{ + int ret; + /* temp buffer */ + u8 tmp[8]; + + /* Read DP Rx Link Capability */ + ret = tc_aux_read(tc, 0x000, tmp, 8); + if (ret) + goto err_dpcd_read; + /* check rev 1.0 or 1.1 */ + if ((tmp[1] != 0x06) && (tmp[1] != 0x0a)) + goto err_dpcd_inval; + + tc->assr = !(tc->rev & 0x02); + tc->link.rev = tmp[0]; + tc->link.rate = tmp[1]; + tc->link.lanes = tmp[2] & 0x0f; + tc->link.enhanced = !!(tmp[2] & 0x80); + tc->link.spread = tmp[3] & 0x01; + tc->link.coding8b10b = tmp[6] & 0x01; + tc->link.scrambler_dis = 0; + /* read assr */ + ret = tc_aux_read(tc, DP_EDP_CONFIGURATION_SET, tmp, 1); + if (ret) + goto err_dpcd_read; + tc->link.assr = tmp[0] & DP_ALTERNATE_SCRAMBLER_RESET_ENABLE; + + dev_dbg(tc->dev, "DPCD rev: %d.%d, rate: %s, lanes: %d, framing: %s\n", + tc->link.rev >> 4, + tc->link.rev & 0x0f, + (tc->link.rate == 0x06) ? "1.62Gbps" : "2.7Gbps", + tc->link.lanes, + tc->link.enhanced ? "enhanced" : "non-enhanced"); + dev_dbg(tc->dev, "ANSI 8B/10B: %d\n", tc->link.coding8b10b); + dev_dbg(tc->dev, "Display ASSR: %d, TC358767 ASSR: %d\n", + tc->link.assr, tc->assr); + + return 0; + +err_dpcd_read: + dev_err(tc->dev, "failed to read DPCD: %d\n", ret); + return ret; +err_dpcd_inval: + dev_err(tc->dev, "invalid DPCD\n"); + return -EINVAL; +} + +static int tc_set_video_mode(struct tc_data *tc, struct fb_videomode *mode) +{ + int ret; + int htotal; + int vtotal; + int vid_sync_dly; + int max_tu_symbol; + + htotal = mode->hsync_len + mode->left_margin + mode->xres + + mode->right_margin; + vtotal = mode->vsync_len + mode->upper_margin + mode->yres + + mode->lower_margin; + + dev_dbg(tc->dev, "set mode %dx%d\n", mode->xres, mode->yres); + dev_dbg(tc->dev, "H margin %d,%d sync %d\n", + mode->left_margin, mode->right_margin, mode->hsync_len); + dev_dbg(tc->dev, "V margin %d,%d sync %d\n", + mode->upper_margin, mode->lower_margin, mode->vsync_len); + dev_dbg(tc->dev, "total: %dx%d\n", htotal, vtotal); + + + /* LCD Ctl Frame Size */ + tc_write(VPCTRL0, (0x40 << 20) /* VSDELAY */ | + OPXLFMT_RGB888 | FRMSYNC_DISABLED | MSF_DISABLED); + tc_write(HTIM01, (mode->left_margin << 16) | /* H back porch */ + (mode->hsync_len << 0)); /* Hsync */ + tc_write(HTIM02, (mode->right_margin << 16) | /* H front porch */ + (mode->xres << 0)); /* width */ + tc_write(VTIM01, (mode->upper_margin << 16) | /* V back porch */ + (mode->vsync_len << 0)); /* Vsync */ + tc_write(VTIM02, (mode->lower_margin << 16) | /* V front porch */ + (mode->yres << 0)); /* height */ + tc_write(VFUEN0, VFUEN); /* update settings */ + + /* Test pattern settings */ + tc_write(TSTCTL, + (120 << 24) | /* Red Color component value */ + (20 << 16) | /* Green Color component value */ + (99 << 8) | /* Blue Color component value */ + (1 << 4) | /* Enable I2C Filter */ + (2 << 0) | /* Color bar Mode */ + 0); + + /* DP Main Stream Attributes */ + vid_sync_dly = mode->hsync_len + mode->left_margin + mode->xres; + tc_write(DP0_VIDSYNCDELAY, + (0x003e << 16) | /* thresh_dly */ + (vid_sync_dly << 0)); + + tc_write(DP0_TOTALVAL, (vtotal << 16) | (htotal)); + + tc_write(DP0_STARTVAL, + ((mode->upper_margin + mode->vsync_len) << 16) | + ((mode->left_margin + mode->hsync_len) << 0)); + + tc_write(DP0_ACTIVEVAL, (mode->yres << 16) | (mode->xres)); + + tc_write(DP0_SYNCVAL, (mode->vsync_len << 16) | (mode->hsync_len << 0)); + + tc_write(DPIPXLFMT, VS_POL_ACTIVE_LOW | HS_POL_ACTIVE_LOW | + DE_POL_ACTIVE_HIGH | SUB_CFG_TYPE_CONFIG1 | DPI_BPP_RGB888); + + /* + * Recommended maximum number of symbols transferred in a transfer unit: + * DIV_ROUND_UP((input active video bandwidth in bytes) * tu_size, + * (output active video bandwidth in bytes)) + * Must be less than tu_size. + */ + max_tu_symbol = TU_SIZE_RECOMMENDED - 1; + tc_write(DP0_MISC, (max_tu_symbol << 23) | TU_SIZE_RECOMMENDED | BPC_8); + + return 0; +err: + return ret; +} + +static int tc_link_training(struct tc_data *tc, int pattern) +{ + const char * const *errors; + u32 srcctrl = tc_srcctrl(tc) | DP0_SRCCTRL_SCRMBLDIS | + DP0_SRCCTRL_AUTOCORRECT; + int timeout; + int retry; + u32 value; + int ret; + + if (pattern == DP_TRAINING_PATTERN_1) { + srcctrl |= DP0_SRCCTRL_TP1; + errors = training_pattern1_errors; + } else { + srcctrl |= DP0_SRCCTRL_TP2; + errors = training_pattern2_errors; + } + + /* Set DPCD 0x102 for Training Part 1 or 2 */ + tc_write(DP0_SNKLTCTRL, DP_LINK_SCRAMBLING_DISABLE | pattern); + + tc_write(DP0_LTLOOPCTRL, + (0x0f << 28) | /* Defer Iteration Count */ + (0x0f << 24) | /* Loop Iteration Count */ + (0x0d << 0)); /* Loop Timer Delay */ + + retry = 5; + do { + /* Set DP0 Training Pattern */ + tc_write(DP0_SRCCTRL, srcctrl); + + /* Enable DP0 to start Link Training */ + tc_write(DP0CTL, DP_EN); + + /* wait */ + timeout = 1000; + do { + tc_read(DP0_LTSTAT, &value); + udelay(1); + } while ((!(value & LT_LOOPDONE)) && (--timeout)); + if (timeout == 0) { + dev_err(tc->dev, "Link training timeout!\n"); + } else { + int pattern = (value >> 11) & 0x3; + int error = (value >> 8) & 0x7; + + dev_dbg(tc->dev, + "Link training phase %d done after %d uS: %s\n", + pattern, 1000 - timeout, errors[error]); + if (pattern == DP_TRAINING_PATTERN_1 && error == 0) + break; + if (pattern == DP_TRAINING_PATTERN_2) { + value &= LT_CHANNEL1_EQ_BITS | + LT_INTERLANE_ALIGN_DONE | + LT_CHANNEL0_EQ_BITS; + /* in case of two lanes */ + if ((tc->link.lanes == 2) && + (value == (LT_CHANNEL1_EQ_BITS | + LT_INTERLANE_ALIGN_DONE | + LT_CHANNEL0_EQ_BITS))) + break; + /* in case of one line */ + if ((tc->link.lanes == 1) && + (value == (LT_INTERLANE_ALIGN_DONE | + LT_CHANNEL0_EQ_BITS))) + break; + } + } + /* restart */ + tc_write(DP0CTL, 0); + udelay(10); + } while (--retry); + if (retry == 0) { + dev_err(tc->dev, "Failed to finish training phase %d\n", + pattern); + } + + return 0; +err: + return ret; +} + +static int tc_main_link_setup(struct tc_data *tc) +{ + struct device_d *dev = tc->dev; + unsigned int rate; + u32 dp_phy_ctrl; + int timeout; + bool aligned; + bool ready; + u32 value; + int ret; + u8 tmp[8]; + + /* display mode should be set at this point */ + if (!tc->mode) + return -EINVAL; + + /* from excel file - DP0_SrcCtrl */ + tc_write(DP0_SRCCTRL, DP0_SRCCTRL_SCRMBLDIS | DP0_SRCCTRL_EN810B | + DP0_SRCCTRL_LANESKEW | DP0_SRCCTRL_LANES_2 | + DP0_SRCCTRL_BW27 | DP0_SRCCTRL_AUTOCORRECT); + /* from excel file - DP1_SrcCtrl */ + tc_write(0x07a0, 0x00003083); + + rate = clk_get_rate(tc->refclk); + switch (rate) { + case 38400000: + value = REF_FREQ_38M4; + break; + case 26000000: + value = REF_FREQ_26M; + break; + case 19200000: + value = REF_FREQ_19M2; + break; + case 13000000: + value = REF_FREQ_13M; + break; + default: + return -EINVAL; + } + value |= SYSCLK_SEL_LSCLK | LSCLK_DIV_2; + tc_write(SYS_PLLPARAM, value); + /* Setup Main Link */ + dp_phy_ctrl = BGREN | PWR_SW_EN | BIT(2) | PHY_A0_EN | PHY_M0_EN; + tc_write(DP_PHY_CTRL, dp_phy_ctrl); + mdelay(100); + + /* PLL setup */ + tc_write(DP0_PLLCTRL, PLLUPDATE | PLLEN); + tc_wait_pll_lock(tc); + + tc_write(DP1_PLLCTRL, PLLUPDATE | PLLEN); + tc_wait_pll_lock(tc); + + /* Reset/Enable Main Links */ + dp_phy_ctrl |= DP_PHY_RST | PHY_M1_RST | PHY_M0_RST; + tc_write(DP_PHY_CTRL, dp_phy_ctrl); + udelay(100); + dp_phy_ctrl &= ~(DP_PHY_RST | PHY_M1_RST | PHY_M0_RST); + tc_write(DP_PHY_CTRL, dp_phy_ctrl); + + timeout = 1000; + do { + tc_read(DP_PHY_CTRL, &value); + udelay(1); + } while ((!(value & PHY_RDY)) && (--timeout)); + + if (timeout == 0) { + dev_err(dev, "timeout waiting for phy become ready"); + return -ETIMEDOUT; + } + + /* Set misc: 8 bits per color */ + tc_read(DP0_MISC, &value); + value |= BPC_8; + tc_write(DP0_MISC, value); + + /* + * ASSR mode + * on TC358767 side ASSR configured through strap pin + * seems there is no way to change this setting from SW + * + * check is tc configured for same mode + */ + if (tc->assr != tc->link.assr) { + dev_dbg(dev, "Trying to set display to ASSR: %d\n", + tc->assr); + /* try to set ASSR on display side */ + tmp[0] = tc->assr; + ret = tc_aux_write(tc, DP_EDP_CONFIGURATION_SET, tmp, 1); + if (ret) + goto err_dpcd_read; + /* read back */ + ret = tc_aux_read(tc, DP_EDP_CONFIGURATION_SET, tmp, 1); + if (ret) + goto err_dpcd_read; + + if (tmp[0] != tc->assr) { + dev_warn(dev, "Failed to switch display ASSR to %d, falling back to unscrambled mode\n", + tc->assr); + /* trying with disabled scrambler */ + tc->link.scrambler_dis = 1; + } + } + + /* Setup Link & DPRx Config for Training */ + /* LINK_BW_SET */ + tmp[0] = tc->link.rate; + /* LANE_COUNT_SET */ + tmp[1] = tc->link.lanes; + if (tc->link.enhanced) + tmp[1] |= (1 << 7); + ret = tc_aux_write(tc, DP_LINK_BW_SET, tmp, 2); + if (ret) + goto err_dpcd_write; + + /* DOWNSPREAD_CTRL */ + tmp[0] = tc->link.spread ? DP_SPREAD_AMP_0_5 : 0x00; + /* MAIN_LINK_CHANNEL_CODING_SET */ + tmp[1] = tc->link.coding8b10b ? DP_SET_ANSI_8B10B : 0x00; + ret = tc_aux_write(tc, DP_DOWNSPREAD_CTRL, tmp, 2); + if (ret) + goto err_dpcd_write; + + ret = tc_link_training(tc, DP_TRAINING_PATTERN_1); + if (ret) + goto err; + + ret = tc_link_training(tc, DP_TRAINING_PATTERN_2); + if (ret) + goto err; + + /* Clear DPCD 0x102 */ + /* Note: Can Not use DP0_SNKLTCTRL (0x06E4) short cut */ + tmp[0] = tc->link.scrambler_dis ? DP_LINK_SCRAMBLING_DISABLE : 0x00; + ret = tc_aux_write(tc, DP_TRAINING_PATTERN_SET, tmp, 1); + if (ret) + goto err_dpcd_write; + + /* Clear Training Pattern, set AutoCorrect Mode = 1 */ + tc_write(DP0_SRCCTRL, tc_srcctrl(tc) | DP0_SRCCTRL_AUTOCORRECT); + + /* Wait */ + timeout = 100; + do { + udelay(1); + /* Read DPCD 0x200-0x206 */ + ret = tc_aux_read(tc, 0x200, tmp, 7); + if (ret) + goto err_dpcd_read; + ready = (tmp[2] == ((DP_CHANNEL_EQ_BITS << 4) | /* Lane1 */ + DP_CHANNEL_EQ_BITS)); /* Lane0 */ + aligned = tmp[4] & DP_INTERLANE_ALIGN_DONE; + } while ((--timeout) && !(ready && aligned)); + + if (timeout == 0) { + dev_info(dev, "0x0200 SINK_COUNT: 0x%02x\n", tmp[0]); + dev_info(dev, "0x0201 DEVICE_SERVICE_IRQ_VECTOR: 0x%02x\n", + tmp[1]); + dev_info(dev, "0x0202 LANE0_1_STATUS: 0x%02x\n", tmp[2]); + dev_info(dev, "0x0204 LANE_ALIGN_STATUS_UPDATED: 0x%02x\n", + tmp[4]); + dev_info(dev, "0x0205 SINK_STATUS: 0x%02x\n", tmp[5]); + dev_info(dev, "0x0206 ADJUST_REQUEST_LANE0_1: 0x%02x\n", + tmp[6]); + + if (!ready) + dev_err(dev, "Lane0/1 not ready\n"); + if (!aligned) + dev_err(dev, "Lane0/1 not aligned\n"); + return -EAGAIN; + } + + ret = tc_set_video_mode(tc, tc->mode); + if (ret) + goto err; + + /* Set M/N */ + ret = tc_stream_clock_calc(tc); + if (ret) + goto err; + + return 0; +err_dpcd_read: + dev_err(tc->dev, "Failed to read DPCD: %d\n", ret); + return ret; +err_dpcd_write: + dev_err(tc->dev, "Failed to write DPCD: %d\n", ret); +err: + return ret; +} + +static int tc_main_link_stream(struct tc_data *tc, int state) +{ + int ret; + u32 value; + + dev_dbg(tc->dev, "stream: %d\n", state); + + if (state) { + value = VID_MN_GEN | DP_EN; + if (tc->link.enhanced) + value |= EF_EN; + tc_write(DP0CTL, value); + /* + * VID_EN assertion should be delayed by at least N * LSCLK + * cycles from the time VID_MN_GEN is enabled in order to + * generate stable values for VID_M. LSCLK is 270 MHz or + * 162 MHz, VID_N is set to 32768 in tc_stream_clock_calc(), + * so a delay of at least 203 us should suffice. + */ + mdelay(1); + value |= VID_EN; + tc_write(DP0CTL, value); + /* Set input interface, currently DPI only */ + value = DP0_AUDSRC_NO_INPUT | DP0_VIDSRC_DPI_RX; + tc_write(SYSCTRL, value); + } else { + tc_write(DP0CTL, 0); + } + + return 0; +err: + return ret; +} + +#define DDC_BLOCK_READ 5 +#define DDC_SEGMENT_ADDR 0x30 +#define DDC_ADDR 0x50 +#define EDID_LENGTH 0x80 + +static int tc_read_edid(struct tc_data *tc) +{ + int i = 0; + int ret; + int block; + unsigned char start = 0; + unsigned char segment = 0; + + struct i2c_msg msgs[] = { + { + .addr = DDC_SEGMENT_ADDR, + .flags = 0, + .len = 1, + .buf = &segment, + }, { + .addr = DDC_ADDR, + .flags = 0, + .len = 1, + .buf = &start, + }, { + .addr = DDC_ADDR, + .flags = I2C_M_RD, + } + }; + tc->edid = xmalloc(EDID_LENGTH); + + do { + block = min(DDC_BLOCK_READ, EDID_LENGTH - i); + + msgs[2].buf = tc->edid + i; + msgs[2].len = block; + + ret = i2c_transfer(&tc->adapter, msgs, 3); + if (ret < 0) + goto err; + + i += DDC_BLOCK_READ; + start = i; + } while (i < EDID_LENGTH); + +#ifdef DEBUG + printk(KERN_DEBUG "eDP display EDID:\n"); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, tc->edid, + EDID_LENGTH, true); +#endif + + return 0; +err: + free(tc->edid); + tc->edid = NULL; + dev_err(tc->dev, "tc_read_edid failed: %d\n", ret); + return ret; +} + +static int tc_get_videomodes(struct tc_data *tc, struct display_timings *timings) +{ + int ret; + + /* edid_read_i2c does not work due to limitation of eDP i2c */ + if (!tc->edid) { + ret = tc_read_edid(tc); + if (ret) { + dev_err(tc->dev, "EDID read error: %d\n", ret); + return ret; + } + } + + ret = edid_to_display_timings(timings, tc->edid); + if (ret < 0) { + dev_err(tc->dev, "Failed to parse EDID: %d\n", ret); + return ret; + } + + /* hsync, vsync active low */ + timings->modes->sync &= ~(FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_VERT_HIGH_ACT); + + return ret; +} + +static int tc_ioctl(struct vpl *vpl, unsigned int port, + unsigned int cmd, void *ptr) +{ + struct tc_data *tc = container_of(vpl, struct tc_data, vpl); + u32 *bus_format; + int ret = 0; + + switch (cmd) { + case VPL_PREPARE: + tc->mode = ptr; + break; + case VPL_ENABLE: + ret = tc_main_link_setup(tc); + if (ret < 0) + break; + + ret = tc_main_link_stream(tc, 1); + break; + case VPL_DISABLE: + ret = tc_main_link_stream(tc, 0); + break; + case VPL_GET_VIDEOMODES: + ret = tc_get_videomodes(tc, ptr); + break; + case VPL_GET_BUS_FORMAT: + bus_format = ptr; + *bus_format = MEDIA_BUS_FMT_RGB888_1X24; + break; + default: + break; + } + + return ret; +} + +static int tc_probe(struct device_d *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tc_data *tc; + enum of_gpio_flags flags; + int ret; + + tc = xzalloc(sizeof(struct tc_data)); + if (!tc) + return -ENOMEM; + + tc->client = client; + tc->dev = dev; + + /* Shut down GPIO is optional */ + tc->sd_gpio = of_get_named_gpio_flags(dev->device_node, + "shutdown-gpios", 0, &flags); + if (gpio_is_valid(tc->sd_gpio)) { + if (!(flags & OF_GPIO_ACTIVE_LOW)) + tc->sd_active_high = 1; + } + + /* Reset GPIO is optional */ + tc->reset_gpio = of_get_named_gpio_flags(dev->device_node, + "reset-gpios", 0, &flags); + if (gpio_is_valid(tc->reset_gpio)) { + if (!(flags & OF_GPIO_ACTIVE_LOW)) + tc->reset_active_high = 1; + } + + if (gpio_is_valid(tc->sd_gpio)) { + ret = gpio_request(tc->sd_gpio, "tc358767"); + if (ret) { + dev_err(tc->dev, "SD (%d) can not be requested\n", tc->sd_gpio); + return ret; + } + gpio_direction_output(tc->sd_gpio, 0); + } + + tc->refclk = of_clk_get_by_name(dev->device_node, "ref"); + if (IS_ERR(tc->refclk)) { + ret = PTR_ERR(tc->refclk); + dev_err(dev, "Failed to get refclk: %d\n", ret); + goto err; + } + + ret = tc_read_reg(tc, TC_IDREG, &tc->rev); + if (ret) { + dev_err(tc->dev, "can not read device ID\n"); + goto err; + } + + if ((tc->rev != 0x6601) && (tc->rev != 0x6603)) { + dev_err(tc->dev, "invalid device ID: 0x%08x\n", tc->rev); + ret = -EINVAL; + goto err; + } + + ret = tc_aux_link_setup(tc); + if (ret) + goto err; + + /* Register DP AUX channel */ + tc->adapter.master_xfer = tc_aux_i2c_xfer; + tc->adapter.nr = -1; /* any free */ + tc->adapter.dev.parent = dev; + tc->adapter.dev.device_node = dev->device_node; + /* Add I2C adapter */ + ret = i2c_add_numbered_adapter(&tc->adapter); + if (ret < 0) { + dev_err(tc->dev, "registration failed\n"); + goto err; + } + + ret = tc_get_display_props(tc); + if (ret) + goto err; + + /* add vlp */ + tc->vpl.node = dev->device_node; + tc->vpl.ioctl = tc_ioctl; + return vpl_register(&tc->vpl); + +err: + free(tc); + return ret; +} + +static struct driver_d tc_driver = { + .name = "tc358767", + .probe = tc_probe, +}; + +static int tc_init(void) +{ + return i2c_driver_register(&tc_driver); +} +device_initcall(tc_init); diff --git a/images/Makefile b/images/Makefile index da9cc8d396..0537af1f6d 100644 --- a/images/Makefile +++ b/images/Makefile @@ -85,7 +85,7 @@ suffix_$(CONFIG_IMAGE_COMPRESSION_GZIP) = gzip suffix_$(CONFIG_IMAGE_COMPRESSION_LZO) = lzo suffix_$(CONFIG_IMAGE_COMPRESSION_LZ4) = lz4 suffix_$(CONFIG_IMAGE_COMPRESSION_XZKERN) = xzkern -suffix_$(CONFIG_IMAGE_COMPRESSION_NONE) = shipped +suffix_$(CONFIG_IMAGE_COMPRESSION_NONE) = comp_copy # barebox.z - compressed barebox binary # ---------------------------------------------------------------- diff --git a/images/Makefile.am33xx b/images/Makefile.am33xx index 8be78eff89..8168fe4c93 100644 --- a/images/Makefile.am33xx +++ b/images/Makefile.am33xx @@ -135,6 +135,14 @@ pblx-$(CONFIG_MACH_BEAGLEBONE) += start_am33xx_beaglebone_sram FILE_barebox-am33xx-beaglebone-mlo.img = start_am33xx_beaglebone_sram.pblx.mlo am33xx-mlo-$(CONFIG_MACH_BEAGLEBONE) += barebox-am33xx-beaglebone-mlo.img +pblx-$(CONFIG_MACH_VSCOM_BALTOS) += start_am33xx_baltos_sdram +FILE_barebox-am33xx-baltos.img = start_am33xx_baltos_sdram.pblx +am33xx-barebox-$(CONFIG_MACH_VSCOM_BALTOS) += barebox-am33xx-baltos.img + +pblx-$(CONFIG_MACH_VSCOM_BALTOS) += start_am33xx_baltos_sram +FILE_barebox-am33xx-baltos-mlo.img = start_am33xx_baltos_sram.pblx.mlo +am33xx-mlo-$(CONFIG_MACH_VSCOM_BALTOS) += barebox-am33xx-baltos-mlo.img + ifdef CONFIG_OMAP_BUILD_IFT image-y += $(am33xx-mlo-y) else diff --git a/images/Makefile.rockchip b/images/Makefile.rockchip index 9715b92084..3f1ee57db2 100644 --- a/images/Makefile.rockchip +++ b/images/Makefile.rockchip @@ -5,3 +5,7 @@ pblx-$(CONFIG_MACH_RADXA_ROCK) += start_radxa_rock FILE_barebox-radxa-rock.img = start_radxa_rock.pblx image-$(CONFIG_MACH_RADXA_ROCK) += barebox-radxa-rock.img + +pblx-$(CONFIG_MACH_PHYTEC_SOM_RK3288) += start_rk3288_phycore_som +FILE_barebox-rk3288-phycore-som.img = start_rk3288_phycore_som.pblx +image-$(CONFIG_MACH_PHYTEC_SOM_RK3288) += barebox-rk3288-phycore-som.img diff --git a/include/bootchooser.h b/include/bootchooser.h new file mode 100644 index 0000000000..c948247722 --- /dev/null +++ b/include/bootchooser.h @@ -0,0 +1,37 @@ +#ifndef __BOOTCHOOSER_H +#define __BOOTCHOOSER_H + +#include <of.h> +#include <boot.h> + +struct bootchooser; +struct bootchooser_target; + +struct bootchooser *bootchooser_get(void); +int bootchooser_save(struct bootchooser *bootchooser); +int bootchooser_put(struct bootchooser *bootchooser); + +void bootchooser_info(struct bootchooser *bootchooser); + +struct bootchooser_target *bootchooser_get_last_chosen(struct bootchooser *bootchooser); +const char *bootchooser_target_name(struct bootchooser_target *target); +struct bootchooser_target *bootchooser_target_by_name(struct bootchooser *bootchooser, + const char *name); +void bootchooser_target_force_boot(struct bootchooser_target *target); + +int bootchooser_create_bootentry(struct bootentries *entries); + +int bootchooser_target_set_attempts(struct bootchooser_target *target, int attempts); +int bootchooser_target_set_priority(struct bootchooser_target *target, int priority); + +void bootchooser_last_boot_successful(void); + +struct bootchooser_target *bootchooser_target_first(struct bootchooser *bootchooser); +struct bootchooser_target *bootchooser_target_next(struct bootchooser *bootchooser, + struct bootchooser_target *cur); + +#define bootchooser_for_each_target(bootchooser, target) \ + for (target = bootchooser_target_first(bootchooser); target; \ + target = bootchooser_target_next(bootchooser, target)) + +#endif /* __BOOTCHOOSER_H */ diff --git a/include/filetype.h b/include/filetype.h index e87ca174a8..cde73c1170 100644 --- a/include/filetype.h +++ b/include/filetype.h @@ -36,6 +36,7 @@ enum filetype { filetype_exe, filetype_xz_compressed, filetype_mxs_bootstream, + filetype_socfpga_xload, filetype_max, }; diff --git a/include/globalvar.h b/include/globalvar.h index 1cd8d21a2e..2a5d8a1a1a 100644 --- a/include/globalvar.h +++ b/include/globalvar.h @@ -18,75 +18,15 @@ void globalvar_remove(const char *name); char *globalvar_get_match(const char *match, const char *separator); void globalvar_set_match(const char *match, const char *val); -static inline int globalvar_add_simple_string(const char *name, - char **value) -{ - struct param_d *p; - - p = dev_add_param_string(&global_device, name, NULL, NULL, - value, NULL); - - if (IS_ERR(p)) - return PTR_ERR(p); - - return 0; -} - -static inline int globalvar_add_simple_int(const char *name, - int *value, const char *format) -{ - struct param_d *p; - - p = dev_add_param_int(&global_device, name, NULL, NULL, - value, format, NULL); - - if (IS_ERR(p)) - return PTR_ERR(p); - - return 0; -} - -static inline int globalvar_add_simple_bool(const char *name, - int *value) -{ - struct param_d *p; - - p = dev_add_param_bool(&global_device, name, NULL, NULL, - value, NULL); - - if (IS_ERR(p)) - return PTR_ERR(p); - - return 0; -} - -static inline int globalvar_add_simple_enum(const char *name, - int *value, const char * const *names, int max) -{ - struct param_d *p; - - p = dev_add_param_enum(&global_device, name, NULL, NULL, - value, names, max, NULL); - - if (IS_ERR(p)) - return PTR_ERR(p); - - return 0; -} - -static inline int globalvar_add_simple_ip(const char *name, - IPaddr_t *ip) -{ - struct param_d *p; - - p = dev_add_param_ip(&global_device, name, NULL, NULL, - ip, NULL); - - if (IS_ERR(p)) - return PTR_ERR(p); - - return 0; -} +int globalvar_add_simple_string(const char *name, char **value); +int globalvar_add_simple_int(const char *name, int *value, + const char *format); +int globalvar_add_simple_bool(const char *name, int *value); +int globalvar_add_simple_enum(const char *name, int *value, + const char * const *names, int max); +int globalvar_add_simple_bitmask(const char *name, unsigned long *value, + const char * const *names, int max); +int globalvar_add_simple_ip(const char *name, IPaddr_t *ip); int nvvar_load(void); void nvvar_print(void); @@ -125,6 +65,14 @@ static inline int globalvar_add_simple_enum(const char *name, return 0; } +static inline int globalvar_add_simple_bitmask(const char *name, + unsigned long *value, + const char * const *names, + int max) +{ + return 0; +} + static inline int globalvar_add_simple_ip(const char *name, IPaddr_t *ip) { diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 76a6425be8..66c936ee70 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -742,4 +742,56 @@ static inline bool nand_is_slc(struct nand_chip *chip) return chip->bits_per_cell == 1; } +/** + * struct nand_sdr_timings - SDR NAND chip timings + * + * This struct defines the timing requirements of a SDR NAND chip. + * These informations can be found in every NAND datasheets and the timings + * meaning are described in the ONFI specifications: + * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing + * Parameters) + * + * All these timings are expressed in picoseconds. + */ + +struct nand_sdr_timings { + u32 tALH_min; + u32 tADL_min; + u32 tALS_min; + u32 tAR_min; + u32 tCEA_max; + u32 tCEH_min; + u32 tCH_min; + u32 tCHZ_max; + u32 tCLH_min; + u32 tCLR_min; + u32 tCLS_min; + u32 tCOH_min; + u32 tCS_min; + u32 tDH_min; + u32 tDS_min; + u32 tFEAT_max; + u32 tIR_min; + u32 tITC_max; + u32 tRC_min; + u32 tREA_max; + u32 tREH_min; + u32 tRHOH_min; + u32 tRHW_min; + u32 tRHZ_max; + u32 tRLOH_min; + u32 tRP_min; + u32 tRR_min; + u64 tRST_max; + u32 tWB_max; + u32 tWC_min; + u32 tWH_min; + u32 tWHR_min; + u32 tWP_min; + u32 tWW_min; +}; + +/* get timing characteristics from ONFI timing mode. */ +const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode); + #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/menu.h b/include/menu.h index 8b0ffb1f83..3e704a8907 100644 --- a/include/menu.h +++ b/include/menu.h @@ -47,7 +47,10 @@ struct menu_entry { struct menu { char *name; - char *display; + /* Multiline title */ + char **display; + /* Number of lines */ + int display_lines; int auto_select; char *auto_display; @@ -88,6 +91,7 @@ int menu_set_selected_entry(struct menu *m, struct menu_entry* me); int menu_set_selected(struct menu *m, int num); int menu_set_auto_select(struct menu *m, int delay); struct menu* menu_get_menus(void); +void menu_add_title(struct menu *m, char *display); /* * menu entry functions diff --git a/include/mfd/mc13xxx.h b/include/mfd/mc13xxx.h index 96a32e4dad..d351c473f4 100644 --- a/include/mfd/mc13xxx.h +++ b/include/mfd/mc13xxx.h @@ -127,12 +127,13 @@ #define MC13892_REVISION_2_0 3 #define MC13892_REVISION_2_0a 4 #define MC13892_REVISION_2_1 5 -#define MC13892_REVISION_3_0 6 -#define MC13892_REVISION_3_1 7 -#define MC13892_REVISION_3_2 8 -#define MC13892_REVISION_3_2a 9 -#define MC13892_REVISION_3_3 10 -#define MC13892_REVISION_3_5 11 +#define MC13892_REVISION_2_4 6 +#define MC13892_REVISION_3_0 7 +#define MC13892_REVISION_3_1 8 +#define MC13892_REVISION_3_2 9 +#define MC13892_REVISION_3_2a 10 +#define MC13892_REVISION_3_3 11 +#define MC13892_REVISION_3_5 12 #define MC13783_SWX_VOLTAGE(x) ((x) & 0x3f) #define MC13783_SWX_VOLTAGE_DVS(x) (((x) & 0x3f) << 6) diff --git a/include/param.h b/include/param.h index 3fb4740b3a..0f7d2446a2 100644 --- a/include/param.h +++ b/include/param.h @@ -6,6 +6,7 @@ #include <linux/list.h> #define PARAM_FLAG_RO (1 << 0) +#define PARAM_GLOBALVAR_UNQUALIFIED (1 << 1) struct device_d; typedef uint32_t IPaddr_t; @@ -52,6 +53,11 @@ struct param_d *dev_add_param_enum(struct device_d *dev, const char *name, int (*get)(struct param_d *p, void *priv), int *value, const char * const *names, int max, void *priv); +struct param_d *dev_add_param_bitmask(struct device_d *dev, const char *name, + int (*set)(struct param_d *p, void *priv), + int (*get)(struct param_d *p, void *priv), + unsigned long *value, const char * const *names, int max, void *priv); + struct param_d *dev_add_param_int_ro(struct device_d *dev, const char *name, int value, const char *format); diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h index 29b117c51f..901b26add6 100644 --- a/include/serial/imx-uart.h +++ b/include/serial/imx-uart.h @@ -146,6 +146,11 @@ static inline void imx_uart_setup(void __iomem *uartbase, writel(UCR1_UARTEN, uartbase + UCR1); } +static inline void imx50_uart_setup(void __iomem *uartbase) +{ + imx_uart_setup(uartbase, 66666666); +} + static inline void imx51_uart_setup(void __iomem *uartbase) { imx_uart_setup(uartbase, 54000000); diff --git a/include/video/fourcc.h b/include/video/fourcc.h index 322142c1ba..211aabb1f3 100644 --- a/include/video/fourcc.h +++ b/include/video/fourcc.h @@ -1,157 +1,6 @@ #ifndef __VIDEO_FOURCC_H #define __VIDEO_FOURCC_H -/* Four-character-code (FOURCC) */ -#define v4l2_fourcc(a, b, c, d)\ - ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) - -/* Pixel format FOURCC depth Description */ - -/* RGB formats */ -#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ -#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ -#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ -#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ -#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ -#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ -#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */ -#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ -#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ -#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ -#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ - -/* Grey formats */ -#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ -#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ -#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ -#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ -#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ -#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ - -/* Grey bit-packed formats */ -#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ - -/* Palette formats */ -#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ - -/* Chrominance formats */ -#define V4L2_PIX_FMT_UV8 v4l2_fourcc('U', 'V', '8', ' ') /* 8 UV 4:4 */ - -/* Luminance+Chrominance formats */ -#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ -#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ -#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ -#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ -#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ -#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ -#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ -#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ -#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ -#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ -#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ -#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ -#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ -#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ -#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ -#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ -#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ -#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ -#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ - -/* two planes -- one Y, one Cr + Cb interleaved */ -#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ -#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ -#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ -#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ -#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ -#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ - -/* two non contiguous planes - one Y, one Cr + Cb interleaved */ -#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ -#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */ -#define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6') /* 16 Y/CbCr 4:2:2 */ -#define V4L2_PIX_FMT_NV61M v4l2_fourcc('N', 'M', '6', '1') /* 16 Y/CrCb 4:2:2 */ -#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ -#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 macroblocks */ - -/* three non contiguous planes - Y, Cb, Cr */ -#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */ -#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1') /* 12 YVU420 planar */ - -/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ -#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ -#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ -#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ -#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ -#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ -#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ -#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ -#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ -#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */ -#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */ -#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ -#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ - /* 10bit raw bayer a-law compressed to 8 bits */ -#define V4L2_PIX_FMT_SBGGR10ALAW8 v4l2_fourcc('a', 'B', 'A', '8') -#define V4L2_PIX_FMT_SGBRG10ALAW8 v4l2_fourcc('a', 'G', 'A', '8') -#define V4L2_PIX_FMT_SGRBG10ALAW8 v4l2_fourcc('a', 'g', 'A', '8') -#define V4L2_PIX_FMT_SRGGB10ALAW8 v4l2_fourcc('a', 'R', 'A', '8') - /* 10bit raw bayer DPCM compressed to 8 bits */ -#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8') -#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8') -#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') -#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8') - /* - * 10bit raw bayer, expanded to 16 bits - * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... - */ -#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ - -/* compressed formats */ -#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ -#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ -#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ -#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */ -#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */ -#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */ -#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */ -#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ -#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */ -#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */ -#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 part 2 ES */ -#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ -#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ -#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ -#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ - -/* Vendor-specific formats */ -#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ -#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ -#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ -#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ -#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ -#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ -#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ -#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ -#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ -#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ -#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ -#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ -#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ -#define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB bayer */ -#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ -#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ -#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ -#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ -#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ -#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ -#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ -#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ -#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ -#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */ -#define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */ -#define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') /* S5C73M3 interleaved UYVY/JPEG */ - #define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \ ((__u32)(c) << 16) | ((__u32)(d) << 24)) diff --git a/include/video/media-bus-format.h b/include/video/media-bus-format.h new file mode 100644 index 0000000000..190d491d5b --- /dev/null +++ b/include/video/media-bus-format.h @@ -0,0 +1,137 @@ +/* + * Media Bus API header + * + * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * 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. + */ + +#ifndef __LINUX_MEDIA_BUS_FORMAT_H +#define __LINUX_MEDIA_BUS_FORMAT_H + +/* + * These bus formats uniquely identify data formats on the data bus. Format 0 + * is reserved, MEDIA_BUS_FMT_FIXED shall be used by host-client pairs, where + * the data format is fixed. Additionally, "2X8" means that one pixel is + * transferred in two 8-bit samples, "BE" or "LE" specify in which order those + * samples are transferred over the bus: "LE" means that the least significant + * bits are transferred first, "BE" means that the most significant bits are + * transferred first, and "PADHI" and "PADLO" define which bits - low or high, + * in the incomplete high byte, are filled with padding bits. + * + * The bus formats are grouped by type, bus_width, bits per component, samples + * per pixel and order of subsamples. Numerical values are sorted using generic + * numerical sort order (8 thus comes before 10). + * + * As their value can't change when a new bus format is inserted in the + * enumeration, the bus formats are explicitly given a numerical value. The next + * free values for each category are listed below, update them when inserting + * new pixel codes. + */ + +#define MEDIA_BUS_FMT_FIXED 0x0001 + +/* RGB - next is 0x1018 */ +#define MEDIA_BUS_FMT_RGB444_1X12 0x1016 +#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 +#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 +#define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE 0x1003 +#define MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE 0x1004 +#define MEDIA_BUS_FMT_RGB565_1X16 0x1017 +#define MEDIA_BUS_FMT_BGR565_2X8_BE 0x1005 +#define MEDIA_BUS_FMT_BGR565_2X8_LE 0x1006 +#define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007 +#define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008 +#define MEDIA_BUS_FMT_RGB666_1X18 0x1009 +#define MEDIA_BUS_FMT_RBG888_1X24 0x100e +#define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015 +#define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010 +#define MEDIA_BUS_FMT_BGR888_1X24 0x1013 +#define MEDIA_BUS_FMT_GBR888_1X24 0x1014 +#define MEDIA_BUS_FMT_RGB888_1X24 0x100a +#define MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b +#define MEDIA_BUS_FMT_RGB888_2X12_LE 0x100c +#define MEDIA_BUS_FMT_RGB888_1X7X4_SPWG 0x1011 +#define MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA 0x1012 +#define MEDIA_BUS_FMT_ARGB8888_1X32 0x100d +#define MEDIA_BUS_FMT_RGB888_1X32_PADHI 0x100f + +/* YUV (including grey) - next is 0x2026 */ +#define MEDIA_BUS_FMT_Y8_1X8 0x2001 +#define MEDIA_BUS_FMT_UV8_1X8 0x2015 +#define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 +#define MEDIA_BUS_FMT_VYUY8_1_5X8 0x2003 +#define MEDIA_BUS_FMT_YUYV8_1_5X8 0x2004 +#define MEDIA_BUS_FMT_YVYU8_1_5X8 0x2005 +#define MEDIA_BUS_FMT_UYVY8_2X8 0x2006 +#define MEDIA_BUS_FMT_VYUY8_2X8 0x2007 +#define MEDIA_BUS_FMT_YUYV8_2X8 0x2008 +#define MEDIA_BUS_FMT_YVYU8_2X8 0x2009 +#define MEDIA_BUS_FMT_Y10_1X10 0x200a +#define MEDIA_BUS_FMT_UYVY10_2X10 0x2018 +#define MEDIA_BUS_FMT_VYUY10_2X10 0x2019 +#define MEDIA_BUS_FMT_YUYV10_2X10 0x200b +#define MEDIA_BUS_FMT_YVYU10_2X10 0x200c +#define MEDIA_BUS_FMT_Y12_1X12 0x2013 +#define MEDIA_BUS_FMT_UYVY12_2X12 0x201c +#define MEDIA_BUS_FMT_VYUY12_2X12 0x201d +#define MEDIA_BUS_FMT_YUYV12_2X12 0x201e +#define MEDIA_BUS_FMT_YVYU12_2X12 0x201f +#define MEDIA_BUS_FMT_UYVY8_1X16 0x200f +#define MEDIA_BUS_FMT_VYUY8_1X16 0x2010 +#define MEDIA_BUS_FMT_YUYV8_1X16 0x2011 +#define MEDIA_BUS_FMT_YVYU8_1X16 0x2012 +#define MEDIA_BUS_FMT_YDYUYDYV8_1X16 0x2014 +#define MEDIA_BUS_FMT_UYVY10_1X20 0x201a +#define MEDIA_BUS_FMT_VYUY10_1X20 0x201b +#define MEDIA_BUS_FMT_YUYV10_1X20 0x200d +#define MEDIA_BUS_FMT_YVYU10_1X20 0x200e +#define MEDIA_BUS_FMT_VUY8_1X24 0x2024 +#define MEDIA_BUS_FMT_YUV8_1X24 0x2025 +#define MEDIA_BUS_FMT_UYVY12_1X24 0x2020 +#define MEDIA_BUS_FMT_VYUY12_1X24 0x2021 +#define MEDIA_BUS_FMT_YUYV12_1X24 0x2022 +#define MEDIA_BUS_FMT_YVYU12_1X24 0x2023 +#define MEDIA_BUS_FMT_YUV10_1X30 0x2016 +#define MEDIA_BUS_FMT_AYUV8_1X32 0x2017 + +/* Bayer - next is 0x3019 */ +#define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001 +#define MEDIA_BUS_FMT_SGBRG8_1X8 0x3013 +#define MEDIA_BUS_FMT_SGRBG8_1X8 0x3002 +#define MEDIA_BUS_FMT_SRGGB8_1X8 0x3014 +#define MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8 0x3015 +#define MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8 0x3016 +#define MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8 0x3017 +#define MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8 0x3018 +#define MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 0x300b +#define MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 0x300c +#define MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 0x3009 +#define MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 0x300d +#define MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE 0x3003 +#define MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE 0x3004 +#define MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE 0x3005 +#define MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE 0x3006 +#define MEDIA_BUS_FMT_SBGGR10_1X10 0x3007 +#define MEDIA_BUS_FMT_SGBRG10_1X10 0x300e +#define MEDIA_BUS_FMT_SGRBG10_1X10 0x300a +#define MEDIA_BUS_FMT_SRGGB10_1X10 0x300f +#define MEDIA_BUS_FMT_SBGGR12_1X12 0x3008 +#define MEDIA_BUS_FMT_SGBRG12_1X12 0x3010 +#define MEDIA_BUS_FMT_SGRBG12_1X12 0x3011 +#define MEDIA_BUS_FMT_SRGGB12_1X12 0x3012 + +/* JPEG compressed formats - next is 0x4002 */ +#define MEDIA_BUS_FMT_JPEG_1X8 0x4001 + +/* Vendor specific formats - next is 0x5002 */ + +/* S5C73M3 sensor specific interleaved UYVY and JPEG */ +#define MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8 0x5001 + +/* HSV - next is 0x6002 */ +#define MEDIA_BUS_FMT_AHSV8888_1X32 0x6001 + +#endif /* __LINUX_MEDIA_BUS_FORMAT_H */ diff --git a/include/video/vpl.h b/include/video/vpl.h index 846007f4f5..6ae7b0f3e0 100644 --- a/include/video/vpl.h +++ b/include/video/vpl.h @@ -8,6 +8,7 @@ #define VPL_ENABLE 0x67660003 #define VPL_DISABLE 0x67660004 #define VPL_GET_VIDEOMODES 0x67660005 +#define VPL_GET_BUS_FORMAT 0x67660006 struct vpl { int (*ioctl)(struct vpl *, unsigned int port, diff --git a/lib/parameter.c b/lib/parameter.c index 656a6037c6..529d7ab92a 100644 --- a/lib/parameter.c +++ b/lib/parameter.c @@ -505,6 +505,141 @@ struct param_d *dev_add_param_enum(struct device_d *dev, const char *name, return &pe->param; } +struct param_bitmask { + struct param_d param; + unsigned long *value; + const char * const *names; + int num_names; + int (*set)(struct param_d *p, void *priv); + int (*get)(struct param_d *p, void *priv); +}; + +static inline struct param_bitmask *to_param_bitmask(struct param_d *p) +{ + return container_of(p, struct param_bitmask, param); +} + +static int param_bitmask_set(struct device_d *dev, struct param_d *p, const char *val) +{ + struct param_bitmask *pb = to_param_bitmask(p); + void *value_save; + int i, ret; + char *freep, *dval, *str; + + if (!val) + val = ""; + + freep = dval = xstrdup(val); + value_save = xmemdup(pb->value, BITS_TO_LONGS(pb->num_names) * sizeof(unsigned long)); + + while (1) { + str = strsep(&dval, " "); + if (!str || !*str) + break; + + for (i = 0; i < pb->num_names; i++) { + if (pb->names[i] && !strcmp(str, pb->names[i])) { + set_bit(i, pb->value); + break; + } + } + + if (i == pb->num_names) { + ret = -EINVAL; + goto out; + } + } + + if (!pb->set) { + ret = 0; + goto out; + } + + ret = pb->set(p, p->driver_priv); + if (ret) + memcpy(pb->value, value_save, BITS_TO_LONGS(pb->num_names) * sizeof(unsigned long)); + +out: + free(value_save); + free(freep); + return ret; +} + +static const char *param_bitmask_get(struct device_d *dev, struct param_d *p) +{ + struct param_bitmask *pb = to_param_bitmask(p); + int ret, bit; + char *pos; + + if (pb->get) { + ret = pb->get(p, p->driver_priv); + if (ret) + return NULL; + } + + pos = p->value; + + for_each_set_bit(bit, pb->value, pb->num_names) + if (pb->names[bit]) + pos += sprintf(pos, "%s ", pb->names[bit]); + + return p->value; +} + +static void param_bitmask_info(struct param_d *p) +{ + struct param_bitmask *pb = to_param_bitmask(p); + int i; + + if (pb->num_names <= 1) + return; + + printf(" (list: "); + + for (i = 0; i < pb->num_names; i++) { + if (!pb->names[i] || !*pb->names[i]) + continue; + printf("\"%s\"%s", pb->names[i], + i == pb->num_names - 1 ? ")" : ", "); + } +} + +struct param_d *dev_add_param_bitmask(struct device_d *dev, const char *name, + int (*set)(struct param_d *p, void *priv), + int (*get)(struct param_d *p, void *priv), + unsigned long *value, const char * const *names, int max, void *priv) +{ + struct param_bitmask *pb; + struct param_d *p; + int ret, i, len = 0; + + pb = xzalloc(sizeof(*pb)); + + pb->value = value; + pb->set = set; + pb->get = get; + pb->names = names; + pb->num_names = max; + p = &pb->param; + p->driver_priv = priv; + + for (i = 0; i < pb->num_names; i++) + if (pb->names[i]) + len += strlen(pb->names[i]) + 1; + + p->value = xzalloc(len); + + ret = __dev_add_param(p, dev, name, param_bitmask_set, param_bitmask_get, 0); + if (ret) { + free(pb); + return ERR_PTR(ret); + } + + p->info = param_bitmask_info; + + return &pb->param; +} + /** * dev_add_param_bool - add an boolean parameter to a device * @param dev The device diff --git a/lib/string.c b/lib/string.c index a3e9fd819b..1d491c9c2f 100644 --- a/lib/string.c +++ b/lib/string.c @@ -641,7 +641,7 @@ char *skip_spaces(const char *str) } /** - * strim - Removes leading and trailing whitespace from @s. + * strim - Removes trailing whitespace from @s. * @s: The string to be stripped. * * Note that the first trailing whitespace is replaced with a %NUL-terminator diff --git a/lib/xfuncs.c b/lib/xfuncs.c index aaf0788544..1dc2ea92d8 100644 --- a/lib/xfuncs.c +++ b/lib/xfuncs.c @@ -56,10 +56,15 @@ EXPORT_SYMBOL(xzalloc); char *xstrdup(const char *s) { - char *p = strdup(s); + char *p; + + if (!s) + return NULL; + p = strdup(s); if (!p) panic("ERROR: out of memory\n"); + return p; } EXPORT_SYMBOL(xstrdup); diff --git a/pbl/console.c b/pbl/console.c index 4cefe74808..007e4e4b83 100644 --- a/pbl/console.c +++ b/pbl/console.c @@ -1,8 +1,13 @@ #include <common.h> #include <debug_ll.h> +#include <linux/err.h> -static void (*__putc)(void *ctx, int c); -static void *putc_ctx; +/* + * Put these in the data section so that they survive the clearing of the + * BSS segment. + */ +static __attribute__ ((section(".data"))) void (*__putc)(void *ctx, int c); +static __attribute__ ((section(".data"))) void *putc_ctx; /** * pbl_set_putc() - setup UART used for PBL console @@ -20,10 +25,10 @@ void pbl_set_putc(void (*putcf)(void *ctx, int c), void *ctx) void console_putc(unsigned int ch, char c) { - if (!__putc) - putc_ll(c); - else + if (__putc) __putc(putc_ctx, c); + else + putc_ll(c); } int console_puts(unsigned int ch, const char *str) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index e55bc27789..e79998c1b9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -380,6 +380,14 @@ cmd_lz4 = (cat $(filter-out FORCE,$^) | \ %.lz4: % $(call if_changed,lz4) +# comp_copy +# --------------------------------------------------------------------------- +# Wrapper which only copies a file, but compatible to the compression +# functions above. Appends the size to the result file +quiet_cmd_comp_copy ?= SHIPPED_S $@ +cmd_comp_copy ?= cat $(filter-out FORCE,$^) > $@; \ + $(call size_append, $(filter-out FORCE,$^)) >> $@ + quiet_cmd_disasm = DISASM $@ cmd_disasm = $(OBJDUMP) -d $< > $@ diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c index c0bf9c004f..650a67f604 100644 --- a/scripts/imx/imx-image.c +++ b/scripts/imx/imx-image.c @@ -274,7 +274,7 @@ static int write_mem_v1(uint32_t addr, uint32_t val, int width, int set_bits, in /* * ============================================================================ - * i.MX flash header v2 handling. Found on i.MX53 and i.MX6 + * i.MX flash header v2 handling. Found on i.MX50, i.MX53 and i.MX6 * ============================================================================ */ @@ -380,7 +380,7 @@ static int write_mem_v2(uint32_t addr, uint32_t val, int width, int set_bits, in if (set_bits) cmd |= 3 << 3; if (clear_bits) - cmd |= 2 << 3; + cmd |= 1 << 3; if (curdcd > MAX_DCD - 3) { fprintf(stderr, "At maximum %d dcd entried are allowed\n", MAX_DCD); @@ -450,6 +450,11 @@ static int write_dcd(const char *outfile) static int check(const struct config_data *data, uint32_t cmd, uint32_t addr, uint32_t mask) { + if (data->header_version != 2) { + fprintf(stderr, "DCD check command is not available or " + "not yet implemented for this SOC\n"); + return -EINVAL; + } if (curdcd > MAX_DCD - 3) { fprintf(stderr, "At maximum %d dcd entried are allowed\n", MAX_DCD); return -ENOMEM; diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c index 17324972bf..c0aaa7d629 100644 --- a/scripts/imx/imx-usb-loader.c +++ b/scripts/imx/imx-usb-loader.c @@ -32,6 +32,7 @@ #include <stdlib.h> #include <libusb.h> #include <getopt.h> +#include <endian.h> #include <arpa/inet.h> #include <linux/kernel.h> @@ -45,7 +46,6 @@ #define FT_LOAD_ONLY 0x00 int verbose; -static int skip_image_dcd; static struct libusb_device_handle *usb_dev_handle; static struct usb_id *usb_id; @@ -67,7 +67,7 @@ struct mach_id { struct usb_work { char filename[256]; - unsigned char dcd; + unsigned char do_dcd_once; unsigned char plug; }; @@ -90,6 +90,9 @@ struct mach_id imx_ids[] = { .vid = 0x15a2, .pid = 0x0052, .name = "i.MX50", + .header_type = HDR_MX53, + .mode = MODE_HID, + .max_transfer = 1024, }, { .vid = 0x15a2, .pid = 0x0054, @@ -743,7 +746,45 @@ static int sdp_jump_address(unsigned addr) return 0; } -static int write_dcd_table_ivt(const struct imx_flash_header_v2 *hdr, +static int do_dcd_v2_cmd_write(const unsigned char *dcd) +{ + int set_bits = 0, clear_bits = 0; + int idx, bytes; + struct imx_dcd_v2_write *recs = (struct imx_dcd_v2_write *) dcd; + int num_rec = (ntohs(recs->length) - 4) / + sizeof(struct imx_dcd_v2_write_rec); + printf("DCD write: sub dcd length: 0x%04x, flags: 0x%02x\n", + ntohs(recs->length), recs->param); + + if (recs->param & PARAMETER_FLAG_MASK) { + if (recs->param & PARAMETER_FLAG_SET) + set_bits = 1; + else + clear_bits = 1; + } + bytes = recs->param & 7; + switch (bytes) { + case 1: + case 2: + case 4: + break; + default: + fprintf(stderr, "ERROR: bad DCD write width %i\n", bytes); + return -1; + } + + for (idx = 0; idx < num_rec; idx++) { + const struct imx_dcd_v2_write_rec *record = &recs->data[idx]; + int ret = modify_memory(ntohl(record->addr), + ntohl(record->val), bytes, + set_bits, clear_bits); + if (ret < 0) + return ret; + } + return 0; +} + +static int process_dcd_table_ivt(const struct imx_flash_header_v2 *hdr, const unsigned char *file_start, unsigned cnt) { unsigned char *dcd_end; @@ -751,7 +792,7 @@ static int write_dcd_table_ivt(const struct imx_flash_header_v2 *hdr, #define cvt_dest_to_src (((unsigned char *)hdr) - hdr->self) unsigned char* dcd; const unsigned char *file_end = file_start + cnt; - int err = 0; + struct imx_ivt_header *dcd_hdr; if (!hdr->dcd_ptr) { printf("No dcd table in this ivt\n"); @@ -761,65 +802,60 @@ static int write_dcd_table_ivt(const struct imx_flash_header_v2 *hdr, dcd = hdr->dcd_ptr + cvt_dest_to_src; if ((dcd < file_start) || ((dcd + 4) > file_end)) { - printf("bad dcd_ptr %08x\n", hdr->dcd_ptr); + fprintf(stderr, "bad dcd_ptr %08x\n", hdr->dcd_ptr); return -1; } - m_length = (dcd[1] << 8) + dcd[2]; - - printf("main dcd length %x\n", m_length); - - if ((dcd[0] != 0xd2) || (dcd[3] != 0x40)) { - printf("Unknown tag\n"); + dcd_hdr = (struct imx_ivt_header *) dcd; + if ((dcd_hdr->tag != TAG_DCD_HEADER) || + (dcd_hdr->version != DCD_VERSION)) { + fprintf(stderr, "Error: Unknown DCD header tag\n"); return -1; } - + m_length = ntohs(dcd_hdr->length); dcd_end = dcd + m_length; - if (dcd_end > file_end) { - printf("bad dcd length %08x\n", m_length); + fprintf(stderr, "Error: DCD length %08x exceeds EOF\n", + m_length); return -1; } + printf("main dcd length %x\n", m_length); dcd += 4; while (dcd < dcd_end) { - unsigned s_length = (dcd[1] << 8) + dcd[2]; - unsigned char *s_end = dcd + s_length; - int set_bits = 0, clear_bits = 0; - - printf("command: 0x%02x sub dcd length: 0x%04x, flags: 0x%02x\n", dcd[0], s_length, dcd[3]); - - if ((dcd[0] != 0xcc)) { - printf("Skipping unknown sub tag 0x%02x with len %04x\n", dcd[0], s_length); - usleep(50000); - dcd += s_length; - continue; - } - - if (dcd[3] & PARAMETER_FLAG_MASK) { - if (dcd[3] & PARAMETER_FLAG_SET) - set_bits = 1; - else - clear_bits = 1; - } - - dcd += 4; - - if (s_end > dcd_end) { - printf("error s_end(%p) > dcd_end(%p)\n", s_end, dcd_end); + int ret = 0; + struct imx_ivt_header *cmd_hdr = (struct imx_ivt_header *) dcd; + unsigned s_length = ntohs(cmd_hdr->length); + if (dcd + s_length > file_end) { + fprintf(stderr, "Error: DCD length %08x exceeds EOF\n", + s_length); return -1; } - - while (dcd < s_end) { - unsigned addr = (dcd[0] << 24) | (dcd[1] << 16) | (dcd[2] << 8) | dcd[3]; - unsigned val = (dcd[4] << 24) | (dcd[5] << 16) | (dcd[6] << 8) | dcd[7]; - - dcd += 8; - - modify_memory(addr, val, 4, set_bits, clear_bits); + switch (cmd_hdr->tag) { + case TAG_WRITE: + ret = do_dcd_v2_cmd_write(dcd); + break; + case TAG_CHECK: + fprintf(stderr, "DCD check not implemented yet\n"); + usleep(50000); + break; + case TAG_UNLOCK: + fprintf(stderr, "DCD unlock not implemented yet\n"); + usleep(50000); + break; + case TAG_NOP: + break; + default: + fprintf(stderr, "Skipping unknown DCD sub tag 0x%02x " + "with len %04x\n", cmd_hdr->tag, s_length); + usleep(50000); + break; } + dcd += s_length; + if (ret < 0) + return ret; } - return err; + return 0; } static int get_dcd_range_old(const struct imx_flash_header *hdr, @@ -872,7 +908,6 @@ static int get_dcd_range_old(const struct imx_flash_header *hdr, static int write_dcd_table_old(const struct imx_flash_header *hdr, const unsigned char *file_start, unsigned cnt) { - unsigned val; unsigned char *dcd_end; unsigned char* dcd; int err = get_dcd_range_old(hdr, file_start, cnt, &dcd, &dcd_end); @@ -882,28 +917,26 @@ static int write_dcd_table_old(const struct imx_flash_header *hdr, printf("writing DCD table...\n"); while (dcd < dcd_end) { - unsigned type = (dcd[0] << 0) | (dcd[1] << 8) | (dcd[2] << 16) | (dcd[3] << 24); - unsigned addr = (dcd[4] << 0) | (dcd[5] << 8) | (dcd[6] << 16) | (dcd[7] << 24); - val = (dcd[8] << 0) | (dcd[9] << 8) | (dcd[10] << 16) | (dcd[11] << 24); - dcd += 12; + struct imx_dcd_rec_v1 *rec = (struct imx_dcd_rec_v1 *) dcd; + unsigned type = le32toh(rec->type); + dcd += sizeof *rec; switch (type) { case 1: - if (verbose > 1) - printf("type=%08x *0x%08x = 0x%08x\n", type, addr, val); - err = write_memory(addr, val, 1); - if (err < 0) - return err; - break; + case 2: case 4: if (verbose > 1) - printf("type=%08x *0x%08x = 0x%08x\n", type, addr, val); - err = write_memory(addr, val, 4); + printf("type=%08x *0x%08x = 0x%08x\n", type, + le32toh(rec->addr), + le32toh(rec->val)); + err = write_memory(le32toh(rec->addr), + le32toh(rec->val), type); if (err < 0) return err; break; default: - printf("!!!unknown type=%08x *0x%08x = 0x%08x\n", type, addr, val); + printf("WARNING: unknown DCD type=%08x ignored\n", + type); } } @@ -980,9 +1013,6 @@ static int perform_dcd(unsigned char *p, const unsigned char *file_start, struct imx_flash_header_v2 *hdr = (struct imx_flash_header_v2 *)p; int ret = 0; - if (skip_image_dcd) - return 0; - switch (usb_id->mach_id->header_type) { case HDR_MX51: ret = write_dcd_table_old(ohdr, file_start, cnt); @@ -990,7 +1020,7 @@ static int perform_dcd(unsigned char *p, const unsigned char *file_start, break; case HDR_MX53: - ret = write_dcd_table_ivt(hdr, file_start, cnt); + ret = process_dcd_table_ivt(hdr, file_start, cnt); hdr->dcd_ptr = 0; break; @@ -1066,13 +1096,13 @@ static int process_header(struct usb_work *curr, unsigned char *buf, int cnt, return ret; } - if (curr->dcd) { + if (curr->do_dcd_once) { ret = perform_dcd(p, buf, cnt); if (ret < 0) { printf("!!perform_dcd returned %i\n", ret); return ret; } - curr->dcd = 0; + curr->do_dcd_once = 0; } if (*p_plugin && (!curr->plug) && (!header_cnt)) { @@ -1264,6 +1294,8 @@ int main(int argc, char *argv[]) int opt; char *initfile = NULL; + w.do_dcd_once = 1; + while ((opt = getopt(argc, argv, "cvhi:s")) != -1) { switch (opt) { case 'c': @@ -1278,7 +1310,7 @@ int main(int argc, char *argv[]) initfile = optarg; break; case 's': - skip_image_dcd = 1; + w.do_dcd_once = 0; break; default: exit(1); @@ -1292,7 +1324,6 @@ int main(int argc, char *argv[]) } w.plug = 1; - w.dcd = 1; strncpy(w.filename, argv[optind], sizeof(w.filename) - 1); r = libusb_init(NULL); diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c index 4ec8c89541..c8ee3091e0 100644 --- a/scripts/imx/imx.c +++ b/scripts/imx/imx.c @@ -219,6 +219,7 @@ struct soc_type { static struct soc_type socs[] = { { .name = "imx25", .header_version = 1, .cpu_type = IMX_CPU_IMX25 }, { .name = "imx35", .header_version = 1, .cpu_type = IMX_CPU_IMX35 }, + { .name = "imx50", .header_version = 2, .cpu_type = IMX_CPU_IMX50 }, { .name = "imx51", .header_version = 1, .cpu_type = IMX_CPU_IMX51 }, { .name = "imx53", .header_version = 2, .cpu_type = IMX_CPU_IMX53 }, { .name = "imx6", .header_version = 2, .cpu_type = IMX_CPU_IMX6 }, diff --git a/scripts/imx/imx.h b/scripts/imx/imx.h index 8db7e7b46c..ae3702c116 100644 --- a/scripts/imx/imx.h +++ b/scripts/imx/imx.h @@ -26,14 +26,22 @@ struct imx_boot_data { uint32_t plugin; } __attribute__((packed)); +struct imx_dcd_rec_v1 { + uint32_t type; + uint32_t addr; + uint32_t val; +} __attribute__((packed)); + #define TAG_IVT_HEADER 0xd1 #define IVT_VERSION 0x40 #define TAG_DCD_HEADER 0xd2 #define DCD_VERSION 0x40 +#define TAG_UNLOCK 0xb2 +#define TAG_NOP 0xc0 #define TAG_WRITE 0xcc +#define TAG_CHECK 0xcf #define PARAMETER_FLAG_MASK (1 << 3) #define PARAMETER_FLAG_SET (1 << 4) -#define TAG_CHECK 0xcf struct imx_ivt_header { uint8_t tag; @@ -73,4 +81,17 @@ struct config_data { char *csf; }; +#define MAX_RECORDS_DCD_V2 1024 +struct imx_dcd_v2_write_rec { + uint32_t addr; + uint32_t val; +} __attribute__((packed)); + +struct imx_dcd_v2_write { + uint8_t tag; + uint16_t length; + uint8_t param; + struct imx_dcd_v2_write_rec data[MAX_RECORDS_DCD_V2]; +} __attribute__((packed)); + int parse_config(struct config_data *data, const char *filename); diff --git a/scripts/socfpga_mkimage.c b/scripts/socfpga_mkimage.c index 4fbd5c748e..d7fe1b1b69 100644 --- a/scripts/socfpga_mkimage.c +++ b/scripts/socfpga_mkimage.c @@ -14,7 +14,10 @@ #define BRANCH_INST 0xea /* ARM opcode for "b" (unconditional branch) */ -#define MAX_IMAGE_SIZE (60 * 1024 - 4) +#define MAX_V0IMAGE_SIZE (60 * 1024 - 4) +/* Max size without authentication is 224 KB, due to memory used by + * the ROM boot code as a workspace out of the 256 KB of OCRAM */ +#define MAX_V1IMAGE_SIZE (224 * 1024 - 4) static int add_barebox_header; @@ -22,10 +25,21 @@ struct socfpga_header { uint8_t validation_word[4]; uint8_t version; uint8_t flags; - uint8_t program_length[2]; - uint8_t spare[2]; - uint8_t checksum[2]; - uint8_t start_vector[4]; + union { + struct { + uint8_t program_length[2]; + uint8_t spare[2]; + uint8_t checksum[2]; + uint8_t start_vector[4]; + } v0; + struct { + uint8_t header_length[2]; + uint8_t program_length[4]; + uint8_t entry_offset[4]; + uint8_t spare[2]; + uint8_t checksum[2]; + } v1; + }; }; static uint32_t bb_header[] = { @@ -87,7 +101,7 @@ static int write_full(int fd, void *buf, size_t size) return insize; } -static uint32_t crc_table[256] = { +static const uint32_t crc_table[256] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, @@ -143,47 +157,94 @@ uint32_t crc32(uint32_t crc, void *_buf, int length) return crc; } +/* Create an ARM relative branch instuction + * branch is where the instruction will be placed and dest points to where + * it should branch too. */ +static void branch(uint8_t *branch, uint8_t *dest) +{ + int offset = dest - branch - 8; /* PC is offset +8 bytes on ARM */ + + branch[0] = (offset >> 2) & 0xff; /* instruction uses offset/4 */ + branch[1] = (offset >> 10) & 0xff; + branch[2] = (offset >> 18) & 0xff; + branch[3] = BRANCH_INST; +} + /* start_addr is where the socfpga header's start instruction should branch to. * It should be relative to the start of buf */ -static int add_socfpga_header(void *buf, size_t size, unsigned start_addr) +static int add_socfpga_header(void *buf, size_t size, unsigned start_addr, unsigned version) { struct socfpga_header *header = buf + 0x40; - uint8_t *bufp; + void *entry; + uint8_t *bufp, *sumendp; uint32_t *crc; unsigned checksum; - size_t length = size >> 2; if (size & 0x3) { fprintf(stderr, "%s: size must be multiple of 4\n", __func__); return -EINVAL; } - /* Calculate relative address of requested start_addr from the - * start_vector's branch instuction PC (+8 bytes on arm). */ - start_addr = start_addr + (int)(buf - (void*)&header->start_vector[0]) - 8; + /* Absolute address of entry point in buf */ + entry = buf + start_addr; + if (version == 0) { + sumendp = &header->v0.checksum[0]; + } else { + sumendp = &header->v1.checksum[0]; + + /* The ROM loader can't handle a negative offset */ + if (entry < (void*)header) { + /* add a trampoline branch inst after end of the header */ + uint8_t *trampoline = (void*)(header + 1); + branch(trampoline, entry); + + /* and then make the trampoline the entry point */ + entry = trampoline; + } + /* Calculate start address as offset relative to start of header */ + start_addr = entry - (void*)header; + } header->validation_word[0] = VALIDATION_WORD & 0xff; header->validation_word[1] = (VALIDATION_WORD >> 8) & 0xff; header->validation_word[2] = (VALIDATION_WORD >> 16) & 0xff; header->validation_word[3] = (VALIDATION_WORD >> 24) & 0xff; - header->version = 0; + header->version = version; header->flags = 0; - header->program_length[0] = length & 0xff; - header->program_length[1] = (length >> 8) & 0xff; - header->spare[0] = 0; - header->spare[1] = 0; - header->start_vector[0] = (start_addr >> 2) & 0xff; /* instruction uses offset/4 */ - header->start_vector[1] = (start_addr >> 10) & 0xff; - header->start_vector[2] = (start_addr >> 18) & 0xff; - header->start_vector[3] = BRANCH_INST; + + if (version == 0) { + header->v0.program_length[0] = (size >> 2) & 0xff; /* length in words */ + header->v0.program_length[1] = (size >> 10) & 0xff; + header->v0.spare[0] = 0; + header->v0.spare[1] = 0; + branch(header->v0.start_vector, entry); + } else { + header->v1.header_length[0] = (sizeof(*header) >> 0) & 0xff; + header->v1.header_length[1] = (sizeof(*header) >> 8) & 0xff; + header->v1.program_length[0] = (size >> 0) & 0xff; + header->v1.program_length[1] = (size >> 8) & 0xff; + header->v1.program_length[2] = (size >> 16) & 0xff; + header->v1.program_length[3] = (size >> 24) & 0xff; + header->v1.entry_offset[0] = (start_addr >> 0) & 0xff; + header->v1.entry_offset[1] = (start_addr >> 8) & 0xff; + header->v1.entry_offset[2] = (start_addr >> 16) & 0xff; + header->v1.entry_offset[3] = (start_addr >> 24) & 0xff; + header->v1.spare[0] = 0; + header->v1.spare[1] = 0; + } /* Sum from beginning of header to start of checksum field */ checksum = 0; - for (bufp = (uint8_t*)header; bufp < &header->checksum[0]; bufp++) + for (bufp = (uint8_t*)header; bufp < sumendp; bufp++) checksum += *bufp; - header->checksum[0] = checksum & 0xff;; - header->checksum[1] = (checksum >> 8) & 0xff;; + if (version == 0) { + header->v0.checksum[0] = checksum & 0xff;; + header->v0.checksum[1] = (checksum >> 8) & 0xff;; + } else { + header->v1.checksum[0] = checksum & 0xff;; + header->v1.checksum[1] = (checksum >> 8) & 0xff;; + } crc = buf + size - sizeof(uint32_t); @@ -195,7 +256,7 @@ static int add_socfpga_header(void *buf, size_t size, unsigned start_addr) static void usage(const char *prgname) { - fprintf(stderr, "usage: %s [OPTIONS] <infile>\n", prgname); + fprintf(stderr, "usage: %s [-hb] [-v version] <infile> -o <outfile>\n", prgname); } int main(int argc, char *argv[]) @@ -205,16 +266,23 @@ int main(int argc, char *argv[]) struct stat s; void *buf; int fd; - int min_image_size = 80; - int max_image_size = MAX_IMAGE_SIZE; + int max_image_size, min_image_size = 80; int addsize = 0, pad; + unsigned int version = 0; - while ((opt = getopt(argc, argv, "o:hb")) != -1) { + while ((opt = getopt(argc, argv, "o:hbv:")) != -1) { switch (opt) { + case 'v': + version = atoi(optarg); + if (version > 1) { + printf("Versions supported: 0 or 1\n"); + usage(argv[0]); + exit(1); + } + break; case 'b': add_barebox_header = 1; min_image_size = 0; - max_image_size = MAX_IMAGE_SIZE - 512; addsize = 512; break; case 'h': @@ -224,15 +292,21 @@ int main(int argc, char *argv[]) outfile = optarg; break; default: + usage(argv[0]); exit(1); } } + if (version == 0) { + max_image_size = MAX_V0IMAGE_SIZE; + } else { + max_image_size = MAX_V1IMAGE_SIZE; + } + max_image_size -= addsize; - if (optind == argc) { + if (optind == argc || !outfile) { usage(argv[0]); exit(1); } - infile = argv[optind]; ret = stat(infile, &s); @@ -242,7 +316,8 @@ int main(int argc, char *argv[]) } if (s.st_size < min_image_size) { - fprintf(stderr, "input image too small. Minimum is 80 bytes\n"); + fprintf(stderr, "input image too small. Minimum is %d bytes\n", + min_image_size); exit(1); } @@ -253,7 +328,7 @@ int main(int argc, char *argv[]) } fd = open(infile, O_RDONLY); - if (fd < 0) { + if (fd == -1) { perror("open infile"); exit(1); } @@ -280,7 +355,8 @@ int main(int argc, char *argv[]) memcpy(buf, bb_header, sizeof(bb_header)); } - ret = add_socfpga_header(buf, s.st_size + 4 + addsize + pad, addsize); + ret = add_socfpga_header(buf, s.st_size + 4 + addsize + pad, addsize, + version); if (ret) exit(1); |