aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/Kconfig100
-rw-r--r--drivers/phy/Makefile8
-rw-r--r--drivers/phy/phy-bcm-kona-usb2.c2
-rw-r--r--drivers/phy/phy-berlin-sata.c284
-rw-r--r--drivers/phy/phy-core.c63
-rw-r--r--drivers/phy/phy-exynos-dp-video.c7
-rw-r--r--drivers/phy/phy-exynos-mipi-video.c7
-rw-r--r--drivers/phy/phy-exynos4x12-usb2.c125
-rw-r--r--drivers/phy/phy-exynos5-usbdrd.c9
-rw-r--r--drivers/phy/phy-exynos5250-sata.c2
-rw-r--r--drivers/phy/phy-exynos5250-usb2.c2
-rw-r--r--drivers/phy/phy-hix5hd2-sata.c192
-rw-r--r--drivers/phy/phy-miphy365x.c636
-rw-r--r--drivers/phy/phy-mvebu-sata.c2
-rw-r--r--drivers/phy/phy-omap-control.c52
-rw-r--r--drivers/phy/phy-omap-usb2.c13
-rw-r--r--drivers/phy/phy-qcom-apq8064-sata.c289
-rw-r--r--drivers/phy/phy-qcom-ipq806x-sata.c211
-rw-r--r--drivers/phy/phy-s5pv210-usb2.c187
-rw-r--r--drivers/phy/phy-samsung-usb2.c16
-rw-r--r--drivers/phy/phy-samsung-usb2.h6
-rw-r--r--drivers/phy/phy-spear1310-miphy.c2
-rw-r--r--drivers/phy/phy-spear1340-miphy.c2
-rw-r--r--drivers/phy/phy-sun4i-usb.c7
-rw-r--r--drivers/phy/phy-ti-pipe3.c107
-rw-r--r--drivers/phy/phy-twl4030-usb.c2
-rw-r--r--drivers/phy/phy-xgene.c2
27 files changed, 2202 insertions, 133 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index e8f8a2d165d1..0dd742719154 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -15,6 +15,13 @@ config GENERIC_PHY
15 phy users can obtain reference to the PHY. All the users of this 15 phy users can obtain reference to the PHY. All the users of this
16 framework should select this config. 16 framework should select this config.
17 17
18config PHY_BERLIN_SATA
19 tristate "Marvell Berlin SATA PHY driver"
20 depends on ARCH_BERLIN && HAS_IOMEM && OF
21 select GENERIC_PHY
22 help
23 Enable this to support the SATA PHY on Marvell Berlin SoCs.
24
18config PHY_EXYNOS_MIPI_VIDEO 25config PHY_EXYNOS_MIPI_VIDEO
19 tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" 26 tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
20 depends on HAS_IOMEM 27 depends on HAS_IOMEM
@@ -27,10 +34,20 @@ config PHY_EXYNOS_MIPI_VIDEO
27 34
28config PHY_MVEBU_SATA 35config PHY_MVEBU_SATA
29 def_bool y 36 def_bool y
30 depends on ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD 37 depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
31 depends on OF 38 depends on OF
32 select GENERIC_PHY 39 select GENERIC_PHY
33 40
41config PHY_MIPHY365X
42 tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
43 depends on ARCH_STI
44 depends on GENERIC_PHY
45 depends on HAS_IOMEM
46 depends on OF
47 help
48 Enable this to support the miphy transceiver (for SATA/PCIE)
49 that is part of STMicroelectronics STiH41x SoC series.
50
34config OMAP_CONTROL_PHY 51config OMAP_CONTROL_PHY
35 tristate "OMAP CONTROL PHY Driver" 52 tristate "OMAP CONTROL PHY Driver"
36 depends on ARCH_OMAP2PLUS || COMPILE_TEST 53 depends on ARCH_OMAP2PLUS || COMPILE_TEST
@@ -109,9 +126,18 @@ config PHY_EXYNOS5250_SATA
109 SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host 126 SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host
110 port to accept one SATA device. 127 port to accept one SATA device.
111 128
129config PHY_HIX5HD2_SATA
130 tristate "HIX5HD2 SATA PHY Driver"
131 depends on ARCH_HIX5HD2 && OF && HAS_IOMEM
132 select GENERIC_PHY
133 select MFD_SYSCON
134 help
135 Support for SATA PHY on Hisilicon hix5hd2 Soc.
136
112config PHY_SUN4I_USB 137config PHY_SUN4I_USB
113 tristate "Allwinner sunxi SoC USB PHY driver" 138 tristate "Allwinner sunxi SoC USB PHY driver"
114 depends on ARCH_SUNXI && HAS_IOMEM && OF 139 depends on ARCH_SUNXI && HAS_IOMEM && OF
140 depends on RESET_CONTROLLER
115 select GENERIC_PHY 141 select GENERIC_PHY
116 help 142 help
117 Enable this to support the transceiver that is part of Allwinner 143 Enable this to support the transceiver that is part of Allwinner
@@ -122,61 +148,68 @@ config PHY_SUN4I_USB
122 148
123config PHY_SAMSUNG_USB2 149config PHY_SAMSUNG_USB2
124 tristate "Samsung USB 2.0 PHY driver" 150 tristate "Samsung USB 2.0 PHY driver"
151 depends on HAS_IOMEM
152 depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2
125 select GENERIC_PHY 153 select GENERIC_PHY
126 select MFD_SYSCON 154 select MFD_SYSCON
155 default ARCH_EXYNOS
127 help 156 help
128 Enable this to support the Samsung USB 2.0 PHY driver for Samsung 157 Enable this to support the Samsung USB 2.0 PHY driver for Samsung
129 SoCs. This driver provides the interface for USB 2.0 PHY. Support for 158 SoCs. This driver provides the interface for USB 2.0 PHY. Support
130 particular SoCs has to be enabled in addition to this driver. Number 159 for particular PHYs will be enabled based on the SoC type in addition
131 and type of supported phys depends on the SoC. 160 to this driver.
132 161
133config PHY_EXYNOS4210_USB2 162config PHY_S5PV210_USB2
134 bool "Support for Exynos 4210" 163 bool "Support for S5PV210"
135 depends on PHY_SAMSUNG_USB2 164 depends on PHY_SAMSUNG_USB2
136 depends on CPU_EXYNOS4210 165 depends on ARCH_S5PV210
137 help 166 help
138 Enable USB PHY support for Exynos 4210. This option requires that 167 Enable USB PHY support for S5PV210. This option requires that Samsung
139 Samsung USB 2.0 PHY driver is enabled and means that support for this 168 USB 2.0 PHY driver is enabled and means that support for this
140 particular SoC is compiled in the driver. In case of Exynos 4210 four 169 particular SoC is compiled in the driver. In case of S5PV210 two phys
141 phys are available - device, host, HSIC0 and HSIC1. 170 are available - device and host.
171
172config PHY_EXYNOS4210_USB2
173 bool
174 depends on PHY_SAMSUNG_USB2
175 default CPU_EXYNOS4210
142 176
143config PHY_EXYNOS4X12_USB2 177config PHY_EXYNOS4X12_USB2
144 bool "Support for Exynos 4x12" 178 bool
145 depends on PHY_SAMSUNG_USB2 179 depends on PHY_SAMSUNG_USB2
146 depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) 180 default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412
147 help
148 Enable USB PHY support for Exynos 4x12. This option requires that
149 Samsung USB 2.0 PHY driver is enabled and means that support for this
150 particular SoC is compiled in the driver. In case of Exynos 4x12 four
151 phys are available - device, host, HSIC0 and HSIC1.
152 181
153config PHY_EXYNOS5250_USB2 182config PHY_EXYNOS5250_USB2
154 bool "Support for Exynos 5250" 183 bool
155 depends on PHY_SAMSUNG_USB2 184 depends on PHY_SAMSUNG_USB2
156 depends on SOC_EXYNOS5250 185 default SOC_EXYNOS5250 || SOC_EXYNOS5420
157 help
158 Enable USB PHY support for Exynos 5250. This option requires that
159 Samsung USB 2.0 PHY driver is enabled and means that support for this
160 particular SoC is compiled in the driver. In case of Exynos 5250 four
161 phys are available - device, host, HSIC0 and HSIC.
162 186
163config PHY_EXYNOS5_USBDRD 187config PHY_EXYNOS5_USBDRD
164 tristate "Exynos5 SoC series USB DRD PHY driver" 188 tristate "Exynos5 SoC series USB DRD PHY driver"
165 depends on ARCH_EXYNOS5 && OF 189 depends on ARCH_EXYNOS5 && OF
166 depends on HAS_IOMEM 190 depends on HAS_IOMEM
191 depends on USB_DWC3_EXYNOS
167 select GENERIC_PHY 192 select GENERIC_PHY
168 select MFD_SYSCON 193 select MFD_SYSCON
194 default y
169 help 195 help
170 Enable USB DRD PHY support for Exynos 5 SoC series. 196 Enable USB DRD PHY support for Exynos 5 SoC series.
171 This driver provides PHY interface for USB 3.0 DRD controller 197 This driver provides PHY interface for USB 3.0 DRD controller
172 present on Exynos5 SoC series. 198 present on Exynos5 SoC series.
173 199
174config PHY_XGENE 200config PHY_QCOM_APQ8064_SATA
175 tristate "APM X-Gene 15Gbps PHY support" 201 tristate "Qualcomm APQ8064 SATA SerDes/PHY driver"
176 depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST) 202 depends on ARCH_QCOM
203 depends on HAS_IOMEM
204 depends on OF
205 select GENERIC_PHY
206
207config PHY_QCOM_IPQ806X_SATA
208 tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
209 depends on ARCH_QCOM
210 depends on HAS_IOMEM
211 depends on OF
177 select GENERIC_PHY 212 select GENERIC_PHY
178 help
179 This option enables support for APM X-Gene SoC multi-purpose PHY.
180 213
181config PHY_ST_SPEAR1310_MIPHY 214config PHY_ST_SPEAR1310_MIPHY
182 tristate "ST SPEAR1310-MIPHY driver" 215 tristate "ST SPEAR1310-MIPHY driver"
@@ -190,4 +223,11 @@ config PHY_ST_SPEAR1340_MIPHY
190 help 223 help
191 Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA. 224 Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA.
192 225
226config PHY_XGENE
227 tristate "APM X-Gene 15Gbps PHY support"
228 depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST)
229 select GENERIC_PHY
230 help
231 This option enables support for APM X-Gene SoC multi-purpose PHY.
232
193endmenu 233endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d39609bb38de..95c69ed5ed45 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -3,22 +3,28 @@
3# 3#
4 4
5obj-$(CONFIG_GENERIC_PHY) += phy-core.o 5obj-$(CONFIG_GENERIC_PHY) += phy-core.o
6obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
6obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o 7obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o
7obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o 8obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
8obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o 9obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
9obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o 10obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
11obj-$(CONFIG_PHY_MIPHY365X) += phy-miphy365x.o
10obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o 12obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o
11obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o 13obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
12obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o 14obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o
13obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o 15obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
14obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o 16obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
17obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
15obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o 18obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
16obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o 19obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
17phy-exynos-usb2-y += phy-samsung-usb2.o 20phy-exynos-usb2-y += phy-samsung-usb2.o
18phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o 21phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
19phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o 22phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
20phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o 23phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
24phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
21obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o 25obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
22obj-$(CONFIG_PHY_XGENE) += phy-xgene.o 26obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
27obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
23obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o 28obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
24obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o 29obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
30obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
diff --git a/drivers/phy/phy-bcm-kona-usb2.c b/drivers/phy/phy-bcm-kona-usb2.c
index e94f5a6a5645..894fe74c1e44 100644
--- a/drivers/phy/phy-bcm-kona-usb2.c
+++ b/drivers/phy/phy-bcm-kona-usb2.c
@@ -117,7 +117,7 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev)
117 117
118 platform_set_drvdata(pdev, phy); 118 platform_set_drvdata(pdev, phy);
119 119
120 gphy = devm_phy_create(dev, &ops, NULL); 120 gphy = devm_phy_create(dev, NULL, &ops, NULL);
121 if (IS_ERR(gphy)) 121 if (IS_ERR(gphy))
122 return PTR_ERR(gphy); 122 return PTR_ERR(gphy);
123 123
diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c
new file mode 100644
index 000000000000..5c3a0424aeb4
--- /dev/null
+++ b/drivers/phy/phy-berlin-sata.c
@@ -0,0 +1,284 @@
1/*
2 * Marvell Berlin SATA PHY driver
3 *
4 * Copyright (C) 2014 Marvell Technology Group Ltd.
5 *
6 * Antoine Ténart <antoine.tenart@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/clk.h>
14#include <linux/module.h>
15#include <linux/phy/phy.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18
19#define HOST_VSA_ADDR 0x0
20#define HOST_VSA_DATA 0x4
21#define PORT_SCR_CTL 0x2c
22#define PORT_VSR_ADDR 0x78
23#define PORT_VSR_DATA 0x7c
24
25#define CONTROL_REGISTER 0x0
26#define MBUS_SIZE_CONTROL 0x4
27
28#define POWER_DOWN_PHY0 BIT(6)
29#define POWER_DOWN_PHY1 BIT(14)
30#define MBUS_WRITE_REQUEST_SIZE_128 (BIT(2) << 16)
31#define MBUS_READ_REQUEST_SIZE_128 (BIT(2) << 19)
32
33#define PHY_BASE 0x200
34
35/* register 0x01 */
36#define REF_FREF_SEL_25 BIT(0)
37#define PHY_MODE_SATA (0x0 << 5)
38
39/* register 0x02 */
40#define USE_MAX_PLL_RATE BIT(12)
41
42/* register 0x23 */
43#define DATA_BIT_WIDTH_10 (0x0 << 10)
44#define DATA_BIT_WIDTH_20 (0x1 << 10)
45#define DATA_BIT_WIDTH_40 (0x2 << 10)
46
47/* register 0x25 */
48#define PHY_GEN_MAX_1_5 (0x0 << 10)
49#define PHY_GEN_MAX_3_0 (0x1 << 10)
50#define PHY_GEN_MAX_6_0 (0x2 << 10)
51
52struct phy_berlin_desc {
53 struct phy *phy;
54 u32 power_bit;
55 unsigned index;
56};
57
58struct phy_berlin_priv {
59 void __iomem *base;
60 spinlock_t lock;
61 struct clk *clk;
62 struct phy_berlin_desc **phys;
63 unsigned nphys;
64};
65
66static inline void phy_berlin_sata_reg_setbits(void __iomem *ctrl_reg, u32 reg,
67 u32 mask, u32 val)
68{
69 u32 regval;
70
71 /* select register */
72 writel(PHY_BASE + reg, ctrl_reg + PORT_VSR_ADDR);
73
74 /* set bits */
75 regval = readl(ctrl_reg + PORT_VSR_DATA);
76 regval &= ~mask;
77 regval |= val;
78 writel(regval, ctrl_reg + PORT_VSR_DATA);
79}
80
81static int phy_berlin_sata_power_on(struct phy *phy)
82{
83 struct phy_berlin_desc *desc = phy_get_drvdata(phy);
84 struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent);
85 void __iomem *ctrl_reg = priv->base + 0x60 + (desc->index * 0x80);
86 int ret = 0;
87 u32 regval;
88
89 clk_prepare_enable(priv->clk);
90
91 spin_lock(&priv->lock);
92
93 /* Power on PHY */
94 writel(CONTROL_REGISTER, priv->base + HOST_VSA_ADDR);
95 regval = readl(priv->base + HOST_VSA_DATA);
96 regval &= ~desc->power_bit;
97 writel(regval, priv->base + HOST_VSA_DATA);
98
99 /* Configure MBus */
100 writel(MBUS_SIZE_CONTROL, priv->base + HOST_VSA_ADDR);
101 regval = readl(priv->base + HOST_VSA_DATA);
102 regval |= MBUS_WRITE_REQUEST_SIZE_128 | MBUS_READ_REQUEST_SIZE_128;
103 writel(regval, priv->base + HOST_VSA_DATA);
104
105 /* set PHY mode and ref freq to 25 MHz */
106 phy_berlin_sata_reg_setbits(ctrl_reg, 0x1, 0xff,
107 REF_FREF_SEL_25 | PHY_MODE_SATA);
108
109 /* set PHY up to 6 Gbps */
110 phy_berlin_sata_reg_setbits(ctrl_reg, 0x25, 0xc00, PHY_GEN_MAX_6_0);
111
112 /* set 40 bits width */
113 phy_berlin_sata_reg_setbits(ctrl_reg, 0x23, 0xc00, DATA_BIT_WIDTH_40);
114
115 /* use max pll rate */
116 phy_berlin_sata_reg_setbits(ctrl_reg, 0x2, 0x0, USE_MAX_PLL_RATE);
117
118 /* set Gen3 controller speed */
119 regval = readl(ctrl_reg + PORT_SCR_CTL);
120 regval &= ~GENMASK(7, 4);
121 regval |= 0x30;
122 writel(regval, ctrl_reg + PORT_SCR_CTL);
123
124 spin_unlock(&priv->lock);
125
126 clk_disable_unprepare(priv->clk);
127
128 return ret;
129}
130
131static int phy_berlin_sata_power_off(struct phy *phy)
132{
133 struct phy_berlin_desc *desc = phy_get_drvdata(phy);
134 struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent);
135 u32 regval;
136
137 clk_prepare_enable(priv->clk);
138
139 spin_lock(&priv->lock);
140
141 /* Power down PHY */
142 writel(CONTROL_REGISTER, priv->base + HOST_VSA_ADDR);
143 regval = readl(priv->base + HOST_VSA_DATA);
144 regval |= desc->power_bit;
145 writel(regval, priv->base + HOST_VSA_DATA);
146
147 spin_unlock(&priv->lock);
148
149 clk_disable_unprepare(priv->clk);
150
151 return 0;
152}
153
154static struct phy *phy_berlin_sata_phy_xlate(struct device *dev,
155 struct of_phandle_args *args)
156{
157 struct phy_berlin_priv *priv = dev_get_drvdata(dev);
158 int i;
159
160 if (WARN_ON(args->args[0] >= priv->nphys))
161 return ERR_PTR(-ENODEV);
162
163 for (i = 0; i < priv->nphys; i++) {
164 if (priv->phys[i]->index == args->args[0])
165 break;
166 }
167
168 if (i == priv->nphys)
169 return ERR_PTR(-ENODEV);
170
171 return priv->phys[i]->phy;
172}
173
174static struct phy_ops phy_berlin_sata_ops = {
175 .power_on = phy_berlin_sata_power_on,
176 .power_off = phy_berlin_sata_power_off,
177 .owner = THIS_MODULE,
178};
179
180static u32 phy_berlin_power_down_bits[] = {
181 POWER_DOWN_PHY0,
182 POWER_DOWN_PHY1,
183};
184
185static int phy_berlin_sata_probe(struct platform_device *pdev)
186{
187 struct device *dev = &pdev->dev;
188 struct device_node *child;
189 struct phy *phy;
190 struct phy_provider *phy_provider;
191 struct phy_berlin_priv *priv;
192 struct resource *res;
193 int i = 0;
194 u32 phy_id;
195
196 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
197 if (!priv)
198 return -ENOMEM;
199
200 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
201 if (!res)
202 return -EINVAL;
203
204 priv->base = devm_ioremap(dev, res->start, resource_size(res));
205 if (!priv->base)
206 return -ENOMEM;
207
208 priv->clk = devm_clk_get(dev, NULL);
209 if (IS_ERR(priv->clk))
210 return PTR_ERR(priv->clk);
211
212 priv->nphys = of_get_child_count(dev->of_node);
213 if (priv->nphys == 0)
214 return -ENODEV;
215
216 priv->phys = devm_kzalloc(dev, priv->nphys * sizeof(*priv->phys),
217 GFP_KERNEL);
218 if (!priv->phys)
219 return -ENOMEM;
220
221 dev_set_drvdata(dev, priv);
222 spin_lock_init(&priv->lock);
223
224 for_each_available_child_of_node(dev->of_node, child) {
225 struct phy_berlin_desc *phy_desc;
226
227 if (of_property_read_u32(child, "reg", &phy_id)) {
228 dev_err(dev, "missing reg property in node %s\n",
229 child->name);
230 return -EINVAL;
231 }
232
233 if (phy_id >= ARRAY_SIZE(phy_berlin_power_down_bits)) {
234 dev_err(dev, "invalid reg in node %s\n", child->name);
235 return -EINVAL;
236 }
237
238 phy_desc = devm_kzalloc(dev, sizeof(*phy_desc), GFP_KERNEL);
239 if (!phy_desc)
240 return -ENOMEM;
241
242 phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops, NULL);
243 if (IS_ERR(phy)) {
244 dev_err(dev, "failed to create PHY %d\n", phy_id);
245 return PTR_ERR(phy);
246 }
247
248 phy_desc->phy = phy;
249 phy_desc->power_bit = phy_berlin_power_down_bits[phy_id];
250 phy_desc->index = phy_id;
251 phy_set_drvdata(phy, phy_desc);
252
253 priv->phys[i++] = phy_desc;
254
255 /* Make sure the PHY is off */
256 phy_berlin_sata_power_off(phy);
257 }
258
259 phy_provider =
260 devm_of_phy_provider_register(dev, phy_berlin_sata_phy_xlate);
261 if (IS_ERR(phy_provider))
262 return PTR_ERR(phy_provider);
263
264 return 0;
265}
266
267static const struct of_device_id phy_berlin_sata_of_match[] = {
268 { .compatible = "marvell,berlin2q-sata-phy" },
269 { },
270};
271
272static struct platform_driver phy_berlin_sata_driver = {
273 .probe = phy_berlin_sata_probe,
274 .driver = {
275 .name = "phy-berlin-sata",
276 .owner = THIS_MODULE,
277 .of_match_table = phy_berlin_sata_of_match,
278 },
279};
280module_platform_driver(phy_berlin_sata_driver);
281
282MODULE_DESCRIPTION("Marvell Berlin SATA PHY driver");
283MODULE_AUTHOR("Antoine Ténart <antoine.tenart@free-electrons.com>");
284MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index c64a2f3b2d62..ff5eec5af817 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -21,6 +21,7 @@
21#include <linux/phy/phy.h> 21#include <linux/phy/phy.h>
22#include <linux/idr.h> 22#include <linux/idr.h>
23#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
24#include <linux/regulator/consumer.h>
24 25
25static struct class *phy_class; 26static struct class *phy_class;
26static DEFINE_MUTEX(phy_provider_mutex); 27static DEFINE_MUTEX(phy_provider_mutex);
@@ -86,10 +87,15 @@ static struct phy *phy_lookup(struct device *device, const char *port)
86static struct phy_provider *of_phy_provider_lookup(struct device_node *node) 87static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
87{ 88{
88 struct phy_provider *phy_provider; 89 struct phy_provider *phy_provider;
90 struct device_node *child;
89 91
90 list_for_each_entry(phy_provider, &phy_provider_list, list) { 92 list_for_each_entry(phy_provider, &phy_provider_list, list) {
91 if (phy_provider->dev->of_node == node) 93 if (phy_provider->dev->of_node == node)
92 return phy_provider; 94 return phy_provider;
95
96 for_each_child_of_node(phy_provider->dev->of_node, child)
97 if (child == node)
98 return phy_provider;
93 } 99 }
94 100
95 return ERR_PTR(-EPROBE_DEFER); 101 return ERR_PTR(-EPROBE_DEFER);
@@ -226,6 +232,12 @@ int phy_power_on(struct phy *phy)
226 if (!phy) 232 if (!phy)
227 return 0; 233 return 0;
228 234
235 if (phy->pwr) {
236 ret = regulator_enable(phy->pwr);
237 if (ret)
238 return ret;
239 }
240
229 ret = phy_pm_runtime_get_sync(phy); 241 ret = phy_pm_runtime_get_sync(phy);
230 if (ret < 0 && ret != -ENOTSUPP) 242 if (ret < 0 && ret != -ENOTSUPP)
231 return ret; 243 return ret;
@@ -247,6 +259,8 @@ int phy_power_on(struct phy *phy)
247out: 259out:
248 mutex_unlock(&phy->mutex); 260 mutex_unlock(&phy->mutex);
249 phy_pm_runtime_put_sync(phy); 261 phy_pm_runtime_put_sync(phy);
262 if (phy->pwr)
263 regulator_disable(phy->pwr);
250 264
251 return ret; 265 return ret;
252} 266}
@@ -272,6 +286,9 @@ int phy_power_off(struct phy *phy)
272 mutex_unlock(&phy->mutex); 286 mutex_unlock(&phy->mutex);
273 phy_pm_runtime_put(phy); 287 phy_pm_runtime_put(phy);
274 288
289 if (phy->pwr)
290 regulator_disable(phy->pwr);
291
275 return 0; 292 return 0;
276} 293}
277EXPORT_SYMBOL_GPL(phy_power_off); 294EXPORT_SYMBOL_GPL(phy_power_off);
@@ -398,13 +415,20 @@ struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
398 struct phy *phy; 415 struct phy *phy;
399 struct class_dev_iter iter; 416 struct class_dev_iter iter;
400 struct device_node *node = dev->of_node; 417 struct device_node *node = dev->of_node;
418 struct device_node *child;
401 419
402 class_dev_iter_init(&iter, phy_class, NULL, NULL); 420 class_dev_iter_init(&iter, phy_class, NULL, NULL);
403 while ((dev = class_dev_iter_next(&iter))) { 421 while ((dev = class_dev_iter_next(&iter))) {
404 phy = to_phy(dev); 422 phy = to_phy(dev);
405 if (node != phy->dev.of_node) 423 if (node != phy->dev.of_node) {
424 for_each_child_of_node(node, child) {
425 if (child == phy->dev.of_node)
426 goto phy_found;
427 }
406 continue; 428 continue;
429 }
407 430
431phy_found:
408 class_dev_iter_exit(&iter); 432 class_dev_iter_exit(&iter);
409 return phy; 433 return phy;
410 } 434 }
@@ -562,13 +586,15 @@ EXPORT_SYMBOL_GPL(devm_of_phy_get);
562/** 586/**
563 * phy_create() - create a new phy 587 * phy_create() - create a new phy
564 * @dev: device that is creating the new phy 588 * @dev: device that is creating the new phy
589 * @node: device node of the phy
565 * @ops: function pointers for performing phy operations 590 * @ops: function pointers for performing phy operations
566 * @init_data: contains the list of PHY consumers or NULL 591 * @init_data: contains the list of PHY consumers or NULL
567 * 592 *
568 * Called to create a phy using phy framework. 593 * Called to create a phy using phy framework.
569 */ 594 */
570struct phy *phy_create(struct device *dev, const struct phy_ops *ops, 595struct phy *phy_create(struct device *dev, struct device_node *node,
571 struct phy_init_data *init_data) 596 const struct phy_ops *ops,
597 struct phy_init_data *init_data)
572{ 598{
573 int ret; 599 int ret;
574 int id; 600 int id;
@@ -588,12 +614,22 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
588 goto free_phy; 614 goto free_phy;
589 } 615 }
590 616
617 /* phy-supply */
618 phy->pwr = regulator_get_optional(dev, "phy");
619 if (IS_ERR(phy->pwr)) {
620 if (PTR_ERR(phy->pwr) == -EPROBE_DEFER) {
621 ret = -EPROBE_DEFER;
622 goto free_ida;
623 }
624 phy->pwr = NULL;
625 }
626
591 device_initialize(&phy->dev); 627 device_initialize(&phy->dev);
592 mutex_init(&phy->mutex); 628 mutex_init(&phy->mutex);
593 629
594 phy->dev.class = phy_class; 630 phy->dev.class = phy_class;
595 phy->dev.parent = dev; 631 phy->dev.parent = dev;
596 phy->dev.of_node = dev->of_node; 632 phy->dev.of_node = node ?: dev->of_node;
597 phy->id = id; 633 phy->id = id;
598 phy->ops = ops; 634 phy->ops = ops;
599 phy->init_data = init_data; 635 phy->init_data = init_data;
@@ -614,8 +650,12 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
614 return phy; 650 return phy;
615 651
616put_dev: 652put_dev:
617 put_device(&phy->dev); 653 put_device(&phy->dev); /* calls phy_release() which frees resources */
618 ida_remove(&phy_ida, phy->id); 654 return ERR_PTR(ret);
655
656free_ida:
657 ida_simple_remove(&phy_ida, phy->id);
658
619free_phy: 659free_phy:
620 kfree(phy); 660 kfree(phy);
621 return ERR_PTR(ret); 661 return ERR_PTR(ret);
@@ -625,6 +665,7 @@ EXPORT_SYMBOL_GPL(phy_create);
625/** 665/**
626 * devm_phy_create() - create a new phy 666 * devm_phy_create() - create a new phy
627 * @dev: device that is creating the new phy 667 * @dev: device that is creating the new phy
668 * @node: device node of the phy
628 * @ops: function pointers for performing phy operations 669 * @ops: function pointers for performing phy operations
629 * @init_data: contains the list of PHY consumers or NULL 670 * @init_data: contains the list of PHY consumers or NULL
630 * 671 *
@@ -633,8 +674,9 @@ EXPORT_SYMBOL_GPL(phy_create);
633 * On driver detach, release function is invoked on the devres data, 674 * On driver detach, release function is invoked on the devres data,
634 * then, devres data is freed. 675 * then, devres data is freed.
635 */ 676 */
636struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops, 677struct phy *devm_phy_create(struct device *dev, struct device_node *node,
637 struct phy_init_data *init_data) 678 const struct phy_ops *ops,
679 struct phy_init_data *init_data)
638{ 680{
639 struct phy **ptr, *phy; 681 struct phy **ptr, *phy;
640 682
@@ -642,7 +684,7 @@ struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
642 if (!ptr) 684 if (!ptr)
643 return ERR_PTR(-ENOMEM); 685 return ERR_PTR(-ENOMEM);
644 686
645 phy = phy_create(dev, ops, init_data); 687 phy = phy_create(dev, node, ops, init_data);
646 if (!IS_ERR(phy)) { 688 if (!IS_ERR(phy)) {
647 *ptr = phy; 689 *ptr = phy;
648 devres_add(dev, ptr); 690 devres_add(dev, ptr);
@@ -799,7 +841,8 @@ static void phy_release(struct device *dev)
799 841
800 phy = to_phy(dev); 842 phy = to_phy(dev);
801 dev_vdbg(dev, "releasing '%s'\n", dev_name(dev)); 843 dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
802 ida_remove(&phy_ida, phy->id); 844 regulator_put(phy->pwr);
845 ida_simple_remove(&phy_ida, phy->id);
803 kfree(phy); 846 kfree(phy);
804} 847}
805 848
diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c
index 0786fef842e7..8b3026e2af7f 100644
--- a/drivers/phy/phy-exynos-dp-video.c
+++ b/drivers/phy/phy-exynos-dp-video.c
@@ -9,6 +9,7 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/err.h>
12#include <linux/io.h> 13#include <linux/io.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <linux/module.h> 15#include <linux/module.h>
@@ -76,7 +77,7 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
76 if (IS_ERR(state->regs)) 77 if (IS_ERR(state->regs))
77 return PTR_ERR(state->regs); 78 return PTR_ERR(state->regs);
78 79
79 phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL); 80 phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops, NULL);
80 if (IS_ERR(phy)) { 81 if (IS_ERR(phy)) {
81 dev_err(dev, "failed to create Display Port PHY\n"); 82 dev_err(dev, "failed to create Display Port PHY\n");
82 return PTR_ERR(phy); 83 return PTR_ERR(phy);
@@ -84,10 +85,8 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
84 phy_set_drvdata(phy, state); 85 phy_set_drvdata(phy, state);
85 86
86 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 87 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
87 if (IS_ERR(phy_provider))
88 return PTR_ERR(phy_provider);
89 88
90 return 0; 89 return PTR_ERR_OR_ZERO(phy_provider);
91} 90}
92 91
93static const struct of_device_id exynos_dp_video_phy_of_match[] = { 92static const struct of_device_id exynos_dp_video_phy_of_match[] = {
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
index ff026689358c..b55a92e12496 100644
--- a/drivers/phy/phy-exynos-mipi-video.c
+++ b/drivers/phy/phy-exynos-mipi-video.c
@@ -9,6 +9,7 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/err.h>
12#include <linux/io.h> 13#include <linux/io.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <linux/module.h> 15#include <linux/module.h>
@@ -135,7 +136,7 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
135 spin_lock_init(&state->slock); 136 spin_lock_init(&state->slock);
136 137
137 for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { 138 for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
138 struct phy *phy = devm_phy_create(dev, 139 struct phy *phy = devm_phy_create(dev, NULL,
139 &exynos_mipi_video_phy_ops, NULL); 140 &exynos_mipi_video_phy_ops, NULL);
140 if (IS_ERR(phy)) { 141 if (IS_ERR(phy)) {
141 dev_err(dev, "failed to create PHY %d\n", i); 142 dev_err(dev, "failed to create PHY %d\n", i);
@@ -149,10 +150,8 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
149 150
150 phy_provider = devm_of_phy_provider_register(dev, 151 phy_provider = devm_of_phy_provider_register(dev,
151 exynos_mipi_video_phy_xlate); 152 exynos_mipi_video_phy_xlate);
152 if (IS_ERR(phy_provider))
153 return PTR_ERR(phy_provider);
154 153
155 return 0; 154 return PTR_ERR_OR_ZERO(phy_provider);
156} 155}
157 156
158static const struct of_device_id exynos_mipi_video_phy_of_match[] = { 157static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
diff --git a/drivers/phy/phy-exynos4x12-usb2.c b/drivers/phy/phy-exynos4x12-usb2.c
index d92a7cc5698a..0b9de88579b1 100644
--- a/drivers/phy/phy-exynos4x12-usb2.c
+++ b/drivers/phy/phy-exynos4x12-usb2.c
@@ -67,6 +67,8 @@
67#define EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ (0x5 << 0) 67#define EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ (0x5 << 0)
68#define EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ (0x7 << 0) 68#define EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ (0x7 << 0)
69 69
70#define EXYNOS_3250_UPHYCLK_REFCLKSEL (0x2 << 8)
71
70#define EXYNOS_4x12_UPHYCLK_PHY0_ID_PULLUP BIT(3) 72#define EXYNOS_4x12_UPHYCLK_PHY0_ID_PULLUP BIT(3)
71#define EXYNOS_4x12_UPHYCLK_PHY0_COMMON_ON BIT(4) 73#define EXYNOS_4x12_UPHYCLK_PHY0_COMMON_ON BIT(4)
72#define EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON BIT(7) 74#define EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON BIT(7)
@@ -86,13 +88,23 @@
86#define EXYNOS_4x12_URSTCON_OTG_HLINK BIT(1) 88#define EXYNOS_4x12_URSTCON_OTG_HLINK BIT(1)
87#define EXYNOS_4x12_URSTCON_OTG_PHYLINK BIT(2) 89#define EXYNOS_4x12_URSTCON_OTG_PHYLINK BIT(2)
88#define EXYNOS_4x12_URSTCON_HOST_PHY BIT(3) 90#define EXYNOS_4x12_URSTCON_HOST_PHY BIT(3)
91/* The following bit defines are presented in the
92 * order taken from the Exynos4412 reference manual.
93 *
94 * During experiments with the hardware and debugging
95 * it was determined that the hardware behaves contrary
96 * to the manual.
97 *
98 * The following bit values were chaned accordingly to the
99 * results of real hardware experiments.
100 */
89#define EXYNOS_4x12_URSTCON_PHY1 BIT(4) 101#define EXYNOS_4x12_URSTCON_PHY1 BIT(4)
90#define EXYNOS_4x12_URSTCON_HSIC0 BIT(5) 102#define EXYNOS_4x12_URSTCON_HSIC0 BIT(6)
91#define EXYNOS_4x12_URSTCON_HSIC1 BIT(6) 103#define EXYNOS_4x12_URSTCON_HSIC1 BIT(5)
92#define EXYNOS_4x12_URSTCON_HOST_LINK_ALL BIT(7) 104#define EXYNOS_4x12_URSTCON_HOST_LINK_ALL BIT(7)
93#define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(8) 105#define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(10)
94#define EXYNOS_4x12_URSTCON_HOST_LINK_P1 BIT(9) 106#define EXYNOS_4x12_URSTCON_HOST_LINK_P1 BIT(9)
95#define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(10) 107#define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(8)
96 108
97/* Isolation, configured in the power management unit */ 109/* Isolation, configured in the power management unit */
98#define EXYNOS_4x12_USB_ISOL_OFFSET 0x704 110#define EXYNOS_4x12_USB_ISOL_OFFSET 0x704
@@ -187,7 +199,12 @@ static void exynos4x12_setup_clk(struct samsung_usb2_phy_instance *inst)
187 199
188 clk = readl(drv->reg_phy + EXYNOS_4x12_UPHYCLK); 200 clk = readl(drv->reg_phy + EXYNOS_4x12_UPHYCLK);
189 clk &= ~EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK; 201 clk &= ~EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK;
202
203 if (drv->cfg->has_refclk_sel)
204 clk = EXYNOS_3250_UPHYCLK_REFCLKSEL;
205
190 clk |= drv->ref_reg_val << EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET; 206 clk |= drv->ref_reg_val << EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET;
207 clk |= EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON;
191 writel(clk, drv->reg_phy + EXYNOS_4x12_UPHYCLK); 208 writel(clk, drv->reg_phy + EXYNOS_4x12_UPHYCLK);
192} 209}
193 210
@@ -198,27 +215,22 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
198 u32 phypwr = 0; 215 u32 phypwr = 0;
199 u32 rst; 216 u32 rst;
200 u32 pwr; 217 u32 pwr;
201 u32 mode = 0;
202 u32 switch_mode = 0;
203 218
204 switch (inst->cfg->id) { 219 switch (inst->cfg->id) {
205 case EXYNOS4x12_DEVICE: 220 case EXYNOS4x12_DEVICE:
206 phypwr = EXYNOS_4x12_UPHYPWR_PHY0; 221 phypwr = EXYNOS_4x12_UPHYPWR_PHY0;
207 rstbits = EXYNOS_4x12_URSTCON_PHY0; 222 rstbits = EXYNOS_4x12_URSTCON_PHY0;
208 mode = EXYNOS_4x12_MODE_SWITCH_DEVICE;
209 switch_mode = 1;
210 break; 223 break;
211 case EXYNOS4x12_HOST: 224 case EXYNOS4x12_HOST:
212 phypwr = EXYNOS_4x12_UPHYPWR_PHY1; 225 phypwr = EXYNOS_4x12_UPHYPWR_PHY1;
213 rstbits = EXYNOS_4x12_URSTCON_HOST_PHY; 226 rstbits = EXYNOS_4x12_URSTCON_HOST_PHY |
214 mode = EXYNOS_4x12_MODE_SWITCH_HOST; 227 EXYNOS_4x12_URSTCON_PHY1 |
215 switch_mode = 1; 228 EXYNOS_4x12_URSTCON_HOST_LINK_P0;
216 break; 229 break;
217 case EXYNOS4x12_HSIC0: 230 case EXYNOS4x12_HSIC0:
218 phypwr = EXYNOS_4x12_UPHYPWR_HSIC0; 231 phypwr = EXYNOS_4x12_UPHYPWR_HSIC0;
219 rstbits = EXYNOS_4x12_URSTCON_HSIC1 | 232 rstbits = EXYNOS_4x12_URSTCON_HSIC0 |
220 EXYNOS_4x12_URSTCON_HOST_LINK_P0 | 233 EXYNOS_4x12_URSTCON_HOST_LINK_P1;
221 EXYNOS_4x12_URSTCON_HOST_PHY;
222 break; 234 break;
223 case EXYNOS4x12_HSIC1: 235 case EXYNOS4x12_HSIC1:
224 phypwr = EXYNOS_4x12_UPHYPWR_HSIC1; 236 phypwr = EXYNOS_4x12_UPHYPWR_HSIC1;
@@ -228,11 +240,6 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
228 }; 240 };
229 241
230 if (on) { 242 if (on) {
231 if (switch_mode)
232 regmap_update_bits(drv->reg_sys,
233 EXYNOS_4x12_MODE_SWITCH_OFFSET,
234 EXYNOS_4x12_MODE_SWITCH_MASK, mode);
235
236 pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); 243 pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR);
237 pwr &= ~phypwr; 244 pwr &= ~phypwr;
238 writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR); 245 writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR);
@@ -253,41 +260,78 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
253 } 260 }
254} 261}
255 262
256static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst) 263static void exynos4x12_power_on_int(struct samsung_usb2_phy_instance *inst)
257{ 264{
258 struct samsung_usb2_phy_driver *drv = inst->drv; 265 if (inst->int_cnt++ > 0)
266 return;
259 267
260 inst->enabled = 1;
261 exynos4x12_setup_clk(inst); 268 exynos4x12_setup_clk(inst);
262 exynos4x12_phy_pwr(inst, 1);
263 exynos4x12_isol(inst, 0); 269 exynos4x12_isol(inst, 0);
270 exynos4x12_phy_pwr(inst, 1);
271}
272
273static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst)
274{
275 struct samsung_usb2_phy_driver *drv = inst->drv;
276
277 if (inst->ext_cnt++ > 0)
278 return 0;
264 279
265 /* Power on the device, as it is necessary for HSIC to work */ 280 if (inst->cfg->id == EXYNOS4x12_HOST) {
266 if (inst->cfg->id == EXYNOS4x12_HSIC0) { 281 regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
267 struct samsung_usb2_phy_instance *device = 282 EXYNOS_4x12_MODE_SWITCH_MASK,
268 &drv->instances[EXYNOS4x12_DEVICE]; 283 EXYNOS_4x12_MODE_SWITCH_HOST);
269 exynos4x12_phy_pwr(device, 1); 284 exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]);
270 exynos4x12_isol(device, 0);
271 } 285 }
272 286
287 if (inst->cfg->id == EXYNOS4x12_DEVICE && drv->cfg->has_mode_switch)
288 regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
289 EXYNOS_4x12_MODE_SWITCH_MASK,
290 EXYNOS_4x12_MODE_SWITCH_DEVICE);
291
292 if (inst->cfg->id == EXYNOS4x12_HSIC0 ||
293 inst->cfg->id == EXYNOS4x12_HSIC1) {
294 exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]);
295 exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_HOST]);
296 }
297
298 exynos4x12_power_on_int(inst);
299
273 return 0; 300 return 0;
274} 301}
275 302
276static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst) 303static void exynos4x12_power_off_int(struct samsung_usb2_phy_instance *inst)
277{ 304{
278 struct samsung_usb2_phy_driver *drv = inst->drv; 305 if (inst->int_cnt-- > 1)
279 struct samsung_usb2_phy_instance *device = 306 return;
280 &drv->instances[EXYNOS4x12_DEVICE];
281 307
282 inst->enabled = 0;
283 exynos4x12_isol(inst, 1); 308 exynos4x12_isol(inst, 1);
284 exynos4x12_phy_pwr(inst, 0); 309 exynos4x12_phy_pwr(inst, 0);
310}
311
312static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst)
313{
314 struct samsung_usb2_phy_driver *drv = inst->drv;
315
316 if (inst->ext_cnt-- > 1)
317 return 0;
318
319 if (inst->cfg->id == EXYNOS4x12_DEVICE && drv->cfg->has_mode_switch)
320 regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
321 EXYNOS_4x12_MODE_SWITCH_MASK,
322 EXYNOS_4x12_MODE_SWITCH_HOST);
323
324 if (inst->cfg->id == EXYNOS4x12_HOST)
325 exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]);
285 326
286 if (inst->cfg->id == EXYNOS4x12_HSIC0 && !device->enabled) { 327 if (inst->cfg->id == EXYNOS4x12_HSIC0 ||
287 exynos4x12_isol(device, 1); 328 inst->cfg->id == EXYNOS4x12_HSIC1) {
288 exynos4x12_phy_pwr(device, 0); 329 exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]);
330 exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_HOST]);
289 } 331 }
290 332
333 exynos4x12_power_off_int(inst);
334
291 return 0; 335 return 0;
292} 336}
293 337
@@ -320,6 +364,13 @@ static const struct samsung_usb2_common_phy exynos4x12_phys[] = {
320 {}, 364 {},
321}; 365};
322 366
367const struct samsung_usb2_phy_config exynos3250_usb2_phy_config = {
368 .has_refclk_sel = 1,
369 .num_phys = 1,
370 .phys = exynos4x12_phys,
371 .rate_to_clk = exynos4x12_rate_to_clk,
372};
373
323const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config = { 374const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config = {
324 .has_mode_switch = 1, 375 .has_mode_switch = 1,
325 .num_phys = EXYNOS4x12_NUM_PHYS, 376 .num_phys = EXYNOS4x12_NUM_PHYS,
diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c
index 76d862b2202f..b05302b09c9f 100644
--- a/drivers/phy/phy-exynos5-usbdrd.c
+++ b/drivers/phy/phy-exynos5-usbdrd.c
@@ -506,7 +506,7 @@ static struct phy_ops exynos5_usbdrd_phy_ops = {
506 .owner = THIS_MODULE, 506 .owner = THIS_MODULE,
507}; 507};
508 508
509const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = { 509static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
510 { 510 {
511 .id = EXYNOS5_DRDPHY_UTMI, 511 .id = EXYNOS5_DRDPHY_UTMI,
512 .phy_isol = exynos5_usbdrd_phy_isol, 512 .phy_isol = exynos5_usbdrd_phy_isol,
@@ -521,13 +521,13 @@ const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
521 }, 521 },
522}; 522};
523 523
524const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { 524static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = {
525 .phy_cfg = phy_cfg_exynos5, 525 .phy_cfg = phy_cfg_exynos5,
526 .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, 526 .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
527 .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL, 527 .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL,
528}; 528};
529 529
530const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { 530static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = {
531 .phy_cfg = phy_cfg_exynos5, 531 .phy_cfg = phy_cfg_exynos5,
532 .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, 532 .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
533}; 533};
@@ -635,7 +635,8 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
635 dev_vdbg(dev, "Creating usbdrd_phy phy\n"); 635 dev_vdbg(dev, "Creating usbdrd_phy phy\n");
636 636
637 for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) { 637 for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {
638 struct phy *phy = devm_phy_create(dev, &exynos5_usbdrd_phy_ops, 638 struct phy *phy = devm_phy_create(dev, NULL,
639 &exynos5_usbdrd_phy_ops,
639 NULL); 640 NULL);
640 if (IS_ERR(phy)) { 641 if (IS_ERR(phy)) {
641 dev_err(dev, "Failed to create usbdrd_phy phy\n"); 642 dev_err(dev, "Failed to create usbdrd_phy phy\n");
diff --git a/drivers/phy/phy-exynos5250-sata.c b/drivers/phy/phy-exynos5250-sata.c
index 05689450f93b..19a679aca4ac 100644
--- a/drivers/phy/phy-exynos5250-sata.c
+++ b/drivers/phy/phy-exynos5250-sata.c
@@ -210,7 +210,7 @@ static int exynos_sata_phy_probe(struct platform_device *pdev)
210 return ret; 210 return ret;
211 } 211 }
212 212
213 sata_phy->phy = devm_phy_create(dev, &exynos_sata_phy_ops, NULL); 213 sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops, NULL);
214 if (IS_ERR(sata_phy->phy)) { 214 if (IS_ERR(sata_phy->phy)) {
215 clk_disable_unprepare(sata_phy->phyclk); 215 clk_disable_unprepare(sata_phy->phyclk);
216 dev_err(dev, "failed to create PHY\n"); 216 dev_err(dev, "failed to create PHY\n");
diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c
index 94179afda951..1c139aa0d074 100644
--- a/drivers/phy/phy-exynos5250-usb2.c
+++ b/drivers/phy/phy-exynos5250-usb2.c
@@ -318,7 +318,6 @@ static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst)
318 318
319 break; 319 break;
320 } 320 }
321 inst->enabled = 1;
322 exynos5250_isol(inst, 0); 321 exynos5250_isol(inst, 0);
323 322
324 return 0; 323 return 0;
@@ -331,7 +330,6 @@ static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst)
331 u32 otg; 330 u32 otg;
332 u32 hsic; 331 u32 hsic;
333 332
334 inst->enabled = 0;
335 exynos5250_isol(inst, 1); 333 exynos5250_isol(inst, 1);
336 334
337 switch (inst->cfg->id) { 335 switch (inst->cfg->id) {
diff --git a/drivers/phy/phy-hix5hd2-sata.c b/drivers/phy/phy-hix5hd2-sata.c
new file mode 100644
index 000000000000..6a08fa5f81eb
--- /dev/null
+++ b/drivers/phy/phy-hix5hd2-sata.c
@@ -0,0 +1,192 @@
1/*
2 * Copyright (c) 2014 Linaro Ltd.
3 * Copyright (c) 2014 Hisilicon Limited.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/delay.h>
12#include <linux/io.h>
13#include <linux/mfd/syscon.h>
14#include <linux/module.h>
15#include <linux/phy/phy.h>
16#include <linux/platform_device.h>
17#include <linux/regmap.h>
18
19#define SATA_PHY0_CTLL 0xa0
20#define MPLL_MULTIPLIER_SHIFT 1
21#define MPLL_MULTIPLIER_MASK 0xfe
22#define MPLL_MULTIPLIER_50M 0x3c
23#define MPLL_MULTIPLIER_100M 0x1e
24#define PHY_RESET BIT(0)
25#define REF_SSP_EN BIT(9)
26#define SSC_EN BIT(10)
27#define REF_USE_PAD BIT(23)
28
29#define SATA_PORT_PHYCTL 0x174
30#define SPEED_MODE_MASK 0x6f0000
31#define HALF_RATE_SHIFT 16
32#define PHY_CONFIG_SHIFT 18
33#define GEN2_EN_SHIFT 21
34#define SPEED_CTRL BIT(20)
35
36#define SATA_PORT_PHYCTL1 0x148
37#define AMPLITUDE_MASK 0x3ffffe
38#define AMPLITUDE_GEN3 0x68
39#define AMPLITUDE_GEN3_SHIFT 15
40#define AMPLITUDE_GEN2 0x56
41#define AMPLITUDE_GEN2_SHIFT 8
42#define AMPLITUDE_GEN1 0x56
43#define AMPLITUDE_GEN1_SHIFT 1
44
45#define SATA_PORT_PHYCTL2 0x14c
46#define PREEMPH_MASK 0x3ffff
47#define PREEMPH_GEN3 0x20
48#define PREEMPH_GEN3_SHIFT 12
49#define PREEMPH_GEN2 0x15
50#define PREEMPH_GEN2_SHIFT 6
51#define PREEMPH_GEN1 0x5
52#define PREEMPH_GEN1_SHIFT 0
53
54struct hix5hd2_priv {
55 void __iomem *base;
56 struct regmap *peri_ctrl;
57};
58
59enum phy_speed_mode {
60 SPEED_MODE_GEN1 = 0,
61 SPEED_MODE_GEN2 = 1,
62 SPEED_MODE_GEN3 = 2,
63};
64
65static int hix5hd2_sata_phy_init(struct phy *phy)
66{
67 struct hix5hd2_priv *priv = phy_get_drvdata(phy);
68 u32 val, data[2];
69 int ret;
70
71 if (priv->peri_ctrl) {
72 ret = of_property_read_u32_array(phy->dev.of_node,
73 "hisilicon,power-reg",
74 &data[0], 2);
75 if (ret) {
76 dev_err(&phy->dev, "Fail read hisilicon,power-reg\n");
77 return ret;
78 }
79
80 regmap_update_bits(priv->peri_ctrl, data[0],
81 BIT(data[1]), BIT(data[1]));
82 }
83
84 /* reset phy */
85 val = readl_relaxed(priv->base + SATA_PHY0_CTLL);
86 val &= ~(MPLL_MULTIPLIER_MASK | REF_USE_PAD);
87 val |= MPLL_MULTIPLIER_50M << MPLL_MULTIPLIER_SHIFT |
88 REF_SSP_EN | PHY_RESET;
89 writel_relaxed(val, priv->base + SATA_PHY0_CTLL);
90 msleep(20);
91 val &= ~PHY_RESET;
92 writel_relaxed(val, priv->base + SATA_PHY0_CTLL);
93
94 val = readl_relaxed(priv->base + SATA_PORT_PHYCTL1);
95 val &= ~AMPLITUDE_MASK;
96 val |= AMPLITUDE_GEN3 << AMPLITUDE_GEN3_SHIFT |
97 AMPLITUDE_GEN2 << AMPLITUDE_GEN2_SHIFT |
98 AMPLITUDE_GEN1 << AMPLITUDE_GEN1_SHIFT;
99 writel_relaxed(val, priv->base + SATA_PORT_PHYCTL1);
100
101 val = readl_relaxed(priv->base + SATA_PORT_PHYCTL2);
102 val &= ~PREEMPH_MASK;
103 val |= PREEMPH_GEN3 << PREEMPH_GEN3_SHIFT |
104 PREEMPH_GEN2 << PREEMPH_GEN2_SHIFT |
105 PREEMPH_GEN1 << PREEMPH_GEN1_SHIFT;
106 writel_relaxed(val, priv->base + SATA_PORT_PHYCTL2);
107
108 /* ensure PHYCTRL setting takes effect */
109 val = readl_relaxed(priv->base + SATA_PORT_PHYCTL);
110 val &= ~SPEED_MODE_MASK;
111 val |= SPEED_MODE_GEN1 << HALF_RATE_SHIFT |
112 SPEED_MODE_GEN1 << PHY_CONFIG_SHIFT |
113 SPEED_MODE_GEN1 << GEN2_EN_SHIFT | SPEED_CTRL;
114 writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
115
116 msleep(20);
117 val &= ~SPEED_MODE_MASK;
118 val |= SPEED_MODE_GEN3 << HALF_RATE_SHIFT |
119 SPEED_MODE_GEN3 << PHY_CONFIG_SHIFT |
120 SPEED_MODE_GEN3 << GEN2_EN_SHIFT | SPEED_CTRL;
121 writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
122
123 val &= ~(SPEED_MODE_MASK | SPEED_CTRL);
124 val |= SPEED_MODE_GEN2 << HALF_RATE_SHIFT |
125 SPEED_MODE_GEN2 << PHY_CONFIG_SHIFT |
126 SPEED_MODE_GEN2 << GEN2_EN_SHIFT;
127 writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
128
129 return 0;
130}
131
132static struct phy_ops hix5hd2_sata_phy_ops = {
133 .init = hix5hd2_sata_phy_init,
134 .owner = THIS_MODULE,
135};
136
137static int hix5hd2_sata_phy_probe(struct platform_device *pdev)
138{
139 struct phy_provider *phy_provider;
140 struct device *dev = &pdev->dev;
141 struct resource *res;
142 struct phy *phy;
143 struct hix5hd2_priv *priv;
144
145 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
146 if (!priv)
147 return -ENOMEM;
148
149 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
150 priv->base = devm_ioremap(dev, res->start, resource_size(res));
151 if (!priv->base)
152 return -ENOMEM;
153
154 priv->peri_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
155 "hisilicon,peripheral-syscon");
156 if (IS_ERR(priv->peri_ctrl))
157 priv->peri_ctrl = NULL;
158
159 phy = devm_phy_create(dev, NULL, &hix5hd2_sata_phy_ops, NULL);
160 if (IS_ERR(phy)) {
161 dev_err(dev, "failed to create PHY\n");
162 return PTR_ERR(phy);
163 }
164
165 phy_set_drvdata(phy, priv);
166 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
167 if (IS_ERR(phy_provider))
168 return PTR_ERR(phy_provider);
169
170 return 0;
171}
172
173static const struct of_device_id hix5hd2_sata_phy_of_match[] = {
174 {.compatible = "hisilicon,hix5hd2-sata-phy",},
175 { },
176};
177MODULE_DEVICE_TABLE(of, hix5hd2_sata_phy_of_match);
178
179static struct platform_driver hix5hd2_sata_phy_driver = {
180 .probe = hix5hd2_sata_phy_probe,
181 .driver = {
182 .name = "hix5hd2-sata-phy",
183 .owner = THIS_MODULE,
184 .of_match_table = hix5hd2_sata_phy_of_match,
185 }
186};
187module_platform_driver(hix5hd2_sata_phy_driver);
188
189MODULE_AUTHOR("Jiancheng Xue <xuejiancheng@huawei.com>");
190MODULE_DESCRIPTION("HISILICON HIX5HD2 SATA PHY driver");
191MODULE_ALIAS("platform:hix5hd2-sata-phy");
192MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
new file mode 100644
index 000000000000..e111baf187ce
--- /dev/null
+++ b/drivers/phy/phy-miphy365x.c
@@ -0,0 +1,636 @@
1/*
2 * Copyright (C) 2014 STMicroelectronics – All Rights Reserved
3 *
4 * STMicroelectronics PHY driver MiPHY365 (for SoC STiH416).
5 *
6 * Authors: Alexandre Torgue <alexandre.torgue@st.com>
7 * Lee Jones <lee.jones@linaro.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/platform_device.h>
16#include <linux/io.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/of_platform.h>
21#include <linux/of_address.h>
22#include <linux/clk.h>
23#include <linux/phy/phy.h>
24#include <linux/delay.h>
25#include <linux/mfd/syscon.h>
26#include <linux/regmap.h>
27
28#include <dt-bindings/phy/phy-miphy365x.h>
29
30#define HFC_TIMEOUT 100
31
32#define SYSCFG_SELECT_SATA_MASK BIT(1)
33#define SYSCFG_SELECT_SATA_POS 1
34
35/* MiPHY365x register definitions */
36#define RESET_REG 0x00
37#define RST_PLL BIT(1)
38#define RST_PLL_CAL BIT(2)
39#define RST_RX BIT(4)
40#define RST_MACRO BIT(7)
41
42#define STATUS_REG 0x01
43#define IDLL_RDY BIT(0)
44#define PLL_RDY BIT(1)
45#define DES_BIT_LOCK BIT(2)
46#define DES_SYMBOL_LOCK BIT(3)
47
48#define CTRL_REG 0x02
49#define TERM_EN BIT(0)
50#define PCI_EN BIT(2)
51#define DES_BIT_LOCK_EN BIT(3)
52#define TX_POL BIT(5)
53
54#define INT_CTRL_REG 0x03
55
56#define BOUNDARY1_REG 0x10
57#define SPDSEL_SEL BIT(0)
58
59#define BOUNDARY3_REG 0x12
60#define TX_SPDSEL_GEN1_VAL 0
61#define TX_SPDSEL_GEN2_VAL 0x01
62#define TX_SPDSEL_GEN3_VAL 0x02
63#define RX_SPDSEL_GEN1_VAL 0
64#define RX_SPDSEL_GEN2_VAL (0x01 << 3)
65#define RX_SPDSEL_GEN3_VAL (0x02 << 3)
66
67#define PCIE_REG 0x16
68
69#define BUF_SEL_REG 0x20
70#define CONF_GEN_SEL_GEN3 0x02
71#define CONF_GEN_SEL_GEN2 0x01
72#define PD_VDDTFILTER BIT(4)
73
74#define TXBUF1_REG 0x21
75#define SWING_VAL 0x04
76#define SWING_VAL_GEN1 0x03
77#define PREEMPH_VAL (0x3 << 5)
78
79#define TXBUF2_REG 0x22
80#define TXSLEW_VAL 0x2
81#define TXSLEW_VAL_GEN1 0x4
82
83#define RXBUF_OFFSET_CTRL_REG 0x23
84
85#define RXBUF_REG 0x25
86#define SDTHRES_VAL 0x01
87#define EQ_ON3 (0x03 << 4)
88#define EQ_ON1 (0x01 << 4)
89
90#define COMP_CTRL1_REG 0x40
91#define START_COMSR BIT(0)
92#define START_COMZC BIT(1)
93#define COMSR_DONE BIT(2)
94#define COMZC_DONE BIT(3)
95#define COMP_AUTO_LOAD BIT(4)
96
97#define COMP_CTRL2_REG 0x41
98#define COMP_2MHZ_RAT_GEN1 0x1e
99#define COMP_2MHZ_RAT 0xf
100
101#define COMP_CTRL3_REG 0x42
102#define COMSR_COMP_REF 0x33
103
104#define COMP_IDLL_REG 0x47
105#define COMZC_IDLL 0x2a
106
107#define PLL_CTRL1_REG 0x50
108#define PLL_START_CAL BIT(0)
109#define BUF_EN BIT(2)
110#define SYNCHRO_TX BIT(3)
111#define SSC_EN BIT(6)
112#define CONFIG_PLL BIT(7)
113
114#define PLL_CTRL2_REG 0x51
115#define BYPASS_PLL_CAL BIT(1)
116
117#define PLL_RAT_REG 0x52
118
119#define PLL_SSC_STEP_MSB_REG 0x56
120#define PLL_SSC_STEP_MSB_VAL 0x03
121
122#define PLL_SSC_STEP_LSB_REG 0x57
123#define PLL_SSC_STEP_LSB_VAL 0x63
124
125#define PLL_SSC_PER_MSB_REG 0x58
126#define PLL_SSC_PER_MSB_VAL 0
127
128#define PLL_SSC_PER_LSB_REG 0x59
129#define PLL_SSC_PER_LSB_VAL 0xf1
130
131#define IDLL_TEST_REG 0x72
132#define START_CLK_HF BIT(6)
133
134#define DES_BITLOCK_REG 0x86
135#define BIT_LOCK_LEVEL 0x01
136#define BIT_LOCK_CNT_512 (0x03 << 5)
137
138struct miphy365x_phy {
139 struct phy *phy;
140 void __iomem *base;
141 bool pcie_tx_pol_inv;
142 bool sata_tx_pol_inv;
143 u32 sata_gen;
144 u64 ctrlreg;
145 u8 type;
146};
147
148struct miphy365x_dev {
149 struct device *dev;
150 struct regmap *regmap;
151 struct mutex miphy_mutex;
152 struct miphy365x_phy **phys;
153};
154
155/*
156 * These values are represented in Device tree. They are considered to be ABI
157 * and although they can be extended any existing values must not change.
158 */
159enum miphy_sata_gen {
160 SATA_GEN1 = 1,
161 SATA_GEN2,
162 SATA_GEN3
163};
164
165static u8 rx_tx_spd[] = {
166 TX_SPDSEL_GEN1_VAL | RX_SPDSEL_GEN1_VAL,
167 TX_SPDSEL_GEN2_VAL | RX_SPDSEL_GEN2_VAL,
168 TX_SPDSEL_GEN3_VAL | RX_SPDSEL_GEN3_VAL
169};
170
171/*
172 * This function selects the system configuration,
173 * either two SATA, one SATA and one PCIe, or two PCIe lanes.
174 */
175static int miphy365x_set_path(struct miphy365x_phy *miphy_phy,
176 struct miphy365x_dev *miphy_dev)
177{
178 bool sata = (miphy_phy->type == MIPHY_TYPE_SATA);
179
180 return regmap_update_bits(miphy_dev->regmap,
181 (unsigned int)miphy_phy->ctrlreg,
182 SYSCFG_SELECT_SATA_MASK,
183 sata << SYSCFG_SELECT_SATA_POS);
184}
185
186static int miphy365x_init_pcie_port(struct miphy365x_phy *miphy_phy,
187 struct miphy365x_dev *miphy_dev)
188{
189 u8 val;
190
191 if (miphy_phy->pcie_tx_pol_inv) {
192 /* Invert Tx polarity and clear pci_txdetect_pol bit */
193 val = TERM_EN | PCI_EN | DES_BIT_LOCK_EN | TX_POL;
194 writeb_relaxed(val, miphy_phy->base + CTRL_REG);
195 writeb_relaxed(0x00, miphy_phy->base + PCIE_REG);
196 }
197
198 return 0;
199}
200
201static inline int miphy365x_hfc_not_rdy(struct miphy365x_phy *miphy_phy,
202 struct miphy365x_dev *miphy_dev)
203{
204 unsigned long timeout = jiffies + msecs_to_jiffies(HFC_TIMEOUT);
205 u8 mask = IDLL_RDY | PLL_RDY;
206 u8 regval;
207
208 do {
209 regval = readb_relaxed(miphy_phy->base + STATUS_REG);
210 if (!(regval & mask))
211 return 0;
212
213 usleep_range(2000, 2500);
214 } while (time_before(jiffies, timeout));
215
216 dev_err(miphy_dev->dev, "HFC ready timeout!\n");
217 return -EBUSY;
218}
219
220static inline int miphy365x_rdy(struct miphy365x_phy *miphy_phy,
221 struct miphy365x_dev *miphy_dev)
222{
223 unsigned long timeout = jiffies + msecs_to_jiffies(HFC_TIMEOUT);
224 u8 mask = IDLL_RDY | PLL_RDY;
225 u8 regval;
226
227 do {
228 regval = readb_relaxed(miphy_phy->base + STATUS_REG);
229 if ((regval & mask) == mask)
230 return 0;
231
232 usleep_range(2000, 2500);
233 } while (time_before(jiffies, timeout));
234
235 dev_err(miphy_dev->dev, "PHY not ready timeout!\n");
236 return -EBUSY;
237}
238
239static inline void miphy365x_set_comp(struct miphy365x_phy *miphy_phy,
240 struct miphy365x_dev *miphy_dev)
241{
242 u8 val, mask;
243
244 if (miphy_phy->sata_gen == SATA_GEN1)
245 writeb_relaxed(COMP_2MHZ_RAT_GEN1,
246 miphy_phy->base + COMP_CTRL2_REG);
247 else
248 writeb_relaxed(COMP_2MHZ_RAT,
249 miphy_phy->base + COMP_CTRL2_REG);
250
251 if (miphy_phy->sata_gen != SATA_GEN3) {
252 writeb_relaxed(COMSR_COMP_REF,
253 miphy_phy->base + COMP_CTRL3_REG);
254 /*
255 * Force VCO current to value defined by address 0x5A
256 * and disable PCIe100Mref bit
257 * Enable auto load compensation for pll_i_bias
258 */
259 writeb_relaxed(BYPASS_PLL_CAL, miphy_phy->base + PLL_CTRL2_REG);
260 writeb_relaxed(COMZC_IDLL, miphy_phy->base + COMP_IDLL_REG);
261 }
262
263 /*
264 * Force restart compensation and enable auto load
265 * for Comzc_Tx, Comzc_Rx and Comsr on macro
266 */
267 val = START_COMSR | START_COMZC | COMP_AUTO_LOAD;
268 writeb_relaxed(val, miphy_phy->base + COMP_CTRL1_REG);
269
270 mask = COMSR_DONE | COMZC_DONE;
271 while ((readb_relaxed(miphy_phy->base + COMP_CTRL1_REG) & mask) != mask)
272 cpu_relax();
273}
274
275static inline void miphy365x_set_ssc(struct miphy365x_phy *miphy_phy,
276 struct miphy365x_dev *miphy_dev)
277{
278 u8 val;
279
280 /*
281 * SSC Settings. SSC will be enabled through Link
282 * SSC Ampl. = 0.4%
283 * SSC Freq = 31KHz
284 */
285 writeb_relaxed(PLL_SSC_STEP_MSB_VAL,
286 miphy_phy->base + PLL_SSC_STEP_MSB_REG);
287 writeb_relaxed(PLL_SSC_STEP_LSB_VAL,
288 miphy_phy->base + PLL_SSC_STEP_LSB_REG);
289 writeb_relaxed(PLL_SSC_PER_MSB_VAL,
290 miphy_phy->base + PLL_SSC_PER_MSB_REG);
291 writeb_relaxed(PLL_SSC_PER_LSB_VAL,
292 miphy_phy->base + PLL_SSC_PER_LSB_REG);
293
294 /* SSC Settings complete */
295 if (miphy_phy->sata_gen == SATA_GEN1) {
296 val = PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
297 writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
298 } else {
299 val = SSC_EN | PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
300 writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
301 }
302}
303
304static int miphy365x_init_sata_port(struct miphy365x_phy *miphy_phy,
305 struct miphy365x_dev *miphy_dev)
306{
307 int ret;
308 u8 val;
309
310 /*
311 * Force PHY macro reset, PLL calibration reset, PLL reset
312 * and assert Deserializer Reset
313 */
314 val = RST_PLL | RST_PLL_CAL | RST_RX | RST_MACRO;
315 writeb_relaxed(val, miphy_phy->base + RESET_REG);
316
317 if (miphy_phy->sata_tx_pol_inv)
318 writeb_relaxed(TX_POL, miphy_phy->base + CTRL_REG);
319
320 /*
321 * Force macro1 to use rx_lspd, tx_lspd
322 * Force Rx_Clock on first I-DLL phase
323 * Force Des in HP mode on macro, rx_lspd, tx_lspd for Gen2/3
324 */
325 writeb_relaxed(SPDSEL_SEL, miphy_phy->base + BOUNDARY1_REG);
326 writeb_relaxed(START_CLK_HF, miphy_phy->base + IDLL_TEST_REG);
327 val = rx_tx_spd[miphy_phy->sata_gen];
328 writeb_relaxed(val, miphy_phy->base + BOUNDARY3_REG);
329
330 /* Wait for HFC_READY = 0 */
331 ret = miphy365x_hfc_not_rdy(miphy_phy, miphy_dev);
332 if (ret)
333 return ret;
334
335 /* Compensation Recalibration */
336 miphy365x_set_comp(miphy_phy, miphy_dev);
337
338 switch (miphy_phy->sata_gen) {
339 case SATA_GEN3:
340 /*
341 * TX Swing target 550-600mv peak to peak diff
342 * Tx Slew target 90-110ps rising/falling time
343 * Rx Eq ON3, Sigdet threshold SDTH1
344 */
345 val = PD_VDDTFILTER | CONF_GEN_SEL_GEN3;
346 writeb_relaxed(val, miphy_phy->base + BUF_SEL_REG);
347 val = SWING_VAL | PREEMPH_VAL;
348 writeb_relaxed(val, miphy_phy->base + TXBUF1_REG);
349 writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG);
350 writeb_relaxed(0x00, miphy_phy->base + RXBUF_OFFSET_CTRL_REG);
351 val = SDTHRES_VAL | EQ_ON3;
352 writeb_relaxed(val, miphy_phy->base + RXBUF_REG);
353 break;
354 case SATA_GEN2:
355 /*
356 * conf gen sel=0x1 to program Gen2 banked registers
357 * VDDT filter ON
358 * Tx Swing target 550-600mV peak-to-peak diff
359 * Tx Slew target 90-110 ps rising/falling time
360 * RX Equalization ON1, Sigdet threshold SDTH1
361 */
362 writeb_relaxed(CONF_GEN_SEL_GEN2,
363 miphy_phy->base + BUF_SEL_REG);
364 writeb_relaxed(SWING_VAL, miphy_phy->base + TXBUF1_REG);
365 writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG);
366 val = SDTHRES_VAL | EQ_ON1;
367 writeb_relaxed(val, miphy_phy->base + RXBUF_REG);
368 break;
369 case SATA_GEN1:
370 /*
371 * conf gen sel = 00b to program Gen1 banked registers
372 * VDDT filter ON
373 * Tx Swing target 500-550mV peak-to-peak diff
374 * Tx Slew target120-140 ps rising/falling time
375 */
376 writeb_relaxed(PD_VDDTFILTER, miphy_phy->base + BUF_SEL_REG);
377 writeb_relaxed(SWING_VAL_GEN1, miphy_phy->base + TXBUF1_REG);
378 writeb_relaxed(TXSLEW_VAL_GEN1, miphy_phy->base + TXBUF2_REG);
379 break;
380 default:
381 break;
382 }
383
384 /* Force Macro1 in partial mode & release pll cal reset */
385 writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
386 usleep_range(100, 150);
387
388 miphy365x_set_ssc(miphy_phy, miphy_dev);
389
390 /* Wait for phy_ready */
391 ret = miphy365x_rdy(miphy_phy, miphy_dev);
392 if (ret)
393 return ret;
394
395 /*
396 * Enable macro1 to use rx_lspd & tx_lspd
397 * Release Rx_Clock on first I-DLL phase on macro1
398 * Assert deserializer reset
399 * des_bit_lock_en is set
400 * bit lock detection strength
401 * Deassert deserializer reset
402 */
403 writeb_relaxed(0x00, miphy_phy->base + BOUNDARY1_REG);
404 writeb_relaxed(0x00, miphy_phy->base + IDLL_TEST_REG);
405 writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
406 val = miphy_phy->sata_tx_pol_inv ?
407 (TX_POL | DES_BIT_LOCK_EN) : DES_BIT_LOCK_EN;
408 writeb_relaxed(val, miphy_phy->base + CTRL_REG);
409
410 val = BIT_LOCK_CNT_512 | BIT_LOCK_LEVEL;
411 writeb_relaxed(val, miphy_phy->base + DES_BITLOCK_REG);
412 writeb_relaxed(0x00, miphy_phy->base + RESET_REG);
413
414 return 0;
415}
416
417static int miphy365x_init(struct phy *phy)
418{
419 struct miphy365x_phy *miphy_phy = phy_get_drvdata(phy);
420 struct miphy365x_dev *miphy_dev = dev_get_drvdata(phy->dev.parent);
421 int ret = 0;
422
423 mutex_lock(&miphy_dev->miphy_mutex);
424
425 ret = miphy365x_set_path(miphy_phy, miphy_dev);
426 if (ret) {
427 mutex_unlock(&miphy_dev->miphy_mutex);
428 return ret;
429 }
430
431 /* Initialise Miphy for PCIe or SATA */
432 if (miphy_phy->type == MIPHY_TYPE_PCIE)
433 ret = miphy365x_init_pcie_port(miphy_phy, miphy_dev);
434 else
435 ret = miphy365x_init_sata_port(miphy_phy, miphy_dev);
436
437 mutex_unlock(&miphy_dev->miphy_mutex);
438
439 return ret;
440}
441
442int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy,
443 int index)
444{
445 struct device_node *phynode = miphy_phy->phy->dev.of_node;
446 const char *name;
447 const __be32 *taddr;
448 int type = miphy_phy->type;
449 int ret;
450
451 ret = of_property_read_string_index(phynode, "reg-names", index, &name);
452 if (ret) {
453 dev_err(dev, "no reg-names property not found\n");
454 return ret;
455 }
456
457 if (!strncmp(name, "syscfg", 6)) {
458 taddr = of_get_address(phynode, index, NULL, NULL);
459 if (!taddr) {
460 dev_err(dev, "failed to fetch syscfg address\n");
461 return -EINVAL;
462 }
463
464 miphy_phy->ctrlreg = of_translate_address(phynode, taddr);
465 if (miphy_phy->ctrlreg == OF_BAD_ADDR) {
466 dev_err(dev, "failed to translate syscfg address\n");
467 return -EINVAL;
468 }
469
470 return 0;
471 }
472
473 if (!((!strncmp(name, "sata", 4) && type == MIPHY_TYPE_SATA) ||
474 (!strncmp(name, "pcie", 4) && type == MIPHY_TYPE_PCIE)))
475 return 0;
476
477 miphy_phy->base = of_iomap(phynode, index);
478 if (!miphy_phy->base) {
479 dev_err(dev, "Failed to map %s\n", phynode->full_name);
480 return -EINVAL;
481 }
482
483 return 0;
484}
485
486static struct phy *miphy365x_xlate(struct device *dev,
487 struct of_phandle_args *args)
488{
489 struct miphy365x_dev *miphy_dev = dev_get_drvdata(dev);
490 struct miphy365x_phy *miphy_phy = NULL;
491 struct device_node *phynode = args->np;
492 int ret, index;
493
494 if (!of_device_is_available(phynode)) {
495 dev_warn(dev, "Requested PHY is disabled\n");
496 return ERR_PTR(-ENODEV);
497 }
498
499 if (args->args_count != 1) {
500 dev_err(dev, "Invalid number of cells in 'phy' property\n");
501 return ERR_PTR(-EINVAL);
502 }
503
504 for (index = 0; index < of_get_child_count(dev->of_node); index++)
505 if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
506 miphy_phy = miphy_dev->phys[index];
507 break;
508 }
509
510 if (!miphy_phy) {
511 dev_err(dev, "Failed to find appropriate phy\n");
512 return ERR_PTR(-EINVAL);
513 }
514
515 miphy_phy->type = args->args[0];
516
517 if (!(miphy_phy->type == MIPHY_TYPE_SATA ||
518 miphy_phy->type == MIPHY_TYPE_PCIE)) {
519 dev_err(dev, "Unsupported device type: %d\n", miphy_phy->type);
520 return ERR_PTR(-EINVAL);
521 }
522
523 /* Each port handles SATA and PCIE - third entry is always sysconf. */
524 for (index = 0; index < 3; index++) {
525 ret = miphy365x_get_addr(dev, miphy_phy, index);
526 if (ret < 0)
527 return ERR_PTR(ret);
528 }
529
530 return miphy_phy->phy;
531}
532
533static struct phy_ops miphy365x_ops = {
534 .init = miphy365x_init,
535 .owner = THIS_MODULE,
536};
537
538static int miphy365x_of_probe(struct device_node *phynode,
539 struct miphy365x_phy *miphy_phy)
540{
541 of_property_read_u32(phynode, "st,sata-gen", &miphy_phy->sata_gen);
542 if (!miphy_phy->sata_gen)
543 miphy_phy->sata_gen = SATA_GEN1;
544
545 miphy_phy->pcie_tx_pol_inv =
546 of_property_read_bool(phynode, "st,pcie-tx-pol-inv");
547
548 miphy_phy->sata_tx_pol_inv =
549 of_property_read_bool(phynode, "st,sata-tx-pol-inv");
550
551 return 0;
552}
553
554static int miphy365x_probe(struct platform_device *pdev)
555{
556 struct device_node *child, *np = pdev->dev.of_node;
557 struct miphy365x_dev *miphy_dev;
558 struct phy_provider *provider;
559 struct phy *phy;
560 int chancount, port = 0;
561 int ret;
562
563 miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL);
564 if (!miphy_dev)
565 return -ENOMEM;
566
567 chancount = of_get_child_count(np);
568 miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount,
569 GFP_KERNEL);
570 if (!miphy_dev->phys)
571 return -ENOMEM;
572
573 miphy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
574 if (IS_ERR(miphy_dev->regmap)) {
575 dev_err(miphy_dev->dev, "No syscfg phandle specified\n");
576 return PTR_ERR(miphy_dev->regmap);
577 }
578
579 miphy_dev->dev = &pdev->dev;
580
581 dev_set_drvdata(&pdev->dev, miphy_dev);
582
583 mutex_init(&miphy_dev->miphy_mutex);
584
585 for_each_child_of_node(np, child) {
586 struct miphy365x_phy *miphy_phy;
587
588 miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy),
589 GFP_KERNEL);
590 if (!miphy_phy)
591 return -ENOMEM;
592
593 miphy_dev->phys[port] = miphy_phy;
594
595 phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops, NULL);
596 if (IS_ERR(phy)) {
597 dev_err(&pdev->dev, "failed to create PHY\n");
598 return PTR_ERR(phy);
599 }
600
601 miphy_dev->phys[port]->phy = phy;
602
603 ret = miphy365x_of_probe(child, miphy_phy);
604 if (ret)
605 return ret;
606
607 phy_set_drvdata(phy, miphy_dev->phys[port]);
608 port++;
609 }
610
611 provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate);
612 if (IS_ERR(provider))
613 return PTR_ERR(provider);
614
615 return 0;
616}
617
618static const struct of_device_id miphy365x_of_match[] = {
619 { .compatible = "st,miphy365x-phy", },
620 { },
621};
622MODULE_DEVICE_TABLE(of, miphy365x_of_match);
623
624static struct platform_driver miphy365x_driver = {
625 .probe = miphy365x_probe,
626 .driver = {
627 .name = "miphy365x-phy",
628 .owner = THIS_MODULE,
629 .of_match_table = miphy365x_of_match,
630 }
631};
632module_platform_driver(miphy365x_driver);
633
634MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>");
635MODULE_DESCRIPTION("STMicroelectronics miphy365x driver");
636MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-mvebu-sata.c b/drivers/phy/phy-mvebu-sata.c
index d70ecd6a1b3f..cc3c0e166daf 100644
--- a/drivers/phy/phy-mvebu-sata.c
+++ b/drivers/phy/phy-mvebu-sata.c
@@ -99,7 +99,7 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev)
99 if (IS_ERR(priv->clk)) 99 if (IS_ERR(priv->clk))
100 return PTR_ERR(priv->clk); 100 return PTR_ERR(priv->clk);
101 101
102 phy = devm_phy_create(&pdev->dev, &phy_mvebu_sata_ops, NULL); 102 phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops, NULL);
103 if (IS_ERR(phy)) 103 if (IS_ERR(phy))
104 return PTR_ERR(phy); 104 return PTR_ERR(phy);
105 105
diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c
index 311b4f9a5132..9487bf112267 100644
--- a/drivers/phy/phy-omap-control.c
+++ b/drivers/phy/phy-omap-control.c
@@ -27,6 +27,41 @@
27#include <linux/phy/omap_control_phy.h> 27#include <linux/phy/omap_control_phy.h>
28 28
29/** 29/**
30 * omap_control_pcie_pcs - set the PCS delay count
31 * @dev: the control module device
32 * @id: index of the pcie PHY (should be 1 or 2)
33 * @delay: 8 bit delay value
34 */
35void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay)
36{
37 u32 val;
38 struct omap_control_phy *control_phy;
39
40 if (IS_ERR(dev) || !dev) {
41 pr_err("%s: invalid device\n", __func__);
42 return;
43 }
44
45 control_phy = dev_get_drvdata(dev);
46 if (!control_phy) {
47 dev_err(dev, "%s: invalid control phy device\n", __func__);
48 return;
49 }
50
51 if (control_phy->type != OMAP_CTRL_TYPE_PCIE) {
52 dev_err(dev, "%s: unsupported operation\n", __func__);
53 return;
54 }
55
56 val = readl(control_phy->pcie_pcs);
57 val &= ~(OMAP_CTRL_PCIE_PCS_MASK <<
58 (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT));
59 val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT);
60 writel(val, control_phy->pcie_pcs);
61}
62EXPORT_SYMBOL_GPL(omap_control_pcie_pcs);
63
64/**
30 * omap_control_phy_power - power on/off the phy using control module reg 65 * omap_control_phy_power - power on/off the phy using control module reg
31 * @dev: the control module device 66 * @dev: the control module device
32 * @on: 0 or 1, based on powering on or off the PHY 67 * @on: 0 or 1, based on powering on or off the PHY
@@ -61,6 +96,7 @@ void omap_control_phy_power(struct device *dev, int on)
61 val |= OMAP_CTRL_DEV_PHY_PD; 96 val |= OMAP_CTRL_DEV_PHY_PD;
62 break; 97 break;
63 98
99 case OMAP_CTRL_TYPE_PCIE:
64 case OMAP_CTRL_TYPE_PIPE3: 100 case OMAP_CTRL_TYPE_PIPE3:
65 rate = clk_get_rate(control_phy->sys_clk); 101 rate = clk_get_rate(control_phy->sys_clk);
66 rate = rate/1000000; 102 rate = rate/1000000;
@@ -211,6 +247,7 @@ EXPORT_SYMBOL_GPL(omap_control_usb_set_mode);
211static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS; 247static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS;
212static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2; 248static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2;
213static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; 249static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3;
250static const enum omap_control_phy_type pcie_data = OMAP_CTRL_TYPE_PCIE;
214static const enum omap_control_phy_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2; 251static const enum omap_control_phy_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2;
215static const enum omap_control_phy_type am437usb2_data = OMAP_CTRL_TYPE_AM437USB2; 252static const enum omap_control_phy_type am437usb2_data = OMAP_CTRL_TYPE_AM437USB2;
216 253
@@ -228,6 +265,10 @@ static const struct of_device_id omap_control_phy_id_table[] = {
228 .data = &pipe3_data, 265 .data = &pipe3_data,
229 }, 266 },
230 { 267 {
268 .compatible = "ti,control-phy-pcie",
269 .data = &pcie_data,
270 },
271 {
231 .compatible = "ti,control-phy-usb2-dra7", 272 .compatible = "ti,control-phy-usb2-dra7",
232 .data = &dra7usb2_data, 273 .data = &dra7usb2_data,
233 }, 274 },
@@ -279,7 +320,8 @@ static int omap_control_phy_probe(struct platform_device *pdev)
279 } 320 }
280 } 321 }
281 322
282 if (control_phy->type == OMAP_CTRL_TYPE_PIPE3) { 323 if (control_phy->type == OMAP_CTRL_TYPE_PIPE3 ||
324 control_phy->type == OMAP_CTRL_TYPE_PCIE) {
283 control_phy->sys_clk = devm_clk_get(control_phy->dev, 325 control_phy->sys_clk = devm_clk_get(control_phy->dev,
284 "sys_clkin"); 326 "sys_clkin");
285 if (IS_ERR(control_phy->sys_clk)) { 327 if (IS_ERR(control_phy->sys_clk)) {
@@ -288,6 +330,14 @@ static int omap_control_phy_probe(struct platform_device *pdev)
288 } 330 }
289 } 331 }
290 332
333 if (control_phy->type == OMAP_CTRL_TYPE_PCIE) {
334 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
335 "pcie_pcs");
336 control_phy->pcie_pcs = devm_ioremap_resource(&pdev->dev, res);
337 if (IS_ERR(control_phy->pcie_pcs))
338 return PTR_ERR(control_phy->pcie_pcs);
339 }
340
291 dev_set_drvdata(control_phy->dev, control_phy); 341 dev_set_drvdata(control_phy->dev, control_phy);
292 342
293 return 0; 343 return 0;
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
index 7007c11fe07d..93d78359246c 100644
--- a/drivers/phy/phy-omap-usb2.c
+++ b/drivers/phy/phy-omap-usb2.c
@@ -233,8 +233,8 @@ static int omap_usb2_probe(struct platform_device *pdev)
233 if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { 233 if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
234 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 234 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
235 phy->phy_base = devm_ioremap_resource(&pdev->dev, res); 235 phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
236 if (!phy->phy_base) 236 if (IS_ERR(phy->phy_base))
237 return -ENOMEM; 237 return PTR_ERR(phy->phy_base);
238 phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; 238 phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT;
239 } 239 }
240 240
@@ -262,18 +262,20 @@ static int omap_usb2_probe(struct platform_device *pdev)
262 otg->phy = &phy->phy; 262 otg->phy = &phy->phy;
263 263
264 platform_set_drvdata(pdev, phy); 264 platform_set_drvdata(pdev, phy);
265 pm_runtime_enable(phy->dev);
266 265
267 generic_phy = devm_phy_create(phy->dev, &ops, NULL); 266 generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL);
268 if (IS_ERR(generic_phy)) 267 if (IS_ERR(generic_phy))
269 return PTR_ERR(generic_phy); 268 return PTR_ERR(generic_phy);
270 269
271 phy_set_drvdata(generic_phy, phy); 270 phy_set_drvdata(generic_phy, phy);
272 271
272 pm_runtime_enable(phy->dev);
273 phy_provider = devm_of_phy_provider_register(phy->dev, 273 phy_provider = devm_of_phy_provider_register(phy->dev,
274 of_phy_simple_xlate); 274 of_phy_simple_xlate);
275 if (IS_ERR(phy_provider)) 275 if (IS_ERR(phy_provider)) {
276 pm_runtime_disable(phy->dev);
276 return PTR_ERR(phy_provider); 277 return PTR_ERR(phy_provider);
278 }
277 279
278 phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); 280 phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
279 if (IS_ERR(phy->wkupclk)) { 281 if (IS_ERR(phy->wkupclk)) {
@@ -317,6 +319,7 @@ static int omap_usb2_remove(struct platform_device *pdev)
317 if (!IS_ERR(phy->optclk)) 319 if (!IS_ERR(phy->optclk))
318 clk_unprepare(phy->optclk); 320 clk_unprepare(phy->optclk);
319 usb_remove_phy(&phy->phy); 321 usb_remove_phy(&phy->phy);
322 pm_runtime_disable(phy->dev);
320 323
321 return 0; 324 return 0;
322} 325}
diff --git a/drivers/phy/phy-qcom-apq8064-sata.c b/drivers/phy/phy-qcom-apq8064-sata.c
new file mode 100644
index 000000000000..b3ef7d805765
--- /dev/null
+++ b/drivers/phy/phy-qcom-apq8064-sata.c
@@ -0,0 +1,289 @@
1/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/io.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/time.h>
19#include <linux/delay.h>
20#include <linux/clk.h>
21#include <linux/slab.h>
22#include <linux/platform_device.h>
23#include <linux/phy/phy.h>
24
25/* PHY registers */
26#define UNIPHY_PLL_REFCLK_CFG 0x000
27#define UNIPHY_PLL_PWRGEN_CFG 0x014
28#define UNIPHY_PLL_GLB_CFG 0x020
29#define UNIPHY_PLL_SDM_CFG0 0x038
30#define UNIPHY_PLL_SDM_CFG1 0x03C
31#define UNIPHY_PLL_SDM_CFG2 0x040
32#define UNIPHY_PLL_SDM_CFG3 0x044
33#define UNIPHY_PLL_SDM_CFG4 0x048
34#define UNIPHY_PLL_SSC_CFG0 0x04C
35#define UNIPHY_PLL_SSC_CFG1 0x050
36#define UNIPHY_PLL_SSC_CFG2 0x054
37#define UNIPHY_PLL_SSC_CFG3 0x058
38#define UNIPHY_PLL_LKDET_CFG0 0x05C
39#define UNIPHY_PLL_LKDET_CFG1 0x060
40#define UNIPHY_PLL_LKDET_CFG2 0x064
41#define UNIPHY_PLL_CAL_CFG0 0x06C
42#define UNIPHY_PLL_CAL_CFG8 0x08C
43#define UNIPHY_PLL_CAL_CFG9 0x090
44#define UNIPHY_PLL_CAL_CFG10 0x094
45#define UNIPHY_PLL_CAL_CFG11 0x098
46#define UNIPHY_PLL_STATUS 0x0C0
47
48#define SATA_PHY_SER_CTRL 0x100
49#define SATA_PHY_TX_DRIV_CTRL0 0x104
50#define SATA_PHY_TX_DRIV_CTRL1 0x108
51#define SATA_PHY_TX_IMCAL0 0x11C
52#define SATA_PHY_TX_IMCAL2 0x124
53#define SATA_PHY_RX_IMCAL0 0x128
54#define SATA_PHY_EQUAL 0x13C
55#define SATA_PHY_OOB_TERM 0x144
56#define SATA_PHY_CDR_CTRL0 0x148
57#define SATA_PHY_CDR_CTRL1 0x14C
58#define SATA_PHY_CDR_CTRL2 0x150
59#define SATA_PHY_CDR_CTRL3 0x154
60#define SATA_PHY_PI_CTRL0 0x168
61#define SATA_PHY_POW_DWN_CTRL0 0x180
62#define SATA_PHY_POW_DWN_CTRL1 0x184
63#define SATA_PHY_TX_DATA_CTRL 0x188
64#define SATA_PHY_ALIGNP 0x1A4
65#define SATA_PHY_TX_IMCAL_STAT 0x1E4
66#define SATA_PHY_RX_IMCAL_STAT 0x1E8
67
68#define UNIPHY_PLL_LOCK BIT(0)
69#define SATA_PHY_TX_CAL BIT(0)
70#define SATA_PHY_RX_CAL BIT(0)
71
72/* default timeout set to 1 sec */
73#define TIMEOUT_MS 10000
74#define DELAY_INTERVAL_US 100
75
76struct qcom_apq8064_sata_phy {
77 void __iomem *mmio;
78 struct clk *cfg_clk;
79 struct device *dev;
80};
81
82/* Helper function to do poll and timeout */
83static int read_poll_timeout(void __iomem *addr, u32 mask)
84{
85 unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
86
87 do {
88 if (readl_relaxed(addr) & mask)
89 return 0;
90
91 usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
92 } while (!time_after(jiffies, timeout));
93
94 return (readl_relaxed(addr) & mask) ? 0 : -ETIMEDOUT;
95}
96
97static int qcom_apq8064_sata_phy_init(struct phy *generic_phy)
98{
99 struct qcom_apq8064_sata_phy *phy = phy_get_drvdata(generic_phy);
100 void __iomem *base = phy->mmio;
101 int ret = 0;
102
103 /* SATA phy initialization */
104 writel_relaxed(0x01, base + SATA_PHY_SER_CTRL);
105 writel_relaxed(0xB1, base + SATA_PHY_POW_DWN_CTRL0);
106 /* Make sure the power down happens before power up */
107 mb();
108 usleep_range(10, 60);
109
110 writel_relaxed(0x01, base + SATA_PHY_POW_DWN_CTRL0);
111 writel_relaxed(0x3E, base + SATA_PHY_POW_DWN_CTRL1);
112 writel_relaxed(0x01, base + SATA_PHY_RX_IMCAL0);
113 writel_relaxed(0x01, base + SATA_PHY_TX_IMCAL0);
114 writel_relaxed(0x02, base + SATA_PHY_TX_IMCAL2);
115
116 /* Write UNIPHYPLL registers to configure PLL */
117 writel_relaxed(0x04, base + UNIPHY_PLL_REFCLK_CFG);
118 writel_relaxed(0x00, base + UNIPHY_PLL_PWRGEN_CFG);
119
120 writel_relaxed(0x0A, base + UNIPHY_PLL_CAL_CFG0);
121 writel_relaxed(0xF3, base + UNIPHY_PLL_CAL_CFG8);
122 writel_relaxed(0x01, base + UNIPHY_PLL_CAL_CFG9);
123 writel_relaxed(0xED, base + UNIPHY_PLL_CAL_CFG10);
124 writel_relaxed(0x02, base + UNIPHY_PLL_CAL_CFG11);
125
126 writel_relaxed(0x36, base + UNIPHY_PLL_SDM_CFG0);
127 writel_relaxed(0x0D, base + UNIPHY_PLL_SDM_CFG1);
128 writel_relaxed(0xA3, base + UNIPHY_PLL_SDM_CFG2);
129 writel_relaxed(0xF0, base + UNIPHY_PLL_SDM_CFG3);
130 writel_relaxed(0x00, base + UNIPHY_PLL_SDM_CFG4);
131
132 writel_relaxed(0x19, base + UNIPHY_PLL_SSC_CFG0);
133 writel_relaxed(0xE1, base + UNIPHY_PLL_SSC_CFG1);
134 writel_relaxed(0x00, base + UNIPHY_PLL_SSC_CFG2);
135 writel_relaxed(0x11, base + UNIPHY_PLL_SSC_CFG3);
136
137 writel_relaxed(0x04, base + UNIPHY_PLL_LKDET_CFG0);
138 writel_relaxed(0xFF, base + UNIPHY_PLL_LKDET_CFG1);
139
140 writel_relaxed(0x02, base + UNIPHY_PLL_GLB_CFG);
141 /* make sure global config LDO power down happens before power up */
142 mb();
143
144 writel_relaxed(0x03, base + UNIPHY_PLL_GLB_CFG);
145 writel_relaxed(0x05, base + UNIPHY_PLL_LKDET_CFG2);
146
147 /* PLL Lock wait */
148 ret = read_poll_timeout(base + UNIPHY_PLL_STATUS, UNIPHY_PLL_LOCK);
149 if (ret) {
150 dev_err(phy->dev, "poll timeout UNIPHY_PLL_STATUS\n");
151 return ret;
152 }
153
154 /* TX Calibration */
155 ret = read_poll_timeout(base + SATA_PHY_TX_IMCAL_STAT, SATA_PHY_TX_CAL);
156 if (ret) {
157 dev_err(phy->dev, "poll timeout SATA_PHY_TX_IMCAL_STAT\n");
158 return ret;
159 }
160
161 /* RX Calibration */
162 ret = read_poll_timeout(base + SATA_PHY_RX_IMCAL_STAT, SATA_PHY_RX_CAL);
163 if (ret) {
164 dev_err(phy->dev, "poll timeout SATA_PHY_RX_IMCAL_STAT\n");
165 return ret;
166 }
167
168 /* SATA phy calibrated succesfully, power up to functional mode */
169 writel_relaxed(0x3E, base + SATA_PHY_POW_DWN_CTRL1);
170 writel_relaxed(0x01, base + SATA_PHY_RX_IMCAL0);
171 writel_relaxed(0x01, base + SATA_PHY_TX_IMCAL0);
172
173 writel_relaxed(0x00, base + SATA_PHY_POW_DWN_CTRL1);
174 writel_relaxed(0x59, base + SATA_PHY_CDR_CTRL0);
175 writel_relaxed(0x04, base + SATA_PHY_CDR_CTRL1);
176 writel_relaxed(0x00, base + SATA_PHY_CDR_CTRL2);
177 writel_relaxed(0x00, base + SATA_PHY_PI_CTRL0);
178 writel_relaxed(0x00, base + SATA_PHY_CDR_CTRL3);
179 writel_relaxed(0x01, base + SATA_PHY_POW_DWN_CTRL0);
180
181 writel_relaxed(0x11, base + SATA_PHY_TX_DATA_CTRL);
182 writel_relaxed(0x43, base + SATA_PHY_ALIGNP);
183 writel_relaxed(0x04, base + SATA_PHY_OOB_TERM);
184
185 writel_relaxed(0x01, base + SATA_PHY_EQUAL);
186 writel_relaxed(0x09, base + SATA_PHY_TX_DRIV_CTRL0);
187 writel_relaxed(0x09, base + SATA_PHY_TX_DRIV_CTRL1);
188
189 return 0;
190}
191
192static int qcom_apq8064_sata_phy_exit(struct phy *generic_phy)
193{
194 struct qcom_apq8064_sata_phy *phy = phy_get_drvdata(generic_phy);
195 void __iomem *base = phy->mmio;
196
197 /* Power down PHY */
198 writel_relaxed(0xF8, base + SATA_PHY_POW_DWN_CTRL0);
199 writel_relaxed(0xFE, base + SATA_PHY_POW_DWN_CTRL1);
200
201 /* Power down PLL block */
202 writel_relaxed(0x00, base + UNIPHY_PLL_GLB_CFG);
203
204 return 0;
205}
206
207static struct phy_ops qcom_apq8064_sata_phy_ops = {
208 .init = qcom_apq8064_sata_phy_init,
209 .exit = qcom_apq8064_sata_phy_exit,
210 .owner = THIS_MODULE,
211};
212
213static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev)
214{
215 struct qcom_apq8064_sata_phy *phy;
216 struct device *dev = &pdev->dev;
217 struct resource *res;
218 struct phy_provider *phy_provider;
219 struct phy *generic_phy;
220 int ret;
221
222 phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
223 if (!phy)
224 return -ENOMEM;
225
226 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
227 phy->mmio = devm_ioremap_resource(dev, res);
228 if (IS_ERR(phy->mmio))
229 return PTR_ERR(phy->mmio);
230
231 generic_phy = devm_phy_create(dev, NULL, &qcom_apq8064_sata_phy_ops,
232 NULL);
233 if (IS_ERR(generic_phy)) {
234 dev_err(dev, "%s: failed to create phy\n", __func__);
235 return PTR_ERR(generic_phy);
236 }
237
238 phy->dev = dev;
239 phy_set_drvdata(generic_phy, phy);
240 platform_set_drvdata(pdev, phy);
241
242 phy->cfg_clk = devm_clk_get(dev, "cfg");
243 if (IS_ERR(phy->cfg_clk)) {
244 dev_err(dev, "Failed to get sata cfg clock\n");
245 return PTR_ERR(phy->cfg_clk);
246 }
247
248 ret = clk_prepare_enable(phy->cfg_clk);
249 if (ret)
250 return ret;
251
252 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
253 if (IS_ERR(phy_provider)) {
254 clk_disable_unprepare(phy->cfg_clk);
255 dev_err(dev, "%s: failed to register phy\n", __func__);
256 return PTR_ERR(phy_provider);
257 }
258
259 return 0;
260}
261
262static int qcom_apq8064_sata_phy_remove(struct platform_device *pdev)
263{
264 struct qcom_apq8064_sata_phy *phy = platform_get_drvdata(pdev);
265
266 clk_disable_unprepare(phy->cfg_clk);
267
268 return 0;
269}
270
271static const struct of_device_id qcom_apq8064_sata_phy_of_match[] = {
272 { .compatible = "qcom,apq8064-sata-phy" },
273 { },
274};
275MODULE_DEVICE_TABLE(of, qcom_apq8064_sata_phy_of_match);
276
277static struct platform_driver qcom_apq8064_sata_phy_driver = {
278 .probe = qcom_apq8064_sata_phy_probe,
279 .remove = qcom_apq8064_sata_phy_remove,
280 .driver = {
281 .name = "qcom-apq8064-sata-phy",
282 .owner = THIS_MODULE,
283 .of_match_table = qcom_apq8064_sata_phy_of_match,
284 }
285};
286module_platform_driver(qcom_apq8064_sata_phy_driver);
287
288MODULE_DESCRIPTION("QCOM apq8064 SATA PHY driver");
289MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-qcom-ipq806x-sata.c b/drivers/phy/phy-qcom-ipq806x-sata.c
new file mode 100644
index 000000000000..909b5a87fc6a
--- /dev/null
+++ b/drivers/phy/phy-qcom-ipq806x-sata.c
@@ -0,0 +1,211 @@
1/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/io.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/time.h>
20#include <linux/delay.h>
21#include <linux/clk.h>
22#include <linux/slab.h>
23#include <linux/platform_device.h>
24#include <linux/phy/phy.h>
25
26struct qcom_ipq806x_sata_phy {
27 void __iomem *mmio;
28 struct clk *cfg_clk;
29 struct device *dev;
30};
31
32#define __set(v, a, b) (((v) << (b)) & GENMASK(a, b))
33
34#define SATA_PHY_P0_PARAM0 0x200
35#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(x) __set(x, 17, 12)
36#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK GENMASK(17, 12)
37#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2(x) __set(x, 11, 6)
38#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK GENMASK(11, 6)
39#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1(x) __set(x, 5, 0)
40#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK GENMASK(5, 0)
41
42#define SATA_PHY_P0_PARAM1 0x204
43#define SATA_PHY_P0_PARAM1_RESERVED_BITS31_21(x) __set(x, 31, 21)
44#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(x) __set(x, 20, 14)
45#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK GENMASK(20, 14)
46#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(x) __set(x, 13, 7)
47#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK GENMASK(13, 7)
48#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(x) __set(x, 6, 0)
49#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK GENMASK(6, 0)
50
51#define SATA_PHY_P0_PARAM2 0x208
52#define SATA_PHY_P0_PARAM2_RX_EQ(x) __set(x, 20, 18)
53#define SATA_PHY_P0_PARAM2_RX_EQ_MASK GENMASK(20, 18)
54
55#define SATA_PHY_P0_PARAM3 0x20C
56#define SATA_PHY_SSC_EN 0x8
57#define SATA_PHY_P0_PARAM4 0x210
58#define SATA_PHY_REF_SSP_EN 0x2
59#define SATA_PHY_RESET 0x1
60
61static int qcom_ipq806x_sata_phy_init(struct phy *generic_phy)
62{
63 struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
64 u32 reg;
65
66 /* Setting SSC_EN to 1 */
67 reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM3);
68 reg = reg | SATA_PHY_SSC_EN;
69 writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM3);
70
71 reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM0) &
72 ~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK |
73 SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK |
74 SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK);
75 reg |= SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(0xf);
76 writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM0);
77
78 reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM1) &
79 ~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK |
80 SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK |
81 SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK);
82 reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) |
83 SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) |
84 SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55);
85 writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM1);
86
87 reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM2) &
88 ~SATA_PHY_P0_PARAM2_RX_EQ_MASK;
89 reg |= SATA_PHY_P0_PARAM2_RX_EQ(0x3);
90 writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM2);
91
92 /* Setting PHY_RESET to 1 */
93 reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
94 reg = reg | SATA_PHY_RESET;
95 writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
96
97 /* Setting REF_SSP_EN to 1 */
98 reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
99 reg = reg | SATA_PHY_REF_SSP_EN | SATA_PHY_RESET;
100 writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
101
102 /* make sure all changes complete before we let the PHY out of reset */
103 mb();
104
105 /* sleep for max. 50us more to combine processor wakeups */
106 usleep_range(20, 20 + 50);
107
108 /* Clearing PHY_RESET to 0 */
109 reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
110 reg = reg & ~SATA_PHY_RESET;
111 writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
112
113 return 0;
114}
115
116static int qcom_ipq806x_sata_phy_exit(struct phy *generic_phy)
117{
118 struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
119 u32 reg;
120
121 /* Setting PHY_RESET to 1 */
122 reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
123 reg = reg | SATA_PHY_RESET;
124 writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
125
126 return 0;
127}
128
129static struct phy_ops qcom_ipq806x_sata_phy_ops = {
130 .init = qcom_ipq806x_sata_phy_init,
131 .exit = qcom_ipq806x_sata_phy_exit,
132 .owner = THIS_MODULE,
133};
134
135static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
136{
137 struct qcom_ipq806x_sata_phy *phy;
138 struct device *dev = &pdev->dev;
139 struct resource *res;
140 struct phy_provider *phy_provider;
141 struct phy *generic_phy;
142 int ret;
143
144 phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
145 if (!phy)
146 return -ENOMEM;
147
148 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
149 phy->mmio = devm_ioremap_resource(dev, res);
150 if (IS_ERR(phy->mmio))
151 return PTR_ERR(phy->mmio);
152
153 generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops,
154 NULL);
155 if (IS_ERR(generic_phy)) {
156 dev_err(dev, "%s: failed to create phy\n", __func__);
157 return PTR_ERR(generic_phy);
158 }
159
160 phy->dev = dev;
161 phy_set_drvdata(generic_phy, phy);
162 platform_set_drvdata(pdev, phy);
163
164 phy->cfg_clk = devm_clk_get(dev, "cfg");
165 if (IS_ERR(phy->cfg_clk)) {
166 dev_err(dev, "Failed to get sata cfg clock\n");
167 return PTR_ERR(phy->cfg_clk);
168 }
169
170 ret = clk_prepare_enable(phy->cfg_clk);
171 if (ret)
172 return ret;
173
174 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
175 if (IS_ERR(phy_provider)) {
176 clk_disable_unprepare(phy->cfg_clk);
177 dev_err(dev, "%s: failed to register phy\n", __func__);
178 return PTR_ERR(phy_provider);
179 }
180
181 return 0;
182}
183
184static int qcom_ipq806x_sata_phy_remove(struct platform_device *pdev)
185{
186 struct qcom_ipq806x_sata_phy *phy = platform_get_drvdata(pdev);
187
188 clk_disable_unprepare(phy->cfg_clk);
189
190 return 0;
191}
192
193static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = {
194 { .compatible = "qcom,ipq806x-sata-phy" },
195 { },
196};
197MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match);
198
199static struct platform_driver qcom_ipq806x_sata_phy_driver = {
200 .probe = qcom_ipq806x_sata_phy_probe,
201 .remove = qcom_ipq806x_sata_phy_remove,
202 .driver = {
203 .name = "qcom-ipq806x-sata-phy",
204 .owner = THIS_MODULE,
205 .of_match_table = qcom_ipq806x_sata_phy_of_match,
206 }
207};
208module_platform_driver(qcom_ipq806x_sata_phy_driver);
209
210MODULE_DESCRIPTION("QCOM IPQ806x SATA PHY driver");
211MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-s5pv210-usb2.c b/drivers/phy/phy-s5pv210-usb2.c
new file mode 100644
index 000000000000..004d320767e4
--- /dev/null
+++ b/drivers/phy/phy-s5pv210-usb2.c
@@ -0,0 +1,187 @@
1/*
2 * Samsung SoC USB 1.1/2.0 PHY driver - S5PV210 support
3 *
4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5 * Authors: Kamil Debski <k.debski@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/delay.h>
13#include <linux/io.h>
14#include <linux/phy/phy.h>
15#include "phy-samsung-usb2.h"
16
17/* Exynos USB PHY registers */
18
19/* PHY power control */
20#define S5PV210_UPHYPWR 0x0
21
22#define S5PV210_UPHYPWR_PHY0_SUSPEND BIT(0)
23#define S5PV210_UPHYPWR_PHY0_PWR BIT(3)
24#define S5PV210_UPHYPWR_PHY0_OTG_PWR BIT(4)
25#define S5PV210_UPHYPWR_PHY0 ( \
26 S5PV210_UPHYPWR_PHY0_SUSPEND | \
27 S5PV210_UPHYPWR_PHY0_PWR | \
28 S5PV210_UPHYPWR_PHY0_OTG_PWR)
29
30#define S5PV210_UPHYPWR_PHY1_SUSPEND BIT(6)
31#define S5PV210_UPHYPWR_PHY1_PWR BIT(7)
32#define S5PV210_UPHYPWR_PHY1 ( \
33 S5PV210_UPHYPWR_PHY1_SUSPEND | \
34 S5PV210_UPHYPWR_PHY1_PWR)
35
36/* PHY clock control */
37#define S5PV210_UPHYCLK 0x4
38
39#define S5PV210_UPHYCLK_PHYFSEL_MASK (0x3 << 0)
40#define S5PV210_UPHYCLK_PHYFSEL_48MHZ (0x0 << 0)
41#define S5PV210_UPHYCLK_PHYFSEL_24MHZ (0x3 << 0)
42#define S5PV210_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0)
43
44#define S5PV210_UPHYCLK_PHY0_ID_PULLUP BIT(2)
45#define S5PV210_UPHYCLK_PHY0_COMMON_ON BIT(4)
46#define S5PV210_UPHYCLK_PHY1_COMMON_ON BIT(7)
47
48/* PHY reset control */
49#define S5PV210_UPHYRST 0x8
50
51#define S5PV210_URSTCON_PHY0 BIT(0)
52#define S5PV210_URSTCON_OTG_HLINK BIT(1)
53#define S5PV210_URSTCON_OTG_PHYLINK BIT(2)
54#define S5PV210_URSTCON_PHY1_ALL BIT(3)
55#define S5PV210_URSTCON_HOST_LINK_ALL BIT(4)
56
57/* Isolation, configured in the power management unit */
58#define S5PV210_USB_ISOL_OFFSET 0x680c
59#define S5PV210_USB_ISOL_DEVICE BIT(0)
60#define S5PV210_USB_ISOL_HOST BIT(1)
61
62
63enum s5pv210_phy_id {
64 S5PV210_DEVICE,
65 S5PV210_HOST,
66 S5PV210_NUM_PHYS,
67};
68
69/*
70 * s5pv210_rate_to_clk() converts the supplied clock rate to the value that
71 * can be written to the phy register.
72 */
73static int s5pv210_rate_to_clk(unsigned long rate, u32 *reg)
74{
75 switch (rate) {
76 case 12 * MHZ:
77 *reg = S5PV210_UPHYCLK_PHYFSEL_12MHZ;
78 break;
79 case 24 * MHZ:
80 *reg = S5PV210_UPHYCLK_PHYFSEL_24MHZ;
81 break;
82 case 48 * MHZ:
83 *reg = S5PV210_UPHYCLK_PHYFSEL_48MHZ;
84 break;
85 default:
86 return -EINVAL;
87 }
88
89 return 0;
90}
91
92static void s5pv210_isol(struct samsung_usb2_phy_instance *inst, bool on)
93{
94 struct samsung_usb2_phy_driver *drv = inst->drv;
95 u32 mask;
96
97 switch (inst->cfg->id) {
98 case S5PV210_DEVICE:
99 mask = S5PV210_USB_ISOL_DEVICE;
100 break;
101 case S5PV210_HOST:
102 mask = S5PV210_USB_ISOL_HOST;
103 break;
104 default:
105 return;
106 };
107
108 regmap_update_bits(drv->reg_pmu, S5PV210_USB_ISOL_OFFSET,
109 mask, on ? 0 : mask);
110}
111
112static void s5pv210_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
113{
114 struct samsung_usb2_phy_driver *drv = inst->drv;
115 u32 rstbits = 0;
116 u32 phypwr = 0;
117 u32 rst;
118 u32 pwr;
119
120 switch (inst->cfg->id) {
121 case S5PV210_DEVICE:
122 phypwr = S5PV210_UPHYPWR_PHY0;
123 rstbits = S5PV210_URSTCON_PHY0;
124 break;
125 case S5PV210_HOST:
126 phypwr = S5PV210_UPHYPWR_PHY1;
127 rstbits = S5PV210_URSTCON_PHY1_ALL |
128 S5PV210_URSTCON_HOST_LINK_ALL;
129 break;
130 };
131
132 if (on) {
133 writel(drv->ref_reg_val, drv->reg_phy + S5PV210_UPHYCLK);
134
135 pwr = readl(drv->reg_phy + S5PV210_UPHYPWR);
136 pwr &= ~phypwr;
137 writel(pwr, drv->reg_phy + S5PV210_UPHYPWR);
138
139 rst = readl(drv->reg_phy + S5PV210_UPHYRST);
140 rst |= rstbits;
141 writel(rst, drv->reg_phy + S5PV210_UPHYRST);
142 udelay(10);
143 rst &= ~rstbits;
144 writel(rst, drv->reg_phy + S5PV210_UPHYRST);
145 } else {
146 pwr = readl(drv->reg_phy + S5PV210_UPHYPWR);
147 pwr |= phypwr;
148 writel(pwr, drv->reg_phy + S5PV210_UPHYPWR);
149 }
150}
151
152static int s5pv210_power_on(struct samsung_usb2_phy_instance *inst)
153{
154 s5pv210_isol(inst, 0);
155 s5pv210_phy_pwr(inst, 1);
156
157 return 0;
158}
159
160static int s5pv210_power_off(struct samsung_usb2_phy_instance *inst)
161{
162 s5pv210_phy_pwr(inst, 0);
163 s5pv210_isol(inst, 1);
164
165 return 0;
166}
167
168static const struct samsung_usb2_common_phy s5pv210_phys[S5PV210_NUM_PHYS] = {
169 [S5PV210_DEVICE] = {
170 .label = "device",
171 .id = S5PV210_DEVICE,
172 .power_on = s5pv210_power_on,
173 .power_off = s5pv210_power_off,
174 },
175 [S5PV210_HOST] = {
176 .label = "host",
177 .id = S5PV210_HOST,
178 .power_on = s5pv210_power_on,
179 .power_off = s5pv210_power_off,
180 },
181};
182
183const struct samsung_usb2_phy_config s5pv210_usb2_phy_config = {
184 .num_phys = ARRAY_SIZE(s5pv210_phys),
185 .phys = s5pv210_phys,
186 .rate_to_clk = s5pv210_rate_to_clk,
187};
diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c
index 8a8c6bc8709a..3732ca25e09f 100644
--- a/drivers/phy/phy-samsung-usb2.c
+++ b/drivers/phy/phy-samsung-usb2.c
@@ -87,6 +87,12 @@ static struct phy *samsung_usb2_phy_xlate(struct device *dev,
87} 87}
88 88
89static const struct of_device_id samsung_usb2_phy_of_match[] = { 89static const struct of_device_id samsung_usb2_phy_of_match[] = {
90#ifdef CONFIG_PHY_EXYNOS4X12_USB2
91 {
92 .compatible = "samsung,exynos3250-usb2-phy",
93 .data = &exynos3250_usb2_phy_config,
94 },
95#endif
90#ifdef CONFIG_PHY_EXYNOS4210_USB2 96#ifdef CONFIG_PHY_EXYNOS4210_USB2
91 { 97 {
92 .compatible = "samsung,exynos4210-usb2-phy", 98 .compatible = "samsung,exynos4210-usb2-phy",
@@ -105,8 +111,15 @@ static const struct of_device_id samsung_usb2_phy_of_match[] = {
105 .data = &exynos5250_usb2_phy_config, 111 .data = &exynos5250_usb2_phy_config,
106 }, 112 },
107#endif 113#endif
114#ifdef CONFIG_PHY_S5PV210_USB2
115 {
116 .compatible = "samsung,s5pv210-usb2-phy",
117 .data = &s5pv210_usb2_phy_config,
118 },
119#endif
108 { }, 120 { },
109}; 121};
122MODULE_DEVICE_TABLE(of, samsung_usb2_phy_of_match);
110 123
111static int samsung_usb2_phy_probe(struct platform_device *pdev) 124static int samsung_usb2_phy_probe(struct platform_device *pdev)
112{ 125{
@@ -189,7 +202,8 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
189 struct samsung_usb2_phy_instance *p = &drv->instances[i]; 202 struct samsung_usb2_phy_instance *p = &drv->instances[i];
190 203
191 dev_dbg(dev, "Creating phy \"%s\"\n", label); 204 dev_dbg(dev, "Creating phy \"%s\"\n", label);
192 p->phy = devm_phy_create(dev, &samsung_usb2_phy_ops, NULL); 205 p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops,
206 NULL);
193 if (IS_ERR(p->phy)) { 207 if (IS_ERR(p->phy)) {
194 dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n", 208 dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n",
195 label); 209 label);
diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/phy-samsung-usb2.h
index 45b3170652bd..44bead9b8f34 100644
--- a/drivers/phy/phy-samsung-usb2.h
+++ b/drivers/phy/phy-samsung-usb2.h
@@ -29,7 +29,8 @@ struct samsung_usb2_phy_instance {
29 const struct samsung_usb2_common_phy *cfg; 29 const struct samsung_usb2_common_phy *cfg;
30 struct phy *phy; 30 struct phy *phy;
31 struct samsung_usb2_phy_driver *drv; 31 struct samsung_usb2_phy_driver *drv;
32 bool enabled; 32 int int_cnt;
33 int ext_cnt;
33}; 34};
34 35
35struct samsung_usb2_phy_driver { 36struct samsung_usb2_phy_driver {
@@ -59,9 +60,12 @@ struct samsung_usb2_phy_config {
59 int (*rate_to_clk)(unsigned long, u32 *); 60 int (*rate_to_clk)(unsigned long, u32 *);
60 unsigned int num_phys; 61 unsigned int num_phys;
61 bool has_mode_switch; 62 bool has_mode_switch;
63 bool has_refclk_sel;
62}; 64};
63 65
66extern const struct samsung_usb2_phy_config exynos3250_usb2_phy_config;
64extern const struct samsung_usb2_phy_config exynos4210_usb2_phy_config; 67extern const struct samsung_usb2_phy_config exynos4210_usb2_phy_config;
65extern const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config; 68extern const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config;
66extern const struct samsung_usb2_phy_config exynos5250_usb2_phy_config; 69extern const struct samsung_usb2_phy_config exynos5250_usb2_phy_config;
70extern const struct samsung_usb2_phy_config s5pv210_usb2_phy_config;
67#endif 71#endif
diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c
index c58c869d57e0..6dcbfcddb372 100644
--- a/drivers/phy/phy-spear1310-miphy.c
+++ b/drivers/phy/phy-spear1310-miphy.c
@@ -229,7 +229,7 @@ static int spear1310_miphy_probe(struct platform_device *pdev)
229 return -EINVAL; 229 return -EINVAL;
230 } 230 }
231 231
232 priv->phy = devm_phy_create(dev, &spear1310_miphy_ops, NULL); 232 priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops, NULL);
233 if (IS_ERR(priv->phy)) { 233 if (IS_ERR(priv->phy)) {
234 dev_err(dev, "failed to create SATA PCIe PHY\n"); 234 dev_err(dev, "failed to create SATA PCIe PHY\n");
235 return PTR_ERR(priv->phy); 235 return PTR_ERR(priv->phy);
diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c
index 8de98adf21c3..7135ba2603b6 100644
--- a/drivers/phy/phy-spear1340-miphy.c
+++ b/drivers/phy/phy-spear1340-miphy.c
@@ -261,7 +261,7 @@ static int spear1340_miphy_probe(struct platform_device *pdev)
261 return PTR_ERR(priv->misc); 261 return PTR_ERR(priv->misc);
262 } 262 }
263 263
264 priv->phy = devm_phy_create(dev, &spear1340_miphy_ops, NULL); 264 priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops, NULL);
265 if (IS_ERR(priv->phy)) { 265 if (IS_ERR(priv->phy)) {
266 dev_err(dev, "failed to create SATA PCIe PHY\n"); 266 dev_err(dev, "failed to create SATA PCIe PHY\n");
267 return PTR_ERR(priv->phy); 267 return PTR_ERR(priv->phy);
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 115d8d5190d5..61ebea49709b 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/err.h>
25#include <linux/io.h> 26#include <linux/io.h>
26#include <linux/kernel.h> 27#include <linux/kernel.h>
27#include <linux/module.h> 28#include <linux/module.h>
@@ -294,7 +295,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
294 return PTR_ERR(phy->pmu); 295 return PTR_ERR(phy->pmu);
295 } 296 }
296 297
297 phy->phy = devm_phy_create(dev, &sun4i_usb_phy_ops, NULL); 298 phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops, NULL);
298 if (IS_ERR(phy->phy)) { 299 if (IS_ERR(phy->phy)) {
299 dev_err(dev, "failed to create PHY %d\n", i); 300 dev_err(dev, "failed to create PHY %d\n", i);
300 return PTR_ERR(phy->phy); 301 return PTR_ERR(phy->phy);
@@ -306,10 +307,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
306 307
307 dev_set_drvdata(dev, data); 308 dev_set_drvdata(dev, data);
308 phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate); 309 phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate);
309 if (IS_ERR(phy_provider))
310 return PTR_ERR(phy_provider);
311 310
312 return 0; 311 return PTR_ERR_OR_ZERO(phy_provider);
313} 312}
314 313
315static const struct of_device_id sun4i_usb_phy_of_match[] = { 314static const struct of_device_id sun4i_usb_phy_of_match[] = {
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c
index 591367654613..b964aa967b46 100644
--- a/drivers/phy/phy-ti-pipe3.c
+++ b/drivers/phy/phy-ti-pipe3.c
@@ -80,7 +80,9 @@ struct ti_pipe3 {
80 struct clk *wkupclk; 80 struct clk *wkupclk;
81 struct clk *sys_clk; 81 struct clk *sys_clk;
82 struct clk *refclk; 82 struct clk *refclk;
83 struct clk *div_clk;
83 struct pipe3_dpll_map *dpll_map; 84 struct pipe3_dpll_map *dpll_map;
85 u8 id;
84}; 86};
85 87
86static struct pipe3_dpll_map dpll_map_usb[] = { 88static struct pipe3_dpll_map dpll_map_usb[] = {
@@ -215,6 +217,11 @@ static int ti_pipe3_init(struct phy *x)
215 u32 val; 217 u32 val;
216 int ret = 0; 218 int ret = 0;
217 219
220 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) {
221 omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1);
222 return 0;
223 }
224
218 /* Bring it out of IDLE if it is IDLE */ 225 /* Bring it out of IDLE if it is IDLE */
219 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); 226 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
220 if (val & PLL_IDLE) { 227 if (val & PLL_IDLE) {
@@ -238,8 +245,11 @@ static int ti_pipe3_exit(struct phy *x)
238 u32 val; 245 u32 val;
239 unsigned long timeout; 246 unsigned long timeout;
240 247
241 /* SATA DPLL can't be powered down due to Errata i783 */ 248 /* SATA DPLL can't be powered down due to Errata i783 and PCIe
242 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata")) 249 * does not have internal DPLL
250 */
251 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") ||
252 of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie"))
243 return 0; 253 return 0;
244 254
245 /* Put DPLL in IDLE mode */ 255 /* Put DPLL in IDLE mode */
@@ -286,32 +296,41 @@ static int ti_pipe3_probe(struct platform_device *pdev)
286 struct device_node *control_node; 296 struct device_node *control_node;
287 struct platform_device *control_pdev; 297 struct platform_device *control_pdev;
288 const struct of_device_id *match; 298 const struct of_device_id *match;
289 299 struct clk *clk;
290 match = of_match_device(of_match_ptr(ti_pipe3_id_table), &pdev->dev);
291 if (!match)
292 return -EINVAL;
293 300
294 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); 301 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
295 if (!phy) { 302 if (!phy) {
296 dev_err(&pdev->dev, "unable to alloc mem for TI PIPE3 PHY\n"); 303 dev_err(&pdev->dev, "unable to alloc mem for TI PIPE3 PHY\n");
297 return -ENOMEM; 304 return -ENOMEM;
298 } 305 }
306 phy->dev = &pdev->dev;
299 307
300 phy->dpll_map = (struct pipe3_dpll_map *)match->data; 308 if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
301 if (!phy->dpll_map) { 309 match = of_match_device(of_match_ptr(ti_pipe3_id_table),
302 dev_err(&pdev->dev, "no DPLL data\n"); 310 &pdev->dev);
303 return -EINVAL; 311 if (!match)
304 } 312 return -EINVAL;
305 313
306 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); 314 phy->dpll_map = (struct pipe3_dpll_map *)match->data;
307 phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); 315 if (!phy->dpll_map) {
308 if (IS_ERR(phy->pll_ctrl_base)) 316 dev_err(&pdev->dev, "no DPLL data\n");
309 return PTR_ERR(phy->pll_ctrl_base); 317 return -EINVAL;
318 }
310 319
311 phy->dev = &pdev->dev; 320 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
321 "pll_ctrl");
322 phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
323 if (IS_ERR(phy->pll_ctrl_base))
324 return PTR_ERR(phy->pll_ctrl_base);
312 325
313 if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { 326 phy->sys_clk = devm_clk_get(phy->dev, "sysclk");
327 if (IS_ERR(phy->sys_clk)) {
328 dev_err(&pdev->dev, "unable to get sysclk\n");
329 return -EINVAL;
330 }
331 }
314 332
333 if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) {
315 phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); 334 phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
316 if (IS_ERR(phy->wkupclk)) { 335 if (IS_ERR(phy->wkupclk)) {
317 dev_err(&pdev->dev, "unable to get wkupclk\n"); 336 dev_err(&pdev->dev, "unable to get wkupclk\n");
@@ -328,10 +347,38 @@ static int ti_pipe3_probe(struct platform_device *pdev)
328 phy->refclk = ERR_PTR(-ENODEV); 347 phy->refclk = ERR_PTR(-ENODEV);
329 } 348 }
330 349
331 phy->sys_clk = devm_clk_get(phy->dev, "sysclk"); 350 if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
332 if (IS_ERR(phy->sys_clk)) { 351 if (of_property_read_u8(node, "id", &phy->id) < 0)
333 dev_err(&pdev->dev, "unable to get sysclk\n"); 352 phy->id = 1;
334 return -EINVAL; 353
354 clk = devm_clk_get(phy->dev, "dpll_ref");
355 if (IS_ERR(clk)) {
356 dev_err(&pdev->dev, "unable to get dpll ref clk\n");
357 return PTR_ERR(clk);
358 }
359 clk_set_rate(clk, 1500000000);
360
361 clk = devm_clk_get(phy->dev, "dpll_ref_m2");
362 if (IS_ERR(clk)) {
363 dev_err(&pdev->dev, "unable to get dpll ref m2 clk\n");
364 return PTR_ERR(clk);
365 }
366 clk_set_rate(clk, 100000000);
367
368 clk = devm_clk_get(phy->dev, "phy-div");
369 if (IS_ERR(clk)) {
370 dev_err(&pdev->dev, "unable to get phy-div clk\n");
371 return PTR_ERR(clk);
372 }
373 clk_set_rate(clk, 100000000);
374
375 phy->div_clk = devm_clk_get(phy->dev, "div-clk");
376 if (IS_ERR(phy->div_clk)) {
377 dev_err(&pdev->dev, "unable to get div-clk\n");
378 return PTR_ERR(phy->div_clk);
379 }
380 } else {
381 phy->div_clk = ERR_PTR(-ENODEV);
335 } 382 }
336 383
337 control_node = of_parse_phandle(node, "ctrl-module", 0); 384 control_node = of_parse_phandle(node, "ctrl-module", 0);
@@ -353,7 +400,7 @@ static int ti_pipe3_probe(struct platform_device *pdev)
353 platform_set_drvdata(pdev, phy); 400 platform_set_drvdata(pdev, phy);
354 pm_runtime_enable(phy->dev); 401 pm_runtime_enable(phy->dev);
355 402
356 generic_phy = devm_phy_create(phy->dev, &ops, NULL); 403 generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL);
357 if (IS_ERR(generic_phy)) 404 if (IS_ERR(generic_phy))
358 return PTR_ERR(generic_phy); 405 return PTR_ERR(generic_phy);
359 406
@@ -387,6 +434,8 @@ static int ti_pipe3_runtime_suspend(struct device *dev)
387 clk_disable_unprepare(phy->wkupclk); 434 clk_disable_unprepare(phy->wkupclk);
388 if (!IS_ERR(phy->refclk)) 435 if (!IS_ERR(phy->refclk))
389 clk_disable_unprepare(phy->refclk); 436 clk_disable_unprepare(phy->refclk);
437 if (!IS_ERR(phy->div_clk))
438 clk_disable_unprepare(phy->div_clk);
390 439
391 return 0; 440 return 0;
392} 441}
@@ -412,8 +461,19 @@ static int ti_pipe3_runtime_resume(struct device *dev)
412 } 461 }
413 } 462 }
414 463
464 if (!IS_ERR(phy->div_clk)) {
465 ret = clk_prepare_enable(phy->div_clk);
466 if (ret) {
467 dev_err(phy->dev, "Failed to enable div_clk %d\n", ret);
468 goto err3;
469 }
470 }
415 return 0; 471 return 0;
416 472
473err3:
474 if (!IS_ERR(phy->wkupclk))
475 clk_disable_unprepare(phy->wkupclk);
476
417err2: 477err2:
418 if (!IS_ERR(phy->refclk)) 478 if (!IS_ERR(phy->refclk))
419 clk_disable_unprepare(phy->refclk); 479 clk_disable_unprepare(phy->refclk);
@@ -446,6 +506,9 @@ static const struct of_device_id ti_pipe3_id_table[] = {
446 .compatible = "ti,phy-pipe3-sata", 506 .compatible = "ti,phy-pipe3-sata",
447 .data = dpll_map_sata, 507 .data = dpll_map_sata,
448 }, 508 },
509 {
510 .compatible = "ti,phy-pipe3-pcie",
511 },
449 {} 512 {}
450}; 513};
451MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); 514MODULE_DEVICE_TABLE(of, ti_pipe3_id_table);
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 2e0e9b3774c8..e1a6623d4696 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -695,7 +695,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
695 otg->set_host = twl4030_set_host; 695 otg->set_host = twl4030_set_host;
696 otg->set_peripheral = twl4030_set_peripheral; 696 otg->set_peripheral = twl4030_set_peripheral;
697 697
698 phy = devm_phy_create(twl->dev, &ops, init_data); 698 phy = devm_phy_create(twl->dev, NULL, &ops, init_data);
699 if (IS_ERR(phy)) { 699 if (IS_ERR(phy)) {
700 dev_dbg(&pdev->dev, "Failed to create PHY\n"); 700 dev_dbg(&pdev->dev, "Failed to create PHY\n");
701 return PTR_ERR(phy); 701 return PTR_ERR(phy);
diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c
index 4aa1ccd1511f..db809b97219e 100644
--- a/drivers/phy/phy-xgene.c
+++ b/drivers/phy/phy-xgene.c
@@ -1707,7 +1707,7 @@ static int xgene_phy_probe(struct platform_device *pdev)
1707 ctx->dev = &pdev->dev; 1707 ctx->dev = &pdev->dev;
1708 platform_set_drvdata(pdev, ctx); 1708 platform_set_drvdata(pdev, ctx);
1709 1709
1710 ctx->phy = devm_phy_create(ctx->dev, &xgene_phy_ops, NULL); 1710 ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops, NULL);
1711 if (IS_ERR(ctx->phy)) { 1711 if (IS_ERR(ctx->phy)) {
1712 dev_dbg(&pdev->dev, "Failed to create PHY\n"); 1712 dev_dbg(&pdev->dev, "Failed to create PHY\n");
1713 rc = PTR_ERR(ctx->phy); 1713 rc = PTR_ERR(ctx->phy);