183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 26001985fSAlexander Graf /* 36001985fSAlexander Graf * Copyright (c) 2018 Alexander Graf <agraf@suse.de> 46001985fSAlexander Graf */ 56001985fSAlexander Graf 66001985fSAlexander Graf #include <common.h> 76001985fSAlexander Graf #include <dm.h> 86001985fSAlexander Graf #include <asm/gpio.h> 96001985fSAlexander Graf #include <dm/pinctrl.h> 106001985fSAlexander Graf #include <dm/platform_data/serial_pl01x.h> 11c9bf43ddSAlexander Graf #include <serial.h> 126001985fSAlexander Graf #include "serial_pl01x_internal.h" 136001985fSAlexander Graf 146001985fSAlexander Graf /* 156001985fSAlexander Graf * Check if this serial device is muxed 166001985fSAlexander Graf * 176001985fSAlexander Graf * The serial device will only work properly if it has been muxed to the serial 186001985fSAlexander Graf * pins by firmware. Check whether that happened here. 196001985fSAlexander Graf * 206001985fSAlexander Graf * @return true if serial device is muxed, false if not 216001985fSAlexander Graf */ 226001985fSAlexander Graf static bool bcm283x_is_serial_muxed(void) 236001985fSAlexander Graf { 246001985fSAlexander Graf int serial_gpio = 15; 256001985fSAlexander Graf struct udevice *dev; 266001985fSAlexander Graf 276001985fSAlexander Graf if (uclass_first_device(UCLASS_PINCTRL, &dev) || !dev) 286001985fSAlexander Graf return false; 296001985fSAlexander Graf 306001985fSAlexander Graf if (pinctrl_get_gpio_mux(dev, 0, serial_gpio) != BCM2835_GPIO_ALT0) 316001985fSAlexander Graf return false; 326001985fSAlexander Graf 336001985fSAlexander Graf return true; 346001985fSAlexander Graf } 356001985fSAlexander Graf 366001985fSAlexander Graf static int bcm283x_pl011_serial_ofdata_to_platdata(struct udevice *dev) 376001985fSAlexander Graf { 386001985fSAlexander Graf struct pl01x_serial_platdata *plat = dev_get_platdata(dev); 396001985fSAlexander Graf int ret; 406001985fSAlexander Graf 416001985fSAlexander Graf /* Don't spawn the device if it's not muxed */ 426001985fSAlexander Graf if (!bcm283x_is_serial_muxed()) 436001985fSAlexander Graf return -ENODEV; 446001985fSAlexander Graf 456001985fSAlexander Graf ret = pl01x_serial_ofdata_to_platdata(dev); 466001985fSAlexander Graf if (ret) 476001985fSAlexander Graf return ret; 486001985fSAlexander Graf 496001985fSAlexander Graf /* 506001985fSAlexander Graf * TODO: Reinitialization doesn't always work for now, just skip 516001985fSAlexander Graf * init always - we know we're already initialized 526001985fSAlexander Graf */ 536001985fSAlexander Graf plat->skip_init = true; 546001985fSAlexander Graf 556001985fSAlexander Graf return 0; 566001985fSAlexander Graf } 576001985fSAlexander Graf 58c9bf43ddSAlexander Graf static int bcm283x_pl011_serial_setbrg(struct udevice *dev, int baudrate) 59c9bf43ddSAlexander Graf { 60c9bf43ddSAlexander Graf int r; 61c9bf43ddSAlexander Graf 62c9bf43ddSAlexander Graf r = pl01x_serial_setbrg(dev, baudrate); 63c9bf43ddSAlexander Graf 64c9bf43ddSAlexander Graf /* 65c9bf43ddSAlexander Graf * We may have been muxed to a bogus line before. Drain the RX 66c9bf43ddSAlexander Graf * queue so we start at a clean slate. 67c9bf43ddSAlexander Graf */ 68c9bf43ddSAlexander Graf while (pl01x_serial_getc(dev) != -EAGAIN) ; 69c9bf43ddSAlexander Graf 70c9bf43ddSAlexander Graf return r; 71c9bf43ddSAlexander Graf } 72c9bf43ddSAlexander Graf 73c9bf43ddSAlexander Graf static const struct dm_serial_ops bcm283x_pl011_serial_ops = { 74c9bf43ddSAlexander Graf .putc = pl01x_serial_putc, 75c9bf43ddSAlexander Graf .pending = pl01x_serial_pending, 76c9bf43ddSAlexander Graf .getc = pl01x_serial_getc, 77c9bf43ddSAlexander Graf .setbrg = bcm283x_pl011_serial_setbrg, 78c9bf43ddSAlexander Graf }; 79c9bf43ddSAlexander Graf 806001985fSAlexander Graf static const struct udevice_id bcm283x_pl011_serial_id[] = { 816001985fSAlexander Graf {.compatible = "brcm,bcm2835-pl011", .data = TYPE_PL011}, 826001985fSAlexander Graf {} 836001985fSAlexander Graf }; 846001985fSAlexander Graf 856001985fSAlexander Graf U_BOOT_DRIVER(bcm283x_pl011_uart) = { 866001985fSAlexander Graf .name = "bcm283x_pl011", 876001985fSAlexander Graf .id = UCLASS_SERIAL, 886001985fSAlexander Graf .of_match = of_match_ptr(bcm283x_pl011_serial_id), 896001985fSAlexander Graf .ofdata_to_platdata = of_match_ptr(bcm283x_pl011_serial_ofdata_to_platdata), 906001985fSAlexander Graf .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata), 916001985fSAlexander Graf .probe = pl01x_serial_probe, 92c9bf43ddSAlexander Graf .ops = &bcm283x_pl011_serial_ops, 93*46879196SBin Meng #if !CONFIG_IS_ENABLED(OF_CONTROL) 946001985fSAlexander Graf .flags = DM_FLAG_PRE_RELOC, 95*46879196SBin Meng #endif 966001985fSAlexander Graf .priv_auto_alloc_size = sizeof(struct pl01x_priv), 976001985fSAlexander Graf }; 98