root/drivers/ide/palm_bk3710.c

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

DEFINITIONS

This source file includes following definitions.
  1. palm_bk3710_setudmamode
  2. palm_bk3710_setdmamode
  3. palm_bk3710_setpiomode
  4. palm_bk3710_set_dma_mode
  5. palm_bk3710_set_pio_mode
  6. palm_bk3710_chipinit
  7. palm_bk3710_cable_detect
  8. palm_bk3710_init_dma
  9. palm_bk3710_probe
  10. palm_bk3710_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Palmchip bk3710 IDE controller
   4  *
   5  * Copyright (C) 2006 Texas Instruments.
   6  * Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com>
   7  *
   8  * ----------------------------------------------------------------------------
   9  *
  10  * ----------------------------------------------------------------------------
  11  */
  12 
  13 #include <linux/types.h>
  14 #include <linux/module.h>
  15 #include <linux/kernel.h>
  16 #include <linux/ioport.h>
  17 #include <linux/ide.h>
  18 #include <linux/delay.h>
  19 #include <linux/init.h>
  20 #include <linux/clk.h>
  21 #include <linux/platform_device.h>
  22 
  23 /* Offset of the primary interface registers */
  24 #define IDE_PALM_ATA_PRI_REG_OFFSET 0x1F0
  25 
  26 /* Primary Control Offset */
  27 #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6
  28 
  29 #define BK3710_BMICP            0x00
  30 #define BK3710_BMISP            0x02
  31 #define BK3710_BMIDTP           0x04
  32 #define BK3710_IDETIMP          0x40
  33 #define BK3710_IDESTATUS        0x47
  34 #define BK3710_UDMACTL          0x48
  35 #define BK3710_MISCCTL          0x50
  36 #define BK3710_REGSTB           0x54
  37 #define BK3710_REGRCVR          0x58
  38 #define BK3710_DATSTB           0x5C
  39 #define BK3710_DATRCVR          0x60
  40 #define BK3710_DMASTB           0x64
  41 #define BK3710_DMARCVR          0x68
  42 #define BK3710_UDMASTB          0x6C
  43 #define BK3710_UDMATRP          0x70
  44 #define BK3710_UDMAENV          0x74
  45 #define BK3710_IORDYTMP         0x78
  46 
  47 static unsigned ideclk_period; /* in nanoseconds */
  48 
  49 struct palm_bk3710_udmatiming {
  50         unsigned int rptime;    /* tRP -- Ready to pause time (nsec) */
  51         unsigned int cycletime; /* tCYCTYP2/2 -- avg Cycle Time (nsec) */
  52                                 /* tENV is always a minimum of 20 nsec */
  53 };
  54 
  55 static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
  56         { 160, 240 / 2 },       /* UDMA Mode 0 */
  57         { 125, 160 / 2 },       /* UDMA Mode 1 */
  58         { 100, 120 / 2 },       /* UDMA Mode 2 */
  59         { 100,  90 / 2 },       /* UDMA Mode 3 */
  60         { 100,  60 / 2 },       /* UDMA Mode 4 */
  61         {  85,  40 / 2 },       /* UDMA Mode 5 */
  62 };
  63 
  64 static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
  65                                     unsigned int mode)
  66 {
  67         u8 tenv, trp, t0;
  68         u32 val32;
  69         u16 val16;
  70 
  71         /* DMA Data Setup */
  72         t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime,
  73                           ideclk_period) - 1;
  74         tenv = DIV_ROUND_UP(20, ideclk_period) - 1;
  75         trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
  76                            ideclk_period) - 1;
  77 
  78         /* udmastb Ultra DMA Access Strobe Width */
  79         val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8));
  80         val32 |= (t0 << (dev ? 8 : 0));
  81         writel(val32, base + BK3710_UDMASTB);
  82 
  83         /* udmatrp Ultra DMA Ready to Pause Time */
  84         val32 = readl(base + BK3710_UDMATRP) & (0xFF << (dev ? 0 : 8));
  85         val32 |= (trp << (dev ? 8 : 0));
  86         writel(val32, base + BK3710_UDMATRP);
  87 
  88         /* udmaenv Ultra DMA envelop Time */
  89         val32 = readl(base + BK3710_UDMAENV) & (0xFF << (dev ? 0 : 8));
  90         val32 |= (tenv << (dev ? 8 : 0));
  91         writel(val32, base + BK3710_UDMAENV);
  92 
  93         /* Enable UDMA for Device */
  94         val16 = readw(base + BK3710_UDMACTL) | (1 << dev);
  95         writew(val16, base + BK3710_UDMACTL);
  96 }
  97 
  98 static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev,
  99                                    unsigned short min_cycle,
 100                                    unsigned int mode)
 101 {
 102         u8 td, tkw, t0;
 103         u32 val32;
 104         u16 val16;
 105         struct ide_timing *t;
 106         int cycletime;
 107 
 108         t = ide_timing_find_mode(mode);
 109         cycletime = max_t(int, t->cycle, min_cycle);
 110 
 111         /* DMA Data Setup */
 112         t0 = DIV_ROUND_UP(cycletime, ideclk_period);
 113         td = DIV_ROUND_UP(t->active, ideclk_period);
 114         tkw = t0 - td - 1;
 115         td -= 1;
 116 
 117         val32 = readl(base + BK3710_DMASTB) & (0xFF << (dev ? 0 : 8));
 118         val32 |= (td << (dev ? 8 : 0));
 119         writel(val32, base + BK3710_DMASTB);
 120 
 121         val32 = readl(base + BK3710_DMARCVR) & (0xFF << (dev ? 0 : 8));
 122         val32 |= (tkw << (dev ? 8 : 0));
 123         writel(val32, base + BK3710_DMARCVR);
 124 
 125         /* Disable UDMA for Device */
 126         val16 = readw(base + BK3710_UDMACTL) & ~(1 << dev);
 127         writew(val16, base + BK3710_UDMACTL);
 128 }
 129 
 130 static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
 131                                    unsigned int dev, unsigned int cycletime,
 132                                    unsigned int mode)
 133 {
 134         u8 t2, t2i, t0;
 135         u32 val32;
 136         struct ide_timing *t;
 137 
 138         t = ide_timing_find_mode(XFER_PIO_0 + mode);
 139 
 140         /* PIO Data Setup */
 141         t0 = DIV_ROUND_UP(cycletime, ideclk_period);
 142         t2 = DIV_ROUND_UP(t->active, ideclk_period);
 143 
 144         t2i = t0 - t2 - 1;
 145         t2 -= 1;
 146 
 147         val32 = readl(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8));
 148         val32 |= (t2 << (dev ? 8 : 0));
 149         writel(val32, base + BK3710_DATSTB);
 150 
 151         val32 = readl(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8));
 152         val32 |= (t2i << (dev ? 8 : 0));
 153         writel(val32, base + BK3710_DATRCVR);
 154 
 155         if (mate) {
 156                 u8 mode2 = mate->pio_mode - XFER_PIO_0;
 157 
 158                 if (mode2 < mode)
 159                         mode = mode2;
 160         }
 161 
 162         /* TASKFILE Setup */
 163         t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period);
 164         t2 = DIV_ROUND_UP(t->act8b, ideclk_period);
 165 
 166         t2i = t0 - t2 - 1;
 167         t2 -= 1;
 168 
 169         val32 = readl(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8));
 170         val32 |= (t2 << (dev ? 8 : 0));
 171         writel(val32, base + BK3710_REGSTB);
 172 
 173         val32 = readl(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8));
 174         val32 |= (t2i << (dev ? 8 : 0));
 175         writel(val32, base + BK3710_REGRCVR);
 176 }
 177 
 178 static void palm_bk3710_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 179 {
 180         int is_slave = drive->dn & 1;
 181         void __iomem *base = (void __iomem *)hwif->dma_base;
 182         const u8 xferspeed = drive->dma_mode;
 183 
 184         if (xferspeed >= XFER_UDMA_0) {
 185                 palm_bk3710_setudmamode(base, is_slave,
 186                                         xferspeed - XFER_UDMA_0);
 187         } else {
 188                 palm_bk3710_setdmamode(base, is_slave,
 189                                        drive->id[ATA_ID_EIDE_DMA_MIN],
 190                                        xferspeed);
 191         }
 192 }
 193 
 194 static void palm_bk3710_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 195 {
 196         unsigned int cycle_time;
 197         int is_slave = drive->dn & 1;
 198         ide_drive_t *mate;
 199         void __iomem *base = (void __iomem *)hwif->dma_base;
 200         const u8 pio = drive->pio_mode - XFER_PIO_0;
 201 
 202         /*
 203          * Obtain the drive PIO data for tuning the Palm Chip registers
 204          */
 205         cycle_time = ide_pio_cycle_time(drive, pio);
 206         mate = ide_get_pair_dev(drive);
 207         palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio);
 208 }
 209 
 210 static void palm_bk3710_chipinit(void __iomem *base)
 211 {
 212         /*
 213          * REVISIT:  the ATA reset signal needs to be managed through a
 214          * GPIO, which means it should come from platform_data.  Until
 215          * we get and use such information, we have to trust that things
 216          * have been reset before we get here.
 217          */
 218 
 219         /*
 220          * Program the IDETIMP Register Value based on the following assumptions
 221          *
 222          * (ATA_IDETIMP_IDEEN           , ENABLE ) |
 223          * (ATA_IDETIMP_PREPOST1        , DISABLE) |
 224          * (ATA_IDETIMP_PREPOST0        , DISABLE) |
 225          *
 226          * DM6446 silicon rev 2.1 and earlier have no observed net benefit
 227          * from enabling prefetch/postwrite.
 228          */
 229         writew(BIT(15), base + BK3710_IDETIMP);
 230 
 231         /*
 232          * UDMACTL Ultra-ATA DMA Control
 233          * (ATA_UDMACTL_UDMAP1  , 0 ) |
 234          * (ATA_UDMACTL_UDMAP0  , 0 )
 235          *
 236          */
 237         writew(0, base + BK3710_UDMACTL);
 238 
 239         /*
 240          * MISCCTL Miscellaneous Conrol Register
 241          * (ATA_MISCCTL_HWNHLD1P        , 1 cycle)
 242          * (ATA_MISCCTL_HWNHLD0P        , 1 cycle)
 243          * (ATA_MISCCTL_TIMORIDE        , 1)
 244          */
 245         writel(0x001, base + BK3710_MISCCTL);
 246 
 247         /*
 248          * IORDYTMP IORDY Timer for Primary Register
 249          * (ATA_IORDYTMP_IORDYTMP     , 0xffff  )
 250          */
 251         writel(0xFFFF, base + BK3710_IORDYTMP);
 252 
 253         /*
 254          * Configure BMISP Register
 255          * (ATA_BMISP_DMAEN1    , DISABLE )     |
 256          * (ATA_BMISP_DMAEN0    , DISABLE )     |
 257          * (ATA_BMISP_IORDYINT  , CLEAR)        |
 258          * (ATA_BMISP_INTRSTAT  , CLEAR)        |
 259          * (ATA_BMISP_DMAERROR  , CLEAR)
 260          */
 261         writew(0, base + BK3710_BMISP);
 262 
 263         palm_bk3710_setpiomode(base, NULL, 0, 600, 0);
 264         palm_bk3710_setpiomode(base, NULL, 1, 600, 0);
 265 }
 266 
 267 static u8 palm_bk3710_cable_detect(ide_hwif_t *hwif)
 268 {
 269         return ATA_CBL_PATA80;
 270 }
 271 
 272 static int palm_bk3710_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
 273 {
 274         printk(KERN_INFO "    %s: MMIO-DMA\n", hwif->name);
 275 
 276         if (ide_allocate_dma_engine(hwif))
 277                 return -1;
 278 
 279         hwif->dma_base = hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET;
 280 
 281         return 0;
 282 }
 283 
 284 static const struct ide_port_ops palm_bk3710_ports_ops = {
 285         .set_pio_mode           = palm_bk3710_set_pio_mode,
 286         .set_dma_mode           = palm_bk3710_set_dma_mode,
 287         .cable_detect           = palm_bk3710_cable_detect,
 288 };
 289 
 290 static struct ide_port_info palm_bk3710_port_info __initdata = {
 291         .init_dma               = palm_bk3710_init_dma,
 292         .port_ops               = &palm_bk3710_ports_ops,
 293         .dma_ops                = &sff_dma_ops,
 294         .host_flags             = IDE_HFLAG_MMIO,
 295         .pio_mask               = ATA_PIO4,
 296         .mwdma_mask             = ATA_MWDMA2,
 297         .chipset                = ide_palm3710,
 298 };
 299 
 300 static int __init palm_bk3710_probe(struct platform_device *pdev)
 301 {
 302         struct clk *clk;
 303         struct resource *mem, *irq;
 304         void __iomem *base;
 305         unsigned long rate, mem_size;
 306         int i, rc;
 307         struct ide_hw hw, *hws[] = { &hw };
 308 
 309         clk = clk_get(&pdev->dev, NULL);
 310         if (IS_ERR(clk))
 311                 return -ENODEV;
 312 
 313         clk_enable(clk);
 314         rate = clk_get_rate(clk);
 315         if (!rate)
 316                 return -EINVAL;
 317 
 318         /* NOTE:  round *down* to meet minimum timings; we count in clocks */
 319         ideclk_period = 1000000000UL / rate;
 320 
 321         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 322         if (mem == NULL) {
 323                 printk(KERN_ERR "failed to get memory region resource\n");
 324                 return -ENODEV;
 325         }
 326 
 327         irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 328         if (irq == NULL) {
 329                 printk(KERN_ERR "failed to get IRQ resource\n");
 330                 return -ENODEV;
 331         }
 332 
 333         mem_size = resource_size(mem);
 334         if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) {
 335                 printk(KERN_ERR "failed to request memory region\n");
 336                 return -EBUSY;
 337         }
 338 
 339         base = ioremap(mem->start, mem_size);
 340         if (!base) {
 341                 printk(KERN_ERR "failed to map IO memory\n");
 342                 release_mem_region(mem->start, mem_size);
 343                 return -ENOMEM;
 344         }
 345 
 346         /* Configure the Palm Chip controller */
 347         palm_bk3710_chipinit(base);
 348 
 349         memset(&hw, 0, sizeof(hw));
 350         for (i = 0; i < IDE_NR_PORTS - 2; i++)
 351                 hw.io_ports_array[i] = (unsigned long)
 352                                 (base + IDE_PALM_ATA_PRI_REG_OFFSET + i);
 353         hw.io_ports.ctl_addr = (unsigned long)
 354                         (base + IDE_PALM_ATA_PRI_CTL_OFFSET);
 355         hw.irq = irq->start;
 356         hw.dev = &pdev->dev;
 357 
 358         palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 :
 359                                                              ATA_UDMA5;
 360 
 361         /* Register the IDE interface with Linux */
 362         rc = ide_host_add(&palm_bk3710_port_info, hws, 1, NULL);
 363         if (rc)
 364                 goto out;
 365 
 366         return 0;
 367 out:
 368         printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n");
 369         return rc;
 370 }
 371 
 372 /* work with hotplug and coldplug */
 373 MODULE_ALIAS("platform:palm_bk3710");
 374 
 375 static struct platform_driver platform_bk_driver = {
 376         .driver = {
 377                 .name = "palm_bk3710",
 378         },
 379 };
 380 
 381 static int __init palm_bk3710_init(void)
 382 {
 383         return platform_driver_probe(&platform_bk_driver, palm_bk3710_probe);
 384 }
 385 
 386 module_init(palm_bk3710_init);
 387 MODULE_LICENSE("GPL");

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