diff options
| author | Kishon Vijay Abraham I <kishon@ti.com> | 2014-03-03 06:38:12 -0500 |
|---|---|---|
| committer | Kishon Vijay Abraham I <kishon@ti.com> | 2014-03-06 04:19:33 -0500 |
| commit | a70143bbef6bf06050c32a26d99e917b3e82deb7 (patch) | |
| tree | 7d84ccb6eddc7768cb688600d7069193a54b9908 | |
| parent | 06c886a95cbb533fb3c4178ec0362460b17926ed (diff) | |
drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
Adapted omap-usb3 PHY driver to Generic PHY Framework and moved phy-omap-usb3
driver in drivers/usb/phy to drivers/phy and also renamed the file to
phy-ti-pipe3 since this same driver will be used for SATA PHY and
PCIE PHY.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
| -rw-r--r-- | drivers/phy/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/phy/Makefile | 1 | ||||
| -rw-r--r-- | drivers/phy/phy-ti-pipe3.c (renamed from drivers/usb/phy/phy-omap-usb3.c) | 240 | ||||
| -rw-r--r-- | drivers/usb/phy/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/usb/phy/Makefile | 1 |
5 files changed, 158 insertions, 106 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index dc1756cf5d75..fde4192cc322 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
| @@ -43,6 +43,17 @@ config OMAP_USB2 | |||
| 43 | The USB OTG controller communicates with the comparator using this | 43 | The USB OTG controller communicates with the comparator using this |
| 44 | driver. | 44 | driver. |
| 45 | 45 | ||
| 46 | config TI_PIPE3 | ||
| 47 | tristate "TI PIPE3 PHY Driver" | ||
| 48 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | ||
| 49 | select GENERIC_PHY | ||
| 50 | select OMAP_CONTROL_USB | ||
| 51 | help | ||
| 52 | Enable this to support the PIPE3 PHY that is part of TI SOCs. This | ||
| 53 | driver takes care of all the PHY functionality apart from comparator. | ||
| 54 | This driver interacts with the "OMAP Control PHY Driver" to power | ||
| 55 | on/off the PHY. | ||
| 56 | |||
| 46 | config TWL4030_USB | 57 | config TWL4030_USB |
| 47 | tristate "TWL4030 USB Transceiver Driver" | 58 | tristate "TWL4030 USB Transceiver Driver" |
| 48 | depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS | 59 | depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 5d0b59edaf88..977a50ead5a4 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
| @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o | |||
| 8 | obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o | 8 | obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o |
| 9 | obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o | 9 | obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o |
| 10 | obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o | 10 | obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o |
| 11 | obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o | ||
| 11 | obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o | 12 | obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o |
| 12 | obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o | 13 | obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o |
| 13 | obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o | 14 | obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o |
diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/phy/phy-ti-pipe3.c index 0c6ba29bdddd..c8d16746a5e2 100644 --- a/drivers/usb/phy/phy-omap-usb3.c +++ b/drivers/phy/phy-ti-pipe3.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP. | 2 | * phy-ti-pipe3 - PIPE3 PHY driver. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | 4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com |
| 5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
| @@ -19,10 +19,11 @@ | |||
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/usb/omap_usb.h> | 22 | #include <linux/phy/phy.h> |
| 23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
| 24 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
| 25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
| 26 | #include <linux/io.h> | ||
| 26 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
| 27 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
| 28 | #include <linux/usb/omap_control_usb.h> | 29 | #include <linux/usb/omap_control_usb.h> |
| @@ -52,17 +53,34 @@ | |||
| 52 | 53 | ||
| 53 | /* | 54 | /* |
| 54 | * This is an Empirical value that works, need to confirm the actual | 55 | * This is an Empirical value that works, need to confirm the actual |
| 55 | * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status | 56 | * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status |
| 56 | * to be correctly reflected in the USB3PHY_PLL_STATUS register. | 57 | * to be correctly reflected in the PIPE3PHY_PLL_STATUS register. |
| 57 | */ | 58 | */ |
| 58 | # define PLL_IDLE_TIME 100; | 59 | # define PLL_IDLE_TIME 100; |
| 59 | 60 | ||
| 60 | struct usb_dpll_map { | 61 | struct pipe3_dpll_params { |
| 62 | u16 m; | ||
| 63 | u8 n; | ||
| 64 | u8 freq:3; | ||
| 65 | u8 sd; | ||
| 66 | u32 mf; | ||
| 67 | }; | ||
| 68 | |||
| 69 | struct ti_pipe3 { | ||
| 70 | void __iomem *pll_ctrl_base; | ||
| 71 | struct device *dev; | ||
| 72 | struct device *control_dev; | ||
| 73 | struct clk *wkupclk; | ||
| 74 | struct clk *sys_clk; | ||
| 75 | struct clk *optclk; | ||
| 76 | }; | ||
| 77 | |||
| 78 | struct pipe3_dpll_map { | ||
| 61 | unsigned long rate; | 79 | unsigned long rate; |
| 62 | struct usb_dpll_params params; | 80 | struct pipe3_dpll_params params; |
| 63 | }; | 81 | }; |
| 64 | 82 | ||
| 65 | static struct usb_dpll_map dpll_map[] = { | 83 | static struct pipe3_dpll_map dpll_map[] = { |
| 66 | {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ | 84 | {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ |
| 67 | {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ | 85 | {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ |
| 68 | {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ | 86 | {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ |
| @@ -71,7 +89,18 @@ static struct usb_dpll_map dpll_map[] = { | |||
| 71 | {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ | 89 | {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ |
| 72 | }; | 90 | }; |
| 73 | 91 | ||
| 74 | static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate) | 92 | static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset) |
| 93 | { | ||
| 94 | return __raw_readl(addr + offset); | ||
| 95 | } | ||
| 96 | |||
| 97 | static inline void ti_pipe3_writel(void __iomem *addr, unsigned offset, | ||
| 98 | u32 data) | ||
| 99 | { | ||
| 100 | __raw_writel(data, addr + offset); | ||
| 101 | } | ||
| 102 | |||
| 103 | static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(unsigned long rate) | ||
| 75 | { | 104 | { |
| 76 | int i; | 105 | int i; |
| 77 | 106 | ||
| @@ -83,110 +112,123 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate) | |||
| 83 | return NULL; | 112 | return NULL; |
| 84 | } | 113 | } |
| 85 | 114 | ||
| 86 | static int omap_usb3_suspend(struct usb_phy *x, int suspend) | 115 | static int ti_pipe3_power_off(struct phy *x) |
| 116 | { | ||
| 117 | struct ti_pipe3 *phy = phy_get_drvdata(x); | ||
| 118 | int val; | ||
| 119 | int timeout = PLL_IDLE_TIME; | ||
| 120 | |||
| 121 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
| 122 | val |= PLL_IDLE; | ||
| 123 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
| 124 | |||
| 125 | do { | ||
| 126 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
| 127 | if (val & PLL_TICOPWDN) | ||
| 128 | break; | ||
| 129 | udelay(5); | ||
| 130 | } while (--timeout); | ||
| 131 | |||
| 132 | if (!timeout) { | ||
| 133 | dev_err(phy->dev, "power off failed\n"); | ||
| 134 | return -EBUSY; | ||
| 135 | } | ||
| 136 | |||
| 137 | omap_control_usb_phy_power(phy->control_dev, 0); | ||
| 138 | |||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | |||
| 142 | static int ti_pipe3_power_on(struct phy *x) | ||
| 87 | { | 143 | { |
| 88 | struct omap_usb *phy = phy_to_omapusb(x); | 144 | struct ti_pipe3 *phy = phy_get_drvdata(x); |
| 89 | int val; | 145 | int val; |
| 90 | int timeout = PLL_IDLE_TIME; | 146 | int timeout = PLL_IDLE_TIME; |
| 91 | 147 | ||
| 92 | if (suspend && !phy->is_suspended) { | 148 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); |
| 93 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | 149 | val &= ~PLL_IDLE; |
| 94 | val |= PLL_IDLE; | 150 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); |
| 95 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | 151 | |
| 96 | 152 | do { | |
| 97 | do { | 153 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); |
| 98 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); | 154 | if (!(val & PLL_TICOPWDN)) |
| 99 | if (val & PLL_TICOPWDN) | 155 | break; |
| 100 | break; | 156 | udelay(5); |
| 101 | udelay(1); | 157 | } while (--timeout); |
| 102 | } while (--timeout); | ||
