Tool/software:
Hello,
this question has been already discussed few years back in the linked thread.
Outcome was that there is no Linux driver support yet and there are no existing plans to support that.
I'm not quite sure whether this has been changed today. In the recent SDK 09.02.01.10 I'm finding in
./board-support/ti-linux-kernel-6.1.83+gitAUTOINC+c1c2f1971f-ti/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
the followng content:
gpmc0: memory-controller@3b000000 {
compatible = "ti,am64-gpmc";
power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 80 0>;
clock-names = "fck";
reg = <0x00 0x3b000000 0x00 0x400>,
<0x00 0x50000000 0x00 0x8000000>;
reg-names = "cfg", "data";
interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
gpmc,num-cs = <3>;
gpmc,num-waitpins = <2>;
#address-cells = <2>;
#size-cells = <1>;
interrupt-controller;
#interrupt-cells = <2>;
gpio-controller;
#gpio-cells = <2>;
status = "disabled";
};
So there seems to be some progress here. In case there is existing a Linux driver support,
are there some links to tutorials/examples from where I can see how to make use of the
GPMC through a driver?
Apart from that, a Linux driver might not be ultimately important here, as the primary
use of the GPMC should boil down to the setting of various configuration registers and
mapping of address windows. In a first attempt to do this by mapping the physical memory
of /dev/mem at 0x3b000000 via mmap() I'm receiving a "bus error" when trying to access
the GPMC CSRs. For reference, here is my simple test program:
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#define GPMC0_CFG_ADDR 0x03B000000
#define GPMC0_CFG_SIZE 4096 //1024
#define GPMC0_DATA_ADDR 0x050000000
#define GPMC0_DATA_SIZE (128*1024*1024)
int main() {
volatile uint32_t *gpmc_config_regs;
volatile uint32_t *gpmc_data;
int fd;
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd == -1) {
printf("failed opening /dev/mem - %s\n", strerror(errno));
exit(-1);
}
gpmc_config_regs = (volatile uint32_t *) mmap(NULL, GPMC0_CFG_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPMC0_CFG_ADDR);
if (gpmc_config_regs == MAP_FAILED) {
printf("failed to map the GPMC config registers - %s\n", strerror(errno));
exit(-1);
}
printf("CFG[0] = 0x%08X\n", gpmc_config_regs[0]);
munmap((void*)gpmc_config_regs, GPMC0_CFG_SIZE);
close(fd);
}
I'm not quite sure, but one reason why this is generating a bus error might be that the GPMC
is some sort of deactivated and does not respond to accesses. If that's the case, what would be needed
to turn on the GPMC?
Any ideas?
Thanks,
Mario