New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raspberry Pi 3 model B Serial console does not use correct baudrate #553

Closed
josn0 opened this Issue Mar 1, 2016 · 80 comments

Comments

Projects
None yet
@josn0

josn0 commented Mar 1, 2016

Serial console seems to give a incorrect baudrate. Overriding frequencies to previous Raspberries in /boot/config.txt helps: everything works as normal. After some iterations, I found that setting 'gpu_freq=300' solves the problem, although that is the default setting on a rpi 3. Probably someone reads that value to initialise the baudrate generator, and uses the old default 'gpu_freq=250' if the value is not set. This is almost certainly done in the closed-source /boot/start*.elf files. All those files do contain the texts 'config.tst' as well as 'gpu_freq'. Please repair this issue..

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 2, 2016

Contributor

An issue with gpu_freq/core_freq handling was discovered and fixed in an rpi-update release made on the 29th, but that hasn't made its way to a Raspbian build yet. You can run "sudo rpi-update" to get the latest firmware, wait for a Raspbian update, or use a workaround: set the frequency using core_freq instead of gpu_freq.

Contributor

pelwell commented Mar 2, 2016

An issue with gpu_freq/core_freq handling was discovered and fixed in an rpi-update release made on the 29th, but that hasn't made its way to a Raspbian build yet. You can run "sudo rpi-update" to get the latest firmware, wait for a Raspbian update, or use a workaround: set the frequency using core_freq instead of gpu_freq.

@josn0

This comment has been minimized.

Show comment
Hide comment
@josn0

josn0 Mar 2, 2016

Thanks for the response. I tried a rpi-update; it did not help. Then tried adding 'core_freq=300'; that did not help either. Put back my 'gpu_freq=300', which again solved the problem. So it seems the issue is not fixed correctly.

josn0 commented Mar 2, 2016

Thanks for the response. I tried a rpi-update; it did not help. Then tried adding 'core_freq=300'; that did not help either. Put back my 'gpu_freq=300', which again solved the problem. So it seems the issue is not fixed correctly.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 3, 2016

Contributor

It looks like there might be a clocking issue - we will investigate.

Contributor

pelwell commented Mar 3, 2016

It looks like there might be a clocking issue - we will investigate.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 4, 2016

Contributor

My Pi3 serial port (ttyS0) has been rock solid with force_turbo=1 and a 2.5A power supply. I think you may be suffering from under-voltage. The gpu_freq=300 setting will have the effect of scaling back all of the non-ARM clocks, which will save power.

Contributor

pelwell commented Mar 4, 2016

My Pi3 serial port (ttyS0) has been rock solid with force_turbo=1 and a 2.5A power supply. I think you may be suffering from under-voltage. The gpu_freq=300 setting will have the effect of scaling back all of the non-ARM clocks, which will save power.

@TheDJVG

This comment has been minimized.

Show comment
Hide comment
@TheDJVG

TheDJVG Mar 4, 2016

@pelwell, I don't get if this issue will be resolved or not. I'm using a 2.5A power supply and force_turbo which makes it work again but I think some firmware needs to be updated to make it work the right way (without force_turbo) or am I missing something?

TheDJVG commented Mar 4, 2016

@pelwell, I don't get if this issue will be resolved or not. I'm using a 2.5A power supply and force_turbo which makes it work again but I think some firmware needs to be updated to make it work the right way (without force_turbo) or am I missing something?

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 5, 2016

Contributor

See my answer in this thread:
RPi-Distro/repo#22

Contributor

pelwell commented Mar 5, 2016

See my answer in this thread:
RPi-Distro/repo#22

@gejanssen

This comment has been minimized.

Show comment
Hide comment
@gejanssen

gejanssen Mar 5, 2016

have the same problem. unfortunately the gpu_freq setting does not work.
Also the new firmware of today works partly.
booting is garbled and after that the login prompt is showing.
21���B�b�
�#)
��2l��L`~Bn�
�nn
�b�nb�Llbr���2nbBbl
Raspbian GNU/Linux 8 rpib3 ttyS0

rpib3 login: gej

now running version 30fe8178d61c1ff9bc168edaafdbcb101aa6245e (05-02)

have the same problem. unfortunately the gpu_freq setting does not work.
Also the new firmware of today works partly.
booting is garbled and after that the login prompt is showing.
21���B�b�
�#)
��2l��L`~Bn�
�nn
�b�nb�Llbr���2nbBbl
Raspbian GNU/Linux 8 rpib3 ttyS0

rpib3 login: gej

now running version 30fe8178d61c1ff9bc168edaafdbcb101aa6245e (05-02)

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 5, 2016

Contributor

If the red power LED flickers then your power supply isn't sufficient. You need a good 2.5A supply. There are extra current demands at boot time, with WiFi and Bluetooth starting and increased parallelism thanks to systemd.

Contributor

pelwell commented Mar 5, 2016

If the red power LED flickers then your power supply isn't sufficient. You need a good 2.5A supply. There are extra current demands at boot time, with WiFi and Bluetooth starting and increased parallelism thanks to systemd.

@gejanssen

This comment has been minimized.

Show comment
Hide comment
@gejanssen

gejanssen Mar 5, 2016

@pelwell The powersupply used is a 5A powersupply and the red led is not flickering.
Also found on another posting that if I use
force_turbo=1
arm_freq=1200
core_freq=250
and fixing the cpu frequence,
gej@rpib3:~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
1200000
gej@rpib3:~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
1200000
gej@rpib3:~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
1200000
the serial works perfectly
also the bluethooth works
gej@rpib3:$ sudo hcitool scan
Scanning ...
10:3B:59:F5:65:6A GT-I9305N
gej@rpib3:
$

@pelwell The powersupply used is a 5A powersupply and the red led is not flickering.
Also found on another posting that if I use
force_turbo=1
arm_freq=1200
core_freq=250
and fixing the cpu frequence,
gej@rpib3:~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
1200000
gej@rpib3:~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
1200000
gej@rpib3:~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
1200000
the serial works perfectly
also the bluethooth works
gej@rpib3:$ sudo hcitool scan
Scanning ...
10:3B:59:F5:65:6A GT-I9305N
gej@rpib3:
$

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 5, 2016

Contributor

It's the core_freq=250 that makes the difference - if your maximum core freq is the same as the minimum core freq then it never changes.

Contributor

pelwell commented Mar 5, 2016

It's the core_freq=250 that makes the difference - if your maximum core freq is the same as the minimum core freq then it never changes.

@TheDJVG

This comment has been minimized.

Show comment
Hide comment
@TheDJVG

TheDJVG Mar 5, 2016

@pelwell Maybe I just don't get it but I'm trying to make it clear. I'm now using a power supply that can deliver up to 12A of current but I still need force_turbo to make the serial output work (= readable). Peak current is around 2.3A at boot. Is the need of force_turbo a workaround for an unresolved bug in the firmware or what is causing this? I don't have this problem with all the other models, that's why I'm asking and trying to understand.

TheDJVG commented Mar 5, 2016

@pelwell Maybe I just don't get it but I'm trying to make it clear. I'm now using a power supply that can deliver up to 12A of current but I still need force_turbo to make the serial output work (= readable). Peak current is around 2.3A at boot. Is the need of force_turbo a workaround for an unresolved bug in the firmware or what is causing this? I don't have this problem with all the other models, that's why I'm asking and trying to understand.

@gejanssen

This comment has been minimized.

Show comment
Hide comment
@gejanssen

gejanssen Mar 5, 2016

I can confirm that only the core_freq=250 works.
gej@rpib3:$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
1200000
gej@rpib3:
$
gej@rpib3:$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
600000
gej@rpib3:
$ sudo hcitool scan
Scanning ...
C8:29:2A:1B:68:74 LGE DTV BCM20702A1
gej@rpib3:~$
At full load an minimal load the bluetooth and serial works.

I can confirm that only the core_freq=250 works.
gej@rpib3:$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
1200000
gej@rpib3:
$
gej@rpib3:$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
600000
gej@rpib3:
$ sudo hcitool scan
Scanning ...
C8:29:2A:1B:68:74 LGE DTV BCM20702A1
gej@rpib3:~$
At full load an minimal load the bluetooth and serial works.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 5, 2016

Contributor

The answers are in the other thread (RPi-Distro/repo#22), but the short version is that the clock is also reduced if the chip is getting too hot. By setting the core VPU clock to the minimum value (250) you avoid this problem.

Contributor

pelwell commented Mar 5, 2016

The answers are in the other thread (RPi-Distro/repo#22), but the short version is that the clock is also reduced if the chip is getting too hot. By setting the core VPU clock to the minimum value (250) you avoid this problem.

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 6, 2016

I pulled down the latest firmware, and I still see some issues re: serial console. Let me know if I should file this as a separate bug. I think it's within the realm of this bug though.

On the RPi 0/1/2, whatever is loaded as kernel.img can immediately start writing to the UART's TX FIFO, and that data will appear on the GPIO header pin at the expected baud rate.

However, on the RPi 3, the following steps are required before this works. I believe the firmware should provide the same guarantees/initial-conditions on all system, so none of these steps should be necessary:

  1. Configure GPIO14/15 pinmux to be ALT5 to select the mini UART.
  2. Write to the AUX block's ENABLES register to enable the mini UART.
  3. Configure the mini UART for 8-bits (it defaults to 7).
  4. Program the UART baud-rate divider.

For reference, see the most recent commit at https://github.com/swarren/u-boot/commits/rpi_dev.

(For the RPi 0/1/2, we do actually do step 4 too. However, Eric Anholt has submitted a patch to skip this so that U-Boot honors whatever the firmware programmed, which means it follows whatever the user requested via config.txt, which makes for a nicer user experience).

One particularly nice benefit of the firmware doing this is that step 4 can be skipped, which means U-Boot wouldn't have to query the core clock rate from the firmware in order to calculate the divider. (Assuming the core clock rate hasn't changed, but there really isn't anything we can do about that.)

swarren commented Mar 6, 2016

I pulled down the latest firmware, and I still see some issues re: serial console. Let me know if I should file this as a separate bug. I think it's within the realm of this bug though.

On the RPi 0/1/2, whatever is loaded as kernel.img can immediately start writing to the UART's TX FIFO, and that data will appear on the GPIO header pin at the expected baud rate.

However, on the RPi 3, the following steps are required before this works. I believe the firmware should provide the same guarantees/initial-conditions on all system, so none of these steps should be necessary:

  1. Configure GPIO14/15 pinmux to be ALT5 to select the mini UART.
  2. Write to the AUX block's ENABLES register to enable the mini UART.
  3. Configure the mini UART for 8-bits (it defaults to 7).
  4. Program the UART baud-rate divider.

For reference, see the most recent commit at https://github.com/swarren/u-boot/commits/rpi_dev.

(For the RPi 0/1/2, we do actually do step 4 too. However, Eric Anholt has submitted a patch to skip this so that U-Boot honors whatever the firmware programmed, which means it follows whatever the user requested via config.txt, which makes for a nicer user experience).

One particularly nice benefit of the firmware doing this is that step 4 can be skipped, which means U-Boot wouldn't have to query the core clock rate from the firmware in order to calculate the divider. (Assuming the core clock rate hasn't changed, but there really isn't anything we can do about that.)

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 6, 2016

Contributor

Before (considering) undertaking this work, I'd like to clarify something.

I had considered the fact that the firmware leaves uart0 mapped to GPIOs 14 and 15 to be anomalous - it seems to go against the DT philosophy of only enabling that which is requested in the DTB. Are you saying that having a UART enabled at boot is the preferred behaviour?

Contributor

pelwell commented Mar 6, 2016

Before (considering) undertaking this work, I'd like to clarify something.

I had considered the fact that the firmware leaves uart0 mapped to GPIOs 14 and 15 to be anomalous - it seems to go against the DT philosophy of only enabling that which is requested in the DTB. Are you saying that having a UART enabled at boot is the preferred behaviour?

swarren referenced this issue in swarren/u-boot Mar 6, 2016

WIP: RPi 3 (32-bit) port
FIXME:
- split up into n patches
- describe

Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 6, 2016

DT isn't meant to prescribe a certain HW configuration; it's simply there to represent the actual HW setup. So, whether the GPIO pins are "pre-muxed" to the UART or not is entirely unrelated to DT.

Most pins on the GPIO expansion header are set up as GPIO in by default solely because there's no way to know ahead of time what the user will use those pins for. This means that if the RPi was to actively drive those pins to a particular output state at boot, then one/both of the following could happen:

  • The FW might just happen to choose a default output value that was inconsistent with the user's desire for how their external circuit interpreted any input value on that signal. This could cause behavioral problems in the external circuit.
  • The external circuit might actually use the signal as an input to the RPi, and hence both circuits would drive the signal at the same time, potentially to different values, which would lead to electrical issues.

The only way to prevent those potential issues is to have the RPi not actively drive the signals by default, until explicitly instructed (via HAT EEPROM content for example) how those signals will be used (or should be configured).

However, some of the GPIO expansion header signals have a known dedicated purpose. For example, two of the pins are used for the HAT EEPROM I2C bus. For pins with such a dedicated purpose, it is entirely safe to configure them at boot, since it's known which are input vs. output etc.

I would argue that the console UART pins fall into this category; they have a dedicated purpose. I don't sure if the HAT specification defines those pins with a fixed purpose, but the Raspbian images certainly use those pins for serial console by default without explicit acknowledgement-from/interaction-with the end-user, so at the very least they have a de-facto dedicated purpose.

Even if the user were to connect the UART pins to some other external device (i.e. not a host's serial port) in an external circuit, they'd have to do so with the full knowledge that a standard RPi SW stack would use the TX pin as an output, and toggle it by default with serial data, and hence they would have to design their external circuit to be compatible with this fact.

My expectation is that the FW would configure all fixed-purpose pins at boot but obviously leave all the undedicated pins at the SoC default (GPIO in w/ pull). IIUC, this is exactly what it does on RPi 0/1/2.

At least, that's the reasoning NVIDIA applied when choosing the default pinmux setup for the Jetson TX1 Developer Kit's GPIO expansion header, which happens to have the same pinout as the RPi 40-pin connector.

BTW, what do config.txt's init_uart_baud and init_uart_clock options do on the RPi 3? Do they still affect the PL01x UART? I suppose that is backwards compatible in a sense, but if you consider those options to semanticalyl be related to configuration of the console (rather than configuration of a particular UART HW module), then they should configure the mini UART.

swarren commented Mar 6, 2016

DT isn't meant to prescribe a certain HW configuration; it's simply there to represent the actual HW setup. So, whether the GPIO pins are "pre-muxed" to the UART or not is entirely unrelated to DT.

Most pins on the GPIO expansion header are set up as GPIO in by default solely because there's no way to know ahead of time what the user will use those pins for. This means that if the RPi was to actively drive those pins to a particular output state at boot, then one/both of the following could happen:

  • The FW might just happen to choose a default output value that was inconsistent with the user's desire for how their external circuit interpreted any input value on that signal. This could cause behavioral problems in the external circuit.
  • The external circuit might actually use the signal as an input to the RPi, and hence both circuits would drive the signal at the same time, potentially to different values, which would lead to electrical issues.

The only way to prevent those potential issues is to have the RPi not actively drive the signals by default, until explicitly instructed (via HAT EEPROM content for example) how those signals will be used (or should be configured).

However, some of the GPIO expansion header signals have a known dedicated purpose. For example, two of the pins are used for the HAT EEPROM I2C bus. For pins with such a dedicated purpose, it is entirely safe to configure them at boot, since it's known which are input vs. output etc.

I would argue that the console UART pins fall into this category; they have a dedicated purpose. I don't sure if the HAT specification defines those pins with a fixed purpose, but the Raspbian images certainly use those pins for serial console by default without explicit acknowledgement-from/interaction-with the end-user, so at the very least they have a de-facto dedicated purpose.

Even if the user were to connect the UART pins to some other external device (i.e. not a host's serial port) in an external circuit, they'd have to do so with the full knowledge that a standard RPi SW stack would use the TX pin as an output, and toggle it by default with serial data, and hence they would have to design their external circuit to be compatible with this fact.

My expectation is that the FW would configure all fixed-purpose pins at boot but obviously leave all the undedicated pins at the SoC default (GPIO in w/ pull). IIUC, this is exactly what it does on RPi 0/1/2.

At least, that's the reasoning NVIDIA applied when choosing the default pinmux setup for the Jetson TX1 Developer Kit's GPIO expansion header, which happens to have the same pinout as the RPi 40-pin connector.

BTW, what do config.txt's init_uart_baud and init_uart_clock options do on the RPi 3? Do they still affect the PL01x UART? I suppose that is backwards compatible in a sense, but if you consider those options to semanticalyl be related to configuration of the console (rather than configuration of a particular UART HW module), then they should configure the mini UART.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 7, 2016

Contributor

Thanks for the clarification.

Currently both init_uart_clock and init_uart_baud still apply to the PL01x. init_uart_clock is meaningless for the mini-UART since the source clock is the core clock, but I think it would be reasonable to pre-configure the mini-UART using the value in init_uart_baud.

Contributor

pelwell commented Mar 7, 2016

Thanks for the clarification.

Currently both init_uart_clock and init_uart_baud still apply to the PL01x. init_uart_clock is meaningless for the mini-UART since the source clock is the core clock, but I think it would be reasonable to pre-configure the mini-UART using the value in init_uart_baud.

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 15, 2016

pelwell, did you get a chance to think about this? I'd like to get the U-Boot support for RPi 3 upstream ASAP (i.e. within the next ~3 weeks, before the current merge window closes), and it'd be nice not to have to include all the extra pinmux and UART setup code if at all possible. Thanks!

swarren commented Mar 15, 2016

pelwell, did you get a chance to think about this? I'd like to get the U-Boot support for RPi 3 upstream ASAP (i.e. within the next ~3 weeks, before the current merge window closes), and it'd be nice not to have to include all the extra pinmux and UART setup code if at all possible. Thanks!

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 15, 2016

Contributor

I'm optimistic I can look at this on Thursday, but probably not before.

Contributor

pelwell commented Mar 15, 2016

I'm optimistic I can look at this on Thursday, but probably not before.

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 16, 2016

Hmm. The existence of pi3-disable-bt-overlay.dts and pi3-miniuart-bt-overlay.dts will complicated this rather. How is code other than the DT-aware Linux kernel (e.g. consider U-Boot, bare metal code, RiscOS?) meant to know whether the mini UART or the regular UART is supposed to be used? I'm confused why there are overlays to promote all kinds of different HW setups rather than just standardizing on one working configuration.

swarren commented Mar 16, 2016

Hmm. The existence of pi3-disable-bt-overlay.dts and pi3-miniuart-bt-overlay.dts will complicated this rather. How is code other than the DT-aware Linux kernel (e.g. consider U-Boot, bare metal code, RiscOS?) meant to know whether the mini UART or the regular UART is supposed to be used? I'm confused why there are overlays to promote all kinds of different HW setups rather than just standardizing on one working configuration.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 17, 2016

Contributor

The overlays use DT aliases (serial0 and serial1) to indicate which UART is the primary in the sense that it has the console. The firmware already reads these aliases, using them to rewrite cmdline.txt replacing serial0 and serial1 with the appropriate UART for the platform, so it should simply be a matter of writing some initialisation code for the mini UART and calling it as necessary.

Some of our users rely on the more capable (larger FIFOs, 8+1 bits) UART for their own applications and are prepared to accept lower BT performance (or forego it completely). Other OSs are free to implement any policy they like - forcing a particular hardware configuration, for example - but as long as Linux has the flexibility why wouldn't we give users the choice?

Contributor

pelwell commented Mar 17, 2016

The overlays use DT aliases (serial0 and serial1) to indicate which UART is the primary in the sense that it has the console. The firmware already reads these aliases, using them to rewrite cmdline.txt replacing serial0 and serial1 with the appropriate UART for the platform, so it should simply be a matter of writing some initialisation code for the mini UART and calling it as necessary.

Some of our users rely on the more capable (larger FIFOs, 8+1 bits) UART for their own applications and are prepared to accept lower BT performance (or forego it completely). Other OSs are free to implement any policy they like - forcing a particular hardware configuration, for example - but as long as Linux has the flexibility why wouldn't we give users the choice?

@popcornmix

This comment has been minimized.

Show comment
Hide comment
@popcornmix

popcornmix Mar 18, 2016

Contributor

@swarren there is a test firmware here:
https://dl.dropboxusercontent.com/u/3669512/temp/firmware_uart.zip

It includes this from @pelwell

This is my patch to fulfil Stephen Warren's request of initialising the
mini-UART on Pi3. It is smart enough to read the DT after the overlays
have been applied, and only initialise the mini-UART when the UARTs are
swapped.

It will appear in next official firmware update (probably in the next few days).

Contributor

popcornmix commented Mar 18, 2016

@swarren there is a test firmware here:
https://dl.dropboxusercontent.com/u/3669512/temp/firmware_uart.zip

It includes this from @pelwell

This is my patch to fulfil Stephen Warren's request of initialising the
mini-UART on Pi3. It is smart enough to read the DT after the overlays
have been applied, and only initialise the mini-UART when the UARTs are
swapped.

It will appear in next official firmware update (probably in the next few days).

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 19, 2016

@popcornmix I'm afraid that firmware doesn't work for me; I just get a rainbow square on HDMI and nothing else. Switching back to the latest files in firmware.git/boot/ works fine, and I changed nothing else either changing to or from the FW in that .zip file.

swarren commented Mar 19, 2016

@popcornmix I'm afraid that firmware doesn't work for me; I just get a rainbow square on HDMI and nothing else. Switching back to the latest files in firmware.git/boot/ works fine, and I changed nothing else either changing to or from the FW in that .zip file.

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 19, 2016

The situation is a bit more complicated with that firmware than simply "doesn't work":

On the RPi3, in either 32- or 64-bit mode, with U-Boot hard-coded to use the mini UART, everything works, with or without U-Boot initializing the pinmux or baud rate of the mini UART. That last part is good since it means the enhancements work.

On the RPi 3 with U-Boot hard-coded to use the PL01x (and without any DT overlay specified in config.txt to request the FW/kernel do the same), I see the HDMI rainbow. I guess when the ARM touches the unclocked/reset PL01x, there's some system-/bus-level error which triggers the rainbow?

On the RPi2, with U-Boot hard-coded to use either the PL01x or mini UART, I see the HDMI rainbow.

On an RPi1 B+, with U-Boot hard-coded to use a PL01x, I see the HDMI rainbow.

On an RPi1 B+, with U-Boot hard-coded to use the mini UART, it seems like the system is rapidly repeatedly rebooting without fully achieving HDMI sync, since my HDMI monitor keeps repeating the "no signal" display in a way that I think means sync is appearing and disappearing. Or, perhaps the Pi is simply hanging with no HDMI output at all.

So I guess that firmware was tested on the RPi3 but not elsewhere, where the DT defaults or alias values for the UART selection are different?

swarren commented Mar 19, 2016

The situation is a bit more complicated with that firmware than simply "doesn't work":

On the RPi3, in either 32- or 64-bit mode, with U-Boot hard-coded to use the mini UART, everything works, with or without U-Boot initializing the pinmux or baud rate of the mini UART. That last part is good since it means the enhancements work.

On the RPi 3 with U-Boot hard-coded to use the PL01x (and without any DT overlay specified in config.txt to request the FW/kernel do the same), I see the HDMI rainbow. I guess when the ARM touches the unclocked/reset PL01x, there's some system-/bus-level error which triggers the rainbow?

On the RPi2, with U-Boot hard-coded to use either the PL01x or mini UART, I see the HDMI rainbow.

On an RPi1 B+, with U-Boot hard-coded to use a PL01x, I see the HDMI rainbow.

On an RPi1 B+, with U-Boot hard-coded to use the mini UART, it seems like the system is rapidly repeatedly rebooting without fully achieving HDMI sync, since my HDMI monitor keeps repeating the "no signal" display in a way that I think means sync is appearing and disappearing. Or, perhaps the Pi is simply hanging with no HDMI output at all.

So I guess that firmware was tested on the RPi3 but not elsewhere, where the DT defaults or alias values for the UART selection are different?

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 19, 2016

Sorry, I think the issues I saw with the RPi2 and RPi1 B+ were because I'd forgotten to disable the config.txt options I used to make AArch64 booting work on the RPi3. I've now seen both of those boards work with the new firmware. But now I'm not convinced the new FW is actually enabling the mini UART in the aux module, setting its baud rate, and setting up the pinmux, although I swear this did work before. I think I'm going to give up on testing this tonight and come back some other time.

swarren commented Mar 19, 2016

Sorry, I think the issues I saw with the RPi2 and RPi1 B+ were because I'd forgotten to disable the config.txt options I used to make AArch64 booting work on the RPi3. I've now seen both of those boards work with the new firmware. But now I'm not convinced the new FW is actually enabling the mini UART in the aux module, setting its baud rate, and setting up the pinmux, although I swear this did work before. I think I'm going to give up on testing this tonight and come back some other time.

popcornmix added a commit that referenced this issue Mar 19, 2016

kernel: Bump to 4.1.20
kernel: BCM270X_DT: Switch Compute Module to MMC

kernel: pwm overlays: Params must have in-overlay targets

kernel: BCM270X_DT: Build and document the wittypi overlay

firmware: di_adv: Avoid setting undefined flags in first deinterlaced frame

firmware: di_adv: acquire user and main when we are releasing every frame
See: #546

firmware: arm_loader: Initialise the mini-UART when appropriate
See: #553

firmware: vchi_services: Increase number of connections to services from 3 to 8
See: #567

firmware: audio_decode: Don't report format changes when passthough is enabled
See: xbianonpi/xbian#807

popcornmix added a commit to Hexxeh/rpi-firmware that referenced this issue Mar 19, 2016

kernel: Bump to 4.1.20
kernel: BCM270X_DT: Switch Compute Module to MMC

kernel: pwm overlays: Params must have in-overlay targets

kernel: BCM270X_DT: Build and document the wittypi overlay

firmware: di_adv: Avoid setting undefined flags in first deinterlaced frame

firmware: di_adv: acquire user and main when we are releasing every frame
See: raspberrypi/firmware#546

firmware: arm_loader: Initialise the mini-UART when appropriate
See: raspberrypi/firmware#553

firmware: vchi_services: Increase number of connections to services from 3 to 8
See: raspberrypi/firmware#567

firmware: audio_decode: Don't report format changes when passthough is enabled
See: xbianonpi/xbian#807
@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 20, 2016

@pelwell, can you please confirm exactly what the latest firmware is doing w.r.t. UART initialization? I was expecting the following logic in the update FW for this issue:

if (DT indicates PL01x is the console) {
do whatever the previous FW revs always used to do to initialize the PL01x
(likely: program its baud rate, enable it in UART CR reg, program pinmux to route it to GPIO header)
} else {
new code to do whatever it takes to initialize the mini UART
(likely: enable it in the AUX regs, set baud rate divider, set any enable bits in the UART regs, program pinmux to route it to GPIO header)
}

... and furthermore, the "if" block should trigger on any RPi 0/1/2, and the "else" block should trigger on the RPi 3, all assuming no overlays are loaded to select a different UART than is default in the DT files.

I've been testing on a B+ with U-Boot build configuration "rpi_1", with empty config.txt:

With FW commit c230b2b (most recent but one), I find that the PL01x is initialized by VC FW as expected. The UART works fine irrespective of whether U-Boot programs the baud rate divider or toggles the enable bits in the UART CR register.

However, with the most recent FW commit 4bf906c, I see:

  • If U-Boot does initialize the UART baud rate and CR register enable bits (the default in the current mainline code), U-Boot still runs correctly and I see its console on HDMI but I see no output on the UART, and sending data on the UART doesn't reach U-Boot. This implies the VC FW is not programming the pinmux to route the PL01x signals to the GPIO header as expected, although other problems could perhaps cause the same symptoms.
  • If I apply the patch from @anholt ("serial: pl01x: Add support for devices with the rate pre-configured.") that skips programming the PL01x baud divider or toggling the UART enable bit in the CR register, then U-Boot does not boot at all, but rather the FW draws the rainbow image on HDMI. I can't imagine why this happens. Is the rainbow drawn initially and simply left on screen if subsequent ARM SW doesn't draw over the top of it, or does the VC FW draw it in response to some error condition it detects? Perhaps accessing the PL01x FIFOs hangs the ARM CPU forever if the enable bit isn't set in the UART CR register???

This implies to me that something about the VC FW's PL01x initialization isn't happening as expected. Could you please double-check that.

I have not yet attempted to re-test all this on an RPi 2 or 3; it took me rather a long time to convince myself all of the above was true and not randomness, my imagination, or me making mistakes in the config file again:-(

swarren commented Mar 20, 2016

@pelwell, can you please confirm exactly what the latest firmware is doing w.r.t. UART initialization? I was expecting the following logic in the update FW for this issue:

if (DT indicates PL01x is the console) {
do whatever the previous FW revs always used to do to initialize the PL01x
(likely: program its baud rate, enable it in UART CR reg, program pinmux to route it to GPIO header)
} else {
new code to do whatever it takes to initialize the mini UART
(likely: enable it in the AUX regs, set baud rate divider, set any enable bits in the UART regs, program pinmux to route it to GPIO header)
}

... and furthermore, the "if" block should trigger on any RPi 0/1/2, and the "else" block should trigger on the RPi 3, all assuming no overlays are loaded to select a different UART than is default in the DT files.

I've been testing on a B+ with U-Boot build configuration "rpi_1", with empty config.txt:

With FW commit c230b2b (most recent but one), I find that the PL01x is initialized by VC FW as expected. The UART works fine irrespective of whether U-Boot programs the baud rate divider or toggles the enable bits in the UART CR register.

However, with the most recent FW commit 4bf906c, I see:

  • If U-Boot does initialize the UART baud rate and CR register enable bits (the default in the current mainline code), U-Boot still runs correctly and I see its console on HDMI but I see no output on the UART, and sending data on the UART doesn't reach U-Boot. This implies the VC FW is not programming the pinmux to route the PL01x signals to the GPIO header as expected, although other problems could perhaps cause the same symptoms.
  • If I apply the patch from @anholt ("serial: pl01x: Add support for devices with the rate pre-configured.") that skips programming the PL01x baud divider or toggling the UART enable bit in the CR register, then U-Boot does not boot at all, but rather the FW draws the rainbow image on HDMI. I can't imagine why this happens. Is the rainbow drawn initially and simply left on screen if subsequent ARM SW doesn't draw over the top of it, or does the VC FW draw it in response to some error condition it detects? Perhaps accessing the PL01x FIFOs hangs the ARM CPU forever if the enable bit isn't set in the UART CR register???

This implies to me that something about the VC FW's PL01x initialization isn't happening as expected. Could you please double-check that.

I have not yet attempted to re-test all this on an RPi 2 or 3; it took me rather a long time to convince myself all of the above was true and not randomness, my imagination, or me making mistakes in the config file again:-(

@popcornmix

This comment has been minimized.

Show comment
Hide comment
@popcornmix

popcornmix Mar 20, 2016

Contributor

Is the rainbow drawn initially and simply left on screen if subsequent ARM SW doesn't draw over the top of it, or does the VC FW draw it in response to some error condition it detects?

The former. The rainbow screen is drawn by firmware before loading the kernel. It will only disappear when the arm has configured the framebuffer through the mailbox interface. If it remains on screen it suggests the arm code didn't load and run as expected.

Contributor

popcornmix commented Mar 20, 2016

Is the rainbow drawn initially and simply left on screen if subsequent ARM SW doesn't draw over the top of it, or does the VC FW draw it in response to some error condition it detects?

The former. The rainbow screen is drawn by firmware before loading the kernel. It will only disappear when the arm has configured the framebuffer through the mailbox interface. If it remains on screen it suggests the arm code didn't load and run as expected.

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 20, 2016

The hang I mentioned in U-Boot is probably due to the UART not being enabled and hence the TX FIFO never draining, so U-Boot waits forever for space in the FIFO when printing its first message, so never gets to the code that initializes the FB. So, both my observations with the most recent FW can be explained simply by it now not performing the UART initialization.

swarren commented Mar 20, 2016

The hang I mentioned in U-Boot is probably due to the UART not being enabled and hence the TX FIFO never draining, so U-Boot waits forever for space in the FIFO when printing its first message, so never gets to the code that initializes the FB. So, both my observations with the most recent FW can be explained simply by it now not performing the UART initialization.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 20, 2016

Contributor

I will get back to you tomorrow after further testing,

Contributor

pelwell commented Mar 20, 2016

I will get back to you tomorrow after further testing,

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 21, 2016

Contributor

I have tried on a B+, a 2 and a 3, and the new firmware works as expected provided the object you are loading is marked as DT-capable and you give it a valid device tree. If you don't, and I suspect you aren't tagging the U-Boot image with the RPTL trailer with the DTOK flag set - why would you? - then it will initialise the mini-UART. This is not the intended behaviour, and will be fixed in the next release.

Contributor

pelwell commented Mar 21, 2016

I have tried on a B+, a 2 and a 3, and the new firmware works as expected provided the object you are loading is marked as DT-capable and you give it a valid device tree. If you don't, and I suspect you aren't tagging the U-Boot image with the RPTL trailer with the DTOK flag set - why would you? - then it will initialise the mini-UART. This is not the intended behaviour, and will be fixed in the next release.

@popcornmix

This comment has been minimized.

Show comment
Hide comment
@popcornmix

popcornmix Mar 21, 2016

Contributor

@swarren
If you want to test the upcoming firmware early then try:
https://dl.dropboxusercontent.com/u/3669512/temp/firmware_uart2.zip

Contributor

popcornmix commented Mar 21, 2016

@swarren
If you want to test the upcoming firmware early then try:
https://dl.dropboxusercontent.com/u/3669512/temp/firmware_uart2.zip

popcornmix added a commit that referenced this issue Mar 21, 2016

kernel: BCM270X_DT: Remove explicit claiming of UART pins
See: raspberrypi/linux@adc10c5

kernel: dwc_otg: Enable the hack for Split Interrupt transactions by default
See: raspberrypi/linux@7956536

firmware: arm_loader: Use the correct UART on non-DT systems
See: #553

firmware: vchiq_arm: Tweak the logging output

firmware: arm_loader: Add enable_uart setting

popcornmix added a commit to Hexxeh/rpi-firmware that referenced this issue Mar 21, 2016

kernel: BCM270X_DT: Remove explicit claiming of UART pins
See: raspberrypi/linux@adc10c5

kernel: dwc_otg: Enable the hack for Split Interrupt transactions by default
See: raspberrypi/linux@7956536

firmware: arm_loader: Use the correct UART on non-DT systems
See: raspberrypi/firmware#553

firmware: vchiq_arm: Tweak the logging output

firmware: arm_loader: Add enable_uart setting

popcornmix added a commit that referenced this issue Mar 21, 2016

kernel: BCM270X_DT: Remove explicit claiming of UART pins
See: raspberrypi/linux@adc10c5

firmware: arm_loader: Use the correct UART on non-DT systems
See: #553

firmware: vchiq_arm: Tweak the logging output

firmware: arm_loader: Add enable_uart setting

popcornmix added a commit to Hexxeh/rpi-firmware that referenced this issue Mar 21, 2016

kernel: BCM270X_DT: Remove explicit claiming of UART pins
See: raspberrypi/linux@adc10c5

firmware: arm_loader: Use the correct UART on non-DT systems
See: raspberrypi/firmware#553

firmware: vchiq_arm: Tweak the logging output

firmware: arm_loader: Add enable_uart setting
@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 21, 2016

Contributor

TL;DR: If you want to use the UART console during booting on a Pi3 then you need to add enable_uart=1 to config.txt. Also, you can use the normal UART pins for other functions without pinctrl getting in the way.

A new firmware package has been released to both rpi-update branches - master and next. In time it will roll out to apt-get upgrade and a full Raspbian release. It includes the following key changes:

  1. The automatic UART initialisation should work on all RPis, whether or not the loaded kernel/U-Boot is DT-capable. The choice of UART to initialise is controlled by the "serial" aliases in the DTB, as set by the pi3-miniuart-bt and pi3-disable-bt overlays, but the default is the mini-UART on Pi3 and PL011 on other models. Note that if a custom dt-blob is in use that remaps pins 14 & 15 to something other than TXD0/RXD0 (even on a Pi3 - don't hard-code TXD1/RXD1) then the pin function is left unchanged to allow, for example, the VGA666 interface to be used.

  2. A new config.txt setting has been introduced - enable_uart - the purpose of which is to control the initialisation of the UART(*). The default value varies according to the primary UART on the platform - if the PL011 is the primary UART (that used for the console and boot messages) then enable_uart defaults to 1, and if the mini-UART is the primary then it defaults to 0.

    The reason for the additional setting is that making use of the mini-UART requires the core frequency to be fixed, so setting enable_uart will limit the core to the minimum (unless force_turbo is set, since that will fix the core frequency to the maximum, provided the Pi is adequately powered and cooled). The previous default behaviour, which rendered much of the output illegible, was not useful, but we didn't want to restrict all users (even those who don't care about the UART) to the minimum core frequency. We also wanted to be able to remove the restriction when the PL011 is chosen on a Pi3, hence the need for a dedicated setting indicating the reason for the frequency limit.

  3. Now that the firmware initialises either UART as needed, it is no longer necessary to claim the UART pins (GPIOs 14 & 15) using pinctrl, so the base per-platform DTBs no longer do this. This makes it easy to use an overlay to change the pin functions without first having to change the pins claimed by one of the two UARTs.

(*) Failing to configure a UART can lead to a lock-up due to polling indefinitely for some operation to complete. Instead, always initialise the UART, but leave the pins set to be inputs (unless overridden by a custom dt-blob.bin).

Contributor

pelwell commented Mar 21, 2016

TL;DR: If you want to use the UART console during booting on a Pi3 then you need to add enable_uart=1 to config.txt. Also, you can use the normal UART pins for other functions without pinctrl getting in the way.

A new firmware package has been released to both rpi-update branches - master and next. In time it will roll out to apt-get upgrade and a full Raspbian release. It includes the following key changes:

  1. The automatic UART initialisation should work on all RPis, whether or not the loaded kernel/U-Boot is DT-capable. The choice of UART to initialise is controlled by the "serial" aliases in the DTB, as set by the pi3-miniuart-bt and pi3-disable-bt overlays, but the default is the mini-UART on Pi3 and PL011 on other models. Note that if a custom dt-blob is in use that remaps pins 14 & 15 to something other than TXD0/RXD0 (even on a Pi3 - don't hard-code TXD1/RXD1) then the pin function is left unchanged to allow, for example, the VGA666 interface to be used.

  2. A new config.txt setting has been introduced - enable_uart - the purpose of which is to control the initialisation of the UART(*). The default value varies according to the primary UART on the platform - if the PL011 is the primary UART (that used for the console and boot messages) then enable_uart defaults to 1, and if the mini-UART is the primary then it defaults to 0.

    The reason for the additional setting is that making use of the mini-UART requires the core frequency to be fixed, so setting enable_uart will limit the core to the minimum (unless force_turbo is set, since that will fix the core frequency to the maximum, provided the Pi is adequately powered and cooled). The previous default behaviour, which rendered much of the output illegible, was not useful, but we didn't want to restrict all users (even those who don't care about the UART) to the minimum core frequency. We also wanted to be able to remove the restriction when the PL011 is chosen on a Pi3, hence the need for a dedicated setting indicating the reason for the frequency limit.

  3. Now that the firmware initialises either UART as needed, it is no longer necessary to claim the UART pins (GPIOs 14 & 15) using pinctrl, so the base per-platform DTBs no longer do this. This makes it easy to use an overlay to change the pin functions without first having to change the pins claimed by one of the two UARTs.

(*) Failing to configure a UART can lead to a lock-up due to polling indefinitely for some operation to complete. Instead, always initialise the UART, but leave the pins set to be inputs (unless overridden by a custom dt-blob.bin).

@popcornmix

This comment has been minimized.

Show comment
Hide comment
Contributor

popcornmix commented Mar 24, 2016

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 24, 2016

Thanks. That simply documents that mkknlimg should be run, but not why it's needed or what effect it actually has in terms of VC FW behaviour. I was hoping for some background on the latter so I could understand the need better.

swarren commented Mar 24, 2016

Thanks. That simply documents that mkknlimg should be run, but not why it's needed or what effect it actually has in terms of VC FW behaviour. I was hoping for some background on the latter so I could understand the need better.

@popcornmix

This comment has been minimized.

Show comment
Hide comment
@popcornmix

popcornmix Mar 24, 2016

Contributor

@pelwell can tell you exactly what the effect is, but without mkknlimg and the trailer, then the firmware won't do anything to do with device tree.

Contributor

popcornmix commented Mar 24, 2016

@pelwell can tell you exactly what the effect is, but without mkknlimg and the trailer, then the firmware won't do anything to do with device tree.

@lurch

This comment has been minimized.

Show comment
Hide comment
@lurch

lurch Mar 24, 2016

It's a fairly simple script - I guess the relevant bit is https://github.com/raspberrypi/linux/blob/rpi-4.1.y/scripts/mkknlimg#L114

lurch commented Mar 24, 2016

It's a fairly simple script - I guess the relevant bit is https://github.com/raspberrypi/linux/blob/rpi-4.1.y/scripts/mkknlimg#L114

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 24, 2016

Contributor

My experience is that the ARM kernels expect either the DT address or the ATAGs address to be in r2. A kernel that is compiled without DT support will crash if you pass it the address of a DTB, hence the need for a trailer. Since then I have added extra flags such as the one to indicate that it is a bcm2835 build, which causes it to load a different DTB.

Contributor

pelwell commented Mar 24, 2016

My experience is that the ARM kernels expect either the DT address or the ATAGs address to be in r2. A kernel that is compiled without DT support will crash if you pass it the address of a DTB, hence the need for a trailer. Since then I have added extra flags such as the one to indicate that it is a bcm2835 build, which causes it to load a different DTB.

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 24, 2016

Oh yes, you're right. Reading Documentation/arm/Booting shows that r2 is either ATAGs or DT, so they can't both be passed together. The machine ID is always passed in a separate register, and I was confusing that with having separate registers for ATAGs/DT.

I'd like to argue that all the DT-/config.txt-driven HW setup by the VC FW should happen in all cases, and the image tag only affect whether an ATAG or DTB gets passed in r2. It seems at least partially reasonable to process overlays and configure HW according to them even if the overlay can't be passed to the "kernel" image; after all, the VC FW and "kernel" have split responsibility for handling different aspects of the HW/DT, and each could do its entire job irrespective of whether the other can. However, I guess the defined solution of tagging binaries already exists so changing things around probably doesn't make sense.

I wonder if I can integrate the tagging process into U-Boot's build system, without relying on external scripts, so that users don't have to add extra steps beyond "make" and "cp". That would simplify life for people (unless someone wants to use U-Boot /and/ receive ATAGs for some odd reason, but that seems reasonably unlikely; I've only seen requests to handle the FW-provided DT in U-Boot).

swarren commented Mar 24, 2016

Oh yes, you're right. Reading Documentation/arm/Booting shows that r2 is either ATAGs or DT, so they can't both be passed together. The machine ID is always passed in a separate register, and I was confusing that with having separate registers for ATAGs/DT.

I'd like to argue that all the DT-/config.txt-driven HW setup by the VC FW should happen in all cases, and the image tag only affect whether an ATAG or DTB gets passed in r2. It seems at least partially reasonable to process overlays and configure HW according to them even if the overlay can't be passed to the "kernel" image; after all, the VC FW and "kernel" have split responsibility for handling different aspects of the HW/DT, and each could do its entire job irrespective of whether the other can. However, I guess the defined solution of tagging binaries already exists so changing things around probably doesn't make sense.

I wonder if I can integrate the tagging process into U-Boot's build system, without relying on external scripts, so that users don't have to add extra steps beyond "make" and "cp". That would simplify life for people (unless someone wants to use U-Boot /and/ receive ATAGs for some odd reason, but that seems reasonably unlikely; I've only seen requests to handle the FW-provided DT in U-Boot).

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Mar 24, 2016

Contributor

I'd like to argue that all the DT-/config.txt-driven HW setup by the VC FW should happen in all cases, and the image tag only affect whether an ATAG or DTB gets passed in r2.

I've come to that conclusion myself this week.

I would have thought that pulling in one script was preferable to duplicating and maintaining a copy, but you are free to choose.

I've got limited connectivity (on a phone) this weekend, but I'll answer when I can.

Contributor

pelwell commented Mar 24, 2016

I'd like to argue that all the DT-/config.txt-driven HW setup by the VC FW should happen in all cases, and the image tag only affect whether an ATAG or DTB gets passed in r2.

I've come to that conclusion myself this week.

I would have thought that pulling in one script was preferable to duplicating and maintaining a copy, but you are free to choose.

I've got limited connectivity (on a phone) this weekend, but I'll answer when I can.

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 24, 2016

I would have thought that pulling in one script was preferable to duplicating and maintaining a copy,
but you are free to choose.

Duplicating the script (or some subset of it targeted at the set of values U-Boot will need) is probably preferable here to avoid introducing new dependencies into the U-Boot build process. While it would be fairly reasonable for active Pi users to have to add something to their PATH to build U-Boot, it isn't so reasonable to do that for non-Pi users. Many U-Boot developers (or automated systems) often build all board ports, or all board ports for a particular architecture/... and I don't want to suddenly break that capability for them, or introduce extra requirements.

swarren commented Mar 24, 2016

I would have thought that pulling in one script was preferable to duplicating and maintaining a copy,
but you are free to choose.

Duplicating the script (or some subset of it targeted at the set of values U-Boot will need) is probably preferable here to avoid introducing new dependencies into the U-Boot build process. While it would be fairly reasonable for active Pi users to have to add something to their PATH to build U-Boot, it isn't so reasonable to do that for non-Pi users. Many U-Boot developers (or automated systems) often build all board ports, or all board ports for a particular architecture/... and I don't want to suddenly break that capability for them, or introduce extra requirements.

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Mar 25, 2016

@pelwell mkknlimg does indeed allow the DT overlay to switch the RPi 3 console UART back to the PL011.

I've tested firmware.git commit 046effa "firmware: arm_loader: emmc clock depends on core clock See: #572" and found no blocking issues. From my perspective this bug can be closed, but I'll leave that up to @josn0 since they filed the bug.

I did find one quirk, but I'm not sure there's anything that can/should be done about it: On the RPi 3, if config.txt specifies enable_uart=0, or has no enable_uart line at all, then the mini UART is still enabled (so as not to hang SW that transmits data on it). However, the RX pinmux is not set up, so the UART continually receives 0x00 bytes (I didn't actually verify the value; I assume 0x00). Perhaps the RX pinmux could still be set up to avoid this, leaving enable_uart simply as a flag that the user actively wants to use the UART so clock rates should be fixed? I suppose it's quite plausible these days that a U-Boot user would only use HDMI+usbkbd, in the same way we assume a user of Linux GUI would.

My test matrix:

RPi B+
HDMI: OK
UART: OK
MMC: OK
Net: OK

RPi 2 B
HDMI: OK
UART: OK
MMC: OK
Net: OK

RPi 3 B 32-bit
MU (rpi_3_32b build):
HDMI: OK
UART: OK
MMC: OK
Net: OK
enable_uart=0 or no enable_uart stanza work: OK, with quirk
PL01x (rpi_2 build w/ DT overlay to switch UARTs):
HDMI: OK
UART: OK
MMC: OK
Net: OK

RPi 3 B 64-bit
MU (rpi_3 build):
HDMI: OK
UART: OK
MMC: OK
Net: OK

swarren commented Mar 25, 2016

@pelwell mkknlimg does indeed allow the DT overlay to switch the RPi 3 console UART back to the PL011.

I've tested firmware.git commit 046effa "firmware: arm_loader: emmc clock depends on core clock See: #572" and found no blocking issues. From my perspective this bug can be closed, but I'll leave that up to @josn0 since they filed the bug.

I did find one quirk, but I'm not sure there's anything that can/should be done about it: On the RPi 3, if config.txt specifies enable_uart=0, or has no enable_uart line at all, then the mini UART is still enabled (so as not to hang SW that transmits data on it). However, the RX pinmux is not set up, so the UART continually receives 0x00 bytes (I didn't actually verify the value; I assume 0x00). Perhaps the RX pinmux could still be set up to avoid this, leaving enable_uart simply as a flag that the user actively wants to use the UART so clock rates should be fixed? I suppose it's quite plausible these days that a U-Boot user would only use HDMI+usbkbd, in the same way we assume a user of Linux GUI would.

My test matrix:

RPi B+
HDMI: OK
UART: OK
MMC: OK
Net: OK

RPi 2 B
HDMI: OK
UART: OK
MMC: OK
Net: OK

RPi 3 B 32-bit
MU (rpi_3_32b build):
HDMI: OK
UART: OK
MMC: OK
Net: OK
enable_uart=0 or no enable_uart stanza work: OK, with quirk
PL01x (rpi_2 build w/ DT overlay to switch UARTs):
HDMI: OK
UART: OK
MMC: OK
Net: OK

RPi 3 B 64-bit
MU (rpi_3 build):
HDMI: OK
UART: OK
MMC: OK
Net: OK

@lurch

This comment has been minimized.

Show comment
Hide comment
@lurch

lurch Mar 25, 2016

From my perspective this bug can be closed

If everyone's happy about how things are now working, then IMHO this behaviour ought to be documented before this bug is closed.
I won't volunteer to do so myself as I don't understand the issue in enough detail!

lurch commented Mar 25, 2016

From my perspective this bug can be closed

If everyone's happy about how things are now working, then IMHO this behaviour ought to be documented before this bug is closed.
I won't volunteer to do so myself as I don't understand the issue in enough detail!

@sukantoghosh

This comment has been minimized.

Show comment
Hide comment
@sukantoghosh

sukantoghosh Apr 6, 2016

@pelwell @swarren How do I use mkknlimg on a non-kernel binary to ensure overlays get applied on RPI3 with my custom firmware?

$ ./linux/scripts/mkknlimg test.bin kernel7.img

  • Is this a valid kernel? In pass-through mode.

Adding --dtok and --283x does help me get rid of the error, but I don't see the overlays get applied while booting (get no prints on uart0).
However if I simply concatenate the trailer attached at the end of raspberrypi/firmware/boot/kernel7.img with my test.bin I do see the overlays getting applied.

I tested this by adding pl011 support to @swarren rpi-3-aarch64-demo. (my changes here https://github.com/sukantoghosh/rpi-3-aarch64-demo/commits/pl01x_master)

My config.txt:

enable_uart=1
kernel_old=1
arm_control=0x200
dtoverlay=pi3-disable-bt
dtoverlay=pi3-miniuart-bt

@pelwell @swarren How do I use mkknlimg on a non-kernel binary to ensure overlays get applied on RPI3 with my custom firmware?

$ ./linux/scripts/mkknlimg test.bin kernel7.img

  • Is this a valid kernel? In pass-through mode.

Adding --dtok and --283x does help me get rid of the error, but I don't see the overlays get applied while booting (get no prints on uart0).
However if I simply concatenate the trailer attached at the end of raspberrypi/firmware/boot/kernel7.img with my test.bin I do see the overlays getting applied.

I tested this by adding pl011 support to @swarren rpi-3-aarch64-demo. (my changes here https://github.com/sukantoghosh/rpi-3-aarch64-demo/commits/pl01x_master)

My config.txt:

enable_uart=1
kernel_old=1
arm_control=0x200
dtoverlay=pi3-disable-bt
dtoverlay=pi3-miniuart-bt

@swarren

This comment has been minimized.

Show comment
Hide comment
@swarren

swarren Apr 6, 2016

I've tested PL011 on the RPi3 in 32-bit mode by running the RPi2 port of U-Boot on it. I did use the --dtok option to mkknlimg, but not --283x. A bit more info is at https://github.com/swarren/u-boot/blob/rpi_dev/arch/arm/mach-bcm283x/Kconfig#L47. I only used dtoverlay=pi3-miniuart-bt in config.txt. I wonder if the pi3-disable-bt overlay causes problems applying the other one for some reason? In this U-Boot configuration, don't use kernel_old=1. Using that option might also be why my rpi-3-aarch64-demo doesn't work with PL011; I think it prevents the FW from applying DT overlays.

swarren commented Apr 6, 2016

I've tested PL011 on the RPi3 in 32-bit mode by running the RPi2 port of U-Boot on it. I did use the --dtok option to mkknlimg, but not --283x. A bit more info is at https://github.com/swarren/u-boot/blob/rpi_dev/arch/arm/mach-bcm283x/Kconfig#L47. I only used dtoverlay=pi3-miniuart-bt in config.txt. I wonder if the pi3-disable-bt overlay causes problems applying the other one for some reason? In this U-Boot configuration, don't use kernel_old=1. Using that option might also be why my rpi-3-aarch64-demo doesn't work with PL011; I think it prevents the FW from applying DT overlays.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Apr 6, 2016

Contributor

@sukantoghosh Because mkknlimg doesn't see any compatible string it recognises it is going into manual mode - you have to tell it which flags to set. You need:

  • --dtok because you are building a DT-aware kernel
  • --ddtk if you are on an rpi-4.4.y kernel or higher because it is a Dynamic Device Tree Kernel that builds *.dtbo instead of *-overlay.dtb (with a different local-fixups format)
  • --283x tells the firmware to load bcm283*.dtb rather than bcm27*.dtb, but this isn't important if you are using device_tree=my_kernel.img (for example).

You don't need pi3-disable-bt and pi3-miniuart-bt. If you want to keep BT functionality then use the miniuart variant, otherwise just disable it.

Contributor

pelwell commented Apr 6, 2016

@sukantoghosh Because mkknlimg doesn't see any compatible string it recognises it is going into manual mode - you have to tell it which flags to set. You need:

  • --dtok because you are building a DT-aware kernel
  • --ddtk if you are on an rpi-4.4.y kernel or higher because it is a Dynamic Device Tree Kernel that builds *.dtbo instead of *-overlay.dtb (with a different local-fixups format)
  • --283x tells the firmware to load bcm283*.dtb rather than bcm27*.dtb, but this isn't important if you are using device_tree=my_kernel.img (for example).

You don't need pi3-disable-bt and pi3-miniuart-bt. If you want to keep BT functionality then use the miniuart variant, otherwise just disable it.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Apr 6, 2016

Contributor

@swarren kernel_old=1 tells the firmware that your kernel image contains its own stub. The firmware will build a DT, but it has no way to tell the kernel where it is, so in the end it falls back to creating ATAGs at 0x100. You will also need to use kernel_address to indicate where the kernel should be loaded to. I agree that is is better to avoid kernel_old.

Contributor

pelwell commented Apr 6, 2016

@swarren kernel_old=1 tells the firmware that your kernel image contains its own stub. The firmware will build a DT, but it has no way to tell the kernel where it is, so in the end it falls back to creating ATAGs at 0x100. You will also need to use kernel_address to indicate where the kernel should be loaded to. I agree that is is better to avoid kernel_old.

@sukantoghosh

This comment has been minimized.

Show comment
Hide comment
@sukantoghosh

sukantoghosh Apr 6, 2016

@swarren Placing kernel_old=1 doesn't prevent application of overlays. As I mentioned, if I copy the mkknlinfo trailer from the kernel7.img from raspberrypi/firmare.git/boot/ I got the PL011 working.

@pelwell I did try only --dtok and I didn't work. BTW I see that the prebuilt kernel7.img in firmware repo has some more tags. Not sure if they are making a difference here.

$ ./mkknlimg --dtok build.txt  kerneltest.img
DT: y
283x: n

$ ./knlinfo kerneltest.img 
Kernel trailer found at 1589120/0x183f80:
  KVer: "?"
  DTOK: true
  283x: false

$ ./knlinfo kernel7.img 
Kernel trailer found at 4057000/0x3de7a8:
  KVer: "Linux version 4.1.20-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #867 SMP Wed Mar 23 20:12:32 GMT 2016"
  DTOK: true
  270X: 01000000
  283X: 00000000
  283x: false

@swarren Placing kernel_old=1 doesn't prevent application of overlays. As I mentioned, if I copy the mkknlinfo trailer from the kernel7.img from raspberrypi/firmare.git/boot/ I got the PL011 working.

@pelwell I did try only --dtok and I didn't work. BTW I see that the prebuilt kernel7.img in firmware repo has some more tags. Not sure if they are making a difference here.

$ ./mkknlimg --dtok build.txt  kerneltest.img
DT: y
283x: n

$ ./knlinfo kerneltest.img 
Kernel trailer found at 1589120/0x183f80:
  KVer: "?"
  DTOK: true
  283x: false

$ ./knlinfo kernel7.img 
Kernel trailer found at 4057000/0x3de7a8:
  KVer: "Linux version 4.1.20-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #867 SMP Wed Mar 23 20:12:32 GMT 2016"
  DTOK: true
  270X: 01000000
  283X: 00000000
  283x: false

@TheSin-

This comment has been minimized.

Show comment
Hide comment
@TheSin-

TheSin- Apr 6, 2016

Yes I see the same results with mkknlimg, I do not get

  270X: 01000000
  283X: 00000000

is there an other options or build flag I need to get the addresses? for 270x and 283x ? I'd like to get as close to foundation kernel as I can.

TheSin- commented Apr 6, 2016

Yes I see the same results with mkknlimg, I do not get

  270X: 01000000
  283X: 00000000

is there an other options or build flag I need to get the addresses? for 270x and 283x ? I'd like to get as close to foundation kernel as I can.

@lurch

This comment has been minimized.

Show comment
Hide comment
@lurch

lurch Apr 7, 2016

Looks like those extra fields are only in the 4.4 tree (and above) version of the script, not the 4.1 tree
https://github.com/raspberrypi/linux/blob/rpi-4.4.y/scripts/mkknlimg#L127

lurch commented Apr 7, 2016

Looks like those extra fields are only in the 4.4 tree (and above) version of the script, not the 4.1 tree
https://github.com/raspberrypi/linux/blob/rpi-4.4.y/scripts/mkknlimg#L127

@TheSin-

This comment has been minimized.

Show comment
Hide comment
@TheSin-

TheSin- Apr 7, 2016

those are y/n though not the same type of values, I'll run tests with the 4.4 tree today, Maybe if they are using the 4.4 version of the script on the foundation 4.1 kernels that is what happens when you use the 4.1 version of knlinfo, it doesn't know to put y or n. I'm just off to work but once I get there I'll run the 4.4 script on my kernel and check it with the 4.1 knlinfo see fi it looks the same. Thanks for the idea @lurch

TheSin- commented Apr 7, 2016

those are y/n though not the same type of values, I'll run tests with the 4.4 tree today, Maybe if they are using the 4.4 version of the script on the foundation 4.1 kernels that is what happens when you use the 4.1 version of knlinfo, it doesn't know to put y or n. I'm just off to work but once I get there I'll run the 4.4 script on my kernel and check it with the 4.1 knlinfo see fi it looks the same. Thanks for the idea @lurch

@TheSin-

This comment has been minimized.

Show comment
Hide comment
@TheSin-

TheSin- Apr 7, 2016

yup @lurch was right, I used the 4.4 version of mkknlimg using --dtok --270x and with the 4.1 version of knlinfo I get

Kernel trailer found at 3340288/0x32f800:
  KVer: "Linux version 4.1.0-2-rpi2 (thesin@southofheaven.org) (gcc version 5.3.1 20160205 (Debian 5.3.1-8) ) #1 SMP Debian 4.1.20-1.20160324 (2016-03-24)"
  DTOK: true
  270X: 01000000
  283X: 00000000
  283x: false

so that is all they are doing I'll switch my builds to use the 4.4 version of the script so it matches, thanks for the help @lurch

Or maybe the version from 4.4 should get moved into the 4.1 tree?

TheSin- commented Apr 7, 2016

yup @lurch was right, I used the 4.4 version of mkknlimg using --dtok --270x and with the 4.1 version of knlinfo I get

Kernel trailer found at 3340288/0x32f800:
  KVer: "Linux version 4.1.0-2-rpi2 (thesin@southofheaven.org) (gcc version 5.3.1 20160205 (Debian 5.3.1-8) ) #1 SMP Debian 4.1.20-1.20160324 (2016-03-24)"
  DTOK: true
  270X: 01000000
  283X: 00000000
  283x: false

so that is all they are doing I'll switch my builds to use the 4.4 version of the script so it matches, thanks for the help @lurch

Or maybe the version from 4.4 should get moved into the 4.1 tree?

@lurch

This comment has been minimized.

Show comment
Hide comment
@lurch

lurch Apr 7, 2016

thanks for the help @lurch

I have to confess that I only got the idea after getting an auto-notification email from GitHub saying that raspberrypi/linux#1195 had been closed.

lurch commented Apr 7, 2016

thanks for the help @lurch

I have to confess that I only got the idea after getting an auto-notification email from GitHub saying that raspberrypi/linux#1195 had been closed.

@TheSin-

This comment has been minimized.

Show comment
Hide comment
@TheSin-

TheSin- Apr 7, 2016

think I should open a new ticket to ask for the mkknlimg form 4.4 to be copied into 4.1 branch? since the official kernel.img and kernel7.img which is 4.1 but is using the 4.4 mkknlimg tool with 270x enabled ? I want to release my 4.1.21 today but I'd like to get that resolved first if at all possible.

TheSin- commented Apr 7, 2016

think I should open a new ticket to ask for the mkknlimg form 4.4 to be copied into 4.1 branch? since the official kernel.img and kernel7.img which is 4.1 but is using the 4.4 mkknlimg tool with 270x enabled ? I want to release my 4.1.21 today but I'd like to get that resolved first if at all possible.

@TheSin-

This comment has been minimized.

Show comment
Hide comment
@TheSin-

TheSin- Apr 7, 2016

and now the current 4.1.21 kernel in the firmware repo is using the mkknlimg from 4.1 and not 4.4 like the hash before it ;) I guess nothing needs to get copied after all.

TheSin- commented Apr 7, 2016

and now the current 4.1.21 kernel in the firmware repo is using the mkknlimg from 4.1 and not 4.4 like the hash before it ;) I guess nothing needs to get copied after all.

XECDesign added a commit to RPi-Distro/firmware that referenced this issue May 4, 2016

kernel: Bump to 4.1.20
kernel: BCM270X_DT: Switch Compute Module to MMC

kernel: pwm overlays: Params must have in-overlay targets

kernel: BCM270X_DT: Build and document the wittypi overlay

firmware: di_adv: Avoid setting undefined flags in first deinterlaced frame

firmware: di_adv: acquire user and main when we are releasing every frame
See: raspberrypi#546

firmware: arm_loader: Initialise the mini-UART when appropriate
See: raspberrypi#553

firmware: vchi_services: Increase number of connections to services from 3 to 8
See: raspberrypi#567

firmware: audio_decode: Don't report format changes when passthough is enabled
See: xbianonpi/xbian#807

XECDesign added a commit to RPi-Distro/firmware that referenced this issue May 4, 2016

kernel: BCM270X_DT: Remove explicit claiming of UART pins
See: raspberrypi/linux@adc10c5

firmware: arm_loader: Use the correct UART on non-DT systems
See: raspberrypi#553

firmware: vchiq_arm: Tweak the logging output

firmware: arm_loader: Add enable_uart setting

XECDesign added a commit to RPi-Distro/firmware that referenced this issue May 4, 2016

kernel: lirc_rpi: Lower IR reception error to debug
See: raspberrypi/linux#1361

kernel: vchiq_arm: Access the dequeue_pending flag locked
See: raspberrypi/linux@a7419d5

kernel: BCM270X_DT: Add pi3-act-led overlay
See: raspberrypi/linux#1363

firmware: sdram: cache the last set_frequency
firmware: pwm_sdm: Set SDRAM turbo frequency to default if pwm_sdm is enabled
See: https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=136445

firmware: vchiq_lib: Don't overwrite loop count mid-loop
See: https://discourse.osmc.tv/t/frequent-random-muting-then-freezing/9875/104

firmware: arm_loader: Change mini-UART initialisation order
See: raspberrypi#553

@pelwell pelwell closed this Jun 6, 2016

@itemir

This comment has been minimized.

Show comment
Hide comment
@itemir

itemir Feb 7, 2017

Quick question on the behavior of enable_uart. Is it only applicable to Raspberry Pi3 or is it also used for other platforms? Thanks in advance.

itemir commented Feb 7, 2017

Quick question on the behavior of enable_uart. Is it only applicable to Raspberry Pi3 or is it also used for other platforms? Thanks in advance.

@pelwell

This comment has been minimized.

Show comment
Hide comment
@pelwell

pelwell Feb 7, 2017

Contributor

It applies to all Pis and CMs, but the setting defaults to 1 (true, enabled) on devices where the main UART isn't used for Bluetooth.

Contributor

pelwell commented Feb 7, 2017

It applies to all Pis and CMs, but the setting defaults to 1 (true, enabled) on devices where the main UART isn't used for Bluetooth.

neuschaefer pushed a commit to neuschaefer/raspi-binary-firmware that referenced this issue Feb 27, 2017

kernel: Bump to 4.1.20
kernel: BCM270X_DT: Switch Compute Module to MMC

kernel: pwm overlays: Params must have in-overlay targets

kernel: BCM270X_DT: Build and document the wittypi overlay

firmware: di_adv: Avoid setting undefined flags in first deinterlaced frame

firmware: di_adv: acquire user and main when we are releasing every frame
See: raspberrypi#546

firmware: arm_loader: Initialise the mini-UART when appropriate
See: raspberrypi#553

firmware: vchi_services: Increase number of connections to services from 3 to 8
See: raspberrypi#567

firmware: audio_decode: Don't report format changes when passthough is enabled
See: xbianonpi/xbian#807

neuschaefer pushed a commit to neuschaefer/raspi-binary-firmware that referenced this issue Feb 27, 2017

kernel: BCM270X_DT: Remove explicit claiming of UART pins
See: raspberrypi/linux@adc10c5

firmware: arm_loader: Use the correct UART on non-DT systems
See: raspberrypi#553

firmware: vchiq_arm: Tweak the logging output

firmware: arm_loader: Add enable_uart setting

neuschaefer pushed a commit to neuschaefer/raspi-binary-firmware that referenced this issue Feb 27, 2017

kernel: lirc_rpi: Lower IR reception error to debug
See: raspberrypi/linux#1361

kernel: vchiq_arm: Access the dequeue_pending flag locked
See: raspberrypi/linux@a7419d5

kernel: BCM270X_DT: Add pi3-act-led overlay
See: raspberrypi/linux#1363

firmware: sdram: cache the last set_frequency
firmware: pwm_sdm: Set SDRAM turbo frequency to default if pwm_sdm is enabled
See: https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=136445

firmware: vchiq_lib: Don't overwrite loop count mid-loop
See: https://discourse.osmc.tv/t/frequent-random-muting-then-freezing/9875/104

firmware: arm_loader: Change mini-UART initialisation order
See: raspberrypi#553
@JamesH65

This comment has been minimized.

Show comment
Hide comment
@JamesH65

JamesH65 Mar 21, 2017

Contributor

Sorry about the necro...

Following a comment from @lurch above, I have written some basic UART documentation which, if the participants of this thread have time, I would like to have checked over. Don't worry about grammar etc, that will be sorted by our copy editors here, but content comments I am looking for. I reckon it's a bit skimpy so far, so if people could give pointers on where things could be expanded that would be great.

https://github.com/raspberrypi/documentation/blob/JamesH65-uart-docs/configuration/uart.md

Contributor

JamesH65 commented Mar 21, 2017

Sorry about the necro...

Following a comment from @lurch above, I have written some basic UART documentation which, if the participants of this thread have time, I would like to have checked over. Don't worry about grammar etc, that will be sorted by our copy editors here, but content comments I am looking for. I reckon it's a bit skimpy so far, so if people could give pointers on where things could be expanded that would be great.

https://github.com/raspberrypi/documentation/blob/JamesH65-uart-docs/configuration/uart.md

@lurch

This comment has been minimized.

Show comment
Hide comment
@lurch

lurch Mar 21, 2017

@JamesH65 could you submit that as a "WIP" PR, so that we have somewhere suitable to leave comments? :)
Or are you looking for comments directly in this thread?

lurch commented Mar 21, 2017

@JamesH65 could you submit that as a "WIP" PR, so that we have somewhere suitable to leave comments? :)
Or are you looking for comments directly in this thread?

@JamesH65

This comment has been minimized.

Show comment
Hide comment
@JamesH65

JamesH65 Mar 21, 2017

Contributor

Hi @lurch, didn't realise you could not comment on a branch. I'll PR it.

Contributor

JamesH65 commented Mar 21, 2017

Hi @lurch, didn't realise you could not comment on a branch. I'll PR it.

@JamesH65

This comment has been minimized.

Show comment
Hide comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment