From ca1a60b1d254ae18d72e6f3e70c041c313f02756 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 14 Jun 2018 20:44:03 -0700 Subject: ARM: i.MX8: Add DDRC PHY support code Add DDRC PHY support code needed to upload DDR training firwmare as well as to wait for the training process to complete. Those are needed to support board specific DDR initialization code. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/imx8-ddrc.c | 107 +++++++++++++++++++++++++++++ arch/arm/mach-imx/include/mach/imx8-ddrc.h | 66 ++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 arch/arm/mach-imx/imx8-ddrc.c create mode 100644 arch/arm/mach-imx/include/mach/imx8-ddrc.h (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 442039a276..28fe60dba2 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -17,6 +17,7 @@ lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o obj-$(CONFIG_ARCH_IMX7) += imx7.o obj-$(CONFIG_ARCH_VF610) += vf610.o obj-$(CONFIG_ARCH_IMX8MQ) += imx8mq.o +lwl-$(CONFIG_ARCH_IMX8MQ) += imx8-ddrc.o obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o obj-$(CONFIG_IMX_IIM) += iim.o obj-$(CONFIG_NAND_IMX) += nand.o diff --git a/arch/arm/mach-imx/imx8-ddrc.c b/arch/arm/mach-imx/imx8-ddrc.c new file mode 100644 index 0000000000..18454a9153 --- /dev/null +++ b/arch/arm/mach-imx/imx8-ddrc.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include + +void ddrc_phy_load_firmware(void __iomem *phy, + enum ddrc_phy_firmware_offset offset, + const u16 *blob, size_t size) +{ + while (size) { + writew(*blob++, phy + DDRC_PHY_REG(offset)); + offset++; + size -= sizeof(*blob); + } +} + +enum pmc_constants { + PMC_MESSAGE_ID, + PMC_MESSAGE_STREAM, + + PMC_TRAIN_SUCCESS = 0x07, + PMC_TRAIN_STREAM_START = 0x08, + PMC_TRAIN_FAIL = 0xff, +}; + +static u32 ddrc_phy_get_message(void __iomem *phy, int type) +{ + u32 r, message; + + /* + * When BIT0 set to 0, the PMU has a message for the user + * 10ms seems not enough for poll message, so use 1s here. + */ + readl_poll_timeout(phy + DDRC_PHY_REG(0xd0004), + r, !(r & BIT(0)), 0); + + switch (type) { + case PMC_MESSAGE_ID: + /* + * Get the major message ID + */ + message = readl(phy + DDRC_PHY_REG(0xd0032)); + break; + case PMC_MESSAGE_STREAM: + message = readl(phy + DDRC_PHY_REG(0xd0034)); + message <<= 16; + message |= readl(phy + DDRC_PHY_REG(0xd0032)); + break; + } + + /* + * By setting this register to 0, the user acknowledges the + * receipt of the message. + */ + writel(0x00000000, phy + DDRC_PHY_REG(0xd0031)); + /* + * When BIT0 set to 0, the PMU has a message for the user + */ + readl_poll_timeout(phy + DDRC_PHY_REG(0xd0004), + r, r & BIT(0), 0); + + writel(0x00000001, phy + DDRC_PHY_REG(0xd0031)); + + return message; +} + +static void ddrc_phy_fetch_streaming_message(void __iomem *phy) +{ + const u16 index = ddrc_phy_get_message(phy, PMC_MESSAGE_STREAM); + u16 i; + + putc_ll('|'); + puthex_ll(index); + + for (i = 0; i < index; i++) { + const u32 arg = ddrc_phy_get_message(phy, PMC_MESSAGE_STREAM); + + putc_ll('|'); + puthex_ll(arg); + } +} + +void ddrc_phy_wait_training_complete(void __iomem *phy) +{ + for (;;) { + const u32 m = ddrc_phy_get_message(phy, PMC_MESSAGE_ID); + + puthex_ll(m); + + switch (m) { + case PMC_TRAIN_STREAM_START: + ddrc_phy_fetch_streaming_message(phy); + break; + case PMC_TRAIN_SUCCESS: + putc_ll('P'); + putc_ll('\r'); + putc_ll('\n'); + return; + case PMC_TRAIN_FAIL: + putc_ll('F'); + hang(); + } + + putc_ll('\r'); + putc_ll('\n'); + } +} \ No newline at end of file diff --git a/arch/arm/mach-imx/include/mach/imx8-ddrc.h b/arch/arm/mach-imx/include/mach/imx8-ddrc.h new file mode 100644 index 0000000000..d49e29f263 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/imx8-ddrc.h @@ -0,0 +1,66 @@ +#ifndef __IMX8_DDRC_H__ +#define __IMX8_DDRC_H__ + +#include +#include +#include +#include + +enum ddrc_phy_firmware_offset { + DDRC_PHY_IMEM = 0x00050000U, + DDRC_PHY_DMEM = 0x00054000U, +}; + +void ddrc_phy_load_firmware(void __iomem *, + enum ddrc_phy_firmware_offset, + const u16 *, size_t); + +#define DDRC_PHY_REG(x) ((x) * 4) + +void ddrc_phy_wait_training_complete(void __iomem *phy); + + +/* + * i.MX8M DDR Tool compatibility layer + */ + +#define reg32_write(a, v) writel(v, a) +#define reg32_read(a) readl(a) + +static inline void wait_ddrphy_training_complete(void) +{ + ddrc_phy_wait_training_complete(IOMEM(MX8MQ_DDRC_PHY_BASE_ADDR)); +} + +#define __ddr_load_train_code(imem, dmem) \ + do { \ + const u16 *__mem; \ + size_t __size; \ + \ + get_builtin_firmware(imem, &__mem, &__size); \ + ddrc_phy_load_firmware(IOMEM(MX8MQ_DDRC_PHY_BASE_ADDR), \ + DDRC_PHY_IMEM, __mem, __size); \ + \ + get_builtin_firmware(dmem, &__mem, &__size); \ + ddrc_phy_load_firmware(IOMEM(MX8MQ_DDRC_PHY_BASE_ADDR), \ + DDRC_PHY_DMEM, __mem, __size); \ + } while (0) + +#define ddr_load_train_code(imem_dmem) __ddr_load_train_code(imem_dmem) + +#define DDRC_IPS_BASE_ADDR(X) (0x3d400000 + (X * 0x2000000)) + +#define DDRC_STAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x04) +#define DDRC_MRSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x18) +#define DDRC_PWRCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x30) +#define DDRC_RFSHCTL3(X) (DDRC_IPS_BASE_ADDR(X) + 0x60) +#define DDRC_CRCPARSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0xcc) +#define DDRC_DFIMISC(X) (DDRC_IPS_BASE_ADDR(X) + 0x1b0) +#define DDRC_DFISTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x1bc) +#define DDRC_SWCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x320) +#define DDRC_SWSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x324) +#define DDRC_PCTRL_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x490) + +#define IP2APB_DDRPHY_IPS_BASE_ADDR(X) (0x3c000000 + (X * 0x2000000)) + +#endif \ No newline at end of file -- cgit v1.2.3 From d36958f2789e7f627c0aa11dc8082893f8866480 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 14 Jun 2018 20:44:08 -0700 Subject: ARM: i.MX8: Add i.MX8mq EVK support Signed-off-by: Sascha Hauer Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- Documentation/boards/imx.rst | 13 +- Documentation/boards/imx/nxp-imx8mq-evk.rst | 116 +++ arch/arm/boards/Makefile | 1 + arch/arm/boards/nxp-imx8mq-evk/.gitignore | 1 + arch/arm/boards/nxp-imx8mq-evk/Makefile | 4 + arch/arm/boards/nxp-imx8mq-evk/board.c | 44 + arch/arm/boards/nxp-imx8mq-evk/ddr.h | 28 + arch/arm/boards/nxp-imx8mq-evk/ddr_init.c | 223 +++++ arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c | 1026 ++++++++++++++++++++ .../nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg | 4 + arch/arm/boards/nxp-imx8mq-evk/lowlevel.c | 81 ++ arch/arm/dts/Makefile | 1 + arch/arm/dts/imx8mq-evk.dts | 444 +++++++++ arch/arm/mach-imx/Kconfig | 5 + firmware/Kconfig | 3 + firmware/Makefile | 6 + images/Makefile.imx | 7 + 17 files changed, 2006 insertions(+), 1 deletion(-) create mode 100644 Documentation/boards/imx/nxp-imx8mq-evk.rst create mode 100644 arch/arm/boards/nxp-imx8mq-evk/.gitignore create mode 100644 arch/arm/boards/nxp-imx8mq-evk/Makefile create mode 100644 arch/arm/boards/nxp-imx8mq-evk/board.c create mode 100644 arch/arm/boards/nxp-imx8mq-evk/ddr.h create mode 100644 arch/arm/boards/nxp-imx8mq-evk/ddr_init.c create mode 100644 arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c create mode 100644 arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg create mode 100644 arch/arm/boards/nxp-imx8mq-evk/lowlevel.c create mode 100644 arch/arm/dts/imx8mq-evk.dts (limited to 'arch/arm/mach-imx') diff --git a/Documentation/boards/imx.rst b/Documentation/boards/imx.rst index b3002badf1..db889ee702 100644 --- a/Documentation/boards/imx.rst +++ b/Documentation/boards/imx.rst @@ -21,6 +21,7 @@ The Internal Boot Mode is supported on: * i.MX53 * i.MX6 * i.MX7 +* i.MX8MQ With the Internal Boot Mode, the images contain a header which describes where the binary shall be loaded and started. These headers also contain @@ -44,6 +45,15 @@ of the image to the card, use:: dd if=images/barebox-freescale-imx51-babbage.img of=/dev/sdd bs=1024 skip=1 seek=1 +NOTE: MaskROM on i.MX8 expects image to start at +33KiB mark, so the +following command has to be used instead: + + dd if=images/barebox-nxp-imx8mq-evk.img of=/dev/sdd bs=1024 skip=33 seek=33 + +Or, in case of NAND: + + dd if=images/barebox-nxp-imx8mq-evk.img of=/dev/nand bs=1024 skip=33 seek=1 + The images can also always be started second stage:: bootm /mnt/tftp/barebox-freescale-imx51-babbage.img @@ -59,7 +69,8 @@ options in this file are: Header: +----------------+--------------------------------------------------------------+ -| soc | soctype can be one of imx35, imx51, imx53, imx6, imx7, vf610 | +| soc |soctype can be one of imx35, imx51, imx53, imx6, imx7, vf610, | +| | imx8mq | +----------------+--------------------------------------------------------------+ | loadaddr | The address the binary is uploaded to | +----------------+--------------------------------------------------------------+ diff --git a/Documentation/boards/imx/nxp-imx8mq-evk.rst b/Documentation/boards/imx/nxp-imx8mq-evk.rst new file mode 100644 index 0000000000..9dfa911bec --- /dev/null +++ b/Documentation/boards/imx/nxp-imx8mq-evk.rst @@ -0,0 +1,116 @@ +NXP i.MX8MQ EVK Evaluation Board +================================ + +Board comes with: + +* 3GiB of LPDDR4 RAM +* 16GiB eMMC + +Not including booting via serial, the device can boot from either SD or eMMC. + +Downloading DDR PHY 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 +the 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 + +Executing that file should produce a EULA acceptance dialog as well as +result in the following files: + +- lpddr4_pmu_train_1d_dmem.bin +- lpddr4_pmu_train_1d_imem.bin +- lpddr4_pmu_train_2d_dmem.bin +- lpddr4_pmu_train_2d_imem.bin + +As a last step of this process those files need to be placed in +"firmware/imx/":: + + for f in lpddr4_pmu_train_1d_dmem.bin \ + lpddr4_pmu_train_1d_imem.bin \ + 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}; \ + done + +DDR Configuration Code +====================== + +The following two files: + + - ddr_init.c + - ddrphy_train.c + +were obtained by running i.MX 8M DDR Tool that can be found here: + +https://community.nxp.com/docs/DOC-340179 + +Only minimal amount of necessary changes were made to those files. +All of the "impedance matching" code is located in "ddr.h". + +Build Barebox +============= + + make imx_v8_defconfig + make + +Boot Configuration +================== + +The NXM i.MX8MQ EVK Evaluation Board has two switches responsible for +configuring bootsource/boot mode: + + * SW802 for selecting appropriate BMOD + * SW801 for selecting appropriate boot medium + +In order to select internal boot set SW802 as follows:: + + +-----+ + | | + | O | | <--- on = high level + | | | | + | | O | <--- off = low level + | | + | 1 2 | + +-----+ + +Bootsource is the internal eMMC:: + + +---------+ + | | + | | | O | | + | | | | | | <---- eMMC + | O O O O | + | | + | 1 2 3 4 | + +---------+ + +Bootsource is the SD2 slot:: + + +---------+ + | | + | O O | | | + | | | | | | <---- SD2 + | | | O O | + | | + | 1 2 3 4 | + +---------+ + + +Serial boot SW802 setting needed for i.MX8 DDR Tool is as follows:: + + +-----+ + | | + | | O | <--- on = high level + | | | | + | O | | <--- off = low level + | | + | 1 2 | + +-----+ \ No newline at end of file diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index b2fea4a40f..711f9548f9 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_MACH_NVIDIA_BEAVER) += nvidia-beaver/ obj-$(CONFIG_MACH_NVIDIA_JETSON) += nvidia-jetson-tk1/ obj-$(CONFIG_MACH_NXDB500) += netx/ obj-$(CONFIG_MACH_NXP_IMX6ULL_EVK) += nxp-imx6ull-evk/ +obj-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += nxp-imx8mq-evk/ obj-$(CONFIG_MACH_OMAP343xSDP) += omap343xdsp/ obj-$(CONFIG_MACH_OMAP3EVM) += omap3evm/ obj-$(CONFIG_MACH_PANDA) += panda/ diff --git a/arch/arm/boards/nxp-imx8mq-evk/.gitignore b/arch/arm/boards/nxp-imx8mq-evk/.gitignore new file mode 100644 index 0000000000..ef13747c92 --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/.gitignore @@ -0,0 +1 @@ +*.ddr-phy-fw* diff --git a/arch/arm/boards/nxp-imx8mq-evk/Makefile b/arch/arm/boards/nxp-imx8mq-evk/Makefile new file mode 100644 index 0000000000..0546b0b078 --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/Makefile @@ -0,0 +1,4 @@ +obj-y += board.o +lwl-y += lowlevel.o ddr_init.o ddrphy_train.o + + diff --git a/arch/arm/boards/nxp-imx8mq-evk/board.c b/arch/arm/boards/nxp-imx8mq-evk/board.c new file mode 100644 index 0000000000..d93e21da17 --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/board.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation. + * + */ + +#include +#include +#include +#include + +static int imx8mq_evk_mem_init(void) +{ + arm_add_mem_device("ram0", 0x40000000, SZ_2G); + + request_sdram_region("ATF", 0x40000000, SZ_128K); + + return 0; +} +mem_initcall(imx8mq_evk_mem_init); + +static int nxp_imx8mq_evk_init(void) +{ + if (!of_machine_is_compatible("fsl,imx8mq-evk")) + return 0; + + barebox_set_hostname("imx8mq-evk"); + + return 0; +} +device_initcall(nxp_imx8mq_evk_init); diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddr.h b/arch/arm/boards/nxp-imx8mq-evk/ddr.h new file mode 100644 index 0000000000..2c25e3f98c --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/ddr.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2018 Zodiac Inflight Innovation + * Author: Andrey Smirnov + * + * Varios wrappers and macros needed to intgrate code generated by + * i.MX8M DDR Tool into rest of Barebox + */ +#include +#include +#include + +/* + * 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 nxp_imx8mq_evk_ddr_init +#define ddr_cfg_phy nxp_imx8mq_evk_ddr_cfg_phy + +void nxp_imx8mq_evk_ddr_init(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 + + diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c b/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c new file mode 100644 index 0000000000..81691b2fae --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c @@ -0,0 +1,223 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + * Generated code from MX8_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,0xbbe580); + 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,0x83080020); + reg32_write(0x3d400064,0x6100e0); + reg32_write(0x3d4000d0,0xc003061c); + reg32_write(0x3d4000d4,0x9e0000); + reg32_write(0x3d4000dc,0xd4002d); + reg32_write(0x3d4000e0,0x310008); + reg32_write(0x3d4000e8,0x46004d); + reg32_write(0x3d4000ec,0x15004d); + reg32_write(0x3d4000f4,0x639); + reg32_write(0x3d400100,0x1a201b22); + reg32_write(0x3d400104,0x60633); + reg32_write(0x3d400108,0x70e1214); + 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(0x3d400190,0x497820a); + reg32_write(0x3d400194,0x80303); + reg32_write(0x3d4001b4,0x170a); + reg32_write(0x3d4001b0,0x11); + reg32_write(0x3d4001a0,0xe0400018); + reg32_write(0x3d4001a4,0xdf00e4); + reg32_write(0x3d4001a8,0x0); + reg32_write(0x3d4001c0,0x1); + reg32_write(0x3d4001c4,0x1); + reg32_write(0x3d400200,0x15); + reg32_write(0x3d40020c,0x0); + reg32_write(0x3d400210,0x1f1f); + reg32_write(0x3d400204,0x80808); + reg32_write(0x3d400214,0x7070707); + reg32_write(0x3d400218,0x48080707); + reg32_write(0x3d400244,0x0); + reg32_write(0x3d400490,0x1); + reg32_write(0x3d400250,0x29001f01); + reg32_write(0x3d400254,0x2c); + reg32_write(0x3d400264,0x900093e7); + reg32_write(0x3d40026c,0x2005574); + reg32_write(0x3d400400,0x400); + reg32_write(0x3d400408,0x72ff); + reg32_write(0x3d400494,0x10e00); + reg32_write(0x3d400498,0x620096); + reg32_write(0x3d40049c,0x10e00); + reg32_write(0x3d4004a0,0x12c); + reg32_write(0x30391000,0x8f000004); + reg32_write(0x30391000,0x8f000000); + reg32_write(0x3d400304,0x0); + reg32_write(0x3d400030,0xa8); + reg32_write(0x3d400320,0x0); + reg32_write(0x3d000000,0x1); + reg32_write(0x3d4001b0,0x10); + reg32_write(0x3d402100,0xa040305); + reg32_write(0x3d402104,0x30407); + reg32_write(0x3d402108,0x203060b); + reg32_write(0x3d40210c,0x505000); + reg32_write(0x3d402110,0x2040202); + reg32_write(0x3d402114,0x2030202); + reg32_write(0x3d402118,0x1010004); + reg32_write(0x3d40211c,0x301); + reg32_write(0x3d402138,0x1d); + reg32_write(0x3d402144,0x14000a); + reg32_write(0x3d403024,0x30d400); + reg32_write(0x3d402050,0x20d040); + reg32_write(0x3d402190,0x3818200); + reg32_write(0x3d4021b4,0x100); + reg32_write(0x3d402064,0xc001c); + reg32_write(0x3d4020dc,0x840000); + reg32_write(0x3d4020e8,0x46004d); + reg32_write(0x3d4020ec,0x15004d); + reg32_write(0x3d4020e0,0x310000); + reg32_write(0x3d403100,0x6010102); + reg32_write(0x3d403104,0x30404); + reg32_write(0x3d403108,0x203060b); + reg32_write(0x3d40310c,0x505000); + reg32_write(0x3d403110,0x2040202); + reg32_write(0x3d403114,0x2030202); + reg32_write(0x3d403118,0x1010004); + reg32_write(0x3d40311c,0x301); + reg32_write(0x3d403138,0x8); + reg32_write(0x3d403144,0x50003); + reg32_write(0x3d403024,0xc3500); + reg32_write(0x3d403050,0x20d040); + reg32_write(0x3d403190,0x3818200); + reg32_write(0x3d4031b4,0x100); + reg32_write(0x3d403064,0x30007); + reg32_write(0x3d4030dc,0x840000); + reg32_write(0x3d4030e8,0x46004d); + reg32_write(0x3d4030ec,0x15004d); + reg32_write(0x3d4030e0,0x310000); + 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); + tmp = reg32_read(DDRC_CRCPARSTAT(0)); + reg32_write(DDRC_RFSHCTL3(0), 0x00000000); +} \ No newline at end of file diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c b/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c new file mode 100644 index 0000000000..156d7cf87e --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c @@ -0,0 +1,1026 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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(0x3c84017c,0x1ff); + reg32_write(0x3c84057c,0x1ff); + reg32_write(0x3c84417c,0x1ff); + reg32_write(0x3c84457c,0x1ff); + reg32_write(0x3c84817c,0x1ff); + reg32_write(0x3c84857c,0x1ff); + reg32_write(0x3c84c17c,0x1ff); + reg32_write(0x3c84c57c,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(0x3c880314,0x7); + reg32_write(0x3c0800b8,0x2); + reg32_write(0x3c4800b8,0x2); + reg32_write(0x3c8800b8,0x2); + reg32_write(0x3c240810,0x0); + reg32_write(0x3c640810,0x0); + reg32_write(0x3ca40810,0x0); + reg32_write(0x3c080090,0xab); + reg32_write(0x3c0800e8,0x0); + reg32_write(0x3c480090,0xab); + reg32_write(0x3c0800e8,0x0); + reg32_write(0x3c880090,0xab); + reg32_write(0x3c0800e8,0x0); + reg32_write(0x3c080158,0x7); + reg32_write(0x3c480158,0xa); + reg32_write(0x3c880158,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(0x3c840134,0xe00); + reg32_write(0x3c840534,0xe00); + reg32_write(0x3c844134,0xe00); + reg32_write(0x3c844534,0xe00); + reg32_write(0x3c848134,0xe00); + reg32_write(0x3c848534,0xe00); + reg32_write(0x3c84c134,0xe00); + reg32_write(0x3c84c534,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(0x3c840124,0xfbe); + reg32_write(0x3c840524,0xfbe); + reg32_write(0x3c844124,0xfbe); + reg32_write(0x3c844524,0xfbe); + reg32_write(0x3c848124,0xfbe); + reg32_write(0x3c848524,0xfbe); + reg32_write(0x3c84c124,0xfbe); + reg32_write(0x3c84c524,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,0x64); + reg32_write(0x3c880020,0x19); + 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(0x3c8802c8,0xdc); + reg32_write(0x3c84010c,0x5a1); + reg32_write(0x3c84050c,0x5a1); + reg32_write(0x3c84410c,0x5a1); + reg32_write(0x3c84450c,0x5a1); + reg32_write(0x3c84810c,0x5a1); + reg32_write(0x3c84850c,0x5a1); + reg32_write(0x3c84c10c,0x5a1); + reg32_write(0x3c84c50c,0x5a1); + reg32_write(0x3c0803e8,0x1); + reg32_write(0x3c4803e8,0x1); + reg32_write(0x3c8803e8,0x1); + reg32_write(0x3c080064,0x1); + reg32_write(0x3c480064,0x1); + reg32_write(0x3c880064,0x1); + reg32_write(0x3c0803c0,0x660); + reg32_write(0x3c0803c4,0x0); + reg32_write(0x3c0803c8,0x4444); + reg32_write(0x3c0803cc,0x8888); + reg32_write(0x3c0803d0,0x5665); + 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(0x3c8800b4,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 * 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,0x4d46); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401c,0x4d08); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401e,0x15); + 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,0x4d46); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54022,0x4d08); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54024,0x15); + 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,0x4600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54035,0x84d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54036,0x4d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54037,0x1500); + 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,0x4600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403b,0x84d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403c,0x4d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403d,0x1500); + + //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(0x3038a008,0x7070000); + reg32_write(0x3038a004,0x5000000); + reg32_write(0x3038a088,0x7070000); + reg32_write(0x3038a084,0x2010000); + reg32_write(0x303a00ec,0xffff); + tmp=reg32_read(0x303a00f8); + tmp |= 0x20; + reg32_write(0x303a00f8,tmp); + reg32_write(0x30389804,0x1000000); + + //enable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0); + + reg32_write(0x3c150008,0x101); + reg32_write(0x3c15000c,0x190); + reg32_write(0x3c150020,0x121f); + reg32_write(0x3c150064,0x84); + reg32_write(0x3c150068,0x31); + reg32_write(0x3c15006c,0x4d46); + reg32_write(0x3c150070,0x4d08); + reg32_write(0x3c150074,0x0); + reg32_write(0x3c150078,0x15); + reg32_write(0x3c15007c,0x84); + reg32_write(0x3c150080,0x31); + reg32_write(0x3c150084,0x4d46); + reg32_write(0x3c150088,0x4d08); + reg32_write(0x3c15008c,0x0); + reg32_write(0x3c150090,0x15); + reg32_write(0x3c1500c8,0x8400); + reg32_write(0x3c1500cc,0x3100); + reg32_write(0x3c1500d0,0x4600); + reg32_write(0x3c1500d4,0x84d); + reg32_write(0x3c1500d8,0x4d); + reg32_write(0x3c1500dc,0x1500); + reg32_write(0x3c1500e0,0x8400); + reg32_write(0x3c1500e4,0x3100); + 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(); + + //configure DDRPHY-FW DMEM structure @clock2... + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1); + + //set the PHY input clock to the desired frequency for pstate 2 + reg32_write(0x3038a008,0x7070000); + reg32_write(0x3038a004,0x2000000); + reg32_write(0x3038a088,0x7070000); + reg32_write(0x3038a084,0x2010000); + reg32_write(0x303a00ec,0xffff); + tmp=reg32_read(0x303a00f8); + tmp |= 0x20; + reg32_write(0x303a00f8,tmp); + reg32_write(0x30389804,0x1000000); + + //enable APB bus to access DDRPHY RAM + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0); + + reg32_write(0x3c150008,0x102); + reg32_write(0x3c15000c,0x64); + reg32_write(0x3c150020,0x121f); + reg32_write(0x3c150064,0x84); + reg32_write(0x3c150068,0x31); + reg32_write(0x3c15006c,0x4d46); + reg32_write(0x3c150070,0x4d08); + reg32_write(0x3c150074,0x0); + reg32_write(0x3c150078,0x15); + reg32_write(0x3c15007c,0x84); + reg32_write(0x3c150080,0x31); + reg32_write(0x3c150084,0x4d46); + reg32_write(0x3c150088,0x4d08); + reg32_write(0x3c15008c,0x0); + reg32_write(0x3c150090,0x15); + reg32_write(0x3c1500c8,0x8400); + reg32_write(0x3c1500cc,0x3100); + reg32_write(0x3c1500d0,0x4600); + reg32_write(0x3c1500d4,0x84d); + reg32_write(0x3c1500d8,0x4d); + reg32_write(0x3c1500dc,0x1500); + reg32_write(0x3c1500e0,0x8400); + reg32_write(0x3c1500e4,0x3100); + 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,0xbbe580); + 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,0x4d46); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401c,0x4d08); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5401e,0x15); + 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,0x4d46); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54022,0x4d08); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54024,0x15); + 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,0x4600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54035,0x84d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54036,0x4d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54037,0x1500); + 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,0x4600); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403b,0x84d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403c,0x4d); + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x5403d,0x1500); + + //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(0x3c88002c,0x65); + reg32_write(0x3c880030,0xc9); + reg32_write(0x3c880034,0x7d1); + reg32_write(0x3c880038,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(0x3c880040,0x5a); + reg32_write(0x3c880044,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(0x3c900200,0xe0); + reg32_write(0x3c900204,0x12); + reg32_write(0x3c900208,0xe0); + reg32_write(0x3c90020c,0x12); + reg32_write(0x3c900210,0xe0); + reg32_write(0x3c900214,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/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg b/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg new file mode 100644 index 0000000000..a12c28fceb --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg @@ -0,0 +1,4 @@ +soc imx8mq + +loadaddr 0x007E1000 +dcdofs 0x400 diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c new file mode 100644 index 0000000000..1ed918ee0e --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c @@ -0,0 +1,81 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ddr.h" + +extern char __dtb_imx8mq_evk_start[]; + +#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('>'); +} + +static void nxp_imx8mq_evk_sram_setup(void) +{ + enum bootsource src = BOOTSOURCE_UNKNOWN; + int instance = BOOTSOURCE_INSTANCE_UNKNOWN; + int ret = -ENOTSUPP; + + ddr_init(); + + imx8_get_boot_source(&src, &instance); + + if (src == BOOTSOURCE_MMC) + ret = imx8_esdhc_start_image(instance); + + BUG_ON(ret); +} + +ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2) +{ + arm_cpu_lowlevel_init(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + setup_uart(); + + if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR) + nxp_imx8mq_evk_sram_setup(); + + barebox_arm_entry(MX8MQ_DDR_CSD1_BASE_ADDR, + SZ_2G + SZ_1G, __dtb_imx8mq_evk_start); +} + diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b69592e64e..10fcfbf1f3 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -86,6 +86,7 @@ pbl-dtb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += imx6dl-hummingboard.dtb.o imx6q-humm pbl-dtb-$(CONFIG_MACH_TECHNEXION_WANDBOARD) += imx6q-wandboard.dtb.o imx6dl-wandboard.dtb.o pbl-dtb-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += imx6ul-pico-hobbit.dtb.o pbl-dtb-$(CONFIG_MACH_NXP_IMX6ULL_EVK) += imx6ull-14x14-evk.dtb.o +pbl-dtb-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += imx8mq-evk.dtb.o pbl-dtb-$(CONFIG_MACH_TORADEX_COLIBRI_T20) += tegra20-colibri-iris.dtb.o pbl-dtb-$(CONFIG_MACH_TOSHIBA_AC100) += tegra20-paz00.dtb.o pbl-dtb-$(CONFIG_MACH_TQMA53) += imx53-mba53.dtb.o diff --git a/arch/arm/dts/imx8mq-evk.dts b/arch/arm/dts/imx8mq-evk.dts new file mode 100644 index 0000000000..3ac13baa18 --- /dev/null +++ b/arch/arm/dts/imx8mq-evk.dts @@ -0,0 +1,444 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2017 NXP + * Copyright (C) 2017 Pengutronix, Lucas Stach + */ + +/dts-v1/; + +#include "imx8mq.dtsi" + +/ { + model = "NXP i.MX8MQ EVK"; + compatible = "fsl,imx8mq-evk", "fsl,imx8mq"; + + chosen { + stdout-path = &uart1; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x00000000 0x40000000 0 0xc0000000>; + }; + + 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; + }; +}; + +&dcss { + status = "okay"; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1_mdc>, <&pinctrl_fec1_mdio>, + <&pinctrl_fec1_data_tx>, <&pinctrl_fec1_data_rx>, + <&pinctrl_fec1_phy_reset>; + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&hdmi { + status ="okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + 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>; + }; + }; + }; +}; + +&ocotp { + barebox,provide-mac-address = <&fec1 0x640>; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&usb3_phy1 { + status = "okay"; +}; + +&usb3_1 { + status = "okay"; +}; + +&usb_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1_cd_reset>, <&pinctrl_usdhc1_clk_strobe>, + <&pinctrl_usdhc1_data>; + pinctrl-1 = <&pinctrl_usdhc1_cd_reset>, + <&pinctrl_usdhc1_clk_strobe_100mhz>, + <&pinctrl_usdhc1_data_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_cd_reset>, + <&pinctrl_usdhc1_clk_strobe_200mhz>, + <&pinctrl_usdhc1_data_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_vselect>, <&pinctrl_usdhc2_clk>, + <&pinctrl_usdhc2_data>; + pinctrl-1 = <&pinctrl_usdhc2_vselect>, <&pinctrl_usdhc2_clk_100mhz>, + <&pinctrl_usdhc2_data_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_vselect>, <&pinctrl_usdhc2_clk_200mhz>, + <&pinctrl_usdhc2_data_200mhz>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_fec1_mdc: fec1mdcgrp { + pinmux = ; + drive-strength = <3>; + slew-rate = <0>; + }; + + pinctrl_fec1_mdio: fec1mdiogrp { + pinmux = ; + drive-strength = <3>; + slew-rate = <0>; + drive-open-drain; + }; + + pinctrl_fec1_phy_reset: fec1phyresetgrp { + pinmux = ; + drive-strength = <1>; + slew-rate = <0>; + }; + + pinctrl_fec1_data_tx: fec1datatxgrp { + pinmux = < + MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 + MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 + MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 + MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 + MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC + MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL + >; + drive-strength = <7>; + slew-rate = <3>; + }; + + pinctrl_fec1_data_rx: fec1datarxgrp { + pinmux = < + MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 + MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 + MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 + MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 + MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC + MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL + >; + drive-strength = <1>; + slew-rate = <2>; + input-schmitt-enable; + }; + + pinctrl_i2c1: i2c1grp { + pinmux = < + MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL + MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA + >; + drive-strength = <7>; + slew-rate = <0>; + drive-open-drain; + input-enable; + }; + + pinctrl_reg_usdhc2: regusdhc2grpgpio { + pinmux = ; + drive-strength = <1>; + slew-rate = <0>; + bias-pull-up; + }; + + pinctrl_uart1: uart1grp { + pinmux = < + MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX + MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX + >; + drive-strength = <1>; + slew-rate = <0>; + bias-pull-up; + }; + + pinctrl_usdhc1_cd_reset: usdhc1cdgrp { + pinmux = < + MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B + >; + drive-strength = <1>; + slew-rate = <0>; + bias-pull-up; + }; + + pinctrl_usdhc1_clk_strobe: usdhc1clkgrp { + pinmux = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE + >; + drive-strength = <3>; + slew-rate = <0>; + }; + + pinctrl_usdhc1_data: usdhc1datagrp { + pinmux = < + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 + >; + drive-strength = <3>; + slew-rate = <0>; + bias-pull-up; + input-schmitt-enable; + }; + + pinctrl_usdhc1_clk_strobe_100mhz: usdhc1clk100grp { + pinmux = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE + >; + drive-strength = <3>; + slew-rate = <0>; + }; + + pinctrl_usdhc1_data_100mhz: usdhc1data100grp { + pinmux = < + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 + >; + drive-strength = <5>; + slew-rate = <1>; + bias-pull-up; + input-schmitt-enable; + }; + + pinctrl_usdhc1_clk_strobe_200mhz: usdhc1clk200grp { + pinmux = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE + >; + drive-strength = <7>; + slew-rate = <3>; + }; + + pinctrl_usdhc1_data_200mhz: usdhc1data200grp { + pinmux = < + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 + >; + drive-strength = <7>; + slew-rate = <3>; + bias-pull-up; + input-schmitt-enable; + }; + + pinctrl_usdhc2_vselect: usdhc2vselectgrp { + pinmux = ; + drive-strength = <1>; + slew-rate = <0>; + bias-pull-up; + }; + + pinctrl_usdhc2_clk: usdhc2clkgrp { + pinmux = ; + drive-strength = <3>; + slew-rate = <0>; + }; + + pinctrl_usdhc2_data: usdhc2datagrp { + pinmux = < + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 + >; + drive-strength = <3>; + slew-rate = <0>; + bias-pull-up; + input-schmitt-enable; + }; + + pinctrl_usdhc2_clk_100mhz: usdhc2clk100grp { + pinmux = ; + drive-strength = <5>; + slew-rate = <1>; + }; + + pinctrl_usdhc2_data_100mhz: usdhc2data100grp { + pinmux = < + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 + >; + drive-strength = <5>; + slew-rate = <1>; + bias-pull-up; + input-schmitt-enable; + }; + + pinctrl_usdhc2_clk_200mhz: usdhc2clk200grp { + pinmux = ; + drive-strength = <7>; + slew-rate = <3>; + }; + + pinctrl_usdhc2_data_200mhz: usdhc2data200grp { + pinmux = < + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 + >; + drive-strength = <7>; + slew-rate = <3>; + bias-pull-up; + input-schmitt-enable; + }; + + pinctrl_wdog: wdoggrp { + pinmux = ; + drive-strength = <6>; + slew-rate = <0>; + bias-pull-up; + }; +}; diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index dec5e387e1..a743bbfda7 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -445,6 +445,11 @@ config MACH_NXP_IMX6ULL_EVK bool "NXP i.MX6ull EVK Board" select ARCH_IMX6UL +config MACH_NXP_IMX8MQ_EVK + bool "NXP i.MX8MQ EVK Board" + select ARCH_IMX8MQ + select FIRMWARE_IMX_LPDDR4_PMU_TRAIN + endif # ---------------------------------------------------------- diff --git a/firmware/Kconfig b/firmware/Kconfig index e0cc7abefd..b6449644be 100644 --- a/firmware/Kconfig +++ b/firmware/Kconfig @@ -4,4 +4,7 @@ config EXTRA_FIRMWARE_DIR string "Firmware blobs root directory" default "firmware" +config FIRMWARE_IMX_LPDDR4_PMU_TRAIN + bool + endmenu diff --git a/firmware/Makefile b/firmware/Makefile index 52984fd165..c82e81ae44 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -3,6 +3,12 @@ # kbuild file for firmware/ # +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 + # Create $(fwabs) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a # leading /, it's relative to $(srctree). fwdir := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE_DIR)) diff --git a/images/Makefile.imx b/images/Makefile.imx index 43505b1ff9..0550686a17 100644 --- a/images/Makefile.imx +++ b/images/Makefile.imx @@ -530,7 +530,14 @@ CFG_start_zii_vf610_dev.pblx.imximg = $(board)/zii-vf610-dev/flash-header-zii-vf FILE_barebox-zii-vf610-dev.img = start_zii_vf610_dev.pblx.imximg image-$(CONFIG_MACH_ZII_VF610_DEV) += barebox-zii-vf610-dev.img +# ----------------------- i.MX7 based boards --------------------------- pblx-$(CONFIG_MACH_FREESCALE_MX7_SABRESD) += start_imx7d_sabresd CFG_start_imx7d_sabresd.pblx.imximg = $(board)/freescale-mx7-sabresd/flash-header-mx7-sabresd.imxcfg FILE_barebox-freescale-mx7-sabresd.img = start_imx7d_sabresd.pblx.imximg image-$(CONFIG_MACH_FREESCALE_MX7_SABRESD) += barebox-freescale-mx7-sabresd.img + +# ----------------------- i.MX8mq based boards -------------------------- +pblx-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += start_nxp_imx8mq_evk +CFG_start_nxp_imx8mq_evk.imx-sram-img = $(board)/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg +FILE_barebox-nxp-imx8mq-evk.img = start_nxp_imx8mq_evk.imx-sram-img +image-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += barebox-nxp-imx8mq-evk.img -- cgit v1.2.3