1*6001985fSAlexander Graf /* 2*6001985fSAlexander Graf * Copyright (c) 2018 Alexander Graf <agraf@suse.de> 3*6001985fSAlexander Graf * 4*6001985fSAlexander Graf * SPDX-License-Identifier: GPL-2.0+ 5*6001985fSAlexander Graf */ 6*6001985fSAlexander Graf 7*6001985fSAlexander Graf #include <common.h> 8*6001985fSAlexander Graf #include <dm.h> 9*6001985fSAlexander Graf #include <asm/gpio.h> 10*6001985fSAlexander Graf #include <dm/pinctrl.h> 11*6001985fSAlexander Graf #include <dm/platform_data/serial_pl01x.h> 12*6001985fSAlexander Graf #include "serial_pl01x_internal.h" 13*6001985fSAlexander Graf 14*6001985fSAlexander Graf /* 15*6001985fSAlexander Graf * Check if this serial device is muxed 16*6001985fSAlexander Graf * 17*6001985fSAlexander Graf * The serial device will only work properly if it has been muxed to the serial 18*6001985fSAlexander Graf * pins by firmware. Check whether that happened here. 19*6001985fSAlexander Graf * 20*6001985fSAlexander Graf * @return true if serial device is muxed, false if not 21*6001985fSAlexander Graf */ 22*6001985fSAlexander Graf static bool bcm283x_is_serial_muxed(void) 23*6001985fSAlexander Graf { 24*6001985fSAlexander Graf int serial_gpio = 15; 25*6001985fSAlexander Graf struct udevice *dev; 26*6001985fSAlexander Graf 27*6001985fSAlexander Graf if (uclass_first_device(UCLASS_PINCTRL, &dev) || !dev) 28*6001985fSAlexander Graf return false; 29*6001985fSAlexander Graf 30*6001985fSAlexander Graf if (pinctrl_get_gpio_mux(dev, 0, serial_gpio) != BCM2835_GPIO_ALT0) 31*6001985fSAlexander Graf return false; 32*6001985fSAlexander Graf 33*6001985fSAlexander Graf return true; 34*6001985fSAlexander Graf } 35*6001985fSAlexander Graf 36*6001985fSAlexander Graf static int bcm283x_pl011_serial_ofdata_to_platdata(struct udevice *dev) 37*6001985fSAlexander Graf { 38*6001985fSAlexander Graf struct pl01x_serial_platdata *plat = dev_get_platdata(dev); 39*6001985fSAlexander Graf int ret; 40*6001985fSAlexander Graf 41*6001985fSAlexander Graf /* Don't spawn the device if it's not muxed */ 42*6001985fSAlexander Graf if (!bcm283x_is_serial_muxed()) 43*6001985fSAlexander Graf return -ENODEV; 44*6001985fSAlexander Graf 45*6001985fSAlexander Graf ret = pl01x_serial_ofdata_to_platdata(dev); 46*6001985fSAlexander Graf if (ret) 47*6001985fSAlexander Graf return ret; 48*6001985fSAlexander Graf 49*6001985fSAlexander Graf /* 50*6001985fSAlexander Graf * TODO: Reinitialization doesn't always work for now, just skip 51*6001985fSAlexander Graf * init always - we know we're already initialized 52*6001985fSAlexander Graf */ 53*6001985fSAlexander Graf plat->skip_init = true; 54*6001985fSAlexander Graf 55*6001985fSAlexander Graf return 0; 56*6001985fSAlexander Graf } 57*6001985fSAlexander Graf 58*6001985fSAlexander Graf static const struct udevice_id bcm283x_pl011_serial_id[] = { 59*6001985fSAlexander Graf {.compatible = "brcm,bcm2835-pl011", .data = TYPE_PL011}, 60*6001985fSAlexander Graf {} 61*6001985fSAlexander Graf }; 62*6001985fSAlexander Graf 63*6001985fSAlexander Graf U_BOOT_DRIVER(bcm283x_pl011_uart) = { 64*6001985fSAlexander Graf .name = "bcm283x_pl011", 65*6001985fSAlexander Graf .id = UCLASS_SERIAL, 66*6001985fSAlexander Graf .of_match = of_match_ptr(bcm283x_pl011_serial_id), 67*6001985fSAlexander Graf .ofdata_to_platdata = of_match_ptr(bcm283x_pl011_serial_ofdata_to_platdata), 68*6001985fSAlexander Graf .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata), 69*6001985fSAlexander Graf .probe = pl01x_serial_probe, 70*6001985fSAlexander Graf .ops = &pl01x_serial_ops, 71*6001985fSAlexander Graf .flags = DM_FLAG_PRE_RELOC, 72*6001985fSAlexander Graf .priv_auto_alloc_size = sizeof(struct pl01x_priv), 73*6001985fSAlexander Graf }; 74