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
  20#include <asm/types.h>
  21#include <asm/prom.h>
  22#include <asm/of_platform.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_std_dev_select(ap,device);
 256}
 257
 258static void
 259mpc52xx_ata_error_handler(struct ata_port *ap)
 260{
 261        ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
 262                        ata_std_postreset);
 263}
 264
 265
 266
 267static struct scsi_host_template mpc52xx_ata_sht = {
 268        .module                 = THIS_MODULE,
 269        .name                   = DRV_NAME,
 270        .ioctl                  = ata_scsi_ioctl,
 271        .queuecommand           = ata_scsi_queuecmd,
 272        .can_queue              = ATA_DEF_QUEUE,
 273        .this_id                = ATA_SHT_THIS_ID,
 274        .sg_tablesize           = LIBATA_MAX_PRD,
 275        .max_sectors            = ATA_MAX_SECTORS,
 276        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
 277        .emulated               = ATA_SHT_EMULATED,
 278        .use_clustering         = ATA_SHT_USE_CLUSTERING,
 279        .proc_name              = DRV_NAME,
 280        .dma_boundary           = ATA_DMA_BOUNDARY,
 281        .slave_configure        = ata_scsi_slave_config,
 282        .bios_param             = ata_std_bios_param,
 283};
 284
 285static struct ata_port_operations mpc52xx_ata_port_ops = {
 286        .set_piomode            = mpc52xx_ata_set_piomode,
 287        .dev_select             = mpc52xx_ata_dev_select,
 288        .tf_load                = ata_tf_load,
 289        .tf_read                = ata_tf_read,
 290        .check_status           = ata_check_status,
 291        .exec_command           = ata_exec_command,
 292        .freeze                 = ata_bmdma_freeze,
 293        .thaw                   = ata_bmdma_thaw,
 294        .error_handler          = mpc52xx_ata_error_handler,
 295        .cable_detect           = ata_cable_40wire,
 296        .qc_prep                = ata_qc_prep,
 297        .qc_issue               = ata_qc_issue_prot,
 298        .data_xfer              = ata_data_xfer,
 299        .irq_clear              = ata_bmdma_irq_clear,
 300        .irq_on                 = ata_irq_on,
 301        .port_start             = ata_port_start,
 302};
 303
 304static int __devinit
 305mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
 306                     unsigned long raw_ata_regs)
 307{
 308        struct ata_host *host;
 309        struct ata_port *ap;
 310        struct ata_ioports *aio;
 311
 312        host = ata_host_alloc(dev, 1);
 313        if (!host)
 314                return -ENOMEM;
 315
 316        ap = host->ports[0];
 317        ap->flags               |= ATA_FLAG_SLAVE_POSS;
 318        ap->pio_mask            = 0x1f; /* Up to PIO4 */
 319        ap->mwdma_mask          = 0x00; /* No MWDMA   */
 320        ap->udma_mask           = 0x00; /* No UDMA    */
 321        ap->ops                 = &mpc52xx_ata_port_ops;
 322        host->private_data      = priv;
 323
 324        aio = &ap->ioaddr;
 325        aio->cmd_addr           = NULL; /* Don't have a classic reg block */
 326        aio->altstatus_addr     = &priv->ata_regs->tf_control;
 327        aio->ctl_addr           = &priv->ata_regs->tf_control;
 328        aio->data_addr          = &priv->ata_regs->tf_data;
 329        aio->error_addr         = &priv->ata_regs->tf_features;
 330        aio->feature_addr       = &priv->ata_regs->tf_features;
 331        aio->nsect_addr         = &priv->ata_regs->tf_sec_count;
 332        aio->lbal_addr          = &priv->ata_regs->tf_sec_num;
 333        aio->lbam_addr          = &priv->ata_regs->tf_cyl_low;
 334        aio->lbah_addr          = &priv->ata_regs->tf_cyl_high;
 335        aio->device_addr        = &priv->ata_regs->tf_dev_head;
 336        aio->status_addr        = &priv->ata_regs->tf_command;
 337        aio->command_addr       = &priv->ata_regs->tf_command;
 338
 339        ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs);
 340
 341        /* activate host */
 342        return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
 343                                 &mpc52xx_ata_sht);
 344}
 345
 346static struct mpc52xx_ata_priv *
 347mpc52xx_ata_remove_one(struct device *dev)
 348{
 349        struct ata_host *host = dev_get_drvdata(dev);
 350        struct mpc52xx_ata_priv *priv = host->private_data;
 351
 352        ata_host_detach(host);
 353
 354        return priv;
 355}
 356
 357
 358/* ======================================================================== */
 359/* OF Platform driver                                                       */
 360/* ======================================================================== */
 361
 362static int __devinit
 363mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
 364{
 365        unsigned int ipb_freq;
 366        struct resource res_mem;
 367        int ata_irq;
 368        struct mpc52xx_ata __iomem *ata_regs;
 369        struct mpc52xx_ata_priv *priv;
 370        int rv;
 371
 372        /* Get ipb frequency */
 373        ipb_freq = mpc52xx_find_ipb_freq(op->node);
 374        if (!ipb_freq) {
 375                printk(KERN_ERR DRV_NAME ": "
 376                        "Unable to find IPB Bus frequency\n" );
 377                return -ENODEV;
 378        }
 379
 380        /* Get IRQ and register */
 381        rv = of_address_to_resource(op->node, 0, &res_mem);
 382        if (rv) {
 383                printk(KERN_ERR DRV_NAME ": "
 384                        "Error while parsing device node resource\n" );
 385                return rv;
 386        }
 387
 388        ata_irq = irq_of_parse_and_map(op->node, 0);
 389        if (ata_irq == NO_IRQ) {
 390                printk(KERN_ERR DRV_NAME ": "
 391                        "Error while mapping the irq\n");
 392                return -EINVAL;
 393        }
 394
 395        /* Request mem region */
 396        if (!devm_request_mem_region(&op->dev, res_mem.start,
 397                                     sizeof(struct mpc52xx_ata), DRV_NAME)) {
 398                printk(KERN_ERR DRV_NAME ": "
 399                        "Error while requesting mem region\n");
 400                rv = -EBUSY;
 401                goto err;
 402        }
 403
 404        /* Remap registers */
 405        ata_regs = devm_ioremap(&op->dev, res_mem.start,
 406                                sizeof(struct mpc52xx_ata));
 407        if (!ata_regs) {
 408                printk(KERN_ERR DRV_NAME ": "
 409                        "Error while mapping register set\n");
 410                rv = -ENOMEM;
 411                goto err;
 412        }
 413
 414        /* Prepare our private structure */
 415        priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv),
 416                            GFP_ATOMIC);
 417        if (!priv) {
 418                printk(KERN_ERR DRV_NAME ": "
 419                        "Error while allocating private structure\n");
 420                rv = -ENOMEM;
 421                goto err;
 422        }
 423
 424        priv->ipb_period = 1000000000 / (ipb_freq / 1000);
 425        priv->ata_regs = ata_regs;
 426        priv->ata_irq = ata_irq;
 427        priv->csel = -1;
 428
 429        /* Init the hw */
 430        rv = mpc52xx_ata_hw_init(priv);
 431        if (rv) {
 432                printk(KERN_ERR DRV_NAME ": Error during HW init\n");
 433                goto err;
 434        }
 435
 436        /* Register ourselves to libata */
 437        rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start);
 438        if (rv) {
 439                printk(KERN_ERR DRV_NAME ": "
 440                        "Error while registering to ATA layer\n");
 441                return rv;
 442        }
 443
 444        /* Done */
 445        return 0;
 446
 447        /* Error path */
 448err:
 449        irq_dispose_mapping(ata_irq);
 450        return rv;
 451}
 452
 453static int
 454mpc52xx_ata_remove(struct of_device *op)
 455{
 456        struct mpc52xx_ata_priv *priv;
 457
 458        priv = mpc52xx_ata_remove_one(&op->dev);
 459        irq_dispose_mapping(priv->ata_irq);
 460
 461        return 0;
 462}
 463
 464
 465#ifdef CONFIG_PM
 466
 467static int
 468mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
 469{
 470        struct ata_host *host = dev_get_drvdata(&op->dev);
 471
 472        return ata_host_suspend(host, state);
 473}
 474
 475static int
 476mpc52xx_ata_resume(struct of_device *op)
 477{
 478        struct ata_host *host = dev_get_drvdata(&op->dev);
 479        struct mpc52xx_ata_priv *priv = host->private_data;
 480        int rv;
 481
 482        rv = mpc52xx_ata_hw_init(priv);
 483        if (rv) {
 484                printk(KERN_ERR DRV_NAME ": Error during HW init\n");
 485                return rv;
 486        }
 487
 488        ata_host_resume(host);
 489
 490        return 0;
 491}
 492
 493#endif
 494
 495
 496static struct of_device_id mpc52xx_ata_of_match[] = {
 497        { .compatible = "fsl,mpc5200-ata", },
 498        { .compatible = "mpc5200-ata", },
 499        {},
 500};
 501
 502
 503static struct of_platform_driver mpc52xx_ata_of_platform_driver = {
 504        .owner          = THIS_MODULE,
 505        .name           = DRV_NAME,
 506        .match_table    = mpc52xx_ata_of_match,
 507        .probe          = mpc52xx_ata_probe,
 508        .remove         = mpc52xx_ata_remove,
 509#ifdef CONFIG_PM
 510        .suspend        = mpc52xx_ata_suspend,
 511        .resume         = mpc52xx_ata_resume,
 512#endif
 513        .driver         = {
 514                .name   = DRV_NAME,
 515                .owner  = THIS_MODULE,
 516        },
 517};
 518
 519
 520/* ======================================================================== */
 521/* Module                                                                   */
 522/* ======================================================================== */
 523
 524static int __init
 525mpc52xx_ata_init(void)
 526{
 527        printk(KERN_INFO "ata: MPC52xx IDE/ATA libata driver\n");
 528        return of_register_platform_driver(&mpc52xx_ata_of_platform_driver);
 529}
 530
 531static void __exit
 532mpc52xx_ata_exit(void)
 533{
 534        of_unregister_platform_driver(&mpc52xx_ata_of_platform_driver);
 535}
 536
 537module_init(mpc52xx_ata_init);
 538module_exit(mpc52xx_ata_exit);
 539
 540MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
 541MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA libata driver");
 542MODULE_LICENSE("GPL");
 543MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match);
 544MODULE_VERSION(DRV_VERSION);
 545
 546
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.