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.

Linux/PROCESSOR-SDK-AM335X: GPIO OE register read issue

Part Number: PROCESSOR-SDK-AM335X

Tool/software: Linux

Working on a beagle bone black derivative board with dual ethernet PHY.  ETH_RESET is driven by GPIO_0_29, which is set as OUTPUT in u-boot.  u-boot also properly resets PHY.

Also have
&gpio0 {
        pinctrl-names = "default";
        pinctrl-0 = <&gpio0_pins_default>;
        status = "okay";

        eth_reset {
                gpio-hog;
                gpios = <29 GPIO_ACTIVE_HIGH>;
                output-low;
                line-name = "ETH_RESET";
        };
};

However, this is processed AFTER drivers/net/ethernet/ti/davinci_mdio.c, and some kernel code is flipping all GPIO pins back to INPUT.  Current board has PULLUP on GPIO_0_29, which causes PHY to stay in reset when driver is looking for PHYs.  So trying to track down where this is done in kernel.  Added following to init/main.c to verify GPIO_0_29 is still in correct state from u-boot.

    void __iomem *gpio0_base = NULL;
    void __iomem *gpio3_base = NULL;

    gpio0_base = ioremap( (unsigned int) 0x44E07000, 4096);
    gpio3_base = ioremap( (unsigned int) 0x481AE000, 4096);

    pr_notice("start_kernel: gpio0_oe=%0x, gpio3_oe=%0x, gpio0_dataout=%0x, gpio3_dataout=%0x\n",
              __raw_readl(gpio0_base + 0x134), __raw_readl(gpio3_base + 0x134),
              __raw_readl(gpio0_base + 0x13C), __raw_readl(gpio3_base + 0x13C));

    iounmap(gpio0_base);
    iounmap(gpio3_base);

This works fine, but when I duplicate this code elsewhere, for instance, drivers/pinctrl/core.c, I will get stuck at
Starting kernel ...

Any ideas why?

 

  • Hi,

    It is possible that the linux kernel did not set the gpio functional clock, and this is blocking the read of gpio0_oe, gpio3_oe, gpio0_dataout & gpio3_dataout registers.

    Can you share your boot log, so we can inspect it?

    Best Regards,
    Yordan
  • The code snippet I included works just fine when I inserted it in init/main.c in the start_kernel() method.  See highlighted text in log below.  i.e. GPIO modules are enabled (clocks are running, etc).
    My question is, should this code snippet work when for example I duplicate this code snippet in drivers/pinctrl/core.c?  Because when I do this, when u-boot is starting up the kernel, the system just hangs.
    i.e. the last log I get is

    ...
    Starting kernel...

    Working log below:

    U-Boot SPL 2017.01 (Nov 12 2017 - 20:15:29)
    Trying to boot from MMC1MMC partition switch failed
    *** Warning - MMC partition switch failed, using default environment

    reading u-boot.img
    reading u-boot.img


    U-Boot 2017.01 (Nov 12 2017 - 20:15:29 +0000)

    CPU : AM335X-GP rev 2.1
    I2C: ready
    DRAM: 512 MiB
    MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
    Card did not respond to voltage select!
    *** Warning - MMC init failed, using default environment

    <ethaddr> not set. Validating first E-fuse MAC
    Net: cpsw, usb_ether
    Press SPACE to abort autoboot in 2 seconds
    switch to partitions #0, OK
    mmc0 is current device
    SD/MMC found on device 0
    reading boot.scr
    ** Unable to read file boot.scr **
    reading uEnv.txt
    ** Unable to read file uEnv.txt **
    switch to partitions #0, OK
    mmc0 is current device
    Scanning mmc 0:1...
    switch to partitions #0, OK
    mmc0 is current device
    SD/MMC found on device 0
    5430432 bytes read in 368 ms (14.1 MiB/s)
    34386 bytes read in 28 ms (1.2 MiB/s)
    ## Flattened Device Tree blob at 88000000
    Booting using the fdt blob at 0x88000000
    Loading Device Tree to 8fff4000, end 8ffff651 ... OK

    Starting kernel ...

    Booting Linux on physical CPU 0x0
    Initializing cgroup subsys cpuset
    Initializing cgroup subsys cpu
    Initializing cgroup subsys cpuacct
    Linux version 4.4.87-yocto-standard (oe-user@oe-host) (gcc version 6.3.0 (GCC) ) #1 PREEMPT Thu Nov 16 04:03:17 UTC 2017
    CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
    CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
    Machine model: TI AM335x BeagleBone DNI
    cma: Reserved 16 MiB at 0x9e800000
    Memory policy: Data cache writeback
    CPU: All CPU(s) started in SVC mode.
    AM335X ES2.1 (sgx neon )
    Built 1 zonelists in Zone order, mobility grouping on. Total pages: 129664
    Kernel command line: console=ttyO0,115200n8 root=PARTUUID=08ffb82b-02 rw rootfstype=ext4 rootwait
    PID hash table entries: 2048 (order: 1, 8192 bytes)
    Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
    Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
    Memory: 488928K/523264K available (8214K kernel code, 706K rwdata, 2528K rodata, 560K init, 633K bss, 17952K reserved, 16384K cma-reserved, 0K highmem)
    Virtual kernel memory layout:
    vector : 0xffff0000 - 0xffff1000 ( 4 kB)
    fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
    vmalloc : 0xe0800000 - 0xff800000 ( 496 MB)
    lowmem : 0xc0000000 - 0xe0000000 ( 512 MB)
    pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
    modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
    .text : 0xc0008000 - 0xc0a85c3c (10744 kB)
    .init : 0xc0a86000 - 0xc0b12000 ( 560 kB)
    .data : 0xc0b12000 - 0xc0bc295c ( 707 kB)
    .bss : 0xc0bc5000 - 0xc0c63650 ( 634 kB)
    SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
    Preemptible hierarchical RCU implementation.
    Build-time adjustment of leaf fanout to 32.
    NR_IRQS:16 nr_irqs:16 16
    IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts
    OMAP clockevent source: timer2 at 24000000 Hz
    sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
    clocksource: timer1: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
    OMAP clocksource: timer1 at 24000000 Hz
    clocksource_probe: no matching clocksources found
    Console: colour dummy device 80x30
    Calibrating delay loop... 996.14 BogoMIPS (lpj=4980736)
    pid_max: default: 32768 minimum: 301
    Security Framework initialized
    Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
    Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
    Initializing cgroup subsys io
    Initializing cgroup subsys memory
    Initializing cgroup subsys devices
    Initializing cgroup subsys freezer
    Initializing cgroup subsys net_cls
    Initializing cgroup subsys debug
    start_kernel: gpio0_oe=dfffffff, gpio3_oe=fffffffb, gpio0_dataout=0, gpio3_dataout=4
    CPU: Testing write buffer coherency: ok
    ftrace: allocating 27666 entries in 82 pages
    Setting up static identity map for 0x80008200 - 0x80008258
    devtmpfs: initialized
    VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
    omap_hwmod: tptc0 using broken dt data from edma
    omap_hwmod: tptc1 using broken dt data from edma
    omap_hwmod: tptc2 using broken dt data from edma
    omap_hwmod: debugss: _wait_target_disable failed
    clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
    futex hash table entries: 256 (order: -1, 3072 bytes)
    xor: measuring software checksum speed
    arm4regs : 1202.000 MB/sec
    8regs : 892.800 MB/sec
    32regs : 1156.800 MB/sec
    xor: using function: arm4regs (1202.000 MB/sec)
    pinctrl core: initialized pinctrl subsystem
    NET: Registered protocol family 16
    DMA: preallocated 256 KiB pool for atomic coherent allocations
    cpuidle: using governor ladder
    cpuidle: using governor menu
    omap_gpio 44e07000.gpio: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/gpio0_pins_default, deferring probe
    omap_gpio 4804c000.gpio: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/gpio1_pins_default, deferring probe
    omap_gpio 481ac000.gpio: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/gpio2_pins_default, deferring probe
    omap_gpio 481ae000.gpio: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/gpio3_pins_default, deferring probe
    hw-breakpoint: debug architecture 0x4 unsupported.
    raid6: int32x1 gen() 209 MB/s
    raid6: int32x1 xor() 142 MB/s
    raid6: int32x2 gen() 226 MB/s
    raid6: int32x2 xor() 162 MB/s
    raid6: int32x4 gen() 209 MB/s
    raid6: int32x4 xor() 136 MB/s
    raid6: int32x8 gen() 175 MB/s
    raid6: int32x8 xor() 118 MB/s
    raid6: using algorithm int32x2 gen() 226 MB/s
    raid6: .... xor() 162 MB/s, rmw enabled
    raid6: using intx1 recovery algorithm
    edma 49000000.edma: Legacy memcpy is enabled, things might not work
    edma 49000000.edma: TI EDMA DMA engine driver
    SCSI subsystem initialized
    usbcore: registered new interface driver usbfs
    usbcore: registered new interface driver hub
    usbcore: registered new device driver usb
    omap_i2c 44e0b000.i2c: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/pinmux_i2c0_pins, deferring probe
    omap_i2c 4819c000.i2c: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/pinmux_i2c2_pins, deferring probe
    clocksource: Switched to clocksource timer1
    NET: Registered protocol family 2
    TCP established hash table entries: 4096 (order: 2, 16384 bytes)
    TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
    TCP: Hash tables configured (established 4096 bind 4096)
    UDP hash table entries: 256 (order: 0, 4096 bytes)
    UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
    NET: Registered protocol family 1
    RPC: Registered named UNIX socket transport module.
    RPC: Registered udp transport module.
    RPC: Registered tcp transport module.
    RPC: Registered tcp NFSv4.1 backchannel transport module.
    hw perfevents: enabled with armv7_cortex_a8 PMU driver, 5 counters available
    NFS: Registering the id_resolver key type
    Key type id_resolver registered
    Key type id_legacy registered
    Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
    io scheduler noop registered
    io scheduler deadline registered
    io scheduler cfq registered (default)
    pinctrl-single 44e10800.pinmux: 142 pins at pa f9e10800 size 568
    omap_uart 44e09000.serial: no wakeirq for uart0
    44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 27, base_baud = 3000000) is a OMAP UART0
    console [ttyO0] enabled
    [drm] Initialized drm 1.1.0 20060810
    brd: module loaded
    mtdoops: mtd device (mtddev=name/number) must be supplied
    davinci_mdio 4a101000.mdio: davinci mdio revision 1.6
    davinci_mdio 4a101000.mdio: no live phy, scanning all
    davinci_mdio: probe of 4a101000.mdio failed with error -5
    cpsw 4a100000.ethernet: Detected MACID = 38:d2:69:55:43:02
    cpsw 4a100000.ethernet: cpsw: Detected MACID = 38:d2:69:55:43:04
    usbcore: registered new interface driver kaweth

  • Just for clarity, here is the code snippet again.  Should this work everywhere in kernel space?

        void __iomem *gpio0_base = NULL;
        void __iomem *gpio3_base = NULL;
    
        gpio0_base = ioremap( (unsigned int) 0x44E07000, 4096);
        gpio3_base = ioremap( (unsigned int) 0x481AE000, 4096);
    
        pr_notice("start_kernel: gpio0_oe=%0x, gpio3_oe=%0x, gpio0_dataout=%0x, gpio3_dataout=%0x\n",
                  __raw_readl(gpio0_base + 0x134), __raw_readl(gpio3_base + 0x134),
                  __raw_readl(gpio0_base + 0x13C), __raw_readl(gpio3_base + 0x13C));
    
        iounmap(gpio0_base);
        iounmap(gpio3_base);
    
    

  • Hi,

    This code should work fine from kernel space. However, as I said, if you try to read the gpio address space, before the gpio clocks have been enabled by the kernel, this will fail with bus error. What I'd suggest s to read the relevant PRCM registers (CM_PER_GPIO3_CLKCTRL & CM_WKUP_GPIO0_CLKCTRL) to see if the GPIO functional clock is enabled and then if gpio clock is running perform the read on OE & DATAOUT registers.

    Best Regards,
    Yordan
  • Thanks for the pointers Yordan.  The GPIO modules were disabled.  Enabled them, and was able to access the GPIO registers.