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