This patch set is based on Kukjin Kim's for-next branch. Tested on SMDKV310 and Origen boards.
The patch set cleans up intermediate functions and combines USB host and device initialisation into a single function.
Pankaj Dubey (2): ARM: EXYNOS4: Code cleanup and remove extra functions. ARM: EXYNOS4: Add USB phy initialization for device
arch/arm/mach-exynos4/include/mach/regs-pmu.h | 2 +- arch/arm/mach-exynos4/setup-usb-phy.c | 123 +++++++++++++++++-------- 2 files changed, 84 insertions(+), 41 deletions(-)
From: Pankaj Dubey pankaj.dubey@samsung.com
This patch removes the intermediate exynos4_usb_phy1_init and exynos4_usb_phy1_exit function calls.
Signed-off-by: Pankaj Dubey pankaj.dubey@samsung.com Signed-off-by: Sachin Kamat sachin.kamat@linaro.org --- arch/arm/mach-exynos4/setup-usb-phy.c | 166 +++++++++++++++----------------- 1 files changed, 78 insertions(+), 88 deletions(-)
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos4/setup-usb-phy.c index 39aca04..f4c944a 100644 --- a/arch/arm/mach-exynos4/setup-usb-phy.c +++ b/arch/arm/mach-exynos4/setup-usb-phy.c @@ -19,118 +19,108 @@ #include <plat/cpu.h> #include <plat/usb-phy.h>
-static int exynos4_usb_phy1_init(struct platform_device *pdev) +int s5p_usb_phy_init(struct platform_device *pdev, int type) { - struct clk *otg_clk; - struct clk *xusbxti_clk; - u32 phyclk; - u32 rstcon; - int err; - - otg_clk = clk_get(&pdev->dev, "otg"); - if (IS_ERR(otg_clk)) { - dev_err(&pdev->dev, "Failed to get otg clock\n"); - return PTR_ERR(otg_clk); - } + if (type == S5P_USB_PHY_HOST) { + struct clk *otg_clk; + struct clk *xusbxti_clk; + u32 phyclk; + u32 rstcon; + int err; + + otg_clk = clk_get(&pdev->dev, "otg"); + if (IS_ERR(otg_clk)) { + dev_err(&pdev->dev, "Failed to get otg clock\n"); + return PTR_ERR(otg_clk); + }
- err = clk_enable(otg_clk); - if (err) { - clk_put(otg_clk); - return err; - } + err = clk_enable(otg_clk); + if (err) { + clk_put(otg_clk); + return err; + }
- writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, + writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
- /* set clock frequency for PLL */ - phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK; - - xusbxti_clk = clk_get(&pdev->dev, "xusbxti"); - if (xusbxti_clk && !IS_ERR(xusbxti_clk)) { - switch (clk_get_rate(xusbxti_clk)) { - case 12 * MHZ: - phyclk |= CLKSEL_12M; - break; - case 24 * MHZ: - phyclk |= CLKSEL_24M; - break; - default: - case 48 * MHZ: - /* default reference clock */ - break; - } + /* set clock frequency for PLL */ + phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK; + + xusbxti_clk = clk_get(&pdev->dev, "xusbxti"); + if (xusbxti_clk && !IS_ERR(xusbxti_clk)) { + switch (clk_get_rate(xusbxti_clk)) { + case 12 * MHZ: + phyclk |= CLKSEL_12M; + break; + case 24 * MHZ: + phyclk |= CLKSEL_24M; + break; + default: + case 48 * MHZ: + /* default reference clock */ + break; + } clk_put(xusbxti_clk); - } + }
- writel(phyclk, EXYNOS4_PHYCLK); + writel(phyclk, EXYNOS4_PHYCLK);
- /* floating prevention logic: disable */ - writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON); + /* floating prevention logic: disable */ + writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
- /* set to normal HSIC 0 and 1 of PHY1 */ - writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK), + /* set to normal HSIC 0 and 1 of PHY1 */ + writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK), EXYNOS4_PHYPWR);
- /* set to normal standard USB of PHY1 */ - writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR); + /* set to normal standard USB of PHY1 */ + writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), + EXYNOS4_PHYPWR);
- /* reset all ports of both PHY and Link */ - rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK | - PHY1_SWRST_MASK; - writel(rstcon, EXYNOS4_RSTCON); - udelay(10); + /* reset all ports of both PHY and Link */ + rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK | + PHY1_SWRST_MASK; + writel(rstcon, EXYNOS4_RSTCON); + udelay(10);
- rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK); - writel(rstcon, EXYNOS4_RSTCON); - udelay(80); + rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK); + writel(rstcon, EXYNOS4_RSTCON); + udelay(80);
- clk_disable(otg_clk); - clk_put(otg_clk); + clk_disable(otg_clk); + clk_put(otg_clk);
- return 0; + return 0; + } + return -EINVAL; }
-static int exynos4_usb_phy1_exit(struct platform_device *pdev) +int s5p_usb_phy_exit(struct platform_device *pdev, int type) { - struct clk *otg_clk; - int err; - - otg_clk = clk_get(&pdev->dev, "otg"); - if (IS_ERR(otg_clk)) { - dev_err(&pdev->dev, "Failed to get otg clock\n"); - return PTR_ERR(otg_clk); - } + if (type == S5P_USB_PHY_HOST) { + struct clk *otg_clk; + int err; + otg_clk = clk_get(&pdev->dev, "otg"); + if (IS_ERR(otg_clk)) { + dev_err(&pdev->dev, "Failed to get otg clock\n"); + return PTR_ERR(otg_clk); + }
- err = clk_enable(otg_clk); - if (err) { - clk_put(otg_clk); - return err; - } + err = clk_enable(otg_clk); + if (err) { + clk_put(otg_clk); + return err; + }
- writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN), + writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN), EXYNOS4_PHYPWR);
- writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE, + writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
- clk_disable(otg_clk); - clk_put(otg_clk); - - return 0; -} - -int s5p_usb_phy_init(struct platform_device *pdev, int type) -{ - if (type == S5P_USB_PHY_HOST) - return exynos4_usb_phy1_init(pdev); - - return -EINVAL; -} - -int s5p_usb_phy_exit(struct platform_device *pdev, int type) -{ - if (type == S5P_USB_PHY_HOST) - return exynos4_usb_phy1_exit(pdev); + clk_disable(otg_clk); + clk_put(otg_clk);
+ return 0; + } return -EINVAL; }
Sachin Kamat wrote:
From: Pankaj Dubey pankaj.dubey@samsung.com
This patch removes the intermediate exynos4_usb_phy1_init and exynos4_usb_phy1_exit function calls.
Signed-off-by: Pankaj Dubey pankaj.dubey@samsung.com Signed-off-by: Sachin Kamat sachin.kamat@linaro.org
arch/arm/mach-exynos4/setup-usb-phy.c | 166 +++++++++++++++-------------
----
1 files changed, 78 insertions(+), 88 deletions(-)
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach- exynos4/setup-usb-phy.c index 39aca04..f4c944a 100644 --- a/arch/arm/mach-exynos4/setup-usb-phy.c +++ b/arch/arm/mach-exynos4/setup-usb-phy.c @@ -19,118 +19,108 @@ #include <plat/cpu.h> #include <plat/usb-phy.h>
-static int exynos4_usb_phy1_init(struct platform_device *pdev) +int s5p_usb_phy_init(struct platform_device *pdev, int type) {
- struct clk *otg_clk;
- struct clk *xusbxti_clk;
- u32 phyclk;
- u32 rstcon;
- int err;
- otg_clk = clk_get(&pdev->dev, "otg");
- if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
return PTR_ERR(otg_clk);
- }
- if (type == S5P_USB_PHY_HOST) {
struct clk *otg_clk;
struct clk *xusbxti_clk;
u32 phyclk;
u32 rstcon;
int err;
otg_clk = clk_get(&pdev->dev, "otg");
if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
return PTR_ERR(otg_clk);
}
- err = clk_enable(otg_clk);
- if (err) {
clk_put(otg_clk);
return err;
- }
err = clk_enable(otg_clk);
if (err) {
clk_put(otg_clk);
return err;
}
- writel(readl(S5P_USBHOST_PHY_CONTROL) |
S5P_USBHOST_PHY_ENABLE,
writel(readl(S5P_USBHOST_PHY_CONTROL) |
S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
- /* set clock frequency for PLL */
- phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
- xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
- if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
switch (clk_get_rate(xusbxti_clk)) {
case 12 * MHZ:
phyclk |= CLKSEL_12M;
break;
case 24 * MHZ:
phyclk |= CLKSEL_24M;
break;
default:
case 48 * MHZ:
/* default reference clock */
break;
}
/* set clock frequency for PLL */
phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
switch (clk_get_rate(xusbxti_clk)) {
case 12 * MHZ:
phyclk |= CLKSEL_12M;
break;
case 24 * MHZ:
phyclk |= CLKSEL_24M;
break;
default:
case 48 * MHZ:
/* default reference clock */
break;
clk_put(xusbxti_clk);}
- }
}
- writel(phyclk, EXYNOS4_PHYCLK);
writel(phyclk, EXYNOS4_PHYCLK);
- /* floating prevention logic: disable */
- writel((readl(EXYNOS4_PHY1CON) | FPENABLEN),
EXYNOS4_PHY1CON);
/* floating prevention logic: disable */
writel((readl(EXYNOS4_PHY1CON) | FPENABLEN),
EXYNOS4_PHY1CON);
- /* set to normal HSIC 0 and 1 of PHY1 */
- writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
/* set to normal HSIC 0 and 1 of PHY1 */
writel((readl(EXYNOS4_PHYPWR) &
~PHY1_HSIC_NORMAL_MASK), EXYNOS4_PHYPWR);
- /* set to normal standard USB of PHY1 */
- writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK),
EXYNOS4_PHYPWR);
/* set to normal standard USB of PHY1 */
writel((readl(EXYNOS4_PHYPWR) &
~PHY1_STD_NORMAL_MASK),
EXYNOS4_PHYPWR);
- /* reset all ports of both PHY and Link */
- rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
PHY1_SWRST_MASK;
- writel(rstcon, EXYNOS4_RSTCON);
- udelay(10);
/* reset all ports of both PHY and Link */
rstcon = readl(EXYNOS4_RSTCON) |
HOST_LINK_PORT_SWRST_MASK |
PHY1_SWRST_MASK;
writel(rstcon, EXYNOS4_RSTCON);
udelay(10);
- rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
- writel(rstcon, EXYNOS4_RSTCON);
- udelay(80);
rstcon &= ~(HOST_LINK_PORT_SWRST_MASK |
PHY1_SWRST_MASK);
writel(rstcon, EXYNOS4_RSTCON);
udelay(80);
- clk_disable(otg_clk);
- clk_put(otg_clk);
clk_disable(otg_clk);
clk_put(otg_clk);
- return 0;
return 0;
- }
- return -EINVAL;
}
-static int exynos4_usb_phy1_exit(struct platform_device *pdev) +int s5p_usb_phy_exit(struct platform_device *pdev, int type) {
- struct clk *otg_clk;
- int err;
- otg_clk = clk_get(&pdev->dev, "otg");
- if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
return PTR_ERR(otg_clk);
- }
- if (type == S5P_USB_PHY_HOST) {
struct clk *otg_clk;
int err;
otg_clk = clk_get(&pdev->dev, "otg");
if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
return PTR_ERR(otg_clk);
}
- err = clk_enable(otg_clk);
- if (err) {
clk_put(otg_clk);
return err;
- }
err = clk_enable(otg_clk);
if (err) {
clk_put(otg_clk);
return err;
}
- writel((readl(EXYNOS4_PHYPWR) |
PHY1_STD_ANALOG_POWERDOWN),
writel((readl(EXYNOS4_PHYPWR) |
PHY1_STD_ANALOG_POWERDOWN), EXYNOS4_PHYPWR);
- writel(readl(S5P_USBHOST_PHY_CONTROL) &
~S5P_USBHOST_PHY_ENABLE,
writel(readl(S5P_USBHOST_PHY_CONTROL) &
~S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
- clk_disable(otg_clk);
- clk_put(otg_clk);
- return 0;
-}
-int s5p_usb_phy_init(struct platform_device *pdev, int type) -{
- if (type == S5P_USB_PHY_HOST)
return exynos4_usb_phy1_init(pdev);
- return -EINVAL;
-}
-int s5p_usb_phy_exit(struct platform_device *pdev, int type) -{
- if (type == S5P_USB_PHY_HOST)
return exynos4_usb_phy1_exit(pdev);
clk_disable(otg_clk);
clk_put(otg_clk);
return 0;
} return -EINVAL;
}
1.7.4.1
(Cc'ed Yulgon Kim and Kyoungil Kim)
Hi Sachin,
I don't know why this is required on usb-phy control for EXYNOS4 now.
Actually, other upcoming EXYNOS SoCs have more usb phys than EXYNOS4210, so this can make it more difficult to control.
Thanks.
Best regards, Kgene. -- Kukjin Kim kgene.kim@samsung.com, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
From: Pankaj Dubey pankaj.dubey@samsung.com
This patch modifies USB PHY initialization code so that USB host and device can be initialized with the same function.
Signed-off-by: Pankaj Dubey pankaj.dubey@samsung.com Signed-off-by: Sachin Kamat sachin.kamat@linaro.org --- arch/arm/mach-exynos4/include/mach/regs-pmu.h | 2 +- arch/arm/mach-exynos4/setup-usb-phy.c | 159 ++++++++++++++++-------- 2 files changed, 107 insertions(+), 54 deletions(-)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h index cdf9b47..c4709f2 100644 --- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h @@ -34,7 +34,7 @@ #define S5P_WAKEUP_STAT S5P_PMUREG(0x0600) #define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) #define S5P_WAKEUP_MASK S5P_PMUREG(0x0608) - +#define S5P_USBDEVICE_PHY_CONTROL S5P_PMUREG(0x0704) #define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708) #define S5P_USBHOST_PHY_ENABLE (1 << 0)
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos4/setup-usb-phy.c index f4c944a..69878a1 100644 --- a/arch/arm/mach-exynos4/setup-usb-phy.c +++ b/arch/arm/mach-exynos4/setup-usb-phy.c @@ -21,51 +21,65 @@
int s5p_usb_phy_init(struct platform_device *pdev, int type) { + struct clk *otg_clk, *usbhost_clk; + struct clk *xusbxti_clk; + u32 phyclk; + u32 rstcon; + int err; + if ((type != S5P_USB_PHY_HOST) && (type != S5P_USB_PHY_DEVICE)) + return -EINVAL; + + otg_clk = clk_get(&pdev->dev, "otg"); + if (IS_ERR(otg_clk)) { + dev_err(&pdev->dev, "Failed to get otg clock\n"); + return PTR_ERR(otg_clk); + } + + err = clk_enable(otg_clk); + if (err) { + clk_put(otg_clk); + return err; + } + + /* set clock frequency for PLL */ + phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK; + + xusbxti_clk = clk_get(&pdev->dev, "xusbxti"); + if (xusbxti_clk && !IS_ERR(xusbxti_clk)) { + switch (clk_get_rate(xusbxti_clk)) { + case 12 * MHZ: + phyclk |= CLKSEL_12M; + break; + case 24 * MHZ: + phyclk |= CLKSEL_24M; + break; + default: + case 48 * MHZ: + /* default reference clock */ + break; + } + clk_put(xusbxti_clk); + } + + writel(phyclk, EXYNOS4_PHYCLK); + if (type == S5P_USB_PHY_HOST) { - struct clk *otg_clk; - struct clk *xusbxti_clk; - u32 phyclk; - u32 rstcon; - int err; - - otg_clk = clk_get(&pdev->dev, "otg"); - if (IS_ERR(otg_clk)) { - dev_err(&pdev->dev, "Failed to get otg clock\n"); - return PTR_ERR(otg_clk); + 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(otg_clk); + err = clk_enable(usbhost_clk); if (err) { - clk_put(otg_clk); + clk_put(usbhost_clk); return err; }
writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
- /* set clock frequency for PLL */ - phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK; - - xusbxti_clk = clk_get(&pdev->dev, "xusbxti"); - if (xusbxti_clk && !IS_ERR(xusbxti_clk)) { - switch (clk_get_rate(xusbxti_clk)) { - case 12 * MHZ: - phyclk |= CLKSEL_12M; - break; - case 24 * MHZ: - phyclk |= CLKSEL_24M; - break; - default: - case 48 * MHZ: - /* default reference clock */ - break; - } - clk_put(xusbxti_clk); - } - - writel(phyclk, EXYNOS4_PHYCLK); - - /* floating prevention logic: disable */ writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
/* set to normal HSIC 0 and 1 of PHY1 */ @@ -84,30 +98,61 @@ int s5p_usb_phy_init(struct platform_device *pdev, int type)
rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK); writel(rstcon, EXYNOS4_RSTCON); - udelay(80); + } else if (type == S5P_USB_PHY_DEVICE) { + writel(readl(S5P_USBDEVICE_PHY_CONTROL) | (0x1<<0), + S5P_USBDEVICE_PHY_CONTROL); + writel((readl(EXYNOS4_PHYPWR) & ~(0x7<<3)&~(0x1<<0)), + EXYNOS4_PHYPWR); + writel((readl(EXYNOS4_PHYCLK) & ~(0x5<<2))|(0x3<<0), + EXYNOS4_PHYCLK); + writel((readl(EXYNOS4_RSTCON) & ~(0x3<<1))|(0x1<<0), + EXYNOS4_RSTCON); + udelay(10); + writel(readl(EXYNOS4_RSTCON) & ~(0x7<<0), + EXYNOS4_RSTCON); + } + udelay(80);
- clk_disable(otg_clk); - clk_put(otg_clk); + clk_disable(otg_clk); + clk_put(otg_clk); + if (type == S5P_USB_PHY_HOST) + clk_put(usbhost_clk);
- return 0; - } - return -EINVAL; + return 0; }
int s5p_usb_phy_exit(struct platform_device *pdev, int type) { + struct clk *otg_clk, *usbhost_clk; + int err; + + if ((type != S5P_USB_PHY_HOST) && (type != S5P_USB_PHY_DEVICE)) + return -EINVAL; + + otg_clk = clk_get(&pdev->dev, "otg"); + if (IS_ERR(otg_clk)) { + dev_err(&pdev->dev, "Failed to get otg clock\n"); + return PTR_ERR(otg_clk); + } + + err = clk_enable(otg_clk); + if (err) { + clk_put(otg_clk); + return err; + } + if (type == S5P_USB_PHY_HOST) { - struct clk *otg_clk; - int err; - otg_clk = clk_get(&pdev->dev, "otg"); - if (IS_ERR(otg_clk)) { - dev_err(&pdev->dev, "Failed to get otg clock\n"); - return PTR_ERR(otg_clk); + + 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(otg_clk); + err = clk_enable(usbhost_clk); if (err) { - clk_put(otg_clk); + clk_put(usbhost_clk); return err; }
@@ -117,10 +162,18 @@ int s5p_usb_phy_exit(struct platform_device *pdev, int type) writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
- clk_disable(otg_clk); - clk_put(otg_clk); + } else if (type == S5P_USB_PHY_DEVICE) { + writel(readl(EXYNOS4_PHYPWR) | (0x3<<3), + EXYNOS4_PHYPWR);
- return 0; + writel(readl(S5P_USBDEVICE_PHY_CONTROL) & ~(1<<0), + S5P_USBDEVICE_PHY_CONTROL); } - return -EINVAL; + + clk_disable(otg_clk); + clk_put(otg_clk); + if (type == S5P_USB_PHY_HOST) + clk_put(usbhost_clk); + + return 0; }
Sachin Kamat wrote:
From: Pankaj Dubey pankaj.dubey@samsung.com
This patch modifies USB PHY initialization code so that USB host and device can be initialized with the same function.
Signed-off-by: Pankaj Dubey pankaj.dubey@samsung.com Signed-off-by: Sachin Kamat sachin.kamat@linaro.org
arch/arm/mach-exynos4/include/mach/regs-pmu.h | 2 +- arch/arm/mach-exynos4/setup-usb-phy.c | 159 ++++++++++++++++---
2 files changed, 107 insertions(+), 54 deletions(-)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h
b/arch/arm/mach-
exynos4/include/mach/regs-pmu.h index cdf9b47..c4709f2 100644 --- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h @@ -34,7 +34,7 @@ #define S5P_WAKEUP_STAT S5P_PMUREG(0x0600) #define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) #define S5P_WAKEUP_MASK S5P_PMUREG(0x0608)
+#define S5P_USBDEVICE_PHY_CONTROL S5P_PMUREG(0x0704) #define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708) #define S5P_USBHOST_PHY_ENABLE (1 << 0)
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach- exynos4/setup-usb-phy.c index f4c944a..69878a1 100644 --- a/arch/arm/mach-exynos4/setup-usb-phy.c +++ b/arch/arm/mach-exynos4/setup-usb-phy.c @@ -21,51 +21,65 @@
int s5p_usb_phy_init(struct platform_device *pdev, int type) {
- struct clk *otg_clk, *usbhost_clk;
- struct clk *xusbxti_clk;
- u32 phyclk;
- u32 rstcon;
- int err;
- if ((type != S5P_USB_PHY_HOST) && (type != S5P_USB_PHY_DEVICE))
return -EINVAL;
- otg_clk = clk_get(&pdev->dev, "otg");
- if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
return PTR_ERR(otg_clk);
- }
- err = clk_enable(otg_clk);
- if (err) {
clk_put(otg_clk);
return err;
- }
- /* set clock frequency for PLL */
- phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
- xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
- if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
switch (clk_get_rate(xusbxti_clk)) {
case 12 * MHZ:
phyclk |= CLKSEL_12M;
break;
case 24 * MHZ:
phyclk |= CLKSEL_24M;
break;
default:
case 48 * MHZ:
/* default reference clock */
break;
}
- clk_put(xusbxti_clk);
- }
- writel(phyclk, EXYNOS4_PHYCLK);
- if (type == S5P_USB_PHY_HOST) {
struct clk *otg_clk;
struct clk *xusbxti_clk;
u32 phyclk;
u32 rstcon;
int err;
otg_clk = clk_get(&pdev->dev, "otg");
if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
return PTR_ERR(otg_clk);
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);
(Cc'ed Yulgon Kim and Kyoungil Kim)
Hmm...I know, since the USB Host PHY Controller is included in the 'otg' clock domain the 'otg' clock is controlled here. But the USB Host clock is controlled in ehci-s5p driver now so we don't need to add this here.
}
err = clk_enable(otg_clk);
if (err) {err = clk_enable(usbhost_clk);
clk_put(otg_clk);
clk_put(usbhost_clk); return err;
}
writel(readl(S5P_USBHOST_PHY_CONTROL) |
S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
/* set clock frequency for PLL */
phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
switch (clk_get_rate(xusbxti_clk)) {
case 12 * MHZ:
phyclk |= CLKSEL_12M;
break;
case 24 * MHZ:
phyclk |= CLKSEL_24M;
break;
default:
case 48 * MHZ:
/* default reference clock */
break;
}
clk_put(xusbxti_clk);
}
writel(phyclk, EXYNOS4_PHYCLK);
writel((readl(EXYNOS4_PHY1CON) | FPENABLEN),/* floating prevention logic: disable */
EXYNOS4_PHY1CON);
/* set to normal HSIC 0 and 1 of PHY1 */
@@ -84,30 +98,61 @@ int s5p_usb_phy_init(struct platform_device *pdev,
int type)
rstcon &= ~(HOST_LINK_PORT_SWRST_MASK |
PHY1_SWRST_MASK); writel(rstcon, EXYNOS4_RSTCON);
udelay(80);
- } else if (type == S5P_USB_PHY_DEVICE) {
writel(readl(S5P_USBDEVICE_PHY_CONTROL) | (0x1<<0),
S5P_USBDEVICE_PHY_CONTROL);
writel((readl(EXYNOS4_PHYPWR) & ~(0x7<<3)&~(0x1<<0)),
EXYNOS4_PHYPWR);
writel((readl(EXYNOS4_PHYCLK) & ~(0x5<<2))|(0x3<<0),
EXYNOS4_PHYCLK);
writel((readl(EXYNOS4_RSTCON) & ~(0x3<<1))|(0x1<<0),
EXYNOS4_RSTCON);
udelay(10);
writel(readl(EXYNOS4_RSTCON) & ~(0x7<<0),
EXYNOS4_RSTCON);
- }
- udelay(80);
clk_disable(otg_clk);
clk_put(otg_clk);
- clk_disable(otg_clk);
- clk_put(otg_clk);
- if (type == S5P_USB_PHY_HOST)
clk_put(usbhost_clk);
return 0;
- }
- return -EINVAL;
- return 0;
}
int s5p_usb_phy_exit(struct platform_device *pdev, int type) {
- struct clk *otg_clk, *usbhost_clk;
- int err;
- if ((type != S5P_USB_PHY_HOST) && (type != S5P_USB_PHY_DEVICE))
return -EINVAL;
- otg_clk = clk_get(&pdev->dev, "otg");
- if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
return PTR_ERR(otg_clk);
- }
- err = clk_enable(otg_clk);
- if (err) {
clk_put(otg_clk);
return err;
- }
- if (type == S5P_USB_PHY_HOST) {
struct clk *otg_clk;
int err;
otg_clk = clk_get(&pdev->dev, "otg");
if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
return PTR_ERR(otg_clk);
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(otg_clk);
err = clk_enable(usbhost_clk);
Wrong, do you _really_ want to enable usbhost_clk here, in usb_phy_exit()?
if (err) {
clk_put(otg_clk);
}clk_put(usbhost_clk); return err;
@@ -117,10 +162,18 @@ int s5p_usb_phy_exit(struct platform_device *pdev,
int
type) writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
clk_disable(otg_clk);
clk_put(otg_clk);
- } else if (type == S5P_USB_PHY_DEVICE) {
writel(readl(EXYNOS4_PHYPWR) | (0x3<<3),
EXYNOS4_PHYPWR);
return 0;
writel(readl(S5P_USBDEVICE_PHY_CONTROL) & ~(1<<0),
}S5P_USBDEVICE_PHY_CONTROL);
- return -EINVAL;
- clk_disable(otg_clk);
- clk_put(otg_clk);
- if (type == S5P_USB_PHY_HOST)
clk_put(usbhost_clk);
- return 0;
}
1.7.4.1
I can't agree this patch. I think you need to check about whole USB PHY structure on EXYNOS4 again.
In addition, I don’t have idea we need to control USB Host clock for handling USB PHY enable/disable.
Thanks.
Best regards, Kgene. -- Kukjin Kim kgene.kim@samsung.com, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.