diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-09-05 12:59:29 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-09-05 12:59:29 +0200 |
commit | 9196d727ad54288977ded7a8ce4ad3dc83eb385a (patch) | |
tree | b29ed67eee25181ce07138de57ec6dea64217957 /arch | |
parent | 038307cb5e6e0e655ec251f561959afd2ef1bfd1 (diff) | |
parent | 74bde540e23dd91ce75cdec7886d183a509ec3bd (diff) | |
download | barebox-9196d727ad54288977ded7a8ce4ad3dc83eb385a.tar.gz barebox-9196d727ad54288977ded7a8ce4ad3dc83eb385a.tar.xz |
Merge branch 'for-next/imx'
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boards/freescale-mx6-sabrelite/board.c | 32 | ||||
-rw-r--r-- | arch/arm/mach-imx/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/devices-imx35.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/devices-imx6.h | 15 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/imx35-regs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/imx6-regs.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-imx/speed-imx35.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/speed-imx6.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-imx/usb-imx6.c | 111 |
9 files changed, 178 insertions, 1 deletions
diff --git a/arch/arm/boards/freescale-mx6-sabrelite/board.c b/arch/arm/boards/freescale-mx6-sabrelite/board.c index 13279bc95c..1ac401ebb1 100644 --- a/arch/arm/boards/freescale-mx6-sabrelite/board.c +++ b/arch/arm/boards/freescale-mx6-sabrelite/board.c @@ -77,6 +77,23 @@ static iomux_v3_cfg_t sabrelite_pads[] = { MX6Q_PAD_EIM_D17__ECSPI1_MISO, MX6Q_PAD_EIM_D18__ECSPI1_MOSI, MX6Q_PAD_EIM_D19__GPIO_3_19, /* CS1 */ + + /* I2C0 */ + MX6Q_PAD_EIM_D21__I2C1_SCL, + MX6Q_PAD_EIM_D28__I2C1_SDA, + + /* I2C1 */ + MX6Q_PAD_KEY_COL3__I2C2_SCL, + MX6Q_PAD_KEY_ROW3__I2C2_SDA, + + /* I2C2 */ + MX6Q_PAD_GPIO_5__I2C3_SCL, + MX6Q_PAD_GPIO_16__I2C3_SDA, + + /* USB */ + MX6Q_PAD_GPIO_17__GPIO_7_12, + MX6Q_PAD_EIM_D22__GPIO_3_22, + MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC, }; static iomux_v3_cfg_t sabrelite_enet_pads[] = { @@ -227,6 +244,19 @@ static struct esdhc_platform_data sabrelite_sd4_data = { .wp_type = ESDHC_WP_NONE, }; +static void sabrelite_ehci_init(void) +{ + imx6_usb_phy1_disable_oc(); + imx6_usb_phy1_enable(); + + /* hub reset */ + gpio_direction_output(204, 0); + udelay(2000); + gpio_set_value(204, 1); + + add_generic_usb_ehci_device(1, MX6_USBOH3_USB_BASE_ADDR + 0x200, NULL); +} + static int sabrelite_devices_init(void) { imx6_add_mmc2(&sabrelite_sd3_data); @@ -237,6 +267,8 @@ static int sabrelite_devices_init(void) imx6_add_fec(&fec_info); mx6_rgmii_rework(); + sabrelite_ehci_init(); + spi_register_board_info(sabrelite_spi_board_info, ARRAY_SIZE(sabrelite_spi_board_info)); imx6_add_spi0(&sabrelite_spi_0_data); diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 2ff537ab89..7b872f6da3 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_ARCH_IMX31) += speed-imx31.o imx31.o iomux-v2.o obj-$(CONFIG_ARCH_IMX35) += speed-imx35.o imx35.o iomux-v3.o obj-$(CONFIG_ARCH_IMX51) += speed-imx51.o imx51.o iomux-v3.o imx5.o obj-$(CONFIG_ARCH_IMX53) += speed-imx53.o imx53.o iomux-v3.o imx5.o -obj-$(CONFIG_ARCH_IMX6) += speed-imx6.o imx6.o iomux-v3.o +obj-$(CONFIG_ARCH_IMX6) += speed-imx6.o imx6.o iomux-v3.o usb-imx6.o obj-$(CONFIG_IMX_CLKO) += clko.o obj-$(CONFIG_IMX_IIM) += iim.o obj-$(CONFIG_NAND_IMX) += nand.o diff --git a/arch/arm/mach-imx/include/mach/devices-imx35.h b/arch/arm/mach-imx/include/mach/devices-imx35.h index 6c0d750050..9ecaa35ffe 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx35.h +++ b/arch/arm/mach-imx/include/mach/devices-imx35.h @@ -16,6 +16,11 @@ static inline struct device_d *imx35_add_i2c2(struct i2c_platform_data *pdata) return imx_add_i2c((void *)IMX_I2C3_BASE, 2, pdata); } +static inline struct device_d *imx35_add_spi0(struct spi_imx_master *pdata) +{ + return imx_add_spi((void *)IMX_CSPI1_BASE, 0, pdata); +} + static inline struct device_d *imx35_add_uart0(void) { return imx_add_uart((void *)IMX_UART1_BASE, 0); diff --git a/arch/arm/mach-imx/include/mach/devices-imx6.h b/arch/arm/mach-imx/include/mach/devices-imx6.h index ca063c5459..c73e4888ed 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx6.h +++ b/arch/arm/mach-imx/include/mach/devices-imx6.h @@ -49,3 +49,18 @@ static inline struct device_d *imx6_add_spi0(struct spi_imx_master *pdata) { return imx_add_spi((void *)MX6_ECSPI1_BASE_ADDR, 0, pdata); } + +static inline struct device_d *imx6_add_i2c0(struct i2c_platform_data *pdata) +{ + return imx_add_i2c((void *)MX6_I2C1_BASE_ADDR, 0, pdata); +} + +static inline struct device_d *imx6_add_i2c1(struct i2c_platform_data *pdata) +{ + return imx_add_i2c((void *)MX6_I2C2_BASE_ADDR, 1, pdata); +} + +static inline struct device_d *imx6_add_i2c2(struct i2c_platform_data *pdata) +{ + return imx_add_i2c((void *)MX6_I2C3_BASE_ADDR, 2, pdata); +} diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h index fafcd61e33..91d4b9bf52 100644 --- a/arch/arm/mach-imx/include/mach/imx35-regs.h +++ b/arch/arm/mach-imx/include/mach/imx35-regs.h @@ -49,6 +49,7 @@ #define IMX_I2C1_BASE 0x43F80000 #define IMX_I2C2_BASE 0x43F98000 #define IMX_I2C3_BASE 0x43F84000 +#define IMX_CSPI1_BASE 0x43FA4000 #define IMX_SDHC1_BASE 0x53FB4000 #define IMX_SDHC2_BASE 0x53FB8000 #define IMX_SDHC3_BASE 0x53FBC000 @@ -75,6 +76,7 @@ #define CCM_CGR2 0x34 #define CCM_CGR3 0x38 +#define CCM_CGR0_CSPI1_SHIFT 10 #define CCM_CGR1_FEC_SHIFT 0 #define CCM_CGR1_I2C1_SHIFT 10 #define CCM_CGR1_SDHC1_SHIFT 26 diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h index e62cc79a07..c7b7481d0f 100644 --- a/arch/arm/mach-imx/include/mach/imx6-regs.h +++ b/arch/arm/mach-imx/include/mach/imx6-regs.h @@ -74,6 +74,7 @@ #define MX6_WDOG2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x40000) #define MX6_CCM_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x44000) #define MX6_ANATOP_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x48000) +#define MX6_USBPHY1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4a000) #define MX6_SNVS_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4C000) #define MX6_EPIT1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x50000) #define MX6_EPIT2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x54000) diff --git a/arch/arm/mach-imx/speed-imx35.c b/arch/arm/mach-imx/speed-imx35.c index ec7d06a11b..e0ff1793c5 100644 --- a/arch/arm/mach-imx/speed-imx35.c +++ b/arch/arm/mach-imx/speed-imx35.c @@ -192,6 +192,11 @@ ulong fsl_get_i2cclk(void) return imx_get_ipg_perclk(); } +unsigned long imx_get_cspiclk(void) +{ + return imx_get_ipgclk(); +} + void imx_dump_clocks(void) { printf("mpll: %10ld Hz\n", imx_get_mpllclk()); diff --git a/arch/arm/mach-imx/speed-imx6.c b/arch/arm/mach-imx/speed-imx6.c index df2454532d..645b2c9735 100644 --- a/arch/arm/mach-imx/speed-imx6.c +++ b/arch/arm/mach-imx/speed-imx6.c @@ -332,6 +332,11 @@ u32 imx_get_fecclk(void) return __get_ipg_clk(); } +u32 imx_get_i2cclk(void) +{ + return __get_ipg_per_clk(); +} + u32 imx_get_cspiclk(void) { return __get_cspi_clk(); @@ -351,6 +356,7 @@ void imx_dump_clocks(void) printf("mx6q pll8: %d\n", freq); printf("mcu main: %d\n", __get_mcu_main_clk()); printf("periph: %d\n", __get_periph_clk()); + printf("i2c: %d\n", __get_ipg_per_clk()); printf("ipg: %d\n", __get_ipg_clk()); printf("ipg per: %d\n", __get_ipg_per_clk()); printf("cspi: %d\n", __get_cspi_clk()); diff --git a/arch/arm/mach-imx/usb-imx6.c b/arch/arm/mach-imx/usb-imx6.c new file mode 100644 index 0000000000..cd234d2084 --- /dev/null +++ b/arch/arm/mach-imx/usb-imx6.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2012 Steffen Trumtrar, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation. + * + */ + +#include <common.h> +#include <io.h> +#include <mach/imx6-regs.h> + +#define SET 0x4 +#define CLR 0x8 + +#define USBPHY_CTRL 0x30 +#define USB_OTG_CTRL 0x800 +#define USB_UH1_CTRL 0x804 +#define USB_UH2_CTRL 0x808 +#define USB_UH3_CTRL 0x80c + +#define USB_UH1_USBCMD 0x340 + +#define USB_CMD_RUNSTOP (1 << 0) +#define USB_CMD_RESET (1 << 1) + +#define USB_OVER_CUR_DIS (1 << 7) +#define USBPHY_CTRL_SFTRST (1 << 31) +#define USBPHY_CTRL_CLKGATE (1 << 30) +#define USBPHY_CTRL_ENUTMILEVEL3 (1 << 15) +#define USBPHY_CTRL_ENUTMILEVEL2 (1 << 14) + +#define USBPHY1_PLL_480_CTRL_EN (1 << 13) +#define USBPHY1_PLL_480_CTRL_POWER (1 << 12) +#define USBPHY1_PLL_480_CTRL_EN_USB_CLK (1 << 6) +#define USBPHY1_PLL_480_CTRL_BYPASS (1 << 16) + +int imx6_usb_phy1_disable_oc(void) +{ + int val; + + /* disable over current detection */ + val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_CTRL); + val |= USB_OVER_CUR_DIS; + writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH1_CTRL); + val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH2_CTRL); + val |= USB_OVER_CUR_DIS; + writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH2_CTRL); + val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH3_CTRL); + val |= USB_OVER_CUR_DIS; + writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH3_CTRL); + + return 0; +} + +int imx6_usb_phy1_enable(void) +{ + int val; + + /* disable external charger detector or DP will be poor */ + writel(0x00180000, MX6_ANATOP_BASE_ADDR + 0x1b0); + writel(0x00180000, MX6_ANATOP_BASE_ADDR + 0x210); + + /* enable usb pll */ + writel(USBPHY1_PLL_480_CTRL_EN | + USBPHY1_PLL_480_CTRL_POWER | + USBPHY1_PLL_480_CTRL_EN_USB_CLK, MX6_ANATOP_BASE_ADDR + 0x24); + + /* turn OFF clk bypass */ + /* at least on imx6 v1.0 this essential for usb to work */ + /* FIXME: test on v1.1. Datasheet declares bit as reserved */ + writel(USBPHY1_PLL_480_CTRL_BYPASS, MX6_ANATOP_BASE_ADDR + 0x28); + + /* stop then reset */ + val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD); + val &= ~USB_CMD_RUNSTOP; + writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD); + while (readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD) & USB_CMD_RUNSTOP); + + val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD); + val |= USB_CMD_RESET; + writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD); + while (readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD) & USB_CMD_RESET); + + /* reset usbphy */ + writel(USBPHY_CTRL_SFTRST, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + SET); + udelay(10); + /* clr reset and clkgate */ + writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + CLR); + + /* clr all pwd bits => power up phy */ + writel(0xffffffff, MX6_USBPHY1_BASE_ADDR + CLR); + + /* set utmilvl2/3 */ + val = readl(MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL); + val |= USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2; + writel(val, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + SET); + + return 0; +} |