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.

AM5708: GPIO state changes at kernel start

Part Number: AM5708
Other Parts Discussed in Thread: SYSCONFIG

Hi,

We noticed the following on our design:

we mux GPMC_A7 (0x145C CTRL_CORE_PAD_GPMC_A7) to mode 14 in U-Boot (or MLO) and drive output to low. With a scope we can see this happens just as expecting.

In Linux we don't use this pin (not that we are aware of) in any dts, or in any driver. but the pin is back to tristate or input during boot of linux.

we explicitly don't use any device tree pinmuxing for any pins in linux since there is a GPIO glitch errata (i869 IO Glitches Can Occur When Changing IO Settings) 

We expected it to maintain its value programmed by U-Boot and cannot find the reason why it is changed during Linux.

Components used:
u-boot ti-sdk-2016.06
linux: ti-sdk_03.03.00.04

  • Hi Stef,

    Please provide me the value of register CTRL_CORE_PAD_GPMC_A7/0x4A00345C in these two points:

    1. in u-boot prompt, get the value with "md" command
    2. in user space prompt, get the value with "devmem2" command

    Regards,
    Pavel
  • Hi Pavel,
    1. In U-Boot (Measured with scope: Line is low as i expected):
    => md 0x4A00345C 1
    4a00345c: 0000000e ....
    =>

    2. root@device:~# devmem2 0x4A00345C
    /dev/mem opened.
    Memory mapped at address 0xb6f89000.
    Read at address 0x4A00345C (0xb6f8945c): 0x0000000E

    Seems Identical

    Regards,
    Stef
  • Stef,

    So CTRL_CORE_PAD_GPMC_A7 register value is not overwritten in linux kernel DTS files, as it keep its value same as u-boot.

    From what I understand you have:
    1. Set the proper value in u-boot stage, then you have K1 pin output to low as expected
    2. During kernel boot up stage, you have K1 pin, tristate or input, which is unexpected to you. Please clarify how do you verify that this pin is input or tristate during kernel boot up?
    3. After kernel boot up finished, you have K1 pin output to low as expected?

    Please also make GPIO1 registers dump in u-boot and kernel and compare the registers values for differences.

    Regards,
    Pavel
  • Hi Pavel,

    Correct:

    1. Pin K1 output is low as expected

    U-boot code:

    unsigned pin = 29 ; //gpio1 29 (0*32 + 29)

    gpio_request(pin, "pin");

    gpio_direction_output(pin, 0);    //force low

    2. During kernel bootup ( i validate using scope) i see the following :

          - we have the K1 connected with a 10K pull up (to 3v3) to a input of another module.
          - during bootup transition of u-boot to kernel we see the level jump from 0.0V -> ~2,3 V once the kernel starts booting.
          - our assumption is that the pin is not driving low anymore at this point

    3. K1 output is still at ~2,3V after boot of kernel is finished (in the kernel / user space we don't use the pin anymore). we hoped U-Boot settings of this register would be enough.

    GPIO registers (0x4AE1 0000) dump:

    U-Boot: 

    => md 0x4AE10000 1
    4ae10000: 50602001 . `P

    Kernel Space:

    root@device: ~# devmem2 0x4AE10000

    /dev/mem opened.
    Memory mapped at address 0xb6fa1000.
    Read at address 0x4AE10000 (0xb6fa1000): 0x50602001

  • Sorry, only the first bytes are a bit short:
    I guessed the relevant registers, if you want dumps of others please let me know

    U-Boot:
    //SYSCONFIG (Offset 0010)
    => md 0x4AE10010 1
    4ae10010: 00000000 ....
    //SYSSTATUS (Offset 114)
    => md 0x4AE10114 1
    4ae10114: 00000001 ....

    Kernel:
    //SYSCONFIG (Offset 0010)
    devmem2 0x4AE10010
    /dev/mem opened.
    Memory mapped at address 0xb6fc3000.
    Read at address 0x4AE10010 (0xb6fc3010): 0x0000001D
    //SYSSTATUS (Offset 114)
    devmem2 0x4AE10114
    /dev/mem opened.
    Memory mapped at address 0xb6f20000.
    Read at address 0x4AE10114 (0xb6f20114): 0x00000001
  • Stef,

    What I need is:

    GPIO_CTRL/0x4AE10130
    GPIO_OE/0x4AE10134
    GPIO_DATAOUT/0x4AE1013C

    These 3 registers are setup in GPIO kernel driver:

    linux-4.9.59/drivers/gpio/gpio-omap.c

    Check also if SW reset has been performed to GPIO module in bit GPIO_SYSCONFIG[1] SOFTRESET, this is done in below file and function:

    linux-4.9.59/arch/arm/mach-omap2/omap_hwmod.c

    static int _set_softreset(struct omap_hwmod *oh, u32 *v)



    Regards,
    Pavel

  • U-Boot Registers:

    GPIO_CTRL/0x4AE10130
    GPIO_OE/0x4AE10134
    GPIO_DATAOUT/0x4AE1013C
    GPIO_SYSCONFIG/0x4AE10010

    => md 0x4AE10130 1
    4ae10130: 00000002 ....
    => md 0x4AE10134 1
    4ae10134: dfffffff ....
    => md 0x4AE1013C 1
    4ae1013c: 00000000 ....
    => md 0x4AE10010 1
    4ae10010: 00000000 ....

    Linux Registers

    devmem2 0x4AE10010
    /dev/mem opened.
    Memory mapped at address 0xb6f8a000.
    Read at address 0x4AE10010 (0xb6f8a010): 0x0000001D

    devmem2 0x4AE10130
    /dev/mem opened.
    Memory mapped at address 0xb6f8a000.
    Read at address 0x4AE10130 (0xb6f8a130): 0x00000002

    devmem2 0x4AE10134
    /dev/mem opened.
    Memory mapped at address 0xb6fbf000.
    Read at address 0x4AE10134 (0xb6fbf134): 0xFF7FFFFF

    devmem2 0x4AE1013C
    /dev/mem opened.
    Memory mapped at address 0xb6f2f000.
    Read at address 0x4AE1013C (0xb6f2f13c): 0x00800000

    SW Reset has been performed for  (Remapped addresses):

    [ 0.345014] SB: --- SoftReset: 0xdf0bfeb4

    [ 0.345533] SB: --- SoftReset: 0xdf0bfeec

  • stef boerrigter said:
    GPIO_OE/0x4AE10134
    GPIO_DATAOUT/0x4AE1013C

    stef boerrigter said:
    => md 0x4AE10134 1
    4ae10134: dfffffff ....
    => md 0x4AE1013C 1
    4ae1013c: 00000000 ....

    stef boerrigter said:

    devmem2 0x4AE10134
    /dev/mem opened.
    Memory mapped at address 0xb6fbf000.
    Read at address 0x4AE10134 (0xb6fbf134): 0xFF7FFFFF

    devmem2 0x4AE1013C
    /dev/mem opened.
    Memory mapped at address 0xb6f2f000.
    Read at address 0x4AE1013C (0xb6f2f13c): 0x00800000

    Seems that linux kernel overwrite u-boot GPIO1 register settings, kernel set gpio1_23 as output and set this output to high (1).

    Do you use gpio1_23 pin in your custom board? Trace the linux kernel GPIO driver and check why is set gpio1_23 settings.

    Regards,
    Pavel

  • its nog 1_23 that is the issue (that is the backlight enable and is done in kernel (devicetree)
    its 1_29 that is the issue (Set in U-Boot to Output_LOW ) an in Kernel we don't do anything (explicit with it).
  • What I mean in my previous post is:

    You program gpio1_23 in kernel, thus overwrite gpio1_29 uboot settings.

    Please share all your kernel (devicetree) gpio1_23 settings, and I will have a look.

    Regards,
    Pavel
  • Linux Gpio 1_23:
    DTS LCD Backlight Enable:

    lcd_bl: backlight {
    compatible = "pwm-backlight";
    enable-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
    power-supply = <&vdd_3v3>;
    pwms-names = "backlight";
    pwms = <&ehrpwm2 0 50000 0>;
    brightness-levels = <0 2 38 74 110 146 182 218 255>;
    default-brightness-level = <8>;
    };

    does this also re-sets all other GPIO's on bank 1??
  • stef boerrigter said:
    Linux Gpio 1_23:
    DTS LCD Backlight Enable:

    lcd_bl: backlight {
    compatible = "pwm-backlight";
    enable-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
    power-supply = <&vdd_3v3>;
    pwms-names = "backlight";
    pwms = <&ehrpwm2 0 50000 0>;
    brightness-levels = <0 2 38 74 110 146 182 218 255>;
    default-brightness-level = <8>;
    };

    does this also re-sets all other GPIO's on bank 1??

    That is all you have done regarding gpio1_23 pin in linux kenel and DTS files, correct?

    Your gpio1_23 kernel settings looks correct and I do not think these settings overwrite the gpio1_29 uboot settings. But we can verify this. Please remove these gpio1_23 kernel/DTS settings and check again gpio1_29 kernel registers settings. Is there any difference?

    Regards,
    Pavel

  • i see a difference after removing the display nodes from devicetree (and therefore gpio1_23 is removed):

    devmem2 0x4AE10010
    /dev/mem opened.
    Memory mapped at address 0xb6ffa000.
    Read at address 0x4AE10010 (0xb6ffa010): 0x0000001D
    devmem2 0x4AE10130
    /dev/mem opened.
    Memory mapped at address 0xb6f8f000.
    Read at address 0x4AE10130 (0xb6f8f130): 0x00000002
    devmem2 0x4AE10134
    /dev/mem opened.
    Memory mapped at address 0xb6fb6000.
    Read at address 0x4AE10134 (0xb6fb6134): 0xFFFFFFFF
    devmem2 0x4AE1013C
    /dev/mem opened.
    Memory mapped at address 0xb6f64000.
    Read at address 0x4AE1013C (0xb6f6413c): 0x00000000
  • Stef,

    OK, you can bring back your gpio1_23 kernel/dts settings, they do not impact gpio1_29 uboot settings.

    The problem comes by the fact that linux kernel automatically reset (softreset) GPIO1 module (and rest of GPIO modules also) at kernel load time. You should remove the 'SYSC_HAS_SOFTRESET' flag in the below file:

    linux-kernel/arch/arm/mach-omap2/omap_hwmod_7xx_data.c

    static struct omap_hwmod_class_sysconfig dra7xx_gpio_sysc = {
    .rev_offs = 0x0000,
    .sysc_offs = 0x0010,
    .syss_offs = 0x0114,
    .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
    SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
    SYSS_HAS_RESET_STATUS),
    .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
    SIDLE_SMART_WKUP),
    .sysc_fields = &omap_hwmod_sysc_type1,
    };

    See the below e2e threads for more info:

    e2e.ti.com/.../519202
    e2e.ti.com/.../291377

    If that doesn't work, you can also add flag 'HWMOD_INIT_NO_RESET', check below e2e for details:

    e2e.ti.com/.../2052522

    Regards,
    Pavel
  • Thanks Pavel!

    Removing the SYSC_HAS_SOFTRESET did the trick!

    Thanks for your help
  • This also explains why we did not see this on the AM3 (since this is DRA7xx specific).