diff options
-rw-r--r-- | arch/arm/cpu/armv7/mx6/soc.c | 70 | ||||
-rw-r--r-- | arch/arm/imx-common/cpu.c | 7 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/imx-regs.h | 12 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/sys_proto.h | 7 | ||||
-rw-r--r-- | board/freescale/mx6qarm2/mx6qarm2.c | 9 | ||||
-rw-r--r-- | board/freescale/mx6qsabreauto/mx6qsabreauto.c | 34 | ||||
-rw-r--r-- | board/freescale/mx6sabresd/mx6sabresd.c | 67 | ||||
-rw-r--r-- | board/freescale/mx6slevk/mx6slevk.c | 41 | ||||
-rw-r--r-- | include/configs/mx6_common.h | 1 | ||||
-rw-r--r-- | include/configs/mx6sabre_common.h | 9 | ||||
-rw-r--r-- | include/configs/mx6slevk.h | 7 |
11 files changed, 257 insertions, 7 deletions
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index c5f3b22..20ee264 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -17,6 +17,7 @@ #include <asm/arch/sys_proto.h> #include <asm/imx-common/boot_mode.h> #include <asm/imx-common/dma.h> +#include <libfdt.h> #include <stdbool.h> #include <asm/arch/mxc_hdmi.h> #include <asm/arch/crm_regs.h> @@ -487,6 +488,75 @@ void s_init(void) writel(mask528, &anatop->pfd_528_clr); } +#ifdef CONFIG_LDO_BYPASS_CHECK +DECLARE_GLOBAL_DATA_PTR; +static int ldo_bypass; + +int check_ldo_bypass(void) +{ + const int *ldo_mode; + int node; + + /* get the right fdt_blob from the global working_fdt */ + gd->fdt_blob = working_fdt; + /* Get the node from FDT for anatop ldo-bypass */ + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, + "fsl,imx6q-gpc"); + if (node < 0) { + printf("No gpc device node %d, force to ldo-enable.\n", node); + return 0; + } + ldo_mode = fdt_getprop(gd->fdt_blob, node, "fsl,ldo-bypass", NULL); + /* + * return 1 if "fsl,ldo-bypass = <1>", else return 0 if + * "fsl,ldo-bypass = <0>" or no "fsl,ldo-bypass" property + */ + ldo_bypass = fdt32_to_cpu(*ldo_mode) == 1 ? 1 : 0; + + return ldo_bypass; +} + +int check_1_2G(void) +{ + u32 reg; + int result = 0; + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[0]; + struct fuse_bank0_regs *fuse_bank0 = + (struct fuse_bank0_regs *)bank->fuse_regs; + + reg = readl(&fuse_bank0->cfg3); + if (((reg >> 16) & 0x3) == 0x3) { + if (ldo_bypass) { + printf("Wrong dtb file used! i.MX6Q@1.2Ghz only " + "works with ldo-enable mode!\n"); + /* + * Currently, only imx6q-sabresd board might be here, + * since only i.MX6Q support 1.2G and only Sabresd board + * support ldo-bypass mode. So hardcode here. + * You can also modify your board(i.MX6Q) dtb name if it + * supports both ldo-bypass and ldo-enable mode. + */ + printf("Please use imx6q-sabresd-ldo.dtb!\n"); + hang(); + } + result = 1; + } + + return result; +} + +void set_anatop_bypass(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + u32 reg = readl(&anatop->reg_core); + + /* bypass VDDARM/VDDSOC */ + reg = reg | (0x1F << 18) | 0x1F; + writel(reg, &anatop->reg_core); +} +#endif + #ifdef CONFIG_IMX_HDMI void imx_enable_hdmi_phy(void) { diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c index a8aeded..341a6ac 100644 --- a/arch/arm/imx-common/cpu.c +++ b/arch/arm/imx-common/cpu.c @@ -178,10 +178,13 @@ u32 get_ahb_clk(void) return get_periph_clk() / (ahb_podf + 1); } -#if defined(CONFIG_VIDEO_IPUV3) void arch_preboot_os(void) { +#if defined(CONFIG_LDO_BYPASS_CHECK) + ldo_mode_set(check_ldo_bypass()); +#endif +#if defined(CONFIG_VIDEO_IPUV3) /* disable video before launching O/S */ ipuv3_fb_shutdown(); -} #endif +} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 8a3243d..29e969d 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -468,12 +468,16 @@ struct fuse_bank0_regs { u32 rsvd1[3]; u32 uid_high; u32 rsvd2[3]; - u32 rsvd3[4]; - u32 rsvd4[4]; - u32 rsvd5[4]; + u32 cfg2; + u32 rsvd3[3]; + u32 cfg3; + u32 rsvd4[3]; + u32 cfg4; + u32 rsvd5[3]; u32 cfg5; u32 rsvd6[3]; - u32 rsvd7[4]; + u32 cfg6; + u32 rsvd7[3]; }; struct fuse_bank1_regs { diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index dfca85d..c546096 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -23,6 +23,13 @@ u32 get_cpu_rev(void); const char *get_imx_type(u32 imxtype); unsigned imx_ddr_size(void); +#ifdef CONFIG_LDO_BYPASS_CHECK +int check_ldo_bypass(void); +int check_1_2G(void); +void set_anatop_bypass(void); +void ldo_mode_set(int ldo_bypass); +#endif + /* * Initializes on-chip ethernet controllers. * to override, implement board_eth_init() diff --git a/board/freescale/mx6qarm2/mx6qarm2.c b/board/freescale/mx6qarm2/mx6qarm2.c index 6c51f3a..7603abe 100644 --- a/board/freescale/mx6qarm2/mx6qarm2.c +++ b/board/freescale/mx6qarm2/mx6qarm2.c @@ -228,3 +228,12 @@ int checkboard(void) return 0; } + +#ifdef CONFIG_LDO_BYPASS_CHECK +/* no external pmic, always ldo_enable */ +void ldo_mode_set(int ldo_bypass) +{ + return; +} +#endif + diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c index 928dadf..1fe13e0 100644 --- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c +++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c @@ -132,6 +132,40 @@ iomux_v3_cfg_t const usdhc3_pads[] = { MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL), }; +#ifdef CONFIG_LDO_BYPASS_CHECK +void ldo_mode_set(int ldo_bypass) +{ + unsigned char value; + /* increase VDDARM/VDDSOC to support 1.2G chip */ + if (check_1_2G()) { + ldo_bypass = 0; /* ldo_enable on 1.2G chip */ + printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n"); + /* increase VDDARM to 1.425V */ + if (i2c_read(0x8, 0x20, 1, &value, 1)) { + printf("Read SW1AB error!\n"); + return; + } + value &= ~0x3f; + value |= 0x2d; + if (i2c_write(0x8, 0x20, 1, &value, 1)) { + printf("Set SW1AB error!\n"); + return; + } + /* increase VDDSOC to 1.425V */ + if (i2c_read(0x8, 0x2e, 1, &value, 1)) { + printf("Read SW1C error!\n"); + return; + } + value &= ~0x3f; + value |= 0x2d; + if (i2c_write(0x8, 0x2e, 1, &value, 1)) { + printf("Set SW1C error!\n"); + return; + } + } +} +#endif + static void setup_iomux_uart(void) { imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads)); diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c index d7d932e..722981e 100644 --- a/board/freescale/mx6sabresd/mx6sabresd.c +++ b/board/freescale/mx6sabresd/mx6sabresd.c @@ -24,6 +24,10 @@ #include <ipu_pixfmt.h> #include <asm/io.h> #include <asm/arch/sys_proto.h> +#ifdef CONFIG_SYS_I2C_MXC +#include <i2c.h> +#include <asm/imx-common/mxc_i2c.h> +#endif DECLARE_GLOBAL_DATA_PTR; #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ @@ -156,6 +160,68 @@ static void setup_iomux_uart(void) imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); } +#ifdef CONFIG_LDO_BYPASS_CHECK +void ldo_mode_set(int ldo_bypass) +{ + unsigned char value; + /* increase VDDARM/VDDSOC to support 1.2G chip */ + if (check_1_2G()) { + ldo_bypass = 0; /* ldo_enable on 1.2G chip */ + printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n"); + /* increase VDDARM to 1.425V */ + if (i2c_read(0x8, 0x20, 1, &value, 1)) { + printf("Read SW1AB error!\n"); + return; + } + value &= ~0x3f; + value |= 0x2d; + if (i2c_write(0x8, 0x20, 1, &value, 1)) { + printf("Set SW1AB error!\n"); + return; + } + /* increase VDDSOC to 1.425V */ + if (i2c_read(0x8, 0x2e, 1, &value, 1)) { + printf("Read SW1C error!\n"); + return; + } + value &= ~0x3f; + value |= 0x2d; + if (i2c_write(0x8, 0x2e, 1, &value, 1)) { + printf("Set SW1C error!\n"); + return; + } + } + /* switch to ldo_bypass mode , boot on 800Mhz */ + if (ldo_bypass) { + /* decrease VDDARM to 1.175V */ + if (i2c_read(0x8, 0x20, 1, &value, 1)) { + printf("Read SW1AB error!\n"); + return; + } + value &= ~0x3f; + value |= 0x23; + if (i2c_write(0x8, 0x20, 1, &value, 1)) { + printf("Set SW1AB error!\n"); + return; + } + /* increase VDDSOC to 1.175V */ + if (i2c_read(0x8, 0x2e, 1, &value, 1)) { + printf("Read SW1C error!\n"); + return; + } + value &= ~0x3f; + value |= 0x23; + if (i2c_write(0x8, 0x2e, 1, &value, 1)) { + printf("Set SW1C error!\n"); + return; + } + + set_anatop_bypass(); + printf("switch to ldo_bypass mode!\n"); + } +} +#endif + #ifdef CONFIG_FSL_ESDHC struct fsl_esdhc_cfg usdhc_cfg[3] = { {USDHC2_BASE_ADDR}, @@ -516,3 +582,4 @@ int checkboard(void) puts("Board: MX6-SabreSD\n"); return 0; } + diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c index aadad32..aeb418b 100644 --- a/board/freescale/mx6slevk/mx6slevk.c +++ b/board/freescale/mx6slevk/mx6slevk.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Freescale Semiconductor, Inc. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. * * Author: Fabio Estevam <fabio.estevam@freescale.com> * @@ -19,6 +19,10 @@ #include <fsl_esdhc.h> #include <mmc.h> #include <netdev.h> +#ifdef CONFIG_SYS_I2C_MXC +#include <i2c.h> +#include <asm/imx-common/mxc_i2c.h> +#endif DECLARE_GLOBAL_DATA_PTR; @@ -128,6 +132,41 @@ static int setup_fec(void) } #endif +#ifdef CONFIG_LDO_BYPASS_CHECK +void ldo_mode_set(int ldo_bypass) +{ + unsigned char value; + /* swith to ldo_bypass mode */ + if (ldo_bypass) { + /* decrease VDDARM to 1.15V */ + if (i2c_read(0x8, 0x20, 1, &value, 1)) { + printf("Read SW1AB error!\n"); + return; + } + value &= ~0x3f; + value |= 0x22; + if (i2c_write(0x8, 0x20, 1, &value, 1)) { + printf("Set SW1AB error!\n"); + return; + } + /* increase VDDSOC to 1.15V */ + if (i2c_read(0x8, 0x2e, 1, &value, 1)) { + printf("Read SW1C error!\n"); + return; + } + value &= ~0x3f; + value |= 0x22; + if (i2c_write(0x8, 0x2e, 1, &value, 1)) { + printf("Set SW1C error!\n"); + return; + } + + set_anatop_bypass(); + printf("switch to ldo_bypass mode!\n"); + } + +} +#endif int board_early_init_f(void) { diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index 8a8920f..1a773db 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -23,6 +23,7 @@ #define CONFIG_ARM_ERRATA_794072 #define CONFIG_ARM_ERRATA_761320 #define CONFIG_BOARD_POSTCLK_INIT +#define CONFIG_LDO_BYPASS_CHECK #ifndef CONFIG_SYS_L2CACHE_OFF #define CONFIG_SYS_L2_PL310 diff --git a/include/configs/mx6sabre_common.h b/include/configs/mx6sabre_common.h index 9686588..b97a3ac 100644 --- a/include/configs/mx6sabre_common.h +++ b/include/configs/mx6sabre_common.h @@ -261,4 +261,13 @@ #define CONFIG_CMD_CACHE #endif +/* + * I2C configs + */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0x8 + #endif /* __MX6QSABRE_COMMON_CONFIG_H */ diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h index 1876dbf..f5df518 100644 --- a/include/configs/mx6slevk.h +++ b/include/configs/mx6slevk.h @@ -64,6 +64,13 @@ #define CONFIG_CONS_INDEX 1 #define CONFIG_BAUDRATE 115200 +/* I2C configs */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0x8 + /* Command definition */ #include <config_cmd_default.h> |