|
@@ -31,144 +31,6 @@
|
|
|
#include <plat/usb.h>
|
|
|
#include "control.h"
|
|
|
|
|
|
-/* OMAP control module register for UTMI PHY */
|
|
|
-#define CONTROL_DEV_CONF 0x300
|
|
|
-#define PHY_PD 0x1
|
|
|
-
|
|
|
-#define USBOTGHS_CONTROL 0x33c
|
|
|
-#define AVALID BIT(0)
|
|
|
-#define BVALID BIT(1)
|
|
|
-#define VBUSVALID BIT(2)
|
|
|
-#define SESSEND BIT(3)
|
|
|
-#define IDDIG BIT(4)
|
|
|
-
|
|
|
-static struct clk *phyclk, *clk48m, *clk32k;
|
|
|
-static void __iomem *ctrl_base;
|
|
|
-static int usbotghs_control;
|
|
|
-
|
|
|
-int omap4430_phy_init(struct device *dev)
|
|
|
-{
|
|
|
- ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
|
|
|
- if (!ctrl_base) {
|
|
|
- pr_err("control module ioremap failed\n");
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
- /* Power down the phy */
|
|
|
- __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
|
|
|
-
|
|
|
- if (!dev) {
|
|
|
- iounmap(ctrl_base);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
|
|
|
- if (IS_ERR(phyclk)) {
|
|
|
- dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n");
|
|
|
- iounmap(ctrl_base);
|
|
|
- return PTR_ERR(phyclk);
|
|
|
- }
|
|
|
-
|
|
|
- clk48m = clk_get(dev, "ocp2scp_usb_phy_phy_48m");
|
|
|
- if (IS_ERR(clk48m)) {
|
|
|
- dev_err(dev, "cannot clk_get ocp2scp_usb_phy_phy_48m\n");
|
|
|
- clk_put(phyclk);
|
|
|
- iounmap(ctrl_base);
|
|
|
- return PTR_ERR(clk48m);
|
|
|
- }
|
|
|
-
|
|
|
- clk32k = clk_get(dev, "usb_phy_cm_clk32k");
|
|
|
- if (IS_ERR(clk32k)) {
|
|
|
- dev_err(dev, "cannot clk_get usb_phy_cm_clk32k\n");
|
|
|
- clk_put(phyclk);
|
|
|
- clk_put(clk48m);
|
|
|
- iounmap(ctrl_base);
|
|
|
- return PTR_ERR(clk32k);
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int omap4430_phy_set_clk(struct device *dev, int on)
|
|
|
-{
|
|
|
- static int state;
|
|
|
-
|
|
|
- if (on && !state) {
|
|
|
- /* Enable the phy clocks */
|
|
|
- clk_enable(phyclk);
|
|
|
- clk_enable(clk48m);
|
|
|
- clk_enable(clk32k);
|
|
|
- state = 1;
|
|
|
- } else if (state) {
|
|
|
- /* Disable the phy clocks */
|
|
|
- clk_disable(phyclk);
|
|
|
- clk_disable(clk48m);
|
|
|
- clk_disable(clk32k);
|
|
|
- state = 0;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int omap4430_phy_power(struct device *dev, int ID, int on)
|
|
|
-{
|
|
|
- if (on) {
|
|
|
- if (ID)
|
|
|
- /* enable VBUS valid, IDDIG groung */
|
|
|
- __raw_writel(AVALID | VBUSVALID, ctrl_base +
|
|
|
- USBOTGHS_CONTROL);
|
|
|
- else
|
|
|
- /*
|
|
|
- * Enable VBUS Valid, AValid and IDDIG
|
|
|
- * high impedance
|
|
|
- */
|
|
|
- __raw_writel(IDDIG | AVALID | VBUSVALID,
|
|
|
- ctrl_base + USBOTGHS_CONTROL);
|
|
|
- } else {
|
|
|
- /* Enable session END and IDIG to high impedance. */
|
|
|
- __raw_writel(SESSEND | IDDIG, ctrl_base +
|
|
|
- USBOTGHS_CONTROL);
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int omap4430_phy_suspend(struct device *dev, int suspend)
|
|
|
-{
|
|
|
- if (suspend) {
|
|
|
- /* Disable the clocks */
|
|
|
- omap4430_phy_set_clk(dev, 0);
|
|
|
- /* Power down the phy */
|
|
|
- __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
|
|
|
-
|
|
|
- /* save the context */
|
|
|
- usbotghs_control = __raw_readl(ctrl_base + USBOTGHS_CONTROL);
|
|
|
- } else {
|
|
|
- /* Enable the internel phy clcoks */
|
|
|
- omap4430_phy_set_clk(dev, 1);
|
|
|
- /* power on the phy */
|
|
|
- if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
|
|
|
- __raw_writel(~PHY_PD, ctrl_base + CONTROL_DEV_CONF);
|
|
|
- mdelay(200);
|
|
|
- }
|
|
|
-
|
|
|
- /* restore the context */
|
|
|
- __raw_writel(usbotghs_control, ctrl_base + USBOTGHS_CONTROL);
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int omap4430_phy_exit(struct device *dev)
|
|
|
-{
|
|
|
- if (ctrl_base)
|
|
|
- iounmap(ctrl_base);
|
|
|
- if (phyclk)
|
|
|
- clk_put(phyclk);
|
|
|
- if (clk48m)
|
|
|
- clk_put(clk48m);
|
|
|
- if (clk32k)
|
|
|
- clk_put(clk32k);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
void am35x_musb_reset(void)
|
|
|
{
|
|
|
u32 regval;
|