Override 8bit access for 16bit only Bus (ARM)

  • David Jedynak

    David Jedynak - 2004-03-31

    I have an ARM core in a TI OMAP 5910.  I am using a PLD hooked to the Extended Memory IF (Slow) and using the chip selects to create a IDE controller (works just fine) and a CF controller (not so good) to talk to both memory cards and "I/O" type cards (like network).

    The EMIFS on the OMAP only does 16 bit addresses (no "AO") and has byte enables for masking when only 8bits are relevant.  I have some address lines going to the PLD to create the maps for attrib & common memory modes, IO mode, and True IDE mode and all of that switches just fine.  I can read the CIS ("dump_cis") and drivers load on insert, etc.

    Now, the problem.  From the CF spec, it says that some cards can use 8-bit writes as well as 16-bit writes.  Due to the nature of my bus (ARM EMIFS), I really can only do 16 bit access (although I can mask using the Byte Enables).  When a card de-asserts signal "IOIS16#" (meaning "8 bit IO"), I can only access the even bytes properly.  I've tried all sorts of things in my PLD and in my kernel code and just can't figure a way to get the card and the ARM to communicate on the odd addresses (CF address 0 = 1) when 8 bit mode is asserted by the CF Card.

    So - questions:

    1) Is there a way to force a card that is saying "8 bit mode" to accept access in 16 bit mode?  I've seen references to the IOIS16# signal being "ignorable", but nothing that helps me.

    2) I've also seen reference in the programmers guide to the following:
    io_req_t->Attribtues |= IO_DATA_PATH_WIDTH_16

    win_req_t->Attributes |= WIN_DATA_WIDTH_16

    SS_[Get|Set]IOMap (and the new version in 2.4):
    pccard_io_map->flags |= MAP_16BIT

    SS_[Get|Set]MemMap (and the new version in 2.4):
    pccard_mem_map->flags |= MAP_16BIT

    Are these the answer - just staring me in the face and I'm not getting it and not using them correctly? If not, what are they there for?

    3) It seems that the CF spec goes out of its way to explain how an 8 bit host can talk to a 16 bit card, but it seems to ignore a 16 bit only host talking to a card.  Is this oversight, or is it so painfully simple that I am making it more difficult than it has to be?  Are there really CF cards that *require* 8 bit access even though there are two byte enables on the thing to allow 16 bit writes with masking?????

    4) If none of these things are the answer, then what have people done?  I'm thinking of putting a 8 bit Mux on D0-7 to switch in D8-15 as required by some combination of ARM Byte Enables and IOIS16#, but that seems like a bad hack at best.

    FYI: here is a snippet of output when trying to ifconfig my Socket LP-E CF+ Ethernet card (uses stuff from 8390.c which I have moded for some debugging)

    # ifconfig eth0
    address ec000301, offset [0], readback = 78
    address ec000302, offset [1], readback = 30
    address ec000303, offset [2], readback = 78
    address ec000304, offset [3], readback = 50
    address ec000305, offset [4], readback = 78
    address ec000306, offset [5], readback = 28
    dev->dev_addr[0] = 0, port ec000301
    Heh! Hw. address read/write mismap 0
    readback = 78
    dev->dev_addr[1] = c0, port ec000302
    dev->dev_addr[2] = 1b, port ec000303
    Heh! Hw. address read/write mismap 2
    readback = 78
    dev->dev_addr[3] = 0, port ec000304
    dev->dev_addr[4] = b2, port ec000305
    Heh! Hw. address read/write mismap 4
    readback = 78
    dev->dev_addr[5] = 4e, port ec000306
    # eth0: interrupt(s) dropped!
    eth0: mismatched read page pointers 79 vs 4c.
    eth0: mismatched read page pointers 79 vs 78.
    eth0: mismatched read page pointers 79 vs 78.
    eth0: mismatched read page pointers 79 vs 78.

    and so on until I eject the card.   The IOIS16# line is goes high during this...

    Thank you much in advance for any help provided...  I'm looking forward to a resolution (and sleep) after many days and nights of pounding on this thing.


    • David Hinds

      David Hinds - 2004-04-01

      Regarding your questions:

      1 - PCMCIA/CF hosts are required to support 8 bit operation; 16-bit support is optional.  I don't think there is any way for a host to force a card to accept 16 bit operations.

      2 - these are instructions to the host bridge and cannot compel a card to do something it does not support.

      3 - It does not discuss 16 bit only hosts because they are not permitted.  I know that there are PCMCIA cards that only implement 8 bit data paths (i.e. D8-D15 are unconnected), and I presume that there are such CF cards as well, though I have no specific data.

      4 - that sounds like a reasonable solution.  I can't really speak to what other people have done because I have no data.

      -- Dave

      • David Jedynak

        David Jedynak - 2004-04-01

        Thanks for the info.

        What we are going to try is to connect ARM_A1 -> CF_A0 and then redefine the io operations for the CF drivers (like outb_p) so that it always left shifts the address, e.g.
        #define outb_p (n,addr) *(unsigned char *)addr << 1 = n

        We do this for our IDE, but that is a lot simpler because we only have to deal with ide.h.  In this case, it looks like some of the PCMCIA / CF device drivers are not writing through some abstraction (like the "VIRTUAL_BUS") so we have to figure out how to fix these drivers without too much extra work.


Log in to post a comment.