This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Can't get EMIFA to work on OMAP-L138

Other Parts Discussed in Thread: OMAP-L138, OMAP-L137

Hi.  I'm working on an OMAP-L138 board, and I'm trying to get the DSP core to talk to an external peripheral with memory-mapped registers.  I've spent the last day banging my head against the wall and getting nowhere.  Bottom line: I never see EMIFA_CS2# assert, so my peripheral never responds.  Here's what I've checked....

I made a .tci file for the memory map, and included it in my project .tcf file:

/* ============================================================================
 * FPGA Registers EMIF peripheral
 * ============================================================================
 */
var FPGA_REGS = prog.module("MEM").create("FPGA_REGS");
FPGA_REGS.base       = 0x60000000;
FPGA_REGS.len        = 0x2000000;
FPGA_REGS.space      = "data";
FPGA_REGS.createHeap = false;
FPGA_REGS.comment    = "FPGA_REGS";

prog.module("GBL").C64PLUSMAR96to127 = 0x00000000 ;

...marked all of EMIF space not cacheable.

Declared the registers in C like this...

static volatile far __attribute__((__section__(".fpga_regs")))
struct fpga_registers {

   /* blah, blah, blah.... */

} fpga_regs;

...and mapped them to the right address with this snippet of linker command file:

    .fpga_regs: {
        *(.fpga_regs)
    } > FPGA_REGS

in a SECTIONS declaration.

Wrote up a little test function to read a register, increment the value, and write it back.  If I look at the post-link disassembly of that function, it goes like this:

c23962a0   0203b80e           LDHU.D2T2     *+B14[952],B4
c23962a4   01800328           MVK.S1        0x0006,A3
c23962a8   01b00069           MVKH.S1       0x60000000,A3
c23962ac   000c0362 ||        B.S2          B3
c23962b0   020c0204           LDHU.D1T1     *+A3[0],A4
c23962b4       0c6e           NOP           1
c23962b6       2651           ADD.L2        B4,1,B5
c23962b8   0283b85e           STH.D2T2      B5,*+B14[952]
c23962bc   e4000000           .fphead       n, l, W, BU, nobr, nosat, 0100000b
c23962c0   020c0256           STH.D1T2      B4,*+A3[0]

That sure looks like a read from, and subsequent write to address 0x60000006, the fourth 16-bit register in the map.

EMIFA is enabled in the PINMUX, and CE2 is configured for the most conservative possible timings...

    /* configure the pinmux for the EMIFA -- pins (BA[1:0], CLK, CS2, OE#,
     * WE#, RNW, WAIT[1:0], DATA[15:0], ADDR[13:0] */
    tmp = (sysCfgRegs->PINMUX5  & 0x00FFFFFF) | 0x11000000;
    sysCfgRegs->PINMUX5 = tmp;
    tmp = (sysCfgRegs->PINMUX6  & 0xF0FFFFF0) | 0x01000001;
    sysCfgRegs->PINMUX6 = tmp;
    tmp = (sysCfgRegs->PINMUX7  & 0x0000FFF0) | 0x11110001;
    sysCfgRegs->PINMUX7 = tmp;
    tmp = (sysCfgRegs->PINMUX8  & 0x00000000) | 0x11111111;
    sysCfgRegs->PINMUX8 = tmp;
    tmp = (sysCfgRegs->PINMUX9  & 0x00000000) | 0x11111111;
    sysCfgRegs->PINMUX9 = tmp;
    tmp = (sysCfgRegs->PINMUX10 & 0xFFFFFFFF) | 0x00000000;
    sysCfgRegs->PINMUX10 = tmp;
    tmp = (sysCfgRegs->PINMUX11 & 0x000000FF) | 0x11111100;
    sysCfgRegs->PINMUX11 = tmp;
    tmp = (sysCfgRegs->PINMUX12 & 0x00000000) | 0x11111111;
    sysCfgRegs->PINMUX12 = tmp;

    emifaRegs->CE2CFG =
        (CSL_EMIFA_CE2CFG_SS_SELSTRB_DISABLE << CSL_EMIFA_CE2CFG_SS_SHIFT)
      | (CSL_EMIFA_CE2CFG_EW_EXT_WAIT_DISABLE << CSL_EMIFA_CE2CFG_EW_SHIFT)
      | (0x0F << CSL_EMIFA_CE2CFG_W_SETUP_SHIFT)
      | (0x3F << CSL_EMIFA_CE2CFG_W_STROBE_SHIFT)
      | (0x07 << CSL_EMIFA_CE2CFG_W_HOLD_SHIFT)
      | (0x0F << CSL_EMIFA_CE2CFG_R_SETUP_SHIFT)
      | (0x3F << CSL_EMIFA_CE2CFG_R_STROBE_SHIFT)
      | (0x07 << CSL_EMIFA_CE2CFG_R_HOLD_SHIFT)
      | (0x03 << CSL_EMIFA_CE2CFG_TA_SHIFT)
      | (CSL_EMIFA_CE2CFG_ASIZE_16BIT << CSL_EMIFA_CE2CFG_ASIZE_SHIFT);

I never see CE2# go low.  I see EMA_CLK toggling at the correct rate.  My DSPCLK is 456MHz; if I configure the EMIF to run from the fixed DIV4.5, then I see a nice 101.3MHz clock on EMA_CLK.  If I configure it to run from SYSCLK3, and make PLL0_PLLDIV3 a divide by 5, then I see a nice 91.2MHz clock on EMA_CLK.  But I never see CE2# fire.  And I know the test code is running -- it's returning me bogus values that it supposedly read from the register.

OK, what am I missing?  What haven't I looked at that could be causing me not to get real EMIF bus accesses?  Thanks much for any thoughts or pointers...

-------Carl

  • I even tried clearing the EMIF Interrupt Raw Status register before the fpga_regs access, and checking it afterwards, just in case the EMIF was throwing some kind of invalid access interrupt.  Nope.  Came back zero.

  • I fired up CCS, put the expression *(unsigned short*)0x60000000 into the data window, and turned on continuous refresh.

    No CE2#, no OE#.

    The DSP does not appear to be generating the bus accesses at all.

  • I do much the same thing on the OMAP-L137, EMIFA, 16-bit, and CE4. Same timings. Did you see if the pinmux registers got changed? I base my code on examples that hit the KICK registers before modifying the pinmux registers. I also not pinmux the upper address lines as high impedance. That probably has nothing to do with your problem. In your tests, is anything on the bus?

  • Good thought on the PINMUX registers.  I didn't include the whole function in the original post, as I do other PINMUX setups that don't relate to EMIFA as well, but yes, I do unlock the KICK registers at the top of the setup function and lock them again at the bottom.  I can verify that the EMIFA PINMUX registers read back later, at program runtime, exactly as I set them in the setup function.

    The FPGA that serves as the target peripheral is the only other thing on the EMIFA bus.

  • Can't think of anything else significant. I was actually surprised how just writing to the CEnCFG register was enough to set memory type. Maybe check NANDFCR to see if it thinks it is talking to NAND. Or try without the FPGA connected. Perhaps the FPGA is pulling down all the lines. Maybe power management or clock? That stuff seems to be handled out of sight in GEL scripts. That's all I got.

  • Well I sure appreciate the pointers, Norman.  Still no joy, but at least you came up with some good things to check that I didn't.

    Verified that all NAND functionality is off.  Found that I wasn't actually setting the KICK registers back to bad values after my configuration run.  Put that bit of code in and nothing changed.  Verified that the EMIF clock is good because I can see it coming out on the EMA_CLK pin.  Looking into power management, which I had ignored because I'm running DSP/BIOS without the PWRM module, since I need max performance all the time, and I won't ever be changing power states on demand.

    Unfortunately running "without the FPGA connected" is easier said than done.  It's a big BGA, and we can't pull it in-house.  The FPGA is working fine apart from the EMIF, and our FPGA guy has triple-checked that all EMIF lines are configured as inputs, except the data lines which are bi-di.  We don't use WAIT.

  • Whoa.   MDSTAT3 in PSC0 reads as 0x00000e02.  Does that mean the EMIF block is disabled?

  • You know more than me. I've been lucky with code libraries and config that I never had to deal with the PSC. I can only confirm your interpretion that EMIFA appears have no clock. Odd that you got EMA_CLK. I guess that would make sense as external SDRAM would need clock to retain it's contents. The TRM suggest that IcePick could mess with the clock. Maybe your ICE has powered down the EMIF when you stop the processor? U-boot has some PSC code to start up a clock. StarterWare has some as well.

    Maybe a short? A possible test, change all the pins to GPIO inputs and get the FPGA to continously toggle the pins. Read the GPIOs or probe the pins if they are accessible.

  • Pow.  Got it.

    I just needed to do

    status = Psc_ModuleClkCtrl(Psc_DevId_0, CSL_PSC_EMIFA, TRUE);

    right before setting up the EMIF registers, and also a

    Psc_init();

    at the top of main, because the dependency array in Psc doesn't auto-initialize to zero.

    It was, in fact, that the EMIF block was disabled.  Thanks for your suggestions, Norman!  One of them did, in fact, lead me to the answer!  Celebratory dinner time....

  • Good news, Bon Appétit.