aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTim Yamin <plasm@roo.me.uk>2008-12-21 04:54:29 -0500
committerGrant Likely <grant.likely@secretlab.ca>2008-12-21 04:54:29 -0500
commit6b61e69e7bc1cfe80ab54c6321f19061f9487ed3 (patch)
tree0e3a4f9f8069186b385f1eba379fad6897df7c81 /drivers
parentaaab5e83c2c25d94f7409bdc947a5cc383514e15 (diff)
powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver
This patch adds MDMA/UDMA support using BestComm for DMA on the MPC5200 platform. Based heavily on previous work by Freescale (Bernard Kuhn, John Rigby) and Domen Puncer. With this patch, a SanDisk Extreme IV CF card gets read speeds of approximately 26.70 MB/sec. Signed-off-by: Tim Yamin <plasm@roo.me.uk> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/Kconfig3
-rw-r--r--drivers/ata/pata_mpc52xx.c546
2 files changed, 483 insertions, 66 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 421b7c71e72d..1a7be96d627b 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -456,7 +456,8 @@ config PATA_MARVELL
456 456
457config PATA_MPC52xx 457config PATA_MPC52xx
458 tristate "Freescale MPC52xx SoC internal IDE" 458 tristate "Freescale MPC52xx SoC internal IDE"
459 depends on PPC_MPC52xx 459 depends on PPC_MPC52xx && PPC_BESTCOMM
460 select PPC_BESTCOMM_ATA
460 help 461 help
461 This option enables support for integrated IDE controller 462 This option enables support for integrated IDE controller
462 of the Freescale MPC52xx SoC. 463 of the Freescale MPC52xx SoC.
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index a9e827356d06..50ae6d13078a 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -6,6 +6,9 @@
6 * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com> 6 * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
7 * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt 7 * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
8 * 8 *
9 * UDMA support based on patches by Freescale (Bernard Kuhn, John Rigby),
10 * Domen Puncer and Tim Yamin.
11 *
9 * This file is licensed under the terms of the GNU General Public License 12 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any 13 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied. 14 * kind, whether express or implied.
@@ -17,28 +20,46 @@
17#include <linux/delay.h> 20#include <linux/delay.h>
18#include <linux/libata.h> 21#include <linux/libata.h>
19#include <linux/of_platform.h> 22#include <linux/of_platform.h>
23#include <linux/types.h>
20 24
21#include <asm/types.h> 25#include <asm/cacheflush.h>
22#include <asm/prom.h> 26#include <asm/prom.h>
23#include <asm/mpc52xx.h> 27#include <asm/mpc52xx.h>
24 28
29#include <sysdev/bestcomm/bestcomm.h>
30#include <sysdev/bestcomm/bestcomm_priv.h>
31#include <sysdev/bestcomm/ata.h>
25 32
26#define DRV_NAME "mpc52xx_ata" 33#define DRV_NAME "mpc52xx_ata"
27#define DRV_VERSION "0.1.2"
28
29 34
30/* Private structures used by the driver */ 35/* Private structures used by the driver */
31struct mpc52xx_ata_timings { 36struct mpc52xx_ata_timings {
32 u32 pio1; 37 u32 pio1;
33 u32 pio2; 38 u32 pio2;
39 u32 mdma1;
40 u32 mdma2;
41 u32 udma1;
42 u32 udma2;
43 u32 udma3;
44 u32 udma4;
45 u32 udma5;
46 int using_udma;
34}; 47};
35 48
36struct mpc52xx_ata_priv { 49struct mpc52xx_ata_priv {
37 unsigned int ipb_period; 50 unsigned int ipb_period;
38 struct mpc52xx_ata __iomem * ata_regs; 51 struct mpc52xx_ata __iomem *ata_regs;
52 phys_addr_t ata_regs_pa;
39 int ata_irq; 53 int ata_irq;
40 struct mpc52xx_ata_timings timings[2]; 54 struct mpc52xx_ata_timings timings[2];
41 int csel; 55 int csel;
56
57 /* DMA */
58 struct bcom_task *dmatsk;
59 const struct udmaspec *udmaspec;
60 const struct mdmaspec *mdmaspec;
61 int mpc52xx_ata_dma_last_write;
62 int waiting_for_dma;
42}; 63};
43 64
44 65
@@ -53,6 +74,107 @@ static const int ataspec_ta[5] = { 35, 35, 35, 35, 35};
53 74
54#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c))) 75#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
55 76
77/* ======================================================================== */
78
79/* ATAPI-4 MDMA specs (in clocks) */
80struct mdmaspec {
81 u32 t0M;
82 u32 td;
83 u32 th;
84 u32 tj;
85 u32 tkw;
86 u32 tm;
87 u32 tn;
88};
89
90static const struct mdmaspec mdmaspec66[3] = {
91 { .t0M = 32, .td = 15, .th = 2, .tj = 2, .tkw = 15, .tm = 4, .tn = 1 },
92 { .t0M = 10, .td = 6, .th = 1, .tj = 1, .tkw = 4, .tm = 2, .tn = 1 },
93 { .t0M = 8, .td = 5, .th = 1, .tj = 1, .tkw = 2, .tm = 2, .tn = 1 },
94};
95
96static const struct mdmaspec mdmaspec132[3] = {
97 { .t0M = 64, .td = 29, .th = 3, .tj = 3, .tkw = 29, .tm = 7, .tn = 2 },
98 { .t0M = 20, .td = 11, .th = 2, .tj = 1, .tkw = 7, .tm = 4, .tn = 1 },
99 { .t0M = 16, .td = 10, .th = 2, .tj = 1, .tkw = 4, .tm = 4, .tn = 1 },
100};
101
102/* ATAPI-4 UDMA specs (in clocks) */
103struct udmaspec {
104 u32 tcyc;
105 u32 t2cyc;
106 u32 tds;
107 u32 tdh;
108 u32 tdvs;
109 u32 tdvh;
110 u32 tfs;
111 u32 tli;
112 u32 tmli;
113 u32 taz;
114 u32 tzah;
115 u32 tenv;
116 u32 tsr;
117 u32 trfs;
118 u32 trp;
119 u32 tack;
120 u32 tss;
121};
122
123static const struct udmaspec udmaspec66[6] = {
124 { .tcyc = 8, .t2cyc = 16, .tds = 1, .tdh = 1, .tdvs = 5, .tdvh = 1,
125 .tfs = 16, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
126 .tsr = 3, .trfs = 5, .trp = 11, .tack = 2, .tss = 4,
127 },
128 { .tcyc = 5, .t2cyc = 11, .tds = 1, .tdh = 1, .tdvs = 4, .tdvh = 1,
129 .tfs = 14, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
130 .tsr = 2, .trfs = 5, .trp = 9, .tack = 2, .tss = 4,
131 },
132 { .tcyc = 4, .t2cyc = 8, .tds = 1, .tdh = 1, .tdvs = 3, .tdvh = 1,
133 .tfs = 12, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
134 .tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
135 },
136 { .tcyc = 3, .t2cyc = 6, .tds = 1, .tdh = 1, .tdvs = 2, .tdvh = 1,
137 .tfs = 9, .tli = 7, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
138 .tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
139 },
140 { .tcyc = 2, .t2cyc = 4, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
141 .tfs = 8, .tli = 8, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
142 .tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
143 },
144 { .tcyc = 2, .t2cyc = 2, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
145 .tfs = 6, .tli = 5, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
146 .tsr = 2, .trfs = 4, .trp = 6, .tack = 2, .tss = 4,
147 },
148};
149
150static const struct udmaspec udmaspec132[6] = {
151 { .tcyc = 15, .t2cyc = 31, .tds = 2, .tdh = 1, .tdvs = 10, .tdvh = 1,
152 .tfs = 30, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
153 .tsr = 7, .trfs = 10, .trp = 22, .tack = 3, .tss = 7,
154 },
155 { .tcyc = 10, .t2cyc = 21, .tds = 2, .tdh = 1, .tdvs = 7, .tdvh = 1,
156 .tfs = 27, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
157 .tsr = 4, .trfs = 10, .trp = 17, .tack = 3, .tss = 7,
158 },
159 { .tcyc = 6, .t2cyc = 12, .tds = 1, .tdh = 1, .tdvs = 5, .tdvh = 1,
160 .tfs = 23, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
161 .tsr = 3, .trfs = 8, .trp = 14, .tack = 3, .tss = 7,
162 },
163 { .tcyc = 7, .t2cyc = 12, .tds = 1, .tdh = 1, .tdvs = 3, .tdvh = 1,
164 .tfs = 15, .tli = 13, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
165 .tsr = 3, .trfs = 8, .trp = 14, .tack = 3, .tss = 7,
166 },
167 { .tcyc = 2, .t2cyc = 5, .tds = 0, .tdh = 0, .tdvs = 1, .tdvh = 1,
168 .tfs = 16, .tli = 14, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
169 .tsr = 2, .trfs = 7, .trp = 13, .tack = 2, .tss = 6,
170 },
171 { .tcyc = 3, .t2cyc = 6, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
172 .tfs = 12, .tli = 10, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
173 .tsr = 3, .trfs = 7, .trp = 12, .tack = 3, .tss = 7,
174 },
175};
176
177/* ======================================================================== */
56 178
57/* Bit definitions inside the registers */ 179/* Bit definitions inside the registers */
58#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */ 180#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */
@@ -66,6 +188,7 @@ static const int ataspec_ta[5] = { 35, 35, 35, 35, 35};
66#define MPC52xx_ATA_HOSTSTAT_WERR 0x01000000UL /* Write Error */ 188#define MPC52xx_ATA_HOSTSTAT_WERR 0x01000000UL /* Write Error */
67 189
68#define MPC52xx_ATA_FIFOSTAT_EMPTY 0x01 /* FIFO Empty */ 190#define MPC52xx_ATA_FIFOSTAT_EMPTY 0x01 /* FIFO Empty */
191#define MPC52xx_ATA_FIFOSTAT_ERROR 0x40 /* FIFO Error */
69 192
70#define MPC52xx_ATA_DMAMODE_WRITE 0x01 /* Write DMA */ 193#define MPC52xx_ATA_DMAMODE_WRITE 0x01 /* Write DMA */
71#define MPC52xx_ATA_DMAMODE_READ 0x02 /* Read DMA */ 194#define MPC52xx_ATA_DMAMODE_READ 0x02 /* Read DMA */
@@ -75,6 +198,8 @@ static const int ataspec_ta[5] = { 35, 35, 35, 35, 35};
75#define MPC52xx_ATA_DMAMODE_FR 0x20 /* FIFO Reset */ 198#define MPC52xx_ATA_DMAMODE_FR 0x20 /* FIFO Reset */
76#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */ 199#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
77 200
201#define MAX_DMA_BUFFERS 128
202#define MAX_DMA_BUFFER_SIZE 0x20000u
78 203
79/* Structure of the hardware registers */ 204/* Structure of the hardware registers */
80struct mpc52xx_ata { 205struct mpc52xx_ata {
@@ -140,7 +265,6 @@ struct mpc52xx_ata {
140 265
141 266
142/* MPC52xx low level hw control */ 267/* MPC52xx low level hw control */
143
144static int 268static int
145mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio) 269mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
146{ 270{
@@ -148,7 +272,7 @@ mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
148 unsigned int ipb_period = priv->ipb_period; 272 unsigned int ipb_period = priv->ipb_period;
149 unsigned int t0, t1, t2_8, t2_16, t2i, t4, ta; 273 unsigned int t0, t1, t2_8, t2_16, t2i, t4, ta;
150 274
151 if ((pio<0) || (pio>4)) 275 if ((pio < 0) || (pio > 4))
152 return -EINVAL; 276 return -EINVAL;
153 277
154 t0 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t0[pio]); 278 t0 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t0[pio]);
@@ -165,6 +289,43 @@ mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
165 return 0; 289 return 0;
166} 290}
167 291
292static int
293mpc52xx_ata_compute_mdma_timings(struct mpc52xx_ata_priv *priv, int dev,
294 int speed)
295{
296 struct mpc52xx_ata_timings *t = &priv->timings[dev];
297 const struct mdmaspec *s = &priv->mdmaspec[speed];
298
299 if (speed < 0 || speed > 2)
300 return -EINVAL;
301
302 t->mdma1 = (s->t0M << 24) | (s->td << 16) | (s->tkw << 8) | (s->tm);
303 t->mdma2 = (s->th << 24) | (s->tj << 16) | (s->tn << 8);
304 t->using_udma = 0;
305
306 return 0;
307}
308
309static int
310mpc52xx_ata_compute_udma_timings(struct mpc52xx_ata_priv *priv, int dev,
311 int speed)
312{
313 struct mpc52xx_ata_timings *t = &priv->timings[dev];
314 const struct udmaspec *s = &priv->udmaspec[speed];
315
316 if (speed < 0 || speed > 2)
317 return -EINVAL;
318
319 t->udma1 = (s->t2cyc << 24) | (s->tcyc << 16) | (s->tds << 8) | s->tdh;
320 t->udma2 = (s->tdvs << 24) | (s->tdvh << 16) | (s->tfs << 8) | s->tli;
321 t->udma3 = (s->tmli << 24) | (s->taz << 16) | (s->tenv << 8) | s->tsr;
322 t->udma4 = (s->tss << 24) | (s->trfs << 16) | (s->trp << 8) | s->tack;
323 t->udma5 = (s->tzah << 24);
324 t->using_udma = 1;
325
326 return 0;
327}
328
168static void 329static void
169mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device) 330mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
170{ 331{
@@ -173,14 +334,13 @@ mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
173 334
174 out_be32(&regs->pio1, timing->pio1); 335 out_be32(&regs->pio1, timing->pio1);
175 out_be32(&regs->pio2, timing->pio2); 336 out_be32(&regs->pio2, timing->pio2);
176 out_be32(&regs->mdma1, 0); 337 out_be32(&regs->mdma1, timing->mdma1);
177 out_be32(&regs->mdma2, 0); 338 out_be32(&regs->mdma2, timing->mdma2);
178 out_be32(&regs->udma1, 0); 339 out_be32(&regs->udma1, timing->udma1);
179 out_be32(&regs->udma2, 0); 340 out_be32(&regs->udma2, timing->udma2);
180 out_be32(&regs->udma3, 0); 341 out_be32(&regs->udma3, timing->udma3);
181 out_be32(&regs->udma4, 0); 342 out_be32(&regs->udma4, timing->udma4);
182 out_be32(&regs->udma5, 0); 343 out_be32(&regs->udma5, timing->udma5);
183
184 priv->csel = device; 344 priv->csel = device;
185} 345}
186 346
@@ -208,7 +368,7 @@ mpc52xx_ata_hw_init(struct mpc52xx_ata_priv *priv)
208 368
209 /* Set the time slot to 1us */ 369 /* Set the time slot to 1us */
210 tslot = CALC_CLKCYC(priv->ipb_period, 1000000); 370 tslot = CALC_CLKCYC(priv->ipb_period, 1000000);
211 out_be32(&regs->share_cnt, tslot << 16 ); 371 out_be32(&regs->share_cnt, tslot << 16);
212 372
213 /* Init timings to PIO0 */ 373 /* Init timings to PIO0 */
214 memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings)); 374 memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings));
@@ -237,13 +397,37 @@ mpc52xx_ata_set_piomode(struct ata_port *ap, struct ata_device *adev)
237 rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio); 397 rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio);
238 398
239 if (rv) { 399 if (rv) {
240 printk(KERN_ERR DRV_NAME 400 dev_err(ap->dev, "error: invalid PIO mode: %d\n", pio);
241 ": Trying to select invalid PIO mode %d\n", pio); 401 return;
402 }
403
404 mpc52xx_ata_apply_timings(priv, adev->devno);
405}
406
407static void
408mpc52xx_ata_set_dmamode(struct ata_port *ap, struct ata_device *adev)
409{
410 struct mpc52xx_ata_priv *priv = ap->host->private_data;
411 int rv;
412
413 if (adev->dma_mode >= XFER_UDMA_0) {
414 int dma = adev->dma_mode - XFER_UDMA_0;
415 rv = mpc52xx_ata_compute_udma_timings(priv, adev->devno, dma);
416 } else {
417 int dma = adev->dma_mode - XFER_MW_DMA_0;
418 rv = mpc52xx_ata_compute_mdma_timings(priv, adev->devno, dma);
419 }
420
421 if (rv) {
422 dev_alert(ap->dev,
423 "Trying to select invalid DMA mode %d\n",
424 adev->dma_mode);
242 return; 425 return;
243 } 426 }
244 427
245 mpc52xx_ata_apply_timings(priv, adev->devno); 428 mpc52xx_ata_apply_timings(priv, adev->devno);
246} 429}
430
247static void 431static void
248mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device) 432mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
249{ 433{
@@ -252,7 +436,173 @@ mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
252 if (device != priv->csel) 436 if (device != priv->csel)
253 mpc52xx_ata_apply_timings(priv, device); 437 mpc52xx_ata_apply_timings(priv, device);
254 438
255 ata_sff_dev_select(ap,device); 439 ata_sff_dev_select(ap, device);
440}
441
442static int
443mpc52xx_ata_build_dmatable(struct ata_queued_cmd *qc)
444{
445 struct ata_port *ap = qc->ap;
446 struct mpc52xx_ata_priv *priv = ap->host->private_data;
447 struct bcom_ata_bd *bd;
448 unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE), si;
449 struct scatterlist *sg;
450 int count = 0;
451
452 if (read)
453 bcom_ata_rx_prepare(priv->dmatsk);
454 else
455 bcom_ata_tx_prepare(priv->dmatsk);
456
457 for_each_sg(qc->sg, sg, qc->n_elem, si) {
458 dma_addr_t cur_addr = sg_dma_address(sg);
459 u32 cur_len = sg_dma_len(sg);
460
461 while (cur_len) {
462 unsigned int tc = min(cur_len, MAX_DMA_BUFFER_SIZE);
463 bd = (struct bcom_ata_bd *)
464 bcom_prepare_next_buffer(priv->dmatsk);
465
466 if (read) {
467 bd->status = tc;
468 bd->src_pa = (__force u32) priv->ata_regs_pa +
469 offsetof(struct mpc52xx_ata, fifo_data);
470 bd->dst_pa = (__force u32) cur_addr;
471 } else {
472 bd->status = tc;
473 bd->src_pa = (__force u32) cur_addr;
474 bd->dst_pa = (__force u32) priv->ata_regs_pa +
475 offsetof(struct mpc52xx_ata, fifo_data);
476 }
477
478 bcom_submit_next_buffer(priv->dmatsk, NULL);
479
480 cur_addr += tc;
481 cur_len -= tc;
482 count++;
483
484 if (count > MAX_DMA_BUFFERS) {
485 dev_alert(ap->dev, "dma table"
486 "too small\n");
487 goto use_pio_instead;
488 }
489 }
490 }
491 return 1;
492
493 use_pio_instead:
494 bcom_ata_reset_bd(priv->dmatsk);
495 return 0;
496}
497
498static void
499mpc52xx_bmdma_setup(struct ata_queued_cmd *qc)
500{
501 struct ata_port *ap = qc->ap;
502 struct mpc52xx_ata_priv *priv = ap->host->private_data;
503 struct mpc52xx_ata __iomem *regs = priv->ata_regs;
504
505 unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE);
506 u8 dma_mode;
507
508 if (!mpc52xx_ata_build_dmatable(qc))
509 dev_alert(ap->dev, "%s: %i, return 1?\n",
510 __func__, __LINE__);
511
512 /* Check FIFO is OK... */
513 if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR)
514 dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
515 __func__, in_8(&priv->ata_regs->fifo_status));
516
517 if (read) {
518 dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_READ |
519 MPC52xx_ATA_DMAMODE_FE;
520
521 /* Setup FIFO if direction changed */
522 if (priv->mpc52xx_ata_dma_last_write != 0) {
523 priv->mpc52xx_ata_dma_last_write = 0;
524
525 /* Configure FIFO with granularity to 7 */
526 out_8(&regs->fifo_control, 7);
527 out_be16(&regs->fifo_alarm, 128);
528
529 /* Set FIFO Reset bit (FR) */
530 out_8(&regs->dma_mode, MPC52xx_ATA_DMAMODE_FR);
531 }
532 } else {
533 dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_WRITE;
534
535 /* Setup FIFO if direction changed */
536 if (priv->mpc52xx_ata_dma_last_write != 1) {
537 priv->mpc52xx_ata_dma_last_write = 1;
538
539 /* Configure FIFO with granularity to 4 */
540 out_8(&regs->fifo_control, 4);
541 out_be16(&regs->fifo_alarm, 128);
542 }
543 }
544
545 if (priv->timings[qc->dev->devno].using_udma)
546 dma_mode |= MPC52xx_ATA_DMAMODE_UDMA;
547
548 out_8(&regs->dma_mode, dma_mode);
549 priv->waiting_for_dma = ATA_DMA_ACTIVE;
550
551 ata_wait_idle(ap);
552 ap->ops->sff_exec_command(ap, &qc->tf);
553}
554
555static void
556mpc52xx_bmdma_start(struct ata_queued_cmd *qc)
557{
558 struct ata_port *ap = qc->ap;
559 struct mpc52xx_ata_priv *priv = ap->host->private_data;
560
561 bcom_set_task_auto_start(priv->dmatsk->tasknum, priv->dmatsk->tasknum);
562 bcom_enable(priv->dmatsk);
563}
564
565static void
566mpc52xx_bmdma_stop(struct ata_queued_cmd *qc)
567{
568 struct ata_port *ap = qc->ap;
569 struct mpc52xx_ata_priv *priv = ap->host->private_data;
570
571 bcom_disable(priv->dmatsk);
572 bcom_ata_reset_bd(priv->dmatsk);
573 priv->waiting_for_dma = 0;
574
575 /* Check FIFO is OK... */
576 if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR)
577 dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
578 __func__, in_8(&priv->ata_regs->fifo_status));
579}
580
581static u8
582mpc52xx_bmdma_status(struct ata_port *ap)
583{
584 struct mpc52xx_ata_priv *priv = ap->host->private_data;
585
586 /* Check FIFO is OK... */
587 if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR) {
588 dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
589 __func__, in_8(&priv->ata_regs->fifo_status));
590 return priv->waiting_for_dma | ATA_DMA_ERR;
591 }
592
593 return priv->waiting_for_dma;
594}
595
596static irqreturn_t
597mpc52xx_ata_task_irq(int irq, void *vpriv)
598{
599 struct mpc52xx_ata_priv *priv = vpriv;
600 while (bcom_buffer_done(priv->dmatsk))
601 bcom_retrieve_buffer(priv->dmatsk, NULL, NULL);
602
603 priv->waiting_for_dma |= ATA_DMA_INTR;
604
605 return IRQ_HANDLED;
256} 606}
257 607
258static struct scsi_host_template mpc52xx_ata_sht = { 608static struct scsi_host_template mpc52xx_ata_sht = {
@@ -262,14 +612,18 @@ static struct scsi_host_template mpc52xx_ata_sht = {
262static struct ata_port_operations mpc52xx_ata_port_ops = { 612static struct ata_port_operations mpc52xx_ata_port_ops = {
263 .inherits = &ata_sff_port_ops, 613 .inherits = &ata_sff_port_ops,
264 .sff_dev_select = mpc52xx_ata_dev_select, 614 .sff_dev_select = mpc52xx_ata_dev_select,
265 .cable_detect = ata_cable_40wire,
266 .set_piomode = mpc52xx_ata_set_piomode, 615 .set_piomode = mpc52xx_ata_set_piomode,
267 .post_internal_cmd = ATA_OP_NULL, 616 .set_dmamode = mpc52xx_ata_set_dmamode,
617 .bmdma_setup = mpc52xx_bmdma_setup,
618 .bmdma_start = mpc52xx_bmdma_start,
619 .bmdma_stop = mpc52xx_bmdma_stop,
620 .bmdma_status = mpc52xx_bmdma_status,
621 .qc_prep = ata_noop_qc_prep,
268}; 622};
269 623
270static int __devinit 624static int __devinit
271mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv, 625mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
272 unsigned long raw_ata_regs) 626 unsigned long raw_ata_regs, int mwdma_mask, int udma_mask)
273{ 627{
274 struct ata_host *host; 628 struct ata_host *host;
275 struct ata_port *ap; 629 struct ata_port *ap;
@@ -281,9 +635,9 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
281 635
282 ap = host->ports[0]; 636 ap = host->ports[0];
283 ap->flags |= ATA_FLAG_SLAVE_POSS; 637 ap->flags |= ATA_FLAG_SLAVE_POSS;
284 ap->pio_mask = 0x1f; /* Up to PIO4 */ 638 ap->pio_mask = ATA_PIO4;
285 ap->mwdma_mask = 0x00; /* No MWDMA */ 639 ap->mwdma_mask = mwdma_mask;
286 ap->udma_mask = 0x00; /* No UDMA */ 640 ap->udma_mask = udma_mask;
287 ap->ops = &mpc52xx_ata_port_ops; 641 ap->ops = &mpc52xx_ata_port_ops;
288 host->private_data = priv; 642 host->private_data = priv;
289 643
@@ -330,89 +684,139 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
330{ 684{
331 unsigned int ipb_freq; 685 unsigned int ipb_freq;
332 struct resource res_mem; 686 struct resource res_mem;
333 int ata_irq; 687 int ata_irq = 0;
334 struct mpc52xx_ata __iomem *ata_regs; 688 struct mpc52xx_ata __iomem *ata_regs;
335 struct mpc52xx_ata_priv *priv; 689 struct mpc52xx_ata_priv *priv = NULL;
336 int rv; 690 int rv, ret, task_irq = 0;
691 int mwdma_mask = 0, udma_mask = 0;
692 const __be32 *prop;
693 int proplen;
694 struct bcom_task *dmatsk = NULL;
337 695
338 /* Get ipb frequency */ 696 /* Get ipb frequency */
339 ipb_freq = mpc52xx_find_ipb_freq(op->node); 697 ipb_freq = mpc52xx_find_ipb_freq(op->node);
340 if (!ipb_freq) { 698 if (!ipb_freq) {
341 printk(KERN_ERR DRV_NAME ": " 699 dev_err(&op->dev, "could not determine IPB bus frequency\n");
342 "Unable to find IPB Bus frequency\n" );
343 return -ENODEV; 700 return -ENODEV;
344 } 701 }
345 702
346 /* Get IRQ and register */ 703 /* Get device base address from device tree, request the region
704 * and ioremap it. */
347 rv = of_address_to_resource(op->node, 0, &res_mem); 705 rv = of_address_to_resource(op->node, 0, &res_mem);
348 if (rv) { 706 if (rv) {
349 printk(KERN_ERR DRV_NAME ": " 707 dev_err(&op->dev, "could not determine device base address\n");
350 "Error while parsing device node resource\n" );
351 return rv; 708 return rv;
352 } 709 }
353 710
354 ata_irq = irq_of_parse_and_map(op->node, 0);
355 if (ata_irq == NO_IRQ) {
356 printk(KERN_ERR DRV_NAME ": "
357 "Error while mapping the irq\n");
358 return -EINVAL;
359 }
360
361 /* Request mem region */
362 if (!devm_request_mem_region(&op->dev, res_mem.start, 711 if (!devm_request_mem_region(&op->dev, res_mem.start,
363 sizeof(struct mpc52xx_ata), DRV_NAME)) { 712 sizeof(*ata_regs), DRV_NAME)) {
364 printk(KERN_ERR DRV_NAME ": " 713 dev_err(&op->dev, "error requesting register region\n");
365 "Error while requesting mem region\n"); 714 return -EBUSY;
366 rv = -EBUSY;
367 goto err;
368 } 715 }
369 716
370 /* Remap registers */ 717 ata_regs = devm_ioremap(&op->dev, res_mem.start, sizeof(*ata_regs));
371 ata_regs = devm_ioremap(&op->dev, res_mem.start,
372 sizeof(struct mpc52xx_ata));
373 if (!ata_regs) { 718 if (!ata_regs) {
374 printk(KERN_ERR DRV_NAME ": " 719 dev_err(&op->dev, "error mapping device registers\n");
375 "Error while mapping register set\n");
376 rv = -ENOMEM; 720 rv = -ENOMEM;
377 goto err; 721 goto err;
378 } 722 }
379 723
724 /*
725 * By default, all DMA modes are disabled for the MPC5200. Some
726 * boards don't have the required signals routed to make DMA work.
727 * Also, the MPC5200B has a silicon bug that causes data corruption
728 * with UDMA if it is used at the same time as the LocalPlus bus.
729 *
730 * Instead of trying to guess what modes are usable, check the
731 * ATA device tree node to find out what DMA modes work on the board.
732 * UDMA/MWDMA modes can also be forced by adding "libata.force=<mode>"
733 * to the kernel boot parameters.
734 *
735 * The MPC5200 ATA controller supports MWDMA modes 0, 1 and 2 and
736 * UDMA modes 0, 1 and 2.
737 */
738 prop = of_get_property(op->node, "mwdma-mode", &proplen);
739 if ((prop) && (proplen >= 4))
740 mwdma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
741 prop = of_get_property(op->node, "udma-mode", &proplen);
742 if ((prop) && (proplen >= 4))
743 udma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
744
745 ata_irq = irq_of_parse_and_map(op->node, 0);
746 if (ata_irq == NO_IRQ) {
747 dev_err(&op->dev, "error mapping irq\n");
748 return -EINVAL;
749 }
750
380 /* Prepare our private structure */ 751 /* Prepare our private structure */
381 priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv), 752 priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_ATOMIC);
382 GFP_ATOMIC);
383 if (!priv) { 753 if (!priv) {
384 printk(KERN_ERR DRV_NAME ": " 754 dev_err(&op->dev, "error allocating private structure\n");
385 "Error while allocating private structure\n");
386 rv = -ENOMEM; 755 rv = -ENOMEM;
387 goto err; 756 goto err;
388 } 757 }
389 758
390 priv->ipb_period = 1000000000 / (ipb_freq / 1000); 759 priv->ipb_period = 1000000000 / (ipb_freq / 1000);
391 priv->ata_regs = ata_regs; 760 priv->ata_regs = ata_regs;
761 priv->ata_regs_pa = res_mem.start;
392 priv->ata_irq = ata_irq; 762 priv->ata_irq = ata_irq;
393 priv->csel = -1; 763 priv->csel = -1;
764 priv->mpc52xx_ata_dma_last_write = -1;
765
766 if (ipb_freq/1000000 == 66) {
767 priv->mdmaspec = mdmaspec66;
768 priv->udmaspec = udmaspec66;
769 } else {
770 priv->mdmaspec = mdmaspec132;
771 priv->udmaspec = udmaspec132;
772 }
773
774 /* Allocate a BestComm task for DMA */
775 dmatsk = bcom_ata_init(MAX_DMA_BUFFERS, MAX_DMA_BUFFER_SIZE);
776 if (!dmatsk) {
777 dev_err(&op->dev, "bestcomm initialization failed\n");
778 rv = -ENOMEM;
779 goto err;
780 }
781
782 task_irq = bcom_get_task_irq(dmatsk);
783 ret = request_irq(task_irq, &mpc52xx_ata_task_irq, IRQF_DISABLED,
784 "ATA task", priv);
785 if (ret) {
786 dev_err(&op->dev, "error requesting DMA IRQ\n");
787 goto err;
788 }
789 priv->dmatsk = dmatsk;
394 790
395 /* Init the hw */ 791 /* Init the hw */
396 rv = mpc52xx_ata_hw_init(priv); 792 rv = mpc52xx_ata_hw_init(priv);
397 if (rv) { 793 if (rv) {
398 printk(KERN_ERR DRV_NAME ": Error during HW init\n"); 794 dev_err(&op->dev, "error initializing hardware\n");
399 goto err; 795 goto err;
400 } 796 }
401 797
402 /* Register ourselves to libata */ 798 /* Register ourselves to libata */
403 rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start); 799 rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start,
800 mwdma_mask, udma_mask);
404 if (rv) { 801 if (rv) {
405 printk(KERN_ERR DRV_NAME ": " 802 dev_err(&op->dev, "error registering with ATA layer\n");
406 "Error while registering to ATA layer\n"); 803 goto err;
407 return rv;
408 } 804 }
409 805
410 /* Done */
411 return 0; 806 return 0;
412 807
413 /* Error path */ 808 err:
414err: 809 devm_release_mem_region(&op->dev, res_mem.start, sizeof(*ata_regs));
415 irq_dispose_mapping(ata_irq); 810 if (ata_irq)
811 irq_dispose_mapping(ata_irq);
812 if (task_irq)
813 irq_dispose_mapping(task_irq);
814 if (dmatsk)
815 bcom_ata_release(dmatsk);
816 if (ata_regs)
817 devm_iounmap(&op->dev, ata_regs);
818 if (priv)
819 devm_kfree(&op->dev, priv);
416 return rv; 820 return rv;
417} 821}
418 822
@@ -420,10 +824,23 @@ static int
420mpc52xx_ata_remove(struct of_device *op) 824mpc52xx_ata_remove(struct of_device *op)
421{ 825{
422 struct mpc52xx_ata_priv *priv; 826 struct mpc52xx_ata_priv *priv;
827 int task_irq;
423 828
829 /* Deregister the ATA interface */
424 priv = mpc52xx_ata_remove_one(&op->dev); 830 priv = mpc52xx_ata_remove_one(&op->dev);
831
832 /* Clean up DMA */
833 task_irq = bcom_get_task_irq(priv->dmatsk);
834 irq_dispose_mapping(task_irq);
835 bcom_ata_release(priv->dmatsk);
425 irq_dispose_mapping(priv->ata_irq); 836 irq_dispose_mapping(priv->ata_irq);
426 837
838 /* Clear up IO allocations */
839 devm_iounmap(&op->dev, priv->ata_regs);
840 devm_release_mem_region(&op->dev, priv->ata_regs_pa,
841 sizeof(*priv->ata_regs));
842 devm_kfree(&op->dev, priv);
843
427 return 0; 844 return 0;
428} 845}
429 846
@@ -447,7 +864,7 @@ mpc52xx_ata_resume(struct of_device *op)
447 864
448 rv = mpc52xx_ata_hw_init(priv); 865 rv = mpc52xx_ata_hw_init(priv);
449 if (rv) { 866 if (rv) {
450 printk(KERN_ERR DRV_NAME ": Error during HW init\n"); 867 dev_err(host->dev, "error initializing hardware\n");
451 return rv; 868 return rv;
452 } 869 }
453 870
@@ -507,5 +924,4 @@ MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
507MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA libata driver"); 924MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA libata driver");
508MODULE_LICENSE("GPL"); 925MODULE_LICENSE("GPL");
509MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match); 926MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match);
510MODULE_VERSION(DRV_VERSION);
511 927