PROCESSOR-SDK-AM64X: overactive chip select when writing to the GPMC

Part Number: PROCESSOR-SDK-AM64X
Other Parts Discussed in Thread: SYSCONFIG

Using a hard coded GPMC configuration we are noticing that the GPMC is not performing as indicated on the AM64 Datasheet/Technical Reference Manual. We are using hardcoded GPMC values due to the limitations of the the Ti driver.

The chip select line seems to be over active on the writing.

  • Hello Steve Jackson,

    The read cycle is OK and the write cycle creates an issue.

    Your expectation is correct to write cycles CS is operating more cycles vs expected.

    I need to check at my Hw .So, that I will get some clue points.

    Can you please share your GPMC configuration register ?

    And please confirm you are trying this experiment on which core A53 or R5F core ?

    In your Application, are you doing only GPMC testing ? Or does it have any other Applications ?

    I just suspect that if any interrupt comes during the writing, so, the GPMC peripheral might be toggling CS line during the Write operation.

    Ideally, GPMC should not toggle CS line, but I am suspecting that one.

    In your testing, if you have only the GPMC, then it is fine, else keep only with GPMC testing  code and check one ore time .

    Actually, read cycle approximately you got 97.8nasec, which should supposed to be 100nsec. I think this seems OK.

    One more thing is that, even with the above CS over operating in write cycles, still are you able to write and read operations properly?

    Regards,

    Anil.

  • Hello Anil,

    My configuration registers are set with the code below

    /* Initialise GMPC Configuration for asynchronous PSRAM
    * The PSRAM uses the NOR protocol
    * Refer to 12.3.3.4.10 GPMC pSRAM Access Specificities on
    * page 8563 of spruim2h.pdf
    *
    * All we need to do is access the PSRAM via pointers therefore
    * minimum initialisation is carried out
    *
    * The TI driver code does not currently support PSRAM or NOR flash
    * TI e2e support for the GPMC has been lamentable thus far
    */

    *(uint32_t*)0x3B000010 = 0; // GPMC_SYSCONFIG
    *(uint32_t*)0x3B00001C = 0; // GPMC_IRQENABLE, disable all interrupts/events
    *(uint32_t*)0x3B000050 = 0; // GPMC_CONFIG, this can remain at its default of 0x00000200

    // GPMC_CONFIG1_i
    val = 0uL;
    val |= (CSL_GPMC_CONFIG1_DEVICESIZE_SIXTEENBITS << CSL_GPMC_CONFIG1_DEVICESIZE_SHIFT);
    val |= (CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_DIVBY1 << CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_SHIFT);
    *(uint32_t*)0x3B000060 = val;

    // GPMC_CONFIG2_i
    val = 0uL;
    val |= ((uint32_t)13 << CSL_GPMC_CONFIG2_CSWROFFTIME_SHIFT);
    val |= ((uint32_t)13 << CSL_GPMC_CONFIG2_CSRDOFFTIME_SHIFT);
    val |= ((uint32_t)1 << CSL_GPMC_CONFIG2_CSONTIME_SHIFT);
    *(uint32_t*)0x3B000064 = val;

    // GPMC_CONFIG3_i
    val = 0uL;
    val |= ((uint32_t)1 << CSL_GPMC_CONFIG3_ADVWROFFTIME_SHIFT);
    val |= ((uint32_t)1 << CSL_GPMC_CONFIG3_ADVRDOFFTIME_SHIFT);
    val |= ((uint32_t)1 << CSL_GPMC_CONFIG3_ADVONTIME_SHIFT);
    *(uint32_t*)0x3B000068 = val;

    // GPMC_CONFIG4_i
    val = 0uL;
    val |= ((uint32_t)12 << CSL_GPMC_CONFIG4_WEOFFTIME_SHIFT);
    val |= ((uint32_t)3 << CSL_GPMC_CONFIG4_WEONTIME_SHIFT);
    val |= ((uint32_t)12 << CSL_GPMC_CONFIG4_OEOFFTIME_SHIFT);
    val |= ((uint32_t)6 << CSL_GPMC_CONFIG4_OEONTIME_SHIFT);
    *(uint32_t*)0x3B00006C = val;

    // GPMC_CONFIG5_i
    val = 0uL;
    val |= ((uint32_t)12 << CSL_GPMC_CONFIG5_RDACCESSTIME_SHIFT);
    val |= ((uint32_t)14 << CSL_GPMC_CONFIG5_WRCYCLETIME_SHIFT);
    val |= ((uint32_t)14 << CSL_GPMC_CONFIG5_RDCYCLETIME_SHIFT);
    *(uint32_t*)0x3B000070 = val;

    // GPMC_CONFIG6_i
    val = CSL_GPMC_CONFIG6_WRDATAONADMUXBUS_RESETVAL;
    val |= ((uint32_t)12 << CSL_GPMC_CONFIG6_WRACCESSTIME_SHIFT); // This may not be correct, see how it performs
    val |= ((uint32_t)2 << CSL_GPMC_CONFIG6_CYCLE2CYCLEDELAY_SHIFT);
    val |= ((uint32_t)1 << CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_SHIFT);
    val |= ((uint32_t)1 << CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_SHIFT);
    val |= ((uint32_t)4 << CSL_GPMC_CONFIG6_BUSTURNAROUND_SHIFT);
    *(uint32_t*)0x3B000074 = val;

    // GPMC_CONFIG7_i
    val = 0uL;
    val |= (0x50000000U >> (24)); // Do this first for CONFIG7_i
    val |= (GPMC_CS_MASK_ADDR_SIZE_16MB << CSL_GPMC_CONFIG7_MASKADDRESS_SHIFT); // This may not be correct, see how it performs
    val |= ((uint32_t)1 << CSL_GPMC_CONFIG7_CSVALID_SHIFT); // CS0 should be enabled by default
    *(uint32_t*)0x3B000078 = val;

    for (z = 0; z < AM64_T4_GPMC_ADDRESS_LINES; z++)
    {
    padreg = (uint32_t*)T4_AddressLines[z].physical_address;

    *padreg = 0x00050000 | (uint32_t)T4_AddressLines[z].mode;
    }
    padreg = (uint32_t*)0x000F40A8;
    *padreg = 0x30000; // Enable CS0 internal pull up

    padreg = (uint32_t*)0x000F4094;
    *padreg = 0x10000; // Select GPMC0_BE1n

    padreg = (uint32_t*)0x000F4090;
    *padreg = 0x10000; // Select GPMC0_BE1n

    /*
    * Enable Data bus AD0 to AD15 by writing to PAD configuration
    * registers
    * Start at PADCFG_CTRL0_CFG0_PADCONFIG15. Refer to page 2098/2099
    * of spruim2h.pdf for register address etc
    */
    padreg = (uint32_t*)0xF403Cu;

    for (z = 0; z < 16; z++)
    {
    *padreg++ = (uint32_t)0x50000;
    }

    // end of initialisation

    We are testing using the R5F core and the application is solely for GPMC testing. We are still able to read back what we are righting so it appears to be working even though the CS line does not appear to be working as intended.

    Thanks

    Steve

  • Hello Steve,

    Thanks for sharing all details.

    I need to do testing on my side then only we can get the some clue, and I will update the status in one or two days after my testing done .

    Regards,

    Anil.

  • Hi

    Reopening this thread...

    When you observe the additional CS activity, have you probed other signals such as WEn, OEn, and Byte Enables (BE1n, BE0n)

    I suspect some of the CS low pulses may not have any corresponding WEn or OEn low pulse. And byte enables may be high (not enabled).
    We have observed "phantom chip selects" coming out of the GPMC pins as an artifact of writes through different hardware interconnects with protocol wrappers - for example a 64-bit CBA bus to 32-bit OCP bus to 16-bit GPMC peripheral may generate some GPMC pin activity where CS goes low but WEn, OEn, and byte enables all stay high.

    This thread may be relevant: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/316742/am335x-gpmc-phantom-chip-select-generation/1106520#1106520

     - Try the asm(" DMB"); instruction after the write.

     - Read about and play with the memory management - https://developer.arm.com/documentation/ddi0333/h/memory-management-unit/memory-attributes-and-types 

    Apologies for dropping this thread over a year ago.

    Regards,
    Mark