root/drivers/ata/pata_mpc52xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mpc52xx_ata_compute_pio_timings
  2. mpc52xx_ata_compute_mdma_timings
  3. mpc52xx_ata_compute_udma_timings
  4. mpc52xx_ata_apply_timings
  5. mpc52xx_ata_hw_init
  6. mpc52xx_ata_set_piomode
  7. mpc52xx_ata_set_dmamode
  8. mpc52xx_ata_dev_select
  9. mpc52xx_ata_build_dmatable
  10. mpc52xx_bmdma_setup
  11. mpc52xx_bmdma_start
  12. mpc52xx_bmdma_stop
  13. mpc52xx_bmdma_status
  14. mpc52xx_ata_task_irq
  15. mpc52xx_ata_init_one
  16. mpc52xx_ata_probe
  17. mpc52xx_ata_remove
  18. mpc52xx_ata_suspend
  19. mpc52xx_ata_resume

   1 /*
   2  * drivers/ata/pata_mpc52xx.c
   3  *
   4  * libata driver for the Freescale MPC52xx on-chip IDE interface
   5  *
   6  * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
   7  * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
   8  *
   9  * UDMA support based on patches by Freescale (Bernard Kuhn, John Rigby),
  10  * Domen Puncer and Tim Yamin.
  11  *
  12  * This file is licensed under the terms of the GNU General Public License
  13  * version 2. This program is licensed "as is" without any warranty of any
  14  * kind, whether express or implied.
  15  */
  16 
  17 #include <linux/kernel.h>
  18 #include <linux/module.h>
  19 #include <linux/gfp.h>
  20 #include <linux/delay.h>
  21 #include <linux/libata.h>
  22 #include <linux/of_platform.h>
  23 #include <linux/types.h>
  24 
  25 #include <asm/cacheflush.h>
  26 #include <asm/prom.h>
  27 #include <asm/mpc52xx.h>
  28 
  29 #include <linux/fsl/bestcomm/bestcomm.h>
  30 #include <linux/fsl/bestcomm/bestcomm_priv.h>
  31 #include <linux/fsl/bestcomm/ata.h>
  32 
  33 #define DRV_NAME        "mpc52xx_ata"
  34 
  35 /* Private structures used by the driver */
  36 struct mpc52xx_ata_timings {
  37         u32     pio1;
  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;
  47 };
  48 
  49 struct mpc52xx_ata_priv {
  50         unsigned int                    ipb_period;
  51         struct mpc52xx_ata __iomem      *ata_regs;
  52         phys_addr_t                     ata_regs_pa;
  53         int                             ata_irq;
  54         struct mpc52xx_ata_timings      timings[2];
  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;
  63 };
  64 
  65 
  66 /* ATAPI-4 PIO specs (in ns) */
  67 static const u16 ataspec_t0[5]          = {600, 383, 240, 180, 120};
  68 static const u16 ataspec_t1[5]          = { 70,  50,  30,  30,  25};
  69 static const u16 ataspec_t2_8[5]        = {290, 290, 290,  80,  70};
  70 static const u16 ataspec_t2_16[5]       = {165, 125, 100,  80,  70};
  71 static const u16 ataspec_t2i[5]         = {  0,   0,   0,  70,  25};
  72 static const u16 ataspec_t4[5]          = { 30,  20,  15,  10,  10};
  73 static const u16 ataspec_ta[5]          = { 35,  35,  35,  35,  35};
  74 
  75 #define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
  76 
  77 /* ======================================================================== */
  78 
  79 /* ATAPI-4 MDMA specs (in clocks) */
  80 struct mdmaspec {
  81         u8 t0M;
  82         u8 td;
  83         u8 th;
  84         u8 tj;
  85         u8 tkw;
  86         u8 tm;
  87         u8 tn;
  88 };
  89 
  90 static 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 
  96 static 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) */
 103 struct udmaspec {
 104         u8 tcyc;
 105         u8 t2cyc;
 106         u8 tds;
 107         u8 tdh;
 108         u8 tdvs;
 109         u8 tdvh;
 110         u8 tfs;
 111         u8 tli;
 112         u8 tmli;
 113         u8 taz;
 114         u8 tzah;
 115         u8 tenv;
 116         u8 tsr;
 117         u8 trfs;
 118         u8 trp;
 119         u8 tack;
 120         u8 tss;
 121 };
 122 
 123 static 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 
 150 static 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 /* ======================================================================== */
 178 
 179 /* Bit definitions inside the registers */
 180 #define MPC52xx_ATA_HOSTCONF_SMR        0x80000000UL /* State machine reset */
 181 #define MPC52xx_ATA_HOSTCONF_FR         0x40000000UL /* FIFO Reset */
 182 #define MPC52xx_ATA_HOSTCONF_IE         0x02000000UL /* Enable interrupt in PIO */
 183 #define MPC52xx_ATA_HOSTCONF_IORDY      0x01000000UL /* Drive supports IORDY protocol */
 184 
 185 #define MPC52xx_ATA_HOSTSTAT_TIP        0x80000000UL /* Transaction in progress */
 186 #define MPC52xx_ATA_HOSTSTAT_UREP       0x40000000UL /* UDMA Read Extended Pause */
 187 #define MPC52xx_ATA_HOSTSTAT_RERR       0x02000000UL /* Read Error */
 188 #define MPC52xx_ATA_HOSTSTAT_WERR       0x01000000UL /* Write Error */
 189 
 190 #define MPC52xx_ATA_FIFOSTAT_EMPTY      0x01 /* FIFO Empty */
 191 #define MPC52xx_ATA_FIFOSTAT_ERROR      0x40 /* FIFO Error */
 192 
 193 #define MPC52xx_ATA_DMAMODE_WRITE       0x01 /* Write DMA */
 194 #define MPC52xx_ATA_DMAMODE_READ        0x02 /* Read DMA */
 195 #define MPC52xx_ATA_DMAMODE_UDMA        0x04 /* UDMA enabled */
 196 #define MPC52xx_ATA_DMAMODE_IE          0x08 /* Enable drive interrupt to CPU in DMA mode */
 197 #define MPC52xx_ATA_DMAMODE_FE          0x10 /* FIFO Flush enable in Rx mode */
 198 #define MPC52xx_ATA_DMAMODE_FR          0x20 /* FIFO Reset */
 199 #define MPC52xx_ATA_DMAMODE_HUT         0x40 /* Host UDMA burst terminate */
 200 
 201 #define MAX_DMA_BUFFERS 128
 202 #define MAX_DMA_BUFFER_SIZE 0x20000u
 203 
 204 /* Structure of the hardware registers */
 205 struct mpc52xx_ata {
 206 
 207         /* Host interface registers */
 208         u32 config;             /* ATA + 0x00 Host configuration */
 209         u32 host_status;        /* ATA + 0x04 Host controller status */
 210         u32 pio1;               /* ATA + 0x08 PIO Timing 1 */
 211         u32 pio2;               /* ATA + 0x0c PIO Timing 2 */
 212         u32 mdma1;              /* ATA + 0x10 MDMA Timing 1 */
 213         u32 mdma2;              /* ATA + 0x14 MDMA Timing 2 */
 214         u32 udma1;              /* ATA + 0x18 UDMA Timing 1 */
 215         u32 udma2;              /* ATA + 0x1c UDMA Timing 2 */
 216         u32 udma3;              /* ATA + 0x20 UDMA Timing 3 */
 217         u32 udma4;              /* ATA + 0x24 UDMA Timing 4 */
 218         u32 udma5;              /* ATA + 0x28 UDMA Timing 5 */
 219         u32 share_cnt;          /* ATA + 0x2c ATA share counter */
 220         u32 reserved0[3];
 221 
 222         /* FIFO registers */
 223         u32 fifo_data;          /* ATA + 0x3c */
 224         u8  fifo_status_frame;  /* ATA + 0x40 */
 225         u8  fifo_status;        /* ATA + 0x41 */
 226         u16 reserved7[1];
 227         u8  fifo_control;       /* ATA + 0x44 */
 228         u8  reserved8[5];
 229         u16 fifo_alarm;         /* ATA + 0x4a */
 230         u16 reserved9;
 231         u16 fifo_rdp;           /* ATA + 0x4e */
 232         u16 reserved10;
 233         u16 fifo_wrp;           /* ATA + 0x52 */
 234         u16 reserved11;
 235         u16 fifo_lfrdp;         /* ATA + 0x56 */
 236         u16 reserved12;
 237         u16 fifo_lfwrp;         /* ATA + 0x5a */
 238 
 239         /* Drive TaskFile registers */
 240         u8  tf_control;         /* ATA + 0x5c TASKFILE Control/Alt Status */
 241         u8  reserved13[3];
 242         u16 tf_data;            /* ATA + 0x60 TASKFILE Data */
 243         u16 reserved14;
 244         u8  tf_features;        /* ATA + 0x64 TASKFILE Features/Error */
 245         u8  reserved15[3];
 246         u8  tf_sec_count;       /* ATA + 0x68 TASKFILE Sector Count */
 247         u8  reserved16[3];
 248         u8  tf_sec_num;         /* ATA + 0x6c TASKFILE Sector Number */
 249         u8  reserved17[3];
 250         u8  tf_cyl_low;         /* ATA + 0x70 TASKFILE Cylinder Low */
 251         u8  reserved18[3];
 252         u8  tf_cyl_high;        /* ATA + 0x74 TASKFILE Cylinder High */
 253         u8  reserved19[3];
 254         u8  tf_dev_head;        /* ATA + 0x78 TASKFILE Device/Head */
 255         u8  reserved20[3];
 256         u8  tf_command;         /* ATA + 0x7c TASKFILE Command/Status */
 257         u8  dma_mode;           /* ATA + 0x7d ATA Host DMA Mode configuration */
 258         u8  reserved21[2];
 259 };
 260 
 261 
 262 /* ======================================================================== */
 263 /* Aux fns                                                                  */
 264 /* ======================================================================== */
 265 
 266 
 267 /* MPC52xx low level hw control */
 268 static int
 269 mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
 270 {
 271         struct mpc52xx_ata_timings *timing = &priv->timings[dev];
 272         unsigned int ipb_period = priv->ipb_period;
 273         u32 t0, t1, t2_8, t2_16, t2i, t4, ta;
 274 
 275         if ((pio < 0) || (pio > 4))
 276                 return -EINVAL;
 277 
 278         t0      = CALC_CLKCYC(ipb_period, 1000 * ataspec_t0[pio]);
 279         t1      = CALC_CLKCYC(ipb_period, 1000 * ataspec_t1[pio]);
 280         t2_8    = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2_8[pio]);
 281         t2_16   = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2_16[pio]);
 282         t2i     = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2i[pio]);
 283         t4      = CALC_CLKCYC(ipb_period, 1000 * ataspec_t4[pio]);
 284         ta      = CALC_CLKCYC(ipb_period, 1000 * ataspec_ta[pio]);
 285 
 286         timing->pio1 = (t0 << 24) | (t2_8 << 16) | (t2_16 << 8) | (t2i);
 287         timing->pio2 = (t4 << 24) | (t1 << 16) | (ta << 8);
 288 
 289         return 0;
 290 }
 291 
 292 static int
 293 mpc52xx_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 = ((u32)s->t0M << 24) | ((u32)s->td << 16) | ((u32)s->tkw << 8) | s->tm;
 303         t->mdma2 = ((u32)s->th << 24) | ((u32)s->tj << 16) | ((u32)s->tn << 8);
 304         t->using_udma = 0;
 305 
 306         return 0;
 307 }
 308 
 309 static int
 310 mpc52xx_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 = ((u32)s->t2cyc << 24) | ((u32)s->tcyc << 16) | ((u32)s->tds << 8) | s->tdh;
 320         t->udma2 = ((u32)s->tdvs << 24) | ((u32)s->tdvh << 16) | ((u32)s->tfs << 8) | s->tli;
 321         t->udma3 = ((u32)s->tmli << 24) | ((u32)s->taz << 16) | ((u32)s->tenv << 8) | s->tsr;
 322         t->udma4 = ((u32)s->tss << 24) | ((u32)s->trfs << 16) | ((u32)s->trp << 8) | s->tack;
 323         t->udma5 = (u32)s->tzah << 24;
 324         t->using_udma = 1;
 325 
 326         return 0;
 327 }
 328 
 329 static void
 330 mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
 331 {
 332         struct mpc52xx_ata __iomem *regs = priv->ata_regs;
 333         struct mpc52xx_ata_timings *timing = &priv->timings[device];
 334 
 335         out_be32(&regs->pio1,  timing->pio1);
 336         out_be32(&regs->pio2,  timing->pio2);
 337         out_be32(&regs->mdma1, timing->mdma1);
 338         out_be32(&regs->mdma2, timing->mdma2);
 339         out_be32(&regs->udma1, timing->udma1);
 340         out_be32(&regs->udma2, timing->udma2);
 341         out_be32(&regs->udma3, timing->udma3);
 342         out_be32(&regs->udma4, timing->udma4);
 343         out_be32(&regs->udma5, timing->udma5);
 344         priv->csel = device;
 345 }
 346 
 347 static int
 348 mpc52xx_ata_hw_init(struct mpc52xx_ata_priv *priv)
 349 {
 350         struct mpc52xx_ata __iomem *regs = priv->ata_regs;
 351         int tslot;
 352 
 353         /* Clear share_cnt (all sample code do this ...) */
 354         out_be32(&regs->share_cnt, 0);
 355 
 356         /* Configure and reset host */
 357         out_be32(&regs->config,
 358                         MPC52xx_ATA_HOSTCONF_IE |
 359                         MPC52xx_ATA_HOSTCONF_IORDY |
 360                         MPC52xx_ATA_HOSTCONF_SMR |
 361                         MPC52xx_ATA_HOSTCONF_FR);
 362 
 363         udelay(10);
 364 
 365         out_be32(&regs->config,
 366                         MPC52xx_ATA_HOSTCONF_IE |
 367                         MPC52xx_ATA_HOSTCONF_IORDY);
 368 
 369         /* Set the time slot to 1us */
 370         tslot = CALC_CLKCYC(priv->ipb_period, 1000000);
 371         out_be32(&regs->share_cnt, tslot << 16);
 372 
 373         /* Init timings to PIO0 */
 374         memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings));
 375 
 376         mpc52xx_ata_compute_pio_timings(priv, 0, 0);
 377         mpc52xx_ata_compute_pio_timings(priv, 1, 0);
 378 
 379         mpc52xx_ata_apply_timings(priv, 0);
 380 
 381         return 0;
 382 }
 383 
 384 
 385 /* ======================================================================== */
 386 /* libata driver                                                            */
 387 /* ======================================================================== */
 388 
 389 static void
 390 mpc52xx_ata_set_piomode(struct ata_port *ap, struct ata_device *adev)
 391 {
 392         struct mpc52xx_ata_priv *priv = ap->host->private_data;
 393         int pio, rv;
 394 
 395         pio = adev->pio_mode - XFER_PIO_0;
 396 
 397         rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio);
 398 
 399         if (rv) {
 400                 dev_err(ap->dev, "error: invalid PIO mode: %d\n", pio);
 401                 return;
 402         }
 403 
 404         mpc52xx_ata_apply_timings(priv, adev->devno);
 405 }
 406 
 407 static void
 408 mpc52xx_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);
 425                 return;
 426         }
 427 
 428         mpc52xx_ata_apply_timings(priv, adev->devno);
 429 }
 430 
 431 static void
 432 mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
 433 {
 434         struct mpc52xx_ata_priv *priv = ap->host->private_data;
 435 
 436         if (device != priv->csel)
 437                 mpc52xx_ata_apply_timings(priv, device);
 438 
 439         ata_sff_dev_select(ap, device);
 440 }
 441 
 442 static int
 443 mpc52xx_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 
 498 static void
 499 mpc52xx_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 
 555 static void
 556 mpc52xx_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 
 565 static void
 566 mpc52xx_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 
 581 static u8
 582 mpc52xx_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 
 596 static irqreturn_t
 597 mpc52xx_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;
 606 }
 607 
 608 static struct scsi_host_template mpc52xx_ata_sht = {
 609         ATA_PIO_SHT(DRV_NAME),
 610 };
 611 
 612 static struct ata_port_operations mpc52xx_ata_port_ops = {
 613         .inherits               = &ata_bmdma_port_ops,
 614         .sff_dev_select         = mpc52xx_ata_dev_select,
 615         .set_piomode            = mpc52xx_ata_set_piomode,
 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,
 622 };
 623 
 624 static int mpc52xx_ata_init_one(struct device *dev,
 625                                 struct mpc52xx_ata_priv *priv,
 626                                 unsigned long raw_ata_regs,
 627                                 int mwdma_mask, int udma_mask)
 628 {
 629         struct ata_host *host;
 630         struct ata_port *ap;
 631         struct ata_ioports *aio;
 632 
 633         host = ata_host_alloc(dev, 1);
 634         if (!host)
 635                 return -ENOMEM;
 636 
 637         ap = host->ports[0];
 638         ap->flags               |= ATA_FLAG_SLAVE_POSS;
 639         ap->pio_mask            = ATA_PIO4;
 640         ap->mwdma_mask          = mwdma_mask;
 641         ap->udma_mask           = udma_mask;
 642         ap->ops                 = &mpc52xx_ata_port_ops;
 643         host->private_data      = priv;
 644 
 645         aio = &ap->ioaddr;
 646         aio->cmd_addr           = NULL; /* Don't have a classic reg block */
 647         aio->altstatus_addr     = &priv->ata_regs->tf_control;
 648         aio->ctl_addr           = &priv->ata_regs->tf_control;
 649         aio->data_addr          = &priv->ata_regs->tf_data;
 650         aio->error_addr         = &priv->ata_regs->tf_features;
 651         aio->feature_addr       = &priv->ata_regs->tf_features;
 652         aio->nsect_addr         = &priv->ata_regs->tf_sec_count;
 653         aio->lbal_addr          = &priv->ata_regs->tf_sec_num;
 654         aio->lbam_addr          = &priv->ata_regs->tf_cyl_low;
 655         aio->lbah_addr          = &priv->ata_regs->tf_cyl_high;
 656         aio->device_addr        = &priv->ata_regs->tf_dev_head;
 657         aio->status_addr        = &priv->ata_regs->tf_command;
 658         aio->command_addr       = &priv->ata_regs->tf_command;
 659 
 660         ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs);
 661 
 662         /* activate host */
 663         return ata_host_activate(host, priv->ata_irq, ata_bmdma_interrupt, 0,
 664                                  &mpc52xx_ata_sht);
 665 }
 666 
 667 /* ======================================================================== */
 668 /* OF Platform driver                                                       */
 669 /* ======================================================================== */
 670 
 671 static int mpc52xx_ata_probe(struct platform_device *op)
 672 {
 673         unsigned int ipb_freq;
 674         struct resource res_mem;
 675         int ata_irq = 0;
 676         struct mpc52xx_ata __iomem *ata_regs;
 677         struct mpc52xx_ata_priv *priv = NULL;
 678         int rv, task_irq;
 679         int mwdma_mask = 0, udma_mask = 0;
 680         const __be32 *prop;
 681         int proplen;
 682         struct bcom_task *dmatsk;
 683 
 684         /* Get ipb frequency */
 685         ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node);
 686         if (!ipb_freq) {
 687                 dev_err(&op->dev, "could not determine IPB bus frequency\n");
 688                 return -ENODEV;
 689         }
 690 
 691         /* Get device base address from device tree, request the region
 692          * and ioremap it. */
 693         rv = of_address_to_resource(op->dev.of_node, 0, &res_mem);
 694         if (rv) {
 695                 dev_err(&op->dev, "could not determine device base address\n");
 696                 return rv;
 697         }
 698 
 699         if (!devm_request_mem_region(&op->dev, res_mem.start,
 700                                      sizeof(*ata_regs), DRV_NAME)) {
 701                 dev_err(&op->dev, "error requesting register region\n");
 702                 return -EBUSY;
 703         }
 704 
 705         ata_regs = devm_ioremap(&op->dev, res_mem.start, sizeof(*ata_regs));
 706         if (!ata_regs) {
 707                 dev_err(&op->dev, "error mapping device registers\n");
 708                 return -ENOMEM;
 709         }
 710 
 711         /*
 712          * By default, all DMA modes are disabled for the MPC5200.  Some
 713          * boards don't have the required signals routed to make DMA work.
 714          * Also, the MPC5200B has a silicon bug that causes data corruption
 715          * with UDMA if it is used at the same time as the LocalPlus bus.
 716          *
 717          * Instead of trying to guess what modes are usable, check the
 718          * ATA device tree node to find out what DMA modes work on the board.
 719          * UDMA/MWDMA modes can also be forced by adding "libata.force=<mode>"
 720          * to the kernel boot parameters.
 721          *
 722          * The MPC5200 ATA controller supports MWDMA modes 0, 1 and 2 and
 723          * UDMA modes 0, 1 and 2.
 724          */
 725         prop = of_get_property(op->dev.of_node, "mwdma-mode", &proplen);
 726         if ((prop) && (proplen >= 4))
 727                 mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1);
 728         prop = of_get_property(op->dev.of_node, "udma-mode", &proplen);
 729         if ((prop) && (proplen >= 4))
 730                 udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1);
 731 
 732         ata_irq = irq_of_parse_and_map(op->dev.of_node, 0);
 733         if (ata_irq == NO_IRQ) {
 734                 dev_err(&op->dev, "error mapping irq\n");
 735                 return -EINVAL;
 736         }
 737 
 738         /* Prepare our private structure */
 739         priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_ATOMIC);
 740         if (!priv) {
 741                 rv = -ENOMEM;
 742                 goto err1;
 743         }
 744 
 745         priv->ipb_period = 1000000000 / (ipb_freq / 1000);
 746         priv->ata_regs = ata_regs;
 747         priv->ata_regs_pa = res_mem.start;
 748         priv->ata_irq = ata_irq;
 749         priv->csel = -1;
 750         priv->mpc52xx_ata_dma_last_write = -1;
 751 
 752         if (ipb_freq/1000000 == 66) {
 753                 priv->mdmaspec = mdmaspec66;
 754                 priv->udmaspec = udmaspec66;
 755         } else {
 756                 priv->mdmaspec = mdmaspec132;
 757                 priv->udmaspec = udmaspec132;
 758         }
 759 
 760         /* Allocate a BestComm task for DMA */
 761         dmatsk = bcom_ata_init(MAX_DMA_BUFFERS, MAX_DMA_BUFFER_SIZE);
 762         if (!dmatsk) {
 763                 dev_err(&op->dev, "bestcomm initialization failed\n");
 764                 rv = -ENOMEM;
 765                 goto err1;
 766         }
 767 
 768         task_irq = bcom_get_task_irq(dmatsk);
 769         rv = devm_request_irq(&op->dev, task_irq, &mpc52xx_ata_task_irq, 0,
 770                                 "ATA task", priv);
 771         if (rv) {
 772                 dev_err(&op->dev, "error requesting DMA IRQ\n");
 773                 goto err2;
 774         }
 775         priv->dmatsk = dmatsk;
 776 
 777         /* Init the hw */
 778         rv = mpc52xx_ata_hw_init(priv);
 779         if (rv) {
 780                 dev_err(&op->dev, "error initializing hardware\n");
 781                 goto err2;
 782         }
 783 
 784         /* Register ourselves to libata */
 785         rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start,
 786                                   mwdma_mask, udma_mask);
 787         if (rv) {
 788                 dev_err(&op->dev, "error registering with ATA layer\n");
 789                 goto err2;
 790         }
 791 
 792         return 0;
 793 
 794  err2:
 795         irq_dispose_mapping(task_irq);
 796         bcom_ata_release(dmatsk);
 797  err1:
 798         irq_dispose_mapping(ata_irq);
 799         return rv;
 800 }
 801 
 802 static int
 803 mpc52xx_ata_remove(struct platform_device *op)
 804 {
 805         struct ata_host *host = platform_get_drvdata(op);
 806         struct mpc52xx_ata_priv *priv = host->private_data;
 807         int task_irq;
 808 
 809         /* Deregister the ATA interface */
 810         ata_platform_remove_one(op);
 811 
 812         /* Clean up DMA */
 813         task_irq = bcom_get_task_irq(priv->dmatsk);
 814         irq_dispose_mapping(task_irq);
 815         bcom_ata_release(priv->dmatsk);
 816         irq_dispose_mapping(priv->ata_irq);
 817 
 818         return 0;
 819 }
 820 
 821 #ifdef CONFIG_PM_SLEEP
 822 static int
 823 mpc52xx_ata_suspend(struct platform_device *op, pm_message_t state)
 824 {
 825         struct ata_host *host = platform_get_drvdata(op);
 826 
 827         return ata_host_suspend(host, state);
 828 }
 829 
 830 static int
 831 mpc52xx_ata_resume(struct platform_device *op)
 832 {
 833         struct ata_host *host = platform_get_drvdata(op);
 834         struct mpc52xx_ata_priv *priv = host->private_data;
 835         int rv;
 836 
 837         rv = mpc52xx_ata_hw_init(priv);
 838         if (rv) {
 839                 dev_err(host->dev, "error initializing hardware\n");
 840                 return rv;
 841         }
 842 
 843         ata_host_resume(host);
 844 
 845         return 0;
 846 }
 847 #endif
 848 
 849 static const struct of_device_id mpc52xx_ata_of_match[] = {
 850         { .compatible = "fsl,mpc5200-ata", },
 851         { .compatible = "mpc5200-ata", },
 852         {},
 853 };
 854 
 855 
 856 static struct platform_driver mpc52xx_ata_of_platform_driver = {
 857         .probe          = mpc52xx_ata_probe,
 858         .remove         = mpc52xx_ata_remove,
 859 #ifdef CONFIG_PM_SLEEP
 860         .suspend        = mpc52xx_ata_suspend,
 861         .resume         = mpc52xx_ata_resume,
 862 #endif
 863         .driver         = {
 864                 .name   = DRV_NAME,
 865                 .of_match_table = mpc52xx_ata_of_match,
 866         },
 867 };
 868 
 869 module_platform_driver(mpc52xx_ata_of_platform_driver);
 870 
 871 MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
 872 MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA libata driver");
 873 MODULE_LICENSE("GPL");
 874 MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match);
 875 

/* [<][>][^][v][top][bottom][index][help] */