aboutsummaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorYuvaraj CD <yuvaraj.cd@gmail.com>2012-12-26 10:48:11 +0530
committerTushar Behera <tushar.behera@linaro.org>2013-01-16 17:14:42 +0530
commit7f50398b5e344b5f4e9008ad1a1b12a371f404ea (patch)
treeb5d86dfb9e4eb9fe9ae1400e04dd2b63b9de2399 /arch/arm
parent94d1464e1ec088683dcf734e18f3e2c4f0fa39a1 (diff)
USB3.0: Migration of Samsung USBPHY changes
Signed-off-by: Yuvaraj CD <yuvaraj.cd@gmail.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi6
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h2
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu.h4
-rw-r--r--arch/arm/mach-exynos/mach-exynos5-dt.c13
-rw-r--r--arch/arm/mach-exynos/setup-usb-phy.c212
-rw-r--r--arch/arm/plat-samsung/include/plat/usb-phy.h8
6 files changed, 80 insertions, 165 deletions
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 686db17ae9b..4e1c5518757 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -81,6 +81,11 @@
interrupts = <0 96 0>;
};
+ usbphy {
+ compatible = "samsung,exynos5250-usbphy";
+ reg = <0x12130000 0x100>, <0x12100000 0x100>;
+ };
+
ohci {
compatible = "samsung,exynos-ohci";
reg = <0x12120000 0x100>;
@@ -288,6 +293,7 @@
#size-cells = <0>;
};
+
amba {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index c20cb439e12..cf9a24848b9 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -190,7 +190,7 @@
#define EXYNOS4_PA_HSOTG 0x12480000
#define EXYNOS4_PA_USB_HSPHY 0x125B0000
-
+#define EXYNOS5_PA_HSPHY 0x12130000
#define EXYNOS4_PA_SATA 0x12560000
#define EXYNOS4_PA_SATAPHY 0x125D0000
#define EXYNOS4_PA_SATAPHY_CTRL 0x126B0000
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
index 3f30aa1ae35..dfc39f204d1 100644
--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -41,6 +41,10 @@
#define S5P_HDMI_PHY_CONTROL S5P_PMUREG(0x0700)
#define S5P_HDMI_PHY_ENABLE (1 << 0)
+/* only for EXYNOS5250*/
+#define S5P_USBDRD_PHY_CONTROL S5P_PMUREG(0x0704)
+#define S5P_USBDRD_PHY_ENABLE (1 << 0)
+
#define S5P_DAC_PHY_CONTROL S5P_PMUREG(0x070C)
#define S5P_DAC_PHY_ENABLE (1 << 0)
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index 18a93c39c3a..74a94f15020 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -17,21 +17,28 @@
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
+
#include <mach/map.h>
#include <mach/regs-pmu.h>
#include <plat/cpu.h>
#include <plat/regs-serial.h>
#include <plat/mfc.h>
-#include <linux/platform_data/usb-exynos.h>
-
#include <plat/regs-srom.h>
#include <plat/devs.h>
#include <plat/usb-phy.h>
+
+#include <linux/platform_data/usb-exynos.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <linux/platform_data/usb-ehci-s5p.h>
#include "common.h"
+static struct samsung_usbphy_data exynos5_usbphy_pdata = {
+ .pmu_isolation = s5p_usb_phy_pmu_isolation,
+ .phy_cfg_sel = s5p_usb_phy_cfg_sel,
+};
+
static struct exynos4_ohci_platdata smdk5250_ohci_pdata = {
.phy_init = s5p_usb_phy_init,
.phy_exit = s5p_usb_phy_exit,
@@ -143,6 +150,8 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
OF_DEV_AUXDATA("samsung,mfc-v6", 0x11000000, "s5p-mfc-v6", NULL),
OF_DEV_AUXDATA("samsung,exynos5250-tmu", 0x10060000,
"exynos-tmu", NULL),
+ OF_DEV_AUXDATA("samsung,exynos5250-usbphy", EXYNOS5_PA_HSPHY,
+ "s3c-usbphy", &exynos5_usbphy_pdata),
OF_DEV_AUXDATA("samsung,exynos-ohci", 0x12120000,
"exynos-ohci", &smdk5250_ohci_pdata),
OF_DEV_AUXDATA("samsung,exynos-ehci", 0x12110000,
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
index e6f2f841376..c9728613138 100644
--- a/arch/arm/mach-exynos/setup-usb-phy.c
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
@@ -14,17 +14,18 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/usb/samsung_usb_phy.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <mach/regs-pmu.h>
#include <mach/regs-usb-phy.h>
#include <plat/cpu.h>
+#include <plat/map-base.h>
#include <plat/usb-phy.h>
#define PHY_ENABLE 1
#define PHY_DISABLE 0
+#define EXYNOS5_USB_CFG (S3C_VA_SYS + 0x230)
-enum usb_phy_type {
- USB_PHY = (0x1 << 0),
-};
static atomic_t host_usage;
@@ -160,7 +161,7 @@ static int exynos4210_usb_phy_clkset(struct platform_device *pdev)
}
return phyclk;
}
-
+#if 0
static void exynos_usb_phy_control(enum usb_phy_type phy_type , int on)
{
if (soc_is_exynos5250()) {
@@ -168,7 +169,7 @@ static void exynos_usb_phy_control(enum usb_phy_type phy_type , int on)
writel(on, S5P_USBHOST_PHY_CONTROL);
}
}
-
+#endif
static int exynos4210_usb_phy0_init(struct platform_device *pdev)
{
u32 rstcon;
@@ -271,156 +272,12 @@ static int exynos4210_usb_phy1_exit(struct platform_device *pdev)
return 0;
}
-static int exynos5_usb_phy20_init(struct platform_device *pdev)
-{
- struct clk *host_clk;
- u32 refclk_freq;
- u32 hostphy_ctrl0;
- u32 otgphy_sys;
- u32 hsic_ctrl;
- u32 ehcictrl;
- u32 ohcictrl;
-
- atomic_inc(&host_usage);
- host_clk = exynos_usb_clock_enable(pdev);
- if (host_clk == NULL) {
- dev_err(&pdev->dev, "Failed to enable USB2.0 host clock\n");
- return -1;
- }
-
- if (exynos4_usb_host_phy_is_on()) {
- dev_err(&pdev->dev, "Already power on PHY\n");
- return 0;
- }
-
- exynos_usb_mux_change(pdev, 1);
-
- exynos_usb_phy_control(USB_PHY, PHY_ENABLE);
-
- /* Host and Device should be set at the same time */
- hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
- hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK);
- otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
- otgphy_sys &= ~(OTG_SYS_CTRL0_FSEL_MASK);
-
- /* 2.0 phy reference clock configuration */
- refclk_freq = exynos4210_usb_phy_clkset(pdev);
- hostphy_ctrl0 |= (refclk_freq << HOST_CTRL0_CLKSEL_SHIFT);
- otgphy_sys |= (refclk_freq << OTG_SYS_CLKSEL_SHIFT);
-
- /* COMMON Block configuration during suspend */
- hostphy_ctrl0 |= (HOST_CTRL0_COMMONON_N);
- otgphy_sys &= ~(OTG_SYS_COMMON_ON);
-
- /* otg phy reset */
- otgphy_sys &= ~(OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG
- | OTG_SYS_FORCE_SLEEP);
- otgphy_sys &= ~(OTG_SYS_REF_CLK_SEL_MASK << OTG_SYS_REF_CLK_SEL_SHIFT);
- otgphy_sys |= (((OTG_SYS_REF_CLK_SEL_CLKCORE & OTG_SYS_REF_CLK_SEL_MASK)
- << OTG_SYS_REF_CLK_SEL_SHIFT)
- | OTG_SYS_OTGDISABLE);
- otgphy_sys |= (OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG
- | OTG_SYS_PHYLINK_SW_RESET);
- writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
- udelay(10);
- otgphy_sys &= ~(OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG
- | OTG_SYS_PHYLINK_SW_RESET);
- writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
-
- /* host phy reset */
- hostphy_ctrl0 &= ~(HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL
- | HOST_CTRL0_SIDDQ);
- hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
- hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
- writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
- udelay(10);
- hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
- writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
-
- /* HSIC phy reset */
- hsic_ctrl = (((HSIC_CTRL_REFCLKDIV_12 & HSIC_CTRL_REFCLKDIV_MASK)
- << HSIC_CTRL_REFCLKDIV_SHIFT)
- | ((HSIC_CTRL_REFCLKSEL & HSIC_CTRL_REFCLKSEL_MASK)
- << HSIC_CTRL_REFCLKSEL_SHIFT)
- | HSIC_CTRL_PHYSWRST);
- writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
- writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
- udelay(10);
- hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST);
- writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
- writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
-
- udelay(80);
-
- /* enable EHCI DMA burst */
- ehcictrl = readl(EXYNOS5_PHY_HOST_EHCICTRL);
- ehcictrl |= (EHCICTRL_ENAINCRXALIGN | EHCICTRL_ENAINCR4
- | EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
- writel(ehcictrl, EXYNOS5_PHY_HOST_EHCICTRL);
-
- /* set ohci_suspend_on_n */
- ohcictrl = readl(EXYNOS5_PHY_HOST_OHCICTRL);
- ohcictrl |= OHCICTRL_SUSPLGCY;
- writel(ohcictrl, EXYNOS5_PHY_HOST_OHCICTRL);
-
- clk_disable(host_clk);
- clk_put(host_clk);
- return 0;
-}
-
-static int exynos5_usb_phy20_exit(struct platform_device *pdev)
-{
- struct clk *host_clk;
- u32 hostphy_ctrl0;
- u32 otgphy_sys;
- u32 hsic_ctrl;
-
- if (atomic_dec_return(&host_usage) > 0) {
- dev_info(&pdev->dev, "still being used\n");
- return -EBUSY;
- }
-
- host_clk = exynos_usb_clock_enable(pdev);
- if (host_clk == NULL) {
- dev_err(&pdev->dev, "Failed to enable otg clock this time\n");
- return -1;
- }
-
- hsic_ctrl = (((HSIC_CTRL_REFCLKDIV_12 & HSIC_CTRL_REFCLKDIV_MASK)
- << HSIC_CTRL_REFCLKDIV_SHIFT)
- | ((HSIC_CTRL_REFCLKSEL & HSIC_CTRL_REFCLKSEL_MASK)
- << HSIC_CTRL_REFCLKSEL_SHIFT)
- | HSIC_CTRL_SIDDQ | HSIC_CTRL_FORCESLEEP
- | HSIC_CTRL_FORCESUSPEND);
- writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
- writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
-
- hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
- hostphy_ctrl0 |= (HOST_CTRL0_SIDDQ);
- hostphy_ctrl0 |= (HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
- hostphy_ctrl0 |= (HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL);
- writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
-
- otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
- otgphy_sys |= (OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG
- | OTG_SYS_FORCE_SLEEP);
- writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
-
- exynos_usb_phy_control(USB_PHY, PHY_DISABLE);
-
- clk_disable(host_clk);
- clk_put(host_clk);
- return 0;
-}
int s5p_usb_phy_init(struct platform_device *pdev, int type)
{
- if (type == S5P_USB_PHY_DEVICE)
+ if (type == USB_PHY_TYPE_DEVICE)
return exynos4210_usb_phy0_init(pdev);
- else if (type == S5P_USB_PHY_HOST) {
- if (soc_is_exynos5250())
- return exynos5_usb_phy20_init(pdev);
- else
+ else if (type == USB_PHY_TYPE_HOST) {
return exynos4210_usb_phy1_init(pdev);
}
@@ -429,13 +286,56 @@ int s5p_usb_phy_init(struct platform_device *pdev, int type)
int s5p_usb_phy_exit(struct platform_device *pdev, int type)
{
- if (type == S5P_USB_PHY_DEVICE)
+
+ if (type == USB_PHY_TYPE_DEVICE)
return exynos4210_usb_phy0_exit(pdev);
- else if (type == S5P_USB_PHY_HOST) {
- if (soc_is_exynos5250())
- return exynos5_usb_phy20_exit(pdev);
- else
+ else if (type == USB_PHY_TYPE_HOST) {
return exynos4210_usb_phy1_exit(pdev);
}
return -EINVAL;
}
+
+ void s5p_usb_phy_pmu_isolation(int on, int type)
+ {
+ if (type == USB_PHY_TYPE_HOST) {
+ if (on)
+ writel(readl(S5P_USBHOST_PHY_CONTROL)
+ & ~S5P_USBHOST_PHY_ENABLE,
+ S5P_USBHOST_PHY_CONTROL);
+ else
+ writel(readl(S5P_USBHOST_PHY_CONTROL)
+ | S5P_USBHOST_PHY_ENABLE,
+ S5P_USBHOST_PHY_CONTROL);
+ }else if(type == USB_PHY_TYPE_DRD) {
+ if (on)
+ writel(readl(S5P_USBDRD_PHY_CONTROL)
+ & ~S5P_USBDRD_PHY_ENABLE,
+ S5P_USBDRD_PHY_CONTROL);
+ else
+ writel(readl(S5P_USBDRD_PHY_CONTROL)
+ | S5P_USBDRD_PHY_ENABLE,
+ S5P_USBDRD_PHY_CONTROL);
+ } else {
+ if (on)
+ writel(readl(S5P_USBDEVICE_PHY_CONTROL)
+ & ~S5P_USBDEVICE_PHY_ENABLE,
+ S5P_USBDEVICE_PHY_CONTROL);
+ else
+ writel(readl(S5P_USBDEVICE_PHY_CONTROL)
+ | S5P_USBDEVICE_PHY_ENABLE,
+ S5P_USBDEVICE_PHY_CONTROL);
+ }
+ }
+
+/* Switch between HOST and OTG link from PHY_CFG */
+void s5p_usb_phy_cfg_sel(struct device *dev, int type)
+{
+ u32 is_host;
+
+ is_host = readl(EXYNOS5_USB_CFG);
+ writel(type, EXYNOS5_USB_CFG);
+
+ if (is_host != type)
+ dev_dbg(dev, "Changed USB MUX from %s to %s",
+ is_host ? "Host" : "Device", type ? "Host" : "Device");
+}
diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h
index 959bcdb03a2..72fb3122912 100644
--- a/arch/arm/plat-samsung/include/plat/usb-phy.h
+++ b/arch/arm/plat-samsung/include/plat/usb-phy.h
@@ -11,12 +11,8 @@
#ifndef __PLAT_SAMSUNG_USB_PHY_H
#define __PLAT_SAMSUNG_USB_PHY_H __FILE__
-enum s5p_usb_phy_type {
- S5P_USB_PHY_DEVICE,
- S5P_USB_PHY_HOST,
-};
-
extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
-
+extern void s5p_usb_phy_pmu_isolation(int on, int type);
+extern void s5p_usb_phy_cfg_sel(struct device *dev, int type);
#endif /* __PLAT_SAMSUNG_USB_PHY_H */