diff options
-rw-r--r-- | MAINTAINERS | 9 | ||||
-rw-r--r-- | drivers/ata/Kconfig | 21 | ||||
-rw-r--r-- | drivers/ata/Makefile | 2 | ||||
-rw-r--r-- | drivers/ata/pata_ftide010.c | 567 | ||||
-rw-r--r-- | drivers/ata/sata_gemini.c | 438 | ||||
-rw-r--r-- | drivers/ata/sata_gemini.h | 21 |
6 files changed, 1058 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index f7d568b8f133..96753be12026 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -7531,6 +7531,15 @@ S: Maintained | |||
7531 | F: drivers/ata/pata_*.c | 7531 | F: drivers/ata/pata_*.c |
7532 | F: drivers/ata/ata_generic.c | 7532 | F: drivers/ata/ata_generic.c |
7533 | 7533 | ||
7534 | LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS | ||
7535 | M: Linus Walleij <linus.walleij@linaro.org> | ||
7536 | L: linux-ide@vger.kernel.org | ||
7537 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git | ||
7538 | S: Maintained | ||
7539 | F: drivers/ata/pata_ftide010.c | ||
7540 | F: drivers/ata/sata_gemini.c | ||
7541 | F: drivers/ata/sata_gemini.h | ||
7542 | |||
7534 | LIBATA SATA AHCI PLATFORM devices support | 7543 | LIBATA SATA AHCI PLATFORM devices support |
7535 | M: Hans de Goede <hdegoede@redhat.com> | 7544 | M: Hans de Goede <hdegoede@redhat.com> |
7536 | M: Tejun Heo <tj@kernel.org> | 7545 | M: Tejun Heo <tj@kernel.org> |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index de3eaf051697..948fc86980a1 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -213,6 +213,16 @@ config SATA_FSL | |||
213 | 213 | ||
214 | If unsure, say N. | 214 | If unsure, say N. |
215 | 215 | ||
216 | config SATA_GEMINI | ||
217 | tristate "Gemini SATA bridge support" | ||
218 | depends on PATA_FTIDE010 | ||
219 | default ARCH_GEMINI | ||
220 | help | ||
221 | This enabled support for the FTIDE010 to SATA bridge | ||
222 | found in Cortina Systems Gemini platform. | ||
223 | |||
224 | If unsure, say N. | ||
225 | |||
216 | config SATA_AHCI_SEATTLE | 226 | config SATA_AHCI_SEATTLE |
217 | tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support" | 227 | tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support" |
218 | depends on ARCH_SEATTLE | 228 | depends on ARCH_SEATTLE |
@@ -599,6 +609,17 @@ config PATA_EP93XX | |||
599 | 609 | ||
600 | If unsure, say N. | 610 | If unsure, say N. |
601 | 611 | ||
612 | config PATA_FTIDE010 | ||
613 | tristate "Faraday Technology FTIDE010 PATA support" | ||
614 | depends on OF | ||
615 | depends on ARM | ||
616 | default ARCH_GEMINI | ||
617 | help | ||
618 | This option enables support for the Faraday FTIDE010 | ||
619 | PATA controller found in the Cortina Gemini SoCs. | ||
620 | |||
621 | If unsure, say N. | ||
622 | |||
602 | config PATA_HPT366 | 623 | config PATA_HPT366 |
603 | tristate "HPT 366/368 PATA support" | 624 | tristate "HPT 366/368 PATA support" |
604 | depends on PCI | 625 | depends on PCI |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index cd931a5eba92..a26ef5a93919 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o | |||
7 | obj-$(CONFIG_SATA_AHCI_SEATTLE) += ahci_seattle.o libahci.o libahci_platform.o | 7 | obj-$(CONFIG_SATA_AHCI_SEATTLE) += ahci_seattle.o libahci.o libahci_platform.o |
8 | obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o | 8 | obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o |
9 | obj-$(CONFIG_SATA_FSL) += sata_fsl.o | 9 | obj-$(CONFIG_SATA_FSL) += sata_fsl.o |
10 | obj-$(CONFIG_SATA_GEMINI) += sata_gemini.o | ||
10 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o | 11 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o |
11 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o | 12 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o |
12 | obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o | 13 | obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o |
@@ -60,6 +61,7 @@ obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o | |||
60 | obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o | 61 | obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o |
61 | obj-$(CONFIG_PATA_EFAR) += pata_efar.o | 62 | obj-$(CONFIG_PATA_EFAR) += pata_efar.o |
62 | obj-$(CONFIG_PATA_EP93XX) += pata_ep93xx.o | 63 | obj-$(CONFIG_PATA_EP93XX) += pata_ep93xx.o |
64 | obj-$(CONFIG_PATA_FTIDE010) += pata_ftide010.o | ||
63 | obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o | 65 | obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o |
64 | obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o | 66 | obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o |
65 | obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o | 67 | obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o |
diff --git a/drivers/ata/pata_ftide010.c b/drivers/ata/pata_ftide010.c new file mode 100644 index 000000000000..7b7e417ba8ba --- /dev/null +++ b/drivers/ata/pata_ftide010.c | |||
@@ -0,0 +1,567 @@ | |||
1 | /* | ||
2 | * Faraday Technology FTIDE010 driver | ||
3 | * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> | ||
4 | * | ||
5 | * Includes portions of the SL2312/SL3516/Gemini PATA driver | ||
6 | * Copyright (C) 2003 StorLine, Inc <jason@storlink.com.tw> | ||
7 | * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com> | ||
8 | * Copyright (C) 2010 Frederic Pecourt <opengemini@free.fr> | ||
9 | * Copyright (C) 2011 Tobias Waldvogel <tobias.waldvogel@gmail.com> | ||
10 | */ | ||
11 | |||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/libata.h> | ||
15 | #include <linux/bitops.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include "sata_gemini.h" | ||
20 | |||
21 | #define DRV_NAME "pata_ftide010" | ||
22 | |||
23 | /** | ||
24 | * struct ftide010 - state container for the Faraday FTIDE010 | ||
25 | * @dev: pointer back to the device representing this controller | ||
26 | * @base: remapped I/O space address | ||
27 | * @pclk: peripheral clock for the IDE block | ||
28 | * @host: pointer to the ATA host for this device | ||
29 | * @master_cbl: master cable type | ||
30 | * @slave_cbl: slave cable type | ||
31 | * @sg: Gemini SATA bridge pointer, if running on the Gemini | ||
32 | * @master_to_sata0: Gemini SATA bridge: the ATA master is connected | ||
33 | * to the SATA0 bridge | ||
34 | * @slave_to_sata0: Gemini SATA bridge: the ATA slave is connected | ||
35 | * to the SATA0 bridge | ||
36 | * @master_to_sata1: Gemini SATA bridge: the ATA master is connected | ||
37 | * to the SATA1 bridge | ||
38 | * @slave_to_sata1: Gemini SATA bridge: the ATA slave is connected | ||
39 | * to the SATA1 bridge | ||
40 | */ | ||
41 | struct ftide010 { | ||
42 | struct device *dev; | ||
43 | void __iomem *base; | ||
44 | struct clk *pclk; | ||
45 | struct ata_host *host; | ||
46 | unsigned int master_cbl; | ||
47 | unsigned int slave_cbl; | ||
48 | /* Gemini-specific properties */ | ||
49 | struct sata_gemini *sg; | ||
50 | bool master_to_sata0; | ||
51 | bool slave_to_sata0; | ||
52 | bool master_to_sata1; | ||
53 | bool slave_to_sata1; | ||
54 | }; | ||
55 | |||
56 | #define FTIDE010_DMA_REG 0x00 | ||
57 | #define FTIDE010_DMA_STATUS 0x02 | ||
58 | #define FTIDE010_IDE_BMDTPR 0x04 | ||
59 | #define FTIDE010_IDE_DEVICE_ID 0x08 | ||
60 | #define FTIDE010_PIO_TIMING 0x10 | ||
61 | #define FTIDE010_MWDMA_TIMING 0x11 | ||
62 | #define FTIDE010_UDMA_TIMING0 0x12 /* Master */ | ||
63 | #define FTIDE010_UDMA_TIMING1 0x13 /* Slave */ | ||
64 | #define FTIDE010_CLK_MOD 0x14 | ||
65 | /* These registers are mapped directly to the IDE registers */ | ||
66 | #define FTIDE010_CMD_DATA 0x20 | ||
67 | #define FTIDE010_ERROR_FEATURES 0x21 | ||
68 | #define FTIDE010_NSECT 0x22 | ||
69 | #define FTIDE010_LBAL 0x23 | ||
70 | #define FTIDE010_LBAM 0x24 | ||
71 | #define FTIDE010_LBAH 0x25 | ||
72 | #define FTIDE010_DEVICE 0x26 | ||
73 | #define FTIDE010_STATUS_COMMAND 0x27 | ||
74 | #define FTIDE010_ALTSTAT_CTRL 0x36 | ||
75 | |||
76 | /* Set this bit for UDMA mode 5 and 6 */ | ||
77 | #define FTIDE010_UDMA_TIMING_MODE_56 BIT(7) | ||
78 | |||
79 | /* 0 = 50 MHz, 1 = 66 MHz */ | ||
80 | #define FTIDE010_CLK_MOD_DEV0_CLK_SEL BIT(0) | ||
81 | #define FTIDE010_CLK_MOD_DEV1_CLK_SEL BIT(1) | ||
82 | /* Enable UDMA on a device */ | ||
83 | #define FTIDE010_CLK_MOD_DEV0_UDMA_EN BIT(4) | ||
84 | #define FTIDE010_CLK_MOD_DEV1_UDMA_EN BIT(5) | ||
85 | |||
86 | static struct scsi_host_template pata_ftide010_sht = { | ||
87 | ATA_BMDMA_SHT(DRV_NAME), | ||
88 | }; | ||
89 | |||
90 | /* | ||
91 | * Bus timings | ||
92 | * | ||
93 | * The unit of the below required timings is two clock periods of the ATA | ||
94 | * reference clock which is 30 nanoseconds per unit at 66MHz and 20 | ||
95 | * nanoseconds per unit at 50 MHz. The PIO timings assume 33MHz speed for | ||
96 | * PIO. | ||
97 | * | ||
98 | * pio_active_time: array of 5 elements for T2 timing for Mode 0, | ||
99 | * 1, 2, 3 and 4. Range 0..15. | ||
100 | * pio_recovery_time: array of 5 elements for T2l timing for Mode 0, | ||
101 | * 1, 2, 3 and 4. Range 0..15. | ||
102 | * mdma_50_active_time: array of 4 elements for Td timing for multi | ||
103 | * word DMA, Mode 0, 1, and 2 at 50 MHz. Range 0..15. | ||
104 | * mdma_50_recovery_time: array of 4 elements for Tk timing for | ||
105 | * multi word DMA, Mode 0, 1 and 2 at 50 MHz. Range 0..15. | ||
106 | * mdma_66_active_time: array of 4 elements for Td timing for multi | ||
107 | * word DMA, Mode 0, 1 and 2 at 66 MHz. Range 0..15. | ||
108 | * mdma_66_recovery_time: array of 4 elements for Tk timing for | ||
109 | * multi word DMA, Mode 0, 1 and 2 at 66 MHz. Range 0..15. | ||
110 | * udma_50_setup_time: array of 4 elements for Tvds timing for ultra | ||
111 | * DMA, Mode 0, 1, 2, 3, 4 and 5 at 50 MHz. Range 0..7. | ||
112 | * udma_50_hold_time: array of 4 elements for Tdvh timing for | ||
113 | * multi word DMA, Mode 0, 1, 2, 3, 4 and 5 at 50 MHz, Range 0..7. | ||
114 | * udma_66_setup_time: array of 4 elements for Tvds timing for multi | ||
115 | * word DMA, Mode 0, 1, 2, 3, 4, 5 and 6 at 66 MHz. Range 0..7. | ||
116 | * udma_66_hold_time: array of 4 elements for Tdvh timing for | ||
117 | * multi word DMA, Mode 0, 1, 2, 3, 4, 5 and 6 at 66 MHz. Range 0..7. | ||
118 | */ | ||
119 | static const u8 pio_active_time[5] = {10, 10, 10, 3, 3}; | ||
120 | static const u8 pio_recovery_time[5] = {10, 3, 1, 3, 1}; | ||
121 | static const u8 mwdma_50_active_time[3] = {6, 2, 2}; | ||
122 | static const u8 mwdma_50_recovery_time[3] = {6, 2, 1}; | ||
123 | static const u8 mwdma_66_active_time[3] = {8, 3, 3}; | ||
124 | static const u8 mwdma_66_recovery_time[3] = {8, 2, 1}; | ||
125 | static const u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 1}; | ||
126 | static const u8 udma_50_hold_time[6] = {3, 1, 1, 1, 1, 1}; | ||
127 | static const u8 udma_66_setup_time[7] = {4, 4, 3, 2, }; | ||
128 | static const u8 udma_66_hold_time[7] = {}; | ||
129 | |||
130 | /* | ||
131 | * We set 66 MHz for all MWDMA modes | ||
132 | */ | ||
133 | static const bool set_mdma_66_mhz[] = { true, true, true, true }; | ||
134 | |||
135 | /* | ||
136 | * We set 66 MHz for UDMA modes 3, 4 and 6 and no others | ||
137 | */ | ||
138 | static const bool set_udma_66_mhz[] = { false, false, false, true, true, false, true }; | ||
139 | |||
140 | static void ftide010_set_dmamode(struct ata_port *ap, struct ata_device *adev) | ||
141 | { | ||
142 | struct ftide010 *ftide = ap->host->private_data; | ||
143 | u8 speed = adev->dma_mode; | ||
144 | u8 devno = adev->devno & 1; | ||
145 | u8 udma_en_mask; | ||
146 | u8 f66m_en_mask; | ||
147 | u8 clkreg; | ||
148 | u8 timreg; | ||
149 | u8 i; | ||
150 | |||
151 | /* Target device 0 (master) or 1 (slave) */ | ||
152 | if (!devno) { | ||
153 | udma_en_mask = FTIDE010_CLK_MOD_DEV0_UDMA_EN; | ||
154 | f66m_en_mask = FTIDE010_CLK_MOD_DEV0_CLK_SEL; | ||
155 | } else { | ||
156 | udma_en_mask = FTIDE010_CLK_MOD_DEV1_UDMA_EN; | ||
157 | f66m_en_mask = FTIDE010_CLK_MOD_DEV1_CLK_SEL; | ||
158 | } | ||
159 | |||
160 | clkreg = readb(ftide->base + FTIDE010_CLK_MOD); | ||
161 | clkreg &= ~udma_en_mask; | ||
162 | clkreg &= ~f66m_en_mask; | ||
163 | |||
164 | if (speed & XFER_UDMA_0) { | ||
165 | i = speed & ~XFER_UDMA_0; | ||
166 | dev_dbg(ftide->dev, "set UDMA mode %02x, index %d\n", | ||
167 | speed, i); | ||
168 | |||
169 | clkreg |= udma_en_mask; | ||
170 | if (set_udma_66_mhz[i]) { | ||
171 | clkreg |= f66m_en_mask; | ||
172 | timreg = udma_66_setup_time[i] << 4 | | ||
173 | udma_66_hold_time[i]; | ||
174 | } else { | ||
175 | timreg = udma_50_setup_time[i] << 4 | | ||
176 | udma_50_hold_time[i]; | ||
177 | } | ||
178 | |||
179 | /* A special bit needs to be set for modes 5 and 6 */ | ||
180 | if (i >= 5) | ||
181 | timreg |= FTIDE010_UDMA_TIMING_MODE_56; | ||
182 | |||
183 | dev_dbg(ftide->dev, "UDMA write clkreg = %02x, timreg = %02x\n", | ||
184 | clkreg, timreg); | ||
185 | |||
186 | writeb(clkreg, ftide->base + FTIDE010_CLK_MOD); | ||
187 | writeb(timreg, ftide->base + FTIDE010_UDMA_TIMING0 + devno); | ||
188 | } else { | ||
189 | i = speed & ~XFER_MW_DMA_0; | ||
190 | dev_dbg(ftide->dev, "set MWDMA mode %02x, index %d\n", | ||
191 | speed, i); | ||
192 | |||
193 | if (set_mdma_66_mhz[i]) { | ||
194 | clkreg |= f66m_en_mask; | ||
195 | timreg = mwdma_66_active_time[i] << 4 | | ||
196 | mwdma_66_recovery_time[i]; | ||
197 | } else { | ||
198 | timreg = mwdma_50_active_time[i] << 4 | | ||
199 | mwdma_50_recovery_time[i]; | ||
200 | } | ||
201 | dev_dbg(ftide->dev, | ||
202 | "MWDMA write clkreg = %02x, timreg = %02x\n", | ||
203 | clkreg, timreg); | ||
204 | /* This will affect all devices */ | ||
205 | writeb(clkreg, ftide->base + FTIDE010_CLK_MOD); | ||
206 | writeb(timreg, ftide->base + FTIDE010_MWDMA_TIMING); | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * Store the current device (master or slave) in ap->private_data | ||
211 | * so that .qc_issue() can detect if this changes and reprogram | ||
212 | * the DMA settings. | ||
213 | */ | ||
214 | ap->private_data = adev; | ||
215 | |||
216 | return; | ||
217 | } | ||
218 | |||
219 | static void ftide010_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
220 | { | ||
221 | struct ftide010 *ftide = ap->host->private_data; | ||
222 | u8 pio = adev->pio_mode - XFER_PIO_0; | ||
223 | |||
224 | dev_dbg(ftide->dev, "set PIO mode %02x, index %d\n", | ||
225 | adev->pio_mode, pio); | ||
226 | writeb(pio_active_time[pio] << 4 | pio_recovery_time[pio], | ||
227 | ftide->base + FTIDE010_PIO_TIMING); | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * We implement our own qc_issue() callback since we may need to set up | ||
232 | * the timings differently for master and slave transfers: the CLK_MOD_REG | ||
233 | * and MWDMA_TIMING_REG is shared between master and slave, so reprogramming | ||
234 | * this may be necessary. | ||
235 | */ | ||
236 | static unsigned int ftide010_qc_issue(struct ata_queued_cmd *qc) | ||
237 | { | ||
238 | struct ata_port *ap = qc->ap; | ||
239 | struct ata_device *adev = qc->dev; | ||
240 | |||
241 | /* | ||
242 | * If the device changed, i.e. slave->master, master->slave, | ||
243 | * then set up the DMA mode again so we are sure the timings | ||
244 | * are correct. | ||
245 | */ | ||
246 | if (adev != ap->private_data && ata_dma_enabled(adev)) | ||
247 | ftide010_set_dmamode(ap, adev); | ||
248 | |||
249 | return ata_bmdma_qc_issue(qc); | ||
250 | } | ||
251 | |||
252 | static struct ata_port_operations pata_ftide010_port_ops = { | ||
253 | .inherits = &ata_bmdma_port_ops, | ||
254 | .set_dmamode = ftide010_set_dmamode, | ||
255 | .set_piomode = ftide010_set_piomode, | ||
256 | .qc_issue = ftide010_qc_issue, | ||
257 | }; | ||
258 | |||
259 | static struct ata_port_info ftide010_port_info[] = { | ||
260 | { | ||
261 | .flags = ATA_FLAG_SLAVE_POSS, | ||
262 | .mwdma_mask = ATA_MWDMA2, | ||
263 | .udma_mask = ATA_UDMA6, | ||
264 | .pio_mask = ATA_PIO4, | ||
265 | .port_ops = &pata_ftide010_port_ops, | ||
266 | }, | ||
267 | }; | ||
268 | |||
269 | #if IS_ENABLED(CONFIG_SATA_GEMINI) | ||
270 | |||
271 | static int pata_ftide010_gemini_port_start(struct ata_port *ap) | ||
272 | { | ||
273 | struct ftide010 *ftide = ap->host->private_data; | ||
274 | struct device *dev = ftide->dev; | ||
275 | struct sata_gemini *sg = ftide->sg; | ||
276 | int bridges = 0; | ||
277 | int ret; | ||
278 | |||
279 | ret = ata_bmdma_port_start(ap); | ||
280 | if (ret) | ||
281 | return ret; | ||
282 | |||
283 | if (ftide->master_to_sata0) { | ||
284 | dev_info(dev, "SATA0 (master) start\n"); | ||
285 | ret = gemini_sata_start_bridge(sg, 0); | ||
286 | if (!ret) | ||
287 | bridges++; | ||
288 | } | ||
289 | if (ftide->master_to_sata1) { | ||
290 | dev_info(dev, "SATA1 (master) start\n"); | ||
291 | ret = gemini_sata_start_bridge(sg, 1); | ||
292 | if (!ret) | ||
293 | bridges++; | ||
294 | } | ||
295 | /* Avoid double-starting */ | ||
296 | if (ftide->slave_to_sata0 && !ftide->master_to_sata0) { | ||
297 | dev_info(dev, "SATA0 (slave) start\n"); | ||
298 | ret = gemini_sata_start_bridge(sg, 0); | ||
299 | if (!ret) | ||
300 | bridges++; | ||
301 | } | ||
302 | /* Avoid double-starting */ | ||
303 | if (ftide->slave_to_sata1 && !ftide->master_to_sata1) { | ||
304 | dev_info(dev, "SATA1 (slave) start\n"); | ||
305 | ret = gemini_sata_start_bridge(sg, 1); | ||
306 | if (!ret) | ||
307 | bridges++; | ||
308 | } | ||
309 | |||
310 | dev_info(dev, "brought %d bridges online\n", bridges); | ||
311 | return (bridges > 0) ? 0 : -EINVAL; // -ENODEV; | ||
312 | } | ||
313 | |||
314 | static void pata_ftide010_gemini_port_stop(struct ata_port *ap) | ||
315 | { | ||
316 | struct ftide010 *ftide = ap->host->private_data; | ||
317 | struct device *dev = ftide->dev; | ||
318 | struct sata_gemini *sg = ftide->sg; | ||
319 | |||
320 | if (ftide->master_to_sata0) { | ||
321 | dev_info(dev, "SATA0 (master) stop\n"); | ||
322 | gemini_sata_stop_bridge(sg, 0); | ||
323 | } | ||
324 | if (ftide->master_to_sata1) { | ||
325 | dev_info(dev, "SATA1 (master) stop\n"); | ||
326 | gemini_sata_stop_bridge(sg, 1); | ||
327 | } | ||
328 | /* Avoid double-stopping */ | ||
329 | if (ftide->slave_to_sata0 && !ftide->master_to_sata0) { | ||
330 | dev_info(dev, "SATA0 (slave) stop\n"); | ||
331 | gemini_sata_stop_bridge(sg, 0); | ||
332 | } | ||
333 | /* Avoid double-stopping */ | ||
334 | if (ftide->slave_to_sata1 && !ftide->master_to_sata1) { | ||
335 | dev_info(dev, "SATA1 (slave) stop\n"); | ||
336 | gemini_sata_stop_bridge(sg, 1); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | static int pata_ftide010_gemini_cable_detect(struct ata_port *ap) | ||
341 | { | ||
342 | struct ftide010 *ftide = ap->host->private_data; | ||
343 | |||
344 | /* | ||
345 | * Return the master cable, I have no clue how to return a different | ||
346 | * cable for the slave than for the master. | ||
347 | */ | ||
348 | return ftide->master_cbl; | ||
349 | } | ||
350 | |||
351 | static int pata_ftide010_gemini_init(struct ftide010 *ftide, | ||
352 | bool is_ata1) | ||
353 | { | ||
354 | struct device *dev = ftide->dev; | ||
355 | struct sata_gemini *sg; | ||
356 | enum gemini_muxmode muxmode; | ||
357 | |||
358 | /* Look up SATA bridge */ | ||
359 | sg = gemini_sata_bridge_get(); | ||
360 | if (IS_ERR(sg)) | ||
361 | return PTR_ERR(sg); | ||
362 | ftide->sg = sg; | ||
363 | |||
364 | muxmode = gemini_sata_get_muxmode(sg); | ||
365 | |||
366 | /* Special ops */ | ||
367 | pata_ftide010_port_ops.port_start = | ||
368 | pata_ftide010_gemini_port_start; | ||
369 | pata_ftide010_port_ops.port_stop = | ||
370 | pata_ftide010_gemini_port_stop; | ||
371 | pata_ftide010_port_ops.cable_detect = | ||
372 | pata_ftide010_gemini_cable_detect; | ||
373 | |||
374 | /* Flag port as SATA-capable */ | ||
375 | if (gemini_sata_bridge_enabled(sg, is_ata1)) | ||
376 | ftide010_port_info[0].flags |= ATA_FLAG_SATA; | ||
377 | |||
378 | /* | ||
379 | * We assume that a simple 40-wire cable is used in the PATA mode. | ||
380 | * if you're adding a system using the PATA interface, make sure | ||
381 | * the right cable is set up here, it might be necessary to use | ||
382 | * special hardware detection or encode the cable type in the device | ||
383 | * tree with special properties. | ||
384 | */ | ||
385 | if (!is_ata1) { | ||
386 | switch (muxmode) { | ||
387 | case GEMINI_MUXMODE_0: | ||
388 | ftide->master_cbl = ATA_CBL_SATA; | ||
389 | ftide->slave_cbl = ATA_CBL_PATA40; | ||
390 | ftide->master_to_sata0 = true; | ||
391 | break; | ||
392 | case GEMINI_MUXMODE_1: | ||
393 | ftide->master_cbl = ATA_CBL_SATA; | ||
394 | ftide->slave_cbl = ATA_CBL_NONE; | ||
395 | ftide->master_to_sata0 = true; | ||
396 | break; | ||
397 | case GEMINI_MUXMODE_2: | ||
398 | ftide->master_cbl = ATA_CBL_PATA40; | ||
399 | ftide->slave_cbl = ATA_CBL_PATA40; | ||
400 | break; | ||
401 | case GEMINI_MUXMODE_3: | ||
402 | ftide->master_cbl = ATA_CBL_SATA; | ||
403 | ftide->slave_cbl = ATA_CBL_SATA; | ||
404 | ftide->master_to_sata0 = true; | ||
405 | ftide->slave_to_sata1 = true; | ||
406 | break; | ||
407 | } | ||
408 | } else { | ||
409 | switch (muxmode) { | ||
410 | case GEMINI_MUXMODE_0: | ||
411 | ftide->master_cbl = ATA_CBL_SATA; | ||
412 | ftide->slave_cbl = ATA_CBL_NONE; | ||
413 | ftide->master_to_sata1 = true; | ||
414 | break; | ||
415 | case GEMINI_MUXMODE_1: | ||
416 | ftide->master_cbl = ATA_CBL_SATA; | ||
417 | ftide->slave_cbl = ATA_CBL_PATA40; | ||
418 | ftide->master_to_sata1 = true; | ||
419 | break; | ||
420 | case GEMINI_MUXMODE_2: | ||
421 | ftide->master_cbl = ATA_CBL_SATA; | ||
422 | ftide->slave_cbl = ATA_CBL_SATA; | ||
423 | ftide->slave_to_sata0 = true; | ||
424 | ftide->master_to_sata1 = true; | ||
425 | break; | ||
426 | case GEMINI_MUXMODE_3: | ||
427 | ftide->master_cbl = ATA_CBL_PATA40; | ||
428 | ftide->slave_cbl = ATA_CBL_PATA40; | ||
429 | break; | ||
430 | } | ||
431 | } | ||
432 | dev_info(dev, "set up Gemini PATA%d\n", is_ata1); | ||
433 | |||
434 | return 0; | ||
435 | } | ||
436 | #else | ||
437 | static int pata_ftide010_gemini_init(struct ftide010 *ftide, | ||
438 | bool is_ata1) | ||
439 | { | ||
440 | return -ENOTSUPP; | ||
441 | } | ||
442 | #endif | ||
443 | |||
444 | |||
445 | static int pata_ftide010_probe(struct platform_device *pdev) | ||
446 | { | ||
447 | struct device *dev = &pdev->dev; | ||
448 | struct device_node *np = dev->of_node; | ||
449 | const struct ata_port_info pi = ftide010_port_info[0]; | ||
450 | const struct ata_port_info *ppi[] = { &pi, NULL }; | ||
451 | struct ftide010 *ftide; | ||
452 | struct resource *res; | ||
453 | int irq; | ||
454 | int ret; | ||
455 | int i; | ||
456 | |||
457 | ftide = devm_kzalloc(dev, sizeof(*ftide), GFP_KERNEL); | ||
458 | if (!ftide) | ||
459 | return -ENOMEM; | ||
460 | ftide->dev = dev; | ||
461 | |||
462 | irq = platform_get_irq(pdev, 0); | ||
463 | if (irq < 0) | ||
464 | return irq; | ||
465 | |||
466 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
467 | if (!res) | ||
468 | return -ENODEV; | ||
469 | |||
470 | ftide->base = devm_ioremap_resource(dev, res); | ||
471 | if (IS_ERR(ftide->base)) | ||
472 | return PTR_ERR(ftide->base); | ||
473 | |||
474 | ftide->pclk = devm_clk_get(dev, "PCLK"); | ||
475 | if (!IS_ERR(ftide->pclk)) { | ||
476 | ret = clk_prepare_enable(ftide->pclk); | ||
477 | if (ret) { | ||
478 | dev_err(dev, "failed to enable PCLK\n"); | ||
479 | return ret; | ||
480 | } | ||
481 | } | ||
482 | |||
483 | /* Some special Cortina Gemini init, if needed */ | ||
484 | if (of_device_is_compatible(np, "cortina,gemini-pata")) { | ||
485 | /* | ||
486 | * We need to know which instance is probing (the | ||
487 | * Gemini has two instances of FTIDE010) and we do | ||
488 | * this simply by looking at the physical base | ||
489 | * address, which is 0x63400000 for ATA1, else we | ||
490 | * are ATA0. This will also set up the cable types. | ||
491 | */ | ||
492 | ret = pata_ftide010_gemini_init(ftide, | ||
493 | (res->start == 0x63400000)); | ||
494 | if (ret) | ||
495 | goto err_dis_clk; | ||
496 | } else { | ||
497 | /* Else assume we are connected using PATA40 */ | ||
498 | ftide->master_cbl = ATA_CBL_PATA40; | ||
499 | ftide->slave_cbl = ATA_CBL_PATA40; | ||
500 | } | ||
501 | |||
502 | ftide->host = ata_host_alloc_pinfo(dev, ppi, 1); | ||
503 | if (!ftide->host) { | ||
504 | ret = -ENOMEM; | ||
505 | goto err_dis_clk; | ||
506 | } | ||
507 | ftide->host->private_data = ftide; | ||
508 | |||
509 | for (i = 0; i < ftide->host->n_ports; i++) { | ||
510 | struct ata_port *ap = ftide->host->ports[i]; | ||
511 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
512 | |||
513 | ioaddr->bmdma_addr = ftide->base + FTIDE010_DMA_REG; | ||
514 | ioaddr->cmd_addr = ftide->base + FTIDE010_CMD_DATA; | ||
515 | ioaddr->ctl_addr = ftide->base + FTIDE010_ALTSTAT_CTRL; | ||
516 | ioaddr->altstatus_addr = ftide->base + FTIDE010_ALTSTAT_CTRL; | ||
517 | ata_sff_std_ports(ioaddr); | ||
518 | } | ||
519 | |||
520 | dev_info(dev, "device ID %08x, irq %d, io base 0x%08x\n", | ||
521 | readl(ftide->base + FTIDE010_IDE_DEVICE_ID), irq, res->start); | ||
522 | |||
523 | ret = ata_host_activate(ftide->host, irq, ata_bmdma_interrupt, | ||
524 | 0, &pata_ftide010_sht); | ||
525 | if (ret) | ||
526 | goto err_dis_clk; | ||
527 | |||
528 | return 0; | ||
529 | |||
530 | err_dis_clk: | ||
531 | if (!IS_ERR(ftide->pclk)) | ||
532 | clk_disable_unprepare(ftide->pclk); | ||
533 | return ret; | ||
534 | } | ||
535 | |||
536 | static int pata_ftide010_remove(struct platform_device *pdev) | ||
537 | { | ||
538 | struct ata_host *host = platform_get_drvdata(pdev); | ||
539 | struct ftide010 *ftide = host->private_data; | ||
540 | |||
541 | ata_host_detach(ftide->host); | ||
542 | if (!IS_ERR(ftide->pclk)) | ||
543 | clk_disable_unprepare(ftide->pclk); | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static const struct of_device_id pata_ftide010_of_match[] = { | ||
549 | { | ||
550 | .compatible = "faraday,ftide010", | ||
551 | }, | ||
552 | {}, | ||
553 | }; | ||
554 | |||
555 | static struct platform_driver pata_ftide010_driver = { | ||
556 | .driver = { | ||
557 | .name = DRV_NAME, | ||
558 | .of_match_table = of_match_ptr(pata_ftide010_of_match), | ||
559 | }, | ||
560 | .probe = pata_ftide010_probe, | ||
561 | .remove = pata_ftide010_remove, | ||
562 | }; | ||
563 | module_platform_driver(pata_ftide010_driver); | ||
564 | |||
565 | MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); | ||
566 | MODULE_LICENSE("GPL"); | ||
567 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c new file mode 100644 index 000000000000..8c704523bae7 --- /dev/null +++ b/drivers/ata/sata_gemini.c | |||
@@ -0,0 +1,438 @@ | |||
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); | ||
diff --git a/drivers/ata/sata_gemini.h b/drivers/ata/sata_gemini.h new file mode 100644 index 000000000000..ca1837a394c8 --- /dev/null +++ b/drivers/ata/sata_gemini.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* Header for the Gemini SATA bridge */ | ||
2 | #ifndef SATA_GEMINI_H | ||
3 | #define SATA_GEMINI_H | ||
4 | |||
5 | struct sata_gemini; | ||
6 | |||
7 | enum gemini_muxmode { | ||
8 | GEMINI_MUXMODE_0 = 0, | ||
9 | GEMINI_MUXMODE_1, | ||
10 | GEMINI_MUXMODE_2, | ||
11 | GEMINI_MUXMODE_3, | ||
12 | }; | ||
13 | |||
14 | struct sata_gemini *gemini_sata_bridge_get(void); | ||
15 | bool gemini_sata_bridge_enabled(struct sata_gemini *sg, bool is_ata1); | ||
16 | enum gemini_muxmode gemini_sata_get_muxmode(struct sata_gemini *sg); | ||
17 | int gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge); | ||
18 | void gemini_sata_stop_bridge(struct sata_gemini *sg, unsigned int bridge); | ||
19 | int gemini_sata_reset_bridge(struct sata_gemini *sg, unsigned int bridge); | ||
20 | |||
21 | #endif | ||