serial: clk: bcm2835: Strange effects when using aux-uart in console
Martin Sperl
kernel at martin.sperl.org
Fri Feb 12 09:34:27 PST 2016
> On 12.02.2016, at 12:56, Martin Sperl <martin at sperl.org> wrote:
>
>
>> On 11.02.2016, at 18:55, Stefan Wahren <stefan.wahren at i2se.com> wrote:
>> I think the reason for this behavior can be found in the uart-pl011 driver which
>> plays with the clocks.
>>
> I will look into the why and share what I find…
Well - just disabling CONFIG_SERIAL_AMBA_PL011_CONSOLE
in config still results in the early-boot getting
dumped to ttyAMA0 and the same behaviour
when starting getty on that tty: crash…
Similarly when compiled amba-pl011 as a module:
* strangely the boot messages still goes to ttyAMA
- this may be something that uboot sets up?
Maybe: earlycon-arm-semihost using SWI?
* loading the module works fine:
[ 65.458754] Serial: AMBA PL011 UART driver
[ 65.547204] 20201000.uart: ttyAMA0 at MMIO 0x20201000 (irq = 81, base_baud = 0) is a PL011 rev2
* using ttyAMA0 (via getty) crashes the system.
[ 73.560708] uart-pl011 20201000.uart: no DMA platform data
[ 73.667150] bcm2835-clk 20101000.cprman: plld: couldn't lock PLL
[ 73.673305] ------------[ cut here ]------------
[ 73.678039] WARNING: CPU: 0 PID: 2377 at drivers/clk/clk.c:680 clk_core_disable+0x34/0xf0()
[ 73.687320] ---[ end trace e38a11a59bfd67ea ]---
[ 73.692196] ------------[ cut here ]------------
[ 73.696973] WARNING: CPU: 0 PID: 2377 at drivers/clk/clk.c:575 clk_core_unprepare+0x34/0x110()
[ 73.706709] ---[ end trace e38a11a59bfd67eb ]---
Now having instrumented clock and amba-pl011 with debug prints I get:
Boot sequence (logged to ttyAMA0 without a driver / earlycon0):
Uncompressing Linux... done, booting the kernel.
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.5.0-rc3+ (root at raspcm.intern.sperl.org) (gcc version 4.7.2 (Debian 4.7.2-5+rpi1) ) #91 Fri Feb 12 13:12:31 UTC 2016
[ 0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[ 0.000000] Machine model: Raspberry Pi Model B+
[ 0.000000] bootconsole [earlycon0] enabled
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 113792
[ 0.000000] Kernel command line: earlyprintk consoleblank=0 console=ttyS0,115200n1 root=/dev/mmcblk0p2 rootwait
[ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Memory: 445500K/458752K available (5768K kernel code, 418K rwdata, 1840K rodata, 420K init, 697K bss, 13252K reserved, 0K cma-reserved)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[ 0.000000] vmalloc : 0xdc800000 - 0xff800000 ( 560 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xdc000000 ( 448 MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB)
[ 0.000000] .text : 0xc0008000 - 0xc0776394 (7609 kB)
[ 0.000000] .init : 0xc0777000 - 0xc07e0000 ( 420 kB)
[ 0.000000] .data : 0xc07e0000 - 0xc0848960 ( 419 kB)
[ 0.000000] .bss : 0xc0848960 - 0xc08f6f68 ( 698 kB)
[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] NR_IRQS:16 nr_irqs:16 16
[ 0.000030] sched_clock: 32 bits at 1000kHz, resolution 1000ns, wraps every 2147483647500ns
[ 0.008591] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275 ns
[ 0.018176] bcm2835: system timer (irq = 27)
[ 0.023023] Console: colour dummy device 80x30
[ 0.027636] Calibrating delay loop... 697.95 BogoMIPS (lpj=3489792)
[ 0.094228] pid_max: default: 32768 minimum: 301
[ 0.099359] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.106197] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.114578] CPU: Testing write buffer coherency: ok
[ 0.119730] ftrace: allocating 19776 entries in 58 pages
[ 0.247172] Setting up static identity map for 0x8220 - 0x8258
[ 0.257687] devtmpfs: initialized
[ 0.267447] VFP support v0.3: implementor 41 architecture 1 part 20 variant b rev 5
[ 0.275647] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.286277] pinctrl core: initialized pinctrl subsystem
[ 0.293168] NET: Registered protocol family 16
[ 0.298438] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.313885] No ATAGs?
[ 0.316051] hw-breakpoint: found 6 breakpoint and 1 watchpoint registers.
[ 0.323345] hw-breakpoint: maximum watchpoint size is 4 bytes.
…
[ 0.366218] clocksource: Switched to clocksource timer
[ 0.424382] simple-framebuffer 5e887000.framebuffer: framebuffer at 0x5e887000, 0x36c600 bytes, mapped to 0xdcc00000
[ 0.435245] simple-framebuffer 5e887000.framebuffer: format=r5g6b5, mode=1824x984x16, linelength=3648
[ 0.482137] Console: switching to colour frame buffer device 228x61
[ 0.524351] simple-framebuffer 5e887000.framebuffer: fb0: simplefb registered
!
…
[ 0.702577] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[ 0.711152] bcm2835-aux-uart 20215040.serial: could not get clk: -517
…
[ 1.962031] usbhid: USB HID core driver
[ 1.966329] bcm2835-clk 20101000.cprman: bcm2835_pll_get_rate - plla
[ 1.972879] bcm2835-clk 20101000.cprman: bcm2835_pll_get_rate - pllb
[ 1.979474] bcm2835-clk 20101000.cprman: bcm2835_pll_get_rate - pllc
[ 1.986019] bcm2835-clk 20101000.cprman: bcm2835_pll_get_rate - plld
[ 1.992608] bcm2835-clk 20101000.cprman: bcm2835_pll_get_rate - pllh
[ 1.999375] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - timer
[ 2.006434] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - timer
[ 2.013468] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - otp
[ 2.020318] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - otp
[ 2.027000] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - tsens
[ 2.033959] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - tsens
[ 2.040831] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - vpu
[ 2.047679] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - vpu
[ 2.054431] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - v3d
[ 2.061271] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - v3d
[ 2.067966] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - isp
[ 2.074749] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - isp
[ 2.081445] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - h264
[ 2.088358] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - h264
[ 2.095120] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - sdram
[ 2.102122] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - sdram
[ 2.109230] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - uart
[ 2.116108] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - uart
[ 2.122907] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - vec
[ 2.129734] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - vec
[ 2.136449] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - hsm
[ 2.143234] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - hsm
[ 2.149939] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - emmc
[ 2.156853] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - emmc
[ 2.163615] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - pwm
[ 2.170448] bcm2835-clk 20101000.cprman: bcm2835_clock_get_rate - pwm
[ 2.177114] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - pwm
[ 2.184451] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - pwm
[ 2.191391] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - pwm
[ 2.198247] bcm2835-clk 20101000.cprman: bcm2835_clock_get_parent - pwm
…
[ 2.259033] bcm2835-clk 20101000.cprman: bcm2835_pll_on - pllc
[ 2.265485] console [ttyS0] disabled
[ 2.269377] 20215040.serial: ttyS0 at MMIO 0x0 (irq = 53, base_baud = 3122499
9) is a 16550
[ 2.277931] console [ttyS0] enabled
[ 2.285083] bootconsole [earlycon0] disabled
Boot sequence after earlycon0 to ttyS0:
[ 2.277931] console [ttyS0] enabled
[ 2.285083] bootconsole [earlycon0] disabled
[ 2.294646] bcm2835-clk 20101000.cprman: bcm2835_clock_on - emmc
[ 2.306321] usb 1-1: new high-speed USB device number 2 using dwc2
[ 2.346289] mmc0: SDHCI controller on 20300000.sdhci [20300000.sdhci] using PIO
[ 2.361549] Waiting for root device /dev/mmcblk0p2...
[ 2.409495] mmc0: MAN_BKOPS_EN bit is not set
[ 2.415026] mmc0: new MMC card at address 0001
[ 2.420585] mmcblk0: mmc0:0001 4FEACB 3.64 GiB
[ 2.425646] mmcblk0boot0: mmc0:0001 4FEACB partition 1 4.00 MiB
[ 2.432466] mmcblk0boot1: mmc0:0001 4FEACB partition 2 4.00 MiB
[ 2.439214] mmcblk0rpmb: mmc0:0001 4FEACB partition 3 512 KiB
[ 2.447959] mmcblk0: p1 p2
[ 2.477939] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
…
getty - Serial open on ttyS0, network up
Loading module:
root at raspcm:~# modprobe amba-pl011
[ 59.238155] Serial: AMBA PL011 UART driver
[ 59.245951] 20201000.uart: ttyAMA0 at MMIO 0x20201000 (irq = 81, base_baud =2
root at raspcm:~#
And when starting getty ttyAMA0:
root at raspcm:~# /sbin/getty -a root -L ttyAMA0 115200 vt100
[ 67.998916] pl011_startup - start
[ 68.002326] pl011_hwinit - prepare-enable
[ 68.006434] bcm2835-clk 20101000.cprman: bcm2835_pll_on - plld
[ 68.012524] bcm2835-clk 20101000.cprman: bcm2835_clock_on - uart
[ 68.018733] pl011_hwinit - prepare-enable - 0
[ 68.024790] uart-pl011 20201000.uart: no DMA platform data
[ 68.030693] pl011_startup - exit
[ 68.038628] pl011_shutdown - start
[ 68.042152] pl011_shutdown - disable_unprepare
[ 68.046715] bcm2835-clk 20101000.cprman: bcm2835_clock_off - uart
[ 68.053040] bcm2835-clk 20101000.cprman: bcm2835_clock_wait_busy - uart
[ 68.059818] bcm2835-clk 20101000.cprman: bcm2835_pll_off - plld
[ 68.065856] pl011_shutdown - exit
Note that I have now a hdmi display connected and the display
stops showing the framebuffer but the display goes off.
So it seems as if pl011_shutdown gets called for some reason,
which turns off the uart clock and as a consequence also the
plld gets shut down (probably ref-counting.
I wonder why we have the VPU as a secondary clock in the dt -
amba-pll11 does not reference it anywhere.
When adding a return to bcm2835_pll_off it looks like this:
root at raspcm:~# /sbin/getty -a root -L ttyAMA0 115200 vt100
[ 73.862152] pl011_startup - start
[ 73.865558] pl011_hwinit - prepare-enable
[ 73.869886] bcm2835-clk 20101000.cprman: bcm2835_pll_on - plld
[ 73.875854] bcm2835-clk 20101000.cprman: bcm2835_clock_on - uart
[ 73.882044] pl011_hwinit - prepare-enable - ret = 0
[ 73.888126] uart-pl011 20201000.uart: no DMA platform data
[ 73.893757] pl011_startup - exit
[ 73.901495] pl011_shutdown - start
[ 73.905034] pl011_shutdown - disable_unprepare
[ 73.909742] bcm2835-clk 20101000.cprman: bcm2835_clock_off - uart
[ 73.915967] bcm2835-clk 20101000.cprman: bcm2835_clock_wait_busy - uart
[ 73.922775] bcm2835-clk 20101000.cprman: bcm2835_pll_off - plld
[ 73.928844] pl011_shutdown - exit
[ 73.934152] pl011_startup - start
[ 73.937617] pl011_hwinit - prepare-enable
[ 73.941726] bcm2835-clk 20101000.cprman: bcm2835_pll_on - plld
[ 73.947738] bcm2835-clk 20101000.cprman: bcm2835_clock_on - uart
[ 73.953865] pl011_hwinit - prepare-enable - ret = 0
[ 73.959776] pl011_startup - exit
The ttyAMA0 console does not work, hdmi display blinks,
but the network works...
When removing the pll_on/off from the pll_ops I have a similar effect
but in this case PLL is not touched at all:
root at raspcm:~# /sbin/getty -a root -L ttyAMA0 115200 vt100
[ 83.345055] pl011_startup - start
[ 83.348580] pl011_hwinit - prepare-enable
[ 83.352725] bcm2835-clk 20101000.cprman: bcm2835_clock_on - uart
[ 83.358910] pl011_hwinit - prepare-enable - 0
[ 83.365083] uart-pl011 20201000.uart: no DMA platform data
[ 83.370790] pl011_startup - exit
[ 83.378653] pl011_shutdown - start
[ 83.382176] pl011_shutdown - disable_unprepare
[ 83.386873] bcm2835-clk 20101000.cprman: bcm2835_clock_off - uart
[ 83.393097] bcm2835-clk 20101000.cprman: bcm2835_clock_wait_busy - uart
[ 83.399888] pl011_shutdown - exit
[ 83.405164] pl011_startup - start
[ 83.408652] pl011_hwinit - prepare-enable
[ 83.412771] bcm2835-clk 20101000.cprman: bcm2835_clock_on - uart
[ 83.418952] pl011_hwinit - prepare-enable - 0
[ 83.423665] pl011_startup - exit
The system continues, but the UART still is not working and the
HDMI-Display is flashing only (but with a certain pattern on the
display: totally blue, then some wait, then a black horizontal bar
finally a full dark screen flash - that happens in a 3-4 second
cycle.
As if there is something else that requires the UART clock running
- maybe in the firmware?
Even making the uart clock a VPU clock does not help:
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 015e687..4856657 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -758,6 +761,7 @@ static const struct bcm2835_clock_data bcm2835_clock_uart_da
.div_reg = CM_UARTDIV,
.int_bits = 10,
.frac_bits = 12,
+ .is_vpu_clock = true,
};
/* HDMI state machine */
This produces the following debug messages:
[ 56.409818] pl011_startup - start
[ 56.413225] pl011_hwinit - prepare-enable
[ 56.417443] pl011_hwinit - prepare-enable - ret = 0
[ 56.423297] uart-pl011 20201000.uart: no DMA platform data
[ 56.428989] pl011_startup - exit
[ 56.435485] pl011_shutdown - start
[ 56.440337] pl011_shutdown - disable_unprepare
[ 56.444913] pl011_shutdown - exit
[ 56.449762] pl011_startup - start
[ 56.453165] pl011_hwinit - prepare-enable
[ 56.457371] pl011_hwinit - prepare-enable - ret = 0
[ 56.462175] pl011_startup - exit
The screen is still blinking and UART does not work.
Maybe the driver is not able to handle the “remapping”
of registers to a different range and is touching ram
used by the FW?
The only solution that I found is using fixed clocks
in the device-tree (which is not what we intended:
/ {
clk_uart0: clock at 3 {
compatible = "fixed-clock";
reg = <3>;
#clock-cells = <0>;
clock-output-names = "uart0_pclk";
clock-frequency = <3000000>;
};
clk_apb_p: clock at 4 {
compatible = "fixed-clock";
reg = <4>;
#clock-cells = <0>;
clock-output-names = "apb_pclk";
clock-frequency = <126000000>;
};
};
&uart0 {
clocks = <&clk_uart0 &clk_apb_p>;
};
(so I have ruled out that the amba-pl011 writes to
the wrong addresses).
So as far as I can tell it is only clock related
and when the new clock-framework is used it fails...
Martin
More information about the linux-arm-kernel
mailing list