summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-09-05 12:59:29 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-09-05 12:59:29 +0200
commit9196d727ad54288977ded7a8ce4ad3dc83eb385a (patch)
treeb29ed67eee25181ce07138de57ec6dea64217957 /arch
parent038307cb5e6e0e655ec251f561959afd2ef1bfd1 (diff)
parent74bde540e23dd91ce75cdec7886d183a509ec3bd (diff)
downloadbarebox-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.c32
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx35.h5
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx6.h15
-rw-r--r--arch/arm/mach-imx/include/mach/imx35-regs.h2
-rw-r--r--arch/arm/mach-imx/include/mach/imx6-regs.h1
-rw-r--r--arch/arm/mach-imx/speed-imx35.c5
-rw-r--r--arch/arm/mach-imx/speed-imx6.c6
-rw-r--r--arch/arm/mach-imx/usb-imx6.c111
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;
+}