Tool/software:
Hello,
as it turns out, during burst write transactions the GPMC asserts both ChipSelect and WriteEnable by one clock cycle longer than anticipated.
I'm not observing this extra cycle during single-word write operations.
The overall configuration of the GPMC interface is as follows:
- 16 Bit interface
- Adress/Data multiplexed mode
- synchronous operation mode (at least for write - there is an issue with read; see that post AM6442: Reading from GPMC Window under Linux does return all zero in synchronous mode (but not in asynchronous mode) )
- The GPMC clock signal provided to the pad is free-running
I have to admit that I'm using a very tight timing regime. A single-word write operation is just taking 2 clock cycles - one cycle for the address and another for the data word. Both ChipSelect and WriteEnable are active for these two cycles only. This appears to work fine. However, when the GPMC interface is configured to allow burst write transactions and is generating one, both ChipSelect and WriteEnable are found to be active for one cycle too long. I.e., a burst write with four words should have activated ChipSelect and WriteEnable for 5 clocks. In fact, both are activated for 6 clocks. The same for bursts with 8 words, which should be 9 clocks in length but are found to be 10 clock cycles long. It might be worth mentioning that the data word that is being transferred within that extra-cycle is the same word that is the formal last word of the transaction. I.e. when there are to be transmitted 8 words indexed 0-7, the 9th "phantom" word is word number 7 duplicated.
It seems there is no explanation for this behavior within the TRM (which can also mean that I did just not find it...).
For reference, I'm providing the relevant Linux device tree settings for the GPMC here:
&gpmc0 {
pinctrl-names = "default";
pinctrl-0 = <&gpmc0_pins_default>;
assigned-clocks = <&k3_clks 80 0>;
assigned-clock-parents = <&k3_clks 80 1>;
assigned-clock-rates = <33333333>;
gpmc,num-cs = <4>;
gpmc,num-waitpins = <2>;
ranges = <0 0 0x00 0x50000000 0x01000000>, /* CS0 space. Min partition = 16MB */
<1 0 0x00 0x51000000 0x01000000>, /* CS1 space. Min partition = 16MB */
<2 0 0x00 0x52000000 0x01000000>, /* CS2 space. Min partition = 16MB */
<3 0 0x00 0x53000000 0x01000000>; /* CS3 space. Min partition = 16MB */
status = "okay";
....
fpga@2,0{
reg = <2 0 0x001000000>;
gpmc,mux-add-data = <2>; // AD multiplexed mode with a single address phase.
gpmc,device-width = <2>; // 16 Bit
gpmc,burst-length = <16>; // 16 words resp. 32 bytes burst length.
gpmc,wait-on-read = <0>; // No wait on read.
gpmc,wait-on-write = <0>; // No wait on write.
//gpmc,sync-read;
gpmc,sync-write;
gpmc,burst-read;
gpmc,burst-write;
gpmc,sync-clk-ps = <30000>;
gpmc,page-burst-access-ns = <30>; // 1 clock ticks. PAGEBURSTACCESSTIME - The number of clocks per word transmitted.
gpmc,cs-on-ns = <0>; // 0 clock ticks. CSONTIME - Immediate ChipSelect assertion without any delay.
gpmc,cs-rd-off-ns = <150>; // 5 clock ticks. CSRDOFFTIME - The clock number CS will be deasserted during read resp. when the first word has been captured.
gpmc,cs-wr-off-ns = <60>; // 2 clock ticks. CSWROFFTIME - The clock number CS will be deasserted during write resp. when the first word has been captured.
gpmc,adv-on-ns = <0>; // 0 clock ticks. ADVONTIME - The clock number the ADV signal will be asserted.
gpmc,adv-rd-off-ns = <30>; // 1 clock ticks. ADVRDOFFTIME - The clock number the ADV signal will be deasserted during read.
gpmc,adv-wr-off-ns = <30>; // 1 clock ticks. ADVWROFFTIME - The clock number the ADV signal will be deasserted during write.
gpmc,wr-data-mux-bus-ns = <30>; // 1 clock ticks. WRDATAONADMUXBUS - The clock number the written data will appear or the address is removed.
gpmc,oe-on-ns = <120>; // 4 clock ticks. OEONTIME - The clock number the OE will be asserted during read.
gpmc,oe-off-ns = <150>; // 5 clock ticks. OEOFFTIME - The clock number the OE will be deasserted during read resp. when the first word has been captured.
gpmc,we-on-ns = <0>; // 0 clock ticks. WEONTIME - The clock number the WE will be asserted during write.
gpmc,we-off-ns = <60>; // 2 clock ticks. WEOFFTIME - The clock number the WE will be deasserted during write resp. when the first word has been captured.
gpmc,rd-cycle-ns = <180>; // 6 clock ticks. RDCYCLETIME - The number of clocks a read takes resp. until one cycle after the first word has been captured.
gpmc,wr-cycle-ns = <60>; // 2 clock ticks. WRCYCLETIME - The number of clocks a write takes resp. until the first word has been captured.
gpmc,wr-access-ns = <60>; // 2 clock ticks. WRACCESSTIME - The number of clocks a write takes resp. until the first word has been captured.
gpmc,access-ns = <150>; // 5 clock ticks. RDACCESSTIME - The clock number the first data word will be sampled during read.
gpmc,bus-turnaround-ns = <30>; // 1 clock tick. BUSTURNAROUND - The number of clock ticks inserted between accesses.
gpmc,cycle2cycle-delay-ns = <30>;
gpmc,cycle2cycle-diffcsen;
gpmc,cycle2cycle-samecsen;
};
};
This is a particular setting for a moderate 33MHz GPMC clock.
The transactions are generated through the processor by mmapping the according GPMC window from /dev/mem and then simply accessing it. I.e.something like
fd = open("/dev/mem", O_RDWR | O_SYNC);
.....
fpga_fast_ram_space = (volatile int64_t *) mmap(NULL, FPGA_RAM_SPACE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, FPGA_FAST_RAM_SPACE_ADDR);
.....
memcpy( (void*)fpga_fast_ram_space, (void*) buffer1, 64);
It should be noted that this effect can be seen without an actual backend-device attached to the GPMC, since one can also write "into the air"...
Btw., the errata document for the AM6442, namely https://www.ti.com/lit/er/sprz457i/sprz457i.pdf, does not list anything that is going into that direction. I'm still using silicon revision 1.0 of the AM6442 but will upgrade soon to SR2.0. It might be an issue that has not been discovered before. It might also be that I'm making some mistake in my configuration.
Are there any ideas/suggestions?
Thanks,
Mario