linux/drivers/ata/pata_mpc52xx.c
<<
>>
Prefs
   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 * 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
  11 * kind, whether express or implied.
  12 */
  13
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/slab.h>
  17#include <linux/delay.h>
  18#include <linux/libata.h>
  19#include <linux/of_platform.h>
  20
  21#include <asm/types.h>
  22#include <asm/prom.h>
  23#include <asm/mpc52xx.h>
  24
  25
  26#define DRV_NAME        "mpc52xx_ata"
  27#define DRV_VERSION     "0.1.2"
  28
  29
  30/* Private structures used by the driver */
  31struct mpc52xx_ata_timings {
  32        u32     pio1;
  33        u32     pio2;
  34};
  35
  36struct mpc52xx_ata_priv {
  37        unsigned int                    ipb_period;
  38        struct mpc52xx_ata __iomem *    ata_regs;
  39        int                             ata_irq;
  40        struct mpc52xx_ata_timings      timings[2];
  41        int                             csel;
  42};
  43
  44
  45/* ATAPI-4 PIO specs (in ns) */
  46static const int ataspec_t0[5]    = {600, 383, 240, 180, 120};
  47static const int ataspec_t1[5]    = { 70,  50,  30,  30,  25};
  48static const int ataspec_t2_8[5]  = {290, 290, 290,  80,  70};
  49static const int ataspec_t2_16[5] = {165, 125, 100,  80,  70};
  50static const int ataspec_t2i[5]   = {  0,   0,   0,  70,  25};
  51static const int ataspec_t4[5]    = { 30,  20,  15,  10,  10};
  52static const int ataspec_ta[5]    = { 35,  35,  35,  35,  35};
  53
  54#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
  55
  56
  57/* Bit definitions inside the registers */
  58#define MPC52xx_ATA_HOSTCONF_SMR        0x80000000UL /* State machine reset */
  59#define MPC52xx_ATA_HOSTCONF_FR         0x40000000UL /* FIFO Reset */
  60#define MPC52xx_ATA_HOSTCONF_IE         0x02000000UL /* Enable interrupt in PIO */
  61#define MPC52xx_ATA_HOSTCONF_IORDY      0x01000000UL /* Drive supports IORDY protocol */
  62
  63#define MPC52xx_ATA_HOSTSTAT_TIP        0x80000000UL /* Transaction in progress */
  64#define MPC52xx_ATA_HOSTSTAT_UREP       0x40000000UL /* UDMA Read Extended Pause */
  65#define MPC52xx_ATA_HOSTSTAT_RERR       0x02000000UL /* Read Error */
  66#define MPC52xx_ATA_HOSTSTAT_WERR       0x01000000UL /* Write Error */
  67
  68#define MPC52xx_ATA_FIFOSTAT_EMPTY      0x01 /* FIFO Empty */
  69
  70#define MPC52xx_ATA_DMAMODE_WRITE       0x01 /* Write DMA */
  71#define MPC52xx_ATA_DMAMODE_READ        0x02 /* Read DMA */
  72#define MPC52xx_ATA_DMAMODE_UDMA        0x04 /* UDMA enabled */
  73#define MPC52xx_ATA_DMAMODE_IE          0x08 /* Enable drive interrupt to CPU in DMA mode */
  74#define MPC52xx_ATA_DMAMODE_FE          0x10 /* FIFO Flush enable in Rx mode */
  75#define MPC52xx_ATA_DMAMODE_FR          0x20 /* FIFO Reset */
  76#define MPC52xx_ATA_DMAMODE_HUT         0x40 /* Host UDMA burst terminate */
  77
  78
  79/* Structure of the hardware registers */
  80struct mpc52xx_ata {
  81
  82        /* Host interface registers */
  83        u32 config;             /* ATA + 0x00 Host configuration */
  84        u32 host_status;        /* ATA + 0x04 Host controller status */
  85        u32 pio1;               /* ATA + 0x08 PIO Timing 1 */
  86        u32 pio2;               /* ATA + 0x0c PIO Timing 2 */
  87        u32 mdma1;              /* ATA + 0x10 MDMA Timing 1 */
  88        u32 mdma2;              /* ATA + 0x14 MDMA Timing 2 */
  89        u32 udma1;              /* ATA + 0x18 UDMA Timing 1 */
  90        u32 udma2;              /* ATA + 0x1c UDMA Timing 2 */
  91        u32 udma3;              /* ATA + 0x20 UDMA Timing 3 */
  92        u32 udma4;              /* ATA + 0x24 UDMA Timing 4 */
  93        u32 udma5;              /* ATA + 0x28 UDMA Timing 5 */
  94        u32 share_cnt;          /* ATA + 0x2c ATA share counter */
  95        u32 reserved0[3];
  96
  97        /* FIFO registers */
  98        u32 fifo_data;          /* ATA + 0x3c */
  99        u8  fifo_status_frame;  /* ATA + 0x40 */
 100        u8  fifo_status;        /* ATA + 0x41 */
 101        u16 reserved7[1];
 102        u8  fifo_control;       /* ATA + 0x44 */
 103        u8  reserved8[5];
 104        u16 fifo_alarm;         /* ATA + 0x4a */
 105        u16 reserved9;
 106        u16 fifo_rdp;           /* ATA + 0x4e */
 107        u16 reserved10;
 108        u16 fifo_wrp;           /* ATA + 0x52 */
 109        u16 reserved11;
 110        u16 fifo_lfrdp;         /* ATA + 0x56 */
 111        u16 reserved12;
 112        u16 fifo_lfwrp;         /* ATA + 0x5a */
 113
 114        /* Drive TaskFile registers */
 115        u8  tf_control;         /* ATA + 0x5c TASKFILE Control/Alt Status */
 116        u8  reserved13[3];
 117        u16 tf_data;            /* ATA + 0x60 TASKFILE Data */
 118        u16 reserved14;
 119        u8  tf_features;        /* ATA + 0x64 TASKFILE Features/Error */
 120        u8  reserved15[3];
 121        u8  tf_sec_count;       /* ATA + 0x68 TASKFILE Sector Count */
 122        u8  reserved16[3];
 123        u8  tf_sec_num;         /* ATA + 0x6c TASKFILE Sector Number */
 124        u8  reserved17[3];
 125        u8  tf_cyl_low;         /* ATA + 0x70 TASKFILE Cylinder Low */
 126        u8  reserved18[3];
 127        u8  tf_cyl_high;        /* ATA + 0x74 TASKFILE Cylinder High */
 128        u8  reserved19[3];
 129        u8  tf_dev_head;        /* ATA + 0x78 TASKFILE Device/Head */
 130        u8  reserved20[3];
 131        u8  tf_command;         /* ATA + 0x7c TASKFILE Command/Status */
 132        u8  dma_mode;           /* ATA + 0x7d ATA Host DMA Mode configuration */
 133        u8  reserved21[2];
 134};
 135
 136
 137/* ======================================================================== */
 138/* Aux fns                                                                  */
 139/* ======================================================================== */
 140
 141
 142/* MPC52xx low level hw control */
 143
 144static int
 145mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
 146{
 147        struct mpc52xx_ata_timings *timing = &priv->timings[dev];
 148        unsigned int ipb_period = priv->ipb_period;
 149        unsigned int t0, t1, t2_8, t2_16, t2i, t4, ta;
 150
 151        if ((pio<0) || (pio>4))
 152                return -EINVAL;
 153
 154        t0      = CALC_CLKCYC(ipb_period, 1000 * ataspec_t0[pio]);
 155        t1      = CALC_CLKCYC(ipb_period, 1000 * ataspec_t1[pio]);
 156        t2_8    = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2_8[pio]);
 157        t2_16   = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2_16[pio]);
 158        t2i     = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2i[pio]);
 159        t4      = CALC_CLKCYC(ipb_period, 1000 * ataspec_t4[pio]);
 160        ta      = CALC_CLKCYC(ipb_period, 1000 * ataspec_ta[pio]);
 161
 162        timing->pio1 = (t0 << 24) | (t2_8 << 16) | (t2_16 << 8) | (t2i);
 163        timing->pio2 = (t4 << 24) | (t1 << 16) | (ta << 8);
 164
 165        return 0;
 166}
 167
 168static void
 169mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
 170{
 171        struct mpc52xx_ata __iomem *regs = priv->ata_regs;
 172        struct mpc52xx_ata_timings *timing = &priv->timings[device];
 173
 174        out_be32(&regs->pio1,  timing->pio1);
 175        out_be32(&regs->pio2,  timing->pio2);
 176        out_be32(&regs->mdma1, 0);
 177        out_be32(&regs->mdma2, 0);
 178        out_be32(&regs->udma1, 0);
 179        out_be32(&regs->udma2, 0);
 180        out_be32(&regs->udma3, 0);
 181        out_be32(&regs->udma4, 0);
 182        out_be32(&regs->udma5, 0);
 183
 184        priv->csel = device;
 185}
 186
 187static int
 188mpc52xx_ata_hw_init(struct mpc52xx_ata_priv *priv)
 189{
 190        struct mpc52xx_ata __iomem *regs = priv->ata_regs;
 191        int tslot;
 192
 193        /* Clear share_cnt (all sample code do this ...) */
 194        out_be32(&regs->share_cnt, 0);
 195
 196        /* Configure and reset host */
 197        out_be32(&regs->config,
 198                        MPC52xx_ATA_HOSTCONF_IE |
 199                        MPC52xx_ATA_HOSTCONF_IORDY |
 200                        MPC52xx_ATA_HOSTCONF_SMR |
 201                        MPC52xx_ATA_HOSTCONF_FR);
 202
 203        udelay(10);
 204
 205        out_be32(&regs->config,
 206                        MPC52xx_ATA_HOSTCONF_IE |
 207                        MPC52xx_ATA_HOSTCONF_IORDY);
 208
 209        /* Set the time slot to 1us */
 210        tslot = CALC_CLKCYC(priv->ipb_period, 1000000);
 211        out_be32(&regs->share_cnt, tslot << 16 );
 212
 213        /* Init timings to PIO0 */
 214        memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings));
 215
 216        mpc52xx_ata_compute_pio_timings(priv, 0, 0);
 217        mpc52xx_ata_compute_pio_timings(priv, 1, 0);
 218
 219        mpc52xx_ata_apply_timings(priv, 0);
 220
 221        return 0;
 222}
 223
 224
 225/* ======================================================================== */
 226/* libata driver                                                            */
 227/* ======================================================================== */
 228
 229static void
 230mpc52xx_ata_set_piomode(struct ata_port *ap, struct ata_device *adev)
 231{
 232        struct mpc52xx_ata_priv *priv = ap->host->private_data;
 233        int pio, rv;
 234
 235        pio = adev->pio_mode - XFER_PIO_0;
 236
 237        rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio);
 238
 239        if (rv) {
 240                printk(KERN_ERR DRV_NAME
 241                        ": Trying to select invalid PIO mode %d\n", pio);
 242                return;
 243        }
 244
 245        mpc52xx_ata_apply_timings(priv, adev->devno);
 246}
 247static void
 248mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
 249{
 250        struct mpc52xx_ata_priv *priv = ap->host->private_data;
 251
 252        if (device != priv->csel)
 253                mpc52xx_ata_apply_timings(priv, device);
 254
 255        ata_sff_dev_select(ap,device);
 256}
 257
 258static struct scsi_host_template mpc52xx_ata_sht = {
 259        ATA_PIO_SHT(DRV_NAME),
 260};
 261
 262static struct ata_port_operations mpc52xx_ata_port_ops = {
 263        .inherits               = &ata_sff_port_ops,
 264        .sff_dev_select         = mpc52xx_ata_dev_select,
 265        .cable_detect           = ata_cable_40wire,
 266        .set_piomode            = mpc52xx_ata_set_piomode,
 267        .post_internal_cmd      = ATA_OP_NULL,
 268};
 269
 270static int __devinit
 271mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
 272                     unsigned long raw_ata_regs)
 273{
 274        struct ata_host *host;
 275        struct ata_port *ap;
 276        struct ata_ioports *aio;
 277
 278        host = ata_host_alloc(dev, 1);
 279        if (!host)
 280                return -ENOMEM;
 281
 282        ap = host->ports[0];
 283        ap->flags               |= ATA_FLAG_SLAVE_POSS;
 284        ap->pio_mask            = 0x1f; /* Up to PIO4 */
 285        ap->mwdma_mask          = 0x00; /* No MWDMA   */
 286        ap->udma_mask           = 0x00; /* No UDMA    */
 287        ap->ops                 = &mpc52xx_ata_port_ops;
 288        host->private_data      = priv;
 289
 290        aio = &ap->ioaddr;
 291        aio->cmd_addr           = NULL; /* Don't have a classic reg block */
 292        aio->altstatus_addr     = &priv->ata_regs->tf_control;
 293        aio->ctl_addr           = &priv->ata_regs->tf_control;
 294        aio->data_addr          = &priv->ata_regs->tf_data;
 295        aio->error_addr         = &priv->ata_regs->tf_features;
 296        aio->feature_addr       = &priv->ata_regs->tf_features;
 297        aio->nsect_addr         = &priv->ata_regs->tf_sec_count;
 298        aio->lbal_addr          = &priv->ata_regs->tf_sec_num;
 299        aio->lbam_addr          = &priv->ata_regs->tf_cyl_low;
 300        aio->lbah_addr          = &priv->ata_regs->tf_cyl_high;
 301        aio->device_addr        = &priv->ata_regs->tf_dev_head;
 302        aio->status_addr        = &priv->ata_regs->tf_command;
 303        aio->command_addr       = &priv->ata_regs->tf_command;
 304
 305        ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs);
 306
 307        /* activate host */
 308        return ata_host_activate(host, priv->ata_irq, ata_sff_interrupt, 0,
 309                                 &mpc52xx_ata_sht);
 310}
 311
 312static struct mpc52xx_ata_priv *
 313mpc52xx_ata_remove_one(struct device *dev)
 314{
 315        struct ata_host *host = dev_get_drvdata(dev);
 316        struct mpc52xx_ata_priv *priv = host->private_data;
 317
 318        ata_host_detach(host);
 319
 320        return priv;
 321}
 322
 323
 324/* ======================================================================== */
 325/* OF Platform driver                                                       */
 326/* ======================================================================== */
 327
 328static int __devinit
 329mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
 330{
 331        unsigned int ipb_freq;
 332        struct resource res_mem;
 333        int ata_irq;
 334        struct mpc52xx_ata __iomem *ata_regs;
 335        struct mpc52xx_ata_priv *priv;
 336        int rv;
 337
 338        /* Get ipb frequency */
 339        ipb_freq = mpc52xx_find_ipb_freq(op->node);
 340        if (!ipb_freq) {
 341                printk(KERN_ERR DRV_NAME ": "
 342                        "Unable to find IPB Bus frequency\n" );
 343                return -ENODEV;
 344        }
 345
 346        /* Get IRQ and register */
 347        rv = of_address_to_resource(op->node, 0, &res_mem);
 348        if (rv) {
 349                printk(KERN_ERR DRV_NAME ": "
 350                        "Error while parsing device node resource\n" );
 351                return rv;
 352        }
 353
 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,
 363                                     sizeof(struct mpc52xx_ata), DRV_NAME)) {
 364                printk(KERN_ERR DRV_NAME ": "
 365                        "Error while requesting mem region\n");
 366                rv = -EBUSY;
 367                goto err;
 368        }
 369
 370        /* Remap registers */
 371        ata_regs = devm_ioremap(&op->dev, res_mem.start,
 372                                sizeof(struct mpc52xx_ata));
 373        if (!ata_regs) {
 374                printk(KERN_ERR DRV_NAME ": "
 375                        "Error while mapping register set\n");
 376                rv = -ENOMEM;
 377                goto err;
 378        }
 379
 380        /* Prepare our private structure */
 381        priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv),
 382                            GFP_ATOMIC);
 383        if (!priv) {
 384                printk(KERN_ERR DRV_NAME ": "
 385                        "Error while allocating private structure\n");
 386                rv = -ENOMEM;
 387                goto err;
 388        }
 389
 390        priv->ipb_period = 1000000000 / (ipb_freq / 1000);
 391        priv->ata_regs = ata_regs;
 392        priv->ata_irq = ata_irq;
 393        priv->csel = -1;
 394
 395        /* Init the hw */
 396        rv = mpc52xx_ata_hw_init(priv);
 397        if (rv) {
 398                printk(KERN_ERR DRV_NAME ": Error during HW init\n");
 399                goto err;
 400        }
 401
 402        /* Register ourselves to libata */
 403        rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start);
 404        if (rv) {
 405                printk(KERN_ERR DRV_NAME ": "
 406                        "Error while registering to ATA layer\n");
 407                return rv;
 408        }
 409
 410        /* Done */
 411        return 0;
 412
 413        /* Error path */
 414err:
 415        irq_dispose_mapping(ata_irq);
 416        return rv;
 417}
 418
 419static int
 420mpc52xx_ata_remove(struct of_device *op)
 421{
 422        struct mpc52xx_ata_priv *priv;
 423
 424        priv = mpc52xx_ata_remove_one(&op->dev);
 425        irq_dispose_mapping(priv->ata_irq);
 426
 427        return 0;
 428}
 429
 430
 431#ifdef CONFIG_PM
 432
 433static int
 434mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
 435{
 436        struct ata_host *host = dev_get_drvdata(&op->dev);
 437
 438        return ata_host_suspend(host, state);
 439}
 440
 441static int
 442mpc52xx_ata_resume(struct of_device *op)
 443{
 444        struct ata_host *host = dev_get_drvdata(&op->dev);
 445        struct mpc52xx_ata_priv *priv = host->private_data;
 446        int rv;
 447
 448        rv = mpc52xx_ata_hw_init(priv);
 449        if (rv) {
 450                printk(KERN_ERR DRV_NAME ": Error during HW init\n");
 451                return rv;
 452        }
 453
 454        ata_host_resume(host);
 455
 456        return 0;
 457}
 458
 459#endif
 460
 461
 462static struct of_device_id mpc52xx_ata_of_match[] = {
 463        { .compatible = "fsl,mpc5200-ata", },
 464        { .compatible = "mpc5200-ata", },
 465        {},
 466};
 467
 468
 469static struct of_platform_driver mpc52xx_ata_of_platform_driver = {
 470        .owner          = THIS_MODULE,
 471        .name           = DRV_NAME,
 472        .match_table    = mpc52xx_ata_of_match,
 473        .probe          = mpc52xx_ata_probe,
 474        .remove         = mpc52xx_ata_remove,
 475#ifdef CONFIG_PM
 476        .suspend        = mpc52xx_ata_suspend,
 477        .resume         = mpc52xx_ata_resume,
 478#endif
 479        .driver         = {
 480                .name   = DRV_NAME,
 481                .owner  = THIS_MODULE,
 482        },
 483};
 484
 485
 486/* ======================================================================== */
 487/* Module                                                                   */
 488/* ======================================================================== */
 489
 490static int __init
 491mpc52xx_ata_init(void)
 492{
 493        printk(KERN_INFO "ata: MPC52xx IDE/ATA libata driver\n");
 494        return of_register_platform_driver(&mpc52xx_ata_of_platform_driver);
 495}
 496
 497static void __exit
 498mpc52xx_ata_exit(void)
 499{
 500        of_unregister_platform_driver(&mpc52xx_ata_of_platform_driver);
 501}
 502
 503module_init(mpc52xx_ata_init);
 504module_exit(mpc52xx_ata_exit);
 505
 506MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
 507MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA libata driver");
 508MODULE_LICENSE("GPL");
 509MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match);
 510MODULE_VERSION(DRV_VERSION);
 511
 512