]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Cortina Systems Gemini SATA bridge add-on to Faraday FTIDE010 | |
3 | * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> | |
4 | */ | |
5 | ||
6 | #include <linux/init.h> | |
7 | #include <linux/module.h> | |
8 | #include <linux/platform_device.h> | |
9 | #include <linux/bitops.h> | |
10 | #include <linux/mfd/syscon.h> | |
11 | #include <linux/regmap.h> | |
12 | #include <linux/delay.h> | |
13 | #include <linux/reset.h> | |
14 | #include <linux/of_address.h> | |
15 | #include <linux/of_device.h> | |
16 | #include <linux/clk.h> | |
17 | #include <linux/io.h> | |
18 | #include "sata_gemini.h" | |
19 | ||
20 | #define DRV_NAME "gemini_sata_bridge" | |
21 | ||
22 | /** | |
23 | * struct sata_gemini - a state container for a Gemini SATA bridge | |
24 | * @dev: the containing device | |
25 | * @base: remapped I/O memory base | |
26 | * @muxmode: the current muxing mode | |
27 | * @ide_pins: if the device is using the plain IDE interface pins | |
28 | * @sata_bridge: if the device enables the SATA bridge | |
29 | * @sata0_reset: SATA0 reset handler | |
30 | * @sata1_reset: SATA1 reset handler | |
31 | * @sata0_pclk: SATA0 PCLK handler | |
32 | * @sata1_pclk: SATA1 PCLK handler | |
33 | */ | |
34 | struct sata_gemini { | |
35 | struct device *dev; | |
36 | void __iomem *base; | |
37 | enum gemini_muxmode muxmode; | |
38 | bool ide_pins; | |
39 | bool sata_bridge; | |
40 | struct reset_control *sata0_reset; | |
41 | struct reset_control *sata1_reset; | |
42 | struct clk *sata0_pclk; | |
43 | struct clk *sata1_pclk; | |
44 | }; | |
45 | ||
46 | /* Global IDE PAD Skew Control Register */ | |
47 | #define GEMINI_GLOBAL_IDE_SKEW_CTRL 0x18 | |
48 | #define GEMINI_IDE1_HOST_STROBE_DELAY_SHIFT 28 | |
49 | #define GEMINI_IDE1_DEVICE_STROBE_DELAY_SHIFT 24 | |
50 | #define GEMINI_IDE1_OUTPUT_IO_SKEW_SHIFT 20 | |
51 | #define GEMINI_IDE1_INPUT_IO_SKEW_SHIFT 16 | |
52 | #define GEMINI_IDE0_HOST_STROBE_DELAY_SHIFT 12 | |
53 | #define GEMINI_IDE0_DEVICE_STROBE_DELAY_SHIFT 8 | |
54 | #define GEMINI_IDE0_OUTPUT_IO_SKEW_SHIFT 4 | |
55 | #define GEMINI_IDE0_INPUT_IO_SKEW_SHIFT 0 | |
56 | ||
57 | /* Miscellaneous Control Register */ | |
58 | #define GEMINI_GLOBAL_MISC_CTRL 0x30 | |
59 | /* | |
60 | * Values of IDE IOMUX bits in the misc control register | |
61 | * | |
62 | * Bits 26:24 are "IDE IO Select", which decides what SATA | |
63 | * adapters are connected to which of the two IDE/ATA | |
64 | * controllers in the Gemini. We can connect the two IDE blocks | |
65 | * to one SATA adapter each, both acting as master, or one IDE | |
66 | * blocks to two SATA adapters so the IDE block can act in a | |
67 | * master/slave configuration. | |
68 | * | |
69 | * We also bring out different blocks on the actual IDE | |
70 | * pins (not SATA pins) if (and only if) these are muxed in. | |
71 | * | |
72 | * 111-100 - Reserved | |
73 | * Mode 0: 000 - ata0 master <-> sata0 | |
74 | * ata1 master <-> sata1 | |
75 | * ata0 slave interface brought out on IDE pads | |
76 | * Mode 1: 001 - ata0 master <-> sata0 | |
77 | * ata1 master <-> sata1 | |
78 | * ata1 slave interface brought out on IDE pads | |
79 | * Mode 2: 010 - ata1 master <-> sata1 | |
80 | * ata1 slave <-> sata0 | |
81 | * ata0 master and slave interfaces brought out | |
82 | * on IDE pads | |
83 | * Mode 3: 011 - ata0 master <-> sata0 | |
84 | * ata1 slave <-> sata1 | |
85 | * ata1 master and slave interfaces brought out | |
86 | * on IDE pads | |
87 | */ | |
88 | #define GEMINI_IDE_IOMUX_MASK (7 << 24) | |
89 | #define GEMINI_IDE_IOMUX_MODE0 (0 << 24) | |
90 | #define GEMINI_IDE_IOMUX_MODE1 (1 << 24) | |
91 | #define GEMINI_IDE_IOMUX_MODE2 (2 << 24) | |
92 | #define GEMINI_IDE_IOMUX_MODE3 (3 << 24) | |
93 | #define GEMINI_IDE_IOMUX_SHIFT (24) | |
94 | #define GEMINI_IDE_PADS_ENABLE BIT(4) | |
95 | #define GEMINI_PFLASH_PADS_DISABLE BIT(1) | |
96 | ||
97 | /* | |
98 | * Registers directly controlling the PATA<->SATA adapters | |
99 | */ | |
100 | #define GEMINI_SATA_ID 0x00 | |
101 | #define GEMINI_SATA_PHY_ID 0x04 | |
102 | #define GEMINI_SATA0_STATUS 0x08 | |
103 | #define GEMINI_SATA1_STATUS 0x0c | |
104 | #define GEMINI_SATA0_CTRL 0x18 | |
105 | #define GEMINI_SATA1_CTRL 0x1c | |
106 | ||
107 | #define GEMINI_SATA_STATUS_BIST_DONE BIT(5) | |
108 | #define GEMINI_SATA_STATUS_BIST_OK BIT(4) | |
109 | #define GEMINI_SATA_STATUS_PHY_READY BIT(0) | |
110 | ||
111 | #define GEMINI_SATA_CTRL_PHY_BIST_EN BIT(14) | |
112 | #define GEMINI_SATA_CTRL_PHY_FORCE_IDLE BIT(13) | |
113 | #define GEMINI_SATA_CTRL_PHY_FORCE_READY BIT(12) | |
114 | #define GEMINI_SATA_CTRL_PHY_AFE_LOOP_EN BIT(10) | |
115 | #define GEMINI_SATA_CTRL_PHY_DIG_LOOP_EN BIT(9) | |
116 | #define GEMINI_SATA_CTRL_HOTPLUG_DETECT_EN BIT(4) | |
117 | #define GEMINI_SATA_CTRL_ATAPI_EN BIT(3) | |
118 | #define GEMINI_SATA_CTRL_BUS_WITH_20 BIT(2) | |
119 | #define GEMINI_SATA_CTRL_SLAVE_EN BIT(1) | |
120 | #define GEMINI_SATA_CTRL_EN BIT(0) | |
121 | ||
122 | /* | |
123 | * There is only ever one instance of this bridge on a system, | |
124 | * so create a singleton so that the FTIDE010 instances can grab | |
125 | * a reference to it. | |
126 | */ | |
127 | static struct sata_gemini *sg_singleton; | |
128 | ||
129 | struct sata_gemini *gemini_sata_bridge_get(void) | |
130 | { | |
131 | if (sg_singleton) | |
132 | return sg_singleton; | |
133 | return ERR_PTR(-EPROBE_DEFER); | |
134 | } | |
135 | EXPORT_SYMBOL(gemini_sata_bridge_get); | |
136 | ||
137 | bool gemini_sata_bridge_enabled(struct sata_gemini *sg, bool is_ata1) | |
138 | { | |
139 | if (!sg->sata_bridge) | |
140 | return false; | |
141 | /* | |
142 | * In muxmode 2 and 3 one of the ATA controllers is | |
143 | * actually not connected to any SATA bridge. | |
144 | */ | |
145 | if ((sg->muxmode == GEMINI_MUXMODE_2) && | |
146 | !is_ata1) | |
147 | return false; | |
148 | if ((sg->muxmode == GEMINI_MUXMODE_3) && | |
149 | is_ata1) | |
150 | return false; | |
151 | ||
152 | return true; | |
153 | } | |
154 | EXPORT_SYMBOL(gemini_sata_bridge_enabled); | |
155 | ||
156 | enum gemini_muxmode gemini_sata_get_muxmode(struct sata_gemini *sg) | |
157 | { | |
158 | return sg->muxmode; | |
159 | } | |
160 | EXPORT_SYMBOL(gemini_sata_get_muxmode); | |
161 | ||
162 | static int gemini_sata_setup_bridge(struct sata_gemini *sg, | |
163 | unsigned int bridge) | |
164 | { | |
165 | unsigned long timeout = jiffies + (HZ * 1); | |
166 | bool bridge_online; | |
167 | u32 val; | |
168 | ||
169 | if (bridge == 0) { | |
170 | val = GEMINI_SATA_CTRL_HOTPLUG_DETECT_EN | GEMINI_SATA_CTRL_EN; | |
171 | /* SATA0 slave mode is only used in muxmode 2 */ | |
172 | if (sg->muxmode == GEMINI_MUXMODE_2) | |
173 | val |= GEMINI_SATA_CTRL_SLAVE_EN; | |
174 | writel(val, sg->base + GEMINI_SATA0_CTRL); | |
175 | } else { | |
176 | val = GEMINI_SATA_CTRL_HOTPLUG_DETECT_EN | GEMINI_SATA_CTRL_EN; | |
177 | /* SATA1 slave mode is only used in muxmode 3 */ | |
178 | if (sg->muxmode == GEMINI_MUXMODE_3) | |
179 | val |= GEMINI_SATA_CTRL_SLAVE_EN; | |
180 | writel(val, sg->base + GEMINI_SATA1_CTRL); | |
181 | } | |
182 | ||
183 | /* Vendor code waits 10 ms here */ | |
184 | msleep(10); | |
185 | ||
186 | /* Wait for PHY to become ready */ | |
187 | do { | |
188 | msleep(100); | |
189 | ||
190 | if (bridge == 0) | |
191 | val = readl(sg->base + GEMINI_SATA0_STATUS); | |
192 | else | |
193 | val = readl(sg->base + GEMINI_SATA1_STATUS); | |
194 | if (val & GEMINI_SATA_STATUS_PHY_READY) | |
195 | break; | |
196 | } while (time_before(jiffies, timeout)); | |
197 | ||
198 | bridge_online = !!(val & GEMINI_SATA_STATUS_PHY_READY); | |
199 | ||
200 | dev_info(sg->dev, "SATA%d PHY %s\n", bridge, | |
201 | bridge_online ? "ready" : "not ready"); | |
202 | ||
203 | return bridge_online ? 0: -ENODEV; | |
204 | } | |
205 | ||
206 | int gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge) | |
207 | { | |
208 | struct clk *pclk; | |
209 | int ret; | |
210 | ||
211 | if (bridge == 0) | |
212 | pclk = sg->sata0_pclk; | |
213 | else | |
214 | pclk = sg->sata1_pclk; | |
215 | clk_enable(pclk); | |
216 | msleep(10); | |
217 | ||
218 | /* Do not keep clocking a bridge that is not online */ | |
219 | ret = gemini_sata_setup_bridge(sg, bridge); | |
220 | if (ret) | |
221 | clk_disable(pclk); | |
222 | ||
223 | return ret; | |
224 | } | |
225 | EXPORT_SYMBOL(gemini_sata_start_bridge); | |
226 | ||
227 | void gemini_sata_stop_bridge(struct sata_gemini *sg, unsigned int bridge) | |
228 | { | |
229 | if (bridge == 0) | |
230 | clk_disable(sg->sata0_pclk); | |
231 | else if (bridge == 1) | |
232 | clk_disable(sg->sata1_pclk); | |
233 | } | |
234 | EXPORT_SYMBOL(gemini_sata_stop_bridge); | |
235 | ||
236 | int gemini_sata_reset_bridge(struct sata_gemini *sg, | |
237 | unsigned int bridge) | |
238 | { | |
239 | if (bridge == 0) | |
240 | reset_control_reset(sg->sata0_reset); | |
241 | else | |
242 | reset_control_reset(sg->sata1_reset); | |
243 | msleep(10); | |
244 | return gemini_sata_setup_bridge(sg, bridge); | |
245 | } | |
246 | EXPORT_SYMBOL(gemini_sata_reset_bridge); | |
247 | ||
248 | static int gemini_sata_bridge_init(struct sata_gemini *sg) | |
249 | { | |
250 | struct device *dev = sg->dev; | |
251 | u32 sata_id, sata_phy_id; | |
252 | int ret; | |
253 | ||
254 | sg->sata0_pclk = devm_clk_get(dev, "SATA0_PCLK"); | |
255 | if (IS_ERR(sg->sata0_pclk)) { | |
256 | dev_err(dev, "no SATA0 PCLK"); | |
257 | return -ENODEV; | |
258 | } | |
259 | sg->sata1_pclk = devm_clk_get(dev, "SATA1_PCLK"); | |
260 | if (IS_ERR(sg->sata1_pclk)) { | |
261 | dev_err(dev, "no SATA1 PCLK"); | |
262 | return -ENODEV; | |
263 | } | |
264 | ||
265 | ret = clk_prepare_enable(sg->sata0_pclk); | |
266 | if (ret) { | |
267 | pr_err("failed to enable SATA0 PCLK\n"); | |
268 | return ret; | |
269 | } | |
270 | ret = clk_prepare_enable(sg->sata1_pclk); | |
271 | if (ret) { | |
272 | pr_err("failed to enable SATA1 PCLK\n"); | |
273 | clk_disable_unprepare(sg->sata0_pclk); | |
274 | return ret; | |
275 | } | |
276 | ||
277 | sg->sata0_reset = devm_reset_control_get(dev, "sata0"); | |
278 | if (IS_ERR(sg->sata0_reset)) { | |
279 | dev_err(dev, "no SATA0 reset controller\n"); | |
280 | clk_disable_unprepare(sg->sata1_pclk); | |
281 | clk_disable_unprepare(sg->sata0_pclk); | |
282 | return PTR_ERR(sg->sata0_reset); | |
283 | } | |
284 | sg->sata1_reset = devm_reset_control_get(dev, "sata1"); | |
285 | if (IS_ERR(sg->sata1_reset)) { | |
286 | dev_err(dev, "no SATA1 reset controller\n"); | |
287 | clk_disable_unprepare(sg->sata1_pclk); | |
288 | clk_disable_unprepare(sg->sata0_pclk); | |
289 | return PTR_ERR(sg->sata1_reset); | |
290 | } | |
291 | ||
292 | sata_id = readl(sg->base + GEMINI_SATA_ID); | |
293 | sata_phy_id = readl(sg->base + GEMINI_SATA_PHY_ID); | |
294 | sg->sata_bridge = true; | |
295 | clk_disable(sg->sata0_pclk); | |
296 | clk_disable(sg->sata1_pclk); | |
297 | ||
298 | dev_info(dev, "SATA ID %08x, PHY ID: %08x\n", sata_id, sata_phy_id); | |
299 | ||
300 | return 0; | |
301 | } | |
302 | ||
303 | static int gemini_sata_probe(struct platform_device *pdev) | |
304 | { | |
305 | struct device *dev = &pdev->dev; | |
306 | struct device_node *np = dev->of_node; | |
307 | struct sata_gemini *sg; | |
308 | static struct regmap *map; | |
309 | struct resource *res; | |
310 | enum gemini_muxmode muxmode; | |
311 | u32 gmode; | |
312 | u32 gmask; | |
313 | u32 val; | |
314 | int ret; | |
315 | ||
316 | sg = devm_kzalloc(dev, sizeof(*sg), GFP_KERNEL); | |
317 | if (!sg) | |
318 | return -ENOMEM; | |
319 | sg->dev = dev; | |
320 | ||
321 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
322 | if (!res) | |
323 | return -ENODEV; | |
324 | ||
325 | sg->base = devm_ioremap_resource(dev, res); | |
326 | if (IS_ERR(sg->base)) | |
327 | return PTR_ERR(sg->base); | |
328 | ||
329 | map = syscon_regmap_lookup_by_phandle(np, "syscon"); | |
330 | if (IS_ERR(map)) { | |
331 | dev_err(dev, "no global syscon\n"); | |
332 | return PTR_ERR(map); | |
333 | } | |
334 | ||
335 | /* Set up the SATA bridge if need be */ | |
336 | if (of_property_read_bool(np, "cortina,gemini-enable-sata-bridge")) { | |
337 | ret = gemini_sata_bridge_init(sg); | |
338 | if (ret) | |
339 | return ret; | |
340 | } | |
341 | ||
342 | if (of_property_read_bool(np, "cortina,gemini-enable-ide-pins")) | |
343 | sg->ide_pins = true; | |
344 | ||
345 | if (!sg->sata_bridge && !sg->ide_pins) { | |
346 | dev_err(dev, "neither SATA bridge or IDE output enabled\n"); | |
347 | ret = -EINVAL; | |
348 | goto out_unprep_clk; | |
349 | } | |
350 | ||
351 | ret = of_property_read_u32(np, "cortina,gemini-ata-muxmode", &muxmode); | |
352 | if (ret) { | |
353 | dev_err(dev, "could not parse ATA muxmode\n"); | |
354 | goto out_unprep_clk; | |
355 | } | |
356 | if (muxmode > GEMINI_MUXMODE_3) { | |
357 | dev_err(dev, "illegal muxmode %d\n", muxmode); | |
358 | ret = -EINVAL; | |
359 | goto out_unprep_clk; | |
360 | } | |
361 | sg->muxmode = muxmode; | |
362 | gmask = GEMINI_IDE_IOMUX_MASK; | |
363 | gmode = (muxmode << GEMINI_IDE_IOMUX_SHIFT); | |
364 | ||
365 | /* | |
366 | * If we mux out the IDE, parallel flash must be disabled. | |
367 | * SATA0 and SATA1 have dedicated pins and may coexist with | |
368 | * parallel flash. | |
369 | */ | |
370 | if (sg->ide_pins) | |
371 | gmode |= GEMINI_IDE_PADS_ENABLE | GEMINI_PFLASH_PADS_DISABLE; | |
372 | else | |
373 | gmask |= GEMINI_IDE_PADS_ENABLE; | |
374 | ||
375 | ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, gmask, gmode); | |
376 | if (ret) { | |
377 | dev_err(dev, "unable to set up IDE muxing\n"); | |
378 | ret = -ENODEV; | |
379 | goto out_unprep_clk; | |
380 | } | |
381 | ||
382 | /* FIXME: add more elaborate IDE skew control handling */ | |
383 | if (sg->ide_pins) { | |
384 | ret = regmap_read(map, GEMINI_GLOBAL_IDE_SKEW_CTRL, &val); | |
385 | if (ret) { | |
386 | dev_err(dev, "cannot read IDE skew control register\n"); | |
387 | return ret; | |
388 | } | |
389 | dev_info(dev, "IDE skew control: %08x\n", val); | |
390 | } | |
391 | ||
392 | dev_info(dev, "set up the Gemini IDE/SATA nexus\n"); | |
393 | platform_set_drvdata(pdev, sg); | |
394 | sg_singleton = sg; | |
395 | ||
396 | return 0; | |
397 | ||
398 | out_unprep_clk: | |
399 | if (sg->sata_bridge) { | |
400 | clk_unprepare(sg->sata1_pclk); | |
401 | clk_unprepare(sg->sata0_pclk); | |
402 | } | |
403 | return ret; | |
404 | } | |
405 | ||
406 | static int gemini_sata_remove(struct platform_device *pdev) | |
407 | { | |
408 | struct sata_gemini *sg = platform_get_drvdata(pdev); | |
409 | ||
410 | if (sg->sata_bridge) { | |
411 | clk_unprepare(sg->sata1_pclk); | |
412 | clk_unprepare(sg->sata0_pclk); | |
413 | } | |
414 | sg_singleton = NULL; | |
415 | ||
416 | return 0; | |
417 | } | |
418 | ||
419 | static const struct of_device_id gemini_sata_of_match[] = { | |
420 | { | |
421 | .compatible = "cortina,gemini-sata-bridge", | |
422 | }, | |
423 | {}, | |
424 | }; | |
425 | ||
426 | static struct platform_driver gemini_sata_driver = { | |
427 | .driver = { | |
428 | .name = DRV_NAME, | |
429 | .of_match_table = of_match_ptr(gemini_sata_of_match), | |
430 | }, | |
431 | .probe = gemini_sata_probe, | |
432 | .remove = gemini_sata_remove, | |
433 | }; | |
434 | module_platform_driver(gemini_sata_driver); | |
435 | ||
436 | MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); | |
437 | MODULE_LICENSE("GPL"); | |
438 | MODULE_ALIAS("platform:" DRV_NAME); |