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:
- Establish the proper pad configuration,
- Configure the desired GPMC clocking,
- Configure the GPMC for our target FPGA communication,
- 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.