Commit 7c7e92a9268965e08bba853ecdb94fa55e886741

Authored by Anton Salnikov
Committed by Bartlomiej Zolnierkiewicz
1 parent b2a53bc636

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>

Showing 5 changed files with 409 additions and 2 deletions Side-by-side Diff

... ... @@ -1009,6 +1009,15 @@
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
drivers/ide/arm/Makefile
... ... @@ -2,6 +2,7 @@
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
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");
drivers/ide/ide-proc.c
... ... @@ -65,6 +65,7 @@
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;
... ... @@ -173,7 +173,7 @@
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,7 +1014,8 @@
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,