Part Number: PROCESSOR-SDK-AM64X
I am working with the AM64x-GP-EVM eval board.
I have been successfully using the board for a few weeks with my own Arago-built kernel.
I am now trying to work with the GPIO pins. What I am finding is that the GPIO1 module is not initializing properly. I have spent hours sleuthing the device tree, the source code for the davinci-gpio driver, trying out different device tree tweaks, and so on. I can't find anything wrong.
The symptom is that, during boot, the GPIO1 module fails to initialize, with this error in dmesg:
[ 2.402358] davinci_gpio 601000.gpio: IRQ index 2 not found
[ 2.408034] davinci_gpio 601000.gpio: IRQ not populated, err = -6
And if you look at the contents of /sys/devices/platform/bus@f4000 for the two devices, GPIO0 looks normal, but GPIO1 does not:
root@am64xx-evm:/sys/devices/platform/bus@f4000# ls 600000.gpio/
driver driver_override gpio gpiochip1 modalias of_node power subsystem uevent
root@am64xx-evm:/sys/devices/platform/bus@f4000# ls 601000.gpio/
driver_override modalias of_node power subsystem uevent
I've dug into the device tree, into the tech ref (Tables 9-79, 9-86) to look at interrupt numbers, all sorts of things like that. I cannot find anything wrong.
I did dig far enough to learn that, down in the device driver, the failure is occurring when the call to platform_get_irq(pdev, num) fails on num=2. (Out of a range of 0..5, representing the six GPIO banked IRQ's which get mapped by GPIOMUX_INTRTR0 through to GICSS0 SPI inputs.)
I started to try to dig deeper to figure out where the pdev is getting populated with values, but presumably that's from the device tree, which looks fine.
Here is the relevant part of k3-am64-main.dsti. I've dug deep into the bindings documentation for both the GPIO device and the interrupt controller, and it all looks fine to me. There are no other devices
main_gpio_intr: interrupt-controller0 {
compatible = "ti,sci-intr";
ti,intr-trigger-type = <1>;
interrupt-controller;
#interrupt-cells = <1>;
ti,sci = <&dmsc>;
ti,sci-dev-id = <3>;
ti,interrupt-ranges = <0 32 16>;
};
main_gpio0: gpio@600000 {
compatible = "ti,am64-gpio", "ti,keystone-gpio";
reg = <0x0 0x00600000 0x0 0x100>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&main_gpio_intr>;
interrupts = <190>, <191>, <192>,
<193>, <194>, <195>;
interrupt-controller;
#interrupt-cells = <2>;
ti,ngpio = <87>;
ti,davinci-gpio-unbanked = <0>;
power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 77 0>;
clock-names = "gpio";
};
main_gpio1: gpio@601000 {
compatible = "ti,am64-gpio", "ti,keystone-gpio";
reg = <0x0 0x00601000 0x0 0x100>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&main_gpio_intr>;
interrupts = <180>, <181>, <182>,
<183>, <184>, <185>;
interrupt-controller;
#interrupt-cells = <2>;
ti,ngpio = <88>;
ti,davinci-gpio-unbanked = <0>;
power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 78 0>;
clock-names = "gpio";
};
The only thing I've found that's not completely symmetric about the way the devices are declared in shift line in the declaration of cbass_main in k3-am64.dtsi. Rather than declaring two devices of size 0x100 at 0x600000 and 0x601000, it appears to simply "lazily" cram them into a single large range declaration. So if there actually were something meaningful for GPIO0 in the range 0x600100-0x600FFF, then GPIO1 would not be picking up the same stuff starting at 0x601100.
ranges = <0x00 0x000f4000 0x00 0x000f4000 0x00 0x000002e4>, /* PINCTRL */
<0x00 0x00600000 0x00 0x00600000 0x00 0x00001100>, /* GPIO */
<0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* Timesync router */
Note that I don't actually use any of the GPIO1 interrupts - I just want to do reads and writes. But the interrupt stuff is causing it to not initialize.
For the moment, for my initial tests, I am working around this by using one of the mere *two* GPIOs on GPIO0 that are not allocated for special functions on the EVM board. But we'd really like to be able to use the rest of the device, of course.
Thanks for any tips,
Brad