summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorBartosz Golaszewski <bgolaszewski@baylibre.com>2017-01-30 05:02:08 -0500
committerSekhar Nori <nsekhar@ti.com>2017-01-31 10:11:52 -0500
commitcdf0ead3747200d527f37170d3fdd41e368f88b0 (patch)
tree5d710408ae682c54c8f0a3d04259183ccaddc39b /drivers/ata
parentd3d557cf646c52add72d050790bdf41670c96bab (diff)
sata: ahci-da850: un-hardcode the MPY bits
All platforms using this driver now register the SATA refclk. Remove the hardcoded default value from the driver and instead read the rate of the external clock and calculate the required MPY value from it. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Acked-by: Tejun Heo <tj@kernel.org> [nsekhar@ti.com: fix checkpatch warning about an unneeded else] Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci_da850.c91
1 files changed, 76 insertions, 15 deletions
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index d65088a2fd5f..1a50cd3b4233 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -29,17 +29,8 @@
29#define SATA_PHY_TXSWING(x) ((x) << 19) 29#define SATA_PHY_TXSWING(x) ((x) << 19)
30#define SATA_PHY_ENPLL(x) ((x) << 31) 30#define SATA_PHY_ENPLL(x) ((x) << 31)
31 31
32/*
33 * The multiplier needed for 1.5GHz PLL output.
34 *
35 * NOTE: This is currently hardcoded to be suitable for 100MHz crystal
36 * frequency (which is used by DA850 EVM board) and may need to be changed
37 * if you would like to use this driver on some other board.
38 */
39#define DA850_SATA_CLK_MULTIPLIER 7
40
41static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, 32static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg,
42 void __iomem *ahci_base) 33 void __iomem *ahci_base, u32 mpy)
43{ 34{
44 unsigned int val; 35 unsigned int val;
45 36
@@ -48,13 +39,61 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg,
48 val &= ~BIT(0); 39 val &= ~BIT(0);
49 writel(val, pwrdn_reg); 40 writel(val, pwrdn_reg);
50 41
51 val = SATA_PHY_MPY(DA850_SATA_CLK_MULTIPLIER + 1) | SATA_PHY_LOS(1) | 42 val = SATA_PHY_MPY(mpy) | SATA_PHY_LOS(1) | SATA_PHY_RXCDR(4) |
52 SATA_PHY_RXCDR(4) | SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) | 43 SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) | SATA_PHY_ENPLL(1);
53 SATA_PHY_ENPLL(1);
54 44
55 writel(val, ahci_base + SATA_P0PHYCR_REG); 45 writel(val, ahci_base + SATA_P0PHYCR_REG);
56} 46}
57 47
48static u32 ahci_da850_calculate_mpy(unsigned long refclk_rate)
49{
50 u32 pll_output = 1500000000, needed;
51
52 /*
53 * We need to determine the value of the multiplier (MPY) bits.
54 * In order to include the 12.5 multiplier we need to first divide
55 * the refclk rate by ten.
56 *
57 * __div64_32() turned out to be unreliable, sometimes returning
58 * false results.
59 */
60 WARN((refclk_rate % 10) != 0, "refclk must be divisible by 10");
61 needed = pll_output / (refclk_rate / 10);
62
63 /*
64 * What we have now is (multiplier * 10).
65 *
66 * Let's determine the actual register value we need to write.
67 */
68
69 switch (needed) {
70 case 50:
71 return 0x1;
72 case 60:
73 return 0x2;
74 case 80:
75 return 0x4;
76 case 100:
77 return 0x5;
78 case 120:
79 return 0x6;
80 case 125:
81 return 0x7;
82 case 150:
83 return 0x8;
84 case 200:
85 return 0x9;
86 case 250:
87 return 0xa;
88 default:
89 /*
90 * We should have divided evenly - if not, return an invalid
91 * value.
92 */
93 return 0;
94 }
95}
96
58static int ahci_da850_softreset(struct ata_link *link, 97static int ahci_da850_softreset(struct ata_link *link,
59 unsigned int *class, unsigned long deadline) 98 unsigned int *class, unsigned long deadline)
60{ 99{
@@ -126,9 +165,10 @@ static int ahci_da850_probe(struct platform_device *pdev)
126{ 165{
127 struct device *dev = &pdev->dev; 166 struct device *dev = &pdev->dev;
128 struct ahci_host_priv *hpriv; 167 struct ahci_host_priv *hpriv;
129 struct resource *res;
130 void __iomem *pwrdn_reg; 168 void __iomem *pwrdn_reg;
169 struct resource *res;
131 struct clk *clk; 170 struct clk *clk;
171 u32 mpy;
132 int rc; 172 int rc;
133 173
134 hpriv = ahci_platform_get_resources(pdev); 174 hpriv = ahci_platform_get_resources(pdev);
@@ -150,6 +190,27 @@ static int ahci_da850_probe(struct platform_device *pdev)
150 hpriv->clks[0] = clk; 190 hpriv->clks[0] = clk;
151 } 191 }
152 192
193 /*
194 * The second clock used by ahci-da850 is the external REFCLK. If we
195 * didn't get it from ahci_platform_get_resources(), let's try to
196 * specify the con_id in clk_get().
197 */
198 if (!hpriv->clks[1]) {
199 clk = clk_get(dev, "refclk");
200 if (IS_ERR(clk)) {
201 dev_err(dev, "unable to obtain the reference clock");
202 return -ENODEV;
203 }
204
205 hpriv->clks[1] = clk;
206 }
207
208 mpy = ahci_da850_calculate_mpy(clk_get_rate(hpriv->clks[1]));
209 if (mpy == 0) {
210 dev_err(dev, "invalid REFCLK multiplier value: 0x%x", mpy);
211 return -EINVAL;
212 }
213
153 rc = ahci_platform_enable_resources(hpriv); 214 rc = ahci_platform_enable_resources(hpriv);
154 if (rc) 215 if (rc)
155 return rc; 216 return rc;
@@ -162,7 +223,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
162 if (!pwrdn_reg) 223 if (!pwrdn_reg)
163 goto disable_resources; 224 goto disable_resources;
164 225
165 da850_sata_init(dev, pwrdn_reg, hpriv->mmio); 226 da850_sata_init(dev, pwrdn_reg, hpriv->mmio, mpy);
166 227
167 rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info, 228 rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info,
168 &ahci_platform_sht); 229 &ahci_platform_sht);