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