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.

AM3359: GPMC access to external memory

Part Number: AM3359

Hi,

I have a custom board running on Linux which has a 6MB external RAM connected to the GPMC. I can interact with the GPMC Registers and it seems to be ok, for example if I write into the reset register then it triggers the reset done register. However, I can't access the external memory and I don't know what I'm missing here. First of all I would like to share my device tree configuration and ask a few questions:

I slightly modified the am33xx.dtsi to have access to the external memory through UIO

soc {
		compatible = "ti,omap-infra";
		mpu {
			compatible = "ti,omap3-mpu";
			ti,hwmods = "mpu";
			pm-sram = <&pm_sram_code
				   &pm_sram_data>;
		};

		dpram_mem: dpram_mem {
			compatible = "ti,uio-module-drv";
			mem = <0x08000000 0x600000>; // dpram 
			mem-names = "dpram";
			status = "disabled";
		};
	};

Then the GMPC part of my board looks as follows:

&gpmc {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&triport_pins_default>;
	/* chip select ranges */
	ranges = <0 0 0x08000000 0x600000>; //6MB RAM: 0x600000
	sram {
		compatible="mtd-ram";
		reg = <0 0 0x08000000>; /*CSn0*/

		bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */

		/*gpmc,burst-write;*/
		/*gpmc,burst-read;*/
		/*gpmc,burst-wrap;*/
		gpmc,sync-read; /* GPMC_CONFIG1_READTYPE_ASYNC */
		gpmc,sync-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */
		gpmc,clk-activation-ns = <0>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */
		gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */
		gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */

		gpmc,sync-clk-ps = <20000>; /* CONFIG2 */

		gpmc,cs-on-ns = <0>;
		gpmc,cs-rd-off-ns = <130>;
		gpmc,cs-wr-off-ns = <100>;

		gpmc,adv-on-ns = <0>; /* CONFIG3 */
		gpmc,adv-rd-off-ns = <45>;
		gpmc,adv-wr-off-ns = <45>;

		gpmc,we-on-ns = <45>; /* CONFIG4 */
		gpmc,we-off-ns = <50>;
		gpmc,oe-on-ns = <45>;
		gpmc,oe-off-ns = <100>;

		//gpmc,page-burst-access-ns = <20>; /* CONFIG 5 */
		gpmc,access-ns = <100>;
		gpmc,rd-cycle-ns = <145>;
		gpmc,wr-cycle-ns = <95>;
		gpmc,wr-access-ns = <45>; /* CONFIG 6 */
		gpmc,wr-data-mux-bus-ns = <20>;

		/*gpmc,bus-turnaround-ns = <40>;*/ /* CONFIG6:3:0 = 4 */
		gpmc,cycle2cycle-samecsen; /* CONFIG6:7 = 1 */
		gpmc,cycle2cycle-delay-ns = <20>; /* CONFIG6:11:8 = 4 */

		};
};

&dpram_mem {
	status = "okay";
};

First of all I wonder with the sram compatible parameter. I set "mtd-ram". I tried first without the compatible parameter but it does not work. Then I tried with mtd-ram and mtd-nor... I guess I need to set something there, otherwise Linux wont be able to load a proper driver to access the external memory. Is my device tree ok? Should I modify something there?

Other than that, this is the configuration I have under Linux:

 dmesg | grep gpmc
[    3.117132] omap-gpmc 50000000.gpmc: GPMC revision 6.0
[    3.122416] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
[    3.130037] gpio gpiochip4: (omap-gpmc): added GPIO chardev (254:4)
[    3.130610] gpiochip_setup_dev: registered GPIOs 510 to 511 on device: gpiochip4 (omap-gpmc)
[    3.132625] gpmc_read_settings_dt: page/burst-length set but not used!
 cat /proc/iomem
......
50000000-50001fff : gpmc@50000000
......

When the uio_module_drv is loaded, it generates the device for the external memory. So I can open the device and map the memory.

[   37.570012] uio_module_drv soc:dpram_mem: registered misc device dpram_mem

However when I ran my application I get this:

/dev/mem opened.
Memory mapped at address 0xb6f94000.
/dev/dpram_mem opened.
Memory mapped at address 0xb67e5000.
Bus error

/dev/mem is used to map the GPMC registers and it works fine. The dpram_mem is used to map the 0x08000000 memory range, where the external memory should be located, but however I get a bus error and the application crashes.

I followed these topics and documentation as reference:

https://e2e.ti.com/support/processors/f/791/t/512464

https://e2e.ti.com/support/processors/f/791/p/315716/1510538

https://e2e.ti.com/support/processors/f/791/p/793386/2960137

https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt

Any hint with this issue?

Many thanks in advance,

Alvaro

  • Alvaro,

    Alvaro Arizaga said:
    /dev/mem is used to map the GPMC registers and it works fine

    What exactly do you mean by this?

    Alvaro Arizaga said:
    /dev/dpram_mem opened.
    Memory mapped at address 0xb67e5000.

    Do you see any activity on the external bus (oscilloscope) when trying to access the memory through your dpram_mem node?

    Regards, Andreas

  • Hi Andreas,

    I mean that I can map the GPMC Registers at the address 0x50000000 and read and write them, so that part of the device tree is ok.

    I am working from home due to the Covid19 so I don't have an oscilloscope here at home... I guess that my device tree is not ok but I don't know what exactly is wrong.

    Kind regards,

    Alvaro 

  • Hi Alvaro,

    Alvaro Arizaga said:
    I mean that I can map the GPMC Registers at the address 0x50000000 and read and write them, so that part of the device tree is ok.

    You mean you update your DTS definition for dpram_mem to point to the range at 0x50000000, and you can then access those through /dev/dpram_mem, this way validating your basic memory mapping/access scheme short of talking to the external device, right?

    Alvaro Arizaga said:
    I am working from home due to the Covid19 so I don't have an oscilloscope here at home...

    Understood.

    Do you have a similar project in your company you could perhaps compare the setup against?

    Can you determine more closely where exactly the "Bus error" is caused? Which userspace call, and then where in the Kernel?

    Then, if you have access to JTAG, you could see if you can access the memory this way after it got mapped.

    Also there is a related thread to that showing a complete solution similar to what you implemented, not sure if you have seen this one yet. Can you please review in detail how the setup is done and try the approach chosen there.

    https://e2e.ti.com/support/processors/f/791/t/770569

    Regards, Andreas