diff options
author | Gabriel FERNANDEZ <gabriel.fernandez@st.com> | 2014-11-04 05:51:21 -0500 |
---|---|---|
committer | Kishon Vijay Abraham I <kishon@ti.com> | 2014-11-12 08:10:12 -0500 |
commit | 2b041b27a83fbe951d4b1cb1523001d4a8a5cccb (patch) | |
tree | f9d29e837f5fdaf8445b603b66c3b6822d7db9d0 | |
parent | 2c14e9be0c60bb3d89cfa16a40222ddcb83660ab (diff) |
phy: miphy28lp: Add SSC support for SATA
This patch to tune on/off the ssc on miphy sata setup.
User can now enable ssc via dt blob, it is useful to reduce
effects of EMI.
Signed-off-by: Giuseppe Condorelli <giuseppe.condorelli@st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@linaro.org>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
-rw-r--r-- | Documentation/devicetree/bindings/phy/phy-miphy28lp.txt | 1 | ||||
-rw-r--r-- | drivers/phy/phy-miphy28lp.c | 46 |
2 files changed, 47 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt index b7c13ad81a22..4a3b4af3c1e6 100644 --- a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt +++ b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt | |||
@@ -39,6 +39,7 @@ Optional properties (port (child) node): | |||
39 | register. | 39 | register. |
40 | - st,px_rx_pol_inv : to invert polarity of RXn/RXp (respectively negative line and positive | 40 | - st,px_rx_pol_inv : to invert polarity of RXn/RXp (respectively negative line and positive |
41 | line). | 41 | line). |
42 | - st,scc-on : enable ssc to reduce effects of EMI (only for sata or PCIe). | ||
42 | 43 | ||
43 | example: | 44 | example: |
44 | 45 | ||
diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index 7d592e6392ac..d2f797c79fbc 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c | |||
@@ -191,6 +191,8 @@ | |||
191 | #define SYSCFG_PCIE_PCIE_VAL 0x80 | 191 | #define SYSCFG_PCIE_PCIE_VAL 0x80 |
192 | #define SATA_SPDMODE 1 | 192 | #define SATA_SPDMODE 1 |
193 | 193 | ||
194 | #define MIPHY_SATA_BANK_NB 3 | ||
195 | |||
194 | struct miphy28lp_phy { | 196 | struct miphy28lp_phy { |
195 | struct phy *phy; | 197 | struct phy *phy; |
196 | struct miphy28lp_dev *phydev; | 198 | struct miphy28lp_dev *phydev; |
@@ -200,6 +202,7 @@ struct miphy28lp_phy { | |||
200 | bool osc_force_ext; | 202 | bool osc_force_ext; |
201 | bool osc_rdy; | 203 | bool osc_rdy; |
202 | bool px_rx_pol_inv; | 204 | bool px_rx_pol_inv; |
205 | bool ssc; | ||
203 | 206 | ||
204 | struct reset_control *miphy_rst; | 207 | struct reset_control *miphy_rst; |
205 | 208 | ||
@@ -550,6 +553,44 @@ static inline void miphy28_usb3_miphy_reset(struct miphy28lp_phy *miphy_phy) | |||
550 | writeb_relaxed(0x00, base + MIPHY_CONF); | 553 | writeb_relaxed(0x00, base + MIPHY_CONF); |
551 | } | 554 | } |
552 | 555 | ||
556 | static void miphy_sata_tune_ssc(struct miphy28lp_phy *miphy_phy) | ||
557 | { | ||
558 | void __iomem *base = miphy_phy->base; | ||
559 | u8 val; | ||
560 | |||
561 | /* Compensate Tx impedance to avoid out of range values */ | ||
562 | /* | ||
563 | * Enable the SSC on PLL for all banks | ||
564 | * SSC Modulation @ 31 KHz and 4000 ppm modulation amp | ||
565 | */ | ||
566 | val = readb_relaxed(base + MIPHY_BOUNDARY_2); | ||
567 | val |= SSC_EN_SW; | ||
568 | writeb_relaxed(val, base + MIPHY_BOUNDARY_2); | ||
569 | |||
570 | val = readb_relaxed(base + MIPHY_BOUNDARY_SEL); | ||
571 | val |= SSC_SEL; | ||
572 | writeb_relaxed(val, base + MIPHY_BOUNDARY_SEL); | ||
573 | |||
574 | for (val = 0; val < MIPHY_SATA_BANK_NB; val++) { | ||
575 | writeb_relaxed(val, base + MIPHY_CONF); | ||
576 | |||
577 | /* Add value to each reference clock cycle */ | ||
578 | /* and define the period length of the SSC */ | ||
579 | writeb_relaxed(0x3c, base + MIPHY_PLL_SBR_2); | ||
580 | writeb_relaxed(0x6c, base + MIPHY_PLL_SBR_3); | ||
581 | writeb_relaxed(0x81, base + MIPHY_PLL_SBR_4); | ||
582 | |||
583 | /* Clear any previous request */ | ||
584 | writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1); | ||
585 | |||
586 | /* requests the PLL to take in account new parameters */ | ||
587 | writeb_relaxed(SET_NEW_CHANGE, base + MIPHY_PLL_SBR_1); | ||
588 | |||
589 | /* To be sure there is no other pending requests */ | ||
590 | writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1); | ||
591 | } | ||
592 | } | ||
593 | |||
553 | static inline int miphy28lp_configure_sata(struct miphy28lp_phy *miphy_phy) | 594 | static inline int miphy28lp_configure_sata(struct miphy28lp_phy *miphy_phy) |
554 | { | 595 | { |
555 | void __iomem *base = miphy_phy->base; | 596 | void __iomem *base = miphy_phy->base; |
@@ -585,6 +626,9 @@ static inline int miphy28lp_configure_sata(struct miphy28lp_phy *miphy_phy) | |||
585 | writeb_relaxed(val, miphy_phy->base + MIPHY_CONTROL); | 626 | writeb_relaxed(val, miphy_phy->base + MIPHY_CONTROL); |
586 | } | 627 | } |
587 | 628 | ||
629 | if (miphy_phy->ssc) | ||
630 | miphy_sata_tune_ssc(miphy_phy); | ||
631 | |||
588 | return 0; | 632 | return 0; |
589 | } | 633 | } |
590 | 634 | ||
@@ -1064,6 +1108,8 @@ static int miphy28lp_of_probe(struct device_node *np, | |||
1064 | miphy_phy->px_rx_pol_inv = | 1108 | miphy_phy->px_rx_pol_inv = |
1065 | of_property_read_bool(np, "st,px_rx_pol_inv"); | 1109 | of_property_read_bool(np, "st,px_rx_pol_inv"); |
1066 | 1110 | ||
1111 | miphy_phy->ssc = of_property_read_bool(np, "st,ssc-on"); | ||
1112 | |||
1067 | of_property_read_u32(np, "st,sata-gen", &miphy_phy->sata_gen); | 1113 | of_property_read_u32(np, "st,sata-gen", &miphy_phy->sata_gen); |
1068 | if (!miphy_phy->sata_gen) | 1114 | if (!miphy_phy->sata_gen) |
1069 | miphy_phy->sata_gen = SATA_GEN1; | 1115 | miphy_phy->sata_gen = SATA_GEN1; |