Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Palmchip BK3710 IDE driver

This is Palmchip BK3710 IDE controller support.

The IDE controller logic supports PIO, MultiWord-DMA and Ultra-DMA modes.
Supports interface to Compact Flash (CF) configured in True-IDE mode.

Bart:
- remove dead code
- fix ide_hwif_setup_dma() build problem

Signed-off-by: Anton Salnikov <asalnikov@ru.mvista.com>
Reviewed-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Reviewed-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

authored by

Anton Salnikov and committed by
Bartlomiej Zolnierkiewicz
7c7e92a9 b2a53bc6

+409 -2
+9
drivers/ide/Kconfig
··· 1009 1009 normally be on; disable it only if you are running a custom hard 1010 1010 drive subsystem through an expansion card. 1011 1011 1012 + config BLK_DEV_PALMCHIP_BK3710 1013 + tristate "Palmchip bk3710 IDE controller support" 1014 + depends on ARCH_DAVINCI 1015 + select BLK_DEV_IDEDMA_PCI 1016 + help 1017 + Say Y here if you want to support the onchip IDE controller on the 1018 + TI DaVinci SoC 1019 + 1020 + 1012 1021 config BLK_DEV_MPC8xx_IDE 1013 1022 tristate "MPC8xx IDE support" 1014 1023 depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE
+1
drivers/ide/arm/Makefile
··· 2 2 obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o 3 3 obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o 4 4 obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o 5 + obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o 5 6 6 7 ifeq ($(CONFIG_IDE_ARM), m) 7 8 obj-m += ide_arm.o
+395
drivers/ide/arm/palm_bk3710.c
··· 1 + /* 2 + * Palmchip bk3710 IDE controller 3 + * 4 + * Copyright (C) 2006 Texas Instruments. 5 + * Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com> 6 + * 7 + * ---------------------------------------------------------------------------- 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License as published by 11 + * the Free Software Foundation; either version 2 of the License, or 12 + * (at your option) any later version. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * You should have received a copy of the GNU General Public License 20 + * along with this program; if not, write to the Free Software 21 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 + * ---------------------------------------------------------------------------- 23 + * 24 + */ 25 + 26 + #include <linux/types.h> 27 + #include <linux/module.h> 28 + #include <linux/kernel.h> 29 + #include <linux/ioport.h> 30 + #include <linux/hdreg.h> 31 + #include <linux/ide.h> 32 + #include <linux/delay.h> 33 + #include <linux/init.h> 34 + #include <linux/clk.h> 35 + #include <linux/platform_device.h> 36 + 37 + /* Offset of the primary interface registers */ 38 + #define IDE_PALM_ATA_PRI_REG_OFFSET 0x1F0 39 + 40 + /* Primary Control Offset */ 41 + #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6 42 + 43 + /* 44 + * PalmChip 3710 IDE Controller UDMA timing structure Definition 45 + */ 46 + struct palm_bk3710_udmatiming { 47 + unsigned int rptime; /* Ready to pause time */ 48 + unsigned int cycletime; /* Cycle Time */ 49 + }; 50 + 51 + #define BK3710_BMICP 0x00 52 + #define BK3710_BMISP 0x02 53 + #define BK3710_BMIDTP 0x04 54 + #define BK3710_BMICS 0x08 55 + #define BK3710_BMISS 0x0A 56 + #define BK3710_BMIDTS 0x0C 57 + #define BK3710_IDETIMP 0x40 58 + #define BK3710_IDETIMS 0x42 59 + #define BK3710_SIDETIM 0x44 60 + #define BK3710_SLEWCTL 0x45 61 + #define BK3710_IDESTATUS 0x47 62 + #define BK3710_UDMACTL 0x48 63 + #define BK3710_UDMATIM 0x4A 64 + #define BK3710_MISCCTL 0x50 65 + #define BK3710_REGSTB 0x54 66 + #define BK3710_REGRCVR 0x58 67 + #define BK3710_DATSTB 0x5C 68 + #define BK3710_DATRCVR 0x60 69 + #define BK3710_DMASTB 0x64 70 + #define BK3710_DMARCVR 0x68 71 + #define BK3710_UDMASTB 0x6C 72 + #define BK3710_UDMATRP 0x70 73 + #define BK3710_UDMAENV 0x74 74 + #define BK3710_IORDYTMP 0x78 75 + #define BK3710_IORDYTMS 0x7C 76 + 77 + #include "../ide-timing.h" 78 + 79 + static long ide_palm_clk; 80 + 81 + static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { 82 + {160, 240}, /* UDMA Mode 0 */ 83 + {125, 160}, /* UDMA Mode 1 */ 84 + {100, 120}, /* UDMA Mode 2 */ 85 + {100, 90}, /* UDMA Mode 3 */ 86 + {85, 60}, /* UDMA Mode 4 */ 87 + }; 88 + 89 + static struct clk *ideclkp; 90 + 91 + static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, 92 + unsigned int mode) 93 + { 94 + u8 tenv, trp, t0; 95 + u32 val32; 96 + u16 val16; 97 + 98 + /* DMA Data Setup */ 99 + t0 = (palm_bk3710_udmatimings[mode].cycletime + ide_palm_clk - 1) 100 + / ide_palm_clk - 1; 101 + tenv = (20 + ide_palm_clk - 1) / ide_palm_clk - 1; 102 + trp = (palm_bk3710_udmatimings[mode].rptime + ide_palm_clk - 1) 103 + / ide_palm_clk - 1; 104 + 105 + /* udmatim Register */ 106 + val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0); 107 + val16 |= (mode << (dev ? 4 : 0)); 108 + writew(val16, base + BK3710_UDMATIM); 109 + 110 + /* udmastb Ultra DMA Access Strobe Width */ 111 + val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8)); 112 + val32 |= (t0 << (dev ? 8 : 0)); 113 + writel(val32, base + BK3710_UDMASTB); 114 + 115 + /* udmatrp Ultra DMA Ready to Pause Time */ 116 + val32 = readl(base + BK3710_UDMATRP) & (0xFF << (dev ? 0 : 8)); 117 + val32 |= (trp << (dev ? 8 : 0)); 118 + writel(val32, base + BK3710_UDMATRP); 119 + 120 + /* udmaenv Ultra DMA envelop Time */ 121 + val32 = readl(base + BK3710_UDMAENV) & (0xFF << (dev ? 0 : 8)); 122 + val32 |= (tenv << (dev ? 8 : 0)); 123 + writel(val32, base + BK3710_UDMAENV); 124 + 125 + /* Enable UDMA for Device */ 126 + val16 = readw(base + BK3710_UDMACTL) | (1 << dev); 127 + writew(val16, base + BK3710_UDMACTL); 128 + } 129 + 130 + static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev, 131 + unsigned short min_cycle, 132 + unsigned int mode) 133 + { 134 + u8 td, tkw, t0; 135 + u32 val32; 136 + u16 val16; 137 + struct ide_timing *t; 138 + int cycletime; 139 + 140 + t = ide_timing_find_mode(mode); 141 + cycletime = max_t(int, t->cycle, min_cycle); 142 + 143 + /* DMA Data Setup */ 144 + t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk; 145 + td = (t->active + ide_palm_clk - 1) / ide_palm_clk; 146 + tkw = t0 - td - 1; 147 + td -= 1; 148 + 149 + val32 = readl(base + BK3710_DMASTB) & (0xFF << (dev ? 0 : 8)); 150 + val32 |= (td << (dev ? 8 : 0)); 151 + writel(val32, base + BK3710_DMASTB); 152 + 153 + val32 = readl(base + BK3710_DMARCVR) & (0xFF << (dev ? 0 : 8)); 154 + val32 |= (tkw << (dev ? 8 : 0)); 155 + writel(val32, base + BK3710_DMARCVR); 156 + 157 + /* Disable UDMA for Device */ 158 + val16 = readw(base + BK3710_UDMACTL) & ~(1 << dev); 159 + writew(val16, base + BK3710_UDMACTL); 160 + } 161 + 162 + static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, 163 + unsigned int dev, unsigned int cycletime, 164 + unsigned int mode) 165 + { 166 + u8 t2, t2i, t0; 167 + u32 val32; 168 + struct ide_timing *t; 169 + 170 + /* PIO Data Setup */ 171 + t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk; 172 + t2 = (ide_timing_find_mode(XFER_PIO_0 + mode)->active + 173 + ide_palm_clk - 1) / ide_palm_clk; 174 + 175 + t2i = t0 - t2 - 1; 176 + t2 -= 1; 177 + 178 + val32 = readl(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8)); 179 + val32 |= (t2 << (dev ? 8 : 0)); 180 + writel(val32, base + BK3710_DATSTB); 181 + 182 + val32 = readl(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8)); 183 + val32 |= (t2i << (dev ? 8 : 0)); 184 + writel(val32, base + BK3710_DATRCVR); 185 + 186 + if (mate && mate->present) { 187 + u8 mode2 = ide_get_best_pio_mode(mate, 255, 4); 188 + 189 + if (mode2 < mode) 190 + mode = mode2; 191 + } 192 + 193 + /* TASKFILE Setup */ 194 + t = ide_timing_find_mode(XFER_PIO_0 + mode); 195 + t0 = (t->cyc8b + ide_palm_clk - 1) / ide_palm_clk; 196 + t2 = (t->act8b + ide_palm_clk - 1) / ide_palm_clk; 197 + 198 + t2i = t0 - t2 - 1; 199 + t2 -= 1; 200 + 201 + val32 = readl(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8)); 202 + val32 |= (t2 << (dev ? 8 : 0)); 203 + writel(val32, base + BK3710_REGSTB); 204 + 205 + val32 = readl(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8)); 206 + val32 |= (t2i << (dev ? 8 : 0)); 207 + writel(val32, base + BK3710_REGRCVR); 208 + } 209 + 210 + static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed) 211 + { 212 + int is_slave = drive->dn & 1; 213 + void __iomem *base = (void *)drive->hwif->dma_base; 214 + 215 + if (xferspeed >= XFER_UDMA_0) { 216 + palm_bk3710_setudmamode(base, is_slave, 217 + xferspeed - XFER_UDMA_0); 218 + } else { 219 + palm_bk3710_setdmamode(base, is_slave, drive->id->eide_dma_min, 220 + xferspeed); 221 + } 222 + } 223 + 224 + static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio) 225 + { 226 + unsigned int cycle_time; 227 + int is_slave = drive->dn & 1; 228 + ide_drive_t *mate; 229 + void __iomem *base = (void *)drive->hwif->dma_base; 230 + 231 + /* 232 + * Obtain the drive PIO data for tuning the Palm Chip registers 233 + */ 234 + cycle_time = ide_pio_cycle_time(drive, pio); 235 + mate = ide_get_paired_drive(drive); 236 + palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio); 237 + } 238 + 239 + static void __devinit palm_bk3710_chipinit(void __iomem *base) 240 + { 241 + /* 242 + * enable the reset_en of ATA controller so that when ata signals 243 + * are brought out, by writing into device config. at that 244 + * time por_n signal should not be 'Z' and have a stable value. 245 + */ 246 + writel(0x0300, base + BK3710_MISCCTL); 247 + 248 + /* wait for some time and deassert the reset of ATA Device. */ 249 + mdelay(100); 250 + 251 + /* Deassert the Reset */ 252 + writel(0x0200, base + BK3710_MISCCTL); 253 + 254 + /* 255 + * Program the IDETIMP Register Value based on the following assumptions 256 + * 257 + * (ATA_IDETIMP_IDEEN , ENABLE ) | 258 + * (ATA_IDETIMP_SLVTIMEN , DISABLE) | 259 + * (ATA_IDETIMP_RDYSMPL , 70NS) | 260 + * (ATA_IDETIMP_RDYRCVRY , 50NS) | 261 + * (ATA_IDETIMP_DMAFTIM1 , PIOCOMP) | 262 + * (ATA_IDETIMP_PREPOST1 , DISABLE) | 263 + * (ATA_IDETIMP_RDYSEN1 , DISABLE) | 264 + * (ATA_IDETIMP_PIOFTIM1 , DISABLE) | 265 + * (ATA_IDETIMP_DMAFTIM0 , PIOCOMP) | 266 + * (ATA_IDETIMP_PREPOST0 , DISABLE) | 267 + * (ATA_IDETIMP_RDYSEN0 , DISABLE) | 268 + * (ATA_IDETIMP_PIOFTIM0 , DISABLE) 269 + */ 270 + writew(0xB388, base + BK3710_IDETIMP); 271 + 272 + /* 273 + * Configure SIDETIM Register 274 + * (ATA_SIDETIM_RDYSMPS1 ,120NS ) | 275 + * (ATA_SIDETIM_RDYRCYS1 ,120NS ) 276 + */ 277 + writeb(0, base + BK3710_SIDETIM); 278 + 279 + /* 280 + * UDMACTL Ultra-ATA DMA Control 281 + * (ATA_UDMACTL_UDMAP1 , 0 ) | 282 + * (ATA_UDMACTL_UDMAP0 , 0 ) 283 + * 284 + */ 285 + writew(0, base + BK3710_UDMACTL); 286 + 287 + /* 288 + * MISCCTL Miscellaneous Conrol Register 289 + * (ATA_MISCCTL_RSTMODEP , 1) | 290 + * (ATA_MISCCTL_RESETP , 0) | 291 + * (ATA_MISCCTL_TIMORIDE , 1) 292 + */ 293 + writel(0x201, base + BK3710_MISCCTL); 294 + 295 + /* 296 + * IORDYTMP IORDY Timer for Primary Register 297 + * (ATA_IORDYTMP_IORDYTMP , 0xffff ) 298 + */ 299 + writel(0xFFFF, base + BK3710_IORDYTMP); 300 + 301 + /* 302 + * Configure BMISP Register 303 + * (ATA_BMISP_DMAEN1 , DISABLE ) | 304 + * (ATA_BMISP_DMAEN0 , DISABLE ) | 305 + * (ATA_BMISP_IORDYINT , CLEAR) | 306 + * (ATA_BMISP_INTRSTAT , CLEAR) | 307 + * (ATA_BMISP_DMAERROR , CLEAR) 308 + */ 309 + writew(0, base + BK3710_BMISP); 310 + 311 + palm_bk3710_setpiomode(base, NULL, 0, 600, 0); 312 + palm_bk3710_setpiomode(base, NULL, 1, 600, 0); 313 + } 314 + static int __devinit palm_bk3710_probe(struct platform_device *pdev) 315 + { 316 + hw_regs_t ide_ctlr_info; 317 + int index = 0; 318 + int pribase; 319 + struct clk *clkp; 320 + struct resource *mem, *irq; 321 + ide_hwif_t *hwif; 322 + void __iomem *base; 323 + 324 + clkp = clk_get(NULL, "IDECLK"); 325 + if (IS_ERR(clkp)) 326 + return -ENODEV; 327 + 328 + ideclkp = clkp; 329 + clk_enable(ideclkp); 330 + ide_palm_clk = clk_get_rate(ideclkp)/100000; 331 + ide_palm_clk = (10000/ide_palm_clk) + 1; 332 + /* Register the IDE interface with Linux ATA Interface */ 333 + memset(&ide_ctlr_info, 0, sizeof(ide_ctlr_info)); 334 + 335 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 336 + if (mem == NULL) { 337 + printk(KERN_ERR "failed to get memory region resource\n"); 338 + return -ENODEV; 339 + } 340 + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 341 + if (irq == NULL) { 342 + printk(KERN_ERR "failed to get IRQ resource\n"); 343 + return -ENODEV; 344 + } 345 + 346 + base = (void *)mem->start; 347 + 348 + /* Configure the Palm Chip controller */ 349 + palm_bk3710_chipinit(base); 350 + 351 + pribase = mem->start + IDE_PALM_ATA_PRI_REG_OFFSET; 352 + for (index = 0; index < IDE_NR_PORTS - 2; index++) 353 + ide_ctlr_info.io_ports[index] = pribase + index; 354 + ide_ctlr_info.io_ports[IDE_CONTROL_OFFSET] = mem->start + 355 + IDE_PALM_ATA_PRI_CTL_OFFSET; 356 + ide_ctlr_info.irq = irq->start; 357 + ide_ctlr_info.chipset = ide_palm3710; 358 + 359 + if (ide_register_hw(&ide_ctlr_info, NULL, &hwif) < 0) { 360 + printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n"); 361 + return -ENODEV; 362 + } 363 + 364 + hwif->set_pio_mode = &palm_bk3710_set_pio_mode; 365 + hwif->set_dma_mode = &palm_bk3710_set_dma_mode; 366 + hwif->mmio = 1; 367 + default_hwif_mmiops(hwif); 368 + hwif->cbl = ATA_CBL_PATA80; 369 + hwif->ultra_mask = 0x1f; /* Ultra DMA Mode 4 Max 370 + (input clk 99MHz) */ 371 + hwif->mwdma_mask = 0x7; 372 + hwif->drives[0].autotune = 1; 373 + hwif->drives[1].autotune = 1; 374 + 375 + ide_setup_dma(hwif, mem->start); 376 + 377 + return 0; 378 + } 379 + 380 + static struct platform_driver platform_bk_driver = { 381 + .driver = { 382 + .name = "palm_bk3710", 383 + }, 384 + .probe = palm_bk3710_probe, 385 + .remove = NULL, 386 + }; 387 + 388 + static int __init palm_bk3710_init(void) 389 + { 390 + return platform_driver_register(&platform_bk_driver); 391 + } 392 + 393 + module_init(palm_bk3710_init); 394 + MODULE_LICENSE("GPL"); 395 +
+1
drivers/ide/ide-proc.c
··· 65 65 case ide_4drives: name = "4drives"; break; 66 66 case ide_pmac: name = "mac-io"; break; 67 67 case ide_au1xxx: name = "au1xxx"; break; 68 + case ide_palm3710: name = "palm3710"; break; 68 69 case ide_etrax100: name = "etrax100"; break; 69 70 case ide_acorn: name = "acorn"; break; 70 71 default: name = "(unknown)"; break;
+3 -2
include/linux/ide.h
··· 173 173 ide_rz1000, ide_trm290, 174 174 ide_cmd646, ide_cy82c693, ide_4drives, 175 175 ide_pmac, ide_etrax100, ide_acorn, 176 - ide_au1xxx, ide_forced 176 + ide_au1xxx, ide_palm3710, ide_forced 177 177 }; 178 178 179 179 typedef u8 hwif_chipset_t; ··· 1014 1014 void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *); 1015 1015 void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *); 1016 1016 1017 - #ifdef CONFIG_BLK_DEV_IDEDMA_PCI 1017 + /* FIXME: palm_bk3710 uses BLK_DEV_IDEDMA_PCI without BLK_DEV_IDEPCI! */ 1018 + #if defined(CONFIG_BLK_DEV_IDEPCI) && defined(CONFIG_BLK_DEV_IDEDMA_PCI) 1018 1019 void ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *); 1019 1020 #else 1020 1021 static inline void ide_hwif_setup_dma(ide_hwif_t *hwif,