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