diff --git a/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt b/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt index ed3efcc..9759210 100644 --- a/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt +++ b/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt @@ -2,7 +2,7 @@ Required properties: -- compatible: fsl,imx-iim +- compatible: fsl,imx27-iim - reg: physical register base and size Optional properties: @@ -14,7 +14,7 @@ Example: iim: iim@83f98000 { - compatible = "fsl,imx51-iim", "fsl,imx-iim"; + compatible = "fsl,imx51-iim", "fsl,imx27-iim"; reg = <0x83f98000 0x4000>; barebox,provide-mac-address = <&fec 1 9>; }; diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index bdde1a4..040eebb 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_MACH_EDB9315A) += edb93xx/ obj-$(CONFIG_MACH_EDB9315) += edb93xx/ obj-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += efika-mx-smartbook/ +obj-$(CONFIG_MACH_EMBEST_RIOTBOARD) += embest-riotboard/ obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += eukrea_cpuimx25/ obj-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27/ obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += eukrea_cpuimx35/ @@ -62,6 +63,7 @@ obj-$(CONFIG_MACH_PCA100) += phytec-phycard-imx27/ obj-$(CONFIG_MACH_PCAAL1) += phytec-phycard-omap3/ obj-$(CONFIG_MACH_PCAAXL2) += phytec-phycard-omap4/ +obj-$(CONFIG_MACH_PCAAXL3) += phytec-phycard-imx6/ obj-$(CONFIG_MACH_PCM037) += phytec-phycore-imx31/ obj-$(CONFIG_MACH_PCM038) += phytec-phycore-imx27/ obj-$(CONFIG_MACH_PCM043) += phytec-phycore-imx35/ diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6x-1g.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6x-1g.imxcfg index 60a39fe..b6c7580 100644 --- a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6x-1g.imxcfg +++ b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6x-1g.imxcfg @@ -99,8 +99,3 @@ wm 32 0x020c4078 0x00fff300 wm 32 0x020c407c 0x0f0000c3 wm 32 0x020c4080 0x000003ff -/* enable AXI cache for VDOA/VPU/IPU */ -wm 32 0x020e0010 0xf00000cf -/* set IPU AXI-id0 Qos=0xf(bypass AXI-id1 Qos=0x7 */ -wm 32 0x020e0018 0x007f007f -wm 32 0x020e001c 0x007f007f diff --git a/arch/arm/boards/embest-riotboard/Makefile b/arch/arm/boards/embest-riotboard/Makefile new file mode 100644 index 0000000..9f8e1f2 --- /dev/null +++ b/arch/arm/boards/embest-riotboard/Makefile @@ -0,0 +1,3 @@ +obj-y += board.o flash-header-embest-riotboard.dcd.o +extra-y += flash-header-embest-riotboard.dcd.S flash-header-embest-riotboard.dcd +lwl-y += lowlevel.o diff --git a/arch/arm/boards/embest-riotboard/board.c b/arch/arm/boards/embest-riotboard/board.c new file mode 100644 index 0000000..638d0f6 --- /dev/null +++ b/arch/arm/boards/embest-riotboard/board.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014 Eric Bénard + * Copyright (C) 2013 Lucas Stach + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int ar8035_phy_fixup(struct phy_device *dev) +{ + u16 val; + + /* Ar803x phy SmartEEE feature cause link status generates glitch, + * which cause ethernet link down/up issue, so disable SmartEEE + */ + phy_write(dev, 0xd, 0x3); + phy_write(dev, 0xe, 0x805d); + phy_write(dev, 0xd, 0x4003); + + val = phy_read(dev, 0xe); + phy_write(dev, 0xe, val & ~(1 << 8)); + + /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ + phy_write(dev, 0xd, 0x7); + phy_write(dev, 0xe, 0x8016); + phy_write(dev, 0xd, 0x4007); + + val = phy_read(dev, 0xe); + val &= 0xffe3; + val |= 0x18; + phy_write(dev, 0xe, val); + + /* introduce tx clock delay */ + phy_write(dev, 0x1d, 0x5); + val = phy_read(dev, 0x1e); + val |= 0x0100; + phy_write(dev, 0x1e, val); + + return 0; +} + +static int riotboard_device_init(void) +{ + if (!of_machine_is_compatible("embest,riotboard")) + return 0; + + phy_register_fixup_for_uid(0x004dd072, 0xffffffef, ar8035_phy_fixup); + + imx6_bbu_internal_mmc_register_handler("emmc", "/dev/mmc3.barebox", + BBU_HANDLER_FLAG_DEFAULT, NULL, 0, 0); + + return 0; +} +device_initcall(riotboard_device_init); + +static int riotboard_lwl_init(void) +{ + if (!of_machine_is_compatible("embest,riotboard")) + return 0; + + barebox_set_hostname("riotboard"); + + imx6_init_lowlevel(); + + return 0; +} +postcore_initcall(riotboard_lwl_init); diff --git a/arch/arm/boards/embest-riotboard/flash-header-embest-riotboard.imxcfg b/arch/arm/boards/embest-riotboard/flash-header-embest-riotboard.imxcfg new file mode 100644 index 0000000..04e162b --- /dev/null +++ b/arch/arm/boards/embest-riotboard/flash-header-embest-riotboard.imxcfg @@ -0,0 +1,62 @@ +loadaddr 0x20000000 +soc imx6 +dcdofs 0x400 +wm 32 0x020e0774 0x000c0000 +wm 32 0x020e0754 0x00000000 +wm 32 0x020e04ac 0x00000030 +wm 32 0x020e04b0 0x00000030 +wm 32 0x020e0464 0x00000030 +wm 32 0x020e0490 0x00000030 +wm 32 0x020e074c 0x00000030 +wm 32 0x020e0494 0x00000030 +wm 32 0x020e04a0 0x00000000 +wm 32 0x020e04b4 0x00000030 +wm 32 0x020e04b8 0x00000030 +wm 32 0x020e076c 0x00000030 +wm 32 0x020e0750 0x00020000 +wm 32 0x020e04bc 0x00000028 +wm 32 0x020e04c0 0x00000028 +wm 32 0x020e04c4 0x00000028 +wm 32 0x020e04c8 0x00000028 +wm 32 0x020e0760 0x00020000 +wm 32 0x020e0764 0x00000028 +wm 32 0x020e0770 0x00000028 +wm 32 0x020e0778 0x00000028 +wm 32 0x020e077c 0x00000028 +wm 32 0x020e0470 0x00000028 +wm 32 0x020e0474 0x00000028 +wm 32 0x020e0478 0x00000028 +wm 32 0x020e047c 0x00000028 +wm 32 0x021b0800 0xa1390003 +wm 32 0x021b080c 0x001f001f +wm 32 0x021b0810 0x001f001f +wm 32 0x021b083c 0x421c0216 +wm 32 0x021b0840 0x017b017a +wm 32 0x021b0848 0x4b4a4e4c +wm 32 0x021b0850 0x3f3f3334 +wm 32 0x021b081c 0x33333333 +wm 32 0x021b0820 0x33333333 +wm 32 0x021b0824 0x33333333 +wm 32 0x021b0828 0x33333333 +wm 32 0x021b08b8 0x00000800 +wm 32 0x021b0004 0x00020025 +wm 32 0x021b0008 0x00333030 +wm 32 0x021b000c 0x676b5313 +wm 32 0x021b0010 0xb66e8b63 +wm 32 0x021b0014 0x01ff00db +wm 32 0x021b0018 0x00001740 +wm 32 0x021b001c 0x00008000 +wm 32 0x021b002c 0x000026d2 +wm 32 0x021b0030 0x006b1023 +wm 32 0x021b0040 0x00000027 +wm 32 0x021b0000 0x84190000 +wm 32 0x021b001c 0x04008032 +wm 32 0x021b001c 0x00008033 +wm 32 0x021b001c 0x00048031 +wm 32 0x021b001c 0x05208030 +wm 32 0x021b001c 0x04008040 +wm 32 0x021b0020 0x00005800 +wm 32 0x021b0818 0x00011117 +wm 32 0x021b0004 0x00025565 +wm 32 0x021b0404 0x00011006 +wm 32 0x021b001c 0x00000000 diff --git a/arch/arm/boards/embest-riotboard/lowlevel.c b/arch/arm/boards/embest-riotboard/lowlevel.c new file mode 100644 index 0000000..814658a --- /dev/null +++ b/arch/arm/boards/embest-riotboard/lowlevel.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline void setup_uart(void) +{ + /* Enable UART for lowlevel debugging purposes */ + writel(0x00000000, 0x021e8080); + writel(0x00004027, 0x021e8084); + writel(0x00000704, 0x021e8088); + writel(0x00000a81, 0x021e8090); + writel(0x0000002b, 0x021e809c); + writel(0x00013880, 0x021e80b0); + writel(0x0000047f, 0x021e80a4); + writel(0x0000c34f, 0x021e80a8); + writel(0x00000001, 0x021e8080); +} + +extern char __dtb_imx6s_riotboard_start[]; + +ENTRY_FUNCTION(start_imx6s_riotboard, r0, r1, r2) +{ + uint32_t fdt; + + arm_cpu_lowlevel_init(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) { + writel(0x4, 0x020e016c); + setup_uart(); + putc_ll('a'); + } + + fdt = (uint32_t)__dtb_imx6s_riotboard_start - get_runtime_offset(); + barebox_arm_entry(0x10000000, SZ_1G, fdt); +} diff --git a/arch/arm/boards/phytec-phycard-imx6/Makefile b/arch/arm/boards/phytec-phycard-imx6/Makefile new file mode 100644 index 0000000..01c7a25 --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/Makefile @@ -0,0 +1,2 @@ +obj-y += board.o +lwl-y += lowlevel.o diff --git a/arch/arm/boards/phytec-phycard-imx6/board.c b/arch/arm/boards/phytec-phycard-imx6/board.c new file mode 100644 index 0000000..6ed431a --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/board.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 Christian Hemp, Phytec Messtechnik GmbH + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static int phytec_pcaaxl3_init(void) +{ + if (!of_machine_is_compatible("phytec,imx6q-pcaaxl3")) + return 0; + + switch (bootsource_get()) { + case BOOTSOURCE_MMC: + of_device_enable_path("/chosen/environment-sd"); + break; + default: + case BOOTSOURCE_NAND: + of_device_enable_path("/chosen/environment-nand"); + break; + } + + imx6_bbu_nand_register_handler("nand", BBU_HANDLER_FLAG_DEFAULT); + + return 0; +} +device_initcall(phytec_pcaaxl3_init); + +static int phytec_pcaaxl3_core_init(void) +{ + if (!of_machine_is_compatible("phytec,imx6q-pcaaxl3")) + return 0; + + imx6_init_lowlevel(); + + return 0; +} +postcore_initcall(phytec_pcaaxl3_core_init); diff --git a/arch/arm/boards/phytec-phycard-imx6/env/boot/nand b/arch/arm/boards/phytec-phycard-imx6/env/boot/nand new file mode 100644 index 0000000..a51da9e --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/env/boot/nand @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "Kernel:nand;rootfs:nand" + exit +fi + +global.bootm.image="/dev/nand0.kernel.bb" +#global.bootm.oftree="/env/oftree" +bootargs-ip +global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root rootfstype=ubifs" + diff --git a/arch/arm/boards/phytec-phycard-imx6/env/boot/sd-ext3 b/arch/arm/boards/phytec-phycard-imx6/env/boot/sd-ext3 new file mode 100644 index 0000000..fa1e9d6 --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/env/boot/sd-ext3 @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "MMC (ext3)" + exit +fi + +global.bootm.image="/mnt/kernel/linuximage" +#global.bootm.oftree="/boot/oftree" +bootargs-ip +global.linux.bootargs.dyn.root="root=/dev/mmcblk0p2 rootfstype=ext3 rootwait" diff --git a/arch/arm/boards/phytec-phycard-imx6/env/config-board b/arch/arm/boards/phytec-phycard-imx6/env/config-board new file mode 100644 index 0000000..44008aa --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/env/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=phyCARD-i.MX6 +global.linux.bootargs.base="console=ttymxc2,115200" diff --git a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg new file mode 100644 index 0000000..481e085 --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg @@ -0,0 +1,7 @@ +#define SETUP_1GIB_2GIB \ + wm 32 0x021b000c 0x54597955; \ + wm 32 0x021b0030 0x00591023; \ + wm 32 0x021b0040 0x00000027; \ + wm 32 0x021b0000 0x831a0000 + +#include "flash-header-phytec-pcaaxl3.h" diff --git a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg new file mode 100644 index 0000000..b21bd89 --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg @@ -0,0 +1,7 @@ +#define SETUP_1GIB_2GIB \ + wm 32 0x021b000c 0x3a3f7975; \ + wm 32 0x021b0030 0x003f1023; \ + wm 32 0x021b0040 0x00000017; \ + wm 32 0x021b0000 0xc21a0000 + +#include "flash-header-phytec-pcaaxl3.h" diff --git a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg new file mode 100644 index 0000000..858b6d7 --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg @@ -0,0 +1,8 @@ + +#define SETUP_1GIB_2GIB \ + wm 32 0x021b000c 0x54597955; \ + wm 32 0x021b0030 0x00591023; \ + wm 32 0x021b0040 0x00000027; \ + wm 32 0x021b0000 0xc31a0000 + +#include "flash-header-phytec-pcaaxl3.h" diff --git a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3.h b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3.h new file mode 100644 index 0000000..aecaf16 --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3.h @@ -0,0 +1,97 @@ +soc imx6 +loadaddr 0x20000000 +dcdofs 0x400 + +wm 32 0x020e05a8 0x00000028 +wm 32 0x020e05b0 0x00000028 +wm 32 0x020e0524 0x00000028 +wm 32 0x020e051c 0x00000028 +wm 32 0x020e0518 0x00000028 +wm 32 0x020e050c 0x00000028 +wm 32 0x020e05b8 0x00000028 +wm 32 0x020e05c0 0x00000028 +wm 32 0x020e05ac 0x00000028 +wm 32 0x020e05b4 0x00000028 +wm 32 0x020e0528 0x00000028 +wm 32 0x020e0520 0x00000028 +wm 32 0x020e0514 0x00000028 +wm 32 0x020e0510 0x00000028 +wm 32 0x020e05bc 0x00000028 +wm 32 0x020e05c4 0x00000028 +wm 32 0x020e056c 0x00000028 +wm 32 0x020e0578 0x00000028 +wm 32 0x020e0588 0x00000028 +wm 32 0x020e0594 0x00000028 +wm 32 0x020e057c 0x00000028 +wm 32 0x020e0590 0x00003000 +wm 32 0x020e0598 0x00003000 +wm 32 0x020e058c 0x00000000 +wm 32 0x020e059c 0x00000028 +wm 32 0x020e05a0 0x00000028 +wm 32 0x020e0784 0x00000028 +wm 32 0x020e0788 0x00000028 +wm 32 0x020e0794 0x00000028 +wm 32 0x020e079c 0x00000028 +wm 32 0x020e07a0 0x00000028 +wm 32 0x020e07a4 0x00000028 +wm 32 0x020e07a8 0x00000028 +wm 32 0x020e0748 0x00000028 +wm 32 0x020e074c 0x00000028 +wm 32 0x020e0750 0x00020000 +wm 32 0x020e0758 0x00000000 +wm 32 0x020e0774 0x00020000 +wm 32 0x020e078c 0x00000028 +wm 32 0x020e0798 0x000c0000 +wm 32 0x021b081c 0x33333333 +wm 32 0x021b0820 0x33333333 +wm 32 0x021b0824 0x33333333 +wm 32 0x021b0828 0x33333333 +wm 32 0x021b481c 0x33333333 +wm 32 0x021b4820 0x33333333 +wm 32 0x021b4824 0x33333333 +wm 32 0x021b4828 0x33333333 +wm 32 0x021b0018 0x00091740 +wm 32 0x021b001c 0x00008000 +wm 32 0x021b0010 0xff328f64 +wm 32 0x021b0014 0x01ff00db +wm 32 0x021b002c 0x000026d2 +wm 32 0x021b0008 0x09444040 +wm 32 0x021b0004 0x00025576 + +SETUP_1GIB_2GIB + +wm 32 0x021b001c 0x04088032 +wm 32 0x021b001c 0x0408803a +wm 32 0x021b001c 0x00008033 +wm 32 0x021b001c 0x0000803b +wm 32 0x021b001c 0x00048031 +wm 32 0x021b001c 0x00048039 +wm 32 0x021b001c 0x09408030 +wm 32 0x021b001c 0x09408038 +wm 32 0x021b001c 0x04008040 +wm 32 0x021b001c 0x04008048 +wm 32 0x021b0800 0xa1390003 +wm 32 0x021b4800 0xa1380003 +wm 32 0x021b0020 0x00007800 +wm 32 0x021b0818 0x00011117 +wm 32 0x021b4818 0x00011117 +wm 32 0x021b083c 0x4350035e +wm 32 0x021b0840 0x035c0358 +wm 32 0x021b483c 0x436e0376 +wm 32 0x021b4840 0x03770352 +wm 32 0x021b0848 0x3c333436 +wm 32 0x021b4848 0x35332f3b +wm 32 0x021b0850 0x37363e39 +wm 32 0x021b4850 0x432f433d +wm 32 0x021b080c 0x0013001b +wm 32 0x021b0810 0x003b0034 +wm 32 0x021b480c 0x0037004b +wm 32 0x021b4810 0x004b0055 +wm 32 0x021b08b8 0x00000800 +wm 32 0x021b48b8 0x00000800 +wm 32 0x021b001c 0x00000000 +wm 32 0x021b0404 0x00011006 +wm 32 0x020e0010 0xf00000ff +wm 32 0x020e0018 0x007f007f +wm 32 0x020e001c 0x007f007f +wm 32 0x020c8000 0x80002021 diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c new file mode 100644 index 0000000..14df18f --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 Christian Hemp + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline void setup_uart(void) +{ + void __iomem *ccmbase = IOMEM(MX6_CCM_BASE_ADDR); + void __iomem *uartbase = IOMEM(MX6_UART3_BASE_ADDR); + void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR); + + writel(0x4, iomuxbase + 0x01f8); + + writel(0xffffffff, ccmbase + 0x68); + writel(0xffffffff, ccmbase + 0x6c); + writel(0xffffffff, ccmbase + 0x70); + writel(0xffffffff, ccmbase + 0x74); + writel(0xffffffff, ccmbase + 0x78); + writel(0xffffffff, ccmbase + 0x7c); + writel(0xffffffff, ccmbase + 0x80); + + writel(0x00000000, uartbase + 0x80); + writel(0x00004027, uartbase + 0x84); + writel(0x00000704, uartbase + 0x88); + writel(0x00000a81, uartbase + 0x90); + writel(0x0000002b, uartbase + 0x9c); + writel(0x00013880, uartbase + 0xb0); + writel(0x0000047f, uartbase + 0xa4); + writel(0x0000c34f, uartbase + 0xa8); + writel(0x00000001, uartbase + 0x80); + + putc_ll('>'); +} + +extern char __dtb_imx6q_phytec_pbaa03_start[]; + +static void __noreturn start_imx6q_phytec_pbaa03_common(uint32_t size) +{ + uint32_t fdt; + + arm_cpu_lowlevel_init(); + + arm_setup_stack(0x00920000 - 8); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + setup_uart(); + + fdt = (uint32_t)__dtb_imx6q_phytec_pbaa03_start - get_runtime_offset(); + + barebox_arm_entry(0x10000000, size, fdt); +} + +ENTRY_FUNCTION(start_phytec_pbaa03_1gib, r0, r1, r2) +{ + start_imx6q_phytec_pbaa03_common(SZ_1G); +} + +ENTRY_FUNCTION(start_phytec_pbaa03_1gib_1bank, r0, r1, r2) +{ + start_imx6q_phytec_pbaa03_common(SZ_1G); +} + +ENTRY_FUNCTION(start_phytec_pbaa03_2gib, r0, r1, r2) +{ + start_imx6q_phytec_pbaa03_common(SZ_2G); +} diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig index f29c968..b3157e3 100644 --- a/arch/arm/configs/imx_v7_defconfig +++ b/arch/arm/configs/imx_v7_defconfig @@ -5,6 +5,7 @@ CONFIG_MACH_FREESCALE_MX53_LOCO=y CONFIG_MACH_TQMA53=y CONFIG_MACH_FREESCALE_MX53_VMX53=y +CONFIG_MACH_PCAAXL3=y CONFIG_MACH_PHYTEC_PFLA02=y CONFIG_MACH_DFI_FS700_M60=y CONFIG_MACH_GUF_SANTARO=y @@ -15,6 +16,7 @@ CONFIG_MACH_SABRESD=y CONFIG_MACH_NITROGEN6X=y CONFIG_MACH_SOLIDRUN_HUMMINGBOARD=y +CONFIG_MACH_EMBEST_RIOTBOARD=y CONFIG_MACH_UDOO=y CONFIG_MACH_VARISCITE_MX6=y CONFIG_IMX_IIM=y diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b45c174..d7f8be0 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -27,7 +27,9 @@ imx6q-nitrogen6x.dtb \ imx6dl-nitrogen6x.dtb \ imx6q-udoo.dtb \ - imx6q-var-custom.dtb + imx6q-var-custom.dtb \ + imx6s-riotboard.dtb \ + imx6q-phytec-pbaa03.dtb dtb-$(CONFIG_ARCH_MVEBU) += dove-cubox-bb.dtb dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5_sockit.dtb \ socfpga_cyclone5_socrates.dtb @@ -40,6 +42,7 @@ pbl-$(CONFIG_MACH_BEAGLEBONE) += am335x-bone.dtb.o am335x-boneblack.dtb.o pbl-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += imx51-genesi-efika-sb.dtb.o +pbl-$(CONFIG_MACH_EMBEST_RIOTBOARD) += imx6s-riotboard.dtb.o pbl-$(CONFIG_MACH_FREESCALE_MX51_PDK) += imx51-babbage.dtb.o pbl-$(CONFIG_MACH_FREESCALE_MX53_LOCO) += imx53-qsb.dtb.o imx53-qsrb.dtb.o pbl-$(CONFIG_MACH_FREESCALE_MX53_VMX53) += imx53-voipac-bsb.dtb.o @@ -63,6 +66,7 @@ pbl-$(CONFIG_MACH_NITROGEN6X) += imx6q-nitrogen6x.dtb.o imx6dl-nitrogen6x.dtb.o pbl-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o pbl-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o +pbl-$(CONFIG_MACH_PCAAXL3) += imx6q-phytec-pbaa03.dtb.o .SECONDARY: $(obj)/$(BUILTIN_DTB).dtb.S .SECONDARY: $(patsubst %,$(obj)/%.S,$(dtb-y)) diff --git a/arch/arm/dts/imx6q-phytec-pbaa03.dts b/arch/arm/dts/imx6q-phytec-pbaa03.dts new file mode 100644 index 0000000..bcb3dd7 --- /dev/null +++ b/arch/arm/dts/imx6q-phytec-pbaa03.dts @@ -0,0 +1,34 @@ +/* + * Copyright 2014 Christian Hemp, Phytec Messtechnik GmbH + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "imx6q-phytec-pcaaxl3.dtsi" + +/ { + model = "Phytec phyCARD-i.MX6 Quad Carrier-Board"; + compatible = "phytec,imx6q-pbaa03", "phytec,imx6q-pcaaxl3", "fsl,imx6q"; + + chosen { + linux,stdout-path = &uart3; + }; +}; + +&fec { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&usdhc3 { + status = "okay"; +}; diff --git a/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi b/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi new file mode 100644 index 0000000..edbc714 --- /dev/null +++ b/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi @@ -0,0 +1,147 @@ +/* + * Copyright 2014444 Christian Hemp, Phytec Messtechnik GmbH + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "imx6q.dtsi" + +/ { + model = "Phytec phyCARD-i.MX6 Quad"; + compatible = "phytec,imx6q-pcaaxl3", "fsl,imx6q"; + + chosen { + environment-sd { + compatible = "barebox,environment"; + device-path = &usdhc3, "partname:barebox-environment"; + status = "disabled"; + }; + + environment-nand { + compatible = "barebox,environment"; + device-path = &gpmi, "partname:barebox-environment"; + status = "disabled"; + }; + }; +}; + +&i2c1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + + eeprom: m24c32@50 { + compatible = "st,24c32", "at24"; + reg = <0x50>; + }; +}; + +&iomuxc { + pinctrl-names = "default"; + + imx6q-phytec-pcaaxl3 { + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_ENET_PINGRP4 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_KEY_COL0__ENET_RX_DATA3 0x1b0b0 + MX6QDL_PAD_KEY_ROW0__ENET_TX_DATA3 0x1b0b0 + MX6QDL_PAD_KEY_ROW1__ENET_COL 0x1b0b0 + MX6QDL_PAD_KEY_COL2__ENET_RX_DATA2 0x1b0b0 + MX6QDL_PAD_KEY_ROW2__ENET_TX_DATA2 0x1b0b0 + MX6QDL_PAD_KEY_COL3__ENET_CRS 0x1b0b0 + MX6QDL_PAD_GPIO_18__ENET_RX_CLK 0x1b0b0 + MX6QDL_PAD_GPIO_19__ENET_TX_ER 0x1b0b0 + >; + }; + + pinctrl_gpmi_nand: gpmigrp { + fsl,pins = ; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = ; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = ; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_USDHC3_PINGRP_D4 + MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22 0x80000000 /* CD */ + >; + }; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "mii"; + status = "disabled"; +}; + +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + nand-on-flash-bbt; + status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0x400000>; + }; + + partition@1 { + label = "barebox-environment"; + reg = <0x400000 0x20000>; + }; + + partition@2 { + label = "kernel"; + reg = <0x420000 0x800000>; + }; + + partition@3 { + label = "root"; + reg = <0xC20000 0x0>; + }; +}; + +&ocotp { + barebox,provide-mac-address = <&fec 0x620>; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + status = "disabled"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + cd-gpios = <&gpio5 22 0>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0x80000>; + }; + partition@1 { + label = "barebox-environment"; + reg = <0x80000 0x80000>; + }; +}; diff --git a/arch/arm/dts/imx6s-riotboard.dts b/arch/arm/dts/imx6s-riotboard.dts new file mode 100644 index 0000000..14d0b80 --- /dev/null +++ b/arch/arm/dts/imx6s-riotboard.dts @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2014 Eric Bénard - Eukréa Electromatique + * + * The code contained herein is licensed under the GNU General Public + * License version 2. + */ +/dts-v1/; + +#include "imx6dl.dtsi" + +/ { + model = "RIoTboard Solo"; + compatible = "embest,riotboard", "fsl,imx6dl"; + + chosen { + linux,stdout-path = &uart2; + + environment@0 { + compatible = "barebox,environment"; + device-path = &usdhc4, "partname:barebox-environment"; + }; + }; + + memory { + reg = <0x10000000 0x40000000>; + }; + + gpio-leds { + compatible = "gpio-leds"; + + d45 { + label = "d45"; + gpios = <&gpio5 2 1>; + linux,default-trigger = "heartbeat"; + }; + + d46 { + label = "d46"; + gpios = <&gpio3 28 1>; + linux,default-trigger = "default-on"; + }; + }; + + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + reg_3p3v: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + imx6s-riotboard { + pinctrl_hog: hoggrp { + fsl,pins = < + MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000 /* LED D45 */ + MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x80000000 /* LED D46 */ + MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16 0x80000000 /* PMIC_INT_B */ + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0 /* CAM_MCLK + SGTL_MCLK */ + >; + }; + pinctrl_uart2: uart2grp { + fsl,pins = ; + }; + pinctrl_rgmii_ar8035: rgmii_ar8035 { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + /* AR8035 reset */ + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x130b0 + /* AR8035 interrupt */ + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 + /* GPIO16 -> AR8035 25MHz */ + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */ + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1 + /* AR8035 pin strapping: IO voltage: pull up */ + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + /* AR8035 pin strapping: PHYADDR#0: pull down */ + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0 + /* AR8035 pin strapping: PHYADDR#1: pull down */ + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x130b0 + /* AR8035 pin strapping: MODE#1: pull up */ + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + /* AR8035 pin strapping: MODE#3: pull up */ + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + /* AR8035 pin strapping: MODE#0: pull down */ + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0 + >; + }; + pinctrl_usdhc4: usdhc4grp { + fsl,pins = < + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x80000000 + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x80000000 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x80000000 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x80000000 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x80000000 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x80000000 + >; + }; + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x80000000 + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x80000000 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x80000000 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x80000000 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x80000000 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x80000000 + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x80000000 + >; + }; + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x80000000 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x80000000 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x80000000 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x80000000 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x80000000 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x80000000 + MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x80000000 + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000 + >; + }; + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x80000000 + MX6QDL_PAD_EIM_D22__USB_OTG_PWR 0x80000000 + MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x80000000 + >; + }; + pinctrl_i2c1_2: i2c1grp-2 { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 + >; + }; + pinctrl_i2c2_2: i2c2grp-2 { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + pinctrl_i2c3_2: i2c3grp-2 { + fsl,pins = < + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + >; + }; + pinctrl_i2c4_2: i2c4grp-2 { + fsl,pins = < + MX6QDL_PAD_GPIO_7__I2C4_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_8__I2C4_SDA 0x4001b8b1 + >; + }; + }; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rgmii_ar8035>; + phy-mode = "rgmii"; + phy-reset-duration = <2>; + phy-reset-gpios = <&gpio3 31 0>; + status = "okay"; +}; + +&usdhc2 { + /* SD card socket - bottom */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + bus-width = <4>; + cd-gpios = <&gpio1 4 0>; + wp-gpios = <&gpio1 2 0>; + status = "okay"; + #address-cells = <1>; + #size-cells = <1>; +}; + +&usdhc3 { + /* uSD card socket - top */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + bus-width = <4>; + cd-gpios = <&gpio7 0 0>; + wp-gpios = <&gpio7 1 0>; + status = "okay"; + #address-cells = <1>; + #size-cells = <1>; +}; + +&usdhc4 { + /* eMMC */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc4>; + bus-width = <4>; + non-removable; + status = "okay"; + + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0x80000>; + }; + + partition@1 { + label = "barebox-environment"; + reg = <0x80000 0x80000>; + }; +}; + +&usbh1 { + status = "okay"; + phy_type = "utmi"; + disable-over-current; +}; + +&usbotg { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + phy_type = "utmi"; + dr_mode = "peripheral"; + otg_id_pin_select_change; + status = "okay"; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_2>; + + pmic: pf0100@08 { + compatible = "pf0100-regulator"; + reg = <0x08>; + interrupt-parent = <&gpio5>; + interrupts = <16 8>; + + regulators { + reg_vddcore: sw1ab { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-always-on; + }; + + reg_vddsoc: sw1c { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-always-on; + }; + + reg_gen_3v3: sw2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_ddr_1v5a: sw3a { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-always-on; + }; + + reg_ddr_1v5b: sw3b { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-always-on; + }; + + reg_ddr_vtt: sw4 { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-always-on; + }; + + reg_5v_600mA: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + regulator-always-on; + }; + + reg_snvs_3v: vsnvs { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + }; + + reg_vrefddr: vrefddr { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-always-on; + }; + + reg_vgen1_1v5: vgen1 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + /* not used */ + }; + + reg_vgen2_1v2_eth: vgen2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + regulator-always-on; + }; + + reg_vgen3_2v8: vgen3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_vgen4_1v8: vgen4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_vgen5_2v5_sgtl: vgen5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_vgen6_3v3: vgen6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; + + codec: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks 201>; + VDDA-supply = <®_vgen5_2v5_sgtl>; + VDDIO-supply = <®_3p3v>; + }; +}; + +&i2c2 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2_2>; +}; + +&i2c3 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3_2>; +}; + +&i2c4 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4_2>; +}; + +&ocotp { + barebox,provide-mac-address = <&fec 0x620>; +}; + diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index d40c944..a6aef24 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -40,6 +40,7 @@ default 0x4fc00000 if MACH_DFI_FS700_M60 default 0x4fc00000 if MACH_UDOO default 0x4fc00000 if MACH_VARISCITE_MX6 + default 0x4fc00000 if MACH_PCAAXL3 config ARCH_IMX_INTERNAL_BOOT bool "support internal boot mode" @@ -208,6 +209,10 @@ Say Y here if you are using the Voipac Technologies X53-DMM-668 module equipped with a Freescale i.MX53 Processor +config MACH_PCAAXL3 + bool "Phytec phyCARD-i.MX6 Quad" + select ARCH_IMX6 + config MACH_PHYTEC_PFLA02 bool "Phytec phyFLEX-i.MX6" select ARCH_IMX6 @@ -250,6 +255,10 @@ bool "SolidRun Hummingboard" select ARCH_IMX6 +config MACH_EMBEST_RIOTBOARD + bool "Embest RIoTboard" + select ARCH_IMX6 + config MACH_UDOO bool "Freescale i.MX6 UDOO Board" select ARCH_IMX6 @@ -621,6 +630,16 @@ only supported functionality is reading the MAC address and assigning it to an ethernet device. +config IMX_OCOTP_WRITE + bool + prompt "Enable write support of i.MX6 CPUs OTP fuses" + depends on IMX_OCOTP + help + This adds write support to IMX6 On-Chip OTP registers. + Example of set MAC to 12:34:56:78:9A:BC (2 words with offset 0x22 * 4): + mw -l -d /dev/imx-ocotp 0x8C 0x00001234 + mw -l -d /dev/imx-ocotp 0x88 0x56789ABC + endmenu endif diff --git a/arch/arm/mach-imx/clk-imx6.c b/arch/arm/mach-imx/clk-imx6.c index 518fc00..4598a62 100644 --- a/arch/arm/mach-imx/clk-imx6.c +++ b/arch/arm/mach-imx/clk-imx6.c @@ -433,6 +433,7 @@ clkdev_add_physbase(clks[ecspi_root], MX6_ECSPI5_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg_per], MX6_GPT_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg], MX6_ENET_BASE_ADDR, NULL); + clkdev_add_physbase(clks[ipg], MX6_OCOTP_BASE_ADDR, NULL); clkdev_add_physbase(clks[usdhc1_podf], MX6_USDHC1_BASE_ADDR, NULL); clkdev_add_physbase(clks[usdhc2_podf], MX6_USDHC2_BASE_ADDR, NULL); clkdev_add_physbase(clks[usdhc3_podf], MX6_USDHC3_BASE_ADDR, NULL); diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c index d11957f..5b49a3d 100644 --- a/arch/arm/mach-imx/esdctl.c +++ b/arch/arm/mach-imx/esdctl.c @@ -21,10 +21,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -33,6 +35,7 @@ #include #include #include +#include struct imx_esdctl_data { unsigned long base0; @@ -163,6 +166,45 @@ return size; } +/* + * MMDC - found on i.MX6 + */ + +static inline unsigned long imx6_mmdc_sdram_size(void __iomem *mmdcbase, int cs) +{ + u32 ctlval = readl(mmdcbase + MDCTL); + u32 mdmisc = readl(mmdcbase + MDMISC); + unsigned long size; + int rows, cols, width = 2, banks = 8; + + if (cs == 0 && !(ctlval & MMDCx_MDCTL_SDE0)) + return 0; + if (cs == 1 && !(ctlval & MMDCx_MDCTL_SDE1)) + return 0; + + rows = ((ctlval >> 24) & 0x7) + 11; + + cols = (ctlval >> 20) & 0x7; + if (cols == 3) + cols = 8; + else if (cols == 4) + cols = 12; + else + cols += 9; + + if (ctlval & MMDCx_MDCTL_DSIZ_32B) + width = 4; + else if (ctlval & MMDCx_MDCTL_DSIZ_64B) + width = 8; + + if (mdmisc & MMDCx_MDMISC_DDR_4_BANKS) + banks = 4; + + size = (1 << cols) * (1 << rows) * banks * width; + + return size; +} + static void add_mem(unsigned long base0, unsigned long size0, unsigned long base1, unsigned long size1) { @@ -237,6 +279,13 @@ data->base1, imx_v4_sdram_size(esdctlbase, 1)); } +static void imx6_mmdc_add_mem(void *mmdcbase, struct imx_esdctl_data *data) +{ + arm_add_mem_device("ram0", data->base0, + imx6_mmdc_sdram_size(mmdcbase, 0) + + imx6_mmdc_sdram_size(mmdcbase, 1)); +} + static int imx_esdctl_probe(struct device_d *dev) { struct imx_esdctl_data *data; @@ -301,6 +350,11 @@ .add_mem = imx_esdctl_v4_add_mem, }; +static __maybe_unused struct imx_esdctl_data imx6q_data = { + .base0 = MX6_MMDC_PORT0_BASE_ADDR, + .add_mem = imx6_mmdc_add_mem, +}; + static struct platform_device_id imx_esdctl_ids[] = { #ifdef CONFIG_ARCH_IMX1 { @@ -349,10 +403,20 @@ }, }; +static __maybe_unused struct of_device_id imx_esdctl_dt_ids[] = { + { + .compatible = "fsl,imx6q-mmdc", + .data = (unsigned long)&imx6q_data + }, { + /* sentinel */ + } +}; + static struct driver_d imx_serial_driver = { .name = "imx-esdctl", .probe = imx_esdctl_probe, .id_table = imx_esdctl_ids, + .of_compatible = DRV_OF_COMPAT(imx_esdctl_dt_ids), }; static int imx_esdctl_init(void) diff --git a/arch/arm/mach-imx/imx6-mmdc.c b/arch/arm/mach-imx/imx6-mmdc.c index d1de593..0e706ce 100644 --- a/arch/arm/mach-imx/imx6-mmdc.c +++ b/arch/arm/mach-imx/imx6-mmdc.c @@ -17,46 +17,8 @@ */ #include #include -#include #include -#define P0_IPS (void __iomem *)MX6_MMDC_P0_BASE_ADDR -#define P1_IPS (void __iomem *)MX6_MMDC_P1_BASE_ADDR - -#define MDCTL 0x000 -#define MDPDC 0x004 -#define MDSCR 0x01c -#define MDMISC 0x018 -#define MDREF 0x020 -#define MAPSR 0x404 -#define MPZQHWCTRL 0x800 -#define MPWLGCR 0x808 -#define MPWLDECTRL0 0x80c -#define MPWLDECTRL1 0x810 -#define MPPDCMPR1 0x88c -#define MPSWDAR 0x894 -#define MPRDDLCTL 0x848 -#define MPMUR 0x8b8 -#define MPDGCTRL0 0x83c -#define MPDGCTRL1 0x840 -#define MPRDDLCTL 0x848 -#define MPWRDLCTL 0x850 -#define MPRDDLHWCTL 0x860 -#define MPWRDLHWCTL 0x864 -#define MPDGHWST0 0x87c -#define MPDGHWST1 0x880 -#define MPDGHWST2 0x884 -#define MPDGHWST3 0x888 - -#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x5a8) -#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x5b0) -#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x524) -#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x51c) -#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x518) -#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x50c) -#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x5b8) -#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x5c0) - int mmdc_do_write_level_calibration(void) { u32 esdmisc_val, zq_val; diff --git a/arch/arm/mach-imx/include/mach/devices-imx53.h b/arch/arm/mach-imx/include/mach/devices-imx53.h index d4e9a4a..88be4fd 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx53.h +++ b/arch/arm/mach-imx/include/mach/devices-imx53.h @@ -2,6 +2,11 @@ #include #include +static inline struct device_d *imx53_add_cspi(struct spi_imx_master *pdata) +{ + return imx_add_spi_imx35((void *)MX53_CSPI_BASE_ADDR, 0, pdata); +} + static inline struct device_d *imx53_add_spi0(struct spi_imx_master *pdata) { return imx_add_spi_imx51((void *)MX53_ECSPI1_BASE_ADDR, 0, pdata); diff --git a/arch/arm/mach-imx/include/mach/imx6-mmdc.h b/arch/arm/mach-imx/include/mach/imx6-mmdc.h index 4ad939e..d07950d 100644 --- a/arch/arm/mach-imx/include/mach/imx6-mmdc.h +++ b/arch/arm/mach-imx/include/mach/imx6-mmdc.h @@ -1,6 +1,55 @@ #ifndef __MACH_MMDC_H #define __MACH_MMDC_H +#include + +#define P0_IPS (void __iomem *)MX6_MMDC_P0_BASE_ADDR +#define P1_IPS (void __iomem *)MX6_MMDC_P1_BASE_ADDR + +#define MDCTL 0x000 +#define MDPDC 0x004 +#define MDSCR 0x01c +#define MDMISC 0x018 +#define MDREF 0x020 +#define MAPSR 0x404 +#define MPZQHWCTRL 0x800 +#define MPWLGCR 0x808 +#define MPWLDECTRL0 0x80c +#define MPWLDECTRL1 0x810 +#define MPPDCMPR1 0x88c +#define MPSWDAR 0x894 +#define MPRDDLCTL 0x848 +#define MPMUR 0x8b8 +#define MPDGCTRL0 0x83c +#define MPDGCTRL1 0x840 +#define MPRDDLCTL 0x848 +#define MPWRDLCTL 0x850 +#define MPRDDLHWCTL 0x860 +#define MPWRDLHWCTL 0x864 +#define MPDGHWST0 0x87c +#define MPDGHWST1 0x880 +#define MPDGHWST2 0x884 +#define MPDGHWST3 0x888 + +#define MMDCx_MDCTL_SDE0 0x80000000 +#define MMDCx_MDCTL_SDE1 0x40000000 + +#define MMDCx_MDCTL_DSIZ_16B 0x00000000 +#define MMDCx_MDCTL_DSIZ_32B 0x00010000 +#define MMDCx_MDCTL_DSIZ_64B 0x00020000 + +#define MMDCx_MDMISC_DDR_4_BANKS 0x00000020 + +#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x5a8) +#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x5b0) +#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x524) +#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x51c) +#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x518) +#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x50c) +#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x5b8) +#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7 ((void __iomem *)MX6_IOMUXC_BASE_ADDR + 0x5c0) + + int mmdc_do_write_level_calibration(void); int mmdc_do_dqs_calibration(void); diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h index facbe51..68be43c 100644 --- a/arch/arm/mach-imx/include/mach/imx6-regs.h +++ b/arch/arm/mach-imx/include/mach/imx6-regs.h @@ -113,4 +113,6 @@ #define MX6_SATA_BASE_ADDR 0x02200000 +#define MX6_MMDC_PORT0_BASE_ADDR 0x10000000 + #endif /* __MACH_IMX6_REGS_H */ diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c index e36b484..476b376 100644 --- a/arch/arm/mach-imx/ocotp.c +++ b/arch/arm/mach-imx/ocotp.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include /* * a single MAC address reference has the form @@ -32,6 +34,292 @@ */ #define MAC_ADDRESS_PROPLEN (2 * sizeof(__be32)) +/* OCOTP Registers offsets */ +#define OCOTP_CTRL_SET 0x04 +#define OCOTP_CTRL_CLR 0x08 +#define OCOTP_TIMING 0x10 +#define OCOTP_DATA 0x20 +#define OCOTP_READ_CTRL 0x30 +#define OCOTP_READ_FUSE_DATA 0x40 + +/* OCOTP Registers bits and masks */ +#define OCOTP_CTRL_WR_UNLOCK 16 +#define OCOTP_CTRL_WR_UNLOCK_KEY 0x3E77 +#define OCOTP_CTRL_WR_UNLOCK_MASK 0xFFFF0000 +#define OCOTP_CTRL_ADDR 0 +#define OCOTP_CTRL_ADDR_MASK 0x0000007F +#define OCOTP_CTRL_BUSY (1 << 8) +#define OCOTP_CTRL_ERROR (1 << 9) +#define OCOTP_CTRL_RELOAD_SHADOWS (1 << 10) + +#define OCOTP_TIMING_STROBE_READ 16 +#define OCOTP_TIMING_STROBE_READ_MASK 0x003F0000 +#define OCOTP_TIMING_RELAX 12 +#define OCOTP_TIMING_RELAX_MASK 0x0000F000 +#define OCOTP_TIMING_STROBE_PROG 0 +#define OCOTP_TIMING_STROBE_PROG_MASK 0x00000FFF + +#define OCOTP_READ_CTRL_READ_FUSE 0x00000001 + +#define BF(value, field) (((value) << field) & field##_MASK) + +/* Other definitions */ +#define FUSE_REGS_COUNT (16 * 8) +#define IMX6_OTP_DATA_ERROR_VAL 0xBADABADA +#define DEF_RELAX 20 +#define MAC_OFFSET (0x22 * 4) +#define MAC_BYTES 8 + +struct ocotp_priv { + struct cdev cdev; + void __iomem *base; + struct clk *clk; + struct device_d dev; + int permanent_write_enable; + int sense_enable; + char ethaddr[6]; +}; + +static int imx6_ocotp_set_timing(struct ocotp_priv *priv) +{ + u32 clk_rate; + u32 relax, strobe_read, strobe_prog; + u32 timing; + + clk_rate = clk_get_rate(priv->clk); + + relax = clk_rate / (1000000000 / DEF_RELAX) - 1; + strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1; + strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1; + + timing = BF(relax, OCOTP_TIMING_RELAX); + timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ); + timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG); + + writel(timing, priv->base + OCOTP_TIMING); + + return 0; +} + +static int imx6_ocotp_wait_busy(u32 flags, struct ocotp_priv *priv) +{ + uint64_t start = get_time_ns(); + + while ((OCOTP_CTRL_BUSY | OCOTP_CTRL_ERROR | flags) & + readl(priv->base)) { + if (is_timeout(start, MSECOND)) { + /* Clear ERROR bit */ + writel(OCOTP_CTRL_ERROR, priv->base + OCOTP_CTRL_CLR); + return -ETIMEDOUT; + } + } + + return 0; +} + +static int imx6_ocotp_prepare(struct ocotp_priv *priv) +{ + int ret; + + ret = imx6_ocotp_set_timing(priv); + if (ret) + return ret; + + ret = imx6_ocotp_wait_busy(0, priv); + if (ret) + return ret; + + return 0; +} + +static int fuse_read_addr(u32 addr, u32 *pdata, struct ocotp_priv *priv) +{ + u32 ctrl_reg; + int ret; + + ctrl_reg = readl(priv->base); + ctrl_reg &= ~OCOTP_CTRL_ADDR_MASK; + ctrl_reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK; + ctrl_reg |= BF(addr, OCOTP_CTRL_ADDR); + writel(ctrl_reg, priv->base); + + writel(OCOTP_READ_CTRL_READ_FUSE, priv->base + OCOTP_READ_CTRL); + ret = imx6_ocotp_wait_busy(0, priv); + if (ret) + return ret; + + *pdata = readl(priv->base + OCOTP_READ_FUSE_DATA); + + return 0; +} + +int imx6_ocotp_read_one_u32(u32 index, u32 *pdata, struct ocotp_priv *priv) +{ + int ret; + + ret = imx6_ocotp_prepare(priv); + if (ret) { + dev_err(priv->cdev.dev, "failed to prepare read fuse 0x%08x\n", + index); + return ret; + } + + ret = fuse_read_addr(index, pdata, priv); + if (ret) { + dev_err(priv->cdev.dev, "failed to read fuse 0x%08x\n", index); + return ret; + } + + if (readl(priv->base) & OCOTP_CTRL_ERROR) { + dev_err(priv->cdev.dev, "bad read status at fuse 0x%08x\n", index); + return -EFAULT; + } + + return 0; +} + +static ssize_t imx6_ocotp_cdev_read(struct cdev *cdev, void *buf, + size_t count, loff_t offset, unsigned long flags) +{ + u32 index; + ssize_t read_count = 0; + int ret, i; + struct ocotp_priv *priv = container_of(cdev, struct ocotp_priv, cdev); + + index = offset >> 2; + count >>= 2; + + if (count > (FUSE_REGS_COUNT - index)) + count = FUSE_REGS_COUNT - index - 1; + + for (i = index; i < (index + count); i++) { + if (priv->sense_enable) { + ret = imx6_ocotp_read_one_u32(i, buf, priv); + if (ret) + return ret; + } else { + *(u32 *)buf = readl(priv->base + 0x400 + i * 0x10); + } + + buf += 4; + read_count++; + } + + return read_count << 2; +} + +static int fuse_blow_addr(u32 addr, u32 value, struct ocotp_priv *priv) +{ + u32 ctrl_reg; + int ret; + + /* Control register */ + ctrl_reg = readl(priv->base); + ctrl_reg &= ~OCOTP_CTRL_ADDR_MASK; + ctrl_reg |= BF(addr, OCOTP_CTRL_ADDR); + ctrl_reg |= BF(OCOTP_CTRL_WR_UNLOCK_KEY, OCOTP_CTRL_WR_UNLOCK); + writel(ctrl_reg, priv->base); + + writel(value, priv->base + OCOTP_DATA); + ret = imx6_ocotp_wait_busy(0, priv); + if (ret) + return ret; + + /* Write postamble */ + udelay(2000); + return 0; +} + +static int imx6_ocotp_reload_shadow(struct ocotp_priv *priv) +{ + dev_info(priv->cdev.dev, "reloading shadow registers...\n"); + writel(OCOTP_CTRL_RELOAD_SHADOWS, priv->base + OCOTP_CTRL_SET); + udelay(1); + + return imx6_ocotp_wait_busy(OCOTP_CTRL_RELOAD_SHADOWS, priv); +} + +int imx6_ocotp_blow_one_u32(u32 index, u32 data, u32 *pfused_value, + struct ocotp_priv *priv) +{ + int ret; + + ret = imx6_ocotp_prepare(priv); + if (ret) { + dev_err(priv->cdev.dev, "prepare to write failed\n"); + return ret; + } + + ret = fuse_blow_addr(index, data, priv); + if (ret) { + dev_err(priv->cdev.dev, "fuse blow failed\n"); + return ret; + } + + if (readl(priv->base) & OCOTP_CTRL_ERROR) { + dev_err(priv->cdev.dev, "bad write status\n"); + return -EFAULT; + } + + ret = imx6_ocotp_read_one_u32(index, pfused_value, priv); + + return ret; +} + +static ssize_t imx6_ocotp_cdev_write(struct cdev *cdev, const void *buf, + size_t count, loff_t offset, unsigned long flags) +{ + struct ocotp_priv *priv = cdev->priv; + int index, i; + ssize_t write_count = 0; + const u32 *data; + u32 pfuse; + int ret; + + /* We could do better, but currently this is what's implemented */ + if (offset & 0x3 || count & 0x3) { + dev_err(cdev->dev, "only u32 aligned writes allowed\n"); + return -EINVAL; + } + + index = offset >> 2; + count >>= 2; + + if (count > (FUSE_REGS_COUNT - index)) + count = FUSE_REGS_COUNT - index - 1; + + data = buf; + + for (i = index; i < (index + count); i++) { + if (priv->permanent_write_enable) { + ret = imx6_ocotp_blow_one_u32(i, *data, + &pfuse, priv); + if (ret < 0) { + goto out; + } + } else { + writel(*data, priv->base + 0x400 + i * 0x10); + } + + data++; + write_count++; + } + + ret = 0; + +out: + if (priv->permanent_write_enable) + imx6_ocotp_reload_shadow(priv); + + return ret < 0 ? ret : (write_count << 2); +} + +static struct file_operations imx6_ocotp_ops = { + .read = imx6_ocotp_cdev_read, + .write = imx6_ocotp_cdev_write, + .lseek = dev_lseek_default, +}; + static void imx_ocotp_init_dt(struct device_d *dev, void __iomem *base) { char mac[6]; @@ -70,9 +358,43 @@ } } +static int imx_ocotp_get_mac(struct param_d *param, void *priv) +{ + struct ocotp_priv *ocotp_priv = priv; + char buf[8]; + int i; + + imx6_ocotp_cdev_read(&ocotp_priv->cdev, buf, MAC_BYTES, MAC_OFFSET, 0); + + for (i = 0; i < 6; i++) + ocotp_priv->ethaddr[i] = buf[5 - i]; + + return 0; +} + +static int imx_ocotp_set_mac(struct param_d *param, void *priv) +{ + struct ocotp_priv *ocotp_priv = priv; + char buf[8]; + int i, ret; + + for (i = 0; i < 6; i++) + buf[5 - i] = ocotp_priv->ethaddr[i]; + buf[6] = 0; buf[7] = 0; + + ret = imx6_ocotp_cdev_write(&ocotp_priv->cdev, buf, MAC_BYTES, MAC_OFFSET, 0); + if (ret < 0) + return ret; + + return 0; +} + static int imx_ocotp_probe(struct device_d *dev) { void __iomem *base; + struct ocotp_priv *priv; + struct cdev *cdev; + int ret = 0; base = dev_request_mem_region(dev, 0); if (!base) @@ -80,6 +402,40 @@ imx_ocotp_init_dt(dev, base); + priv = xzalloc(sizeof(*priv)); + + priv->base = base; + priv->clk = clk_get(dev, NULL); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + + cdev = &priv->cdev; + cdev->dev = dev; + cdev->ops = &imx6_ocotp_ops; + cdev->priv = priv; + cdev->size = 192; + cdev->name = "imx-ocotp"; + if (cdev->name == NULL) + return -ENOMEM; + + ret = devfs_create(cdev); + + if (ret < 0) + return ret; + + strcpy(priv->dev.name, "ocotp"); + priv->dev.parent = dev; + register_device(&priv->dev); + + if (IS_ENABLED(CONFIG_IMX_OCOTP_WRITE)) { + dev_add_param_bool(&(priv->dev), "permanent_write_enable", + NULL, NULL, &priv->permanent_write_enable, NULL); + } + + dev_add_param_mac(&(priv->dev), "mac_addr", imx_ocotp_set_mac, + imx_ocotp_get_mac, priv->ethaddr, priv); + dev_add_param_bool(&(priv->dev), "sense_enable", NULL, NULL, &priv->sense_enable, priv); + return 0; } diff --git a/drivers/gpio/gpio-imx.c b/drivers/gpio/gpio-imx.c index a71492a..d32638c 100644 --- a/drivers/gpio/gpio-imx.c +++ b/drivers/gpio/gpio-imx.c @@ -113,11 +113,21 @@ return val & (1 << gpio) ? 1 : 0; } +static int imx_get_direction(struct gpio_chip *chip, unsigned offset) +{ + struct imx_gpio_chip *imxgpio = container_of(chip, struct imx_gpio_chip, chip); + void __iomem *base = imxgpio->base; + u32 val = readl(base + imxgpio->regs->gdir); + + return (val & (1 << offset)) ? GPIOF_DIR_OUT : GPIOF_DIR_IN; +} + static struct gpio_ops imx_gpio_ops = { .direction_input = imx_gpio_direction_input, .direction_output = imx_gpio_direction_output, .get = imx_gpio_get_value, .set = imx_gpio_set_value, + .get_direction = imx_get_direction, }; static int imx_gpio_probe(struct device_d *dev) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 422693c..e429ea1 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -25,7 +25,7 @@ config DRIVER_SPI_IMX_0_7 bool - depends on ARCH_IMX25 || ARCH_IMX35 + depends on ARCH_IMX25 || ARCH_IMX35 || ARCH_IMX53 default y config DRIVER_SPI_IMX_2_3 diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c index 45461bd..bd8fe35 100644 --- a/drivers/spi/imx_spi.c +++ b/drivers/spi/imx_spi.c @@ -67,6 +67,8 @@ #define CSPI_0_0_TEST_LBC (1 << 14) +#define CSPI_0_0_RESET_START (1 << 0) + #define CSPI_0_7_RXDATA 0x00 #define CSPI_0_7_TXDATA 0x04 #define CSPI_0_7_CTRL 0x08 @@ -115,7 +117,6 @@ unsigned int (*xchg_single)(struct imx_spi *imx, u32 data); void (*chipselect)(struct spi_device *spi, int active); - void (*init)(struct imx_spi *imx); }; struct spi_imx_devtype_data { @@ -197,13 +198,9 @@ { void __iomem *base = imx->regs; - writel(CSPI_0_0_CTRL_ENABLE | CSPI_0_0_CTRL_MASTER, - base + CSPI_0_0_CTRL); - writel(CSPI_0_0_PERIOD_32KHZ, - base + CSPI_0_0_PERIOD); - while (readl(base + CSPI_0_0_INT) & CSPI_0_0_STAT_RR) - readl(base + CSPI_0_0_RXDATA); - writel(0, base + CSPI_0_0_INT); + writel(CSPI_0_0_RESET_START, base + CSPI_0_0_RESET); + do { + } while (readl(base + CSPI_0_0_RESET) & CSPI_0_0_RESET_START); } static unsigned int cspi_0_7_xchg_single(struct imx_spi *imx, unsigned int data) @@ -385,10 +382,6 @@ gpio_set_value(gpio, gpio_cs); } -static void cspi_2_3_init(struct imx_spi *imx) -{ -} - static void imx_spi_do_transfer(struct spi_device *spi, struct spi_transfer *t) { struct imx_spi *imx = container_of(spi->master, struct imx_spi, master); @@ -461,7 +454,6 @@ static __maybe_unused struct spi_imx_devtype_data spi_imx_devtype_data_2_3 = { .chipselect = cspi_2_3_chipselect, .xchg_single = cspi_2_3_xchg_single, - .init = cspi_2_3_init, }; static int imx_spi_dt_probe(struct imx_spi *imx) @@ -525,10 +517,10 @@ imx->chipselect = devdata->chipselect; imx->xchg_single = devdata->xchg_single; - imx->init = devdata->init; imx->regs = dev_request_mem_region(dev, 0); - imx->init(imx); + if (devdata->init) + devdata->init(imx); spi_register_master(master); diff --git a/images/Makefile.imx b/images/Makefile.imx index 06794fd..d00a3e5 100644 --- a/images/Makefile.imx +++ b/images/Makefile.imx @@ -166,3 +166,23 @@ CFG_start_variscite_custom.pblx.imximg = $(board)/variscite-mx6/flash-header-variscite.imxcfg FILE_barebox-variscite-custom.img = start_variscite_custom.pblx.imximg image-$(CONFIG_MACH_VARISCITE_MX6) += barebox-variscite-custom.img + +pblx-$(CONFIG_MACH_EMBEST_RIOTBOARD) += start_imx6s_riotboard +CFG_start_imx6s_riotboard.pblx.imximg = $(board)/embest-riotboard/flash-header-embest-riotboard.imxcfg +FILE_barebox-embest-imx6s-riotboard.img = start_imx6s_riotboard.pblx.imximg +image-$(CONFIG_MACH_EMBEST_RIOTBOARD) += barebox-embest-imx6s-riotboard.img + +pblx-$(CONFIG_MACH_PCAAXL3) += start_phytec_pbaa03_1gib +CFG_start_phytec_pbaa03_1gib.pblx.imximg = $(board)/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg +FILE_barebox-phytec-pbaa03-1gib.img = start_phytec_pbaa03_1gib.pblx.imximg +image-$(CONFIG_MACH_PCAAXL3) += barebox-phytec-pbaa03-1gib.img + +pblx-$(CONFIG_MACH_PCAAXL3) += start_phytec_pbaa03_1gib_1bank +CFG_start_phytec_pbaa03_1gib_1bank.pblx.imximg = $(board)/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg +FILE_barebox-phytec-pbaa03-1gib-1bank.img = start_phytec_pbaa03_1gib_1bank.pblx.imximg +image-$(CONFIG_MACH_PCAAXL3) += barebox-phytec-pbaa03-1gib-1bank.img + +pblx-$(CONFIG_MACH_PCAAXL3) += start_phytec_pbaa03_2gib +CFG_start_phytec_pbaa03_2gib.pblx.imximg = $(board)/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg +FILE_barebox-phytec-pbaa03-2gib.img = start_phytec_pbaa03_2gib.pblx.imximg +image-$(CONFIG_MACH_PCAAXL3) += barebox-phytec-pbaa03-2gib.img