Commit 6001985f92e4a99504343485bfe2c18940a41011

Authored by Alexander Graf
Committed by Tom Rini
1 parent 958d55f26c

bcm2835_pl011_serial: Add BCM2835 specific serial driver

On bcm2835 we need to ensure we only access serial devices that are
muxed to the serial output pins of the pin header. To achieve this
for the pl011 device, add a bcm2835 specific pl011 wrapper device
that does this check but otherwise behaves like a pl011 device.

Signed-off-by: Alexander Graf <agraf@suse.de>

Showing 6 changed files with 101 additions and 9 deletions Side-by-side Diff

... ... @@ -99,6 +99,7 @@
99 99 F: drivers/mmc/bcm2835_sdhci.c
100 100 F: drivers/mmc/bcm2835_sdhost.c
101 101 F: drivers/serial/serial_bcm283x_mu.c
  102 +F: drivers/serial/serial_bcm283x_pl011.c
102 103 F: drivers/video/bcm2835.c
103 104 F: include/dm/platform_data/serial_bcm283x_mu.h
104 105 F: drivers/pinctrl/broadcom/
drivers/serial/Kconfig
... ... @@ -395,6 +395,15 @@
395 395 help
396 396 Select this to enable Mini-UART support on BCM283X family of SoCs.
397 397  
  398 +config BCM283X_PL011_SERIAL
  399 + bool "Support for BCM283x PL011 UART"
  400 + depends on PL01X_SERIAL && ARCH_BCM283X
  401 + default y
  402 + help
  403 + Select this to enable an overriding PL011 driver for BCM283X SoCs
  404 + that supports automatic disable, so that it only gets used when
  405 + the UART is actually muxed.
  406 +
398 407 config BCM6345_SERIAL
399 408 bool "Support for BCM6345 UART"
400 409 depends on DM_SERIAL && ARCH_BMIPS
drivers/serial/Makefile
... ... @@ -46,6 +46,7 @@
46 46 obj-$(CONFIG_PIC32_SERIAL) += serial_pic32.o
47 47 obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o
48 48 obj-$(CONFIG_BCM283X_MU_SERIAL) += serial_bcm283x_mu.o
  49 +obj-$(CONFIG_BCM283X_PL011_SERIAL) += serial_bcm283x_pl011.o
49 50 obj-$(CONFIG_MSM_SERIAL) += serial_msm.o
50 51 obj-$(CONFIG_MVEBU_A3700_UART) += serial_mvebu_a3700.o
51 52 obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o
drivers/serial/serial_bcm283x_pl011.c
  1 +/*
  2 + * Copyright (c) 2018 Alexander Graf <agraf@suse.de>
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#include <common.h>
  8 +#include <dm.h>
  9 +#include <asm/gpio.h>
  10 +#include <dm/pinctrl.h>
  11 +#include <dm/platform_data/serial_pl01x.h>
  12 +#include "serial_pl01x_internal.h"
  13 +
  14 +/*
  15 + * Check if this serial device is muxed
  16 + *
  17 + * The serial device will only work properly if it has been muxed to the serial
  18 + * pins by firmware. Check whether that happened here.
  19 + *
  20 + * @return true if serial device is muxed, false if not
  21 + */
  22 +static bool bcm283x_is_serial_muxed(void)
  23 +{
  24 + int serial_gpio = 15;
  25 + struct udevice *dev;
  26 +
  27 + if (uclass_first_device(UCLASS_PINCTRL, &dev) || !dev)
  28 + return false;
  29 +
  30 + if (pinctrl_get_gpio_mux(dev, 0, serial_gpio) != BCM2835_GPIO_ALT0)
  31 + return false;
  32 +
  33 + return true;
  34 +}
  35 +
  36 +static int bcm283x_pl011_serial_ofdata_to_platdata(struct udevice *dev)
  37 +{
  38 + struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
  39 + int ret;
  40 +
  41 + /* Don't spawn the device if it's not muxed */
  42 + if (!bcm283x_is_serial_muxed())
  43 + return -ENODEV;
  44 +
  45 + ret = pl01x_serial_ofdata_to_platdata(dev);
  46 + if (ret)
  47 + return ret;
  48 +
  49 + /*
  50 + * TODO: Reinitialization doesn't always work for now, just skip
  51 + * init always - we know we're already initialized
  52 + */
  53 + plat->skip_init = true;
  54 +
  55 + return 0;
  56 +}
  57 +
  58 +static const struct udevice_id bcm283x_pl011_serial_id[] = {
  59 + {.compatible = "brcm,bcm2835-pl011", .data = TYPE_PL011},
  60 + {}
  61 +};
  62 +
  63 +U_BOOT_DRIVER(bcm283x_pl011_uart) = {
  64 + .name = "bcm283x_pl011",
  65 + .id = UCLASS_SERIAL,
  66 + .of_match = of_match_ptr(bcm283x_pl011_serial_id),
  67 + .ofdata_to_platdata = of_match_ptr(bcm283x_pl011_serial_ofdata_to_platdata),
  68 + .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata),
  69 + .probe = pl01x_serial_probe,
  70 + .ops = &pl01x_serial_ops,
  71 + .flags = DM_FLAG_PRE_RELOC,
  72 + .priv_auto_alloc_size = sizeof(struct pl01x_priv),
  73 +};
drivers/serial/serial_pl01x.c
... ... @@ -273,11 +273,6 @@
273 273  
274 274 #ifdef CONFIG_DM_SERIAL
275 275  
276   -struct pl01x_priv {
277   - struct pl01x_regs *regs;
278   - enum pl01x_type type;
279   -};
280   -
281 276 static int pl01x_serial_setbrg(struct udevice *dev, int baudrate)
282 277 {
283 278 struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
... ... @@ -291,7 +286,7 @@
291 286 return 0;
292 287 }
293 288  
294   -static int pl01x_serial_probe(struct udevice *dev)
  289 +int pl01x_serial_probe(struct udevice *dev)
295 290 {
296 291 struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
297 292 struct pl01x_priv *priv = dev_get_priv(dev);
... ... @@ -329,7 +324,7 @@
329 324 return fr & UART_PL01x_FR_TXFF ? 0 : 1;
330 325 }
331 326  
332   -static const struct dm_serial_ops pl01x_serial_ops = {
  327 +const struct dm_serial_ops pl01x_serial_ops = {
333 328 .putc = pl01x_serial_putc,
334 329 .pending = pl01x_serial_pending,
335 330 .getc = pl01x_serial_getc,
... ... @@ -343,7 +338,7 @@
343 338 {}
344 339 };
345 340  
346   -static int pl01x_serial_ofdata_to_platdata(struct udevice *dev)
  341 +int pl01x_serial_ofdata_to_platdata(struct udevice *dev)
347 342 {
348 343 struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
349 344 fdt_addr_t addr;
drivers/serial/serial_pl01x_internal.h
... ... @@ -38,7 +38,20 @@
38 38 u32 pl011_lcrh; /* 0x2C Line control register */
39 39 u32 pl011_cr; /* 0x30 Control register */
40 40 };
41   -#endif
  41 +
  42 +#ifdef CONFIG_DM_SERIAL
  43 +
  44 +int pl01x_serial_ofdata_to_platdata(struct udevice *dev);
  45 +int pl01x_serial_probe(struct udevice *dev);
  46 +extern const struct dm_serial_ops pl01x_serial_ops;
  47 +
  48 +struct pl01x_priv {
  49 + struct pl01x_regs *regs;
  50 + enum pl01x_type type;
  51 +};
  52 +
  53 +#endif /* CONFIG_DM_SERIAL */
  54 +#endif /* !__ASSEMBLY__ */
42 55  
43 56 #define UART_PL01x_RSR_OE 0x08
44 57 #define UART_PL01x_RSR_BE 0x04