diff options
author | Bhuvana Kakunoori <bhuvana.kakunoori@linaro.org> | 2011-08-05 11:10:40 +0530 |
---|---|---|
committer | Angus Ainslie <angus.ainslie@linaro.org> | 2011-08-18 17:15:38 -0600 |
commit | 4b50b3e8683be5401da8e59753cbd27915499994 (patch) | |
tree | 1b96aa0d895f01f82277ae1477c22ad5bf844598 | |
parent | f49afde15e1c0b6e634b6ac5b19ac2110bc0f4a2 (diff) |
ARM: EXYNOS4: Enable USB OHCI device on EXYNOS4210
This patch adds support for usb ohci device on SMDKV310
board. In addition, USB PHY configuration for OHCI driver
for EXYNOS4 series is also added.
Signed-off-by: Bhuvana Kakunoori <bhuvana.kakunoori@linaro.org>
Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
-rw-r--r-- | arch/arm/mach-exynos4/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/include/mach/map.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-smdkv310.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/setup-usb-phy.c | 38 |
4 files changed, 53 insertions, 4 deletions
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index a351725c8251..c5a44f065f3c 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -163,6 +163,7 @@ config MACH_SMDKV310 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 select S5P_DEV_USB_HSDEVICE + select S5P_DEV_USB_OHCI select EXYNOS4_DEV_AHCI select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_TS diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h index 033ec76fe640..9e487c7dc268 100644 --- a/arch/arm/mach-exynos4/include/mach/map.h +++ b/arch/arm/mach-exynos4/include/mach/map.h @@ -110,6 +110,7 @@ #define EXYNOS4_PA_SROMC 0x12570000 #define EXYNOS4_PA_EHCI 0x12580000 +#define EXYNOS4_PA_OHCI 0x12590000 #define EXYNOS4_PA_HSPHY 0x125B0000 #define EXYNOS4_PA_UART 0x13800000 @@ -160,6 +161,7 @@ #define S5P_PA_TIMER EXYNOS4_PA_TIMER #define S5P_PA_EHCI EXYNOS4_PA_EHCI #define S5P_PA_HSDEVICE EXYNOS4_PA_HSDEVICE +#define S5P_PA_OHCI EXYNOS4_PA_OHCI #define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c index 6e1f3e22be12..8de2ee7461cc 100644 --- a/arch/arm/mach-exynos4/mach-smdkv310.c +++ b/arch/arm/mach-exynos4/mach-smdkv310.c @@ -46,6 +46,8 @@ #include <plat/ts.h> #include <plat/fimc.h> #include <plat/otg.h> +#include <plat/ohci.h> +#include <plat/clock.h> #include <mach/regs-gpio.h> #include <mach/regs-mem.h> @@ -428,6 +430,16 @@ static void __init smdkv310_otg_init(void) s5p_otg_set_platdata(pdata); } +/*USB OHCI*/ +static struct s5p_ohci_platdata smdkv310_ohci_pdata; + +static void __init smdkv310_ohci_init(void) +{ + struct s5p_ohci_platdata *pdata = &smdkv310_ohci_pdata; + + s5p_ohci_set_platdata(pdata); +} + static struct platform_device *smdkv310_devices[] __initdata = { #ifdef CONFIG_FB_S3C &s3c_device_fb, @@ -448,6 +460,7 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s3c_device_i2c1, &s3c_device_rtc, &s3c_device_wdt, + &s5p_device_ohci, &exynos4_device_ac97, &exynos4_device_i2s0, &exynos4_device_pcm0, @@ -554,6 +567,9 @@ static void __init smdkv310_machine_init(void) s3cfb_set_platdata(NULL); #endif #endif + smdkv310_ohci_init(); + + clk_xusbxti.rate = 24000000; #ifdef CONFIG_USB_GADGET_S3C_OTGD smdkv310_otg_init(); diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos4/setup-usb-phy.c index bec562662149..4a5f83e62810 100644 --- a/arch/arm/mach-exynos4/setup-usb-phy.c +++ b/arch/arm/mach-exynos4/setup-usb-phy.c @@ -23,7 +23,7 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev, int type) { - struct clk *otg_clk; + struct clk *otg_clk, *usbhost_clk; struct clk *xusbxti_clk; u32 phyclk; u32 rstcon; @@ -64,6 +64,19 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev, int type) writel(phyclk, EXYNOS4_PHYCLK); if (type == S5P_USB_PHY_HOST) { + usbhost_clk = clk_get(&pdev->dev, "usbhost"); + + if (IS_ERR(usbhost_clk)) { + dev_err(&pdev->dev, "Failed to get usbhost clock\n"); + return PTR_ERR(usbhost_clk); + } + + err = clk_enable(usbhost_clk); + if (err) { + clk_put(usbhost_clk); + return err; + } + writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL); @@ -99,18 +112,19 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev, int type) writel(readl(EXYNOS4_RSTCON) & ~(0x7<<0), EXYNOS4_RSTCON); } - udelay(50); clk_disable(otg_clk); clk_put(otg_clk); + if (type == S5P_USB_PHY_HOST) + clk_put(usbhost_clk); return 0; } static int exynos4_usb_phy1_exit(struct platform_device *pdev, int type) { - struct clk *otg_clk; + struct clk *otg_clk, *usbhost_clk; int err; otg_clk = clk_get(&pdev->dev, "otg"); @@ -126,22 +140,38 @@ static int exynos4_usb_phy1_exit(struct platform_device *pdev, int type) } if (type == S5P_USB_PHY_HOST) { + + usbhost_clk = clk_get(&pdev->dev, "usbhost"); + + if (IS_ERR(usbhost_clk)) { + dev_err(&pdev->dev, "Failed to get usbhost clock\n"); + return PTR_ERR(usbhost_clk); + } + + err = clk_enable(usbhost_clk); + if (err) { + clk_put(usbhost_clk); + return err; + } + writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN), EXYNOS4_PHYPWR); writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL); + } else if (type == S5P_USB_PHY_DEVICE) { writel(readl(EXYNOS4_PHYPWR) | (0x3<<3), EXYNOS4_PHYPWR); writel(readl(S5P_USBDEVICE_PHY_CONTROL) & ~(1<<0), S5P_USBDEVICE_PHY_CONTROL); - } clk_disable(otg_clk); clk_put(otg_clk); + if (type == S5P_USB_PHY_HOST) + clk_put(usbhost_clk); return 0; } |