aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2014-06-25 13:52:57 -0400
committerKishon Vijay Abraham I <kishon@ti.com>2014-07-22 03:16:10 -0400
commitf0e2cf7b912522c9c7146d9d6e99d1b0ea5c97c6 (patch)
tree61081c79d550c40df4aa0f684e198c72eb4784d5
parent99bbd48c2065552fd2d224c9f065dcac9b7e25ce (diff)
phy: pipe3: insert delay to enumerate in GEN2 mode
8-bit delay value (0xF1) is required for GEN2 devices to be enumerated consistently. Added an API to be called from PHY drivers to set this delay value and called it from PIPE3 driver to set the delay value. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Reviewed-by: Roger Quadros <rogerq@ti.com>
-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__ */