diff --git a/arch/arm/cpu/armv8/imx8m/Kconfig b/arch/arm/cpu/armv8/imx8m/Kconfig index b28be0eee0e1a0f9acd2aa15d047226a257df0fb..09f4b734591d61c29d3cbb0b0793db2628f30f9e 100644 --- a/arch/arm/cpu/armv8/imx8m/Kconfig +++ b/arch/arm/cpu/armv8/imx8m/Kconfig @@ -90,6 +90,12 @@ config TARGET_EMCRAFT_IMX8M_LPDDR4_800MHZ_2GB_SOM endchoice +config TARGET_PURISM_LIBREM5_DEVKIT + bool "Purism Librem5 devkit" + select IMX8M + select IMX8MQ + select SUPPORT_SPL + config SYS_SOC default "imx8m" @@ -99,5 +105,6 @@ source "board/freescale/imx8mq_arm2/Kconfig" source "board/freescale/imx8mm_evk/Kconfig" source "board/freescale/imx8mm_val/Kconfig" source "board/emcraft/imx8m_som/Kconfig" +source "board/purism/librem5/Kconfig" endif diff --git a/board/purism/common b/board/purism/common new file mode 120000 index 0000000000000000000000000000000000000000..75060789860dbed9f7a1e08edfff5dfa397ee035 --- /dev/null +++ b/board/purism/common @@ -0,0 +1 @@ +../freescale/common \ No newline at end of file diff --git a/board/purism/librem5/Kconfig b/board/purism/librem5/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..8597d85319392307d97929513b5b83a8a6500edc --- /dev/null +++ b/board/purism/librem5/Kconfig @@ -0,0 +1,15 @@ +if TARGET_PURISM_LIBREM5_DEVKIT + +config SYS_BOARD + default "librem5" + +config SYS_VENDOR + default "purism" + +config SYS_CONFIG_NAME + default "librem5" + +config M4_LOAD_DDR_TRAINING + bool "Use the M4 to load the DDR training firmware" + +endif diff --git a/board/purism/librem5/Makefile b/board/purism/librem5/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..efbeb7eebc8c6baf0572202fa78b9a696f6c4afe --- /dev/null +++ b/board/purism/librem5/Makefile @@ -0,0 +1,13 @@ +# +# Copyright 2016 Freescale Semiconductor +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += imx8m_som.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +obj-y += ddr/lpddr4_3gb/ddr_init.o ddr/lpddr4_3gb/ddrphy_train.o \ + ddr/lpddr4_3gb/helper.o +endif diff --git a/board/purism/librem5/ddr/lpddr4_3gb/ddr.h b/board/purism/librem5/ddr/lpddr4_3gb/ddr.h new file mode 100644 index 0000000000000000000000000000000000000000..9acb29c7a5f92a3416fcbefc4eaa64b34e9100ca --- /dev/null +++ b/board/purism/librem5/ddr/lpddr4_3gb/ddr.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +enum fw_type { + FW_1D_IMAGE, + FW_2D_IMAGE, +}; + +void ddr_init(void); +void ddr_load_train_code(enum fw_type type); +void lpddr4_800M_cfg_phy(void); + +static inline void reg32_write(unsigned long addr, u32 val) +{ + writel(val, addr); +} + +static inline uint32_t reg32_read(unsigned long addr) +{ + return readl(addr); +} + +static void inline dwc_ddrphy_apb_wr(unsigned long addr, u32 val) +{ + writel(val, addr); +} + +static inline void reg32setbit(unsigned long addr, u32 bit) +{ + setbits_le32(addr, (1 << bit)); +} diff --git a/board/purism/librem5/ddr/lpddr4_3gb/ddr_init.c b/board/purism/librem5/ddr/lpddr4_3gb/ddr_init.c new file mode 100644 index 0000000000000000000000000000000000000000..2e05b02e0a586400f2e74354a1b71584db0193f6 --- /dev/null +++ b/board/purism/librem5/ddr/lpddr4_3gb/ddr_init.c @@ -0,0 +1,244 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Generated code from MX8M_DDR_tool + */ + +#include +#include +#include +#include +#include +#include "ddr.h" + +#ifdef CONFIG_ENABLE_DDR_TRAINING_DEBUG +#define ddr_printf(args...) printf(args) +#else +#define ddr_printf(args...) +#endif + +#include "wait_ddrphy_training_complete.c" +#ifndef SRC_DDRC_RCR_ADDR +#define SRC_DDRC_RCR_ADDR SRC_IPS_BASE_ADDR +0x1000 +#endif +#ifndef DDR_CSD1_BASE_ADDR +#define DDR_CSD1_BASE_ADDR 0x40000000 +#endif +#define SILICON_TRAIN + +void ddr_cfg_phy(void); +volatile unsigned int tmp, tmp_t, i; +void ddr_init(void) +{ + /** 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,0x15); + reg32_write(0x3d40020c,0x0); + reg32_write(0x3d400210,0x1f1f); + reg32_write(0x3d400204,0x80808); + reg32_write(0x3d400214,0x7070707); + reg32_write(0x3d400218,0x48080707); + 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/board/purism/librem5/ddr/lpddr4_3gb/ddrphy_train.c b/board/purism/librem5/ddr/lpddr4_3gb/ddrphy_train.c new file mode 100644 index 0000000000000000000000000000000000000000..bc3e1c3f1a48603004aa9698a7a5eec713b33ce0 --- /dev/null +++ b/board/purism/librem5/ddr/lpddr4_3gb/ddrphy_train.c @@ -0,0 +1,939 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Generated code from MX8M_DDR_tool + */ + +#include +#include +#include +#include "ddr.h" + +extern void wait_ddrphy_training_complete(void); +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/board/purism/librem5/ddr/lpddr4_3gb/helper.c b/board/purism/librem5/ddr/lpddr4_3gb/helper.c new file mode 100644 index 0000000000000000000000000000000000000000..0f48b8ec17f3d793d4e2cbdada89dd4d9bedc9bd --- /dev/null +++ b/board/purism/librem5/ddr/lpddr4_3gb/helper.c @@ -0,0 +1,456 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ddr.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define OCRAM_BASE 0x900000 +#define OCRAM_SIZE (128*1024) + +#define TCML_BASE 0x7e0000 +#define TCMU_BASE 0x800000 +#define TCMU_SIZE 0x20000 +#define TCMU_CMD_M4 (TCMU_BASE + TCMU_SIZE - 24) /* command mailbox */ +#define TCMU_ARG_M4 (TCMU_BASE + TCMU_SIZE - 20) /* arg mailbox */ +#define TCMU_ST_M4 (TCMU_BASE + TCMU_SIZE - 16) /* status mailbox */ +#define TCMU_CMD_A53 (TCMU_BASE + TCMU_SIZE - 12) /* command mailbox */ +#define TCMU_ARG_A53 (TCMU_BASE + TCMU_SIZE - 8) /* arg mailbox */ +#define TCMU_ST_A53 (TCMU_BASE + TCMU_SIZE - 4) /* status mailbox */ + +#define CMD_NONE 0 +#define CMD_READY 1 +#define CMD_WRITE_FW 2 +#define ST_NONE 0 +#define ST_READY 1 +#define ST_FAIL 2 +#define ST_SUCCESS 3 +#define ST_BUSY 4 +#define ST_EXCEPT 5 + +#define IMEM_LEN 32768//23400 //byte +#define DMEM_LEN 16384//1720 //byte +#define IMEM_2D_OFFSET 49152 +#define FIRMWARE_BASE (OCRAM_BASE + OCRAM_SIZE / 2) + +#define IMEM_OFFSET_ADDR 0x00050000 +#define DMEM_OFFSET_ADDR 0x00054000 +#define DDR_TRAIN_CODE_BASE_ADDR IP2APB_DDRPHY_IPS_BASE_ADDR(0) + +struct aipstz_regs { + u32 mprot0; + u32 mprot1; + u32 rsvd[0xe]; + u32 opacr0; + u32 opacr1; + u32 opacr2; + u32 opacr3; + u32 opacr4; +}; + +/* We need PHY iMEM PHY is 32KB padded */ +void old_ddr_load_train_code(enum fw_type type) +{ + u32 tmp32, i; + u32 error = 0; + unsigned long pr_to32, pr_from32; + unsigned long fw_offset = type ? IMEM_2D_OFFSET : 0; + unsigned long imem_start = (unsigned long)&_end + fw_offset; + unsigned long dmem_start = imem_start + IMEM_LEN; + + pr_from32 = imem_start; + pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * IMEM_OFFSET_ADDR; + for(i = 0x0; i < IMEM_LEN; ){ + tmp32 = readl(pr_from32); + writew(tmp32 & 0x0000ffff, pr_to32); + pr_to32 += 4; + writew((tmp32 >> 16) & 0x0000ffff, pr_to32); + pr_to32 += 4; + pr_from32 += 4; + i += 4; + } + + pr_from32 = dmem_start; + pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * DMEM_OFFSET_ADDR; + for(i = 0x0; i < DMEM_LEN;){ + tmp32 = readl(pr_from32); + writew(tmp32 & 0x0000ffff, pr_to32); + pr_to32 += 4; + writew((tmp32 >> 16) & 0x0000ffff, pr_to32); + pr_to32 += 4; + pr_from32 += 4; + i += 4; + } + + printf("check ddr4_pmu_train_imem code\n"); + pr_from32 = imem_start; + pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * IMEM_OFFSET_ADDR; + for(i = 0x0; i < IMEM_LEN;){ + tmp32 = (readw(pr_to32) & 0x0000ffff); + pr_to32 += 4; + tmp32 += ((readw(pr_to32) & 0x0000ffff) << 16); + + if(tmp32 != readl(pr_from32)){ + printf("%lx %lx\n", pr_from32, pr_to32); + error++; + } + pr_from32 += 4; + pr_to32 += 4; + i += 4; + } + if(error){ + printf("check ddr4_pmu_train_imem code fail=%d\n",error); + }else{ + printf("check ddr4_pmu_train_imem code pass\n"); + } + + printf("check ddr4_pmu_train_dmem code\n"); + pr_from32 = dmem_start; + pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * DMEM_OFFSET_ADDR; + for(i = 0x0; i < DMEM_LEN;){ + tmp32 = (readw(pr_to32) & 0x0000ffff); + pr_to32 += 4; + tmp32 += ((readw(pr_to32) & 0x0000ffff) << 16); + if(tmp32 != readl(pr_from32)){ + printf("%lx %lx\n", pr_from32, pr_to32); + error++; + } + pr_from32 += 4; + pr_to32 += 4; + i += 4; + } + + if(error){ + printf("check ddr4_pmu_train_dmem code fail=%d",error); + }else{ + printf("check ddr4_pmu_train_dmem code pass\n"); + } +} + +void load_train_code_tcmu(enum fw_type type) +{ + u32 tmp32, i; + unsigned long pr_to32, pr_from32; + unsigned long fw_offset = type ? IMEM_2D_OFFSET : 0; + unsigned long imem_start = (unsigned long)&_end + fw_offset; + unsigned long dmem_start = imem_start + IMEM_LEN; + + printf("copying ddr4_pmu_train_imem code\n"); + pr_from32 = imem_start; + pr_to32 = FIRMWARE_BASE; + for(i = 0x0; i < IMEM_LEN; ){ + tmp32 = readl(pr_from32); + writel(tmp32, pr_to32); + pr_to32 += 4; + pr_from32 += 4; + i += 4; + } + + printf("copying ddr4_pmu_train_dmem code\n"); + pr_from32 = dmem_start; + pr_to32 = FIRMWARE_BASE+IMEM_LEN; + for(i = 0x0; i < DMEM_LEN;){ + tmp32 = readl(pr_from32); + writel(tmp32, pr_to32); + pr_to32 += 4; + pr_from32 += 4; + i += 4; + } +} + +extern int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device); + +int is_mx8(void) +{ + return 1; +} + +void init_aips(void) +{ + struct aipstz_regs *aips[4]; + int num_aips = 2, i; + + aips[0] = (struct aipstz_regs *)AIPS1_BASE_ADDR; + aips[1] = (struct aipstz_regs *)AIPS2_BASE_ADDR; + aips[2] = (struct aipstz_regs *)AIPS3_BASE_ADDR; + aips[3] = (struct aipstz_regs *)AIPS4_BASE_ADDR; + + if (is_mx6ull() || is_mx6sx() || is_mx7()) + num_aips = 3; + + if(is_mx8()) + num_aips = 4; + + for( i=0; improt0); + //writel(0x77777777, &aips[i]->mprot1); + + /* + * Set all OPACRx to be non-bufferable, not require + * supervisor privilege level for access,allow for + * write access and untrusted master access. + */ + writel(0x00000000, &aips[i]->opacr0); + writel(0x00000000, &aips[i]->opacr1); + writel(0x00000000, &aips[i]->opacr2); + writel(0x00000000, &aips[i]->opacr3); + writel(0x00000000, &aips[i]->opacr4); + } +} + +#define SRC_M4RCR 0x3039000C + +void M4_load_firmware( enum fw_type type ) +{ +#if defined(CONFIG_M4_LOAD_DDR_TRAINING) + uint32_t status; + + printf("Set A53 ready\n"); + writel(CMD_READY, TCMU_CMD_A53); + + printf("Wait for M4 cmd finished\n"); + status = readl(TCMU_ST_M4); + while(status != ST_FAIL && status != ST_SUCCESS) + { + status = readl(TCMU_ST_M4); + /*if(status == ST_EXCEPT) + { + printf( "M4 Exception : %d\n", readl(TCMU_CMD_M4)); + return; + }*/ + } + + printf("Clear A53 command\n"); + writel(0, TCMU_CMD_A53); + while(status != ST_READY) + status = readl(TCMU_ST_M4); + printf("Cortex M4 synchronized\n"); + + load_train_code_tcmu(type); + writel(type, TCMU_ARG_A53); + writel(0, TCMU_ST_A53); + printf("Cmd write firmware\n"); + writel(CMD_WRITE_FW, TCMU_CMD_A53); + + status = readl(TCMU_ST_M4); + printf("Wait for M4 to complete\n"); + while(status != ST_FAIL && status != ST_SUCCESS) + { + status = readl(TCMU_ST_M4); + /*if(status == ST_EXCEPT) + { + printf( "M4 Exception : %d\n", readl(TCMU_CMD_M4)); + return; + }*/ + } + + /* + printf("ddr trainging code loaded - type 0x%x\n", type); + writel(0, TCMU_CMD_A53); + while(status != ST_READY) + status = readl(TCMU_ST_M4); + */ +#endif +} + +static struct mmc *prepare_mmc_boot_device(void) +{ + struct mmc *mmc; + int err; + int boot_device; + int boot_mode; + __maybe_unused int part; + + printf("Finding MMC device\n"); + + boot_device = spl_boot_device(); + boot_mode = spl_boot_mode(boot_device); + + err = spl_mmc_find_device(&mmc, boot_device); + if (err) { + printf("spl: mmc find device failed with error: %d\n", err); + return NULL; + } + + err = mmc_init(mmc); + if (err) { + printf("spl: mmc init failed with error: %d\n", err); + return NULL; + } + + /* Switch to the same partition as where the SPL is stored */ + if (boot_mode == MMCSD_MODE_EMMCBOOT) { + int part; + part = (mmc->part_config >> 3) & PART_ACCESS_MASK; + if (part == 7) + part = 0; + + printf("spl: switching to mmc hwpartition %d\n", part); + if (CONFIG_IS_ENABLED(MMC_TINY)) { + err = mmc_switch_part(mmc, part); + } else { + err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part); + } + + if (err) { + printf("spl: mmc partition switch failed\n"); + return NULL; + } + } + return mmc; +} + +void start_M4(void) +{ + struct mmc *mmc; + struct blk_desc *block_dev; + void *vect_buffer = (void *)TCML_BASE; + void *buffer = (void *)OCRAM_BASE; + uint32_t status, reg, stack, pc; + int count; +#if 0 + /* use this wait to stop the code for the OpenOCD debugger */ + volatile int i = 0; + + printf("busy wait"); + + while( i==0 ); +#endif + + printf("Setting up AIPS\n"); + init_aips(); + + mmc = prepare_mmc_boot_device(); + if (!mmc) + return; + + printf("Disabling Cortex M4 clock\n"); + clock_enable(CCGR_M4, 0); + + printf("Getting block device\n"); + block_dev = mmc_get_blk_desc(mmc); + printf("Loading Cortex M4 firmware loader\n"); + /* From 2k copy - blocks are 512 bytes each */ + blk_dread(block_dev, 4, 64, buffer); + printf("Loading Cortex M4 exception vectors\n"); + blk_dread(block_dev, 4, 1, vect_buffer); + + printf("Starting Cortex M4 core\n"); + + stack = *(u32 *)buffer; + pc = *(u32 *)(buffer + 4); + + /* Set the stack and pc to M4 bootROM */ + writel(stack, M4_BOOTROM_BASE_ADDR); + writel(pc, M4_BOOTROM_BASE_ADDR + 4); + + printf("Enabling Cortex M4 clock\n"); + clock_enable(CCGR_M4, 1); + + printf("reset M4 core\n"); + reg = readl(SRC_M4RCR); + writel((reg & ~0xF)| 0xa, SRC_M4RCR); + status = readl(TCMU_ST_M4); + + for(count = 0; count < 50000; count++) + { + status = readl(TCMU_ST_M4); + if( status == ST_READY ) + break; + udelay( 10 ); + } + + if(status == ST_READY) { + printf("Cortex M4 ready\n"); + } else { + printf("Cortex M4 NOT ready\n"); + } +} + +#if defined(CONFIG_M4_LOAD_DDR_TRAINING) +void ddr_load_train_code(enum fw_type type) +{ + struct mmc *mmc; + struct blk_desc *block_dev; + void *vect_buffer = (void *)TCML_BASE; + void *buffer = (void *)OCRAM_BASE; + uint32_t status, reg, stack, pc; + int count; + + mmc = prepare_mmc_boot_device(); + if (!mmc) + return; + + printf("Disabling Cortex M4 clock\n"); + clock_enable(CCGR_M4, 0); + + printf("Getting block device\n"); + block_dev = mmc_get_blk_desc(mmc); + printf("Loading Cortex M4 firmware loader\n"); + /* From 2k copy - blocks are 512 bytes each */ + blk_dread(block_dev, 4, 64, buffer); + printf("Loading Cortex M4 exception vectors\n"); + blk_dread(block_dev, 4, 1, vect_buffer); + + printf("Starting Cortex M4 core\n"); + + stack = *(u32 *)buffer; + pc = *(u32 *)(buffer + 4); + + /* Set the stack and pc to M4 bootROM */ + writel(stack, M4_BOOTROM_BASE_ADDR); + writel(pc, M4_BOOTROM_BASE_ADDR + 4); + + printf("Enabling Cortex M4 clock\n"); + clock_enable(CCGR_M4, 1); + + printf("reset M4 core\n"); + reg = readl(SRC_M4RCR); + writel((reg & ~0xF)| 0xa, SRC_M4RCR); + status = readl(TCMU_ST_M4); + + for(count = 0; count < 50000; count++) + { + status = readl(TCMU_ST_M4); + if( status == ST_READY ) + break; + udelay( 10 ); + } + + if(status == ST_READY) { + printf("Cortex M4 ready\n"); + } + else + { + printf("Cortex M4 NOT ready\n"); + } + + //if( boot_M4() == ST_READY ) + M4_load_firmware( type ); +} +#else /* !defined(CONFIG_M4_LOAD_DDR_TRAINING) */ +void ddr_load_train_code(enum fw_type type) +{ + old_ddr_load_train_code(type); +} +#endif diff --git a/board/purism/librem5/ddr/lpddr4_3gb/wait_ddrphy_training_complete.c b/board/purism/librem5/ddr/lpddr4_3gb/wait_ddrphy_training_complete.c new file mode 100644 index 0000000000000000000000000000000000000000..1bb8bc189d08dbe86d92759c53e63366ac5583a8 --- /dev/null +++ b/board/purism/librem5/ddr/lpddr4_3gb/wait_ddrphy_training_complete.c @@ -0,0 +1,96 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +static inline void poll_pmu_message_ready(void) +{ + unsigned int reg; + + do { + reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0004); + } while (reg & 0x1); +} + +static inline void ack_pmu_message_recieve(void) +{ + unsigned int reg; + + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0031,0x0); + + do { + reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0004); + } while (!(reg & 0x1)); + + reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0031,0x1); +} + +static inline unsigned int get_mail(void) +{ + unsigned int reg; + + poll_pmu_message_ready(); + + reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0032); + + ack_pmu_message_recieve(); + + return reg; +} + +static inline unsigned int get_stream_message(void) +{ + unsigned int reg, reg2; + + poll_pmu_message_ready(); + + reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0032); + + reg2 = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0034); + + reg2 = (reg2 << 16) | reg; + + ack_pmu_message_recieve(); + + return reg2; +} + +static inline void decode_major_message(unsigned int mail) +{ + ddr_printf("[PMU Major message = 0x%08x]\n", mail); +} + +static inline void decode_streaming_message(void) +{ + unsigned int string_index, arg __maybe_unused; + int i = 0; + + string_index = get_stream_message(); + ddr_printf(" PMU String index = 0x%08x\n", string_index); + while (i < (string_index & 0xffff)){ + arg = get_stream_message(); + ddr_printf(" arg[%d] = 0x%08x\n", i, arg); + i++; + } + + ddr_printf("\n"); +} + +void wait_ddrphy_training_complete(void) +{ + unsigned int mail; + while (1) { + mail = get_mail(); + decode_major_message(mail); + if (mail == 0x08) { + decode_streaming_message(); + } else if (mail == 0x07) { + /* Training PASS */ + break; + } else if (mail == 0xff) { + printf("Training FAILED\n"); + break; + } + } +} diff --git a/board/purism/librem5/imx8m_som.c b/board/purism/librem5/imx8m_som.c new file mode 100644 index 0000000000000000000000000000000000000000..a9b952ade2d77421a759892384cad8398140b5af --- /dev/null +++ b/board/purism/librem5/imx8m_som.c @@ -0,0 +1,323 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * Copyright 2017 EmCraft Systems + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define QSPI_PAD_CTRL (PAD_CTL_DSE2 | PAD_CTL_HYS) + +#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1) + +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE) + +static iomux_v3_cfg_t const wdog_pads[] = { + IMX8MQ_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), +}; + +#ifdef CONFIG_FSL_QSPI +static iomux_v3_cfg_t const qspi_pads[] = { + IMX8MQ_PAD_NAND_ALE__QSPI_A_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL), + IMX8MQ_PAD_NAND_CE0_B__QSPI_A_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL), + + IMX8MQ_PAD_NAND_DATA00__QSPI_A_DATA0 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA01__QSPI_A_DATA1 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA02__QSPI_A_DATA2 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA03__QSPI_A_DATA3 | MUX_PAD_CTRL(QSPI_PAD_CTRL), +}; + +int board_qspi_init(void) +{ + imx_iomux_v3_setup_multiple_pads(qspi_pads, ARRAY_SIZE(qspi_pads)); + + set_clk_qspi(); + + return 0; +} +#endif + +static iomux_v3_cfg_t const uart_pads[] = { +#if defined(CONFIG_MXC_UART_BASE) + IMX8MQ_PAD_UART1_RXD__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_UART1_TXD__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +#if (CONFIG_MXC_UART_BASE == UART3_BASE_ADDR) + IMX8MQ_PAD_UART3_RXD__UART3_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_UART3_TXD__UART3_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +#endif +#endif +}; + +int board_early_init_f(void) +{ + imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); + + return 0; +} + +#ifdef CONFIG_BOARD_POSTCLK_INIT +int board_postclk_init(void) +{ + /* TODO */ + return 0; +} +#endif + +int dram_init(void) +{ + gd->ram_size = PHYS_SDRAM_SIZE; + + return 0; +} + +#ifdef CONFIG_OF_BOARD_SETUP +int ft_board_setup(void *blob, bd_t *bd) +{ + return 0; +} +#endif + +#ifdef CONFIG_FEC_MXC +#define FEC_RST_PAD IMX_GPIO_NR(1, 9) +static iomux_v3_cfg_t const fec1_rst_pads[] = { + IMX8MQ_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(NO_PAD_CTRL), + IMX8MQ_PAD_GPIO1_IO15__CCM_CLKO2 | MUX_PAD_CTRL(0x1F), +}; + +static void setup_iomux_fec(void) +{ + imx_iomux_v3_setup_multiple_pads(fec1_rst_pads, ARRAY_SIZE(fec1_rst_pads)); + + gpio_request(FEC_RST_PAD, "fec1_rst"); + gpio_direction_output(FEC_RST_PAD, 0); + udelay(500); + gpio_direction_output(FEC_RST_PAD, 1); +} + +static int setup_fec(void) +{ + setup_iomux_fec(); + + /* Use 125M anatop REF_CLK1 for ENET1, not from external */ + clrsetbits_le32(IOMUXC_GPR1, + BIT(13) | BIT(17), 0); + return set_clk_enet(ENET_125MHz); +} + + +int board_phy_config(struct phy_device *phydev) +{ + /* enable rgmii rxc skew and phy mode select to RGMII copper */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); + + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif + +#ifdef CONFIG_USB_DWC3 +#define USB_PHY_CTRL0 0xF0040 +#define USB_PHY_CTRL0_REF_SSP_EN BIT(2) + +#define USB_PHY_CTRL1 0xF0044 +#define USB_PHY_CTRL1_RESET BIT(0) +#define USB_PHY_CTRL1_COMMONONN BIT(1) +#define USB_PHY_CTRL1_ATERESET BIT(3) +#define USB_PHY_CTRL1_VDATSRCENB0 BIT(19) +#define USB_PHY_CTRL1_VDATDETENB0 BIT(20) + +#define USB_PHY_CTRL2 0xF0048 +#define USB_PHY_CTRL2_TXENABLEN0 BIT(8) + +static struct dwc3_device dwc3_device_data = { + .maximum_speed = USB_SPEED_SUPER, + .base = USB1_BASE_ADDR, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 0, + .power_down_scale = 2, +}; + +static void dwc3_nxp_usb_phy_init(struct dwc3_device *dwc3) +{ + u32 RegData; + + RegData = readl(dwc3->base + USB_PHY_CTRL1); + RegData &= ~(USB_PHY_CTRL1_VDATSRCENB0 | USB_PHY_CTRL1_VDATDETENB0 | + USB_PHY_CTRL1_COMMONONN); + RegData |= USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET; + writel(RegData, dwc3->base + USB_PHY_CTRL1); + + RegData = readl(dwc3->base + USB_PHY_CTRL0); + RegData |= USB_PHY_CTRL0_REF_SSP_EN; + writel(RegData, dwc3->base + USB_PHY_CTRL0); + + RegData = readl(dwc3->base + USB_PHY_CTRL2); + RegData |= USB_PHY_CTRL2_TXENABLEN0; + writel(RegData, dwc3->base + USB_PHY_CTRL2); + + RegData = readl(dwc3->base + USB_PHY_CTRL1); + RegData &= ~(USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET); + writel(RegData, dwc3->base + USB_PHY_CTRL1); +} +#endif + +int usb_gadget_handle_interrupts(void) +{ + dwc3_uboot_handle_interrupt(0); + return 0; +} + +#ifdef CONFIG_USB_TCPC +struct tcpc_port port; +struct tcpc_port_config port_config = { + .i2c_bus = 0, + .addr = 0x50, + .port_type = TYPEC_PORT_UFP, + .max_snk_mv = 20000, + .max_snk_ma = 3000, + .max_snk_mw = 15000, + .op_snk_mv = 9000, +}; + +#define USB_TYPEC_SEL IMX_GPIO_NR(3, 15) + +static iomux_v3_cfg_t ss_mux_gpio[] = { + IMX8MQ_PAD_NAND_RE_B__GPIO3_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +void ss_mux_select(enum typec_cc_polarity pol) +{ + if (pol == TYPEC_POLARITY_CC1) + gpio_direction_output(USB_TYPEC_SEL, 1); + else + gpio_direction_output(USB_TYPEC_SEL, 0); +} + +static int setup_typec(void) +{ + int ret; + + imx_iomux_v3_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); + gpio_request(USB_TYPEC_SEL, "typec_sel"); + + ret = tcpc_init(&port, port_config, &ss_mux_select); + if (ret) { + printf("%s: tcpc init failed, err=%d\n", + __func__, ret); + } + + return ret; +} +#endif + +#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_IMX8M) +int board_usb_init(int index, enum usb_init_type init) +{ + int ret = 0; + imx8m_usb_power(index, true); + + if (index == 0 && init == USB_INIT_DEVICE) { +#ifdef CONFIG_USB_TCPC + ret = tcpc_setup_ufp_mode(&port); +#endif + dwc3_nxp_usb_phy_init(&dwc3_device_data); + return dwc3_uboot_init(&dwc3_device_data); + } else if (index == 0 && init == USB_INIT_HOST) { +#ifdef CONFIG_USB_TCPC + ret = tcpc_setup_dfp_mode(&port); +#endif + return ret; + } + + return 0; +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + int ret = 0; + if (index == 0 && init == USB_INIT_DEVICE) { + dwc3_uboot_exit(index); + } else if (index == 0 && init == USB_INIT_HOST) { +#ifdef CONFIG_USB_TCPC + ret = tcpc_disable_src_vbus(&port); +#endif + } + + imx8m_usb_power(index, false); + + return ret; +} +#endif + + +int board_init(void) +{ + board_qspi_init(); + +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + +#ifdef CONFIG_USB_TCPC + setup_typec(); +#endif + return 0; + return 0; +} + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} + +int board_late_init(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; + + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); + + set_wdog_reset(wdog); + +#ifdef CONFIG_ENV_IS_IN_MMC + board_late_mmc_env_init(); +#endif + + return 0; +} + +#ifdef CONFIG_FSL_FASTBOOT +#ifdef CONFIG_ANDROID_RECOVERY +int is_recovery_key_pressing(void) +{ + return 0; /*TODO*/ +} +#endif /*CONFIG_ANDROID_RECOVERY*/ +#endif /*CONFIG_FSL_FASTBOOT*/ diff --git a/board/purism/librem5/spl.c b/board/purism/librem5/spl.c new file mode 100644 index 0000000000000000000000000000000000000000..3a890d90ab5ab3ae647cc7e74ffcc959053aeb71 --- /dev/null +++ b/board/purism/librem5/spl.c @@ -0,0 +1,428 @@ +/* + * Copyright 2017 NXP + * Copyright 2017 EmCraft Systems + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ddr/lpddr4_3gb/ddr.h" + +DECLARE_GLOBAL_DATA_PTR; + +extern int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device); + +void spl_dram_init(void) +{ + /* ddr init */ + ddr_init(); + udelay(100000); + if(0) + { + volatile u32 *addrA = (u32 *)0x40000000; + + volatile u32 *addrB = (u32 *)0x50000000; + + volatile u32 *addr; + + for(addr = addrA; addr < addrB; addr++){ + //*addr = addr; + writel((u64)addr, addr); + } + + + //writel((uint32_t)0, (uint32_t)0x40100000); + + for(addr = addrA; addr < addrB; addr++){ + //readl((uint32_t)addr): + //if(*addr != (uint32_t)addr) + if(readl((u64)addr) != (u64)addr) + { + printf(".................. addr check fail at 0x%llx \n", + (u64)addr); + while(1); + } + } + + printf(".................. 256M addr check pass \n"); + } + + +} + +#define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS) +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | PC, + .gpio_mode = IMX8MQ_PAD_I2C1_SCL__GPIO5_IO14 | PC, + .gp = IMX_GPIO_NR(5, 14), + }, + .sda = { + .i2c_mode = IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | PC, + .gpio_mode = IMX8MQ_PAD_I2C1_SDA__GPIO5_IO15 | PC, + .gp = IMX_GPIO_NR(5, 15), + }, +}; + +#define USDHC1_PWR_GPIO IMX_GPIO_NR(2, 10) +#define USDHC2_PWR_GPIO IMX_GPIO_NR(2, 19) + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC1_BASE_ADDR: + ret = 1; + break; + case USDHC2_BASE_ADDR: + ret = 1; + return ret; + } + + return 1; +} + +#define USDHC1_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \ + PAD_CTL_FSEL1) +#define USDHC0_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \ + PAD_CTL_FSEL0) +#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1) + +static iomux_v3_cfg_t const usdhc1_pads[] = { + IMX8MQ_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA4__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA5__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA6__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA7__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), + IMX8MQ_PAD_SD1_RESET_B__GPIO2_IO10 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc2_pads[] = { + IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC0_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC0_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), /* 0x16 */ + IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC0_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_GPIO1_IO04__USDHC2_VSELECT | MUX_PAD_CTRL(USDHC1_PAD_CTRL), + IMX8MQ_PAD_SD2_RESET_B__GPIO2_IO19 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), +}; + +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC1_BASE_ADDR, 0, 8}, + {USDHC2_BASE_ADDR, 0, 4}, +}; + +int board_mmc_init(bd_t *bis) +{ + int i, ret; + /* + * According to the board_mmc_init() the following map is done: + * (U-Boot device node) (Physical Port) + * mmc0 USDHC1 + * mmc1 USDHC2 + */ + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + printf( "Initializing FSL USDHC port %d\n", i ); + switch (i) { + case 0: + usdhc_cfg[0].sdhc_clk = mxc_get_clock(USDHC1_CLK_ROOT); + imx_iomux_v3_setup_multiple_pads( + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + gpio_request(USDHC1_PWR_GPIO, "usdhc1_reset"); + gpio_direction_output(USDHC1_PWR_GPIO, 0); + udelay(500); + gpio_direction_output(USDHC1_PWR_GPIO, 1); + break; + case 1: + usdhc_cfg[1].sdhc_clk = mxc_get_clock(USDHC2_CLK_ROOT); + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + gpio_request(USDHC2_PWR_GPIO, "usdhc2_reset"); + gpio_direction_output(USDHC2_PWR_GPIO, 0); + udelay(500); + gpio_direction_output(USDHC2_PWR_GPIO, 1); + break; + default: + printf("Warning: you configured more USDHC controllers" + "(%d) than supported by the board\n", i + 1); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) { + printf( "fsl_esdhc_initialize failed\n" ); + return ret; + } + } + + return 0; +} + +#ifdef CONFIG_POWER +#define PWR_EN IMX_GPIO_NR(1, 8) +#define HAPTIC_nEN IMX_GPIO_NR(5, 4) +#define IMU_INT IMX_GPIO_NR(3, 19) +static iomux_v3_cfg_t const pwr_en_pads[] = { + IMX8MQ_PAD_GPIO1_IO08__GPIO1_IO8 | MUX_PAD_CTRL(PAD_CTL_DSE6 | PAD_CTL_FSEL0), + IMX8MQ_PAD_SPDIF_RX__GPIO5_IO4 | MUX_PAD_CTRL(PAD_CTL_DSE6 | PAD_CTL_FSEL1), + IMX8MQ_PAD_SAI5_RXFS__GPIO3_IO19 | MUX_PAD_CTRL(PAD_CTL_FSEL5), +}; + +/* + * set some safe defaults for the battery charger + */ +void init_charger_bq25896(void) +{ + u8 val; + + /* limit the charge current to 1.6A */ + i2c_reg_write(0x68, 0x12, 0x20); + + /* set the max voltage to 4.912V */ + val = i2c_reg_read(0x68, 0x6); + val = (val & 0xFC) | 0x16 << 2; + i2c_reg_write(0x68, 0x6, val); +} + +#define LDO_VOLT_EN (1 << 6) +#define I2C_PMIC 0 +int power_init_board(void) +{ + struct pmic *p; + int ldo[] = {BD71837_LDO5_VOLT, BD71837_LDO6_VOLT, + BD71837_LDO7_VOLT}; + u32 val; + int i, rv; + + /* + * Init PMIC + */ + rv = power_bd71837_init(CONFIG_POWER_BD71837_I2C_BUS); + if (rv) { + printf("%s: power_bd71837_init(%d) error %d\n", __func__, + CONFIG_POWER_BD71837_I2C_BUS, rv); + goto out; + } + + p = pmic_get("BD71837"); + if (!p) { + printf("%s: pmic_get(%s) failed\n", __func__, BD71837_REGULATOR_DRIVER); + rv = -ENODEV; + goto out; + } + + rv = pmic_probe(p); + if (rv) { + printf("%s: pmic_probe() error %d\n", __func__, rv); + goto out; + } + + /* + * Unlock all regs + */ + pmic_reg_write(p, BD71837_REGLOCK, 0); + + /* + * Reconfigure default voltages: + * - BUCK3: VDD_GPU_0V9 (1.00 -> 0.90) + * - BUCK4: VDD_VPU_0V9 (1.00 -> 0.90) + */ + pmic_reg_write(p, BD71837_BUCK3_VOLT_RUN, 0x14); + pmic_reg_write(p, BD71837_BUCK4_VOLT_RUN, 0x14); + + /* + * Enable PHYs voltages: LDO5-7 + */ + for (i = 0; i < ARRAY_SIZE(ldo); i++) { + rv = pmic_reg_read(p, ldo[i], &val); + if (rv) { + printf("%s: pmic_read(%x) error %d\n", __func__, + ldo[i], rv); + continue; + } + + pmic_reg_write(p, ldo[i], val | LDO_VOLT_EN); + } + + imx_iomux_v3_setup_multiple_pads(pwr_en_pads, ARRAY_SIZE(pwr_en_pads)); + + /* set IMU_INT as input */ + gpio_request(IMU_INT, "imu_int"); + gpio_direction_input(IMU_INT); + + /* disable the haptic motor */ + gpio_request(HAPTIC_nEN, "haptic_en"); + gpio_direction_output(HAPTIC_nEN, 1); + + gpio_request(PWR_EN, "pwr_en"); + gpio_direction_output(PWR_EN, 1); + + udelay(500); + + rv = 0; +out: + return rv; +} +#endif + +void spl_board_init(void) +{ +#ifndef CONFIG_SPL_USB_SDP_SUPPORT + /* Serial download mode */ + if (is_usb_boot()) { + puts("Back to ROM, SDP\n"); + restore_boot_params(); + } +#endif + puts("Normal Boot\n"); +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif + +#ifdef CONFIG_USB_TCPC +struct tcpc_port port; +struct tcpc_port_config port_config = { + .i2c_bus = 0, + .addr = 0x50, + .port_type = TYPEC_PORT_UFP, + .max_snk_mv = 20000, + .max_snk_ma = 3000, + .max_snk_mw = 15000, + .op_snk_mv = 9000, +}; + +#define USB_TYPEC_SEL IMX_GPIO_NR(3, 15) + +static iomux_v3_cfg_t ss_mux_gpio[] = { + IMX8MQ_PAD_NAND_RE_B__GPIO3_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +void ss_mux_select(enum typec_cc_polarity pol) +{ + if (pol == TYPEC_POLARITY_CC1) + gpio_direction_output(USB_TYPEC_SEL, 1); + else + gpio_direction_output(USB_TYPEC_SEL, 0); +} + +static int setup_typec(void) +{ + int ret; + + imx_iomux_v3_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); + gpio_request(USB_TYPEC_SEL, "typec_sel"); + + ret = tcpc_init(&port, port_config, &ss_mux_select); + if (ret) { + printf("%s: tcpc init failed, err=%d\n", + __func__, ret); + } + + return ret; +} +#endif + +static int sdp_mmc_init(void) +{ + struct mmc *mmc = NULL; + int err = 0; + + err = spl_mmc_find_device(&mmc, BOOT_DEVICE_MMC1); + if (err) + return err; + + err = mmc_init(mmc); + if (err) { + printf("spl: mmc_init failed: %d\n", err); + } + + return 0; +} + +void board_init_f(ulong dummy) +{ + int ret; + + /* Clear global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + arch_cpu_init(); + + board_early_init_f(); + + timer_init(); + + preloader_console_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + ret = spl_init(); + if (ret) { + debug("spl_init() failed: %d\n", ret); + hang(); + } + + enable_tzc380(); + + printf( "Initializing Charger\n" ); + + /* Adjust pmic voltage VDD_DRAM to 1.0V for DRAM RUN >= 2400MHZ */ + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + + init_charger_bq25896(); + + power_init_board(); + + printf( "Initializing DDR\n" ); + + /* DDR initialization */ + spl_dram_init(); + + if( is_usb_boot() ) { + printf( "MMC init\n" ); + sdp_mmc_init(); + } + + printf( "Board init\n" ); + board_init_r(NULL, 0); + +} + diff --git a/configs/librem5_devkit_base_defconfig b/configs/librem5_devkit_base_defconfig index 3f4e1cda930b51e38257ac156a3945eda3fab66a..c6436ba72e1a1e41a19af4d4e36d9c78d07b2d40 100644 --- a/configs/librem5_devkit_base_defconfig +++ b/configs/librem5_devkit_base_defconfig @@ -1,7 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_IMX8M=y CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_TARGET_EMCRAFT_IMX8M_LPDDR4_3GB_SOM=y +CONFIG_TARGET_PURISM_LIBREM5_DEVKIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg" CONFIG_DEFAULT_FDT_FILE="librem5-evk.dtb" CONFIG_SPL=y diff --git a/configs/librem5_devkit_defconfig b/configs/librem5_devkit_defconfig index b58a1e6fd5179dd0d16c1796ba9dbb182af095b0..f1dbd57b617427177f5251add9e996e95310f245 100644 --- a/configs/librem5_devkit_defconfig +++ b/configs/librem5_devkit_defconfig @@ -1,7 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_IMX8M=y CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_TARGET_EMCRAFT_IMX8M_LPDDR4_3GB_SOM=y +CONFIG_TARGET_PURISM_LIBREM5_DEVKIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg" CONFIG_DEFAULT_FDT_FILE="librem5-evk.dtb" CONFIG_SPL=y diff --git a/include/configs/librem5.h b/include/configs/librem5.h new file mode 100644 index 0000000000000000000000000000000000000000..62865b44676bbfaed0e1354898bea12be2d0a145 --- /dev/null +++ b/include/configs/librem5.h @@ -0,0 +1,310 @@ +/* + * Copyright 2017 NXP + * Copyright 2018 Emcraft Systems + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __IMX8M_SOM_H +#define __IMX8M_SOM_H + +/* #define DEBUG */ + +#include +#include + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_CSF_SIZE 0x2000 /* 8K region */ +#endif + +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_TEXT_BASE 0x7E1000 +#define CONFIG_SPL_MAX_SIZE (124 * 1024) +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 + +#ifdef CONFIG_SPL_BUILD +/*#define CONFIG_ENABLE_DDR_TRAINING_DEBUG*/ +#define CONFIG_SPL_THERM_SUPPORT +#define CONFIG_SPL_WATCHDOG_SUPPORT +#define CONFIG_SPL_DRIVERS_MISC_SUPPORT +#define CONFIG_SPL_POWER_SUPPORT +#define CONFIG_SPL_I2C_SUPPORT +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds" +#define CONFIG_SPL_STACK 0x187FF0 +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SPL_BSS_START_ADDR 0x00180000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x2000 /* 8 KB */ +#define CONFIG_SPL_STACK_R_ADDR 0x42300000 +#define CONFIG_SPL_STACK_R +#define CONFIG_SPL_SEPARATE_BSS +#define CONFIG_SYS_SPL_MALLOC_START 0x42200000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 /* 512 KB */ +#define CONFIG_SYS_ICACHE_OFF +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_MALLOC_F_ADDR 0x182000 /* malloc f used before GD_FLG_FULL_MALLOC_INIT set */ + +#define CONFIG_SPL_ABORT_ON_RAW_IMAGE /* For RAW image gives a error info not panic */ + +#undef CONFIG_DM_MMC +#undef CONFIG_DM_PMIC +#undef CONFIG_DM_PMIC_PFUZE100 + +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ + +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_BD71837 +#define CONFIG_POWER_BD71837_I2C_BUS 0 +#define CONFIG_POWER_BD71837_I2C_ADDR 0x4B + +#if defined(CONFIG_NAND_BOOT) +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_DMA_SUPPORT +#define CONFIG_SPL_NAND_MXS +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x8000000 /* Put the FIT out of first 128MB boot area */ +#endif +#define CONFIG_SPL_DMA_SUPPORT + +#endif /* CONFIG_SPL_BUILD*/ + +#define CONFIG_REMAKE_ELF + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_POSTCLK_INIT +#define CONFIG_BOARD_LATE_INIT + +/* Flat Device Tree Definitions */ +#define CONFIG_OF_BOARD_SETUP + +#undef CONFIG_CMD_EXPORTENV +#undef CONFIG_CMD_IMPORTENV +#undef CONFIG_CMD_IMLS + +#undef CONFIG_CMD_CRC32 +#undef CONFIG_BOOTM_NETBSD + +/* ENET Config */ +/* ENET1 */ +#if defined(CONFIG_CMD_NET) +#define CONFIG_MII +#define CONFIG_ETHPRIME "FEC" + +#define CONFIG_NET_RANDOM_ETHADDR +#define CONFIG_LIB_RAND + +#define CONFIG_FEC_MXC +#define FEC_QUIRK_ENET_MAC + +#define IMX_FEC_BASE 0x30BE0000 + +#define CONFIG_PHYLIB + +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_PHY_REALTEK +#define CONFIG_FEC_MXC_PHYADDR 1 + +#endif + +#define CONFIG_CMD_USB +#define CONFIG_CMD_MMC + +#ifndef CONFIG_SPL_BUILD +#include +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(MMC, mmc, 1) \ + func(USB, usb, 0) \ + func(PXE, pxe, na) \ + func(DHCP, dhcp, na) +#include +#else +#define BOOTENV +#endif + +#ifdef CONFIG_NAND_BOOT +#define MFG_NAND_PARTITION "mtdparts=gpmi-nand:64m(boot),16m(fit),32m(kernel),16m(dtb),8m(misc),-(rootfs) " +#else +#define MFG_NAND_PARTITION "" +#endif + +#define CONFIG_MFG_ENV_SETTINGS \ + "mfgtool_args=setenv bootargs console=${console},${baudrate} " \ + "rdinit=/linuxrc " \ + "g_mass_storage.stall=0 g_mass_storage.removable=1 " \ + "g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF "\ + "g_mass_storage.iSerialNumber=\"\" "\ + MFG_NAND_PARTITION \ + "clk_ignore_unused "\ + "\0" \ + "initrd_addr=0x43800000\0" \ + "initrd_high=0xffffffff\0" \ + "bootcmd_mfg=run mfgtool_args;booti ${loadaddr} ${initrd_addr} ${fdt_addr};\0" \ + +/* Initial environment variables */ +#if defined(CONFIG_NAND_BOOT) +#define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_MFG_ENV_SETTINGS \ + "fdt_addr=0x43000000\0" \ + "fdt_high=0xffffffffffffffff\0" \ + "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200\0" \ + "bootargs=console=${console} ubi.mtd=5 " \ + "root=ubi0:rootfs rootfstype=ubifs " \ + MFG_NAND_PARTITION \ + "\0" \ + "bootcmd=nand read ${loadaddr} 0x5000000 0x1400000;"\ + "nand read ${fdt_addr} 0x7000000 0x100000;"\ + "booti ${loadaddr} - ${fdt_addr}" + +#else +#define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_MFG_ENV_SETTINGS \ + "scriptaddr=0x80000000\0" \ + "pxefile_addr_r=0x80100000\0" \ + "kernel_addr_r=0x80800000\0" \ + "fdt_addr_r=0x83000000\0" \ + "ramdisk_addr_r=0x83800000\0" \ + "console=ttymxc0,115200\0" \ + BOOTENV +#endif + +/* Link Definitions */ +/* TODO: replace addresses with 0x8... definitions found used in practice? */ +#define CONFIG_LOADADDR 0x40480000 +#define CONFIG_SYS_TEXT_BASE 0x40200000 + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 +#define CONFIG_SYS_INIT_RAM_SIZE 0x80000 +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +#define CONFIG_ENV_OVERWRITE +#define CONFIG_ENV_OFFSET (64 * SZ_64K) +#define CONFIG_ENV_SIZE 0x1000 +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC2 */ +#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */ + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN ((CONFIG_ENV_SIZE + (2*1024)) * 1024) + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define PHYS_SDRAM 0x40000000 +#define PHYS_SDRAM_SIZE 0xc0000000 /* 3GB LPDDR4 one Rank */ +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_SYS_MEMTEST_START 0x40000000 +/* Save upper 2MB for U-Boot code and data */ +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + \ + PHYS_SDRAM_SIZE - 32*1024*1024) +#define CONFIG_SYS_ALT_MEMTEST + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_MXC_UART +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR + +/* Monitor Command Prompt */ +#undef CONFIG_SYS_PROMPT +#define CONFIG_SYS_PROMPT "u-boot=> " +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_CBSIZE 1024 +#define CONFIG_SYS_MAXARGS 64 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_IMX_BOOTAUX + +#define CONFIG_FSL_ESDHC +#define CONFIG_FSL_USDHC + +#define CONFIG_SYS_FSL_USDHC_NUM 2 +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 + +#define CONFIG_CMD_EXT4_WRITE + +#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */ +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 + +#define CONFIG_FSL_QSPI /* enable the QUADSPI driver */ + +#ifdef CONFIG_FSL_QSPI +#define CONFIG_CMD_SF +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_GIGADEVICE +#define CONFIG_SF_DEFAULT_BUS 0 +#define CONFIG_SF_DEFAULT_CS 1 +#define CONFIG_SF_DEFAULT_SPEED 40000000 +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 + +#define FSL_QSPI_FLASH_SIZE (SZ_2M) +#define FSL_QSPI_FLASH_NUM 2 +#endif + +#define CONFIG_MXC_GPIO + +#define CONFIG_MXC_OCOTP +#define CONFIG_CMD_FUSE + +/* I2C Configs */ +#define CONFIG_SYS_I2C_SPEED 100000 + +/* USB configs */ +#ifndef CONFIG_SPL_BUILD +#define CONFIG_HAS_FSL_XHCI_USB + +#ifdef CONFIG_HAS_FSL_XHCI_USB +#define CONFIG_USB_XHCI_IMX8M +#define CONFIG_USB_XHCI_DWC3 +#define CONFIG_USB_XHCI_HCD +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 +#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 +#endif + +#define CONFIG_USB_STORAGE + +#define CONFIG_USBD_HS + +/* +#define CONFIG_USB_DWC3 +#define CONFIG_USB_DWC3_GADGET +#define CONFIG_USB_GADGET +#define CONFIG_CMD_USB_MASS_STORAGE +#define CONFIG_USB_GADGET_MASS_STORAGE +#define CONFIG_USB_GADGET_DOWNLOAD +*/ +#define CONFIG_USB_GADGET_VBUS_DRAW 2 +/* #define CONFIG_USB_GADGET_DUALSPEED +#define CONFIG_USB_FUNCTION_MASS_STORAGE +*/ +/* +#define CONFIG_G_DNL_VENDOR_NUM 0x0525 +#define CONFIG_G_DNL_PRODUCT_NUM 0xa4a5 +#define CONFIG_G_DNL_MANUFACTURER "FSL" +*/ + +#endif + +#define CONFIG_OF_SYSTEM_SETUP + +#endif