9
0
Fork 0

Merge branch 'for-next/imx-usb-chipidea'

This commit is contained in:
Sascha Hauer 2013-02-04 15:48:53 +01:00
commit 9c5172fac2
11 changed files with 168 additions and 12 deletions

View File

@ -231,8 +231,8 @@ static struct esdhc_platform_data sabrelite_sd4_data = {
static void sabrelite_ehci_init(void) static void sabrelite_ehci_init(void)
{ {
imx6_usb_phy1_disable_oc(); imx6_usb_phy2_disable_oc();
imx6_usb_phy1_enable(); imx6_usb_phy2_enable();
/* hub reset */ /* hub reset */
gpio_direction_output(204, 0); gpio_direction_output(204, 0);

View File

@ -205,6 +205,9 @@ static int imx6_ccm_probe(struct device_d *dev)
clks[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3); clks[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3);
clks[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); clks[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
clks[usbphy1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6);
clks[usbphy2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6);
clks[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); clks[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
clks[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); clks[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
clks[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20); clks[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
@ -298,6 +301,8 @@ static int imx6_ccm_probe(struct device_d *dev)
clkdev_add_physbase(clks[ipg_per], MX6_I2C2_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg_per], MX6_I2C2_BASE_ADDR, NULL);
clkdev_add_physbase(clks[ipg_per], MX6_I2C3_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg_per], MX6_I2C3_BASE_ADDR, NULL);
clkdev_add_physbase(clks[ahb], MX6_SATA_BASE_ADDR, NULL); clkdev_add_physbase(clks[ahb], MX6_SATA_BASE_ADDR, NULL);
clkdev_add_physbase(clks[usbphy1], MX6_USBPHY1_BASE_ADDR, NULL);
clkdev_add_physbase(clks[usbphy2], MX6_USBPHY2_BASE_ADDR, NULL);
writel(0xffffffff, ccm_base + CCGR0); writel(0xffffffff, ccm_base + CCGR0);
writel(0xffffffff, ccm_base + CCGR1); writel(0xffffffff, ccm_base + CCGR1);

View File

@ -68,6 +68,7 @@ static int imx6_init(void)
add_generic_device("imx31-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("imx21-wdt", 0, NULL, MX6_WDOG1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); add_generic_device("imx21-wdt", 0, NULL, MX6_WDOG1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("imx6-usb-misc", 0, NULL, MX6_USBOH3_USB_BASE_ADDR + 0x800, 0x100, IORESOURCE_MEM, NULL);
return 0; return 0;
} }

View File

@ -69,3 +69,29 @@ static inline struct device_d *imx6_add_sata(void)
{ {
return add_generic_device("imx6-sata", 0, NULL, MX6_SATA_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); return add_generic_device("imx6-sata", 0, NULL, MX6_SATA_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
} }
static inline struct device_d *imx6_add_usbotg(void *pdata)
{
add_generic_device("imx-usb-phy", 0, NULL, MX6_USBPHY1_BASE_ADDR, 0x1000,
IORESOURCE_MEM, NULL);
return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR, 0, pdata);
}
static inline struct device_d *imx6_add_usbh1(void *pdata)
{
add_generic_device("imx-usb-phy", 1, NULL, MX6_USBPHY2_BASE_ADDR, 0x1000,
IORESOURCE_MEM, NULL);
return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x200, 1, pdata);
}
static inline struct device_d *imx6_add_usbh2(void *pdata)
{
return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x400, 2, pdata);
}
static inline struct device_d *imx6_add_usbh3(void *pdata)
{
return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x600, 2, pdata);
}

View File

@ -49,7 +49,8 @@
#define MX6_WDOG2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x40000) #define MX6_WDOG2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x40000)
#define MX6_CCM_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x44000) #define MX6_CCM_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x44000)
#define MX6_ANATOP_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x48000) #define MX6_ANATOP_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x48000)
#define MX6_USBPHY1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4a000) #define MX6_USBPHY1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x49000)
#define MX6_USBPHY2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4a000)
#define MX6_SNVS_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4C000) #define MX6_SNVS_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4C000)
#define MX6_EPIT1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x50000) #define MX6_EPIT1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x50000)
#define MX6_EPIT2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x54000) #define MX6_EPIT2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x54000)

View File

@ -11,7 +11,7 @@
#define MX35_H1_USBTE_BIT (1 << 4) #define MX35_H1_USBTE_BIT (1 << 4)
#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0) #define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0)
int imx6_usb_phy1_disable_oc(void); int imx6_usb_phy2_disable_oc(void);
int imx6_usb_phy1_enable(void); int imx6_usb_phy2_enable(void);
#endif /* __MACH_USB_H_*/ #endif /* __MACH_USB_H_*/

View File

@ -46,7 +46,7 @@
#define USBPHY1_PLL_480_CTRL_EN_USB_CLK (1 << 6) #define USBPHY1_PLL_480_CTRL_EN_USB_CLK (1 << 6)
#define USBPHY1_PLL_480_CTRL_BYPASS (1 << 16) #define USBPHY1_PLL_480_CTRL_BYPASS (1 << 16)
int imx6_usb_phy1_disable_oc(void) int imx6_usb_phy2_disable_oc(void)
{ {
int val; int val;
@ -64,7 +64,7 @@ int imx6_usb_phy1_disable_oc(void)
return 0; return 0;
} }
int imx6_usb_phy1_enable(void) int imx6_usb_phy2_enable(void)
{ {
int val; int val;
@ -94,18 +94,18 @@ int imx6_usb_phy1_enable(void)
while (readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD) & USB_CMD_RESET); while (readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD) & USB_CMD_RESET);
/* reset usbphy */ /* reset usbphy */
writel(USBPHY_CTRL_SFTRST, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + SET); writel(USBPHY_CTRL_SFTRST, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + SET);
udelay(10); udelay(10);
/* clr reset and clkgate */ /* clr reset and clkgate */
writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + CLR); writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + CLR);
/* clr all pwd bits => power up phy */ /* clr all pwd bits => power up phy */
writel(0xffffffff, MX6_USBPHY1_BASE_ADDR + CLR); writel(0xffffffff, MX6_USBPHY2_BASE_ADDR + CLR);
/* set utmilvl2/3 */ /* set utmilvl2/3 */
val = readl(MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL); val = readl(MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL);
val |= USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2; val |= USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2;
writel(val, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + SET); writel(val, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + SET);
return 0; return 0;
} }

View File

@ -13,3 +13,8 @@ config USB_IMX_CHIPIDEA
This driver is recommended for new designs, but it needs board This driver is recommended for new designs, but it needs board
support to work. support to work.
It's safe to say yes here. Also select EHCI support for USB host. It's safe to say yes here. Also select EHCI support for USB host.
config USB_IMX_PHY
bool
depends on ARCH_IMX
default y if ARCH_IMX6

View File

@ -1 +1,2 @@
obj-$(CONFIG_USB_IMX_CHIPIDEA) += imx-usb-misc.o chipidea-imx.o obj-$(CONFIG_USB_IMX_CHIPIDEA) += imx-usb-misc.o chipidea-imx.o
obj-$(CONFIG_USB_IMX_PHY) += imx-usb-phy.o

View File

@ -324,6 +324,12 @@ static __maybe_unused int mx5_initialize_usb_hw(void __iomem *base, int port,
return 0; return 0;
} }
static __maybe_unused int mx6_initialize_usb_hw(void __iomem *base, int port,
unsigned int flags)
{
return 0;
}
static struct platform_device_id imx_usbmisc_ids[] = { static struct platform_device_id imx_usbmisc_ids[] = {
#ifdef CONFIG_ARCH_IMX25 #ifdef CONFIG_ARCH_IMX25
{ {
@ -360,6 +366,12 @@ static struct platform_device_id imx_usbmisc_ids[] = {
.name = "imx53-usb-misc", .name = "imx53-usb-misc",
.driver_data = (unsigned long)&mx5_initialize_usb_hw, .driver_data = (unsigned long)&mx5_initialize_usb_hw,
}, },
#endif
#ifdef CONFIG_ARCH_IMX6
{
.name = "imx6-usb-misc",
.driver_data = (unsigned long)&mx6_initialize_usb_hw,
},
#endif #endif
{ {
/* sentinel */ /* sentinel */

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2013 Sascha Hauer <s.hauer@pengutronix.de>
*
* 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.
*/
#include <common.h>
#include <init.h>
#include <io.h>
#include <driver.h>
#include <malloc.h>
#include <linux/clk.h>
#include <linux/err.h>
#define SET 0x4
#define CLR 0x8
#define USBPHY_CTRL 0x30
#define USBPHY_CTRL_SFTRST (1 << 31)
#define USBPHY_CTRL_CLKGATE (1 << 30)
#define USBPHY_CTRL_ENUTMILEVEL3 (1 << 15)
#define USBPHY_CTRL_ENUTMILEVEL2 (1 << 14)
struct imx_usbphy {
void __iomem *base;
struct clk *clk;
};
static int imx_usbphy_enable(struct imx_usbphy *imxphy)
{
u32 val;
clk_enable(imxphy->clk);
/* reset usbphy */
writel(USBPHY_CTRL_SFTRST, imxphy->base + USBPHY_CTRL + SET);
udelay(10);
/* clr reset and clkgate */
writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE,
imxphy->base + USBPHY_CTRL + CLR);
/* clr all pwd bits => power up phy */
writel(0xffffffff, imxphy->base + CLR);
/* set utmilvl2/3 */
val = readl(imxphy->base + USBPHY_CTRL);
val |= USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2;
writel(val, imxphy->base + USBPHY_CTRL + SET);
return 0;
}
static int imx_usbphy_probe(struct device_d *dev)
{
int ret;
struct imx_usbphy *imxphy;
imxphy = xzalloc(sizeof(*imxphy));
imxphy->base = dev_request_mem_region(dev, 0);
if (!imxphy->base) {
ret = -ENODEV;
goto err_free;
}
imxphy->clk = clk_get(dev, NULL);
if (IS_ERR(imxphy->clk)) {
dev_err(dev, "could not get clk: %s\n", strerror(-PTR_ERR(imxphy->clk)));
goto err_clk;
}
imx_usbphy_enable(imxphy);
dev_dbg(dev, "phy enabled\n");
return 0;
err_clk:
err_free:
free(imxphy);
return ret;
};
static struct driver_d imx_usbphy_driver = {
.name = "imx-usb-phy",
.probe = imx_usbphy_probe,
};
static int imx_usbphy_init(void)
{
return platform_driver_register(&imx_usbphy_driver);
}
coredevice_initcall(imx_usbphy_init);