aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/phy/ti-phy.txt12
-rw-r--r--drivers/phy/phy-omap-control.c52
-rw-r--r--drivers/phy/phy-ti-pipe3.c4
-rw-r--r--include/linux/phy/omap_control_phy.h10
4 files changed, 71 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt
index b50e1c10a05d..305e3df3d9b1 100644
--- a/Documentation/devicetree/bindings/phy/ti-phy.txt
+++ b/Documentation/devicetree/bindings/phy/ti-phy.txt
@@ -9,15 +9,17 @@ Required properties:
9 e.g. USB2_PHY on OMAP5. 9 e.g. USB2_PHY on OMAP5.
10 "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control 10 "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control
11 e.g. USB3 PHY and SATA PHY on OMAP5. 11 e.g. USB3 PHY and SATA PHY on OMAP5.
12 "ti,control-phy-pcie" - for pcie to support external clock for pcie and to
13 set PCS delay value.
14 e.g. PCIE PHY in DRA7x
12 "ti,control-phy-usb2-dra7" - if it has power down register like USB2 PHY on 15 "ti,control-phy-usb2-dra7" - if it has power down register like USB2 PHY on
13 DRA7 platform. 16 DRA7 platform.
14 "ti,control-phy-usb2-am437" - if it has power down register like USB2 PHY on 17 "ti,control-phy-usb2-am437" - if it has power down register like USB2 PHY on
15 AM437 platform. 18 AM437 platform.
16 - reg : Address and length of the register set for the device. It contains 19 - reg : register ranges as listed in the reg-names property
17 the address of "otghs_control" for control-phy-otghs or "power" register 20 - reg-names: "otghs_control" for control-phy-otghs
18 for other types. 21 "power", "pcie_pcs" and "control_sma" for control-phy-pcie
19 - reg-names: should be "otghs_control" control-phy-otghs and "power" for 22 "power" for all other types
20 other types.
21 23
22omap_control_usb: omap-control-usb@4a002300 { 24omap_control_usb: omap-control-usb@4a002300 {
23 compatible = "ti,control-phy-otghs"; 25 compatible = "ti,control-phy-otghs";
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-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c
index 6174f4b1a5de..93bcd67f1b22 100644
--- a/drivers/phy/phy-ti-pipe3.c
+++ b/drivers/phy/phy-ti-pipe3.c
@@ -217,8 +217,10 @@ static int ti_pipe3_init(struct phy *x)
217 u32 val; 217 u32 val;
218 int ret = 0; 218 int ret = 0;
219 219
220 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) 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);
221 return 0; 222 return 0;
223 }
222 224
223 /* Bring it out of IDLE if it is IDLE */ 225 /* Bring it out of IDLE if it is IDLE */
224 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); 226 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
diff --git a/include/linux/phy/omap_control_phy.h b/include/linux/phy/omap_control_phy.h
index 5450403c7546..e9e6cfbfbb58 100644
--- a/include/linux/phy/omap_control_phy.h
+++ b/include/linux/phy/omap_control_phy.h
@@ -23,6 +23,7 @@ enum omap_control_phy_type {
23 OMAP_CTRL_TYPE_OTGHS = 1, /* Mailbox OTGHS_CONTROL */ 23 OMAP_CTRL_TYPE_OTGHS = 1, /* Mailbox OTGHS_CONTROL */
24 OMAP_CTRL_TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */ 24 OMAP_CTRL_TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */
25 OMAP_CTRL_TYPE_PIPE3, /* PIPE3 PHY, DPLL & seperate Rx/Tx power */ 25 OMAP_CTRL_TYPE_PIPE3, /* PIPE3 PHY, DPLL & seperate Rx/Tx power */
26 OMAP_CTRL_TYPE_PCIE, /* RX TX control of ACSPCIE */
26 OMAP_CTRL_TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */ 27 OMAP_CTRL_TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */
27 OMAP_CTRL_TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */ 28 OMAP_CTRL_TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */
28}; 29};
@@ -33,6 +34,7 @@ struct omap_control_phy {
33 u32 __iomem *otghs_control; 34 u32 __iomem *otghs_control;
34 u32 __iomem *power; 35 u32 __iomem *power;
35 u32 __iomem *power_aux; 36 u32 __iomem *power_aux;
37 u32 __iomem *pcie_pcs;
36 38
37 struct clk *sys_clk; 39 struct clk *sys_clk;
38 40
@@ -63,6 +65,9 @@ enum omap_control_usb_mode {
63#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON 0x3 65#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON 0x3
64#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 66#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0
65 67
68#define OMAP_CTRL_PCIE_PCS_MASK 0xff
69#define OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT 0x8
70
66#define OMAP_CTRL_USB2_PHY_PD BIT(28) 71#define OMAP_CTRL_USB2_PHY_PD BIT(28)
67 72
68#define AM437X_CTRL_USB2_PHY_PD BIT(0) 73#define AM437X_CTRL_USB2_PHY_PD BIT(0)
@@ -74,6 +79,7 @@ enum omap_control_usb_mode {
74void omap_control_phy_power(struct device *dev, int on); 79void omap_control_phy_power(struct device *dev, int on);
75void omap_control_usb_set_mode(struct device *dev, 80void omap_control_usb_set_mode(struct device *dev,
76 enum omap_control_usb_mode mode); 81 enum omap_control_usb_mode mode);
82void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay);
77#else 83#else
78 84
79static inline void omap_control_phy_power(struct device *dev, int on) 85static inline void omap_control_phy_power(struct device *dev, int on)
@@ -84,6 +90,10 @@ static inline void omap_control_usb_set_mode(struct device *dev,
84 enum omap_control_usb_mode mode) 90 enum omap_control_usb_mode mode)
85{ 91{
86} 92}
93
94static inline void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay)
95{
96}
87#endif 97#endif
88 98
89#endif /* __OMAP_CONTROL_PHY_H__ */ 99#endif /* __OMAP_CONTROL_PHY_H__ */