Merge branch '2019-07-26-ti-imports'
authorTom Rini <trini@konsulko.com>
Sat, 27 Jul 2019 23:50:52 +0000 (19:50 -0400)
committerTom Rini <trini@konsulko.com>
Sat, 27 Jul 2019 23:50:52 +0000 (19:50 -0400)
- Bring in the rest of the J271E platform
- Various OMAP3/AM3517, DA850 fixes

164 files changed:
MAINTAINERS
README
arch/arm/dts/Makefile
arch/arm/dts/fsl-imx8dx.dtsi
arch/arm/dts/imx28-pinfunc.h [new file with mode: 0644]
arch/arm/dts/imx28-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/imx28.dtsi [new file with mode: 0644]
arch/arm/dts/imx53-m53menlo-u-boot.dtsi
arch/arm/dts/imx6dl-dhcom-pdk2.dts [new file with mode: 0644]
arch/arm/dts/imx6q-dhcom-pdk2.dts
arch/arm/dts/imx6q-dhcom-som.dtsi [deleted file]
arch/arm/dts/imx6q-display5-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/imx6q-display5.dts
arch/arm/dts/imx6qdl-dhcom-pdk2.dtsi [new file with mode: 0644]
arch/arm/dts/imx6qdl-dhcom.dtsi [new file with mode: 0644]
arch/arm/dts/imx7d-pico.dtsi
arch/arm/dts/mxs-pinfunc.h [new file with mode: 0644]
arch/arm/include/asm/arch-imx8/sci/sci.h
arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h
arch/arm/include/asm/arch-imx8/sys_proto.h
arch/arm/include/asm/mach-imx/imx-nandbcb.h [new file with mode: 0644]
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/cmd_nandbcb.c [new file with mode: 0644]
arch/arm/mach-imx/cpu.c
arch/arm/mach-imx/imx8/Makefile
arch/arm/mach-imx/imx8/misc.c [new file with mode: 0644]
arch/arm/mach-imx/mx6/soc.c
arch/arm/mach-imx/spl.c
arch/sandbox/dts/test.dts
board/armadeus/opos6uldev/board.c
board/dhelectronics/dh_imx6/dh_imx6.c
board/dhelectronics/dh_imx6/dh_imx6_spl.c
board/engicam/common/board.c
board/freescale/imx8qm_mek/imx8qm_mek.c
board/freescale/imx8qxp_mek/imx8qxp_mek.c
board/freescale/mx6sxsabresd/imximage.cfg
board/freescale/mx7ulp_evk/imximage.cfg
board/freescale/mx7ulp_evk/plugin.S
board/liebherr/display5/common.c
board/liebherr/display5/display5.c
board/logicpd/imx6/imx6logic.c
board/technexion/pico-imx7d/pico-imx7d.c
board/toradex/apalis-imx8/apalis-imx8.c
board/toradex/colibri-imx8x/colibri-imx8x.c
board/toradex/common/tdx-cfg-block.c
cmd/Kconfig
cmd/eeprom.c
common/board_r.c
common/spl/Kconfig
common/spl/spl.c
configs/apalis_imx6_defconfig
configs/aristainetos2_defconfig
configs/aristainetos2b_defconfig
configs/aristainetos_defconfig
configs/colibri-imx6ull_defconfig
configs/colibri_imx6_defconfig
configs/colibri_imx7_emmc_defconfig
configs/dh_imx6_defconfig
configs/display5_defconfig
configs/dms-ba16-1g_defconfig
configs/dms-ba16_defconfig
configs/ge_bx50v3_defconfig
configs/imx6q_logic_defconfig
configs/imx6qdl_icore_mmc_defconfig
configs/imx6qdl_icore_nand_defconfig
configs/imx8qxp_mek_defconfig
configs/kp_imx53_defconfig
configs/m53menlo_defconfig
configs/mccmon6_nor_defconfig
configs/mccmon6_sd_defconfig
configs/mt7629_rfb_defconfig
configs/mx53ppd_defconfig
configs/pico-hobbit-imx7d_defconfig
configs/pico-imx7d_bl33_defconfig
configs/pico-imx7d_defconfig
configs/pico-pi-imx7d_defconfig
configs/sandbox_defconfig
configs/sandbox_flattree_defconfig
configs/vining_2000_defconfig
configs/warp7_bl33_defconfig
doc/README.falcon
doc/imx/clk/ccf.txt [new file with mode: 0644]
doc/imx/common/imx6.txt
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/clk-divider.c [new file with mode: 0644]
drivers/clk/clk-fixed-factor.c [new file with mode: 0644]
drivers/clk/clk-mux.c [new file with mode: 0644]
drivers/clk/clk-uclass.c
drivers/clk/clk.c [new file with mode: 0644]
drivers/clk/clk_fixed_factor.c
drivers/clk/clk_fixed_rate.c
drivers/clk/clk_sandbox_ccf.c [new file with mode: 0644]
drivers/clk/imx/Kconfig
drivers/clk/imx/Makefile
drivers/clk/imx/clk-gate2.c [new file with mode: 0644]
drivers/clk/imx/clk-imx6q.c [new file with mode: 0644]
drivers/clk/imx/clk-pfd.c [new file with mode: 0644]
drivers/clk/imx/clk-pllv3.c [new file with mode: 0644]
drivers/clk/imx/clk.h [new file with mode: 0644]
drivers/gpio/mxc_gpio.c
drivers/gpio/mxs_gpio.c
drivers/misc/imx8/scu_api.c
drivers/mmc/mmc_spi.c
drivers/mtd/nand/raw/mxs_nand.c
drivers/mtd/nand/raw/mxs_nand.h [deleted file]
drivers/mtd/nand/raw/mxs_nand_dt.c
drivers/mtd/nand/raw/mxs_nand_spl.c
drivers/mtd/spi/spi-nor-ids.c
drivers/net/Kconfig
drivers/net/fec_mxc.c
drivers/pinctrl/nxp/Kconfig
drivers/pinctrl/nxp/Makefile
drivers/pinctrl/nxp/pinctrl-mxs.c [new file with mode: 0644]
drivers/pinctrl/nxp/pinctrl-mxs.h [new file with mode: 0644]
drivers/power/pmic/bd71837.c
drivers/power/regulator/Kconfig
drivers/power/regulator/Makefile
drivers/power/regulator/bd71837.c [new file with mode: 0644]
drivers/pwm/Kconfig
drivers/pwm/pwm-imx.c
drivers/serial/serial_mxc.c
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/fsl_qspi.c
drivers/spi/mtk_qspi.c [deleted file]
drivers/spi/mtk_snfi_spi.c [new file with mode: 0644]
drivers/spi/mxs_spi.c
drivers/spi/spi-mem.c
drivers/spi/spi-sifive.c [new file with mode: 0644]
drivers/thermal/Kconfig
drivers/thermal/Makefile
drivers/thermal/imx_scu_thermal.c [new file with mode: 0644]
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/imx_watchdog.c
include/asm-generic/global_data.h
include/clk.h
include/configs/advantech_dms-ba16.h
include/configs/apalis_imx6.h
include/configs/aristainetos-common.h
include/configs/aristainetos2.h
include/configs/aristainetos2b.h
include/configs/colibri-imx6ull.h
include/configs/colibri_imx6.h
include/configs/colibri_imx7.h
include/configs/dh_imx6.h
include/configs/display5.h
include/configs/ge_bx50v3.h
include/configs/m53menlo.h
include/configs/mccmon6.h
include/configs/mx53ppd.h
include/configs/vining_2000.h
include/configs/warp7.h
include/linux/clk-provider.h [new file with mode: 0644]
include/mxs_nand.h [new file with mode: 0644]
include/power/bd71837.h
include/sandbox-clk.h [new file with mode: 0644]
include/wdt.h
lib/optee/Kconfig
scripts/config_whitelist.txt
test/dm/Makefile
test/dm/clk_ccf.c [new file with mode: 0644]

index a72ccd0b5854dfe375f394aa75172f7228a682a5..4285d566265577f327b135b32b5a00822dcea493 100644 (file)
@@ -205,7 +205,7 @@ F:  drivers/mmc/mtk-sd.c
 F:     drivers/pinctrl/mediatek/
 F:     drivers/power/domain/mtk-power-domain.c
 F:     drivers/ram/mediatek/
-F:     drivers/spi/mtk_qspi.c
+F:     drivers/spi/mtk_snfi_spi.c
 F:     drivers/timer/mtk_timer.c
 F:     drivers/watchdog/mtk_wdt.c
 F:     drivers/net/mtk_eth.c
@@ -445,6 +445,13 @@ T: git https://gitlab.denx.de/u-boot/custodians/u-boot-cfi-flash.git
 F:     drivers/mtd/cfi_flash.c
 F:     drivers/mtd/jedec_flash.c
 
+CLOCK
+M:     Lukasz Majewski <lukma@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-dfu.git
+F:     drivers/clk/
+F:     drivers/clk/imx/
+
 COLDFIRE
 M:     Huan Wang <alison.wang@nxp.com>
 M:     Angelo Dureghello <angelo@sysam.it>
@@ -778,6 +785,11 @@ F: drivers/tee/
 F:     include/tee.h
 F:     include/tee/
 
+TEE-lib
+M:     Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+S:     Maintained
+F:     lib/optee
+
 UBI
 M:     Kyungmin Park <kmpark@infradead.org>
 M:     Heiko Schocher <hs@denx.de>
diff --git a/README b/README
index 8f816ad2aff4d141e689dba5adbf5945cdf358b2..7e610a8ebda3a669f0e1f9cb3a7eaeaf0420336c 100644 (file)
--- a/README
+++ b/README
@@ -960,10 +960,6 @@ The following options need to be configured:
                        CONFIG_SH_ETHER_CACHE_WRITEBACK
                        If this option is set, the driver enables cache flush.
 
-- PWM Support:
-               CONFIG_PWM_IMX
-               Support for PWM module on the imx6.
-
 - TPM Support:
                CONFIG_TPM
                Support TPM devices.
index 77d1b6021b2d3216d13e0705d8ddc167c8b17753..49d1faef3235967811a3c52d1abedac583ae9e3f 100644 (file)
@@ -551,6 +551,7 @@ dtb-$(CONFIG_MX6Q) += \
        imx6q-tbs2910.dtb
 
 dtb-$(CONFIG_MX6QDL) += \
+       imx6dl-dhcom-pdk2.dtb \
        imx6dl-icore.dtb \
        imx6dl-icore-mipi.dtb \
        imx6dl-icore-rqs.dtb \
@@ -559,6 +560,7 @@ dtb-$(CONFIG_MX6QDL) += \
        imx6dl-sabresd.dtb \
        imx6dl-wandboard-revb1.dtb \
        imx6q-cm-fx6.dtb \
+       imx6q-dhcom-pdk2.dtb \
        imx6q-icore.dtb \
        imx6q-icore-mipi.dtb \
        imx6q-icore-rqs.dtb \
@@ -599,8 +601,7 @@ dtb-$(CONFIG_MX6ULL) += \
 
 dtb-$(CONFIG_ARCH_MX6) += \
        imx6-apalis.dtb \
-       imx6-colibri.dtb \
-       imx6q-dhcom-pdk2.dtb
+       imx6-colibri.dtb
 
 dtb-$(CONFIG_MX7) += imx7d-sdb.dtb \
        imx7d-sdb-qspi.dtb \
index 715abb413d8e803a6d095c11f2d44f26e3a0846d..0c33eee6d2dcb29a8d5cc9cfdd97fb21354347b1 100644 (file)
@@ -11,6 +11,7 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/pads-imx8qxp.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
        model = "Freescale i.MX8DX";
                i2c1 = &i2c1;
                i2c2 = &i2c2;
                i2c3 = &i2c3;
+               gpio0 = &gpio0;
+               gpio1 = &gpio1;
+               gpio2 = &gpio2;
+               gpio3 = &gpio3;
+               gpio4 = &gpio4;
+               gpio5 = &gpio5;
+               gpio6 = &gpio6;
+               gpio7 = &gpio7;
        };
 
        memory@80000000 {
                power-domains = <&pd_conn_enet1>;
                status = "disabled";
        };
+
+       tsens: thermal-sensor {
+               compatible = "nxp,imx8qxp-sc-tsens";
+               /* number of the temp sensor on the chip */
+               tsens-num = <2>;
+               #thermal-sensor-cells = <1>;
+       };
+
+       thermal_zones: thermal-zones {
+               /* cpu thermal */
+               cpu-thermal0 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <2000>;
+                       /*the slope and offset of the temp sensor */
+                       thermal-sensors = <&tsens 0>;
+                       trips {
+                               cpu_alert0: trip0 {
+                                       temperature = <107000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                               cpu_crit0: trip1 {
+                                       temperature = <127000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu_alert0>;
+                                       cooling-device =
+                                       <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               drc-thermal0 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <2000>;
+                       thermal-sensors = <&tsens 1>;
+                       status = "disabled";
+                       trips {
+                               drc_alert0: trip0 {
+                                       temperature = <107000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                               drc_crit0: trip1 {
+                                       temperature = <127000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+       };
 };
 
 &A35_0 {
diff --git a/arch/arm/dts/imx28-pinfunc.h b/arch/arm/dts/imx28-pinfunc.h
new file mode 100644 (file)
index 0000000..e11f69b
--- /dev/null
@@ -0,0 +1,506 @@
+/*
+ * Header providing constants for i.MX28 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * 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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MX28_PINCTRL_H__
+#define __DT_BINDINGS_MX28_PINCTRL_H__
+
+#include "mxs-pinfunc.h"
+
+#define MX28_PAD_GPMI_D00__GPMI_D0                     0x0000
+#define MX28_PAD_GPMI_D01__GPMI_D1                     0x0010
+#define MX28_PAD_GPMI_D02__GPMI_D2                     0x0020
+#define MX28_PAD_GPMI_D03__GPMI_D3                     0x0030
+#define MX28_PAD_GPMI_D04__GPMI_D4                     0x0040
+#define MX28_PAD_GPMI_D05__GPMI_D5                     0x0050
+#define MX28_PAD_GPMI_D06__GPMI_D6                     0x0060
+#define MX28_PAD_GPMI_D07__GPMI_D7                     0x0070
+#define MX28_PAD_GPMI_CE0N__GPMI_CE0N                  0x0100
+#define MX28_PAD_GPMI_CE1N__GPMI_CE1N                  0x0110
+#define MX28_PAD_GPMI_CE2N__GPMI_CE2N                  0x0120
+#define MX28_PAD_GPMI_CE3N__GPMI_CE3N                  0x0130
+#define MX28_PAD_GPMI_RDY0__GPMI_READY0                        0x0140
+#define MX28_PAD_GPMI_RDY1__GPMI_READY1                        0x0150
+#define MX28_PAD_GPMI_RDY2__GPMI_READY2                        0x0160
+#define MX28_PAD_GPMI_RDY3__GPMI_READY3                        0x0170
+#define MX28_PAD_GPMI_RDN__GPMI_RDN                    0x0180
+#define MX28_PAD_GPMI_WRN__GPMI_WRN                    0x0190
+#define MX28_PAD_GPMI_ALE__GPMI_ALE                    0x01a0
+#define MX28_PAD_GPMI_CLE__GPMI_CLE                    0x01b0
+#define MX28_PAD_GPMI_RESETN__GPMI_RESETN              0x01c0
+#define MX28_PAD_LCD_D00__LCD_D0                       0x1000
+#define MX28_PAD_LCD_D01__LCD_D1                       0x1010
+#define MX28_PAD_LCD_D02__LCD_D2                       0x1020
+#define MX28_PAD_LCD_D03__LCD_D3                       0x1030
+#define MX28_PAD_LCD_D04__LCD_D4                       0x1040
+#define MX28_PAD_LCD_D05__LCD_D5                       0x1050
+#define MX28_PAD_LCD_D06__LCD_D6                       0x1060
+#define MX28_PAD_LCD_D07__LCD_D7                       0x1070
+#define MX28_PAD_LCD_D08__LCD_D8                       0x1080
+#define MX28_PAD_LCD_D09__LCD_D9                       0x1090
+#define MX28_PAD_LCD_D10__LCD_D10                      0x10a0
+#define MX28_PAD_LCD_D11__LCD_D11                      0x10b0
+#define MX28_PAD_LCD_D12__LCD_D12                      0x10c0
+#define MX28_PAD_LCD_D13__LCD_D13                      0x10d0
+#define MX28_PAD_LCD_D14__LCD_D14                      0x10e0
+#define MX28_PAD_LCD_D15__LCD_D15                      0x10f0
+#define MX28_PAD_LCD_D16__LCD_D16                      0x1100
+#define MX28_PAD_LCD_D17__LCD_D17                      0x1110
+#define MX28_PAD_LCD_D18__LCD_D18                      0x1120
+#define MX28_PAD_LCD_D19__LCD_D19                      0x1130
+#define MX28_PAD_LCD_D20__LCD_D20                      0x1140
+#define MX28_PAD_LCD_D21__LCD_D21                      0x1150
+#define MX28_PAD_LCD_D22__LCD_D22                      0x1160
+#define MX28_PAD_LCD_D23__LCD_D23                      0x1170
+#define MX28_PAD_LCD_RD_E__LCD_RD_E                    0x1180
+#define MX28_PAD_LCD_WR_RWN__LCD_WR_RWN                        0x1190
+#define MX28_PAD_LCD_RS__LCD_RS                                0x11a0
+#define MX28_PAD_LCD_CS__LCD_CS                                0x11b0
+#define MX28_PAD_LCD_VSYNC__LCD_VSYNC                  0x11c0
+#define MX28_PAD_LCD_HSYNC__LCD_HSYNC                  0x11d0
+#define MX28_PAD_LCD_DOTCLK__LCD_DOTCLK                        0x11e0
+#define MX28_PAD_LCD_ENABLE__LCD_ENABLE                        0x11f0
+#define MX28_PAD_SSP0_DATA0__SSP0_D0                   0x2000
+#define MX28_PAD_SSP0_DATA1__SSP0_D1                   0x2010
+#define MX28_PAD_SSP0_DATA2__SSP0_D2                   0x2020
+#define MX28_PAD_SSP0_DATA3__SSP0_D3                   0x2030
+#define MX28_PAD_SSP0_DATA4__SSP0_D4                   0x2040
+#define MX28_PAD_SSP0_DATA5__SSP0_D5                   0x2050
+#define MX28_PAD_SSP0_DATA6__SSP0_D6                   0x2060
+#define MX28_PAD_SSP0_DATA7__SSP0_D7                   0x2070
+#define MX28_PAD_SSP0_CMD__SSP0_CMD                    0x2080
+#define MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT         0x2090
+#define MX28_PAD_SSP0_SCK__SSP0_SCK                    0x20a0
+#define MX28_PAD_SSP1_SCK__SSP1_SCK                    0x20c0
+#define MX28_PAD_SSP1_CMD__SSP1_CMD                    0x20d0
+#define MX28_PAD_SSP1_DATA0__SSP1_D0                   0x20e0
+#define MX28_PAD_SSP1_DATA3__SSP1_D3                   0x20f0
+#define MX28_PAD_SSP2_SCK__SSP2_SCK                    0x2100
+#define MX28_PAD_SSP2_MOSI__SSP2_CMD                   0x2110
+#define MX28_PAD_SSP2_MISO__SSP2_D0                    0x2120
+#define MX28_PAD_SSP2_SS0__SSP2_D3                     0x2130
+#define MX28_PAD_SSP2_SS1__SSP2_D4                     0x2140
+#define MX28_PAD_SSP2_SS2__SSP2_D5                     0x2150
+#define MX28_PAD_SSP3_SCK__SSP3_SCK                    0x2180
+#define MX28_PAD_SSP3_MOSI__SSP3_CMD                   0x2190
+#define MX28_PAD_SSP3_MISO__SSP3_D0                    0x21a0
+#define MX28_PAD_SSP3_SS0__SSP3_D3                     0x21b0
+#define MX28_PAD_AUART0_RX__AUART0_RX                  0x3000
+#define MX28_PAD_AUART0_TX__AUART0_TX                  0x3010
+#define MX28_PAD_AUART0_CTS__AUART0_CTS                        0x3020
+#define MX28_PAD_AUART0_RTS__AUART0_RTS                        0x3030
+#define MX28_PAD_AUART1_RX__AUART1_RX                  0x3040
+#define MX28_PAD_AUART1_TX__AUART1_TX                  0x3050
+#define MX28_PAD_AUART1_CTS__AUART1_CTS                        0x3060
+#define MX28_PAD_AUART1_RTS__AUART1_RTS                        0x3070
+#define MX28_PAD_AUART2_RX__AUART2_RX                  0x3080
+#define MX28_PAD_AUART2_TX__AUART2_TX                  0x3090
+#define MX28_PAD_AUART2_CTS__AUART2_CTS                        0x30a0
+#define MX28_PAD_AUART2_RTS__AUART2_RTS                        0x30b0
+#define MX28_PAD_AUART3_RX__AUART3_RX                  0x30c0
+#define MX28_PAD_AUART3_TX__AUART3_TX                  0x30d0
+#define MX28_PAD_AUART3_CTS__AUART3_CTS                        0x30e0
+#define MX28_PAD_AUART3_RTS__AUART3_RTS                        0x30f0
+#define MX28_PAD_PWM0__PWM_0                           0x3100
+#define MX28_PAD_PWM1__PWM_1                           0x3110
+#define MX28_PAD_PWM2__PWM_2                           0x3120
+#define MX28_PAD_SAIF0_MCLK__SAIF0_MCLK                        0x3140
+#define MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK              0x3150
+#define MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK            0x3160
+#define MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0            0x3170
+#define MX28_PAD_I2C0_SCL__I2C0_SCL                    0x3180
+#define MX28_PAD_I2C0_SDA__I2C0_SDA                    0x3190
+#define MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0            0x31a0
+#define MX28_PAD_SPDIF__SPDIF_TX                       0x31b0
+#define MX28_PAD_PWM3__PWM_3                           0x31c0
+#define MX28_PAD_PWM4__PWM_4                           0x31d0
+#define MX28_PAD_LCD_RESET__LCD_RESET                  0x31e0
+#define MX28_PAD_ENET0_MDC__ENET0_MDC                  0x4000
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO                        0x4010
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN              0x4020
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0                        0x4030
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1                        0x4040
+#define MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK            0x4050
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN              0x4060
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0                        0x4070
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1                        0x4080
+#define MX28_PAD_ENET0_RXD2__ENET0_RXD2                        0x4090
+#define MX28_PAD_ENET0_RXD3__ENET0_RXD3                        0x40a0
+#define MX28_PAD_ENET0_TXD2__ENET0_TXD2                        0x40b0
+#define MX28_PAD_ENET0_TXD3__ENET0_TXD3                        0x40c0
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK            0x40d0
+#define MX28_PAD_ENET0_COL__ENET0_COL                  0x40e0
+#define MX28_PAD_ENET0_CRS__ENET0_CRS                  0x40f0
+#define MX28_PAD_ENET_CLK__CLKCTRL_ENET                        0x4100
+#define MX28_PAD_JTAG_RTCK__JTAG_RTCK                  0x4140
+#define MX28_PAD_EMI_D00__EMI_DATA0                    0x5000
+#define MX28_PAD_EMI_D01__EMI_DATA1                    0x5010
+#define MX28_PAD_EMI_D02__EMI_DATA2                    0x5020
+#define MX28_PAD_EMI_D03__EMI_DATA3                    0x5030
+#define MX28_PAD_EMI_D04__EMI_DATA4                    0x5040
+#define MX28_PAD_EMI_D05__EMI_DATA5                    0x5050
+#define MX28_PAD_EMI_D06__EMI_DATA6                    0x5060
+#define MX28_PAD_EMI_D07__EMI_DATA7                    0x5070
+#define MX28_PAD_EMI_D08__EMI_DATA8                    0x5080
+#define MX28_PAD_EMI_D09__EMI_DATA9                    0x5090
+#define MX28_PAD_EMI_D10__EMI_DATA10                   0x50a0
+#define MX28_PAD_EMI_D11__EMI_DATA11                   0x50b0
+#define MX28_PAD_EMI_D12__EMI_DATA12                   0x50c0
+#define MX28_PAD_EMI_D13__EMI_DATA13                   0x50d0
+#define MX28_PAD_EMI_D14__EMI_DATA14                   0x50e0
+#define MX28_PAD_EMI_D15__EMI_DATA15                   0x50f0
+#define MX28_PAD_EMI_ODT0__EMI_ODT0                    0x5100
+#define MX28_PAD_EMI_DQM0__EMI_DQM0                    0x5110
+#define MX28_PAD_EMI_ODT1__EMI_ODT1                    0x5120
+#define MX28_PAD_EMI_DQM1__EMI_DQM1                    0x5130
+#define MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK        0x5140
+#define MX28_PAD_EMI_CLK__EMI_CLK                      0x5150
+#define MX28_PAD_EMI_DQS0__EMI_DQS0                    0x5160
+#define MX28_PAD_EMI_DQS1__EMI_DQS1                    0x5170
+#define MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN            0x51a0
+#define MX28_PAD_EMI_A00__EMI_ADDR0                    0x6000
+#define MX28_PAD_EMI_A01__EMI_ADDR1                    0x6010
+#define MX28_PAD_EMI_A02__EMI_ADDR2                    0x6020
+#define MX28_PAD_EMI_A03__EMI_ADDR3                    0x6030
+#define MX28_PAD_EMI_A04__EMI_ADDR4                    0x6040
+#define MX28_PAD_EMI_A05__EMI_ADDR5                    0x6050
+#define MX28_PAD_EMI_A06__EMI_ADDR6                    0x6060
+#define MX28_PAD_EMI_A07__EMI_ADDR7                    0x6070
+#define MX28_PAD_EMI_A08__EMI_ADDR8                    0x6080
+#define MX28_PAD_EMI_A09__EMI_ADDR9                    0x6090
+#define MX28_PAD_EMI_A10__EMI_ADDR10                   0x60a0
+#define MX28_PAD_EMI_A11__EMI_ADDR11                   0x60b0
+#define MX28_PAD_EMI_A12__EMI_ADDR12                   0x60c0
+#define MX28_PAD_EMI_A13__EMI_ADDR13                   0x60d0
+#define MX28_PAD_EMI_A14__EMI_ADDR14                   0x60e0
+#define MX28_PAD_EMI_BA0__EMI_BA0                      0x6100
+#define MX28_PAD_EMI_BA1__EMI_BA1                      0x6110
+#define MX28_PAD_EMI_BA2__EMI_BA2                      0x6120
+#define MX28_PAD_EMI_CASN__EMI_CASN                    0x6130
+#define MX28_PAD_EMI_RASN__EMI_RASN                    0x6140
+#define MX28_PAD_EMI_WEN__EMI_WEN                      0x6150
+#define MX28_PAD_EMI_CE0N__EMI_CE0N                    0x6160
+#define MX28_PAD_EMI_CE1N__EMI_CE1N                    0x6170
+#define MX28_PAD_EMI_CKE__EMI_CKE                      0x6180
+#define MX28_PAD_GPMI_D00__SSP1_D0                     0x0001
+#define MX28_PAD_GPMI_D01__SSP1_D1                     0x0011
+#define MX28_PAD_GPMI_D02__SSP1_D2                     0x0021
+#define MX28_PAD_GPMI_D03__SSP1_D3                     0x0031
+#define MX28_PAD_GPMI_D04__SSP1_D4                     0x0041
+#define MX28_PAD_GPMI_D05__SSP1_D5                     0x0051
+#define MX28_PAD_GPMI_D06__SSP1_D6                     0x0061
+#define MX28_PAD_GPMI_D07__SSP1_D7                     0x0071
+#define MX28_PAD_GPMI_CE0N__SSP3_D0                    0x0101
+#define MX28_PAD_GPMI_CE1N__SSP3_D3                    0x0111
+#define MX28_PAD_GPMI_CE2N__CAN1_TX                    0x0121
+#define MX28_PAD_GPMI_CE3N__CAN1_RX                    0x0131
+#define MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT           0x0141
+#define MX28_PAD_GPMI_RDY1__SSP1_CMD                   0x0151
+#define MX28_PAD_GPMI_RDY2__CAN0_TX                    0x0161
+#define MX28_PAD_GPMI_RDY3__CAN0_RX                    0x0171
+#define MX28_PAD_GPMI_RDN__SSP3_SCK                    0x0181
+#define MX28_PAD_GPMI_WRN__SSP1_SCK                    0x0191
+#define MX28_PAD_GPMI_ALE__SSP3_D1                     0x01a1
+#define MX28_PAD_GPMI_CLE__SSP3_D2                     0x01b1
+#define MX28_PAD_GPMI_RESETN__SSP3_CMD                 0x01c1
+#define MX28_PAD_LCD_D03__ETM_DA8                      0x1031
+#define MX28_PAD_LCD_D04__ETM_DA9                      0x1041
+#define MX28_PAD_LCD_D08__ETM_DA3                      0x1081
+#define MX28_PAD_LCD_D09__ETM_DA4                      0x1091
+#define MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT                0x1141
+#define MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN         0x1151
+#define MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT                0x1161
+#define MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN         0x1171
+#define MX28_PAD_LCD_RD_E__LCD_VSYNC                   0x1181
+#define MX28_PAD_LCD_WR_RWN__LCD_HSYNC                 0x1191
+#define MX28_PAD_LCD_RS__LCD_DOTCLK                    0x11a1
+#define MX28_PAD_LCD_CS__LCD_ENABLE                    0x11b1
+#define MX28_PAD_LCD_VSYNC__SAIF1_SDATA0               0x11c1
+#define MX28_PAD_LCD_HSYNC__SAIF1_SDATA1               0x11d1
+#define MX28_PAD_LCD_DOTCLK__SAIF1_MCLK                        0x11e1
+#define MX28_PAD_SSP0_DATA4__SSP2_D0                   0x2041
+#define MX28_PAD_SSP0_DATA5__SSP2_D3                   0x2051
+#define MX28_PAD_SSP0_DATA6__SSP2_CMD                  0x2061
+#define MX28_PAD_SSP0_DATA7__SSP2_SCK                  0x2071
+#define MX28_PAD_SSP1_SCK__SSP2_D1                     0x20c1
+#define MX28_PAD_SSP1_CMD__SSP2_D2                     0x20d1
+#define MX28_PAD_SSP1_DATA0__SSP2_D6                   0x20e1
+#define MX28_PAD_SSP1_DATA3__SSP2_D7                   0x20f1
+#define MX28_PAD_SSP2_SCK__AUART2_RX                   0x2101
+#define MX28_PAD_SSP2_MOSI__AUART2_TX                  0x2111
+#define MX28_PAD_SSP2_MISO__AUART3_RX                  0x2121
+#define MX28_PAD_SSP2_SS0__AUART3_TX                   0x2131
+#define MX28_PAD_SSP2_SS1__SSP2_D1                     0x2141
+#define MX28_PAD_SSP2_SS2__SSP2_D2                     0x2151
+#define MX28_PAD_SSP3_SCK__AUART4_TX                   0x2181
+#define MX28_PAD_SSP3_MOSI__AUART4_RX                  0x2191
+#define MX28_PAD_SSP3_MISO__AUART4_RTS                 0x21a1
+#define MX28_PAD_SSP3_SS0__AUART4_CTS                  0x21b1
+#define MX28_PAD_AUART0_RX__I2C0_SCL                   0x3001
+#define MX28_PAD_AUART0_TX__I2C0_SDA                   0x3011
+#define MX28_PAD_AUART0_CTS__AUART4_RX                 0x3021
+#define MX28_PAD_AUART0_RTS__AUART4_TX                 0x3031
+#define MX28_PAD_AUART1_RX__SSP2_CARD_DETECT           0x3041
+#define MX28_PAD_AUART1_TX__SSP3_CARD_DETECT           0x3051
+#define MX28_PAD_AUART1_CTS__USB0_OVERCURRENT          0x3061
+#define MX28_PAD_AUART1_RTS__USB0_ID                   0x3071
+#define MX28_PAD_AUART2_RX__SSP3_D1                    0x3081
+#define MX28_PAD_AUART2_TX__SSP3_D2                    0x3091
+#define MX28_PAD_AUART2_CTS__I2C1_SCL                  0x30a1
+#define MX28_PAD_AUART2_RTS__I2C1_SDA                  0x30b1
+#define MX28_PAD_AUART3_RX__CAN0_TX                    0x30c1
+#define MX28_PAD_AUART3_TX__CAN0_RX                    0x30d1
+#define MX28_PAD_AUART3_CTS__CAN1_TX                   0x30e1
+#define MX28_PAD_AUART3_RTS__CAN1_RX                   0x30f1
+#define MX28_PAD_PWM0__I2C1_SCL                                0x3101
+#define MX28_PAD_PWM1__I2C1_SDA                                0x3111
+#define MX28_PAD_PWM2__USB0_ID                         0x3121
+#define MX28_PAD_SAIF0_MCLK__PWM_3                     0x3141
+#define MX28_PAD_SAIF0_LRCLK__PWM_4                    0x3151
+#define MX28_PAD_SAIF0_BITCLK__PWM_5                   0x3161
+#define MX28_PAD_SAIF0_SDATA0__PWM_6                   0x3171
+#define MX28_PAD_I2C0_SCL__TIMROT_ROTARYA              0x3181
+#define MX28_PAD_I2C0_SDA__TIMROT_ROTARYB              0x3191
+#define MX28_PAD_SAIF1_SDATA0__PWM_7                   0x31a1
+#define MX28_PAD_LCD_RESET__LCD_VSYNC                  0x31e1
+#define MX28_PAD_ENET0_MDC__GPMI_CE4N                  0x4001
+#define MX28_PAD_ENET0_MDIO__GPMI_CE5N                 0x4011
+#define MX28_PAD_ENET0_RX_EN__GPMI_CE6N                        0x4021
+#define MX28_PAD_ENET0_RXD0__GPMI_CE7N                 0x4031
+#define MX28_PAD_ENET0_RXD1__GPMI_READY4               0x4041
+#define MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER           0x4051
+#define MX28_PAD_ENET0_TX_EN__GPMI_READY5              0x4061
+#define MX28_PAD_ENET0_TXD0__GPMI_READY6               0x4071
+#define MX28_PAD_ENET0_TXD1__GPMI_READY7               0x4081
+#define MX28_PAD_ENET0_RXD2__ENET1_RXD0                        0x4091
+#define MX28_PAD_ENET0_RXD3__ENET1_RXD1                        0x40a1
+#define MX28_PAD_ENET0_TXD2__ENET1_TXD0                        0x40b1
+#define MX28_PAD_ENET0_TXD3__ENET1_TXD1                        0x40c1
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER             0x40d1
+#define MX28_PAD_ENET0_COL__ENET1_TX_EN                        0x40e1
+#define MX28_PAD_ENET0_CRS__ENET1_RX_EN                        0x40f1
+#define MX28_PAD_GPMI_CE2N__ENET0_RX_ER                        0x0122
+#define MX28_PAD_GPMI_CE3N__SAIF1_MCLK                 0x0132
+#define MX28_PAD_GPMI_RDY0__USB0_ID                    0x0142
+#define MX28_PAD_GPMI_RDY2__ENET0_TX_ER                        0x0162
+#define MX28_PAD_GPMI_RDY3__HSADC_TRIGGER              0x0172
+#define MX28_PAD_GPMI_ALE__SSP3_D4                     0x01a2
+#define MX28_PAD_GPMI_CLE__SSP3_D5                     0x01b2
+#define MX28_PAD_LCD_D00__ETM_DA0                      0x1002
+#define MX28_PAD_LCD_D01__ETM_DA1                      0x1012
+#define MX28_PAD_LCD_D02__ETM_DA2                      0x1022
+#define MX28_PAD_LCD_D03__ETM_DA3                      0x1032
+#define MX28_PAD_LCD_D04__ETM_DA4                      0x1042
+#define MX28_PAD_LCD_D05__ETM_DA5                      0x1052
+#define MX28_PAD_LCD_D06__ETM_DA6                      0x1062
+#define MX28_PAD_LCD_D07__ETM_DA7                      0x1072
+#define MX28_PAD_LCD_D08__ETM_DA8                      0x1082
+#define MX28_PAD_LCD_D09__ETM_DA9                      0x1092
+#define MX28_PAD_LCD_D10__ETM_DA10                     0x10a2
+#define MX28_PAD_LCD_D11__ETM_DA11                     0x10b2
+#define MX28_PAD_LCD_D12__ETM_DA12                     0x10c2
+#define MX28_PAD_LCD_D13__ETM_DA13                     0x10d2
+#define MX28_PAD_LCD_D14__ETM_DA14                     0x10e2
+#define MX28_PAD_LCD_D15__ETM_DA15                     0x10f2
+#define MX28_PAD_LCD_D16__ETM_DA7                      0x1102
+#define MX28_PAD_LCD_D17__ETM_DA6                      0x1112
+#define MX28_PAD_LCD_D18__ETM_DA5                      0x1122
+#define MX28_PAD_LCD_D19__ETM_DA4                      0x1132
+#define MX28_PAD_LCD_D20__ETM_DA3                      0x1142
+#define MX28_PAD_LCD_D21__ETM_DA2                      0x1152
+#define MX28_PAD_LCD_D22__ETM_DA1                      0x1162
+#define MX28_PAD_LCD_D23__ETM_DA0                      0x1172
+#define MX28_PAD_LCD_RD_E__ETM_TCTL                    0x1182
+#define MX28_PAD_LCD_WR_RWN__ETM_TCLK                  0x1192
+#define MX28_PAD_LCD_HSYNC__ETM_TCTL                   0x11d2
+#define MX28_PAD_LCD_DOTCLK__ETM_TCLK                  0x11e2
+#define MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT       0x20c2
+#define MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN                0x20d2
+#define MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT     0x20e2
+#define MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN      0x20f2
+#define MX28_PAD_SSP2_SCK__SAIF0_SDATA1                        0x2102
+#define MX28_PAD_SSP2_MOSI__SAIF0_SDATA2               0x2112
+#define MX28_PAD_SSP2_MISO__SAIF1_SDATA1               0x2122
+#define MX28_PAD_SSP2_SS0__SAIF1_SDATA2                        0x2132
+#define MX28_PAD_SSP2_SS1__USB1_OVERCURRENT            0x2142
+#define MX28_PAD_SSP2_SS2__USB0_OVERCURRENT            0x2152
+#define MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT       0x2182
+#define MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN       0x2192
+#define MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT      0x21a2
+#define MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN                0x21b2
+#define MX28_PAD_AUART0_RX__DUART_CTS                  0x3002
+#define MX28_PAD_AUART0_TX__DUART_RTS                  0x3012
+#define MX28_PAD_AUART0_CTS__DUART_RX                  0x3022
+#define MX28_PAD_AUART0_RTS__DUART_TX                  0x3032
+#define MX28_PAD_AUART1_RX__PWM_0                      0x3042
+#define MX28_PAD_AUART1_TX__PWM_1                      0x3052
+#define MX28_PAD_AUART1_CTS__TIMROT_ROTARYA            0x3062
+#define MX28_PAD_AUART1_RTS__TIMROT_ROTARYB            0x3072
+#define MX28_PAD_AUART2_RX__SSP3_D4                    0x3082
+#define MX28_PAD_AUART2_TX__SSP3_D5                    0x3092
+#define MX28_PAD_AUART2_CTS__SAIF1_BITCLK              0x30a2
+#define MX28_PAD_AUART2_RTS__SAIF1_LRCLK               0x30b2
+#define MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT      0x30c2
+#define MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN       0x30d2
+#define MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT     0x30e2
+#define MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN      0x30f2
+#define MX28_PAD_PWM0__DUART_RX                                0x3102
+#define MX28_PAD_PWM1__DUART_TX                                0x3112
+#define MX28_PAD_PWM2__USB1_OVERCURRENT                        0x3122
+#define MX28_PAD_SAIF0_MCLK__AUART4_CTS                        0x3142
+#define MX28_PAD_SAIF0_LRCLK__AUART4_RTS               0x3152
+#define MX28_PAD_SAIF0_BITCLK__AUART4_RX               0x3162
+#define MX28_PAD_SAIF0_SDATA0__AUART4_TX               0x3172
+#define MX28_PAD_I2C0_SCL__DUART_RX                    0x3182
+#define MX28_PAD_I2C0_SDA__DUART_TX                    0x3192
+#define MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1            0x31a2
+#define MX28_PAD_SPDIF__ENET1_RX_ER                    0x31b2
+#define MX28_PAD_ENET0_MDC__SAIF0_SDATA1               0x4002
+#define MX28_PAD_ENET0_MDIO__SAIF0_SDATA2              0x4012
+#define MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1             0x4022
+#define MX28_PAD_ENET0_RXD0__SAIF1_SDATA2              0x4032
+#define MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT   0x4052
+#define MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT     0x4092
+#define MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN      0x40a2
+#define MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT     0x40b2
+#define MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN      0x40c2
+#define MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN    0x40d2
+#define MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT      0x40e2
+#define MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN       0x40f2
+#define MX28_PAD_GPMI_D00__GPIO_0_0                    0x0003
+#define MX28_PAD_GPMI_D01__GPIO_0_1                    0x0013
+#define MX28_PAD_GPMI_D02__GPIO_0_2                    0x0023
+#define MX28_PAD_GPMI_D03__GPIO_0_3                    0x0033
+#define MX28_PAD_GPMI_D04__GPIO_0_4                    0x0043
+#define MX28_PAD_GPMI_D05__GPIO_0_5                    0x0053
+#define MX28_PAD_GPMI_D06__GPIO_0_6                    0x0063
+#define MX28_PAD_GPMI_D07__GPIO_0_7                    0x0073
+#define MX28_PAD_GPMI_CE0N__GPIO_0_16                  0x0103
+#define MX28_PAD_GPMI_CE1N__GPIO_0_17                  0x0113
+#define MX28_PAD_GPMI_CE2N__GPIO_0_18                  0x0123
+#define MX28_PAD_GPMI_CE3N__GPIO_0_19                  0x0133
+#define MX28_PAD_GPMI_RDY0__GPIO_0_20                  0x0143
+#define MX28_PAD_GPMI_RDY1__GPIO_0_21                  0x0153
+#define MX28_PAD_GPMI_RDY2__GPIO_0_22                  0x0163
+#define MX28_PAD_GPMI_RDY3__GPIO_0_23                  0x0173
+#define MX28_PAD_GPMI_RDN__GPIO_0_24                   0x0183
+#define MX28_PAD_GPMI_WRN__GPIO_0_25                   0x0193
+#define MX28_PAD_GPMI_ALE__GPIO_0_26                   0x01a3
+#define MX28_PAD_GPMI_CLE__GPIO_0_27                   0x01b3
+#define MX28_PAD_GPMI_RESETN__GPIO_0_28                        0x01c3
+#define MX28_PAD_LCD_D00__GPIO_1_0                     0x1003
+#define MX28_PAD_LCD_D01__GPIO_1_1                     0x1013
+#define MX28_PAD_LCD_D02__GPIO_1_2                     0x1023
+#define MX28_PAD_LCD_D03__GPIO_1_3                     0x1033
+#define MX28_PAD_LCD_D04__GPIO_1_4                     0x1043
+#define MX28_PAD_LCD_D05__GPIO_1_5                     0x1053
+#define MX28_PAD_LCD_D06__GPIO_1_6                     0x1063
+#define MX28_PAD_LCD_D07__GPIO_1_7                     0x1073
+#define MX28_PAD_LCD_D08__GPIO_1_8                     0x1083
+#define MX28_PAD_LCD_D09__GPIO_1_9                     0x1093
+#define MX28_PAD_LCD_D10__GPIO_1_10                    0x10a3
+#define MX28_PAD_LCD_D11__GPIO_1_11                    0x10b3
+#define MX28_PAD_LCD_D12__GPIO_1_12                    0x10c3
+#define MX28_PAD_LCD_D13__GPIO_1_13                    0x10d3
+#define MX28_PAD_LCD_D14__GPIO_1_14                    0x10e3
+#define MX28_PAD_LCD_D15__GPIO_1_15                    0x10f3
+#define MX28_PAD_LCD_D16__GPIO_1_16                    0x1103
+#define MX28_PAD_LCD_D17__GPIO_1_17                    0x1113
+#define MX28_PAD_LCD_D18__GPIO_1_18                    0x1123
+#define MX28_PAD_LCD_D19__GPIO_1_19                    0x1133
+#define MX28_PAD_LCD_D20__GPIO_1_20                    0x1143
+#define MX28_PAD_LCD_D21__GPIO_1_21                    0x1153
+#define MX28_PAD_LCD_D22__GPIO_1_22                    0x1163
+#define MX28_PAD_LCD_D23__GPIO_1_23                    0x1173
+#define MX28_PAD_LCD_RD_E__GPIO_1_24                   0x1183
+#define MX28_PAD_LCD_WR_RWN__GPIO_1_25                 0x1193
+#define MX28_PAD_LCD_RS__GPIO_1_26                     0x11a3
+#define MX28_PAD_LCD_CS__GPIO_1_27                     0x11b3
+#define MX28_PAD_LCD_VSYNC__GPIO_1_28                  0x11c3
+#define MX28_PAD_LCD_HSYNC__GPIO_1_29                  0x11d3
+#define MX28_PAD_LCD_DOTCLK__GPIO_1_30                 0x11e3
+#define MX28_PAD_LCD_ENABLE__GPIO_1_31                 0x11f3
+#define MX28_PAD_SSP0_DATA0__GPIO_2_0                  0x2003
+#define MX28_PAD_SSP0_DATA1__GPIO_2_1                  0x2013
+#define MX28_PAD_SSP0_DATA2__GPIO_2_2                  0x2023
+#define MX28_PAD_SSP0_DATA3__GPIO_2_3                  0x2033
+#define MX28_PAD_SSP0_DATA4__GPIO_2_4                  0x2043
+#define MX28_PAD_SSP0_DATA5__GPIO_2_5                  0x2053
+#define MX28_PAD_SSP0_DATA6__GPIO_2_6                  0x2063
+#define MX28_PAD_SSP0_DATA7__GPIO_2_7                  0x2073
+#define MX28_PAD_SSP0_CMD__GPIO_2_8                    0x2083
+#define MX28_PAD_SSP0_DETECT__GPIO_2_9                 0x2093
+#define MX28_PAD_SSP0_SCK__GPIO_2_10                   0x20a3
+#define MX28_PAD_SSP1_SCK__GPIO_2_12                   0x20c3
+#define MX28_PAD_SSP1_CMD__GPIO_2_13                   0x20d3
+#define MX28_PAD_SSP1_DATA0__GPIO_2_14                 0x20e3
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15                 0x20f3
+#define MX28_PAD_SSP2_SCK__GPIO_2_16                   0x2103
+#define MX28_PAD_SSP2_MOSI__GPIO_2_17                  0x2113
+#define MX28_PAD_SSP2_MISO__GPIO_2_18                  0x2123
+#define MX28_PAD_SSP2_SS0__GPIO_2_19                   0x2133
+#define MX28_PAD_SSP2_SS1__GPIO_2_20                   0x2143
+#define MX28_PAD_SSP2_SS2__GPIO_2_21                   0x2153
+#define MX28_PAD_SSP3_SCK__GPIO_2_24                   0x2183
+#define MX28_PAD_SSP3_MOSI__GPIO_2_25                  0x2193
+#define MX28_PAD_SSP3_MISO__GPIO_2_26                  0x21a3
+#define MX28_PAD_SSP3_SS0__GPIO_2_27                   0x21b3
+#define MX28_PAD_AUART0_RX__GPIO_3_0                   0x3003
+#define MX28_PAD_AUART0_TX__GPIO_3_1                   0x3013
+#define MX28_PAD_AUART0_CTS__GPIO_3_2                  0x3023
+#define MX28_PAD_AUART0_RTS__GPIO_3_3                  0x3033
+#define MX28_PAD_AUART1_RX__GPIO_3_4                   0x3043
+#define MX28_PAD_AUART1_TX__GPIO_3_5                   0x3053
+#define MX28_PAD_AUART1_CTS__GPIO_3_6                  0x3063
+#define MX28_PAD_AUART1_RTS__GPIO_3_7                  0x3073
+#define MX28_PAD_AUART2_RX__GPIO_3_8                   0x3083
+#define MX28_PAD_AUART2_TX__GPIO_3_9                   0x3093
+#define MX28_PAD_AUART2_CTS__GPIO_3_10                 0x30a3
+#define MX28_PAD_AUART2_RTS__GPIO_3_11                 0x30b3
+#define MX28_PAD_AUART3_RX__GPIO_3_12                  0x30c3
+#define MX28_PAD_AUART3_TX__GPIO_3_13                  0x30d3
+#define MX28_PAD_AUART3_CTS__GPIO_3_14                 0x30e3
+#define MX28_PAD_AUART3_RTS__GPIO_3_15                 0x30f3
+#define MX28_PAD_PWM0__GPIO_3_16                       0x3103
+#define MX28_PAD_PWM1__GPIO_3_17                       0x3113
+#define MX28_PAD_PWM2__GPIO_3_18                       0x3123
+#define MX28_PAD_SAIF0_MCLK__GPIO_3_20                 0x3143
+#define MX28_PAD_SAIF0_LRCLK__GPIO_3_21                        0x3153
+#define MX28_PAD_SAIF0_BITCLK__GPIO_3_22               0x3163
+#define MX28_PAD_SAIF0_SDATA0__GPIO_3_23               0x3173
+#define MX28_PAD_I2C0_SCL__GPIO_3_24                   0x3183
+#define MX28_PAD_I2C0_SDA__GPIO_3_25                   0x3193
+#define MX28_PAD_SAIF1_SDATA0__GPIO_3_26               0x31a3
+#define MX28_PAD_SPDIF__GPIO_3_27                      0x31b3
+#define MX28_PAD_PWM3__GPIO_3_28                       0x31c3
+#define MX28_PAD_PWM4__GPIO_3_29                       0x31d3
+#define MX28_PAD_LCD_RESET__GPIO_3_30                  0x31e3
+#define MX28_PAD_ENET0_MDC__GPIO_4_0                   0x4003
+#define MX28_PAD_ENET0_MDIO__GPIO_4_1                  0x4013
+#define MX28_PAD_ENET0_RX_EN__GPIO_4_2                 0x4023
+#define MX28_PAD_ENET0_RXD0__GPIO_4_3                  0x4033
+#define MX28_PAD_ENET0_RXD1__GPIO_4_4                  0x4043
+#define MX28_PAD_ENET0_TX_CLK__GPIO_4_5                        0x4053
+#define MX28_PAD_ENET0_TX_EN__GPIO_4_6                 0x4063
+#define MX28_PAD_ENET0_TXD0__GPIO_4_7                  0x4073
+#define MX28_PAD_ENET0_TXD1__GPIO_4_8                  0x4083
+#define MX28_PAD_ENET0_RXD2__GPIO_4_9                  0x4093
+#define MX28_PAD_ENET0_RXD3__GPIO_4_10                 0x40a3
+#define MX28_PAD_ENET0_TXD2__GPIO_4_11                 0x40b3
+#define MX28_PAD_ENET0_TXD3__GPIO_4_12                 0x40c3
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13               0x40d3
+#define MX28_PAD_ENET0_COL__GPIO_4_14                  0x40e3
+#define MX28_PAD_ENET0_CRS__GPIO_4_15                  0x40f3
+#define MX28_PAD_ENET_CLK__GPIO_4_16                   0x4103
+#define MX28_PAD_JTAG_RTCK__GPIO_4_20                  0x4143
+
+#endif /* __DT_BINDINGS_MX28_PINCTRL_H__ */
diff --git a/arch/arm/dts/imx28-u-boot.dtsi b/arch/arm/dts/imx28-u-boot.dtsi
new file mode 100644 (file)
index 0000000..d545b40
--- /dev/null
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * SPDX-License-Identifier:     GPL-2.0+ or X11
+ */
+#include "imx28.dtsi"
+
+&gpio0 {
+       gpio-ranges = <&pinctrl 0 0 29>;
+};
+
+&gpio1 {
+       gpio-ranges = <&pinctrl 0 29 32>;
+};
+
+&gpio2 {
+       gpio-ranges = <&pinctrl 0 61 28>;
+};
+
+&gpio3 {
+       gpio-ranges = <&pinctrl 0 89 31>;
+};
+
+&gpio4 {
+       gpio-ranges = <&pinctrl 0 120 21>;
+};
diff --git a/arch/arm/dts/imx28.dtsi b/arch/arm/dts/imx28.dtsi
new file mode 100644 (file)
index 0000000..e14d8ef
--- /dev/null
@@ -0,0 +1,1330 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2012 Freescale Semiconductor, Inc.
+
+#include <dt-bindings/gpio/gpio.h>
+#include "imx28-pinfunc.h"
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       interrupt-parent = <&icoll>;
+       /*
+        * The decompressor and also some bootloaders rely on a
+        * pre-existing /chosen node to be available to insert the
+        * command line and merge other ATAGS info.
+        */
+       chosen {};
+
+       aliases {
+               ethernet0 = &mac0;
+               ethernet1 = &mac1;
+               gpio0 = &gpio0;
+               gpio1 = &gpio1;
+               gpio2 = &gpio2;
+               gpio3 = &gpio3;
+               gpio4 = &gpio4;
+               saif0 = &saif0;
+               saif1 = &saif1;
+               serial0 = &auart0;
+               serial1 = &auart1;
+               serial2 = &auart2;
+               serial3 = &auart3;
+               serial4 = &auart4;
+               spi0 = &ssp1;
+               spi1 = &ssp2;
+               usbphy0 = &usbphy0;
+               usbphy1 = &usbphy1;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       compatible = "arm,arm926ej-s";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+       };
+
+       apb@80000000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x80000000 0x80000>;
+               ranges;
+
+               apbh@80000000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x80000000 0x3c900>;
+                       ranges;
+
+                       icoll: interrupt-controller@80000000 {
+                               compatible = "fsl,imx28-icoll", "fsl,icoll";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x80000000 0x2000>;
+                       };
+
+                       hsadc: hsadc@80002000 {
+                               reg = <0x80002000 0x2000>;
+                               interrupts = <13>;
+                               dmas = <&dma_apbh 12>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+
+                       dma_apbh: dma-apbh@80004000 {
+                               compatible = "fsl,imx28-dma-apbh";
+                               reg = <0x80004000 0x2000>;
+                               interrupts = <82 83 84 85
+                                             88 88 88 88
+                                             88 88 88 88
+                                             87 86 0 0>;
+                               interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3",
+                                                 "gpmi0", "gmpi1", "gpmi2", "gmpi3",
+                                                 "gpmi4", "gmpi5", "gpmi6", "gmpi7",
+                                                 "hsadc", "lcdif", "empty", "empty";
+                               #dma-cells = <1>;
+                               dma-channels = <16>;
+                               clocks = <&clks 25>;
+                       };
+
+                       perfmon: perfmon@80006000 {
+                               reg = <0x80006000 0x800>;
+                               interrupts = <27>;
+                               status = "disabled";
+                       };
+
+                       gpmi: gpmi-nand@8000c000 {
+                               compatible = "fsl,imx28-gpmi-nand";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>;
+                               reg-names = "gpmi-nand", "bch";
+                               interrupts = <41>;
+                               interrupt-names = "bch";
+                               clocks = <&clks 50>;
+                               clock-names = "gpmi_io";
+                               dmas = <&dma_apbh 4>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       ssp0: spi@80010000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x80010000 0x2000>;
+                               interrupts = <96>;
+                               clocks = <&clks 46>;
+                               dmas = <&dma_apbh 0>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       ssp1: spi@80012000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x80012000 0x2000>;
+                               interrupts = <97>;
+                               clocks = <&clks 47>;
+                               dmas = <&dma_apbh 1>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       ssp2: spi@80014000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x80014000 0x2000>;
+                               interrupts = <98>;
+                               clocks = <&clks 48>;
+                               dmas = <&dma_apbh 2>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       ssp3: spi@80016000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x80016000 0x2000>;
+                               interrupts = <99>;
+                               clocks = <&clks 49>;
+                               dmas = <&dma_apbh 3>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       pinctrl: pinctrl@80018000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx28-pinctrl", "simple-bus";
+                               reg = <0x80018000 0x2000>;
+
+                               gpio0: gpio@0 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       reg = <0>;
+                                       interrupts = <127>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio1: gpio@1 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       reg = <1>;
+                                       interrupts = <126>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio2: gpio@2 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       reg = <2>;
+                                       interrupts = <125>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio3: gpio@3 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       reg = <3>;
+                                       interrupts = <124>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio4: gpio@4 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       reg = <4>;
+                                       interrupts = <123>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               duart_pins_a: duart@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_PWM0__DUART_RX
+                                               MX28_PAD_PWM1__DUART_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               duart_pins_b: duart@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART0_CTS__DUART_RX
+                                               MX28_PAD_AUART0_RTS__DUART_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               duart_4pins_a: duart-4pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART0_CTS__DUART_RX
+                                               MX28_PAD_AUART0_RTS__DUART_TX
+                                               MX28_PAD_AUART0_RX__DUART_CTS
+                                               MX28_PAD_AUART0_TX__DUART_RTS
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               gpmi_pins_a: gpmi-nand@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_GPMI_D00__GPMI_D0
+                                               MX28_PAD_GPMI_D01__GPMI_D1
+                                               MX28_PAD_GPMI_D02__GPMI_D2
+                                               MX28_PAD_GPMI_D03__GPMI_D3
+                                               MX28_PAD_GPMI_D04__GPMI_D4
+                                               MX28_PAD_GPMI_D05__GPMI_D5
+                                               MX28_PAD_GPMI_D06__GPMI_D6
+                                               MX28_PAD_GPMI_D07__GPMI_D7
+                                               MX28_PAD_GPMI_CE0N__GPMI_CE0N
+                                               MX28_PAD_GPMI_RDY0__GPMI_READY0
+                                               MX28_PAD_GPMI_RDN__GPMI_RDN
+                                               MX28_PAD_GPMI_WRN__GPMI_WRN
+                                               MX28_PAD_GPMI_ALE__GPMI_ALE
+                                               MX28_PAD_GPMI_CLE__GPMI_CLE
+                                               MX28_PAD_GPMI_RESETN__GPMI_RESETN
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               gpmi_status_cfg: gpmi-status-cfg@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_GPMI_RDN__GPMI_RDN
+                                               MX28_PAD_GPMI_WRN__GPMI_WRN
+                                               MX28_PAD_GPMI_RESETN__GPMI_RESETN
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                               };
+
+                               auart0_pins_a: auart0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART0_RX__AUART0_RX
+                                               MX28_PAD_AUART0_TX__AUART0_TX
+                                               MX28_PAD_AUART0_CTS__AUART0_CTS
+                                               MX28_PAD_AUART0_RTS__AUART0_RTS
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart0_2pins_a: auart0-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART0_RX__AUART0_RX
+                                               MX28_PAD_AUART0_TX__AUART0_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart1_pins_a: auart1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_RX__AUART1_RX
+                                               MX28_PAD_AUART1_TX__AUART1_TX
+                                               MX28_PAD_AUART1_CTS__AUART1_CTS
+                                               MX28_PAD_AUART1_RTS__AUART1_RTS
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart1_2pins_a: auart1-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_RX__AUART1_RX
+                                               MX28_PAD_AUART1_TX__AUART1_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart2_2pins_a: auart2-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP2_SCK__AUART2_RX
+                                               MX28_PAD_SSP2_MOSI__AUART2_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart2_2pins_b: auart2-2pins@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART2_RX__AUART2_RX
+                                               MX28_PAD_AUART2_TX__AUART2_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart2_pins_a: auart2-pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART2_RX__AUART2_RX
+                                               MX28_PAD_AUART2_TX__AUART2_TX
+                                               MX28_PAD_AUART2_CTS__AUART2_CTS
+                                               MX28_PAD_AUART2_RTS__AUART2_RTS
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart3_pins_a: auart3@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART3_RX__AUART3_RX
+                                               MX28_PAD_AUART3_TX__AUART3_TX
+                                               MX28_PAD_AUART3_CTS__AUART3_CTS
+                                               MX28_PAD_AUART3_RTS__AUART3_RTS
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart3_2pins_a: auart3-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP2_MISO__AUART3_RX
+                                               MX28_PAD_SSP2_SS0__AUART3_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart3_2pins_b: auart3-2pins@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART3_RX__AUART3_RX
+                                               MX28_PAD_AUART3_TX__AUART3_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart4_2pins_a: auart4@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP3_SCK__AUART4_TX
+                                               MX28_PAD_SSP3_MOSI__AUART4_RX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               auart4_2pins_b: auart4@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART0_CTS__AUART4_RX
+                                               MX28_PAD_AUART0_RTS__AUART4_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               mac0_pins_a: mac0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_ENET0_MDC__ENET0_MDC
+                                               MX28_PAD_ENET0_MDIO__ENET0_MDIO
+                                               MX28_PAD_ENET0_RX_EN__ENET0_RX_EN
+                                               MX28_PAD_ENET0_RXD0__ENET0_RXD0
+                                               MX28_PAD_ENET0_RXD1__ENET0_RXD1
+                                               MX28_PAD_ENET0_TX_EN__ENET0_TX_EN
+                                               MX28_PAD_ENET0_TXD0__ENET0_TXD0
+                                               MX28_PAD_ENET0_TXD1__ENET0_TXD1
+                                               MX28_PAD_ENET_CLK__CLKCTRL_ENET
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mac0_pins_b: mac0@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_ENET0_MDC__ENET0_MDC
+                                               MX28_PAD_ENET0_MDIO__ENET0_MDIO
+                                               MX28_PAD_ENET0_RX_EN__ENET0_RX_EN
+                                               MX28_PAD_ENET0_RXD0__ENET0_RXD0
+                                               MX28_PAD_ENET0_RXD1__ENET0_RXD1
+                                               MX28_PAD_ENET0_RXD2__ENET0_RXD2
+                                               MX28_PAD_ENET0_RXD3__ENET0_RXD3
+                                               MX28_PAD_ENET0_TX_EN__ENET0_TX_EN
+                                               MX28_PAD_ENET0_TXD0__ENET0_TXD0
+                                               MX28_PAD_ENET0_TXD1__ENET0_TXD1
+                                               MX28_PAD_ENET0_TXD2__ENET0_TXD2
+                                               MX28_PAD_ENET0_TXD3__ENET0_TXD3
+                                               MX28_PAD_ENET_CLK__CLKCTRL_ENET
+                                               MX28_PAD_ENET0_COL__ENET0_COL
+                                               MX28_PAD_ENET0_CRS__ENET0_CRS
+                                               MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK
+                                               MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK
+                                               >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mac1_pins_a: mac1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_ENET0_CRS__ENET1_RX_EN
+                                               MX28_PAD_ENET0_RXD2__ENET1_RXD0
+                                               MX28_PAD_ENET0_RXD3__ENET1_RXD1
+                                               MX28_PAD_ENET0_COL__ENET1_TX_EN
+                                               MX28_PAD_ENET0_TXD2__ENET1_TXD0
+                                               MX28_PAD_ENET0_TXD3__ENET1_TXD1
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mmc0_8bit_pins_a: mmc0-8bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP0_DATA0__SSP0_D0
+                                               MX28_PAD_SSP0_DATA1__SSP0_D1
+                                               MX28_PAD_SSP0_DATA2__SSP0_D2
+                                               MX28_PAD_SSP0_DATA3__SSP0_D3
+                                               MX28_PAD_SSP0_DATA4__SSP0_D4
+                                               MX28_PAD_SSP0_DATA5__SSP0_D5
+                                               MX28_PAD_SSP0_DATA6__SSP0_D6
+                                               MX28_PAD_SSP0_DATA7__SSP0_D7
+                                               MX28_PAD_SSP0_CMD__SSP0_CMD
+                                               MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+                                               MX28_PAD_SSP0_SCK__SSP0_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mmc0_4bit_pins_a: mmc0-4bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP0_DATA0__SSP0_D0
+                                               MX28_PAD_SSP0_DATA1__SSP0_D1
+                                               MX28_PAD_SSP0_DATA2__SSP0_D2
+                                               MX28_PAD_SSP0_DATA3__SSP0_D3
+                                               MX28_PAD_SSP0_CMD__SSP0_CMD
+                                               MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+                                               MX28_PAD_SSP0_SCK__SSP0_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mmc0_cd_cfg: mmc0-cd-cfg@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+                                       >;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               mmc0_sck_cfg: mmc0-sck-cfg@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP0_SCK__SSP0_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               mmc1_4bit_pins_a: mmc1-4bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_GPMI_D00__SSP1_D0
+                                               MX28_PAD_GPMI_D01__SSP1_D1
+                                               MX28_PAD_GPMI_D02__SSP1_D2
+                                               MX28_PAD_GPMI_D03__SSP1_D3
+                                               MX28_PAD_GPMI_RDY1__SSP1_CMD
+                                               MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT
+                                               MX28_PAD_GPMI_WRN__SSP1_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mmc1_cd_cfg: mmc1-cd-cfg@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT
+                                       >;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               mmc1_sck_cfg: mmc1-sck-cfg@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_GPMI_WRN__SSP1_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+
+                               mmc2_4bit_pins_a: mmc2-4bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP0_DATA4__SSP2_D0
+                                               MX28_PAD_SSP1_SCK__SSP2_D1
+                                               MX28_PAD_SSP1_CMD__SSP2_D2
+                                               MX28_PAD_SSP0_DATA5__SSP2_D3
+                                               MX28_PAD_SSP0_DATA6__SSP2_CMD
+                                               MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+                                               MX28_PAD_SSP0_DATA7__SSP2_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mmc2_4bit_pins_b: mmc2-4bit@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP2_SCK__SSP2_SCK
+                                               MX28_PAD_SSP2_MOSI__SSP2_CMD
+                                               MX28_PAD_SSP2_MISO__SSP2_D0
+                                               MX28_PAD_SSP2_SS0__SSP2_D3
+                                               MX28_PAD_SSP2_SS1__SSP2_D1
+                                               MX28_PAD_SSP2_SS2__SSP2_D2
+                                               MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mmc2_cd_cfg: mmc2-cd-cfg@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+                                       >;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               mmc2_sck_cfg_a: mmc2-sck-cfg@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP0_DATA7__SSP2_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               mmc2_sck_cfg_b: mmc2-sck-cfg@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP2_SCK__SSP2_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               i2c0_pins_a: i2c0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_I2C0_SCL__I2C0_SCL
+                                               MX28_PAD_I2C0_SDA__I2C0_SDA
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               i2c0_pins_b: i2c0@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART0_RX__I2C0_SCL
+                                               MX28_PAD_AUART0_TX__I2C0_SDA
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               i2c1_pins_a: i2c1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_PWM0__I2C1_SCL
+                                               MX28_PAD_PWM1__I2C1_SDA
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               i2c1_pins_b: i2c1@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART2_CTS__I2C1_SCL
+                                               MX28_PAD_AUART2_RTS__I2C1_SDA
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               saif0_pins_a: saif0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SAIF0_MCLK__SAIF0_MCLK
+                                               MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK
+                                               MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK
+                                               MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               saif0_pins_b: saif0@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK
+                                               MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK
+                                               MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               saif1_pins_a: saif1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               pwm0_pins_a: pwm0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_PWM0__PWM_0
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               pwm2_pins_a: pwm2@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_PWM2__PWM_2
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               pwm3_pins_a: pwm3@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_PWM3__PWM_3
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               pwm3_pins_b: pwm3@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SAIF0_MCLK__PWM_3
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               pwm4_pins_a: pwm4@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_PWM4__PWM_4
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               lcdif_24bit_pins_a: lcdif-24bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
+                                               MX28_PAD_LCD_D16__LCD_D16
+                                               MX28_PAD_LCD_D17__LCD_D17
+                                               MX28_PAD_LCD_D18__LCD_D18
+                                               MX28_PAD_LCD_D19__LCD_D19
+                                               MX28_PAD_LCD_D20__LCD_D20
+                                               MX28_PAD_LCD_D21__LCD_D21
+                                               MX28_PAD_LCD_D22__LCD_D22
+                                               MX28_PAD_LCD_D23__LCD_D23
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               lcdif_18bit_pins_a: lcdif-18bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
+                                               MX28_PAD_LCD_D16__LCD_D16
+                                               MX28_PAD_LCD_D17__LCD_D17
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               lcdif_16bit_pins_a: lcdif-16bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               lcdif_sync_pins_a: lcdif-sync@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               can0_pins_a: can0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_GPMI_RDY2__CAN0_TX
+                                               MX28_PAD_GPMI_RDY3__CAN0_RX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               can1_pins_a: can1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_GPMI_CE2N__CAN1_TX
+                                               MX28_PAD_GPMI_CE3N__CAN1_RX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               spi2_pins_a: spi2@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP2_SCK__SSP2_SCK
+                                               MX28_PAD_SSP2_MOSI__SSP2_CMD
+                                               MX28_PAD_SSP2_MISO__SSP2_D0
+                                               MX28_PAD_SSP2_SS0__SSP2_D3
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               spi3_pins_a: spi3@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART2_RX__SSP3_D4
+                                               MX28_PAD_AUART2_TX__SSP3_D5
+                                               MX28_PAD_SSP3_SCK__SSP3_SCK
+                                               MX28_PAD_SSP3_MOSI__SSP3_CMD
+                                               MX28_PAD_SSP3_MISO__SSP3_D0
+                                               MX28_PAD_SSP3_SS0__SSP3_D3
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               spi3_pins_b: spi3@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP3_SCK__SSP3_SCK
+                                               MX28_PAD_SSP3_MOSI__SSP3_CMD
+                                               MX28_PAD_SSP3_MISO__SSP3_D0
+                                               MX28_PAD_SSP3_SS0__SSP3_D3
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               usb0_pins_a: usb0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP2_SS2__USB0_OVERCURRENT
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               usb0_pins_b: usb0@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_CTS__USB0_OVERCURRENT
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               usb1_pins_a: usb1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP2_SS1__USB1_OVERCURRENT
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               usb0_id_pins_a: usb0id@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_RTS__USB0_ID
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               usb0_id_pins_b: usb0id1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_PWM2__USB0_ID
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                       };
+
+                       digctl: digctl@8001c000 {
+                               compatible = "fsl,imx28-digctl", "fsl,imx23-digctl";
+                               reg = <0x8001c000 0x2000>;
+                               interrupts = <89>;
+                               status = "disabled";
+                       };
+
+                       etm: etm@80022000 {
+                               reg = <0x80022000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       dma_apbx: dma-apbx@80024000 {
+                               compatible = "fsl,imx28-dma-apbx";
+                               reg = <0x80024000 0x2000>;
+                               interrupts = <78 79 66 0
+                                             80 81 68 69
+                                             70 71 72 73
+                                             74 75 76 77>;
+                               interrupt-names = "auart4-rx", "auart4-tx", "spdif-tx", "empty",
+                                                 "saif0", "saif1", "i2c0", "i2c1",
+                                                 "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
+                                                 "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
+                               #dma-cells = <1>;
+                               dma-channels = <16>;
+                               clocks = <&clks 26>;
+                       };
+
+                       dcp: dcp@80028000 {
+                               compatible = "fsl,imx28-dcp", "fsl,imx23-dcp";
+                               reg = <0x80028000 0x2000>;
+                               interrupts = <52 53 54>;
+                               status = "okay";
+                       };
+
+                       pxp: pxp@8002a000 {
+                               reg = <0x8002a000 0x2000>;
+                               interrupts = <39>;
+                               status = "disabled";
+                       };
+
+                       ocotp: ocotp@8002c000 {
+                               compatible = "fsl,imx28-ocotp", "fsl,ocotp";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x8002c000 0x2000>;
+                               clocks = <&clks 25>;
+                       };
+
+                       axi-ahb@8002e000 {
+                               reg = <0x8002e000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       lcdif: lcdif@80030000 {
+                               compatible = "fsl,imx28-lcdif";
+                               reg = <0x80030000 0x2000>;
+                               interrupts = <38>;
+                               clocks = <&clks 55>;
+                               dmas = <&dma_apbh 13>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+
+                       can0: can@80032000 {
+                               compatible = "fsl,imx28-flexcan";
+                               reg = <0x80032000 0x2000>;
+                               interrupts = <8>;
+                               clocks = <&clks 58>, <&clks 58>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       can1: can@80034000 {
+                               compatible = "fsl,imx28-flexcan";
+                               reg = <0x80034000 0x2000>;
+                               interrupts = <9>;
+                               clocks = <&clks 59>, <&clks 59>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       simdbg: simdbg@8003c000 {
+                               reg = <0x8003c000 0x200>;
+                               status = "disabled";
+                       };
+
+                       simgpmisel: simgpmisel@8003c200 {
+                               reg = <0x8003c200 0x100>;
+                               status = "disabled";
+                       };
+
+                       simsspsel: simsspsel@8003c300 {
+                               reg = <0x8003c300 0x100>;
+                               status = "disabled";
+                       };
+
+                       simmemsel: simmemsel@8003c400 {
+                               reg = <0x8003c400 0x100>;
+                               status = "disabled";
+                       };
+
+                       gpiomon: gpiomon@8003c500 {
+                               reg = <0x8003c500 0x100>;
+                               status = "disabled";
+                       };
+
+                       simenet: simenet@8003c700 {
+                               reg = <0x8003c700 0x100>;
+                               status = "disabled";
+                       };
+
+                       armjtag: armjtag@8003c800 {
+                               reg = <0x8003c800 0x100>;
+                               status = "disabled";
+                       };
+               };
+
+               apbx@80040000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x80040000 0x40000>;
+                       ranges;
+
+                       clks: clkctrl@80040000 {
+                               compatible = "fsl,imx28-clkctrl", "fsl,clkctrl";
+                               reg = <0x80040000 0x2000>;
+                               #clock-cells = <1>;
+                       };
+
+                       saif0: saif@80042000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx28-saif";
+                               reg = <0x80042000 0x2000>;
+                               interrupts = <59>;
+                               #clock-cells = <0>;
+                               clocks = <&clks 53>;
+                               dmas = <&dma_apbx 4>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       power: power@80044000 {
+                               reg = <0x80044000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       saif1: saif@80046000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx28-saif";
+                               reg = <0x80046000 0x2000>;
+                               interrupts = <58>;
+                               clocks = <&clks 54>;
+                               dmas = <&dma_apbx 5>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       lradc: lradc@80050000 {
+                               compatible = "fsl,imx28-lradc";
+                               reg = <0x80050000 0x2000>;
+                               interrupts = <10 14 15 16 17 18 19
+                                               20 21 22 23 24 25>;
+                               status = "disabled";
+                               clocks = <&clks 41>;
+                               #io-channel-cells = <1>;
+                       };
+
+                       spdif: spdif@80054000 {
+                               reg = <0x80054000 0x2000>;
+                               interrupts = <45>;
+                               dmas = <&dma_apbx 2>;
+                               dma-names = "tx";
+                               status = "disabled";
+                       };
+
+                       mxs_rtc: rtc@80056000 {
+                               compatible = "fsl,imx28-rtc", "fsl,stmp3xxx-rtc";
+                               reg = <0x80056000 0x2000>;
+                               interrupts = <29>;
+                       };
+
+                       i2c0: i2c@80058000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx28-i2c";
+                               reg = <0x80058000 0x2000>;
+                               interrupts = <111>;
+                               clock-frequency = <100000>;
+                               dmas = <&dma_apbx 6>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@8005a000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx28-i2c";
+                               reg = <0x8005a000 0x2000>;
+                               interrupts = <110>;
+                               clock-frequency = <100000>;
+                               dmas = <&dma_apbx 7>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       pwm: pwm@80064000 {
+                               compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
+                               reg = <0x80064000 0x2000>;
+                               clocks = <&clks 44>;
+                               #pwm-cells = <2>;
+                               fsl,pwm-number = <8>;
+                               status = "disabled";
+                       };
+
+                       timer: timrot@80068000 {
+                               compatible = "fsl,imx28-timrot", "fsl,timrot";
+                               reg = <0x80068000 0x2000>;
+                               interrupts = <48 49 50 51>;
+                               clocks = <&clks 26>;
+                       };
+
+                       auart0: serial@8006a000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x8006a000 0x2000>;
+                               interrupts = <112>;
+                               dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+                               dma-names = "rx", "tx";
+                               clocks = <&clks 45>;
+                               status = "disabled";
+                       };
+
+                       auart1: serial@8006c000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x8006c000 0x2000>;
+                               interrupts = <113>;
+                               dmas = <&dma_apbx 10>, <&dma_apbx 11>;
+                               dma-names = "rx", "tx";
+                               clocks = <&clks 45>;
+                               status = "disabled";
+                       };
+
+                       auart2: serial@8006e000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x8006e000 0x2000>;
+                               interrupts = <114>;
+                               dmas = <&dma_apbx 12>, <&dma_apbx 13>;
+                               dma-names = "rx", "tx";
+                               clocks = <&clks 45>;
+                               status = "disabled";
+                       };
+
+                       auart3: serial@80070000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x80070000 0x2000>;
+                               interrupts = <115>;
+                               dmas = <&dma_apbx 14>, <&dma_apbx 15>;
+                               dma-names = "rx", "tx";
+                               clocks = <&clks 45>;
+                               status = "disabled";
+                       };
+
+                       auart4: serial@80072000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x80072000 0x2000>;
+                               interrupts = <116>;
+                               dmas = <&dma_apbx 0>, <&dma_apbx 1>;
+                               dma-names = "rx", "tx";
+                               clocks = <&clks 45>;
+                               status = "disabled";
+                       };
+
+                       duart: serial@80074000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x80074000 0x1000>;
+                               interrupts = <47>;
+                               clocks = <&clks 45>, <&clks 26>;
+                               clock-names = "uart", "apb_pclk";
+                               status = "disabled";
+                       };
+
+                       usbphy0: usbphy@8007c000 {
+                               compatible = "fsl,imx28-usbphy", "fsl,imx23-usbphy";
+                               reg = <0x8007c000 0x2000>;
+                               clocks = <&clks 62>;
+                               status = "disabled";
+                       };
+
+                       usbphy1: usbphy@8007e000 {
+                               compatible = "fsl,imx28-usbphy", "fsl,imx23-usbphy";
+                               reg = <0x8007e000 0x2000>;
+                               clocks = <&clks 63>;
+                               status = "disabled";
+                       };
+               };
+       };
+
+       ahb@80080000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x80080000 0x80000>;
+               ranges;
+
+               usb0: usb@80080000 {
+                       compatible = "fsl,imx28-usb", "fsl,imx27-usb";
+                       reg = <0x80080000 0x10000>;
+                       interrupts = <93>;
+                       clocks = <&clks 60>;
+                       fsl,usbphy = <&usbphy0>;
+                       status = "disabled";
+               };
+
+               usb1: usb@80090000 {
+                       compatible = "fsl,imx28-usb", "fsl,imx27-usb";
+                       reg = <0x80090000 0x10000>;
+                       interrupts = <92>;
+                       clocks = <&clks 61>;
+                       fsl,usbphy = <&usbphy1>;
+                       dr_mode = "host";
+                       status = "disabled";
+               };
+
+               dflpt: dflpt@800c0000 {
+                       reg = <0x800c0000 0x10000>;
+                       status = "disabled";
+               };
+
+               mac0: ethernet@800f0000 {
+                       compatible = "fsl,imx28-fec";
+                       reg = <0x800f0000 0x4000>;
+                       interrupts = <101>;
+                       clocks = <&clks 57>, <&clks 57>, <&clks 64>;
+                       clock-names = "ipg", "ahb", "enet_out";
+                       status = "disabled";
+               };
+
+               mac1: ethernet@800f4000 {
+                       compatible = "fsl,imx28-fec";
+                       reg = <0x800f4000 0x4000>;
+                       interrupts = <102>;
+                       clocks = <&clks 57>, <&clks 57>;
+                       clock-names = "ipg", "ahb";
+                       status = "disabled";
+               };
+
+               etn_switch: switch@800f8000 {
+                       reg = <0x800f8000 0x8000>;
+                       status = "disabled";
+               };
+       };
+
+       iio-hwmon {
+               compatible = "iio-hwmon";
+               io-channels = <&lradc 8>;
+       };
+};
index 329fa3b5e273fce316c9626e9774c900d6226671..bc4b3483a6b4b8ddd1dd587c4c9b82cbbb7e617b 100644 (file)
                        u-boot,dm-pre-reloc;
                };
        };
+
+       wdt-reboot {
+               compatible = "wdt-reboot";
+               wdt = <&wdog1>;
+       };
 };
 
 &gpio1 {
diff --git a/arch/arm/dts/imx6dl-dhcom-pdk2.dts b/arch/arm/dts/imx6dl-dhcom-pdk2.dts
new file mode 100644 (file)
index 0000000..a0b51bc
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+)
+/*
+ * Copyright (C) 2019 DH electronics GmbH
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-dhcom-pdk2.dtsi"
+
+/ {
+       model = "Freescale i.MX6 Duallite/Solo DHCOM Premium Developer Kit (2)";
+       compatible = "dh,imx6dl-dhcom-pdk2", "dh,imx6dl-dhcom", "fsl,imx6dl";
+};
index 9c61e3be2d9a37613f42efaf72cb13e982e830af..5bab2db656e352d800812f031dbb0aa1b7ad0099 100644 (file)
 // SPDX-License-Identifier: (GPL-2.0+)
 /*
- * Copyright (C) 2015 DH electronics GmbH
+ * Copyright (C) 2015-2019 DH electronics GmbH
  * Copyright (C) 2018 Marek Vasut <marex@denx.de>
  */
 
 /dts-v1/;
 
-#include "imx6q-dhcom-som.dtsi"
+#include "imx6q.dtsi"
+#include "imx6qdl-dhcom-pdk2.dtsi"
 
 / {
-       model = "Freescale i.MX6 Quad DHCOM Premium Developer Kit (2)";
-       compatible = "dh,imx6q-dhcom-pdk2", "dh,imx6q-dhcom-som", "fsl,imx6q";
-
-       chosen {
-               stdout-path = &uart1;
-       };
-
-       clk_ext_audio_codec: clock-codec {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <24000000>;
-       };
-
-       sound {
-               compatible = "fsl,imx-audio-sgtl5000";
-               model = "imx-sgtl5000";
-               ssi-controller = <&ssi1>;
-               audio-codec = <&sgtl5000>;
-               audio-routing =
-                       "MIC_IN", "Mic Jack",
-                       "Mic Jack", "Mic Bias",
-                       "LINE_IN", "Line In Jack",
-                       "Headphone Jack", "HP_OUT";
-               mux-int-port = <1>;
-               mux-ext-port = <3>;
-       };
-};
-
-&audmux {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_ext>;
-       status = "okay";
-};
-
-&hdmi {
-       ddc-i2c-bus = <&i2c2>;
-       status = "okay";
-};
-
-&i2c2 {
-       sgtl5000: codec@a {
-               compatible = "fsl,sgtl5000";
-               reg = <0x0a>;
-               #sound-dai-cells = <0>;
-               clocks = <&clk_ext_audio_codec>;
-               VDDA-supply = <&reg_3p3v>;
-               VDDIO-supply = <&reg_3p3v>;
-       };
-};
-
-&iomuxc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_hog_base &pinctrl_hog>;
-
-       pinctrl_hog: hog-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x400120b0
-                       MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x400120b0
-                       MX6QDL_PAD_GPIO_5__GPIO1_IO05           0x400120b0
-                       MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03       0x400120b0
-                       MX6QDL_PAD_GPIO_19__GPIO4_IO05          0x120b0
-                       MX6QDL_PAD_DI0_PIN4__GPIO4_IO20         0x400120b0
-                       MX6QDL_PAD_EIM_D27__GPIO3_IO27          0x120b0
-                       MX6QDL_PAD_KEY_ROW0__GPIO4_IO07         0x120b0
-                       MX6QDL_PAD_KEY_COL1__GPIO4_IO08         0x400120b0
-                       MX6QDL_PAD_NANDF_CS1__GPIO6_IO14        0x400120b0
-                       MX6QDL_PAD_NANDF_CS2__GPIO6_IO15        0x400120b0
-                       MX6QDL_PAD_KEY_ROW1__GPIO4_IO09         0x400120b0
-                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x400120b0
-                       MX6QDL_PAD_SD3_DAT4__GPIO7_IO01         0x400120b0
-                       MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21       0x400120b0
-                       MX6QDL_PAD_GPIO_18__GPIO7_IO13          0x400120b0
-                       MX6QDL_PAD_SD1_CMD__GPIO1_IO18          0x400120b0
-                       MX6QDL_PAD_SD1_DAT0__GPIO1_IO16         0x400120b0
-                       MX6QDL_PAD_SD1_DAT1__GPIO1_IO17         0x400120b0
-                       MX6QDL_PAD_SD1_DAT2__GPIO1_IO19         0x400120b0
-                       MX6QDL_PAD_SD1_CLK__GPIO1_IO20          0x400120b0
-                       MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18      0x400120b0
-                       MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19        0x400120b0
-                       MX6QDL_PAD_KEY_COL0__GPIO4_IO06         0x400120b0
-               >;
-       };
-
-       pinctrl_audmux_ext: audmux-ext-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_CSI0_DAT7__AUD3_RXD          0x130b0
-                       MX6QDL_PAD_CSI0_DAT4__AUD3_TXC          0x130b0
-                       MX6QDL_PAD_CSI0_DAT5__AUD3_TXD          0x110b0
-                       MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS         0x130b0
-               >;
-       };
-
-       pinctrl_enet_1G: enet-1G-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x100b0
-                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x100b0
-                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x100b0
-                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x100b0
-                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x100b0
-                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x100b0
-                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x100b0
-                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x100b0
-                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x100b0
-                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
-                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
-                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
-                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
-                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
-                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
-                       MX6QDL_PAD_EIM_D29__GPIO3_IO29          0x000b0
-                       MX6QDL_PAD_GPIO_0__GPIO1_IO00           0x000b1
-                       MX6QDL_PAD_EIM_D26__GPIO3_IO26          0x000b1
-               >;
-       };
-
-       pinctrl_pcie: pcie-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20     0x1b0b1
-               >;
-       };
-};
-
-&pcie {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_pcie>;
-       reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>;
-       status = "okay";
-};
-
-&ssi1 {
-       status = "okay";
+       model = "Freescale i.MX6 Quad/Dual DHCOM Premium Developer Kit (2)";
+       compatible = "dh,imx6q-dhcom-pdk2", "dh,imx6q-dhcom", "fsl,imx6q";
 };
 
 &sata {
        status = "okay";
 };
 
-&usdhc3 {
-       status = "okay";
-};
diff --git a/arch/arm/dts/imx6q-dhcom-som.dtsi b/arch/arm/dts/imx6q-dhcom-som.dtsi
deleted file mode 100644 (file)
index 524cd28..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+)
-/*
- * Copyright (C) 2015 DH electronics GmbH
- * Copyright (C) 2018 Marek Vasut <marex@denx.de>
- */
-
-#include "imx6q.dtsi"
-#include <dt-bindings/pwm/pwm.h>
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clock/imx6qdl-clock.h>
-#include <dt-bindings/input/input.h>
-
-/ {
-       aliases {
-               mmc0 = &usdhc2;
-               mmc1 = &usdhc3;
-               mmc2 = &usdhc4;
-               mmc3 = &usdhc1;
-       };
-
-       memory@10000000 {
-               device_type = "memory";
-               reg = <0x10000000 0x40000000>;
-       };
-
-       reg_usb_otg_vbus: regulator-usb-otg-vbus {
-               compatible = "regulator-fixed";
-               regulator-name = "usb_otg_vbus";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-       };
-
-       reg_usb_h1_vbus: regulator-usb-h1-vbus {
-               compatible = "regulator-fixed";
-               regulator-name = "usb_h1_vbus";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-
-       reg_3p3v: regulator-3P3V {
-               compatible = "regulator-fixed";
-               regulator-name = "3P3V";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-always-on;
-       };
-};
-
-&can1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_flexcan1>;
-       status = "okay";
-};
-
-&can2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_flexcan2>;
-       status = "okay";
-};
-
-&ecspi1 {
-       cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>, <&gpio4 11 GPIO_ACTIVE_LOW>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1>;
-       status = "okay";
-
-       flash@0 {       /* S25FL116K */
-               #address-cells = <1>;
-               #size-cells = <1>;
-               compatible = "jedec,spi-nor";
-               spi-max-frequency = <50000000>;
-               reg = <0>;
-               m25p,fast-read;
-       };
-};
-
-&ecspi2 {
-       cs-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi2>;
-       status = "okay";
-};
-
-&fec {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_100M>;
-       phy-mode = "rmii";
-       phy-handle = <&ethphy0>;
-       status = "okay";
-
-       mdio {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               ethphy0: ethernet-phy@0 {       /* SMSC LAN8710Ai */
-                       reg = <0>;
-                       max-speed = <100>;
-                       reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
-                       reset-delay-us = <1000>;
-                       reset-post-delay-us = <1000>;
-               };
-       };
-};
-
-&i2c1 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1>;
-       status = "okay";
-};
-
-&i2c2 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2>;
-       status = "okay";
-};
-
-&i2c3 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3>;
-       status = "okay";
-
-       ltc3676: pmic@3c {
-               compatible = "lltc,ltc3676";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_pmic_hw300>;
-               reg = <0x3c>;
-               interrupt-parent = <&gpio5>;
-               interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
-
-               regulators {
-                       sw1_reg: sw1 {
-                               regulator-min-microvolt = <787500>;
-                               regulator-max-microvolt = <1527272>;
-                               lltc,fb-voltage-divider = <100000 110000>;
-                               regulator-suspend-mem-microvolt = <1040000>;
-                               regulator-ramp-delay = <7000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       sw2_reg: sw2 {
-                               regulator-min-microvolt = <1885714>;
-                               regulator-max-microvolt = <3657142>;
-                               lltc,fb-voltage-divider = <100000 28000>;
-                               regulator-ramp-delay = <7000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       sw3_reg: sw3 {
-                               regulator-min-microvolt = <787500>;
-                               regulator-max-microvolt = <1527272>;
-                               lltc,fb-voltage-divider = <100000 110000>;
-                               regulator-suspend-mem-microvolt = <980000>;
-                               regulator-ramp-delay = <7000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       sw4_reg: sw4 {
-                               regulator-min-microvolt = <855571>;
-                               regulator-max-microvolt = <1659291>;
-                               lltc,fb-voltage-divider = <100000 93100>;
-                               regulator-ramp-delay = <7000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       ldo1_reg: ldo1 {
-                               regulator-min-microvolt = <3240306>;
-                               regulator-max-microvolt = <3240306>;
-                               lltc,fb-voltage-divider = <102000 29400>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       ldo2_reg: ldo2 {
-                               regulator-min-microvolt = <2484708>;
-                               regulator-max-microvolt = <2484708>;
-                               lltc,fb-voltage-divider = <100000 41200>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-               };
-       };
-
-       touchscreen@49 {        /* TSC2004 */
-               compatible = "ti,tsc2004";
-               reg = <0x49>;
-               vio-supply = <&reg_3p3v>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_tsc2004_hw300>;
-               interrupts-extended = <&gpio4 14 IRQ_TYPE_EDGE_FALLING>;
-               status = "disabled";
-       };
-
-       eeprom@50 {
-               compatible = "atmel,24c02";
-               reg = <0x50>;
-               pagesize = <16>;
-       };
-
-       rtc@56 {
-               compatible = "rv3029c2";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_rtc_hw300>;
-               reg = <0x56>;
-               interrupt-parent = <&gpio7>;
-               interrupts = <12 2>;
-       };
-};
-
-&iomuxc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_hog_base>;
-
-       pinctrl_hog_base: hog-base-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_EIM_A19__GPIO2_IO19          0x120b0
-                       MX6QDL_PAD_EIM_A23__GPIO6_IO06          0x120b0
-                       MX6QDL_PAD_EIM_A22__GPIO2_IO16          0x120b0
-                       MX6QDL_PAD_EIM_A16__GPIO2_IO22          0x120b0
-                       MX6QDL_PAD_EIM_A17__GPIO2_IO21          0x120b0
-               >;
-       };
-
-       pinctrl_ecspi1: ecspi1-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_EIM_D17__ECSPI1_MISO         0x100b1
-                       MX6QDL_PAD_EIM_D18__ECSPI1_MOSI         0x100b1
-                       MX6QDL_PAD_EIM_D16__ECSPI1_SCLK         0x100b1
-                       MX6QDL_PAD_EIM_EB2__GPIO2_IO30          0x1b0b0
-                       MX6QDL_PAD_KEY_ROW2__GPIO4_IO11         0x1b0b0
-               >;
-       };
-
-       pinctrl_ecspi2: ecspi2-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO      0x100b1
-                       MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI       0x100b1
-                       MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK       0x100b1
-                       MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29       0x1b0b0
-               >;
-       };
-
-       pinctrl_enet_100M: enet-100M-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
-                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
-                       MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN      0x1b0b0
-                       MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER       0x1b0b0
-                       MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0     0x1b0b0
-                       MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1     0x1b0b0
-                       MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN       0x1b0b0
-                       MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0     0x1b0b0
-                       MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1     0x1b0b0
-                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
-                       MX6QDL_PAD_EIM_WAIT__GPIO5_IO00         0x000b0
-                       MX6QDL_PAD_KEY_ROW4__GPIO4_IO15         0x000b1
-                       MX6QDL_PAD_GPIO_7__GPIO1_IO07           0x120b0
-               >;
-       };
-
-       pinctrl_flexcan1: flexcan1-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX        0x1b0b0
-                       MX6QDL_PAD_GPIO_8__FLEXCAN1_RX          0x1b0b0
-               >;
-       };
-
-       pinctrl_flexcan2: flexcan2-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD3_DAT0__FLEXCAN2_TX        0x1b0b0
-                       MX6QDL_PAD_SD3_DAT1__FLEXCAN2_RX        0x1b0b0
-               >;
-       };
-
-       pinctrl_i2c1: i2c1-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
-                       MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
-               >;
-       };
-
-       pinctrl_i2c2: i2c2-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
-                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
-               >;
-       };
-
-       pinctrl_i2c3: i2c3-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
-                       MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
-               >;
-       };
-
-       pinctrl_pmic_hw300: pmic-hw300-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_EIM_A25__GPIO5_IO02          0x1B0B0
-               >;
-       };
-
-       pinctrl_rtc_hw300: rtc-hw300-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_GPIO_17__GPIO7_IO12          0x120B0
-               >;
-       };
-
-       pinctrl_tsc2004_hw300: tsc2004-hw300-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_KEY_COL4__GPIO4_IO14         0x120B0
-               >;
-       };
-
-       pinctrl_uart1: uart1-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
-                       MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
-                       MX6QDL_PAD_EIM_D20__UART1_RTS_B         0x1b0b1
-                       MX6QDL_PAD_EIM_D19__UART1_CTS_B         0x4001b0b1
-                       MX6QDL_PAD_EIM_D23__GPIO3_IO23          0x4001b0b1
-                       MX6QDL_PAD_EIM_D24__GPIO3_IO24          0x4001b0b1
-                       MX6QDL_PAD_EIM_D25__GPIO3_IO25          0x4001b0b1
-                       MX6QDL_PAD_EIM_EB3__GPIO2_IO31          0x4001b0b1
-               >;
-       };
-
-       pinctrl_uart4: uart4-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA    0x1b0b1
-                       MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA    0x1b0b1
-               >;
-       };
-
-       pinctrl_uart5: uart5-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA    0x1b0b1
-                       MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA    0x1b0b1
-                       MX6QDL_PAD_CSI0_DAT18__UART5_RTS_B      0x1b0b1
-                       MX6QDL_PAD_CSI0_DAT19__UART5_CTS_B      0x4001b0b1
-               >;
-       };
-
-       pinctrl_usbh1: usbh1-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_EIM_D31__GPIO3_IO31          0x120B0
-               >;
-       };
-
-       pinctrl_usbotg: usbotg-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
-               >;
-       };
-
-       pinctrl_usdhc2: usdhc2-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD2_CMD__SD2_CMD             0x17059
-                       MX6QDL_PAD_SD2_CLK__SD2_CLK             0x10059
-                       MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x17059
-                       MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
-                       MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
-                       MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
-                       MX6QDL_PAD_NANDF_CS3__GPIO6_IO16        0x120B0
-               >;
-       };
-
-       pinctrl_usdhc3: usdhc3-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
-                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
-                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
-                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
-                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
-                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
-                       MX6QDL_PAD_SD3_RST__GPIO7_IO08          0x120B0
-               >;
-       };
-
-       pinctrl_usdhc4: usdhc4-grp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
-                       MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
-                       MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
-                       MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
-                       MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
-                       MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
-                       MX6QDL_PAD_SD4_DAT4__SD4_DATA4          0x17059
-                       MX6QDL_PAD_SD4_DAT5__SD4_DATA5          0x17059
-                       MX6QDL_PAD_SD4_DAT6__SD4_DATA6          0x17059
-                       MX6QDL_PAD_SD4_DAT7__SD4_DATA7          0x17059
-               >;
-       };
-};
-
-&reg_arm {
-       vin-supply = <&sw3_reg>;
-};
-
-&reg_soc {
-       vin-supply = <&sw1_reg>;
-};
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1>;
-       uart-has-rtscts;
-       dtr-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
-       dsr-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
-       dcd-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
-       rng-gpios = <&gpio2 31 GPIO_ACTIVE_LOW>;
-       status = "okay";
-};
-
-&uart4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart4>;
-       status = "okay";
-};
-
-&uart5 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart5>;
-       uart-has-rtscts;
-       status = "okay";
-};
-
-&usbh1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbh1>;
-       vbus-supply = <&reg_usb_h1_vbus>;
-       dr_mode = "host";
-       status = "okay";
-};
-
-&usbotg {
-       vbus-supply = <&reg_usb_otg_vbus>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg>;
-       disable-over-current;
-       dr_mode = "otg";
-       status = "okay";
-};
-
-&usdhc2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2>;
-       cd-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;
-       keep-power-in-suspend;
-       status = "okay";
-};
-
-&usdhc3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3>;
-       cd-gpios = <&gpio7 8 GPIO_ACTIVE_LOW>;
-       fsl,wp-controller;
-       keep-power-in-suspend;
-       status = "disabled";
-};
-
-&usdhc4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc4>;
-       non-removable;
-       bus-width = <8>;
-       no-1-8-v;
-       keep-power-in-suspend;
-       status = "okay";
-};
diff --git a/arch/arm/dts/imx6q-display5-u-boot.dtsi b/arch/arm/dts/imx6q-display5-u-boot.dtsi
new file mode 100644 (file)
index 0000000..b942218
--- /dev/null
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * SPDX-License-Identifier:     GPL-2.0+ or X11
+ */
+
+/*
+ * The minimal augmentation DTS U-Boot file to allow UART5
+ * configuration in the pre-relocation stage of U-Boot
+ * proper.
+ *
+ * As the same UART is already configured in SPL, we don't need
+ * setup pinmux for it again.
+ */
+
+/ {
+       aliases {
+               mmc0 = &usdhc4;
+       };
+
+       soc {
+               u-boot,dm-pre-reloc;
+
+               aips-bus@2100000 {
+                       u-boot,dm-pre-reloc;
+               };
+       };
+
+       chosen {
+               stdout-path = &uart5;
+       };
+};
+
+&i2c3 {
+       at24@50 {
+               u-boot,i2c-offset-len = <2>;
+       };
+};
+
+&uart5 {
+       u-boot,dm-pre-reloc;
+};
index 50347ff26be3b7a608ae0e8eb097bc8be11a5a03..4e2aa363edaad702f58e9b67541b79fd4e8c0d76 100644 (file)
 
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
 #include "imx6q.dtsi"
 
 / {
        model = "Liebherr (LWN) display5 i.MX6 Quad Board";
        compatible = "lwn,display5", "fsl,imx6q";
+
+       memory@10000000 {
+               device_type = "memory";
+               reg = <0x10000000 0x40000000>;
+       };
+};
+
+&ecspi2 {
+       cs-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs &pinctrl_ecspi2_flwp>;
+       status = "okay";
+
+       s25fl256s: flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               spi-max-frequency = <40000000>;
+               reg = <0>;
+
+               partition@0 {
+                       label = "SPL (spi)";
+                       reg = <0x0 0x20000>;
+                       read-only;
+               };
+               partition@1 {
+                       label = "u-boot (spi)";
+                       reg = <0x20000 0x100000>;
+                       read-only;
+               };
+               partition@2 {
+                       label = "uboot-env (spi)";
+                       reg = <0x120000 0x10000>;
+               };
+               partition@3 {
+                       label = "uboot-envr (spi)";
+                       reg = <0x130000 0x10000>;
+               };
+               partition@4 {
+                       label = "linux-recovery (spi)";
+                       reg = <0x140000 0x800000>;
+               };
+               partition@5 {
+                       label = "swupdate-fitImg (spi)";
+                       reg = <0x940000 0x400000>;
+               };
+               partition@6 {
+                       label = "swupdate-initramfs (spi)";
+                       reg = <0xD40000 0x800000>;
+               };
+       };
+};
+
+&ecspi3 {
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs &pinctrl_ecspi3_flwp>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-handle = <&ethernet_phy0>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               ethernet_phy0: ethernet-phy@0 {
+                       compatible = "marvell,88E1510";
+                       device_type = "ethernet-phy";
+                       /* Set LED0 control: */
+                       /* On - Link, Blink - Activity, Off - No Link */
+                       marvell,reg-init = <3 0x10 0 0x1011>;
+                       max-speed = <100>;
+                       reg = <0>;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       codec: tfa9879@6c {
+               #sound-dai-cells = <0>;
+               compatible = "nxp,tfa9879";
+               reg = <0x6C>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       at24@50 {
+               compatible = "atmel,24c256";
+               pagesize = <64>;
+               reg = <0x50>;
+       };
+
+       pfuze100: pmic@8 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc4>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_ecspi2: ecspi2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO      0x100b1
+                       MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI       0x100b1
+                       MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK       0x100b1
+               >;
+       };
+
+       pinctrl_ecspi2_cs: ecspi2csgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29 0x100b1
+               >;
+       };
+
+       pinctrl_ecspi2_flwp: ecspi2flwpgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0
+               >;
+       };
+
+       pinctrl_ecspi3: ecspi3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO      0x100b1
+                       MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI      0x100b1
+                       MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK      0x100b1
+               >;
+       };
+
+       pinctrl_ecspi3_cs: ecspi3csgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x1b0b0
+               >;
+       };
+
+       pinctrl_ecspi3_flwp: ecspi3flwpgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27 0x1b0b0
+               >;
+       };
+
+       pinctrl_enet: enetgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                       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
+                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+                       MX6QDL_PAD_GPIO_6__ENET_IRQ             0x000b1
+                       MX6QDL_PAD_ENET_RXD0__GPIO1_IO27        0x1b0b0
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D21__I2C1_SCL    0x4001b8b1
+                       MX6QDL_PAD_EIM_D28__I2C1_SDA    0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_EB2__I2C2_SCL    0x4001b8b1
+                       MX6QDL_PAD_EIM_D16__I2C2_SDA    0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D17__I2C3_SCL    0x4001b8b1
+                       MX6QDL_PAD_EIM_D18__I2C3_SDA    0x4001b8b1
+               >;
+       };
+
+       pinctrl_uart4: uart4grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B      0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA    0x1b0b1
+               >;
+       };
+
+       pinctrl_usdhc4: usdhc4grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
+                       MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
+                       MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
+                       MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
+                       MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
+                       MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
+                       MX6QDL_PAD_SD4_DAT4__SD4_DATA4          0x17059
+                       MX6QDL_PAD_SD4_DAT5__SD4_DATA5          0x17059
+                       MX6QDL_PAD_SD4_DAT6__SD4_DATA6          0x17059
+                       MX6QDL_PAD_SD4_DAT7__SD4_DATA7          0x17059
+                       MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x17059
+               >;
+       };
 };
diff --git a/arch/arm/dts/imx6qdl-dhcom-pdk2.dtsi b/arch/arm/dts/imx6qdl-dhcom-pdk2.dtsi
new file mode 100644 (file)
index 0000000..af4719a
--- /dev/null
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: (GPL-2.0+)
+/*
+ * Copyright (C) 2015-2019 DH electronics GmbH
+ * Copyright (C) 2018 Marek Vasut <marex@denx.de>
+ */
+
+#include "imx6qdl-dhcom.dtsi"
+
+/ {
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       clk_ext_audio_codec: clock-codec {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24000000>;
+       };
+
+       sound {
+               compatible = "fsl,imx-audio-sgtl5000";
+               model = "imx-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&sgtl5000>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "LINE_IN", "Line In Jack",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <3>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux_ext>;
+       status = "okay";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c2>;
+       status = "okay";
+};
+
+&i2c2 {
+       sgtl5000: codec@a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               #sound-dai-cells = <0>;
+               clocks = <&clk_ext_audio_codec>;
+               VDDA-supply = <&reg_3p3v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog_base &pinctrl_hog>;
+
+       pinctrl_hog: hog-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x400120b0
+                       MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x400120b0
+                       MX6QDL_PAD_GPIO_5__GPIO1_IO05           0x400120b0
+                       MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03       0x400120b0
+                       MX6QDL_PAD_GPIO_19__GPIO4_IO05          0x120b0
+                       MX6QDL_PAD_DI0_PIN4__GPIO4_IO20         0x400120b0
+                       MX6QDL_PAD_EIM_D27__GPIO3_IO27          0x120b0
+                       MX6QDL_PAD_KEY_ROW0__GPIO4_IO07         0x120b0
+                       MX6QDL_PAD_KEY_COL1__GPIO4_IO08         0x400120b0
+                       MX6QDL_PAD_NANDF_CS1__GPIO6_IO14        0x400120b0
+                       MX6QDL_PAD_NANDF_CS2__GPIO6_IO15        0x400120b0
+                       MX6QDL_PAD_KEY_ROW1__GPIO4_IO09         0x400120b0
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x400120b0
+                       MX6QDL_PAD_SD3_DAT4__GPIO7_IO01         0x400120b0
+                       MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21       0x400120b0
+                       MX6QDL_PAD_GPIO_18__GPIO7_IO13          0x400120b0
+                       MX6QDL_PAD_SD1_CMD__GPIO1_IO18          0x400120b0
+                       MX6QDL_PAD_SD1_DAT0__GPIO1_IO16         0x400120b0
+                       MX6QDL_PAD_SD1_DAT1__GPIO1_IO17         0x400120b0
+                       MX6QDL_PAD_SD1_DAT2__GPIO1_IO19         0x400120b0
+                       MX6QDL_PAD_SD1_CLK__GPIO1_IO20          0x400120b0
+                       MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18      0x400120b0
+                       MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19        0x400120b0
+                       MX6QDL_PAD_KEY_COL0__GPIO4_IO06         0x400120b0
+               >;
+       };
+
+       pinctrl_audmux_ext: audmux-ext-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT7__AUD3_RXD          0x130b0
+                       MX6QDL_PAD_CSI0_DAT4__AUD3_TXC          0x130b0
+                       MX6QDL_PAD_CSI0_DAT5__AUD3_TXD          0x110b0
+                       MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS         0x130b0
+               >;
+       };
+
+       pinctrl_enet_1G: enet-1G-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x100b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x100b0
+                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x100b0
+                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x100b0
+                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x100b0
+                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x100b0
+                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x100b0
+                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x100b0
+                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x100b0
+                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                       MX6QDL_PAD_EIM_D29__GPIO3_IO29          0x000b0
+                       MX6QDL_PAD_GPIO_0__GPIO1_IO00           0x000b1
+                       MX6QDL_PAD_EIM_D26__GPIO3_IO26          0x000b1
+               >;
+       };
+
+       pinctrl_pcie: pcie-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20     0x1b0b1
+               >;
+       };
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pcie>;
+       reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&ssi1 {
+       status = "okay";
+};
+
+&usdhc3 {
+       status = "okay";
+};
diff --git a/arch/arm/dts/imx6qdl-dhcom.dtsi b/arch/arm/dts/imx6qdl-dhcom.dtsi
new file mode 100644 (file)
index 0000000..1141b6a
--- /dev/null
@@ -0,0 +1,476 @@
+// SPDX-License-Identifier: (GPL-2.0+)
+/*
+ * Copyright (C) 2015-2019 DH electronics GmbH
+ * Copyright (C) 2018 Marek Vasut <marex@denx.de>
+ */
+
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/imx6qdl-clock.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+       aliases {
+               mmc0 = &usdhc2;
+               mmc1 = &usdhc3;
+               mmc2 = &usdhc4;
+               mmc3 = &usdhc1;
+       };
+
+       memory@10000000 {
+               device_type = "memory";
+               reg = <0x10000000 0x40000000>;
+       };
+
+       reg_usb_otg_vbus: regulator-usb-otg-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       reg_usb_h1_vbus: regulator-usb-h1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_h1_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_3p3v: regulator-3P3V {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "okay";
+};
+
+&can2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan2>;
+       status = "okay";
+};
+
+&ecspi1 {
+       cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>, <&gpio4 11 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       status = "okay";
+
+       flash@0 {       /* S25FL116K */
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               spi-max-frequency = <50000000>;
+               reg = <0>;
+               m25p,fast-read;
+       };
+};
+
+&ecspi2 {
+       cs-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi2>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet_100M>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy0>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {       /* SMSC LAN8710Ai */
+                       reg = <0>;
+                       max-speed = <100>;
+                       reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+                       reset-delay-us = <1000>;
+                       reset-post-delay-us = <1000>;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       ltc3676: pmic@3c {
+               compatible = "lltc,ltc3676";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pmic_hw300>;
+               reg = <0x3c>;
+               interrupt-parent = <&gpio5>;
+               interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+
+               regulators {
+                       sw1_reg: sw1 {
+                               regulator-min-microvolt = <787500>;
+                               regulator-max-microvolt = <1527272>;
+                               lltc,fb-voltage-divider = <100000 110000>;
+                               regulator-suspend-mem-microvolt = <1040000>;
+                               regulator-ramp-delay = <7000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <1885714>;
+                               regulator-max-microvolt = <3657142>;
+                               lltc,fb-voltage-divider = <100000 28000>;
+                               regulator-ramp-delay = <7000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3_reg: sw3 {
+                               regulator-min-microvolt = <787500>;
+                               regulator-max-microvolt = <1527272>;
+                               lltc,fb-voltage-divider = <100000 110000>;
+                               regulator-suspend-mem-microvolt = <980000>;
+                               regulator-ramp-delay = <7000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <855571>;
+                               regulator-max-microvolt = <1659291>;
+                               lltc,fb-voltage-divider = <100000 93100>;
+                               regulator-ramp-delay = <7000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo1_reg: ldo1 {
+                               regulator-min-microvolt = <3240306>;
+                               regulator-max-microvolt = <3240306>;
+                               lltc,fb-voltage-divider = <102000 29400>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2_reg: ldo2 {
+                               regulator-min-microvolt = <2484708>;
+                               regulator-max-microvolt = <2484708>;
+                               lltc,fb-voltage-divider = <100000 41200>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+               };
+       };
+
+       touchscreen@49 {        /* TSC2004 */
+               compatible = "ti,tsc2004";
+               reg = <0x49>;
+               vio-supply = <&reg_3p3v>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_tsc2004_hw300>;
+               interrupts-extended = <&gpio4 14 IRQ_TYPE_EDGE_FALLING>;
+               status = "disabled";
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       rtc@56 {
+               compatible = "rv3029c2";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_rtc_hw300>;
+               reg = <0x56>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <12 2>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog_base>;
+
+       pinctrl_hog_base: hog-base-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_A19__GPIO2_IO19          0x120b0
+                       MX6QDL_PAD_EIM_A23__GPIO6_IO06          0x120b0
+                       MX6QDL_PAD_EIM_A22__GPIO2_IO16          0x120b0
+                       MX6QDL_PAD_EIM_A16__GPIO2_IO22          0x120b0
+                       MX6QDL_PAD_EIM_A17__GPIO2_IO21          0x120b0
+               >;
+       };
+
+       pinctrl_ecspi1: ecspi1-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D17__ECSPI1_MISO         0x100b1
+                       MX6QDL_PAD_EIM_D18__ECSPI1_MOSI         0x100b1
+                       MX6QDL_PAD_EIM_D16__ECSPI1_SCLK         0x100b1
+                       MX6QDL_PAD_EIM_EB2__GPIO2_IO30          0x1b0b0
+                       MX6QDL_PAD_KEY_ROW2__GPIO4_IO11         0x1b0b0
+               >;
+       };
+
+       pinctrl_ecspi2: ecspi2-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO      0x100b1
+                       MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI       0x100b1
+                       MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK       0x100b1
+                       MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29       0x1b0b0
+               >;
+       };
+
+       pinctrl_enet_100M: enet-100M-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                       MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN      0x1b0b0
+                       MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER       0x1b0b0
+                       MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0     0x1b0b0
+                       MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1     0x1b0b0
+                       MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN       0x1b0b0
+                       MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0     0x1b0b0
+                       MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1     0x1b0b0
+                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       MX6QDL_PAD_EIM_WAIT__GPIO5_IO00         0x000b0
+                       MX6QDL_PAD_KEY_ROW4__GPIO4_IO15         0x000b1
+                       MX6QDL_PAD_GPIO_7__GPIO1_IO07           0x120b0
+               >;
+       };
+
+       pinctrl_flexcan1: flexcan1-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX        0x1b0b0
+                       MX6QDL_PAD_GPIO_8__FLEXCAN1_RX          0x1b0b0
+               >;
+       };
+
+       pinctrl_flexcan2: flexcan2-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_DAT0__FLEXCAN2_TX        0x1b0b0
+                       MX6QDL_PAD_SD3_DAT1__FLEXCAN2_RX        0x1b0b0
+               >;
+       };
+
+       pinctrl_i2c1: i2c1-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                       MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c2: i2c2-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c3: i2c3-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                       MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+               >;
+       };
+
+       pinctrl_pmic_hw300: pmic-hw300-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_A25__GPIO5_IO02          0x1B0B0
+               >;
+       };
+
+       pinctrl_rtc_hw300: rtc-hw300-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_17__GPIO7_IO12          0x120B0
+               >;
+       };
+
+       pinctrl_tsc2004_hw300: tsc2004-hw300-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL4__GPIO4_IO14         0x120B0
+               >;
+       };
+
+       pinctrl_uart1: uart1-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       MX6QDL_PAD_EIM_D20__UART1_RTS_B         0x1b0b1
+                       MX6QDL_PAD_EIM_D19__UART1_CTS_B         0x4001b0b1
+                       MX6QDL_PAD_EIM_D23__GPIO3_IO23          0x4001b0b1
+                       MX6QDL_PAD_EIM_D24__GPIO3_IO24          0x4001b0b1
+                       MX6QDL_PAD_EIM_D25__GPIO3_IO25          0x4001b0b1
+                       MX6QDL_PAD_EIM_EB3__GPIO2_IO31          0x4001b0b1
+               >;
+       };
+
+       pinctrl_uart4: uart4-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT18__UART5_RTS_B      0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT19__UART5_CTS_B      0x4001b0b1
+               >;
+       };
+
+       pinctrl_usbh1: usbh1-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D31__GPIO3_IO31          0x120B0
+               >;
+       };
+
+       pinctrl_usbotg: usbotg-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD2_CMD__SD2_CMD             0x17059
+                       MX6QDL_PAD_SD2_CLK__SD2_CLK             0x10059
+                       MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x17059
+                       MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
+                       MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
+                       MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
+                       MX6QDL_PAD_NANDF_CS3__GPIO6_IO16        0x120B0
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       MX6QDL_PAD_SD3_RST__GPIO7_IO08          0x120B0
+               >;
+       };
+
+       pinctrl_usdhc4: usdhc4-grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
+                       MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
+                       MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
+                       MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
+                       MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
+                       MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
+                       MX6QDL_PAD_SD4_DAT4__SD4_DATA4          0x17059
+                       MX6QDL_PAD_SD4_DAT5__SD4_DATA5          0x17059
+                       MX6QDL_PAD_SD4_DAT6__SD4_DATA6          0x17059
+                       MX6QDL_PAD_SD4_DAT7__SD4_DATA7          0x17059
+               >;
+       };
+};
+
+&reg_arm {
+       vin-supply = <&sw3_reg>;
+};
+
+&reg_soc {
+       vin-supply = <&sw1_reg>;
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       uart-has-rtscts;
+       dtr-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
+       dsr-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+       dcd-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+       rng-gpios = <&gpio2 31 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&usbh1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbh1>;
+       vbus-supply = <&reg_usb_h1_vbus>;
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       cd-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;
+       keep-power-in-suspend;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 8 GPIO_ACTIVE_LOW>;
+       fsl,wp-controller;
+       keep-power-in-suspend;
+       status = "disabled";
+};
+
+&usdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc4>;
+       non-removable;
+       bus-width = <8>;
+       no-1-8-v;
+       keep-power-in-suspend;
+       status = "okay";
+};
index 9f1fe683db3a506f43ceb121ac4570f9063338ca..7cd8be24c874f5b48b7815c6e9d7c1031d0ea2a0 100644 (file)
@@ -10,6 +10,7 @@
 / {
        aliases {
                mmc0 = &usdhc3;
+               usb0 = &usbotg1;
        };
 
        /* Will be filled by the bootloader */
 
 &usbotg1 {
        vbus-supply = <&reg_usb_otg1_vbus>;
+       dr_mode = "peripheral";
        status = "okay";
 };
 
diff --git a/arch/arm/dts/mxs-pinfunc.h b/arch/arm/dts/mxs-pinfunc.h
new file mode 100644 (file)
index 0000000..c6da987
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Header providing constants for i.MX28 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * 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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MXS_PINCTRL_H__
+#define __DT_BINDINGS_MXS_PINCTRL_H__
+
+/* fsl,drive-strength property */
+#define MXS_DRIVE_4mA          0
+#define MXS_DRIVE_8mA          1
+#define MXS_DRIVE_12mA         2
+#define MXS_DRIVE_16mA         3
+
+/* fsl,voltage property */
+#define MXS_VOLTAGE_LOW                0
+#define MXS_VOLTAGE_HIGH       1
+
+/* fsl,pull-up property */
+#define MXS_PULL_DISABLE       0
+#define MXS_PULL_ENABLE                1
+
+#endif /* __DT_BINDINGS_MXS_PINCTRL_H__ */
index 97377697f097fdfc0d54b424cddd387e3117f995..901b90d705f08d453e9738c934fbd7902e5b85a6 100644 (file)
@@ -72,6 +72,8 @@ void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev);
 void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
 void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit);
 int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val);
+int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
+                    s16 *celsius, s8 *tenths);
 
 /* RM API */
 sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr);
index 5d17b553d7f6050275cd64e4444133140d69e23c..3629eb68d7ab78ac3936939358b8a6f4fc98c2e2 100644 (file)
@@ -26,5 +26,6 @@
 #define SC_MISC_REL_CONTAINER  2U      /* Release container */
 
 typedef u8 sc_misc_boot_status_t;
+typedef u8 sc_misc_temp_t;
 
 #endif /* SC_MISC_API_H */
index 73ffaba7d55bd03f7a2b3b850faa3da15b6cca64..b8d2a0b8f0c3bb4edcd263b90fd6b64f80d280a6 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright 2018 NXP
  */
 
+#include <asm/arch/sci/sci.h>
 #include <asm/mach-imx/sys_proto.h>
 #include <linux/types.h>
 
@@ -15,5 +16,7 @@ struct pass_over_info_t {
        u32 g_ap_mu;
 };
 
+void build_info(void);
 enum boot_device get_boot_device(void);
 int print_bootinfo(void);
+int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate);
diff --git a/arch/arm/include/asm/mach-imx/imx-nandbcb.h b/arch/arm/include/asm/mach-imx/imx-nandbcb.h
new file mode 100644 (file)
index 0000000..033659a
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2017 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _IMX_NAND_BCB_H_
+#define _IMX_NAND_BCB_H_
+
+#define FCB_FINGERPRINT                0x20424346      /* 'FCB' */
+#define FCB_VERSION_1          0x01000000
+
+#define DBBT_FINGERPRINT2      0x54424244      /* 'DBBT' */
+#define DBBT_VERSION_1         0x01000000
+
+struct dbbt_block {
+       u32 checksum;   /* reserved on i.MX6 */
+       u32 fingerprint;
+       u32 version;
+       u32 numberbb;   /* reserved on i.MX6 */
+       u32 dbbtpages;
+};
+
+struct fcb_block {
+       u32 checksum;           /* First fingerprint in first byte */
+       u32 fingerprint;        /* 2nd fingerprint at byte 4 */
+       u32 version;            /* 3rd fingerprint at byte 8 */
+       u8 datasetup;
+       u8 datahold;
+       u8 addr_setup;
+       u8 dsample_time;
+
+       /* These are for application use only and not for ROM. */
+       u8 nandtiming;
+       u8 rea;
+       u8 rloh;
+       u8 rhoh;
+       u32 pagesize;           /* 2048 for 2K pages, 4096 for 4K pages */
+       u32 oob_pagesize;       /* 2112 for 2K pages, 4314 for 4K pages */
+       u32 sectors;            /* Number of 2K sections per block */
+       u32 nr_nand;            /* Total Number of NANDs - not used by ROM */
+       u32 nr_die;             /* Number of separate chips in this NAND */
+       u32 celltype;           /* MLC or SLC */
+       u32 ecc_type;           /* Type of ECC, can be one of BCH-0-20 */
+       u32 ecc_nr;             /* Number of bytes for Block0 - BCH */
+
+       /* Block size in bytes for all blocks other than Block0 - BCH */
+       u32 ecc_size;
+       u32 ecc_level;          /* Ecc level for Block 0 - BCH */
+       u32 meta_size;          /* Metadata size - BCH */
+       /* Number of blocks per page for ROM use - BCH */
+       u32 nr_blocks;
+       u32 ecc_type_sdk;       /* Type of ECC, can be one of BCH-0-20 */
+       u32 ecc_nr_sdk;         /* Number of bytes for Block0 - BCH */
+       /* Block size in bytes for all blocks other than Block0 - BCH */
+       u32 ecc_size_sdk;
+       u32 ecc_level_sdk;      /* Ecc level for Block 0 - BCH */
+       /* Number of blocks per page for SDK use - BCH */
+       u32 nr_blocks_sdk;
+       u32 meta_size_sdk;      /* Metadata size - BCH */
+       u32 erase_th;           /* To set into BCH_MODE register */
+
+       /*
+        * 0: normal boot
+        * 1: to load patch starting next to FCB
+        */
+       u32 bootpatch;
+       u32 patch_size; /* Size of patch in sectors */
+       u32 fw1_start;  /* Firmware image starts on this sector */
+       u32 fw2_start;  /* Secondary FW Image starting Sector */
+       u32 fw1_pages;  /* Number of sectors in firmware image */
+       u32 fw2_pages;  /* Number of sector in secondary FW image */
+       u32 dbbt_start; /* Page address where dbbt search area begins */
+
+       /*
+        * Byte in page data that have manufacturer marked bad block marker,
+        * this will be swapped with metadata[0] to complete page data.
+        */
+       u32 bb_byte;
+
+       /*
+        * For BCH ECC sizes other than 8 and 16 the bad block marker does not
+        * start at 0th bit of bb_byte. This field is used to get to
+        * the start bit of bad block marker byte with in bb_byte
+        */
+       u32 bb_start_bit;
+
+       /*
+        * FCB value that gives byte offset for
+        * bad block marker on physical NAND page
+        */
+       u32 phy_offset;
+       u32 bchtype;
+
+       u32 readlatency;
+       u32 predelay;
+       u32 cedelay;
+       u32 postdelay;
+       u32 cmdaddpause;
+       u32 datapause;
+       u32 tmspeed;
+       u32 busytimeout;
+
+       /* the flag to enable (1)/disable(0) bi swap */
+       u32 disbbm;
+
+       /* The swap position of main area in spare area */
+       u32 spare_offset;
+};
+
+#endif /* _IMX_NAND_BCB_H_ */
index b6fd1595f0463db4ff36cebdec166bf069bfec5d..aeb54934888d65de6538aa98e6a0c8ce9df7ec75 100644 (file)
@@ -71,6 +71,17 @@ config CMD_HDMIDETECT
          This enables the 'hdmidet' command which detects if an HDMI monitor
          is connected.
 
+config CMD_NANDBCB
+       bool "i.MX6 NAND Boot Control Block(BCB) command"
+       depends on NAND && CMD_MTDPARTS
+       default y if ARCH_MX6 && NAND_MXS
+       help
+         Unlike normal 'nand write/erase' commands, this command update
+         Boot Control Block(BCB) for i.MX6 platform NAND IP's.
+
+         This is similar to kobs-ng, which is used in Linux as separate
+         rootfs package.
+
 config NXP_BOARD_REVISION
        bool "Read NXP board revision from fuses"
        depends on ARCH_MX6 || ARCH_MX7
index 898478fc4a40e8156155748daf210d2bf8a70f9c..08ee52edbffdc3faffa5b7c32a4dde55f48825b3 100644 (file)
@@ -59,6 +59,7 @@ ifneq ($(CONFIG_SPL_BUILD),y)
 obj-$(CONFIG_CMD_BMODE) += cmd_bmode.o
 obj-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o
 obj-$(CONFIG_CMD_DEKBLOB) += cmd_dek.o
+obj-$(CONFIG_CMD_NANDBCB) += cmd_nandbcb.o
 endif
 
 PLUGIN = board/$(BOARDDIR)/plugin
diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c
new file mode 100644 (file)
index 0000000..065b814
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * i.MX6 nand boot control block(bcb).
+ *
+ * Based on the common/imx-bbu-nand-fcb.c from barebox and imx kobs-ng
+ *
+ * Copyright (C) 2017 Jagan Teki <jagan@amarulasolutions.com>
+ * Copyright (C) 2016 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <nand.h>
+
+#include <asm/io.h>
+#include <jffs2/jffs2.h>
+#include <linux/mtd/mtd.h>
+
+#include <asm/mach-imx/imx-nandbcb.h>
+#include <asm/mach-imx/imximage.cfg>
+#include <mxs_nand.h>
+#include <linux/mtd/mtd.h>
+#include <nand.h>
+
+#define BF_VAL(v, bf)          (((v) & bf##_MASK) >> bf##_OFFSET)
+#define GETBIT(v, n)           (((v) >> (n)) & 0x1)
+
+static u8 calculate_parity_13_8(u8 d)
+{
+       u8 p = 0;
+
+       p |= (GETBIT(d, 6) ^ GETBIT(d, 5) ^ GETBIT(d, 3) ^ GETBIT(d, 2)) << 0;
+       p |= (GETBIT(d, 7) ^ GETBIT(d, 5) ^ GETBIT(d, 4) ^ GETBIT(d, 2) ^
+             GETBIT(d, 1)) << 1;
+       p |= (GETBIT(d, 7) ^ GETBIT(d, 6) ^ GETBIT(d, 5) ^ GETBIT(d, 1) ^
+             GETBIT(d, 0)) << 2;
+       p |= (GETBIT(d, 7) ^ GETBIT(d, 4) ^ GETBIT(d, 3) ^ GETBIT(d, 0)) << 3;
+       p |= (GETBIT(d, 6) ^ GETBIT(d, 4) ^ GETBIT(d, 3) ^ GETBIT(d, 2) ^
+             GETBIT(d, 1) ^ GETBIT(d, 0)) << 4;
+
+       return p;
+}
+
+static void encode_hamming_13_8(void *_src, void *_ecc, size_t size)
+{
+       int i;
+       u8 *src = _src;
+       u8 *ecc = _ecc;
+
+       for (i = 0; i < size; i++)
+               ecc[i] = calculate_parity_13_8(src[i]);
+}
+
+static u32 calc_chksum(void *buf, size_t size)
+{
+       u32 chksum = 0;
+       u8 *bp = buf;
+       size_t i;
+
+       for (i = 0; i < size; i++)
+               chksum += bp[i];
+
+       return ~chksum;
+}
+
+static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd)
+{
+       struct nand_chip *chip = mtd_to_nand(mtd);
+       struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
+
+       fcb->fingerprint = FCB_FINGERPRINT;
+       fcb->version = FCB_VERSION_1;
+       fcb->pagesize = mtd->writesize;
+       fcb->oob_pagesize = mtd->writesize + mtd->oobsize;
+       fcb->sectors = mtd->erasesize / mtd->writesize;
+
+       /* Divide ECC strength by two and save the value into FCB structure. */
+       fcb->ecc_level = nand_info->bch_geometry.ecc_strength >> 1;
+
+       fcb->ecc_type = fcb->ecc_level;
+
+       /* Also hardcoded in kobs-ng */
+       fcb->ecc_nr = 0x00000200;
+       fcb->ecc_size = 0x00000200;
+       fcb->datasetup = 80;
+       fcb->datahold = 60;
+       fcb->addr_setup = 25;
+       fcb->dsample_time = 6;
+       fcb->meta_size = 10;
+
+       /* DBBT search area starts at second page on first block */
+       fcb->dbbt_start = 1;
+
+       fcb->bb_byte = nand_info->bch_geometry.block_mark_byte_offset;
+       fcb->bb_start_bit = nand_info->bch_geometry.block_mark_bit_offset;
+
+       fcb->phy_offset = mtd->writesize;
+
+       fcb->nr_blocks = mtd->writesize / fcb->ecc_nr - 1;
+
+       fcb->checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4);
+}
+
+static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks)
+{
+       int n, n_bad_blocks = 0;
+       u32 *bb = buf + 0x8;
+       u32 *n_bad_blocksp = buf + 0x4;
+
+       for (n = 0; n < num_blocks; n++) {
+               loff_t offset = n * mtd->erasesize;
+                       if (mtd_block_isbad(mtd, offset)) {
+                               n_bad_blocks++;
+                               *bb = n;
+                               bb++;
+               }
+       }
+
+       *n_bad_blocksp = n_bad_blocks;
+
+       return n_bad_blocks;
+}
+
+static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
+                         size_t maxsize, const u_char *buf)
+{
+       nand_erase_options_t opts;
+       struct fcb_block *fcb;
+       struct dbbt_block *dbbt;
+       loff_t fw1_off;
+       void *fwbuf, *fcb_raw_page, *dbbt_page, *dbbt_data_page;
+       int nr_blks, nr_blks_fcb, fw1_blk;
+       size_t fwsize, dummy;
+       int i, ret;
+
+       /* erase */
+       memset(&opts, 0, sizeof(opts));
+       opts.offset = off;
+       opts.length = maxsize - 1;
+       ret = nand_erase_opts(mtd, &opts);
+       if (ret) {
+               printf("%s: erase failed (ret = %d)\n", __func__, ret);
+               return ret;
+       }
+
+       /*
+        * Reference documentation from i.MX6DQRM section 8.5.2.2
+        *
+        * Nand Boot Control Block(BCB) contains two data structures,
+        * - Firmware Configuration Block(FCB)
+        * - Discovered Bad Block Table(DBBT)
+        *
+        * FCB contains,
+        * - nand timings
+        * - DBBT search page address,
+        * - start page address of primary firmware
+        * - start page address of secondary firmware
+        *
+        * setup fcb:
+        * - number of blocks = mtd partition size / mtd erasesize
+        * - two firmware blocks, primary and secondary
+        * - first 4 block for FCB/DBBT
+        * - rest split in half for primary and secondary firmware
+        * - same firmware will write two times
+        */
+       nr_blks_fcb = 2;
+       nr_blks = maxsize / mtd->erasesize;
+       fw1_blk = nr_blks_fcb;
+
+       /* write fw */
+       fwsize = ALIGN(size + FLASH_OFFSET_STANDARD + mtd->writesize,
+                      mtd->writesize);
+       fwbuf = kzalloc(fwsize, GFP_KERNEL);
+       if (!fwbuf) {
+               debug("failed to allocate fwbuf\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, size);
+       fw1_off = fw1_blk * mtd->erasesize;
+       ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize,
+                                 (u_char *)fwbuf, WITH_WR_VERIFY);
+       printf("NAND fw write: 0x%llx offset, 0x%x bytes written: %s\n",
+              fw1_off, fwsize, ret ? "ERROR" : "OK");
+       if (ret)
+               goto fwbuf_err;
+
+       /* fill fcb */
+       fcb = kzalloc(sizeof(*fcb), GFP_KERNEL);
+       if (!fcb) {
+               debug("failed to allocate fcb\n");
+               ret = -ENOMEM;
+               goto fwbuf_err;
+       }
+
+       fcb->fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize;
+       fcb->fw1_pages = size / mtd->writesize + 1;
+       fill_fcb(fcb, mtd);
+
+       /* fill dbbt */
+       dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL);
+       if (!dbbt_page) {
+               debug("failed to allocate dbbt_page\n");
+               ret = -ENOMEM;
+               goto fcb_err;
+       }
+
+       dbbt_data_page = kzalloc(mtd->writesize, GFP_KERNEL);
+       if (!dbbt_data_page) {
+               debug("failed to allocate dbbt_data_page\n");
+               ret = -ENOMEM;
+               goto dbbt_page_err;
+       }
+
+       dbbt = dbbt_page;
+       dbbt->checksum = 0;
+       dbbt->fingerprint = DBBT_FINGERPRINT2;
+       dbbt->version = DBBT_VERSION_1;
+       ret = dbbt_fill_data(mtd, dbbt_data_page, nr_blks);
+       if (ret < 0)
+               goto dbbt_data_page_err;
+       else if (ret > 0)
+               dbbt->dbbtpages = 1;
+
+       /* write fcb/dbbt */
+       fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
+       if (!fcb_raw_page) {
+               debug("failed to allocate fcb_raw_page\n");
+               ret = -ENOMEM;
+               goto dbbt_data_page_err;
+       }
+
+       memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block));
+       encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + 12 + 512, 512);
+       /*
+        * Set the first and second byte of OOB data to 0xFF, not 0x00. These
+        * bytes are used as the Manufacturers Bad Block Marker (MBBM). Since
+        * the FCB is mostly written to the first page in a block, a scan for
+        * factory bad blocks will detect these blocks as bad, e.g. when
+        * function nand_scan_bbt() is executed to build a new bad block table.
+        */
+       memset(fcb_raw_page + mtd->writesize, 0xFF, 2);
+
+       for (i = 0; i < nr_blks_fcb; i++) {
+               if (mtd_block_isbad(mtd, off)) {
+                       printf("Block %d is bad, skipped\n", i);
+                       continue;
+               }
+
+               /* raw write */
+               mtd_oob_ops_t ops = {
+                       .datbuf = (u8 *)fcb_raw_page,
+                       .oobbuf = ((u8 *)fcb_raw_page) + mtd->writesize,
+                       .len = mtd->writesize,
+                       .ooblen = mtd->oobsize,
+                       .mode = MTD_OPS_RAW
+               };
+
+               ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops);
+               if (ret)
+                       goto fcb_raw_page_err;
+               debug("NAND fcb write: 0x%x offset, 0x%x bytes written: %s\n",
+                     mtd->erasesize * i, ops.len, ret ? "ERROR" : "OK");
+
+               ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize,
+                               mtd->writesize, &dummy, dbbt_page);
+               if (ret)
+                       goto fcb_raw_page_err;
+               debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n",
+                     mtd->erasesize * i + mtd->writesize, dummy,
+                     ret ? "ERROR" : "OK");
+
+               /* dbbtpages == 0 if no bad blocks */
+               if (dbbt->dbbtpages > 0) {
+                       loff_t to = (mtd->erasesize * i + mtd->writesize * 5);
+
+                       ret = mtd_write(mtd, to, mtd->writesize, &dummy,
+                                       dbbt_data_page);
+                       if (ret)
+                               goto fcb_raw_page_err;
+               }
+       }
+
+fcb_raw_page_err:
+       kfree(fcb_raw_page);
+dbbt_data_page_err:
+       kfree(dbbt_data_page);
+dbbt_page_err:
+       kfree(dbbt_page);
+fcb_err:
+       kfree(fcb);
+fwbuf_err:
+       kfree(fwbuf);
+err:
+       return ret;
+}
+
+static int do_nandbcb_update(int argc, char * const argv[])
+{
+       struct mtd_info *mtd;
+       loff_t addr, offset, size, maxsize;
+       char *endp;
+       u_char *buf;
+       int dev;
+       int ret;
+
+       if (argc != 4)
+               return CMD_RET_USAGE;
+
+       dev = nand_curr_device;
+       if (dev < 0) {
+               printf("failed to get nand_curr_device, run nand device");
+               return CMD_RET_FAILURE;
+       }
+
+       addr = simple_strtoul(argv[1], &endp, 16);
+       if (*argv[1] == 0 || *endp != 0)
+               return CMD_RET_FAILURE;
+
+       mtd = get_nand_dev_by_index(dev);
+       if (mtd_arg_off_size(argc - 2, argv + 2, &dev, &offset, &size,
+                            &maxsize, MTD_DEV_TYPE_NAND, mtd->size))
+               return CMD_RET_FAILURE;
+
+       buf = map_physmem(addr, size, MAP_WRBACK);
+       if (!buf) {
+               puts("failed to map physical memory\n");
+               return CMD_RET_FAILURE;
+       }
+
+       ret = nandbcb_update(mtd, offset, size, maxsize, buf);
+
+       return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+}
+
+static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc,
+                     char * const argv[])
+{
+       const char *cmd;
+       int ret = 0;
+
+       if (argc < 5)
+               goto usage;
+
+       cmd = argv[1];
+       --argc;
+       ++argv;
+
+       if (strcmp(cmd, "update") == 0) {
+               ret = do_nandbcb_update(argc, argv);
+               goto done;
+       }
+
+done:
+       if (ret != -1)
+               return ret;
+usage:
+       return CMD_RET_USAGE;
+}
+
+static char nandbcb_help_text[] =
+       "update addr off|partition len  - update 'len' bytes starting at\n"
+       "       'off|part' to memory address 'addr', skipping  bad blocks";
+
+U_BOOT_CMD(nandbcb, 5, 1, do_nandbcb,
+          "i.MX6 Nand BCB",
+          nandbcb_help_text
+);
index 3a8cf30c0655819fed421ab29f2fd015480dda1d..6e9a17521097744abe3666c62a716cb0d4178e2c 100644 (file)
@@ -289,10 +289,12 @@ void arch_preboot_os(void)
        imx_pcie_remove();
 #endif
 #if defined(CONFIG_SATA)
-       sata_remove(0);
+       if (!is_mx6sdl()) {
+               sata_remove(0);
 #if defined(CONFIG_MX6)
-       disable_sata_clock();
+               disable_sata_clock();
 #endif
+       }
 #endif
 #if defined(CONFIG_VIDEO_IPUV3)
        /* disable video before launching O/S */
index 31ad169ccf3c1e937c2c17e1fe5c4df01d8f4be4..92b5c56acb25c1d77d2d4969521204bb6dd54bc2 100644 (file)
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y += cpu.o iomux.o
+obj-y += cpu.o iomux.o misc.o
diff --git a/arch/arm/mach-imx/imx8/misc.c b/arch/arm/mach-imx/imx8/misc.c
new file mode 100644 (file)
index 0000000..fe73e29
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <common.h>
+#include <asm/arch/sci/sci.h>
+
+int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate)
+{
+       sc_pm_clock_rate_t rate = clk_rate;
+       int ret;
+
+       /* Power up UARTn */
+       ret = sc_pm_set_resource_power_mode(-1, uart_rsrc, SC_PM_PW_MODE_ON);
+       if (ret)
+               return ret;
+
+       /* Set UARTn clock root to 'rate' MHz */
+       ret = sc_pm_set_clock_rate(-1, uart_rsrc, SC_PM_CLK_PER, &rate);
+       if (ret)
+               return ret;
+
+       /* Enable UARTn clock root */
+       ret = sc_pm_clock_enable(-1, uart_rsrc, SC_PM_CLK_PER, true, false);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+void build_info(void)
+{
+       u32 sc_build = 0, sc_commit = 0;
+
+       /* Get SCFW build and commit id */
+       sc_misc_build_info(-1, &sc_build, &sc_commit);
+       if (!sc_build) {
+               printf("SCFW does not support build info\n");
+               sc_commit = 0; /* Display 0 if build info not supported */
+       }
+       printf("Build: SCFW %x\n", sc_commit);
+}
index e80f1d484b0c2ea7f5700a0662a43ca80c808c5d..4084ab767291675a3bcba61f5dd5e722d04a8550 100644 (file)
@@ -95,6 +95,11 @@ u32 get_cpu_rev(void)
                        type = MXC_CPU_MX6DP;
        }
        reg &= 0xff;            /* mx6 silicon revision */
+
+       /* For 6DQ, the value 0x00630005 is Silicon revision 1.3*/
+       if (((type == MXC_CPU_MX6Q) || (type == MXC_CPU_MX6D)) && (reg == 0x5))
+               reg = 0x3;
+
        return (type << 12) | (reg + (0x10 * (major + 1)));
 }
 
index 9f1e0f6a720d1e5abe166f653055d7b782c0a569..1f230aca3397af2de617c7551d249bfb3cbaadf9 100644 (file)
@@ -24,6 +24,7 @@ u32 spl_boot_device(void)
 {
        unsigned int bmode = readl(&src_base->sbmr2);
        u32 reg = imx6_src_get_boot_mode();
+       u32 mmc_index = ((reg >> 11) & 0x03);
 
        /*
         * Check for BMODE if serial downloader is enabled
@@ -84,11 +85,12 @@ u32 spl_boot_device(void)
        /* SD/eSD: 8.5.3, Table 8-15  */
        case IMX6_BMODE_SD:
        case IMX6_BMODE_ESD:
-               return BOOT_DEVICE_MMC1;
-       /* MMC/eMMC: 8.5.3 */
        case IMX6_BMODE_MMC:
        case IMX6_BMODE_EMMC:
-               return BOOT_DEVICE_MMC1;
+               if (mmc_index == 1)
+                       return BOOT_DEVICE_MMC2;
+               else
+                       return BOOT_DEVICE_MMC1;
        /* NAND Flash: 8.5.2, Table 8-10 */
        case IMX6_BMODE_NAND_MIN ... IMX6_BMODE_NAND_MAX:
                return BOOT_DEVICE_NAND;
index a05414e294eb13f6b6716b806798ef9387b9184a..27b0baab2781717ddbaf2a9128666275f4bb6ef0 100644 (file)
                        clock-mult = <2>;
                        clocks = <&clk_fixed>;
                };
+
+               osc {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <20000000>;
+               };
        };
 
        clk_sandbox: clk-sbox {
                clock-names = "fixed", "i2c", "spi";
        };
 
+       ccf: clk-ccf {
+               compatible = "sandbox,clk-ccf";
+       };
+
        eth@10002000 {
                compatible = "sandbox,eth";
                reg = <0x10002000 0x1000>;
index aed334f8fb5fbec52fef925de6f640397673d51e..cbf40d5c4aeb87e841aca4f3c99e74389056616b 100644 (file)
@@ -70,27 +70,6 @@ int setup_lcd(void)
 }
 #endif
 
-#ifdef CONFIG_USB_EHCI_MX6
-#define USB_OTHERREGS_OFFSET   0x800
-#define UCTRL_PWR_POL          (1 << 9)
-
-int board_ehci_hcd_init(int port)
-{
-       u32 *usbnc_usb_ctrl;
-
-       if (port > 1)
-               return -EINVAL;
-
-       usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
-                                port * 4);
-
-       /* Set Power polarity */
-       setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
-
-       return 0;
-}
-#endif
-
 int opos6ul_board_late_init(void)
 {
 #ifdef CONFIG_VIDEO_MXS
index 1d41690c0ca41fe4ae42ed2411a82cef08b7cd57..40cc2a854eeea55fc51bbd1ef6c821ba90c6f906 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/io.h>
 #include <asm/mach-imx/boot_mode.h>
 #include <asm/mach-imx/iomux-v3.h>
-#include <asm/mach-imx/mxc_i2c.h>
 #include <asm/mach-imx/sata.h>
 #include <ahci.h>
 #include <dwc_ahsata.h>
@@ -26,7 +25,7 @@
 #include <errno.h>
 #include <fsl_esdhc_imx.h>
 #include <fuse.h>
-#include <i2c.h>
+#include <i2c_eeprom.h>
 #include <miiphy.h>
 #include <mmc.h>
 #include <net.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define I2C_PAD_CTRL                                                   \
-       (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |  \
-       PAD_CTL_HYS | PAD_CTL_ODE | PAD_CTL_SRE_FAST)
-
-#define EEPROM_I2C_ADDRESS     0x50
-
-#define PC                     MUX_PAD_CTRL(I2C_PAD_CTRL)
-
-static struct i2c_pads_info dh6sdl_i2c_pad_info0 = {
-       .scl = {
-               .i2c_mode  = MX6DL_PAD_EIM_D21__I2C1_SCL | PC,
-               .gpio_mode = MX6DL_PAD_EIM_D21__GPIO3_IO21 | PC,
-               .gp = IMX_GPIO_NR(3, 21)
-       },
-       .sda = {
-                .i2c_mode = MX6DL_PAD_EIM_D28__I2C1_SDA | PC,
-                .gpio_mode = MX6DL_PAD_EIM_D28__GPIO3_IO28 | PC,
-                .gp = IMX_GPIO_NR(3, 28)
-        }
-};
-
-static struct i2c_pads_info dh6sdl_i2c_pad_info1 = {
-       .scl = {
-               .i2c_mode  = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC,
-               .gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC,
-               .gp = IMX_GPIO_NR(4, 12)
-       },
-       .sda = {
-                .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
-                .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
-                .gp = IMX_GPIO_NR(4, 13)
-        }
-};
-
-static struct i2c_pads_info dh6sdl_i2c_pad_info2 = {
-       .scl = {
-               .i2c_mode  = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
-               .gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
-               .gp = IMX_GPIO_NR(1, 3)
-       },
-       .sda = {
-                .i2c_mode = MX6DL_PAD_GPIO_6__I2C3_SDA | PC,
-                .gpio_mode = MX6DL_PAD_GPIO_6__GPIO1_IO06 | PC,
-                .gp = IMX_GPIO_NR(1, 6)
-        }
-};
-
-static struct i2c_pads_info dh6dq_i2c_pad_info0 = {
-       .scl = {
-               .i2c_mode  = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
-               .gpio_mode = MX6Q_PAD_EIM_D21__GPIO3_IO21 | PC,
-               .gp = IMX_GPIO_NR(3, 21)
-       },
-       .sda = {
-                .i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
-                .gpio_mode = MX6Q_PAD_EIM_D28__GPIO3_IO28 | PC,
-                .gp = IMX_GPIO_NR(3, 28)
-        }
-};
-
-static struct i2c_pads_info dh6dq_i2c_pad_info1 = {
-       .scl = {
-               .i2c_mode  = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
-               .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC,
-               .gp = IMX_GPIO_NR(4, 12)
-       },
-       .sda = {
-                .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
-                .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
-                .gp = IMX_GPIO_NR(4, 13)
-        }
-};
-
-static struct i2c_pads_info dh6dq_i2c_pad_info2 = {
-       .scl = {
-               .i2c_mode  = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
-               .gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
-               .gp = IMX_GPIO_NR(1, 3)
-       },
-       .sda = {
-                .i2c_mode = MX6Q_PAD_GPIO_6__I2C3_SDA | PC,
-                .gpio_mode = MX6Q_PAD_GPIO_6__GPIO1_IO06 | PC,
-                .gp = IMX_GPIO_NR(1, 6)
-        }
-};
-
 int dram_init(void)
 {
        gd->ram_size = imx_ddr_size();
@@ -196,7 +109,6 @@ int board_eth_init(bd_t *bis)
 #ifdef CONFIG_USB_EHCI_MX6
 static void setup_usb(void)
 {
-       gpio_request(IMX_GPIO_NR(3, 31), "USB-VBUS");
        /*
         * Set daisy chain for otg_pin_id on MX6Q.
         * For MX6DL, this bit is reserved.
@@ -211,26 +123,12 @@ int board_usb_phy_mode(int port)
        else
                return USB_INIT_DEVICE;
 }
-
-int board_ehci_power(int port, int on)
-{
-       switch (port) {
-       case 0:
-               break;
-       case 1:
-               gpio_direction_output(IMX_GPIO_NR(3, 31), !!on);
-               break;
-       default:
-               printf("MXC USB port %d not yet supported\n", port);
-               return -EINVAL;
-       }
-
-       return 0;
-}
 #endif
 
 static int setup_dhcom_mac_from_fuse(void)
 {
+       struct udevice *dev;
+       ofnode eeprom;
        unsigned char enetaddr[6];
        int ret;
 
@@ -245,13 +143,19 @@ static int setup_dhcom_mac_from_fuse(void)
                return 0;
        }
 
-       ret = i2c_set_bus_num(2);
+       eeprom = ofnode_path("/soc/aips-bus@2100000/i2c@21a8000/eeprom@50");
+       if (!ofnode_valid(eeprom)) {
+               printf("Invalid hardware path to EEPROM!\n");
+               return -ENODEV;
+       }
+
+       ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev);
        if (ret) {
-               printf("Error switching I2C bus!\n");
+               printf("Cannot find EEPROM!\n");
                return ret;
        }
 
-       ret = i2c_read(EEPROM_I2C_ADDRESS, 0xfa, 0x1, enetaddr, 0x6);
+       ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6);
        if (ret) {
                printf("Error reading configuration EEPROM!\n");
                return ret;
@@ -282,18 +186,6 @@ int board_init(void)
        /* Enable eim_slow clocks */
        setbits_le32(&mxc_ccm->CCGR6, 0x1 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET);
 
-#ifdef CONFIG_SYS_I2C_MXC
-       if (is_mx6dq()) {
-               setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6dq_i2c_pad_info0);
-               setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6dq_i2c_pad_info1);
-               setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6dq_i2c_pad_info2);
-       } else {
-               setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6sdl_i2c_pad_info0);
-               setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6sdl_i2c_pad_info1);
-               setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6sdl_i2c_pad_info2);
-       }
-#endif
-
        setup_dhcom_mac_from_fuse();
 
        return 0;
@@ -372,3 +264,18 @@ int checkboard(void)
        puts("Board: DHCOM i.MX6\n");
        return 0;
 }
+
+#ifdef CONFIG_MULTI_DTB_FIT
+int board_fit_config_name_match(const char *name)
+{
+       if (is_mx6dq()) {
+               if (!strcmp(name, "imx6q-dhcom-pdk2"))
+                       return 0;
+       } else if (is_mx6sdl()) {
+               if (!strcmp(name, "imx6dl-dhcom-pdk2"))
+                       return 0;
+       }
+
+       return -1;
+}
+#endif
index b49296104283111c84ede426dec8ef6f07b68684..1b7acc8df7eb94f7a241661ba3c10652fdb6972f 100644 (file)
@@ -440,8 +440,13 @@ static void setup_iomux_sd(void)
 
 /* SPI */
 static iomux_v3_cfg_t const ecspi1_pads[] = {
-       /* SS0 */
-       IOMUX_PADS(PAD_EIM_EB2__GPIO2_IO30      | MUX_PAD_CTRL(SPI_PAD_CTRL)),
+       /* SS0 - SS of boot flash */
+       IOMUX_PADS(PAD_EIM_EB2__GPIO2_IO30      |
+               MUX_PAD_CTRL(SPI_PAD_CTRL | PAD_CTL_PUS_100K_UP)),
+       /* SS2 - SS of DHCOM SPI1 */
+       IOMUX_PADS(PAD_KEY_ROW2__GPIO4_IO11     |
+               MUX_PAD_CTRL(SPI_PAD_CTRL | PAD_CTL_PUS_100K_UP)),
+
        IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO     | MUX_PAD_CTRL(SPI_PAD_CTRL)),
        IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI     | MUX_PAD_CTRL(SPI_PAD_CTRL)),
        IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK     | MUX_PAD_CTRL(SPI_PAD_CTRL)),
index 7486f0ac2d9cfaa6a0f65e7ed8d2076466fdaf88..567b9f63e5969df788e19fff0f943ebe9028ed79 100644 (file)
@@ -53,8 +53,6 @@ static void setenv_fdt_file(void)
                        env_set("fdt_file", "imx6dl-icore-rqs.dtb");
        } else if (!strcmp(cmp_dtb, "imx6ul-geam"))
                env_set("fdt_file", "imx6ul-geam.dtb");
-       else if (!strcmp(cmp_dtb, "imx6ul-isiot-mmc"))
-               env_set("fdt_file", "imx6ul-isiot-emmc.dtb");
        else if (!strcmp(cmp_dtb, "imx6ul-isiot-emmc"))
                env_set("fdt_file", "imx6ul-isiot-emmc.dtb");
        else if (!strcmp(cmp_dtb, "imx6ul-isiot-nand"))
index e69efc4dd62a36d41627fa467b29129b602667c6..b7a609b0971bec39151f9311a06c617ea8cd810a 100644 (file)
@@ -34,21 +34,11 @@ static void setup_iomux_uart(void)
 
 int board_early_init_f(void)
 {
+       sc_pm_clock_rate_t rate = SC_80MHZ;
        int ret;
-       /* Set UART0 clock root to 80 MHz */
-       sc_pm_clock_rate_t rate = 80000000;
-
-       /* Power up UART0 */
-       ret = sc_pm_set_resource_power_mode(-1, SC_R_UART_0, SC_PM_PW_MODE_ON);
-       if (ret)
-               return ret;
 
-       ret = sc_pm_set_clock_rate(-1, SC_R_UART_0, 2, &rate);
-       if (ret)
-               return ret;
-
-       /* Enable UART0 clock root */
-       ret = sc_pm_clock_enable(-1, SC_R_UART_0, 2, true, false);
+       /* Set UART0 clock root to 80 MHz */
+       ret = sc_pm_setup_uart(SC_R_UART_0, rate);
        if (ret)
                return ret;
 
@@ -88,19 +78,6 @@ int board_phy_config(struct phy_device *phydev)
 }
 #endif
 
-void build_info(void)
-{
-       u32 sc_build = 0, sc_commit = 0;
-
-       /* Get SCFW build and commit id */
-       sc_misc_build_info(-1, &sc_build, &sc_commit);
-       if (!sc_build) {
-               printf("SCFW does not support build info\n");
-               sc_commit = 0; /* Display 0 when the build info is not supported*/
-       }
-       printf("Build: SCFW %x\n", sc_commit);
-}
-
 int checkboard(void)
 {
        puts("Board: iMX8QM MEK\n");
index 120731422c973445dc9221d33b2483ca7480167f..3cf73e1ab645ebf55ce2e586c5df12c5659b14b3 100644 (file)
@@ -40,21 +40,11 @@ static void setup_iomux_uart(void)
 
 int board_early_init_f(void)
 {
+       sc_pm_clock_rate_t rate = SC_80MHZ;
        int ret;
-       /* Set UART0 clock root to 80 MHz */
-       sc_pm_clock_rate_t rate = 80000000;
-
-       /* Power up UART0 */
-       ret = sc_pm_set_resource_power_mode(-1, SC_R_UART_0, SC_PM_PW_MODE_ON);
-       if (ret)
-               return ret;
 
-       ret = sc_pm_set_clock_rate(-1, SC_R_UART_0, 2, &rate);
-       if (ret)
-               return ret;
-
-       /* Enable UART0 clock root */
-       ret = sc_pm_clock_enable(-1, SC_R_UART_0, 2, true, false);
+       /* Set UART0 clock root to 80 MHz */
+       ret = sc_pm_setup_uart(SC_R_UART_0, rate);
        if (ret)
                return ret;
 
@@ -104,19 +94,6 @@ int board_phy_config(struct phy_device *phydev)
 }
 #endif
 
-void build_info(void)
-{
-       u32 sc_build = 0, sc_commit = 0;
-
-       /* Get SCFW build and commit id */
-       sc_misc_build_info(-1, &sc_build, &sc_commit);
-       if (!sc_build) {
-               printf("SCFW does not support build info\n");
-               sc_commit = 0; /* Display 0 when the build info is not supported */
-       }
-       printf("Build: SCFW %x\n", sc_commit);
-}
-
 int checkboard(void)
 {
        puts("Board: iMX8QXP MEK\n");
index 3e94f6ab668dae970e856a187055c05cbe383280..0354bb36e25372c5c68c0b4aa9c1a5c404730f18 100644 (file)
@@ -17,6 +17,13 @@ IMAGE_VERSION 2
 
 BOOT_FROM      sd
 
+/*
+ * Secure boot support
+ */
+#ifdef CONFIG_SECURE_BOOT
+CSF CONFIG_CSF_SIZE
+#endif
+
 /*
  * Device Configuration Data (DCD)
  *
index a6e18d9440784a354352cffca47f8eca26c7ca02..43ebc23091424af5a183237531e030326a721955 100644 (file)
@@ -45,12 +45,12 @@ DATA 4   0x403f00dc 0x00000000
 DATA 4   0x403e0040 0x01000020
 DATA 4   0x403e0500 0x01000000
 DATA 4   0x403e050c 0x80808080
-DATA 4   0x403e0508 0x00140000
-DATA 4   0x403E0510 0x00000004
-DATA 4   0x403E0514 0x00000002
+DATA 4   0x403e0508 0x00160002
+DATA 4   0x403E0510 0x00000001
+DATA 4   0x403E0514 0x00000014
 DATA 4   0x403e0500 0x00000001
 CHECK_BITS_SET 4 0x403e0500 0x01000000
-DATA 4   0x403e050c 0x8080801E
+DATA 4   0x403e050c 0x8080801B
 CHECK_BITS_SET 4 0x403e050c 0x00000040
 DATA 4   0x403E0030 0x00000001
 DATA 4   0x403e0040 0x11000020
@@ -94,11 +94,6 @@ DATA 4   0x40AB0820 0x33333333
 DATA 4   0x40AB0824 0x33333333
 DATA 4   0x40AB0828 0x33333333
 
-DATA 4   0x40AB082C 0xf3333333
-DATA 4   0x40AB0830 0xf3333333
-DATA 4   0x40AB0834 0xf3333333
-DATA 4   0x40AB0838 0xf3333333
-
 DATA 4   0x40AB08C0 0x24922492
 DATA 4   0x40AB08B8 0x00000800
 
@@ -113,8 +108,8 @@ DATA 4   0x40AB0030 0x009F0E10
 DATA 4   0x40AB0040 0x0000003F
 DATA 4   0x40AB0000 0xC3190000
 
-DATA 4   0x40AB001C 0x00008050
-DATA 4   0x40AB001C 0x00008058
+DATA 4   0x40AB001C 0x00008010
+DATA 4   0x40AB001C 0x00008018
 DATA 4   0x40AB001C 0x003F8030
 DATA 4   0x40AB001C 0x003F8038
 DATA 4   0x40AB001C 0xFF0A8030
index 082b2beaa3c78e451151d885999360d474232c02..2cc93dbdd57c629f76a1092bc1af9b01c98ae99d 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2019 NXP
  */
 
 #include <config.h>
        str r3, [r2, #0x40]
        ldr r3, =0x01000000
        str r3, [r2, #0x500]
+
        ldr r3, =0x80808080
        str r3, [r2, #0x50c]
-       ldr r3, =0x00140000
+       ldr r3, =0x00160002
        str r3, [r2, #0x508]
-       ldr r3, =0x00000004
+       ldr r3, =0x00000001
        str r3, [r2, #0x510]
-       ldr r3, =0x00000002
+       ldr r3, =0x00000014
        str r3, [r2, #0x514]
        ldr r3, =0x00000001
        str r3, [r2, #0x500]
@@ -33,7 +35,7 @@ wait1:
        cmp r4, r3
        bne wait1
 
-       ldr r3, =0x8080801E
+       ldr r3, =0x8080801B
        str r3, [r2, #0x50c]
 
        ldr r3, =0x00000040
@@ -132,15 +134,6 @@ wait2:
        ldr r1, =0x33333333
        str r1, [r0, #0x828]
 
-       ldr r1, =0xf3333333
-       str r1, [r0, #0x82c]
-       ldr r1, =0xf3333333
-       str r1, [r0, #0x830]
-       ldr r1, =0xf3333333
-       str r1, [r0, #0x834]
-       ldr r1, =0xf3333333
-       str r1, [r0, #0x838]
-
        ldr r1, =0x24922492
        str r1, [r0, #0x8c0]
        ldr r1, =0x00000800
@@ -168,9 +161,9 @@ wait2:
        ldr r1, =0xC3190000
        str r1, [r0, #0x0]
 
-       ldr r1, =0x00008050
+       ldr r1, =0x00008010
        str r1, [r0, #0x1c]
-       ldr r1, =0x00008058
+       ldr r1, =0x00008018
        str r1, [r0, #0x1c]
        ldr r1, =0x003F8030
        str r1, [r0, #0x1c]
index 7b89d169703624ef8ef2591d29543001a1f3ffd2..8390d9a0f31cb425d9f9c45fff658b4432b603d4 100644 (file)
@@ -68,7 +68,7 @@ iomux_v3_cfg_t const ecspi2_pads[] = {
 
 int board_spi_cs_gpio(unsigned int bus, unsigned int cs)
 {
-       if (bus != 1 || cs != (IMX_GPIO_NR(5, 29) << 8))
+       if (bus != 1 || cs != 0)
                return -EINVAL;
 
        return IMX_GPIO_NR(5, 29);
index 6b7ff0acb68595956195cb0dbbff789a13b72ec1..ea49b7197f930bf3f713830d3fb86e6b4cdd32f3 100644 (file)
@@ -413,12 +413,3 @@ int misc_init_r(void)
 
        return 0;
 }
-
-static struct mxc_serial_platdata mxc_serial_plat = {
-       .reg = (struct mxc_uart *)UART5_BASE,
-};
-
-U_BOOT_DEVICE(mxc_serial) = {
-       .name = "serial_mxc",
-       .platdata = &mxc_serial_plat,
-};
index e48b3beb1602537aa89a36eca2fc3865708cd67f..6e3ffa72d7f390ac8c90c953d13a283914ec513a 100644 (file)
@@ -223,25 +223,15 @@ int board_mmc_init(bd_t *bis)
        switch (reg) {
        case 0:
                SETUP_IOMUX_PADS(usdhc1_pads);
-               usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR;
-               usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
-               gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
                break;
        case 1:
                SETUP_IOMUX_PADS(usdhc2_pads);
-               usdhc_cfg[1].esdhc_base = USDHC2_BASE_ADDR;
-               usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
-               gd->arch.sdhc_clk = usdhc_cfg[1].sdhc_clk;
                break;
        }
 
-       return fsl_esdhc_initialize(bis, &usdhc_cfg[reg]);
+       return 0;
 }
 
-int board_mmc_getcd(struct mmc *mmc)
-{
-       return 1;
-}
 #endif
 
 static void ccgr_init(void)
index e3d75e549a6da098d580348eb8ca929728fa7e37..216475c8dec15fa9d30d5549996b23cdd4a1a62b 100644 (file)
@@ -16,7 +16,6 @@
 #include <i2c.h>
 #include <miiphy.h>
 #include <netdev.h>
-#include <usb.h>
 #include <power/pmic.h>
 #include <power/pfuze3000_pmic.h>
 #include "../../freescale/common/pfuze.h"
@@ -328,15 +327,3 @@ int board_ehci_hcd_init(int port)
        return 0;
 }
 
-int board_usb_phy_mode(int port)
-{
-       switch (port) {
-       case 0:
-               return USB_INIT_DEVICE;
-       case 1:
-               return USB_INIT_HOST;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
index f516e546a8d6c62de85c3a91df09386c6b371e82..5433c7581b480475089f76c7c60cf05fe830233f 100644 (file)
@@ -37,22 +37,11 @@ static void setup_iomux_uart(void)
 
 int board_early_init_f(void)
 {
-       sc_pm_clock_rate_t rate;
+       sc_pm_clock_rate_t rate = SC_80MHZ;
        sc_err_t err = 0;
 
-       /* Power up UART1 */
-       err = sc_pm_set_resource_power_mode(-1, SC_R_UART_1, SC_PM_PW_MODE_ON);
-       if (err != SC_ERR_NONE)
-               return 0;
-
-       /* Set UART3 clock root to 80 MHz */
-       rate = 80000000;
-       err = sc_pm_set_clock_rate(-1, SC_R_UART_1, SC_PM_CLK_PER, &rate);
-       if (err != SC_ERR_NONE)
-               return 0;
-
-       /* Enable UART1 clock root */
-       err = sc_pm_clock_enable(-1, SC_R_UART_1, SC_PM_CLK_PER, true, false);
+       /* Set UART1 clock root to 80 MHz and enable it */
+       err = sc_pm_setup_uart(SC_R_UART_1, rate);
        if (err != SC_ERR_NONE)
                return 0;
 
@@ -82,19 +71,6 @@ int board_phy_config(struct phy_device *phydev)
 }
 #endif
 
-void build_info(void)
-{
-       u32 sc_build = 0, sc_commit = 0;
-
-       /* Get SCFW build and commit id */
-       sc_misc_build_info(-1, &sc_build, &sc_commit);
-       if (!sc_build) {
-               printf("SCFW does not support build info\n");
-               sc_commit = 0; /* Display 0 if build info not supported */
-       }
-       printf("Build: SCFW %x\n", sc_commit);
-}
-
 int checkboard(void)
 {
        puts("Model: Toradex Apalis iMX8\n");
index aa8eaa0ea13aa43ffae26de17df5357efc354998..8c725b759311686b01569f44b8eeb0bae7ebe4fd 100644 (file)
@@ -51,19 +51,9 @@ int board_early_init_f(void)
        if (err != SC_ERR_NONE)
                return 0;
 
-       /* Power up UART3 */
-       err = sc_pm_set_resource_power_mode(-1, SC_R_UART_3, SC_PM_PW_MODE_ON);
-       if (err != SC_ERR_NONE)
-               return 0;
-
-       /* Set UART3 clock root to 80 MHz */
-       rate = 80000000;
-       err = sc_pm_set_clock_rate(-1, SC_R_UART_3, SC_PM_CLK_PER, &rate);
-       if (err != SC_ERR_NONE)
-               return 0;
-
-       /* Enable UART3 clock root */
-       err = sc_pm_clock_enable(-1, SC_R_UART_3, SC_PM_CLK_PER, true, false);
+       /* Set UART3 clock root to 80 MHz and enable it */
+       rate = SC_80MHZ;
+       err = sc_pm_setup_uart(SC_R_UART_3, rate);
        if (err != SC_ERR_NONE)
                return 0;
 
@@ -93,19 +83,6 @@ int board_phy_config(struct phy_device *phydev)
 }
 #endif
 
-void build_info(void)
-{
-       u32 sc_build = 0, sc_commit = 0;
-
-       /* Get SCFW build and commit id */
-       sc_misc_build_info(-1, &sc_build, &sc_commit);
-       if (!sc_build) {
-               printf("SCFW does not support build info\n");
-               sc_commit = 0; /* Display 0 if build info not supported */
-       }
-       printf("Build: SCFW %x\n", sc_commit);
-}
-
 int checkboard(void)
 {
        puts("Model: Toradex Colibri iMX8X\n");
index f69c4433b24376398724e155cf38e3677e278888..c19d7611c2fd552054d6f561775ee290113057f5 100644 (file)
@@ -7,8 +7,9 @@
 #include "tdx-cfg-block.h"
 
 #if defined(CONFIG_TARGET_APALIS_IMX6) || \
+       defined(CONFIG_TARGET_APALIS_IMX8) || \
        defined(CONFIG_TARGET_COLIBRI_IMX6) || \
-       defined(CONFIG_TARGET_COLIBRI_IMX8QXP)
+       defined(CONFIG_TARGET_COLIBRI_IMX8X)
 #include <asm/arch/sys_proto.h>
 #else
 #define is_cpu_type(cpu) (0)
@@ -129,6 +130,10 @@ static int tdx_cfg_block_mmc_storage(u8 *config_block, int write)
                ret = -ENODEV;
                goto out;
        }
+       if (mmc_init(mmc)) {
+               puts("MMC init failed\n");
+               return -EINVAL;
+       }
        if (part != mmc_get_blk_desc(mmc)->hwpart) {
                if (blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part)) {
                        puts("MMC partition switch failed\n");
@@ -287,6 +292,7 @@ static int get_cfgblock_interactive(void)
        char message[CONFIG_SYS_CBSIZE];
        char *soc;
        char it = 'n';
+       char wb = 'n';
        int len;
 
        /* Unknown module by default */
@@ -296,10 +302,17 @@ static int get_cfgblock_interactive(void)
                sprintf(message, "Is the module the 312 MHz version? [y/N] ");
        else
                sprintf(message, "Is the module an IT version? [y/N] ");
-
        len = cli_readline(message);
        it = console_buffer[0];
 
+#if defined(CONFIG_TARGET_APALIS_IMX8) || \
+               defined(CONFIG_TARGET_COLIBRI_IMX6ULL) || \
+               defined(CONFIG_TARGET_COLIBRI_IMX8X)
+       sprintf(message, "Does the module have Wi-Fi / Bluetooth? [y/N] ");
+       len = cli_readline(message);
+       wb = console_buffer[0];
+#endif
+
        soc = env_get("soc");
        if (!strcmp("mx6", soc)) {
 #ifdef CONFIG_TARGET_APALIS_IMX6
@@ -327,12 +340,6 @@ static int get_cfgblock_interactive(void)
                                tdx_hw_tag.prodid = COLIBRI_IMX6S;
                }
 #elif CONFIG_TARGET_COLIBRI_IMX6ULL
-               char wb = 'n';
-
-               sprintf(message, "Does the module have Wi-Fi / Bluetooth? " \
-                                "[y/N] ");
-               len = cli_readline(message);
-               wb = console_buffer[0];
                if (it == 'y' || it == 'Y') {
                        if (wb == 'y' || wb == 'Y')
                                tdx_hw_tag.prodid = COLIBRI_IMX6ULL_WIFI_BT_IT;
@@ -349,9 +356,31 @@ static int get_cfgblock_interactive(void)
                tdx_hw_tag.prodid = COLIBRI_IMX7D;
        else if (!strcmp("imx7s", soc))
                tdx_hw_tag.prodid = COLIBRI_IMX7S;
-       else if (is_cpu_type(MXC_CPU_IMX8QXP))
-               tdx_hw_tag.prodid = COLIBRI_IMX8QXP_WIFI_BT_IT;
-       else if (!strcmp("tegra20", soc)) {
+       else if (is_cpu_type(MXC_CPU_IMX8QM)) {
+               if (it == 'y' || it == 'Y') {
+                       if (wb == 'y' || wb == 'Y')
+                               tdx_hw_tag.prodid = APALIS_IMX8QM_WIFI_BT_IT;
+                       else
+                               tdx_hw_tag.prodid = APALIS_IMX8QM_IT;
+               } else {
+                       if (wb == 'y' || wb == 'Y')
+                               tdx_hw_tag.prodid = APALIS_IMX8QP_WIFI_BT;
+                       else
+                               tdx_hw_tag.prodid = APALIS_IMX8QP;
+               }
+       } else if (is_cpu_type(MXC_CPU_IMX8QXP)) {
+               if (it == 'y' || it == 'Y') {
+                       if (wb == 'y' || wb == 'Y')
+                               tdx_hw_tag.prodid = COLIBRI_IMX8QXP_WIFI_BT_IT;
+                       else
+                               tdx_hw_tag.prodid = COLIBRI_IMX8QXP_IT;
+               } else {
+                       if (wb == 'y' || wb == 'Y')
+                               tdx_hw_tag.prodid = COLIBRI_IMX8DX_WIFI_BT;
+                       else
+                               tdx_hw_tag.prodid = COLIBRI_IMX8DX;
+               }
+       } else if (!strcmp("tegra20", soc)) {
                if (it == 'y' || it == 'Y')
                        if (gd->ram_size == 0x10000000)
                                tdx_hw_tag.prodid = COLIBRI_T20_256MB_IT;
@@ -482,8 +511,7 @@ static int do_cfgblock_create(cmd_tbl_t *cmdtp, int flag, int argc,
                 * On NAND devices, recreation is only allowed if the page is
                 * empty (config block invalid...)
                 */
-               printf("NAND erase block %d need to be erased before creating" \
-                      " a Toradex config block\n",
+               printf("NAND erase block %d need to be erased before creating a Toradex config block\n",
                       CONFIG_TDX_CFG_BLOCK_OFFSET /
                       get_nand_dev_by_index(0)->erasesize);
                goto out;
@@ -492,8 +520,7 @@ static int do_cfgblock_create(cmd_tbl_t *cmdtp, int flag, int argc,
                 * On NOR devices, recreation is only allowed if the sector is
                 * empty and write protection is off (config block invalid...)
                 */
-               printf("NOR sector at offset 0x%02x need to be erased and " \
-                      "unprotected before creating a Toradex config block\n",
+               printf("NOR sector at offset 0x%02x need to be erased and unprotected before creating a Toradex config block\n",
                       CONFIG_TDX_CFG_BLOCK_OFFSET);
                goto out;
 #else
@@ -604,9 +631,8 @@ static int do_cfgblock(cmd_tbl_t *cmdtp, int flag, int argc,
        return CMD_RET_USAGE;
 }
 
-U_BOOT_CMD(
-       cfgblock, 4, 0, do_cfgblock,
-       "Toradex config block handling commands",
-       "create [-y] [barcode] - (Re-)create Toradex config block\n"
-       "cfgblock reload - Reload Toradex config block from flash"
+U_BOOT_CMD(cfgblock, 4, 0, do_cfgblock,
+          "Toradex config block handling commands",
+          "create [-y] [barcode] - (Re-)create Toradex config block\n"
+          "cfgblock reload - Reload Toradex config block from flash"
 );
index 9e66cc110de2a7bf07bd0eb8605326bdf1ddd262..16cb5c2956c182fbbd82940f3a39e6b68a0112e0 100644 (file)
@@ -325,8 +325,8 @@ config CMD_SPL
          command.
 
 config CMD_SPL_NAND_OFS
-       hex "Offset of OS command line args for Falcon-mode NAND boot"
-       depends on CMD_SPL
+       hex "Offset of OS args or dtb for Falcon-mode NAND boot"
+       depends on CMD_SPL && (TPL_NAND_SUPPORT || SPL_NAND_SUPPORT)
        default 0
        help
          This provides the offset of the command line arguments for Linux
@@ -334,6 +334,14 @@ config CMD_SPL_NAND_OFS
          for full information about how to use this option (and also see
          board/gateworks/gw_ventana/README for an example).
 
+config CMD_SPL_NOR_OFS
+       hex "Offset of OS args or dtb for Falcon-mode NOR boot"
+       depends on CMD_SPL && SPL_NOR_SUPPORT
+       default 0
+       help
+         This provides the offset of the command line arguments or dtb for
+         Linux when booting from NOR in Falcon mode.
+
 config CMD_SPL_WRITE_SIZE
        hex "Size of argument area"
        depends on CMD_SPL
index 7b1f81477fd83cd733e3d6d61bcedf95e9fe5189..19953df082fbc7c2af425c893f5ded133bf94dcc 100644 (file)
@@ -108,7 +108,7 @@ static int eeprom_len(unsigned offset, unsigned end)
 
        /*
         * For a FRAM device there is no limit on the number of the
-        * bytes that can be ccessed with the single read or write
+        * bytes that can be accessed with the single read or write
         * operation.
         */
 #if !defined(CONFIG_SYS_I2C_FRAM)
index abc31b17b813f33d029dda37e41b713144fd4886..ee4dcedd5fa97973c679dc721900111b89bbc498 100644 (file)
@@ -700,7 +700,7 @@ static init_fnc_t init_sequence_r[] = {
        stdio_init_tables,
        initr_serial,
        initr_announce,
-#if defined(CONFIG_WDT)
+#if CONFIG_IS_ENABLED(WDT)
        initr_watchdog,
 #endif
        INIT_FUNC_WATCHDOG_RESET
index 5d6da5db89bc553a429b5c008814c45ab7db2cf0..54154b93c9498a21ee114e7aa96bc0b87ec25022 100644 (file)
@@ -1075,6 +1075,7 @@ endif
 
 config SPL_WATCHDOG_SUPPORT
        bool "Support watchdog drivers"
+       imply SPL_WDT if !HW_WATCHDOG
        help
          Enable support for watchdog drivers in SPL. A watchdog is
          typically a hardware peripheral which can reset the system when it
index d5e3f680f4cb61bfa054684db5fd657425436c2c..c182705b3fc9cad2b6fac694ed937cdeca5fe895 100644 (file)
@@ -603,7 +603,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
        spl_board_init();
 #endif
 
-#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && defined(CONFIG_WDT)
+#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && CONFIG_IS_ENABLED(WDT)
        initr_watchdog();
 #endif
 
index cad3f1a69c110f687d02baf61817dc2b295c9285..b76c4c1b85a26f85f9bc58969257c039ef9c0132 100644 (file)
@@ -37,7 +37,6 @@ CONFIG_CMD_ASKENV=y
 CONFIG_CRC32_VERIFY=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_ALT_MEMTEST=y
-CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -56,7 +55,6 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_IP_DEFRAG=y
 CONFIG_TFTP_BLOCKSIZE=4096
 CONFIG_DWC_AHSATA=y
-CONFIG_DFU_MMC=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
index 49dd9bb755336bc39265d743d184f1dc50703c9f..33e40cd7d3a2e3ca53a7081a1595339599fb6ef8 100644 (file)
@@ -50,6 +50,7 @@ CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y
index 06c05f7e2223b8c837d252902cd1694418b12595..34a6cde1ee88ff61c3f74abc6f578e42b17236ee 100644 (file)
@@ -48,6 +48,7 @@ CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y
index e645055afa11649993cc7e9a722c12e4dba26be3..cb361daafb0f9e84ad92bd74f94800bb52f2786b 100644 (file)
@@ -49,6 +49,7 @@ CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ8XXX=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y
index c28a167f5becb86dd0abfcf0fdb37c9de123bd1c..2b57b5e41ef9c394dbd9d8c49e4efb4dc8eab833 100644 (file)
@@ -47,7 +47,6 @@ CONFIG_ENV_IS_IN_NAND=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_IP_DEFRAG=y
 CONFIG_TFTP_BLOCKSIZE=16352
-CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
index b343178b9c4a8d9b1aa99212885163d4e4e36a9b..f792a9ef5c479d30efbac146a68826b69d1c47f2 100644 (file)
@@ -36,7 +36,6 @@ CONFIG_CMD_ASKENV=y
 CONFIG_CRC32_VERIFY=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_ALT_MEMTEST=y
-CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -55,7 +54,6 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_IP_DEFRAG=y
 CONFIG_TFTP_BLOCKSIZE=16352
-CONFIG_DFU_MMC=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
index aaab4c82f0c6fa7d79929a5d33d1812d96689ed3..0c3a898aabb036921d976e948a5b0f0db83c4396 100644 (file)
@@ -24,10 +24,9 @@ CONFIG_SYS_PROMPT="Colibri iMX7 # "
 CONFIG_CMD_ASKENV=y
 CONFIG_CRC32_VERIFY=y
 CONFIG_CMD_MEMTEST=y
-CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
-# CONFIG_RANDOM_UUID is not set
+CONFIG_RANDOM_UUID=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
@@ -43,13 +42,13 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_IP_DEFRAG=y
 CONFIG_TFTP_BLOCKSIZE=16352
 CONFIG_FSL_CAAM=y
-CONFIG_DFU_MMC=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x10000000
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
index 3b24dd326ec47244a2a71febc3c21f19c537802b..3022a187cc2f5f4c56c75c33646464fb60f7236a 100644 (file)
@@ -16,13 +16,13 @@ CONFIG_AHCI=y
 CONFIG_DISTRO_DEFAULTS=y
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_FIT=y
+CONFIG_SPL_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
 CONFIG_BOOTDELAY=3
 # CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
 CONFIG_BOUNCE_BUFFER=y
 CONFIG_SPL_TEXT_BASE=0x00908000
-CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_WATCHDOG_SUPPORT=y
 CONFIG_CMD_MEMTEST=y
@@ -41,10 +41,16 @@ CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-dhcom-pdk2"
+CONFIG_OF_LIST="imx6q-dhcom-pdk2 imx6dl-dhcom-pdk2"
+CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_DWC_AHSATA=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MXC=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
 CONFIG_DM_MMC=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_DM_SPI_FLASH=y
@@ -64,6 +70,8 @@ CONFIG_FEC_MXC=y
 CONFIG_MII=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX6=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_SCSI=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
index 938414c3ddd5a93b355ef945be74b4b0b977a2d7..2275ee7d1bc4bdb995b9d75e6ca517310724127f 100644 (file)
@@ -4,16 +4,19 @@ CONFIG_SYS_TEXT_BASE=0x17800000
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x1000
 CONFIG_MX6_DDRCAL=y
 CONFIG_TARGET_DISPLAY5=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x400
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
 CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
 CONFIG_SYS_BOOTCOUNT_ADDR=0x020CC068
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_TPL_SYS_MALLOC_F_LEN=0x400
 CONFIG_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_OF_BOARD_SETUP=y
index 4231adb6a729c2c29cdde96b27c771a1be4de4ea..91b6a7424f962576fefd3406069d7ad4a7e2ac35 100644 (file)
@@ -41,6 +41,7 @@ CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHYLIB=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y
index f98088deb74be3a1cb848f0a5f7972405542e48e..fbf1f89ece210e4a2db768327a3ebfafb1a88b17 100644 (file)
@@ -40,6 +40,7 @@ CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHYLIB=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y
index 60bdcd67a00fc281ab40586eeed723aa7ce14794..54197f7541cd77837e04493d9930067a04db70a3 100644 (file)
@@ -55,6 +55,7 @@ CONFIG_CMD_E1000=y
 CONFIG_MII=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX6=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_MXC_SPI=y
index cf6964bd9a6174aa3618e3ca47decf0711aa95a3..b95c9783a4878a66dffa09707a6b96c6ee33f019 100644 (file)
@@ -4,6 +4,7 @@ CONFIG_SYS_TEXT_BASE=0x17800000
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_TARGET_MX6LOGICPD=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
@@ -54,12 +55,16 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:2m(spl),2m(uboot),1m(env),16m(kernel),1m(dtb),-(fs)"
 CONFIG_CMD_UBI=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-logicpd"
 CONFIG_ENV_IS_IN_FAT=y
 CONFIG_ENV_IS_IN_NAND=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_PCF8575_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
@@ -82,6 +87,7 @@ CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_MXC_UART=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+# CONFIG_SPL_DM_USB is not set
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="FSL"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0525
index b15c547e372b45f90035071a08229ff39d101553..353582a6c7bb79d75b04fc60d732d3aa15587675 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_DEBUG_UART_BASE=0x021f0000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_SPL_LIBDISK_SUPPORT=y
 # CONFIG_CMD_BMODE is not set
+CONFIG_CMD_NANDBCB=y
 CONFIG_DEBUG_UART=y
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
index 4ea0803ab543e18840d4bf580b9cc69ad1a67795..4672563ff97e2e970137c68b04de555459746d4a 100644 (file)
@@ -8,6 +8,7 @@ CONFIG_TARGET_MX6Q_ENGICAM=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 # CONFIG_CMD_BMODE is not set
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
index 39e5f5e71d217fa625ebc944995c837f1237322c..cf83a671f7b947168ca87f2a3d940b2c041e9a78 100644 (file)
@@ -78,5 +78,7 @@ CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_SPL_DM_REGULATOR_GPIO=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
+CONFIG_DM_THERMAL=y
+CONFIG_IMX_SCU_THERMAL=y
 CONFIG_SPL_TINY_MEMSET=y
 # CONFIG_EFI_LOADER is not set
index 86d672784c99ef97887fad18600c56fb480c7789..ea6f8f6d313afebe565d05d6ca944ac91b81c018 100644 (file)
@@ -47,3 +47,5 @@ CONFIG_MXC_UART=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_MX5=y
 CONFIG_USB_STORAGE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
index 3a5fa26bcd3da800b7ad35f55f9257c687856e6d..c551ea2daa29055fd09f6ed4c5597fcbfae79a84 100644 (file)
@@ -72,6 +72,8 @@ CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_RTC_M41T62=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EHCI_MX5=y
index 781620048d2809037b08fcbb6652a75f40fa36fe..cd78c5cb33e23f1f51300af87e42e146a250b63e 100644 (file)
@@ -20,7 +20,6 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
-CONFIG_CMD_USB=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
@@ -50,5 +49,4 @@ CONFIG_MII=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_DM_THERMAL=y
-CONFIG_USB=y
 CONFIG_OF_LIBFDT=y
index 522207afcad457e4902da23970fb66e10ad2223c..17947860eec06d23fec2000dc7e43ca2b5d84d5b 100644 (file)
@@ -21,7 +21,6 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
-CONFIG_CMD_USB=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
@@ -51,5 +50,4 @@ CONFIG_MII=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_DM_THERMAL=y
-CONFIG_USB=y
 CONFIG_OF_LIBFDT=y
index d6a7c84df35ea53a7563e5572ec8377e547df28e..c0a586f24865b48eef148c0bebd4b9a817d4eb33 100644 (file)
@@ -64,7 +64,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_MTK_SERIAL=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
-CONFIG_MTK_QSPI=y
+CONFIG_MTK_SNFI_SPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_WATCHDOG=y
index a88af15760ea7b22ab90e202324cc6b585f80824..cad798a4166b56ba02822c402d2699ab1b4a98b4 100644 (file)
@@ -43,6 +43,7 @@ CONFIG_FSL_ESDHC_IMX=y
 CONFIG_MII=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX5=y
+CONFIG_PWM_IMX=y
 CONFIG_RTC_S35392A=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_MX5=y
index bc34e995e3a3020c62b3332d62344de709d883e8..263f8f29a023ca835b894efa9877324087fb6678 100644 (file)
@@ -51,6 +51,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+CONFIG_DM_USB=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
index b609b6d7b904dcd8863699c0c24543d671a7b1cd..7c559cfec4f34e6810e62794b0cb5d5cb1a1dc19 100644 (file)
@@ -43,6 +43,7 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+CONFIG_DM_USB=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
 CONFIG_MII=y
index f23bbf7814461fb6256784c69f1c5b9022e6c467..09b81e485e98d532c7b6b83e49d3eb5e6f915936 100644 (file)
@@ -51,6 +51,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+CONFIG_DM_USB=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
index 14c0817127446c939224c3193489a24ff55079ff..7689242716a0481987600dfd6d05e3366e05824e 100644 (file)
@@ -51,6 +51,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+CONFIG_DM_USB=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
index 11cc097cd558a64e807cad7ff909a6c1ef5f4ae0..62594e3c2152aa0e23895bb622cf1e641b34ee5c 100644 (file)
@@ -93,6 +93,7 @@ CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
 CONFIG_CLK=y
+CONFIG_SANDBOX_CLK_CCF=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
 CONFIG_DM_DEMO_SIMPLE=y
index af335285c9adae4d98e94d9c076072fe8e8ba927..2429ae46216460f4cdd0313f051201667c6b6d87 100644 (file)
@@ -66,6 +66,7 @@ CONFIG_DEBUG_DEVRES=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_CLK=y
+CONFIG_SANDBOX_CLK_CCF=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
 CONFIG_DM_DEMO_SIMPLE=y
index 7364c67cd7d87cb0a5466e31780d6860d8ca88d9..6b9691ad3e3ef331f03cbdabc46cb24061f5914b 100644 (file)
@@ -45,6 +45,7 @@ CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
 CONFIG_PINCTRL=y
index 8a4e29419ce6838cbcb7f03e7adae9de2c214fd7..0f28d5881d7ef8bc3b3333885a84f6e069ceddf9 100644 (file)
@@ -54,4 +54,11 @@ CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_USB_ETHER=y
 CONFIG_USB_ETH_CDC=y
 CONFIG_USBNET_HOST_ADDR="de:ad:be:af:00:00"
-CONFIG_OPTEE_TZDRAM_SIZE=0x2000000
+CONFIG_OPTEE=y
+CONFIG_OPTEE_TZDRAM_BASE=0x9e000000
+CONFIG_OPTEE_TZDRAM_SIZE=0x02000000
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_LIBFDT=y
+CONFIG_OF_LIBFDT_OVERLAY=y
index 9a7f0bc23515089d1a5e8e968c7db58f051cb613..713d7063a1d8cb0e8642f5540ac0e52d87ec1e58 100644 (file)
@@ -67,6 +67,8 @@ CONFIG_SYS_NAND_SPL_KERNEL_OFFS       Offset in NAND where the kernel is stored
 
 CONFIG_CMD_SPL_NAND_OFS        Offset in NAND where the parameters area was saved.
 
+CONFIG_CMD_SPL_NOR_OFS Offset in NOR where the parameters area was saved.
+
 CONFIG_CMD_SPL_WRITE_SIZE      Size of the parameters area to be copied
 
 CONFIG_SPL_OS_BOOT     Activate Falcon Mode.
diff --git a/doc/imx/clk/ccf.txt b/doc/imx/clk/ccf.txt
new file mode 100644 (file)
index 0000000..36b60dc
--- /dev/null
@@ -0,0 +1,101 @@
+Introduction:
+=============
+
+This documentation entry describes the Common Clock Framework [CCF]
+port from Linux kernel (v5.1.12) to U-Boot.
+
+This code is supposed to bring CCF to IMX based devices (imx6q, imx7
+imx8). Moreover, it also provides some common clock code, which would
+allow easy porting of CCF Linux code to other platforms.
+
+Design decisions:
+=================
+
+* U-Boot's driver model [DM] for clk differs from Linux CCF. The most
+  notably difference is the lack of support for hierarchical clocks and
+  "clock as a manager driver" (single clock DTS node acts as a starting
+  point for all other clocks).
+
+* The clk_get_rate() caches the previously read data if CLK_GET_RATE_NOCACHE
+  is not set (no need for recursive access).
+
+* On purpose the "manager" clk driver (clk-imx6q.c) is not using large
+  table to store pointers to clocks - e.g. clk[IMX6QDL_CLK_USDHC2_SEL] = ....
+  Instead we use udevice's linked list for the same class (UCLASS_CLK).
+
+  Rationale:
+  ----------
+    When porting the code as is from Linux, one would need ~1KiB of RAM to
+    store it. This is way too much if we do plan to use this driver in SPL.
+
+* The "central" structure of this patch series is struct udevice and its
+  uclass_priv field contains the struct clk pointer (to the originally created
+  one).
+
+* Up till now U-Boot's driver model (DM) CLK operates on udevice (main
+  access to clock is by udevice ops)
+  In the CCF the access to struct clk (embodying pointer to *dev) is
+  possible via dev_get_clk_ptr() (it is a wrapper on dev_get_uclass_priv()).
+
+* To keep things simple the struct udevice's uclass_priv pointer is used to
+  store back pointer to corresponding struct clk. However, it is possible to
+  modify clk-uclass.c file and add there struct uc_clk_priv, which would have
+  clock related members (like pointer to clk). As of this writing there is no
+  such need, so to avoid extra allocations (as it can be auto allocated by
+  setting .per_device_auto_alloc_size = sizeof(struct uc_clk_priv)) the
+  uclass_priv stores the pointer to struct clk.
+
+* It is advised to add common clock code (like already added rate and flags) to
+  the struct clk, which is a top level description of the clock.
+
+* U-Boot's driver model already provides the facility to automatically allocate
+  (via private_alloc_size) device private data (accessible via dev->priv).
+  It may look appealing to use this feature to allocate private structures for
+  CCF clk devices e.g. divider (struct clk_divider *divider) for IMX6Q clock.
+
+  The above feature had not been used for following reasons:
+  - The original CCF Linux kernel driver is the "manager" for clocks - it
+    decides when clock is instantiated (and when memory for it is allocated).
+
+  - Using it would change the original structure of the CCF code.
+
+  - To bind (via clk_register()) the clock device with U-Boot driver model we
+    first need udevice for it (the "chicken and egg problem").
+
+* I've added the clk_get_parent(), which reads parent's dev->uclass_priv to
+  provide parent's struct clk pointer. This seems the easiest way to get
+  child/parent relationship for struct clk in U-Boot's udevice based clocks.
+
+* Linux's CCF 'struct clk_core' corresponds to U-Boot's udevice in 'struct clk'.
+  Clock IP block agnostic flags from 'struct clk_core' (e.g. NOCACHE) have been
+  moved from this struct one level up to 'struct clk'.
+
+* For tests the new ./test/dm/clk_ccf.c and ./drivers/clk/clk_sandbox_ccf.c
+  files have been introduced. The latter setups the CCF clock structure for
+  sandbox by reusing, if possible, generic clock primitives - like divier
+  and mux. The former file provides code to tests this setup.
+
+  For sandbox new CONFIG_SANDBOX_CLK_CCF Kconfig define has been introduced.
+  All new primitives added for new architectures must have corresponding test
+  in the two aforementioned files.
+
+
+Testing (sandbox):
+==================
+
+make mrproper; make sandbox_defconfig; make -j4
+./u-boot -i -d arch/sandbox/dts/test.dtb
+=> ut dm clk
+
+or in a more "scriptable" way (with -v to print debug output):
+./u-boot --fdt arch/sandbox/dts/test.dtb --command "ut dm clk_ccf" -v
+
+To do:
+------
+
+* Use of OF_PLATDATA in the SPL setup for CCF - as it is now - the SPL grows
+  considerably and using CCF in boards with tiny resources (OCRAM) is
+  problematic.
+
+* On demand port other parts of CCF to U-Boot - as now only features _really_
+  needed by DM/DTS converted drivers are used.
index eab88353f6cfd81a45e2dadafda3d2c60d8188d0..0b5061128c45847b089871a382415a157e058328 100644 (file)
@@ -88,3 +88,77 @@ Reading bank 4:
 
 Word 0x00000002: 9f027772 00000004
 
+NAND Boot on i.MX6 with SPL support
+--------------------------------------
+
+Writing/updating boot image in nand device is not straight forward in
+i.MX6 platform and it requires boot control block(BCB) to be configured.
+
+BCB contains two data structures, Firmware Configuration Block(FCB) and
+Discovered Bad Block Table(DBBT). FCB has nand timings, DBBT search area,
+and firmware. See IMX6DQRM Section 8.5.2.2
+for more information.
+
+We can't use 'nand write' command to write SPL/firmware image directly
+like other platforms does. So we need special setup to write BCB block
+as per IMX6QDL reference manual 'nandbcb update' command do that job.
+
+for nand boot, up on reset bootrom look for FCB structure in
+first block's if FCB found the nand timings are loaded for
+further reads. once FCB read done, DTTB will be loaded and
+finally firmware will be loaded which is boot image.
+
+cmd_nandbcb will create FCB these structures
+by taking mtd partition as an example.
+- initial code will erase entire partition
+- followed by FCB setup, like first 2 blocks for FCB/DBBT write,
+  and next block for FW1/SPL
+- write firmware at FW1 block and
+- finally write fcb/dttb in first 2 block.
+
+Typical NAND BCB layout:
+=======================
+
+   no.of blocks = partition size / erasesize
+   no.of fcb/dbbt blocks = 2
+   FW1 offset = no.of fcb/dbbt
+
+block  0          1          2
+        -------------------------------
+       |FCB/DBBT 0|FCB/DBBT 1|  FW 1  |
+       --------------------------------
+
+On summary, nandbcb update will
+- erase the entire partition
+- create BCB by creating 2 FCB/BDDT block followed by
+  1 FW blocks based on partition size and erasesize.
+- fill FCB/DBBT structures
+- write FW/SPL in FW1
+- write FCB/DBBT in first 2 blocks
+
+step-1: write SPL
+
+icorem6qdl> ext4load mmc 0:1 $loadaddr SPL
+39936 bytes read in 10 ms (3.8 MiB/s)
+
+icorem6qdl> nandbcb update $loadaddr spl $filesize
+device 0 offset 0x0, size 0x9c00
+Erasing at 0x1c0000 -- 100% complete.
+NAND fw write: 0x80000 offset, 0xb000 bytes written: OK
+
+step-2: write u-boot-dtb.img
+
+icorem6qdl> nand erase.part uboot
+
+NAND erase.part: device 0 offset 0x200000, size 0x200000
+Erasing at 0x3c0000 -- 100% complete.
+OK
+
+icorem6qdl> ext4load mmc 0:1 $loadaddr u-boot-dtb.img
+589094 bytes read in 37 ms (15.2 MiB/s)
+
+icorem6qdl> nand write ${loadaddr} uboot ${filesize}
+
+NAND write: device 0 offset 0x200000, size 0x8fd26
+ 589094 bytes written: OK
+icorem6qdl>
index 7b81eacf50e66a622d93084be27c80a235b44d5c..5e92446c18c786690f6fda1a96b256957e143c16 100644 (file)
@@ -46,6 +46,20 @@ config CLK_BOSTON
        help
          Enable this to support the clocks
 
+config SPL_CLK_CCF
+       bool "SPL Common Clock Framework [CCF] support "
+       depends on SPL_CLK_IMX6Q
+       help
+         Enable this option if you want to (re-)use the Linux kernel's Common
+         Clock Framework [CCF] code in U-Boot's SPL.
+
+config CLK_CCF
+       bool "Common Clock Framework [CCF] support "
+       depends on CLK_IMX6Q || SANDBOX_CLK_CCF
+       help
+         Enable this option if you want to (re-)use the Linux kernel's Common
+         Clock Framework [CCF] code in U-Boot's clock driver.
+
 config CLK_STM32F
        bool "Enable clock driver support for STM32F family"
        depends on CLK && (STM32F7 || STM32F4)
@@ -125,4 +139,12 @@ config CLK_MPC83XX
        help
          Support for the clock driver of the MPC83xx series of SoCs.
 
+config SANDBOX_CLK_CCF
+       bool "Sandbox Common Clock Framework [CCF] support "
+       depends on SANDBOX
+       select CLK_CCF
+       help
+         Enable this option if you want to test the Linux kernel's Common
+         Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
+
 endmenu
index f0ced49e5a3b6287124180270a2f789e06e30178..b7fec605c6ced602dcc19dab63be35f26977134c 100644 (file)
@@ -7,6 +7,8 @@
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_rate.o
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_factor.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk.o clk-divider.o clk-mux.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk-fixed-factor.o
 
 obj-y += analogbits/
 obj-y += imx/
@@ -37,5 +39,6 @@ obj-$(CONFIG_ICS8N3QV01) += ics8n3qv01.o
 obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
 obj-$(CONFIG_SANDBOX) += clk_sandbox.o
 obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
+obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
 obj-$(CONFIG_STM32H7) += clk_stm32h7.o
 obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
new file mode 100644 (file)
index 0000000..6921c76
--- /dev/null
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+#include <linux/clk-provider.h>
+#include <div64.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_CCF_DIVIDER "ccf_clk_divider"
+
+static unsigned int _get_table_div(const struct clk_div_table *table,
+                                  unsigned int val)
+{
+       const struct clk_div_table *clkt;
+
+       for (clkt = table; clkt->div; clkt++)
+               if (clkt->val == val)
+                       return clkt->div;
+       return 0;
+}
+
+static unsigned int _get_div(const struct clk_div_table *table,
+                            unsigned int val, unsigned long flags, u8 width)
+{
+       if (flags & CLK_DIVIDER_ONE_BASED)
+               return val;
+       if (flags & CLK_DIVIDER_POWER_OF_TWO)
+               return 1 << val;
+       if (flags & CLK_DIVIDER_MAX_AT_ZERO)
+               return val ? val : clk_div_mask(width) + 1;
+       if (table)
+               return _get_table_div(table, val);
+       return val + 1;
+}
+
+unsigned long divider_recalc_rate(struct clk *hw, unsigned long parent_rate,
+                                 unsigned int val,
+                                 const struct clk_div_table *table,
+                                 unsigned long flags, unsigned long width)
+{
+       unsigned int div;
+
+       div = _get_div(table, val, flags, width);
+       if (!div) {
+               WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
+                    "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
+                    clk_hw_get_name(hw));
+               return parent_rate;
+       }
+
+       return DIV_ROUND_UP_ULL((u64)parent_rate, div);
+}
+
+static ulong clk_divider_recalc_rate(struct clk *clk)
+{
+       struct clk_divider *divider =
+               to_clk_divider(dev_get_clk_ptr(clk->dev));
+       unsigned long parent_rate = clk_get_parent_rate(clk);
+       unsigned int val;
+
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+       val = divider->io_divider_val;
+#else
+       val = readl(divider->reg);
+#endif
+       val >>= divider->shift;
+       val &= clk_div_mask(divider->width);
+
+       return divider_recalc_rate(clk, parent_rate, val, divider->table,
+                                  divider->flags, divider->width);
+}
+
+const struct clk_ops clk_divider_ops = {
+       .get_rate = clk_divider_recalc_rate,
+};
+
+static struct clk *_register_divider(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags, const struct clk_div_table *table)
+{
+       struct clk_divider *div;
+       struct clk *clk;
+       int ret;
+
+       if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
+               if (width + shift > 16) {
+                       pr_warn("divider value exceeds LOWORD field\n");
+                       return ERR_PTR(-EINVAL);
+               }
+       }
+
+       /* allocate the divider */
+       div = kzalloc(sizeof(*div), GFP_KERNEL);
+       if (!div)
+               return ERR_PTR(-ENOMEM);
+
+       /* struct clk_divider assignments */
+       div->reg = reg;
+       div->shift = shift;
+       div->width = width;
+       div->flags = clk_divider_flags;
+       div->table = table;
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+       div->io_divider_val = *(u32 *)reg;
+#endif
+
+       /* register the clock */
+       clk = &div->clk;
+
+       ret = clk_register(clk, UBOOT_DM_CLK_CCF_DIVIDER, name, parent_name);
+       if (ret) {
+               kfree(div);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+struct clk *clk_register_divider(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags)
+{
+       struct clk *clk;
+
+       clk =  _register_divider(dev, name, parent_name, flags, reg, shift,
+                                width, clk_divider_flags, NULL);
+       if (IS_ERR(clk))
+               return ERR_CAST(clk);
+       return clk;
+}
+
+U_BOOT_DRIVER(ccf_clk_divider) = {
+       .name   = UBOOT_DM_CLK_CCF_DIVIDER,
+       .id     = UCLASS_CLK,
+       .ops    = &clk_divider_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
new file mode 100644 (file)
index 0000000..711b058
--- /dev/null
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ */
+#include <common.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <div64.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
+
+static ulong clk_factor_recalc_rate(struct clk *clk)
+{
+       struct clk_fixed_factor *fix =
+               to_clk_fixed_factor(dev_get_clk_ptr(clk->dev));
+       unsigned long parent_rate = clk_get_parent_rate(clk);
+       unsigned long long int rate;
+
+       rate = (unsigned long long int)parent_rate * fix->mult;
+       do_div(rate, fix->div);
+       return (ulong)rate;
+}
+
+const struct clk_ops ccf_clk_fixed_factor_ops = {
+       .get_rate = clk_factor_recalc_rate,
+};
+
+struct clk *clk_hw_register_fixed_factor(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               unsigned int mult, unsigned int div)
+{
+       struct clk_fixed_factor *fix;
+       struct clk *clk;
+       int ret;
+
+       fix = kzalloc(sizeof(*fix), GFP_KERNEL);
+       if (!fix)
+               return ERR_PTR(-ENOMEM);
+
+       /* struct clk_fixed_factor assignments */
+       fix->mult = mult;
+       fix->div = div;
+       clk = &fix->clk;
+
+       ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, name,
+                          parent_name);
+       if (ret) {
+               kfree(fix);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned int mult, unsigned int div)
+{
+       struct clk *clk;
+
+       clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
+                                         div);
+       if (IS_ERR(clk))
+               return ERR_CAST(clk);
+       return clk;
+}
+
+U_BOOT_DRIVER(imx_clk_fixed_factor) = {
+       .name   = UBOOT_DM_CLK_IMX_FIXED_FACTOR,
+       .id     = UCLASS_CLK,
+       .ops    = &ccf_clk_fixed_factor_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
new file mode 100644 (file)
index 0000000..3c075aa
--- /dev/null
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * Simple multiplexer clock implementation
+ */
+
+/*
+ * U-Boot CCF porting node:
+ *
+ * The Linux kernel - as of tag: 5.0-rc3 is using also the imx_clk_fixup_mux()
+ * version of CCF mux. It is used on e.g. imx6q to provide fixes (like
+ * imx_cscmr1_fixup) for broken HW.
+ *
+ * At least for IMX6Q (but NOT IMX6QP) it is important when we set the parent
+ * clock.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_CCF_MUX "ccf_clk_mux"
+
+int clk_mux_val_to_index(struct clk *clk, u32 *table, unsigned int flags,
+                        unsigned int val)
+{
+       struct clk_mux *mux = to_clk_mux(clk);
+       int num_parents = mux->num_parents;
+
+       if (table) {
+               int i;
+
+               for (i = 0; i < num_parents; i++)
+                       if (table[i] == val)
+                               return i;
+               return -EINVAL;
+       }
+
+       if (val && (flags & CLK_MUX_INDEX_BIT))
+               val = ffs(val) - 1;
+
+       if (val && (flags & CLK_MUX_INDEX_ONE))
+               val--;
+
+       if (val >= num_parents)
+               return -EINVAL;
+
+       return val;
+}
+
+static u8 clk_mux_get_parent(struct clk *clk)
+{
+       struct clk_mux *mux = to_clk_mux(clk);
+       u32 val;
+
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+       val = mux->io_mux_val;
+#else
+       val = readl(mux->reg);
+#endif
+       val >>= mux->shift;
+       val &= mux->mask;
+
+       return clk_mux_val_to_index(clk, mux->table, mux->flags, val);
+}
+
+const struct clk_ops clk_mux_ops = {
+               .get_rate = clk_generic_get_rate,
+};
+
+struct clk *clk_hw_register_mux_table(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags,
+               void __iomem *reg, u8 shift, u32 mask,
+               u8 clk_mux_flags, u32 *table)
+{
+       struct clk_mux *mux;
+       struct clk *clk;
+       u8 width = 0;
+       int ret;
+
+       if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
+               width = fls(mask) - ffs(mask) + 1;
+               if (width + shift > 16) {
+                       pr_err("mux value exceeds LOWORD field\n");
+                       return ERR_PTR(-EINVAL);
+               }
+       }
+
+       /* allocate the mux */
+       mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+       if (!mux)
+               return ERR_PTR(-ENOMEM);
+
+       /* U-boot specific assignments */
+       mux->parent_names = parent_names;
+       mux->num_parents = num_parents;
+
+       /* struct clk_mux assignments */
+       mux->reg = reg;
+       mux->shift = shift;
+       mux->mask = mask;
+       mux->flags = clk_mux_flags;
+       mux->table = table;
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+       mux->io_mux_val = *(u32 *)reg;
+#endif
+
+       clk = &mux->clk;
+
+       /*
+        * Read the current mux setup - so we assign correct parent.
+        *
+        * Changing parent would require changing internals of udevice struct
+        * for the corresponding clock (to do that define .set_parent() method.
+        */
+       ret = clk_register(clk, UBOOT_DM_CLK_CCF_MUX, name,
+                          parent_names[clk_mux_get_parent(clk)]);
+       if (ret) {
+               kfree(mux);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags,
+               void __iomem *reg, u8 shift, u32 mask,
+               u8 clk_mux_flags, u32 *table)
+{
+       struct clk *clk;
+
+       clk = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
+                                      flags, reg, shift, mask, clk_mux_flags,
+                                      table);
+       if (IS_ERR(clk))
+               return ERR_CAST(clk);
+       return clk;
+}
+
+struct clk *clk_register_mux(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_mux_flags)
+{
+       u32 mask = BIT(width) - 1;
+
+       return clk_register_mux_table(dev, name, parent_names, num_parents,
+                                     flags, reg, shift, mask, clk_mux_flags,
+                                     NULL);
+}
+
+U_BOOT_DRIVER(ccf_clk_mux) = {
+       .name   = UBOOT_DM_CLK_CCF_MUX,
+       .id     = UCLASS_CLK,
+       .ops    = &clk_mux_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
index 06a8258d5faceb205404ffe4fed553b829feedac..85dfe712f5acf76dbf4f2bc2b7a3d496dccff66f 100644 (file)
@@ -13,6 +13,7 @@
 #include <dm/read.h>
 #include <dt-structs.h>
 #include <errno.h>
+#include <linux/clk-provider.h>
 
 static inline const struct clk_ops *clk_dev_ops(struct udevice *dev)
 {
@@ -381,6 +382,43 @@ ulong clk_get_rate(struct clk *clk)
        return ops->get_rate(clk);
 }
 
+struct clk *clk_get_parent(struct clk *clk)
+{
+       struct udevice *pdev;
+       struct clk *pclk;
+
+       debug("%s(clk=%p)\n", __func__, clk);
+
+       pdev = dev_get_parent(clk->dev);
+       pclk = dev_get_clk_ptr(pdev);
+       if (!pclk)
+               return ERR_PTR(-ENODEV);
+
+       return pclk;
+}
+
+long long clk_get_parent_rate(struct clk *clk)
+{
+       const struct clk_ops *ops;
+       struct clk *pclk;
+
+       debug("%s(clk=%p)\n", __func__, clk);
+
+       pclk = clk_get_parent(clk);
+       if (IS_ERR(pclk))
+               return -ENODEV;
+
+       ops = clk_dev_ops(pclk->dev);
+       if (!ops->get_rate)
+               return -ENOSYS;
+
+       /* Read the 'rate' if not already set or if proper flag set*/
+       if (!pclk->rate || pclk->flags & CLK_GET_RATE_NOCACHE)
+               pclk->rate = clk_get_rate(pclk);
+
+       return pclk->rate;
+}
+
 ulong clk_set_rate(struct clk *clk, ulong rate)
 {
        const struct clk_ops *ops = clk_dev_ops(clk->dev);
@@ -455,6 +493,28 @@ int clk_disable_bulk(struct clk_bulk *bulk)
        return 0;
 }
 
+int clk_get_by_id(ulong id, struct clk **clkp)
+{
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       ret = uclass_get(UCLASS_CLK, &uc);
+       if (ret)
+               return ret;
+
+       uclass_foreach_dev(dev, uc) {
+               struct clk *clk = dev_get_clk_ptr(dev);
+
+               if (clk && clk->id == id) {
+                       *clkp = clk;
+                       return 0;
+               }
+       }
+
+       return -ENOENT;
+}
+
 UCLASS_DRIVER(clk) = {
        .id             = UCLASS_CLK,
        .name           = "clk",
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
new file mode 100644 (file)
index 0000000..7d748c9
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+#include <clk.h>
+
+int clk_register(struct clk *clk, const char *drv_name,
+                const char *name, const char *parent_name)
+{
+       struct udevice *parent;
+       struct driver *drv;
+       int ret;
+
+       ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent);
+       if (ret)
+               printf("%s: UCLASS parent: 0x%p\n", __func__, parent);
+
+       debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, parent->name,
+             parent);
+
+       drv = lists_driver_lookup_name(drv_name);
+       if (!drv) {
+               printf("%s: %s is not a valid driver name\n",
+                      __func__, drv_name);
+               return -ENOENT;
+       }
+
+       ret = device_bind(parent, drv, name, NULL, -1, &clk->dev);
+       if (ret) {
+               printf("%s: CLK: %s driver bind error [%d]!\n", __func__, name,
+                      ret);
+               return ret;
+       }
+
+       /* Store back pointer to clk from udevice */
+       clk->dev->uclass_priv = clk;
+
+       return 0;
+}
+
+ulong clk_generic_get_rate(struct clk *clk)
+{
+       return clk_get_parent_rate(clk);
+}
+
+const char *clk_hw_get_name(const struct clk *hw)
+{
+       return hw->dev->name;
+}
index 5fa20a84dbb02bf0ee85331e44f723d64dcbfc36..dcdb6ddf5cf898d40ffec551b0c742b55734e58e 100644 (file)
@@ -24,9 +24,6 @@ static ulong clk_fixed_factor_get_rate(struct clk *clk)
        uint64_t rate;
        struct clk_fixed_factor *ff = to_clk_fixed_factor(clk->dev);
 
-       if (clk->id != 0)
-               return -EINVAL;
-
        rate = clk_get_rate(&ff->parent);
        if (IS_ERR_VALUE(rate))
                return rate;
index d8d9f86c8642c927bce696ab97d111090895d8d0..1fdf8c4e540a7962297c53038a01916d33a3f11f 100644 (file)
@@ -8,6 +8,7 @@
 #include <dm.h>
 
 struct clk_fixed_rate {
+       struct clk clk;
        unsigned long fixed_rate;
 };
 
@@ -15,9 +16,6 @@ struct clk_fixed_rate {
 
 static ulong clk_fixed_rate_get_rate(struct clk *clk)
 {
-       if (clk->id != 0)
-               return -EINVAL;
-
        return to_clk_fixed_rate(clk->dev)->fixed_rate;
 }
 
@@ -27,10 +25,14 @@ const struct clk_ops clk_fixed_rate_ops = {
 
 static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev)
 {
+       struct clk *clk = &to_clk_fixed_rate(dev)->clk;
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
        to_clk_fixed_rate(dev)->fixed_rate =
                dev_read_u32_default(dev, "clock-frequency", 0);
 #endif
+       /* Make fixed rate clock accessible from higher level struct clk */
+       dev->uclass_priv = clk;
+       clk->dev = dev;
 
        return 0;
 }
diff --git a/drivers/clk/clk_sandbox_ccf.c b/drivers/clk/clk_sandbox_ccf.c
new file mode 100644 (file)
index 0000000..edeb0f2
--- /dev/null
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Common Clock Framework [CCF] driver for Sandbox
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <clk.h>
+#include <asm/clk.h>
+#include <clk-uclass.h>
+#include <linux/clk-provider.h>
+#include <sandbox-clk.h>
+
+/*
+ * Sandbox implementation of CCF primitives necessary for clk-uclass testing
+ *
+ * --- Sandbox PLLv3 ---
+ */
+struct clk_pllv3 {
+       struct clk      clk;
+       u32             div_mask;
+       u32             div_shift;
+};
+
+static ulong clk_pllv3_get_rate(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_parent_rate(clk);
+
+       return parent_rate * 24;
+}
+
+static const struct clk_ops clk_pllv3_generic_ops = {
+       .get_rate       = clk_pllv3_get_rate,
+};
+
+struct clk *sandbox_clk_pllv3(enum sandbox_pllv3_type type, const char *name,
+                             const char *parent_name, void __iomem *base,
+                             u32 div_mask)
+{
+       struct clk_pllv3 *pll;
+       struct clk *clk;
+       char *drv_name = "sandbox_clk_pllv3";
+       int ret;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       pll->div_mask = div_mask;
+       clk = &pll->clk;
+
+       ret = clk_register(clk, drv_name, name, parent_name);
+       if (ret) {
+               kfree(pll);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+U_BOOT_DRIVER(sandbox_clk_pll_generic) = {
+       .name   = "sandbox_clk_pllv3",
+       .id     = UCLASS_CLK,
+       .ops    = &clk_pllv3_generic_ops,
+};
+
+/* --- Sandbox PLLv3 --- */
+/* --- Sandbox Gate  --- */
+struct clk_gate2 {
+       struct clk clk;
+       bool    state;
+};
+
+#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
+
+static int clk_gate2_enable(struct clk *clk)
+{
+       struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev));
+
+       gate->state = 1;
+       return 0;
+}
+
+static int clk_gate2_disable(struct clk *clk)
+{
+       struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev));
+
+       gate->state = 0;
+       return 0;
+}
+
+static const struct clk_ops clk_gate2_ops = {
+       .enable = clk_gate2_enable,
+       .disable = clk_gate2_disable,
+       .get_rate = clk_generic_get_rate,
+};
+
+struct clk *sandbox_clk_register_gate2(struct device *dev, const char *name,
+                                      const char *parent_name,
+                                      unsigned long flags, void __iomem *reg,
+                                      u8 bit_idx, u8 cgr_val,
+                                      u8 clk_gate2_flags)
+{
+       struct clk_gate2 *gate;
+       struct clk *clk;
+       int ret;
+
+       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+       if (!gate)
+               return ERR_PTR(-ENOMEM);
+
+       gate->state = 0;
+       clk = &gate->clk;
+
+       ret = clk_register(clk, "sandbox_clk_gate2", name, parent_name);
+       if (ret) {
+               kfree(gate);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+U_BOOT_DRIVER(sandbox_clk_gate2) = {
+       .name   = "sandbox_clk_gate2",
+       .id     = UCLASS_CLK,
+       .ops    = &clk_gate2_ops,
+};
+
+/* --- Sandbox Gate --- */
+/* The CCF core driver itself */
+static const struct udevice_id sandbox_clk_ccf_test_ids[] = {
+       { .compatible = "sandbox,clk-ccf" },
+       { }
+};
+
+static const char *const usdhc_sels[] = { "pll3_60m", "pll3_80m", };
+
+static int sandbox_clk_ccf_probe(struct udevice *dev)
+{
+       void *base = NULL;
+       u32 reg;
+
+       clk_dm(SANDBOX_CLK_PLL3,
+              sandbox_clk_pllv3(SANDBOX_PLLV3_USB, "pll3_usb_otg", "osc",
+                                base + 0x10, 0x3));
+
+       clk_dm(SANDBOX_CLK_PLL3_60M,
+              sandbox_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8));
+
+       clk_dm(SANDBOX_CLK_PLL3_80M,
+              sandbox_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1, 6));
+
+       /* The HW adds +1 to the divider value (2+1) is the divider */
+       reg = (2 << 19);
+       clk_dm(SANDBOX_CLK_ECSPI_ROOT,
+              sandbox_clk_divider("ecspi_root", "pll3_60m", &reg, 19, 6));
+
+       clk_dm(SANDBOX_CLK_ECSPI1,
+              sandbox_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0));
+
+       /* Select 'pll3_60m' */
+       reg = 0;
+       clk_dm(SANDBOX_CLK_USDHC1_SEL,
+              sandbox_clk_mux("usdhc1_sel", &reg, 16, 1, usdhc_sels,
+                              ARRAY_SIZE(usdhc_sels)));
+
+       /* Select 'pll3_80m' */
+       reg = BIT(17);
+       clk_dm(SANDBOX_CLK_USDHC2_SEL,
+              sandbox_clk_mux("usdhc2_sel", &reg, 17, 1, usdhc_sels,
+                              ARRAY_SIZE(usdhc_sels)));
+
+       return 0;
+}
+
+U_BOOT_DRIVER(sandbox_clk_ccf) = {
+       .name = "sandbox_clk_ccf",
+       .id = UCLASS_CLK,
+       .probe = sandbox_clk_ccf_probe,
+       .of_match = sandbox_clk_ccf_test_ids,
+};
index a6fb58d6cf68c4bfe53ad0080ce2de8bf107e4c9..3e6a980c8c3933d4aa0905bb1afea072b18eaeb2 100644 (file)
@@ -1,3 +1,19 @@
+config SPL_CLK_IMX6Q
+       bool "SPL clock support for i.MX6Q"
+       depends on ARCH_MX6 && SPL
+       select SPL_CLK
+       select SPL_CLK_CCF
+       help
+         This enables SPL DM/DTS support for clock driver in i.MX6Q platforms.
+
+config CLK_IMX6Q
+       bool "Clock support for i.MX6Q"
+       depends on ARCH_MX6
+       select CLK
+       select CLK_CCF
+       help
+         This enables DM/DTS support for clock driver in i.MX6Q platforms.
+
 config CLK_IMX8
        bool "Clock support for i.MX8"
        depends on ARCH_IMX8
index eb379c188aebc82f0f9a8bd4236c1b4fa6cec565..105a58ca907eddb8c5b869a7f905a13b5034fa51 100644 (file)
@@ -2,6 +2,8 @@
 #
 # SPDX-License-Identifier: GPL-2.0
 
+obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk-gate2.o clk-pllv3.o clk-pfd.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_IMX6Q) += clk-imx6q.o
 obj-$(CONFIG_CLK_IMX8) += clk-imx8.o
 
 ifdef CONFIG_CLK_IMX8
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
new file mode 100644 (file)
index 0000000..571be32
--- /dev/null
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * 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.
+ *
+ * Gated clock implementation
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_GATE2 "imx_clk_gate2"
+
+struct clk_gate2 {
+       struct clk clk;
+       void __iomem    *reg;
+       u8              bit_idx;
+       u8              cgr_val;
+       u8              flags;
+};
+
+#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
+
+static int clk_gate2_enable(struct clk *clk)
+{
+       struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev));
+       u32 reg;
+
+       reg = readl(gate->reg);
+       reg &= ~(3 << gate->bit_idx);
+       reg |= gate->cgr_val << gate->bit_idx;
+       writel(reg, gate->reg);
+
+       return 0;
+}
+
+static int clk_gate2_disable(struct clk *clk)
+{
+       struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev));
+       u32 reg;
+
+       reg = readl(gate->reg);
+       reg &= ~(3 << gate->bit_idx);
+       writel(reg, gate->reg);
+
+       return 0;
+}
+
+static const struct clk_ops clk_gate2_ops = {
+       .enable = clk_gate2_enable,
+       .disable = clk_gate2_disable,
+       .get_rate = clk_generic_get_rate,
+};
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 bit_idx, u8 cgr_val,
+               u8 clk_gate2_flags)
+{
+       struct clk_gate2 *gate;
+       struct clk *clk;
+       int ret;
+
+       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+       if (!gate)
+               return ERR_PTR(-ENOMEM);
+
+       gate->reg = reg;
+       gate->bit_idx = bit_idx;
+       gate->cgr_val = cgr_val;
+       gate->flags = clk_gate2_flags;
+
+       clk = &gate->clk;
+
+       ret = clk_register(clk, UBOOT_DM_CLK_IMX_GATE2, name, parent_name);
+       if (ret) {
+               kfree(gate);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+U_BOOT_DRIVER(clk_gate2) = {
+       .name   = UBOOT_DM_CLK_IMX_GATE2,
+       .id     = UCLASS_CLK,
+       .ops    = &clk_gate2_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
new file mode 100644 (file)
index 0000000..92e9337
--- /dev/null
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <dt-bindings/clock/imx6qdl-clock.h>
+
+#include "clk.h"
+
+static int imx6q_check_id(ulong id)
+{
+       if (id < IMX6QDL_CLK_DUMMY || id >= IMX6QDL_CLK_END) {
+               printf("%s: Invalid clk ID #%lu\n", __func__, id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static ulong imx6q_clk_get_rate(struct clk *clk)
+{
+       struct clk *c;
+       int ret;
+
+       debug("%s(#%lu)\n", __func__, clk->id);
+
+       ret = imx6q_check_id(clk->id);
+       if (ret)
+               return ret;
+
+       ret = clk_get_by_id(clk->id, &c);
+       if (ret)
+               return ret;
+
+       return clk_get_rate(c);
+}
+
+static ulong imx6q_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
+
+       return rate;
+}
+
+static int __imx6q_clk_enable(struct clk *clk, bool enable)
+{
+       struct clk *c;
+       int ret = 0;
+
+       debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
+
+       ret = imx6q_check_id(clk->id);
+       if (ret)
+               return ret;
+
+       ret = clk_get_by_id(clk->id, &c);
+       if (ret)
+               return ret;
+
+       if (enable)
+               ret = clk_enable(c);
+       else
+               ret = clk_disable(c);
+
+       return ret;
+}
+
+static int imx6q_clk_disable(struct clk *clk)
+{
+       return __imx6q_clk_enable(clk, 0);
+}
+
+static int imx6q_clk_enable(struct clk *clk)
+{
+       return __imx6q_clk_enable(clk, 1);
+}
+
+static struct clk_ops imx6q_clk_ops = {
+       .set_rate = imx6q_clk_set_rate,
+       .get_rate = imx6q_clk_get_rate,
+       .enable = imx6q_clk_enable,
+       .disable = imx6q_clk_disable,
+};
+
+static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+
+static int imx6q_clk_probe(struct udevice *dev)
+{
+       void *base;
+
+       /* Anatop clocks */
+       base = (void *)ANATOP_BASE_ADDR;
+
+       clk_dm(IMX6QDL_CLK_PLL2,
+              imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc",
+                            base + 0x30, 0x1));
+       clk_dm(IMX6QDL_CLK_PLL3_USB_OTG,
+              imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc",
+                            base + 0x10, 0x3));
+       clk_dm(IMX6QDL_CLK_PLL3_60M,
+              imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8));
+       clk_dm(IMX6QDL_CLK_PLL2_PFD0_352M,
+              imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0));
+       clk_dm(IMX6QDL_CLK_PLL2_PFD2_396M,
+              imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2));
+
+       /* CCM clocks */
+       base = dev_read_addr_ptr(dev);
+       if (base == (void *)FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       clk_dm(IMX6QDL_CLK_USDHC1_SEL,
+              imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1,
+                          usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+       clk_dm(IMX6QDL_CLK_USDHC2_SEL,
+              imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1,
+                          usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+       clk_dm(IMX6QDL_CLK_USDHC3_SEL,
+              imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1,
+                          usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+       clk_dm(IMX6QDL_CLK_USDHC4_SEL,
+              imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1,
+                          usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+
+       clk_dm(IMX6QDL_CLK_USDHC1_PODF,
+              imx_clk_divider("usdhc1_podf", "usdhc1_sel",
+                              base + 0x24, 11, 3));
+       clk_dm(IMX6QDL_CLK_USDHC2_PODF,
+              imx_clk_divider("usdhc2_podf", "usdhc2_sel",
+                              base + 0x24, 16, 3));
+       clk_dm(IMX6QDL_CLK_USDHC3_PODF,
+              imx_clk_divider("usdhc3_podf", "usdhc3_sel",
+                              base + 0x24, 19, 3));
+       clk_dm(IMX6QDL_CLK_USDHC4_PODF,
+              imx_clk_divider("usdhc4_podf", "usdhc4_sel",
+                              base + 0x24, 22, 3));
+
+       clk_dm(IMX6QDL_CLK_ECSPI_ROOT,
+              imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6));
+
+       clk_dm(IMX6QDL_CLK_ECSPI1,
+              imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0));
+       clk_dm(IMX6QDL_CLK_ECSPI2,
+              imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2));
+       clk_dm(IMX6QDL_CLK_ECSPI3,
+              imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4));
+       clk_dm(IMX6QDL_CLK_ECSPI4,
+              imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6));
+       clk_dm(IMX6QDL_CLK_USDHC1,
+              imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2));
+       clk_dm(IMX6QDL_CLK_USDHC2,
+              imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4));
+       clk_dm(IMX6QDL_CLK_USDHC3,
+              imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6));
+       clk_dm(IMX6QDL_CLK_USDHC4,
+              imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8));
+
+       return 0;
+}
+
+static const struct udevice_id imx6q_clk_ids[] = {
+       { .compatible = "fsl,imx6q-ccm" },
+       { },
+};
+
+U_BOOT_DRIVER(imx6q_clk) = {
+       .name = "clk_imx6q",
+       .id = UCLASS_CLK,
+       .of_match = imx6q_clk_ids,
+       .ops = &imx6q_clk_ops,
+       .probe = imx6q_clk_probe,
+       .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c
new file mode 100644 (file)
index 0000000..188b2b3
--- /dev/null
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * 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 <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <div64.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_PFD "imx_clk_pfd"
+
+struct clk_pfd {
+       struct clk      clk;
+       void __iomem    *reg;
+       u8              idx;
+};
+
+#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk)
+
+#define SET    0x4
+#define CLR    0x8
+#define OTG    0xc
+
+static unsigned long clk_pfd_recalc_rate(struct clk *clk)
+{
+       struct clk_pfd *pfd =
+               to_clk_pfd(dev_get_clk_ptr(clk->dev));
+       unsigned long parent_rate = clk_get_parent_rate(clk);
+       u64 tmp = parent_rate;
+       u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
+
+       tmp *= 18;
+       do_div(tmp, frac);
+
+       return tmp;
+}
+
+static const struct clk_ops clk_pfd_ops = {
+       .get_rate       = clk_pfd_recalc_rate,
+};
+
+struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+                       void __iomem *reg, u8 idx)
+{
+       struct clk_pfd *pfd;
+       struct clk *clk;
+       int ret;
+
+       pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
+       if (!pfd)
+               return ERR_PTR(-ENOMEM);
+
+       pfd->reg = reg;
+       pfd->idx = idx;
+
+       /* register the clock */
+       clk = &pfd->clk;
+
+       ret = clk_register(clk, UBOOT_DM_CLK_IMX_PFD, name, parent_name);
+       if (ret) {
+               kfree(pfd);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+U_BOOT_DRIVER(clk_pfd) = {
+       .name   = UBOOT_DM_CLK_IMX_PFD,
+       .id     = UCLASS_CLK,
+       .ops    = &clk_pfd_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
new file mode 100644 (file)
index 0000000..fbb7b24
--- /dev/null
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_PLLV3 "imx_clk_pllv3"
+
+struct clk_pllv3 {
+       struct clk      clk;
+       void __iomem    *base;
+       u32             div_mask;
+       u32             div_shift;
+};
+
+#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
+
+static ulong clk_pllv3_get_rate(struct clk *clk)
+{
+       struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
+       unsigned long parent_rate = clk_get_parent_rate(clk);
+
+       u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
+
+       return (div == 1) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static const struct clk_ops clk_pllv3_generic_ops = {
+       .get_rate       = clk_pllv3_get_rate,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+                         const char *parent_name, void __iomem *base,
+                         u32 div_mask)
+{
+       struct clk_pllv3 *pll;
+       struct clk *clk;
+       char *drv_name;
+       int ret;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       switch (type) {
+       case IMX_PLLV3_GENERIC:
+       case IMX_PLLV3_USB:
+               drv_name = UBOOT_DM_CLK_IMX_PLLV3;
+               break;
+       default:
+               kfree(pll);
+               return ERR_PTR(-ENOTSUPP);
+       }
+
+       pll->base = base;
+       pll->div_mask = div_mask;
+       clk = &pll->clk;
+
+       ret = clk_register(clk, drv_name, name, parent_name);
+       if (ret) {
+               kfree(pll);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+U_BOOT_DRIVER(clk_pllv3_generic) = {
+       .name   = UBOOT_DM_CLK_IMX_PLLV3,
+       .id     = UCLASS_CLK,
+       .ops    = &clk_pllv3_generic_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
new file mode 100644 (file)
index 0000000..e6d5183
--- /dev/null
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+#ifndef __MACH_IMX_CLK_H
+#define __MACH_IMX_CLK_H
+
+#include <linux/clk-provider.h>
+
+enum imx_pllv3_type {
+       IMX_PLLV3_GENERIC,
+       IMX_PLLV3_SYS,
+       IMX_PLLV3_USB,
+       IMX_PLLV3_USB_VF610,
+       IMX_PLLV3_AV,
+       IMX_PLLV3_ENET,
+       IMX_PLLV3_ENET_IMX7,
+       IMX_PLLV3_SYS_VF610,
+       IMX_PLLV3_DDR_IMX7,
+};
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 bit_idx, u8 cgr_val,
+               u8 clk_gate_flags);
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+                         const char *parent_name, void __iomem *base,
+                         u32 div_mask);
+
+static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
+                                       void __iomem *reg, u8 shift)
+{
+       return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+                       shift, 0x3, 0);
+}
+
+static inline struct clk *imx_clk_fixed_factor(const char *name,
+               const char *parent, unsigned int mult, unsigned int div)
+{
+       return clk_register_fixed_factor(NULL, name, parent,
+                       CLK_SET_RATE_PARENT, mult, div);
+}
+
+static inline struct clk *imx_clk_divider(const char *name, const char *parent,
+               void __iomem *reg, u8 shift, u8 width)
+{
+       return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+                       reg, shift, width, 0);
+}
+
+struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+                       void __iomem *reg, u8 idx);
+
+struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
+                             u8 shift, u8 width, const char * const *parents,
+                             int num_parents, void (*fixup)(u32 *val));
+
+static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
+                       u8 shift, u8 width, const char * const *parents,
+                       int num_parents)
+{
+       return clk_register_mux(NULL, name, parents, num_parents,
+                       CLK_SET_RATE_NO_REPARENT, reg, shift,
+                       width, 0);
+}
+
+#endif /* __MACH_IMX_CLK_H */
index 8bd30c75b2ffc96a93fb6886d0876150c65a3e39..64ab7a303f111f38d6998cd96a4d4dc655af0665 100644 (file)
@@ -31,7 +31,7 @@ struct mxc_bank_info {
 };
 
 #ifndef CONFIG_DM_GPIO
-#define GPIO_TO_PORT(n)                (n / 32)
+#define GPIO_TO_PORT(n)                ((n) / 32)
 
 /* GPIO port description */
 static unsigned long gpio_ports[] = {
index c2c8a25886ab18233d2416cbe5d0c32e1bbe9fc4..b2451fdda8ab31a917565cf2b7d78e2e68cf7436 100644 (file)
@@ -51,6 +51,7 @@ void mxs_gpio_init(void)
        }
 }
 
+#if !CONFIG_IS_ENABLED(DM_GPIO)
 int gpio_get_value(unsigned gpio)
 {
        uint32_t bank = PAD_BANK(gpio);
@@ -127,3 +128,150 @@ int name_to_gpio(const char *name)
 
        return (bank << MXS_PAD_BANK_SHIFT) | (pin << MXS_PAD_PIN_SHIFT);
 }
+#else /* CONFIG_DM_GPIO */
+#include <dm.h>
+#include <asm/gpio.h>
+#include <asm/arch/gpio.h>
+#define MXS_MAX_GPIO_PER_BANK          32
+
+DECLARE_GLOBAL_DATA_PTR;
+/*
+ * According to i.MX28 Reference Manual:
+ * 'i.MX28 Applications Processor Reference Manual, Rev. 1, 2010'
+ * The i.MX28 has following number of GPIOs available:
+ * Bank 0: 0-28 -> 29 PINS
+ * Bank 1: 0-31 -> 32 PINS
+ * Bank 2: 0-27 -> 28 PINS
+ * Bank 3: 0-30 -> 31 PINS
+ * Bank 4: 0-20 -> 21 PINS
+ */
+
+struct mxs_gpio_priv {
+       unsigned int bank;
+};
+
+static int mxs_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+       struct mxs_gpio_priv *priv = dev_get_priv(dev);
+       struct mxs_register_32 *reg =
+               (struct mxs_register_32 *)(MXS_PINCTRL_BASE +
+                                          PINCTRL_DIN(priv->bank));
+
+       return (readl(&reg->reg) >> offset) & 1;
+}
+
+static int mxs_gpio_set_value(struct udevice *dev, unsigned offset,
+                             int value)
+{
+       struct mxs_gpio_priv *priv = dev_get_priv(dev);
+       struct mxs_register_32 *reg =
+               (struct mxs_register_32 *)(MXS_PINCTRL_BASE +
+                                          PINCTRL_DOUT(priv->bank));
+       if (value)
+               writel(BIT(offset), &reg->reg_set);
+       else
+               writel(BIT(offset), &reg->reg_clr);
+
+       return 0;
+}
+
+static int mxs_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+       struct mxs_gpio_priv *priv = dev_get_priv(dev);
+       struct mxs_register_32 *reg =
+               (struct mxs_register_32 *)(MXS_PINCTRL_BASE +
+                                          PINCTRL_DOE(priv->bank));
+
+       writel(BIT(offset), &reg->reg_clr);
+
+       return 0;
+}
+
+static int mxs_gpio_direction_output(struct udevice *dev, unsigned offset,
+                                    int value)
+{
+       struct mxs_gpio_priv *priv = dev_get_priv(dev);
+       struct mxs_register_32 *reg =
+               (struct mxs_register_32 *)(MXS_PINCTRL_BASE +
+                                          PINCTRL_DOE(priv->bank));
+
+       mxs_gpio_set_value(dev, offset, value);
+
+       writel(BIT(offset), &reg->reg_set);
+
+       return 0;
+}
+
+static int mxs_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+       struct mxs_gpio_priv *priv = dev_get_priv(dev);
+       struct mxs_register_32 *reg =
+               (struct mxs_register_32 *)(MXS_PINCTRL_BASE +
+                                          PINCTRL_DOE(priv->bank));
+       bool is_output = !!(readl(&reg->reg) >> offset);
+
+       return is_output ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+static const struct dm_gpio_ops gpio_mxs_ops = {
+       .direction_input        = mxs_gpio_direction_input,
+       .direction_output       = mxs_gpio_direction_output,
+       .get_value              = mxs_gpio_get_value,
+       .set_value              = mxs_gpio_set_value,
+       .get_function           = mxs_gpio_get_function,
+};
+
+static int mxs_gpio_probe(struct udevice *dev)
+{
+       struct mxs_gpio_priv *priv = dev_get_priv(dev);
+       struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       struct fdtdec_phandle_args args;
+       int node = dev_of_offset(dev);
+       char name[16], *str;
+       fdt_addr_t addr;
+       int ret;
+
+       addr = devfdt_get_addr(dev);
+       if (addr == FDT_ADDR_T_NONE) {
+               printf("%s: No 'reg' property defined!\n", __func__);
+               return -EINVAL;
+       }
+
+       priv->bank = (unsigned int)addr;
+
+       snprintf(name, sizeof(name), "GPIO%d_", priv->bank);
+       str = strdup(name);
+       if (!str)
+               return -ENOMEM;
+
+       uc_priv->bank_name = str;
+
+       ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node, "gpio-ranges",
+                                            NULL, 3, 0, &args);
+       if (ret)
+               printf("%s: 'gpio-ranges' not defined - using default!\n",
+                      __func__);
+
+       uc_priv->gpio_count = ret == 0 ? args.args[2] : MXS_MAX_GPIO_PER_BANK;
+
+       debug("%s: %s: %d pins\n", __func__, uc_priv->bank_name,
+             uc_priv->gpio_count);
+
+       return 0;
+}
+
+static const struct udevice_id mxs_gpio_ids[] = {
+       { .compatible = "fsl,imx23-gpio" },
+       { .compatible = "fsl,imx28-gpio" },
+       { }
+};
+
+U_BOOT_DRIVER(gpio_mxs) = {
+       .name   = "gpio_mxs",
+       .id     = UCLASS_GPIO,
+       .ops    = &gpio_mxs_ops,
+       .probe  = mxs_gpio_probe,
+       .priv_auto_alloc_size = sizeof(struct mxs_gpio_priv),
+       .of_match = mxs_gpio_ids,
+};
+#endif /* CONFIG_DM_GPIO */
index d9c4d5d78406fc79281b641fc7ee0f371d985f4d..031bc0048b6ff266d45e4efd1d8e43e4ad46cfd5 100644 (file)
@@ -273,6 +273,34 @@ int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val)
        return 0;
 }
 
+int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
+                    s16 *celsius, s8 *tenths)
+{
+       struct udevice *dev = gd->arch.scu_dev;
+       int size = sizeof(struct sc_rpc_msg_s);
+       struct sc_rpc_msg_s msg;
+       int ret;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_TEMP;
+       RPC_U16(&msg, 0U) = (u16)resource;
+       RPC_U8(&msg, 2U) = (u8)temp;
+       RPC_SIZE(&msg) = 2U;
+
+       ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+       if (ret < 0)
+               return ret;
+
+       if (celsius)
+               *celsius = RPC_I16(&msg, 0U);
+
+       if (tenths)
+               *tenths = RPC_I8(&msg, 2U);
+
+       return 0;
+}
+
 /* RM */
 sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
 {
index f3d687ae806f6aded5f9f6f210e7b93e39f78c44..350812a04ba982514d55dae3e0b7c0f44070d0e9 100644 (file)
@@ -84,7 +84,7 @@ static int mmc_spi_sendcmd(struct udevice *dev,
        cmdo[4] = cmdarg >> 8;
        cmdo[5] = cmdarg;
        cmdo[6] = (crc7(0, &cmdo[1], 5) << 1) | 0x01;
-       ret = dm_spi_xfer(dev, sizeof(cmdo) * 8, cmdo, NULL, 0);
+       ret = dm_spi_xfer(dev, sizeof(cmdo) * 8, cmdo, NULL, SPI_XFER_BEGIN);
        if (ret)
                return ret;
 
@@ -360,6 +360,8 @@ static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd,
        }
 
 done:
+       dm_spi_xfer(dev, 0, NULL, NULL, SPI_XFER_END);
+
        dm_spi_release_bus(dev);
 
        return ret;
index b93d77a39518ed0db5d48e7d151790bb04fcf172..a41b9620d0a6ad040f3e617b2fc93f91796c0903 100644 (file)
@@ -25,7 +25,7 @@
 #include <asm/mach-imx/regs-bch.h>
 #include <asm/mach-imx/regs-gpmi.h>
 #include <asm/arch/sys_proto.h>
-#include "mxs_nand.h"
+#include <mxs_nand.h>
 
 #define        MXS_NAND_DMA_DESCRIPTOR_COUNT           4
 
diff --git a/drivers/mtd/nand/raw/mxs_nand.h b/drivers/mtd/nand/raw/mxs_nand.h
deleted file mode 100644 (file)
index 4bd65cd..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * NXP GPMI NAND flash driver
- *
- * Copyright (C) 2018 Toradex
- * Authors:
- * Stefan Agner <stefan.agner@toradex.com>
- */
-
-#include <linux/mtd/mtd.h>
-#include <asm/cache.h>
-#include <nand.h>
-#include <asm/mach-imx/dma.h>
-
-/**
- * @gf_len:                   The length of Galois Field. (e.g., 13 or 14)
- * @ecc_strength:             A number that describes the strength of the ECC
- *                            algorithm.
- * @ecc_chunk_size:           The size, in bytes, of a single ECC chunk. Note
- *                            the first chunk in the page includes both data and
- *                            metadata, so it's a bit larger than this value.
- * @ecc_chunk_count:          The number of ECC chunks in the page,
- * @block_mark_byte_offset:   The byte offset in the ECC-based page view at
- *                            which the underlying physical block mark appears.
- * @block_mark_bit_offset:    The bit offset into the ECC-based page view at
- *                            which the underlying physical block mark appears.
- */
-struct bch_geometry {
-       unsigned int  gf_len;
-       unsigned int  ecc_strength;
-       unsigned int  ecc_chunk_size;
-       unsigned int  ecc_chunk_count;
-       unsigned int  block_mark_byte_offset;
-       unsigned int  block_mark_bit_offset;
-};
-
-struct mxs_nand_info {
-       struct nand_chip chip;
-       struct udevice *dev;
-       unsigned int    max_ecc_strength_supported;
-       bool            use_minimum_ecc;
-       int             cur_chip;
-
-       uint32_t        cmd_queue_len;
-       uint32_t        data_buf_size;
-       struct bch_geometry bch_geometry;
-
-       uint8_t         *cmd_buf;
-       uint8_t         *data_buf;
-       uint8_t         *oob_buf;
-
-       uint8_t         marking_block_bad;
-       uint8_t         raw_oob_mode;
-
-       struct mxs_gpmi_regs *gpmi_regs;
-       struct mxs_bch_regs *bch_regs;
-
-       /* Functions with altered behaviour */
-       int             (*hooked_read_oob)(struct mtd_info *mtd,
-                               loff_t from, struct mtd_oob_ops *ops);
-       int             (*hooked_write_oob)(struct mtd_info *mtd,
-                               loff_t to, struct mtd_oob_ops *ops);
-       int             (*hooked_block_markbad)(struct mtd_info *mtd,
-                               loff_t ofs);
-
-       /* DMA descriptors */
-       struct mxs_dma_desc     **desc;
-       uint32_t                desc_index;
-};
-
-int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info);
-int mxs_nand_init_spl(struct nand_chip *nand);
-int mxs_nand_setup_ecc(struct mtd_info *mtd);
index 44dec5dedf90f1ad754ad152b8767b2dd0d5b7e3..8ad7d618c64ee6bc8e10b118a62eaf25e708e033 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/printk.h>
 
-#include "mxs_nand.h"
+#include <mxs_nand.h>
 
 struct mxs_nand_dt_data {
        unsigned int max_ecc_strength_supported;
index ee7d9cb9571dd3548718579e85026c82223cc002..975a91a37d2e25e7ac89c4520bb02f4e24656546 100644 (file)
@@ -6,7 +6,7 @@
 #include <common.h>
 #include <nand.h>
 #include <malloc.h>
-#include "mxs_nand.h"
+#include <mxs_nand.h>
 
 static struct mtd_info *mtd;
 static struct nand_chip nand_chip;
index ec929760eee4768522bed3f564128b4963c717ea..a3920ba520e0eb9d414a0e2f5f913e0b52ab5b1e 100644 (file)
@@ -163,11 +163,15 @@ const struct flash_info spi_nor_ids[] = {
        { INFO("n25q128a13",  0x20ba18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
        { INFO("n25q256a",    0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
        { INFO("n25q256ax1",  0x20bb19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+       { INFO6("mt25qu512a",  0x20bb20, 0x104400, 64 * 1024, 1024,
+                SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
        { INFO("n25q512a",    0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
        { INFO("n25q512ax3",  0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
        { INFO("n25q00",      0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
        { INFO("n25q00a",     0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
        { INFO("mt25qu02g",   0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
+       { INFO("mt35xu512aba", 0x2c5b1a, 0,  128 * 1024,  512, USE_FSR | SPI_NOR_4B_OPCODES) },
+       { INFO("mt35xu02g",  0x2c5b1c, 0, 128 * 1024,  2048, USE_FSR | SPI_NOR_4B_OPCODES) },
 #endif
 #ifdef CONFIG_SPI_FLASH_SPANSION       /* SPANSION */
        /* Spansion/Cypress -- single (large) sector size only, at least
index 883b849b7831e9932b7b2e165c46f413e60ab370..0a1d228a8833a0ca680488d3e31eb77ba0806705 100644 (file)
@@ -235,7 +235,7 @@ config FEC_MXC_MDIO_BASE
 
 config FEC_MXC
        bool "FEC Ethernet controller"
-       depends on MX5 || MX6 || MX7 || IMX8 || VF610
+       depends on MX28 || MX5 || MX6 || MX7 || IMX8 || VF610
        help
          This driver supports the 10/100 Fast Ethernet controller for
          NXP i.MX processors.
index d7c080943a53984f895ef0de8f3da242575b1a53..96e3ad9a1a29b316404af4a79e4f36292fc91f2c 100644 (file)
@@ -1485,6 +1485,7 @@ static int fecmxc_ofdata_to_platdata(struct udevice *dev)
 }
 
 static const struct udevice_id fecmxc_ids[] = {
+       { .compatible = "fsl,imx28-fec" },
        { .compatible = "fsl,imx6q-fec" },
        { .compatible = "fsl,imx6sl-fec" },
        { .compatible = "fsl,imx6sx-fec" },
index 61f93be42d2c0b78e650f98138f0db30f2348391..f2e67ca2319b2d837595271c2aa8eabd9fccf6f7 100644 (file)
@@ -89,6 +89,16 @@ config PINCTRL_IMX8M
          only parses the 'fsl,pins' property and configure related
          registers.
 
+config PINCTRL_MXS
+       bool "NXP MXS pinctrl driver"
+       depends on ARCH_MX28 && PINCTRL_FULL
+       help
+         Say Y here to enable the i.MX mxs pinctrl driver
+
+         This option provides a simple pinctrl driver for i.MX mxs SoC
+         familiy, e.g. i.MX28. This feature depends on device tree
+         configuration.
+
 config PINCTRL_VYBRID
        bool "Vybrid (vf610) pinctrl driver"
        depends on ARCH_VF610 && PINCTRL_FULL
index b340d9448aa552a31eadd395c26d018ee6556bbb..b86448aac9a57bda6f27c70dd0f26db25eeb54f0 100644 (file)
@@ -6,4 +6,5 @@ obj-$(CONFIG_PINCTRL_IMX7ULP)           += pinctrl-imx7ulp.o
 obj-$(CONFIG_PINCTRL_IMX_SCU)          += pinctrl-scu.o
 obj-$(CONFIG_PINCTRL_IMX8)             += pinctrl-imx8.o
 obj-$(CONFIG_PINCTRL_IMX8M)            += pinctrl-imx8m.o
+obj-$(CONFIG_PINCTRL_MXS)              += pinctrl-mxs.o
 obj-$(CONFIG_PINCTRL_VYBRID)           += pinctrl-vf610.o
diff --git a/drivers/pinctrl/nxp/pinctrl-mxs.c b/drivers/pinctrl/nxp/pinctrl-mxs.c
new file mode 100644 (file)
index 0000000..6f6ca84
--- /dev/null
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <dm/read.h>
+#include "pinctrl-mxs.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mxs_pinctrl_priv {
+       void __iomem *base;
+       const struct mxs_regs *regs;
+};
+
+static unsigned long mxs_dt_node_to_map(struct udevice *conf)
+{
+       unsigned long config = 0;
+       int ret;
+       u32 val;
+
+       ret = dev_read_u32(conf, "fsl,drive-strength", &val);
+       if (!ret)
+               config = val | MA_PRESENT;
+
+       ret = dev_read_u32(conf, "fsl,voltage", &val);
+       if (!ret)
+               config |= val << VOL_SHIFT | VOL_PRESENT;
+
+       ret = dev_read_u32(conf, "fsl,pull-up", &val);
+       if (!ret)
+               config |= val << PULL_SHIFT | PULL_PRESENT;
+
+       return config;
+}
+
+static int mxs_pinctrl_set_mux(struct udevice *dev, u32 val, int bank, int pin)
+{
+       struct mxs_pinctrl_priv *iomux = dev_get_priv(dev);
+       int muxsel = MUXID_TO_MUXSEL(val), shift;
+       void __iomem *reg;
+
+       reg = iomux->base + iomux->regs->muxsel;
+       reg += bank * 0x20 + pin / 16 * 0x10;
+       shift = pin % 16 * 2;
+
+       mxs_pinctrl_rmwl(muxsel, 0x3, shift, reg);
+       debug(" mux %d,", muxsel);
+
+       return 0;
+}
+
+static int mxs_pinctrl_set_state(struct udevice *dev, struct udevice *conf)
+{
+       struct mxs_pinctrl_priv *iomux = dev_get_priv(dev);
+       u32 *pin_data, val, ma, vol, pull;
+       int npins, size, i, ret;
+       unsigned long config;
+
+       debug("\n%s: set state: %s\n", __func__, conf->name);
+
+       size = dev_read_size(conf, "fsl,pinmux-ids");
+       if (size < 0)
+               return size;
+
+       if (!size || size % sizeof(int)) {
+               dev_err(dev, "Invalid fsl,pinmux-ids property in %s\n",
+                       conf->name);
+               return -EINVAL;
+       }
+
+       npins = size / sizeof(int);
+
+       pin_data = devm_kzalloc(dev, size, 0);
+       if (!pin_data)
+               return -ENOMEM;
+
+       ret = dev_read_u32_array(conf, "fsl,pinmux-ids", pin_data, npins);
+       if (ret) {
+               dev_err(dev, "Error reading pin data.\n");
+               devm_kfree(dev, pin_data);
+               return -EINVAL;
+       }
+
+       config = mxs_dt_node_to_map(conf);
+
+       ma = CONFIG_TO_MA(config);
+       vol = CONFIG_TO_VOL(config);
+       pull = CONFIG_TO_PULL(config);
+
+       for (i = 0; i < npins; i++) {
+               int pinid, bank, pin, shift;
+               void __iomem *reg;
+
+               val = pin_data[i];
+
+               pinid = MUXID_TO_PINID(val);
+               bank = PINID_TO_BANK(pinid);
+               pin = PINID_TO_PIN(pinid);
+
+               debug("(val: 0x%x) pin %d,", val, pinid);
+               /* Setup pinmux */
+               mxs_pinctrl_set_mux(dev, val, bank, pin);
+
+               debug(" ma: %d, vol: %d, pull: %d\n", ma, vol, pull);
+
+               /* drive */
+               reg = iomux->base + iomux->regs->drive;
+               reg += bank * 0x40 + pin / 8 * 0x10;
+
+               /* mA */
+               if (config & MA_PRESENT) {
+                       shift = pin % 8 * 4;
+                       mxs_pinctrl_rmwl(ma, 0x3, shift, reg);
+               }
+
+               /* vol */
+               if (config & VOL_PRESENT) {
+                       shift = pin % 8 * 4 + 2;
+                       if (vol)
+                               writel(1 << shift, reg + SET);
+                       else
+                               writel(1 << shift, reg + CLR);
+               }
+
+               /* pull */
+               if (config & PULL_PRESENT) {
+                       reg = iomux->base + iomux->regs->pull;
+                       reg += bank * 0x10;
+                       shift = pin;
+                       if (pull)
+                               writel(1 << shift, reg + SET);
+                       else
+                               writel(1 << shift, reg + CLR);
+               }
+       }
+
+       devm_kfree(dev, pin_data);
+       return 0;
+}
+
+static struct pinctrl_ops mxs_pinctrl_ops = {
+       .set_state = mxs_pinctrl_set_state,
+};
+
+static int mxs_pinctrl_probe(struct udevice *dev)
+{
+       struct mxs_pinctrl_priv *iomux = dev_get_priv(dev);
+
+       iomux->base = dev_read_addr_ptr(dev);
+       iomux->regs = (struct mxs_regs *)dev_get_driver_data(dev);
+
+       return 0;
+}
+
+static const struct mxs_regs imx23_regs = {
+       .muxsel = 0x100,
+       .drive = 0x200,
+       .pull = 0x400,
+};
+
+static const struct mxs_regs imx28_regs = {
+       .muxsel = 0x100,
+       .drive = 0x300,
+       .pull = 0x600,
+};
+
+static const struct udevice_id mxs_pinctrl_match[] = {
+       { .compatible = "fsl,imx23-pinctrl", .data = (ulong)&imx23_regs },
+       { .compatible = "fsl,imx28-pinctrl", .data = (ulong)&imx28_regs },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mxs_pinctrl) = {
+       .name = "mxs-pinctrl",
+       .id = UCLASS_PINCTRL,
+       .of_match = of_match_ptr(mxs_pinctrl_match),
+       .probe = mxs_pinctrl_probe,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+       .bind           = dm_scan_fdt_dev,
+#endif
+       .priv_auto_alloc_size = sizeof(struct mxs_pinctrl_priv),
+       .ops = &mxs_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/nxp/pinctrl-mxs.h b/drivers/pinctrl/nxp/pinctrl-mxs.h
new file mode 100644 (file)
index 0000000..a398e43
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ */
+
+#ifndef __PINCTRL_MXS_H
+#define __PINCTRL_MXS_H
+
+#include <dm/pinctrl.h>
+
+#define SET    0x4
+#define CLR    0x8
+#define TOG    0xc
+
+#define MXS_PINCTRL_PIN(pin)   PINCTRL_PIN(pin, #pin)
+#define PINID(bank, pin)       ((bank) * 32 + (pin))
+
+/*
+ * pinmux-id bit field definitions
+ *
+ * bank:       15..12  (4)
+ * pin:                11..4   (8)
+ * muxsel:     3..0    (4)
+ */
+#define MUXID_TO_PINID(m)      PINID((m) >> 12 & 0xf, (m) >> 4 & 0xff)
+#define MUXID_TO_MUXSEL(m)     ((m) & 0xf)
+
+#define PINID_TO_BANK(p)       ((p) >> 5)
+#define PINID_TO_PIN(p)                ((p) % 32)
+
+/*
+ * pin config bit field definitions
+ *
+ * pull-up:    6..5    (2)
+ * voltage:    4..3    (2)
+ * mA:         2..0    (3)
+ *
+ * MSB of each field is presence bit for the config.
+ */
+#define PULL_PRESENT           (1 << 6)
+#define PULL_SHIFT             5
+#define VOL_PRESENT            (1 << 4)
+#define VOL_SHIFT              3
+#define MA_PRESENT             (1 << 2)
+#define MA_SHIFT               0
+#define CONFIG_TO_PULL(c)      ((c) >> PULL_SHIFT & 0x1)
+#define CONFIG_TO_VOL(c)       ((c) >> VOL_SHIFT & 0x1)
+#define CONFIG_TO_MA(c)                ((c) >> MA_SHIFT & 0x3)
+
+struct mxs_regs {
+       u16 muxsel;
+       u16 drive;
+       u16 pull;
+};
+
+static inline void mxs_pinctrl_rmwl(u32 value, u32 mask, u8 shift,
+                                   void __iomem *reg)
+{
+       clrsetbits_le32(reg, mask << shift, value << shift);
+}
+#endif /* __PINCTRL_MXS_H */
index 24d9f7fab73754c0b4c8891d817d06507bb78fc7..e292d42a8c6074163f8711f068d43af765117721 100644 (file)
@@ -3,6 +3,8 @@
  * Copyright 2018 NXP
  */
 
+#define DEBUG
+
 #include <common.h>
 #include <errno.h>
 #include <dm.h>
@@ -15,15 +17,15 @@ DECLARE_GLOBAL_DATA_PTR;
 
 static const struct pmic_child_info pmic_children_info[] = {
        /* buck */
-       { .prefix = "b", .driver = BD71837_REGULATOR_DRIVER},
+       { .prefix = "b", .driver = BD718XX_REGULATOR_DRIVER},
        /* ldo */
-       { .prefix = "l", .driver = BD71837_REGULATOR_DRIVER},
+       { .prefix = "l", .driver = BD718XX_REGULATOR_DRIVER},
        { },
 };
 
 static int bd71837_reg_count(struct udevice *dev)
 {
-       return BD71837_REG_NUM;
+       return BD718XX_MAX_REGISTER - 1;
 }
 
 static int bd71837_write(struct udevice *dev, uint reg, const uint8_t *buff,
@@ -54,7 +56,7 @@ static int bd71837_bind(struct udevice *dev)
 
        regulators_node = dev_read_subnode(dev, "regulators");
        if (!ofnode_valid(regulators_node)) {
-               debug("%s: %s regulators subnode not found!", __func__,
+               debug("%s: %s regulators subnode not found!\n", __func__,
                      dev->name);
                return -ENXIO;
        }
@@ -69,6 +71,24 @@ static int bd71837_bind(struct udevice *dev)
        return 0;
 }
 
+static int bd718x7_probe(struct udevice *dev)
+{
+       int ret;
+       uint8_t mask = BD718XX_REGLOCK_PWRSEQ | BD718XX_REGLOCK_VREG;
+
+       /* Unlock the PMIC regulator control before probing the children */
+       ret = pmic_clrsetbits(dev, BD718XX_REGLOCK, mask, 0);
+       if (ret) {
+               debug("%s: %s Failed to unlock regulator control\n", __func__,
+                     dev->name);
+               return ret;
+       }
+       debug("%s: '%s' - BD718x7 PMIC registers unlocked\n", __func__,
+             dev->name);
+
+       return 0;
+}
+
 static struct dm_pmic_ops bd71837_ops = {
        .reg_count = bd71837_reg_count,
        .read = bd71837_read,
@@ -76,7 +96,8 @@ static struct dm_pmic_ops bd71837_ops = {
 };
 
 static const struct udevice_id bd71837_ids[] = {
-       { .compatible = "rohm,bd71837", .data = 0x4b, },
+       { .compatible = "rohm,bd71837", .data = ROHM_CHIP_TYPE_BD71837, },
+       { .compatible = "rohm,bd71847", .data = ROHM_CHIP_TYPE_BD71847, },
        { }
 };
 
@@ -85,5 +106,6 @@ U_BOOT_DRIVER(pmic_bd71837) = {
        .id = UCLASS_PMIC,
        .of_match = bd71837_ids,
        .bind = bd71837_bind,
+       .probe = bd718x7_probe,
        .ops = &bd71837_ops,
 };
index 337e9e7471c7b09103cdd6ed6e72699fe7dd8cf2..9aa00fad42f4962784bb1ed914d55f12e599fccb 100644 (file)
@@ -43,6 +43,23 @@ config REGULATOR_AS3722
          but does not yet support change voltages. Currently this must be
          done using direct register writes to the PMIC.
 
+config DM_REGULATOR_BD71837
+       bool "Enable Driver Model for ROHM BD71837/BD71847 regulators"
+       depends on DM_REGULATOR && DM_PMIC_BD71837
+       help
+       This config enables implementation of driver-model regulator uclass
+       features for regulators on ROHM BD71837 and BD71847 PMICs.
+       BD71837 contains 8 bucks and 7 LDOS. BD71847 is reduced version
+       containing 6 bucks and 6 LDOs. The driver implements get/set api for
+       value and enable.
+
+config SPL_DM_REGULATOR_BD71837
+       bool "Enable Driver Model for ROHM BD71837/BD71847 regulators in SPL"
+       depends on DM_REGULATOR_BD71837
+       help
+       This config enables implementation of driver-model regulator uclass
+       features for regulators on ROHM BD71837 and BD71847 in SPL.
+
 config DM_REGULATOR_PFUZE100
        bool "Enable Driver Model for REGULATOR PFUZE100"
        depends on DM_REGULATOR && DM_PMIC_PFUZE100
index e728b73aee33718eb84e96ceae1739149f6acd16..6a3d4bbee4c6270b362c9d2113e7bda9ce270770 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
 obj-$(CONFIG_REGULATOR_AS3722) += as3722_regulator.o
 obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
 obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_BD71837) += bd71837.o
 obj-$(CONFIG_$(SPL_)REGULATOR_PWM) += pwm_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_FAN53555) += fan53555.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_COMMON) += regulator_common.o
diff --git a/drivers/power/regulator/bd71837.c b/drivers/power/regulator/bd71837.c
new file mode 100644 (file)
index 0000000..575429a
--- /dev/null
@@ -0,0 +1,468 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 ROHM Semiconductors
+ *
+ * ROHM BD71837 regulator driver
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <power/bd71837.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+
+#define HW_STATE_CONTROL 0
+#define DEBUG
+
+/**
+ * struct bd71837_vrange - describe linear range of voltages
+ *
+ * @min_volt:  smallest voltage in range
+ * @step:      how much voltage changes at each selector step
+ * @min_sel:   smallest selector in the range
+ * @max_sel:   maximum selector in the range
+ * @rangeval:  register value used to select this range if selectible
+ *             ranges are supported
+ */
+struct bd71837_vrange {
+       unsigned int    min_volt;
+       unsigned int    step;
+       u8              min_sel;
+       u8              max_sel;
+       u8              rangeval;
+};
+
+/**
+ * struct bd71837_platdata - describe regulator control registers
+ *
+ * @name:      name of the regulator. Used for matching the dt-entry
+ * @enable_reg:        register address used to enable/disable regulator
+ * @enablemask:        register mask used to enable/disable regulator
+ * @volt_reg:  register address used to configure regulator voltage
+ * @volt_mask: register mask used to configure regulator voltage
+ * @ranges:    pointer to ranges of regulator voltages and matching register
+ *             values
+ * @numranges: number of voltage ranges pointed by ranges
+ * @rangemask: mask for selecting used ranges if multiple ranges are supported
+ * @sel_mask:  bit to toggle in order to transfer the register control to SW
+ * @dvs:       whether the voltage can be changed when regulator is enabled
+ */
+struct bd71837_platdata {
+       const char              *name;
+       u8                      enable_reg;
+       u8                      enablemask;
+       u8                      volt_reg;
+       u8                      volt_mask;
+       struct bd71837_vrange   *ranges;
+       unsigned int            numranges;
+       u8                      rangemask;
+       u8                      sel_mask;
+       bool                    dvs;
+};
+
+#define BD_RANGE(_min, _vstep, _sel_low, _sel_hi, _range_sel) \
+{ \
+       .min_volt = (_min), .step = (_vstep), .min_sel = (_sel_low), \
+       .max_sel = (_sel_hi), .rangeval = (_range_sel) \
+}
+
+#define BD_DATA(_name, enreg, enmask, vreg, vmask, _range, rmask, _dvs, sel) \
+{ \
+       .name = (_name), .enable_reg = (enreg), .enablemask = (enmask), \
+       .volt_reg = (vreg), .volt_mask = (vmask), .ranges = (_range), \
+       .numranges = ARRAY_SIZE(_range), .rangemask = (rmask), .dvs = (_dvs), \
+       .sel_mask = (sel) \
+}
+
+static struct bd71837_vrange dvs_buck_vranges[] = {
+       BD_RANGE(700000, 10000, 0, 0x3c, 0),
+       BD_RANGE(1300000, 0, 0x3d, 0x3f, 0),
+};
+
+static struct bd71837_vrange bd71847_buck3_vranges[] = {
+       BD_RANGE(700000, 100000, 0x00, 0x03, 0),
+       BD_RANGE(1050000, 50000, 0x04, 0x05, 0),
+       BD_RANGE(1200000, 150000, 0x06, 0x07, 0),
+       BD_RANGE(550000, 50000, 0x0, 0x7, 0x40),
+       BD_RANGE(675000, 100000, 0x0, 0x3, 0x80),
+       BD_RANGE(1025000, 50000, 0x4, 0x5, 0x80),
+       BD_RANGE(1175000, 150000, 0x6, 0x7, 0x80),
+};
+
+static struct bd71837_vrange bd71847_buck4_vranges[] = {
+       BD_RANGE(3000000, 100000, 0x00, 0x03, 0),
+       BD_RANGE(2600000, 100000, 0x00, 0x03, 40),
+};
+
+static struct bd71837_vrange bd71837_buck5_vranges[] = {
+       BD_RANGE(700000, 100000, 0, 0x3, 0),
+       BD_RANGE(1050000, 50000, 0x04, 0x05, 0),
+       BD_RANGE(1200000, 150000, 0x06, 0x07, 0),
+       BD_RANGE(675000, 100000, 0x0, 0x3, 0x80),
+       BD_RANGE(1025000, 50000, 0x04, 0x05, 0x80),
+       BD_RANGE(1175000, 150000, 0x06, 0x07, 0x80),
+};
+
+static struct bd71837_vrange bd71837_buck6_vranges[] = {
+       BD_RANGE(3000000, 100000, 0x00, 0x03, 0),
+};
+
+static struct bd71837_vrange nodvs_buck3_vranges[] = {
+       BD_RANGE(1605000, 90000, 0, 1, 0),
+       BD_RANGE(1755000, 45000, 2, 4, 0),
+       BD_RANGE(1905000, 45000, 5, 7, 0),
+};
+
+static struct bd71837_vrange nodvs_buck4_vranges[] = {
+       BD_RANGE(800000, 10000, 0x00, 0x3C, 0),
+};
+
+static struct bd71837_vrange ldo1_vranges[] = {
+       BD_RANGE(3000000, 100000, 0x00, 0x03, 0),
+       BD_RANGE(1600000, 100000, 0x00, 0x03, 0x20),
+};
+
+static struct bd71837_vrange ldo2_vranges[] = {
+       BD_RANGE(900000, 0, 0, 0, 0),
+       BD_RANGE(800000, 0, 1, 1, 0),
+};
+
+static struct bd71837_vrange ldo3_vranges[] = {
+       BD_RANGE(1800000, 100000, 0x00, 0x0f, 0),
+};
+
+static struct bd71837_vrange ldo4_vranges[] = {
+       BD_RANGE(900000, 100000, 0x00, 0x09, 0),
+};
+
+static struct bd71837_vrange bd71837_ldo5_vranges[] = {
+       BD_RANGE(1800000, 100000, 0x00, 0x0f, 0),
+};
+
+static struct bd71837_vrange bd71847_ldo5_vranges[] = {
+       BD_RANGE(1800000, 100000, 0x00, 0x0f, 0),
+       BD_RANGE(800000, 100000, 0x00, 0x0f, 0x20),
+};
+
+static struct bd71837_vrange ldo6_vranges[] = {
+       BD_RANGE(900000, 100000, 0x00, 0x09, 0),
+};
+
+static struct bd71837_vrange ldo7_vranges[] = {
+       BD_RANGE(1800000, 100000, 0x00, 0x0f, 0),
+};
+
+/*
+ * We use enable mask 'HW_STATE_CONTROL' to indicate that this regulator
+ * must not be enabled or disabled by SW. The typical use-case for BD71837
+ * is powering NXP i.MX8. In this use-case we (for now) only allow control
+ * for BUCK3 and BUCK4 which are not boot critical.
+ */
+static struct bd71837_platdata bd71837_reg_data[] = {
+/* Bucks 1-4 which support dynamic voltage scaling */
+       BD_DATA("BUCK1", BD718XX_BUCK1_CTRL, HW_STATE_CONTROL,
+               BD718XX_BUCK1_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
+               true, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK2", BD718XX_BUCK2_CTRL, HW_STATE_CONTROL,
+               BD718XX_BUCK2_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
+               true, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK3", BD71837_BUCK3_CTRL, BD718XX_BUCK_EN,
+               BD71837_BUCK3_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
+               true, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK4", BD71837_BUCK4_CTRL, BD718XX_BUCK_EN,
+               BD71837_BUCK4_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
+               true, BD718XX_BUCK_SEL),
+/* Bucks 5-8 which do not support dynamic voltage scaling */
+       BD_DATA("BUCK5", BD718XX_1ST_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
+               BD718XX_1ST_NODVS_BUCK_VOLT, BD718XX_1ST_NODVS_BUCK_MASK,
+               bd71837_buck5_vranges, 0x80, false, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK6", BD718XX_2ND_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
+               BD718XX_2ND_NODVS_BUCK_VOLT, BD71837_BUCK6_MASK,
+               bd71837_buck6_vranges, 0, false, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK7", BD718XX_3RD_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
+               BD718XX_3RD_NODVS_BUCK_VOLT, BD718XX_3RD_NODVS_BUCK_MASK,
+               nodvs_buck3_vranges, 0, false, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK8", BD718XX_4TH_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
+               BD718XX_4TH_NODVS_BUCK_VOLT, BD718XX_4TH_NODVS_BUCK_MASK,
+               nodvs_buck4_vranges, 0, false, BD718XX_BUCK_SEL),
+/* LDOs */
+       BD_DATA("LDO1", BD718XX_LDO1_VOLT, HW_STATE_CONTROL, BD718XX_LDO1_VOLT,
+               BD718XX_LDO1_MASK, ldo1_vranges, 0x20, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO2", BD718XX_LDO2_VOLT, HW_STATE_CONTROL, BD718XX_LDO2_VOLT,
+               BD718XX_LDO2_MASK, ldo2_vranges, 0, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO3", BD718XX_LDO3_VOLT, HW_STATE_CONTROL, BD718XX_LDO3_VOLT,
+               BD718XX_LDO3_MASK, ldo3_vranges, 0, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO4", BD718XX_LDO4_VOLT, HW_STATE_CONTROL, BD718XX_LDO4_VOLT,
+               BD718XX_LDO4_MASK, ldo4_vranges, 0, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO5", BD718XX_LDO5_VOLT, HW_STATE_CONTROL, BD718XX_LDO5_VOLT,
+               BD71837_LDO5_MASK, bd71837_ldo5_vranges, 0, false,
+               BD718XX_LDO_SEL),
+       BD_DATA("LDO6", BD718XX_LDO6_VOLT, HW_STATE_CONTROL, BD718XX_LDO6_VOLT,
+               BD718XX_LDO6_MASK, ldo6_vranges, 0, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO7", BD71837_LDO7_VOLT, HW_STATE_CONTROL, BD71837_LDO7_VOLT,
+               BD71837_LDO7_MASK, ldo7_vranges, 0, false, BD718XX_LDO_SEL),
+};
+
+static struct bd71837_platdata bd71847_reg_data[] = {
+/* Bucks 1 and 2 which support dynamic voltage scaling */
+       BD_DATA("BUCK1", BD718XX_BUCK1_CTRL, HW_STATE_CONTROL,
+               BD718XX_BUCK1_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
+               true, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK2", BD718XX_BUCK2_CTRL, HW_STATE_CONTROL,
+               BD718XX_BUCK2_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
+               true, BD718XX_BUCK_SEL),
+/* Bucks 3-6 which do not support dynamic voltage scaling */
+       BD_DATA("BUCK3", BD718XX_1ST_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
+               BD718XX_1ST_NODVS_BUCK_VOLT, BD718XX_1ST_NODVS_BUCK_MASK,
+               bd71847_buck3_vranges, 0xc0, false, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK4", BD718XX_2ND_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
+               BD718XX_2ND_NODVS_BUCK_VOLT, BD71837_BUCK6_MASK,
+               bd71847_buck4_vranges, 0x40, false, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK5", BD718XX_3RD_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
+               BD718XX_3RD_NODVS_BUCK_VOLT, BD718XX_3RD_NODVS_BUCK_MASK,
+               nodvs_buck3_vranges, 0, false, BD718XX_BUCK_SEL),
+       BD_DATA("BUCK6", BD718XX_4TH_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
+               BD718XX_4TH_NODVS_BUCK_VOLT, BD718XX_4TH_NODVS_BUCK_MASK,
+               nodvs_buck4_vranges, 0, false, BD718XX_BUCK_SEL),
+/* LDOs */
+       BD_DATA("LDO1", BD718XX_LDO1_VOLT, HW_STATE_CONTROL, BD718XX_LDO1_VOLT,
+               BD718XX_LDO1_MASK, ldo1_vranges, 0x20, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO2", BD718XX_LDO2_VOLT, HW_STATE_CONTROL, BD718XX_LDO2_VOLT,
+               BD718XX_LDO2_MASK, ldo2_vranges, 0, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO3", BD718XX_LDO3_VOLT, HW_STATE_CONTROL, BD718XX_LDO3_VOLT,
+               BD718XX_LDO3_MASK, ldo3_vranges, 0, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO4", BD718XX_LDO4_VOLT, HW_STATE_CONTROL, BD718XX_LDO4_VOLT,
+               BD718XX_LDO4_MASK, ldo4_vranges, 0, false, BD718XX_LDO_SEL),
+       BD_DATA("LDO5", BD718XX_LDO5_VOLT, HW_STATE_CONTROL, BD718XX_LDO5_VOLT,
+               BD71847_LDO5_MASK, bd71847_ldo5_vranges, 0x20, false,
+               BD718XX_LDO_SEL),
+       BD_DATA("LDO6", BD718XX_LDO6_VOLT, HW_STATE_CONTROL, BD718XX_LDO6_VOLT,
+               BD718XX_LDO6_MASK, ldo6_vranges, 0, false, BD718XX_LDO_SEL),
+};
+
+static int vrange_find_value(struct bd71837_vrange *r, unsigned int sel,
+                            unsigned int *val)
+{
+       if (!val || sel < r->min_sel || sel > r->max_sel)
+               return -EINVAL;
+
+       *val = r->min_volt + r->step * (sel - r->min_sel);
+       return 0;
+}
+
+static int vrange_find_selector(struct bd71837_vrange *r, int val,
+                               unsigned int *sel)
+{
+       int ret = -EINVAL;
+       int num_vals = r->max_sel - r->min_sel + 1;
+
+       if (val >= r->min_volt &&
+           val <= r->min_volt + r->step * (num_vals - 1)) {
+               if (r->step) {
+                       *sel = r->min_sel + ((val - r->min_volt) / r->step);
+                       ret = 0;
+               } else {
+                       *sel = r->min_sel;
+                       ret = 0;
+               }
+       }
+       return ret;
+}
+
+static int bd71837_get_enable(struct udevice *dev)
+{
+       int val;
+       struct bd71837_platdata *plat = dev_get_platdata(dev);
+
+       /*
+        * boot critical regulators on bd71837 must not be controlled by sw
+        * due to the 'feature' which leaves power rails down if bd71837 is
+        * reseted to snvs state. hence we can't get the state here.
+        *
+        * if we are alive it means we probably are on run state and
+        * if the regulator can't be controlled we can assume it is
+        * enabled.
+        */
+       if (plat->enablemask == HW_STATE_CONTROL)
+               return 1;
+
+       val = pmic_reg_read(dev->parent, plat->enable_reg);
+       if (val < 0)
+               return val;
+
+       return (val & plat->enablemask);
+}
+
+static int bd71837_set_enable(struct udevice *dev, bool enable)
+{
+       int val = 0;
+       struct bd71837_platdata *plat = dev_get_platdata(dev);
+
+       /*
+        * boot critical regulators on bd71837 must not be controlled by sw
+        * due to the 'feature' which leaves power rails down if bd71837 is
+        * reseted to snvs state. Hence we can't set the state here.
+        */
+       if (plat->enablemask == HW_STATE_CONTROL)
+               return -EINVAL;
+
+       if (enable)
+               val = plat->enablemask;
+
+       return pmic_clrsetbits(dev->parent, plat->enable_reg, plat->enablemask,
+                              val);
+}
+
+static int bd71837_set_value(struct udevice *dev, int uvolt)
+{
+       unsigned int sel;
+       unsigned int range;
+       int i;
+       int found = 0;
+       struct bd71837_platdata *plat = dev_get_platdata(dev);
+
+       /*
+        * An under/overshooting may occur if voltage is changed for other
+        * regulators but buck 1,2,3 or 4 when regulator is enabled. Prevent
+        * change to protect the HW
+        */
+       if (!plat->dvs)
+               if (bd71837_get_enable(dev)) {
+                       pr_err("Only DVS bucks can be changed when enabled\n");
+                       return -EINVAL;
+               }
+
+       for (i = 0; i < plat->numranges; i++) {
+               struct bd71837_vrange *r = &plat->ranges[i];
+
+               found = !vrange_find_selector(r, uvolt, &sel);
+               if (found) {
+                       unsigned int tmp;
+
+                       /*
+                        * We require exactly the requested value to be
+                        * supported - this can be changed later if needed
+                        */
+                       range = r->rangeval;
+                       found = !vrange_find_value(r, sel, &tmp);
+                       if (found && tmp == uvolt)
+                               break;
+                       found = 0;
+               }
+       }
+
+       if (!found)
+               return -EINVAL;
+
+       sel <<= ffs(plat->volt_mask) - 1;
+
+       if (plat->rangemask)
+               sel |= range;
+
+       return pmic_clrsetbits(dev->parent, plat->volt_reg, plat->volt_mask |
+                              plat->rangemask, sel);
+}
+
+static int bd71837_get_value(struct udevice *dev)
+{
+       unsigned int reg, range;
+       unsigned int tmp;
+       struct bd71837_platdata *plat = dev_get_platdata(dev);
+       int i;
+
+       reg = pmic_reg_read(dev->parent, plat->volt_reg);
+       if (((int)reg) < 0)
+               return reg;
+
+       range = reg & plat->rangemask;
+
+       reg &= plat->volt_mask;
+       reg >>= ffs(plat->volt_mask) - 1;
+
+       for (i = 0; i < plat->numranges; i++) {
+               struct bd71837_vrange *r = &plat->ranges[i];
+
+               if (plat->rangemask && ((plat->rangemask & range) !=
+                   r->rangeval))
+                       continue;
+
+               if (!vrange_find_value(r, reg, &tmp))
+                       return tmp;
+       }
+
+       pr_err("Unknown voltage value read from pmic\n");
+
+       return -EINVAL;
+}
+
+static int bd71837_regulator_probe(struct udevice *dev)
+{
+       struct bd71837_platdata *plat = dev_get_platdata(dev);
+       int i, ret;
+       struct dm_regulator_uclass_platdata *uc_pdata;
+       int type;
+       struct bd71837_platdata *init_data;
+       int data_amnt;
+
+       type = dev_get_driver_data(dev_get_parent(dev));
+
+       switch (type) {
+       case ROHM_CHIP_TYPE_BD71837:
+               init_data = bd71837_reg_data;
+               data_amnt = ARRAY_SIZE(bd71837_reg_data);
+               break;
+       case ROHM_CHIP_TYPE_BD71847:
+               init_data = bd71847_reg_data;
+               data_amnt = ARRAY_SIZE(bd71847_reg_data);
+               break;
+       default:
+               debug("Unknown PMIC type\n");
+               init_data = NULL;
+               data_amnt = 0;
+               break;
+       }
+
+       for (i = 0; i < data_amnt; i++) {
+               if (!strcmp(dev->name, init_data[i].name)) {
+                       *plat = init_data[i];
+                       if (plat->enablemask != HW_STATE_CONTROL) {
+                               /*
+                                * Take the regulator under SW control. Ensure
+                                * the initial state matches dt flags and then
+                                * write the SEL bit
+                                */
+                               uc_pdata = dev_get_uclass_platdata(dev);
+                               ret = bd71837_set_enable(dev,
+                                                        !!(uc_pdata->boot_on ||
+                                                        uc_pdata->always_on));
+                               if (ret)
+                                       return ret;
+
+                               return pmic_clrsetbits(dev->parent,
+                                                     plat->enable_reg,
+                                                     plat->sel_mask,
+                                                     plat->sel_mask);
+                       }
+                       return 0;
+               }
+       }
+
+       pr_err("Unknown regulator '%s'\n", dev->name);
+
+       return -ENOENT;
+}
+
+static const struct dm_regulator_ops bd71837_regulator_ops = {
+       .get_value  = bd71837_get_value,
+       .set_value  = bd71837_set_value,
+       .get_enable = bd71837_get_enable,
+       .set_enable = bd71837_set_enable,
+};
+
+U_BOOT_DRIVER(bd71837_regulator) = {
+       .name = BD718XX_REGULATOR_DRIVER,
+       .id = UCLASS_REGULATOR,
+       .ops = &bd71837_regulator_ops,
+       .probe = bd71837_regulator_probe,
+       .platdata_auto_alloc_size = sizeof(struct bd71837_platdata),
+};
index 2984b7976637caad4759149bd4fb19224989b5b1..1f36fc78fa7b3df4d9095f5cafdde7c0400d43a6 100644 (file)
@@ -18,6 +18,11 @@ config PWM_EXYNOS
          used. It provides 5 channels which can be independently
          programmed. Channel 4 (the last) is normally used as a timer.
 
+config PWM_IMX
+       bool "Enable support for i.MX27 and later PWM"
+       help
+         This PWM is found i.MX27 and later i.MX SoCs.
+
 config PWM_ROCKCHIP
        bool "Enable support for the Rockchip PWM"
        depends on DM_PWM
index 83c1bfa8206aaf7d9046488d68b9d0d70ddaedb4..8d8f3e6f9f98603ed5b07d2e23ce42eff079319d 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <div64.h>
+#include <dm.h>
 #include <pwm.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/io.h>
@@ -24,18 +25,12 @@ int pwm_init(int pwm_id, int div, int invert)
        return 0;
 }
 
-int pwm_config(int pwm_id, int duty_ns, int period_ns)
+int pwm_config_internal(struct pwm_regs *pwm, unsigned long period_cycles,
+                       unsigned long duty_cycles, unsigned long prescale)
 {
-       struct pwm_regs *pwm = (struct pwm_regs *)pwm_id_to_reg(pwm_id);
-       unsigned long period_cycles, duty_cycles, prescale;
        u32 cr;
 
-       if (!pwm)
-               return -1;
-
-       pwm_imx_get_parms(period_ns, duty_ns, &period_cycles, &duty_cycles,
-                         &prescale);
-
+       writel(0, &pwm->ir);
        cr = PWMCR_PRESCALER(prescale) |
                PWMCR_DOZEEN | PWMCR_WAITEN |
                PWMCR_DBGEN | PWMCR_CLKSRC_IPG_HIGH;
@@ -48,6 +43,20 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns)
        return 0;
 }
 
+int pwm_config(int pwm_id, int duty_ns, int period_ns)
+{
+       struct pwm_regs *pwm = (struct pwm_regs *)pwm_id_to_reg(pwm_id);
+       unsigned long period_cycles, duty_cycles, prescale;
+
+       if (!pwm)
+               return -1;
+
+       pwm_imx_get_parms(period_ns, duty_ns, &period_cycles, &duty_cycles,
+                         &prescale);
+
+       return pwm_config_internal(pwm, period_cycles, duty_cycles, prescale);
+}
+
 int pwm_enable(int pwm_id)
 {
        struct pwm_regs *pwm = (struct pwm_regs *)pwm_id_to_reg(pwm_id);
@@ -68,3 +77,86 @@ void pwm_disable(int pwm_id)
 
        clrbits_le32(&pwm->cr, PWMCR_EN);
 }
+
+#if defined(CONFIG_DM_PWM)
+struct imx_pwm_priv {
+       struct pwm_regs *regs;
+       bool invert;
+};
+
+static int imx_pwm_set_invert(struct udevice *dev, uint channel,
+                             bool polarity)
+{
+       struct imx_pwm_priv *priv = dev_get_priv(dev);
+
+       debug("%s: polarity=%u\n", __func__, polarity);
+       priv->invert = polarity;
+
+       return 0;
+}
+
+static int imx_pwm_set_config(struct udevice *dev, uint channel,
+                             uint period_ns, uint duty_ns)
+{
+       struct imx_pwm_priv *priv = dev_get_priv(dev);
+       struct pwm_regs *regs = priv->regs;
+       unsigned long period_cycles, duty_cycles, prescale;
+
+       debug("%s: Config '%s' channel: %d\n", __func__, dev->name, channel);
+
+       pwm_imx_get_parms(period_ns, duty_ns, &period_cycles, &duty_cycles,
+                         &prescale);
+
+       return pwm_config_internal(regs, period_cycles, duty_cycles, prescale);
+};
+
+static int imx_pwm_set_enable(struct udevice *dev, uint channel, bool enable)
+{
+       struct imx_pwm_priv *priv = dev_get_priv(dev);
+       struct pwm_regs *regs = priv->regs;
+
+       debug("%s: Enable '%s' state: %d\n", __func__, dev->name, enable);
+
+       if (enable)
+               setbits_le32(&regs->cr, PWMCR_EN);
+       else
+               clrbits_le32(&regs->cr, PWMCR_EN);
+
+       return 0;
+};
+
+static int imx_pwm_ofdata_to_platdata(struct udevice *dev)
+{
+       struct imx_pwm_priv *priv = dev_get_priv(dev);
+
+       priv->regs = (struct pwm_regs *)devfdt_get_addr(dev);
+
+       return 0;
+}
+
+static int imx_pwm_probe(struct udevice *dev)
+{
+       return 0;
+}
+
+static const struct pwm_ops imx_pwm_ops = {
+       .set_invert     = imx_pwm_set_invert,
+       .set_config     = imx_pwm_set_config,
+       .set_enable     = imx_pwm_set_enable,
+};
+
+static const struct udevice_id imx_pwm_ids[] = {
+       { .compatible = "fsl,imx27-pwm" },
+       { }
+};
+
+U_BOOT_DRIVER(imx_pwm) = {
+       .name   = "imx_pwm",
+       .id     = UCLASS_PWM,
+       .of_match = imx_pwm_ids,
+       .ops    = &imx_pwm_ops,
+       .ofdata_to_platdata     = imx_pwm_ofdata_to_platdata,
+       .probe          = imx_pwm_probe,
+       .priv_auto_alloc_size   = sizeof(struct imx_pwm_priv),
+};
+#endif
index a435e68005ff8dbc541634385fe0838cb1977016..42abb96a26f4e15a5fa3b20698f479712b49c6ea 100644 (file)
@@ -342,6 +342,8 @@ static int mxc_serial_ofdata_to_platdata(struct udevice *dev)
 }
 
 static const struct udevice_id mxc_serial_ids[] = {
+       { .compatible = "fsl,imx21-uart" },
+       { .compatible = "fsl,imx53-uart" },
        { .compatible = "fsl,imx6sx-uart" },
        { .compatible = "fsl,imx6ul-uart" },
        { .compatible = "fsl,imx7d-uart" },
@@ -360,9 +362,7 @@ U_BOOT_DRIVER(serial_mxc) = {
 #endif
        .probe = mxc_serial_probe,
        .ops    = &mxc_serial_ops,
-#if !CONFIG_IS_ENABLED(OF_CONTROL)
        .flags = DM_FLAG_PRE_RELOC,
-#endif
 };
 #endif
 
index cc174dd0363a846d323dcc9cf548bcfb5f3b0595..f459c0a41138fe56fe4092637ad7fd86d898c6a8 100644 (file)
@@ -158,13 +158,14 @@ config MT7621_SPI
          the SPI NOR flash on platforms embedding this Ralink / MediaTek
          SPI core, like MT7621/7628/7688.
 
-config MTK_QSPI
-       bool "Mediatek QSPI driver"
-       imply SPI_FLASH_BAR
+config MTK_SNFI_SPI
+       bool "Mediatek SPI memory controller driver"
+       depends on SPI_MEM
        help
-         Enable the Mediatek QSPI driver. This driver can be
-         used to access the SPI NOR flash on platforms embedding this
-         Mediatek QSPI IP core.
+         Enable the Mediatek SPI memory controller driver. This driver is
+         originally based on the MediaTek SNFI IP core. It can only be
+         used to access SPI memory devices like SPI-NOR or SPI-NAND on
+         platforms embedding this IP core, like MT7622/M7629.
 
 config MVEBU_A3700_SPI
        bool "Marvell Armada 3700 SPI driver"
@@ -232,6 +233,14 @@ config SANDBOX_SPI
                };
          };
 
+config SPI_SIFIVE
+       bool "SiFive SPI driver"
+       help
+         This driver supports the SiFive SPI IP. If unsure say N.
+         Enable the SiFive SPI controller driver.
+
+         The SiFive SPI controller driver is found on various SiFive SoCs.
+
 config SPI_SUNXI
        bool "Allwinner SoC SPI controllers"
        help
index ab84122f0834586abbbd07ea563ff960313c9aab..ae4f2958f8a21121d32cfd07a1aeb2b9de9d9591 100644 (file)
@@ -37,7 +37,7 @@ obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
 obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
 obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
 obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
-obj-$(CONFIG_MTK_QSPI) += mtk_qspi.o
+obj-$(CONFIG_MTK_SNFI_SPI) += mtk_snfi_spi.o
 obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
 obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o
 obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
@@ -50,6 +50,7 @@ obj-$(CONFIG_PL022_SPI) += pl022_spi.o
 obj-$(CONFIG_RENESAS_RPC_SPI) += renesas_rpc_spi.o
 obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
 obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
+obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o
 obj-$(CONFIG_SPI_SUNXI) += spi-sunxi.o
 obj-$(CONFIG_SH_SPI) += sh_spi.o
 obj-$(CONFIG_SH_QSPI) += sh_qspi.o
index 1598c4f698907cafb1f1667847b7031c191d98c0..41abe1996f2592a8cdfdca15b4e40863da975676 100644 (file)
@@ -10,6 +10,7 @@
 #include <spi.h>
 #include <asm/io.h>
 #include <linux/sizes.h>
+#include <linux/iopoll.h>
 #include <dm.h>
 #include <errno.h>
 #include <watchdog.h>
@@ -150,20 +151,13 @@ static void qspi_write32(u32 flags, u32 *addr, u32 val)
 static inline int is_controller_busy(const struct fsl_qspi_priv *priv)
 {
        u32 val;
-       const u32 mask = QSPI_SR_BUSY_MASK | QSPI_SR_AHB_ACC_MASK |
-                        QSPI_SR_IP_ACC_MASK;
-       unsigned int retry = 5;
+       u32 mask = QSPI_SR_BUSY_MASK | QSPI_SR_AHB_ACC_MASK |
+                  QSPI_SR_IP_ACC_MASK;
 
-       do {
-               val = qspi_read32(priv->flags, &priv->regs->sr);
+       if (priv->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG)
+               mask = (u32)cpu_to_be32(mask);
 
-               if ((~val & mask) == mask)
-                       return 0;
-
-               udelay(1);
-       } while (--retry);
-
-       return -ETIMEDOUT;
+       return readl_poll_timeout(&priv->regs->sr, val, !(val & mask), 1000);
 }
 
 /* QSPI support swapping the flash read/write data
diff --git a/drivers/spi/mtk_qspi.c b/drivers/spi/mtk_qspi.c
deleted file mode 100644 (file)
index b510733..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2018  MediaTek, Inc.
- * Author : Guochun.Mao@mediatek.com
- */
-
-#include <common.h>
-#include <dm.h>
-#include <malloc.h>
-#include <spi.h>
-#include <asm/io.h>
-#include <linux/iopoll.h>
-#include <linux/ioport.h>
-
-/* Register Offset */
-struct mtk_qspi_regs {
-       u32 cmd;
-       u32 cnt;
-       u32 rdsr;
-       u32 rdata;
-       u32 radr[3];
-       u32 wdata;
-       u32 prgdata[6];
-       u32 shreg[10];
-       u32 cfg[2];
-       u32 shreg10;
-       u32 mode_mon;
-       u32 status[4];
-       u32 flash_time;
-       u32 flash_cfg;
-       u32 reserved_0[3];
-       u32 sf_time;
-       u32 pp_dw_data;
-       u32 reserved_1;
-       u32 delsel_0[2];
-       u32 intrstus;
-       u32 intren;
-       u32 reserved_2;
-       u32 cfg3;
-       u32 reserved_3;
-       u32 chksum;
-       u32 aaicmd;
-       u32 wrprot;
-       u32 radr3;
-       u32 dual;
-       u32 delsel_1[3];
-};
-
-struct mtk_qspi_platdata {
-       fdt_addr_t reg_base;
-       fdt_addr_t mem_base;
-};
-
-struct mtk_qspi_priv {
-       struct mtk_qspi_regs *regs;
-       unsigned long *mem_base;
-       u8 op;
-       u8 tx[3]; /* only record max 3 bytes paras, when it's address. */
-       u32 txlen; /* dout buffer length  - op code length */
-       u8 *rx;
-       u32 rxlen;
-};
-
-#define MTK_QSPI_CMD_POLLINGREG_US 500000
-#define MTK_QSPI_WRBUF_SIZE        256
-#define MTK_QSPI_COMMAND_ENABLE    0x30
-
-/* NOR flash controller commands */
-#define MTK_QSPI_RD_TRIGGER        BIT(0)
-#define MTK_QSPI_READSTATUS        BIT(1)
-#define MTK_QSPI_PRG_CMD           BIT(2)
-#define MTK_QSPI_WR_TRIGGER        BIT(4)
-#define MTK_QSPI_WRITESTATUS       BIT(5)
-#define MTK_QSPI_AUTOINC           BIT(7)
-
-#define MTK_QSPI_MAX_RX_TX_SHIFT   0x6
-#define MTK_QSPI_MAX_SHIFT         0x8
-
-#define MTK_QSPI_WR_BUF_ENABLE     0x1
-#define MTK_QSPI_WR_BUF_DISABLE    0x0
-
-static int mtk_qspi_execute_cmd(struct mtk_qspi_priv *priv, u8 cmd)
-{
-       u8 tmp;
-       u8 val = cmd & ~MTK_QSPI_AUTOINC;
-
-       writeb(cmd, &priv->regs->cmd);
-
-       return readb_poll_timeout(&priv->regs->cmd, tmp, !(val & tmp),
-                                 MTK_QSPI_CMD_POLLINGREG_US);
-}
-
-static int mtk_qspi_tx_rx(struct mtk_qspi_priv *priv)
-{
-       int len = 1 + priv->txlen + priv->rxlen;
-       int i, ret, idx;
-
-       if (len > MTK_QSPI_MAX_SHIFT)
-               return -ERR_INVAL;
-
-       writeb(len * 8, &priv->regs->cnt);
-
-       /* start at PRGDATA5, go down to PRGDATA0 */
-       idx = MTK_QSPI_MAX_RX_TX_SHIFT - 1;
-
-       /* opcode */
-       writeb(priv->op, &priv->regs->prgdata[idx]);
-       idx--;
-
-       /* program TX data */
-       for (i = 0; i < priv->txlen; i++, idx--)
-               writeb(priv->tx[i], &priv->regs->prgdata[idx]);
-
-       /* clear out rest of TX registers */
-       while (idx >= 0) {
-               writeb(0, &priv->regs->prgdata[idx]);
-               idx--;
-       }
-
-       ret = mtk_qspi_execute_cmd(priv, MTK_QSPI_PRG_CMD);
-       if (ret)
-               return ret;
-
-       /* restart at first RX byte */
-       idx = priv->rxlen - 1;
-
-       /* read out RX data */
-       for (i = 0; i < priv->rxlen; i++, idx--)
-               priv->rx[i] = readb(&priv->regs->shreg[idx]);
-
-       return 0;
-}
-
-static int mtk_qspi_read(struct mtk_qspi_priv *priv,
-                        u32 addr, u8 *buf, u32 len)
-{
-       memcpy(buf, (u8 *)priv->mem_base + addr, len);
-       return 0;
-}
-
-static void mtk_qspi_set_addr(struct mtk_qspi_priv *priv, u32 addr)
-{
-       int i;
-
-       for (i = 0; i < 3; i++) {
-               writeb(addr & 0xff, &priv->regs->radr[i]);
-               addr >>= 8;
-       }
-}
-
-static int mtk_qspi_write_single_byte(struct mtk_qspi_priv *priv,
-                                     u32 addr, u32 length, const u8 *data)
-{
-       int i, ret;
-
-       mtk_qspi_set_addr(priv, addr);
-
-       for (i = 0; i < length; i++) {
-               writeb(*data++, &priv->regs->wdata);
-               ret = mtk_qspi_execute_cmd(priv, MTK_QSPI_WR_TRIGGER);
-               if (ret < 0)
-                       return ret;
-       }
-       return 0;
-}
-
-static int mtk_qspi_write_buffer(struct mtk_qspi_priv *priv, u32 addr,
-                                const u8 *buf)
-{
-       int i, data;
-
-       mtk_qspi_set_addr(priv, addr);
-
-       for (i = 0; i < MTK_QSPI_WRBUF_SIZE; i += 4) {
-               data = buf[i + 3] << 24 | buf[i + 2] << 16 |
-                      buf[i + 1] << 8 | buf[i];
-               writel(data, &priv->regs->pp_dw_data);
-       }
-
-       return mtk_qspi_execute_cmd(priv, MTK_QSPI_WR_TRIGGER);
-}
-
-static int mtk_qspi_write(struct mtk_qspi_priv *priv,
-                         u32 addr, const u8 *buf, u32 len)
-{
-       int ret;
-
-       /* setting pre-fetch buffer for page program */
-       writel(MTK_QSPI_WR_BUF_ENABLE, &priv->regs->cfg[1]);
-       while (len >= MTK_QSPI_WRBUF_SIZE) {
-               ret = mtk_qspi_write_buffer(priv, addr, buf);
-               if (ret < 0)
-                       return ret;
-
-               len -= MTK_QSPI_WRBUF_SIZE;
-               addr += MTK_QSPI_WRBUF_SIZE;
-               buf += MTK_QSPI_WRBUF_SIZE;
-       }
-       /* disable pre-fetch buffer for page program */
-       writel(MTK_QSPI_WR_BUF_DISABLE, &priv->regs->cfg[1]);
-
-       if (len)
-               return mtk_qspi_write_single_byte(priv, addr, len, buf);
-
-       return 0;
-}
-
-static int mtk_qspi_claim_bus(struct udevice *dev)
-{
-       /* nothing to do */
-       return 0;
-}
-
-static int mtk_qspi_release_bus(struct udevice *dev)
-{
-       /* nothing to do */
-       return 0;
-}
-
-static int mtk_qspi_transfer(struct mtk_qspi_priv *priv, unsigned int bitlen,
-                            const void *dout, void *din, unsigned long flags)
-{
-       u32 bytes = DIV_ROUND_UP(bitlen, 8);
-       u32 addr;
-
-       if (!bytes)
-               return -ERR_INVAL;
-
-       if (dout) {
-               if (flags & SPI_XFER_BEGIN) {
-                       /* parse op code and potential paras first */
-                       priv->op = *(u8 *)dout;
-                       if (bytes > 1)
-                               memcpy(priv->tx, (u8 *)dout + 1,
-                                      bytes <= 4 ? bytes - 1 : 3);
-                       priv->txlen = bytes - 1;
-               }
-
-               if (flags == SPI_XFER_ONCE) {
-                       /* operations without receiving or sending data.
-                        * for example: erase, write flash register or write
-                        * enable...
-                        */
-                       priv->rx = NULL;
-                       priv->rxlen = 0;
-                       return mtk_qspi_tx_rx(priv);
-               }
-
-               if (flags & SPI_XFER_END) {
-                       /* here, dout should be data to be written.
-                        * and priv->tx should be filled 3Bytes address.
-                        */
-                       addr = priv->tx[0] << 16 | priv->tx[1] << 8 |
-                              priv->tx[2];
-                       return mtk_qspi_write(priv, addr, (u8 *)dout, bytes);
-               }
-       }
-
-       if (din) {
-               if (priv->txlen >= 3) {
-                       /* if run to here, priv->tx[] should be the address
-                        * where read data from,
-                        * and, din is the buf to receive data.
-                        */
-                       addr = priv->tx[0] << 16 | priv->tx[1] << 8 |
-                              priv->tx[2];
-                       return mtk_qspi_read(priv, addr, (u8 *)din, bytes);
-               }
-
-               /* should be reading flash's register */
-               priv->rx = (u8 *)din;
-               priv->rxlen = bytes;
-               return mtk_qspi_tx_rx(priv);
-       }
-
-       return 0;
-}
-
-static int mtk_qspi_xfer(struct udevice *dev, unsigned int bitlen,
-                        const void *dout, void *din, unsigned long flags)
-{
-       struct udevice *bus = dev->parent;
-       struct mtk_qspi_priv *priv = dev_get_priv(bus);
-
-       return  mtk_qspi_transfer(priv, bitlen, dout, din, flags);
-}
-
-static int mtk_qspi_set_speed(struct udevice *bus, uint speed)
-{
-       /* nothing to do */
-       return 0;
-}
-
-static int mtk_qspi_set_mode(struct udevice *bus, uint mode)
-{
-       /* nothing to do */
-       return 0;
-}
-
-static int mtk_qspi_ofdata_to_platdata(struct udevice *bus)
-{
-       struct resource res_reg, res_mem;
-       struct mtk_qspi_platdata *plat = bus->platdata;
-       int ret;
-
-       ret = dev_read_resource_byname(bus, "reg_base", &res_reg);
-       if (ret) {
-               debug("can't get reg_base resource(ret = %d)\n", ret);
-               return -ENOMEM;
-       }
-
-       ret = dev_read_resource_byname(bus, "mem_base", &res_mem);
-       if (ret) {
-               debug("can't get map_base resource(ret = %d)\n", ret);
-               return -ENOMEM;
-       }
-
-       plat->mem_base = res_mem.start;
-       plat->reg_base = res_reg.start;
-
-       return 0;
-}
-
-static int mtk_qspi_probe(struct udevice *bus)
-{
-       struct mtk_qspi_platdata *plat = dev_get_platdata(bus);
-       struct mtk_qspi_priv *priv = dev_get_priv(bus);
-
-       priv->regs = (struct mtk_qspi_regs *)plat->reg_base;
-       priv->mem_base = (unsigned long *)plat->mem_base;
-
-       writel(MTK_QSPI_COMMAND_ENABLE, &priv->regs->wrprot);
-
-       return 0;
-}
-
-static const struct dm_spi_ops mtk_qspi_ops = {
-       .claim_bus      = mtk_qspi_claim_bus,
-       .release_bus    = mtk_qspi_release_bus,
-       .xfer           = mtk_qspi_xfer,
-       .set_speed      = mtk_qspi_set_speed,
-       .set_mode       = mtk_qspi_set_mode,
-};
-
-static const struct udevice_id mtk_qspi_ids[] = {
-       { .compatible = "mediatek,mt7629-qspi" },
-       { }
-};
-
-U_BOOT_DRIVER(mtk_qspi) = {
-       .name     = "mtk_qspi",
-       .id       = UCLASS_SPI,
-       .of_match = mtk_qspi_ids,
-       .ops      = &mtk_qspi_ops,
-       .ofdata_to_platdata       = mtk_qspi_ofdata_to_platdata,
-       .platdata_auto_alloc_size = sizeof(struct mtk_qspi_platdata),
-       .priv_auto_alloc_size     = sizeof(struct mtk_qspi_priv),
-       .probe    = mtk_qspi_probe,
-};
diff --git a/drivers/spi/mtk_snfi_spi.c b/drivers/spi/mtk_snfi_spi.c
new file mode 100644 (file)
index 0000000..2a89476
--- /dev/null
@@ -0,0 +1,318 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <spi.h>
+#include <spi-mem.h>
+#include <stdbool.h>
+#include <watchdog.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#define SNFI_MAC_CTL                   0x500
+#define MAC_XIO_SEL                    BIT(4)
+#define SF_MAC_EN                      BIT(3)
+#define SF_TRIG                                BIT(2)
+#define WIP_READY                      BIT(1)
+#define WIP                            BIT(0)
+
+#define SNFI_MAC_OUTL                  0x504
+#define SNFI_MAC_INL                   0x508
+
+#define SNFI_MISC_CTL                  0x538
+#define SW_RST                         BIT(28)
+#define FIFO_RD_LTC_SHIFT              25
+#define FIFO_RD_LTC                    GENMASK(26, 25)
+#define LATCH_LAT_SHIFT                        8
+#define LATCH_LAT                      GENMASK(9, 8)
+#define CS_DESELECT_CYC_SHIFT          0
+#define CS_DESELECT_CYC                        GENMASK(4, 0)
+
+#define SNF_STA_CTL1                   0x550
+#define SPI_STATE                      GENMASK(3, 0)
+
+#define SNFI_GPRAM_OFFSET              0x800
+#define SNFI_GPRAM_SIZE                        0x80
+
+#define SNFI_POLL_INTERVAL             500000
+#define SNFI_RST_POLL_INTERVAL         1000000
+
+struct mtk_snfi_priv {
+       void __iomem *base;
+
+       struct clk nfi_clk;
+       struct clk pad_clk;
+};
+
+static int mtk_snfi_adjust_op_size(struct spi_slave *slave,
+                                  struct spi_mem_op *op)
+{
+       u32 nbytes;
+
+       /*
+        * When there is input data, it will be appended after the output
+        * data in the GPRAM. So the total size of either pure output data
+        * or the output+input data must not exceed the GPRAM size.
+        */
+
+       nbytes = sizeof(op->cmd.opcode) + op->addr.nbytes +
+               op->dummy.nbytes;
+
+       if (nbytes + op->data.nbytes <= SNFI_GPRAM_SIZE)
+               return 0;
+
+       if (nbytes >= SNFI_GPRAM_SIZE)
+               return -ENOTSUPP;
+
+       op->data.nbytes = SNFI_GPRAM_SIZE - nbytes;
+
+       return 0;
+}
+
+static bool mtk_snfi_supports_op(struct spi_slave *slave,
+                                const struct spi_mem_op *op)
+{
+       if (op->cmd.buswidth > 1 || op->addr.buswidth > 1 ||
+           op->dummy.buswidth > 1 || op->data.buswidth > 1)
+               return false;
+
+       return true;
+}
+
+static int mtk_snfi_mac_trigger(struct mtk_snfi_priv *priv,
+                               struct udevice *bus, u32 outlen, u32 inlen)
+{
+       int ret;
+       u32 val;
+
+#ifdef CONFIG_PINCTRL
+       pinctrl_select_state(bus, "snfi");
+#endif
+
+       writel(SF_MAC_EN, priv->base + SNFI_MAC_CTL);
+       writel(outlen, priv->base + SNFI_MAC_OUTL);
+       writel(inlen, priv->base + SNFI_MAC_INL);
+
+       writel(SF_MAC_EN | SF_TRIG, priv->base + SNFI_MAC_CTL);
+
+       ret = readl_poll_timeout(priv->base + SNFI_MAC_CTL, val,
+                                val & WIP_READY, SNFI_POLL_INTERVAL);
+       if (ret) {
+               printf("%s: timed out waiting for WIP_READY\n", __func__);
+               goto cleanup;
+       }
+
+       ret = readl_poll_timeout(priv->base + SNFI_MAC_CTL, val,
+                                !(val & WIP), SNFI_POLL_INTERVAL);
+       if (ret)
+               printf("%s: timed out waiting for WIP cleared\n", __func__);
+
+       writel(0, priv->base + SNFI_MAC_CTL);
+
+cleanup:
+#ifdef CONFIG_PINCTRL
+       pinctrl_select_state(bus, "default");
+#endif
+
+       return ret;
+}
+
+static int mtk_snfi_mac_reset(struct mtk_snfi_priv *priv)
+{
+       int ret;
+       u32 val;
+
+       setbits_32(priv->base + SNFI_MISC_CTL, SW_RST);
+
+       ret = readl_poll_timeout(priv->base + SNF_STA_CTL1, val,
+                                !(val & SPI_STATE), SNFI_POLL_INTERVAL);
+       if (ret)
+               printf("%s: failed to reset snfi mac\n", __func__);
+
+       writel((2 << FIFO_RD_LTC_SHIFT) |
+               (10 << CS_DESELECT_CYC_SHIFT),
+               priv->base + SNFI_MISC_CTL);
+
+       return ret;
+}
+
+static void mtk_snfi_copy_to_gpram(struct mtk_snfi_priv *priv,
+                                  const void *data, size_t len)
+{
+       void __iomem *gpram = priv->base + SNFI_GPRAM_OFFSET;
+       size_t i, n = (len + sizeof(u32) - 1) / sizeof(u32);
+       const u32 *buff = data;
+
+       /*
+        * The output data will always be copied to the beginning of
+        * the GPRAM. Uses word write for better performace.
+        *
+        * Trailing bytes in the last word are not cared.
+        */
+
+       for (i = 0; i < n; i++)
+               writel(buff[i], gpram + i * sizeof(u32));
+}
+
+static void mtk_snfi_copy_from_gpram(struct mtk_snfi_priv *priv, u8 *cache,
+                                    void *data, size_t pos, size_t len)
+{
+       void __iomem *gpram = priv->base + SNFI_GPRAM_OFFSET;
+       u32 *buff = (u32 *)cache;
+       size_t i, off, end;
+
+       /* Start position in the buffer */
+       off = pos & (sizeof(u32) - 1);
+
+       /* End position for copy */
+       end = (len + pos + sizeof(u32) - 1) & (~(sizeof(u32) - 1));
+
+       /* Start position for copy */
+       pos &= ~(sizeof(u32) - 1);
+
+       /*
+        * Read aligned data from GPRAM to buffer first.
+        * Uses word read for better performace.
+        */
+       i = 0;
+       while (pos < end) {
+               buff[i++] = readl(gpram + pos);
+               pos += sizeof(u32);
+       }
+
+       /* Copy rx data */
+       memcpy(data, cache + off, len);
+}
+
+static int mtk_snfi_exec_op(struct spi_slave *slave,
+                           const struct spi_mem_op *op)
+{
+       struct udevice *bus = dev_get_parent(slave->dev);
+       struct mtk_snfi_priv *priv = dev_get_priv(bus);
+       u8 gpram_cache[SNFI_GPRAM_SIZE];
+       u32 i, len = 0, inlen = 0;
+       int addr_sh;
+       int ret;
+
+       WATCHDOG_RESET();
+
+       ret = mtk_snfi_mac_reset(priv);
+       if (ret)
+               return ret;
+
+       /* Put opcode */
+       gpram_cache[len++] = op->cmd.opcode;
+
+       /* Put address */
+       addr_sh = (op->addr.nbytes - 1) * 8;
+       while (addr_sh >= 0) {
+               gpram_cache[len++] = (op->addr.val >> addr_sh) & 0xff;
+               addr_sh -= 8;
+       }
+
+       /* Put dummy bytes */
+       for (i = 0; i < op->dummy.nbytes; i++)
+               gpram_cache[len++] = 0;
+
+       /* Put output data */
+       if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) {
+               memcpy(gpram_cache + len, op->data.buf.out, op->data.nbytes);
+               len += op->data.nbytes;
+       }
+
+       /* Copy final output data to GPRAM */
+       mtk_snfi_copy_to_gpram(priv, gpram_cache, len);
+
+       /* Start one SPI transaction */
+       if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN)
+               inlen = op->data.nbytes;
+
+       ret = mtk_snfi_mac_trigger(priv, bus, len, inlen);
+       if (ret)
+               return ret;
+
+       /* Copy input data from GPRAM */
+       if (inlen)
+               mtk_snfi_copy_from_gpram(priv, gpram_cache, op->data.buf.in,
+                                        len, inlen);
+
+       return 0;
+}
+
+static int mtk_snfi_spi_probe(struct udevice *bus)
+{
+       struct mtk_snfi_priv *priv = dev_get_priv(bus);
+       int ret;
+
+       priv->base = (void __iomem *)devfdt_get_addr(bus);
+       if (!priv->base)
+               return -EINVAL;
+
+       ret = clk_get_by_name(bus, "nfi_clk", &priv->nfi_clk);
+       if (ret < 0)
+               return ret;
+
+       ret = clk_get_by_name(bus, "pad_clk", &priv->pad_clk);
+       if (ret < 0)
+               return ret;
+
+       clk_enable(&priv->nfi_clk);
+       clk_enable(&priv->pad_clk);
+
+       return 0;
+}
+
+static int mtk_snfi_set_speed(struct udevice *bus, uint speed)
+{
+       /*
+        * The SNFI does not have a bus clock divider.
+        * The bus clock is set in dts (pad_clk, UNIVPLL2_D8 = 50MHz).
+        */
+
+       return 0;
+}
+
+static int mtk_snfi_set_mode(struct udevice *bus, uint mode)
+{
+       /* The SNFI supports only mode 0 */
+
+       if (mode)
+               return -EINVAL;
+
+       return 0;
+}
+
+static const struct spi_controller_mem_ops mtk_snfi_mem_ops = {
+       .adjust_op_size = mtk_snfi_adjust_op_size,
+       .supports_op = mtk_snfi_supports_op,
+       .exec_op = mtk_snfi_exec_op,
+};
+
+static const struct dm_spi_ops mtk_snfi_spi_ops = {
+       .mem_ops        = &mtk_snfi_mem_ops,
+       .set_speed      = mtk_snfi_set_speed,
+       .set_mode       = mtk_snfi_set_mode,
+};
+
+static const struct udevice_id mtk_snfi_spi_ids[] = {
+       { .compatible = "mediatek,mtk-snfi-spi" },
+       { }
+};
+
+U_BOOT_DRIVER(mtk_snfi_spi) = {
+       .name                   = "mtk_snfi_spi",
+       .id                     = UCLASS_SPI,
+       .of_match               = mtk_snfi_spi_ids,
+       .ops                    = &mtk_snfi_spi_ops,
+       .priv_auto_alloc_size   = sizeof(struct mtk_snfi_priv),
+       .probe                  = mtk_snfi_spi_probe,
+};
index 5065e407f82466ba45ea6f8336179d3d5952c936..3a9756fbf1b15a8b4b1e0c2bc006dc0fbacd1cb5 100644 (file)
@@ -2,6 +2,9 @@
 /*
  * Freescale i.MX28 SPI driver
  *
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
  * on behalf of DENX Software Engineering GmbH
  *
 
 #define MXSSSP_SMALL_TRANSFER  512
 
+static void mxs_spi_start_xfer(struct mxs_ssp_regs *ssp_regs)
+{
+       writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set);
+       writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr);
+}
+
+static void mxs_spi_end_xfer(struct mxs_ssp_regs *ssp_regs)
+{
+       writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr);
+       writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set);
+}
+
+#if !CONFIG_IS_ENABLED(DM_SPI)
 struct mxs_spi_slave {
        struct spi_slave        slave;
        uint32_t                max_khz;
@@ -38,94 +54,38 @@ static inline struct mxs_spi_slave *to_mxs_slave(struct spi_slave *slave)
 {
        return container_of(slave, struct mxs_spi_slave, slave);
 }
+#else
+#include <dm.h>
+#include <errno.h>
+struct mxs_spi_platdata {
+       s32 frequency;          /* Default clock frequency, -1 for none */
+       fdt_addr_t base;        /* SPI IP block base address */
+       int num_cs;             /* Number of CSes supported */
+       int dma_id;             /* ID of the DMA channel */
+       int clk_id;             /* ID of the SSP clock */
+};
 
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-       /* MXS SPI: 4 ports and 3 chip selects maximum */
-       if (!mxs_ssp_bus_id_valid(bus) || cs > 2)
-               return 0;
-       else
-               return 1;
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-                                 unsigned int max_hz, unsigned int mode)
-{
-       struct mxs_spi_slave *mxs_slave;
-
-       if (!spi_cs_is_valid(bus, cs)) {
-               printf("mxs_spi: invalid bus %d / chip select %d\n", bus, cs);
-               return NULL;
-       }
-
-       mxs_slave = spi_alloc_slave(struct mxs_spi_slave, bus, cs);
-       if (!mxs_slave)
-               return NULL;
-
-       if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + bus))
-               goto err_init;
-
-       mxs_slave->max_khz = max_hz / 1000;
-       mxs_slave->mode = mode;
-       mxs_slave->regs = mxs_ssp_regs_by_bus(bus);
-
-       return &mxs_slave->slave;
-
-err_init:
-       free(mxs_slave);
-       return NULL;
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
-       struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave);
-       free(mxs_slave);
-}
-
-int spi_claim_bus(struct spi_slave *slave)
-{
-       struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave);
-       struct mxs_ssp_regs *ssp_regs = mxs_slave->regs;
-       uint32_t reg = 0;
-
-       mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg);
-
-       writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) |
-              SSP_CTRL0_BUS_WIDTH_ONE_BIT,
-              &ssp_regs->hw_ssp_ctrl0);
-
-       reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS;
-       reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0;
-       reg |= (mxs_slave->mode & SPI_CPHA) ? SSP_CTRL1_PHASE : 0;
-       writel(reg, &ssp_regs->hw_ssp_ctrl1);
-
-       writel(0, &ssp_regs->hw_ssp_cmd0);
-
-       mxs_set_ssp_busclock(slave->bus, mxs_slave->max_khz);
-
-       return 0;
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
-}
-
-static void mxs_spi_start_xfer(struct mxs_ssp_regs *ssp_regs)
-{
-       writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set);
-       writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr);
-}
-
-static void mxs_spi_end_xfer(struct mxs_ssp_regs *ssp_regs)
-{
-       writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr);
-       writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set);
-}
+struct mxs_spi_priv {
+       struct mxs_ssp_regs *regs;
+       unsigned int dma_channel;
+       unsigned int max_freq;
+       unsigned int clk_id;
+       unsigned int mode;
+};
+#endif
 
+#if !CONFIG_IS_ENABLED(DM_SPI)
 static int mxs_spi_xfer_pio(struct mxs_spi_slave *slave,
                        char *data, int length, int write, unsigned long flags)
 {
        struct mxs_ssp_regs *ssp_regs = slave->regs;
+#else
+static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv,
+                           char *data, int length, int write,
+                           unsigned long flags)
+{
+       struct mxs_ssp_regs *ssp_regs = priv->regs;
+#endif
 
        if (flags & SPI_XFER_BEGIN)
                mxs_spi_start_xfer(ssp_regs);
@@ -181,12 +141,19 @@ static int mxs_spi_xfer_pio(struct mxs_spi_slave *slave,
        return 0;
 }
 
+#if !CONFIG_IS_ENABLED(DM_SPI)
 static int mxs_spi_xfer_dma(struct mxs_spi_slave *slave,
                        char *data, int length, int write, unsigned long flags)
 {
+       struct mxs_ssp_regs *ssp_regs = slave->regs;
+#else
+static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv,
+                           char *data, int length, int write,
+                           unsigned long flags)
+{      struct mxs_ssp_regs *ssp_regs = priv->regs;
+#endif
        const int xfer_max_sz = 0xff00;
        const int desc_count = DIV_ROUND_UP(length, xfer_max_sz) + 1;
-       struct mxs_ssp_regs *ssp_regs = slave->regs;
        struct mxs_dma_desc *dp;
        uint32_t ctrl0;
        uint32_t cache_data_count;
@@ -225,7 +192,11 @@ static int mxs_spi_xfer_dma(struct mxs_spi_slave *slave,
        /* Invalidate the area, so no writeback into the RAM races with DMA */
        invalidate_dcache_range(dstart, dstart + cache_data_count);
 
+#if !CONFIG_IS_ENABLED(DM_SPI)
        dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + slave->slave.bus;
+#else
+       dmach = priv->dma_channel;
+#endif
 
        dp = desc;
        while (length) {
@@ -302,11 +273,20 @@ static int mxs_spi_xfer_dma(struct mxs_spi_slave *slave,
        return ret;
 }
 
+#if !CONFIG_IS_ENABLED(DM_SPI)
 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                const void *dout, void *din, unsigned long flags)
 {
        struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave);
        struct mxs_ssp_regs *ssp_regs = mxs_slave->regs;
+#else
+int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                const void *dout, void *din, unsigned long flags)
+{
+       struct udevice *bus = dev_get_parent(dev);
+       struct mxs_spi_priv *priv = dev_get_priv(bus);
+       struct mxs_ssp_regs *ssp_regs = priv->regs;
+#endif
        int len = bitlen / 8;
        char dummy;
        int write = 0;
@@ -350,9 +330,263 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 
        if (!dma || (len < MXSSSP_SMALL_TRANSFER)) {
                writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr);
+#if !CONFIG_IS_ENABLED(DM_SPI)
                return mxs_spi_xfer_pio(mxs_slave, data, len, write, flags);
+#else
+               return mxs_spi_xfer_pio(priv, data, len, write, flags);
+#endif
        } else {
                writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set);
+#if !CONFIG_IS_ENABLED(DM_SPI)
                return mxs_spi_xfer_dma(mxs_slave, data, len, write, flags);
+#else
+               return mxs_spi_xfer_dma(priv, data, len, write, flags);
+#endif
        }
 }
+
+#if !CONFIG_IS_ENABLED(DM_SPI)
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       /* MXS SPI: 4 ports and 3 chip selects maximum */
+       if (!mxs_ssp_bus_id_valid(bus) || cs > 2)
+               return 0;
+       else
+               return 1;
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode)
+{
+       struct mxs_spi_slave *mxs_slave;
+
+       if (!spi_cs_is_valid(bus, cs)) {
+               printf("mxs_spi: invalid bus %d / chip select %d\n", bus, cs);
+               return NULL;
+       }
+
+       mxs_slave = spi_alloc_slave(struct mxs_spi_slave, bus, cs);
+       if (!mxs_slave)
+               return NULL;
+
+       if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + bus))
+               goto err_init;
+
+       mxs_slave->max_khz = max_hz / 1000;
+       mxs_slave->mode = mode;
+       mxs_slave->regs = mxs_ssp_regs_by_bus(bus);
+
+       return &mxs_slave->slave;
+
+err_init:
+       free(mxs_slave);
+       return NULL;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave);
+
+       free(mxs_slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave);
+       struct mxs_ssp_regs *ssp_regs = mxs_slave->regs;
+       u32 reg = 0;
+
+       mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg);
+
+       writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) |
+              SSP_CTRL0_BUS_WIDTH_ONE_BIT,
+              &ssp_regs->hw_ssp_ctrl0);
+
+       reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS;
+       reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0;
+       reg |= (mxs_slave->mode & SPI_CPHA) ? SSP_CTRL1_PHASE : 0;
+       writel(reg, &ssp_regs->hw_ssp_ctrl1);
+
+       writel(0, &ssp_regs->hw_ssp_cmd0);
+
+       mxs_set_ssp_busclock(slave->bus, mxs_slave->max_khz);
+
+       return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+}
+
+#else /* CONFIG_DM_SPI */
+/* Base numbers of i.MX2[38] clk for ssp0 IP block */
+#define MXS_SSP_IMX23_CLKID_SSP0 33
+#define MXS_SSP_IMX28_CLKID_SSP0 46
+
+static int mxs_spi_probe(struct udevice *bus)
+{
+       struct mxs_spi_platdata *plat = dev_get_platdata(bus);
+       struct mxs_spi_priv *priv = dev_get_priv(bus);
+       int ret;
+
+       debug("%s: probe\n", __func__);
+       priv->regs = (struct mxs_ssp_regs *)plat->base;
+       priv->max_freq = plat->frequency;
+
+       priv->dma_channel = plat->dma_id;
+       priv->clk_id = plat->clk_id;
+
+       ret = mxs_dma_init_channel(priv->dma_channel);
+       if (ret) {
+               printf("%s: DMA init channel error %d\n", __func__, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int mxs_spi_claim_bus(struct udevice *dev)
+{
+       struct udevice *bus = dev_get_parent(dev);
+       struct mxs_spi_priv *priv = dev_get_priv(bus);
+       struct mxs_ssp_regs *ssp_regs = priv->regs;
+       int cs = spi_chip_select(dev);
+
+       /*
+        * i.MX28 supports up to 3 CS (SSn0, SSn1, SSn2)
+        * To set them it uses following tuple (WAIT_FOR_IRQ,WAIT_FOR_CMD),
+        * where:
+        *
+        * WAIT_FOR_IRQ is bit 21 of HW_SSP_CTRL0
+        * WAIT_FOR_CMD is bit 20 (#defined as MXS_SSP_CHIPSELECT_SHIFT here) of
+        *                        HW_SSP_CTRL0
+        * SSn0 b00
+        * SSn1 b01
+        * SSn2 b10 (which require setting WAIT_FOR_IRQ)
+        *
+        * However, for now i.MX28 SPI driver will support up till 2 CSes
+        * (SSn0, and SSn1).
+        */
+
+       /* Ungate SSP clock and set active CS */
+       clrsetbits_le32(&ssp_regs->hw_ssp_ctrl0,
+                       BIT(MXS_SSP_CHIPSELECT_SHIFT) |
+                       SSP_CTRL0_CLKGATE, (cs << MXS_SSP_CHIPSELECT_SHIFT));
+
+       return 0;
+}
+
+static int mxs_spi_release_bus(struct udevice *dev)
+{
+       struct udevice *bus = dev_get_parent(dev);
+       struct mxs_spi_priv *priv = dev_get_priv(bus);
+       struct mxs_ssp_regs *ssp_regs = priv->regs;
+
+       /* Gate SSP clock */
+       setbits_le32(&ssp_regs->hw_ssp_ctrl0, SSP_CTRL0_CLKGATE);
+
+       return 0;
+}
+
+static int mxs_spi_set_speed(struct udevice *bus, uint speed)
+{
+       struct mxs_spi_priv *priv = dev_get_priv(bus);
+#ifdef CONFIG_MX28
+       int clkid = priv->clk_id - MXS_SSP_IMX28_CLKID_SSP0;
+#else /* CONFIG_MX23 */
+       int clkid = priv->clk_id - MXS_SSP_IMX23_CLKID_SSP0;
+#endif
+       if (speed > priv->max_freq)
+               speed = priv->max_freq;
+
+       debug("%s speed: %u [Hz] clkid: %d\n", __func__, speed, clkid);
+       mxs_set_ssp_busclock(clkid, speed / 1000);
+
+       return 0;
+}
+
+static int mxs_spi_set_mode(struct udevice *bus, uint mode)
+{
+       struct mxs_spi_priv *priv = dev_get_priv(bus);
+       struct mxs_ssp_regs *ssp_regs = priv->regs;
+       u32 reg;
+
+       priv->mode = mode;
+       debug("%s: mode 0x%x\n", __func__, mode);
+
+       reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS;
+       reg |= (priv->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0;
+       reg |= (priv->mode & SPI_CPHA) ? SSP_CTRL1_PHASE : 0;
+       writel(reg, &ssp_regs->hw_ssp_ctrl1);
+
+       /* Single bit SPI support */
+       writel(SSP_CTRL0_BUS_WIDTH_ONE_BIT, &ssp_regs->hw_ssp_ctrl0);
+
+       return 0;
+}
+
+static const struct dm_spi_ops mxs_spi_ops = {
+       .claim_bus      = mxs_spi_claim_bus,
+       .release_bus    = mxs_spi_release_bus,
+       .xfer           = mxs_spi_xfer,
+       .set_speed      = mxs_spi_set_speed,
+       .set_mode       = mxs_spi_set_mode,
+       /*
+        * cs_info is not needed, since we require all chip selects to be
+        * in the device tree explicitly
+        */
+};
+
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+static int mxs_ofdata_to_platdata(struct udevice *bus)
+{
+       struct mxs_spi_platdata *plat = bus->platdata;
+       u32 prop[2];
+       int ret;
+
+       plat->base = dev_read_addr(bus);
+       plat->frequency =
+               dev_read_u32_default(bus, "spi-max-frequency", 40000000);
+       plat->num_cs = dev_read_u32_default(bus, "num-cs", 2);
+
+       ret = dev_read_u32_array(bus, "dmas", prop, ARRAY_SIZE(prop));
+       if (ret) {
+               printf("%s: Reading 'dmas' property failed!\n", __func__);
+               return ret;
+       }
+       plat->dma_id = prop[1];
+
+       ret = dev_read_u32_array(bus, "clocks", prop, ARRAY_SIZE(prop));
+       if (ret) {
+               printf("%s: Reading 'clocks' property failed!\n", __func__);
+               return ret;
+       }
+       plat->clk_id = prop[1];
+
+       debug("%s: base=0x%x, max-frequency=%d num-cs=%d dma_id=%d clk_id=%d\n",
+             __func__, (uint)plat->base, plat->frequency, plat->num_cs,
+             plat->dma_id, plat->clk_id);
+
+       return 0;
+}
+#endif
+
+static const struct udevice_id mxs_spi_ids[] = {
+       { .compatible = "fsl,imx23-spi" },
+       { .compatible = "fsl,imx28-spi" },
+       { }
+};
+
+U_BOOT_DRIVER(mxs_spi) = {
+       .name   = "mxs_spi",
+       .id     = UCLASS_SPI,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+       .of_match = mxs_spi_ids,
+       .ofdata_to_platdata = mxs_ofdata_to_platdata,
+#endif
+       .priv_auto_alloc_size = sizeof(struct mxs_spi_platdata),
+       .ops    = &mxs_spi_ops,
+       .priv_auto_alloc_size = sizeof(struct mxs_spi_priv),
+       .probe  = mxs_spi_probe,
+};
+#endif
index 7aabebeff5fa35a6aef80bb1a412403138fd778e..7788ab995344332a1280b196c52de652dd55de5a 100644 (file)
@@ -430,12 +430,14 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op)
                if (slave->max_write_size && len > slave->max_write_size)
                        return -EINVAL;
 
-               if (op->data.dir == SPI_MEM_DATA_IN && slave->max_read_size)
-                       op->data.nbytes = min(op->data.nbytes,
+               if (op->data.dir == SPI_MEM_DATA_IN) {
+                       if (slave->max_read_size)
+                               op->data.nbytes = min(op->data.nbytes,
                                              slave->max_read_size);
-               else if (slave->max_write_size)
+               } else if (slave->max_write_size) {
                        op->data.nbytes = min(op->data.nbytes,
                                              slave->max_write_size - len);
+               }
 
                if (!op->data.nbytes)
                        return -EINVAL;
diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
new file mode 100644 (file)
index 0000000..969bd4b
--- /dev/null
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 SiFive, Inc.
+ * Copyright 2019 Bhargav Shah <bhargavshah1988@gmail.com>
+ *
+ * SiFive SPI controller driver (master mode only)
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <spi.h>
+#include <asm/io.h>
+#include <linux/log2.h>
+#include <clk.h>
+
+#define SIFIVE_SPI_MAX_CS              32
+
+#define SIFIVE_SPI_DEFAULT_DEPTH       8
+#define SIFIVE_SPI_DEFAULT_BITS                8
+
+/* register offsets */
+#define SIFIVE_SPI_REG_SCKDIV            0x00 /* Serial clock divisor */
+#define SIFIVE_SPI_REG_SCKMODE           0x04 /* Serial clock mode */
+#define SIFIVE_SPI_REG_CSID              0x10 /* Chip select ID */
+#define SIFIVE_SPI_REG_CSDEF             0x14 /* Chip select default */
+#define SIFIVE_SPI_REG_CSMODE            0x18 /* Chip select mode */
+#define SIFIVE_SPI_REG_DELAY0            0x28 /* Delay control 0 */
+#define SIFIVE_SPI_REG_DELAY1            0x2c /* Delay control 1 */
+#define SIFIVE_SPI_REG_FMT               0x40 /* Frame format */
+#define SIFIVE_SPI_REG_TXDATA            0x48 /* Tx FIFO data */
+#define SIFIVE_SPI_REG_RXDATA            0x4c /* Rx FIFO data */
+#define SIFIVE_SPI_REG_TXMARK            0x50 /* Tx FIFO watermark */
+#define SIFIVE_SPI_REG_RXMARK            0x54 /* Rx FIFO watermark */
+#define SIFIVE_SPI_REG_FCTRL             0x60 /* SPI flash interface control */
+#define SIFIVE_SPI_REG_FFMT              0x64 /* SPI flash instruction format */
+#define SIFIVE_SPI_REG_IE                0x70 /* Interrupt Enable Register */
+#define SIFIVE_SPI_REG_IP                0x74 /* Interrupt Pendings Register */
+
+/* sckdiv bits */
+#define SIFIVE_SPI_SCKDIV_DIV_MASK       0xfffU
+
+/* sckmode bits */
+#define SIFIVE_SPI_SCKMODE_PHA           BIT(0)
+#define SIFIVE_SPI_SCKMODE_POL           BIT(1)
+#define SIFIVE_SPI_SCKMODE_MODE_MASK     (SIFIVE_SPI_SCKMODE_PHA | \
+                                         SIFIVE_SPI_SCKMODE_POL)
+
+/* csmode bits */
+#define SIFIVE_SPI_CSMODE_MODE_AUTO      0U
+#define SIFIVE_SPI_CSMODE_MODE_HOLD      2U
+#define SIFIVE_SPI_CSMODE_MODE_OFF       3U
+
+/* delay0 bits */
+#define SIFIVE_SPI_DELAY0_CSSCK(x)       ((u32)(x))
+#define SIFIVE_SPI_DELAY0_CSSCK_MASK     0xffU
+#define SIFIVE_SPI_DELAY0_SCKCS(x)       ((u32)(x) << 16)
+#define SIFIVE_SPI_DELAY0_SCKCS_MASK     (0xffU << 16)
+
+/* delay1 bits */
+#define SIFIVE_SPI_DELAY1_INTERCS(x)     ((u32)(x))
+#define SIFIVE_SPI_DELAY1_INTERCS_MASK   0xffU
+#define SIFIVE_SPI_DELAY1_INTERXFR(x)    ((u32)(x) << 16)
+#define SIFIVE_SPI_DELAY1_INTERXFR_MASK  (0xffU << 16)
+
+/* fmt bits */
+#define SIFIVE_SPI_FMT_PROTO_SINGLE      0U
+#define SIFIVE_SPI_FMT_PROTO_DUAL        1U
+#define SIFIVE_SPI_FMT_PROTO_QUAD        2U
+#define SIFIVE_SPI_FMT_PROTO_MASK        3U
+#define SIFIVE_SPI_FMT_ENDIAN            BIT(2)
+#define SIFIVE_SPI_FMT_DIR               BIT(3)
+#define SIFIVE_SPI_FMT_LEN(x)            ((u32)(x) << 16)
+#define SIFIVE_SPI_FMT_LEN_MASK          (0xfU << 16)
+
+/* txdata bits */
+#define SIFIVE_SPI_TXDATA_DATA_MASK      0xffU
+#define SIFIVE_SPI_TXDATA_FULL           BIT(31)
+
+/* rxdata bits */
+#define SIFIVE_SPI_RXDATA_DATA_MASK      0xffU
+#define SIFIVE_SPI_RXDATA_EMPTY          BIT(31)
+
+/* ie and ip bits */
+#define SIFIVE_SPI_IP_TXWM               BIT(0)
+#define SIFIVE_SPI_IP_RXWM               BIT(1)
+
+struct sifive_spi {
+       void            *regs;          /* base address of the registers */
+       u32             fifo_depth;
+       u32             bits_per_word;
+       u32             cs_inactive;    /* Level of the CS pins when inactive*/
+       u32             freq;
+       u32             num_cs;
+};
+
+static void sifive_spi_prep_device(struct sifive_spi *spi,
+                                  struct dm_spi_slave_platdata *slave)
+{
+       /* Update the chip select polarity */
+       if (slave->mode & SPI_CS_HIGH)
+               spi->cs_inactive &= ~BIT(slave->cs);
+       else
+               spi->cs_inactive |= BIT(slave->cs);
+       writel(spi->cs_inactive, spi->regs + SIFIVE_SPI_REG_CSDEF);
+
+       /* Select the correct device */
+       writel(slave->cs, spi->regs + SIFIVE_SPI_REG_CSID);
+}
+
+static int sifive_spi_set_cs(struct sifive_spi *spi,
+                            struct dm_spi_slave_platdata *slave)
+{
+       u32 cs_mode = SIFIVE_SPI_CSMODE_MODE_HOLD;
+
+       if (slave->mode & SPI_CS_HIGH)
+               cs_mode = SIFIVE_SPI_CSMODE_MODE_AUTO;
+
+       writel(cs_mode, spi->regs + SIFIVE_SPI_REG_CSMODE);
+
+       return 0;
+}
+
+static void sifive_spi_clear_cs(struct sifive_spi *spi)
+{
+       writel(SIFIVE_SPI_CSMODE_MODE_AUTO, spi->regs + SIFIVE_SPI_REG_CSMODE);
+}
+
+static void sifive_spi_prep_transfer(struct sifive_spi *spi,
+                                    bool is_rx_xfer,
+                                    struct dm_spi_slave_platdata *slave)
+{
+       u32 cr;
+
+       /* Modify the SPI protocol mode */
+       cr = readl(spi->regs + SIFIVE_SPI_REG_FMT);
+
+       /* Bits per word ? */
+       cr &= ~SIFIVE_SPI_FMT_LEN_MASK;
+       cr |= SIFIVE_SPI_FMT_LEN(spi->bits_per_word);
+
+       /* LSB first? */
+       cr &= ~SIFIVE_SPI_FMT_ENDIAN;
+       if (slave->mode & SPI_LSB_FIRST)
+               cr |= SIFIVE_SPI_FMT_ENDIAN;
+
+       /* Number of wires ? */
+       cr &= ~SIFIVE_SPI_FMT_PROTO_MASK;
+       if ((slave->mode & SPI_TX_QUAD) || (slave->mode & SPI_RX_QUAD))
+               cr |= SIFIVE_SPI_FMT_PROTO_QUAD;
+       else if ((slave->mode & SPI_TX_DUAL) || (slave->mode & SPI_RX_DUAL))
+               cr |= SIFIVE_SPI_FMT_PROTO_DUAL;
+       else
+               cr |= SIFIVE_SPI_FMT_PROTO_SINGLE;
+
+       /* SPI direction in/out ? */
+       cr &= ~SIFIVE_SPI_FMT_DIR;
+       if (!is_rx_xfer)
+               cr |= SIFIVE_SPI_FMT_DIR;
+
+       writel(cr, spi->regs + SIFIVE_SPI_REG_FMT);
+}
+
+static void sifive_spi_rx(struct sifive_spi *spi, u8 *rx_ptr)
+{
+       u32 data;
+
+       do {
+               data = readl(spi->regs + SIFIVE_SPI_REG_RXDATA);
+       } while (data & SIFIVE_SPI_RXDATA_EMPTY);
+
+       if (rx_ptr)
+               *rx_ptr = data & SIFIVE_SPI_RXDATA_DATA_MASK;
+}
+
+static void sifive_spi_tx(struct sifive_spi *spi, const u8 *tx_ptr)
+{
+       u32 data;
+       u8 tx_data = (tx_ptr) ? *tx_ptr & SIFIVE_SPI_TXDATA_DATA_MASK :
+                               SIFIVE_SPI_TXDATA_DATA_MASK;
+
+       do {
+               data = readl(spi->regs + SIFIVE_SPI_REG_TXDATA);
+       } while (data & SIFIVE_SPI_TXDATA_FULL);
+
+       writel(tx_data, spi->regs + SIFIVE_SPI_REG_TXDATA);
+}
+
+static int sifive_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                          const void *dout, void *din, unsigned long flags)
+{
+       struct udevice *bus = dev->parent;
+       struct sifive_spi *spi = dev_get_priv(bus);
+       struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
+       const unsigned char *tx_ptr = dout;
+       u8 *rx_ptr = din;
+       u32 remaining_len;
+       int ret;
+
+       if (flags & SPI_XFER_BEGIN) {
+               sifive_spi_prep_device(spi, slave);
+
+               ret = sifive_spi_set_cs(spi, slave);
+               if (ret)
+                       return ret;
+       }
+
+       sifive_spi_prep_transfer(spi, true, slave);
+
+       remaining_len = bitlen / 8;
+
+       while (remaining_len) {
+               int n_words, tx_words, rx_words;
+
+               n_words = min(remaining_len, spi->fifo_depth);
+
+               /* Enqueue n_words for transmission */
+               if (tx_ptr) {
+                       for (tx_words = 0; tx_words < n_words; ++tx_words) {
+                               sifive_spi_tx(spi, tx_ptr);
+                               sifive_spi_rx(spi, NULL);
+                               tx_ptr++;
+                       }
+               }
+
+               /* Read out all the data from the RX FIFO */
+               if (rx_ptr) {
+                       for (rx_words = 0; rx_words < n_words; ++rx_words) {
+                               sifive_spi_tx(spi, NULL);
+                               sifive_spi_rx(spi, rx_ptr);
+                               rx_ptr++;
+                       }
+               }
+
+               remaining_len -= n_words;
+       }
+
+       if (flags & SPI_XFER_END)
+               sifive_spi_clear_cs(spi);
+
+       return 0;
+}
+
+static int sifive_spi_set_speed(struct udevice *bus, uint speed)
+{
+       struct sifive_spi *spi = dev_get_priv(bus);
+       u32 scale;
+
+       if (speed > spi->freq)
+               speed = spi->freq;
+
+       /* Cofigure max speed */
+       scale = (DIV_ROUND_UP(spi->freq >> 1, speed) - 1)
+                                       & SIFIVE_SPI_SCKDIV_DIV_MASK;
+       writel(scale, spi->regs + SIFIVE_SPI_REG_SCKDIV);
+
+       return 0;
+}
+
+static int sifive_spi_set_mode(struct udevice *bus, uint mode)
+{
+       struct sifive_spi *spi = dev_get_priv(bus);
+       u32 cr;
+
+       /* Switch clock mode bits */
+       cr = readl(spi->regs + SIFIVE_SPI_REG_SCKMODE) &
+                               ~SIFIVE_SPI_SCKMODE_MODE_MASK;
+       if (mode & SPI_CPHA)
+               cr |= SIFIVE_SPI_SCKMODE_PHA;
+       if (mode & SPI_CPOL)
+               cr |= SIFIVE_SPI_SCKMODE_POL;
+
+       writel(cr, spi->regs + SIFIVE_SPI_REG_SCKMODE);
+
+       return 0;
+}
+
+static int sifive_spi_cs_info(struct udevice *bus, uint cs,
+                             struct spi_cs_info *info)
+{
+       struct sifive_spi *spi = dev_get_priv(bus);
+
+       if (cs >= spi->num_cs)
+               return -EINVAL;
+
+       return 0;
+}
+
+static void sifive_spi_init_hw(struct sifive_spi *spi)
+{
+       u32 cs_bits;
+
+       /* probe the number of CS lines */
+       spi->cs_inactive = readl(spi->regs + SIFIVE_SPI_REG_CSDEF);
+       writel(0xffffffffU, spi->regs + SIFIVE_SPI_REG_CSDEF);
+       cs_bits = readl(spi->regs + SIFIVE_SPI_REG_CSDEF);
+       writel(spi->cs_inactive, spi->regs + SIFIVE_SPI_REG_CSDEF);
+       if (!cs_bits) {
+               printf("Could not auto probe CS lines\n");
+               return;
+       }
+
+       spi->num_cs = ilog2(cs_bits) + 1;
+       if (spi->num_cs > SIFIVE_SPI_MAX_CS) {
+               printf("Invalid number of spi slaves\n");
+               return;
+       }
+
+       /* Watermark interrupts are disabled by default */
+       writel(0, spi->regs + SIFIVE_SPI_REG_IE);
+
+       /* Set CS/SCK Delays and Inactive Time to defaults */
+       writel(SIFIVE_SPI_DELAY0_CSSCK(1) | SIFIVE_SPI_DELAY0_SCKCS(1),
+              spi->regs + SIFIVE_SPI_REG_DELAY0);
+       writel(SIFIVE_SPI_DELAY1_INTERCS(1) | SIFIVE_SPI_DELAY1_INTERXFR(0),
+              spi->regs + SIFIVE_SPI_REG_DELAY1);
+
+       /* Exit specialized memory-mapped SPI flash mode */
+       writel(0, spi->regs + SIFIVE_SPI_REG_FCTRL);
+}
+
+static int sifive_spi_probe(struct udevice *bus)
+{
+       struct sifive_spi *spi = dev_get_priv(bus);
+       struct clk clkdev;
+       int ret;
+
+       spi->regs = (void *)(ulong)dev_remap_addr(bus);
+       if (!spi->regs)
+               return -ENODEV;
+
+       spi->fifo_depth = dev_read_u32_default(bus,
+                                              "sifive,fifo-depth",
+                                              SIFIVE_SPI_DEFAULT_DEPTH);
+
+       spi->bits_per_word = dev_read_u32_default(bus,
+                                                 "sifive,max-bits-per-word",
+                                                 SIFIVE_SPI_DEFAULT_BITS);
+
+       ret = clk_get_by_index(bus, 0, &clkdev);
+       if (ret)
+               return ret;
+       spi->freq = clk_get_rate(&clkdev);
+
+       /* init the sifive spi hw */
+       sifive_spi_init_hw(spi);
+
+       return 0;
+}
+
+static const struct dm_spi_ops sifive_spi_ops = {
+       .xfer           = sifive_spi_xfer,
+       .set_speed      = sifive_spi_set_speed,
+       .set_mode       = sifive_spi_set_mode,
+       .cs_info        = sifive_spi_cs_info,
+};
+
+static const struct udevice_id sifive_spi_ids[] = {
+       { .compatible = "sifive,spi0" },
+       { }
+};
+
+U_BOOT_DRIVER(sifive_spi) = {
+       .name   = "sifive_spi",
+       .id     = UCLASS_SPI,
+       .of_match = sifive_spi_ids,
+       .ops    = &sifive_spi_ops,
+       .priv_auto_alloc_size = sizeof(struct sifive_spi),
+       .probe  = sifive_spi_probe,
+};
index a71b9be5fb53c78b3fb3edde7ea0e61297ca1024..bdf8dc6fef50ca102f47541e818bf40667c7e455 100644 (file)
@@ -17,6 +17,15 @@ config IMX_THERMAL
           cpufreq is used as the cooling device to throttle CPUs when the
           passive trip is crossed.
 
+config IMX_SCU_THERMAL
+       bool "Temperature sensor driver for NXP i.MX8"
+       depends on ARCH_IMX8
+       help
+         Support for Temperature sensors on NXP i.MX8.
+         It supports one critical trip point and one passive trip point. The
+         boot is hold to the cool device to throttle CPUs when the passive
+         trip is crossed
+
 config TI_DRA7_THERMAL
         bool "Temperature sensor driver for TI dra7xx SOCs"
         help
index cc75e387e4c55aec6a66294f7a4bbd98cd1bef90..ef2929d180821b2ae7eb9d74a4447a28ce073b7f 100644 (file)
@@ -5,4 +5,5 @@
 
 obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o
 obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
+obj-$(CONFIG_IMX_SCU_THERMAL) += imx_scu_thermal.o
 obj-$(CONFIG_TI_DRA7_THERMAL) += ti-bandgap.o
diff --git a/drivers/thermal/imx_scu_thermal.c b/drivers/thermal/imx_scu_thermal.c
new file mode 100644 (file)
index 0000000..7e17377
--- /dev/null
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <config.h>
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <thermal.h>
+#include <dm/device-internal.h>
+#include <dm/device.h>
+#include <asm/arch/sci/sci.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct imx_sc_thermal_plat {
+       int critical;
+       int alert;
+       int polling_delay;
+       int id;
+       bool zone_node;
+};
+
+static int read_temperature(struct udevice *dev, int *temp)
+{
+       s16 celsius;
+       s8 tenths;
+       int ret;
+
+       sc_rsrc_t *sensor_rsrc = (sc_rsrc_t *)dev_get_driver_data(dev);
+
+       struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev);
+
+       if (!temp)
+               return -EINVAL;
+
+       ret = sc_misc_get_temp(-1, sensor_rsrc[pdata->id], SC_C_TEMP,
+                              &celsius, &tenths);
+       if (ret) {
+               printf("Error: get temperature failed! (error = %d)\n", ret);
+               return ret;
+       }
+
+       *temp = celsius * 1000 + tenths * 100;
+
+       return 0;
+}
+
+int imx_sc_thermal_get_temp(struct udevice *dev, int *temp)
+{
+       struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev);
+       int cpu_temp = 0;
+       int ret;
+
+       ret = read_temperature(dev, &cpu_temp);
+       if (ret)
+               return ret;
+
+       while (cpu_temp >= pdata->alert) {
+               printf("CPU Temperature (%dC) has beyond alert (%dC), close to critical (%dC)",
+                      cpu_temp, pdata->alert, pdata->critical);
+               puts(" waiting...\n");
+               mdelay(pdata->polling_delay);
+               ret = read_temperature(dev, &cpu_temp);
+               if (ret)
+                       return ret;
+       }
+
+       *temp = cpu_temp / 1000;
+
+       return 0;
+}
+
+static const struct dm_thermal_ops imx_sc_thermal_ops = {
+       .get_temp       = imx_sc_thermal_get_temp,
+};
+
+static int imx_sc_thermal_probe(struct udevice *dev)
+{
+       debug("%s dev name %s\n", __func__, dev->name);
+       return 0;
+}
+
+static int imx_sc_thermal_bind(struct udevice *dev)
+{
+       struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev);
+       int reg, ret;
+       int offset;
+       const char *name;
+       const void *prop;
+
+       debug("%s dev name %s\n", __func__, dev->name);
+
+       prop = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "compatible",
+                          NULL);
+       if (!prop)
+               return 0;
+
+       pdata->zone_node = 1;
+
+       reg = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "tsens-num", 0);
+       if (reg == 0) {
+               printf("%s: no temp sensor number provided!\n", __func__);
+               return -EINVAL;
+       }
+
+       offset = fdt_subnode_offset(gd->fdt_blob, 0, "thermal-zones");
+       fdt_for_each_subnode(offset, gd->fdt_blob, offset) {
+               /* Bind the subnode to this driver */
+               name = fdt_get_name(gd->fdt_blob, offset, NULL);
+
+               ret = device_bind_with_driver_data(dev, dev->driver, name,
+                                                  dev->driver_data,
+                                                  offset_to_ofnode(offset),
+                                                  NULL);
+               if (ret)
+                       printf("Error binding driver '%s': %d\n",
+                              dev->driver->name, ret);
+       }
+       return 0;
+}
+
+static int imx_sc_thermal_ofdata_to_platdata(struct udevice *dev)
+{
+       struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev);
+       struct fdtdec_phandle_args args;
+       const char *type;
+       int ret;
+       int trips_np;
+
+       debug("%s dev name %s\n", __func__, dev->name);
+
+       if (pdata->zone_node)
+               return 0;
+
+       ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
+                                            "thermal-sensors",
+                                            "#thermal-sensor-cells",
+                                            0, 0, &args);
+       if (ret)
+               return ret;
+
+       if (args.node != dev_of_offset(dev->parent))
+               return -EFAULT;
+
+       if (args.args_count >= 1)
+               pdata->id = args.args[0];
+       else
+               pdata->id = 0;
+
+       debug("args.args_count %d, id %d\n", args.args_count, pdata->id);
+
+       pdata->polling_delay = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+                                             "polling-delay", 1000);
+
+       trips_np = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(dev),
+                                     "trips");
+       fdt_for_each_subnode(trips_np, gd->fdt_blob, trips_np) {
+               type = fdt_getprop(gd->fdt_blob, trips_np, "type", NULL);
+               if (type) {
+                       if (strcmp(type, "critical") == 0) {
+                               pdata->critical = fdtdec_get_int(gd->fdt_blob,
+                                                                trips_np,
+                                                                "temperature",
+                                                                85);
+                       } else if (strcmp(type, "passive") == 0) {
+                               pdata->alert = fdtdec_get_int(gd->fdt_blob,
+                                                             trips_np,
+                                                             "temperature",
+                                                             80);
+                       }
+               }
+       }
+
+       debug("id %d polling_delay %d, critical %d, alert %d\n", pdata->id,
+             pdata->polling_delay, pdata->critical, pdata->alert);
+
+       return 0;
+}
+
+static const sc_rsrc_t imx8qxp_sensor_rsrc[] = {
+       SC_R_SYSTEM, SC_R_DRC_0, SC_R_PMIC_0,
+       SC_R_PMIC_1, SC_R_PMIC_2,
+};
+
+static const struct udevice_id imx_sc_thermal_ids[] = {
+       { .compatible = "nxp,imx8qxp-sc-tsens", .data =
+               (ulong)&imx8qxp_sensor_rsrc, },
+       { }
+};
+
+U_BOOT_DRIVER(imx_sc_thermal) = {
+       .name   = "imx_sc_thermal",
+       .id     = UCLASS_THERMAL,
+       .ops    = &imx_sc_thermal_ops,
+       .of_match = imx_sc_thermal_ids,
+       .bind = imx_sc_thermal_bind,
+       .probe  = imx_sc_thermal_probe,
+       .ofdata_to_platdata = imx_sc_thermal_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct imx_sc_thermal_plat),
+       .flags  = DM_FLAG_PRE_RELOC,
+};
index ee0ddffe7355e8193070c951d5a8bedb54059d3c..ccda432f49ab27a408bd27386d7ca52a1fc1328e 100644 (file)
@@ -28,7 +28,7 @@ config BCM2835_WDT
 
 config IMX_WATCHDOG
        bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP"
-       select HW_WATCHDOG
+       select HW_WATCHDOG if !WDT
        help
           Select this to enable the IMX and LSCH2 of Layerscape watchdog
           driver.
@@ -169,4 +169,11 @@ config WDT_TANGIER
          Intel Tangier SoC. If you're using a board with Intel Tangier
          SoC, say Y here.
 
+config SPL_WDT
+       bool "Enable driver model for watchdog timer drivers in SPL"
+       depends on SPL_DM
+       help
+         Enable driver model for watchdog timer in SPL.
+         This is similar to CONFIG_WDT in U-Boot.
+
 endmenu
index 68c989aa0b905fe09d66805953d914d810ccacc3..97aa6a836ce67e4dd217b6b053d5b586dae18d4d 100644 (file)
@@ -15,7 +15,7 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
 obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
 obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o
 obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o
-obj-$(CONFIG_WDT) += wdt-uclass.o
+obj-$(CONFIG_$(SPL_TPL_)WDT) += wdt-uclass.o
 obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
 obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o
 obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
index 14cc618074bd84f312b502c16cc01389d8095b42..53a3e9f5c78e8a794c7098468973bafb78ec02f9 100644 (file)
@@ -5,7 +5,9 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <asm/io.h>
+#include <wdt.h>
 #include <watchdog.h>
 #include <asm/arch/imx-regs.h>
 #ifdef CONFIG_FSL_LSCH2
 #endif
 #include <fsl_wdog.h>
 
-#ifdef CONFIG_IMX_WATCHDOG
-void hw_watchdog_reset(void)
+static void imx_watchdog_expire_now(struct watchdog_regs *wdog)
+{
+       clrsetbits_le16(&wdog->wcr, WCR_WT_MSK, WCR_WDE);
+
+       writew(0x5555, &wdog->wsr);
+       writew(0xaaaa, &wdog->wsr);     /* load minimum 1/2 second timeout */
+       while (1) {
+               /*
+                * spin for .5 seconds before reset
+                */
+       }
+}
+
+#if !defined(CONFIG_IMX_WATCHDOG) || \
+    (defined(CONFIG_IMX_WATCHDOG) && !CONFIG_IS_ENABLED(WDT))
+void __attribute__((weak)) reset_cpu(ulong addr)
 {
-#ifndef CONFIG_WATCHDOG_RESET_DISABLE
        struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
 
+       imx_watchdog_expire_now(wdog);
+}
+#endif
+
+#if defined(CONFIG_IMX_WATCHDOG)
+static void imx_watchdog_reset(struct watchdog_regs *wdog)
+{
+#ifndef CONFIG_WATCHDOG_RESET_DISABLE
        writew(0x5555, &wdog->wsr);
        writew(0xaaaa, &wdog->wsr);
 #endif /* CONFIG_WATCHDOG_RESET_DISABLE*/
 }
 
-void hw_watchdog_init(void)
+static void imx_watchdog_init(struct watchdog_regs *wdog)
 {
-       struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
        u16 timeout;
 
        /*
@@ -44,21 +66,86 @@ void hw_watchdog_init(void)
        writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT | WCR_SRS |
                WCR_WDA | SET_WCR_WT(timeout), &wdog->wcr);
 #endif /* CONFIG_FSL_LSCH2*/
-       hw_watchdog_reset();
+       imx_watchdog_reset(wdog);
 }
-#endif
 
-void __attribute__((weak)) reset_cpu(ulong addr)
+#if !CONFIG_IS_ENABLED(WDT)
+void hw_watchdog_reset(void)
 {
        struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
 
-       clrsetbits_le16(&wdog->wcr, WCR_WT_MSK, WCR_WDE);
+       imx_watchdog_reset(wdog);
+}
 
-       writew(0x5555, &wdog->wsr);
-       writew(0xaaaa, &wdog->wsr);     /* load minimum 1/2 second timeout */
-       while (1) {
-               /*
-                * spin for .5 seconds before reset
-                */
-       }
+void hw_watchdog_init(void)
+{
+       struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+       imx_watchdog_init(wdog);
+}
+#else
+struct imx_wdt_priv {
+       void __iomem *base;
+};
+
+static int imx_wdt_reset(struct udevice *dev)
+{
+       struct imx_wdt_priv *priv = dev_get_priv(dev);
+
+       imx_watchdog_reset(priv->base);
+
+       return 0;
+}
+
+static int imx_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+       struct imx_wdt_priv *priv = dev_get_priv(dev);
+
+       imx_watchdog_expire_now(priv->base);
+       hang();
+
+       return 0;
+}
+
+static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+       struct imx_wdt_priv *priv = dev_get_priv(dev);
+
+       imx_watchdog_init(priv->base);
+
+       return 0;
+}
+
+static int imx_wdt_probe(struct udevice *dev)
+{
+       struct imx_wdt_priv *priv = dev_get_priv(dev);
+
+       priv->base = dev_read_addr_ptr(dev);
+       if (!priv->base)
+               return -ENOENT;
+
+       return 0;
 }
+
+static const struct wdt_ops imx_wdt_ops = {
+       .start          = imx_wdt_start,
+       .reset          = imx_wdt_reset,
+       .expire_now     = imx_wdt_expire_now,
+};
+
+static const struct udevice_id imx_wdt_ids[] = {
+       { .compatible = "fsl,imx21-wdt" },
+       {}
+};
+
+U_BOOT_DRIVER(imx_wdt) = {
+       .name           = "imx_wdt",
+       .id             = UCLASS_WDT,
+       .of_match       = imx_wdt_ids,
+       .probe          = imx_wdt_probe,
+       .ops            = &imx_wdt_ops,
+       .priv_auto_alloc_size = sizeof(struct imx_wdt_priv),
+       .flags          = DM_FLAG_PRE_RELOC,
+};
+#endif
+#endif
index 02a3ed683821fa1af7d16296c472e4033526e5a5..7c2220643b5b1f3f3f13414138f11e1651e03675 100644 (file)
@@ -137,7 +137,7 @@ typedef struct global_data {
 #if defined(CONFIG_TRANSLATION_OFFSET)
        fdt_addr_t translation_offset;  /* optional translation offset */
 #endif
-#if defined(CONFIG_WDT)
+#if CONFIG_IS_ENABLED(WDT)
        struct udevice *watchdog_dev;
 #endif
 } gd_t;
index d24e99713a3591f4565ecf30b49b9358cd582a0d..f8f56d9cf01db92094fa91960120e31f35a48d21 100644 (file)
@@ -20,7 +20,7 @@
  * clock provider. This API provides a standard means for drivers to enable and
  * disable clocks, and to set the rate at which they oscillate.
  *
- * A driver that implements UCLASS_CLOCK is a clock provider. A provider will
+ * A driver that implements UCLASS_CLK is a clock provider. A provider will
  * often implement multiple separate clocks, since the hardware it manages
  * often has this capability. clk-uclass.h describes the interface which
  * clock providers must implement.
@@ -40,6 +40,10 @@ struct udevice;
  * other clock APIs to identify which clock signal to operate upon.
  *
  * @dev: The device which implements the clock signal.
+ * @rate: The clock rate (in HZ).
+ * @flags: Flags used across common clock structure (e.g. CLK_)
+ *         Clock IP blocks specific flags (i.e. mux, div, gate, etc) are defined
+ *         in struct's for those devices (e.g. struct clk_mux).
  * @id: The clock signal ID within the provider.
  * @data: An optional data field for scenarios where a single integer ID is not
  *       sufficient. If used, it can be populated through an .of_xlate op and
@@ -55,6 +59,8 @@ struct udevice;
  */
 struct clk {
        struct udevice *dev;
+       long long rate; /* in HZ */
+       u32 flags;
        /*
         * Written by of_xlate. In the future, we might add more fields here.
         */
@@ -252,6 +258,24 @@ int clk_free(struct clk *clk);
  */
 ulong clk_get_rate(struct clk *clk);
 
+/**
+ * clk_get_parent() - Get current clock's parent.
+ *
+ * @clk:       A clock struct that was previously successfully requested by
+ *             clk_request/get_by_*().
+ * @return pointer to parent's struct clk, or error code passed as pointer
+ */
+struct clk *clk_get_parent(struct clk *clk);
+
+/**
+ * clk_get_parent_rate() - Get parent of current clock rate.
+ *
+ * @clk:       A clock struct that was previously successfully requested by
+ *             clk_request/get_by_*().
+ * @return clock rate in Hz, or -ve error code.
+ */
+long long clk_get_parent_rate(struct clk *clk);
+
 /**
  * clk_set_rate() - Set current clock rate.
  *
@@ -321,4 +345,15 @@ static inline bool clk_valid(struct clk *clk)
 {
        return !!clk->dev;
 }
+
+/**
+ * clk_get_by_id() - Get the clock by its ID
+ *
+ * @id:        The clock ID to search for
+ *
+ * @clkp:      A pointer to clock struct that has been found among added clocks
+ *              to UCLASS_CLK
+ * @return zero on success, or -ENOENT on error
+ */
+int clk_get_by_id(ulong id, struct clk **clkp);
 #endif
index 22d1e41bc8dcac903fdbaed34bcb2e95f6ce5fd7..a03734916278fc757e416fb877a6cfb925c5ddc7 100644 (file)
 #define CONFIG_IMX_VIDEO_SKIP
 #endif
 
-#define CONFIG_PWM_IMX
 #define CONFIG_IMX6_PWM_PER_CLK         66000000
 
 #ifdef CONFIG_CMD_PCI
index db37fa7b731a9cabb67455a8c72a079842445d23..974571df435e268448592cc012e926019613bde0 100644 (file)
        "sdfinduuid=part uuid mmc ${sddev}:${sdrootpart} uuid\0" \
        "sdrootpart=2\0"
 
-
-#define USB_BOOTCMD \
-       "set_usbargs=setenv usbargs ip=off root=PARTUUID=${uuid} ro,noatime " \
-               "rootfstype=ext4 rootwait\0" \
-       "usbboot=run setup; usb start; run usbfinduuid; run set_usbargs; " \
-               "setenv bootargs ${defargs} ${setupargs} " \
-               "${usbargs} ${vidargs}; echo Booting from USB stick...; " \
-               "run usbdtbload; load usb " \
-               "${usbdev}:${usbbootpart} ${kernel_addr_r} " \
-               "${boot_file} && run fdt_fixup && " \
-               "bootz ${kernel_addr_r} ${dtbparam}\0" \
-       "usbbootpart=1\0" \
-       "usbdev=0\0" \
-       "usbdtbload=setenv dtbparam; load usb ${usbdev}:${usbbootpart} "\
-               "${fdt_addr_r} " \
-               "${fdt_file} && setenv dtbparam \" - " \
-               "${fdt_addr_r}\" && true\0" \
-       "usbfinduuid=part uuid usb ${usbdev}:${usbrootpart} uuid\0" \
-       "usbrootpart=2\0"
-
-
 #ifndef CONFIG_TDX_APALIS_IMX6_V1_0
 #define FDT_FILE "imx6q-apalis-eval.dtb"
 #define FDT_FILE_V1_0 "imx6q-apalis_v1_0-eval.dtb"
        MEM_LAYOUT_ENV_SETTINGS \
        NFS_BOOTCMD \
        SD_BOOTCMD \
-       USB_BOOTCMD \
        "setethupdate=if env exists ethaddr; then; else setenv ethaddr " \
                "00:14:2d:00:00:00; fi; tftpboot ${loadaddr} " \
                "flash_eth.img && source ${loadaddr}\0" \
index a24814673c5fba64c64973366b890e359f11e9b2..e998d9b1b279800f27a67be3e091574d9aec6cf9 100644 (file)
 #define CONFIG_VIDEO_BMP_LOGO
 #define CONFIG_IMX_VIDEO_SKIP
 
-#define CONFIG_PWM_IMX
 #define CONFIG_IMX6_PWM_PER_CLK        66000000
 
 #endif /* __ARISTAINETOS_COMMON_CONFIG_H */
index 00e5667499e4f91842f3fdbd86810acb7c38e1f4..361e6ac65425f818cbd7f4e84be3fbd53f969c4d 100644 (file)
@@ -45,9 +45,6 @@
 #define CONFIG_LG4573_BUS 0
 #define CONFIG_LG4573_CS 0
 
-#define CONFIG_PWM_IMX
-#define CONFIG_IMX6_PWM_PER_CLK        66000000
-
 #include "aristainetos-common.h"
 
 #endif                         /* __ARISTAINETOS2_CONFIG_H */
index cfe0e053b6638cb7ca196df339a32fc7cfe6501f..cdeb7a3b032f40e50a90979d7158f96cc6ad8520 100644 (file)
@@ -45,9 +45,6 @@
 #define CONFIG_LG4573_BUS 0
 #define CONFIG_LG4573_CS 1
 
-#define CONFIG_PWM_IMX
-#define CONFIG_IMX6_PWM_PER_CLK        66000000
-
 #include "aristainetos-common.h"
 
 #endif                         /* __ARISTAINETOS2B_CONFIG_H */
index 21d9a3da01fa47818dfeae468dd7f1386185ca74..2c43862800a29a866ca3a16457d1a1cb26691e4a 100644 (file)
                "${board}/flash_blk.img && source ${loadaddr}\0" \
        "splashpos=m,m\0" \
        "videomode=video=ctfb:x:640,y:480,depth:18,pclk:39722,le:48,ri:16,up:33,lo:10,hs:96,vs:2,sync:0,vmode:0\0" \
-       "vidargs=video=mxsfb:640x480-16@60"
+       "vidargs=video=mxsfb:640x480M-16@60"
 
 #define CONFIG_SYS_MEMTEST_START       0x80000000
 #define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START + 0x08000000)
index 86f3f0d4fa2d666a931f9bef17832c7c2e207d75..147f801353447f4691141558a6e40e550a038920 100644 (file)
        "sdfinduuid=part uuid mmc ${sddev}:${sdrootpart} uuid\0" \
        "sdrootpart=2\0"
 
-#define USB_BOOTCMD \
-       "set_usbargs=setenv usbargs ip=off root=PARTUUID=${uuid} rw,noatime " \
-               "rootfstype=ext4 rootwait\0" \
-       "usbboot=run setup; usb start; run usbfinduuid; run set_usbargs; " \
-               "setenv bootargs ${defargs} ${setupargs} " \
-               "${usbargs} ${vidargs}; echo Booting from USB stick...; " \
-               "run usbdtbload; " \
-               "load usb ${usbdev}:${usbbootpart} ${kernel_addr_r} " \
-               "${boot_file} && run fdt_fixup && " \
-               "bootz ${kernel_addr_r} ${dtbparam}\0" \
-       "usbbootpart=1\0" \
-       "usbdev=0\0" \
-       "usbdtbload=setenv dtbparam; load usb ${usbdev}:${usbbootpart} " \
-               "${fdt_addr_r} " \
-               "${fdt_file} && setenv dtbparam \" - ${fdt_addr_r}\" && " \
-               "true\0" \
-       "usbfinduuid=part uuid usb ${usbdev}:${usbrootpart} uuid\0" \
-       "usbrootpart=2\0"
-
 #define FDT_FILE "imx6dl-colibri-eval-v3.dtb"
 #define CONFIG_EXTRA_ENV_SETTINGS \
        BOOTENV \
        MEM_LAYOUT_ENV_SETTINGS \
        NFS_BOOTCMD \
        SD_BOOTCMD \
-       USB_BOOTCMD \
        "setethupdate=if env exists ethaddr; then; else setenv ethaddr " \
                "00:14:2d:00:00:00; fi; tftpboot ${loadaddr} " \
                "flash_eth.img && source ${loadaddr}\0" \
index 40173b18fa77f7acab2cee04ee15eba67e662c15..49cdd610387eba9d68a2d465636475633f0f94f8 100644 (file)
 #define CONFIG_NETMASK                 255.255.255.0
 #define CONFIG_SERVERIP                        192.168.10.1
 
+#ifndef PARTS_DEFAULT
+/* Define the default GPT table for eMMC */
+#define PARTS_DEFAULT \
+       /* Android partitions */ \
+       "partitions_android=" \
+       "uuid_disk=${uuid_gpt_disk};" \
+       "name=boot,start=1M,size=32M,uuid=${uuid_gpt_boot};" \
+       "name=environment,size=4M,uuid=${uuid_gpt_environment};" \
+       "name=recovery,size=16M,uuid=${uuid_gpt_recovery};" \
+       "name=system,size=1536M,uuid=${uuid_gpt_system};" \
+       "name=cache,size=512M,uuid=${uuid_gpt_cache};" \
+       "name=device,size=8M,uuid=${uuid_gpt_device};" \
+       "name=misc,size=4M,uuid=${uuid_gpt_misc};" \
+       "name=datafooter,size=2M,uuid=${uuid_gpt_datafooter};" \
+       "name=metadata,size=2M,uuid=${uuid_gpt_metadata};" \
+       "name=persistdata,size=2M,uuid=${uuid_gpt_persistdata};" \
+       "name=userdata,size=128M,uuid=${uuid_gpt_userdata};" \
+       "name=fbmisc,size=-,uuid=${uuid_gpt_fbmisc}\0"
+#endif /* PARTS_DEFAULT */
+
+#define EMMC_ANDROID_BOOTCMD \
+       "android_args=androidboot.storage_type=emmc\0" \
+       PARTS_DEFAULT \
+       "android_fdt_addr=0x83700000\0" \
+       "android_mmc_dev=0\0" \
+       "m4binary=rpmsg_imu_freertos.elf\0" \
+       "androidboot=ext4load mmc 0:a ${loadaddr} media/0/${m4binary}; "\
+               "bootaux ${loadaddr}; " \
+               "setenv loadaddr 0x88000000; " \
+               "setenv bootm_boot_mode sec;" \
+               "setenv bootargs androidboot.serialno=${serial#} " \
+                       "$android_args; " \
+               "part start mmc ${android_mmc_dev} boot boot_start; " \
+               "part size mmc ${android_mmc_dev} boot boot_size; " \
+               "mmc read ${loadaddr} ${boot_start} ${boot_size}; " \
+               "part start mmc ${android_mmc_dev} environment env_start; " \
+               "part size mmc ${android_mmc_dev} environment env_size; " \
+               "mmc read ${android_fdt_addr} ${env_start} ${env_size}; " \
+               "bootm ${loadaddr} ${loadaddr} ${android_fdt_addr}\0 "
+
 #define EMMC_BOOTCMD \
        "set_emmcargs=setenv emmcargs ip=off root=PARTUUID=${uuid} ro " \
                "rootfstype=ext4 rootwait\0" \
        "emmcfinduuid=part uuid mmc ${emmcdev}:${emmcrootpart} uuid\0" \
        "emmcrootpart=2\0"
 
-
 #define MEM_LAYOUT_ENV_SETTINGS \
        "bootm_size=0x10000000\0" \
        "fdt_addr_r=0x82000000\0" \
        "setenv fdtfile ${soc}-colibri-emmc-${fdt_board}.dtb && run distro_bootcmd;"
 #define MODULE_EXTRA_ENV_SETTINGS \
        "variant=-emmc\0" \
-       EMMC_BOOTCMD
+       EMMC_BOOTCMD \
+       EMMC_ANDROID_BOOTCMD
 #endif
 
 #if defined(CONFIG_TARGET_COLIBRI_IMX7_NAND)
index 3b1d0a99a19016dcb4f8bc5a7dd7048b2ef3d220..7d2e5738467207d8abb2476d3bf66b6ad56f4a69 100644 (file)
 #define CONFIG_FEC_MXC_PHYADDR         0
 #define CONFIG_ARP_TIMEOUT             200UL
 
-/* I2C Configs */
-#define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_MXC
-#define CONFIG_SYS_I2C_MXC_I2C1                /* enable I2C bus 1 */
-#define CONFIG_SYS_I2C_MXC_I2C2                /* enable I2C bus 2 */
-#define CONFIG_SYS_I2C_MXC_I2C3                /* enable I2C bus 3 */
-#define CONFIG_SYS_I2C_SPEED           100000
-
 /* MMC Configs */
 #define CONFIG_FSL_USDHC
 #define CONFIG_SYS_FSL_ESDHC_ADDR      0
index 8829cbad913c05ff94d0009e7852b7171a94307a..1d3334ff12c92db4a78c878f96e5ae3517755686 100644 (file)
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN          (16 * 1024 * 1024)
 
-/*#define CONFIG_MXC_UART*/
 #define CONFIG_MXC_UART_BASE           UART5_BASE
 
-/* SPI NOR Flash */
-
 /* I2C Configs */
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MXC
 #define CONFIG_SYS_INIT_SP_ADDR \
        (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
 
-/* Commands */
-
 /* Watchdog */
 #define CONFIG_WATCHDOG_TIMEOUT_MSECS   15000
 
index 0481ed06a91f22ce4da0e700c3d19f7c0a9d6f2e..31214a6aa78e2beb43bf4ca30aac03dd88626606 100644 (file)
 #define CONFIG_IMX_VIDEO_SKIP
 #define CONFIG_CMD_BMP
 
-#define CONFIG_PWM_IMX
 #define CONFIG_IMX6_PWM_PER_CLK        66000000
 
 #define CONFIG_PCI
index 7b68c1c0a1e54ff2be05237453ff2d620d0de7ec..e98dbfbb7ee1857eff0b721fea2bbd118ca1171b 100644 (file)
                "fi ; "                                                 \
                "fi\0"
 
+#if defined(CONFIG_SPL_BUILD)
+#undef CONFIG_WATCHDOG
+#define CONFIG_HW_WATCHDOG
+#endif
+
 #endif /* __M53MENLO_CONFIG_H__ */
index a1774c027a955823c5d9026864b39f18bf8e0a8b..667dac7340a15a9f21b9442f4c37e690a70e814c 100644 (file)
 #define CONFIG_SYS_FLASH_BANKS_LIST    { (CONFIG_SYS_FLASH_BASE) }
 #define CONFIG_SYS_FLASH_BANKS_SIZES   { (32 * SZ_1M) }
 
-/* MTD support */
-
-/* USB Configs */
-#define CONFIG_USB_MAX_CONTROLLER_COUNT        2
-#define CONFIG_MXC_USB_PORTSC          (PORT_PTS_UTMI | PORT_PTS_PTW)
-#define CONFIG_MXC_USB_FLAGS           0
-
 /* Ethernet Configuration */
 #define CONFIG_FEC_MXC
 #define IMX_FEC_BASE                   ENET_BASE_ADDR
@@ -85,6 +78,7 @@
        "fdt_high=0xffffffff\0" \
        "initrd_high=0xffffffff\0" \
        "boot_os=yes\0" \
+       "disable_giga=yes\0" \
        "download_kernel=" \
                "tftpboot ${kernel_addr} ${kernel_file};" \
                "tftpboot ${fdt_addr} ${fdtfile};\0" \
index 2d6715cba260245b0594f04f982af2b187f490b9..d5b54dfa15e0cc01f35a181632a4adf8f422918d 100644 (file)
 #define CONFIG_BCH
 
 /* Backlight Control */
-#define CONFIG_PWM_IMX
 #define CONFIG_IMX6_PWM_PER_CLK 66666000
 
 #endif                         /* __CONFIG_H */
index d4db9b4a567187894e62ab3dcb567d6bf0183b15..33f06c00b1d8c5f57d4bd8ffa12d88d827504e85 100644 (file)
@@ -83,7 +83,6 @@
 
 #define CONFIG_IMX_THERMAL
 
-#define CONFIG_PWM_IMX
 #define CONFIG_IMX6_PWM_PER_CLK 66000000
 
 #define CONFIG_ENV_OFFSET              (8 * SZ_64K)
index 8ceaa0c6c604a3c35f3d5543c9def16fb522109a..73541fe176081990602903db29a59687b81d3952 100644 (file)
 #define CONFIG_DFU_ENV_SETTINGS \
        "dfu_alt_info=boot raw 0x2 0x1000 mmcpart 1\0" \
 
+/* When booting with FIT specify the node entry containing boot.scr */
+#if defined(CONFIG_FIT)
+#define BOOT_SCR_STRING "source ${bootscriptaddr}:${bootscr_fitimage_name}\0"
+#else
+#define BOOT_SCR_STRING "source ${bootscriptaddr}\0"
+#endif
+
+#ifndef CONFIG_OPTEE_LOAD_ADDR
+#define CONFIG_OPTEE_LOAD_ADDR 0
+#endif
+
 #define CONFIG_EXTRA_ENV_SETTINGS \
        CONFIG_DFU_ENV_SETTINGS \
        "script=boot.scr\0" \
+       "bootscr_fitimage_name=bootscr\0" \
        "script_signed=boot.scr.imx-signed\0" \
+       "bootscriptaddr=0x83200000\0" \
        "image=zImage\0" \
        "console=ttymxc0\0" \
        "ethact=usb_ether\0" \
@@ -38,6 +51,7 @@
        "initrd_high=0xffffffff\0" \
        "fdt_file=imx7s-warp.dtb\0" \
        "fdt_addr=" __stringify(CONFIG_SYS_FDT_ADDR)"\0" \
+       "fdtovaddr=0x83100000\0" \
        "optee_addr=" __stringify(CONFIG_OPTEE_LOAD_ADDR)"\0" \
        "boot_fdt=try\0" \
        "ip_dyn=yes\0" \
        "warp7_auth_or_fail=hab_auth_img_or_fail ${hab_ivt_addr} ${filesize} 0;\0" \
        "do_bootscript_hab=" \
                "if test ${hab_enabled} -eq 1; then " \
-                       "setexpr hab_ivt_addr ${loadaddr} - ${ivt_offset}; " \
+                       "setexpr hab_ivt_addr ${bootscriptaddr} - ${ivt_offset}; " \
                        "setenv script ${script_signed}; " \
                        "load mmc ${mmcdev}:${mmcpart} ${hab_ivt_addr} ${script}; " \
                        "run warp7_auth_or_fail; " \
                        "run bootscript; "\
                "fi;\0" \
        "loadbootscript=" \
-               "load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+               "load mmc ${mmcdev}:${mmcpart} ${bootscriptaddr} ${script};\0" \
        "bootscript=echo Running bootscript from mmc ...; " \
-               "source\0" \
+               BOOT_SCR_STRING \
        "loadimage=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
        "loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
        "mmcboot=echo Booting from mmc ...; " \
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
new file mode 100644 (file)
index 0000000..43a25e9
--- /dev/null
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (c) 2010-2011 Jeremy Kerr <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
+ */
+#ifndef __LINUX_CLK_PROVIDER_H
+#define __LINUX_CLK_PROVIDER_H
+
+static inline void clk_dm(ulong id, struct clk *clk)
+{
+       if (!IS_ERR(clk))
+               clk->id = id;
+}
+
+/*
+ * flags used across common struct clk.  these flags should only affect the
+ * top-level framework.  custom flags for dealing with hardware specifics
+ * belong in struct clk_foo
+ *
+ * Please update clk_flags[] in drivers/clk/clk.c when making changes here!
+ */
+#define CLK_SET_RATE_GATE      BIT(0) /* must be gated across rate change */
+#define CLK_SET_PARENT_GATE    BIT(1) /* must be gated across re-parent */
+#define CLK_SET_RATE_PARENT    BIT(2) /* propagate rate change up one level */
+#define CLK_IGNORE_UNUSED      BIT(3) /* do not gate even if unused */
+                               /* unused */
+#define CLK_IS_BASIC           BIT(5) /* Basic clk, can't do a to_clk_foo() */
+#define CLK_GET_RATE_NOCACHE   BIT(6) /* do not use the cached clk rate */
+#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
+#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
+#define CLK_RECALC_NEW_RATES   BIT(9) /* recalc rates after notifications */
+#define CLK_SET_RATE_UNGATE    BIT(10) /* clock needs to run to set rate */
+#define CLK_IS_CRITICAL                BIT(11) /* do not gate, ever */
+/* parents need enable during gate/ungate, set rate and re-parent */
+#define CLK_OPS_PARENT_ENABLE  BIT(12)
+/* duty cycle call may be forwarded to the parent clock */
+#define CLK_DUTY_CYCLE_PARENT  BIT(13)
+
+#define CLK_MUX_INDEX_ONE              BIT(0)
+#define CLK_MUX_INDEX_BIT              BIT(1)
+#define CLK_MUX_HIWORD_MASK            BIT(2)
+#define CLK_MUX_READ_ONLY              BIT(3) /* mux can't be changed */
+#define CLK_MUX_ROUND_CLOSEST          BIT(4)
+
+struct clk_mux {
+       struct clk      clk;
+       void __iomem    *reg;
+       u32             *table;
+       u32             mask;
+       u8              shift;
+       u8              flags;
+
+       /*
+        * Fields from struct clk_init_data - this struct has been
+        * omitted to avoid too deep level of CCF for bootloader
+        */
+       const char      * const *parent_names;
+       u8              num_parents;
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+       u32             io_mux_val;
+#endif
+
+};
+
+#define to_clk_mux(_clk) container_of(_clk, struct clk_mux, clk)
+
+struct clk_div_table {
+       unsigned int    val;
+       unsigned int    div;
+};
+
+struct clk_divider {
+       struct clk      clk;
+       void __iomem    *reg;
+       u8              shift;
+       u8              width;
+       u8              flags;
+       const struct clk_div_table      *table;
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+       u32             io_divider_val;
+#endif
+};
+
+#define clk_div_mask(width)    ((1 << (width)) - 1)
+#define to_clk_divider(_clk) container_of(_clk, struct clk_divider, clk)
+
+#define CLK_DIVIDER_ONE_BASED          BIT(0)
+#define CLK_DIVIDER_POWER_OF_TWO       BIT(1)
+#define CLK_DIVIDER_ALLOW_ZERO         BIT(2)
+#define CLK_DIVIDER_HIWORD_MASK                BIT(3)
+#define CLK_DIVIDER_ROUND_CLOSEST      BIT(4)
+#define CLK_DIVIDER_READ_ONLY          BIT(5)
+#define CLK_DIVIDER_MAX_AT_ZERO                BIT(6)
+
+struct clk_fixed_factor {
+       struct clk      clk;
+       unsigned int    mult;
+       unsigned int    div;
+};
+
+#define to_clk_fixed_factor(_clk) container_of(_clk, struct clk_fixed_factor,\
+                                              clk)
+
+int clk_register(struct clk *clk, const char *drv_name, const char *name,
+                const char *parent_name);
+
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned int mult, unsigned int div);
+
+struct clk *clk_register_divider(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags);
+
+struct clk *clk_register_mux(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_mux_flags);
+
+const char *clk_hw_get_name(const struct clk *hw);
+ulong clk_generic_get_rate(struct clk *clk);
+
+static inline struct clk *dev_get_clk_ptr(struct udevice *dev)
+{
+       return (struct clk *)dev_get_uclass_priv(dev);
+}
+#endif /* __LINUX_CLK_PROVIDER_H */
diff --git a/include/mxs_nand.h b/include/mxs_nand.h
new file mode 100644 (file)
index 0000000..4bd65cd
--- /dev/null
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * NXP GPMI NAND flash driver
+ *
+ * Copyright (C) 2018 Toradex
+ * Authors:
+ * Stefan Agner <stefan.agner@toradex.com>
+ */
+
+#include <linux/mtd/mtd.h>
+#include <asm/cache.h>
+#include <nand.h>
+#include <asm/mach-imx/dma.h>
+
+/**
+ * @gf_len:                   The length of Galois Field. (e.g., 13 or 14)
+ * @ecc_strength:             A number that describes the strength of the ECC
+ *                            algorithm.
+ * @ecc_chunk_size:           The size, in bytes, of a single ECC chunk. Note
+ *                            the first chunk in the page includes both data and
+ *                            metadata, so it's a bit larger than this value.
+ * @ecc_chunk_count:          The number of ECC chunks in the page,
+ * @block_mark_byte_offset:   The byte offset in the ECC-based page view at
+ *                            which the underlying physical block mark appears.
+ * @block_mark_bit_offset:    The bit offset into the ECC-based page view at
+ *                            which the underlying physical block mark appears.
+ */
+struct bch_geometry {
+       unsigned int  gf_len;
+       unsigned int  ecc_strength;
+       unsigned int  ecc_chunk_size;
+       unsigned int  ecc_chunk_count;
+       unsigned int  block_mark_byte_offset;
+       unsigned int  block_mark_bit_offset;
+};
+
+struct mxs_nand_info {
+       struct nand_chip chip;
+       struct udevice *dev;
+       unsigned int    max_ecc_strength_supported;
+       bool            use_minimum_ecc;
+       int             cur_chip;
+
+       uint32_t        cmd_queue_len;
+       uint32_t        data_buf_size;
+       struct bch_geometry bch_geometry;
+
+       uint8_t         *cmd_buf;
+       uint8_t         *data_buf;
+       uint8_t         *oob_buf;
+
+       uint8_t         marking_block_bad;
+       uint8_t         raw_oob_mode;
+
+       struct mxs_gpmi_regs *gpmi_regs;
+       struct mxs_bch_regs *bch_regs;
+
+       /* Functions with altered behaviour */
+       int             (*hooked_read_oob)(struct mtd_info *mtd,
+                               loff_t from, struct mtd_oob_ops *ops);
+       int             (*hooked_write_oob)(struct mtd_info *mtd,
+                               loff_t to, struct mtd_oob_ops *ops);
+       int             (*hooked_block_markbad)(struct mtd_info *mtd,
+                               loff_t ofs);
+
+       /* DMA descriptors */
+       struct mxs_dma_desc     **desc;
+       uint32_t                desc_index;
+};
+
+int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info);
+int mxs_nand_init_spl(struct nand_chip *nand);
+int mxs_nand_setup_ecc(struct mtd_info *mtd);
index 38c69b2b90985ba254749a738e6eefd188a07204..75e07e1de31e8df136ec5d74a55901c6ade8d72a 100644 (file)
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /* Copyright (C) 2018 ROHM Semiconductors */
 
-#ifndef BD71837_H_
-#define BD71837_H_
+#ifndef BD718XX_H_
+#define BD718XX_H_
 
-#define BD71837_REGULATOR_DRIVER "bd71837_regulator"
+#define BD718XX_REGULATOR_DRIVER "bd718x7_regulator"
 
 enum {
-       BD71837_REV             = 0x00,
-       BD71837_SWRESET         = 0x01,
-       BD71837_I2C_DEV         = 0x02,
-       BD71837_PWRCTRL0        = 0x03,
-       BD71837_PWRCTRL1        = 0x04,
-       BD71837_BUCK1_CTRL      = 0x05,
-       BD71837_BUCK2_CTRL      = 0x06,
-       BD71837_BUCK3_CTRL      = 0x07,
-       BD71837_BUCK4_CTRL      = 0x08,
-       BD71837_BUCK5_CTRL      = 0x09,
-       BD71837_BUCK6_CTRL      = 0x0a,
-       BD71837_BUCK7_CTRL      = 0x0b,
-       BD71837_BUCK8_CTRL      = 0x0c,
-       BD71837_BUCK1_VOLT_RUN  = 0x0d,
-       BD71837_BUCK1_VOLT_IDLE = 0x0e,
-       BD71837_BUCK1_VOLT_SUSP = 0x0f,
-       BD71837_BUCK2_VOLT_RUN  = 0x10,
-       BD71837_BUCK2_VOLT_IDLE = 0x11,
-       BD71837_BUCK3_VOLT_RUN  = 0x12,
-       BD71837_BUCK4_VOLT_RUN  = 0x13,
-       BD71837_BUCK5_VOLT      = 0x14,
-       BD71837_BUCK6_VOLT      = 0x15,
-       BD71837_BUCK7_VOLT      = 0x16,
-       BD71837_BUCK8_VOLT      = 0x17,
-       BD71837_LDO1_VOLT       = 0x18,
-       BD71837_LDO2_VOLT       = 0x19,
-       BD71837_LDO3_VOLT       = 0x1a,
-       BD71837_LDO4_VOLT       = 0x1b,
-       BD71837_LDO5_VOLT       = 0x1c,
-       BD71837_LDO6_VOLT       = 0x1d,
-       BD71837_LDO7_VOLT       = 0x1e,
-       BD71837_TRANS_COND0     = 0x1f,
-       BD71837_TRANS_COND1     = 0x20,
-       BD71837_VRFAULTEN       = 0x21,
-       BD71837_MVRFLTMASK0     = 0x22,
-       BD71837_MVRFLTMASK1     = 0x23,
-       BD71837_MVRFLTMASK2     = 0x24,
-       BD71837_RCVCFG          = 0x25,
-       BD71837_RCVNUM          = 0x26,
-       BD71837_PWRONCONFIG0    = 0x27,
-       BD71837_PWRONCONFIG1    = 0x28,
-       BD71837_RESETSRC        = 0x29,
-       BD71837_MIRQ            = 0x2a,
-       BD71837_IRQ             = 0x2b,
-       BD71837_IN_MON          = 0x2c,
-       BD71837_POW_STATE       = 0x2d,
-       BD71837_OUT32K          = 0x2e,
-       BD71837_REGLOCK         = 0x2f,
-       BD71837_MUXSW_EN        = 0x30,
-       BD71837_REG_NUM,
+       ROHM_CHIP_TYPE_BD71837 = 0,
+       ROHM_CHIP_TYPE_BD71847,
+       ROHM_CHIP_TYPE_BD70528,
+       ROHM_CHIP_TYPE_AMOUNT
 };
 
+enum {
+       BD718XX_REV                     = 0x00,
+       BD718XX_SWRESET                 = 0x01,
+       BD718XX_I2C_DEV                 = 0x02,
+       BD718XX_PWRCTRL0                = 0x03,
+       BD718XX_PWRCTRL1                = 0x04,
+       BD718XX_BUCK1_CTRL              = 0x05,
+       BD718XX_BUCK2_CTRL              = 0x06,
+       BD71837_BUCK3_CTRL              = 0x07,
+       BD71837_BUCK4_CTRL              = 0x08,
+       BD718XX_1ST_NODVS_BUCK_CTRL     = 0x09,
+       BD718XX_2ND_NODVS_BUCK_CTRL     = 0x0a,
+       BD718XX_3RD_NODVS_BUCK_CTRL     = 0x0b,
+       BD718XX_4TH_NODVS_BUCK_CTRL     = 0x0c,
+       BD718XX_BUCK1_VOLT_RUN          = 0x0d,
+       BD718XX_BUCK1_VOLT_IDLE         = 0x0e,
+       BD718XX_BUCK1_VOLT_SUSP         = 0x0f,
+       BD718XX_BUCK2_VOLT_RUN          = 0x10,
+       BD718XX_BUCK2_VOLT_IDLE         = 0x11,
+       BD71837_BUCK3_VOLT_RUN          = 0x12,
+       BD71837_BUCK4_VOLT_RUN          = 0x13,
+       BD718XX_1ST_NODVS_BUCK_VOLT     = 0x14,
+       BD718XX_2ND_NODVS_BUCK_VOLT     = 0x15,
+       BD718XX_3RD_NODVS_BUCK_VOLT     = 0x16,
+       BD718XX_4TH_NODVS_BUCK_VOLT     = 0x17,
+       BD718XX_LDO1_VOLT               = 0x18,
+       BD718XX_LDO2_VOLT               = 0x19,
+       BD718XX_LDO3_VOLT               = 0x1a,
+       BD718XX_LDO4_VOLT               = 0x1b,
+       BD718XX_LDO5_VOLT               = 0x1c,
+       BD718XX_LDO6_VOLT               = 0x1d,
+       BD71837_LDO7_VOLT               = 0x1e,
+       BD718XX_TRANS_COND0             = 0x1f,
+       BD718XX_TRANS_COND1             = 0x20,
+       BD718XX_VRFAULTEN               = 0x21,
+       BD718XX_MVRFLTMASK0             = 0x22,
+       BD718XX_MVRFLTMASK1             = 0x23,
+       BD718XX_MVRFLTMASK2             = 0x24,
+       BD718XX_RCVCFG                  = 0x25,
+       BD718XX_RCVNUM                  = 0x26,
+       BD718XX_PWRONCONFIG0            = 0x27,
+       BD718XX_PWRONCONFIG1            = 0x28,
+       BD718XX_RESETSRC                = 0x29,
+       BD718XX_MIRQ                    = 0x2a,
+       BD718XX_IRQ                     = 0x2b,
+       BD718XX_IN_MON                  = 0x2c,
+       BD718XX_POW_STATE               = 0x2d,
+       BD718XX_OUT32K                  = 0x2e,
+       BD718XX_REGLOCK                 = 0x2f,
+       BD718XX_MUXSW_EN                = 0x30,
+       BD718XX_REG_OTPVER              = 0xff,
+       BD718XX_MAX_REGISTER            = 0x100,
+};
+
+#define BD718XX_REGLOCK_PWRSEQ         0x1
+#define BD718XX_REGLOCK_VREG           0x10
+
+#define BD718XX_BUCK_EN                        0x01
+#define BD718XX_LDO_EN                 0x40
+#define BD718XX_BUCK_SEL               0x02
+#define BD718XX_LDO_SEL                        0x80
+
+#define DVS_BUCK_RUN_MASK              0x3f
+#define BD718XX_1ST_NODVS_BUCK_MASK    0x07
+#define BD718XX_3RD_NODVS_BUCK_MASK    0x07
+#define BD718XX_4TH_NODVS_BUCK_MASK    0x3f
+
+#define BD71847_BUCK3_MASK             0x07
+#define BD71847_BUCK3_RANGE_MASK       0xc0
+#define BD71847_BUCK4_MASK             0x03
+#define BD71847_BUCK4_RANGE_MASK       0x40
+
+#define BD71837_BUCK5_RANGE_MASK       0x80
+#define BD71837_BUCK6_MASK             0x03
+
+#define BD718XX_LDO1_MASK              0x03
+#define BD718XX_LDO1_RANGE_MASK                0x20
+#define BD718XX_LDO2_MASK              0x20
+#define BD718XX_LDO3_MASK              0x0f
+#define BD718XX_LDO4_MASK              0x0f
+#define BD718XX_LDO6_MASK              0x0f
+
+#define BD71837_LDO5_MASK              0x0f
+#define BD71847_LDO5_MASK              0x0f
+#define BD71847_LDO5_RANGE_MASK                0x20
+#define BD71837_LDO7_MASK              0x0f
+
 #endif
diff --git a/include/sandbox-clk.h b/include/sandbox-clk.h
new file mode 100644 (file)
index 0000000..37c9838
--- /dev/null
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#ifndef __SANDBOX_CLK_H__
+#define __SANDBOX_CLK_H__
+
+#include <linux/clk-provider.h>
+
+enum {
+       SANDBOX_CLK_PLL2 = 1,
+       SANDBOX_CLK_PLL3,
+       SANDBOX_CLK_PLL3_60M,
+       SANDBOX_CLK_PLL3_80M,
+       SANDBOX_CLK_ECSPI_ROOT,
+       SANDBOX_CLK_ECSPI0,
+       SANDBOX_CLK_ECSPI1,
+       SANDBOX_CLK_USDHC1_SEL,
+       SANDBOX_CLK_USDHC2_SEL,
+};
+
+enum sandbox_pllv3_type {
+       SANDBOX_PLLV3_GENERIC,
+       SANDBOX_PLLV3_USB,
+};
+
+struct clk *sandbox_clk_pllv3(enum sandbox_pllv3_type type, const char *name,
+                             const char *parent_name, void __iomem *base,
+                             u32 div_mask);
+
+static inline struct clk *sandbox_clk_fixed_factor(const char *name,
+                                                  const char *parent,
+                                                  unsigned int mult,
+                                                  unsigned int div)
+{
+       return clk_register_fixed_factor(NULL, name, parent,
+                       CLK_SET_RATE_PARENT, mult, div);
+}
+
+static inline struct clk *sandbox_clk_divider(const char *name,
+                                             const char *parent,
+                                             void __iomem *reg, u8 shift,
+                                             u8 width)
+{
+       return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+                       reg, shift, width, 0);
+}
+
+struct clk *sandbox_clk_register_gate2(struct device *dev, const char *name,
+                                      const char *parent_name,
+                                      unsigned long flags,
+                                      void __iomem *reg, u8 bit_idx,
+                                      u8 cgr_val, u8 clk_gate_flags);
+
+static inline struct clk *sandbox_clk_gate2(const char *name,
+                                           const char *parent,
+                                           void __iomem *reg, u8 shift)
+{
+       return sandbox_clk_register_gate2(NULL, name, parent,
+                                         CLK_SET_RATE_PARENT, reg, shift,
+                                         0x3, 0);
+}
+
+static inline struct clk *sandbox_clk_mux(const char *name, void __iomem *reg,
+                                         u8 shift, u8 width,
+                                         const char * const *parents,
+                                         int num_parents)
+{
+       return clk_register_mux(NULL, name, parents, num_parents,
+                               CLK_SET_RATE_NO_REPARENT, reg, shift,
+                               width, 0);
+}
+
+#endif /* __SANDBOX_CLK_H__ */
index aa77d3e9b40368af889b67e81fa411d9c66d42e4..5bcff24ab310020a19b053e22e85db7345a62b64 100644 (file)
@@ -106,7 +106,7 @@ struct wdt_ops {
        int (*expire_now)(struct udevice *dev, ulong flags);
 };
 
-#if defined(CONFIG_WDT)
+#if CONFIG_IS_ENABLED(WDT)
 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
 #define CONFIG_WATCHDOG_TIMEOUT_MSECS  (60 * 1000)
 #endif
index 3773d89c313f083e3516abf332978bcfffefe4e4..c398f9b953577f7575b9c629a70d3ba1048bb065 100644 (file)
@@ -17,6 +17,7 @@ config OPTEE_LOAD_ADDR
 config OPTEE_TZDRAM_SIZE
        hex "Amount of Trust-Zone RAM for the OPTEE image"
        default 0x0000000
+       depends on OPTEE
        help
          The size of pre-allocated Trust Zone DRAM to allocate for the OPTEE
          runtime.
@@ -24,6 +25,7 @@ config OPTEE_TZDRAM_SIZE
 config OPTEE_TZDRAM_BASE
        hex "Base address of Trust-Zone RAM for the OPTEE image"
        default 0x00000000
+       depends on OPTEE
        help
          The base address of pre-allocated Trust Zone DRAM for
          the OPTEE runtime.
index e616f7229b4e4f63ff074694ef3e327673f1d976..495988cdcf41024cbe83987b3d8fbda91d3abd47 100644 (file)
@@ -1459,7 +1459,6 @@ CONFIG_PROOF_POINTS
 CONFIG_PRPMC_PCI_ALIAS
 CONFIG_PSRAM_SCFG
 CONFIG_PWM
-CONFIG_PWM_IMX
 CONFIG_PXA_LCD
 CONFIG_PXA_MMC_GENERIC
 CONFIG_PXA_PWR_I2C
index 7b4dd6e12e6e1029efb2e815b6edb13ccac0d322..55a7940053e00e64b72636b7787e81b1044f2fef 100644 (file)
@@ -17,7 +17,7 @@ obj-$(CONFIG_SOUND) += audio.o
 obj-$(CONFIG_BLK) += blk.o
 obj-$(CONFIG_BOARD) += board.o
 obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
-obj-$(CONFIG_CLK) += clk.o
+obj-$(CONFIG_CLK) += clk.o clk_ccf.o
 obj-$(CONFIG_DM_ETH) += eth.o
 obj-$(CONFIG_FIRMWARE) += firmware.o
 obj-$(CONFIG_DM_GPIO) += gpio.o
diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c
new file mode 100644 (file)
index 0000000..8d39759
--- /dev/null
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <asm/clk.h>
+#include <dm/test.h>
+#include <dm/uclass.h>
+#include <linux/err.h>
+#include <test/ut.h>
+#include <sandbox-clk.h>
+
+/* Tests for Common Clock Framework driver */
+static int dm_test_clk_ccf(struct unit_test_state *uts)
+{
+       struct clk *clk, *pclk;
+       struct udevice *dev;
+       long long rate;
+       int ret;
+
+       /* Get the device using the clk device */
+       ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-ccf", &dev));
+
+       /* Test for clk_get_by_id() */
+       ret = clk_get_by_id(SANDBOX_CLK_ECSPI_ROOT, &clk);
+       ut_assertok(ret);
+       ut_asserteq_str("ecspi_root", clk->dev->name);
+
+       /* Test for clk_get_parent_rate() */
+       ret = clk_get_by_id(SANDBOX_CLK_ECSPI1, &clk);
+       ut_assertok(ret);
+       ut_asserteq_str("ecspi1", clk->dev->name);
+
+       rate = clk_get_parent_rate(clk);
+       ut_asserteq(rate, 20000000);
+
+       /* Test the mux of CCF */
+       ret = clk_get_by_id(SANDBOX_CLK_USDHC1_SEL, &clk);
+       ut_assertok(ret);
+       ut_asserteq_str("usdhc1_sel", clk->dev->name);
+
+       rate = clk_get_parent_rate(clk);
+       ut_asserteq(rate, 60000000);
+
+       ret = clk_get_by_id(SANDBOX_CLK_USDHC2_SEL, &clk);
+       ut_assertok(ret);
+       ut_asserteq_str("usdhc2_sel", clk->dev->name);
+
+       rate = clk_get_parent_rate(clk);
+       ut_asserteq(rate, 80000000);
+
+       pclk = clk_get_parent(clk);
+       ut_asserteq_str("pll3_80m", pclk->dev->name);
+
+       return 1;
+}
+
+DM_TEST(dm_test_clk_ccf, DM_TESTF_SCAN_FDT);