UDMA for Compact Flash over PC Card?

Steven John Newbury steve at snewbury.org.uk
Mon Feb 11 15:59:41 EST 2008


On Tuesday 05 February 2008 16:46:38 Iain Barker wrote:
> FYI, we've been looking at this recently, and the DMA-related PXA patch
> from this email thread:
> http://lists.infradead.org/pipermail/linux-pcmcia/2007-April/004473.html
>
> On Wed Apr 4 06:36:35 EDT 2007, Steve Newbury wrote:
> > The only way of getting CF devices to run in (U)DMA mode is to physically
> > attach them to an IDE controller.  CF devices can electrically operate as
> > either PCMCIA-like or IDE devices.  If operating as a PCMCIA device it
> > can only be accessed with IO or MMIO.  If you want more performance 
than
> > the 300ns cycle IO access time you need to use MMIO **and set the 
access
> > speed to the correct value for that CF device**, you'll then get much
> > higher performace (upto 20MB/s).  Using a variation on Thomas Kleffel's
> > patch I've tried before, not completely managed to get it working, see
> > this lists archives.  I couldn't get the interrupt working for some
> > reason.
> >
> > Steve
>
> The compact flash spec has a feature that allows DMA host controllers to
> move data to and from the CF data buffer WHEN USING PIO MODE, more
> efficiently and quicker than simply doing individual reads and writes to
> and from the single 16-bit ata data register.
>
> i.e. for architectures which have a DMA controller (for example, PCI
> bridges) when used with PCMCIA controllers which DO NOT support DMA (for
> example, TI PCI1510), this can reduce CPU overhead for PIO transfers
> considerably.
>
> This feature is simply a pseudo buffer, that resides at ata offset
> 0x0400-0x0800,  that allows incrementing dmas sequential access to the 
same
> ata data register, which in reality is just a fifo, but the feature is only
> available when the cf is configured for MEMORY mode.
>
> There was an earlier attempt to support MMIO by Thomas Kleffel, but his
> patch was reverted in 2.6.19 by Andrew Morton due to various problems.
>
> Although it's not in the mainline Linux code, I know readers on this list
> who use Thomas' patch, so this is an attempt at summarising the problems
> and possible fixes.
>
> 1/ It has a problem with still using the default PCI IO access functions to
> communicate with the cf's ATA registers during probe, rather than using
> MMIO for all operations.
>
> Fix: Adding specific code to ide_register_hw_with_fixup function to load
> the PCI MEM functions into the hwif struct when that struct is being
> initialized and the is_mmio flag is set.
>
> In drivers/ide/legacy/ide-cs.c
>
> Within the CIS parser, set the memory mode per Thomas' is_mmio patch:
> >                 link->conf.IntType = INT_MEMORY;
>
> Then pass is_mmio from Thomas' patch as the last parameter when calling 
the fixup function:
> > int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp,
> > void(*fixup)(ide_hwif_t *hwif), int is_mmio)
>
> 807a808,821
>
> >       if (is_mmio)
> >       {
> >               default_hwif_mmiops(hwif);
> >               hwif->io_ports[IDE_DATA_OFFSET] += 0x0400;
> >               hwif->mmio = 2;
> >       }
>
> 2/ Once the ide driver was able to communicate successfully with the cf ATA
> registers in MEM mode we could see that the interrupts didn't work.
>
> Fix: Changing the desired interrupt mode from INT_MEMORY_AND_IO to
> INT_MEMORY when configuring the pcmcia socket controller. The lowest-level
> yenta socket code could handle this functionality but the higher-level
> pcmcia code could not handle it.
>
> i.e. fix this by adding 2 lines of of INT_MEMORY support code to the
> pcmcia_request_configuration function.
>
> In drivers/pcmcia/pcmcia_resource.c
> 628a629,633
>
> >       if (req->IntType & INT_MEMORY)
> >       {
> >               s->socket.flags    &= ~SS_IOCARD; // this is not an IO card
> >               s->socket.csc_mask |=  SS_READY;  // enable the READY
> > interrupt }
>
> 3/ Extend the base register so that it looks at the MMIO buffer at +400
> instead of the base data register.
>
> In drivers/ide/legacy/ide-cs.c
>
> > int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp,
> > void(*fixup)(ide_hwif_t *hwif), int is_mmio)
>
> 807a808,821
>
> >       /* if the mmio flag is set we populate the hwif structure with
> >        * the functions used to access PCI memory space (as opposed to
> >        * the default functions which access PCI io space). we also
> >        * change the 'data' offset to the address of the data buffer
> >        * that exists at offset 0x0400 so that we can use pci dmas
> >        * to move data faster.
> >        */
> >       if (is_mmio)
> >       {
> >               default_hwif_mmiops(hwif);
> >               hwif->io_ports[IDE_DATA_OFFSET] += 0x0400;
> >               hwif->mmio = 2;
> >       }
>
> Note: This isn't a complete solution, as with the ide driver now working in
> MEMORY mode it still needs architecture-specific code to implement the DMA
> transfer to the MMIO FIFO buffer.  That's relatively trivial using the arch
> native PCI driver functions to move 16-bit data to and from the PCI bus
> using block transfers instead of single-access transfers, for example the
> PXA driver from Steven.

Hi Iain, good job! Do you have a patch?  I'm busy with other things at the 
moment but I'll find some time to try this out.  You managed to get further 
than I did, I was quit stuck on the lack of IRQ from the drive, the datasheet 
I was using for reference didn't mention that the interrupt for memory 
accesses is only generated in memory only mode!



More information about the linux-pcmcia mailing list