Hi,
Am Sonntag, 2. April 2017, 09:20:06 CEST schrieb Alex Deymo:
> The Raspberry Pi 3 has two UART interfaces that can be pinmuxed to the
> header pins. The PL011 is by default muxed to the Bluetooth chip and
> the mini-UART can be muxed to the pin headers passing "enabled_uart=1"
> in the config.txt file.
>
> Passing "enable_uart=1" has other implications, since the baudrate of
> the miniuart depends on the clock frequency of the main core, which
> is normally dynamic unless enable_uart=1 is set.
> If Bluetooth is not
> used or not required, it is possible to set the PL011 UART to the
> header pins passing either "dtoverlay=pi3-disable-bt" or
> "dtoverlay=pi3-miniuart-bt" to disable Bluetooth or use it via the
> miniuart respectively.
>
> This patch disables (for U-Boot) the UARTs modules not muxed to the
> header pins so the serial port is used only if available in the
> header pins, avoiding writing to the Bluetooth chip if needed. This
> allows to enable the PL01X driver for the Raspberry Pi 3, previously
> disabled for that board, which can be used for the U-Boot console if
> properly configured in the device tree.
>
> Note that in order to get the PL01X driver in the Raspberry Pi 3 to
> work with U-Boot the device tree must set "skip-init" in the uart0
> block, for example this device tree fragment would do it:
>
> fragment@0 {
> target = <>;
> __overlay__ {
> skip-init;
> };
> };
This is already done in arch/arm/dts/bcm283x-uboot.dtsi:
{
skip-init;
u-boot,dm-pre-reloc;
};
{
skip-init;
u-boot,dm-pre-reloc;
};
> Test: Booted a rpi3 with either UART output.
> Signed-off-by: Alex Deymo
Acked-by: Fabian Vogt
Cheers,
Fabian
> ---
> board/raspberrypi/rpi/rpi.c | 78
> +++--
> drivers/serial/serial_pl01x.c | 3 ++
> include/configs/rpi.h | 8 +++-
> include/dm/platform_data/serial_pl01x.h | 2 +
> 4 files changed, 66 insertions(+), 25 deletions(-)
>
> diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
> index 2146534b36..58f07953f5 100644
> --- a/board/raspberrypi/rpi/rpi.c
> +++ b/board/raspberrypi/rpi/rpi.c
> @@ -18,6 +18,7 @@
> #include
> #include
> #include
> +#include
> #include
> #ifdef CONFIG_ARM64
> #include
> @@ -442,8 +443,19 @@ static void get_board_rev(void)
> printf("RPI %s (0x%x)\n", model->name, revision);
> }
>
> -#ifndef CONFIG_PL01X_SERIAL
> -static bool rpi_is_serial_active(void)
> +/* An enum describing the pin muxing selection for the UART RX/TX pins. */
> +enum rpi_uart_mux {
> + /* The pin is associated with the internal "miniuart" block. */
> + RPI_UART_BCM283X_MU,
> +
> + /* The pin is associated with the PL01X uart driver. */
> + RPI_UART_PL01X,
> +
> + /* The pin is associated with a different function. */
> + RPI_UART_OTHER,
> +};
> +
> +static enum rpi_uart_mux rpi_get_uart_mux_setting(void)
> {
> int serial_gpio = 15;
> struct udevice *dev;
> @@ -452,41 +464,61 @@ static bool rpi_is_serial_active(void)
>* The RPi3 disables the mini uart by default. The easiest way to find
>* out whether it is available is to check if the RX pin is muxed.
>*/
> -
> if (uclass_first_device(UCLASS_GPIO, ) || !dev)
> - return true;
> -
> - if (bcm2835_gpio_get_func_id(dev, serial_gpio) != BCM2835_GPIO_ALT5)
> - return false;
> + return RPI_UART_OTHER;
>
> - return true;
> + switch (bcm2835_gpio_get_func_id(dev, serial_gpio)) {
> + case BCM2835_GPIO_ALT5:
> + return RPI_UART_BCM283X_MU;
> + case BCM2835_GPIO_ALT0:
> + return RPI_UART_PL01X;
> + }
> + return RPI_UART_OTHER;
> }
>
> -/* Disable mini-UART I/O if it's not pinmuxed to our pins.
> - * The firmware only enables it if explicitly done in config.txt:
> enable_uart=1
> +/* Disable UART I/O for the mini-UART and PL01X UART if they are not
> pinmuxed to
> + * the Raspberry Pi header. The mini-UART is only enabled in the header if
> + * explicitly done in config.txt: enable_uart=1, and the PL01X is only
> enabled
> + * if not used for Bluetooth and explicitly exposed in config.txt as either
> + * dtoverlay=pi3-disable-bt or dtoverlay=pi3-miniuart-bt.
> */
> -static void rpi_disable_inactive_uart(void)
> +static void rpi_disable_inactive_uarts(void)
> {
> struct udevice *dev;
> - struct bcm283x_mu_serial_platdata *plat;
> + enum rpi_uart_mux mux;
>
> - if (uclass_get_device_by_driver(UCLASS_SERIAL,
> - DM_GET_DRIVER(serial_bcm283x_mu),
> - ) || !dev)
> - return;
> + mux = rpi_get_uart_mux_setting();
> +
> +#ifdef CONFIG_BCM283X_MU_SERIAL
> + struct bcm283x_mu_serial_platdata *bcm283x_mu_plat;
>
> -