diff options
183 files changed, 5034 insertions, 651 deletions
diff --git a/Documentation/boards/imx.rst b/Documentation/boards/imx.rst index 2e6a30fd2f..27d0123c87 100644 --- a/Documentation/boards/imx.rst +++ b/Documentation/boards/imx.rst @@ -201,6 +201,7 @@ or ``imx_defconfig`` instead. .. toctree:: :glob: - :maxdepth: 1 + :maxdepth: 2 imx/* + imx/*/* diff --git a/Documentation/boards/imx/nxp-imx8mq-evk.rst b/Documentation/boards/imx/nxp-imx8mq-evk.rst index dfe004e0e4..8bad9455a5 100644 --- a/Documentation/boards/imx/nxp-imx8mq-evk.rst +++ b/Documentation/boards/imx/nxp-imx8mq-evk.rst @@ -8,17 +8,17 @@ Board comes with: Not including booting via serial, the device can boot from either SD or eMMC. -Downloading DDR PHY Firmware ----------------------------- +Downloading DDR PHY and HDMI/eDP Firmware +----------------------------------------- As a part of DDR intialization routine NXP i.MX8MQ EVK requires and uses several binary firmware blobs that are distributed under a separate EULA and cannot be included in Barebox. In order to obtain them do the following:: - wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.2.bin - chmod +x firmware-imx-7.2.bin - ./firmware-imx-7.2.bin + wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.0.bin + chmod +x firmware-imx-8.0.bin + ./firmware-imx-8.0.bin Executing that file should produce a EULA acceptance dialog as well as result in the following files: @@ -36,8 +36,18 @@ As a last step of this process those files need to be placed in lpddr4_pmu_train_2d_dmem.bin \ lpddr4_pmu_train_2d_imem.bin; \ do \ - cp firmware-imx-7.2/firmware/ddr/synopsys/${f} \ - firmware/imx/${f}; \ + cp firmware-imx-8.0/firmware/ddr/synopsys/${f} \ + firmware/${f}; \ + done + +You will also need to copy the HDMITX controller firmware in order to +use the HDMI and/or eDP display output:: + + for f in signed_dp_imx8m.bin \ + signed_hdmi_imx8m.bin; \ + do \ + cp firmware-imx-8.0/firmware/hdmi/cadence/${f} \ + firmware/${f}; \ done DDR Configuration Code diff --git a/Documentation/boards/imx/zii-imx8mq-dev/openocd.cfg b/Documentation/boards/imx/zii-imx8mq-dev/openocd.cfg new file mode 100644 index 0000000000..31f94227e6 --- /dev/null +++ b/Documentation/boards/imx/zii-imx8mq-dev/openocd.cfg @@ -0,0 +1,86 @@ +interface ftdi +ftdi_vid_pid 0x0403 0x6011 + +ftdi_layout_init 0x0038 0x003b +ftdi_layout_signal nSRST -data 0x0010 +ftdi_layout_signal LED -data 0x0020 + +# Board has a standard ARM-20 JTAG connector with +# nSRST available. +reset_config srst_only srst_push_pull connect_deassert_srst + +# select JTAG +transport select jtag + +# set a slow default JTAG clock, can be overridden later +adapter_khz 1000 + +# delay after SRST goes inactive +adapter_nsrst_delay 70 + +# board has an i.MX8MQ with 4 Cortex-A53 cores +set CHIPNAME imx8mq +set CHIPCORES 4 + +# source SoC configuration +source [find target/imx8m.cfg] +source [find mem_helper.tcl] + +proc ddr_init { } { + # + # We use the same start address as is configured in our i.MX boot + # header (address originally taken from U-Boot). + # + set IMX8MQ_TCM_BASE_ADDR 0x007e1000 + set IMX8MQ_TCM_MAX_SIZE 0x3f000 + # + # Header word at offset 0x28 is not used on AArch64 and is just + # filled with placeholder value 0xffff_ffff, see + # arch/arm/include/asm/barebox-arm-head.h for more details + # + set RDU3_TCM_MAIC_LOCATION [expr $IMX8MQ_TCM_BASE_ADDR + 0x28] + set RDU3_TCM_MAGIC_REQUEST 0xdeadbeef + set RDU3_TCM_MAGIC_REPLY 0xbaadf00d + + echo "==== Uploading DDR helper ====" + + halt + load_image images/start_zii_imx8mq_dev.pblb \ + $IMX8MQ_TCM_BASE_ADDR \ + bin \ + $IMX8MQ_TCM_BASE_ADDR \ + $IMX8MQ_TCM_MAX_SIZE + + echo "==== Running DDR helper ====" + + mww phys $RDU3_TCM_MAIC_LOCATION $RDU3_TCM_MAGIC_REQUEST + resume $IMX8MQ_TCM_BASE_ADDR + + echo "==== Waiting for DDR helper to finish ====" + + if {[catch {wait_halt} errmsg] || + [mrw $RDU3_TCM_MAIC_LOCATION] != $RDU3_TCM_MAGIC_REPLY} { + echo "==== DDR initialization FAILED ====" + } else { + echo "==== DDR is ready ====" + } +} + +proc start_barebox {} { + # + # We have to place our image at MX8MQ_ATF_BL33_BASE_ADDR in order + # to be able to initialize ATF firmware since that's where it + # expects entry point to BL33 would be + # + set MX8MQ_ATF_BL33_BASE_ADDR 0x40200000 + + echo "==== Starting Barebox ====" + load_image images/start_zii_imx8mq_dev.pblb $MX8MQ_ATF_BL33_BASE_ADDR bin + resume $MX8MQ_ATF_BL33_BASE_ADDR +} + +# proc board_init { } { +# ddr_init +# } + +# ${_TARGETNAME}.0 configure -event reset-init { board_init } diff --git a/Documentation/boards/imx/zii-imx8mq-dev/readme.rst b/Documentation/boards/imx/zii-imx8mq-dev/readme.rst new file mode 100644 index 0000000000..dc031e4af4 --- /dev/null +++ b/Documentation/boards/imx/zii-imx8mq-dev/readme.rst @@ -0,0 +1,24 @@ +ZII i.MX8MQ Based Boards +======================== + +Building Barebox +---------------- + +To build Barebox of ZII i.MX8MQ based board do the following: + +.. code-block:: sh + + make ARCH=arm CROSS_COMPILE=<AArch64 toolchain prefix> mrproper + make ARCH=arm CROSS_COMPILE=<AArch64 toolchain prefix> imx_v8_defconfig + make ARCH=arm CROSS_COMPILE=<AArch64 toolchain prefix> + +Uploading Barebox via JTAG +-------------------------- + +Barebox can be bootstrapped via JTAG using OpenOCD (latest master) as +follows: + +.. code-block:: sh + + cd barebox + openocd -f Documentation/boards/imx/zii-imx8mq-dev/openocd.cfg --command "init; ddr_init; start_barebox" @@ -1,5 +1,5 @@ VERSION = 2019 -PATCHLEVEL = 01 +PATCHLEVEL = 02 SUBLEVEL = 0 EXTRAVERSION = NAME = None diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c1f385b11b..f5c14718f0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -257,6 +257,7 @@ config ARCH_ZYNQMP select OFTREE select RELOCATABLE select SYS_SUPPORTS_64BIT_KERNEL + select HAS_MACB config ARCH_QEMU bool "ARM QEMU boards" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 0fd63105d7..6b5f21a7a9 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -252,15 +252,12 @@ barebox.imximg: $(KBUILD_BINARY) FORCE boarddir = $(srctree)/arch/arm/boards imxcfg-$(CONFIG_MACH_FREESCALE_MX53_SMD) += $(boarddir)/freescale-mx53-smd/flash-header.imxcfg imxcfg-$(CONFIG_MACH_TX51) += $(boarddir)/karo-tx51/flash-header-karo-tx51.imxcfg -imxcfg-$(CONFIG_MACH_GUF_VINCELL) += $(boarddir)/guf-vincell/flash-header.imxcfg imxcfg-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += $(boarddir)/eukrea_cpuimx51/flash-header.imxcfg imxcfg-$(CONFIG_MACH_FREESCALE_MX25_3STACK) += $(boarddir)/freescale-mx25-3ds/flash-header.imxcfg imxcfg-$(CONFIG_MACH_FREESCALE_MX35_3STACK) += $(boarddir)/freescale-mx35-3ds/flash-header.imxcfg -imxcfg-$(CONFIG_MACH_TQMA53) += $(boarddir)/tqma53/flash-header.imxcfg imxcfg-$(CONFIG_MACH_EUKREA_CPUIMX25) += $(boarddir)/eukrea_cpuimx25/flash-header.imxcfg imxcfg-$(CONFIG_MACH_EUKREA_CPUIMX35) += $(boarddir)/eukrea_cpuimx35/flash-header.imxcfg imxcfg-$(CONFIG_MACH_PCM043) += $(boarddir)/phytec-phycore-imx35/flash-header.imxcfg -imxcfg-$(CONFIG_MACH_KINDLE3) += $(boarddir)/kindle3/flash-header.imxcfg ifneq ($(imxcfg-y),) CFG_barebox.imximg := $(imxcfg-y) KBUILD_IMAGE := barebox.imximg diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index ab5191fe04..3cea2e0e5d 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -139,6 +139,7 @@ obj-$(CONFIG_MACH_TX51) += karo-tx51/ obj-$(CONFIG_MACH_TX53) += karo-tx53/ obj-$(CONFIG_MACH_TX6X) += karo-tx6x/ obj-$(CONFIG_MACH_UDOO) += udoo/ +obj-$(CONFIG_MACH_UDOO_NEO) += udoo-neo/ obj-$(CONFIG_MACH_USB_A9260) += usb-a926x/ obj-$(CONFIG_MACH_USB_A9263) += usb-a926x/ obj-$(CONFIG_MACH_USB_A9G20) += usb-a926x/ @@ -156,6 +157,7 @@ obj-$(CONFIG_MACH_VF610_TWR) += freescale-vf610-twr/ obj-$(CONFIG_MACH_XILINX_ZCU104) += xilinx-zcu104/ obj-$(CONFIG_MACH_ZII_RDU1) += zii-imx51-rdu1/ obj-$(CONFIG_MACH_ZII_RDU2) += zii-imx6q-rdu2/ +obj-$(CONFIG_MACH_ZII_IMX8MQ_DEV) += zii-imx8mq-dev/ obj-$(CONFIG_MACH_ZII_VF610_DEV) += zii-vf610-dev/ obj-$(CONFIG_MACH_ZII_IMX7D_RPU2) += zii-imx7d-rpu2/ obj-$(CONFIG_MACH_WAGO_PFC_AM35XX) += wago-pfc-am35xx/ diff --git a/arch/arm/boards/advantech-mx6/lowlevel.c b/arch/arm/boards/advantech-mx6/lowlevel.c index 8921cd4dd8..de1d344dc1 100644 --- a/arch/arm/boards/advantech-mx6/lowlevel.c +++ b/arch/arm/boards/advantech-mx6/lowlevel.c @@ -23,9 +23,6 @@ #include <mach/iomux-mx6.h> #include <linux/sizes.h> -#include <linux/sizes.h> -#include <asm/barebox-arm-head.h> -#include <asm/barebox-arm.h> static inline void setup_uart(void) { void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; diff --git a/arch/arm/boards/beaglebone/board.c b/arch/arm/boards/beaglebone/board.c index 5717c45020..819bdfae46 100644 --- a/arch/arm/boards/beaglebone/board.c +++ b/arch/arm/boards/beaglebone/board.c @@ -29,7 +29,6 @@ #include <globalvar.h> #include <linux/sizes.h> #include <net.h> -#include <envfs.h> #include <bootsource.h> #include <asm/armlinux.h> #include <generated/mach-types.h> diff --git a/arch/arm/boards/karo-tx25/lowlevel.c b/arch/arm/boards/karo-tx25/lowlevel.c index 78e6f4d823..3bbc930931 100644 --- a/arch/arm/boards/karo-tx25/lowlevel.c +++ b/arch/arm/boards/karo-tx25/lowlevel.c @@ -23,7 +23,6 @@ #include <io.h> #include <linux/sizes.h> #include <mach/imx-nand.h> -#include <mach/esdctl.h> #include <asm/barebox-arm.h> #include <asm/barebox-arm-head.h> #include <asm/system.h> diff --git a/arch/arm/boards/mx31moboard/lowlevel.c b/arch/arm/boards/mx31moboard/lowlevel.c index b00c4bb2c0..02b7ab3c7a 100644 --- a/arch/arm/boards/mx31moboard/lowlevel.c +++ b/arch/arm/boards/mx31moboard/lowlevel.c @@ -27,7 +27,6 @@ #include <asm/barebox-arm-head.h> #include <mach/imx31-regs.h> #include <mach/imx-pll.h> -#include <asm/barebox-arm-head.h> #include <mach/esdctl.h> static noinline __noreturn void mx31moboard_startup(void) diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddr.h b/arch/arm/boards/nxp-imx8mq-evk/ddr.h index 8f494ae7a2..65115dba1e 100644 --- a/arch/arm/boards/nxp-imx8mq-evk/ddr.h +++ b/arch/arm/boards/nxp-imx8mq-evk/ddr.h @@ -21,9 +21,9 @@ void nxp_imx8mq_evk_ddr_init(void); void nxp_imx8mq_evk_ddr_cfg_phy(void); -#define FW_1D_IMAGE imx_lpddr4_pmu_train_1d_imem_bin, \ - imx_lpddr4_pmu_train_1d_dmem_bin -#define FW_2D_IMAGE imx_lpddr4_pmu_train_2d_imem_bin, \ - imx_lpddr4_pmu_train_2d_dmem_bin +#define FW_1D_IMAGE lpddr4_pmu_train_1d_imem_bin, \ + lpddr4_pmu_train_1d_dmem_bin +#define FW_2D_IMAGE lpddr4_pmu_train_2d_imem_bin, \ + lpddr4_pmu_train_2d_dmem_bin diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c index 1dff4b4d31..ffbe14836f 100644 --- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c +++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c @@ -115,7 +115,7 @@ ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2) const u8 *bl31; size_t bl31_size; - get_builtin_firmware(imx_imx8m_bl31_bin, &bl31, &bl31_size); + get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size); imx8mq_atf_load_bl31(bl31, bl31_size); } diff --git a/arch/arm/boards/panda/board.c b/arch/arm/boards/panda/board.c index acba689623..a0a00782d3 100644 --- a/arch/arm/boards/panda/board.c +++ b/arch/arm/boards/panda/board.c @@ -18,7 +18,6 @@ #include <asm/mmu.h> #include <envfs.h> #include <i2c/i2c.h> -#include <gpio.h> #include <led.h> static int board_revision; diff --git a/arch/arm/boards/phytec-phycard-imx27/pca100.c b/arch/arm/boards/phytec-phycard-imx27/pca100.c index b0fee46d3b..60f1505ccb 100644 --- a/arch/arm/boards/phytec-phycard-imx27/pca100.c +++ b/arch/arm/boards/phytec-phycard-imx27/pca100.c @@ -33,7 +33,6 @@ #include <mach/imx-nand.h> #include <mach/imx-pll.h> #include <mach/imxfb.h> -#include <gpio.h> #include <asm/mmu.h> #include <usb/ulpi.h> #include <mach/bbu.h> diff --git a/arch/arm/boards/phytec-phycore-imx31/lowlevel.c b/arch/arm/boards/phytec-phycore-imx31/lowlevel.c index 27e275676f..a3ba1c05dd 100644 --- a/arch/arm/boards/phytec-phycore-imx31/lowlevel.c +++ b/arch/arm/boards/phytec-phycore-imx31/lowlevel.c @@ -27,7 +27,6 @@ #include <asm/barebox-arm-head.h> #include <mach/imx31-regs.h> #include <mach/imx-pll.h> -#include <asm/barebox-arm-head.h> #include <mach/esdctl.h> #define ESDCTL0_VAL (ESDCTL0_SDE | ESDCTL0_ROW13 | ESDCTL0_COL10) diff --git a/arch/arm/boards/phytec-som-imx6/board.c b/arch/arm/boards/phytec-som-imx6/board.c index 38a2ef641e..d808517975 100644 --- a/arch/arm/boards/phytec-som-imx6/board.c +++ b/arch/arm/boards/phytec-som-imx6/board.c @@ -36,8 +36,6 @@ #include <globalvar.h> -#include <linux/micrel_phy.h> - #include <mach/iomux-mx6.h> #include <mach/imx6.h> diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c index 650b26ce7d..b2febec991 100644 --- a/arch/arm/boards/raspberry-pi/rpi-common.c +++ b/arch/arm/boards/raspberry-pi/rpi-common.c @@ -180,7 +180,7 @@ const struct rpi_model rpi_models_new_scheme[] = { }; static int rpi_board_rev = 0; -const struct rpi_model *model; +const struct rpi_model *model = NULL; static void rpi_get_board_rev(void) { @@ -251,6 +251,9 @@ unknown_rev: static void rpi_model_init(void) { + if (!model) + return; + if (!model->init) return; diff --git a/arch/arm/boards/sama5d3xek/init.c b/arch/arm/boards/sama5d3xek/init.c index 08ccbcf4a3..c768e98d26 100644 --- a/arch/arm/boards/sama5d3xek/init.c +++ b/arch/arm/boards/sama5d3xek/init.c @@ -31,7 +31,6 @@ #include <linux/mtd/nand.h> #include <mach/board.h> #include <mach/at91sam9_smc.h> -#include <mach/at91sam9_smc.h> #include <gpio.h> #include <mach/iomux.h> #include <mach/at91_pmc.h> diff --git a/arch/arm/boards/udoo-neo/Makefile b/arch/arm/boards/udoo-neo/Makefile new file mode 100644 index 0000000000..01c7a259e9 --- /dev/null +++ b/arch/arm/boards/udoo-neo/Makefile @@ -0,0 +1,2 @@ +obj-y += board.o +lwl-y += lowlevel.o diff --git a/arch/arm/boards/udoo-neo/board.c b/arch/arm/boards/udoo-neo/board.c new file mode 100644 index 0000000000..9bf480305d --- /dev/null +++ b/arch/arm/boards/udoo-neo/board.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 Pengutronix, Sascha Hauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <init.h> +#include <linux/clk.h> + +static int imx6sx_udoneo_coredevices_init(void) +{ + if (!of_machine_is_compatible("fsl,imx6sx-udoo-neo")) + return 0; + + barebox_set_hostname("mx6sx-udooneo"); + + return 0; +} +coredevice_initcall(imx6sx_udoneo_coredevices_init); diff --git a/arch/arm/boards/udoo-neo/flash-header-mx6sx-udoo-neo_full.imxcfg b/arch/arm/boards/udoo-neo/flash-header-mx6sx-udoo-neo_full.imxcfg new file mode 100644 index 0000000000..39f2a8a221 --- /dev/null +++ b/arch/arm/boards/udoo-neo/flash-header-mx6sx-udoo-neo_full.imxcfg @@ -0,0 +1,131 @@ +/* + * These values are taken from: + * repository: https://github.com/UDOOboard/uboot-imx + * branch: udoo/2015.04.imx + * file: board/udoo/udoo_neo/udoo_neo.cfg + */ + +loadaddr 0x80000000 +soc imx6 +dcdofs 0x400 + +/* Enable all clocks */ +wm 32 0x020c4068 0xffffffff +wm 32 0x020c406c 0xffffffff +wm 32 0x020c4070 0xffffffff +wm 32 0x020c4074 0xffffffff +wm 32 0x020c4078 0xffffffff +wm 32 0x020c407c 0xffffffff +wm 32 0x020c4080 0xffffffff +wm 32 0x020c4084 0xffffffff +/********************************************/ + +/* IOMUX */ +/* DDR IO TYPE */ +wm 32 0x020e0618 0x000c0000 +wm 32 0x020e05fc 0x00000000 +/********************************************/ + +/* CLOCK */ +wm 32 0x020e032c 0x00000030 +/********************************************/ + +/* ADDRESS */ +wm 32 0x020e0300 0x00000020 +wm 32 0x020e02fc 0x00000020 +wm 32 0x020e05f4 0x00000020 +/********************************************/ + +/* CONTROL */ +wm 32 0x020e0340 0x00000020 + +wm 32 0x020e0320 0x00000000 +wm 32 0x020e0310 0x00000020 +wm 32 0x020e0314 0x00000020 +wm 32 0x020e0614 0x00000020 +/********************************************/ + +/* DATA STROBE */ +wm 32 0x020e05f8 0x00020000 +wm 32 0x020e0330 0x00000028 +wm 32 0x020e0334 0x00000028 +wm 32 0x020e0338 0x00000028 +wm 32 0x020e033c 0x00000028 +/********************************************/ + +/* DATA */ +wm 32 0x020e0608 0x00020000 +wm 32 0x020e060c 0x00000028 +wm 32 0x020e0610 0x00000028 +wm 32 0x020e061c 0x00000028 +wm 32 0x020e0620 0x00000028 +wm 32 0x020e02ec 0x00000028 +wm 32 0x020e02f0 0x00000028 +wm 32 0x020e02f4 0x00000028 +wm 32 0x020e02f8 0x00000028 +/********************************************/ + +/* Calibrations */ +/* ZQ */ +wm 32 0x021b0800 0xa1390003 +/********************************************/ + +/* write leveling */ +wm 32 0x021b080c 0x000E000B +wm 32 0x021b0810 0x000E0010 +/********************************************/ + +/* DQS Read Gate */ +wm 32 0x021b083c 0x41600158 +wm 32 0x021b0840 0x01500140 +/********************************************/ + +/* Read/Write Delay */ +wm 32 0x021b0848 0x3A383E3E +wm 32 0x021b0850 0x3A383C38 +/********************************************/ + +/* read data bit delay */ +wm 32 0x021b081c 0x33333333 +wm 32 0x021b0820 0x33333333 +wm 32 0x021b0824 0x33333333 +wm 32 0x021b0828 0x33333333 +/********************************************/ + +/* Complete calibration by forced measurment */ +wm 32 0x021b08b8 0x00000800 +/********************************************/ + +/* MMDC init */ +/* in DDR3, 64-bit mode, only MMDC0 is initiated */ +wm 32 0x021b0004 0x0002002d +wm 32 0x021b0008 0x00333030 +wm 32 0x021b000c 0x676b52f3 +wm 32 0x021b0010 0xb66d8b63 +wm 32 0x021b0014 0x01ff00db +wm 32 0x021b0018 0x00011740 +wm 32 0x021b001c 0x00008000 +wm 32 0x021b002c 0x000026d2 +wm 32 0x021b0030 0x006b1023 +wm 32 0x021b0040 0x0000005f +wm 32 0x021b0000 0x83190000 +/********************************************/ + +/* Initialize MT41K256M16HA-125 */ +/* MR2 */ +wm 32 0x021b001c 0x04008032 +/* MR3 */ +wm 32 0x021b001c 0x00008033 +/* MR1 */ +wm 32 0x021b001c 0x00048031 +/* MR0 */ +wm 32 0x021b001c 0x05208030 +/* DDR device ZQ calibration */ +wm 32 0x021b001c 0x04008040 +/********************************************/ + +/* final DDR setup, before operation start */ +wm 32 0x021b0020 0x00000800 +wm 32 0x021b0818 0x00011117 +wm 32 0x021b001c 0x00000000 +/********************************************/ diff --git a/arch/arm/boards/udoo-neo/lowlevel.c b/arch/arm/boards/udoo-neo/lowlevel.c new file mode 100644 index 0000000000..bb6b7d8332 --- /dev/null +++ b/arch/arm/boards/udoo-neo/lowlevel.c @@ -0,0 +1,39 @@ +#include <debug_ll.h> +#include <common.h> +#include <linux/sizes.h> +#include <mach/generic.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <mach/esdctl.h> + +static inline void setup_uart(void) +{ + void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; + + imx6_ungate_all_peripherals(); + + writel(0x0, iomuxbase + 0x24); + writel(0x1b0b1, iomuxbase + 0x036C); + writel(0x0, iomuxbase + 0x28); + writel(0x1b0b1, iomuxbase + 0x0370); + + imx6_uart_setup_ll(); + + putc_ll('>'); +} + +extern char __dtb_imx6sx_udoo_neo_full_start[]; + +ENTRY_FUNCTION(start_imx6sx_udoo_neo, r0, r1, r2) +{ + void *fdt; + + imx6_cpu_lowlevel_init(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + setup_uart(); + + fdt = __dtb_imx6sx_udoo_neo_full_start + get_runtime_offset(); + + imx6sx_barebox_entry(fdt); +} diff --git a/arch/arm/boards/vscom-baltos/board.c b/arch/arm/boards/vscom-baltos/board.c index c64864d432..3f9b7d76bb 100644 --- a/arch/arm/boards/vscom-baltos/board.c +++ b/arch/arm/boards/vscom-baltos/board.c @@ -29,7 +29,6 @@ #include <globalvar.h> #include <linux/sizes.h> #include <net.h> -#include <envfs.h> #include <bootsource.h> #include <asm/armlinux.h> #include <generated/mach-types.h> diff --git a/arch/arm/boards/zii-imx8mq-dev/Makefile b/arch/arm/boards/zii-imx8mq-dev/Makefile new file mode 100644 index 0000000000..2995f06f0f --- /dev/null +++ b/arch/arm/boards/zii-imx8mq-dev/Makefile @@ -0,0 +1,2 @@ +obj-y += board.o +lwl-y += lowlevel.o ddr_init.o ddrphy_train.o diff --git a/arch/arm/boards/zii-imx8mq-dev/board.c b/arch/arm/boards/zii-imx8mq-dev/board.c new file mode 100644 index 0000000000..94e71f58ce --- /dev/null +++ b/arch/arm/boards/zii-imx8mq-dev/board.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Zodiac Inflight Innovation + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + */ + +#include <common.h> +#include <init.h> +#include <asm/memory.h> +#include <linux/sizes.h> +#include <mach/bbu.h> + +static int zii_imx8mq_dev_init(void) +{ + if (!of_machine_is_compatible("zii,imx8mq-ultra")) + return 0; + + barebox_set_hostname("imx8mq-zii-rdu3"); + + imx8mq_bbu_internal_mmcboot_register_handler("eMMC", "/dev/mmc0", 0); + + return 0; +} +device_initcall(zii_imx8mq_dev_init); diff --git a/arch/arm/boards/zii-imx8mq-dev/ddr.h b/arch/arm/boards/zii-imx8mq-dev/ddr.h new file mode 100644 index 0000000000..1293ad3f34 --- /dev/null +++ b/arch/arm/boards/zii-imx8mq-dev/ddr.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2018 Zodiac Inflight Innovation + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + * + * Varios wrappers and macros needed to intgrate code generated by + * i.MX8M DDR Tool into rest of Barebox + */ +#include <common.h> +#include <io.h> +#include <mach/imx8-ddrc.h> + +/* + * Code generated by i.MX8 M DDR Tool doesn't have any prefixes in the + * global identifiers below, so in order to avoid symbol name + * collisions with other boards we re-name them via a #define + */ +#define ddr_init zii_imx8mq_rdu3_ddr_init +#define ddr_cfg_phy zii_imx8mq_rdu3_ddr_cfg_phy + +void zii_imx8mq_rdu3_ddr_init(void); +void zii_imx8mq_rdu3_ddr_cfg_phy(void); + +#define FW_1D_IMAGE lpddr4_pmu_train_1d_imem_bin, \ + lpddr4_pmu_train_1d_dmem_bin +#define FW_2D_IMAGE lpddr4_pmu_train_2d_imem_bin, \ + lpddr4_pmu_train_2d_dmem_bin + + diff --git a/arch/arm/boards/zii-imx8mq-dev/ddr_init.c b/arch/arm/boards/zii-imx8mq-dev/ddr_init.c new file mode 100644 index 0000000000..7a955193fd --- /dev/null +++ b/arch/arm/boards/zii-imx8mq-dev/ddr_init.c @@ -0,0 +1,225 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Generated code from MX8M_DDR_tool + */ + +#include "ddr.h" + +void ddr_cfg_phy(void); +void ddr_init(void) +{ + volatile unsigned int tmp, tmp_t; + + /** Initialize DDR clock and DDRC registers **/ + reg32_write(0x3038a088,0x7070000); + reg32_write(0x3038a084,0x4030000); + reg32_write(0x303a00ec,0xffff); + tmp=reg32_read(0x303a00f8); + tmp |= 0x20; + reg32_write(0x303a00f8,tmp); + reg32_write(0x30391000,0x8f000000); + reg32_write(0x30391004,0x8f000000); + reg32_write(0x30360068,0xece580); + tmp=reg32_read(0x30360060); + tmp &= ~0x80; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp |= 0x200; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp &= ~0x20; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp &= ~0x10; + reg32_write(0x30360060,tmp); + do{ + tmp=reg32_read(0x30360060); + if(tmp&0x80000000) break; + }while(1); + reg32_write(0x30391000,0x8f000006); + reg32_write(0x3d400304,0x1); + reg32_write(0x3d400030,0x1); + reg32_write(0x3d400000,0xa3080020); + reg32_write(0x3d400028,0x0); + reg32_write(0x3d400020,0x203); + reg32_write(0x3d400024,0x186a000); + reg32_write(0x3d400064,0x6100e0); + reg32_write(0x3d4000d0,0xc003061c); + reg32_write(0x3d4000d4,0x9e0000); + reg32_write(0x3d4000dc,0xd4002d); + reg32_write(0x3d4000e0,0x310008); + reg32_write(0x3d4000e8,0x66004a); + reg32_write(0x3d4000ec,0x16004a); + reg32_write(0x3d400100,0x1a201b22); + reg32_write(0x3d400104,0x60633); + reg32_write(0x3d40010c,0xc0c000); + reg32_write(0x3d400110,0xf04080f); + reg32_write(0x3d400114,0x2040c0c); + reg32_write(0x3d400118,0x1010007); + reg32_write(0x3d40011c,0x401); + reg32_write(0x3d400130,0x20600); + reg32_write(0x3d400134,0xc100002); + reg32_write(0x3d400138,0xe6); + reg32_write(0x3d400144,0xa00050); + reg32_write(0x3d400180,0x3200018); + reg32_write(0x3d400184,0x28061a8); + reg32_write(0x3d400188,0x0); + reg32_write(0x3d400190,0x497820a); + reg32_write(0x3d400194,0x80303); + reg32_write(0x3d4001a0,0xe0400018); + reg32_write(0x3d4001a4,0xdf00e4); + reg32_write(0x3d4001a8,0x80000000); + reg32_write(0x3d4001b0,0x11); + reg32_write(0x3d4001b4,0x170a); + reg32_write(0x3d4001c0,0x1); + reg32_write(0x3d4001c4,0x1); + reg32_write(0x3d4000f4,0x639); + reg32_write(0x3d400108,0x70e1214); + reg32_write(0x3d400200,0x17); + reg32_write(0x3d40020c,0x0); + reg32_write(0x3d400210,0x1f1f); + reg32_write(0x3d400204,0x80808); + reg32_write(0x3d400214,0x7070707); + reg32_write(0x3d400218,0x7070707); + reg32_write(0x3d402020,0x1); + reg32_write(0x3d402024,0x518b00); + reg32_write(0x3d402050,0x20d040); + reg32_write(0x3d402064,0x14002f); + reg32_write(0x3d4020dc,0x940009); + reg32_write(0x3d4020e0,0x310000); + reg32_write(0x3d4020e8,0x66004a); + reg32_write(0x3d4020ec,0x16004a); + reg32_write(0x3d402100,0xb070508); + reg32_write(0x3d402104,0x3040b); + reg32_write(0x3d402108,0x305090c); + reg32_write(0x3d40210c,0x505000); + reg32_write(0x3d402110,0x4040204); + reg32_write(0x3d402114,0x2030303); + reg32_write(0x3d402118,0x1010004); + reg32_write(0x3d40211c,0x301); + reg32_write(0x3d402130,0x20300); + reg32_write(0x3d402134,0xa100002); + reg32_write(0x3d402138,0x31); + reg32_write(0x3d402144,0x220011); + reg32_write(0x3d402180,0xa70006); + reg32_write(0x3d402190,0x3858202); + reg32_write(0x3d402194,0x80303); + reg32_write(0x3d4021b4,0x502); + reg32_write(0x3d400244,0x0); + reg32_write(0x3d400250,0x29001505); + reg32_write(0x3d400254,0x2c); + reg32_write(0x3d40025c,0x5900575b); + reg32_write(0x3d400264,0x9); + reg32_write(0x3d40026c,0x2005574); + reg32_write(0x3d400300,0x16); + reg32_write(0x3d400304,0x0); + reg32_write(0x3d40030c,0x0); + reg32_write(0x3d400320,0x1); + reg32_write(0x3d40036c,0x11); + reg32_write(0x3d400400,0x111); + reg32_write(0x3d400404,0x10f3); + reg32_write(0x3d400408,0x72ff); + reg32_write(0x3d400490,0x1); + reg32_write(0x3d400494,0x1110d00); + reg32_write(0x3d400498,0x620790); + reg32_write(0x3d40049c,0x100001); + reg32_write(0x3d4004a0,0x41f); + reg32_write(0x30391000,0x8f000004); + reg32_write(0x30391000,0x8f000000); + reg32_write(0x3d400030,0xa8); + do{ + tmp=reg32_read(0x3d400004); + if(tmp&0x223) break; + }while(1); + reg32_write(0x3d400320,0x0); + reg32_write(0x3d000000,0x1); + reg32_write(0x3d4001b0,0x10); + reg32_write(0x3c040280,0x0); + reg32_write(0x3c040284,0x1); + reg32_write(0x3c040288,0x2); + reg32_write(0x3c04028c,0x3); + reg32_write(0x3c040290,0x4); + reg32_write(0x3c040294,0x5); + reg32_write(0x3c040298,0x6); + reg32_write(0x3c04029c,0x7); + reg32_write(0x3c044280,0x0); + reg32_write(0x3c044284,0x1); + reg32_write(0x3c044288,0x2); + reg32_write(0x3c04428c,0x3); + reg32_write(0x3c044290,0x4); + reg32_write(0x3c044294,0x5); + reg32_write(0x3c044298,0x6); + reg32_write(0x3c04429c,0x7); + reg32_write(0x3c048280,0x0); + reg32_write(0x3c048284,0x1); + reg32_write(0x3c048288,0x2); + reg32_write(0x3c04828c,0x3); + reg32_write(0x3c048290,0x4); + reg32_write(0x3c048294,0x5); + reg32_write(0x3c048298,0x6); + reg32_write(0x3c04829c,0x7); + reg32_write(0x3c04c280,0x0); + reg32_write(0x3c04c284,0x1); + reg32_write(0x3c04c288,0x2); + reg32_write(0x3c04c28c,0x3); + reg32_write(0x3c04c290,0x4); + reg32_write(0x3c04c294,0x5); + reg32_write(0x3c04c298,0x6); + reg32_write(0x3c04c29c,0x7); + + /* Configure DDR PHY's registers */ + ddr_cfg_phy(); + + reg32_write(DDRC_RFSHCTL3(0), 0x00000000); + reg32_write(DDRC_SWCTL(0), 0x0000); + /* + * ------------------- 9 ------------------- + * Set DFIMISC.dfi_init_start to 1 + * ----------------------------------------- + */ + reg32_write(DDRC_DFIMISC(0), 0x00000030); + reg32_write(DDRC_SWCTL(0), 0x0001); + + /* wait DFISTAT.dfi_init_complete to 1 */ + tmp_t = 0; + while(tmp_t==0){ + tmp = reg32_read(DDRC_DFISTAT(0)); + tmp_t = tmp & 0x01; + tmp = reg32_read(DDRC_MRSTAT(0)); + } + + reg32_write(DDRC_SWCTL(0), 0x0000); + + /* clear DFIMISC.dfi_init_complete_en */ + reg32_write(DDRC_DFIMISC(0), 0x00000010); + reg32_write(DDRC_DFIMISC(0), 0x00000011); + reg32_write(DDRC_PWRCTL(0), 0x00000088); + + tmp = reg32_read(DDRC_CRCPARSTAT(0)); + /* + * set SWCTL.sw_done to enable quasi-dynamic register + * programming outside reset. + */ + reg32_write(DDRC_SWCTL(0), 0x00000001); + + /* wait SWSTAT.sw_done_ack to 1 */ + while((reg32_read(DDRC_SWSTAT(0)) & 0x1) == 0) + ; + + /* wait STAT.operating_mode([1:0] for ddr3) to normal state */ + while ((reg32_read(DDRC_STAT(0)) & 0x3) != 0x1) + ; + + reg32_write(DDRC_PWRCTL(0), 0x00000088); + /* reg32_write(DDRC_PWRCTL(0), 0x018a); */ + tmp = reg32_read(DDRC_CRCPARSTAT(0)); + + /* enable port 0 */ + reg32_write(DDRC_PCTRL_0(0), 0x00000001); + /* enable DDR auto-refresh mode */ + tmp = reg32_read(DDRC_RFSHCTL3(0)) & ~0x1; + reg32_write(DDRC_RFSHCTL3(0), tmp); +}
\ No newline at end of file diff --git a/arch/arm/boards/zii-imx8mq-dev/ddrphy_train.c b/arch/arm/boards/zii-imx8mq-dev/ddrphy_train.c new file mode 100644 index 0000000000..1b30ff7257 --- /dev/null +++ b/arch/arm/boards/zii-imx8mq-dev/ddrphy_train.c @@ -0,0 +1,935 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Generated code from MX8M_DDR_tool + */ + +#include "ddr.h" + +void ddr_cfg_phy(void) { + unsigned int tmp, tmp_t; + + //Init DDRPHY register... + reg32_write(0x3c080440,0x2); + reg32_write(0x3c080444,0x3); + reg32_write(0x3c080448,0x4); + reg32_write(0x3c08044c,0x5); + reg32_write(0x3c080450,0x0); + reg32_write(0x3c080454,0x1); + reg32_write(0x3c04017c,0x1ff); + reg32_write(0x3c04057c,0x1ff); + reg32_write(0x3c04417c,0x1ff); + reg32_write(0x3c04457c,0x1ff); + reg32_write(0x3c04817c,0x1ff); + reg32_write(0x3c04857c,0x1ff); + reg32_write(0x3c04c17c,0x1ff); + reg32_write(0x3c04c57c,0x1ff); + reg32_write(0x3c44017c,0x1ff); + reg32_write(0x3c44057c,0x1ff); + reg32_write(0x3c44417c,0x1ff); + reg32_write(0x3c44457c,0x1ff); + reg32_write(0x3c44817c,0x1ff); + reg32_write(0x3c44857c,0x1ff); + reg32_write(0x3c44c17c,0x1ff); + reg32_write(0x3c44c57c,0x1ff); + reg32_write(0x3c000154,0x1ff); + reg32_write(0x3c004154,0x1ff); + reg32_write(0x3c008154,0x1ff); + reg32_write(0x3c00c154,0x1ff); + reg32_write(0x3c010154,0x1ff); + reg32_write(0x3c014154,0x1ff); + reg32_write(0x3c018154,0x1ff); + reg32_write(0x3c01c154,0x1ff); + reg32_write(0x3c020154,0x1ff); + reg32_write(0x3c024154,0x1ff); + reg32_write(0x3c080314,0x19); + reg32_write(0x3c480314,0x7); + reg32_write(0x3c0800b8,0x2); + reg32_write(0x3c4800b8,0x1); + reg32_write(0x3c240810,0x0); + reg32_write(0x3c640810,0x0); + reg32_write(0x3c080090,0xab); + reg32_write(0x3c0800e8,0x0); + reg32_write(0x3c480090,0xab); + reg32_write(0x3c0800e8,0x0); + reg32_write(0x3c080158,0x3); + reg32_write(0x3c480158,0xa); + reg32_write(0x3c040134,0xe00); + reg32_write(0x3c040534,0xe00); + reg32_write(0x3c044134,0xe00); + reg32_write(0x3c044534,0xe00); + reg32_write(0x3c048134,0xe00); + reg32_write(0x3c048534,0xe00); + reg32_write(0x3c04c134,0xe00); + reg32_write(0x3c04c534,0xe00); + reg32_write(0x3c440134,0xe00); + reg32_write(0x3c440534,0xe00); + reg32_write(0x3c444134,0xe00); + reg32_write(0x3c444534,0xe00); + reg32_write(0x3c448134,0xe00); + reg32_write(0x3c448534,0xe00); + reg32_write(0x3c44c134,0xe00); + reg32_write(0x3c44c534,0xe00); + reg32_write(0x3c040124,0xfbe); + reg32_write(0x3c040524,0xfbe); + reg32_write(0x3c044124,0xfbe); + reg32_write(0x3c044524,0xfbe); + reg32_write(0x3c048124,0xfbe); + reg32_write(0x3c048524,0xfbe); + reg32_write(0x3c04c124,0xfbe); + reg32_write(0x3c04c524,0xfbe); + reg32_write(0x3c440124,0xfbe); + reg32_write(0x3c440524,0xfbe); + reg32_write(0x3c444124,0xfbe); + reg32_write(0x3c444524,0xfbe); + reg32_write(0x3c448124,0xfbe); + reg32_write(0x3c448524,0xfbe); + reg32_write(0x3c44c124,0xfbe); + reg32_write(0x3c44c524,0xfbe); + reg32_write(0x3c00010c,0x63); + reg32_write(0x3c00410c,0x63); + reg32_write(0x3c00810c,0x63); + reg32_write(0x3c00c10c,0x63); + reg32_write(0x3c01010c,0x63); + reg32_write(0x3c01410c,0x63); + reg32_write(0x3c01810c,0x63); + reg32_write(0x3c01c10c,0x63); + reg32_write(0x3c02010c,0x63); + reg32_write(0x3c02410c,0x63); + reg32_write(0x3c080060,0x3); + reg32_write(0x3c0801d4,0x4); + reg32_write(0x3c080140,0x0); + reg32_write(0x3c080020,0x320); + reg32_write(0x3c480020,0xa7); + reg32_write(0x3c080220,0x9); + reg32_write(0x3c0802c8,0xdc); + reg32_write(0x3c04010c,0x5a1); + reg32_write(0x3c04050c,0x5a1); + reg32_write(0x3c04410c,0x5a1); + reg32_write(0x3c04450c,0x5a1); + reg32_write(0x3c04810c,0x5a1); + reg32_write(0x3c04850c,0x5a1); + reg32_write(0x3c04c10c,0x5a1); + reg32_write(0x3c04c50c,0x5a1); + reg32_write(0x3c4802c8,0xdc); + reg32_write(0x3c44010c,0x5a1); + reg32_write(0x3c44050c,0x5a1); + reg32_write(0x3c44410c,0x5a1); + reg32_write(0x3c44450c,0x5a1); + reg32_write(0x3c44810c,0x5a1); + reg32_write(0x3c44850c,0x5a1); + reg32_write(0x3c44c10c,0x5a1); + reg32_write(0x3c44c50c,0x5a1); + reg32_write(0x3c0803e8,0x1); + reg32_write(0x3c4803e8,0x1); + reg32_write(0x3c080064,0x1); + reg32_write(0x3c480064,0x1); + reg32_write(0x3c0803c0,0x0); + reg32_write(0x3c0803c4,0x0); + reg32_write(0x3c0803c8,0x4444); + reg32_write(0x3c0803cc,0x8888); + reg32_write(0x3c0803d0,0x5555); + reg32_write(0x3c0803d4,0x0); + reg32_write(0x3c0803d8,0x0); + reg32_write(0x3c0803dc,0xf000); + reg32_write(0x3c080094,0x0); + reg32_write(0x3c0800b4,0x0); + reg32_write(0x3c4800b4,0x0); + reg32_write(0x3c080180,0x2); + + //enable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0); + //load the 1D training image + ddr_load_train_code(FW_1D_IMAGE); + + //configure DDRPHY-FW DMEM structure @clock0... + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1); + + //set the PHY input clock to the desired frequency for pstate 0 + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54003,0xc80); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54004,0x2); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54006,0x11); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54008,0x131f); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54009,0xc8); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5400b,0x2); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5400d,0x100); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54012,0x310); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54019,0x2dd4); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401a,0x31); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401b,0x4a66); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401c,0x4a08); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401e,0x16); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401f,0x2dd4); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54020,0x31); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54021,0x4a66); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54022,0x4a08); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54024,0x16); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5402b,0x1000); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5402c,0x3); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54032,0xd400); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54033,0x312d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54034,0x6600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54035,0x84a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54036,0x4a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54037,0x1600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54038,0xd400); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54039,0x312d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403a,0x6600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403b,0x84a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403c,0x4a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403d,0x1600); + + //disable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x1); + //Reset MPU and run + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x9); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x0); + wait_ddrphy_training_complete(); + + //configure DDRPHY-FW DMEM structure @clock1... + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1); + + //set the PHY input clock to the desired frequency for pstate 1 + reg32_write(0x3038a088,0x7070000); + reg32_write(0x3038a084,0x4030000); + reg32_write(0x303a00ec,0xffff); + tmp=reg32_read(0x303a00f8); + tmp |= 0x20; + reg32_write(0x303a00f8,tmp); + reg32_write(0x30360068,0xf5a406); + tmp=reg32_read(0x30360060); + tmp &= ~0x80; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp |= 0x200; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp &= ~0x20; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp &= ~0x10; + reg32_write(0x30360060,tmp); + do{ + tmp=reg32_read(0x30360060); + if(tmp&0x80000000) break; + }while(1); + reg32_write(0x30389808,0x1000000); + + //enable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0); + + reg32_write(0x3c150008,0x1); + reg32_write(0x3c15000c,0x29c); + reg32_write(0x3c150020,0x121f); + reg32_write(0x3c150064,0x994); + reg32_write(0x3c150068,0x31); + reg32_write(0x3c15006c,0x4d46); + reg32_write(0x3c150070,0x4d08); + reg32_write(0x3c150074,0x0); + reg32_write(0x3c150078,0x15); + reg32_write(0x3c15007c,0x994); + reg32_write(0x3c150080,0x31); + reg32_write(0x3c150084,0x4d46); + reg32_write(0x3c150088,0x4d08); + reg32_write(0x3c15008c,0x0); + reg32_write(0x3c150090,0x15); + reg32_write(0x3c1500c8,0x9400); + reg32_write(0x3c1500cc,0x3109); + reg32_write(0x3c1500d0,0x4600); + reg32_write(0x3c1500d4,0x84d); + reg32_write(0x3c1500d8,0x4d); + reg32_write(0x3c1500dc,0x1500); + reg32_write(0x3c1500e0,0x9400); + reg32_write(0x3c1500e4,0x3109); + reg32_write(0x3c1500e8,0x4600); + reg32_write(0x3c1500ec,0x84d); + reg32_write(0x3c1500f0,0x4d); + reg32_write(0x3c1500f4,0x1500); + reg32_write(0x3c1500f8,0x0); + + //disable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x1); + //Reset MPU and run + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x9); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x0); + wait_ddrphy_training_complete(); + + //set the PHY input clock to the desired frequency for pstate 0 + reg32_write(0x3038a088,0x7070000); + reg32_write(0x3038a084,0x4030000); + reg32_write(0x303a00ec,0xffff); + tmp=reg32_read(0x303a00f8); + tmp |= 0x20; + reg32_write(0x303a00f8,tmp); + reg32_write(0x30360068,0xece580); + tmp=reg32_read(0x30360060); + tmp &= ~0x80; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp |= 0x200; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp &= ~0x20; + reg32_write(0x30360060,tmp); + tmp=reg32_read(0x30360060); + tmp &= ~0x10; + reg32_write(0x30360060,tmp); + do{ + tmp=reg32_read(0x30360060); + if(tmp&0x80000000) break; + }while(1); + reg32_write(0x30389808,0x1000000); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1); + + + //enable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0); + //load the 2D training image + ddr_load_train_code(FW_2D_IMAGE); + + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54003,0xc80); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54006,0x11); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54008,0x61); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54009,0xc8); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5400b,0x2); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5400f,0x100); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54010,0x1f7f); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54012,0x310); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54019,0x2dd4); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401a,0x31); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401b,0x4a66); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401c,0x4a08); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401e,0x16); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401f,0x2dd4); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54020,0x31); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54021,0x4a66); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54022,0x4a08); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54024,0x16); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5402b,0x1000); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5402c,0x3); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54032,0xd400); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54033,0x312d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54034,0x6600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54035,0x84a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54036,0x4a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54037,0x1600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54038,0xd400); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54039,0x312d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403a,0x6600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403b,0x84a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403c,0x4a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403d,0x1600); + + //disable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x1); + //Reset MPU and run + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x9); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x0); + wait_ddrphy_training_complete(); + + //Halt MPU + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1); + //enable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0); + + //Load firmware PIE image + reg32_write(0x3c240000,0x10); + reg32_write(0x3c240004,0x400); + reg32_write(0x3c240008,0x10e); + reg32_write(0x3c24000c,0x0); + reg32_write(0x3c240010,0x0); + reg32_write(0x3c240014,0x8); + reg32_write(0x3c2400a4,0xb); + reg32_write(0x3c2400a8,0x480); + reg32_write(0x3c2400ac,0x109); + reg32_write(0x3c2400b0,0x8); + reg32_write(0x3c2400b4,0x448); + reg32_write(0x3c2400b8,0x139); + reg32_write(0x3c2400bc,0x8); + reg32_write(0x3c2400c0,0x478); + reg32_write(0x3c2400c4,0x109); + reg32_write(0x3c2400c8,0x0); + reg32_write(0x3c2400cc,0xe8); + reg32_write(0x3c2400d0,0x109); + reg32_write(0x3c2400d4,0x2); + reg32_write(0x3c2400d8,0x10); + reg32_write(0x3c2400dc,0x139); + reg32_write(0x3c2400e0,0xf); + reg32_write(0x3c2400e4,0x7c0); + reg32_write(0x3c2400e8,0x139); + reg32_write(0x3c2400ec,0x44); + reg32_write(0x3c2400f0,0x630); + reg32_write(0x3c2400f4,0x159); + reg32_write(0x3c2400f8,0x14f); + reg32_write(0x3c2400fc,0x630); + reg32_write(0x3c240100,0x159); + reg32_write(0x3c240104,0x47); + reg32_write(0x3c240108,0x630); + reg32_write(0x3c24010c,0x149); + reg32_write(0x3c240110,0x4f); + reg32_write(0x3c240114,0x630); + reg32_write(0x3c240118,0x179); + reg32_write(0x3c24011c,0x8); + reg32_write(0x3c240120,0xe0); + reg32_write(0x3c240124,0x109); + reg32_write(0x3c240128,0x0); + reg32_write(0x3c24012c,0x7c8); + reg32_write(0x3c240130,0x109); + reg32_write(0x3c240134,0x0); + reg32_write(0x3c240138,0x1); + reg32_write(0x3c24013c,0x8); + reg32_write(0x3c240140,0x0); + reg32_write(0x3c240144,0x45a); + reg32_write(0x3c240148,0x9); + reg32_write(0x3c24014c,0x0); + reg32_write(0x3c240150,0x448); + reg32_write(0x3c240154,0x109); + reg32_write(0x3c240158,0x40); + reg32_write(0x3c24015c,0x630); + reg32_write(0x3c240160,0x179); + reg32_write(0x3c240164,0x1); + reg32_write(0x3c240168,0x618); + reg32_write(0x3c24016c,0x109); + reg32_write(0x3c240170,0x40c0); + reg32_write(0x3c240174,0x630); + reg32_write(0x3c240178,0x149); + reg32_write(0x3c24017c,0x8); + reg32_write(0x3c240180,0x4); + reg32_write(0x3c240184,0x48); + reg32_write(0x3c240188,0x4040); + reg32_write(0x3c24018c,0x630); + reg32_write(0x3c240190,0x149); + reg32_write(0x3c240194,0x0); + reg32_write(0x3c240198,0x4); + reg32_write(0x3c24019c,0x48); + reg32_write(0x3c2401a0,0x40); + reg32_write(0x3c2401a4,0x630); + reg32_write(0x3c2401a8,0x149); + reg32_write(0x3c2401ac,0x10); + reg32_write(0x3c2401b0,0x4); + reg32_write(0x3c2401b4,0x18); + reg32_write(0x3c2401b8,0x0); + reg32_write(0x3c2401bc,0x4); + reg32_write(0x3c2401c0,0x78); + reg32_write(0x3c2401c4,0x549); + reg32_write(0x3c2401c8,0x630); + reg32_write(0x3c2401cc,0x159); + reg32_write(0x3c2401d0,0xd49); + reg32_write(0x3c2401d4,0x630); + reg32_write(0x3c2401d8,0x159); + reg32_write(0x3c2401dc,0x94a); + reg32_write(0x3c2401e0,0x630); + reg32_write(0x3c2401e4,0x159); + reg32_write(0x3c2401e8,0x441); + reg32_write(0x3c2401ec,0x630); + reg32_write(0x3c2401f0,0x149); + reg32_write(0x3c2401f4,0x42); + reg32_write(0x3c2401f8,0x630); + reg32_write(0x3c2401fc,0x149); + reg32_write(0x3c240200,0x1); + reg32_write(0x3c240204,0x630); + reg32_write(0x3c240208,0x149); + reg32_write(0x3c24020c,0x0); + reg32_write(0x3c240210,0xe0); + reg32_write(0x3c240214,0x109); + reg32_write(0x3c240218,0xa); + reg32_write(0x3c24021c,0x10); + reg32_write(0x3c240220,0x109); + reg32_write(0x3c240224,0x9); + reg32_write(0x3c240228,0x3c0); + reg32_write(0x3c24022c,0x149); + reg32_write(0x3c240230,0x9); + reg32_write(0x3c240234,0x3c0); + reg32_write(0x3c240238,0x159); + reg32_write(0x3c24023c,0x18); + reg32_write(0x3c240240,0x10); + reg32_write(0x3c240244,0x109); + reg32_write(0x3c240248,0x0); + reg32_write(0x3c24024c,0x3c0); + reg32_write(0x3c240250,0x109); + reg32_write(0x3c240254,0x18); + reg32_write(0x3c240258,0x4); + reg32_write(0x3c24025c,0x48); + reg32_write(0x3c240260,0x18); + reg32_write(0x3c240264,0x4); + reg32_write(0x3c240268,0x58); + reg32_write(0x3c24026c,0xa); + reg32_write(0x3c240270,0x10); + reg32_write(0x3c240274,0x109); + reg32_write(0x3c240278,0x2); + reg32_write(0x3c24027c,0x10); + reg32_write(0x3c240280,0x109); + reg32_write(0x3c240284,0x5); + reg32_write(0x3c240288,0x7c0); + reg32_write(0x3c24028c,0x109); + reg32_write(0x3c240290,0x10); + reg32_write(0x3c240294,0x10); + reg32_write(0x3c240298,0x109); + reg32_write(0x3c100000,0x811); + reg32_write(0x3c100080,0x880); + reg32_write(0x3c100100,0x0); + reg32_write(0x3c100180,0x0); + reg32_write(0x3c100004,0x4008); + reg32_write(0x3c100084,0x83); + reg32_write(0x3c100104,0x4f); + reg32_write(0x3c100184,0x0); + reg32_write(0x3c100008,0x4040); + reg32_write(0x3c100088,0x83); + reg32_write(0x3c100108,0x51); + reg32_write(0x3c100188,0x0); + reg32_write(0x3c10000c,0x811); + reg32_write(0x3c10008c,0x880); + reg32_write(0x3c10010c,0x0); + reg32_write(0x3c10018c,0x0); + reg32_write(0x3c100010,0x720); + reg32_write(0x3c100090,0xf); + reg32_write(0x3c100110,0x1740); + reg32_write(0x3c100190,0x0); + reg32_write(0x3c100014,0x16); + reg32_write(0x3c100094,0x83); + reg32_write(0x3c100114,0x4b); + reg32_write(0x3c100194,0x0); + reg32_write(0x3c100018,0x716); + reg32_write(0x3c100098,0xf); + reg32_write(0x3c100118,0x2001); + reg32_write(0x3c100198,0x0); + reg32_write(0x3c10001c,0x716); + reg32_write(0x3c10009c,0xf); + reg32_write(0x3c10011c,0x2800); + reg32_write(0x3c10019c,0x0); + reg32_write(0x3c100020,0x716); + reg32_write(0x3c1000a0,0xf); + reg32_write(0x3c100120,0xf00); + reg32_write(0x3c1001a0,0x0); + reg32_write(0x3c100024,0x720); + reg32_write(0x3c1000a4,0xf); + reg32_write(0x3c100124,0x1400); + reg32_write(0x3c1001a4,0x0); + reg32_write(0x3c100028,0xe08); + reg32_write(0x3c1000a8,0xc15); + reg32_write(0x3c100128,0x0); + reg32_write(0x3c1001a8,0x0); + reg32_write(0x3c10002c,0x623); + reg32_write(0x3c1000ac,0x15); + reg32_write(0x3c10012c,0x0); + reg32_write(0x3c1001ac,0x0); + reg32_write(0x3c100030,0x4028); + reg32_write(0x3c1000b0,0x80); + reg32_write(0x3c100130,0x0); + reg32_write(0x3c1001b0,0x0); + reg32_write(0x3c100034,0xe08); + reg32_write(0x3c1000b4,0xc1a); + reg32_write(0x3c100134,0x0); + reg32_write(0x3c1001b4,0x0); + reg32_write(0x3c100038,0x623); + reg32_write(0x3c1000b8,0x1a); + reg32_write(0x3c100138,0x0); + reg32_write(0x3c1001b8,0x0); + reg32_write(0x3c10003c,0x4040); + reg32_write(0x3c1000bc,0x80); + reg32_write(0x3c10013c,0x0); + reg32_write(0x3c1001bc,0x0); + reg32_write(0x3c100040,0x2604); + reg32_write(0x3c1000c0,0x15); + reg32_write(0x3c100140,0x0); + reg32_write(0x3c1001c0,0x0); + reg32_write(0x3c100044,0x708); + reg32_write(0x3c1000c4,0x5); + reg32_write(0x3c100144,0x0); + reg32_write(0x3c1001c4,0x2002); + reg32_write(0x3c100048,0x8); + reg32_write(0x3c1000c8,0x80); + reg32_write(0x3c100148,0x0); + reg32_write(0x3c1001c8,0x0); + reg32_write(0x3c10004c,0x2604); + reg32_write(0x3c1000cc,0x1a); + reg32_write(0x3c10014c,0x0); + reg32_write(0x3c1001cc,0x0); + reg32_write(0x3c100050,0x708); + reg32_write(0x3c1000d0,0xa); + reg32_write(0x3c100150,0x0); + reg32_write(0x3c1001d0,0x2002); + reg32_write(0x3c100054,0x4040); + reg32_write(0x3c1000d4,0x80); + reg32_write(0x3c100154,0x0); + reg32_write(0x3c1001d4,0x0); + reg32_write(0x3c100058,0x60a); + reg32_write(0x3c1000d8,0x15); + reg32_write(0x3c100158,0x1200); + reg32_write(0x3c1001d8,0x0); + reg32_write(0x3c10005c,0x61a); + reg32_write(0x3c1000dc,0x15); + reg32_write(0x3c10015c,0x1300); + reg32_write(0x3c1001dc,0x0); + reg32_write(0x3c100060,0x60a); + reg32_write(0x3c1000e0,0x1a); + reg32_write(0x3c100160,0x1200); + reg32_write(0x3c1001e0,0x0); + reg32_write(0x3c100064,0x642); + reg32_write(0x3c1000e4,0x1a); + reg32_write(0x3c100164,0x1300); + reg32_write(0x3c1001e4,0x0); + reg32_write(0x3c100068,0x4808); + reg32_write(0x3c1000e8,0x880); + reg32_write(0x3c100168,0x0); + reg32_write(0x3c1001e8,0x0); + reg32_write(0x3c24029c,0x0); + reg32_write(0x3c2402a0,0x790); + reg32_write(0x3c2402a4,0x11a); + reg32_write(0x3c2402a8,0x8); + reg32_write(0x3c2402ac,0x7aa); + reg32_write(0x3c2402b0,0x2a); + reg32_write(0x3c2402b4,0x10); + reg32_write(0x3c2402b8,0x7b2); + reg32_write(0x3c2402bc,0x2a); + reg32_write(0x3c2402c0,0x0); + reg32_write(0x3c2402c4,0x7c8); + reg32_write(0x3c2402c8,0x109); + reg32_write(0x3c2402cc,0x10); + reg32_write(0x3c2402d0,0x2a8); + reg32_write(0x3c2402d4,0x129); + reg32_write(0x3c2402d8,0x8); + reg32_write(0x3c2402dc,0x370); + reg32_write(0x3c2402e0,0x129); + reg32_write(0x3c2402e4,0xa); + reg32_write(0x3c2402e8,0x3c8); + reg32_write(0x3c2402ec,0x1a9); + reg32_write(0x3c2402f0,0xc); + reg32_write(0x3c2402f4,0x408); + reg32_write(0x3c2402f8,0x199); + reg32_write(0x3c2402fc,0x14); + reg32_write(0x3c240300,0x790); + reg32_write(0x3c240304,0x11a); + reg32_write(0x3c240308,0x8); + reg32_write(0x3c24030c,0x4); + reg32_write(0x3c240310,0x18); + reg32_write(0x3c240314,0xe); + reg32_write(0x3c240318,0x408); + reg32_write(0x3c24031c,0x199); + reg32_write(0x3c240320,0x8); + reg32_write(0x3c240324,0x8568); + reg32_write(0x3c240328,0x108); + reg32_write(0x3c24032c,0x18); + reg32_write(0x3c240330,0x790); + reg32_write(0x3c240334,0x16a); + reg32_write(0x3c240338,0x8); + reg32_write(0x3c24033c,0x1d8); + reg32_write(0x3c240340,0x169); + reg32_write(0x3c240344,0x10); + reg32_write(0x3c240348,0x8558); + reg32_write(0x3c24034c,0x168); + reg32_write(0x3c240350,0x70); + reg32_write(0x3c240354,0x788); + reg32_write(0x3c240358,0x16a); + reg32_write(0x3c24035c,0x1ff8); + reg32_write(0x3c240360,0x85a8); + reg32_write(0x3c240364,0x1e8); + reg32_write(0x3c240368,0x50); + reg32_write(0x3c24036c,0x798); + reg32_write(0x3c240370,0x16a); + reg32_write(0x3c240374,0x60); + reg32_write(0x3c240378,0x7a0); + reg32_write(0x3c24037c,0x16a); + reg32_write(0x3c240380,0x8); + reg32_write(0x3c240384,0x8310); + reg32_write(0x3c240388,0x168); + reg32_write(0x3c24038c,0x8); + reg32_write(0x3c240390,0xa310); + reg32_write(0x3c240394,0x168); + reg32_write(0x3c240398,0xa); + reg32_write(0x3c24039c,0x408); + reg32_write(0x3c2403a0,0x169); + reg32_write(0x3c2403a4,0x6e); + reg32_write(0x3c2403a8,0x0); + reg32_write(0x3c2403ac,0x68); + reg32_write(0x3c2403b0,0x0); + reg32_write(0x3c2403b4,0x408); + reg32_write(0x3c2403b8,0x169); + reg32_write(0x3c2403bc,0x0); + reg32_write(0x3c2403c0,0x8310); + reg32_write(0x3c2403c4,0x168); + reg32_write(0x3c2403c8,0x0); + reg32_write(0x3c2403cc,0xa310); + reg32_write(0x3c2403d0,0x168); + reg32_write(0x3c2403d4,0x1ff8); + reg32_write(0x3c2403d8,0x85a8); + reg32_write(0x3c2403dc,0x1e8); + reg32_write(0x3c2403e0,0x68); + reg32_write(0x3c2403e4,0x798); + reg32_write(0x3c2403e8,0x16a); + reg32_write(0x3c2403ec,0x78); + reg32_write(0x3c2403f0,0x7a0); + reg32_write(0x3c2403f4,0x16a); + reg32_write(0x3c2403f8,0x68); + reg32_write(0x3c2403fc,0x790); + reg32_write(0x3c240400,0x16a); + reg32_write(0x3c240404,0x8); + reg32_write(0x3c240408,0x8b10); + reg32_write(0x3c24040c,0x168); + reg32_write(0x3c240410,0x8); + reg32_write(0x3c240414,0xab10); + reg32_write(0x3c240418,0x168); + reg32_write(0x3c24041c,0xa); + reg32_write(0x3c240420,0x408); + reg32_write(0x3c240424,0x169); + reg32_write(0x3c240428,0x58); + reg32_write(0x3c24042c,0x0); + reg32_write(0x3c240430,0x68); + reg32_write(0x3c240434,0x0); + reg32_write(0x3c240438,0x408); + reg32_write(0x3c24043c,0x169); + reg32_write(0x3c240440,0x0); + reg32_write(0x3c240444,0x8b10); + reg32_write(0x3c240448,0x168); + reg32_write(0x3c24044c,0x0); + reg32_write(0x3c240450,0xab10); + reg32_write(0x3c240454,0x168); + reg32_write(0x3c240458,0x0); + reg32_write(0x3c24045c,0x1d8); + reg32_write(0x3c240460,0x169); + reg32_write(0x3c240464,0x80); + reg32_write(0x3c240468,0x790); + reg32_write(0x3c24046c,0x16a); + reg32_write(0x3c240470,0x18); + reg32_write(0x3c240474,0x7aa); + reg32_write(0x3c240478,0x6a); + reg32_write(0x3c24047c,0xa); + reg32_write(0x3c240480,0x0); + reg32_write(0x3c240484,0x1e9); + reg32_write(0x3c240488,0x8); + reg32_write(0x3c24048c,0x8080); + reg32_write(0x3c240490,0x108); + reg32_write(0x3c240494,0xf); + reg32_write(0x3c240498,0x408); + reg32_write(0x3c24049c,0x169); + reg32_write(0x3c2404a0,0xc); + reg32_write(0x3c2404a4,0x0); + reg32_write(0x3c2404a8,0x68); + reg32_write(0x3c2404ac,0x9); + reg32_write(0x3c2404b0,0x0); + reg32_write(0x3c2404b4,0x1a9); + reg32_write(0x3c2404b8,0x0); + reg32_write(0x3c2404bc,0x408); + reg32_write(0x3c2404c0,0x169); + reg32_write(0x3c2404c4,0x0); + reg32_write(0x3c2404c8,0x8080); + reg32_write(0x3c2404cc,0x108); + reg32_write(0x3c2404d0,0x8); + reg32_write(0x3c2404d4,0x7aa); + reg32_write(0x3c2404d8,0x6a); + reg32_write(0x3c2404dc,0x0); + reg32_write(0x3c2404e0,0x8568); + reg32_write(0x3c2404e4,0x108); + reg32_write(0x3c2404e8,0xb7); + reg32_write(0x3c2404ec,0x790); + reg32_write(0x3c2404f0,0x16a); + reg32_write(0x3c2404f4,0x1f); + reg32_write(0x3c2404f8,0x0); + reg32_write(0x3c2404fc,0x68); + reg32_write(0x3c240500,0x8); + reg32_write(0x3c240504,0x8558); + reg32_write(0x3c240508,0x168); + reg32_write(0x3c24050c,0xf); + reg32_write(0x3c240510,0x408); + reg32_write(0x3c240514,0x169); + reg32_write(0x3c240518,0xc); + reg32_write(0x3c24051c,0x0); + reg32_write(0x3c240520,0x68); + reg32_write(0x3c240524,0x0); + reg32_write(0x3c240528,0x408); + reg32_write(0x3c24052c,0x169); + reg32_write(0x3c240530,0x0); + reg32_write(0x3c240534,0x8558); + reg32_write(0x3c240538,0x168); + reg32_write(0x3c24053c,0x8); + reg32_write(0x3c240540,0x3c8); + reg32_write(0x3c240544,0x1a9); + reg32_write(0x3c240548,0x3); + reg32_write(0x3c24054c,0x370); + reg32_write(0x3c240550,0x129); + reg32_write(0x3c240554,0x20); + reg32_write(0x3c240558,0x2aa); + reg32_write(0x3c24055c,0x9); + reg32_write(0x3c240560,0x0); + reg32_write(0x3c240564,0x400); + reg32_write(0x3c240568,0x10e); + reg32_write(0x3c24056c,0x8); + reg32_write(0x3c240570,0xe8); + reg32_write(0x3c240574,0x109); + reg32_write(0x3c240578,0x0); + reg32_write(0x3c24057c,0x8140); + reg32_write(0x3c240580,0x10c); + reg32_write(0x3c240584,0x10); + reg32_write(0x3c240588,0x8138); + reg32_write(0x3c24058c,0x10c); + reg32_write(0x3c240590,0x8); + reg32_write(0x3c240594,0x7c8); + reg32_write(0x3c240598,0x101); + reg32_write(0x3c24059c,0x8); + reg32_write(0x3c2405a0,0x0); + reg32_write(0x3c2405a4,0x8); + reg32_write(0x3c2405a8,0x8); + reg32_write(0x3c2405ac,0x448); + reg32_write(0x3c2405b0,0x109); + reg32_write(0x3c2405b4,0xf); + reg32_write(0x3c2405b8,0x7c0); + reg32_write(0x3c2405bc,0x109); + reg32_write(0x3c2405c0,0x0); + reg32_write(0x3c2405c4,0xe8); + reg32_write(0x3c2405c8,0x109); + reg32_write(0x3c2405cc,0x47); + reg32_write(0x3c2405d0,0x630); + reg32_write(0x3c2405d4,0x109); + reg32_write(0x3c2405d8,0x8); + reg32_write(0x3c2405dc,0x618); + reg32_write(0x3c2405e0,0x109); + reg32_write(0x3c2405e4,0x8); + reg32_write(0x3c2405e8,0xe0); + reg32_write(0x3c2405ec,0x109); + reg32_write(0x3c2405f0,0x0); + reg32_write(0x3c2405f4,0x7c8); + reg32_write(0x3c2405f8,0x109); + reg32_write(0x3c2405fc,0x8); + reg32_write(0x3c240600,0x8140); + reg32_write(0x3c240604,0x10c); + reg32_write(0x3c240608,0x0); + reg32_write(0x3c24060c,0x1); + reg32_write(0x3c240610,0x8); + reg32_write(0x3c240614,0x8); + reg32_write(0x3c240618,0x4); + reg32_write(0x3c24061c,0x8); + reg32_write(0x3c240620,0x8); + reg32_write(0x3c240624,0x7c8); + reg32_write(0x3c240628,0x101); + reg32_write(0x3c240018,0x0); + reg32_write(0x3c24001c,0x0); + reg32_write(0x3c240020,0x8); + reg32_write(0x3c240024,0x0); + reg32_write(0x3c240028,0x0); + reg32_write(0x3c24002c,0x0); + reg32_write(0x3c34039c,0x400); + reg32_write(0x3c24005c,0x0); + reg32_write(0x3c24007c,0x2a); + reg32_write(0x3c240098,0x6a); + reg32_write(0x3c100340,0x0); + reg32_write(0x3c100344,0x101); + reg32_write(0x3c100348,0x105); + reg32_write(0x3c10034c,0x107); + reg32_write(0x3c100350,0x10f); + reg32_write(0x3c100354,0x202); + reg32_write(0x3c100358,0x20a); + reg32_write(0x3c10035c,0x20b); + reg32_write(0x3c0800e8,0x2); + reg32_write(0x3c08002c,0x65); + reg32_write(0x3c080030,0xc9); + reg32_write(0x3c080034,0x7d1); + reg32_write(0x3c080038,0x2c); + reg32_write(0x3c48002c,0x65); + reg32_write(0x3c480030,0xc9); + reg32_write(0x3c480034,0x7d1); + reg32_write(0x3c480038,0x2c); + reg32_write(0x3c240030,0x0); + reg32_write(0x3c240034,0x173); + reg32_write(0x3c240038,0x60); + reg32_write(0x3c24003c,0x6110); + reg32_write(0x3c240040,0x2152); + reg32_write(0x3c240044,0xdfbd); + reg32_write(0x3c240048,0x60); + reg32_write(0x3c24004c,0x6152); + reg32_write(0x3c080040,0x5a); + reg32_write(0x3c080044,0x3); + reg32_write(0x3c480040,0x5a); + reg32_write(0x3c480044,0x3); + reg32_write(0x3c100200,0xe0); + reg32_write(0x3c100204,0x12); + reg32_write(0x3c100208,0xe0); + reg32_write(0x3c10020c,0x12); + reg32_write(0x3c100210,0xe0); + reg32_write(0x3c100214,0x12); + reg32_write(0x3c500200,0xe0); + reg32_write(0x3c500204,0x12); + reg32_write(0x3c500208,0xe0); + reg32_write(0x3c50020c,0x12); + reg32_write(0x3c500210,0xe0); + reg32_write(0x3c500214,0x12); + reg32_write(0x3c1003f4,0xf); + reg32_write(0x3c040044,0x1); + reg32_write(0x3c040048,0x1); + reg32_write(0x3c04004c,0x180); + reg32_write(0x3c040060,0x1); + reg32_write(0x3c040008,0x6209); + reg32_write(0x3c0402c8,0x1); + reg32_write(0x3c0406d0,0x1); + reg32_write(0x3c040ad0,0x1); + reg32_write(0x3c040ed0,0x1); + reg32_write(0x3c0412d0,0x1); + reg32_write(0x3c0416d0,0x1); + reg32_write(0x3c041ad0,0x1); + reg32_write(0x3c041ed0,0x1); + reg32_write(0x3c0422d0,0x1); + reg32_write(0x3c044044,0x1); + reg32_write(0x3c044048,0x1); + reg32_write(0x3c04404c,0x180); + reg32_write(0x3c044060,0x1); + reg32_write(0x3c044008,0x6209); + reg32_write(0x3c0442c8,0x1); + reg32_write(0x3c0446d0,0x1); + reg32_write(0x3c044ad0,0x1); + reg32_write(0x3c044ed0,0x1); + reg32_write(0x3c0452d0,0x1); + reg32_write(0x3c0456d0,0x1); + reg32_write(0x3c045ad0,0x1); + reg32_write(0x3c045ed0,0x1); + reg32_write(0x3c0462d0,0x1); + reg32_write(0x3c048044,0x1); + reg32_write(0x3c048048,0x1); + reg32_write(0x3c04804c,0x180); + reg32_write(0x3c048060,0x1); + reg32_write(0x3c048008,0x6209); + reg32_write(0x3c0482c8,0x1); + reg32_write(0x3c0486d0,0x1); + reg32_write(0x3c048ad0,0x1); + reg32_write(0x3c048ed0,0x1); + reg32_write(0x3c0492d0,0x1); + reg32_write(0x3c0496d0,0x1); + reg32_write(0x3c049ad0,0x1); + reg32_write(0x3c049ed0,0x1); + reg32_write(0x3c04a2d0,0x1); + reg32_write(0x3c04c044,0x1); + reg32_write(0x3c04c048,0x1); + reg32_write(0x3c04c04c,0x180); + reg32_write(0x3c04c060,0x1); + reg32_write(0x3c04c008,0x6209); + reg32_write(0x3c04c2c8,0x1); + reg32_write(0x3c04c6d0,0x1); + reg32_write(0x3c04cad0,0x1); + reg32_write(0x3c04ced0,0x1); + reg32_write(0x3c04d2d0,0x1); + reg32_write(0x3c04d6d0,0x1); + reg32_write(0x3c04dad0,0x1); + reg32_write(0x3c04ded0,0x1); + reg32_write(0x3c04e2d0,0x1); + reg32_write(0x3c0800e8,0x2); + reg32_write(0x3c300200,0x2); + //customer Post Train + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x00020010, 0x0000006a); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x0002001d, 0x00000001); + /* + * CalBusy.0 =1, indicates the calibrator is actively calibrating. + * Wait Calibrating done. + */ + tmp_t = 1; + while(tmp_t) { + tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x20097); + tmp_t = tmp & 0x01; + } + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x2006e, 0x0); + //disable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x1); +}
\ No newline at end of file diff --git a/arch/arm/boards/zii-imx8mq-dev/flash-header-zii-imx8mq-dev.imxcfg b/arch/arm/boards/zii-imx8mq-dev/flash-header-zii-imx8mq-dev.imxcfg new file mode 100644 index 0000000000..aff8321b9a --- /dev/null +++ b/arch/arm/boards/zii-imx8mq-dev/flash-header-zii-imx8mq-dev.imxcfg @@ -0,0 +1,5 @@ +soc imx8mq + +loadaddr 0x007E1000 +max_load_size 0x3F000 +dcdofs 0x400 diff --git a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c new file mode 100644 index 0000000000..059e4c9efd --- /dev/null +++ b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Zodiac Inflight Innovation + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + */ + +#include <common.h> +#include <linux/sizes.h> +#include <mach/generic.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <mach/imx8-ccm-regs.h> +#include <mach/iomux-mx8.h> +#include <mach/imx8-ddrc.h> +#include <mach/xload.h> +#include <io.h> +#include <debug_ll.h> +#include <asm/cache.h> +#include <asm/sections.h> +#include <asm/mmu.h> +#include <mach/atf.h> +#include <mach/esdctl.h> + +#include "ddr.h" + +#define UART_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DSE_3P3V_45_OHM) + +static void setup_uart(void) +{ + void __iomem *iomux = IOMEM(MX8MQ_IOMUXC_BASE_ADDR); + void __iomem *ccm = IOMEM(MX8MQ_CCM_BASE_ADDR); + + writel(CCM_CCGR_SETTINGn_NEEDED(0), + ccm + CCM_CCGRn_CLR(CCM_CCGR_UART1)); + writel(CCM_TARGET_ROOTn_ENABLE | UART1_CLK_ROOT__25M_REF_CLK, + ccm + CCM_TARGET_ROOTn(UART1_CLK_ROOT)); + writel(CCM_CCGR_SETTINGn_NEEDED(0), + ccm + CCM_CCGRn_SET(CCM_CCGR_UART1)); + + imx_setup_pad(iomux, IMX8MQ_PAD_UART1_TXD__UART1_TX | UART_PAD_CTRL); + + imx8_uart_setup_ll(); + + putc_ll('>'); +} + +/* + * Two functions below are used when Barebox is used as a DDR + * initializing payload for OpenOCD + */ +#define RDU3_TCM_MAGIC_LOCATION 0x007e1028 +#define RDU3_TCM_MAGIC_REQUEST 0xdeadbeef +#define RDU3_TCM_MAGIC_REPLY 0xbaadf00d + +static bool running_as_ddr_helper(void) +{ + return readl(RDU3_TCM_MAGIC_LOCATION) == RDU3_TCM_MAGIC_REQUEST; +} + +static __noreturn void ddr_helper_halt(void) +{ + writel(RDU3_TCM_MAGIC_REPLY, RDU3_TCM_MAGIC_LOCATION); + asm volatile("hlt 0"); + BUG(); /* To prevent noreturn warnings */ +} + +static void zii_imx8mq_dev_sram_setup(void) +{ + enum bootsource src = BOOTSOURCE_UNKNOWN; + int instance = BOOTSOURCE_INSTANCE_UNKNOWN; + int ret = -ENOTSUPP; + + ddr_init(); + + if (running_as_ddr_helper()) + ddr_helper_halt(); + + imx8_get_boot_source(&src, &instance); + + if (src == BOOTSOURCE_MMC) + ret = imx8_esdhc_start_image(instance); + + BUG_ON(ret); +} + +enum zii_platform_imx8mq_type { + ZII_PLATFORM_IMX8MQ_ULTRA_RMB3 = 0b0000, + ZII_PLATFORM_IMX8MQ_ULTRA_ZEST = 0b1000, +}; + +static unsigned int get_system_type(void) +{ +#define GPIO_DR 0x000 +#define GPIO_GDIR 0x004 +#define SYSTEM_TYPE GENMASK(24, 21) + + u32 gdir, dr; + void __iomem *gpio3 = IOMEM(MX8MQ_GPIO3_BASE_ADDR); + void __iomem *iomuxbase = IOMEM(MX8MQ_IOMUXC_BASE_ADDR); + + /* + * System type is encoded as a 4-bit number specified by the + * following pins (pulled up or down with resistors on the + * board). + */ + imx_setup_pad(iomuxbase, IMX8MQ_PAD_SAI5_RXD0__GPIO3_IO21); + imx_setup_pad(iomuxbase, IMX8MQ_PAD_SAI5_RXD1__GPIO3_IO22); + imx_setup_pad(iomuxbase, IMX8MQ_PAD_SAI5_RXD2__GPIO3_IO23); + imx_setup_pad(iomuxbase, IMX8MQ_PAD_SAI5_RXD3__GPIO3_IO24); + + gdir = readl(gpio3 + GPIO_GDIR); + gdir &= ~SYSTEM_TYPE; + writel(gdir, gpio3 + GPIO_GDIR); + + dr = readl(gpio3 + GPIO_DR); + + return FIELD_GET(SYSTEM_TYPE, dr); +} + +extern char __dtb_imx8mq_zii_ultra_rmb3_start[]; +extern char __dtb_imx8mq_zii_ultra_zest_start[]; + +/* + * Power-on execution flow of start_zii_imx8mq_dev() might not be + * obvious for a very frist read, so here's, hopefully helpful, + * summary: + * + * 1. MaskROM uploads PBL into OCRAM and that's where this function is + * executed for the first time + * + * 2. DDR is initialized and full i.MX image is loaded to the + * beginning of RAM + * + * 3. start_nxp_imx8mq_evk, now in RAM, is executed again + * + * 4. BL31 blob is uploaded to OCRAM and the control is transfer to it + * + * 5. BL31 exits EL3 into EL2 at address MX8MQ_ATF_BL33_BASE_ADDR, + * executing start_nxp_imx8mq_evk() the third time + * + * 6. Standard barebox boot flow continues + */ +ENTRY_FUNCTION(start_zii_imx8mq_dev, r0, r1, r2) +{ + unsigned int system_type; + void *fdt; + + arm_cpu_lowlevel_init(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + setup_uart(); + + if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR) { + /* + * We assume that we were just loaded by MaskROM into + * SRAM if we are not running from DDR. We also assume + * that means DDR needs to be initialized for the + * first time. + */ + zii_imx8mq_dev_sram_setup(); + } + /* + * Straight from the power-on we are at EL3, so the following + * code _will_ load and jump to ATF. + * + * However when we are re-executed upon exit from ATF's + * initialization routine, it is EL2 which means we'll skip + * loadting ATF blob again + */ + if (current_el() == 3) { + const u8 *bl31; + size_t bl31_size; + + get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size); + imx8mq_atf_load_bl31(bl31, bl31_size); + } + + system_type = get_system_type(); + + switch (system_type) { + default: + /* + * see similar code in + * arch/arm/boards/zii-vf610-dev/lowlevel.c for + * reasoning for placing barrier() below. + */ + barrier(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) { + relocate_to_current_adr(); + setup_c(); + puts_ll("\n*********************************\n"); + puts_ll("* Unknown system type: "); + puthex_ll(system_type); + puts_ll("\n* Assuming Ultra RMB3\n"); + puts_ll("*********************************\n"); + } + /* FALLTHROUGH */ + case ZII_PLATFORM_IMX8MQ_ULTRA_RMB3: + fdt = __dtb_imx8mq_zii_ultra_rmb3_start; + break; + case ZII_PLATFORM_IMX8MQ_ULTRA_ZEST: + fdt = __dtb_imx8mq_zii_ultra_zest_start; + break; + } + + /* + * Standard entry we hit once we initialized both DDR and ATF + */ + imx8mq_barebox_entry(fdt); +} diff --git a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/boot/sd b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/boot/sd index cf8eec363c..dd8e99ba68 100644 --- a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/boot/sd +++ b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/boot/sd @@ -1,4 +1,13 @@ #!/bin/sh -global.bootm.image=/mnt/sd/zImage -global.bootm.oftree=/mnt/sd/${global.bootm.oftree} +detect mmc1 + +path="/mnt/mmc1.0" + +global.bootm.image="${path}/zImage" +global.bootm.oftree="${path}/vf610-zii-${global.hostname}.dtb" + +initramfs="${path}/initramfs" +if [ -f "${initramfs}" ]; then + global.bootm.initrd="$initramfs" +fi diff --git a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/automount-sd b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/automount-sd deleted file mode 100644 index f44dab34e4..0000000000 --- a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/automount-sd +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -if [ x${global.hostname} = xdev-rev-b -o x${global.hostname} = xdev-rev-c ]; -then - global sd=0 -else - global sd=1 -fi - -mkdir -p /mnt/sd -automount /mnt/sd 'mci${global.sd}.probe=1 && mount /dev/disk${global.sd}.0 /mnt/sd' - -exit 0 diff --git a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/choose-dtb b/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/choose-dtb deleted file mode 100644 index 41a74c3a98..0000000000 --- a/arch/arm/boards/zii-vf610-dev/defaultenv-zii-vf610-dev/init/choose-dtb +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -global.bootm.oftree=vf610-zii-${global.hostname}.dtb - diff --git a/arch/arm/configs/am335x_mlo_defconfig b/arch/arm/configs/am335x_mlo_defconfig index 58034b6cea..b58b71a859 100644 --- a/arch/arm/configs/am335x_mlo_defconfig +++ b/arch/arm/configs/am335x_mlo_defconfig @@ -8,7 +8,6 @@ CONFIG_MACH_PHYTEC_SOM_AM335X=y CONFIG_THUMB2_BAREBOX=y # CONFIG_MEMINFO is not set CONFIG_MMU=y -CONFIG_TEXT_BASE=0x0 CONFIG_BAREBOX_MAX_PBLX_SIZE=0x1b400 CONFIG_MALLOC_SIZE=0x0 CONFIG_MALLOC_TLSF=y @@ -38,6 +37,7 @@ CONFIG_MCI=y CONFIG_MCI_OMAP_HSMMC=y CONFIG_PINCTRL_SINGLE=y CONFIG_BUS_OMAP_GPMC=y +CONFIG_TI_SYSC=y # CONFIG_FS_DEVFS is not set CONFIG_FS_FAT=y CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/configs/imx_v8_defconfig b/arch/arm/configs/imx_v8_defconfig index cc41f49754..aa0a78ad93 100644 --- a/arch/arm/configs/imx_v8_defconfig +++ b/arch/arm/configs/imx_v8_defconfig @@ -1,5 +1,6 @@ CONFIG_ARCH_IMX=y CONFIG_IMX_MULTI_BOARDS=y +CONFIG_MACH_ZII_IMX8MQ_DEV=y CONFIG_MACH_NXP_IMX8MQ_EVK=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_MMU=y @@ -8,7 +9,6 @@ CONFIG_MALLOC_TLSF=y CONFIG_KALLSYMS=y CONFIG_RELOCATABLE=y CONFIG_HUSH_FANCY_PROMPT=y -CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y CONFIG_BOOTM_SHOW_TYPE=y @@ -18,6 +18,7 @@ CONFIG_BOOTM_OFTREE=y CONFIG_BOOTM_OFTREE_UIMAGE=y CONFIG_BLSPEC=y CONFIG_CONSOLE_ACTIVATE_NONE=y +CONFIG_CONSOLE_RATP=y CONFIG_PARTITION_DISK_EFI=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_RESET_SOURCE=y @@ -76,32 +77,47 @@ CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_NET=y CONFIG_NET_NETCONSOLE=y -CONFIG_NET_RESOLV=y CONFIG_OFDEVICE=y CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_SERIAL_DEV_BUS=y CONFIG_DRIVER_NET_FEC_IMX=y +CONFIG_MICREL_PHY=y +CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_GPIO=y +CONFIG_MDIO_BUS_MUX_GPIO=y CONFIG_DRIVER_SPI_IMX=y CONFIG_I2C=y CONFIG_I2C_IMX=y +CONFIG_MTD=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_M25P80=y CONFIG_MCI=y CONFIG_MCI_MMC_BOOT_PARTITIONS=y CONFIG_MCI_IMX_ESDHC=y +CONFIG_RAVE_SP_CORE=y CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_LED_GPIO_OF=y CONFIG_LED_TRIGGERS=y CONFIG_EEPROM_AT25=y +CONFIG_EEPROM_AT24=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_IMX=y +CONFIG_RAVE_SP_WATCHDOG=y CONFIG_NVMEM=y CONFIG_IMX_OCOTP=y +CONFIG_RAVE_SP_EEPROM=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=y CONFIG_FS_EXT4=y CONFIG_FS_TFTP=y CONFIG_FS_NFS=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y +CONFIG_FS_RATP=y CONFIG_ZLIB=y CONFIG_LZO_DECOMPRESS=y diff --git a/arch/arm/configs/omap_defconfig b/arch/arm/configs/omap_defconfig index 128027a640..8615283453 100644 --- a/arch/arm/configs/omap_defconfig +++ b/arch/arm/configs/omap_defconfig @@ -97,7 +97,6 @@ CONFIG_CMD_BOOTCHOOSER=y CONFIG_NET=y CONFIG_NET_NFS=y CONFIG_NET_NETCONSOLE=y -CONFIG_NET_RESOLV=y CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_DRIVER_SERIAL_NS16550=y CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS=y @@ -141,6 +140,7 @@ CONFIG_WATCHDOG_OMAP=y CONFIG_GPIO_GENERIC_PLATFORM=y CONFIG_PINCTRL_SINGLE=y CONFIG_BUS_OMAP_GPMC=y +CONFIG_TI_SYSC=y CONFIG_FS_EXT4=y CONFIG_FS_TFTP=y CONFIG_FS_NFS=y diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig index 2359c56b30..2577103293 100644 --- a/arch/arm/cpu/Kconfig +++ b/arch/arm/cpu/Kconfig @@ -13,6 +13,7 @@ config CPU_64 bool select PHYS_ADDR_T_64BIT select HAVE_PBL_IMAGE + select HAS_DMA # Select CPU types depending on the architecture selected. This selects # which CPUs we support in the kernel image, and the compiler instruction diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index a35db435c1..8e1af8bf8d 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -1,7 +1,7 @@ obj-y += cpu.o obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions$(S64).o interrupts$(S64).o -obj-$(CONFIG_MMU) += mmu$(S64).o +obj-$(CONFIG_MMU) += mmu$(S64).o mmu-common.o lwl-y += lowlevel$(S64).o obj-pbl-$(CONFIG_MMU) += mmu-early$(S64).o obj-pbl-$(CONFIG_CPU_32v7) += hyp.o diff --git a/arch/arm/cpu/mmu-common.c b/arch/arm/cpu/mmu-common.c new file mode 100644 index 0000000000..aeefbb2daa --- /dev/null +++ b/arch/arm/cpu/mmu-common.c @@ -0,0 +1,82 @@ + +#define pr_fmt(fmt) "mmu: " fmt + +#include <common.h> +#include <init.h> +#include <dma-dir.h> +#include <dma.h> +#include <mmu.h> +#include <asm/system.h> +#include <memory.h> +#include "mmu.h" + + +void dma_sync_single_for_cpu(dma_addr_t address, size_t size, + enum dma_data_direction dir) +{ + if (dir != DMA_TO_DEVICE) + dma_inv_range((void *)address, size); +} + +dma_addr_t dma_map_single(struct device_d *dev, void *ptr, size_t size, + enum dma_data_direction dir) +{ + unsigned long addr = (unsigned long)ptr; + + dma_sync_single_for_device(addr, size, dir); + + return addr; +} + +void dma_unmap_single(struct device_d *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir) +{ + dma_sync_single_for_cpu(addr, size, dir); +} + +void *dma_alloc_map(size_t size, dma_addr_t *dma_handle, unsigned flags) +{ + void *ret; + + size = PAGE_ALIGN(size); + ret = xmemalign(PAGE_SIZE, size); + if (dma_handle) + *dma_handle = (dma_addr_t)ret; + + memset(ret, 0, size); + dma_flush_range(ret, size); + + arch_remap_range(ret, size, flags); + + return ret; +} + +void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) +{ + return dma_alloc_map(size, dma_handle, MAP_UNCACHED); +} + +void dma_free_coherent(void *mem, dma_addr_t dma_handle, size_t size) +{ + size = PAGE_ALIGN(size); + arch_remap_range(mem, size, MAP_CACHED); + + free(mem); +} + +static int mmu_init(void) +{ + if (list_empty(&memory_banks)) + /* + * If you see this it means you have no memory registered. + * This can be done either with arm_add_mem_device() in an + * initcall prior to mmu_initcall or via devicetree in the + * memory node. + */ + panic("MMU: No memory bank found! Cannot continue\n"); + + __mmu_init(get_cr() & CR_M); + + return 0; +} +mmu_initcall(mmu_init);
\ No newline at end of file diff --git a/arch/arm/cpu/mmu-common.h b/arch/arm/cpu/mmu-common.h new file mode 100644 index 0000000000..0a33b138e1 --- /dev/null +++ b/arch/arm/cpu/mmu-common.h @@ -0,0 +1,20 @@ +#ifndef __ARM_MMU_COMMON_H +#define __ARM_MMU_COMMON_H + +void dma_inv_range(void *ptr, size_t size); +void dma_flush_range(void *ptr, size_t size); +void *dma_alloc_map(size_t size, dma_addr_t *dma_handle, unsigned flags); +void __mmu_init(bool mmu_on); + +static inline void arm_mmu_not_initialized_error(void) +{ + /* + * This means: + * - one of the MMU functions like dma_alloc_coherent + * or remap_range is called too early, before the MMU is initialized + * - Or the MMU initialization has failed earlier + */ + panic("MMU not initialized\n"); +} + +#endif
\ No newline at end of file diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index fc48376f66..29816ad563 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -75,17 +75,6 @@ static uint32_t pgd_flags_wc; #define PTE_MASK ((1 << 12) - 1) -static void arm_mmu_not_initialized_error(void) -{ - /* - * This means: - * - one of the MMU functions like dma_alloc_coherent - * or remap_range is called too early, before the MMU is initialized - * - Or the MMU initialization has failed earlier - */ - panic("MMU not initialized\n"); -} - static bool pgd_type_table(u32 pgd) { return (pgd & PMD_TYPE_MASK) == PMD_TYPE_TABLE; @@ -108,7 +97,7 @@ static u32 *find_pte(unsigned long adr) return &table[(adr >> PAGE_SHIFT) & 0xff]; } -static void dma_flush_range(void *ptr, size_t size) +void dma_flush_range(void *ptr, size_t size) { unsigned long start = (unsigned long)ptr; unsigned long end = start + size; @@ -118,8 +107,11 @@ static void dma_flush_range(void *ptr, size_t size) outer_cache.flush_range(start, end); } -static void dma_inv_range(unsigned long start, unsigned long end) +void dma_inv_range(void *ptr, size_t size) { + unsigned long start = (unsigned long)ptr; + unsigned long end = start + size; + if (outer_cache.inv_range) outer_cache.inv_range(start, end); __dma_inv_range(start, end); @@ -409,19 +401,10 @@ static void vectors_init(void) /* * Prepare MMU for usage enable it. */ -static int mmu_init(void) +void __mmu_init(bool mmu_on) { struct memory_bank *bank; - if (list_empty(&memory_banks)) - /* - * If you see this it means you have no memory registered. - * This can be done either with arm_add_mem_device() in an - * initcall prior to mmu_initcall or via devicetree in the - * memory node. - */ - panic("MMU: No memory bank found! Cannot continue\n"); - arm_set_cache_functions(); if (cpu_architecture() >= CPU_ARCH_ARMv7) { @@ -436,7 +419,7 @@ static int mmu_init(void) pte_flags_uncached = PTE_FLAGS_UNCACHED_V4; } - if (get_cr() & CR_M) { + if (mmu_on) { /* * Early MMU code has already enabled the MMU. We assume a * flat 1:1 section mapping in this case. @@ -480,10 +463,7 @@ static int mmu_init(void) } __mmu_cache_on(); - - return 0; } -mmu_initcall(mmu_init); /* * Clean and invalide caches, disable MMU @@ -498,57 +478,11 @@ void mmu_disable(void) __mmu_cache_off(); } -static void *dma_alloc_map(size_t size, dma_addr_t *dma_handle, unsigned flags) -{ - void *ret; - - size = PAGE_ALIGN(size); - ret = xmemalign(PAGE_SIZE, size); - if (dma_handle) - *dma_handle = (dma_addr_t)ret; - - dma_inv_range((unsigned long)ret, (unsigned long)ret + size); - - arch_remap_range(ret, size, flags); - - return ret; -} - -void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) -{ - return dma_alloc_map(size, dma_handle, MAP_UNCACHED); -} - void *dma_alloc_writecombine(size_t size, dma_addr_t *dma_handle) { return dma_alloc_map(size, dma_handle, ARCH_MAP_WRITECOMBINE); } -unsigned long virt_to_phys(volatile void *virt) -{ - return (unsigned long)virt; -} - -void *phys_to_virt(unsigned long phys) -{ - return (void *)phys; -} - -void dma_free_coherent(void *mem, dma_addr_t dma_handle, size_t size) -{ - size = PAGE_ALIGN(size); - arch_remap_range(mem, size, MAP_CACHED); - - free(mem); -} - -void dma_sync_single_for_cpu(dma_addr_t address, size_t size, - enum dma_data_direction dir) -{ - if (dir != DMA_TO_DEVICE) - dma_inv_range(address, address + size); -} - void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir) { @@ -562,19 +496,3 @@ void dma_sync_single_for_device(dma_addr_t address, size_t size, outer_cache.clean_range(address, address + size); } } - -dma_addr_t dma_map_single(struct device_d *dev, void *ptr, size_t size, - enum dma_data_direction dir) -{ - unsigned long addr = (unsigned long)ptr; - - dma_sync_single_for_device(addr, size, dir); - - return addr; -} - -void dma_unmap_single(struct device_d *dev, dma_addr_t addr, size_t size, - enum dma_data_direction dir) -{ - dma_sync_single_for_cpu(addr, size, dir); -} diff --git a/arch/arm/cpu/mmu.h b/arch/arm/cpu/mmu.h index 2e425e092e..338728aacd 100644 --- a/arch/arm/cpu/mmu.h +++ b/arch/arm/cpu/mmu.h @@ -4,6 +4,8 @@ #include <asm/pgtable.h> #include <linux/sizes.h> +#include "mmu-common.h" + #define PGDIR_SHIFT 20 #define PGDIR_SIZE (1UL << PGDIR_SHIFT) diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c index 99ddd5a441..b45a69661e 100644 --- a/arch/arm/cpu/mmu_64.c +++ b/arch/arm/cpu/mmu_64.c @@ -37,17 +37,6 @@ static uint64_t *ttb; -static void arm_mmu_not_initialized_error(void) -{ - /* - * This means: - * - one of the MMU functions like dma_alloc_coherent - * or remap_range is called too early, before the MMU is initialized - * - Or the MMU initialization has failed earlier - */ - panic("MMU not initialized\n"); -} - static void set_table(uint64_t *pt, uint64_t *table_addr) { uint64_t val; @@ -119,7 +108,8 @@ static void split_block(uint64_t *pte, int level) set_table(pte, new_table); } -static void map_region(uint64_t virt, uint64_t phys, uint64_t size, uint64_t attr) +static void create_sections(uint64_t virt, uint64_t phys, uint64_t size, + uint64_t attr) { uint64_t block_size; uint64_t block_shift; @@ -162,11 +152,7 @@ static void map_region(uint64_t virt, uint64_t phys, uint64_t size, uint64_t att } } -} -static void create_sections(uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags) -{ - map_region(virt, phys, size, flags); tlb_invalidate(); } @@ -183,9 +169,8 @@ int arch_remap_range(void *_start, size_t size, unsigned flags) return -EINVAL; } - map_region((uint64_t)_start, (uint64_t)_start, (uint64_t)size, flags); - tlb_invalidate(); - + create_sections((uint64_t)_start, (uint64_t)_start, (uint64_t)size, + flags); return 0; } @@ -198,21 +183,12 @@ static void mmu_enable(void) /* * Prepare MMU for usage enable it. */ -static int mmu_init(void) +void __mmu_init(bool mmu_on) { struct memory_bank *bank; unsigned int el; - if (list_empty(&memory_banks)) - /* - * If you see this it means you have no memory registered. - * This can be done either with arm_add_mem_device() in an - * initcall prior to mmu_initcall or via devicetree in the - * memory node. - */ - panic("MMU: No memory bank found! Cannot continue\n"); - - if (get_cr() & CR_M) + if (mmu_on) mmu_disable(); ttb = create_table(); @@ -232,10 +208,7 @@ static int mmu_init(void) create_sections(0x0, 0x0, 0x1000, 0x0); mmu_enable(); - - return 0; } -mmu_initcall(mmu_init); void mmu_disable(void) { @@ -252,45 +225,20 @@ void mmu_disable(void) isb(); } -unsigned long virt_to_phys(volatile void *virt) -{ - return (unsigned long)virt; -} - -void *phys_to_virt(unsigned long phys) -{ - return (void *)phys; -} - -void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) +void dma_inv_range(void *ptr, size_t size) { - void *ret; + unsigned long start = (unsigned long)ptr; + unsigned long end = start + size - 1; - size = PAGE_ALIGN(size); - ret = xmemalign(PAGE_SIZE, size); - if (dma_handle) - *dma_handle = (dma_addr_t)ret; - - map_region((unsigned long)ret, (unsigned long)ret, size, UNCACHED_MEM); - tlb_invalidate(); - - return ret; + v8_inv_dcache_range(start, end); } -void dma_free_coherent(void *mem, dma_addr_t dma_handle, size_t size) +void dma_flush_range(void *ptr, size_t size) { - size = PAGE_ALIGN(size); - - map_region((unsigned long)mem, (unsigned long)mem, size, CACHED_MEM); + unsigned long start = (unsigned long)ptr; + unsigned long end = start + size - 1; - free(mem); -} - -void dma_sync_single_for_cpu(dma_addr_t address, size_t size, - enum dma_data_direction dir) -{ - if (dir != DMA_TO_DEVICE) - v8_inv_dcache_range(address, address + size - 1); + v8_flush_dcache_range(start, end); } void dma_sync_single_for_device(dma_addr_t address, size_t size, @@ -301,19 +249,3 @@ void dma_sync_single_for_device(dma_addr_t address, size_t size, else v8_flush_dcache_range(address, address + size - 1); } - -dma_addr_t dma_map_single(struct device_d *dev, void *ptr, size_t size, - enum dma_data_direction dir) -{ - unsigned long addr = (unsigned long)ptr; - - dma_sync_single_for_device(addr, size, dir); - - return addr; -} - -void dma_unmap_single(struct device_d *dev, dma_addr_t addr, size_t size, - enum dma_data_direction dir) -{ - dma_sync_single_for_cpu(addr, size, dir); -} diff --git a/arch/arm/cpu/mmu_64.h b/arch/arm/cpu/mmu_64.h index 2cbe720625..e2e125686d 100644 --- a/arch/arm/cpu/mmu_64.h +++ b/arch/arm/cpu/mmu_64.h @@ -1,4 +1,6 @@ +#include "mmu-common.h" + #define CACHED_MEM (PTE_BLOCK_MEMTYPE(MT_NORMAL) | \ PTE_BLOCK_OUTER_SHARE | \ PTE_BLOCK_AF) diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index caa97e7137..3cdee1ffb7 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -100,6 +100,7 @@ pbl-dtb-$(CONFIG_MACH_TX6X) += imx6dl-tx6u.dtb.o pbl-dtb-$(CONFIG_MACH_TX6X) += imx6q-tx6q.dtb.o pbl-dtb-$(CONFIG_MACH_TURRIS_OMNIA) += armada-385-turris-omnia-bb.dtb.o pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o +pbl-dtb-$(CONFIG_MACH_UDOO_NEO) += imx6sx-udoo-neo-full.dtb.o pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o pbl-dtb-$(CONFIG_MACH_VEXPRESS) += vexpress-v2p-ca9.dtb.o @@ -112,6 +113,9 @@ pbl-dtb-$(CONFIG_MACH_ZII_RDU1) += \ imx51-zii-scu2-mezz.dtb.o \ imx51-zii-scu3-esb.dtb.o pbl-dtb-$(CONFIG_MACH_ZII_RDU2) += imx6q-zii-rdu2.dtb.o imx6qp-zii-rdu2.dtb.o +pbl-dtb-$(CONFIG_MACH_ZII_IMX8MQ_DEV) += \ + imx8mq-zii-ultra-rmb3.dtb.o \ + imx8mq-zii-ultra-zest.dtb.o pbl-dtb-$(CONFIG_MACH_ZII_VF610_DEV) += \ vf610-zii-dev-rev-b.dtb.o \ vf610-zii-dev-rev-c.dtb.o \ diff --git a/arch/arm/dts/am335x-phytec-phycard-som.dtsi b/arch/arm/dts/am335x-phytec-phycard-som.dtsi index 6a0442916b..2320ca1807 100644 --- a/arch/arm/dts/am335x-phytec-phycard-som.dtsi +++ b/arch/arm/dts/am335x-phytec-phycard-som.dtsi @@ -122,6 +122,10 @@ pinctrl-names = "default"; pinctrl-0 = <&davinci_mdio_default>; status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; }; &phy_sel { @@ -129,8 +133,9 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <&phy0>; phy-mode = "rmii"; + dual_emac_res_vlan = <1>; }; &mac { diff --git a/arch/arm/dts/am335x-phytec-phycore-som.dtsi b/arch/arm/dts/am335x-phytec-phycore-som.dtsi index cb2d30a15c..0601f5ab7b 100644 --- a/arch/arm/dts/am335x-phytec-phycore-som.dtsi +++ b/arch/arm/dts/am335x-phytec-phycore-som.dtsi @@ -244,6 +244,10 @@ pinctrl-names = "default"; pinctrl-0 = <&davinci_mdio_default>; status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; }; &phy_sel { @@ -251,8 +255,9 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <&phy0>; phy-mode = "rmii"; + dual_emac_res_vlan = <1>; }; &mac { diff --git a/arch/arm/dts/am335x-phytec-phyflex-som.dtsi b/arch/arm/dts/am335x-phytec-phyflex-som.dtsi index 465d3fa16c..4d0a913988 100644 --- a/arch/arm/dts/am335x-phytec-phyflex-som.dtsi +++ b/arch/arm/dts/am335x-phytec-phyflex-som.dtsi @@ -197,6 +197,14 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_default>; status = "okay"; + + phy0: ethernet-phy@0 { + reg = <1>; + }; + + phy1: ethernet-phy@1 { + reg = <2>; + }; }; &phy_sel { @@ -204,7 +212,7 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <1>; + phy-handle = <&phy0>; phy-mode = "rgmii"; dual_emac_res_vlan = <1>; @@ -221,7 +229,7 @@ }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <2>; + phy-handle = <&phy1>; phy-mode = "rmii"; dual_emac_res_vlan = <2>; status = "disabled"; diff --git a/arch/arm/dts/imx6sx-udoo-neo-full.dts b/arch/arm/dts/imx6sx-udoo-neo-full.dts new file mode 100644 index 0000000000..9203d40207 --- /dev/null +++ b/arch/arm/dts/imx6sx-udoo-neo-full.dts @@ -0,0 +1,4 @@ +#include <arm/imx6sx-udoo-neo-full.dts> + +/{ +}; diff --git a/arch/arm/dts/imx8mq-zii-ultra-rmb3.dts b/arch/arm/dts/imx8mq-zii-ultra-rmb3.dts new file mode 100644 index 0000000000..b2b3a560b5 --- /dev/null +++ b/arch/arm/dts/imx8mq-zii-ultra-rmb3.dts @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2019 Zodiac Inflight Innovations + */ + +/dts-v1/; + +#include "imx8mq-zii-ultra.dtsi" + +/ { + model = "ZII i.MX8MQ Ultra RMB3 Board"; + compatible = "zii,imx8mq-ultra-rmb3", "zii,imx8mq-ultra", "fsl,imx8mq"; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + nor_flash: flash@0 { + compatible = "st,m25p128", "jedec,spi-nor"; + spi-max-frequency = <20000000>; + reg = <0>; + }; +}; + +&iomuxc { + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX8MQ_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x19 + MX8MQ_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x82 + MX8MQ_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82 + MX8MQ_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82 + >; + }; +}; diff --git a/arch/arm/dts/imx8mq-zii-ultra-zest.dts b/arch/arm/dts/imx8mq-zii-ultra-zest.dts new file mode 100644 index 0000000000..c2ac05d8e8 --- /dev/null +++ b/arch/arm/dts/imx8mq-zii-ultra-zest.dts @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2019 Zodiac Inflight Innovations + */ + +/dts-v1/; + +#include "imx8mq-zii-ultra.dtsi" + +/ { + model = "ZII i.MX8MQ Ultra Zest Board"; + compatible = "zii,imx8mq-ultra-zest", "zii,imx8mq-ultra", "fsl,imx8mq"; +}; diff --git a/arch/arm/dts/imx8mq-zii-ultra.dtsi b/arch/arm/dts/imx8mq-zii-ultra.dtsi new file mode 100644 index 0000000000..a6b2b89662 --- /dev/null +++ b/arch/arm/dts/imx8mq-zii-ultra.dtsi @@ -0,0 +1,453 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2019 Zodiac Inflight Innovations + */ + +#include <arm64/freescale/imx8mq.dtsi> +#include "imx8mq.dtsi" +#include "imx8mq-ddrc.dtsi" + +/ { + chosen { + stdout-path = &uart1; + }; + + mdio0: bitbang-mdio { + compatible = "virtual,mdio-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mdio_bitbang>, <&pinctrl_fec1_phy_reset>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>, /* MDC */ + <&gpio1 14 GPIO_ACTIVE_HIGH>; /* MDIO */ + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@0 { + reg = <0>; + reset-gpios = <&gpio1 29 GPIO_ACTIVE_LOW>; + }; + }; + + reg_usdhc2_vmmc: regulator-vsd-3v3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2>; + compatible = "regulator-fixed"; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + + phy-handle = <&phy0>; + phy-mode = "rmii"; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + switch: switch@0 { + compatible = "marvell,mv88e6085"; + reg = <0>; + dsa,member = <0 0>; + eeprom-length = <512>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "gigabit_proc"; + }; + + port@1 { + reg = <1>; + label = "netaux"; + }; + + port@2 { + reg = <2>; + label = "cpu"; + + fixed-link { + speed = <100>; + full-duplex; + }; + }; + + port@3 { + reg = <3>; + label = "netright"; + }; + + port@4 { + reg = <4>; + label = "netleft"; + }; + }; + }; + }; +}; + +&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"; + + pmic@8 { + compatible = "fsl,pfuze100"; + reg = <0x8>; + + regulators { + sw1a_reg: sw1ab { + regulator-min-microvolt = <825000>; + regulator-max-microvolt = <1100000>; + }; + + sw1c_reg: sw1c { + regulator-min-microvolt = <825000>; + regulator-max-microvolt = <1100000>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + sw3a_reg: sw3ab { + regulator-min-microvolt = <825000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + sw4_reg: sw4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-always-on; + }; + + vgen1_reg: vgen1 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <975000>; + regulator-always-on; + }; + + vgen3_reg: vgen3 { + regulator-min-microvolt = <1675000>; + regulator-max-microvolt = <1975000>; + regulator-always-on; + }; + + vgen4_reg: vgen4 { + regulator-min-microvolt = <1625000>; + regulator-max-microvolt = <1875000>; + regulator-always-on; + }; + + vgen5_reg: vgen5 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3625000>; + regulator-always-on; + }; + + vgen6_reg: vgen6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + }; + }; + + temp-sense@48 { + compatible = "national,lm75"; + reg = <0x48>; + }; + + eeprom@54 { + compatible = "atmel,24c128"; + reg = <0x54>; + }; + + ds1341: rtc@68 { + compatible = "dallas,ds1341"; + reg = <0x68>; + }; +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; +}; + +&i2c4 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; +}; + +&ocotp { + barebox,provide-mac-address = <&fec1 0x640>; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; + + rave-sp { + compatible = "zii,rave-sp-rdu2"; + current-speed = <1000000>; + #address-cells = <1>; + #size-cells = <1>; + + watchdog { + compatible = "zii,rave-sp-watchdog"; + }; + + main_eeprom: eeprom@a4 { + compatible = "zii,rave-sp-eeprom"; + reg = <0xa4 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + zii,eeprom-name = "main-eeprom"; + }; + + eeprom@a3 { + compatible = "zii,rave-sp-eeprom"; + reg = <0xa3 0x4000>; + zii,eeprom-name = "dds-eeprom"; + }; + }; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + vqmmc-supply = <&sw4_reg>; + bus-width = <8>; + non-removable; + no-sd; + no-sdio; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&iomuxc { + pinctrl_mdio_bitbang: bitbangmdiogrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x44 + MX8MQ_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x64 + >; + }; + + pinctrl_fec1: fec1grp { + fsl,pins = < + MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23 + MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MQ_IOMUXC_ENET_TD2_ENET1_TX_CLK 0x1f + MX8MQ_IOMUXC_ENET_RXC_ENET1_RX_ER 0x91 + MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + >; + }; + + pinctrl_fec1_phy_reset: fec1phyresetgrp { + fsl,pins = < + MX8MQ_IOMUXC_ENET_RD3_GPIO1_IO29 0x11 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f + MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000007f + MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000007f + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x4000007f + MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x4000007f + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL 0x4000007f + MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA 0x4000007f + >; + }; + + pinctrl_reg_usdhc2: regusdhc2grpgpio { + fsl,pins = < + MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x49 + MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x49 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x49 + MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x49 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83 + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1-100grp { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x85 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc5 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc5 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc5 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc5 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc5 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc5 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc5 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc5 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc5 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x85 + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200grp { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x87 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc7 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc7 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc7 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc7 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc7 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc7 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc7 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc7 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc7 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x87 + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100grp { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x85 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc5 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc5 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc5 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc5 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200grp { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc7 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc7 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc7 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc7 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; +};
\ No newline at end of file diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index d06ff8323f..56db546341 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -69,10 +69,6 @@ extern void memset_io(volatile void __iomem *, int, size_t); #define setbits_8(addr, set) setbits(8, addr, set) #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) -#ifdef CONFIG_MMU -void *phys_to_virt(unsigned long phys); -unsigned long virt_to_phys(volatile void *virt); -#else static inline void *phys_to_virt(unsigned long phys) { return (void *)phys; @@ -82,6 +78,5 @@ static inline unsigned long virt_to_phys(volatile void *mem) { return (unsigned long)mem; } -#endif #endif /* __ASM_ARM_IO_H */ diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S index e7a94f912e..53c9ce0fe6 100644 --- a/arch/arm/lib/pbl.lds.S +++ b/arch/arm/lib/pbl.lds.S @@ -95,6 +95,6 @@ SECTIONS .image_end : { *(.__image_end) } - _barebox_image_size = __piggydata_end - BASE; + _barebox_image_size = __image_end - BASE; _barebox_pbl_size = __bss_start - BASE; } diff --git a/arch/arm/lib64/barebox.lds.S b/arch/arm/lib64/barebox.lds.S index 08adc44e86..b3e6843a15 100644 --- a/arch/arm/lib64/barebox.lds.S +++ b/arch/arm/lib64/barebox.lds.S @@ -86,6 +86,18 @@ SECTIONS __usymtab : { BAREBOX_SYMS } __usymtab_end = .; +#ifdef CONFIG_PCI + __start_pci_fixups_early = .; + .pci_fixup_early : { KEEP(*(.pci_fixup_early)) } + __end_pci_fixups_early = .; + __start_pci_fixups_header = .; + .pci_fixup_header : { KEEP(*(.pci_fixup_header)) } + __end_pci_fixups_header = .; + __start_pci_fixups_enable = .; + .pci_fixup_enable : { KEEP(*(.pci_fixup_enable)) } + __end_pci_fixups_enable = .; +#endif + .oftables : { BAREBOX_CLK_TABLE() } .dtb : { BAREBOX_DTB() } diff --git a/arch/arm/lib64/runtime-offset.S b/arch/arm/lib64/runtime-offset.S index 177ca64784..6624fdfa15 100644 --- a/arch/arm/lib64/runtime-offset.S +++ b/arch/arm/lib64/runtime-offset.S @@ -1,7 +1,19 @@ #include <linux/linkage.h> #include <asm/assembler.h> -.section ".text_bare_init","ax" +/* + * The .section directive below intentionally omits "a", since that + * appears to be the simplest way to force assembler to not generate + * R_AARCH64_RELATIVE relocation for + * + * linkadr: + * .quad get_runtime_offset + * + * statement below. While having that relocating was relatively + * harmless with GCC8, builging the code with GCC5 resulted in + * "linkaddr" being initialized to 0 causing complete boot breakdown + */ +.section ".text_bare_init","x" /* * Get the offset between the link address and the address diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 44ca27096b..8b859ab2f6 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -173,6 +173,7 @@ config ARCH_IMX7 select COMMON_CLK_OF_PROVIDER select ARCH_HAS_FEC_IMX select ARCH_HAS_IMX_GPT + select HW_HAS_PCI config ARCH_IMX8MQ bool @@ -182,6 +183,7 @@ config ARCH_IMX8MQ select SYS_SUPPORTS_64BIT_KERNEL select COMMON_CLK_OF_PROVIDER select ARCH_HAS_FEC_IMX + select HW_HAS_PCI config ARCH_VF610 bool @@ -395,6 +397,10 @@ config MACH_UDOO bool "Freescale i.MX6 UDOO Board" select ARCH_IMX6 +config MACH_UDOO_NEO + bool "i.MX6 UDOO Neo Board (full variant)" + select ARCH_IMX6SX + config MACH_VARISCITE_MX6 bool "Variscite i.MX6 Quad SOM" select ARCH_IMX6 @@ -434,6 +440,13 @@ config MACH_ZII_RDU2 bool "ZII i.MX6Q(+) RDU2" select ARCH_IMX6 +config MACH_ZII_IMX8MQ_DEV + bool "ZII i.MX8MQ based devices" + select ARCH_IMX8MQ + select FIRMWARE_IMX_LPDDR4_PMU_TRAIN + select FIRMWARE_IMX8MQ_ATF + select ARM_SMCCC + config MACH_ZII_VF610_DEV bool "ZII VF610 Dev Family" select ARCH_VF610 diff --git a/arch/arm/mach-imx/imx-bbu-internal.c b/arch/arm/mach-imx/imx-bbu-internal.c index 5f85b13dca..188369fe34 100644 --- a/arch/arm/mach-imx/imx-bbu-internal.c +++ b/arch/arm/mach-imx/imx-bbu-internal.c @@ -629,6 +629,11 @@ int imx7_bbu_internal_mmcboot_register_handler(const char *name, unsigned long flags) __alias(imx_bbu_internal_mmcboot_register_handler); +int imx8mq_bbu_internal_mmcboot_register_handler(const char *name, + const char *devicefile, + unsigned long flags) + __alias(imx_bbu_internal_mmcboot_register_handler); + /* * Register an i.MX53 internal boot update handler for i2c/spi * EEPROMs / flashes. Nearly the same as MMC/SD, but we do not need to diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c index 81b9f539df..1c6244990d 100644 --- a/arch/arm/mach-imx/imx27.c +++ b/arch/arm/mach-imx/imx27.c @@ -20,7 +20,6 @@ #include <mach/generic.h> #include <init.h> #include <io.h> -#include <mach/generic.h> static int imx27_silicon_revision(void) { diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c index cc368c5820..01b4274ed3 100644 --- a/arch/arm/mach-imx/imx6.c +++ b/arch/arm/mach-imx/imx6.c @@ -23,15 +23,11 @@ #include <mach/reset-reason.h> #include <mach/imx6-anadig.h> #include <mach/imx6-regs.h> -#include <mach/generic.h> #include <mach/usb.h> #include <asm/mmu.h> #include <asm/cache-l2x0.h> #include <poweroff.h> -#include <mach/imx6-regs.h> -#include <mach/clock-imx6.h> -#include <io.h> #define CLPCR 0x54 #define BP_CLPCR_LPM(mode) ((mode) & 0x3) diff --git a/arch/arm/mach-imx/include/mach/bbu.h b/arch/arm/mach-imx/include/mach/bbu.h index c8223c8405..10638a7fc7 100644 --- a/arch/arm/mach-imx/include/mach/bbu.h +++ b/arch/arm/mach-imx/include/mach/bbu.h @@ -76,6 +76,8 @@ int imx7_bbu_internal_spi_i2c_register_handler(const char *name, const char *dev int imx8mq_bbu_internal_mmc_register_handler(const char *name, const char *devicefile, unsigned long flags); +int imx8mq_bbu_internal_mmcboot_register_handler(const char *name, const char *devicefile, + unsigned long flags); int imx_bbu_external_nor_register_handler(const char *name, const char *devicefile, unsigned long flags); @@ -165,6 +167,13 @@ static inline int imx8mq_bbu_internal_mmc_register_handler(const char *name, con return -ENOSYS; } +static inline int imx8mq_bbu_internal_mmcboot_register_handler(const char *name, + const char *devicefile, + unsigned long flags) +{ + return -ENOSYS; +} + static inline int imx_bbu_external_nor_register_handler(const char *name, const char *devicefile, unsigned long flags) { diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h index bc6c733953..18c4a28360 100644 --- a/arch/arm/mach-imx/include/mach/esdctl.h +++ b/arch/arm/mach-imx/include/mach/esdctl.h @@ -141,6 +141,7 @@ void __noreturn imx6ul_barebox_entry(void *boarddata); void __noreturn vf610_barebox_entry(void *boarddata); void __noreturn imx8mq_barebox_entry(void *boarddata); void __noreturn imx7d_barebox_entry(void *boarddata); +#define imx6sx_barebox_entry(boarddata) imx6ul_barebox_entry(boarddata) void imx_esdctl_disable(void); #endif diff --git a/arch/arm/mach-imx/include/mach/imx8mq.h b/arch/arm/mach-imx/include/mach/imx8mq.h index f4a537d2b1..08dc06fdb4 100644 --- a/arch/arm/mach-imx/include/mach/imx8mq.h +++ b/arch/arm/mach-imx/include/mach/imx8mq.h @@ -9,6 +9,8 @@ #define IMX8MQ_ROM_VERSION_A0 0x800 #define IMX8MQ_ROM_VERSION_B0 0x83C +#define IMX8MQ_OCOTP_VERSION_B1 0x40 +#define IMX8MQ_OCOTP_VERSION_B1_MAGIC 0xff0055aa #define MX8MQ_ANATOP_DIGPROG 0x6c @@ -20,21 +22,28 @@ static inline int imx8mq_cpu_revision(void) { void __iomem *anatop = IOMEM(MX8MQ_ANATOP_BASE_ADDR); + void __iomem *ocotp = IOMEM(MX8MQ_OCOTP_BASE_ADDR); uint32_t revision = FIELD_GET(DIGPROG_MINOR, readl(anatop + MX8MQ_ANATOP_DIGPROG)); - - if (revision == IMX_CHIP_REV_1_0) { - uint32_t rom_version; - /* - * For B0 chip, the DIGPROG is not updated, still TO1.0. - * we have to check ROM version further - */ - rom_version = readl(IOMEM(IMX8MQ_ROM_VERSION_A0)); - if (rom_version != IMX_CHIP_REV_1_0) { - rom_version = readl(IOMEM(IMX8MQ_ROM_VERSION_B0)); - if (rom_version >= IMX_CHIP_REV_2_0) - revision = IMX_CHIP_REV_2_0; - } + uint32_t rom_version; + + if (revision != IMX_CHIP_REV_1_0) + return revision; + /* + * For B1 chip we need to check OCOTP + */ + if (readl(ocotp + IMX8MQ_OCOTP_VERSION_B1) == + IMX8MQ_OCOTP_VERSION_B1_MAGIC) + return IMX_CHIP_REV_2_1; + /* + * For B0 chip, the DIGPROG is not updated, still TO1.0. + * we have to check ROM version further + */ + rom_version = readb(IOMEM(IMX8MQ_ROM_VERSION_A0)); + if (rom_version != IMX_CHIP_REV_1_0) { + rom_version = readb(IOMEM(IMX8MQ_ROM_VERSION_B0)); + if (rom_version >= IMX_CHIP_REV_2_0) + revision = IMX_CHIP_REV_2_0; } return revision; diff --git a/arch/arm/mach-nomadik/8815.c b/arch/arm/mach-nomadik/8815.c index af32c9ccb4..dc1bcd2bcd 100644 --- a/arch/arm/mach-nomadik/8815.c +++ b/arch/arm/mach-nomadik/8815.c @@ -18,7 +18,6 @@ #include <init.h> #include <linux/clkdev.h> #include <mach/hardware.h> -#include <mach/hardware.h> #include <asm/armlinux.h> #include <generated/mach-types.h> #include <linux/amba/bus.h> diff --git a/arch/arm/mach-omap/am33xx_generic.c b/arch/arm/mach-omap/am33xx_generic.c index fe3c4a8b17..7577df761c 100644 --- a/arch/arm/mach-omap/am33xx_generic.c +++ b/arch/arm/mach-omap/am33xx_generic.c @@ -474,18 +474,18 @@ int am33xx_of_register_bootdevice(void) switch (bootsource_get()) { case BOOTSOURCE_MMC: if (bootsource_get_instance() == 0) - dev = of_device_enable_and_register_by_name("mmc@48060000"); + dev = of_device_enable_and_register_by_alias("mmc0"); else - dev = of_device_enable_and_register_by_name("mmc@481d8000"); + dev = of_device_enable_and_register_by_alias("mmc1"); break; case BOOTSOURCE_NAND: dev = of_device_enable_and_register_by_name("gpmc@50000000"); break; case BOOTSOURCE_SPI: - dev = of_device_enable_and_register_by_name("spi@48030000"); + dev = of_device_enable_and_register_by_alias("spi0"); break; case BOOTSOURCE_NET: - dev = of_device_enable_and_register_by_name("ethernet@4a100000"); + dev = of_device_enable_and_register_by_alias("ethernet0"); break; default: /* Use nand fallback */ diff --git a/arch/arm/mach-zynq/zynq.c b/arch/arm/mach-zynq/zynq.c index a0a8d0d249..f6112fd249 100644 --- a/arch/arm/mach-zynq/zynq.c +++ b/arch/arm/mach-zynq/zynq.c @@ -14,7 +14,7 @@ */ #include <asm/system.h> -#include <asm-generic/io.h> +#include <io.h> #include <common.h> #include <init.h> #include <restart.h> diff --git a/commands/digest.c b/commands/digest.c index 0edbbec32c..99b27dcc25 100644 --- a/commands/digest.c +++ b/commands/digest.c @@ -6,6 +6,7 @@ #include <common.h> #include <command.h> +#include <linux/pagemap.h> #include <fs.h> #include <fcntl.h> #include <errno.h> @@ -35,7 +36,7 @@ int __do_digest(struct digest *d, unsigned char *sig, while (*argv) { char *filename = "/dev/mem"; - loff_t start = 0, size = ~0; + loff_t start = 0, size = MAX_LFS_FILESIZE; int show_area = 1; /* arguments are either file, file+area or area */ diff --git a/commands/go.c b/commands/go.c index fb319b320c..ecc2ceb6e4 100644 --- a/commands/go.c +++ b/commands/go.c @@ -45,7 +45,7 @@ static int do_go(int argc, char *argv[]) } addr = memmap(fd, PROT_READ); - if (addr == (void *)-1) { + if (addr == MAP_FAILED) { perror("memmap"); goto out; } diff --git a/commands/md.c b/commands/md.c index 3e83c723a3..a495fc8b41 100644 --- a/commands/md.c +++ b/commands/md.c @@ -68,7 +68,7 @@ static int do_mem_md(int argc, char *argv[]) return 1; map = memmap(fd, PROT_READ); - if (map != (void *)-1) { + if (map != MAP_FAILED) { ret = memory_display(map + start, start, size, mode >> O_RWSIZE_SHIFT, swab); goto out; diff --git a/common/ratp/md.c b/common/ratp/md.c index 9ce7e99dfd..ce343d7c7b 100644 --- a/common/ratp/md.c +++ b/common/ratp/md.c @@ -76,7 +76,7 @@ static int do_ratp_mem_md(const char *filename, return -errno; map = memmap(fd, PROT_READ); - if (map != (void *)-1) { + if (map != MAP_FAILED) { memcpy(output, (uint8_t *)(map + start), size); goto out; } diff --git a/crypto/digest.c b/crypto/digest.c index bc6de0b98f..2c4de2e4f1 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -211,15 +211,76 @@ void digest_free(struct digest *d) } EXPORT_SYMBOL_GPL(digest_free); +static int digest_update_interruptible(struct digest *d, const void *data, + unsigned long len) +{ + if (ctrlc()) + return -EINTR; + + return digest_update(d, data, len); +} + +static int digest_update_from_fd(struct digest *d, int fd, + loff_t start, loff_t size) +{ + unsigned char *buf = xmalloc(PAGE_SIZE); + int ret = 0; + + if (lseek(fd, start, SEEK_SET) != start) { + perror("lseek"); + ret = -errno; + goto out_free; + } + + while (size) { + const ssize_t now = read(fd, buf, PAGE_SIZE); + if (now < 0) { + ret = now; + perror("read"); + goto out_free; + } + + if (!now) + break; + + ret = digest_update_interruptible(d, buf, now); + if (ret) + goto out_free; + + size -= now; + } + +out_free: + free(buf); + return ret; +} + +static int digest_update_from_memory(struct digest *d, + const unsigned char *buf, + loff_t size) +{ + while (size) { + unsigned long now = min_t(typeof(size), PAGE_SIZE, size); + int ret; + + ret = digest_update_interruptible(d, buf, now); + if (ret) + return ret; + + size -= now; + buf += now; + } + + return 0; +} + int digest_file_window(struct digest *d, const char *filename, unsigned char *hash, const unsigned char *sig, - ulong start, ulong size) + loff_t start, loff_t size) { - ulong len = 0; - int fd, now, ret = 0; + int fd, ret; unsigned char *buf; - int flags = 0; ret = digest_init(d); if (ret) @@ -228,63 +289,22 @@ int digest_file_window(struct digest *d, const char *filename, fd = open(filename, O_RDONLY); if (fd < 0) { perror(filename); - return fd; + return -errno; } buf = memmap(fd, PROT_READ); - if (buf == (void *)-1) { - buf = xmalloc(4096); - flags = 1; - } - - if (start > 0) { - if (flags) { - ret = lseek(fd, start, SEEK_SET); - if (ret == -1) { - perror("lseek"); - goto out; - } - } else { - buf += start; - } - } - - while (size) { - now = min((ulong)4096, size); - if (flags) { - now = read(fd, buf, now); - if (now < 0) { - ret = now; - perror("read"); - goto out_free; - } - if (!now) - break; - } - - if (ctrlc()) { - ret = -EINTR; - goto out_free; - } - - ret = digest_update(d, buf, now); - if (ret) - goto out_free; - size -= now; - len += now; + if (buf == MAP_FAILED) + ret = digest_update_from_fd(d, fd, start, size); + else + ret = digest_update_from_memory(d, buf + start, size); - if (!flags) - buf += now; - } + if (ret) + goto out; if (sig) ret = digest_verify(d, sig); else ret = digest_final(d, hash); - -out_free: - if (flags) - free(buf); out: close(fd); @@ -297,12 +317,9 @@ int digest_file(struct digest *d, const char *filename, const unsigned char *sig) { struct stat st; - int ret; - - ret = stat(filename, &st); - if (ret < 0) - return ret; + if (stat(filename, &st)) + return -errno; return digest_file_window(d, filename, hash, sig, 0, st.st_size); } diff --git a/drivers/Kconfig b/drivers/Kconfig index 1e0246da6d..c6c2eb14db 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -1,5 +1,6 @@ menu "Drivers" +source "drivers/base/Kconfig" source "drivers/efi/Kconfig" source "drivers/of/Kconfig" source "drivers/aiodev/Kconfig" @@ -37,5 +38,6 @@ source "drivers/firmware/Kconfig" source "drivers/phy/Kconfig" source "drivers/crypto/Kconfig" source "drivers/memory/Kconfig" +source "drivers/soc/imx/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 767789d541..752fd66242 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_HAB) += hab/ obj-$(CONFIG_CRYPTO_HW) += crypto/ obj-$(CONFIG_AIODEV) += aiodev/ obj-y += memory/ +obj-y += soc/imx/ diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig new file mode 100644 index 0000000000..1e13e5ed9d --- /dev/null +++ b/drivers/base/Kconfig @@ -0,0 +1,3 @@ + +config PM_GENERIC_DOMAINS + bool diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 4bd4217745..6d2cef8e1a 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -2,4 +2,6 @@ obj-y += bus.o obj-y += driver.o obj-y += platform.o obj-y += resource.o -obj-y += regmap/
\ No newline at end of file +obj-y += regmap/ + +obj-$(CONFIG_PM_GENERIC_DOMAINS) += power.o diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 1fd890542e..1fd6bbc014 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -269,7 +269,7 @@ static int device_probe_deferred(void) success = false; if (list_empty(&deferred)) - break; + return 0; list_for_each_entry_safe(dev, tmp, &deferred, active) { list_del(&dev->active); @@ -285,9 +285,6 @@ static int device_probe_deferred(void) } } while (success); - if (list_empty(&deferred)) - return 0; - list_for_each_entry(dev, &deferred, active) dev_err(dev, "probe permanently deferred\n"); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 85bdfb0149..1d3fa2eb44 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -21,9 +21,16 @@ #include <errno.h> #include <init.h> #include <of.h> +#include <pm_domain.h> static int platform_probe(struct device_d *dev) { + int ret; + + ret = genpd_dev_pm_attach(dev); + if (ret < 0) + return ret; + return dev->driver->probe(dev); } diff --git a/drivers/base/power.c b/drivers/base/power.c new file mode 100644 index 0000000000..12674ca7d9 --- /dev/null +++ b/drivers/base/power.c @@ -0,0 +1,249 @@ +#include <common.h> +#include <driver.h> +#include <errno.h> +#include <of.h> + +#include <pm_domain.h> + +#define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE) + +static LIST_HEAD(gpd_list); + +/** + * pm_genpd_init - Initialize a generic I/O PM domain object. + * @genpd: PM domain object to initialize. + * @gov: PM domain governor to associate with the domain (may be NULL). + * @is_off: Initial value of the domain's power_is_off field. + * + * Returns 0 on successful initialization, else a negative error code. + */ +int pm_genpd_init(struct generic_pm_domain *genpd, void *gov, bool is_off) +{ + if (IS_ERR_OR_NULL(genpd)) + return -EINVAL; + + genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE; + + list_add(&genpd->gpd_list_node, &gpd_list); + + return 0; +} +EXPORT_SYMBOL_GPL(pm_genpd_init); + +/** + * struct of_genpd_provider - PM domain provider registration structure + * @link: Entry in global list of PM domain providers + * @node: Pointer to device tree node of PM domain provider + * @xlate: Provider-specific xlate callback mapping a set of specifier cells + * into a PM domain. + * @data: context pointer to be passed into @xlate callback + */ +struct of_genpd_provider { + struct list_head link; + struct device_node *node; + genpd_xlate_t xlate; + void *data; +}; + +/* List of registered PM domain providers. */ +static LIST_HEAD(of_genpd_providers); + +static bool genpd_present(const struct generic_pm_domain *genpd) +{ + const struct generic_pm_domain *gpd; + + if (IS_ERR_OR_NULL(genpd)) + return false; + + list_for_each_entry(gpd, &gpd_list, gpd_list_node) + if (gpd == genpd) + return true; + + return false; +} + +/** + * genpd_xlate_simple() - Xlate function for direct node-domain mapping + * @genpdspec: OF phandle args to map into a PM domain + * @data: xlate function private data - pointer to struct generic_pm_domain + * + * This is a generic xlate function that can be used to model PM domains that + * have their own device tree nodes. The private data of xlate function needs + * to be a valid pointer to struct generic_pm_domain. + */ +static struct generic_pm_domain *genpd_xlate_simple( + struct of_phandle_args *genpdspec, + void *data) +{ + return data; +} + +/** + * genpd_add_provider() - Register a PM domain provider for a node + * @np: Device node pointer associated with the PM domain provider. + * @xlate: Callback for decoding PM domain from phandle arguments. + * @data: Context pointer for @xlate callback. + */ +static int genpd_add_provider(struct device_node *np, genpd_xlate_t xlate, + void *data) +{ + struct of_genpd_provider *cp; + + cp = kzalloc(sizeof(*cp), GFP_KERNEL); + if (!cp) + return -ENOMEM; + + cp->node = np; + cp->data = data; + cp->xlate = xlate; + + list_add(&cp->link, &of_genpd_providers); + pr_debug("Added domain provider from %pOF\n", np); + + return 0; +} + +/** + * of_genpd_add_provider_simple() - Register a simple PM domain provider + * @np: Device node pointer associated with the PM domain provider. + * @genpd: Pointer to PM domain associated with the PM domain provider. + */ +int of_genpd_add_provider_simple(struct device_node *np, + struct generic_pm_domain *genpd) +{ + int ret = -EINVAL; + + if (!np || !genpd) + return -EINVAL; + + if (genpd_present(genpd)) + ret = genpd_add_provider(np, genpd_xlate_simple, genpd); + + return ret; +} +EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple); + +/** + * genpd_get_from_provider() - Look-up PM domain + * @genpdspec: OF phandle args to use for look-up + * + * Looks for a PM domain provider under the node specified by @genpdspec and if + * found, uses xlate function of the provider to map phandle args to a PM + * domain. + * + * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR() + * on failure. + */ +static struct generic_pm_domain *genpd_get_from_provider( + struct of_phandle_args *genpdspec) +{ + struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); + struct of_genpd_provider *provider; + + if (!genpdspec) + return ERR_PTR(-EINVAL); + + /* Check if we have such a provider in our array */ + list_for_each_entry(provider, &of_genpd_providers, link) { + if (provider->node == genpdspec->np) + genpd = provider->xlate(genpdspec, provider->data); + if (!IS_ERR(genpd)) + break; + } + + return genpd; +} + +static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) +{ + if (!genpd->power_on) + return 0; + + return genpd->power_on(genpd); +} + +/** + * genpd_power_on - Restore power to a given PM domain and its masters. + * @genpd: PM domain to power up. + * @depth: nesting count for lockdep. + * + * Restore power to @genpd and all of its masters so that it is possible to + * resume a device belonging to it. + */ +static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) +{ + int ret; + + if (genpd_status_on(genpd)) + return 0; + + ret = _genpd_power_on(genpd, true); + if (ret) + return ret; + + genpd->status = GPD_STATE_ACTIVE; + + return 0; +} + +static int __genpd_dev_pm_attach(struct device_d *dev, struct device_node *np, + unsigned int index, bool power_on) +{ + struct of_phandle_args pd_args; + struct generic_pm_domain *pd; + int ret; + + ret = of_parse_phandle_with_args(np, "power-domains", + "#power-domain-cells", index, &pd_args); + if (ret < 0) + return ret; + + pd = genpd_get_from_provider(&pd_args); + if (IS_ERR(pd)) { + ret = PTR_ERR(pd); + dev_dbg(dev, "%s() failed to find PM domain: %d\n", + __func__, ret); + /* + * Assume that missing genpds are unresolved + * dependency are report them as deferred + */ + return (ret == -ENOENT) ? -EPROBE_DEFER : ret; + } + + dev_dbg(dev, "adding to PM domain %s\n", pd->name); + + if (power_on) + ret = genpd_power_on(pd, 0); + + return ret ?: 1; +} + +/** + * genpd_dev_pm_attach - Attach a device to its PM domain using DT. + * @dev: Device to attach. + * + * Parse device's OF node to find a PM domain specifier. If such is found, + * attaches the device to retrieved pm_domain ops. + * + * Returns 1 on successfully attached PM domain, 0 when the device don't need a + * PM domain or when multiple power-domains exists for it, else a negative error + * code. Note that if a power-domain exists for the device, but it cannot be + * found or turned on, then return -EPROBE_DEFER to ensure that the device is + * not probed and to re-try again later. + */ +int genpd_dev_pm_attach(struct device_d *dev) +{ + if (!dev->device_node) + return 0; + + /* + * Devices with multiple PM domains must be attached separately, as we + * can only attach one PM domain per device. + */ + if (of_count_phandle_with_args(dev->device_node, "power-domains", + "#power-domain-cells") != 1) + return 0; + + return __genpd_dev_pm_attach(dev, dev->device_node, 0, true); +} +EXPORT_SYMBOL_GPL(genpd_dev_pm_attach); diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 202df59762..219982d878 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -6,6 +6,14 @@ config BUS_OMAP_GPMC depends on OMAP_GPMC bool "TI OMAP/AM33xx GPMC support" +config TI_SYSC + depends on ARCH_OMAP + bool "TI sysc interconnect target module driver" + default y + help + Generic driver for Texas Instruments interconnect target module + found on many TI SoCs. + config IMX_WEIM depends on ARCH_IMX bool "i.MX WEIM driver" diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 4b7aa888ab..ba5cee4063 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_BUS_OMAP_GPMC) += omap-gpmc.o obj-$(CONFIG_IMX_WEIM) += imx-weim.o obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o +obj-$(CONFIG_TI_SYSC) += ti-sysc.o diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c new file mode 100644 index 0000000000..af52d839bd --- /dev/null +++ b/drivers/bus/ti-sysc.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 Phytec Messtechnik GmbH, Teresa Remmet <t.remmet@phytec.de> + */ + +#include <common.h> +#include <init.h> +#include <of.h> +#include <linux/err.h> + +static int ti_sysc_probe(struct device_d *dev) +{ + int ret; + + ret = of_platform_populate(dev->device_node, + of_default_bus_match_table, dev); + if (ret) + dev_err(dev, "%s fail to create devices.\n", + dev->device_node->full_name); + return ret; +}; + +static struct of_device_id ti_sysc_dt_ids[] = { + { .compatible = "ti,sysc-omap4",}, + { .compatible = "ti,sysc-omap4-simple",}, + { .compatible = "ti,sysc-omap4-timer",}, + { .compatible = "ti,sysc-omap2",}, + { }, +}; + +static struct driver_d ti_sysc_driver = { + .name = "ti-sysc", + .probe = ti_sysc_probe, + .of_compatible = DRV_OF_COMPAT(ti_sysc_dt_ids), +}; + +postcore_platform_driver(ti_sysc_driver); diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index 432004ec9c..65f71c6fce 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -1053,6 +1053,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv) { struct device_d *dev = priv->dev; struct device_node *np = dev->device_node, *child; + struct device_node *physel; int ret, i = 0; ret = of_property_read_u32(np, "slaves", &priv->num_slaves); @@ -1061,13 +1062,17 @@ static int cpsw_probe_dt(struct cpsw_priv *priv) priv->slaves = xzalloc(sizeof(struct cpsw_slave) * priv->num_slaves); - for_each_child_of_node(np, child) { - if (of_device_is_compatible(child, "ti,am3352-cpsw-phy-sel")) { - ret = cpsw_phy_sel_init(priv, child); - if (ret) - return ret; - } + physel = of_parse_phandle(dev->device_node, "cpsw-phy-sel", 0); + if (!physel) { + physel = of_get_child_by_name(dev->device_node, "cpsw-phy-sel"); + if (!physel) + dev_err(dev, "Phy mode node not found\n"); + } + ret = cpsw_phy_sel_init(priv, physel); + if (ret) + return ret; + for_each_child_of_node(np, child) { if (of_device_is_compatible(child, "ti,davinci_mdio")) { ret = of_pinctrl_select_state_default(child); if (ret) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index ad70967e8c..3c9bca981c 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -291,12 +291,14 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length) if (priv->enh_desc) { desc_p->txrx_status |= DESC_ENH_TXSTS_TXFIRST | DESC_ENH_TXSTS_TXLAST; + desc_p->dmamac_cntl &= ~(DESC_ENH_TXCTRL_SIZE1MASK); desc_p->dmamac_cntl |= (length << DESC_ENH_TXCTRL_SIZE1SHFT) & DESC_ENH_TXCTRL_SIZE1MASK; desc_p->txrx_status &= ~(DESC_ENH_TXSTS_MSK); desc_p->txrx_status |= DESC_ENH_TXSTS_OWNBYDMA; } else { + desc_p->dmamac_cntl &= ~(DESC_TXCTRL_SIZE1MASK); desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | DESC_TXCTRL_TXFIRST; diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 0a9e107c07..52ad3d4cdb 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -2182,6 +2182,7 @@ struct e1000_hw { struct e1000_tx_desc *tx_base; struct e1000_rx_desc *rx_base; unsigned char *packet; + dma_addr_t packet_dma; int tx_tail; int rx_tail, rx_last; diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c index c0f2db552a..36d818b3f3 100644 --- a/drivers/net/e1000/eeprom.c +++ b/drivers/net/e1000/eeprom.c @@ -1000,7 +1000,8 @@ int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, (words > eeprom->word_size - offset) || (words == 0)) { dev_dbg(hw->dev, "\"words\" parameter out of bounds." - "Words = %d, size = %d\n", offset, eeprom->word_size); + "Words = %d, size = %d\n", offset, + (int)eeprom->word_size); return -E1000_ERR_EEPROM; } diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 0ef8fd6231..774e3d030f 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -33,13 +33,10 @@ tested on both gig copper and gig fiber boards #include <init.h> #include <malloc.h> #include <linux/pci.h> +#include <linux/iopoll.h> #include <dma.h> #include "e1000.h" - -static u32 inline virt_to_bus(struct pci_dev *pdev, void *adr) -{ - return (u32)adr; -} +#include <io-64-nonatomic-lo-hi.h> #define PCI_VENDOR_ID_INTEL 0x8086 @@ -3201,21 +3198,24 @@ static int e1000_sw_init(struct eth_device *edev) return E1000_SUCCESS; } -static void fill_rx(struct e1000_hw *hw) +static int e1000_bd_next_index(int index) { - volatile struct e1000_rx_desc *rd; - volatile u32 *bla; - int i; + return (index + 1) % 8; +} - hw->rx_last = hw->rx_tail; - rd = hw->rx_base + hw->rx_tail; - hw->rx_tail = (hw->rx_tail + 1) % 8; +static void e1000_fill_rx(struct e1000_hw *hw) +{ + struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_tail]; - bla = (void *)rd; - for (i = 0; i < 4; i++) - *bla++ = 0; + hw->rx_last = hw->rx_tail; + hw->rx_tail = e1000_bd_next_index(hw->rx_tail); - rd->buffer_addr = cpu_to_le64((unsigned long)hw->packet); + writeq(hw->packet_dma, &rd->buffer_addr); + writew(0, &rd->length); + writew(0, &rd->csum); + writeb(0, &rd->status); + writeb(0, &rd->errors); + writew(0, &rd->special); e1000_write_reg(hw, E1000_RDT, hw->rx_tail); } @@ -3232,9 +3232,10 @@ static void e1000_configure_tx(struct e1000_hw *hw) unsigned long tctl; unsigned long tipg, tarc; uint32_t ipgr1, ipgr2; + const unsigned long tx_base = (unsigned long)hw->tx_base; - e1000_write_reg(hw, E1000_TDBAL, (unsigned long)hw->tx_base); - e1000_write_reg(hw, E1000_TDBAH, 0); + e1000_write_reg(hw, E1000_TDBAL, lower_32_bits(tx_base)); + e1000_write_reg(hw, E1000_TDBAH, upper_32_bits(tx_base)); e1000_write_reg(hw, E1000_TDLEN, 128); @@ -3350,6 +3351,7 @@ static void e1000_setup_rctl(struct e1000_hw *hw) static void e1000_configure_rx(struct e1000_hw *hw) { unsigned long rctl, ctrl_ext; + const unsigned long rx_base = (unsigned long)hw->rx_base; hw->rx_tail = 0; /* make sure receives are disabled while setting up the descriptors */ @@ -3371,8 +3373,8 @@ static void e1000_configure_rx(struct e1000_hw *hw) e1000_write_flush(hw); } /* Setup the Base and Length of the Rx Descriptor Ring */ - e1000_write_reg(hw, E1000_RDBAL, (unsigned long)hw->rx_base); - e1000_write_reg(hw, E1000_RDBAH, 0); + e1000_write_reg(hw, E1000_RDBAL, lower_32_bits(rx_base)); + e1000_write_reg(hw, E1000_RDBAH, upper_32_bits(rx_base)); e1000_write_reg(hw, E1000_RDLEN, 128); @@ -3390,59 +3392,62 @@ static void e1000_configure_rx(struct e1000_hw *hw) e1000_write_reg(hw, E1000_RCTL, rctl); - fill_rx(hw); + e1000_fill_rx(hw); } static int e1000_poll(struct eth_device *edev) { struct e1000_hw *hw = edev->priv; - volatile struct e1000_rx_desc *rd; - uint32_t len; + struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_last]; - rd = hw->rx_base + hw->rx_last; + if (readb(&rd->status) & E1000_RXD_STAT_DD) { + const uint16_t len = readw(&rd->length); - if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) - return 0; + dma_sync_single_for_cpu(hw->packet_dma, len, + DMA_FROM_DEVICE); - len = le32_to_cpu(rd->length); + net_receive(edev, hw->packet, len); - dma_sync_single_for_cpu((unsigned long)hw->packet, len, DMA_FROM_DEVICE); + dma_sync_single_for_device(hw->packet_dma, len, + DMA_FROM_DEVICE); + e1000_fill_rx(hw); + return 1; + } - net_receive(edev, (uchar *)hw->packet, len); - fill_rx(hw); - return 1; + return 0; } static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) { struct e1000_hw *hw = edev->priv; - volatile struct e1000_tx_desc *txp; - uint64_t to; + struct e1000_tx_desc *txp = &hw->tx_base[hw->tx_tail]; + dma_addr_t dma; + uint32_t stat; + int ret; - txp = hw->tx_base + hw->tx_tail; - hw->tx_tail = (hw->tx_tail + 1) % 8; + hw->tx_tail = e1000_bd_next_index(hw->tx_tail); - txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, txpacket)); - txp->lower.data = cpu_to_le32(hw->txd_cmd | length); - txp->upper.data = 0; + writel(hw->txd_cmd | length, &txp->lower.data); + writel(0, &txp->upper.data); - dma_sync_single_for_device((unsigned long)txpacket, length, DMA_TO_DEVICE); + dma = dma_map_single(hw->dev, txpacket, length, DMA_TO_DEVICE); + if (dma_mapping_error(hw->dev, dma)) + return -EFAULT; + writeq(dma, &txp->buffer_addr); e1000_write_reg(hw, E1000_TDT, hw->tx_tail); e1000_write_flush(hw); - to = get_time_ns(); - while (1) { - if (le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD) - break; - if (is_timeout(to, MSECOND)) { - dev_dbg(hw->dev, "e1000: tx timeout\n"); - return -ETIMEDOUT; - } - } + ret = readl_poll_timeout(&txp->upper.data, + stat, stat & E1000_TXD_STAT_DD, + MSECOND / USECOND); + if (ret) + dev_dbg(hw->dev, "e1000: tx timeout\n"); - return 0; + dma_unmap_single(hw->dev, dma, length, DMA_TO_DEVICE); + + return ret; } static void e1000_disable(struct eth_device *edev) @@ -3561,7 +3566,6 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id) hw->tx_base = dma_alloc_coherent(16 * sizeof(*hw->tx_base), DMA_ADDRESS_BROKEN); hw->rx_base = dma_alloc_coherent(16 * sizeof(*hw->rx_base), DMA_ADDRESS_BROKEN); - hw->packet = dma_alloc_coherent(4096, DMA_ADDRESS_BROKEN); edev = &hw->edev; @@ -3570,6 +3574,15 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id) pdev->dev.priv = hw; edev->priv = hw; + hw->packet = dma_alloc(PAGE_SIZE); + if (!hw->packet) + return -ENOMEM; + + hw->packet_dma = dma_map_single(hw->dev, hw->packet, PAGE_SIZE, + DMA_FROM_DEVICE); + if (dma_mapping_error(hw->dev, hw->packet_dma)) + return -EFAULT; + hw->hw_addr = pci_iomap(pdev, 0); /* MAC and Phy settings */ diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 4823b08340..38a29fc83e 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -395,6 +395,13 @@ static void fec_halt(struct eth_device *dev) struct fec_priv *fec = (struct fec_priv *)dev->priv; uint32_t reg; + /* + * Only halt if fec has been started. Otherwise we would have to wait + * for the timeout below. + */ + if (!(readl(fec->regs + FEC_ECNTRL) & FEC_ECNTRL_ETHER_EN)) + return; + /* issue graceful stop command to the FEC transmitter if necessary */ writel(readl(fec->regs + FEC_X_CNTRL) | FEC_ECNTRL_RESET, fec->regs + FEC_X_CNTRL); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ef8969ca8b..d3795d799a 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -207,6 +207,25 @@ struct device_d *of_device_enable_and_register_by_name(const char *name) } EXPORT_SYMBOL(of_device_enable_and_register_by_name); +/** + * of_device_enable_and_register_by_alias - Enable and register device by alias + * @name: alias of the device node + * + * Returns pointer to created platform device, or NULL if a device was not + * registered. Unavailable devices will not get registered. + */ +struct device_d *of_device_enable_and_register_by_alias(const char *alias) +{ + struct device_node *node; + + node = of_find_node_by_alias(NULL, alias); + if (!node) + return NULL; + + return of_device_enable_and_register(node); +} +EXPORT_SYMBOL(of_device_enable_and_register_by_alias); + #ifdef CONFIG_ARM_AMBA static struct device_d *of_amba_device_create(struct device_node *np) { diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 1c45a1c225..44a89d005f 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -41,8 +41,8 @@ config PCI_TEGRA select PCI config PCI_IMX6 - bool "Freescale i.MX6 PCIe controller" - depends on ARCH_IMX6 + bool "Freescale i.MX6/7/8 PCIe controller" + depends on ARCH_IMX6 || ARCH_IMX7 || ARCH_IMX8MQ select PCIE_DW select OF_PCI select PCI diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c index 38e002a1c6..138b4ca8b3 100644 --- a/drivers/pci/pci-imx6.c +++ b/drivers/pci/pci-imx6.c @@ -26,17 +26,37 @@ #include <linux/phy/phy.h> #include <linux/reset.h> #include <linux/sizes.h> +#include <linux/bitfield.h> #include <mfd/imx6q-iomuxc-gpr.h> +#include <mfd/imx7-iomuxc-gpr.h> #include <mach/imx6-regs.h> +#include <mach/imx7-regs.h> +#include <mach/imx8mq-regs.h> #include "pcie-designware.h" +#define IMX8MQ_GPR_PCIE_REF_USE_PAD BIT(9) +#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN BIT(10) +#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE BIT(11) +#define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE GENMASK(11, 8) +#define IMX8MQ_PCIE2_BASE_ADDR 0x33c00000 + #define to_imx6_pcie(x) ((x)->dev->priv) enum imx6_pcie_variants { IMX6Q, IMX6QP, + IMX7D, + IMX8MQ, +}; + +#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) +#define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1) + +struct imx6_pcie_drvdata { + enum imx6_pcie_variants variant; + u32 flags; }; struct imx6_pcie { @@ -46,15 +66,23 @@ struct imx6_pcie { struct clk *pcie_phy; struct clk *pcie; void __iomem *iomuxc_gpr; - enum imx6_pcie_variants variant; + u32 controller_id; + struct reset_control *pciephy_reset; + struct reset_control *apps_reset; u32 tx_deemph_gen1; u32 tx_deemph_gen2_3p5db; u32 tx_deemph_gen2_6db; u32 tx_swing_full; u32 tx_swing_low; int link_gen; + const struct imx6_pcie_drvdata *drvdata; }; +/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ +#define PHY_PLL_LOCK_WAIT_MAX_RETRIES 2000 +#define PHY_PLL_LOCK_WAIT_USLEEP_MIN 50 +#define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200 + /* PCIe Root Complex registers (memory-mapped) */ #define PCIE_RC_LCR 0x7c #define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1 @@ -221,6 +249,9 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) { uint32_t temp; + if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) + return; + pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &temp); temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | PHY_RX_OVRD_IN_LO_RX_PLL_EN); @@ -238,7 +269,12 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) { u32 gpr1; - switch (imx6_pcie->variant) { + switch (imx6_pcie->drvdata->variant) { + case IMX7D: + case IMX8MQ: + reset_control_assert(imx6_pcie->pciephy_reset); + reset_control_assert(imx6_pcie->apps_reset); + break; case IMX6QP: gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); gpr1 |= IMX6Q_GPR1_PCIE_SW_RST; @@ -255,28 +291,74 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) } } +static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) +{ + WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ); + return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14; +} + static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) { - u32 gpr1; + u32 gpr1, gpr1x; + unsigned int offset; - /* power up core phy and enable ref clock */ - gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); - gpr1 &= ~IMX6Q_GPR1_PCIE_TEST_PD; - writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); - /* - * the async reset input need ref clock to sync internally, - * when the ref clock comes after reset, internal synced - * reset time is too short, cannot meet the requirement. - * add one ~10us delay here. - */ - udelay(10); - gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); - gpr1 |= IMX6Q_GPR1_PCIE_REF_CLK_EN; - writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); + switch (imx6_pcie->drvdata->variant) { + case IMX6QP: + case IMX6Q: /* FALLTHROUGH */ + /* power up core phy and enable ref clock */ + gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); + gpr1 &= ~IMX6Q_GPR1_PCIE_TEST_PD; + writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); + /* + * the async reset input need ref clock to sync + * internally, when the ref clock comes after reset, + * internal synced reset time is too short, cannot + * meet the requirement. add one ~10us delay here. + */ + udelay(10); + gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); + gpr1 |= IMX6Q_GPR1_PCIE_REF_CLK_EN; + writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); + break; + case IMX7D: + break; + case IMX8MQ: + offset = imx6_pcie_grp_offset(imx6_pcie); + /* + * Set the over ride low and enabled + * make sure that REF_CLK is turned on. + */ + gpr1x = readl(imx6_pcie->iomuxc_gpr + offset); + gpr1x &= ~IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE; + writel(gpr1x, imx6_pcie->iomuxc_gpr + offset); + + gpr1x = readl(imx6_pcie->iomuxc_gpr + offset); + gpr1x |= IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN; + writel(gpr1x, imx6_pcie->iomuxc_gpr + offset); + break; + } return 0; } +static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie) +{ + u32 val; + unsigned int retries; + struct device_d *dev = imx6_pcie->pci->dev; + + for (retries = 0; retries < PHY_PLL_LOCK_WAIT_MAX_RETRIES; retries++) { + val = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR22); + + if (val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED) + return; + + udelay(PHY_PLL_LOCK_WAIT_USLEEP_MAX); + } + + dev_err(dev, "PCIe PLL lock timeout\n"); +} + static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) { struct device_d *dev = imx6_pcie->pci->dev; @@ -320,7 +402,14 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) /* * Release the PCIe PHY reset here */ - switch (imx6_pcie->variant) { + switch (imx6_pcie->drvdata->variant) { + case IMX8MQ: + reset_control_deassert(imx6_pcie->pciephy_reset); + break; + case IMX7D: + reset_control_deassert(imx6_pcie->pciephy_reset); + imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie); + break; case IMX6QP: gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1); gpr1 &= ~IMX6Q_GPR1_PCIE_SW_RST; @@ -342,43 +431,84 @@ err_pcie_bus: clk_disable(imx6_pcie->pcie_phy); } -static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) +static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie) { - u32 gpr12, gpr8; + unsigned int mask, val; + u32 gpr12; - gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); - gpr12 &= ~IMX6Q_GPR12_PCIE_CTL_2; - writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); + if (imx6_pcie->drvdata->variant == IMX8MQ && + imx6_pcie->controller_id == 1) { + mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE; + val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, + PCI_EXP_TYPE_ROOT_PORT); + } else { + mask = IMX6Q_GPR12_DEVICE_TYPE; + val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, + PCI_EXP_TYPE_ROOT_PORT); + } - /* configure constant input signal to the pcie ctrl and phy */ - gpr12 &= ~IMX6Q_GPR12_DEVICE_TYPE; - gpr12 |= PCI_EXP_TYPE_ROOT_PORT << 12; + gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); + gpr12 &= ~mask; + gpr12 |= val; writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); +} - gpr12 &= ~IMX6Q_GPR12_LOS_LEVEL; - gpr12 |= 9 << 4; - writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); +static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) +{ + u32 gpr12, gpr8, gpr1x; + unsigned int offset; - gpr8 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); - gpr8 &= ~IMX6Q_GPR8_TX_DEEMPH_GEN1; - gpr8 |= imx6_pcie->tx_deemph_gen1 << 0; - writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + switch (imx6_pcie->drvdata->variant) { + case IMX8MQ: + offset = imx6_pcie_grp_offset(imx6_pcie); + /* + * TODO: Currently this code assumes external + * oscillator is being used + */ + gpr1x = readl(imx6_pcie->iomuxc_gpr + offset); + gpr1x |= IMX8MQ_GPR_PCIE_REF_USE_PAD; + writel(gpr1x, imx6_pcie->iomuxc_gpr + offset); + break; + case IMX7D: + gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); + gpr12 &= ~IMX7D_GPR12_PCIE_PHY_REFCLK_SEL; + writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); + break; + case IMX6QP: + case IMX6Q: /* FALLTHROUGH */ + gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); + gpr12 &= ~IMX6Q_GPR12_PCIE_CTL_2; + writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); - gpr8 &= ~IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB; - gpr8 |= imx6_pcie->tx_deemph_gen2_3p5db << 6; - writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + /* configure constant input signal to the pcie ctrl and phy */ + gpr12 &= ~IMX6Q_GPR12_LOS_LEVEL; + gpr12 |= 9 << 4; + writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); - gpr8 &= ~IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB; - gpr8 |= imx6_pcie->tx_deemph_gen2_6db << 12; - writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + gpr8 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + gpr8 &= ~IMX6Q_GPR8_TX_DEEMPH_GEN1; + gpr8 |= imx6_pcie->tx_deemph_gen1 << 0; + writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); - gpr8 &= ~IMX6Q_GPR8_TX_SWING_FULL; - gpr8 |= imx6_pcie->tx_swing_full << 18; - writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + gpr8 &= ~IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB; + gpr8 |= imx6_pcie->tx_deemph_gen2_3p5db << 6; + writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); - gpr8 &= ~IMX6Q_GPR8_TX_SWING_LOW; - gpr8 |= imx6_pcie->tx_swing_low << 25; - writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + gpr8 &= ~IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB; + gpr8 |= imx6_pcie->tx_deemph_gen2_6db << 12; + writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + + gpr8 &= ~IMX6Q_GPR8_TX_SWING_FULL; + gpr8 |= imx6_pcie->tx_swing_full << 18; + writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + + gpr8 &= ~IMX6Q_GPR8_TX_SWING_LOW; + gpr8 |= imx6_pcie->tx_swing_low << 25; + writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8); + break; + } + + imx6_pcie_configure_type(imx6_pcie); } static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie) @@ -404,6 +534,24 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie) return -EINVAL; } +static void imx6_pcie_ltssm_enable(struct device_d *dev) +{ + struct imx6_pcie *imx6_pcie = dev->priv; + u32 gpr12; + + switch (imx6_pcie->drvdata->variant) { + case IMX6Q: + case IMX6QP: + gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); + gpr12 |= IMX6Q_GPR12_PCIE_CTL_2; + writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); + break; + case IMX7D: + case IMX8MQ: + reset_control_deassert(imx6_pcie->apps_reset); + break; + } +} static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) { @@ -411,7 +559,6 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) struct device_d *dev = pci->dev; uint32_t tmp; int ret; - u32 gpr12; /* * Force Gen1 operation when starting the link. In case the link is @@ -423,10 +570,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp); - /* Start LTSSM. */ - gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); - gpr12 |= IMX6Q_GPR12_PCIE_CTL_2; - writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12); + imx6_pcie_ltssm_enable(dev); ret = imx6_pcie_wait_for_link(imx6_pcie); if (ret) @@ -439,30 +583,43 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2; dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp); - } else { - dev_info(dev, "Link: Gen2 disabled\n"); - } - /* - * Start Directed Speed Change so the best possible speed both link - * partners support can be negotiated. - */ - tmp = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); - tmp |= PORT_LOGIC_SPEED_CHANGE; - dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp); - - ret = imx6_pcie_wait_for_speed_change(imx6_pcie); - if (ret) { - dev_err(dev, "Failed to bring link up!\n"); - goto err_reset_phy; - } + /* + * Start Directed Speed Change so the best possible + * speed both link partners support can be negotiated. + */ + tmp = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); + tmp |= PORT_LOGIC_SPEED_CHANGE; + dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp); + + if (imx6_pcie->drvdata->flags & + IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE) { + /* + * On i.MX7, DIRECT_SPEED_CHANGE behaves + * differently from i.MX6 family when no link + * speed transition occurs and we go Gen1 -> + * yep, Gen1. The difference is that, in such + * case, it will not be cleared by HW which + * will cause the following code to report + * false failure. + */ + + ret = imx6_pcie_wait_for_speed_change(imx6_pcie); + if (ret) { + dev_err(dev, "Failed to bring link up!\n"); + goto err_reset_phy; + } + } - /* Make sure link training is finished as well! */ - ret = imx6_pcie_wait_for_link(imx6_pcie); - if (ret) { - dev_err(dev, "Failed to bring link up!\n"); - goto err_reset_phy; - } + /* Make sure link training is finished as well! */ + ret = imx6_pcie_wait_for_link(imx6_pcie); + if (ret) { + dev_err(dev, "Failed to bring link up!\n"); + goto err_reset_phy; + } + } else { + dev_info(dev, "Link: Gen2 disabled\n"); + } tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCSR); dev_info(dev, "Link up, Gen%i\n", (tmp >> 16) & 0xf); @@ -505,14 +662,13 @@ static const struct dw_pcie_host_ops imx6_pcie_host_ops = { .host_init = imx6_pcie_host_init, }; -static int __init imx6_add_pcie_port(struct imx6_pcie *imx6_pcie, - struct device_d *dev) +static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie, + struct device_d *dev) { struct dw_pcie *pci = imx6_pcie->pci; struct pcie_port *pp = &pci->pp; int ret; - pp->root_bus_nr = -1; pp->ops = &imx6_pcie_host_ops; ret = dw_pcie_host_init(pp); @@ -524,7 +680,7 @@ static int __init imx6_add_pcie_port(struct imx6_pcie *imx6_pcie, return 0; } -static int __init imx6_pcie_probe(struct device_d *dev) +static int imx6_pcie_probe(struct device_d *dev) { struct resource *iores; struct dw_pcie *pci; @@ -539,16 +695,13 @@ static int __init imx6_pcie_probe(struct device_d *dev) pci->ops = &dw_pcie_ops; imx6_pcie->pci = pci; - imx6_pcie->variant = - (enum imx6_pcie_variants)of_device_get_match_data(dev); - - iores = dev_request_mem_resource(dev, 0); - if (IS_ERR(iores)) - return PTR_ERR(iores); - pci->dbi_base = IOMEM(iores->start); + imx6_pcie->drvdata = of_device_get_match_data(dev); /* Fetch GPIOs */ imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); + if (imx6_pcie->reset_gpio == -EPROBE_DEFER) + return imx6_pcie->reset_gpio; + if (gpio_is_valid(imx6_pcie->reset_gpio)) { ret = gpio_request_one(imx6_pcie->reset_gpio, GPIOF_OUT_INIT_LOW, "PCIe reset"); @@ -558,6 +711,11 @@ static int __init imx6_pcie_probe(struct device_d *dev) } } + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + pci->dbi_base = IOMEM(iores->start); + /* Fetch clocks */ imx6_pcie->pcie_phy = clk_get(dev, "pcie_phy"); if (IS_ERR(imx6_pcie->pcie_phy)) { @@ -577,8 +735,35 @@ static int __init imx6_pcie_probe(struct device_d *dev) return PTR_ERR(imx6_pcie->pcie); } - /* Grab GPR config register range */ - imx6_pcie->iomuxc_gpr = IOMEM(MX6_IOMUXC_BASE_ADDR); + + switch (imx6_pcie->drvdata->variant) { + case IMX8MQ: + imx6_pcie->iomuxc_gpr = IOMEM(MX8MQ_IOMUXC_GPR_BASE_ADDR); + if (iores->start == IMX8MQ_PCIE2_BASE_ADDR) + imx6_pcie->controller_id = 1; + + goto imx7d_init; + case IMX7D: + imx6_pcie->iomuxc_gpr = IOMEM(MX7_IOMUXC_GPR_BASE_ADDR); + imx7d_init: + imx6_pcie->pciephy_reset = reset_control_get(dev, "pciephy"); + if (IS_ERR(imx6_pcie->pciephy_reset)) { + dev_err(dev, "Failed to get PCIEPHY reset control\n"); + return PTR_ERR(imx6_pcie->pciephy_reset); + } + + imx6_pcie->apps_reset = reset_control_get(dev, "apps"); + if (IS_ERR(imx6_pcie->apps_reset)) { + dev_err(dev, "Failed to get PCIE APPS reset control\n"); + return PTR_ERR(imx6_pcie->apps_reset); + } + break; + default: + /* Grab GPR config register range */ + imx6_pcie->iomuxc_gpr = IOMEM(MX6_IOMUXC_BASE_ADDR); + break; + } + /* Grab PCIe PHY Tx Settings */ if (of_property_read_u32(np, "fsl,tx-deemph-gen1", @@ -620,7 +805,7 @@ static void imx6_pcie_remove(struct device_d *dev) { struct imx6_pcie *imx6_pcie = dev->priv; - if (imx6_pcie->variant == IMX6Q) { + if (imx6_pcie->drvdata->variant == IMX6Q) { /* * If the bootloader already enabled the link we need * some special handling to get the core back into a @@ -650,9 +835,30 @@ static void imx6_pcie_remove(struct device_d *dev) imx6_pcie_assert_core_reset(imx6_pcie); } +static const struct imx6_pcie_drvdata drvdata[] = { + [IMX6Q] = { + .variant = IMX6Q, + .flags = IMX6_PCIE_FLAG_IMX6_PHY | + IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, + }, + [IMX6QP] = { + .variant = IMX6QP, + .flags = IMX6_PCIE_FLAG_IMX6_PHY | + IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, + }, + [IMX7D] = { + .variant = IMX7D, + }, + [IMX8MQ] = { + .variant = IMX8MQ, + }, +}; + static struct of_device_id imx6_pcie_of_match[] = { - { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, }, - { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, }, + { .compatible = "fsl,imx6q-pcie", .data = &drvdata[IMX6Q], }, + { .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], }, + { .compatible = "fsl,imx7d-pcie", .data = &drvdata[IMX7D], }, + { .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], } , {}, }; diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c index 6cc4b93a31..dc38cdc8f6 100644 --- a/drivers/pci/pcie-designware-host.c +++ b/drivers/pci/pcie-designware-host.c @@ -150,15 +150,15 @@ int __init dw_pcie_host_init(struct pcie_port *pp) } if (!pci->dbi_base) - pci->dbi_base = (void __force *)pp->cfg.start; + pci->dbi_base = IOMEM(pp->cfg.start); pp->mem_base = pp->mem.start; if (!pp->va_cfg0_base) - pp->va_cfg0_base = (void __force *)(u32)pp->cfg0_base; + pp->va_cfg0_base = IOMEM((unsigned long)pp->cfg0_base); if (!pp->va_cfg1_base) - pp->va_cfg1_base = (void __force *)(u32)pp->cfg1_base; + pp->va_cfg1_base = IOMEM((unsigned long)pp->cfg1_base); ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport); if (ret) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 92db8dc0e0..c734ef5ef9 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -21,4 +21,12 @@ config REGULATOR_PFUZE depends on I2C depends on ARCH_IMX6 +config REGULATOR_ANATOP + tristate "Freescale i.MX on-chip ANATOP LDO regulators" + depends on MFD_SYSCON + help + Say y here to support Freescale i.MX on-chip ANATOP LDOs + regulators. It is recommended that this option be + enabled on i.MX6 platform. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index ff5daf9a7d..b2fc5b79b6 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -1,4 +1,5 @@ -obj-$(CONFIG_REGULATOR) += core.o +obj-$(CONFIG_REGULATOR) += core.o helpers.o obj-$(CONFIG_REGULATOR_FIXED) += fixed.o obj-$(CONFIG_REGULATOR_BCM283X) += bcm2835.o -obj-$(CONFIG_REGULATOR_PFUZE) += pfuze.o
\ No newline at end of file +obj-$(CONFIG_REGULATOR_PFUZE) += pfuze.o +obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
\ No newline at end of file diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c new file mode 100644 index 0000000000..7ec9446a0a --- /dev/null +++ b/drivers/regulator/anatop-regulator.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <common.h> +#include <init.h> +#include <mfd/syscon.h> +#include <regmap.h> +#include <regulator.h> + +struct anatop_regulator { + u32 control_reg; + struct regmap *anatop; + int vol_bit_shift; + int vol_bit_width; + u32 delay_reg; + int delay_bit_shift; + int delay_bit_width; + int min_bit_val; + int min_voltage; + int max_voltage; + + struct regulator_dev rdev; + struct regulator_desc rdesc; + + bool bypass; + int sel; +}; + +static struct regulator_ops anatop_rops = { + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +static int anatop_regulator_probe(struct device_d *dev) +{ + struct device_node *np = dev->device_node; + struct device_node *anatop_np; + struct regulator_desc *rdesc; + struct regulator_dev *rdev; + struct anatop_regulator *sreg; + int ret = 0; + + sreg = xzalloc(sizeof(*sreg)); + rdesc = &sreg->rdesc; + rdev = &sreg->rdev; + + anatop_np = of_get_parent(np); + if (!anatop_np) + return -ENODEV; + + rdev->desc = rdesc; + rdev->regmap = syscon_node_to_regmap(anatop_np); + if (IS_ERR(rdev->regmap)) + return PTR_ERR(rdev->regmap); + + ret = of_property_read_u32(np, "anatop-reg-offset", + &sreg->control_reg); + if (ret) { + dev_err(dev, "no anatop-reg-offset property set\n"); + return ret; + } + ret = of_property_read_u32(np, "anatop-vol-bit-width", + &sreg->vol_bit_width); + if (ret) { + dev_err(dev, "no anatop-vol-bit-width property set\n"); + return ret; + } + ret = of_property_read_u32(np, "anatop-vol-bit-shift", + &sreg->vol_bit_shift); + if (ret) { + dev_err(dev, "no anatop-vol-bit-shift property set\n"); + return ret; + } + ret = of_property_read_u32(np, "anatop-min-bit-val", + &sreg->min_bit_val); + if (ret) { + dev_err(dev, "no anatop-min-bit-val property set\n"); + return ret; + } + ret = of_property_read_u32(np, "anatop-min-voltage", + &sreg->min_voltage); + if (ret) { + dev_err(dev, "no anatop-min-voltage property set\n"); + return ret; + } + ret = of_property_read_u32(np, "anatop-max-voltage", + &sreg->max_voltage); + if (ret) { + dev_err(dev, "no anatop-max-voltage property set\n"); + return ret; + } + + /* read LDO ramp up setting, only for core reg */ + of_property_read_u32(np, "anatop-delay-reg-offset", + &sreg->delay_reg); + of_property_read_u32(np, "anatop-delay-bit-width", + &sreg->delay_bit_width); + of_property_read_u32(np, "anatop-delay-bit-shift", + &sreg->delay_bit_shift); + + rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1 + + sreg->min_bit_val; + rdesc->min_uV = sreg->min_voltage; + rdesc->uV_step = 25000; + rdesc->linear_min_sel = sreg->min_bit_val; + rdesc->vsel_reg = sreg->control_reg; + rdesc->vsel_mask = GENMASK(sreg->vol_bit_width + sreg->vol_bit_shift, + sreg->vol_bit_shift); + + /* Only core regulators have the ramp up delay configuration. */ + if (sreg->control_reg && sreg->delay_bit_width) { + free(sreg); + /* FIXME: This case is not supported */ + return 0; + } else { + u32 enable_bit; + + rdesc->ops = &anatop_rops; + + if (!of_property_read_u32(np, "anatop-enable-bit", + &enable_bit)) { + anatop_rops.enable = regulator_enable_regmap; + anatop_rops.disable = regulator_disable_regmap; + anatop_rops.is_enabled = regulator_is_enabled_regmap; + + rdesc->enable_reg = sreg->control_reg; + rdesc->enable_mask = BIT(enable_bit); + } + } + + return of_regulator_register(rdev, dev->device_node); +} + +static const struct of_device_id of_anatop_regulator_match_tbl[] = { + { .compatible = "fsl,anatop-regulator", }, + { /* end */ } +}; + +static struct driver_d anatop_regulator_driver = { + .name = "anatop_regulator", + .probe = anatop_regulator_probe, + .of_compatible = DRV_OF_COMPAT(of_anatop_regulator_match_tbl), +}; +device_platform_driver(anatop_regulator_driver); + diff --git a/drivers/regulator/bcm2835.c b/drivers/regulator/bcm2835.c index 0ada05db16..ea7cf7fe1e 100644 --- a/drivers/regulator/bcm2835.c +++ b/drivers/regulator/bcm2835.c @@ -24,6 +24,7 @@ static struct regulator_bcm2835 { struct device_d *dev; struct regulator_dev rdev; + struct regulator_desc rdesc; } regs[] = { REG_DEV(BCM2835_MBOX_POWER_DEVID_SDHCI, "bcm2835_mci0"), REG_DEV(BCM2835_MBOX_POWER_DEVID_UART0, "uart0-pl0110"), @@ -108,7 +109,7 @@ static int regulator_bcm2835_is_enabled(struct regulator_dev *rdev) return msg_pwr->get_power_state.body.resp.state; } -static struct regulator_ops bcm2835_ops = { +const static struct regulator_ops bcm2835_ops = { .enable = regulator_bcm2835_enable, .disable = regulator_bcm2835_disable, .is_enabled = regulator_bcm2835_is_enabled, @@ -122,7 +123,8 @@ static int regulator_bcm2835_probe(struct device_d *dev) for (i = 0; i < ARRAY_SIZE(regs); i++) { rb = ®s[i]; - rb->rdev.ops = &bcm2835_ops; + rb->rdesc.ops = &bcm2835_ops; + rb->rdev.desc = &rb->rdesc; rb->dev = dev; ret = dev_regulator_register(&rb->rdev, rb->devname, NULL); diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 39df980dcb..4ca035ae94 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -43,6 +43,15 @@ struct regulator { struct device_d *dev; }; +static int regulator_map_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV) +{ + if (rdev->desc->ops->list_voltage == regulator_list_voltage_linear) + return regulator_map_voltage_linear(rdev, min_uV, max_uV); + + return -ENOSYS; +} + static int regulator_enable_internal(struct regulator_internal *ri) { int ret; @@ -52,10 +61,10 @@ static int regulator_enable_internal(struct regulator_internal *ri) return 0; } - if (!ri->rdev->ops->enable) + if (!ri->rdev->desc->ops->enable) return -ENOSYS; - ret = ri->rdev->ops->enable(ri->rdev); + ret = ri->rdev->desc->ops->enable(ri->rdev); if (ret) return ret; @@ -74,10 +83,10 @@ static int regulator_disable_internal(struct regulator_internal *ri) if (!ri->enable_count) return -EINVAL; - if (!ri->rdev->ops->disable) + if (!ri->rdev->desc->ops->disable) return -ENOSYS; - ret = ri->rdev->ops->disable(ri->rdev); + ret = ri->rdev->desc->ops->disable(ri->rdev); if (ret) return ret; @@ -86,6 +95,33 @@ static int regulator_disable_internal(struct regulator_internal *ri) return 0; } +static int regulator_set_voltage_internal(struct regulator_internal *ri, + int min_uV, int max_uV) +{ + struct regulator_dev *rdev = ri->rdev; + const struct regulator_ops *ops = rdev->desc->ops; + unsigned int selector; + int best_val = 0; + int ret; + + if (ops->set_voltage_sel) { + ret = regulator_map_voltage(rdev, min_uV, max_uV); + if (ret >= 0) { + best_val = ops->list_voltage(rdev, ret); + if (min_uV <= best_val && max_uV >= best_val) { + selector = ret; + ret = ops->set_voltage_sel(rdev, selector); + } else { + ret = -EINVAL; + } + } + + return ret; + } + + return -ENOSYS; +} + static struct regulator_internal * __regulator_register(struct regulator_dev *rd, const char *name) { struct regulator_internal *ri; @@ -191,7 +227,12 @@ static struct regulator_internal *of_regulator_get(struct device_d *dev, const c } } - ri = ERR_PTR(-ENODEV); + /* + * It is possible that regulator we are looking for will be + * added in future initcalls, so, instead of reporting a + * complete failure report probe deferral + */ + ri = ERR_PTR(-EPROBE_DEFER); out: free(propname); @@ -320,6 +361,14 @@ int regulator_disable(struct regulator *r) return regulator_disable_internal(r->ri); } +int regulator_set_voltage(struct regulator *r, int min_uV, int max_uV) +{ + if (!r) + return 0; + + return regulator_set_voltage_internal(r->ri, min_uV, max_uV); +} + static void regulator_print_one(struct regulator_internal *ri) { struct regulator *r; diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 87554d22e3..cb5d785817 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -29,6 +29,7 @@ struct regulator_fixed { int active_low; int always_on; struct regulator_dev rdev; + struct regulator_desc rdesc; }; static int regulator_fixed_enable(struct regulator_dev *rdev) @@ -54,7 +55,7 @@ static int regulator_fixed_disable(struct regulator_dev *rdev) return gpio_direction_output(fix->gpio, fix->active_low); } -static struct regulator_ops fixed_ops = { +const static struct regulator_ops fixed_ops = { .enable = regulator_fixed_enable, .disable = regulator_fixed_disable, }; @@ -82,7 +83,8 @@ static int regulator_fixed_probe(struct device_d *dev) fix->active_low = 1; } - fix->rdev.ops = &fixed_ops; + fix->rdesc.ops = &fixed_ops; + fix->rdev.desc = &fix->rdesc; if (of_find_property(dev->device_node, "regulator-always-on", NULL)) { fix->always_on = 1; diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c new file mode 100644 index 0000000000..f22d21b35d --- /dev/null +++ b/drivers/regulator/helpers.c @@ -0,0 +1,186 @@ +#include <common.h> +#include <regmap.h> +#include <regulator.h> + +/** + * regulator_is_enabled_regmap - standard is_enabled() for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their descriptor and then use + * this as their is_enabled operation, saving some code. + */ +int regulator_is_enabled_regmap(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); + if (ret != 0) + return ret; + + val &= rdev->desc->enable_mask; + + if (rdev->desc->enable_is_inverted) { + if (rdev->desc->enable_val) + return val != rdev->desc->enable_val; + return val == 0; + } else { + if (rdev->desc->enable_val) + return val == rdev->desc->enable_val; + return val != 0; + } +} +EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); + +/** + * regulator_enable_regmap - standard enable() for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their descriptor and then use + * this as their enable() operation, saving some code. + */ +int regulator_enable_regmap(struct regulator_dev *rdev) +{ + unsigned int val; + + if (rdev->desc->enable_is_inverted) { + val = rdev->desc->disable_val; + } else { + val = rdev->desc->enable_val; + if (!val) + val = rdev->desc->enable_mask; + } + + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, val); +} +EXPORT_SYMBOL_GPL(regulator_enable_regmap); + +/** + * regulator_disable_regmap - standard disable() for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their descriptor and then use + * this as their disable() operation, saving some code. + */ +int regulator_disable_regmap(struct regulator_dev *rdev) +{ + unsigned int val; + + if (rdev->desc->enable_is_inverted) { + val = rdev->desc->enable_val; + if (!val) + val = rdev->desc->enable_mask; + } else { + val = rdev->desc->disable_val; + } + + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, val); +} +EXPORT_SYMBOL_GPL(regulator_disable_regmap); + +/** + * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users + * + * @rdev: regulator to operate on + * @sel: Selector to set + * + * Regulators that use regmap for their register I/O can set the + * vsel_reg and vsel_mask fields in their descriptor and then use this + * as their set_voltage_vsel operation, saving some code. + */ +int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) +{ + int ret; + + sel <<= ffs(rdev->desc->vsel_mask) - 1; + + ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, + rdev->desc->vsel_mask, sel); + if (ret) + return ret; + + if (rdev->desc->apply_bit) + ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg, + rdev->desc->apply_bit, + rdev->desc->apply_bit); + return ret; +} +EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap); + +/** + * regulator_map_voltage_linear - map_voltage() for simple linear mappings + * + * @rdev: Regulator to operate on + * @min_uV: Lower bound for voltage + * @max_uV: Upper bound for voltage + * + * Drivers providing min_uV and uV_step in their regulator_desc can + * use this as their map_voltage() operation. + */ +int regulator_map_voltage_linear(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + int ret, voltage; + + /* Allow uV_step to be 0 for fixed voltage */ + if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) { + if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV) + return 0; + else + return -EINVAL; + } + + if (!rdev->desc->uV_step) { + BUG_ON(!rdev->desc->uV_step); + return -EINVAL; + } + + if (min_uV < rdev->desc->min_uV) + min_uV = rdev->desc->min_uV; + + ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); + if (ret < 0) + return ret; + + ret += rdev->desc->linear_min_sel; + + /* Map back into a voltage to verify we're still in bounds */ + voltage = rdev->desc->ops->list_voltage(rdev, ret); + if (voltage < min_uV || voltage > max_uV) + return -EINVAL; + + return ret; +} +EXPORT_SYMBOL_GPL(regulator_map_voltage_linear); + +/** + * regulator_list_voltage_linear - List voltages with simple calculation + * + * @rdev: Regulator device + * @selector: Selector to convert into a voltage + * + * Regulators with a simple linear mapping between voltages and + * selectors can set min_uV and uV_step in the regulator descriptor + * and then use this function as their list_voltage() operation, + */ +int regulator_list_voltage_linear(struct regulator_dev *rdev, + unsigned int selector) +{ + if (selector >= rdev->desc->n_voltages) + return -EINVAL; + if (selector < rdev->desc->linear_min_sel) + return 0; + + selector -= rdev->desc->linear_min_sel; + + return rdev->desc->min_uV + (rdev->desc->uV_step * selector); +} +EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index c9d04f7978..caf1dc9acb 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -11,3 +11,14 @@ menuconfig RESET_CONTROLLER via GPIOs or SoC-internal reset controller modules. If unsure, say no. + +if RESET_CONTROLLER + +config RESET_IMX7 + bool "i.MX7 Reset Driver" + default SOC_IMX7D + select MFD_SYSCON + help + This enables the reset controller driver for i.MX7 SoCs. + +endif diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 52b10cd480..0b55caa204 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_RESET_CONTROLLER) += core.o obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o +obj-$(CONFIG_RESET_IMX7) += reset-imx7.o diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 59f75ca475..99b9c80655 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -147,8 +147,8 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); * * Use of id names is optional. */ -struct reset_control *of_reset_control_get(struct device_node *node, - const char *id) +static struct reset_control *of_reset_control_get(struct device_node *node, + const char *id) { struct reset_control *rstc = ERR_PTR(-ENODEV); struct reset_controller_dev *r, *rcdev; @@ -194,9 +194,9 @@ struct reset_control *of_reset_control_get(struct device_node *node, return rstc; } -EXPORT_SYMBOL_GPL(of_reset_control_get); -struct reset_control *gpio_reset_control_get(struct device_d *dev, const char *id) +static struct reset_control * +gpio_reset_control_get(struct device_d *dev, const char *id) { struct reset_control *rc; int gpio; diff --git a/drivers/reset/reset-imx7.c b/drivers/reset/reset-imx7.c new file mode 100644 index 0000000000..9d4344a94c --- /dev/null +++ b/drivers/reset/reset-imx7.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2017, Impinj, Inc. + * + * i.MX7 System Reset Controller (SRC) driver + * + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <dt-bindings/reset/imx7-reset.h> +#include <dt-bindings/reset/imx8mq-reset.h> +#include <init.h> +#include <linux/err.h> +#include <linux/reset-controller.h> +#include <mfd/syscon.h> +#include <regmap.h> +#include <of_device.h> + +struct imx7_src_signal { + unsigned int offset, bit; +}; + +struct imx7_src_variant { + const struct imx7_src_signal *signals; + unsigned int signals_num; + struct reset_control_ops ops; +}; + +struct imx7_src { + struct reset_controller_dev rcdev; + struct regmap *regmap; + const struct imx7_src_signal *signals; +}; + +enum imx7_src_registers { + SRC_A7RCR0 = 0x0004, + SRC_M4RCR = 0x000c, + SRC_ERCR = 0x0014, + SRC_HSICPHY_RCR = 0x001c, + SRC_USBOPHY1_RCR = 0x0020, + SRC_USBOPHY2_RCR = 0x0024, + SRC_MIPIPHY_RCR = 0x0028, + SRC_PCIEPHY_RCR = 0x002c, + SRC_DDRC_RCR = 0x1000, +}; + +static int imx7_reset_update(struct imx7_src *imx7src, + unsigned long id, unsigned int value) +{ + const struct imx7_src_signal *signal = &imx7src->signals[id]; + + return regmap_update_bits(imx7src->regmap, + signal->offset, signal->bit, value); +} + +static const struct imx7_src_signal imx7_src_signals[IMX7_RESET_NUM] = { + [IMX7_RESET_A7_CORE_POR_RESET0] = { SRC_A7RCR0, BIT(0) }, + [IMX7_RESET_A7_CORE_POR_RESET1] = { SRC_A7RCR0, BIT(1) }, + [IMX7_RESET_A7_CORE_RESET0] = { SRC_A7RCR0, BIT(4) }, + [IMX7_RESET_A7_CORE_RESET1] = { SRC_A7RCR0, BIT(5) }, + [IMX7_RESET_A7_DBG_RESET0] = { SRC_A7RCR0, BIT(8) }, + [IMX7_RESET_A7_DBG_RESET1] = { SRC_A7RCR0, BIT(9) }, + [IMX7_RESET_A7_ETM_RESET0] = { SRC_A7RCR0, BIT(12) }, + [IMX7_RESET_A7_ETM_RESET1] = { SRC_A7RCR0, BIT(13) }, + [IMX7_RESET_A7_SOC_DBG_RESET] = { SRC_A7RCR0, BIT(20) }, + [IMX7_RESET_A7_L2RESET] = { SRC_A7RCR0, BIT(21) }, + [IMX7_RESET_SW_M4C_RST] = { SRC_M4RCR, BIT(1) }, + [IMX7_RESET_SW_M4P_RST] = { SRC_M4RCR, BIT(2) }, + [IMX7_RESET_EIM_RST] = { SRC_ERCR, BIT(0) }, + [IMX7_RESET_HSICPHY_PORT_RST] = { SRC_HSICPHY_RCR, BIT(1) }, + [IMX7_RESET_USBPHY1_POR] = { SRC_USBOPHY1_RCR, BIT(0) }, + [IMX7_RESET_USBPHY1_PORT_RST] = { SRC_USBOPHY1_RCR, BIT(1) }, + [IMX7_RESET_USBPHY2_POR] = { SRC_USBOPHY2_RCR, BIT(0) }, + [IMX7_RESET_USBPHY2_PORT_RST] = { SRC_USBOPHY2_RCR, BIT(1) }, + [IMX7_RESET_MIPI_PHY_MRST] = { SRC_MIPIPHY_RCR, BIT(1) }, + [IMX7_RESET_MIPI_PHY_SRST] = { SRC_MIPIPHY_RCR, BIT(2) }, + [IMX7_RESET_PCIEPHY] = { SRC_PCIEPHY_RCR, BIT(2) | BIT(1) }, + [IMX7_RESET_PCIEPHY_PERST] = { SRC_PCIEPHY_RCR, BIT(3) }, + [IMX7_RESET_PCIE_CTRL_APPS_EN] = { SRC_PCIEPHY_RCR, BIT(6) }, + [IMX7_RESET_DDRC_PRST] = { SRC_DDRC_RCR, BIT(0) }, + [IMX7_RESET_DDRC_CORE_RST] = { SRC_DDRC_RCR, BIT(1) }, +}; + +static struct imx7_src *to_imx7_src(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct imx7_src, rcdev); +} + +static int imx7_reset_set(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct imx7_src *imx7src = to_imx7_src(rcdev); + const unsigned int bit = imx7src->signals[id].bit; + unsigned int value = assert ? bit : 0; + + switch (id) { + case IMX7_RESET_PCIEPHY: + /* + * wait for more than 10us to release phy g_rst and + * btnrst + */ + if (!assert) + udelay(10); + break; + + case IMX7_RESET_PCIE_CTRL_APPS_EN: + value = assert ? 0 : bit; + break; + } + + return imx7_reset_update(imx7src, id, value); +} + +static int imx7_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return imx7_reset_set(rcdev, id, true); +} + +static int imx7_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return imx7_reset_set(rcdev, id, false); +} + +static const struct imx7_src_variant variant_imx7 = { + .signals = imx7_src_signals, + .signals_num = ARRAY_SIZE(imx7_src_signals), + .ops = { + .assert = imx7_reset_assert, + .deassert = imx7_reset_deassert, + }, +}; + +enum imx8mq_src_registers { + SRC_A53RCR0 = 0x0004, + SRC_HDMI_RCR = 0x0030, + SRC_DISP_RCR = 0x0034, + SRC_GPU_RCR = 0x0040, + SRC_VPU_RCR = 0x0044, + SRC_PCIE2_RCR = 0x0048, + SRC_MIPIPHY1_RCR = 0x004c, + SRC_MIPIPHY2_RCR = 0x0050, + SRC_DDRC2_RCR = 0x1004, +}; + +static const struct imx7_src_signal imx8mq_src_signals[IMX8MQ_RESET_NUM] = { + [IMX8MQ_RESET_A53_CORE_POR_RESET0] = { SRC_A53RCR0, BIT(0) }, + [IMX8MQ_RESET_A53_CORE_POR_RESET1] = { SRC_A53RCR0, BIT(1) }, + [IMX8MQ_RESET_A53_CORE_POR_RESET2] = { SRC_A53RCR0, BIT(2) }, + [IMX8MQ_RESET_A53_CORE_POR_RESET3] = { SRC_A53RCR0, BIT(3) }, + [IMX8MQ_RESET_A53_CORE_RESET0] = { SRC_A53RCR0, BIT(4) }, + [IMX8MQ_RESET_A53_CORE_RESET1] = { SRC_A53RCR0, BIT(5) }, + [IMX8MQ_RESET_A53_CORE_RESET2] = { SRC_A53RCR0, BIT(6) }, + [IMX8MQ_RESET_A53_CORE_RESET3] = { SRC_A53RCR0, BIT(7) }, + [IMX8MQ_RESET_A53_DBG_RESET0] = { SRC_A53RCR0, BIT(8) }, + [IMX8MQ_RESET_A53_DBG_RESET1] = { SRC_A53RCR0, BIT(9) }, + [IMX8MQ_RESET_A53_DBG_RESET2] = { SRC_A53RCR0, BIT(10) }, + [IMX8MQ_RESET_A53_DBG_RESET3] = { SRC_A53RCR0, BIT(11) }, + [IMX8MQ_RESET_A53_ETM_RESET0] = { SRC_A53RCR0, BIT(12) }, + [IMX8MQ_RESET_A53_ETM_RESET1] = { SRC_A53RCR0, BIT(13) }, + [IMX8MQ_RESET_A53_ETM_RESET2] = { SRC_A53RCR0, BIT(14) }, + [IMX8MQ_RESET_A53_ETM_RESET3] = { SRC_A53RCR0, BIT(15) }, + [IMX8MQ_RESET_A53_SOC_DBG_RESET] = { SRC_A53RCR0, BIT(20) }, + [IMX8MQ_RESET_A53_L2RESET] = { SRC_A53RCR0, BIT(21) }, + [IMX8MQ_RESET_SW_NON_SCLR_M4C_RST] = { SRC_M4RCR, BIT(0) }, + [IMX8MQ_RESET_OTG1_PHY_RESET] = { SRC_USBOPHY1_RCR, BIT(0) }, + [IMX8MQ_RESET_OTG2_PHY_RESET] = { SRC_USBOPHY2_RCR, BIT(0) }, + [IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N] = { SRC_MIPIPHY_RCR, BIT(1) }, + [IMX8MQ_RESET_MIPI_DSI_RESET_N] = { SRC_MIPIPHY_RCR, BIT(2) }, + [IMX8MQ_RESET_MIPI_DIS_DPI_RESET_N] = { SRC_MIPIPHY_RCR, BIT(3) }, + [IMX8MQ_RESET_MIPI_DIS_ESC_RESET_N] = { SRC_MIPIPHY_RCR, BIT(4) }, + [IMX8MQ_RESET_MIPI_DIS_PCLK_RESET_N] = { SRC_MIPIPHY_RCR, BIT(5) }, + [IMX8MQ_RESET_PCIEPHY] = { SRC_PCIEPHY_RCR, + BIT(2) | BIT(1) }, + [IMX8MQ_RESET_PCIEPHY_PERST] = { SRC_PCIEPHY_RCR, BIT(3) }, + [IMX8MQ_RESET_PCIE_CTRL_APPS_EN] = { SRC_PCIEPHY_RCR, BIT(6) }, + [IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF] = { SRC_PCIEPHY_RCR, BIT(11) }, + [IMX8MQ_RESET_HDMI_PHY_APB_RESET] = { SRC_HDMI_RCR, BIT(0) }, + [IMX8MQ_RESET_DISP_RESET] = { SRC_DISP_RCR, BIT(0) }, + [IMX8MQ_RESET_GPU_RESET] = { SRC_GPU_RCR, BIT(0) }, + [IMX8MQ_RESET_VPU_RESET] = { SRC_VPU_RCR, BIT(0) }, + [IMX8MQ_RESET_PCIEPHY2] = { SRC_PCIE2_RCR, + BIT(2) | BIT(1) }, + [IMX8MQ_RESET_PCIEPHY2_PERST] = { SRC_PCIE2_RCR, BIT(3) }, + [IMX8MQ_RESET_PCIE2_CTRL_APPS_EN] = { SRC_PCIE2_RCR, BIT(6) }, + [IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF] = { SRC_PCIE2_RCR, BIT(11) }, + [IMX8MQ_RESET_MIPI_CSI1_CORE_RESET] = { SRC_MIPIPHY1_RCR, BIT(0) }, + [IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET] = { SRC_MIPIPHY1_RCR, BIT(1) }, + [IMX8MQ_RESET_MIPI_CSI1_ESC_RESET] = { SRC_MIPIPHY1_RCR, BIT(2) }, + [IMX8MQ_RESET_MIPI_CSI2_CORE_RESET] = { SRC_MIPIPHY2_RCR, BIT(0) }, + [IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET] = { SRC_MIPIPHY2_RCR, BIT(1) }, + [IMX8MQ_RESET_MIPI_CSI2_ESC_RESET] = { SRC_MIPIPHY2_RCR, BIT(2) }, + [IMX8MQ_RESET_DDRC1_PRST] = { SRC_DDRC_RCR, BIT(0) }, + [IMX8MQ_RESET_DDRC1_CORE_RESET] = { SRC_DDRC_RCR, BIT(1) }, + [IMX8MQ_RESET_DDRC1_PHY_RESET] = { SRC_DDRC_RCR, BIT(2) }, + [IMX8MQ_RESET_DDRC2_PHY_RESET] = { SRC_DDRC2_RCR, BIT(0) }, + [IMX8MQ_RESET_DDRC2_CORE_RESET] = { SRC_DDRC2_RCR, BIT(1) }, + [IMX8MQ_RESET_DDRC2_PRST] = { SRC_DDRC2_RCR, BIT(2) }, +}; + +static int imx8mq_reset_set(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct imx7_src *imx7src = to_imx7_src(rcdev); + const unsigned int bit = imx7src->signals[id].bit; + unsigned int value = assert ? bit : 0; + + switch (id) { + case IMX8MQ_RESET_PCIEPHY: + case IMX8MQ_RESET_PCIEPHY2: /* fallthrough */ + /* + * wait for more than 10us to release phy g_rst and + * btnrst + */ + if (!assert) + udelay(10); + break; + + case IMX8MQ_RESET_PCIE_CTRL_APPS_EN: + case IMX8MQ_RESET_PCIE2_CTRL_APPS_EN: /* fallthrough */ + case IMX8MQ_RESET_MIPI_DIS_PCLK_RESET_N: /* fallthrough */ + case IMX8MQ_RESET_MIPI_DIS_ESC_RESET_N: /* fallthrough */ + case IMX8MQ_RESET_MIPI_DIS_DPI_RESET_N: /* fallthrough */ + case IMX8MQ_RESET_MIPI_DSI_RESET_N: /* fallthrough */ + case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N: /* fallthrough */ + value = assert ? 0 : bit; + break; + } + + return imx7_reset_update(imx7src, id, value); +} + +static int imx8mq_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return imx8mq_reset_set(rcdev, id, true); +} + +static int imx8mq_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return imx8mq_reset_set(rcdev, id, false); +} + +static const struct imx7_src_variant variant_imx8mq = { + .signals = imx8mq_src_signals, + .signals_num = ARRAY_SIZE(imx8mq_src_signals), + .ops = { + .assert = imx8mq_reset_assert, + .deassert = imx8mq_reset_deassert, + }, +}; + +static int imx7_reset_probe(struct device_d *dev) +{ + struct imx7_src *imx7src; + const struct imx7_src_variant *variant = of_device_get_match_data(dev); + + imx7src = xzalloc(sizeof(*imx7src)); + imx7src->signals = variant->signals; + imx7src->regmap = syscon_node_to_regmap(dev->device_node); + if (IS_ERR(imx7src->regmap)) { + dev_err(dev, "Unable to get imx7-src regmap"); + return PTR_ERR(imx7src->regmap); + } + + imx7src->rcdev.nr_resets = variant->signals_num; + imx7src->rcdev.ops = &variant->ops; + imx7src->rcdev.of_node = dev->device_node; + + return reset_controller_register(&imx7src->rcdev); +} + +static const struct of_device_id imx7_reset_dt_ids[] = { + { .compatible = "fsl,imx7d-src", .data = &variant_imx7 }, + { .compatible = "fsl,imx8mq-src", .data = &variant_imx8mq }, + { /* sentinel */ }, +}; + +static struct driver_d imx7_reset_driver = { + .name = "imx7d-src", + .probe = imx7_reset_probe, + .of_compatible = DRV_OF_COMPAT(imx7_reset_dt_ids), +}; +device_platform_driver(imx7_reset_driver); diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index b6faa0217e..9b499f23c5 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -73,7 +73,7 @@ static int socfpga_reset_deassert(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops socfpga_reset_ops = { +static const struct reset_control_ops socfpga_reset_ops = { .assert = socfpga_reset_assert, .deassert = socfpga_reset_deassert, }; diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig new file mode 100644 index 0000000000..32ec76feaf --- /dev/null +++ b/drivers/soc/imx/Kconfig @@ -0,0 +1,9 @@ +menu "i.MX SoC drivers" + +config IMX_GPCV2_PM_DOMAINS + bool "i.MX GPCv2 PM domains" + depends on ARCH_IMX7 || ARCH_IMX8MQ + select PM_GENERIC_DOMAINS + default y if ARCH_IMX7 || ARCH_IMX8MQ + +endmenu diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile new file mode 100644 index 0000000000..d60056c7b6 --- /dev/null +++ b/drivers/soc/imx/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c new file mode 100644 index 0000000000..bc373ecf40 --- /dev/null +++ b/drivers/soc/imx/gpcv2.c @@ -0,0 +1,498 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2017 Impinj, Inc + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + * + * Based on the code of analogus driver: + * + * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de> + */ + +#include <of_device.h> +#include <common.h> +#include <clock.h> +#include <abort.h> +#include <malloc.h> +#include <io.h> +#include <init.h> +#include <linux/iopoll.h> + +#include <pm_domain.h> +#include <regulator.h> +#include <dt-bindings/power/imx7-power.h> + +#include <dt-bindings/power/imx8mq-power.h> + +#define GPC_LPCR_A_BSC 0x000 + +#define GPC_PGC_CPU_MAPPING 0x0ec + +#define IMX7_USB_HSIC_PHY_A_DOMAIN BIT(6) +#define IMX7_USB_OTG2_PHY_A_DOMAIN BIT(5) +#define IMX7_USB_OTG1_PHY_A_DOMAIN BIT(4) +#define IMX7_PCIE_PHY_A_DOMAIN BIT(3) +#define IMX7_MIPI_PHY_A_DOMAIN BIT(2) + +#define IMX8M_PCIE2_A53_DOMAIN BIT(15) +#define IMX8M_MIPI_CSI2_A53_DOMAIN BIT(14) +#define IMX8M_MIPI_CSI1_A53_DOMAIN BIT(13) +#define IMX8M_DISP_A53_DOMAIN BIT(12) +#define IMX8M_HDMI_A53_DOMAIN BIT(11) +#define IMX8M_VPU_A53_DOMAIN BIT(10) +#define IMX8M_GPU_A53_DOMAIN BIT(9) +#define IMX8M_DDR2_A53_DOMAIN BIT(8) +#define IMX8M_DDR1_A53_DOMAIN BIT(7) +#define IMX8M_OTG2_A53_DOMAIN BIT(5) +#define IMX8M_OTG1_A53_DOMAIN BIT(4) +#define IMX8M_PCIE1_A53_DOMAIN BIT(3) +#define IMX8M_MIPI_A53_DOMAIN BIT(2) + +#define GPC_PU_PGC_SW_PUP_REQ 0x0f8 +#define GPC_PU_PGC_SW_PDN_REQ 0x104 + +#define IMX7_USB_HSIC_PHY_SW_Pxx_REQ BIT(4) +#define IMX7_USB_OTG2_PHY_SW_Pxx_REQ BIT(3) +#define IMX7_USB_OTG1_PHY_SW_Pxx_REQ BIT(2) +#define IMX7_PCIE_PHY_SW_Pxx_REQ BIT(1) +#define IMX7_MIPI_PHY_SW_Pxx_REQ BIT(0) + +#define IMX8M_PCIE2_SW_Pxx_REQ BIT(13) +#define IMX8M_MIPI_CSI2_SW_Pxx_REQ BIT(12) +#define IMX8M_MIPI_CSI1_SW_Pxx_REQ BIT(11) +#define IMX8M_DISP_SW_Pxx_REQ BIT(10) +#define IMX8M_HDMI_SW_Pxx_REQ BIT(9) +#define IMX8M_VPU_SW_Pxx_REQ BIT(8) +#define IMX8M_GPU_SW_Pxx_REQ BIT(7) +#define IMX8M_DDR2_SW_Pxx_REQ BIT(6) +#define IMX8M_DDR1_SW_Pxx_REQ BIT(5) +#define IMX8M_OTG2_SW_Pxx_REQ BIT(3) +#define IMX8M_OTG1_SW_Pxx_REQ BIT(2) +#define IMX8M_PCIE1_SW_Pxx_REQ BIT(1) +#define IMX8M_MIPI_SW_Pxx_REQ BIT(0) + +#define GPC_M4_PU_PDN_FLG 0x1bc + +/* + * The PGC offset values in Reference Manual + * (Rev. 1, 01/2018 and the older ones) GPC chapter's + * GPC_PGC memory map are incorrect, below offset + * values are from design RTL. + */ +#define IMX7_PGC_MIPI 16 +#define IMX7_PGC_PCIE 17 +#define IMX7_PGC_USB_HSIC 20 + + +#define IMX8M_PGC_MIPI 16 +#define IMX8M_PGC_PCIE1 17 +#define IMX8M_PGC_OTG1 18 +#define IMX8M_PGC_OTG2 19 +#define IMX8M_PGC_DDR1 21 +#define IMX8M_PGC_GPU 23 +#define IMX8M_PGC_VPU 24 +#define IMX8M_PGC_DISP 26 +#define IMX8M_PGC_MIPI_CSI1 27 +#define IMX8M_PGC_MIPI_CSI2 28 +#define IMX8M_PGC_PCIE2 29 + +#define GPC_PGC_CTRL(n) (0x800 + (n) * 0x40) +#define GPC_PGC_SR(n) (GPC_PGC_CTRL(n) + 0xc) + +#define GPC_PGC_CTRL_PCR BIT(0) + +struct imx_pgc_domain { + struct generic_pm_domain genpd; + void __iomem *base; + struct regulator *regulator; + + unsigned int pgc; + + const struct { + u32 pxx; + u32 map; + } bits; + + const int voltage; + struct device_d *dev; +}; + +struct imx_pgc_domain_data { + const struct imx_pgc_domain *domains; + size_t domains_num; +}; + +static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd, + bool on) +{ + struct imx_pgc_domain *domain = container_of(genpd, + struct imx_pgc_domain, + genpd); + unsigned int offset = on ? + GPC_PU_PGC_SW_PUP_REQ : GPC_PU_PGC_SW_PDN_REQ; + const bool enable_power_control = !on; + const bool has_regulator = !IS_ERR(domain->regulator); + int ret = 0; + unsigned int mapping, ctrl = 0, pxx; + + mapping = readl(domain->base + GPC_PGC_CPU_MAPPING); + mapping |= domain->bits.map; + writel(mapping, domain->base + GPC_PGC_CPU_MAPPING); + + if (has_regulator && on) { + ret = regulator_enable(domain->regulator); + if (ret) { + dev_err(domain->dev, "failed to enable regulator\n"); + goto unmap; + } + } + + if (enable_power_control) { + ctrl = readl(domain->base + GPC_PGC_CTRL(domain->pgc)); + ctrl |= GPC_PGC_CTRL_PCR; + writel(ctrl, domain->base + GPC_PGC_CTRL(domain->pgc)); + } + + pxx = readl(domain->base + offset); + pxx |= domain->bits.pxx; + writel(pxx, domain->base + offset); + + /* + * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait + * for PUP_REQ/PDN_REQ bit to be cleared + */ + ret = readl_poll_timeout(domain->base + offset, pxx, + !(pxx & domain->bits.pxx), MSECOND); + if (ret < 0) { + dev_err(domain->dev, "falied to command PGC\n"); + /* + * If we were in a process of enabling a + * domain and failed we might as well disable + * the regulator we just enabled. And if it + * was the opposite situation and we failed to + * power down -- keep the regulator on + */ + on = !on; + } + + if (enable_power_control) { + ctrl &= ~GPC_PGC_CTRL_PCR; + writel(ctrl, domain->base + GPC_PGC_CTRL(domain->pgc)); + } + + if (has_regulator && !on) { + int err; + + err = regulator_disable(domain->regulator); + if (err) + dev_err(domain->dev, + "failed to disable regulator: %d\n", ret); + /* Preserve earlier error code */ + ret = ret ?: err; + } +unmap: + mapping &= ~domain->bits.map; + writel(mapping, domain->base + GPC_PGC_CPU_MAPPING); + + return ret; +} + +static int imx_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd) +{ + return imx_gpc_pu_pgc_sw_pxx_req(genpd, true); +} + +static int imx_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd) +{ + return imx_gpc_pu_pgc_sw_pxx_req(genpd, false); +} + +static const struct imx_pgc_domain imx7_pgc_domains[] = { + [IMX7_POWER_DOMAIN_MIPI_PHY] = { + .genpd = { + .name = "mipi-phy", + }, + .bits = { + .pxx = IMX7_MIPI_PHY_SW_Pxx_REQ, + .map = IMX7_MIPI_PHY_A_DOMAIN, + }, + .voltage = 1000000, + .pgc = IMX7_PGC_MIPI, + }, + + [IMX7_POWER_DOMAIN_PCIE_PHY] = { + .genpd = { + .name = "pcie-phy", + }, + .bits = { + .pxx = IMX7_PCIE_PHY_SW_Pxx_REQ, + .map = IMX7_PCIE_PHY_A_DOMAIN, + }, + .voltage = 1000000, + .pgc = IMX7_PGC_PCIE, + }, + + [IMX7_POWER_DOMAIN_USB_HSIC_PHY] = { + .genpd = { + .name = "usb-hsic-phy", + }, + .bits = { + .pxx = IMX7_USB_HSIC_PHY_SW_Pxx_REQ, + .map = IMX7_USB_HSIC_PHY_A_DOMAIN, + }, + .voltage = 1200000, + .pgc = IMX7_PGC_USB_HSIC, + }, +}; + +static const struct imx_pgc_domain_data imx7_pgc_domain_data = { + .domains = imx7_pgc_domains, + .domains_num = ARRAY_SIZE(imx7_pgc_domains), +}; + +static const struct imx_pgc_domain imx8m_pgc_domains[] = { + [IMX8M_POWER_DOMAIN_MIPI] = { + .genpd = { + .name = "mipi", + }, + .bits = { + .pxx = IMX8M_MIPI_SW_Pxx_REQ, + .map = IMX8M_MIPI_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_MIPI, + }, + + [IMX8M_POWER_DOMAIN_PCIE1] = { + .genpd = { + .name = "pcie1", + }, + .bits = { + .pxx = IMX8M_PCIE1_SW_Pxx_REQ, + .map = IMX8M_PCIE1_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_PCIE1, + }, + + [IMX8M_POWER_DOMAIN_USB_OTG1] = { + .genpd = { + .name = "usb-otg1", + }, + .bits = { + .pxx = IMX8M_OTG1_SW_Pxx_REQ, + .map = IMX8M_OTG1_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_OTG1, + }, + + [IMX8M_POWER_DOMAIN_USB_OTG2] = { + .genpd = { + .name = "usb-otg2", + }, + .bits = { + .pxx = IMX8M_OTG2_SW_Pxx_REQ, + .map = IMX8M_OTG2_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_OTG2, + }, + + [IMX8M_POWER_DOMAIN_DDR1] = { + .genpd = { + .name = "ddr1", + }, + .bits = { + .pxx = IMX8M_DDR1_SW_Pxx_REQ, + .map = IMX8M_DDR2_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_DDR1, + }, + + [IMX8M_POWER_DOMAIN_GPU] = { + .genpd = { + .name = "gpu", + }, + .bits = { + .pxx = IMX8M_GPU_SW_Pxx_REQ, + .map = IMX8M_GPU_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_GPU, + }, + + [IMX8M_POWER_DOMAIN_VPU] = { + .genpd = { + .name = "vpu", + }, + .bits = { + .pxx = IMX8M_VPU_SW_Pxx_REQ, + .map = IMX8M_VPU_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_VPU, + }, + + [IMX8M_POWER_DOMAIN_DISP] = { + .genpd = { + .name = "disp", + }, + .bits = { + .pxx = IMX8M_DISP_SW_Pxx_REQ, + .map = IMX8M_DISP_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_DISP, + }, + + [IMX8M_POWER_DOMAIN_MIPI_CSI1] = { + .genpd = { + .name = "mipi-csi1", + }, + .bits = { + .pxx = IMX8M_MIPI_CSI1_SW_Pxx_REQ, + .map = IMX8M_MIPI_CSI1_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_MIPI_CSI1, + }, + + [IMX8M_POWER_DOMAIN_MIPI_CSI2] = { + .genpd = { + .name = "mipi-csi2", + }, + .bits = { + .pxx = IMX8M_MIPI_CSI2_SW_Pxx_REQ, + .map = IMX8M_MIPI_CSI2_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_MIPI_CSI2, + }, + + [IMX8M_POWER_DOMAIN_PCIE2] = { + .genpd = { + .name = "pcie2", + }, + .bits = { + .pxx = IMX8M_PCIE2_SW_Pxx_REQ, + .map = IMX8M_PCIE2_A53_DOMAIN, + }, + .pgc = IMX8M_PGC_PCIE2, + }, +}; + +static const struct imx_pgc_domain_data imx8m_pgc_domain_data = { + .domains = imx8m_pgc_domains, + .domains_num = ARRAY_SIZE(imx8m_pgc_domains), +}; + +static int imx_pgc_domain_probe(struct device_d *dev) +{ + struct imx_pgc_domain *domain = dev->priv; + int ret; + + domain->dev = dev; + + domain->regulator = regulator_get(domain->dev, "power"); + if (IS_ERR(domain->regulator)) { + if (PTR_ERR(domain->regulator) != -ENODEV) { + if (PTR_ERR(domain->regulator) != -EPROBE_DEFER) + dev_err(domain->dev, "Failed to get domain's regulator\n"); + return PTR_ERR(domain->regulator); + } + } else { + regulator_set_voltage(domain->regulator, + domain->voltage, domain->voltage); + } + + ret = pm_genpd_init(&domain->genpd, NULL, true); + if (ret) { + dev_err(domain->dev, "Failed to init power domain\n"); + return ret; + } + + ret = of_genpd_add_provider_simple(domain->dev->device_node, + &domain->genpd); + if (ret) { + dev_err(domain->dev, "Failed to add genpd provider\n"); + } + + return ret; +} + +static const struct platform_device_id imx_pgc_domain_id[] = { + { "imx-pgc-domain", }, + { }, +}; + +static struct driver_d imx_pgc_domain_driver = { + .name = "imx-pgc", + .probe = imx_pgc_domain_probe, + .id_table = imx_pgc_domain_id, +}; +coredevice_platform_driver(imx_pgc_domain_driver); + +static int imx_gpcv2_probe(struct device_d *dev) +{ + static const struct imx_pgc_domain_data *domain_data; + struct device_node *pgc_np, *np; + struct resource *res; + void __iomem *base; + int ret; + + pgc_np = of_get_child_by_name(dev->device_node, "pgc"); + if (!pgc_np) { + dev_err(dev, "No power domains specified in DT\n"); + return -EINVAL; + } + + res = dev_request_mem_resource(dev, 0); + if (IS_ERR(res)) + return PTR_ERR(res); + + base = IOMEM(res->start); + + domain_data = of_device_get_match_data(dev); + + for_each_child_of_node(pgc_np, np) { + struct device_d *pd_dev; + struct imx_pgc_domain *domain; + u32 domain_index; + ret = of_property_read_u32(np, "reg", &domain_index); + if (ret) { + dev_err(dev, "Failed to read 'reg' property\n"); + return ret; + } + + if (domain_index >= domain_data->domains_num) { + dev_warn(dev, + "Domain index %d is out of bounds\n", + domain_index); + continue; + } + + domain = xmemdup(&domain_data->domains[domain_index], + sizeof(domain_data->domains[domain_index])); + domain->base = base; + domain->genpd.power_on = imx_gpc_pu_pgc_sw_pup_req; + domain->genpd.power_off = imx_gpc_pu_pgc_sw_pdn_req; + + pd_dev = xzalloc(sizeof(*pd_dev)); + pd_dev->device_node = np; + pd_dev->id = domain_index; + pd_dev->parent = dev; + pd_dev->priv = domain; + pd_dev->device_node = np; + dev_set_name(pd_dev, imx_pgc_domain_id[0].name); + + ret = platform_device_register(pd_dev); + if (ret) + return ret; + } + + return 0; +} + +static const struct of_device_id imx_gpcv2_dt_ids[] = { + { .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data }, + { .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, }, + { } +}; + +static struct driver_d imx_gpcv2_driver = { + .name = "imx7d-gpc", + .probe = imx_gpcv2_probe, + .of_compatible = DRV_OF_COMPAT(imx_gpcv2_dt_ids), +}; +coredevice_platform_driver(imx_gpcv2_driver); diff --git a/dts/Bindings/Makefile b/dts/Bindings/Makefile index 6e5cef0ed6..50daa0b3b0 100644 --- a/dts/Bindings/Makefile +++ b/dts/Bindings/Makefile @@ -17,7 +17,11 @@ extra-y += $(DT_TMP_SCHEMA) quiet_cmd_mk_schema = SCHEMA $@ cmd_mk_schema = $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $(filter-out FORCE, $^) -DT_DOCS = $(shell cd $(srctree)/$(src) && find * -name '*.yaml') +DT_DOCS = $(shell \ + cd $(srctree)/$(src) && \ + find * \( -name '*.yaml' ! -name $(DT_TMP_SCHEMA) \) \ + ) + DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS)) extra-y += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES)) diff --git a/dts/Bindings/arm/cpu-capacity.txt b/dts/Bindings/arm/cpu-capacity.txt index 84262cdb8d..96fa46cb13 100644 --- a/dts/Bindings/arm/cpu-capacity.txt +++ b/dts/Bindings/arm/cpu-capacity.txt @@ -235,4 +235,4 @@ cpus { =========================================== [1] ARM Linux Kernel documentation - CPUs bindings - Documentation/devicetree/bindings/arm/cpus.txt + Documentation/devicetree/bindings/arm/cpus.yaml diff --git a/dts/Bindings/arm/idle-states.txt b/dts/Bindings/arm/idle-states.txt index 8f0937db55..45730ba60a 100644 --- a/dts/Bindings/arm/idle-states.txt +++ b/dts/Bindings/arm/idle-states.txt @@ -684,7 +684,7 @@ cpus { =========================================== [1] ARM Linux Kernel documentation - CPUs bindings - Documentation/devicetree/bindings/arm/cpus.txt + Documentation/devicetree/bindings/arm/cpus.yaml [2] ARM Linux Kernel documentation - PSCI bindings Documentation/devicetree/bindings/arm/psci.txt diff --git a/dts/Bindings/arm/sp810.txt b/dts/Bindings/arm/sp810.txt index 1b2ab1ff55..46652bf651 100644 --- a/dts/Bindings/arm/sp810.txt +++ b/dts/Bindings/arm/sp810.txt @@ -4,7 +4,7 @@ SP810 System Controller Required properties: - compatible: standard compatible string for a Primecell peripheral, - see Documentation/devicetree/bindings/arm/primecell.txt + see Documentation/devicetree/bindings/arm/primecell.yaml for more details should be: "arm,sp810", "arm,primecell" diff --git a/dts/Bindings/arm/topology.txt b/dts/Bindings/arm/topology.txt index de9eb04866..b0d80c0fb2 100644 --- a/dts/Bindings/arm/topology.txt +++ b/dts/Bindings/arm/topology.txt @@ -472,4 +472,4 @@ cpus { =============================================================================== [1] ARM Linux kernel documentation - Documentation/devicetree/bindings/arm/cpus.txt + Documentation/devicetree/bindings/arm/cpus.yaml diff --git a/dts/Bindings/clock/marvell,mmp2.txt b/dts/Bindings/clock/marvell,mmp2.txt index af376a01f2..23b52dc022 100644 --- a/dts/Bindings/clock/marvell,mmp2.txt +++ b/dts/Bindings/clock/marvell,mmp2.txt @@ -18,4 +18,4 @@ Required Properties: Each clock is assigned an identifier and client nodes use this identifier to specify the clock which they consume. -All these identifier could be found in <dt-bindings/clock/marvell-mmp2.h>. +All these identifiers could be found in <dt-bindings/clock/marvell,mmp2.h>. diff --git a/dts/Bindings/display/arm,pl11x.txt b/dts/Bindings/display/arm,pl11x.txt index ef89ab46b2..572fa2773e 100644 --- a/dts/Bindings/display/arm,pl11x.txt +++ b/dts/Bindings/display/arm,pl11x.txt @@ -1,6 +1,6 @@ * ARM PrimeCell Color LCD Controller PL110/PL111 -See also Documentation/devicetree/bindings/arm/primecell.txt +See also Documentation/devicetree/bindings/arm/primecell.yaml Required properties: diff --git a/dts/Bindings/display/msm/gpu.txt b/dts/Bindings/display/msm/gpu.txt index ac8df3b871..f8759145ce 100644 --- a/dts/Bindings/display/msm/gpu.txt +++ b/dts/Bindings/display/msm/gpu.txt @@ -27,7 +27,6 @@ Example: reg = <0x04300000 0x20000>; reg-names = "kgsl_3d0_reg_memory"; interrupts = <GIC_SPI 80 0>; - interrupt-names = "kgsl_3d0_irq"; clock-names = "core", "iface", diff --git a/dts/Bindings/gpio/gpio-mvebu.txt b/dts/Bindings/gpio/gpio-mvebu.txt index 38ca2201e8..2e097b57f1 100644 --- a/dts/Bindings/gpio/gpio-mvebu.txt +++ b/dts/Bindings/gpio/gpio-mvebu.txt @@ -14,8 +14,6 @@ Required properties: "marvell,armada-8k-gpio" should be used for the Armada 7K and 8K SoCs (either from AP or CP), see - Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt - and Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt for specific details about the offset property. diff --git a/dts/Bindings/interrupt-controller/arm,gic-v3.txt b/dts/Bindings/interrupt-controller/arm,gic-v3.txt index b83bb82490..a3be5298a5 100644 --- a/dts/Bindings/interrupt-controller/arm,gic-v3.txt +++ b/dts/Bindings/interrupt-controller/arm,gic-v3.txt @@ -78,7 +78,7 @@ Sub-nodes: PPI affinity can be expressed as a single "ppi-partitions" node, containing a set of sub-nodes, each with the following property: - affinity: Should be a list of phandles to CPU nodes (as described in -Documentation/devicetree/bindings/arm/cpus.txt). + Documentation/devicetree/bindings/arm/cpus.yaml). GICv3 has one or more Interrupt Translation Services (ITS) that are used to route Message Signalled Interrupts (MSI) to the CPUs. diff --git a/dts/Bindings/serio/olpc,ap-sp.txt b/dts/Bindings/serio/olpc,ap-sp.txt index 36603419d6..0e72183f52 100644 --- a/dts/Bindings/serio/olpc,ap-sp.txt +++ b/dts/Bindings/serio/olpc,ap-sp.txt @@ -4,14 +4,10 @@ Required properties: - compatible : "olpc,ap-sp" - reg : base address and length of SoC's WTM registers - interrupts : SP-AP interrupt -- clocks : phandle + clock-specifier for the clock that drives the WTM -- clock-names: should be "sp" Example: ap-sp@d4290000 { compatible = "olpc,ap-sp"; reg = <0xd4290000 0x1000>; interrupts = <40>; - clocks = <&soc_clocks MMP2_CLK_SP>; - clock-names = "sp"; } diff --git a/dts/Bindings/soc/qcom/qcom,glink.txt b/dts/Bindings/soc/qcom/qcom,glink.txt index 0b8cc533ca..cf759e5f9b 100644 --- a/dts/Bindings/soc/qcom/qcom,glink.txt +++ b/dts/Bindings/soc/qcom/qcom,glink.txt @@ -55,7 +55,7 @@ of these nodes are defined by the individual bindings for the specific function = EXAMPLE The following example represents the GLINK RPM node on a MSM8996 device, with the function for the "rpm_request" channel defined, which is used for -regualtors and root clocks. +regulators and root clocks. apcs_glb: mailbox@9820000 { compatible = "qcom,msm8996-apcs-hmss-global"; diff --git a/dts/Bindings/soc/qcom/qcom,smp2p.txt b/dts/Bindings/soc/qcom/qcom,smp2p.txt index a35af2dafd..49e1d72d36 100644 --- a/dts/Bindings/soc/qcom/qcom,smp2p.txt +++ b/dts/Bindings/soc/qcom/qcom,smp2p.txt @@ -41,12 +41,12 @@ processor ID) and a string identifier. - qcom,local-pid: Usage: required Value type: <u32> - Definition: specifies the identfier of the local endpoint of this edge + Definition: specifies the identifier of the local endpoint of this edge - qcom,remote-pid: Usage: required Value type: <u32> - Definition: specifies the identfier of the remote endpoint of this edge + Definition: specifies the identifier of the remote endpoint of this edge = SUBNODES Each SMP2P pair contain a set of inbound and outbound entries, these are diff --git a/dts/include/dt-bindings/clock/imx8mq-clock.h b/dts/include/dt-bindings/clock/imx8mq-clock.h index b53be41929..04f7ac3459 100644 --- a/dts/include/dt-bindings/clock/imx8mq-clock.h +++ b/dts/include/dt-bindings/clock/imx8mq-clock.h @@ -350,7 +350,7 @@ #define IMX8MQ_CLK_VPU_G2_ROOT 241 /* SCCG PLL GATE */ -#define IMX8MQ_SYS1_PLL_OUT 232 +#define IMX8MQ_SYS1_PLL_OUT 242 #define IMX8MQ_SYS2_PLL_OUT 243 #define IMX8MQ_SYS3_PLL_OUT 244 #define IMX8MQ_DRAM_PLL_OUT 245 @@ -372,24 +372,24 @@ /* txesc clock */ #define IMX8MQ_CLK_DSI_IPG_DIV 256 -#define IMX8MQ_CLK_TMU_ROOT 265 +#define IMX8MQ_CLK_TMU_ROOT 257 /* Display root clocks */ -#define IMX8MQ_CLK_DISP_AXI_ROOT 266 -#define IMX8MQ_CLK_DISP_APB_ROOT 267 -#define IMX8MQ_CLK_DISP_RTRM_ROOT 268 +#define IMX8MQ_CLK_DISP_AXI_ROOT 258 +#define IMX8MQ_CLK_DISP_APB_ROOT 259 +#define IMX8MQ_CLK_DISP_RTRM_ROOT 260 -#define IMX8MQ_CLK_OCOTP_ROOT 269 +#define IMX8MQ_CLK_OCOTP_ROOT 261 -#define IMX8MQ_CLK_DRAM_ALT_ROOT 270 -#define IMX8MQ_CLK_DRAM_CORE 271 +#define IMX8MQ_CLK_DRAM_ALT_ROOT 262 +#define IMX8MQ_CLK_DRAM_CORE 263 -#define IMX8MQ_CLK_MU_ROOT 272 -#define IMX8MQ_VIDEO2_PLL_OUT 273 +#define IMX8MQ_CLK_MU_ROOT 264 +#define IMX8MQ_VIDEO2_PLL_OUT 265 -#define IMX8MQ_CLK_CLKO2 274 +#define IMX8MQ_CLK_CLKO2 266 -#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 275 +#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 267 -#define IMX8MQ_CLK_END 276 +#define IMX8MQ_CLK_END 268 #endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */ diff --git a/dts/include/dt-bindings/clock/marvell,mmp2.h b/dts/include/dt-bindings/clock/marvell,mmp2.h index 7b24fc7911..228a5e234a 100644 --- a/dts/include/dt-bindings/clock/marvell,mmp2.h +++ b/dts/include/dt-bindings/clock/marvell,mmp2.h @@ -71,7 +71,6 @@ #define MMP2_CLK_CCIC1_MIX 117 #define MMP2_CLK_CCIC1_PHY 118 #define MMP2_CLK_CCIC1_SPHY 119 -#define MMP2_CLK_SP 120 #define MMP2_NR_CLKS 200 #endif diff --git a/dts/include/dt-bindings/reset/amlogic,meson-axg-reset.h b/dts/include/dt-bindings/reset/amlogic,meson-axg-reset.h index ad6f55dabd..0f2e0fe45c 100644 --- a/dts/include/dt-bindings/reset/amlogic,meson-axg-reset.h +++ b/dts/include/dt-bindings/reset/amlogic,meson-axg-reset.h @@ -1,12 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* - * * Copyright (c) 2016 BayLibre, SAS. * Author: Neil Armstrong <narmstrong@baylibre.com> * * Copyright (c) 2017 Amlogic, inc. * Author: Yixun Lan <yixun.lan@amlogic.com> * - * SPDX-License-Identifier: (GPL-2.0+ OR BSD) */ #ifndef _DT_BINDINGS_AMLOGIC_MESON_AXG_RESET_H diff --git a/dts/src/arm/am335x-shc.dts b/dts/src/arm/am335x-shc.dts index d0fd688736..5b250060f6 100644 --- a/dts/src/arm/am335x-shc.dts +++ b/dts/src/arm/am335x-shc.dts @@ -215,7 +215,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; bus-width = <0x4>; - cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; + cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; cd-inverted; max-frequency = <26000000>; vmmc-supply = <&vmmcsd_fixed>; diff --git a/dts/src/arm/da850.dtsi b/dts/src/arm/da850.dtsi index 47aa53ba6b..559659b399 100644 --- a/dts/src/arm/da850.dtsi +++ b/dts/src/arm/da850.dtsi @@ -476,7 +476,7 @@ clocksource: timer@20000 { compatible = "ti,da830-timer"; reg = <0x20000 0x1000>; - interrupts = <12>, <13>; + interrupts = <21>, <22>; interrupt-names = "tint12", "tint34"; clocks = <&pll0_auxclk>; }; diff --git a/dts/src/arm/imx6q-pistachio.dts b/dts/src/arm/imx6q-pistachio.dts index 5edf858c8b..a31b17eaf5 100644 --- a/dts/src/arm/imx6q-pistachio.dts +++ b/dts/src/arm/imx6q-pistachio.dts @@ -103,7 +103,7 @@ power { label = "Power Button"; gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = <KEY_POWER>; }; }; diff --git a/dts/src/arm/imx6sll-evk.dts b/dts/src/arm/imx6sll-evk.dts index d816370536..4a31a415f8 100644 --- a/dts/src/arm/imx6sll-evk.dts +++ b/dts/src/arm/imx6sll-evk.dts @@ -309,7 +309,7 @@ pinctrl-2 = <&pinctrl_usdhc3_200mhz>; cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; vmmc-supply = <®_sd3_vmmc>; status = "okay"; }; diff --git a/dts/src/arm/imx6sx.dtsi b/dts/src/arm/imx6sx.dtsi index 272ff6133e..d1375d3650 100644 --- a/dts/src/arm/imx6sx.dtsi +++ b/dts/src/arm/imx6sx.dtsi @@ -467,7 +467,7 @@ }; gpt: gpt@2098000 { - compatible = "fsl,imx6sx-gpt", "fsl,imx31-gpt"; + compatible = "fsl,imx6sx-gpt", "fsl,imx6dl-gpt"; reg = <0x02098000 0x4000>; interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6SX_CLK_GPT_BUS>, diff --git a/dts/src/arm/meson.dtsi b/dts/src/arm/meson.dtsi index e4645f6127..2ab74860d9 100644 --- a/dts/src/arm/meson.dtsi +++ b/dts/src/arm/meson.dtsi @@ -274,7 +274,7 @@ compatible = "amlogic,meson6-dwmac", "snps,dwmac"; reg = <0xc9410000 0x10000 0xc1108108 0x4>; - interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>; + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq"; status = "disabled"; }; diff --git a/dts/src/arm/meson8b-ec100.dts b/dts/src/arm/meson8b-ec100.dts index 0872f6e3ab..d50fc2f60f 100644 --- a/dts/src/arm/meson8b-ec100.dts +++ b/dts/src/arm/meson8b-ec100.dts @@ -205,8 +205,7 @@ cap-sd-highspeed; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vcc_3v3>; }; diff --git a/dts/src/arm/meson8b-odroidc1.dts b/dts/src/arm/meson8b-odroidc1.dts index 58669abda2..0f0a46ddf3 100644 --- a/dts/src/arm/meson8b-odroidc1.dts +++ b/dts/src/arm/meson8b-odroidc1.dts @@ -221,7 +221,6 @@ /* Realtek RTL8211F (0x001cc916) */ eth_phy: ethernet-phy@0 { reg = <0>; - eee-broken-1000t; interrupt-parent = <&gpio_intc>; /* GPIOH_3 */ interrupts = <17 IRQ_TYPE_LEVEL_LOW>; @@ -273,8 +272,7 @@ cap-sd-highspeed; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&tflash_vdd>; vqmmc-supply = <&tf_io>; diff --git a/dts/src/arm/meson8m2-mxiii-plus.dts b/dts/src/arm/meson8m2-mxiii-plus.dts index f5853610b2..6ac02beb5f 100644 --- a/dts/src/arm/meson8m2-mxiii-plus.dts +++ b/dts/src/arm/meson8m2-mxiii-plus.dts @@ -206,8 +206,7 @@ cap-sd-highspeed; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vcc_3v3>; }; diff --git a/dts/src/arm/motorola-cpcap-mapphone.dtsi b/dts/src/arm/motorola-cpcap-mapphone.dtsi index ddc7a7bb33..f57acf8f66 100644 --- a/dts/src/arm/motorola-cpcap-mapphone.dtsi +++ b/dts/src/arm/motorola-cpcap-mapphone.dtsi @@ -105,7 +105,7 @@ interrupts-extended = < &cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0 &cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0 - &cpcap 48 1 + &cpcap 48 0 >; interrupt-names = "id_ground", "id_float", "se0conn", "vbusvld", diff --git a/dts/src/arm/omap3-gta04.dtsi b/dts/src/arm/omap3-gta04.dtsi index e53d326913..93b420934e 100644 --- a/dts/src/arm/omap3-gta04.dtsi +++ b/dts/src/arm/omap3-gta04.dtsi @@ -714,11 +714,7 @@ vdda-supply = <&vdac>; - #address-cells = <1>; - #size-cells = <0>; - port { - reg = <0>; venc_out: endpoint { remote-endpoint = <&opa_in>; ti,channels = <1>; diff --git a/dts/src/arm/omap3-n900.dts b/dts/src/arm/omap3-n900.dts index 182a53991c..826920e6b8 100644 --- a/dts/src/arm/omap3-n900.dts +++ b/dts/src/arm/omap3-n900.dts @@ -814,7 +814,7 @@ /* For debugging, it is often good idea to remove this GPIO. It means you can remove back cover (to reboot by removing battery) and still use the MMC card. */ - cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */ + cd-gpios = <&gpio6 0 GPIO_ACTIVE_LOW>; /* 160 */ }; /* most boards use vaux3, only some old versions use vmmc2 instead */ diff --git a/dts/src/arm/omap3-n950-n9.dtsi b/dts/src/arm/omap3-n950-n9.dtsi index 0d9b853175..e142e6c70a 100644 --- a/dts/src/arm/omap3-n950-n9.dtsi +++ b/dts/src/arm/omap3-n950-n9.dtsi @@ -370,6 +370,19 @@ compatible = "ti,omap2-onenand"; reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */ + /* + * These timings are based on CONFIG_OMAP_GPMC_DEBUG=y reported + * bootloader set values when booted with v4.19 using both N950 + * and N9 devices (OneNAND Manufacturer: Samsung): + * + * gpmc cs0 before gpmc_cs_program_settings: + * cs0 GPMC_CS_CONFIG1: 0xfd001202 + * cs0 GPMC_CS_CONFIG2: 0x00181800 + * cs0 GPMC_CS_CONFIG3: 0x00030300 + * cs0 GPMC_CS_CONFIG4: 0x18001804 + * cs0 GPMC_CS_CONFIG5: 0x03171d1d + * cs0 GPMC_CS_CONFIG6: 0x97080000 + */ gpmc,sync-read; gpmc,sync-write; gpmc,burst-length = <16>; @@ -379,26 +392,27 @@ gpmc,device-width = <2>; gpmc,mux-add-data = <2>; gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <87>; - gpmc,cs-wr-off-ns = <87>; + gpmc,cs-rd-off-ns = <122>; + gpmc,cs-wr-off-ns = <122>; gpmc,adv-on-ns = <0>; - gpmc,adv-rd-off-ns = <10>; - gpmc,adv-wr-off-ns = <10>; - gpmc,oe-on-ns = <15>; - gpmc,oe-off-ns = <87>; + gpmc,adv-rd-off-ns = <15>; + gpmc,adv-wr-off-ns = <15>; + gpmc,oe-on-ns = <20>; + gpmc,oe-off-ns = <122>; gpmc,we-on-ns = <0>; - gpmc,we-off-ns = <87>; - gpmc,rd-cycle-ns = <112>; - gpmc,wr-cycle-ns = <112>; - gpmc,access-ns = <81>; + gpmc,we-off-ns = <122>; + gpmc,rd-cycle-ns = <148>; + gpmc,wr-cycle-ns = <148>; + gpmc,access-ns = <117>; gpmc,page-burst-access-ns = <15>; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,wait-monitoring-ns = <0>; - gpmc,clk-activation-ns = <5>; - gpmc,wr-data-mux-bus-ns = <30>; - gpmc,wr-access-ns = <81>; - gpmc,sync-clk-ps = <15000>; + gpmc,clk-activation-ns = <10>; + gpmc,wr-data-mux-bus-ns = <40>; + gpmc,wr-access-ns = <117>; + + gpmc,sync-clk-ps = <15000>; /* TBC; Where this value came? */ /* * MTD partition table corresponding to Nokia's MeeGo 1.2 diff --git a/dts/src/arm/omap5-l4.dtsi b/dts/src/arm/omap5-l4.dtsi index 9c7e309d9c..0960348002 100644 --- a/dts/src/arm/omap5-l4.dtsi +++ b/dts/src/arm/omap5-l4.dtsi @@ -1046,8 +1046,6 @@ <SYSC_IDLE_SMART>, <SYSC_IDLE_SMART_WKUP>; ti,syss-mask = <1>; - ti,no-reset-on-init; - ti,no-idle-on-init; /* Domains (V, P, C): core, core_pwrdm, l4per_clkdm */ clocks = <&l4per_clkctrl OMAP5_UART3_CLKCTRL 0>; clock-names = "fck"; diff --git a/dts/src/arm/r8a7743.dtsi b/dts/src/arm/r8a7743.dtsi index 3cc33f7ff7..3adc158a40 100644 --- a/dts/src/arm/r8a7743.dtsi +++ b/dts/src/arm/r8a7743.dtsi @@ -1681,15 +1681,12 @@ du: display@feb00000 { compatible = "renesas,du-r8a7743"; - reg = <0 0xfeb00000 0 0x40000>, - <0 0xfeb90000 0 0x1c>; - reg-names = "du", "lvds.0"; + reg = <0 0xfeb00000 0 0x40000>; interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cpg CPG_MOD 724>, - <&cpg CPG_MOD 723>, - <&cpg CPG_MOD 726>; - clock-names = "du.0", "du.1", "lvds.0"; + <&cpg CPG_MOD 723>; + clock-names = "du.0", "du.1"; status = "disabled"; ports { @@ -1704,6 +1701,33 @@ port@1 { reg = <1>; du_out_lvds0: endpoint { + remote-endpoint = <&lvds0_in>; + }; + }; + }; + }; + + lvds0: lvds@feb90000 { + compatible = "renesas,r8a7743-lvds"; + reg = <0 0xfeb90000 0 0x1c>; + clocks = <&cpg CPG_MOD 726>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 726>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lvds0_in: endpoint { + remote-endpoint = <&du_out_lvds0>; + }; + }; + port@1 { + reg = <1>; + lvds0_out: endpoint { }; }; }; diff --git a/dts/src/arm/sun6i-a31.dtsi b/dts/src/arm/sun6i-a31.dtsi index 353d90f99b..13304b8c51 100644 --- a/dts/src/arm/sun6i-a31.dtsi +++ b/dts/src/arm/sun6i-a31.dtsi @@ -216,6 +216,7 @@ #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <24000000>; + clock-output-names = "osc24M"; }; osc32k: clk-32k { diff --git a/dts/src/arm/sun8i-h3-beelink-x2.dts b/dts/src/arm/sun8i-h3-beelink-x2.dts index 5d23667dc2..25540b7694 100644 --- a/dts/src/arm/sun8i-h3-beelink-x2.dts +++ b/dts/src/arm/sun8i-h3-beelink-x2.dts @@ -53,7 +53,7 @@ aliases { serial0 = &uart0; - /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */ + ethernet0 = &emac; ethernet1 = &sdiowifi; }; diff --git a/dts/src/arm/vf610-bk4.dts b/dts/src/arm/vf610-bk4.dts index 689c8930dc..b08d561d67 100644 --- a/dts/src/arm/vf610-bk4.dts +++ b/dts/src/arm/vf610-bk4.dts @@ -110,11 +110,11 @@ bus-num = <3>; status = "okay"; spi-slave; + #address-cells = <0>; - slave@0 { + slave { compatible = "lwn,bk4"; spi-max-frequency = <30000000>; - reg = <0>; }; }; diff --git a/dts/src/arm64/allwinner/sun50i-a64-orangepi-win.dts b/dts/src/arm64/allwinner/sun50i-a64-orangepi-win.dts index b0c64f7579..8974b5a1d3 100644 --- a/dts/src/arm64/allwinner/sun50i-a64-orangepi-win.dts +++ b/dts/src/arm64/allwinner/sun50i-a64-orangepi-win.dts @@ -188,6 +188,7 @@ reg = <0x3a3>; interrupt-parent = <&r_intc>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */ }; }; diff --git a/dts/src/arm64/allwinner/sun50i-a64.dtsi b/dts/src/arm64/allwinner/sun50i-a64.dtsi index 837a03dee8..2abb335145 100644 --- a/dts/src/arm64/allwinner/sun50i-a64.dtsi +++ b/dts/src/arm64/allwinner/sun50i-a64.dtsi @@ -390,7 +390,7 @@ }; video-codec@1c0e000 { - compatible = "allwinner,sun50i-h5-video-engine"; + compatible = "allwinner,sun50i-a64-video-engine"; reg = <0x01c0e000 0x1000>; clocks = <&ccu CLK_BUS_VE>, <&ccu CLK_VE>, <&ccu CLK_DRAM_VE>; diff --git a/dts/src/arm64/amlogic/meson-gx-p23x-q20x.dtsi b/dts/src/arm64/amlogic/meson-gx-p23x-q20x.dtsi index e14e0ce7e8..016641a416 100644 --- a/dts/src/arm64/amlogic/meson-gx-p23x-q20x.dtsi +++ b/dts/src/arm64/amlogic/meson-gx-p23x-q20x.dtsi @@ -187,8 +187,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_boot>; diff --git a/dts/src/arm64/amlogic/meson-gxbb-nanopi-k2.dts b/dts/src/arm64/amlogic/meson-gxbb-nanopi-k2.dts index 8cd50b7517..ade2ee09ae 100644 --- a/dts/src/arm64/amlogic/meson-gxbb-nanopi-k2.dts +++ b/dts/src/arm64/amlogic/meson-gxbb-nanopi-k2.dts @@ -305,8 +305,7 @@ max-frequency = <200000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddio_ao3v3>; vqmmc-supply = <&vddio_tf>; diff --git a/dts/src/arm64/amlogic/meson-gxbb-nexbox-a95x.dts b/dts/src/arm64/amlogic/meson-gxbb-nexbox-a95x.dts index 4cf7f6e80c..25105ac96d 100644 --- a/dts/src/arm64/amlogic/meson-gxbb-nexbox-a95x.dts +++ b/dts/src/arm64/amlogic/meson-gxbb-nexbox-a95x.dts @@ -238,8 +238,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_card>; diff --git a/dts/src/arm64/amlogic/meson-gxbb-odroidc2.dts b/dts/src/arm64/amlogic/meson-gxbb-odroidc2.dts index 2e1cd5e3a2..1cc9dc68ef 100644 --- a/dts/src/arm64/amlogic/meson-gxbb-odroidc2.dts +++ b/dts/src/arm64/amlogic/meson-gxbb-odroidc2.dts @@ -258,8 +258,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&tflash_vdd>; vqmmc-supply = <&tf_io>; diff --git a/dts/src/arm64/amlogic/meson-gxbb-p20x.dtsi b/dts/src/arm64/amlogic/meson-gxbb-p20x.dtsi index ce862266b9..0be0f2a5d2 100644 --- a/dts/src/arm64/amlogic/meson-gxbb-p20x.dtsi +++ b/dts/src/arm64/amlogic/meson-gxbb-p20x.dtsi @@ -196,8 +196,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_card>; diff --git a/dts/src/arm64/amlogic/meson-gxbb-vega-s95.dtsi b/dts/src/arm64/amlogic/meson-gxbb-vega-s95.dtsi index 93a4acf2c4..ad4d50bd9d 100644 --- a/dts/src/arm64/amlogic/meson-gxbb-vega-s95.dtsi +++ b/dts/src/arm64/amlogic/meson-gxbb-vega-s95.dtsi @@ -154,8 +154,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vcc_3v3>; }; diff --git a/dts/src/arm64/amlogic/meson-gxbb-wetek.dtsi b/dts/src/arm64/amlogic/meson-gxbb-wetek.dtsi index ec09bb5792..2d2db783c4 100644 --- a/dts/src/arm64/amlogic/meson-gxbb-wetek.dtsi +++ b/dts/src/arm64/amlogic/meson-gxbb-wetek.dtsi @@ -211,8 +211,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vcc_3v3>; diff --git a/dts/src/arm64/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/dts/src/arm64/amlogic/meson-gxl-s905x-hwacom-amazetv.dts index f1c410e2da..796baea7a0 100644 --- a/dts/src/arm64/amlogic/meson-gxl-s905x-hwacom-amazetv.dts +++ b/dts/src/arm64/amlogic/meson-gxl-s905x-hwacom-amazetv.dts @@ -131,8 +131,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_card>; diff --git a/dts/src/arm64/amlogic/meson-gxl-s905x-libretech-cc.dts b/dts/src/arm64/amlogic/meson-gxl-s905x-libretech-cc.dts index db293440e4..255cede7b4 100644 --- a/dts/src/arm64/amlogic/meson-gxl-s905x-libretech-cc.dts +++ b/dts/src/arm64/amlogic/meson-gxl-s905x-libretech-cc.dts @@ -238,8 +238,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vcc_3v3>; vqmmc-supply = <&vcc_card>; diff --git a/dts/src/arm64/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/dts/src/arm64/amlogic/meson-gxl-s905x-nexbox-a95x.dts index 6739697be1..9cbdb85fb5 100644 --- a/dts/src/arm64/amlogic/meson-gxl-s905x-nexbox-a95x.dts +++ b/dts/src/arm64/amlogic/meson-gxl-s905x-nexbox-a95x.dts @@ -183,8 +183,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_card>; diff --git a/dts/src/arm64/amlogic/meson-gxl-s905x-p212.dtsi b/dts/src/arm64/amlogic/meson-gxl-s905x-p212.dtsi index a1b31013ab..bc811a2faf 100644 --- a/dts/src/arm64/amlogic/meson-gxl-s905x-p212.dtsi +++ b/dts/src/arm64/amlogic/meson-gxl-s905x-p212.dtsi @@ -137,8 +137,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_boot>; diff --git a/dts/src/arm64/amlogic/meson-gxm-khadas-vim2.dts b/dts/src/arm64/amlogic/meson-gxm-khadas-vim2.dts index 3c3a667a8d..3f086ed7de 100644 --- a/dts/src/arm64/amlogic/meson-gxm-khadas-vim2.dts +++ b/dts/src/arm64/amlogic/meson-gxm-khadas-vim2.dts @@ -356,8 +356,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_boot>; diff --git a/dts/src/arm64/amlogic/meson-gxm-nexbox-a1.dts b/dts/src/arm64/amlogic/meson-gxm-nexbox-a1.dts index f7a1cffab4..8acfd40090 100644 --- a/dts/src/arm64/amlogic/meson-gxm-nexbox-a1.dts +++ b/dts/src/arm64/amlogic/meson-gxm-nexbox-a1.dts @@ -147,8 +147,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_boot>; diff --git a/dts/src/arm64/amlogic/meson-gxm-rbox-pro.dts b/dts/src/arm64/amlogic/meson-gxm-rbox-pro.dts index 7212dc4531..7fa20a8ede 100644 --- a/dts/src/arm64/amlogic/meson-gxm-rbox-pro.dts +++ b/dts/src/arm64/amlogic/meson-gxm-rbox-pro.dts @@ -170,8 +170,7 @@ max-frequency = <100000000>; disable-wp; - cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; - cd-inverted; + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_boot>; diff --git a/dts/src/arm64/qcom/msm8996.dtsi b/dts/src/arm64/qcom/msm8996.dtsi index 99b7495455..838e32cc14 100644 --- a/dts/src/arm64/qcom/msm8996.dtsi +++ b/dts/src/arm64/qcom/msm8996.dtsi @@ -404,7 +404,7 @@ }; intc: interrupt-controller@9bc0000 { - compatible = "arm,gic-v3"; + compatible = "qcom,msm8996-gic-v3", "arm,gic-v3"; #interrupt-cells = <3>; interrupt-controller; #redistributor-regions = <1>; diff --git a/dts/src/arm64/renesas/r8a774a1.dtsi b/dts/src/arm64/renesas/r8a774a1.dtsi index 20745a8528..719ed9d906 100644 --- a/dts/src/arm64/renesas/r8a774a1.dtsi +++ b/dts/src/arm64/renesas/r8a774a1.dtsi @@ -1011,6 +1011,9 @@ <&cpg CPG_CORE R8A774A1_CLK_S3D1>, <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac1 0x13>, <&dmac1 0x12>, + <&dmac2 0x13>, <&dmac2 0x12>; + dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>; resets = <&cpg 310>; status = "disabled"; diff --git a/dts/src/arm64/renesas/r8a7796.dtsi b/dts/src/arm64/renesas/r8a7796.dtsi index afedbf5728..0648d12778 100644 --- a/dts/src/arm64/renesas/r8a7796.dtsi +++ b/dts/src/arm64/renesas/r8a7796.dtsi @@ -1262,6 +1262,9 @@ <&cpg CPG_CORE R8A7796_CLK_S3D1>, <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac1 0x13>, <&dmac1 0x12>, + <&dmac2 0x13>, <&dmac2 0x12>; + dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; resets = <&cpg 310>; status = "disabled"; diff --git a/dts/src/arm64/renesas/r8a77965.dtsi b/dts/src/arm64/renesas/r8a77965.dtsi index 6dc9b1fef8..4b3730f640 100644 --- a/dts/src/arm64/renesas/r8a77965.dtsi +++ b/dts/src/arm64/renesas/r8a77965.dtsi @@ -1068,6 +1068,9 @@ <&cpg CPG_CORE R8A77965_CLK_S3D1>, <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac1 0x13>, <&dmac1 0x12>, + <&dmac2 0x13>, <&dmac2 0x12>; + dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; resets = <&cpg 310>; status = "disabled"; diff --git a/dts/src/mips/ingenic/ci20.dts b/dts/src/mips/ingenic/ci20.dts index 50cff3cbcc..4f7b1fa31c 100644 --- a/dts/src/mips/ingenic/ci20.dts +++ b/dts/src/mips/ingenic/ci20.dts @@ -76,7 +76,7 @@ status = "okay"; pinctrl-names = "default"; - pinctrl-0 = <&pins_uart2>; + pinctrl-0 = <&pins_uart3>; }; &uart4 { @@ -196,9 +196,9 @@ bias-disable; }; - pins_uart2: uart2 { - function = "uart2"; - groups = "uart2-data", "uart2-hwflow"; + pins_uart3: uart3 { + function = "uart3"; + groups = "uart3-data", "uart3-hwflow"; bias-disable; }; diff --git a/dts/src/mips/ingenic/jz4740.dtsi b/dts/src/mips/ingenic/jz4740.dtsi index 6fb16fd240..2beb78a62b 100644 --- a/dts/src/mips/ingenic/jz4740.dtsi +++ b/dts/src/mips/ingenic/jz4740.dtsi @@ -161,7 +161,7 @@ #dma-cells = <2>; interrupt-parent = <&intc>; - interrupts = <29>; + interrupts = <20>; clocks = <&cgu JZ4740_CLK_DMA>; diff --git a/dts/src/mips/xilfpga/nexys4ddr.dts b/dts/src/mips/xilfpga/nexys4ddr.dts index 2152b7ba65..cc8dbea091 100644 --- a/dts/src/mips/xilfpga/nexys4ddr.dts +++ b/dts/src/mips/xilfpga/nexys4ddr.dts @@ -90,11 +90,11 @@ interrupts = <0>; }; - axi_i2c: i2c@10A00000 { + axi_i2c: i2c@10a00000 { compatible = "xlnx,xps-iic-2.00.a"; interrupt-parent = <&axi_intc>; interrupts = <4>; - reg = < 0x10A00000 0x10000 >; + reg = < 0x10a00000 0x10000 >; clocks = <&ext>; xlnx,clk-freq = <0x5f5e100>; xlnx,family = "Artix7"; @@ -106,9 +106,9 @@ #address-cells = <1>; #size-cells = <0>; - ad7420@4B { + ad7420@4b { compatible = "adi,adt7420"; - reg = <0x4B>; + reg = <0x4b>; }; } ; }; diff --git a/firmware/Makefile b/firmware/Makefile index 7f4dc49326..f238ce2538 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -4,12 +4,12 @@ # firmware-$(CONFIG_FIRMWARE_IMX_LPDDR4_PMU_TRAIN) += \ - imx/lpddr4_pmu_train_1d_dmem.bin \ - imx/lpddr4_pmu_train_1d_imem.bin \ - imx/lpddr4_pmu_train_2d_dmem.bin \ - imx/lpddr4_pmu_train_2d_imem.bin + lpddr4_pmu_train_1d_dmem.bin \ + lpddr4_pmu_train_1d_imem.bin \ + lpddr4_pmu_train_2d_dmem.bin \ + lpddr4_pmu_train_2d_imem.bin -firmware-$(CONFIG_FIRMWARE_IMX8MQ_ATF) += imx/imx8m-bl31.bin +firmware-$(CONFIG_FIRMWARE_IMX8MQ_ATF) += imx8mq-bl31.bin # Create $(fwabs) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a # leading /, it's relative to $(srctree). diff --git a/firmware/README b/firmware/README new file mode 100644 index 0000000000..1150a5cb0b --- /dev/null +++ b/firmware/README @@ -0,0 +1,7 @@ +This is where you need to place any firmware files that need to be built +into the boot image. + +Note that if you need to place any files here, the resulting boot image +is not completely governed by the GPLv2, as used for the Barebox binary, +but will be subject to additional terms of use imposed by the various +licenses that apply to the firmware files. diff --git a/firmware/imx/imx8m-bl31.bin b/firmware/imx/imx8m-bl31.bin Binary files differdeleted file mode 100755 index b2310e4334..0000000000 --- a/firmware/imx/imx8m-bl31.bin +++ /dev/null @@ -533,7 +533,7 @@ void *memmap(int fd, int flags) { struct fs_driver_d *fsdrv; FILE *f; - void *retp = (void *)-1; + void *retp = MAP_FAILED; int ret; if (check_fd(fd)) diff --git a/images/Makefile b/images/Makefile index eeea172d63..4e82dc92ee 100644 --- a/images/Makefile +++ b/images/Makefile @@ -44,7 +44,8 @@ quiet_cmd_objcopy_bin = OBJCOPYB $@ cmd_objcopy_bin = \ - $(OBJCOPY) -O binary $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ + $(OBJCOPY) -O binary $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ && \ + $(objtree)/scripts/fix_size -i -f $@ pbl-lds := $(obj)/pbl.lds extra-y += $(pbl-lds) diff --git a/images/Makefile.imx b/images/Makefile.imx index 3d2e352a39..f9432015d5 100644 --- a/images/Makefile.imx +++ b/images/Makefile.imx @@ -263,6 +263,11 @@ CFG_start_imx6q_sabresd.pblb.imximg = $(board)/freescale-mx6-sabresd/flash-heade FILE_barebox-freescale-imx6q-sabresd.img = start_imx6q_sabresd.pblb.imximg image-$(CONFIG_MACH_SABRESD) += barebox-freescale-imx6q-sabresd.img +pblb-$(CONFIG_MACH_UDOO_NEO) += start_imx6sx_udoo_neo +CFG_start_imx6sx_udoo_neo.pblb.imximg = $(board)/udoo-neo/flash-header-mx6sx-udoo-neo_full.imxcfg +FILE_barebox-udoo-neo.img = start_imx6sx_udoo_neo.pblb.imximg +image-$(CONFIG_MACH_UDOO_NEO) += barebox-udoo-neo.img + pblb-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += start_imx6sx_sabresdb CFG_start_imx6sx_sabresdb.pblb.imximg = $(board)/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg FILE_barebox-freescale-imx6sx-sabresdb.img = start_imx6sx_sabresdb.pblb.imximg @@ -549,3 +554,8 @@ pblb-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += start_nxp_imx8mq_evk CFG_start_nxp_imx8mq_evk.pblb.imximg = $(board)/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg FILE_barebox-nxp-imx8mq-evk.img = start_nxp_imx8mq_evk.pblb.imximg image-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += barebox-nxp-imx8mq-evk.img + +pblb-$(CONFIG_MACH_ZII_IMX8MQ_DEV) += start_zii_imx8mq_dev +CFG_start_zii_imx8mq_dev.pblb.imximg = $(board)/zii-imx8mq-dev/flash-header-zii-imx8mq-dev.imxcfg +FILE_barebox-zii-imx8mq-dev.img = start_zii_imx8mq_dev.pblb.imximg +image-$(CONFIG_MACH_ZII_IMX8MQ_DEV) += barebox-zii-imx8mq-dev.img diff --git a/include/digest.h b/include/digest.h index a1cdbb2d7a..a87e29bd28 100644 --- a/include/digest.h +++ b/include/digest.h @@ -100,7 +100,7 @@ void digest_free(struct digest *d); int digest_file_window(struct digest *d, const char *filename, unsigned char *hash, const unsigned char *sig, - ulong start, ulong size); + loff_t start, loff_t size); int digest_file(struct digest *d, const char *filename, unsigned char *hash, const unsigned char *sig); diff --git a/include/dt-bindings/reset/imx8mq-reset.h b/include/dt-bindings/reset/imx8mq-reset.h new file mode 100644 index 0000000000..57c592498a --- /dev/null +++ b/include/dt-bindings/reset/imx8mq-reset.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Zodiac Inflight Innovations + * + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + */ + +#ifndef DT_BINDING_RESET_IMX8MQ_H +#define DT_BINDING_RESET_IMX8MQ_H + +#define IMX8MQ_RESET_A53_CORE_POR_RESET0 0 +#define IMX8MQ_RESET_A53_CORE_POR_RESET1 1 +#define IMX8MQ_RESET_A53_CORE_POR_RESET2 2 +#define IMX8MQ_RESET_A53_CORE_POR_RESET3 3 +#define IMX8MQ_RESET_A53_CORE_RESET0 4 +#define IMX8MQ_RESET_A53_CORE_RESET1 5 +#define IMX8MQ_RESET_A53_CORE_RESET2 6 +#define IMX8MQ_RESET_A53_CORE_RESET3 7 +#define IMX8MQ_RESET_A53_DBG_RESET0 8 +#define IMX8MQ_RESET_A53_DBG_RESET1 9 +#define IMX8MQ_RESET_A53_DBG_RESET2 10 +#define IMX8MQ_RESET_A53_DBG_RESET3 11 +#define IMX8MQ_RESET_A53_ETM_RESET0 12 +#define IMX8MQ_RESET_A53_ETM_RESET1 13 +#define IMX8MQ_RESET_A53_ETM_RESET2 14 +#define IMX8MQ_RESET_A53_ETM_RESET3 15 +#define IMX8MQ_RESET_A53_SOC_DBG_RESET 16 +#define IMX8MQ_RESET_A53_L2RESET 17 +#define IMX8MQ_RESET_SW_NON_SCLR_M4C_RST 18 +#define IMX8MQ_RESET_OTG1_PHY_RESET 19 +#define IMX8MQ_RESET_OTG2_PHY_RESET 20 +#define IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N 21 +#define IMX8MQ_RESET_MIPI_DSI_RESET_N 22 +#define IMX8MQ_RESET_MIPI_DIS_DPI_RESET_N 23 +#define IMX8MQ_RESET_MIPI_DIS_ESC_RESET_N 24 +#define IMX8MQ_RESET_MIPI_DIS_PCLK_RESET_N 25 +#define IMX8MQ_RESET_PCIEPHY 26 +#define IMX8MQ_RESET_PCIEPHY_PERST 27 +#define IMX8MQ_RESET_PCIE_CTRL_APPS_EN 28 +#define IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF 29 +#define IMX8MQ_RESET_HDMI_PHY_APB_RESET 30 +#define IMX8MQ_RESET_DISP_RESET 31 +#define IMX8MQ_RESET_GPU_RESET 32 +#define IMX8MQ_RESET_VPU_RESET 33 +#define IMX8MQ_RESET_PCIEPHY2 34 +#define IMX8MQ_RESET_PCIEPHY2_PERST 35 +#define IMX8MQ_RESET_PCIE2_CTRL_APPS_EN 36 +#define IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF 37 +#define IMX8MQ_RESET_MIPI_CSI1_CORE_RESET 38 +#define IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET 39 +#define IMX8MQ_RESET_MIPI_CSI1_ESC_RESET 40 +#define IMX8MQ_RESET_MIPI_CSI2_CORE_RESET 41 +#define IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET 42 +#define IMX8MQ_RESET_MIPI_CSI2_ESC_RESET 43 +#define IMX8MQ_RESET_DDRC1_PRST 44 +#define IMX8MQ_RESET_DDRC1_CORE_RESET 45 +#define IMX8MQ_RESET_DDRC1_PHY_RESET 46 +#define IMX8MQ_RESET_DDRC2_PRST 47 +#define IMX8MQ_RESET_DDRC2_CORE_RESET 48 +#define IMX8MQ_RESET_DDRC2_PHY_RESET 49 + +#define IMX8MQ_RESET_NUM 50 + +#endif diff --git a/include/fs.h b/include/fs.h index 181318f404..f1514afa92 100644 --- a/include/fs.h +++ b/include/fs.h @@ -130,6 +130,8 @@ int protect(int fd, size_t count, loff_t offset, int prot); int protect_file(const char *file, int prot); void *memmap(int fd, int flags); +#define MAP_FAILED ((void *)-1) + #define FILESIZE_MAX ((loff_t)-1) #define PROT_READ 1 diff --git a/include/io-64-nonatomic-hi-lo.h b/include/io-64-nonatomic-hi-lo.h new file mode 100644 index 0000000000..3393e6317e --- /dev/null +++ b/include/io-64-nonatomic-hi-lo.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_IO_64_NONATOMIC_HI_LO_H_ +#define _LINUX_IO_64_NONATOMIC_HI_LO_H_ + +#include <io.h> + +static inline __u64 hi_lo_readq(const volatile void __iomem *addr) +{ + const volatile u32 __iomem *p = addr; + u32 low, high; + + high = readl(p + 1); + low = readl(p); + + return low + ((u64)high << 32); +} + +static inline void hi_lo_writeq(__u64 val, volatile void __iomem *addr) +{ + writel(val >> 32, addr + 4); + writel(val, addr); +} + +#ifndef readq +#define readq hi_lo_readq +#endif + +#ifndef writeq +#define writeq hi_lo_writeq +#endif + +#endif /* _LINUX_IO_64_NONATOMIC_HI_LO_H_ */ diff --git a/include/io-64-nonatomic-lo-hi.h b/include/io-64-nonatomic-lo-hi.h new file mode 100644 index 0000000000..62b4022794 --- /dev/null +++ b/include/io-64-nonatomic-lo-hi.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_IO_64_NONATOMIC_LO_HI_H_ +#define _LINUX_IO_64_NONATOMIC_LO_HI_H_ + +#include <io.h> + +static inline __u64 lo_hi_readq(const volatile void __iomem *addr) +{ + const volatile u32 __iomem *p = addr; + u32 low, high; + + low = readl(p); + high = readl(p + 1); + + return low + ((u64)high << 32); +} + +static inline void lo_hi_writeq(__u64 val, volatile void __iomem *addr) +{ + writel(val, addr); + writel(val >> 32, addr + 4); +} + +#ifndef readq +#define readq lo_hi_readq +#endif + +#ifndef writeq +#define writeq lo_hi_writeq +#endif + +#endif /* _LINUX_IO_64_NONATOMIC_LO_HI_H_ */ diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h index d8265486a0..aff03a9c62 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h @@ -35,7 +35,7 @@ struct of_phandle_args; * @nr_resets: number of reset controls in this reset controller device */ struct reset_controller_dev { - struct reset_control_ops *ops; + const struct reset_control_ops *ops; struct list_head list; struct device_node *of_node; int of_reset_n_cells; diff --git a/include/of.h b/include/of.h index 184acb4741..b5f54dd4e5 100644 --- a/include/of.h +++ b/include/of.h @@ -255,6 +255,8 @@ extern int of_platform_populate(struct device_node *root, extern struct device_d *of_find_device_by_node(struct device_node *np); extern struct device_d *of_device_enable_and_register(struct device_node *np); extern struct device_d *of_device_enable_and_register_by_name(const char *name); +extern struct device_d *of_device_enable_and_register_by_alias( + const char *alias); struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node); int of_parse_partitions(struct cdev *cdev, struct device_node *node); @@ -670,6 +672,12 @@ static inline struct device_d *of_device_enable_and_register_by_name( return NULL; } +static inline struct device_d *of_device_enable_and_register_by_alias( + const char *alias) +{ + return NULL; +} + static inline int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context) { diff --git a/include/pm_domain.h b/include/pm_domain.h new file mode 100644 index 0000000000..6d59587ece --- /dev/null +++ b/include/pm_domain.h @@ -0,0 +1,82 @@ +#ifndef _PM_DOMAIN_H +#define _PM_DOMAIN_H + +enum gpd_status { + GPD_STATE_ACTIVE = 0, /* PM domain is active */ + GPD_STATE_POWER_OFF, /* PM domain is off */ +}; + +struct generic_pm_domain { + const char *name; + struct list_head gpd_list_node; /* Node in the global PM domains list */ + + enum gpd_status status; /* Current state of the domain */ + + int (*power_off)(struct generic_pm_domain *domain); + int (*power_on)(struct generic_pm_domain *domain); +}; + +typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args, + void *data); + +#ifdef CONFIG_PM_GENERIC_DOMAINS + +int genpd_dev_pm_attach(struct device_d *dev); + +/** + * dev_pm_domain_attach - Attach a device to its PM domain. + * @dev: Device to attach. + * @power_on: Used to indicate whether we should power on the device. + * + * The @dev may only be attached to a single PM domain. By iterating through + * the available alternatives we try to find a valid PM domain for the device. + * As attachment succeeds, the ->detach() callback in the struct dev_pm_domain + * should be assigned by the corresponding attach function. + * + * This function should typically be invoked from subsystem level code during + * the probe phase. Especially for those that holds devices which requires + * power management through PM domains. + * + * Callers must ensure proper synchronization of this function with power + * management callbacks. + * + * Returns 0 on successfully attached PM domain or negative error code. + */ +static inline int dev_pm_domain_attach(struct device_d *dev, bool power_on) +{ + return genpd_dev_pm_attach(dev); +} + +int pm_genpd_init(struct generic_pm_domain *genpd, void *gov, bool is_off); + +int of_genpd_add_provider_simple(struct device_node *np, + struct generic_pm_domain *genpd); + +#else + +static inline int pm_genpd_init(struct generic_pm_domain *genpd, + void *gov, bool is_off) +{ + return -ENOSYS; +} + +static inline int genpd_dev_pm_attach(struct device_d *dev) +{ + return 0; +} + +static inline int dev_pm_domain_attach(struct device_d *dev, bool power_on) +{ + return 0; +} + +static inline int +of_genpd_add_provider_simple(struct device_node *np, + struct generic_pm_domain *genpd) +{ + return -ENOTSUPP; +} + +#endif + +#endif
\ No newline at end of file diff --git a/include/regulator.h b/include/regulator.h index 367e13f05b..cd1d3ccf55 100644 --- a/include/regulator.h +++ b/include/regulator.h @@ -4,8 +4,28 @@ /* struct regulator is an opaque object for consumers */ struct regulator; +struct regulator_desc { + unsigned n_voltages; + const struct regulator_ops *ops; + + unsigned int min_uV; + unsigned int uV_step; + unsigned int linear_min_sel; + + unsigned int vsel_reg; + unsigned int vsel_mask; + unsigned int apply_reg; + unsigned int apply_bit; + unsigned int enable_reg; + unsigned int enable_mask; + unsigned int enable_val; + unsigned int disable_val; + bool enable_is_inverted; +}; + struct regulator_dev { - struct regulator_ops *ops; + const struct regulator_desc *desc; + struct regmap *regmap; int boot_on; }; @@ -14,6 +34,9 @@ struct regulator_ops { int (*enable) (struct regulator_dev *); int (*disable) (struct regulator_dev *); int (*is_enabled) (struct regulator_dev *); + + int (*list_voltage) (struct regulator_dev *, unsigned int); + int (*set_voltage_sel) (struct regulator_dev *, unsigned int); }; #ifdef CONFIG_OFDEVICE @@ -35,7 +58,15 @@ void regulators_print(void); struct regulator *regulator_get(struct device_d *, const char *); int regulator_enable(struct regulator *); int regulator_disable(struct regulator *); - +int regulator_is_enabled_regmap(struct regulator_dev *); +int regulator_enable_regmap(struct regulator_dev *); +int regulator_disable_regmap(struct regulator_dev *); +int regulator_set_voltage_sel_regmap(struct regulator_dev *, unsigned); +int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); +int regulator_map_voltage_linear(struct regulator_dev *rdev, + int min_uV, int max_uV); +int regulator_list_voltage_linear(struct regulator_dev *rdev, + unsigned int selector); #else static inline struct regulator *regulator_get(struct device_d *dev, const char *id) @@ -53,6 +84,12 @@ static inline int regulator_disable(struct regulator *r) return 0; } +static inline int regulator_set_voltage(struct regulator *regulator, + int min_uV, int max_uV) +{ + return 0; +} + #endif #endif /* __REGULATOR_H */ diff --git a/scripts/bareboxenv.c b/scripts/bareboxenv.c index e95bdeaa5e..c512a105ef 100644 --- a/scripts/bareboxenv.c +++ b/scripts/bareboxenv.c @@ -97,16 +97,6 @@ static char *concat_subpath_file(const char *path, const char *f) return concat_path_file(path, f); } -static char *xstrdup(const char *s) -{ - int len = strlen(s) + 1; - char *d = xmalloc(len); - - memcpy(d, s, len); - - return d; -} - #include <linux/list.h> #include <linux/list_sort.h> #include "../lib/list_sort.c" diff --git a/scripts/fix_size.c b/scripts/fix_size.c index 7014a3faf6..cb074e3cbc 100644 --- a/scripts/fix_size.c +++ b/scripts/fix_size.c @@ -68,11 +68,12 @@ int main(int argc, char**argv) } if (strcmp(magic, "barebox")) { - fprintf(stderr, "invalid magic\n"); - if (ignore_unknown) + if (ignore_unknown) { ret = 0; - else + } else { + fprintf(stderr, "invalid magic\n"); ret = 1; + } goto err; } diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c index 34a072039d..a7f1421fa3 100644 --- a/scripts/imx/imx-image.c +++ b/scripts/imx/imx-image.c @@ -153,7 +153,8 @@ static int extract_key(const char *certfile, uint8_t **modulus, int *modulus_len fp = fopen(certfile, "r"); if (!fp) { - fprintf(stderr, "unable to open certfile: %s\n", certfile); + fprintf(stderr, "unable to open certfile %s: %s\n", certfile, + strerror(errno)); return -errno; } @@ -458,7 +459,8 @@ static void write_dcd(const char *outfile) outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (outfd < 0) { - perror("open"); + fprintf(stderr, "Cannot open %s for wrinting: %s\n", outfile, + strerror(errno)); exit(1); } @@ -671,6 +673,11 @@ static int hab_sign(struct config_data *data) } outfd = open(data->outfile, O_WRONLY | O_APPEND); + if (outfd < 0) { + fprintf(stderr, "Cannot open %s for writing: %s\n", data->outfile, + strerror(errno)); + exit(1); + } ret = xwrite(outfd, buf, csf_space); if (ret < 0) { @@ -687,7 +694,7 @@ static int hab_sign(struct config_data *data) return 0; } -static void *read_file(const char *filename, size_t *size) +static void *xread_file(const char *filename, size_t *size) { int fd, ret; void *buf; @@ -695,18 +702,22 @@ static void *read_file(const char *filename, size_t *size) fd = open(filename, O_RDONLY); if (fd < 0) { - perror("open"); + fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno)); exit(1); } ret = fstat(fd, &s); - if (ret) - return NULL; + if (ret) { + fprintf(stderr, "Cannot stat %s: %s\n", filename, strerror(errno)); + exit(1); + } *size = s.st_size; buf = malloc(*size); - if (!buf) + if (!buf) { + perror("malloc"); exit(1); + } xread(fd, buf, *size); @@ -877,12 +888,8 @@ int main(int argc, char *argv[]) if (data.signed_hdmi_firmware_file) { free(buf); - buf = read_file(data.signed_hdmi_firmware_file, + buf = xread_file(data.signed_hdmi_firmware_file, &signed_hdmi_firmware_size); - if (!buf) { - perror("read_file"); - exit(1); - } signed_hdmi_firmware_size = roundup(signed_hdmi_firmware_size, @@ -924,13 +931,12 @@ int main(int argc, char *argv[]) bb_header[0] = data.first_opcode; bb_header[ARM_HEAD_SIZE_INDEX] = barebox_image_size; - infile = read_file(imagename, &insize); - if (!infile) - exit(1); + infile = xread_file(imagename, &insize); outfd = open(data.outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (outfd < 0) { - perror("open"); + fprintf(stderr, "Cannot open %s for writing: %s\n", data.outfile, + strerror(errno)); exit(1); } @@ -990,7 +996,7 @@ int main(int argc, char *argv[]) if (create_usb_image) { uint32_t *dcd; - infile = read_file(data.outfile, &insize); + infile = xread_file(data.outfile, &insize); dcd = infile + dcd_ptr_offset; *dcd = dcd_ptr_content; |