From 27e3a3c7f8a469c61509102a672d210bdff46059 Mon Sep 17 00:00:00 2001 From: "Ye.Li" Date: Sat, 8 Oct 2016 16:58:29 +0800 Subject: imx: mx6sx: Disable ENET clock before switching clock parent Need to gate ENET clock when switching to a new clock parent, because the mux is not glitchless. Signed-off-by: Peng Fan Signed-off-by: Ye.Li Cc: Stefano Babic diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index ae3143c..96fbd81 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -881,6 +881,11 @@ int enable_fec_anatop_clock(int fec_id, enum enet_freq freq) writel(reg, &anatop->pll_enet); #ifdef CONFIG_MX6SX + /* Disable enet system clcok before switching clock parent */ + reg = readl(&imx_ccm->CCGR3); + reg &= ~MXC_CCM_CCGR3_ENET_MASK; + writel(reg, &imx_ccm->CCGR3); + /* * Set enet ahb clock to 200MHz * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB -- cgit v0.10.2 From 97c16dc8bf0981d9c3ba04f1b8cc54b751a00f3f Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 8 Oct 2016 17:03:00 +0800 Subject: imx: mx6ull: update the REFTOP_VBGADJ setting According to design team, we need to set REFTOP_VBGADJ in PMU MISC0 according to the REFTOP_TRIM[2:0] fuse. the actually table is as below: '000" - set REFTOP_VBGADJ[2:0] to 3'b000 '001" - set REFTOP_VBGADJ[2:0] to 3'b001 '010" - set REFTOP_VBGADJ[2:0] to 3'b010 '011" - set REFTOP_VBGADJ[2:0] to 3'b011 '100" - set REFTOP_VBGADJ[2:0] to 3'b100 '101" - set REFTOP_VBGADJ[2:0] to 3'b101 '110" - set REFTOP_VBGADJ[2:0] to 3'b110 '111" - set REFTOP_VBGADJ[2:0] to 3'b111 Signed-off-by: Peng Fan Signed-off-by: Bai Ping diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 7b53bfd..dd94797 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -300,9 +300,17 @@ static void clear_mmdc_ch_mask(void) writel(reg, &mxc_ccm->ccdr); } +#define OCOTP_MEM0_REFTOP_TRIM_SHIFT 8 + static void init_bandgap(void) { struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[1]; + struct fuse_bank1_regs *fuse = + (struct fuse_bank1_regs *)bank->fuse_regs; + uint32_t val; + /* * Ensure the bandgap has stabilized. */ @@ -315,13 +323,26 @@ static void init_bandgap(void) */ writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set); /* - * On i.MX6ULL, the LDO 1.2V bandgap voltage is 30mV higher. so set - * VBGADJ bits to 2b'110 to adjust it. + * On i.MX6ULL,we need to set VBGADJ bits according to the + * REFTOP_TRIM[3:0] in fuse table + * 000 - set REFTOP_VBGADJ[2:0] to 3b'110, + * 110 - set REFTOP_VBGADJ[2:0] to 3b'000, + * 001 - set REFTOP_VBGADJ[2:0] to 3b'001, + * 010 - set REFTOP_VBGADJ[2:0] to 3b'010, + * 011 - set REFTOP_VBGADJ[2:0] to 3b'011, + * 100 - set REFTOP_VBGADJ[2:0] to 3b'100, + * 101 - set REFTOP_VBGADJ[2:0] to 3b'101, + * 111 - set REFTOP_VBGADJ[2:0] to 3b'111, */ - if (is_mx6ull()) - writel(BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ, &anatop->ana_misc0_set); -} + if (is_mx6ull()) { + val = readl(&fuse->mem0); + val >>= OCOTP_MEM0_REFTOP_TRIM_SHIFT; + val &= 0x7; + writel(val << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT, + &anatop->ana_misc0_set); + } +} #ifdef CONFIG_MX6SL static void set_preclk_from_osc(void) diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h index f74737a..29674ce 100644 --- a/arch/arm/include/asm/arch-mx6/crm_regs.h +++ b/arch/arm/include/asm/arch-mx6/crm_regs.h @@ -1272,6 +1272,7 @@ struct mxc_ccm_reg { #define BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF 0x00000008 #define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ 0x60 +#define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT 4 #define BM_PMU_MISC2_AUDIO_DIV_MSB (1 << 23) #define BP_PMU_MISC2_AUDIO_DIV_MSB 23 -- cgit v0.10.2 From 72c1015307afe6cf4541166964216a4f733b3faa Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 17 Oct 2016 15:51:32 +0200 Subject: mx35: add DT support to flea3 board Signed-off-by: Heiko Schocher diff --git a/board/CarMediaLab/flea3/flea3.c b/board/CarMediaLab/flea3/flea3.c index 2463077..be42863 100644 --- a/board/CarMediaLab/flea3/flea3.c +++ b/board/CarMediaLab/flea3/flea3.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #ifndef CONFIG_BOARD_EARLY_INIT_F #error "CONFIG_BOARD_EARLY_INIT_F must be set for this board" @@ -276,3 +279,24 @@ u32 get_board_rev(void) return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8; } + +/* + * called prior to booting kernel or by 'fdt boardsetup' command + * + */ +int ft_board_setup(void *blob, bd_t *bd) +{ + struct node_info nodes[] = { + { "physmap-flash.0", MTD_DEV_TYPE_NOR, }, /* NOR flash */ + { "mxc_nand", MTD_DEV_TYPE_NAND, }, /* NAND flash */ + }; + + if (getenv("fdt_noauto")) { + puts(" Skiping ft_board_setup (fdt_noauto defined)\n"); + return 0; + } + + fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); + + return 0; +} diff --git a/configs/flea3_defconfig b/configs/flea3_defconfig index 7aa1ba8..c5ccbd6 100644 --- a/configs/flea3_defconfig +++ b/configs/flea3_defconfig @@ -1,6 +1,7 @@ CONFIG_ARM=y CONFIG_TARGET_FLEA3=y CONFIG_FIT=y +CONFIG_OF_BOARD_SETUP=y CONFIG_BOOTDELAY=3 # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_HUSH_PARSER=y @@ -12,3 +13,6 @@ CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y CONFIG_CMD_CACHE=y +CONFIG_OF_LIBFDT=y +CONFIG_FDT_FIXUP_PARTITIONS=y +# CONFIG_EFI_LOADER is not set -- cgit v0.10.2 From 146fff347aaf241246a59ce0fe02543499a45147 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Mon, 17 Oct 2016 15:51:33 +0200 Subject: mx35: factorize SDRAM setup in flea3 Drop local function to setup SDRAM controller and use the common one for i.MX35. Signed-off-by: Stefano Babic Signed-off-by: Heiko Schocher diff --git a/board/CarMediaLab/flea3/flea3.c b/board/CarMediaLab/flea3/flea3.c index be42863..ca3e44b 100644 --- a/board/CarMediaLab/flea3/flea3.c +++ b/board/CarMediaLab/flea3/flea3.c @@ -30,18 +30,6 @@ #define CCM_CCMR_CONFIG 0x003F4208 #define ESDCTL_DDR2_CONFIG 0x007FFC3F -#define ESDCTL_0x92220000 0x92220000 -#define ESDCTL_0xA2220000 0xA2220000 -#define ESDCTL_0xB2220000 0xB2220000 -#define ESDCTL_0x82228080 0x82228080 -#define ESDCTL_DDR2_EMR2 0x04000000 -#define ESDCTL_DDR2_EMR3 0x06000000 -#define ESDCTL_PRECHARGE 0x00000400 -#define ESDCTL_DDR2_EN_DLL 0x02000400 -#define ESDCTL_DDR2_RESET_DLL 0x00000333 -#define ESDCTL_DDR2_MR 0x00000233 -#define ESDCTL_DDR2_OCD_DEFAULT 0x02000780 -#define ESDCTL_DELAY_LINE5 0x00F49F00 static inline void dram_wait(unsigned int count) { @@ -61,83 +49,6 @@ int dram_init(void) return 0; } -static void board_setup_sdram_bank(u32 start_address) - -{ - struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR; - u32 *cfg_reg, *ctl_reg; - u32 val; - - switch (start_address) { - case CSD0_BASE_ADDR: - cfg_reg = &esdc->esdcfg0; - ctl_reg = &esdc->esdctl0; - break; - case CSD1_BASE_ADDR: - cfg_reg = &esdc->esdcfg1; - ctl_reg = &esdc->esdctl1; - break; - default: - return; - } - - /* Initialize MISC register for DDR2 */ - val = ESDC_MISC_RST | ESDC_MISC_MDDR_EN | ESDC_MISC_MDDR_DL_RST | - ESDC_MISC_DDR_EN | ESDC_MISC_DDR2_EN; - writel(val, &esdc->esdmisc); - val &= ~(ESDC_MISC_RST | ESDC_MISC_MDDR_DL_RST); - writel(val, &esdc->esdmisc); - - /* - * according to DDR2 specs, wait a while before - * the PRECHARGE_ALL command - */ - dram_wait(0x20000); - - /* Load DDR2 config and timing */ - writel(ESDCTL_DDR2_CONFIG, cfg_reg); - - /* Precharge ALL */ - writel(ESDCTL_0x92220000, - ctl_reg); - writel(0xda, start_address + ESDCTL_PRECHARGE); - - /* Load mode */ - writel(ESDCTL_0xB2220000, - ctl_reg); - writeb(0xda, start_address + ESDCTL_DDR2_EMR2); /* EMRS2 */ - writeb(0xda, start_address + ESDCTL_DDR2_EMR3); /* EMRS3 */ - writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */ - writeb(0xda, start_address + ESDCTL_DDR2_RESET_DLL); /* Reset DLL */ - - /* Precharge ALL */ - writel(ESDCTL_0x92220000, - ctl_reg); - writel(0xda, start_address + ESDCTL_PRECHARGE); - - /* Set mode auto refresh : at least two refresh are required */ - writel(ESDCTL_0xA2220000, - ctl_reg); - writel(0xda, start_address); - writel(0xda, start_address); - - writel(ESDCTL_0xB2220000, - ctl_reg); - writeb(0xda, start_address + ESDCTL_DDR2_MR); - writeb(0xda, start_address + ESDCTL_DDR2_OCD_DEFAULT); - - /* OCD mode exit */ - writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */ - - /* Set normal mode */ - writel(ESDCTL_0x82228080, - ctl_reg); - - dram_wait(0x20000); - - /* Do not set delay lines, only for MDDR */ -} - static void board_setup_sdram(void) { struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR; @@ -146,7 +57,9 @@ static void board_setup_sdram(void) writel(0x2000, &esdc->esdctl0); writel(0x2000, &esdc->esdctl1); - board_setup_sdram_bank(CSD0_BASE_ADDR); + + mx3_setup_sdram_bank(CSD0_BASE_ADDR, ESDCTL_DDR2_CONFIG, + 13, 10, 2, 0x8080); } static void setup_iomux_uart3(void) -- cgit v0.10.2 From 322ac5f1d5e564bca95cce7d8410c215f93a0255 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Mon, 17 Oct 2016 15:51:34 +0200 Subject: mx35: add GPIO setup on flea3 board Hardware revision "e" of the board introduces a GPIO to reduce power consumption in stand-by mode. This must be enable (active low) at the startup for normal behaviour. Signed-off-by: Stefano Babic Signed-off-by: Heiko Schocher diff --git a/board/CarMediaLab/flea3/flea3.c b/board/CarMediaLab/flea3/flea3.c index ca3e44b..3cd4dc9 100644 --- a/board/CarMediaLab/flea3/flea3.c +++ b/board/CarMediaLab/flea3/flea3.c @@ -122,6 +122,8 @@ static void setup_iomux_fec(void) MX35_PAD_FEC_TDATA2__FEC_TDATA_2, MX35_PAD_FEC_RDATA3__FEC_RDATA_3, MX35_PAD_FEC_TDATA3__FEC_TDATA_3, + /* GPIO used to power off ethernet */ + MX35_PAD_STXFS4__GPIO2_31, }; /* setup pins for FEC */ @@ -183,6 +185,11 @@ int board_init(void) /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + /* Enable power for ethernet */ + gpio_direction_output(63, 0); + + udelay(2000); + return 0; } -- cgit v0.10.2 From 45a3ad81fafe3090f7f89b458f6bd9f547a453df Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 17 Oct 2016 15:51:35 +0200 Subject: mx35: adjust default environment for flea3 board Signed-off-by: Stefano Babic Signed-off-by: Heiko Schocher diff --git a/include/configs/flea3.h b/include/configs/flea3.h index 11d9391..0f7b3c8 100644 --- a/include/configs/flea3.h +++ b/include/configs/flea3.h @@ -101,10 +101,9 @@ #define CONFIG_CMDLINE_EDITING #define CONFIG_AUTO_COMPLETE -#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_CBSIZE 512 /* Console I/O Buffer Size */ /* Print Buffer Size */ -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) -#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_MAXARGS 32 /* max number of command args */ #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */ #define CONFIG_SYS_MEMTEST_START 0 /* memtest works on */ @@ -227,8 +226,8 @@ "u-boot=" __stringify(CONFIG_HOSTNAME) "/u-boot.bin\0" \ "load=tftp ${loadaddr} ${u-boot}\0" \ "uboot_addr=" __stringify(CONFIG_SYS_MONITOR_BASE) "\0" \ - "update=protect off ${uboot_addr} +40000;" \ - "erase ${uboot_addr} +40000;" \ + "update=protect off ${uboot_addr} +80000;" \ + "erase ${uboot_addr} +80000;" \ "cp.b ${loadaddr} ${uboot_addr} ${filesize}\0" \ "upd=if run load;then echo Updating u-boot;if run update;" \ "then echo U-Boot updated;" \ -- cgit v0.10.2 From 54e4fcfa3c749a789192e83740a53234182f4ca3 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Fri, 21 Oct 2016 13:53:54 +0200 Subject: ARM: mx6: add MMC2 boot device detection support in SPL Check BOOT_CFG2[3:4] to determine which SD/MMC port is selected to boot from. If MMC2 is selected return BOOT_DEVICE_MMC2. In all other cases return BOOT_DEVICE_MMC1, as we do not have corresponding macro for MMC3 and MMC4. Signed-off-by: Marcin Niestroj diff --git a/arch/arm/imx-common/spl.c b/arch/arm/imx-common/spl.c index bdcda7d..325ba26 100644 --- a/arch/arm/imx-common/spl.c +++ b/arch/arm/imx-common/spl.c @@ -14,6 +14,9 @@ #include #if defined(CONFIG_MX6) +#define MX6_MMC_PORT_MASK GENMASK(12, 11) +#define MX6_MMC_PORT_2 BIT(11) + /* determine boot device from SRC_SBMR1 (BOOT_CFG[4:1]) or SRC_GPR9 register */ u32 spl_boot_device(void) { @@ -55,10 +58,11 @@ u32 spl_boot_device(void) /* SD/eSD: 8.5.3, Table 8-15 */ case 0x4: case 0x5: - return BOOT_DEVICE_MMC1; /* MMC/eMMC: 8.5.3 */ case 0x6: case 0x7: + if ((reg & MX6_MMC_PORT_MASK) == MX6_MMC_PORT_2) + return BOOT_DEVICE_MMC2; return BOOT_DEVICE_MMC1; /* NAND Flash: 8.5.2 */ case 0x8 ... 0xf: -- cgit v0.10.2 From c8d7647f639813cff08a4a7de62db815829ec72b Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Tue, 1 Nov 2016 15:04:20 +0100 Subject: spl: mmc: fix switch statement If CONFIG_SPL_LIBCOMMON_SUPPORT is not defined there is a lone case statement at the end of the switch leading to a compile error. Remove the offending case statement. | common/spl/spl_mmc.c:339:7: error: label at end of compound statement Signed-off-by: Max Krummenacher Reviewed-by: Tom Rini Acked-by: Marek Vasut diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 0b681c2..a3d6b36 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -342,7 +342,6 @@ static int spl_mmc_load_image(struct spl_image_info *spl_image, return err; break; - case MMCSD_MODE_UNDEFINED: #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT default: puts("spl: mmc: wrong boot mode\n"); -- cgit v0.10.2 From 15fde0fc11f93f19f40c9cda36e7c8d4848d9c75 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Tue, 1 Nov 2016 15:04:21 +0100 Subject: imx: make ipu's di configurable The ipu has two display interfaces. Make the used one a parameter in struct display_info_t instead of using unconditionally DI0. DI0 is the default setting. Signed-off-by: Max Krummenacher Reviewed-by: Eric Nelson diff --git a/arch/arm/imx-common/video.c b/arch/arm/imx-common/video.c index fdc987f..549bf9d 100644 --- a/arch/arm/imx-common/video.c +++ b/arch/arm/imx-common/video.c @@ -34,7 +34,7 @@ int board_video_skip(void) } if (i < display_count) { - ret = ipuv3_fb_init(&displays[i].mode, 0, + ret = ipuv3_fb_init(&displays[i].mode, displays[i].di ? 1 : 0, displays[i].pixfmt); if (!ret) { if (displays[i].enable) diff --git a/arch/arm/include/asm/imx-common/video.h b/arch/arm/include/asm/imx-common/video.h index cad5f86..941a031 100644 --- a/arch/arm/include/asm/imx-common/video.h +++ b/arch/arm/include/asm/imx-common/video.h @@ -12,6 +12,7 @@ struct display_info_t { int bus; int addr; int pixfmt; + int di; int (*detect)(struct display_info_t const *dev); void (*enable)(struct display_info_t const *dev); struct fb_videomode mode; -- cgit v0.10.2 From 84a62ca85d559c94779e985ea5e071aec3395bc5 Mon Sep 17 00:00:00 2001 From: Soeren Moch Date: Sun, 27 Nov 2016 16:02:19 +0100 Subject: tbs2910: Make Ethernet functional again Configure the PHY to output a 125MHz clk from CLK_25M and set tx clock delay. This patch is similar to commit 4b6035da482cccda06aeb419634f99937c9fc783 ("mx6sabresd: Make Ethernet functional again"). Signed-off-by: Soeren Moch diff --git a/board/tbs/tbs2910/tbs2910.c b/board/tbs/tbs2910/tbs2910.c index 0d9d17a..db0c58f 100644 --- a/board/tbs/tbs2910/tbs2910.c +++ b/board/tbs/tbs2910/tbs2910.c @@ -359,6 +359,39 @@ static void setup_display(void) } #endif /* CONFIG_VIDEO_IPUV3 */ +static int ar8035_phy_fixup(struct phy_device *phydev) +{ + unsigned short val; + + /* To enable AR8035 ouput a 125MHz clk from CLK_25M */ + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); + + val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); + val &= 0xffe3; + val |= 0x18; + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); + + /* introduce tx clock delay */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); + val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); + val |= 0x0100; + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); + + return 0; +} + +int board_phy_config(struct phy_device *phydev) +{ + ar8035_phy_fixup(phydev); + + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + int board_eth_init(bd_t *bis) { setup_iomux_enet(); -- cgit v0.10.2 From de19773535d4eb4e698aec4ab0cdfe86d51a4696 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Tue, 22 Nov 2016 12:01:28 +0100 Subject: pwm: imx: increase support up to PWM8 for i.MX6SX This patch increases supported PWMs from previously PWM4 now up to PWM8 if i.MX6SX is in use. Signed-off-by: Christoph Fritz diff --git a/drivers/pwm/pwm-imx-util.c b/drivers/pwm/pwm-imx-util.c index 285564a..534dd8e 100644 --- a/drivers/pwm/pwm-imx-util.c +++ b/drivers/pwm/pwm-imx-util.c @@ -15,7 +15,7 @@ #include #include -/* pwm_id from 0..3 */ +/* pwm_id from 0..7 */ struct pwm_regs *pwm_id_to_reg(int pwm_id) { switch (pwm_id) { @@ -27,6 +27,16 @@ struct pwm_regs *pwm_id_to_reg(int pwm_id) return (struct pwm_regs *)PWM3_BASE_ADDR; case 3: return (struct pwm_regs *)PWM4_BASE_ADDR; +#ifdef CONFIG_MX6SX + case 4: + return (struct pwm_regs *)PWM5_BASE_ADDR; + case 5: + return (struct pwm_regs *)PWM6_BASE_ADDR; + case 6: + return (struct pwm_regs *)PWM7_BASE_ADDR; + case 7: + return (struct pwm_regs *)PWM8_BASE_ADDR; +#endif default: printf("unknown pwm_id: %d\n", pwm_id); break; -- cgit v0.10.2 From 36c0627ba5efd602d9ca8ebaae06f30d1890a41a Mon Sep 17 00:00:00 2001 From: Sven Ebenfeld Date: Fri, 25 Nov 2016 21:42:53 +0100 Subject: arm: imx: wandboard: fix compile error if CONFIG_VIDEO is deactivated When I tried to deactivate VIDEO support for the Wandboard, it still tried to initialize the Framebuffer and so on. That is the reason for the added ifdefs. CONFIG_VIDEO is enabled in the configuration as default and therefore nothing changes for the default user. The structs mx6dl_i2c2_pad_info and mx6q_i2c2_pad_info are only available when CONFIG_IPUV3 are set and should not be tried to access, when that define is not defined. Signed-off-by: Sven Ebenfeld diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c index b3f3b34..2c9dc8b 100644 --- a/board/wandboard/wandboard.c +++ b/board/wandboard/wandboard.c @@ -442,11 +442,13 @@ int board_init(void) /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; +#if defined(CONFIG_VIDEO_IPUV3) setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c2_pad_info); if (is_mx6dq()) setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c2_pad_info); else setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c2_pad_info); +#endif return 0; } diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h index 8c5cf33..406591c 100644 --- a/include/configs/wandboard.h +++ b/include/configs/wandboard.h @@ -74,6 +74,7 @@ #define CONFIG_PHY_ATHEROS /* Framebuffer */ +#ifdef CONFIG_VIDEO #define CONFIG_VIDEO_IPUV3 #define CONFIG_VIDEO_BMP_RLE8 #define CONFIG_SPLASH_SCREEN @@ -85,6 +86,7 @@ #define CONFIG_CMD_HDMIDETECT #define CONFIG_IMX_HDMI #define CONFIG_IMX_VIDEO_SKIP +#endif #define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG #define CONFIG_EXTRA_ENV_SETTINGS \ -- cgit v0.10.2 From e5491f3ef5aa4b38067bd10dbdded9520305670f Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Wed, 16 Nov 2016 17:13:41 -0700 Subject: tools: imximage: display DCD block offset, length These values can be used to sign a U-Boot image for use when loading an image through the Serial Download Protocol (SDP). Note that the address of 0x910000 is usable with the stock configuration of imx_usb_loader on i.MX6 and i.MX7 SOCs: https://github.com/boundarydevices/imx_usb_loader/blob/master/mx6_usb_work.conf#L3 Refer to the section on imx_usb_loader in this post for more details: https://boundarydevices.com/high-assurance-boot-hab-dummies/ Signed-off-by: Eric Nelson diff --git a/tools/imximage.c b/tools/imximage.c index c9e42ec..2cd8d88 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -281,7 +281,6 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, d = (struct dcd_v2_cmd *)(((char *)d) + len); len = (char *)d - (char *)&dcd_v2->header; - dcd_v2->header.tag = DCD_HEADER_TAG; dcd_v2->header.length = cpu_to_be16(len); dcd_v2->header.version = DCD_VERSION; @@ -501,10 +500,19 @@ static void print_hdr_v2(struct imx_header *imx_hdr) printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry); if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) && (imximage_csf_size != UNDEFINED)) { + uint16_t dcdlen; + int offs; + + dcdlen = hdr_v2->data.dcd_table.header.length; + offs = (char *)&hdr_v2->data.dcd_table + - (char *)hdr_v2; + printf("HAB Blocks: %08x %08x %08x\n", (uint32_t)fhdr_v2->self, 0, hdr_v2->boot_data.size - imximage_ivt_offset - imximage_csf_size); + printf("DCD Blocks: 00910000 %08x %08x\n", + offs, be16_to_cpu(dcdlen)); } } else { imx_header_v2_t *next_hdr_v2; -- cgit v0.10.2 From c8c35155082d11deb7a2f9ccb99b11216cbd9d55 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Fri, 28 Oct 2016 10:13:57 -0700 Subject: imx: mx6: ddr: add register MPZQLP2CTL for LPDDR2 Add constants for the MPZQLP2CTL DDR register for both banks to allow setting the LPDDR2 timing values in .cfg files using a named constant instead of hex addresses as is currently done in mx6slevk and other board files. Signed-off-by: Eric Nelson diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h index 9922409..53eb5fa 100644 --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h @@ -495,6 +495,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *, #define MX6_MMDC_P0_MPDGCTRL1 0x021b0840 #define MX6_MMDC_P0_MPRDDLCTL 0x021b0848 #define MX6_MMDC_P0_MPWRDLCTL 0x021b0850 +#define MX6_MMDC_P0_MPZQLP2CTL 0x021b085C #define MX6_MMDC_P0_MPMUR0 0x021b08b8 #define MX6_MMDC_P1_MDCTL 0x021b4000 @@ -522,6 +523,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *, #define MX6_MMDC_P1_MPDGCTRL1 0x021b4840 #define MX6_MMDC_P1_MPRDDLCTL 0x021b4848 #define MX6_MMDC_P1_MPWRDLCTL 0x021b4850 +#define MX6_MMDC_P1_MPZQLP2CTL 0x021b485C #define MX6_MMDC_P1_MPMUR0 0x021b48b8 #endif /*__ASM_ARCH_MX6_DDR_H__ */ -- cgit v0.10.2 From b33f74ead4dfd1ec0b500dc3d1cfef0e308b45c3 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Sun, 30 Oct 2016 16:33:47 -0700 Subject: mx6: ddr: allow 32 cycles for DQS gating calibration The DDR calibration code is only setting flag DG_CMP_CYC (DQS gating sample cycle) for the first PHY. Set the 32-cycle flag for both PHYs and clear when done so the MPDGCTRL0 output value isn't polluted with calibration artifacts. Signed-off-by: Eric Nelson Reviewed-by: Marek Vasut diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c index 7beb7ea..b15f376 100644 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ b/arch/arm/cpu/armv7/mx6/ddr.c @@ -347,6 +347,8 @@ int mmdc_do_dqs_calibration(void) * 16 before comparing read data. */ setbits_le32(&mmdc0->mpdgctrl0, 1 << 30); + if (sysinfo->dsize == 2) + setbits_le32(&mmdc1->mpdgctrl0, 1 << 30); /* Set bit 28 to start automatic read DQS gating calibration */ setbits_le32(&mmdc0->mpdgctrl0, 5 << 28); @@ -365,6 +367,11 @@ int mmdc_do_dqs_calibration(void) if ((bus_size == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000)) errors |= 2; + /* now disable mpdgctrl0[DG_CMP_CYC] */ + clrbits_le32(&mmdc0->mpdgctrl0, 1 << 30); + if (sysinfo->dsize == 2) + clrbits_le32(&mmdc1->mpdgctrl0, 1 << 30); + /* * DQS gating absolute offset should be modified from * reflecting (HW_DG_LOWx + HW_DG_UPx)/2 to -- cgit v0.10.2 From 7f17fb7400ff091dd48f86977655c6a57d06b17c Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Sun, 30 Oct 2016 16:33:48 -0700 Subject: mx6: ddr: pass mx6_ddr_sysinfo to calibration routines The DDR calibration routines have scattered support for bus widths other than 64-bits: -- The mmdc_do_write_level_calibration() routine assumes the presence of PHY1, and -- The mmdc_do_dqs_calibration() routine tries to determine whether one or two DDR PHYs are active by reading MDCTL. Since a caller of these routines must have a valid struct mx6_ddr_sysinfo for use in calling mx6_dram_cfg(), and the bus width is available in the "dsize" field, use this structure to inform the calibration routines which PHYs are active. This allows the use of the DDR calibration routines on CPU variants like i.MX6SL that only have a single MMDC port. Signed-off-by: Eric Nelson Reviewed-by: Marek Vasut diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c index b15f376..274a0ba 100644 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ b/arch/arm/cpu/armv7/mx6/ddr.c @@ -86,14 +86,15 @@ static void modify_dg_result(u32 *reg_st0, u32 *reg_st1, u32 *reg_ctrl) writel(val_ctrl, reg_ctrl); } -int mmdc_do_write_level_calibration(void) +int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo) { struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; u32 esdmisc_val, zq_val; u32 errors = 0; - u32 ldectrl[4]; + u32 ldectrl[4] = {0}; u32 ddr_mr1 = 0x4; + u32 rwalat_max; /* * Stash old values in case calibration fails, @@ -101,8 +102,10 @@ int mmdc_do_write_level_calibration(void) */ ldectrl[0] = readl(&mmdc0->mpwldectrl0); ldectrl[1] = readl(&mmdc0->mpwldectrl1); - ldectrl[2] = readl(&mmdc1->mpwldectrl0); - ldectrl[3] = readl(&mmdc1->mpwldectrl1); + if (sysinfo->dsize == 2) { + ldectrl[2] = readl(&mmdc1->mpwldectrl0); + ldectrl[3] = readl(&mmdc1->mpwldectrl1); + } /* disable DDR logic power down timer */ clrbits_le32(&mmdc0->mdpdc, 0xff00); @@ -122,10 +125,10 @@ int mmdc_do_write_level_calibration(void) writel(zq_val & ~0x3, &mmdc0->mpzqhwctrl); /* 3. increase walat and ralat to maximum */ - setbits_le32(&mmdc0->mdmisc, - (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17)); - setbits_le32(&mmdc1->mdmisc, - (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17)); + rwalat_max = (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17); + setbits_le32(&mmdc0->mdmisc, rwalat_max); + if (sysinfo->dsize == 2) + setbits_le32(&mmdc1->mdmisc, rwalat_max); /* * 4 & 5. Configure the external DDR device to enter write-leveling * mode through Load Mode Register command. @@ -152,21 +155,25 @@ int mmdc_do_write_level_calibration(void) */ if (readl(&mmdc0->mpwlgcr) & 0x00000F00) errors |= 1; - if (readl(&mmdc1->mpwlgcr) & 0x00000F00) - errors |= 2; + if (sysinfo->dsize == 2) + if (readl(&mmdc1->mpwlgcr) & 0x00000F00) + errors |= 2; debug("Ending write leveling calibration. Error mask: 0x%x\n", errors); /* check to see if cal failed */ if ((readl(&mmdc0->mpwldectrl0) == 0x001F001F) && (readl(&mmdc0->mpwldectrl1) == 0x001F001F) && - (readl(&mmdc1->mpwldectrl0) == 0x001F001F) && - (readl(&mmdc1->mpwldectrl1) == 0x001F001F)) { + ((sysinfo->dsize < 2) || + ((readl(&mmdc1->mpwldectrl0) == 0x001F001F) && + (readl(&mmdc1->mpwldectrl1) == 0x001F001F)))) { debug("Cal seems to have soft-failed due to memory not supporting write leveling on all channels. Restoring original write leveling values.\n"); writel(ldectrl[0], &mmdc0->mpwldectrl0); writel(ldectrl[1], &mmdc0->mpwldectrl1); - writel(ldectrl[2], &mmdc1->mpwldectrl0); - writel(ldectrl[3], &mmdc1->mpwldectrl1); + if (sysinfo->dsize == 2) { + writel(ldectrl[2], &mmdc1->mpwldectrl0); + writel(ldectrl[3], &mmdc1->mpwldectrl1); + } errors |= 4; } @@ -189,16 +196,20 @@ int mmdc_do_write_level_calibration(void) readl(&mmdc0->mpwldectrl0)); debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n", readl(&mmdc0->mpwldectrl1)); - debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n", - readl(&mmdc1->mpwldectrl0)); - debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n", - readl(&mmdc1->mpwldectrl1)); + if (sysinfo->dsize == 2) { + debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n", + readl(&mmdc1->mpwldectrl0)); + debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n", + readl(&mmdc1->mpwldectrl1)); + } /* We must force a readback of these values, to get them to stick */ readl(&mmdc0->mpwldectrl0); readl(&mmdc0->mpwldectrl1); - readl(&mmdc1->mpwldectrl0); - readl(&mmdc1->mpwldectrl1); + if (sysinfo->dsize == 2) { + readl(&mmdc1->mpwldectrl0); + readl(&mmdc1->mpwldectrl1); + } /* enable DDR logic power down timer: */ setbits_le32(&mmdc0->mdpdc, 0x00005500); @@ -212,7 +223,7 @@ int mmdc_do_write_level_calibration(void) return errors; } -int mmdc_do_dqs_calibration(void) +int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo) { struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; @@ -223,7 +234,6 @@ int mmdc_do_dqs_calibration(void) bool cs0_enable_initial; bool cs1_enable_initial; u32 esdmisc_val; - u32 bus_size; u32 temp_ref; u32 pddword = 0x00ffff00; /* best so far, place into MPPDCMPR1 */ u32 errors = 0; @@ -292,10 +302,6 @@ int mmdc_do_dqs_calibration(void) cs0_enable = readl(&mmdc0->mdctl) & 0x80000000; cs1_enable = readl(&mmdc0->mdctl) & 0x40000000; - /* Check to see what the data bus size is */ - bus_size = (readl(&mmdc0->mdctl) & 0x30000) >> 16; - debug("Data bus size: %d (%d bits)\n", bus_size, 1 << (bus_size + 4)); - precharge_all(cs0_enable, cs1_enable); /* Write the pre-defined value into MPPDCMPR1 */ @@ -314,11 +320,11 @@ int mmdc_do_dqs_calibration(void) * Both PHYs for x64 configuration, if x32, do only PHY0. */ writel(initdelay, &mmdc0->mprddlctl); - if (bus_size == 0x2) + if (sysinfo->dsize == 0x2) writel(initdelay, &mmdc1->mprddlctl); /* Force a measurment, for previous delay setup to take effect. */ - force_delay_measurement(bus_size); + force_delay_measurement(sysinfo->dsize); /* * *************************** @@ -364,7 +370,7 @@ int mmdc_do_dqs_calibration(void) if (readl(&mmdc0->mpdgctrl0) & 0x00001000) errors |= 1; - if ((bus_size == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000)) + if ((sysinfo->dsize == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000)) errors |= 2; /* now disable mpdgctrl0[DG_CMP_CYC] */ @@ -381,7 +387,7 @@ int mmdc_do_dqs_calibration(void) &mmdc0->mpdgctrl0); modify_dg_result(&mmdc0->mpdghwst2, &mmdc0->mpdghwst3, &mmdc0->mpdgctrl1); - if (bus_size == 0x2) { + if (sysinfo->dsize == 0x2) { modify_dg_result(&mmdc1->mpdghwst0, &mmdc1->mpdghwst1, &mmdc1->mpdgctrl0); modify_dg_result(&mmdc1->mpdghwst2, &mmdc1->mpdghwst3, @@ -424,7 +430,8 @@ int mmdc_do_dqs_calibration(void) if (readl(&mmdc0->mprddlhwctl) & 0x0000000f) errors |= 4; - if ((bus_size == 0x2) && (readl(&mmdc1->mprddlhwctl) & 0x0000000f)) + if ((sysinfo->dsize == 0x2) && + (readl(&mmdc1->mprddlhwctl) & 0x0000000f)) errors |= 8; debug("Ending Read Delay calibration. Error mask: 0x%x\n", errors); @@ -450,14 +457,14 @@ int mmdc_do_dqs_calibration(void) * Both PHYs for x64 configuration, if x32, do only PHY0. */ writel(initdelay, &mmdc0->mpwrdlctl); - if (bus_size == 0x2) + if (sysinfo->dsize == 0x2) writel(initdelay, &mmdc1->mpwrdlctl); /* * XXX This isn't in the manual. Force a measurement, * for previous delay setup to effect. */ - force_delay_measurement(bus_size); + force_delay_measurement(sysinfo->dsize); /* * 9. 10. Start the automatic write calibration process @@ -477,7 +484,8 @@ int mmdc_do_dqs_calibration(void) if (readl(&mmdc0->mpwrdlhwctl) & 0x0000000f) errors |= 16; - if ((bus_size == 0x2) && (readl(&mmdc1->mpwrdlhwctl) & 0x0000000f)) + if ((sysinfo->dsize == 0x2) && + (readl(&mmdc1->mpwrdlhwctl) & 0x0000000f)) errors |= 32; debug("Ending Write Delay calibration. Error mask: 0x%x\n", errors); @@ -529,14 +537,18 @@ int mmdc_do_dqs_calibration(void) debug("Read DQS gating calibration:\n"); debug("\tMPDGCTRL0 PHY0 = 0x%08X\n", readl(&mmdc0->mpdgctrl0)); debug("\tMPDGCTRL1 PHY0 = 0x%08X\n", readl(&mmdc0->mpdgctrl1)); - debug("\tMPDGCTRL0 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl0)); - debug("\tMPDGCTRL1 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl1)); + if (sysinfo->dsize == 2) { + debug("\tMPDGCTRL0 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl0)); + debug("\tMPDGCTRL1 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl1)); + } debug("Read calibration:\n"); debug("\tMPRDDLCTL PHY0 = 0x%08X\n", readl(&mmdc0->mprddlctl)); - debug("\tMPRDDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mprddlctl)); + if (sysinfo->dsize == 2) + debug("\tMPRDDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mprddlctl)); debug("Write calibration:\n"); debug("\tMPWRDLCTL PHY0 = 0x%08X\n", readl(&mmdc0->mpwrdlctl)); - debug("\tMPWRDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mpwrdlctl)); + if (sysinfo->dsize == 2) + debug("\tMPWRDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mpwrdlctl)); /* * Registers below are for debugging purposes. These print out @@ -548,10 +560,12 @@ int mmdc_do_dqs_calibration(void) debug("\tMPDGHWST1 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst1)); debug("\tMPDGHWST2 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst2)); debug("\tMPDGHWST3 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst3)); - debug("\tMPDGHWST0 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst0)); - debug("\tMPDGHWST1 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst1)); - debug("\tMPDGHWST2 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst2)); - debug("\tMPDGHWST3 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst3)); + if (sysinfo->dsize == 2) { + debug("\tMPDGHWST0 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst0)); + debug("\tMPDGHWST1 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst1)); + debug("\tMPDGHWST2 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst2)); + debug("\tMPDGHWST3 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst3)); + } debug("Final do_dqs_calibration error mask: 0x%x\n", errors); diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h index 53eb5fa..cd5bc97 100644 --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h @@ -459,8 +459,8 @@ void mx6sl_dram_iocfg(unsigned width, const struct mx6sl_iomux_grp_regs *); #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) -int mmdc_do_write_level_calibration(void); -int mmdc_do_dqs_calibration(void); +int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo); +int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo); #endif /* configure mx6 mmdc registers */ diff --git a/board/kosagi/novena/novena_spl.c b/board/kosagi/novena/novena_spl.c index 92c61ae..b934d36 100644 --- a/board/kosagi/novena/novena_spl.c +++ b/board/kosagi/novena/novena_spl.c @@ -605,8 +605,8 @@ void board_init_f(ulong dummy) /* Perform DDR DRAM calibration */ udelay(100); - mmdc_do_write_level_calibration(); - mmdc_do_dqs_calibration(); + mmdc_do_write_level_calibration(&novena_ddr_info); + mmdc_do_dqs_calibration(&novena_ddr_info); /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); -- cgit v0.10.2 From 48c7d4379bcf70ce331e441b135cfbf3546dd574 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Sun, 30 Oct 2016 16:33:49 -0700 Subject: mx6: ddr: add routine to return DDR calibration data Add routine mmdc_read_calibration() to return the output of DDR calibration. This can be used for debugging or to aid in construction of static memory configuration. This routine will be used in a subsequent patch set adding a virtual "mx6memcal" board, but could also be useful when gathering statistics during an initial production run. Signed-off-by: Eric Nelson diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c index 274a0ba..b12fb64 100644 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ b/arch/arm/cpu/armv7/mx6/ddr.c @@ -1501,6 +1501,29 @@ void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo, mdelay(1); } +void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo, + struct mx6_mmdc_calibration *calib) +{ + struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; + struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; + + calib->p0_mpwldectrl0 = readl(&mmdc0->mpwldectrl0); + calib->p0_mpwldectrl1 = readl(&mmdc0->mpwldectrl1); + calib->p0_mpdgctrl0 = readl(&mmdc0->mpdgctrl0); + calib->p0_mpdgctrl1 = readl(&mmdc0->mpdgctrl1); + calib->p0_mprddlctl = readl(&mmdc0->mprddlctl); + calib->p0_mpwrdlctl = readl(&mmdc0->mpwrdlctl); + + if (sysinfo->dsize == 2) { + calib->p1_mpwldectrl0 = readl(&mmdc1->mpwldectrl0); + calib->p1_mpwldectrl1 = readl(&mmdc1->mpwldectrl1); + calib->p1_mpdgctrl0 = readl(&mmdc1->mpdgctrl0); + calib->p1_mpdgctrl1 = readl(&mmdc1->mpdgctrl1); + calib->p1_mprddlctl = readl(&mmdc1->mprddlctl); + calib->p1_mpwrdlctl = readl(&mmdc1->mpwrdlctl); + } +} + void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, const struct mx6_mmdc_calibration *calib, const void *ddr_cfg) diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h index cd5bc97..12454fa 100644 --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h @@ -461,6 +461,8 @@ void mx6sl_dram_iocfg(unsigned width, #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo); int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo); +void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo, + struct mx6_mmdc_calibration *calib); #endif /* configure mx6 mmdc registers */ -- cgit v0.10.2 From a425bf72816abbc3996540e42c33a386e8b8a221 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Sun, 30 Oct 2016 16:33:50 -0700 Subject: ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines The DDR calibration routines are gated by conditionals for the i.MX6DQ SOCs, but with the use of the sysinfo parameter, these are usable on at least i.MX6SDL and i.MX6SL variants with DDR3. Also, since only the Novena board currently uses the dynamic DDR calibration routines, these routines waste space on other boards using SPL. Add a KConfig entry to allow boards to selectively include the DDR calibration routines. Signed-off-by: Eric Nelson diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig index 762a581..8b2217e 100644 --- a/arch/arm/cpu/armv7/mx6/Kconfig +++ b/arch/arm/cpu/armv7/mx6/Kconfig @@ -35,6 +35,14 @@ config MX6ULL bool select MX6UL +config MX6_DDRCAL + bool "Include dynamic DDR calibration routines" + depends on SPL + default n + help + Say "Y" if your board uses dynamic (per-boot) DDR calibration. + If unsure, say N. + choice prompt "MX6 board select" optional diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c index b12fb64..0cf391e 100644 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ b/arch/arm/cpu/armv7/mx6/ddr.c @@ -14,8 +14,7 @@ #include #include -#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) - +#if defined(CONFIG_MX6_DDRCAL) static void reset_read_data_fifos(void) { struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h index 12454fa..2a8d443 100644 --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h @@ -458,7 +458,7 @@ void mx6sl_dram_iocfg(unsigned width, const struct mx6sl_iomux_ddr_regs *, const struct mx6sl_iomux_grp_regs *); -#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) +#if defined(CONFIG_MX6_DDRCAL) int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo); int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo); void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo, diff --git a/configs/novena_defconfig b/configs/novena_defconfig index e0d6f2e..4a3e266 100644 --- a/configs/novena_defconfig +++ b/configs/novena_defconfig @@ -3,6 +3,7 @@ CONFIG_ARCH_MX6=y CONFIG_SPL_GPIO_SUPPORT=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_MX6_DDRCAL=y CONFIG_TARGET_KOSAGI_NOVENA=y CONFIG_SPL_EXT_SUPPORT=y CONFIG_SPL_FAT_SUPPORT=y -- cgit v0.10.2 From 22d358da0b06a60d7163e56234dd7f166fdd7b73 Mon Sep 17 00:00:00 2001 From: Ken Lin Date: Fri, 18 Nov 2016 12:20:54 -0500 Subject: board: ge: bx50v3: add the PMIC configuration support Change the PMIC bulk configuration from auto mode to sync mode to avoid voltage dropout issue seen in auto mode. Signed-off-by: Ken Lin Signed-off-by: Akshay Bhat diff --git a/board/ge/bx50v3/bx50v3.c b/board/ge/bx50v3/bx50v3.c index 7e62aef..2fc1144 100644 --- a/board/ge/bx50v3/bx50v3.c +++ b/board/ge/bx50v3/bx50v3.c @@ -596,6 +596,57 @@ static const struct boot_mode board_boot_modes[] = { }; #endif +void pmic_init(void) +{ +#define I2C_PMIC 0x2 +#define DA9063_I2C_ADDR 0x58 +#define DA9063_REG_BCORE2_CFG 0x9D +#define DA9063_REG_BCORE1_CFG 0x9E +#define DA9063_REG_BPRO_CFG 0x9F +#define DA9063_REG_BIO_CFG 0xA0 +#define DA9063_REG_BMEM_CFG 0xA1 +#define DA9063_REG_BPERI_CFG 0xA2 +#define DA9063_BUCK_MODE_MASK 0xC0 +#define DA9063_BUCK_MODE_MANUAL 0x00 +#define DA9063_BUCK_MODE_SLEEP 0x40 +#define DA9063_BUCK_MODE_SYNC 0x80 +#define DA9063_BUCK_MODE_AUTO 0xC0 + + uchar val; + + i2c_set_bus_num(I2C_PMIC); + + i2c_read(DA9063_I2C_ADDR, DA9063_REG_BCORE2_CFG, 1, &val, 1); + val &= ~DA9063_BUCK_MODE_MASK; + val |= DA9063_BUCK_MODE_SYNC; + i2c_write(DA9063_I2C_ADDR, DA9063_REG_BCORE2_CFG, 1, &val, 1); + + i2c_read(DA9063_I2C_ADDR, DA9063_REG_BCORE1_CFG, 1, &val, 1); + val &= ~DA9063_BUCK_MODE_MASK; + val |= DA9063_BUCK_MODE_SYNC; + i2c_write(DA9063_I2C_ADDR, DA9063_REG_BCORE1_CFG, 1, &val, 1); + + i2c_read(DA9063_I2C_ADDR, DA9063_REG_BPRO_CFG, 1, &val, 1); + val &= ~DA9063_BUCK_MODE_MASK; + val |= DA9063_BUCK_MODE_SYNC; + i2c_write(DA9063_I2C_ADDR, DA9063_REG_BPRO_CFG, 1, &val, 1); + + i2c_read(DA9063_I2C_ADDR, DA9063_REG_BIO_CFG, 1, &val, 1); + val &= ~DA9063_BUCK_MODE_MASK; + val |= DA9063_BUCK_MODE_SYNC; + i2c_write(DA9063_I2C_ADDR, DA9063_REG_BIO_CFG, 1, &val, 1); + + i2c_read(DA9063_I2C_ADDR, DA9063_REG_BMEM_CFG, 1, &val, 1); + val &= ~DA9063_BUCK_MODE_MASK; + val |= DA9063_BUCK_MODE_SYNC; + i2c_write(DA9063_I2C_ADDR, DA9063_REG_BMEM_CFG, 1, &val, 1); + + i2c_read(DA9063_I2C_ADDR, DA9063_REG_BPERI_CFG, 1, &val, 1); + val &= ~DA9063_BUCK_MODE_MASK; + val |= DA9063_BUCK_MODE_SYNC; + i2c_write(DA9063_I2C_ADDR, DA9063_REG_BPERI_CFG, 1, &val, 1); +} + int board_late_init(void) { #ifdef CONFIG_CMD_BMODE @@ -619,6 +670,9 @@ int board_late_init(void) pwm_enable(0); #endif + /* board specific pmic init */ + pmic_init(); + return 0; } -- cgit v0.10.2 From d9e268ed766b03c7d2fc36debcd62b6696395aad Mon Sep 17 00:00:00 2001 From: Sebastien Bourdelin Date: Tue, 8 Nov 2016 12:18:07 -0500 Subject: ARM: ts4600: add basic board support This commit adds basic support including: MMC, Serial console Signed-off-by: Sebastien Bourdelin Reviewed-by: Fabio Estevam diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 220022b..ed25e35 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -574,6 +574,11 @@ config ARCH_SUNXI select USB_KEYBOARD if DISTRO_DEFAULTS select USE_TINY_PRINTF +config TARGET_TS4600 + bool "Support TS4600" + select CPU_ARM926EJS + select SUPPORT_SPL + config TARGET_TS4800 bool "Support TS4800" select CPU_V7 @@ -1025,6 +1030,7 @@ source "board/ti/ti816x/Kconfig" source "board/timll/devkit3250/Kconfig" source "board/toradex/colibri_pxa270/Kconfig" source "board/toradex/colibri_vf/Kconfig" +source "board/technologic/ts4600/Kconfig" source "board/technologic/ts4800/Kconfig" source "board/vscom/baltos/Kconfig" source "board/woodburn/Kconfig" diff --git a/board/technologic/ts4600/Kconfig b/board/technologic/ts4600/Kconfig new file mode 100644 index 0000000..d0dc2e1 --- /dev/null +++ b/board/technologic/ts4600/Kconfig @@ -0,0 +1,15 @@ +if TARGET_TS4600 + +config SYS_BOARD + default "ts4600" + +config SYS_VENDOR + default "technologic" + +config SYS_SOC + default "mxs" + +config SYS_CONFIG_NAME + default "ts4600" + +endif diff --git a/board/technologic/ts4600/MAINTAINERS b/board/technologic/ts4600/MAINTAINERS new file mode 100644 index 0000000..6f683b5 --- /dev/null +++ b/board/technologic/ts4600/MAINTAINERS @@ -0,0 +1,6 @@ +TS4600 BOARD +M: Sebastien Bourdelin +S: Maintained +F: board/technologic/ts4600/ +F: include/configs/ts4600.h +F: configs/ts4600_defconfig diff --git a/board/technologic/ts4600/Makefile b/board/technologic/ts4600/Makefile new file mode 100644 index 0000000..faa2970 --- /dev/null +++ b/board/technologic/ts4600/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2016 Savoir-faire Linux +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifndef CONFIG_SPL_BUILD +obj-y := ts4600.o +else +obj-y := iomux.o +endif diff --git a/board/technologic/ts4600/iomux.c b/board/technologic/ts4600/iomux.c new file mode 100644 index 0000000..1398bbe --- /dev/null +++ b/board/technologic/ts4600/iomux.c @@ -0,0 +1,149 @@ +/* + * (C) Copyright 2016 Savoir-faire Linux Inc. + * + * Author: Sebastien Bourdelin + * + * Based on work from TS7680 code by: + * Kris Bahnsen + * Mark Featherston + * https://github.com/embeddedarm/u-boot/tree/master/board/technologic/ts7680 + * + * Derived from MX28EVK code by + * Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +#define MUX_CONFIG_SSP0 (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP) +#define MUX_CONFIG_EMI (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL) + +const iomux_cfg_t iomux_setup[] = { + /* DUART */ + MX28_PAD_PWM0__DUART_RX, + MX28_PAD_PWM1__DUART_TX, + + /* MMC0 */ + MX28_PAD_SSP0_DATA0__SSP0_D0 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA1__SSP0_D1 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA2__SSP0_D2 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA3__SSP0_D3 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_CMD__SSP0_CMD | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_SCK__SSP0_SCK | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + + /* MMC0 slot power enable */ + MX28_PAD_PWM3__GPIO_3_28 | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + + /* EMI */ + MX28_PAD_EMI_D00__EMI_DATA0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D01__EMI_DATA1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D02__EMI_DATA2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D03__EMI_DATA3 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D04__EMI_DATA4 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D05__EMI_DATA5 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D06__EMI_DATA6 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D07__EMI_DATA7 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D08__EMI_DATA8 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D09__EMI_DATA9 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D10__EMI_DATA10 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D11__EMI_DATA11 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D12__EMI_DATA12 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D13__EMI_DATA13 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D14__EMI_DATA14 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D15__EMI_DATA15 | MUX_CONFIG_EMI, + MX28_PAD_EMI_ODT0__EMI_ODT0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQM0__EMI_DQM0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_ODT1__EMI_ODT1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQM1__EMI_DQM1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK | MUX_CONFIG_EMI, + MX28_PAD_EMI_CLK__EMI_CLK | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQS0__EMI_DQS0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQS1__EMI_DQS1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN | MUX_CONFIG_EMI, + MX28_PAD_EMI_A00__EMI_ADDR0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A01__EMI_ADDR1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A02__EMI_ADDR2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A03__EMI_ADDR3 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A04__EMI_ADDR4 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A05__EMI_ADDR5 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A06__EMI_ADDR6 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A07__EMI_ADDR7 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A08__EMI_ADDR8 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A09__EMI_ADDR9 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A10__EMI_ADDR10 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A11__EMI_ADDR11 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A12__EMI_ADDR12 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A13__EMI_ADDR13 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A14__EMI_ADDR14 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA0__EMI_BA0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA1__EMI_BA1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA2__EMI_BA2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_CASN__EMI_CASN | MUX_CONFIG_EMI, + MX28_PAD_EMI_RASN__EMI_RASN | MUX_CONFIG_EMI, + MX28_PAD_EMI_WEN__EMI_WEN | MUX_CONFIG_EMI, + MX28_PAD_EMI_CE0N__EMI_CE0N | MUX_CONFIG_EMI, + MX28_PAD_EMI_CE1N__EMI_CE1N | MUX_CONFIG_EMI, + MX28_PAD_EMI_CKE__EMI_CKE | MUX_CONFIG_EMI, + + /* I2C */ + MX28_PAD_I2C0_SCL__I2C0_SCL, + MX28_PAD_I2C0_SDA__I2C0_SDA, + +}; + +#define HW_DRAM_CTL29 (0x74 >> 2) +#define CS_MAP 0xf +#define COLUMN_SIZE 0x2 +#define ADDR_PINS 0x1 +#define APREBIT 0xa + +#define HW_DRAM_CTL29_CONFIG (CS_MAP << 24 | COLUMN_SIZE << 16 | \ + ADDR_PINS << 8 | APREBIT) + +#define HW_DRAM_CTL39 (0x9c >> 2) +#define TFAW 0xb +#define TDLL 0xc8 + +#define HW_DRAM_CTL39_CONFIG (TFAW << 24 | TDLL) + +#define HW_DRAM_CTL41 (0xa4 >> 2) +#define TPDEX 0x2 +#define TRCD_INT 0x4 +#define TRC 0xd + +#define HW_DRAM_CTL41_CONFIG (TPDEX << 24 | TRCD_INT << 8 | TRC) + +#define HW_DRAM_CTL42 (0xa8 >> 2) +#define TRAS_MAX 0x36a6 +#define TRAS_MIN 0xa + +#define HW_DRAM_CTL42_CONFIG (TRAS_MAX << 8 | TRAS_MIN) + +#define HW_DRAM_CTL43 (0xac >> 2) +#define TRP 0x4 +#define TRFC 0x27 +#define TREF 0x2a0 + +#define HW_DRAM_CTL43_CONFIG (TRP << 24 | TRFC << 16 | TREF) + +void mxs_adjust_memory_params(uint32_t *dram_vals) +{ + dram_vals[HW_DRAM_CTL29] = HW_DRAM_CTL29_CONFIG; + dram_vals[HW_DRAM_CTL39] = HW_DRAM_CTL39_CONFIG; + dram_vals[HW_DRAM_CTL41] = HW_DRAM_CTL41_CONFIG; + dram_vals[HW_DRAM_CTL42] = HW_DRAM_CTL42_CONFIG; + dram_vals[HW_DRAM_CTL43] = HW_DRAM_CTL43_CONFIG; +} + +void board_init_ll(const uint32_t arg, const uint32_t *resptr) +{ + mxs_common_spl_init(arg, resptr, iomux_setup, ARRAY_SIZE(iomux_setup)); +} diff --git a/board/technologic/ts4600/ts4600.c b/board/technologic/ts4600/ts4600.c new file mode 100644 index 0000000..70dfead --- /dev/null +++ b/board/technologic/ts4600/ts4600.c @@ -0,0 +1,89 @@ +/* + * (C) Copyright 2016 Savoir-faire Linux Inc. + * + * Author: Sebastien Bourdelin + * + * Based on work from TS7680 code by: + * Kris Bahnsen + * Mark Featherston + * https://github.com/embeddedarm/u-boot/tree/master/board/technologic/ts7680 + * + * Derived from MX28EVK code by + * Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ + /* IO0 clock at 480MHz */ + mxs_set_ioclk(MXC_IOCLK0, 480000); + /* IO1 clock at 480MHz */ + mxs_set_ioclk(MXC_IOCLK1, 480000); + + /* SSP0 clocks at 96MHz */ + mxs_set_sspclk(MXC_SSPCLK0, 96000, 0); + + return 0; +} + +int dram_init(void) +{ + return mxs_dram_init(); +} + +int board_init(void) +{ + /* Adress of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + + return 0; +} + +#ifdef CONFIG_CMD_MMC +static int ts4600_mmc_cd(int id) +{ + return 1; +} + +int board_mmc_init(bd_t *bis) +{ + int ret; + + mxs_iomux_setup_pad(MX28_PAD_PWM3__GPIO_3_28); + + /* Power-on SD */ + gpio_direction_output(MX28_PAD_PWM3__GPIO_3_28, 1); + udelay(1000); + gpio_direction_output(MX28_PAD_PWM3__GPIO_3_28, 0); + + /* SD card */ + ret = mxsmmc_initialize(bis, 0, NULL, ts4600_mmc_cd); + if(ret != 0) { + printf("SD controller initialized with %d\n", ret); + } + + return ret; +} +#endif + +int checkboard(void) +{ + puts("Board: TS4600\n"); + + return 0; +} diff --git a/configs/ts4600_defconfig b/configs/ts4600_defconfig new file mode 100644 index 0000000..c052ded --- /dev/null +++ b/configs/ts4600_defconfig @@ -0,0 +1,18 @@ +CONFIG_ARM=y +CONFIG_TARGET_TS4600=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_FIT=y +CONFIG_SYS_EXTRA_OPTIONS="ENV_IS_IN_MMC" +CONFIG_SYS_CONSOLE_IS_IN_ENV=y +CONFIG_SPL=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_OF_LIBFDT=y diff --git a/include/configs/ts4600.h b/include/configs/ts4600.h new file mode 100644 index 0000000..9b7bd1b --- /dev/null +++ b/include/configs/ts4600.h @@ -0,0 +1,70 @@ +/* + * (C) Copyright 2016 Savoir-faire Linux Inc. + * + * Author: Sebastien Bourdelin + * + * Derived from MX28EVK code by + * Fabio Estevam + * Freescale Semiconductor, Inc. + * + * Configuration settings for the TS4600 Board + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __CONFIGS_TS4600_H__ +#define __CONFIGS_TS4600_H__ + +/* System configurations */ +#define CONFIG_MX28 /* i.MX28 SoC */ + +/* U-Boot Commands */ +#define CONFIG_SYS_NO_FLASH /* No NOR Flash */ +#define CONFIG_DOS_PARTITION + +/* Memory configuration */ +#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */ +#define PHYS_SDRAM_1 0x40000000 /* Base address */ +#define PHYS_SDRAM_1_SIZE 0x40000000 /* Max 1 GB RAM */ +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 + +/* Environment */ +#define CONFIG_ENV_SIZE (8 * 1024) + +/* Environment is in MMC */ +#if defined(CONFIG_CMD_MMC) && defined(CONFIG_ENV_IS_IN_MMC) +#define CONFIG_ENV_OFFSET (256 * 1024) +#define CONFIG_SYS_MMC_ENV_DEV 0 +#endif + +/* Boot Linux */ +#define CONFIG_LOADADDR 0x42000000 +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +/* Extra Environment */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_addr=0x41000000\0" \ + "loadkernel=load mmc ${mmcdev}:${mmcpart} ${loadaddr} zImage\0" \ + "loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr} imx28-ts4600.dtb\0" \ + "loadbootscript=load mmc ${mmcdev}:${mmcpart} ${loadaddr} boot.ub\0" \ + "bootscript=echo Running bootscript from mmc...; " \ + "setenv mmcdev 0; " \ + "setenv mmcpart 2; " \ + "run loadbootscript && source ${loadaddr}; \0" \ + "sdboot=echo Booting from SD card ...; " \ + "setenv mmcdev 0; " \ + "setenv mmcpart 2; " \ + "setenv root /dev/mmcblk0p3; " \ + "run loadkernel && run loadfdt; \0" \ + "startbootsequence=run bootscript || run sdboot \0" \ + +#define CONFIG_BOOTCOMMAND \ + "mmc rescan; " \ + "run startbootsequence; " \ + "setenv cmdline_append console=ttyAMA0,115200; " \ + "setenv bootargs root=${root} rootwait rw ${cmdline_append}; " \ + "bootz ${loadaddr} - ${fdt_addr}; " + +/* The rest of the configuration is shared */ +#include + +#endif /* __CONFIGS_TS4600_H__ */ -- cgit v0.10.2 From 3ed82d6f9bcb3dd2403d432af28787ba1d83fe1b Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Fri, 25 Nov 2016 16:19:17 +0530 Subject: colibri_vf: Read kernel and device tree from static UBI volumes Our update scripts write the kernel and device tree in seperate UBI volumes. This allows to use a lot less UBI/UBIFS support in U-Boot, which should lower the risk of hitting bugs in this area. Signed-off-by: Sanchayan Maity diff --git a/include/configs/colibri_vf.h b/include/configs/colibri_vf.h index 0cd77ff..d58145e 100644 --- a/include/configs/colibri_vf.h +++ b/include/configs/colibri_vf.h @@ -116,9 +116,9 @@ "ubiboot=run setup; " \ "setenv bootargs ${defargs} ${ubiargs} ${mtdparts} " \ "${setupargs} ${vidargs}; echo Booting from NAND...; " \ - "ubi part ubi && ubifsmount ubi0:rootfs && " \ - "ubifsload ${kernel_addr_r} /boot/${kernel_file} && " \ - "ubifsload ${fdt_addr_r} /boot/${soc}-colibri-${fdt_board}.dtb && " \ + "ubi part ubi && " \ + "ubi read ${kernel_addr_r} kernel && " \ + "ubi read ${fdt_addr_r} dtb && " \ "bootz ${kernel_addr_r} - ${fdt_addr_r}\0" \ #define CONFIG_BOOTCOMMAND "run ubiboot; run sdboot; run nfsboot" -- cgit v0.10.2 From 792f186846672140deca7dfbf2f20aece26b5348 Mon Sep 17 00:00:00 2001 From: Breno Lima Date: Fri, 25 Nov 2016 16:56:57 -0200 Subject: mx6sx: Add initial support for UDOO Neo Board UDOO Neo Board is a development board from Seco that has three models: - UDOO Neo Basic - UDOO Neo Basic Kick Starter - UDOO Neo Extended - UDOO Neo Full All versions are based on the i.MX6 SoloX processor. For more details about the UDOO Neo board, please refer to: http://www.udoo.org/udoo-neo/ This work is based on a previous commit of Francesco Montefoschi : https://github.com/fmntf/u-boot/commit/877b71184a5105e708024f232d36aed574961844 Only tested on the UDOO Neo Full board. Signed-off-by: Breno Lima Reviewed-by: Fabio Estevam diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig index 8b2217e..a81d944 100644 --- a/arch/arm/cpu/armv7/mx6/Kconfig +++ b/arch/arm/cpu/armv7/mx6/Kconfig @@ -200,6 +200,10 @@ config TARGET_UDOO bool "udoo" select SUPPORT_SPL +config TARGET_UDOO_NEO + bool "UDOO Neo" + select SUPPORT_SPL + config TARGET_WANDBOARD bool "wandboard" select SUPPORT_SPL @@ -261,6 +265,7 @@ source "board/technexion/pico-imx6ul/Kconfig" source "board/tbs/tbs2910/Kconfig" source "board/tqc/tqma6/Kconfig" source "board/udoo/Kconfig" +source "board/udoo/neo/Kconfig" source "board/wandboard/Kconfig" source "board/warp/Kconfig" diff --git a/board/udoo/neo/Kconfig b/board/udoo/neo/Kconfig new file mode 100644 index 0000000..8f474df --- /dev/null +++ b/board/udoo/neo/Kconfig @@ -0,0 +1,12 @@ +if TARGET_UDOO_NEO + +config SYS_VENDOR + default "udoo" + +config SYS_BOARD + default "neo" + +config SYS_CONFIG_NAME + default "udoo_neo" + +endif diff --git a/board/udoo/neo/MAINTAINERS b/board/udoo/neo/MAINTAINERS new file mode 100644 index 0000000..743fe33 --- /dev/null +++ b/board/udoo/neo/MAINTAINERS @@ -0,0 +1,7 @@ +UDOO NEO BOARD +M: Breno Lima +M: Francesco Montefoschi +S: Maintained +F: board/udoo/neo/ +F: include/configs/udoo_neo.h +F: configs/udoo_neo_defconfig diff --git a/board/udoo/neo/Makefile b/board/udoo/neo/Makefile new file mode 100644 index 0000000..150cbc1 --- /dev/null +++ b/board/udoo/neo/Makefile @@ -0,0 +1,6 @@ +# (C) Copyright 2015 UDOO Team +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := neo.o diff --git a/board/udoo/neo/neo.c b/board/udoo/neo/neo.c new file mode 100644 index 0000000..7f17469 --- /dev/null +++ b/board/udoo/neo/neo.c @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. + * Copyright (C) Jasbir Matharu + * Copyright (C) UDOO Team + * + * Author: Breno Lima + * Author: Francesco Montefoschi + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +enum { + UDOO_NEO_TYPE_BASIC, + UDOO_NEO_TYPE_BASIC_KS, + UDOO_NEO_TYPE_FULL, + UDOO_NEO_TYPE_EXTENDED, +}; + +#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define WDOG_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm) + +#define BOARD_DETECT_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_34ohm | PAD_CTL_HYS | PAD_CTL_SRE_FAST) +#define BOARD_DETECT_PAD_CFG (MUX_PAD_CTRL(BOARD_DETECT_PAD_CTRL) | \ + MUX_MODE_SION) + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + return 0; +} + +static iomux_v3_cfg_t const uart1_pads[] = { + MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc2_pads[] = { + MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + /* CD pin */ + MX6_PAD_SD1_DATA0__GPIO6_IO_2 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* Power */ + MX6_PAD_SD1_CMD__GPIO6_IO_1 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const board_recognition_pads[] = { + /*Connected to R184*/ + MX6_PAD_NAND_READY_B__GPIO4_IO_13 | BOARD_DETECT_PAD_CFG, + /*Connected to R185*/ + MX6_PAD_NAND_ALE__GPIO4_IO_0 | BOARD_DETECT_PAD_CFG, +}; + +static iomux_v3_cfg_t const usdhc3_pads[] = { + /* Configured for WLAN */ + MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA0__USDHC3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA1__USDHC3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA2__USDHC3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA3__USDHC3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +static iomux_v3_cfg_t const wdog_b_pad = { + MX6_PAD_GPIO1_IO13__GPIO1_IO_13 | MUX_PAD_CTRL(WDOG_PAD_CTRL), +}; + +static iomux_v3_cfg_t const peri_3v3_pads[] = { + MX6_PAD_QSPI1A_DATA0__GPIO4_IO_16 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void setup_iomux_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); +} + +int board_init(void) +{ + /* Address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + /* + * Because kernel set WDOG_B mux before pad with the commone pinctrl + * framwork now and wdog reset will be triggered once set WDOG_B mux + * with default pad setting, we set pad setting here to workaround this. + * Since imx_iomux_v3_setup_pad also set mux before pad setting, we set + * as GPIO mux firstly here to workaround it. + */ + imx_iomux_v3_setup_pad(wdog_b_pad); + + /* Enable PERI_3V3, which is used by SD2, ENET, LVDS, BT */ + imx_iomux_v3_setup_multiple_pads(peri_3v3_pads, + ARRAY_SIZE(peri_3v3_pads)); + + /* Active high for ncp692 */ + gpio_direction_output(IMX_GPIO_NR(4, 16) , 1); + + return 0; +} + +static int get_board_value(void) +{ + int r184, r185; + + imx_iomux_v3_setup_multiple_pads(board_recognition_pads, + ARRAY_SIZE(board_recognition_pads)); + + gpio_direction_input(IMX_GPIO_NR(4, 13)); + gpio_direction_input(IMX_GPIO_NR(4, 0)); + + r184 = gpio_get_value(IMX_GPIO_NR(4, 13)); + r185 = gpio_get_value(IMX_GPIO_NR(4, 0)); + + /* + * Machine selection - + * Machine r184, r185 + * --------------------------------- + * Basic 0 0 + * Basic Ks 0 1 + * Full 1 0 + * Extended 1 1 + */ + + return (r184 << 1) + r185; +} + +int board_early_init_f(void) +{ + setup_iomux_uart(); + + return 0; +} + +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC2_BASE_ADDR, 0, 4}, + {USDHC3_BASE_ADDR, 0, 4}, +}; + +#define USDHC2_PWR_GPIO IMX_GPIO_NR(6, 1) +#define USDHC2_CD_GPIO IMX_GPIO_NR(6, 2) + +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 USDHC2_BASE_ADDR: + ret = !gpio_get_value(USDHC2_CD_GPIO); + break; + } + + return ret; +} + +int board_mmc_init(bd_t *bis) +{ +#ifndef CONFIG_SPL_BUILD + int i, ret; + + /* + * According to the board_mmc_init() the following map is done: + * (U-boot device node) (Physical Port) + * mmc0 USDHC2 + */ + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + switch (i) { + case 0: + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gpio_direction_input(USDHC2_CD_GPIO); + gpio_direction_output(USDHC2_PWR_GPIO, 1); + break; + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + 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("Warning:\ + failed to initialize mmc dev %d\n", i); + return ret; + } + } + + return 0; +#else + struct src *src_regs = (struct src *)SRC_BASE_ADDR; + u32 val; + u32 port; + + val = readl(&src_regs->sbmr1); + + if ((val & 0xc0) != 0x40) { + printf("Not boot from USDHC!\n"); + return -EINVAL; + } + + port = (val >> 11) & 0x3; + printf("port %d\n", port); + switch (port) { + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; + gpio_direction_input(USDHC2_CD_GPIO); + gpio_direction_output(USDHC2_PWR_GPIO, 1); + break; + case 2: + imx_iomux_v3_setup_multiple_pads( + usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + usdhc_cfg[1].esdhc_base = USDHC3_BASE_ADDR; + break; + } + + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +#endif +} + +char *board_string(void) +{ + switch (get_board_value()) { + case UDOO_NEO_TYPE_BASIC: + return "BASIC"; + case UDOO_NEO_TYPE_BASIC_KS: + return "BASICKS"; + case UDOO_NEO_TYPE_FULL: + return "FULL"; + case UDOO_NEO_TYPE_EXTENDED: + return "EXTENDED"; + } + return "UNDEFINED"; +} + +int checkboard(void) +{ + printf("Board: UDOO Neo %s\n", board_string()); + return 0; +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + setenv("board_name", board_string()); +#endif + + return 0; +} + +#ifdef CONFIG_SPL_BUILD + +#include +#include + +static const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = { + .dram_dqm0 = 0x00000028, + .dram_dqm1 = 0x00000028, + .dram_dqm2 = 0x00000028, + .dram_dqm3 = 0x00000028, + .dram_ras = 0x00000020, + .dram_cas = 0x00000020, + .dram_odt0 = 0x00000020, + .dram_odt1 = 0x00000020, + .dram_sdba2 = 0x00000000, + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + .dram_sdclk_0 = 0x00000030, + .dram_sdqs0 = 0x00000028, + .dram_sdqs1 = 0x00000028, + .dram_sdqs2 = 0x00000028, + .dram_sdqs3 = 0x00000028, + .dram_reset = 0x00000020, +}; + +static const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = { + .grp_addds = 0x00000020, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000028, + .grp_b1ds = 0x00000028, + .grp_ctlds = 0x00000020, + .grp_ddr_type = 0x000c0000, + .grp_b2ds = 0x00000028, + .grp_b3ds = 0x00000028, +}; + +static const struct mx6_mmdc_calibration neo_mmcd_calib = { + .p0_mpwldectrl0 = 0x000E000B, + .p0_mpwldectrl1 = 0x000E0010, + .p0_mpdgctrl0 = 0x41600158, + .p0_mpdgctrl1 = 0x01500140, + .p0_mprddlctl = 0x3A383E3E, + .p0_mpwrdlctl = 0x3A383C38, +}; + +static const struct mx6_mmdc_calibration neo_basic_mmcd_calib = { + .p0_mpwldectrl0 = 0x001E0022, + .p0_mpwldectrl1 = 0x001C0019, + .p0_mpdgctrl0 = 0x41540150, + .p0_mpdgctrl1 = 0x01440138, + .p0_mprddlctl = 0x403E4644, + .p0_mpwrdlctl = 0x3C3A4038, +}; + +/* MT41K256M16 */ +static struct mx6_ddr3_cfg neo_mem_ddr = { + .mem_speed = 1600, + .density = 4, + .width = 16, + .banks = 8, + .rowaddr = 15, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +/* MT41K128M16 */ +static struct mx6_ddr3_cfg neo_basic_mem_ddr = { + .mem_speed = 1600, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0xFFFFFFFF, &ccm->CCGR0); + writel(0xFFFFFFFF, &ccm->CCGR1); + writel(0xFFFFFFFF, &ccm->CCGR2); + writel(0xFFFFFFFF, &ccm->CCGR3); + writel(0xFFFFFFFF, &ccm->CCGR4); + writel(0xFFFFFFFF, &ccm->CCGR5); + writel(0xFFFFFFFF, &ccm->CCGR6); + writel(0xFFFFFFFF, &ccm->CCGR7); +} + +static void spl_dram_init(void) +{ + int board = get_board_value(); + + struct mx6_ddr_sysinfo sysinfo = { + .dsize = 1, /* width of data bus: 1 = 32 bits */ + .cs_density = 24, + .ncs = 1, + .cs1_mirror = 0, + .rtt_wr = 2, + .rtt_nom = 2, /* RTT_Nom = RZQ/2 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + }; + + mx6sx_dram_iocfg(32, &mx6_ddr_ioregs, &mx6_grp_ioregs); + if (board == UDOO_NEO_TYPE_BASIC || board == UDOO_NEO_TYPE_BASIC_KS) + mx6_dram_cfg(&sysinfo, &neo_basic_mmcd_calib, + &neo_basic_mem_ddr); + else + mx6_dram_cfg(&sysinfo, &neo_mmcd_calib, &neo_mem_ddr); +} + +void board_init_f(ulong dummy) +{ + ccgr_init(); + + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* DDR initialization */ + spl_dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} + +#endif diff --git a/configs/udoo_neo_defconfig b/configs/udoo_neo_defconfig new file mode 100644 index 0000000..3304afb --- /dev/null +++ b/configs/udoo_neo_defconfig @@ -0,0 +1,30 @@ +CONFIG_ARM=y +CONFIG_ARCH_MX6=y +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_TARGET_UDOO_NEO=y +CONFIG_SPL_EXT_SUPPORT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_WATCHDOG_SUPPORT=y +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6SX" +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_DHCP=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_OF_LIBFDT=y diff --git a/include/configs/udoo_neo.h b/include/configs/udoo_neo.h new file mode 100644 index 0000000..81e0481 --- /dev/null +++ b/include/configs/udoo_neo.h @@ -0,0 +1,94 @@ +/* + * Copyright 2014-2015 Freescale Semiconductor, Inc. + * Copyright Jasbir Matharu + * Copyright 2015 UDOO Team + * + * Configuration settings for the UDOO NEO board. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include +#include "mx6_common.h" + +#include "imx6_spl.h" + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (3 * SZ_1M) +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT +#define CONFIG_MXC_UART + +/* MMC Configuration */ +#define CONFIG_SYS_FSL_ESDHC_ADDR USDHC2_BASE_ADDR + +/* Command definition */ +#define CONFIG_MXC_UART_BASE UART1_BASE +#define CONFIG_SYS_FSL_USDHC_NUM 2 +#define CONFIG_SYS_MMC_ENV_DEV 0 /*USDHC2*/ + +/* Linux only */ +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#define CONFIG_EXTRA_ENV_SETTINGS \ + "console=ttymxc0,115200\0" \ + "fdt_high=0xffffffff\0" \ + "initrd_high=0xffffffff\0" \ + "fdt_file=undefined\0" \ + "fdt_addr=0x83000000\0" \ + "ip_dyn=yes\0" \ + "mmcdev=0\0" \ + "mmcrootfstype=ext4\0" \ + "mmcautodetect=no\0" \ + "findfdt="\ + "if test $board_name = BASIC; then " \ + "setenv fdt_file imx6sx-udoo-neo-basic.dtb; fi; " \ + "if test $board_name = BASICKS; then " \ + "setenv fdt_file imx6sx-udoo-neo-basic.dtb; fi; " \ + "if test $board_name = FULL; then " \ + "setenv fdt_file imx6sx-udoo-neo-full.dtb; fi; " \ + "if test $board_name = EXTENDED; then " \ + "setenv fdt_file imx6sx-udoo-neo-extended.dtb; fi; " \ + "if test $fdt_file = UNDEFINED; then " \ + "echo WARNING: Could not determine dtb to use; fi; \0" \ + "kernel_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \ + "pxefile_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \ + "ramdisk_addr_r=0x83000000\0" \ + "ramdiskaddr=0x83000000\0" \ + "scriptaddr=" __stringify(CONFIG_LOADADDR) "\0" \ + BOOTENV + +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) + +#define CONFIG_BOOTCOMMAND \ + "run findfdt; " \ + "run distro_bootcmd" + +#include + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_MEMTEST_START 0x80000000 +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x10000) +#define CONFIG_STACKSIZE SZ_128K + +/* Physical Memory Map */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE + +#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) + +/* Environment organization */ +#define CONFIG_ENV_OFFSET (8 * SZ_64K) +#define CONFIG_ENV_SIZE SZ_8K +#define CONFIG_ENV_IS_IN_MMC + +#endif /* __CONFIG_H */ -- cgit v0.10.2 From 0405092bd21a44f5af22f17aeb0b82a0a11e1252 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 15 Nov 2016 10:38:23 -0800 Subject: arm: mx6: specify SPL padding Specify standard padding for payload to 68KB. This is derived from the maximum header size plus maximum SPL size. It matches the already defined offset for SD/eMMC devices (69KB) too. This allows to use the u-boot-with-spl.imx build target to generate a directly flashable image which can be flashed using: dd if=u-boot-with-spl.imx of=/dev/mmcblk0 bs=512 skip=2 While the patch has been created with SD/eMMC in mind, this also works with other boot media. The board file needs to configure the media specific (absolute) payload offset accordingly. Especially the IVT offset is boot media specific and can be retrieved from the reference manual (Table 8-25. Image Vector Table Offset and Initial Load Region Size). For NAND boot a define like this should do the job: #define CONFIG_SYS_NAND_U_BOOT_OFFS (SPL_PAD_TO + 0x400) Signed-off-by: Stefan Agner diff --git a/include/configs/imx6_spl.h b/include/configs/imx6_spl.h index dce4438..c5a035f 100644 --- a/include/configs/imx6_spl.h +++ b/include/configs/imx6_spl.h @@ -29,6 +29,12 @@ #define CONFIG_SPL_TEXT_BASE 0x00908000 #define CONFIG_SPL_MAX_SIZE 0x10000 #define CONFIG_SPL_STACK 0x0091FFB8 +/* + * Pad SPL to 68KB (4KB header + 64KB max size). This allows to write the + * SPL/U-Boot combination generated with u-boot-with-spl.imx directly to a + * boot media (given that boot media specific offset is configured properly). + */ +#define CONFIG_SPL_PAD_TO 0x11000 /* NAND support */ #if defined(CONFIG_SPL_NAND_SUPPORT) -- cgit v0.10.2 From 9cd37b02a010addfbe6b2ed5b2eacd5bd7e36fb8 Mon Sep 17 00:00:00 2001 From: Angus Ainslie Date: Fri, 11 Nov 2016 11:31:39 -0700 Subject: imx7: SPI: add suport for SPI flash in mikroBUS slot Enable the escpi3 nets attached to the mikroBUS slot on the i.MX7 Sabre evalution board. Also enble the SPI flash commands to work with the "flash click" board. This is V2 of this patch with changes recommended by the maintainer CC: Jagan Teki diff --git a/board/freescale/mx7dsabresd/mx7dsabresd.c b/board/freescale/mx7dsabresd/mx7dsabresd.c index b936544..6ccdd4b 100644 --- a/board/freescale/mx7dsabresd/mx7dsabresd.c +++ b/board/freescale/mx7dsabresd/mx7dsabresd.c @@ -50,6 +50,9 @@ DECLARE_GLOBAL_DATA_PTR; #define NAND_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_SRE_SLOW | PAD_CTL_HYS) +#define SPI_PAD_CTRL \ + (PAD_CTL_HYS | PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_SRE_FAST) + #define NAND_PAD_READY0_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_PUS_PU5KOHM) #ifdef CONFIG_SYS_I2C_MXC #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) @@ -68,6 +71,23 @@ static struct i2c_pads_info i2c_pad_info1 = { }; #endif +static iomux_v3_cfg_t const ecspi3_pads[] = { + MX7D_PAD_SAI2_RX_DATA__ECSPI3_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX7D_PAD_SAI2_TX_SYNC__ECSPI3_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX7D_PAD_SAI2_TX_BCLK__ECSPI3_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX7D_PAD_SAI2_TX_DATA__GPIO6_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +int board_spi_cs_gpio(unsigned bus, unsigned cs) +{ + return (bus == 2 && cs == 0) ? (IMX_GPIO_NR(6, 22)) : -1; +} + +static void setup_spi(void) +{ + imx_iomux_v3_setup_multiple_pads(ecspi3_pads, ARRAY_SIZE(ecspi3_pads)); +} + int dram_init(void) { gd->ram_size = PHYS_SDRAM_SIZE; @@ -553,6 +573,10 @@ int board_init(void) board_qspi_init(); #endif +#ifdef CONFIG_MXC_SPI + setup_spi(); +#endif + return 0; } diff --git a/configs/mx7dsabresd_secure_defconfig b/configs/mx7dsabresd_secure_defconfig index 126ce31..ef93522 100644 --- a/configs/mx7dsabresd_secure_defconfig +++ b/configs/mx7dsabresd_secure_defconfig @@ -45,3 +45,6 @@ CONFIG_G_DNL_MANUFACTURER="FSL" CONFIG_G_DNL_VENDOR_NUM=0x0525 CONFIG_G_DNL_PRODUCT_NUM=0xa4a5 CONFIG_OF_LIBFDT=y +CONFIG_SPI_FLASH=y +CONFIG_CMD_SF=y +CONFIG_SPI_FLASH_EON=y diff --git a/include/configs/mx7dsabresd.h b/include/configs/mx7dsabresd.h index 360a5e0..ca5f9db 100644 --- a/include/configs/mx7dsabresd.h +++ b/include/configs/mx7dsabresd.h @@ -201,6 +201,9 @@ #define CONFIG_ENV_SIZE SZ_8K #define CONFIG_ENV_IS_IN_MMC +/* MXC SPI driver support */ +#define CONFIG_MXC_SPI + /* * If want to use nand, define CONFIG_NAND_MXS and rework board * to support nand, since emmc has pin conflicts with nand -- cgit v0.10.2 From 730d25443aa894a32b9f66ebde3bfbf64b73ac7a Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Tue, 29 Nov 2016 16:13:40 +0100 Subject: mx6sx: Add initial support for Samtec VIN|ING 2000 board This patch adds initial support for Samtec VIN|ING 2000 board. Signed-off-by: Christoph Fritz Reviewed-by: Stefano Babic Acked-by: Marek Vasut diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig index a81d944..8c96ba3 100644 --- a/arch/arm/cpu/armv7/mx6/Kconfig +++ b/arch/arm/cpu/armv7/mx6/Kconfig @@ -204,6 +204,12 @@ config TARGET_UDOO_NEO bool "UDOO Neo" select SUPPORT_SPL +config TARGET_SAMTEC_VINING_2000 + bool "samtec VIN|ING 2000" + select MX6SX + select DM + select DM_THERMAL + config TARGET_WANDBOARD bool "wandboard" select SUPPORT_SPL @@ -259,6 +265,7 @@ source "board/freescale/mx6ullevk/Kconfig" source "board/phytec/pcm058/Kconfig" source "board/gateworks/gw_ventana/Kconfig" source "board/kosagi/novena/Kconfig" +source "board/samtec/vining_2000/Kconfig" source "board/seco/Kconfig" source "board/solidrun/mx6cuboxi/Kconfig" source "board/technexion/pico-imx6ul/Kconfig" diff --git a/board/samtec/vining_2000/Kconfig b/board/samtec/vining_2000/Kconfig new file mode 100644 index 0000000..3447c27 --- /dev/null +++ b/board/samtec/vining_2000/Kconfig @@ -0,0 +1,12 @@ +if TARGET_SAMTEC_VINING_2000 + +config SYS_BOARD + default "vining_2000" + +config SYS_VENDOR + default "samtec" + +config SYS_CONFIG_NAME + default "vining_2000" + +endif diff --git a/board/samtec/vining_2000/MAINTAINERS b/board/samtec/vining_2000/MAINTAINERS new file mode 100644 index 0000000..027e527 --- /dev/null +++ b/board/samtec/vining_2000/MAINTAINERS @@ -0,0 +1,6 @@ +VINING_2000 BOARD +M: Ingo Schroeck +S: Maintained +F: board/samtec/vining_2000/ +F: include/configs/vining_2000.h +F: configs/vining_2000_defconfig diff --git a/board/samtec/vining_2000/Makefile b/board/samtec/vining_2000/Makefile new file mode 100644 index 0000000..1b32f66 --- /dev/null +++ b/board/samtec/vining_2000/Makefile @@ -0,0 +1,6 @@ +# (C) Copyright 2016 samtec automotive software & electronics gmbh +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := vining_2000.o diff --git a/board/samtec/vining_2000/imximage.cfg b/board/samtec/vining_2000/imximage.cfg new file mode 100644 index 0000000..4133dda --- /dev/null +++ b/board/samtec/vining_2000/imximage.cfg @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2016 samtec automotive software & electronics gmbh + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define __ASSEMBLY__ +#include + +/* image version */ + +IMAGE_VERSION 2 + +/* + * Boot Device : one of + * spi/sd/nand/onenand, qspi/nor + */ + +BOOT_FROM sd + +/* + * Device Configuration Data (DCD) + * + * Each entry must have the format: + * Addr-type Address Value + * + * where: + * Addr-type register length (1,2 or 4 bytes) + * Address absolute address of the register + * value value to be stored in the register + */ + +/* Enable all clocks */ +DATA 4 0x020c4068 0xffffffff +DATA 4 0x020c406c 0xffffffff +DATA 4 0x020c4070 0xffffffff +DATA 4 0x020c4074 0xffffffff +DATA 4 0x020c4078 0xffffffff +DATA 4 0x020c407c 0xffffffff +DATA 4 0x020c4080 0xffffffff +DATA 4 0x020c4084 0xffffffff + +/* IOMUX - DDR IO Type */ +DATA 4 0x020e0618 0x000c0000 +DATA 4 0x020e05fc 0x00000000 + +/* Clock */ +DATA 4 0x020e032c 0x00000030 + +/* Address */ +DATA 4 0x020e0300 0x00000028 +DATA 4 0x020e02fc 0x00000028 +DATA 4 0x020e05f4 0x00000028 + +/* Control */ +DATA 4 0x020e0340 0x00000028 + +DATA 4 0x020e0320 0x00000000 +DATA 4 0x020e0310 0x00000028 +DATA 4 0x020e0314 0x00000028 +DATA 4 0x020e0614 0x00000028 + +/* Data Strobe */ +DATA 4 0x020e05f8 0x00020000 +DATA 4 0x020e0330 0x00000028 +DATA 4 0x020e0334 0x00000028 +DATA 4 0x020e0338 0x00000028 +DATA 4 0x020e033c 0x00000028 + +/* Data */ +DATA 4 0x020e0608 0x00020000 +DATA 4 0x020e060c 0x00000028 +DATA 4 0x020e0610 0x00000028 +DATA 4 0x020e061c 0x00000028 +DATA 4 0x020e0620 0x00000028 +DATA 4 0x020e02ec 0x00000028 +DATA 4 0x020e02f0 0x00000028 +DATA 4 0x020e02f4 0x00000028 +DATA 4 0x020e02f8 0x00000028 + +/* Calibrations - ZQ */ +DATA 4 0x021b0800 0xa1390003 + +/* Write leveling */ +DATA 4 0x021b080c 0x00290025 +DATA 4 0x021b0810 0x00210022 + +/* DQS Read Gate */ +DATA 4 0x021b083c 0x4142013a +DATA 4 0x021b0840 0x012e0123 + +/* Read/Write Delay */ +DATA 4 0x021b0848 0x43474949 +DATA 4 0x021b0850 0x38383c38 + +/* Read data bit delay */ +DATA 4 0x021b081c 0x33333333 +DATA 4 0x021b0820 0x33333333 +DATA 4 0x021b0824 0x33333333 +DATA 4 0x021b0828 0x33333333 + +/* Complete calibration by forced measurement */ +DATA 4 0x021b08b8 0x00000800 + +/* MMDC init - DDR3, 64-bit mode, only MMDC0 is initiated */ +DATA 4 0x021b0004 0x0002002d +DATA 4 0x021b0008 0x00333040 +DATA 4 0x021b000c 0x676b52f2 +DATA 4 0x021b0010 0x926e8b63 +DATA 4 0x021b0014 0x01ff00db +DATA 4 0x021b0018 0x00011740 +DATA 4 0x021b001c 0x00008000 +DATA 4 0x021b002c 0x000026d2 +DATA 4 0x021b0030 0x006b1023 +DATA 4 0x021b0040 0x0000005f +DATA 4 0x021b0000 0x84190000 + +/* Initialize MT41K256M16HA-125 - MR2 */ +DATA 4 0x021b001c 0x02008032 +/* MR3 */ +DATA 4 0x021b001c 0x00008033 +/* MR1 */ +DATA 4 0x021b001c 0x00048031 +/* MR0 */ +DATA 4 0x021b001c 0x15108030 +/* DDR device ZQ calibration */ +DATA 4 0x021b001c 0x04008040 + +/* Final DDR setup, before operation start */ +DATA 4 0x021b0020 0x00007800 +DATA 4 0x021b0818 0x00022227 +DATA 4 0x021b001c 0x00000000 diff --git a/board/samtec/vining_2000/vining_2000.c b/board/samtec/vining_2000/vining_2000.c new file mode 100644 index 0000000..c92f37c --- /dev/null +++ b/board/samtec/vining_2000/vining_2000.c @@ -0,0 +1,517 @@ +/* + * Copyright (C) 2016 samtec automotive software & electronics gmbh + * + * Author: Christoph Fritz + * + * 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 +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ + PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PKE | \ + PAD_CTL_SPEED_HIGH | PAD_CTL_DSE_48ohm | \ + PAD_CTL_SRE_FAST) + +#define ENET_CLK_PAD_CTRL PAD_CTL_DSE_34ohm + +#define ENET_RX_PAD_CTRL (PAD_CTL_PKE | \ + PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_HIGH | \ + PAD_CTL_SRE_FAST) + +#define I2C_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ + PAD_CTL_PKE | PAD_CTL_ODE | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm) + +#define USDHC_CLK_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST) + +#define USDHC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \ + PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST) + +#define GPIO_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ + PAD_CTL_PKE) + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + + return 0; +} + +static iomux_v3_cfg_t const uart1_pads[] = { + MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc2_pads[] = { + MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_CLK_PAD_CTRL), + MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_LCD1_VSYNC__GPIO3_IO_28 | MUX_PAD_CTRL(GPIO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc4_pads[] = { + MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_CLK_PAD_CTRL), + MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA4__USDHC4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA5__USDHC4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA6__USDHC4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA7__USDHC4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +static iomux_v3_cfg_t const fec1_pads[] = { + MX6_PAD_ENET1_MDC__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET1_MDIO__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII1_RD0__ENET1_RX_DATA_0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX6_PAD_RGMII1_RD1__ENET1_RX_DATA_1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX6_PAD_RGMII1_TD0__ENET1_TX_DATA_0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII1_TD1__ENET1_TX_DATA_1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII1_RX_CTL__ENET1_RX_EN | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX6_PAD_RGMII1_TX_CTL__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL) | + MUX_MODE_SION, + /* LAN8720 PHY Reset */ + MX6_PAD_RGMII1_TD3__GPIO5_IO_9 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const pwm_led_pads[] = { + MX6_PAD_RGMII2_RD2__PWM2_OUT | MUX_PAD_CTRL(NO_PAD_CTRL), /* green */ + MX6_PAD_RGMII2_TD2__PWM6_OUT | MUX_PAD_CTRL(NO_PAD_CTRL), /* red */ + MX6_PAD_RGMII2_RD3__PWM1_OUT | MUX_PAD_CTRL(NO_PAD_CTRL), /* blue */ +}; + +static void setup_iomux_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); +} + +#define PHY_RESET IMX_GPIO_NR(5, 9) + +int board_eth_init(bd_t *bis) +{ + struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; + int ret; + unsigned char eth1addr[6]; + + /* just to get secound mac address */ + imx_get_mac_from_fuse(1, eth1addr); + if (!getenv("eth1addr") && is_valid_ethaddr(eth1addr)) + eth_setenv_enetaddr("eth1addr", eth1addr); + + imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); + + /* + * Generate phy reference clock via pin IOMUX ENET_REF_CLK1/2 by erasing + * ENET1/2_TX_CLK_DIR gpr1[14:13], so that reference clock is driven by + * ref_enetpll0/1 and enable ENET1/2_TX_CLK output driver. + */ + clrsetbits_le32(&iomuxc_regs->gpr[1], + IOMUX_GPR1_FEC1_CLOCK_MUX2_SEL_MASK | + IOMUX_GPR1_FEC2_CLOCK_MUX2_SEL_MASK, + IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK | + IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK); + + ret = enable_fec_anatop_clock(0, ENET_50MHZ); + if (ret) + goto eth_fail; + + /* reset phy */ + gpio_direction_output(PHY_RESET, 0); + mdelay(16); + gpio_set_value(PHY_RESET, 1); + mdelay(1); + + ret = fecmxc_initialize_multi(bis, 0, CONFIG_FEC_MXC_PHYADDR, + IMX_FEC_BASE); + if (ret) + goto eth_fail; + + return ret; + +eth_fail: + printf("FEC MXC: %s:failed (%i)\n", __func__, ret); + gpio_set_value(PHY_RESET, 0); + return ret; +} + +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +/* I2C1 for PMIC */ +static struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = MX6_PAD_GPIO1_IO00__I2C1_SCL | PC, + .gpio_mode = MX6_PAD_GPIO1_IO00__GPIO1_IO_0 | PC, + .gp = IMX_GPIO_NR(1, 0), + }, + .sda = { + .i2c_mode = MX6_PAD_GPIO1_IO01__I2C1_SDA | PC, + .gpio_mode = MX6_PAD_GPIO1_IO01__GPIO1_IO_1 | PC, + .gp = IMX_GPIO_NR(1, 1), + }, +}; + +static struct pmic *pfuze_init(unsigned char i2cbus) +{ + struct pmic *p; + int ret; + u32 reg; + + ret = power_pfuze100_init(i2cbus); + if (ret) + return NULL; + + p = pmic_get("PFUZE100"); + ret = pmic_probe(p); + if (ret) + return NULL; + + pmic_reg_read(p, PFUZE100_DEVICEID, ®); + printf("PMIC: PFUZE100 ID=0x%02x\n", reg); + + /* Set SW1AB stanby volage to 0.975V */ + pmic_reg_read(p, PFUZE100_SW1ABSTBY, ®); + reg &= ~SW1x_STBY_MASK; + reg |= SW1x_0_975V; + pmic_reg_write(p, PFUZE100_SW1ABSTBY, reg); + + /* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ + pmic_reg_read(p, PFUZE100_SW1ABCONF, ®); + reg &= ~SW1xCONF_DVSSPEED_MASK; + reg |= SW1xCONF_DVSSPEED_4US; + pmic_reg_write(p, PFUZE100_SW1ABCONF, reg); + + /* Set SW1C standby voltage to 0.975V */ + pmic_reg_read(p, PFUZE100_SW1CSTBY, ®); + reg &= ~SW1x_STBY_MASK; + reg |= SW1x_0_975V; + pmic_reg_write(p, PFUZE100_SW1CSTBY, reg); + + /* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */ + pmic_reg_read(p, PFUZE100_SW1CCONF, ®); + reg &= ~SW1xCONF_DVSSPEED_MASK; + reg |= SW1xCONF_DVSSPEED_4US; + pmic_reg_write(p, PFUZE100_SW1CCONF, reg); + + return p; +} + +static int pfuze_mode_init(struct pmic *p, u32 mode) +{ + unsigned char offset, i, switch_num; + u32 id; + int ret; + + pmic_reg_read(p, PFUZE100_DEVICEID, &id); + id = id & 0xf; + + if (id == 0) { + switch_num = 6; + offset = PFUZE100_SW1CMODE; + } else if (id == 1) { + switch_num = 4; + offset = PFUZE100_SW2MODE; + } else { + printf("Not supported, id=%d\n", id); + return -EINVAL; + } + + ret = pmic_reg_write(p, PFUZE100_SW1ABMODE, mode); + if (ret < 0) { + printf("Set SW1AB mode error!\n"); + return ret; + } + + for (i = 0; i < switch_num - 1; i++) { + ret = pmic_reg_write(p, offset + i * SWITCH_SIZE, mode); + if (ret < 0) { + printf("Set switch 0x%x mode error!\n", + offset + i * SWITCH_SIZE); + return ret; + } + } + + return ret; +} + +int power_init_board(void) +{ + struct pmic *p; + int ret; + + p = pfuze_init(I2C_PMIC); + if (!p) + return -ENODEV; + + ret = pfuze_mode_init(p, APS_PFM); + if (ret < 0) + return ret; + + return 0; +} + +#ifdef CONFIG_USB_EHCI_MX6 +static iomux_v3_cfg_t const usb_otg_pads[] = { + /* OGT1 */ + MX6_PAD_GPIO1_IO09__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_GPIO1_IO10__ANATOP_OTG1_ID | MUX_PAD_CTRL(NO_PAD_CTRL), + /* OTG2 */ + MX6_PAD_GPIO1_IO12__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL) +}; + +static void setup_iomux_usb(void) +{ + imx_iomux_v3_setup_multiple_pads(usb_otg_pads, + ARRAY_SIZE(usb_otg_pads)); +} + +int board_usb_phy_mode(int port) +{ + if (port == 1) + return USB_INIT_HOST; + else + return usb_phy_mode(port); +} +#endif + +#ifdef CONFIG_PWM_IMX +static int set_pwm_leds(void) +{ + int ret; + + imx_iomux_v3_setup_multiple_pads(pwm_led_pads, + ARRAY_SIZE(pwm_led_pads)); + /* enable backlight PWM 2, green LED */ + ret = pwm_init(1, 0, 0); + if (ret) + goto error; + /* duty cycle 200ns, period: 8000ns */ + ret = pwm_config(1, 200, 8000); + if (ret) + goto error; + ret = pwm_enable(1); + if (ret) + goto error; + + /* enable backlight PWM 1, blue LED */ + ret = pwm_init(0, 0, 0); + if (ret) + goto error; + /* duty cycle 200ns, period: 8000ns */ + ret = pwm_config(0, 200, 8000); + if (ret) + goto error; + ret = pwm_enable(0); + if (ret) + goto error; + + /* enable backlight PWM 6, red LED */ + ret = pwm_init(5, 0, 0); + if (ret) + goto error; + /* duty cycle 200ns, period: 8000ns */ + ret = pwm_config(5, 200, 8000); + if (ret) + goto error; + ret = pwm_enable(5); + +error: + return ret; +} +#else +static int set_pwm_leds(void) +{ + return 0; +} +#endif + +#define ADCx_HC0 0x00 +#define ADCx_HS 0x08 +#define ADCx_HS_C0 BIT(0) +#define ADCx_R0 0x0c +#define ADCx_CFG 0x14 +#define ADCx_CFG_SWMODE 0x308 +#define ADCx_GC 0x18 +#define ADCx_GC_CAL BIT(7) + +static int read_adc(u32 *val) +{ + int ret; + void __iomem *b = map_physmem(ADC1_BASE_ADDR, 0x100, MAP_NOCACHE); + + /* use software mode */ + writel(ADCx_CFG_SWMODE, b + ADCx_CFG); + + /* start auto calibration */ + setbits_le32(b + ADCx_GC, ADCx_GC_CAL); + ret = wait_for_bit("ADC", b + ADCx_GC, ADCx_GC_CAL, ADCx_GC_CAL, 10, 0); + if (ret) + goto adc_exit; + + /* start conversion */ + writel(0, b + ADCx_HC0); + + /* wait for conversion */ + ret = wait_for_bit("ADC", b + ADCx_HS, ADCx_HS_C0, ADCx_HS_C0, 10, 0); + if (ret) + goto adc_exit; + + /* read result */ + *val = readl(b + ADCx_R0); + +adc_exit: + if (ret) + printf("ADC failure (ret=%i)\n", ret); + unmap_physmem(b, MAP_NOCACHE); + return ret; +} + +#define VAL_UPPER 2498 +#define VAL_LOWER 1550 + +static int set_pin_state(void) +{ + u32 val; + int ret; + + ret = read_adc(&val); + if (ret) + return ret; + + if (val >= VAL_UPPER) + setenv("pin_state", "connected"); + else if (val < VAL_UPPER && val > VAL_LOWER) + setenv("pin_state", "open"); + else + setenv("pin_state", "button"); + + return ret; +} + +int board_late_init(void) +{ + int ret; + + ret = set_pwm_leds(); + if (ret) + return ret; + + ret = set_pin_state(); + + return ret; +} + +int board_early_init_f(void) +{ + setup_iomux_uart(); + + setup_iomux_usb(); + + return 0; +} + +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC4_BASE_ADDR, 0, 8}, + {USDHC2_BASE_ADDR, 0, 4}, +}; + +#define USDHC2_CD_GPIO IMX_GPIO_NR(3, 28) + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + + if (cfg->esdhc_base == USDHC4_BASE_ADDR) + return 1; + if (cfg->esdhc_base == USDHC2_BASE_ADDR) + return !gpio_get_value(USDHC2_CD_GPIO); + + return -EINVAL; +} + +int board_mmc_init(bd_t *bis) +{ + int ret; + + /* + * According to the board_mmc_init() the following map is done: + * (U-Boot device node) (Physical Port) + * mmc0 USDHC4 + * mmc1 USDHC2 + */ + imx_iomux_v3_setup_multiple_pads( + usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + gpio_direction_input(USDHC2_CD_GPIO); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[0]); + if (ret) { + printf("Warning: failed to initialize USDHC4\n"); + return ret; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[1]); + if (ret) { + printf("Warning: failed to initialize USDHC2\n"); + return ret; + } + + return 0; +} + +int board_init(void) +{ + /* Address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#ifdef CONFIG_SYS_I2C_MXC + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); +#endif + + return 0; +} + +int checkboard(void) +{ + puts("Board: VIN|ING 2000\n"); + + return 0; +} diff --git a/configs/vining_2000_defconfig b/configs/vining_2000_defconfig new file mode 100644 index 0000000..b1f64f1 --- /dev/null +++ b/configs/vining_2000_defconfig @@ -0,0 +1,31 @@ +CONFIG_ARM=y +CONFIG_ARCH_MX6=y +CONFIG_TARGET_SAMTEC_VINING_2000=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/samtec/vining_2000/imximage.cfg" +CONFIG_BOOTDELAY=0 +CONFIG_CONSOLE_MUX is not set +CONFIG_SYS_CONSOLE_IS_IN_ENV=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PCI=y +CONFIG_USB=y +CONFIG_USB_STORAGE=y +CONFIG_OF_LIBFDT=y +CONFIG_MXC_USB_OTG_HACTIVE=y diff --git a/include/configs/vining_2000.h b/include/configs/vining_2000.h new file mode 100644 index 0000000..235574d --- /dev/null +++ b/include/configs/vining_2000.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2016 samtec automotive software & electronics gmbh + * + * Configuration settings for the Samtec VIN|ING 2000 board. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include "mx6_common.h" + +#ifdef CONFIG_SPL +#include "imx6_spl.h" +#endif + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (3 * SZ_1M) + +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_MXC_UART +#define CONFIG_MXC_UART_BASE UART1_BASE + +#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 + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_MEMTEST_START 0x80000000 +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x10000) + +#define CONFIG_STACKSIZE SZ_128K + +/* Physical Memory Map */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE + +#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) + +/* MMC Configuration */ +#define CONFIG_SYS_FSL_ESDHC_ADDR USDHC4_BASE_ADDR + +/* I2C Configs */ +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ +#define CONFIG_SYS_I2C_SPEED 100000 + +/* PMIC */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_PFUZE100 +#define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08 + +/* Network */ +#define CONFIG_FEC_MXC +#define CONFIG_MII + +#define IMX_FEC_BASE ENET_BASE_ADDR +#define CONFIG_FEC_MXC_PHYADDR 0x0 + +#define CONFIG_FEC_XCV_TYPE RMII +#define CONFIG_ETHPRIME "FEC" + +#define CONFIG_PHYLIB +#define CONFIG_PHY_ATHEROS + +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_MX6 +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_ASIX +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) +#define CONFIG_MXC_USB_FLAGS 0 +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 +#endif + +#define CONFIG_CMD_PCI +#ifdef CONFIG_CMD_PCI +#define CONFIG_PCI_SCAN_SHOW +#define CONFIG_PCIE_IMX +#define CONFIG_PCIE_IMX_PERST_GPIO IMX_GPIO_NR(4, 6) +#endif + +#define CONFIG_IMX_THERMAL + +#define CONFIG_PWM_IMX +#define CONFIG_IMX6_PWM_PER_CLK 66000000 +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#define CONFIG_ENV_OFFSET (8 * SZ_64K) +#define CONFIG_ENV_SIZE SZ_8K +#define CONFIG_ENV_OFFSET_REDUND (9 * SZ_64K) +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE +#define CONFIG_ENV_IS_IN_MMC + +#ifdef CONFIG_ENV_IS_IN_MMC +#define CONFIG_SUPPORT_EMMC_BOOT +#define CONFIG_EFI_PARTITION +#define CONFIG_DOS_PARTITION +#define CONFIG_SUPPORT_EMMC_RPMB +#define CONFIG_SYS_MMC_ENV_DEV 0 /* USDHC4 eMMC */ +/* 0=user, 1=boot0, 2=boot1, * 4..7=general0..3. */ +#define CONFIG_SYS_MMC_ENV_PART 1 /* boot0 */ +#endif + +#endif /* __CONFIG_H */ -- cgit v0.10.2 From 4db4d42ee290a8cad00b358b2e7ef6a00483893b Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 28 Nov 2016 07:18:14 +0100 Subject: imx6: clock: Enable External Memory Interface [EIM] clock (eim_slow_clock) This patch extends the imx6 clock code to enable or disable the EIM slow clock, which in necessary when one wants to use EIM interface t o read/write from external memory (e.g. NOR). Signed-off-by: Lukasz Majewski diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index 96fbd81..2995628 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -1384,6 +1384,20 @@ void select_ldb_di_clock_source(enum ldb_di_clock clk) } #endif +#ifndef CONFIG_SYS_NO_FLASH +void enable_eim_clk(unsigned char enable) +{ + u32 reg; + + reg = __raw_readl(&imx_ccm->CCGR6); + if (enable) + reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK; + else + reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK; + __raw_writel(reg, &imx_ccm->CCGR6); +} +#endif + /***************************************************/ U_BOOT_CMD( diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h index 82f9f92..ed1433e 100644 --- a/arch/arm/include/asm/arch-mx6/clock.h +++ b/arch/arm/include/asm/arch-mx6/clock.h @@ -79,4 +79,5 @@ void enable_qspi_clk(int qspi_num); void enable_thermal_clk(void); void mxs_set_lcdclk(u32 base_addr, u32 freq); void select_ldb_di_clock_source(enum ldb_di_clock clk); +void enable_eim_clk(unsigned char enable); #endif /* __ASM_ARCH_CLOCK_H */ -- cgit v0.10.2