pata_mpc52xx - no interrupts when using bestcomm/dma?
Domen Puncer
domen.puncer at telargo.com
Mon Aug 27 19:44:54 EST 2007
Hi!
I'm taking a stab at adding DMA support to pata_mpc52xx driver.
It's based on patches from Freescale's ltib (old ide driver).
The problem is that I can't seem to get any interrupts
(not ata, not bestcomm task), when setting up MWDMA/UDMA mode.
Ideas?
My current patch:
---
drivers/ata/pata_mpc52xx.c | 491 +++++++++++++++++++++++++++++++++++++++++++--
include/linux/libata.h | 2
2 files changed, 477 insertions(+), 16 deletions(-)
Index: work-powerpc.git/drivers/ata/pata_mpc52xx.c
===================================================================
--- work-powerpc.git.orig/drivers/ata/pata_mpc52xx.c
+++ work-powerpc.git/drivers/ata/pata_mpc52xx.c
@@ -4,6 +4,7 @@
* libata driver for the Freescale MPC52xx on-chip IDE interface
*
* Copyright (C) 2006 Sylvain Munaut <tnt at 246tNt.com>
+ * Copyright (C) 2005,2006 Freescale - Bernard Kuhn, John Rigby
* Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
*
* This file is licensed under the terms of the GNU General Public License
@@ -22,6 +23,8 @@
#include <asm/of_platform.h>
#include <asm/mpc52xx.h>
+#include <sysdev/bestcomm/bestcomm.h>
+#include <sysdev/bestcomm/ata.h>
#define DRV_NAME "mpc52xx_ata"
#define DRV_VERSION "0.1.0ac2"
@@ -31,6 +34,14 @@
struct mpc52xx_ata_timings {
u32 pio1;
u32 pio2;
+ u32 mdma1;
+ u32 mdma2;
+ u32 udma1;
+ u32 udma2;
+ u32 udma3;
+ u32 udma4;
+ u32 udma5;
+ int using_udma;
};
struct mpc52xx_ata_priv {
@@ -39,6 +50,12 @@ struct mpc52xx_ata_priv {
int ata_irq;
struct mpc52xx_ata_timings timings[2];
int csel;
+
+ /* dma stuff follows */
+ struct bcom_task * dmatsk;
+ const struct udmaspec * udmaspec;
+ const struct mdmaspec * mdmaspec;
+ int mpc52xx_ata_dma_last_write;
};
@@ -53,6 +70,102 @@ static const int ataspec_ta[5] = { 35
#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
+/* ATAPI-4 MDMA specs (in clocks) */
+struct mdmaspec {
+ u32 t0M[3];
+ u32 td[3];
+ u32 th[3];
+ u32 tj[3];
+ u32 tkw[3];
+ u32 tm[3];
+ u32 tn[3];
+};
+
+// -----------------------------------------------------------------------------------------------
+
+static const struct mdmaspec mdmaspec66 = {
+ {32, 10, 8},
+ {15, 6, 5},
+ {2, 1, 1},
+ {2, 1, 1},
+ {15, 4, 2},
+ {4, 2, 2},
+ {1, 1, 1}
+};
+
+static const struct mdmaspec mdmaspec132 = {
+ {64, 20, 16},
+ {29, 11, 10},
+ {3, 2, 2},
+ {3, 1, 1},
+ {29, 7, 4},
+ {7, 4, 4},
+ {2, 1, 1}
+};
+
+
+/* ATAPI-4 UDMA specs (in clocks) */
+struct udmaspec {
+ u32 tcyc[6];
+ u32 t2cyc[6];
+ u32 tds[6];
+ u32 tdh[6];
+ u32 tdvs[6];
+ u32 tdvh[6];
+ u32 tfs_min[6];
+ u32 tli_max[6];
+ u32 tmli[6];
+ u32 taz[6];
+ u32 tzah[6];
+ u32 tenv_min[6];
+ u32 tsr[6];
+ u32 trfs[6];
+ u32 trp[6];
+ u32 tack[6];
+ u32 tss[6];
+};
+
+static const struct udmaspec udmaspec66 = {
+ { 8, 5, 4, 3, 2, 2},
+ {16, 11, 8, 6, 4 , 2},
+ { 1, 1, 1, 1, 1, 1},
+ { 1, 1, 1, 1, 1, 1},
+ { 5, 4, 3, 2, 1, 1},
+ { 1, 1, 1, 1, 1, 1},
+ {16, 14, 12, 9, 8, 6},
+ {10, 10, 10, 7, 8, 5},
+ { 2, 2, 2, 2, 2, 2},
+ { 1, 1, 1, 1, 1, 1},
+ { 2, 2, 2, 2, 2, 2},
+ { 2, 2, 2, 2, 2, 2},
+ { 3, 2, 2, 2, 2, 2},
+ { 5, 5, 4, 4, 4, 4},
+ {11, 9, 7, 7, 7, 6},
+ { 2, 2, 2, 2, 2, 2},
+ { 4, 4, 4, 4, 4, 4}
+};
+
+static const struct udmaspec udmaspec132 = {
+ {15, 10, 6, 7, 2, 3},
+ {31, 21, 12, 12, 5, 6},
+ { 2, 2, 1, 1, 0, 1},
+ { 1, 1, 1, 1, 0, 1},
+ {10, 7, 5, 3, 1, 1},
+ { 1, 1, 1, 1, 1, 1},
+ {30, 27, 23, 15, 16, 12},
+ {20, 20, 20, 13, 14, 10},
+ { 3, 3, 3, 3, 2, 3},
+ { 2, 2, 2, 2, 1, 2},
+ { 3, 3, 3, 3, 2, 3},
+ { 3, 3, 3, 3, 2, 3},
+ { 7, 4, 3, 3, 2, 3},
+ {10, 10, 8, 8, 7, 7},
+ {22, 17, 14, 14, 13, 12},
+ { 3, 3, 3, 3, 2, 3},
+ { 7, 7, 7, 7, 6, 7},
+};
+
+// -----------------------------------------------------------------------------------------------
/* Bit definitions inside the registers */
#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */
@@ -76,6 +189,10 @@ static const int ataspec_ta[5] = { 35
#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
+#define MAX_DMA_BUFFERS 128
+#define MAX_DMA_BUFFER_SIZE 0x20000u
+
+
/* Structure of the hardware registers */
struct mpc52xx_ata {
@@ -141,6 +258,19 @@ struct mpc52xx_ata {
/* MPC52xx low level hw control */
+static inline void
+mpc52xx_ata_wait_tip_bit_clear(struct mpc52xx_ata __iomem *regs)
+{
+ int timeout = 1000;
+
+ while (in_be32(®s->host_status) & MPC52xx_ATA_HOSTSTAT_TIP)
+ if (timeout-- == 0) {
+ printk(KERN_ERR "mpc52xx-ide: Timeout waiting for TIP clear\n");
+ break;
+ }
+ udelay(10); /* FIXME: Necessary ??? */
+}
+
static int
mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
{
@@ -165,6 +295,96 @@ mpc52xx_ata_compute_pio_timings(struct m
return 0;
}
+static int
+mpc52xx_ata_compute_mdma_timings(struct mpc52xx_ata_priv *priv, int dev, int speed)
+{
+ struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+ u32 t0M, td, tkw, tm, th, tj, tn;
+
+ if (speed < 0 || speed > 2)
+ return -EINVAL;
+
+ t0M = priv->mdmaspec->t0M[speed];
+ td = priv->mdmaspec->td[speed];
+ tkw = priv->mdmaspec->tkw[speed];
+ tm = priv->mdmaspec->tm[speed];
+ th = priv->mdmaspec->th[speed];
+ tj = priv->mdmaspec->tj[speed];
+ tn = priv->mdmaspec->tn[speed];
+
+ /*
+ DPRINTK ("t0M = %d\n", t0M);
+ DPRINTK ("td = %d\n", td);
+ DPRINTK ("tkw = %d\n", tkw);
+ DPRINTK ("tm = %d\n", tm);
+ DPRINTK ("th = %d\n", th);
+ DPRINTK ("tj = %d\n", tj);
+ DPRINTK ("tn = %d\n", tn);
+ */
+ timing->mdma1 = (t0M << 24) | (td << 16) | (tkw << 8) | (tm);
+ timing->mdma2 = (th << 24) | (tj << 16) | (tn << 8);
+
+ timing->using_udma = 0;
+
+ return 0;
+}
+
+static int
+mpc52xx_ata_compute_udma_timings(struct mpc52xx_ata_priv *priv, int dev, int speed)
+{
+ struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+ u32 t2cyc, tcyc, tds, tdh, tdvs, tdvh, tfs, tli, tmli, taz, tenv, tsr, tss, trfs, trp, tack, tzah;
+
+ if (speed < 0 || speed > 2)
+ return -EINVAL;
+
+ t2cyc = priv->udmaspec->t2cyc[speed];
+ tcyc = priv->udmaspec->tcyc[speed];
+ tds = priv->udmaspec->tds[speed];
+ tdh = priv->udmaspec->tdh[speed];
+ tdvs = priv->udmaspec->tdvs[speed];
+ tdvh = priv->udmaspec->tdvh[speed];
+ tfs = priv->udmaspec->tfs_min[speed];
+ tmli = priv->udmaspec->tmli[speed];
+ tenv = priv->udmaspec->tenv_min[speed];
+ tss = priv->udmaspec->tss[speed];
+ trp = priv->udmaspec->trp[speed];
+ tack = priv->udmaspec->tack[speed];
+ tzah = priv->udmaspec->tzah[speed];
+ taz = priv->udmaspec->taz[speed];
+ trfs = priv->udmaspec->trfs[speed];
+ tsr = priv->udmaspec->tsr[speed];
+ tli = priv->udmaspec->tli_max[speed];
+/*
+ DPRINTK ("UDMA t2cyc = %d\n", t2cyc);
+ DPRINTK ("UDMA tcyc = %d\n", tcyc);
+ DPRINTK ("UDMA tds = %d\n", tds);
+ DPRINTK ("UDMA tdh = %d\n", tdh);
+ DPRINTK ("UDMA tdvs = %d\n", tdvs);
+ DPRINTK ("UDMA tdvh = %d\n", tdvh);
+ DPRINTK ("UDMA tfs = %d\n", tfs);
+ DPRINTK ("UDMA tli = %d\n", tli);
+ DPRINTK ("UDMA tmli = %d\n", tmli);
+ DPRINTK ("UDMA taz = %d\n", taz);
+ DPRINTK ("UDMA tenv = %d\n", tenv);
+ DPRINTK ("UDMA tsr = %d\n", tsr);
+ DPRINTK ("UDMA tss = %d\n", tss);
+ DPRINTK ("UDMA trfs = %d\n", trfs);
+ DPRINTK ("UDMA trp = %d\n", trp);
+ DPRINTK ("UDMA tack = %d\n", tack);
+ DPRINTK ("UDMA tzah = %d\n", tzah);
+*/
+ timing->udma1 = (t2cyc << 24) | (tcyc << 16) | (tds << 8) | (tdh);
+ timing->udma2 = (tdvs << 24) | (tdvh << 16) | (tfs << 8) | (tli);
+ timing->udma3 = (tmli << 24) | (taz << 16) | (tenv << 8) | (tsr);
+ timing->udma4 = (tss << 24) | (trfs << 16) | (trp << 8) | (tack);
+ timing->udma5 = (tzah << 24);
+
+ timing->using_udma = 1;
+
+ return 0;
+}
+
static void
mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
{
@@ -173,13 +393,13 @@ mpc52xx_ata_apply_timings(struct mpc52xx
out_be32(®s->pio1, timing->pio1);
out_be32(®s->pio2, timing->pio2);
- out_be32(®s->mdma1, 0);
- out_be32(®s->mdma2, 0);
- out_be32(®s->udma1, 0);
- out_be32(®s->udma2, 0);
- out_be32(®s->udma3, 0);
- out_be32(®s->udma4, 0);
- out_be32(®s->udma5, 0);
+ out_be32(®s->mdma1, timing->mdma1);
+ out_be32(®s->mdma2, timing->mdma2);
+ out_be32(®s->udma1, timing->udma1);
+ out_be32(®s->udma2, timing->udma2);
+ out_be32(®s->udma3, timing->udma3);
+ out_be32(®s->udma4, timing->udma4);
+ out_be32(®s->udma5, timing->udma5);
priv->csel = device;
}
@@ -234,6 +454,7 @@ mpc52xx_ata_set_piomode(struct ata_port
pio = adev->pio_mode - XFER_PIO_0;
+ // FIXME, can be called for dma mode?
rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio);
if (rv) {
@@ -245,6 +466,28 @@ mpc52xx_ata_set_piomode(struct ata_port
mpc52xx_ata_apply_timings(priv, adev->devno);
}
static void
+mpc52xx_ata_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ int rv;
+
+ if (adev->dma_mode >= XFER_UDMA_0) {
+ int dma = adev->dma_mode - XFER_UDMA_0;
+ rv = mpc52xx_ata_compute_udma_timings(priv, adev->devno, dma);
+ } else {
+ int dma = adev->dma_mode - XFER_MW_DMA_0;
+ rv = mpc52xx_ata_compute_mdma_timings(priv, adev->devno, dma);
+ }
+
+ if (rv) {
+ printk(KERN_ERR DRV_NAME
+ ": Trying to select invalid DMA mode %d\n", adev->dma_mode);
+ return;
+ }
+
+ mpc52xx_ata_apply_timings(priv, adev->devno);
+}
+static void
mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
{
struct mpc52xx_ata_priv *priv = ap->host->private_data;
@@ -258,10 +501,174 @@ mpc52xx_ata_dev_select(struct ata_port *
static void
mpc52xx_ata_error_handler(struct ata_port *ap)
{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+
+ printk(KERN_ALERT "%s: status: %08x; fifo_status_frame: %08x; fifo_status: %08x\n",
+ __func__, in_be32(®s->host_status),
+ in_be32(®s->fifo_status_frame),
+ in_be32(®s->fifo_status));
+
ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
ata_std_postreset);
}
+static void
+mpc52xx_ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+ mpc52xx_ata_wait_tip_bit_clear(priv->ata_regs);
+
+ ata_exec_command(ap, tf);
+}
+
+static int
+mpc52xx_ata_build_dmatable(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+ struct scatterlist *sg;
+ unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE);
+ int count = 0;
+
+ if (read)
+ bcom_ata_rx_prepare(priv->dmatsk);
+ else
+ bcom_ata_tx_prepare(priv->dmatsk);
+
+
+ ata_for_each_sg(sg, qc) {
+ u32 cur_addr = sg_dma_address(sg);
+ u32 cur_len = sg_dma_len(sg);
+
+ while (cur_len) {
+ unsigned int tc = min(cur_len, MAX_DMA_BUFFER_SIZE);
+ struct bcom_ata_bd *bd;
+
+ bd = (struct bcom_ata_bd *)
+ bcom_prepare_next_buffer(priv->dmatsk);
+
+ if (read) {
+ bd->status = tc;
+ bd->dst_pa = cur_addr;
+ bd->src_pa = (__force u32)®s->fifo_data; // virt_to_phys?
+ } else {
+ bd->status = tc;
+ bd->dst_pa = (__force u32)®s->fifo_data; // virt_to_phys?
+ bd->src_pa = cur_addr;
+
+ /* and how does bestcomm know to increase one, and not other?
+ * XXX TODO */
+ }
+
+ bcom_submit_next_buffer(priv->dmatsk, phys_to_virt(cur_addr)); // qc is just a cookie
+
+ cur_addr += tc;
+ cur_len -= tc;
+ count++;
+
+ if (count == MAX_DMA_BUFFERS) {
+ printk(KERN_ALERT "%s: %i dma table too small\n",
+ __func__, __LINE__);
+ goto use_pio_instead;
+ }
+ }
+ }
+ return 1;
+
+ use_pio_instead:
+ bcom_ata_reset_bd(priv->dmatsk);
+ //pci_unmap_sg ???
+
+ return 0;
+}
+
+static void
+mpc52xx_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+ unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE);
+ u8 dma_mode;
+printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+
+ if (!mpc52xx_ata_build_dmatable(qc)) {
+ //ide_map_sg(drive, rq);
+ printk(KERN_ALERT "%s: %i, return 1?\n", __func__, __LINE__);
+ }
+
+ if (read) {
+ dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_READ |
+ MPC52xx_ATA_DMAMODE_FE;
+
+ /* Setup FIFO if direction changed */
+ if (priv->mpc52xx_ata_dma_last_write) {
+ priv->mpc52xx_ata_dma_last_write = 0;
+ mpc52xx_ata_wait_tip_bit_clear(regs);
+ out_8(®s->dma_mode, MPC52xx_ATA_DMAMODE_FR);
+ /* Configure it with granularity to 7 like sample code */
+ out_8(®s->fifo_control, 7);
+ out_be16(®s->fifo_alarm, 128);
+ }
+ } else {
+ dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_WRITE;
+
+ /* Setup FIFO if direction changed */
+ if (!priv->mpc52xx_ata_dma_last_write) {
+ priv->mpc52xx_ata_dma_last_write = 1;
+ mpc52xx_ata_wait_tip_bit_clear(regs);
+ /* Configure FIFO with granularity to 4 like sample code */
+ out_8(®s->fifo_control, 4);
+ //out_be16(®s->fifo_alarm, 256);
+ out_be16(®s->fifo_alarm, 128);
+ }
+ }
+
+ if (priv->timings[qc->dev->devno].using_udma)
+ dma_mode |= MPC52xx_ATA_DMAMODE_UDMA;
+
+ mpc52xx_ata_wait_tip_bit_clear(regs);
+ out_8(®s->dma_mode, dma_mode);
+
+ ap->ops->exec_command(ap, &qc->tf); // added, ata_bmdma_setup has it
+}
+
+static void
+mpc52xx_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+
+ //xlb_clear(); // WTF
+ bcom_enable(priv->dmatsk);
+}
+
+static void
+mpc52xx_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ // uh? looks like destructor for setup not start
+ struct ata_port *ap = qc->ap;
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+
+ bcom_disable(priv->dmatsk);
+ //bcom_clear_irq(priv->dmatsk); //!!
+ bcom_ata_reset_bd(priv->dmatsk);
+
+ // mpc52xx_ata_destroy_dmatable();
+}
+// waiting_for_dma eliminated
+
+static u8
+mpc52xx_bmdma_status(struct ata_port *ap)
+{
+printk(KERN_ALERT "%s: %i TODO\n", __func__, __LINE__);
+ return 0;
+}
static struct scsi_host_template mpc52xx_ata_sht = {
@@ -282,25 +689,47 @@ static struct scsi_host_template mpc52xx
.bios_param = ata_std_bios_param,
};
+static void mpc52xx_ata_bmdma_freeze(struct ata_port *ap)
+{
+ printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+ ata_bmdma_freeze(ap);
+}
+static void mpc52xx_ata_bmdma_thaw(struct ata_port *ap)
+{
+ printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+ ata_bmdma_thaw(ap);
+}
+static void ata_dummy_noret(struct ata_port *ap)
+{
+printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+}
static struct ata_port_operations mpc52xx_ata_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = mpc52xx_ata_set_piomode,
+ .set_dmamode = mpc52xx_ata_set_dmamode,
.dev_select = mpc52xx_ata_dev_select,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
+ .exec_command = mpc52xx_ata_exec_command,
+ .freeze = mpc52xx_ata_bmdma_freeze,
+ .thaw = mpc52xx_ata_bmdma_thaw,
.error_handler = mpc52xx_ata_error_handler,
.cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,
- .irq_clear = ata_bmdma_irq_clear,
+// .irq_clear = ata_bmdma_irq_clear,
+ .irq_clear = ata_dummy_noret,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
.port_start = ata_port_start,
+ .bmdma_setup = mpc52xx_bmdma_setup,
+ .bmdma_start = mpc52xx_bmdma_start,
+ .bmdma_stop = mpc52xx_bmdma_stop,
+ .bmdma_status = mpc52xx_bmdma_status,
+
+// not ide_dma_check int (*check_atapi_dma) (struct ata_queued_cmd *qc);
};
static int __devinit
@@ -309,7 +738,6 @@ mpc52xx_ata_init_one(struct device *dev,
struct ata_host *host;
struct ata_port *ap;
struct ata_ioports *aio;
- int rc;
host = ata_host_alloc(dev, 1);
if (!host)
@@ -317,9 +745,9 @@ mpc52xx_ata_init_one(struct device *dev,
ap = host->ports[0];
ap->flags |= ATA_FLAG_SLAVE_POSS;
- ap->pio_mask = 0x1f; /* Up to PIO4 */
- ap->mwdma_mask = 0x00; /* No MWDMA */
- ap->udma_mask = 0x00; /* No UDMA */
+ ap->pio_mask = ATA_PIO4; /* Up to PIO4 */
+ ap->mwdma_mask = 0x07; /* Up to MWDMA2 */
+ ap->udma_mask = ATA_UDMA2; /* Up to UDMA2 */
ap->ops = &mpc52xx_ata_port_ops;
host->private_data = priv;
@@ -359,6 +787,15 @@ mpc52xx_ata_remove_one(struct device *de
/* OF Platform driver */
/* ======================================================================== */
+static irqreturn_t
+mpc52xx_ata_task_irq(int irq, void *vpriv)
+{
+ struct mpc52xx_ata_priv *priv = vpriv;
+printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+
+ return IRQ_HANDLED;
+}
+
static int __devinit
mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
{
@@ -426,6 +863,30 @@ mpc52xx_ata_probe(struct of_device *op,
priv->ata_irq = ata_irq;
priv->csel = -1;
+ if (ipb_freq/1000000 == 66) {
+ priv->mdmaspec = &mdmaspec66;
+ priv->udmaspec = &udmaspec66;
+ } else {
+ priv->mdmaspec = &mdmaspec132;
+ priv->udmaspec = &udmaspec132;
+ }
+
+ priv->dmatsk = bcom_ata_init(MAX_DMA_BUFFERS, MAX_DMA_BUFFER_SIZE);
+ if (!priv->dmatsk) {
+ printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+ rv = -ENOMEM;
+ goto err;
+ }
+ // XXX task irq? nope, it doesn't get any irq's
+ {
+ int ret;
+ int task_irq = bcom_get_task_irq(priv->dmatsk);
+ printk(KERN_ALERT "%s: ata task irq: %i\n", __func__, task_irq);
+ ret = request_irq(task_irq, &mpc52xx_ata_task_irq, IRQF_DISABLED, "ata task", priv);
+ if (ret)
+ printk(KERN_ALERT "%s: request_irq failed with: %i\n", __func__, ret);
+ }
+
/* Init the hw */
rv = mpc52xx_ata_hw_init(priv);
if (rv) {
Index: work-powerpc.git/include/linux/libata.h
===================================================================
--- work-powerpc.git.orig/include/linux/libata.h
+++ work-powerpc.git/include/linux/libata.h
@@ -51,7 +51,7 @@
* compile-time options: to be removed as soon as all the drivers are
* converted to the new debugging mechanism
*/
-#undef ATA_DEBUG /* debugging output */
+#define ATA_DEBUG /* debugging output */
#undef ATA_VERBOSE_DEBUG /* yet more debugging output */
#undef ATA_IRQ_TRAP /* define to ack screaming irqs */
#undef ATA_NDEBUG /* define to disable quick runtime checks */
More information about the Linuxppc-embedded
mailing list