Commit 37897989232e6533772b0e24369b35ee9f56c8b6

Authored by Atsushi Nemoto
Committed by Bartlomiej Zolnierkiewicz
1 parent 1f1ab2745b

ide: Add tx4939ide driver (v6)

This is the driver for the Toshiba TX4939 SoC ATA controller.

This controller has standard ATA taskfile registers and DMA
command/status registers, but the register layout is swapped on big
endian.  There are some other endian issue and some special registers
which requires many custom dma_ops/tp_ops routines and build_dmatable.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: ralf@linux-mips.org
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

Showing 3 changed files with 761 additions and 0 deletions Side-by-side Diff

... ... @@ -720,6 +720,11 @@
720 720 default "128"
721 721 depends on BLK_DEV_IDE_AU1XXX
722 722  
  723 +config BLK_DEV_IDE_TX4939
  724 + tristate "TX4939 internal IDE support"
  725 + depends on SOC_TX4939
  726 + select BLK_DEV_IDEDMA_SFF
  727 +
723 728 config IDE_ARM
724 729 tristate "ARM IDE support"
725 730 depends on ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
drivers/ide/Makefile
... ... @@ -111,4 +111,6 @@
111 111 obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o
112 112  
113 113 obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o
  114 +
  115 +obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o
drivers/ide/tx4939ide.c
  1 +/*
  2 + * TX4939 internal IDE driver
  3 + * Based on RBTX49xx patch from CELF patch archive.
  4 + *
  5 + * This file is subject to the terms and conditions of the GNU General Public
  6 + * License. See the file "COPYING" in the main directory of this archive
  7 + * for more details.
  8 + *
  9 + * (C) Copyright TOSHIBA CORPORATION 2005-2007
  10 + */
  11 +
  12 +#include <linux/module.h>
  13 +#include <linux/types.h>
  14 +#include <linux/ide.h>
  15 +#include <linux/init.h>
  16 +#include <linux/delay.h>
  17 +#include <linux/platform_device.h>
  18 +#include <linux/io.h>
  19 +#include <linux/scatterlist.h>
  20 +
  21 +#define MODNAME "tx4939ide"
  22 +
  23 +/* ATA Shadow Registers (8-bit except for Data which is 16-bit) */
  24 +#define TX4939IDE_Data 0x000
  25 +#define TX4939IDE_Error_Feature 0x001
  26 +#define TX4939IDE_Sec 0x002
  27 +#define TX4939IDE_LBA0 0x003
  28 +#define TX4939IDE_LBA1 0x004
  29 +#define TX4939IDE_LBA2 0x005
  30 +#define TX4939IDE_DevHead 0x006
  31 +#define TX4939IDE_Stat_Cmd 0x007
  32 +#define TX4939IDE_AltStat_DevCtl 0x402
  33 +/* H/W DMA Registers */
  34 +#define TX4939IDE_DMA_Cmd 0x800 /* 8-bit */
  35 +#define TX4939IDE_DMA_Stat 0x802 /* 8-bit */
  36 +#define TX4939IDE_PRD_Ptr 0x804 /* 32-bit */
  37 +/* ATA100 CORE Registers (16-bit) */
  38 +#define TX4939IDE_Sys_Ctl 0xc00
  39 +#define TX4939IDE_Xfer_Cnt_1 0xc08
  40 +#define TX4939IDE_Xfer_Cnt_2 0xc0a
  41 +#define TX4939IDE_Sec_Cnt 0xc10
  42 +#define TX4939IDE_Start_Lo_Addr 0xc18
  43 +#define TX4939IDE_Start_Up_Addr 0xc20
  44 +#define TX4939IDE_Add_Ctl 0xc28
  45 +#define TX4939IDE_Lo_Burst_Cnt 0xc30
  46 +#define TX4939IDE_Up_Burst_Cnt 0xc38
  47 +#define TX4939IDE_PIO_Addr 0xc88
  48 +#define TX4939IDE_H_Rst_Tim 0xc90
  49 +#define TX4939IDE_Int_Ctl 0xc98
  50 +#define TX4939IDE_Pkt_Cmd 0xcb8
  51 +#define TX4939IDE_Bxfer_Cnt_Hi 0xcc0
  52 +#define TX4939IDE_Bxfer_Cnt_Lo 0xcc8
  53 +#define TX4939IDE_Dev_TErr 0xcd0
  54 +#define TX4939IDE_Pkt_Xfer_Ctl 0xcd8
  55 +#define TX4939IDE_Start_TAddr 0xce0
  56 +
  57 +/* bits for Int_Ctl */
  58 +#define TX4939IDE_INT_ADDRERR 0x80
  59 +#define TX4939IDE_INT_REACHMUL 0x40
  60 +#define TX4939IDE_INT_DEVTIMING 0x20
  61 +#define TX4939IDE_INT_UDMATERM 0x10
  62 +#define TX4939IDE_INT_TIMER 0x08
  63 +#define TX4939IDE_INT_BUSERR 0x04
  64 +#define TX4939IDE_INT_XFEREND 0x02
  65 +#define TX4939IDE_INT_HOST 0x01
  66 +
  67 +#define TX4939IDE_IGNORE_INTS \
  68 + (TX4939IDE_INT_ADDRERR | TX4939IDE_INT_REACHMUL | \
  69 + TX4939IDE_INT_DEVTIMING | TX4939IDE_INT_UDMATERM | \
  70 + TX4939IDE_INT_TIMER | TX4939IDE_INT_XFEREND)
  71 +
  72 +#ifdef __BIG_ENDIAN
  73 +#define tx4939ide_swizzlel(a) ((a) ^ 4)
  74 +#define tx4939ide_swizzlew(a) ((a) ^ 6)
  75 +#define tx4939ide_swizzleb(a) ((a) ^ 7)
  76 +#else
  77 +#define tx4939ide_swizzlel(a) (a)
  78 +#define tx4939ide_swizzlew(a) (a)
  79 +#define tx4939ide_swizzleb(a) (a)
  80 +#endif
  81 +
  82 +static u16 tx4939ide_readw(void __iomem *base, u32 reg)
  83 +{
  84 + return __raw_readw(base + tx4939ide_swizzlew(reg));
  85 +}
  86 +static u8 tx4939ide_readb(void __iomem *base, u32 reg)
  87 +{
  88 + return __raw_readb(base + tx4939ide_swizzleb(reg));
  89 +}
  90 +static void tx4939ide_writel(u32 val, void __iomem *base, u32 reg)
  91 +{
  92 + __raw_writel(val, base + tx4939ide_swizzlel(reg));
  93 +}
  94 +static void tx4939ide_writew(u16 val, void __iomem *base, u32 reg)
  95 +{
  96 + __raw_writew(val, base + tx4939ide_swizzlew(reg));
  97 +}
  98 +static void tx4939ide_writeb(u8 val, void __iomem *base, u32 reg)
  99 +{
  100 + __raw_writeb(val, base + tx4939ide_swizzleb(reg));
  101 +}
  102 +
  103 +#define TX4939IDE_BASE(hwif) ((void __iomem *)(hwif)->extra_base)
  104 +
  105 +static void tx4939ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
  106 +{
  107 + ide_hwif_t *hwif = drive->hwif;
  108 + int is_slave = drive->dn;
  109 + u32 mask, val;
  110 + u8 safe = pio;
  111 + ide_drive_t *pair;
  112 +
  113 + pair = ide_get_pair_dev(drive);
  114 + if (pair)
  115 + safe = min(safe, ide_get_best_pio_mode(pair, 255, 4));
  116 + /*
  117 + * Update Command Transfer Mode for master/slave and Data
  118 + * Transfer Mode for this drive.
  119 + */
  120 + mask = is_slave ? 0x07f00000 : 0x000007f0;
  121 + val = ((safe << 8) | (pio << 4)) << (is_slave ? 16 : 0);
  122 + hwif->select_data = (hwif->select_data & ~mask) | val;
  123 + /* tx4939ide_tf_load_fixup() will set the Sys_Ctl register */
  124 +}
  125 +
  126 +static void tx4939ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
  127 +{
  128 + ide_hwif_t *hwif = drive->hwif;
  129 + u32 mask, val;
  130 +
  131 + /* Update Data Transfer Mode for this drive. */
  132 + if (mode >= XFER_UDMA_0)
  133 + val = mode - XFER_UDMA_0 + 8;
  134 + else
  135 + val = mode - XFER_MW_DMA_0 + 5;
  136 + if (drive->dn) {
  137 + mask = 0x00f00000;
  138 + val <<= 20;
  139 + } else {
  140 + mask = 0x000000f0;
  141 + val <<= 4;
  142 + }
  143 + hwif->select_data = (hwif->select_data & ~mask) | val;
  144 + /* tx4939ide_tf_load_fixup() will set the Sys_Ctl register */
  145 +}
  146 +
  147 +static u16 tx4939ide_check_error_ints(ide_hwif_t *hwif)
  148 +{
  149 + void __iomem *base = TX4939IDE_BASE(hwif);
  150 + u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl);
  151 +
  152 + if (ctl & TX4939IDE_INT_BUSERR) {
  153 + /* reset FIFO */
  154 + u16 sysctl = tx4939ide_readw(base, TX4939IDE_Sys_Ctl);
  155 +
  156 + tx4939ide_writew(sysctl | 0x4000, base, TX4939IDE_Sys_Ctl);
  157 + mmiowb();
  158 + /* wait 12GBUSCLK (typ. 60ns @ GBUS200MHz, max 270ns) */
  159 + ndelay(270);
  160 + tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
  161 + }
  162 + if (ctl & (TX4939IDE_INT_ADDRERR |
  163 + TX4939IDE_INT_DEVTIMING | TX4939IDE_INT_BUSERR))
  164 + pr_err("%s: Error interrupt %#x (%s%s%s )\n",
  165 + hwif->name, ctl,
  166 + ctl & TX4939IDE_INT_ADDRERR ? " Address-Error" : "",
  167 + ctl & TX4939IDE_INT_DEVTIMING ? " DEV-Timing" : "",
  168 + ctl & TX4939IDE_INT_BUSERR ? " Bus-Error" : "");
  169 + return ctl;
  170 +}
  171 +
  172 +static void tx4939ide_clear_irq(ide_drive_t *drive)
  173 +{
  174 + ide_hwif_t *hwif;
  175 + void __iomem *base;
  176 + u16 ctl;
  177 +
  178 + /*
  179 + * tx4939ide_dma_test_irq() and tx4939ide_dma_end() do all job
  180 + * for DMA case.
  181 + */
  182 + if (drive->waiting_for_dma)
  183 + return;
  184 + hwif = drive->hwif;
  185 + base = TX4939IDE_BASE(hwif);
  186 + ctl = tx4939ide_check_error_ints(hwif);
  187 + tx4939ide_writew(ctl, base, TX4939IDE_Int_Ctl);
  188 +}
  189 +
  190 +static u8 tx4939ide_cable_detect(ide_hwif_t *hwif)
  191 +{
  192 + void __iomem *base = TX4939IDE_BASE(hwif);
  193 +
  194 + return tx4939ide_readw(base, TX4939IDE_Sys_Ctl) & 0x2000 ?
  195 + ATA_CBL_PATA40 : ATA_CBL_PATA80;
  196 +}
  197 +
  198 +#ifdef __BIG_ENDIAN
  199 +static void tx4939ide_dma_host_set(ide_drive_t *drive, int on)
  200 +{
  201 + ide_hwif_t *hwif = drive->hwif;
  202 + u8 unit = drive->dn;
  203 + void __iomem *base = TX4939IDE_BASE(hwif);
  204 + u8 dma_stat = tx4939ide_readb(base, TX4939IDE_DMA_Stat);
  205 +
  206 + if (on)
  207 + dma_stat |= (1 << (5 + unit));
  208 + else
  209 + dma_stat &= ~(1 << (5 + unit));
  210 +
  211 + tx4939ide_writeb(dma_stat, base, TX4939IDE_DMA_Stat);
  212 +}
  213 +#else
  214 +#define tx4939ide_dma_host_set ide_dma_host_set
  215 +#endif
  216 +
  217 +static u8 tx4939ide_clear_dma_status(void __iomem *base)
  218 +{
  219 + u8 dma_stat;
  220 +
  221 + /* read DMA status for INTR & ERROR flags */
  222 + dma_stat = tx4939ide_readb(base, TX4939IDE_DMA_Stat);
  223 + /* clear INTR & ERROR flags */
  224 + tx4939ide_writeb(dma_stat | ATA_DMA_INTR | ATA_DMA_ERR, base,
  225 + TX4939IDE_DMA_Stat);
  226 + /* recover intmask cleared by writing to bit2 of DMA_Stat */
  227 + tx4939ide_writew(TX4939IDE_IGNORE_INTS << 8, base, TX4939IDE_Int_Ctl);
  228 + return dma_stat;
  229 +}
  230 +
  231 +#ifdef __BIG_ENDIAN
  232 +/* custom ide_build_dmatable to handle swapped layout */
  233 +static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
  234 +{
  235 + ide_hwif_t *hwif = drive->hwif;
  236 + u32 *table = (u32 *)hwif->dmatable_cpu;
  237 + unsigned int count = 0;
  238 + int i;
  239 + struct scatterlist *sg;
  240 +
  241 + hwif->sg_nents = ide_build_sglist(drive, rq);
  242 + if (hwif->sg_nents == 0)
  243 + return 0;
  244 +
  245 + for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
  246 + u32 cur_addr, cur_len, bcount;
  247 +
  248 + cur_addr = sg_dma_address(sg);
  249 + cur_len = sg_dma_len(sg);
  250 +
  251 + /*
  252 + * Fill in the DMA table, without crossing any 64kB boundaries.
  253 + */
  254 +
  255 + while (cur_len) {
  256 + if (count++ >= PRD_ENTRIES)
  257 + goto use_pio_instead;
  258 +
  259 + bcount = 0x10000 - (cur_addr & 0xffff);
  260 + if (bcount > cur_len)
  261 + bcount = cur_len;
  262 + *table++ = bcount & 0xffff;
  263 + *table++ = cur_addr;
  264 + cur_addr += bcount;
  265 + cur_len -= bcount;
  266 + }
  267 + }
  268 +
  269 + if (count) {
  270 + *(table - 2) |= 0x80000000;
  271 + return count;
  272 + }
  273 +
  274 +use_pio_instead:
  275 + printk(KERN_ERR "%s: %s\n", drive->name,
  276 + count ? "DMA table too small" : "empty DMA table?");
  277 +
  278 + ide_destroy_dmatable(drive);
  279 +
  280 + return 0; /* revert to PIO for this request */
  281 +}
  282 +#else
  283 +#define tx4939ide_build_dmatable ide_build_dmatable
  284 +#endif
  285 +
  286 +static int tx4939ide_dma_setup(ide_drive_t *drive)
  287 +{
  288 + ide_hwif_t *hwif = drive->hwif;
  289 + void __iomem *base = TX4939IDE_BASE(hwif);
  290 + struct request *rq = hwif->hwgroup->rq;
  291 + u8 reading;
  292 + int nent;
  293 +
  294 + if (rq_data_dir(rq))
  295 + reading = 0;
  296 + else
  297 + reading = ATA_DMA_WR;
  298 +
  299 + /* fall back to PIO! */
  300 + nent = tx4939ide_build_dmatable(drive, rq);
  301 + if (!nent) {
  302 + ide_map_sg(drive, rq);
  303 + return 1;
  304 + }
  305 +
  306 + /* PRD table */
  307 + tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr);
  308 +
  309 + /* specify r/w */
  310 + tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd);
  311 +
  312 + /* clear INTR & ERROR flags */
  313 + tx4939ide_clear_dma_status(base);
  314 +
  315 + drive->waiting_for_dma = 1;
  316 +
  317 + tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
  318 + TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
  319 + tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
  320 + return 0;
  321 +}
  322 +
  323 +static int tx4939ide_dma_end(ide_drive_t *drive)
  324 +{
  325 + ide_hwif_t *hwif = drive->hwif;
  326 + u8 dma_stat, dma_cmd;
  327 + void __iomem *base = TX4939IDE_BASE(hwif);
  328 + u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl);
  329 +
  330 + drive->waiting_for_dma = 0;
  331 +
  332 + /* get DMA command mode */
  333 + dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd);
  334 + /* stop DMA */
  335 + tx4939ide_writeb(dma_cmd & ~ATA_DMA_START, base, TX4939IDE_DMA_Cmd);
  336 +
  337 + /* read and clear the INTR & ERROR bits */
  338 + dma_stat = tx4939ide_clear_dma_status(base);
  339 +
  340 + /* purge DMA mappings */
  341 + ide_destroy_dmatable(drive);
  342 + /* verify good DMA status */
  343 + wmb();
  344 +
  345 + if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
  346 + (ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
  347 + (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
  348 + /* INT_IDE lost... bug? */
  349 + return 0;
  350 + return ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) !=
  351 + ATA_DMA_INTR) ? 0x10 | dma_stat : 0;
  352 +}
  353 +
  354 +/* returns 1 if DMA IRQ issued, 0 otherwise */
  355 +static int tx4939ide_dma_test_irq(ide_drive_t *drive)
  356 +{
  357 + ide_hwif_t *hwif = drive->hwif;
  358 + void __iomem *base = TX4939IDE_BASE(hwif);
  359 + u16 ctl, ide_int;
  360 + u8 dma_stat, stat;
  361 + int found = 0;
  362 +
  363 + ctl = tx4939ide_check_error_ints(hwif);
  364 + ide_int = ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST);
  365 + switch (ide_int) {
  366 + case TX4939IDE_INT_HOST:
  367 + /* On error, XFEREND might not be asserted. */
  368 + stat = tx4939ide_readb(base, TX4939IDE_AltStat_DevCtl);
  369 + if ((stat & (ATA_BUSY | ATA_DRQ | ATA_ERR)) == ATA_ERR)
  370 + found = 1;
  371 + else
  372 + /* Wait for XFEREND (Mask HOST and unmask XFEREND) */
  373 + ctl &= ~TX4939IDE_INT_XFEREND << 8;
  374 + ctl |= ide_int << 8;
  375 + break;
  376 + case TX4939IDE_INT_HOST | TX4939IDE_INT_XFEREND:
  377 + dma_stat = tx4939ide_readb(base, TX4939IDE_DMA_Stat);
  378 + if (!(dma_stat & ATA_DMA_INTR))
  379 + pr_warning("%s: weird interrupt status. "
  380 + "DMA_Stat %#02x int_ctl %#04x\n",
  381 + hwif->name, dma_stat, ctl);
  382 + found = 1;
  383 + break;
  384 + }
  385 + /*
  386 + * Do not clear XFEREND, HOST now. They will be cleared by
  387 + * clearing bit2 of DMA_Stat.
  388 + */
  389 + ctl &= ~ide_int;
  390 + tx4939ide_writew(ctl, base, TX4939IDE_Int_Ctl);
  391 + return found;
  392 +}
  393 +
  394 +static void tx4939ide_init_hwif(ide_hwif_t *hwif)
  395 +{
  396 + void __iomem *base = TX4939IDE_BASE(hwif);
  397 +
  398 + /* Soft Reset */
  399 + tx4939ide_writew(0x8000, base, TX4939IDE_Sys_Ctl);
  400 + mmiowb();
  401 + /* at least 20 GBUSCLK (typ. 100ns @ GBUS200MHz, max 450ns) */
  402 + ndelay(450);
  403 + tx4939ide_writew(0x0000, base, TX4939IDE_Sys_Ctl);
  404 + /* mask some interrupts and clear all interrupts */
  405 + tx4939ide_writew((TX4939IDE_IGNORE_INTS << 8) | 0xff, base,
  406 + TX4939IDE_Int_Ctl);
  407 +
  408 + tx4939ide_writew(0x0008, base, TX4939IDE_Lo_Burst_Cnt);
  409 + tx4939ide_writew(0, base, TX4939IDE_Up_Burst_Cnt);
  410 +}
  411 +
  412 +static int tx4939ide_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
  413 +{
  414 + hwif->dma_base =
  415 + hwif->extra_base + tx4939ide_swizzleb(TX4939IDE_DMA_Cmd);
  416 + /*
  417 + * Note that we cannot use ATA_DMA_TABLE_OFS, ATA_DMA_STATUS
  418 + * for big endian.
  419 + */
  420 + return ide_allocate_dma_engine(hwif);
  421 +}
  422 +
  423 +static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task)
  424 +{
  425 + ide_hwif_t *hwif = drive->hwif;
  426 + void __iomem *base = TX4939IDE_BASE(hwif);
  427 + u16 sysctl = hwif->select_data >> (drive->dn ? 16 : 0);
  428 +
  429 + /*
  430 + * Fix ATA100 CORE System Control Register. (The write to the
  431 + * Device/Head register may write wrong data to the System
  432 + * Control Register)
  433 + * While Sys_Ctl is written here, selectproc is not needed.
  434 + */
  435 + tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
  436 +}
  437 +
  438 +#ifdef __BIG_ENDIAN
  439 +
  440 +static u8 tx4939ide_read_sff_dma_status(ide_hwif_t *hwif)
  441 +{
  442 + void __iomem *base = TX4939IDE_BASE(hwif);
  443 +
  444 + return tx4939ide_readb(base, TX4939IDE_DMA_Stat);
  445 +}
  446 +
  447 +/* custom iops (independent from SWAP_IO_SPACE) */
  448 +static u8 tx4939ide_inb(unsigned long port)
  449 +{
  450 + return __raw_readb((void __iomem *)port);
  451 +}
  452 +
  453 +static void tx4939ide_outb(u8 value, unsigned long port)
  454 +{
  455 + __raw_writeb(value, (void __iomem *)port);
  456 +}
  457 +
  458 +static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
  459 +{
  460 + ide_hwif_t *hwif = drive->hwif;
  461 + struct ide_io_ports *io_ports = &hwif->io_ports;
  462 + struct ide_taskfile *tf = &task->tf;
  463 + u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
  464 +
  465 + if (task->tf_flags & IDE_TFLAG_FLAGGED)
  466 + HIHI = 0xFF;
  467 +
  468 + if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
  469 + u16 data = (tf->hob_data << 8) | tf->data;
  470 +
  471 + /* no endian swap */
  472 + __raw_writew(data, (void __iomem *)io_ports->data_addr);
  473 + }
  474 +
  475 + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
  476 + tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
  477 + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
  478 + tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr);
  479 + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
  480 + tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr);
  481 + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
  482 + tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr);
  483 + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
  484 + tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr);
  485 +
  486 + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
  487 + tx4939ide_outb(tf->feature, io_ports->feature_addr);
  488 + if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
  489 + tx4939ide_outb(tf->nsect, io_ports->nsect_addr);
  490 + if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
  491 + tx4939ide_outb(tf->lbal, io_ports->lbal_addr);
  492 + if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
  493 + tx4939ide_outb(tf->lbam, io_ports->lbam_addr);
  494 + if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
  495 + tx4939ide_outb(tf->lbah, io_ports->lbah_addr);
  496 +
  497 + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) {
  498 + tx4939ide_outb((tf->device & HIHI) | drive->select,
  499 + io_ports->device_addr);
  500 + tx4939ide_tf_load_fixup(drive, task);
  501 + }
  502 +}
  503 +
  504 +static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task)
  505 +{
  506 + ide_hwif_t *hwif = drive->hwif;
  507 + struct ide_io_ports *io_ports = &hwif->io_ports;
  508 + struct ide_taskfile *tf = &task->tf;
  509 +
  510 + if (task->tf_flags & IDE_TFLAG_IN_DATA) {
  511 + u16 data;
  512 +
  513 + /* no endian swap */
  514 + data = __raw_readw((void __iomem *)io_ports->data_addr);
  515 + tf->data = data & 0xff;
  516 + tf->hob_data = (data >> 8) & 0xff;
  517 + }
  518 +
  519 + /* be sure we're looking at the low order bits */
  520 + tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
  521 +
  522 + if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
  523 + tf->feature = tx4939ide_inb(io_ports->feature_addr);
  524 + if (task->tf_flags & IDE_TFLAG_IN_NSECT)
  525 + tf->nsect = tx4939ide_inb(io_ports->nsect_addr);
  526 + if (task->tf_flags & IDE_TFLAG_IN_LBAL)
  527 + tf->lbal = tx4939ide_inb(io_ports->lbal_addr);
  528 + if (task->tf_flags & IDE_TFLAG_IN_LBAM)
  529 + tf->lbam = tx4939ide_inb(io_ports->lbam_addr);
  530 + if (task->tf_flags & IDE_TFLAG_IN_LBAH)
  531 + tf->lbah = tx4939ide_inb(io_ports->lbah_addr);
  532 + if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
  533 + tf->device = tx4939ide_inb(io_ports->device_addr);
  534 +
  535 + if (task->tf_flags & IDE_TFLAG_LBA48) {
  536 + tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
  537 +
  538 + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
  539 + tf->hob_feature =
  540 + tx4939ide_inb(io_ports->feature_addr);
  541 + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
  542 + tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
  543 + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
  544 + tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
  545 + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
  546 + tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
  547 + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
  548 + tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
  549 + }
  550 +}
  551 +
  552 +static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq,
  553 + void *buf, unsigned int len)
  554 +{
  555 + unsigned long port = drive->hwif->io_ports.data_addr;
  556 + unsigned short *ptr = buf;
  557 + unsigned int count = (len + 1) / 2;
  558 +
  559 + while (count--)
  560 + *ptr++ = cpu_to_le16(__raw_readw((void __iomem *)port));
  561 + __ide_flush_dcache_range((unsigned long)buf, count * 2);
  562 +}
  563 +
  564 +static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq,
  565 + void *buf, unsigned int len)
  566 +{
  567 + unsigned long port = drive->hwif->io_ports.data_addr;
  568 + unsigned short *ptr = buf;
  569 + unsigned int count = (len + 1) / 2;
  570 +
  571 + while (count--) {
  572 + __raw_writew(le16_to_cpu(*ptr), (void __iomem *)port);
  573 + ptr++;
  574 + }
  575 + __ide_flush_dcache_range((unsigned long)buf, count * 2);
  576 +}
  577 +
  578 +static const struct ide_tp_ops tx4939ide_tp_ops = {
  579 + .exec_command = ide_exec_command,
  580 + .read_status = ide_read_status,
  581 + .read_altstatus = ide_read_altstatus,
  582 + .read_sff_dma_status = tx4939ide_read_sff_dma_status,
  583 +
  584 + .set_irq = ide_set_irq,
  585 +
  586 + .tf_load = tx4939ide_tf_load,
  587 + .tf_read = tx4939ide_tf_read,
  588 +
  589 + .input_data = tx4939ide_input_data_swap,
  590 + .output_data = tx4939ide_output_data_swap,
  591 +};
  592 +
  593 +#else /* __LITTLE_ENDIAN */
  594 +
  595 +static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
  596 +{
  597 + ide_tf_load(drive, task);
  598 + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
  599 + tx4939ide_tf_load_fixup(drive, task);
  600 +}
  601 +
  602 +static const struct ide_tp_ops tx4939ide_tp_ops = {
  603 + .exec_command = ide_exec_command,
  604 + .read_status = ide_read_status,
  605 + .read_altstatus = ide_read_altstatus,
  606 + .read_sff_dma_status = ide_read_sff_dma_status,
  607 +
  608 + .set_irq = ide_set_irq,
  609 +
  610 + .tf_load = tx4939ide_tf_load,
  611 + .tf_read = ide_tf_read,
  612 +
  613 + .input_data = ide_input_data,
  614 + .output_data = ide_output_data,
  615 +};
  616 +
  617 +#endif /* __LITTLE_ENDIAN */
  618 +
  619 +static const struct ide_port_ops tx4939ide_port_ops = {
  620 + .set_pio_mode = tx4939ide_set_pio_mode,
  621 + .set_dma_mode = tx4939ide_set_dma_mode,
  622 + .clear_irq = tx4939ide_clear_irq,
  623 + .cable_detect = tx4939ide_cable_detect,
  624 +};
  625 +
  626 +static const struct ide_dma_ops tx4939ide_dma_ops = {
  627 + .dma_host_set = tx4939ide_dma_host_set,
  628 + .dma_setup = tx4939ide_dma_setup,
  629 + .dma_exec_cmd = ide_dma_exec_cmd,
  630 + .dma_start = ide_dma_start,
  631 + .dma_end = tx4939ide_dma_end,
  632 + .dma_test_irq = tx4939ide_dma_test_irq,
  633 + .dma_lost_irq = ide_dma_lost_irq,
  634 + .dma_timeout = ide_dma_timeout,
  635 +};
  636 +
  637 +static const struct ide_port_info tx4939ide_port_info __initdata = {
  638 + .init_hwif = tx4939ide_init_hwif,
  639 + .init_dma = tx4939ide_init_dma,
  640 + .port_ops = &tx4939ide_port_ops,
  641 + .dma_ops = &tx4939ide_dma_ops,
  642 + .tp_ops = &tx4939ide_tp_ops,
  643 + .host_flags = IDE_HFLAG_MMIO,
  644 + .pio_mask = ATA_PIO4,
  645 + .mwdma_mask = ATA_MWDMA2,
  646 + .udma_mask = ATA_UDMA5,
  647 +};
  648 +
  649 +static int __init tx4939ide_probe(struct platform_device *pdev)
  650 +{
  651 + hw_regs_t hw;
  652 + hw_regs_t *hws[] = { &hw, NULL, NULL, NULL };
  653 + struct ide_host *host;
  654 + struct resource *res;
  655 + int irq, ret;
  656 + unsigned long mapbase;
  657 +
  658 + irq = platform_get_irq(pdev, 0);
  659 + if (irq < 0)
  660 + return -ENODEV;
  661 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  662 + if (!res)
  663 + return -ENODEV;
  664 +
  665 + if (!devm_request_mem_region(&pdev->dev, res->start,
  666 + res->end - res->start + 1, "tx4938ide"))
  667 + return -EBUSY;
  668 + mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start,
  669 + res->end - res->start + 1);
  670 + if (!mapbase)
  671 + return -EBUSY;
  672 + memset(&hw, 0, sizeof(hw));
  673 + hw.io_ports.data_addr =
  674 + mapbase + tx4939ide_swizzlew(TX4939IDE_Data);
  675 + hw.io_ports.error_addr =
  676 + mapbase + tx4939ide_swizzleb(TX4939IDE_Error_Feature);
  677 + hw.io_ports.nsect_addr =
  678 + mapbase + tx4939ide_swizzleb(TX4939IDE_Sec);
  679 + hw.io_ports.lbal_addr =
  680 + mapbase + tx4939ide_swizzleb(TX4939IDE_LBA0);
  681 + hw.io_ports.lbam_addr =
  682 + mapbase + tx4939ide_swizzleb(TX4939IDE_LBA1);
  683 + hw.io_ports.lbah_addr =
  684 + mapbase + tx4939ide_swizzleb(TX4939IDE_LBA2);
  685 + hw.io_ports.device_addr =
  686 + mapbase + tx4939ide_swizzleb(TX4939IDE_DevHead);
  687 + hw.io_ports.command_addr =
  688 + mapbase + tx4939ide_swizzleb(TX4939IDE_Stat_Cmd);
  689 + hw.io_ports.ctl_addr =
  690 + mapbase + tx4939ide_swizzleb(TX4939IDE_AltStat_DevCtl);
  691 + hw.irq = irq;
  692 + hw.dev = &pdev->dev;
  693 +
  694 + pr_info("TX4939 IDE interface (base %#lx, irq %d)\n", mapbase, irq);
  695 + host = ide_host_alloc(&tx4939ide_port_info, hws);
  696 + if (!host)
  697 + return -ENOMEM;
  698 + /* use extra_base for base address of the all registers */
  699 + host->ports[0]->extra_base = mapbase;
  700 + ret = ide_host_register(host, &tx4939ide_port_info, hws);
  701 + if (ret) {
  702 + ide_host_free(host);
  703 + return ret;
  704 + }
  705 + platform_set_drvdata(pdev, host);
  706 + return 0;
  707 +}
  708 +
  709 +static int __exit tx4939ide_remove(struct platform_device *pdev)
  710 +{
  711 + struct ide_host *host = platform_get_drvdata(pdev);
  712 +
  713 + ide_host_remove(host);
  714 + return 0;
  715 +}
  716 +
  717 +#ifdef CONFIG_PM
  718 +static int tx4939ide_resume(struct platform_device *dev)
  719 +{
  720 + struct ide_host *host = platform_get_drvdata(dev);
  721 + ide_hwif_t *hwif = host->ports[0];
  722 +
  723 + tx4939ide_init_hwif(hwif);
  724 + return 0;
  725 +}
  726 +#else
  727 +#define tx4939ide_resume NULL
  728 +#endif
  729 +
  730 +static struct platform_driver tx4939ide_driver = {
  731 + .driver = {
  732 + .name = MODNAME,
  733 + .owner = THIS_MODULE,
  734 + },
  735 + .remove = __exit_p(tx4939ide_remove),
  736 + .resume = tx4939ide_resume,
  737 +};
  738 +
  739 +static int __init tx4939ide_init(void)
  740 +{
  741 + return platform_driver_probe(&tx4939ide_driver, tx4939ide_probe);
  742 +}
  743 +
  744 +static void __exit tx4939ide_exit(void)
  745 +{
  746 + platform_driver_unregister(&tx4939ide_driver);
  747 +}
  748 +
  749 +module_init(tx4939ide_init);
  750 +module_exit(tx4939ide_exit);
  751 +
  752 +MODULE_DESCRIPTION("TX4939 internal IDE driver");
  753 +MODULE_LICENSE("GPL");
  754 +MODULE_ALIAS("platform:tx4939ide");