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.

AM6442: GPMC Testing on EVM (TMDS64GPEVM)

Part Number: AM6442

Hello,

  We are looking to use an AM64x device to communicate with an FPGA through the GPMC. We are verifying configuration and timing using a TMDS64GPEVM evaluation module.

  I am attempting to configure the GPMC and read/write a register in the GPMC0_DATA space in order to scope the output signals. The configuration appears correct, but any read/write access to the GPMC0_DATA space hangs. I do not see most of the expected waveforms on the GPMC signals, however I can confirm the proper waveform and frequency of the GPMC_CLK.

  Based upon the TRM, I am running the following general sequence:

  1. Establish the proper pad configuration,
  2. Configure the desired GPMC clocking,
  3. Configure the GPMC for our target FPGA communication,
  4. Attempt to read/write to the configured CS data space.

  Here is the current state of the code I am running:

#include <stdio.h>
#include <kernel/dpl/DebugP.h>
#include "ti_drivers_config.h"
#include "ti_drivers_open_close.h"
#include "ti_board_open_close.h"
#include <drivers/gpmc/v0/cslr_gpmc.h>                                  // GPMC_*
#include <drivers/hw_include/am64x_am243x/cslr_soc_baseaddress.h>       // CSL_GPMC0_CFG_BASE

/*
    TRM: MAIN Domain Memory Map
    GPMC0_CFG   0x03B000000 0x03B0003FF   1 KB
    GPMC0_DATA  0x050000000 0x057FFFFFF 128 MB
*/

void pad_config()
{
    HW_WR_REG32(0x000F403C, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG15 (GPMC0_AD0)
    HW_WR_REG32(0x000F4040, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG16 (GPMC0_AD1)
    HW_WR_REG32(0x000F4044, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG17 (GPMC0_AD2)
    HW_WR_REG32(0x000F4048, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG18 (GPMC0_AD3)
    HW_WR_REG32(0x000F404C, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG19 (GPMC0_AD4)
    HW_WR_REG32(0x000F4050, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG20 (GPMC0_AD5)
    HW_WR_REG32(0x000F4054, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG21 (GPMC0_AD6)
    HW_WR_REG32(0x000F4058, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG22 (GPMC0_AD7)
    HW_WR_REG32(0x000F405C, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG23 (GPMC0_AD8)
    HW_WR_REG32(0x000F4060, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG24 (GPMC0_AD9)
    HW_WR_REG32(0x000F4064, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG25 (GPMC0_AD10)
    HW_WR_REG32(0x000F4068, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG26 (GPMC0_AD11)
    HW_WR_REG32(0x000F406C, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG27 (GPMC0_AD12)
    HW_WR_REG32(0x000F4070, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG28 (GPMC0_AD13)
    HW_WR_REG32(0x000F4074, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG29 (GPMC0_AD14)
    HW_WR_REG32(0x000F4078, 0x54000);   // PADCFG_CTRL0_CFG0_PADCONFIG30 (GPMC0_AD15)

    HW_WR_REG32(0x000F407C, 0x54004);   // PADCFG_CTRL0_CFG0_PADCONFIG31 (GPMC0_CLK)
    HW_WR_REG32(0x000F4084, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG33 (GPMC0_ADVn_ALE)
    HW_WR_REG32(0x000F4088, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG34 (GPMC0_OEn_REn)
    HW_WR_REG32(0x000F408C, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG35 (GPMC0_WEn)
    HW_WR_REG32(0x000F4090, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG36 (GPMC0_BE0n_CLE)
    HW_WR_REG32(0x000F4094, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG37 (GPMC0_BE1n)
    HW_WR_REG32(0x000F4098, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG38 (GPMC0_WAIT0)
    HW_WR_REG32(0x000F409C, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG39 (GPMC0_WAIT1)
    HW_WR_REG32(0x000F40A0, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG40 (GPMC0_WPn)
    HW_WR_REG32(0x000F40A4, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG41 (GPMC0_DIR)

    HW_WR_REG32(0x000F40A8, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG42 (GPMC0_CSn0)
    HW_WR_REG32(0x000F40AC, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG43 (GPMC0_CSn1)
    HW_WR_REG32(0x000F40B0, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG44 (GPMC0_CSn2)
    HW_WR_REG32(0x000F40B4, 0x10000);   // PADCFG_CTRL0_CFG0_PADCONFIG45 (GPMC0_CSn3)

    HW_WR_REG32(0x000F40B8, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG46 (GPMC0_AD16)
    HW_WR_REG32(0x000F40BC, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG47 (GPMC0_AD17)
    HW_WR_REG32(0x000F40C0, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG48 (GPMC0_AD18)
    HW_WR_REG32(0x000F40C4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG49 (GPMC0_AD19)
    HW_WR_REG32(0x000F40C8, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG50 (GPMC0_AD20)
    HW_WR_REG32(0x000F40CC, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG51 (GPMC0_AD21)
    HW_WR_REG32(0x000F40D0, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG52 (GPMC0_AD22)
    HW_WR_REG32(0x000F40D4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG53 (GPMC0_AD23)
    HW_WR_REG32(0x000F40D8, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG54 (GPMC0_AD24)
    HW_WR_REG32(0x000F40DC, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG55 (GPMC0_AD25)
    HW_WR_REG32(0x000F40E0, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG56 (GPMC0_AD26)
    HW_WR_REG32(0x000F40E4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG57 (GPMC0_AD27)
    HW_WR_REG32(0x000F40E8, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG58 (GPMC0_AD28)
    HW_WR_REG32(0x000F40EC, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG59 (GPMC0_AD29)
    HW_WR_REG32(0x000F40F0, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG60 (GPMC0_AD30)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG61 (GPMC0_AD31)

    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG63 (GPMC0_A0)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG64 (GPMC0_A1)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG65 (GPMC0_A2)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG66 (GPMC0_A3)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG67 (GPMC0_A4)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG68 (GPMC0_A5)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG69 (GPMC0_A6)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG70 (GPMC0_A7)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG71 (GPMC0_A8)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG72 (GPMC0_A9)
    HW_WR_REG32(0x000F40F4, 0x54008);   // PADCFG_CTRL0_CFG0_PADCONFIG73 (GPMC0_A10)

    DebugP_log("Pad Configuration Complete.\r\n");
}

void gpmc_init()
{
    uint32_t gpmc_revision;

    // For FPGA clocking, configure the GPMC_FCLK (100MHz).
    HW_WR_REG32(0x43008180, 0x1); 		// CTRLMMR_GPMC_CLKSEL (MAIN_PLL2_HSDIV3_CLKOUT)
    DebugP_log("GPMC_FCLK Configured\r\n");

    // Read GPMC0 revision.
    gpmc_revision = HW_RD_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_REVISION);
    DebugP_log("GPMC Revision: 0x%X\r\n", gpmc_revision);

    // Disable the target chip selects for configuration. Per TRM:
    // Chip-select configuration (base and mask address or any protocol and
    // timing settings) must be performed while the associated chip-select
    // is disabled through the GPMC_CONFIG7_i[6] CSVALID bit.
    HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG7(0),
                ((0x0U << CSL_GPMC_CONFIG7_CSVALID_SHIFT) & CSL_GPMC_CONFIG7_CSVALID_MASK));

    // Program GPMC_CONFIG1
    HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG1(0),
                ((CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_DIVBY1 <<          CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_SHIFT) &           CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_MASK) |
                ((CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_X1 <<          CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_SHIFT) &       CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_MASK) |
                ((CSL_GPMC_CONFIG1_MUXADDDATA_NONMUX <<               CSL_GPMC_CONFIG1_MUXADDDATA_SHIFT) &                CSL_GPMC_CONFIG1_MUXADDDATA_MASK) |
                ((CSL_GPMC_CONFIG1_DEVICETYPE_NORLIKE <<              CSL_GPMC_CONFIG1_DEVICETYPE_SHIFT) &                CSL_GPMC_CONFIG1_DEVICETYPE_MASK) |
                ((CSL_GPMC_CONFIG1_DEVICESIZE_THIRTYTWOBITS <<        CSL_GPMC_CONFIG1_DEVICESIZE_SHIFT) &                CSL_GPMC_CONFIG1_DEVICESIZE_MASK) |
                ((CSL_GPMC_CONFIG1_WAITPINSELECT_W0 <<                CSL_GPMC_CONFIG1_WAITPINSELECT_SHIFT) &             CSL_GPMC_CONFIG1_WAITPINSELECT_MASK) |
                ((CSL_GPMC_CONFIG1_WAITMONITORINGTIME_ATVALID <<      CSL_GPMC_CONFIG1_WAITMONITORINGTIME_SHIFT) &        CSL_GPMC_CONFIG1_WAITMONITORINGTIME_MASK) |
                ((CSL_GPMC_CONFIG1_WAITWRITEMONITORING_WNOTMONIT <<   CSL_GPMC_CONFIG1_WAITWRITEMONITORING_SHIFT) &       CSL_GPMC_CONFIG1_WAITWRITEMONITORING_MASK) |
                ((CSL_GPMC_CONFIG1_WAITREADMONITORING_WNOTMONIT <<    CSL_GPMC_CONFIG1_WAITREADMONITORING_SHIFT) &        CSL_GPMC_CONFIG1_WAITREADMONITORING_MASK) |
                ((CSL_GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_FOUR <<   CSL_GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_SHIFT) &  CSL_GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_MASK) |
                ((CSL_GPMC_CONFIG1_CLKACTIVATIONTIME_ATSTART <<       CSL_GPMC_CONFIG1_CLKACTIVATIONTIME_SHIFT) &         CSL_GPMC_CONFIG1_CLKACTIVATIONTIME_MASK)|
                ((CSL_GPMC_CONFIG1_WRITETYPE_WRSYNC <<                CSL_GPMC_CONFIG1_WRITETYPE_SHIFT) &                 CSL_GPMC_CONFIG1_WRITETYPE_MASK) |
                ((CSL_GPMC_CONFIG1_WRITEMULTIPLE_WRSINGLE <<          CSL_GPMC_CONFIG1_WRITEMULTIPLE_SHIFT) &             CSL_GPMC_CONFIG1_WRITEMULTIPLE_MASK) |
                ((CSL_GPMC_CONFIG1_READTYPE_RDSYNC <<                 CSL_GPMC_CONFIG1_READTYPE_SHIFT) &                  CSL_GPMC_CONFIG1_READTYPE_MASK) |
                ((CSL_GPMC_CONFIG1_READMULTIPLE_RDSINGLE <<           CSL_GPMC_CONFIG1_READMULTIPLE_SHIFT) &              CSL_GPMC_CONFIG1_READMULTIPLE_MASK) |
                ((CSL_GPMC_CONFIG1_WRAPBURST_WRAPNOTSUPP <<           CSL_GPMC_CONFIG1_WRAPBURST_SHIFT) &                 CSL_GPMC_CONFIG1_WRAPBURST_MASK)
                );

    // Program GPMC_CONFIG2
    HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG2(0),
                ((0x0U <<                                       CSL_GPMC_CONFIG2_CSONTIME_SHIFT) &      CSL_GPMC_CONFIG2_CSONTIME_MASK) |
                ((CSL_GPMC_CONFIG2_CSEXTRADELAY_NOTDELAYED <<   CSL_GPMC_CONFIG2_CSEXTRADELAY_SHIFT) &  CSL_GPMC_CONFIG2_CSEXTRADELAY_MASK) |
                ((0xCU <<                                       CSL_GPMC_CONFIG2_CSRDOFFTIME_SHIFT) &   CSL_GPMC_CONFIG2_CSRDOFFTIME_MASK) |
                ((0xFU <<                                       CSL_GPMC_CONFIG2_CSWROFFTIME_SHIFT) &   CSL_GPMC_CONFIG2_CSWROFFTIME_MASK)
                );

    // Program GPMC_CONFIG3
    HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG3(0), 0x0U);

    // Program GPMC_CONFIG4
    HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG4(0),
                ((0x2U <<                                       CSL_GPMC_CONFIG4_OEONTIME_SHIFT) &          CSL_GPMC_CONFIG4_OEONTIME_MASK) |
                ((0x0U <<                                       CSL_GPMC_CONFIG4_OEAADMUXONTIME_SHIFT) &    CSL_GPMC_CONFIG4_OEAADMUXONTIME_MASK) |
                ((CSL_GPMC_CONFIG4_OEEXTRADELAY_NOTDELAYED <<   CSL_GPMC_CONFIG4_OEEXTRADELAY_SHIFT) &      CSL_GPMC_CONFIG4_OEEXTRADELAY_MASK) |
                ((0xAU <<                                       CSL_GPMC_CONFIG4_OEOFFTIME_SHIFT) &         CSL_GPMC_CONFIG4_OEOFFTIME_MASK) |
                ((0x0U <<                                       CSL_GPMC_CONFIG4_OEAADMUXOFFTIME_SHIFT) &   CSL_GPMC_CONFIG4_OEAADMUXOFFTIME_MASK) |
                ((0x3U <<                                       CSL_GPMC_CONFIG4_WEONTIME_SHIFT) &          CSL_GPMC_CONFIG4_WEONTIME_MASK) |
                ((CSL_GPMC_CONFIG4_WEEXTRADELAY_NOTDELAYED <<   CSL_GPMC_CONFIG4_WEEXTRADELAY_SHIFT) &      CSL_GPMC_CONFIG4_WEEXTRADELAY_MASK) |
                ((0x8U <<                                       CSL_GPMC_CONFIG4_WEOFFTIME_SHIFT) &         CSL_GPMC_CONFIG4_WEOFFTIME_MASK)
                );

    // Program GPMC_CONFIG5
    HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG5(0),
                ((0x5U <<                                       CSL_GPMC_CONFIG5_RDCYCLETIME_SHIFT) &           CSL_GPMC_CONFIG5_RDCYCLETIME_MASK) |
                ((0x3U <<                                       CSL_GPMC_CONFIG5_WRCYCLETIME_SHIFT) &           CSL_GPMC_CONFIG5_WRCYCLETIME_MASK) |
                ((0x4U <<                                       CSL_GPMC_CONFIG5_RDACCESSTIME_SHIFT) &          CSL_GPMC_CONFIG5_RDACCESSTIME_MASK) |
                ((0x1U <<                                       CSL_GPMC_CONFIG5_PAGEBURSTACCESSTIME_SHIFT) &   CSL_GPMC_CONFIG5_PAGEBURSTACCESSTIME_MASK)
                );

    // Program GPMC_CONFIG6
    HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG6(0),
                ((0x2U <<                                       CSL_GPMC_CONFIG6_BUSTURNAROUND_SHIFT) &             CSL_GPMC_CONFIG6_BUSTURNAROUND_MASK) |
                ((CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_NOC2CDELAY << CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_SHIFT) &  CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_MASK) |
                ((CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_NOC2CDELAY << CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_SHIFT) &  CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_MASK) |
                ((0x0U <<                                       CSL_GPMC_CONFIG6_CYCLE2CYCLEDELAY_SHIFT) &          CSL_GPMC_CONFIG6_CYCLE2CYCLEDELAY_MASK) |
                ((0x7U <<                                       CSL_GPMC_CONFIG6_WRDATAONADMUXBUS_SHIFT) &          CSL_GPMC_CONFIG6_WRDATAONADMUXBUS_MASK) |
                ((0x3U <<                                       CSL_GPMC_CONFIG6_WRACCESSTIME_SHIFT) &              CSL_GPMC_CONFIG6_WRACCESSTIME_MASK)
                );

    // Program GPMC_CONFIG7
    HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG7(0),
                ((0x0U <<                                       CSL_GPMC_CONFIG7_BASEADDRESS_SHIFT) &   CSL_GPMC_CONFIG7_BASEADDRESS_MASK) |
                ((0x1U <<                                       CSL_GPMC_CONFIG7_CSVALID_SHIFT) &       CSL_GPMC_CONFIG7_CSVALID_MASK) |
                ((0xFU <<                                       CSL_GPMC_CONFIG7_MASKADDRESS_SHIFT) &   CSL_GPMC_CONFIG7_MASKADDRESS_MASK)
                );

    DebugP_log("GPMC Initialization Complete.\r\n");
}

void gpmc_test_main(void *args)
{
    uint32_t value;

    /* Open drivers to open the UART driver for console */
    Drivers_open();
    Board_driversOpen();

    pad_config();
    gpmc_init();

    while ( 1 )
    {
        DebugP_log("Pre Read Reg\r\n");
        value = HW_RD_REG32(CSL_GPMC0_DATA_BASE);
        DebugP_log("Post Read Reg: 0x%X\r\n", value);
    }

    Board_driversClose();
    Drivers_close();
}

Any guidance with what I am missing or doing incorrectly would be greatly appreciated.

  • Update: Turns out that I had the GPMC_CONFIG7 BASEADDRESS field definition completely wrong. When I applied the fix, it became functional.

  • Thanks Chris , I appreciate the quick update. 

    Curious if the issue was in our code base or documentation , if so, please let us know where so we can file appropriate bugs to track and fix. 

    Regards

    Mukul 

  • Chris, I am having a similar issue. Could you share what you changed on the CS Base Address to correct your problem?

  • My problem came from the definition of the GPMC7_CONFIG register setting, specifically the BASEADDRESS bitfield. The configuration of this bitfield is described in the TRM (pg 8526 of the October 2023 revision). However, the TRM provides an example that doesn't make sense. It says: "For example, to map the 128MB address space (from 5000 0000h to 57FF FFFFh), the GPMC_CONFIG7_i[5-0] BASEADDRESS bit field should be set to 20h." However, that never made sense to me. Since the 6 bits of the BASEADDRESS bitfield are intended to map to A29:24 of the physical address space, a value of 0x20h would correspond with address 0x2000_0000h, not 0x5000_0000h. I believe that line to be incorrect, perhaps copied from another device which used a different address space. The proper AM64x BASEADDRESS bitfield value for 0x5000_0000h is 0x10h (bit A30 of the address space being truncated away).

    When I made this change, it functioned properly. 

  • Ahh, I didn't realize the BASEADDRESS needed to include the GPMC_DATA offset. I can now successfully access this memory location. Much appreciated.