Commit e63b68de authored by Mikael Starvik's avatar Mikael Starvik Committed by Linus Torvalds

[PATCH] CRIS IDE driver

  * Added abstraction layer for subarchs.
  * Added v32 support.
  * Renamed driver.
Signed-off-by: default avatarMikael Starvik <starvik@axis.com>
Acked-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 51533b61
EXTRA_CFLAGS += -Idrivers/ide EXTRA_CFLAGS += -Idrivers/ide
obj-$(CONFIG_ETRAX_ARCH_V10) += ide-v10.o obj-y += ide-cris.o
/* $Id: ide.c,v 1.4 2004/10/12 07:55:48 starvik Exp $ /* $Id: cris-ide-driver.patch,v 1.1 2005/06/29 21:39:07 akpm Exp $
* *
* Etrax specific IDE functions, like init and PIO-mode setting etc. * Etrax specific IDE functions, like init and PIO-mode setting etc.
* Almost the entire ide.c is used for the rest of the Etrax ATA driver. * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
* Copyright (c) 2000-2004 Axis Communications AB * Copyright (c) 2000-2005 Axis Communications AB
* *
* Authors: Bjorn Wesen (initial version) * Authors: Bjorn Wesen (initial version)
* Mikael Starvik (pio setup stuff, Linux 2.6 port) * Mikael Starvik (crisv32 port)
*/ */
/* Regarding DMA: /* Regarding DMA:
...@@ -30,13 +30,11 @@ ...@@ -30,13 +30,11 @@
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/scatterlist.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/svinto.h>
#include <asm/dma.h> #include <asm/dma.h>
/* number of Etrax DMA descriptors */ /* number of DMA descriptors */
#define MAX_DMA_DESCRS 64 #define MAX_DMA_DESCRS 64
/* number of times to retry busy-flags when reading/writing IDE-registers /* number of times to retry busy-flags when reading/writing IDE-registers
...@@ -46,113 +44,244 @@ ...@@ -46,113 +44,244 @@
#define IDE_REGISTER_TIMEOUT 300 #define IDE_REGISTER_TIMEOUT 300
static int e100_read_command = 0;
#define LOWDB(x) #define LOWDB(x)
#define D(x) #define D(x)
static int e100_ide_build_dmatable (ide_drive_t *drive); enum /* Transfer types */
static ide_startstop_t etrax_dma_intr (ide_drive_t *drive); {
TYPE_PIO,
TYPE_DMA,
TYPE_UDMA
};
/* CRISv32 specifics */
#ifdef CONFIG_ETRAX_ARCH_V32
#include <asm/arch/hwregs/ata_defs.h>
#include <asm/arch/hwregs/dma_defs.h>
#include <asm/arch/hwregs/dma.h>
#include <asm/arch/pinmux.h>
#define ATA_UDMA2_CYC 2
#define ATA_UDMA2_DVS 3
#define ATA_UDMA1_CYC 2
#define ATA_UDMA1_DVS 4
#define ATA_UDMA0_CYC 4
#define ATA_UDMA0_DVS 6
#define ATA_DMA2_STROBE 7
#define ATA_DMA2_HOLD 1
#define ATA_DMA1_STROBE 8
#define ATA_DMA1_HOLD 3
#define ATA_DMA0_STROBE 25
#define ATA_DMA0_HOLD 19
#define ATA_PIO4_SETUP 3
#define ATA_PIO4_STROBE 7
#define ATA_PIO4_HOLD 1
#define ATA_PIO3_SETUP 3
#define ATA_PIO3_STROBE 9
#define ATA_PIO3_HOLD 3
#define ATA_PIO2_SETUP 3
#define ATA_PIO2_STROBE 13
#define ATA_PIO2_HOLD 5
#define ATA_PIO1_SETUP 5
#define ATA_PIO1_STROBE 23
#define ATA_PIO1_HOLD 9
#define ATA_PIO0_SETUP 9
#define ATA_PIO0_STROBE 39
#define ATA_PIO0_HOLD 9
int
cris_ide_ack_intr(ide_hwif_t* hwif)
{
reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2,
int, hwif->io_ports[0]);
REG_WR_INT(ata, regi_ata, rw_ack_intr, 1 << ctrl2.sel);
return 1;
}
void static inline int
etrax100_ide_outw(unsigned short data, unsigned long reg) { cris_ide_busy(void)
int timeleft; {
LOWDB(printk("ow: data 0x%x, reg 0x%x\n", data, reg)); reg_ata_rs_stat_data stat_data;
stat_data = REG_RD(ata, regi_ata, rs_stat_data);
return stat_data.busy;
}
/* note the lack of handling any timeouts. we stop waiting, but we don't static inline int
* really notify anybody. cris_ide_ready(void)
*/ {
return !cris_ide_busy();
}
timeleft = IDE_REGISTER_TIMEOUT; static inline int
/* wait for busy flag */ cris_ide_data_available(unsigned short* data)
while(timeleft && (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy))) {
timeleft--; reg_ata_rs_stat_data stat_data;
stat_data = REG_RD(ata, regi_ata, rs_stat_data);
*data = stat_data.data;
return stat_data.dav;
}
/* static void
* Fall through at a timeout, so the ongoing command will be cris_ide_write_command(unsigned long command)
* aborted by the write below, which is expected to be a dummy {
* command to the command register. This happens when a faulty REG_WR_INT(ata, regi_ata, rw_ctrl2, command); /* write data to the drive's register */
* drive times out on a command. See comment on timeout in }
* INB.
*/
if(!timeleft)
printk("ATA timeout reg 0x%lx := 0x%x\n", reg, data);
*R_ATA_CTRL_DATA = reg | data; /* write data to the drive's register */ static void
cris_ide_set_speed(int type, int setup, int strobe, int hold)
{
reg_ata_rw_ctrl0 ctrl0 = REG_RD(ata, regi_ata, rw_ctrl0);
reg_ata_rw_ctrl1 ctrl1 = REG_RD(ata, regi_ata, rw_ctrl1);
if (type == TYPE_PIO) {
ctrl0.pio_setup = setup;
ctrl0.pio_strb = strobe;
ctrl0.pio_hold = hold;
} else if (type == TYPE_DMA) {
ctrl0.dma_strb = strobe;
ctrl0.dma_hold = hold;
} else if (type == TYPE_UDMA) {
ctrl1.udma_tcyc = setup;
ctrl1.udma_tdvs = strobe;
}
REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
REG_WR(ata, regi_ata, rw_ctrl1, ctrl1);
}
timeleft = IDE_REGISTER_TIMEOUT; static unsigned long
/* wait for transmitter ready */ cris_ide_base_address(int bus)
while(timeleft && !(*R_ATA_STATUS_DATA & {
IO_MASK(R_ATA_STATUS_DATA, tr_rdy))) reg_ata_rw_ctrl2 ctrl2 = {0};
timeleft--; ctrl2.sel = bus;
return REG_TYPE_CONV(int, reg_ata_rw_ctrl2, ctrl2);
} }
void static unsigned long
etrax100_ide_outb(unsigned char data, unsigned long reg) cris_ide_reg_addr(unsigned long addr, int cs0, int cs1)
{ {
etrax100_ide_outw(data, reg); reg_ata_rw_ctrl2 ctrl2 = {0};
ctrl2.addr = addr;
ctrl2.cs1 = cs1;
ctrl2.cs0 = cs0;
return REG_TYPE_CONV(int, reg_ata_rw_ctrl2, ctrl2);
} }
void static __init void
etrax100_ide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port) cris_ide_reset(unsigned val)
{ {
etrax100_ide_outw(addr, port); reg_ata_rw_ctrl0 ctrl0 = {0};
ctrl0.rst = val ? regk_ata_active : regk_ata_inactive;
REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
} }
unsigned short static __init void
etrax100_ide_inw(unsigned long reg) { cris_ide_init(void)
int status; {
int timeleft; reg_ata_rw_ctrl0 ctrl0 = {0};
reg_ata_rw_intr_mask intr_mask = {0};
timeleft = IDE_REGISTER_TIMEOUT; ctrl0.en = regk_ata_yes;
/* wait for busy flag */ REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
while(timeleft && (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)))
timeleft--;
if(!timeleft) { intr_mask.bus0 = regk_ata_yes;
/* intr_mask.bus1 = regk_ata_yes;
* If we're asked to read the status register, like for intr_mask.bus2 = regk_ata_yes;
* example when a command does not complete for an intr_mask.bus3 = regk_ata_yes;
* extended time, but the ATA interface is stuck in a
* busy state at the *ETRAX* ATA interface level (as has
* happened repeatedly with at least one bad disk), then
* the best thing to do is to pretend that we read
* "busy" in the status register, so the IDE driver will
* time-out, abort the ongoing command and perform a
* reset sequence. Note that the subsequent OUT_BYTE
* call will also timeout on busy, but as long as the
* write is still performed, everything will be fine.
*/
if ((reg & IO_MASK (R_ATA_CTRL_DATA, addr))
== IO_FIELD (R_ATA_CTRL_DATA, addr, IDE_STATUS_OFFSET))
return BUSY_STAT;
else
/* For other rare cases we assume 0 is good enough. */
return 0;
}
*R_ATA_CTRL_DATA = reg | IO_STATE(R_ATA_CTRL_DATA, rw, read); /* read data */ REG_WR(ata, regi_ata, rw_intr_mask, intr_mask);
timeleft = IDE_REGISTER_TIMEOUT; crisv32_request_dma(2, "ETRAX FS built-in ATA", DMA_VERBOSE_ON_ERROR, 0, dma_ata);
/* wait for available */ crisv32_request_dma(3, "ETRAX FS built-in ATA", DMA_VERBOSE_ON_ERROR, 0, dma_ata);
while(timeleft && !((status = *R_ATA_STATUS_DATA) &
IO_MASK(R_ATA_STATUS_DATA, dav)))
timeleft--;
if(!timeleft) crisv32_pinmux_alloc_fixed(pinmux_ata);
return 0; crisv32_pinmux_alloc_fixed(pinmux_ata0);
crisv32_pinmux_alloc_fixed(pinmux_ata1);
crisv32_pinmux_alloc_fixed(pinmux_ata2);
crisv32_pinmux_alloc_fixed(pinmux_ata3);
LOWDB(printk("inb: 0x%x from reg 0x%x\n", status & 0xff, reg)); DMA_RESET(regi_dma2);
DMA_ENABLE(regi_dma2);
DMA_RESET(regi_dma3);
DMA_ENABLE(regi_dma3);
return (unsigned short)status; DMA_WR_CMD (regi_dma2, regk_dma_set_w_size2);
DMA_WR_CMD (regi_dma3, regk_dma_set_w_size2);
} }
unsigned char static dma_descr_context mycontext __attribute__ ((__aligned__(32)));
etrax100_ide_inb(unsigned long reg)
#define cris_dma_descr_type dma_descr_data
#define cris_pio_read regk_ata_rd
#define cris_ultra_mask 0x7
#define MAX_DESCR_SIZE 0xffffffffUL
static unsigned long
cris_ide_get_reg(unsigned long reg)
{ {
return (unsigned char)etrax100_ide_inw(reg); return (reg & 0x0e000000) >> 25;
} }
static void
cris_ide_fill_descriptor(cris_dma_descr_type *d, void* buf, unsigned int len, int last)
{
d->buf = (char*)virt_to_phys(buf);
d->after = d->buf + len;
d->eol = last;
}
static void
cris_ide_start_dma(ide_drive_t *drive, cris_dma_descr_type *d, int dir,int type,int len)
{
reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int, IDE_DATA_REG);
reg_ata_rw_trf_cnt trf_cnt = {0};
mycontext.saved_data = (dma_descr_data*)virt_to_phys(d);
mycontext.saved_data_buf = d->buf;
/* start the dma channel */
DMA_START_CONTEXT(dir ? regi_dma3 : regi_dma2, virt_to_phys(&mycontext));
/* initiate a multi word dma read using PIO handshaking */
trf_cnt.cnt = len >> 1;
/* Due to a "feature" the transfer count has to be one extra word for UDMA. */
if (type == TYPE_UDMA)
trf_cnt.cnt++;
REG_WR(ata, regi_ata, rw_trf_cnt, trf_cnt);
ctrl2.rw = dir ? regk_ata_rd : regk_ata_wr;
ctrl2.trf_mode = regk_ata_dma;
ctrl2.hsh = type == TYPE_PIO ? regk_ata_pio :
type == TYPE_DMA ? regk_ata_dma : regk_ata_udma;
ctrl2.multi = regk_ata_yes;
ctrl2.dma_size = regk_ata_word;
REG_WR(ata, regi_ata, rw_ctrl2, ctrl2);
}
static void
cris_ide_wait_dma(int dir)
{
reg_dma_rw_stat status;
do
{
status = REG_RD(dma, dir ? regi_dma3 : regi_dma2, rw_stat);
} while(status.list_state != regk_dma_data_at_eol);
}
static int cris_dma_test_irq(ide_drive_t *drive)
{
int intr = REG_RD_INT(ata, regi_ata, r_intr);
reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int, IDE_DATA_REG);
return intr & (1 << ctrl2.sel) ? 1 : 0;
}
static void cris_ide_initialize_dma(int dir)
{
}
#else
/* CRISv10 specifics */
#include <asm/arch/svinto.h>
#include <asm/arch/io_interface_mux.h>
/* PIO timing (in R_ATA_CONFIG) /* PIO timing (in R_ATA_CONFIG)
* *
* _____________________________ * _____________________________
...@@ -183,6 +312,12 @@ etrax100_ide_inb(unsigned long reg) ...@@ -183,6 +312,12 @@ etrax100_ide_inb(unsigned long reg)
* TODO: Is this true for the latest LX boards still ? * TODO: Is this true for the latest LX boards still ?
*/ */
#define ATA_UDMA2_CYC 0 /* No UDMA supported, just to make it compile. */
#define ATA_UDMA2_DVS 0
#define ATA_UDMA1_CYC 0
#define ATA_UDMA1_DVS 0
#define ATA_UDMA0_CYC 0
#define ATA_UDMA0_DVS 0
#define ATA_DMA2_STROBE 4 #define ATA_DMA2_STROBE 4
#define ATA_DMA2_HOLD 0 #define ATA_DMA2_HOLD 0
#define ATA_DMA1_STROBE 4 #define ATA_DMA1_STROBE 4
...@@ -205,204 +340,130 @@ etrax100_ide_inb(unsigned long reg) ...@@ -205,204 +340,130 @@ etrax100_ide_inb(unsigned long reg)
#define ATA_PIO0_STROBE 19 #define ATA_PIO0_STROBE 19
#define ATA_PIO0_HOLD 4 #define ATA_PIO0_HOLD 4
static int e100_dma_check (ide_drive_t *drive); int
static void e100_dma_start(ide_drive_t *drive); cris_ide_ack_intr(ide_hwif_t* hwif)
static int e100_dma_end (ide_drive_t *drive);
static void e100_ide_input_data (ide_drive_t *drive, void *, unsigned int);
static void e100_ide_output_data (ide_drive_t *drive, void *, unsigned int);
static void e100_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
static void e100_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
static int e100_dma_off (ide_drive_t *drive);
/*
* good_dma_drives() lists the model names (from "hdparm -i")
* of drives which do not support mword2 DMA but which are
* known to work fine with this interface under Linux.
*/
const char *good_dma_drives[] = {"Micropolis 2112A",
"CONNER CTMA 4000",
"CONNER CTT8000-A",
NULL};
static void tune_e100_ide(ide_drive_t *drive, byte pio)
{ {
pio = 4; return 1;
/* pio = ide_get_best_pio_mode(drive, pio, 4, NULL); */
/* set pio mode! */
switch(pio) {
case 0:
*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) |
IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
IO_FIELD( R_ATA_CONFIG, dma_hold, ATA_DMA2_HOLD ) |
IO_FIELD( R_ATA_CONFIG, pio_setup, ATA_PIO0_SETUP ) |
IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO0_STROBE ) |
IO_FIELD( R_ATA_CONFIG, pio_hold, ATA_PIO0_HOLD ) );
break;
case 1:
*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) |
IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
IO_FIELD( R_ATA_CONFIG, dma_hold, ATA_DMA2_HOLD ) |
IO_FIELD( R_ATA_CONFIG, pio_setup, ATA_PIO1_SETUP ) |
IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO1_STROBE ) |
IO_FIELD( R_ATA_CONFIG, pio_hold, ATA_PIO1_HOLD ) );
break;
case 2:
*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) |
IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
IO_FIELD( R_ATA_CONFIG, dma_hold, ATA_DMA2_HOLD ) |
IO_FIELD( R_ATA_CONFIG, pio_setup, ATA_PIO2_SETUP ) |
IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO2_STROBE ) |
IO_FIELD( R_ATA_CONFIG, pio_hold, ATA_PIO2_HOLD ) );
break;
case 3:
*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) |
IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
IO_FIELD( R_ATA_CONFIG, dma_hold, ATA_DMA2_HOLD ) |
IO_FIELD( R_ATA_CONFIG, pio_setup, ATA_PIO3_SETUP ) |
IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO3_STROBE ) |
IO_FIELD( R_ATA_CONFIG, pio_hold, ATA_PIO3_HOLD ) );
break;
case 4:
*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) |
IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
IO_FIELD( R_ATA_CONFIG, dma_hold, ATA_DMA2_HOLD ) |
IO_FIELD( R_ATA_CONFIG, pio_setup, ATA_PIO4_SETUP ) |
IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO4_STROBE ) |
IO_FIELD( R_ATA_CONFIG, pio_hold, ATA_PIO4_HOLD ) );
break;
}
} }
static int e100_dma_setup(ide_drive_t *drive) static inline int
cris_ide_busy(void)
{ {
struct request *rq = drive->hwif->hwgroup->rq; return *R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy) ;
if (rq_data_dir(rq)) {
e100_read_command = 0;
RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
WAIT_DMA(ATA_TX_DMA_NBR);
} else {
e100_read_command = 1;
RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
WAIT_DMA(ATA_RX_DMA_NBR);
}
/* set up the Etrax DMA descriptors */
if (e100_ide_build_dmatable(drive)) {
ide_map_sg(drive, rq);
return 1;
}
return 0;
} }
static void e100_dma_exec_cmd(ide_drive_t *drive, u8 command) static inline int
cris_ide_ready(void)
{ {
/* set the irq handler which will finish the request when DMA is done */ return *R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy) ;
ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
/* issue cmd to drive */
etrax100_ide_outb(command, IDE_COMMAND_REG);
} }
void __init static inline int
init_e100_ide (void) cris_ide_data_available(unsigned short* data)
{ {
volatile unsigned int dummy; unsigned long status = *R_ATA_STATUS_DATA;
int h; *data = (unsigned short)status;
return status & IO_MASK(R_ATA_STATUS_DATA, dav);
printk("ide: ETRAX 100LX built-in ATA DMA controller\n"); }
/* first fill in some stuff in the ide_hwifs fields */ static void
cris_ide_write_command(unsigned long command)
{
*R_ATA_CTRL_DATA = command;
}
for(h = 0; h < MAX_HWIFS; h++) { static void
ide_hwif_t *hwif = &ide_hwifs[h]; cris_ide_set_speed(int type, int setup, int strobe, int hold)
hwif->mmio = 2; {
hwif->chipset = ide_etrax100; static int pio_setup = ATA_PIO4_SETUP;
hwif->tuneproc = &tune_e100_ide; static int pio_strobe = ATA_PIO4_STROBE;
hwif->ata_input_data = &e100_ide_input_data; static int pio_hold = ATA_PIO4_HOLD;
hwif->ata_output_data = &e100_ide_output_data; static int dma_strobe = ATA_DMA2_STROBE;
hwif->atapi_input_bytes = &e100_atapi_input_bytes; static int dma_hold = ATA_DMA2_HOLD;
hwif->atapi_output_bytes = &e100_atapi_output_bytes;
hwif->ide_dma_check = &e100_dma_check; if (type == TYPE_PIO) {
hwif->ide_dma_end = &e100_dma_end; pio_setup = setup;
hwif->dma_setup = &e100_dma_setup; pio_strobe = strobe;
hwif->dma_exec_cmd = &e100_dma_exec_cmd; pio_hold = hold;
hwif->dma_start = &e100_dma_start; } else if (type == TYPE_DMA) {
hwif->OUTB = &etrax100_ide_outb; dma_strobe = strobe;
hwif->OUTW = &etrax100_ide_outw; dma_hold = hold;
hwif->OUTBSYNC = &etrax100_ide_outbsync;
hwif->INB = &etrax100_ide_inb;
hwif->INW = &etrax100_ide_inw;
hwif->ide_dma_off_quietly = &e100_dma_off;
} }
*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) |
IO_FIELD( R_ATA_CONFIG, dma_strobe, dma_strobe ) |
IO_FIELD( R_ATA_CONFIG, dma_hold, dma_hold ) |
IO_FIELD( R_ATA_CONFIG, pio_setup, pio_setup ) |
IO_FIELD( R_ATA_CONFIG, pio_strobe, pio_strobe ) |
IO_FIELD( R_ATA_CONFIG, pio_hold, pio_hold ) );
}
/* actually reset and configure the etrax100 ide/ata interface */ static unsigned long
cris_ide_base_address(int bus)
*R_ATA_CTRL_DATA = 0; {
*R_ATA_TRANSFER_CNT = 0; return IO_FIELD(R_ATA_CTRL_DATA, sel, bus);
*R_ATA_CONFIG = 0; }
genconfig_shadow = (genconfig_shadow &
~IO_MASK(R_GEN_CONFIG, dma2) &
~IO_MASK(R_GEN_CONFIG, dma3) &
~IO_MASK(R_GEN_CONFIG, ata)) |
( IO_STATE( R_GEN_CONFIG, dma3, ata ) |
IO_STATE( R_GEN_CONFIG, dma2, ata ) |
IO_STATE( R_GEN_CONFIG, ata, select ) );
*R_GEN_CONFIG = genconfig_shadow;
/* pull the chosen /reset-line low */ static unsigned long
cris_ide_reg_addr(unsigned long addr, int cs0, int cs1)
{
return IO_FIELD(R_ATA_CTRL_DATA, addr, addr) |
IO_FIELD(R_ATA_CTRL_DATA, cs0, cs0) |
IO_FIELD(R_ATA_CTRL_DATA, cs1, cs1);
}
static __init void
cris_ide_reset(unsigned val)
{
#ifdef CONFIG_ETRAX_IDE_G27_RESET #ifdef CONFIG_ETRAX_IDE_G27_RESET
REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 0); REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, val);
#endif #endif
#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 0); REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, val);
#endif #endif
#ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET #ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 0); REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, val);
#endif #endif
#ifdef CONFIG_ETRAX_IDE_PB7_RESET #ifdef CONFIG_ETRAX_IDE_PB7_RESET
port_pb_dir_shadow = port_pb_dir_shadow | port_pb_dir_shadow = port_pb_dir_shadow |
IO_STATE(R_PORT_PB_DIR, dir7, output); IO_STATE(R_PORT_PB_DIR, dir7, output);
*R_PORT_PB_DIR = port_pb_dir_shadow; *R_PORT_PB_DIR = port_pb_dir_shadow;
REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, 1); REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, val);
#endif #endif
}
/* wait some */ static __init void
cris_ide_init(void)
udelay(25); {
volatile unsigned int dummy;
/* de-assert bus-reset */ *R_ATA_CTRL_DATA = 0;
*R_ATA_TRANSFER_CNT = 0;
*R_ATA_CONFIG = 0;
#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET if (cris_request_io_interface(if_ata, "ETRAX100LX IDE")) {
REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 1); printk(KERN_CRIT "ide: Failed to get IO interface\n");
#endif return;
#ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET } else if (cris_request_dma(ATA_TX_DMA_NBR,
REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 1); "ETRAX100LX IDE TX",
#endif DMA_VERBOSE_ON_ERROR,
#ifdef CONFIG_ETRAX_IDE_G27_RESET dma_ata)) {
REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 1); cris_free_io_interface(if_ata);
#endif printk(KERN_CRIT "ide: Failed to get Tx DMA channel\n");
return;
} else if (cris_request_dma(ATA_RX_DMA_NBR,
"ETRAX100LX IDE RX",
DMA_VERBOSE_ON_ERROR,
dma_ata)) {
cris_free_dma(ATA_TX_DMA_NBR, "ETRAX100LX IDE Tx");
cris_free_io_interface(if_ata);
printk(KERN_CRIT "ide: Failed to get Rx DMA channel\n");
return;
}
/* make a dummy read to set the ata controller in a proper state */ /* make a dummy read to set the ata controller in a proper state */
dummy = *R_ATA_STATUS_DATA; dummy = *R_ATA_STATUS_DATA;
*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) | *R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ));
IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
IO_FIELD( R_ATA_CONFIG, dma_hold, ATA_DMA2_HOLD ) |
IO_FIELD( R_ATA_CONFIG, pio_setup, ATA_PIO4_SETUP ) |
IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO4_STROBE ) |
IO_FIELD( R_ATA_CONFIG, pio_hold, ATA_PIO4_HOLD ) );
*R_ATA_CTRL_DATA = ( IO_STATE( R_ATA_CTRL_DATA, rw, read) | *R_ATA_CTRL_DATA = ( IO_STATE( R_ATA_CTRL_DATA, rw, read) |
IO_FIELD( R_ATA_CTRL_DATA, addr, 1 ) ); IO_FIELD( R_ATA_CTRL_DATA, addr, 1 ) );
...@@ -413,229 +474,463 @@ init_e100_ide (void) ...@@ -413,229 +474,463 @@ init_e100_ide (void)
IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) | IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) ); IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
printk("ide: waiting %d seconds for drives to regain consciousness\n",
CONFIG_ETRAX_IDE_DELAY);
h = jiffies + (CONFIG_ETRAX_IDE_DELAY * HZ);
while(time_before(jiffies, h)) /* nothing */ ;
/* reset the dma channels we will use */ /* reset the dma channels we will use */
RESET_DMA(ATA_TX_DMA_NBR); RESET_DMA(ATA_TX_DMA_NBR);
RESET_DMA(ATA_RX_DMA_NBR); RESET_DMA(ATA_RX_DMA_NBR);
WAIT_DMA(ATA_TX_DMA_NBR); WAIT_DMA(ATA_TX_DMA_NBR);
WAIT_DMA(ATA_RX_DMA_NBR); WAIT_DMA(ATA_RX_DMA_NBR);
}
#define cris_dma_descr_type etrax_dma_descr
#define cris_pio_read IO_STATE(R_ATA_CTRL_DATA, rw, read)
#define cris_ultra_mask 0x0
#define MAX_DESCR_SIZE 0x10000UL
static unsigned long
cris_ide_get_reg(unsigned long reg)
{
return (reg & 0x0e000000) >> 25;
} }
static int e100_dma_off (ide_drive_t *drive) static void
cris_ide_fill_descriptor(cris_dma_descr_type *d, void* buf, unsigned int len, int last)
{ {
return 0; d->buf = virt_to_phys(buf);
d->sw_len = len == MAX_DESCR_SIZE ? 0 : len;
if (last)
d->ctrl |= d_eol;
} }
static etrax_dma_descr mydescr; static void cris_ide_start_dma(ide_drive_t *drive, cris_dma_descr_type *d, int dir, int type, int len)
{
unsigned long cmd;
/* if (dir) {
* The following routines are mainly used by the ATAPI drivers. /* need to do this before RX DMA due to a chip bug
* * it is enough to just flush the part of the cache that
* These routines will round up any request for an odd number of bytes, * corresponds to the buffers we start, but since HD transfers
* so if an odd bytecount is specified, be sure that there's at least one * usually are more than 8 kB, it is easier to optimize for the
* extra byte allocated for the buffer. * normal case and just flush the entire cache. its the only
* way to be sure! (OB movie quote)
*/ */
flush_etrax_cache();
*R_DMA_CH3_FIRST = virt_to_phys(d);
*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start);
} else {
*R_DMA_CH2_FIRST = virt_to_phys(d);
*R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, start);
}
/* initiate a multi word dma read using DMA handshaking */
*R_ATA_TRANSFER_CNT =
IO_FIELD(R_ATA_TRANSFER_CNT, count, len >> 1);
cmd = dir ? IO_STATE(R_ATA_CTRL_DATA, rw, read) : IO_STATE(R_ATA_CTRL_DATA, rw, write);
cmd |= type == TYPE_PIO ? IO_STATE(R_ATA_CTRL_DATA, handsh, pio) :
IO_STATE(R_ATA_CTRL_DATA, handsh, dma);
*R_ATA_CTRL_DATA =
cmd |
IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
IO_STATE(R_ATA_CTRL_DATA, src_dst, dma) |
IO_STATE(R_ATA_CTRL_DATA, multi, on) |
IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
}
static void static void
e100_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) cris_ide_wait_dma(int dir)
{ {
unsigned long data_reg = IDE_DATA_REG; if (dir)
WAIT_DMA(ATA_RX_DMA_NBR);
else
WAIT_DMA(ATA_TX_DMA_NBR);
}
D(printk("atapi_input_bytes, dreg 0x%x, buffer 0x%x, count %d\n", static int cris_dma_test_irq(ide_drive_t *drive)
data_reg, buffer, bytecount)); {
int intr = *R_IRQ_MASK0_RD;
int bus = IO_EXTRACT(R_ATA_CTRL_DATA, sel, IDE_DATA_REG);
return intr & (1 << (bus + IO_BITNR(R_IRQ_MASK0_RD, ata_irq0))) ? 1 : 0;
}
if(bytecount & 1) {
printk("warning, odd bytecount in cdrom_in_bytes = %d.\n", bytecount);
bytecount++; /* to round off */
}
/* make sure the DMA channel is available */ static void cris_ide_initialize_dma(int dir)
RESET_DMA(ATA_RX_DMA_NBR); {
if (dir)
{
RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
WAIT_DMA(ATA_RX_DMA_NBR); WAIT_DMA(ATA_RX_DMA_NBR);
}
else
{
RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
WAIT_DMA(ATA_TX_DMA_NBR);
}
}
/* setup DMA descriptor */ #endif
mydescr.sw_len = bytecount; void
mydescr.ctrl = d_eol; cris_ide_outw(unsigned short data, unsigned long reg) {
mydescr.buf = virt_to_phys(buffer); int timeleft;
/* start the dma channel */ LOWDB(printk("ow: data 0x%x, reg 0x%x\n", data, reg));
*R_DMA_CH3_FIRST = virt_to_phys(&mydescr); /* note the lack of handling any timeouts. we stop waiting, but we don't
*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start); * really notify anybody.
*/
/* initiate a multi word dma read using PIO handshaking */ timeleft = IDE_REGISTER_TIMEOUT;
/* wait for busy flag */
do {
timeleft--;
} while(timeleft && cris_ide_busy());
*R_ATA_TRANSFER_CNT = IO_FIELD(R_ATA_TRANSFER_CNT, count, bytecount >> 1); /*
* Fall through at a timeout, so the ongoing command will be
* aborted by the write below, which is expected to be a dummy
* command to the command register. This happens when a faulty
* drive times out on a command. See comment on timeout in
* INB.
*/
if(!timeleft)
printk("ATA timeout reg 0x%lx := 0x%x\n", reg, data);
*R_ATA_CTRL_DATA = data_reg | cris_ide_write_command(reg|data); /* write data to the drive's register */
IO_STATE(R_ATA_CTRL_DATA, rw, read) |
IO_STATE(R_ATA_CTRL_DATA, src_dst, dma) |
IO_STATE(R_ATA_CTRL_DATA, handsh, pio) |
IO_STATE(R_ATA_CTRL_DATA, multi, on) |
IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
/* wait for completion */ timeleft = IDE_REGISTER_TIMEOUT;
/* wait for transmitter ready */
do {
timeleft--;
} while(timeleft && !cris_ide_ready());
}
LED_DISK_READ(1); void
WAIT_DMA(ATA_RX_DMA_NBR); cris_ide_outb(unsigned char data, unsigned long reg)
LED_DISK_READ(0); {
cris_ide_outw(data, reg);
}
void
cris_ide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
{
cris_ide_outw(addr, port);
}
unsigned short
cris_ide_inw(unsigned long reg) {
int timeleft;
unsigned short val;
timeleft = IDE_REGISTER_TIMEOUT;
/* wait for busy flag */
do {
timeleft--;
} while(timeleft && cris_ide_busy());
#if 0 if(!timeleft) {
/* old polled transfer code /*
* this should be moved into a new function that can do polled * If we're asked to read the status register, like for
* transfers if DMA is not available * example when a command does not complete for an
* extended time, but the ATA interface is stuck in a
* busy state at the *ETRAX* ATA interface level (as has
* happened repeatedly with at least one bad disk), then
* the best thing to do is to pretend that we read
* "busy" in the status register, so the IDE driver will
* time-out, abort the ongoing command and perform a
* reset sequence. Note that the subsequent OUT_BYTE
* call will also timeout on busy, but as long as the
* write is still performed, everything will be fine.
*/ */
if (cris_ide_get_reg(reg) == IDE_STATUS_OFFSET)
return BUSY_STAT;
else
/* For other rare cases we assume 0 is good enough. */
return 0;
}
/* initiate a multi word read */ cris_ide_write_command(reg | cris_pio_read);
*R_ATA_TRANSFER_CNT = wcount << 1; timeleft = IDE_REGISTER_TIMEOUT;
/* wait for available */
do {
timeleft--;
} while(timeleft && !cris_ide_data_available(&val));
*R_ATA_CTRL_DATA = data_reg | if(!timeleft)
IO_STATE(R_ATA_CTRL_DATA, rw, read) | return 0;
IO_STATE(R_ATA_CTRL_DATA, src_dst, register) |
IO_STATE(R_ATA_CTRL_DATA, handsh, pio) |
IO_STATE(R_ATA_CTRL_DATA, multi, on) |
IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
/* svinto has a latency until the busy bit actually is set */ LOWDB(printk("inb: 0x%x from reg 0x%x\n", val & 0xff, reg));
nop(); nop(); return val;
nop(); nop(); }
nop(); nop();
nop(); nop();
nop(); nop();
/* unit should be busy during multi transfer */ unsigned char
while((status = *R_ATA_STATUS_DATA) & IO_MASK(R_ATA_STATUS_DATA, busy)) { cris_ide_inb(unsigned long reg)
while(!(status & IO_MASK(R_ATA_STATUS_DATA, dav))) {
status = *R_ATA_STATUS_DATA; return (unsigned char)cris_ide_inw(reg);
*ptr++ = (unsigned short)(status & 0xffff);
}
#endif
} }
static void static int cris_dma_check (ide_drive_t *drive);
e100_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) static int cris_dma_end (ide_drive_t *drive);
static int cris_dma_setup (ide_drive_t *drive);
static void cris_dma_exec_cmd (ide_drive_t *drive, u8 command);
static int cris_dma_test_irq(ide_drive_t *drive);
static void cris_dma_start(ide_drive_t *drive);
static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int);
static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
static int cris_dma_off (ide_drive_t *drive);
static int cris_dma_on (ide_drive_t *drive);
static void tune_cris_ide(ide_drive_t *drive, u8 pio)
{ {
unsigned long data_reg = IDE_DATA_REG; int setup, strobe, hold;
D(printk("atapi_output_bytes, dreg 0x%x, buffer 0x%x, count %d\n", switch(pio)
data_reg, buffer, bytecount)); {
case 0:
setup = ATA_PIO0_SETUP;
strobe = ATA_PIO0_STROBE;
hold = ATA_PIO0_HOLD;
break;
case 1:
setup = ATA_PIO1_SETUP;
strobe = ATA_PIO1_STROBE;
hold = ATA_PIO1_HOLD;
break;
case 2:
setup = ATA_PIO2_SETUP;
strobe = ATA_PIO2_STROBE;
hold = ATA_PIO2_HOLD;
break;
case 3:
setup = ATA_PIO3_SETUP;
strobe = ATA_PIO3_STROBE;
hold = ATA_PIO3_HOLD;
break;
case 4:
setup = ATA_PIO4_SETUP;
strobe = ATA_PIO4_STROBE;
hold = ATA_PIO4_HOLD;
break;
default:
return;
}
if(bytecount & 1) { cris_ide_set_speed(TYPE_PIO, setup, strobe, hold);
printk("odd bytecount %d in atapi_out_bytes!\n", bytecount); }
bytecount++;
static int speed_cris_ide(ide_drive_t *drive, u8 speed)
{
int cyc = 0, dvs = 0, strobe = 0, hold = 0;
if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
tune_cris_ide(drive, speed - XFER_PIO_0);
return 0;
} }
/* make sure the DMA channel is available */ switch(speed)
RESET_DMA(ATA_TX_DMA_NBR); {
WAIT_DMA(ATA_TX_DMA_NBR); case XFER_UDMA_0:
cyc = ATA_UDMA0_CYC;
dvs = ATA_UDMA0_DVS;
break;
case XFER_UDMA_1:
cyc = ATA_UDMA1_CYC;
dvs = ATA_UDMA1_DVS;
break;
case XFER_UDMA_2:
cyc = ATA_UDMA2_CYC;
dvs = ATA_UDMA2_DVS;
break;
case XFER_MW_DMA_0:
strobe = ATA_DMA0_STROBE;
hold = ATA_DMA0_HOLD;
break;
case XFER_MW_DMA_1:
strobe = ATA_DMA1_STROBE;
hold = ATA_DMA1_HOLD;
break;
case XFER_MW_DMA_2:
strobe = ATA_DMA2_STROBE;
hold = ATA_DMA2_HOLD;
break;
default:
return 0;
}
/* setup DMA descriptor */ if (speed >= XFER_UDMA_0)
cris_ide_set_speed(TYPE_UDMA, cyc, dvs, 0);
else
cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
mydescr.sw_len = bytecount; return 0;
mydescr.ctrl = d_eol; }
mydescr.buf = virt_to_phys(buffer);
/* start the dma channel */ void __init
init_e100_ide (void)
{
hw_regs_t hw;
int ide_offsets[IDE_NR_PORTS];
int h;
int i;
*R_DMA_CH2_FIRST = virt_to_phys(&mydescr); printk("ide: ETRAX FS built-in ATA DMA controller\n");
*R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, start);
/* initiate a multi word dma write using PIO handshaking */ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
ide_offsets[i] = cris_ide_reg_addr(i, 0, 1);
*R_ATA_TRANSFER_CNT = IO_FIELD(R_ATA_TRANSFER_CNT, count, bytecount >> 1); /* the IDE control register is at ATA address 6, with CS1 active instead of CS0 */
ide_offsets[IDE_CONTROL_OFFSET] = cris_ide_reg_addr(6, 1, 0);
*R_ATA_CTRL_DATA = data_reg | /* first fill in some stuff in the ide_hwifs fields */
IO_STATE(R_ATA_CTRL_DATA, rw, write) |
IO_STATE(R_ATA_CTRL_DATA, src_dst, dma) |
IO_STATE(R_ATA_CTRL_DATA, handsh, pio) |
IO_STATE(R_ATA_CTRL_DATA, multi, on) |
IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
/* wait for completion */ for(h = 0; h < MAX_HWIFS; h++) {
ide_hwif_t *hwif = &ide_hwifs[h];
ide_setup_ports(&hw, cris_ide_base_address(h),
ide_offsets,
0, 0, cris_ide_ack_intr,
ide_default_irq(0));
ide_register_hw(&hw, &hwif);
hwif->mmio = 2;
hwif->chipset = ide_etrax100;
hwif->tuneproc = &tune_cris_ide;
hwif->speedproc = &speed_cris_ide;
hwif->ata_input_data = &cris_ide_input_data;
hwif->ata_output_data = &cris_ide_output_data;
hwif->atapi_input_bytes = &cris_atapi_input_bytes;
hwif->atapi_output_bytes = &cris_atapi_output_bytes;
hwif->ide_dma_check = &cris_dma_check;
hwif->ide_dma_end = &cris_dma_end;
hwif->dma_setup = &cris_dma_setup;
hwif->dma_exec_cmd = &cris_dma_exec_cmd;
hwif->ide_dma_test_irq = &cris_dma_test_irq;
hwif->dma_start = &cris_dma_start;
hwif->OUTB = &cris_ide_outb;
hwif->OUTW = &cris_ide_outw;
hwif->OUTBSYNC = &cris_ide_outbsync;
hwif->INB = &cris_ide_inb;
hwif->INW = &cris_ide_inw;
hwif->ide_dma_host_off = &cris_dma_off;
hwif->ide_dma_host_on = &cris_dma_on;
hwif->ide_dma_off_quietly = &cris_dma_off;
hwif->udma_four = 0;
hwif->ultra_mask = cris_ultra_mask;
hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */
}
LED_DISK_WRITE(1); /* Reset pulse */
WAIT_DMA(ATA_TX_DMA_NBR); cris_ide_reset(0);
LED_DISK_WRITE(0); udelay(25);
cris_ide_reset(1);
#if 0 cris_ide_init();
/* old polled write code - see comment in input_bytes */
/* wait for busy flag */ cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD);
while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD);
cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
}
/* initiate a multi word write */ static int cris_dma_off (ide_drive_t *drive)
{
return 0;
}
*R_ATA_TRANSFER_CNT = bytecount >> 1; static int cris_dma_on (ide_drive_t *drive)
{
return 0;
}
ctrl = data_reg |
IO_STATE(R_ATA_CTRL_DATA, rw, write) |
IO_STATE(R_ATA_CTRL_DATA, src_dst, register) |
IO_STATE(R_ATA_CTRL_DATA, handsh, pio) |
IO_STATE(R_ATA_CTRL_DATA, multi, on) |
IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
LED_DISK_WRITE(1); static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16)));
/* Etrax will set busy = 1 until the multi pio transfer has finished /*
* and tr_rdy = 1 after each successful word transfer. * The following routines are mainly used by the ATAPI drivers.
* When the last byte has been transferred Etrax will first set tr_tdy = 1 *
* and then busy = 0 (not in the same cycle). If we read busy before it * These routines will round up any request for an odd number of bytes,
* has been set to 0 we will think that we should transfer more bytes * so if an odd bytecount is specified, be sure that there's at least one
* and then tr_rdy would be 0 forever. This is solved by checking busy * extra byte allocated for the buffer.
* in the inner loop.
*/ */
static void
cris_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
{
D(printk("atapi_input_bytes, buffer 0x%x, count %d\n",
buffer, bytecount));
do { if(bytecount & 1) {
*R_ATA_CTRL_DATA = ctrl | *ptr++; printk("warning, odd bytecount in cdrom_in_bytes = %d.\n", bytecount);
while(!(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy)) && bytecount++; /* to round off */
(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy))); }
} while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
LED_DISK_WRITE(0); /* setup DMA and start transfer */
#endif
cris_ide_fill_descriptor(&mydescr, buffer, bytecount, 1);
cris_ide_start_dma(drive, &mydescr, 1, TYPE_PIO, bytecount);
/* wait for completion */
LED_DISK_READ(1);
cris_ide_wait_dma(1);
LED_DISK_READ(0);
}
static void
cris_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
{
D(printk("atapi_output_bytes, buffer 0x%x, count %d\n",
buffer, bytecount));
if(bytecount & 1) {
printk("odd bytecount %d in atapi_out_bytes!\n", bytecount);
bytecount++;
}
cris_ide_fill_descriptor(&mydescr, buffer, bytecount, 1);
cris_ide_start_dma(drive, &mydescr, 0, TYPE_PIO, bytecount);
/* wait for completion */
LED_DISK_WRITE(1);
LED_DISK_READ(1);
cris_ide_wait_dma(0);
LED_DISK_WRITE(0);
} }
/* /*
* This is used for most PIO data transfers *from* the IDE interface * This is used for most PIO data transfers *from* the IDE interface
*/ */
static void static void
e100_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) cris_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
{ {
e100_atapi_input_bytes(drive, buffer, wcount << 2); cris_atapi_input_bytes(drive, buffer, wcount << 2);
} }
/* /*
* This is used for most PIO data transfers *to* the IDE interface * This is used for most PIO data transfers *to* the IDE interface
*/ */
static void static void
e100_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) cris_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
{ {
e100_atapi_output_bytes(drive, buffer, wcount << 2); cris_atapi_output_bytes(drive, buffer, wcount << 2);
} }
/* we only have one DMA channel on the chip for ATA, so we can keep these statically */ /* we only have one DMA channel on the chip for ATA, so we can keep these statically */
static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS]; static cris_dma_descr_type ata_descrs[MAX_DMA_DESCRS] __attribute__ ((__aligned__(16)));
static unsigned int ata_tot_size; static unsigned int ata_tot_size;
/* /*
* e100_ide_build_dmatable() prepares a dma request. * cris_ide_build_dmatable() prepares a dma request.
* Returns 0 if all went okay, returns 1 otherwise. * Returns 0 if all went okay, returns 1 otherwise.
*/ */
static int e100_ide_build_dmatable (ide_drive_t *drive) static int cris_ide_build_dmatable (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = drive->hwif;
struct scatterlist* sg; struct scatterlist* sg;
struct request *rq = HWGROUP(drive)->rq; struct request *rq = drive->hwif->hwgroup->rq;
unsigned long size, addr; unsigned long size, addr;
unsigned int count = 0; unsigned int count = 0;
int i = 0; int i = 0;
...@@ -645,7 +940,6 @@ static int e100_ide_build_dmatable (ide_drive_t *drive) ...@@ -645,7 +940,6 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
ata_tot_size = 0; ata_tot_size = 0;
ide_map_sg(drive, rq); ide_map_sg(drive, rq);
i = hwif->sg_nents; i = hwif->sg_nents;
while(i) { while(i) {
...@@ -672,9 +966,9 @@ static int e100_ide_build_dmatable (ide_drive_t *drive) ...@@ -672,9 +966,9 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
return 1; return 1;
} }
/* however, this case is more difficult - R_ATA_TRANSFER_CNT cannot be more /* however, this case is more difficult - rw_trf_cnt cannot be more
than 65536 words per transfer, so in that case we need to either than 65536 words per transfer, so in that case we need to either
1) use a DMA interrupt to re-trigger R_ATA_TRANSFER_CNT and continue with 1) use a DMA interrupt to re-trigger rw_trf_cnt and continue with
the descriptors, or the descriptors, or
2) simply do the request here, and get dma_intr to only ide_end_request on 2) simply do the request here, and get dma_intr to only ide_end_request on
those blocks that were actually set-up for transfer. those blocks that were actually set-up for transfer.
...@@ -685,37 +979,23 @@ static int e100_ide_build_dmatable (ide_drive_t *drive) ...@@ -685,37 +979,23 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
return 1; return 1;
} }
/* If size > 65536 it has to be splitted into new descriptors. Since we don't handle /* If size > MAX_DESCR_SIZE it has to be splitted into new descriptors. Since we
size > 131072 only one split is necessary */ don't handle size > 131072 only one split is necessary */
if(size > 65536) { if(size > MAX_DESCR_SIZE) {
/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */ cris_ide_fill_descriptor(&ata_descrs[count], (void*)addr, MAX_DESCR_SIZE, 0);
ata_descrs[count].sw_len = 0; /* 0 means 65536, this is a 16-bit field */
ata_descrs[count].ctrl = 0;
ata_descrs[count].buf = addr;
ata_descrs[count].next = virt_to_phys(&ata_descrs[count + 1]);
count++; count++;
ata_tot_size += 65536; ata_tot_size += MAX_DESCR_SIZE;
/* size and addr should refere to not handled data */ size -= MAX_DESCR_SIZE;
size -= 65536; addr += MAX_DESCR_SIZE;
addr += 65536;
}
/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
if(size == 65536) {
ata_descrs[count].sw_len = 0; /* 0 means 65536, this is a 16-bit field */
} else {
ata_descrs[count].sw_len = size;
} }
ata_descrs[count].ctrl = 0;
ata_descrs[count].buf = addr; cris_ide_fill_descriptor(&ata_descrs[count], (void*)addr, size,i ? 0 : 1);
ata_descrs[count].next = virt_to_phys(&ata_descrs[count + 1]);
count++; count++;
ata_tot_size += size; ata_tot_size += size;
} }
if (count) { if (count) {
/* set the end-of-list flag on the last descriptor */
ata_descrs[count - 1].ctrl |= d_eol;
/* return and say all is ok */ /* return and say all is ok */
return 0; return 0;
} }
...@@ -724,34 +1004,23 @@ static int e100_ide_build_dmatable (ide_drive_t *drive) ...@@ -724,34 +1004,23 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
return 1; /* let the PIO routines handle this weirdness */ return 1; /* let the PIO routines handle this weirdness */
} }
static int config_drive_for_dma (ide_drive_t *drive) static int cris_config_drive_for_dma (ide_drive_t *drive)
{ {
const char **list; u8 speed = ide_dma_speed(drive, 1);
struct hd_driveid *id = drive->id;
if (id && (id->capability & 1)) { if (!speed)
/* Enable DMA on any drive that supports mword2 DMA */ return 0;
if ((id->field_valid & 2) && (id->dma_mword & 0x404) == 0x404) {
drive->using_dma = 1;
return 0; /* DMA enabled */
}
/* Consult the list of known "good" drives */ speed_cris_ide(drive, speed);
list = good_dma_drives; ide_config_drive_speed(drive, speed);
while (*list) {
if (!strcmp(*list++,id->model)) { return ide_dma_enable(drive);
drive->using_dma = 1;
return 0; /* DMA enabled */
}
}
}
return 1; /* DMA not enabled */
} }
/* /*
* etrax_dma_intr() is the handler for disk read/write DMA interrupts * cris_dma_intr() is the handler for disk read/write DMA interrupts
*/ */
static ide_startstop_t etrax_dma_intr (ide_drive_t *drive) static ide_startstop_t cris_dma_intr (ide_drive_t *drive)
{ {
LED_DISK_READ(0); LED_DISK_READ(0);
LED_DISK_WRITE(0); LED_DISK_WRITE(0);
...@@ -766,77 +1035,73 @@ static ide_startstop_t etrax_dma_intr (ide_drive_t *drive) ...@@ -766,77 +1035,73 @@ static ide_startstop_t etrax_dma_intr (ide_drive_t *drive)
* sector address using CHS or LBA. All that remains is to prepare for DMA * sector address using CHS or LBA. All that remains is to prepare for DMA
* and then issue the actual read/write DMA/PIO command to the drive. * and then issue the actual read/write DMA/PIO command to the drive.
* *
* For ATAPI devices, we just prepare for DMA and return. The caller should
* then issue the packet command to the drive and call us again with
* cris_dma_start afterwards.
*
* Returns 0 if all went well. * Returns 0 if all went well.
* Returns 1 if DMA read/write could not be started, in which case * Returns 1 if DMA read/write could not be started, in which case
* the caller should revert to PIO for the current request. * the caller should revert to PIO for the current request.
*/ */
static int e100_dma_check(ide_drive_t *drive) static int cris_dma_check(ide_drive_t *drive)
{ {
return config_drive_for_dma (drive); ide_hwif_t *hwif = drive->hwif;
struct hd_driveid* id = drive->id;
if (id && (id->capability & 1)) {
if (ide_use_dma(drive)) {
if (cris_config_drive_for_dma(drive))
return hwif->ide_dma_on(drive);
}
}
return hwif->ide_dma_off_quietly(drive);
} }
static int e100_dma_end(ide_drive_t *drive) static int cris_dma_end(ide_drive_t *drive)
{ {
/* TODO: check if something went wrong with the DMA */ drive->waiting_for_dma = 0;
return 0; return 0;
} }
static void e100_dma_start(ide_drive_t *drive) static int cris_dma_setup(ide_drive_t *drive)
{ {
if (e100_read_command) { struct request *rq = drive->hwif->hwgroup->rq;
/* begin DMA */
/* need to do this before RX DMA due to a chip bug
* it is enough to just flush the part of the cache that
* corresponds to the buffers we start, but since HD transfers
* usually are more than 8 kB, it is easier to optimize for the
* normal case and just flush the entire cache. its the only
* way to be sure! (OB movie quote)
*/
flush_etrax_cache();
*R_DMA_CH3_FIRST = virt_to_phys(ata_descrs);
*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start);
/* initiate a multi word dma read using DMA handshaking */
*R_ATA_TRANSFER_CNT =
IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
*R_ATA_CTRL_DATA =
IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
IO_STATE(R_ATA_CTRL_DATA, rw, read) |
IO_STATE(R_ATA_CTRL_DATA, src_dst, dma) |
IO_STATE(R_ATA_CTRL_DATA, handsh, dma) |
IO_STATE(R_ATA_CTRL_DATA, multi, on) |
IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
LED_DISK_READ(1); cris_ide_initialize_dma(!rq_data_dir(rq));
if (cris_ide_build_dmatable (drive)) {
ide_map_sg(drive, rq);
return 1;
}
D(printk("dma read of %d bytes.\n", ata_tot_size)); drive->waiting_for_dma = 1;
return 0;
}
} else { static void cris_dma_exec_cmd(ide_drive_t *drive, u8 command)
/* writing */ {
/* begin DMA */ /* set the irq handler which will finish the request when DMA is done */
ide_set_handler(drive, &cris_dma_intr, WAIT_CMD, NULL);
*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs); /* issue cmd to drive */
*R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, start); cris_ide_outb(command, IDE_COMMAND_REG);
}
/* initiate a multi word dma write using DMA handshaking */ static void cris_dma_start(ide_drive_t *drive)
{
struct request *rq = drive->hwif->hwgroup->rq;
int writing = rq_data_dir(rq);
int type = TYPE_DMA;
*R_ATA_TRANSFER_CNT = if (drive->current_speed >= XFER_UDMA_0)
IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1); type = TYPE_UDMA;
*R_ATA_CTRL_DATA = cris_ide_start_dma(drive, &ata_descrs[0], writing ? 0 : 1, type, ata_tot_size);
IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
IO_STATE(R_ATA_CTRL_DATA, rw, write) |
IO_STATE(R_ATA_CTRL_DATA, src_dst, dma) |
IO_STATE(R_ATA_CTRL_DATA, handsh, dma) |
IO_STATE(R_ATA_CTRL_DATA, multi, on) |
IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
if (writing) {
LED_DISK_WRITE(1); LED_DISK_WRITE(1);
} else {
D(printk("dma write of %d bytes.\n", ata_tot_size)); LED_DISK_READ(1);
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment