aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhuvana Kakunoori <bhuvana.kakunoori@linaro.org>2011-08-05 11:10:40 +0530
committerAngus Ainslie <angus.ainslie@linaro.org>2011-08-18 17:15:38 -0600
commit4b50b3e8683be5401da8e59753cbd27915499994 (patch)
tree1b96aa0d895f01f82277ae1477c22ad5bf844598
parentf49afde15e1c0b6e634b6ac5b19ac2110bc0f4a2 (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/Kconfig1
-rw-r--r--arch/arm/mach-exynos4/include/mach/map.h2
-rw-r--r--arch/arm/mach-exynos4/mach-smdkv310.c16
-rw-r--r--arch/arm/mach-exynos4/setup-usb-phy.c38
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;
}