153bdae24SGregory CLEMENT // SPDX-License-Identifier: (GPL-2.0 OR MIT) 253bdae24SGregory CLEMENT /* 353bdae24SGregory CLEMENT * Microsemi SoCs pinctrl driver 453bdae24SGregory CLEMENT * 553bdae24SGregory CLEMENT * Author: <alexandre.belloni@free-electrons.com> 653bdae24SGregory CLEMENT * Author: <gregory.clement@bootlin.com> 753bdae24SGregory CLEMENT * License: Dual MIT/GPL 853bdae24SGregory CLEMENT * Copyright (c) 2017 Microsemi Corporation 953bdae24SGregory CLEMENT */ 1053bdae24SGregory CLEMENT 1153bdae24SGregory CLEMENT #include <asm/gpio.h> 1253bdae24SGregory CLEMENT #include <asm/system.h> 1353bdae24SGregory CLEMENT #include <common.h> 1453bdae24SGregory CLEMENT #include <config.h> 1553bdae24SGregory CLEMENT #include <dm.h> 1653bdae24SGregory CLEMENT #include <dm/device-internal.h> 1753bdae24SGregory CLEMENT #include <dm/lists.h> 1853bdae24SGregory CLEMENT #include <dm/pinctrl.h> 1953bdae24SGregory CLEMENT #include <dm/root.h> 2053bdae24SGregory CLEMENT #include <errno.h> 2153bdae24SGregory CLEMENT #include <fdtdec.h> 2253bdae24SGregory CLEMENT #include <linux/io.h> 2353bdae24SGregory CLEMENT #include "mscc-common.h" 2453bdae24SGregory CLEMENT 2553bdae24SGregory CLEMENT enum { 2653bdae24SGregory CLEMENT FUNC_NONE, 2753bdae24SGregory CLEMENT FUNC_GPIO, 2853bdae24SGregory CLEMENT FUNC_IRQ0_IN, 2953bdae24SGregory CLEMENT FUNC_IRQ0_OUT, 3053bdae24SGregory CLEMENT FUNC_IRQ1_IN, 3153bdae24SGregory CLEMENT FUNC_IRQ1_OUT, 3253bdae24SGregory CLEMENT FUNC_MIIM1, 3353bdae24SGregory CLEMENT FUNC_PCI_WAKE, 3453bdae24SGregory CLEMENT FUNC_PTP0, 3553bdae24SGregory CLEMENT FUNC_PTP1, 3653bdae24SGregory CLEMENT FUNC_PTP2, 3753bdae24SGregory CLEMENT FUNC_PTP3, 3853bdae24SGregory CLEMENT FUNC_PWM, 3953bdae24SGregory CLEMENT FUNC_RECO_CLK0, 4053bdae24SGregory CLEMENT FUNC_RECO_CLK1, 4153bdae24SGregory CLEMENT FUNC_SFP0, 4253bdae24SGregory CLEMENT FUNC_SFP1, 4353bdae24SGregory CLEMENT FUNC_SFP2, 4453bdae24SGregory CLEMENT FUNC_SFP3, 4553bdae24SGregory CLEMENT FUNC_SFP4, 4653bdae24SGregory CLEMENT FUNC_SFP5, 4753bdae24SGregory CLEMENT FUNC_SG0, 4853bdae24SGregory CLEMENT FUNC_SI, 4953bdae24SGregory CLEMENT FUNC_TACHO, 5053bdae24SGregory CLEMENT FUNC_TWI, 5153bdae24SGregory CLEMENT FUNC_TWI_SCL_M, 5253bdae24SGregory CLEMENT FUNC_UART, 5353bdae24SGregory CLEMENT FUNC_UART2, 5453bdae24SGregory CLEMENT FUNC_MAX 5553bdae24SGregory CLEMENT }; 5653bdae24SGregory CLEMENT 5753bdae24SGregory CLEMENT static char * const ocelot_function_names[] = { 5853bdae24SGregory CLEMENT [FUNC_NONE] = "none", 5953bdae24SGregory CLEMENT [FUNC_GPIO] = "gpio", 6053bdae24SGregory CLEMENT [FUNC_IRQ0_IN] = "irq0_in", 6153bdae24SGregory CLEMENT [FUNC_IRQ0_OUT] = "irq0_out", 6253bdae24SGregory CLEMENT [FUNC_IRQ1_IN] = "irq1_in", 6353bdae24SGregory CLEMENT [FUNC_IRQ1_OUT] = "irq1_out", 6453bdae24SGregory CLEMENT [FUNC_MIIM1] = "miim1", 6553bdae24SGregory CLEMENT [FUNC_PCI_WAKE] = "pci_wake", 6653bdae24SGregory CLEMENT [FUNC_PTP0] = "ptp0", 6753bdae24SGregory CLEMENT [FUNC_PTP1] = "ptp1", 6853bdae24SGregory CLEMENT [FUNC_PTP2] = "ptp2", 6953bdae24SGregory CLEMENT [FUNC_PTP3] = "ptp3", 7053bdae24SGregory CLEMENT [FUNC_PWM] = "pwm", 7153bdae24SGregory CLEMENT [FUNC_RECO_CLK0] = "reco_clk0", 7253bdae24SGregory CLEMENT [FUNC_RECO_CLK1] = "reco_clk1", 7353bdae24SGregory CLEMENT [FUNC_SFP0] = "sfp0", 7453bdae24SGregory CLEMENT [FUNC_SFP1] = "sfp1", 7553bdae24SGregory CLEMENT [FUNC_SFP2] = "sfp2", 7653bdae24SGregory CLEMENT [FUNC_SFP3] = "sfp3", 7753bdae24SGregory CLEMENT [FUNC_SFP4] = "sfp4", 7853bdae24SGregory CLEMENT [FUNC_SFP5] = "sfp5", 7953bdae24SGregory CLEMENT [FUNC_SG0] = "sg0", 8053bdae24SGregory CLEMENT [FUNC_SI] = "si", 8153bdae24SGregory CLEMENT [FUNC_TACHO] = "tacho", 8253bdae24SGregory CLEMENT [FUNC_TWI] = "twi", 8353bdae24SGregory CLEMENT [FUNC_TWI_SCL_M] = "twi_scl_m", 8453bdae24SGregory CLEMENT [FUNC_UART] = "uart", 8553bdae24SGregory CLEMENT [FUNC_UART2] = "uart2", 8653bdae24SGregory CLEMENT }; 8753bdae24SGregory CLEMENT 8853bdae24SGregory CLEMENT MSCC_P(0, SG0, NONE, NONE); 8953bdae24SGregory CLEMENT MSCC_P(1, SG0, NONE, NONE); 9053bdae24SGregory CLEMENT MSCC_P(2, SG0, NONE, NONE); 9153bdae24SGregory CLEMENT MSCC_P(3, SG0, NONE, NONE); 9253bdae24SGregory CLEMENT MSCC_P(4, IRQ0_IN, IRQ0_OUT, TWI); 9353bdae24SGregory CLEMENT MSCC_P(5, IRQ1_IN, IRQ1_OUT, PCI_WAKE); 9453bdae24SGregory CLEMENT MSCC_P(6, UART, TWI_SCL_M, NONE); 9553bdae24SGregory CLEMENT MSCC_P(7, UART, TWI_SCL_M, NONE); 9653bdae24SGregory CLEMENT MSCC_P(8, SI, TWI_SCL_M, IRQ0_OUT); 9753bdae24SGregory CLEMENT MSCC_P(9, SI, TWI_SCL_M, IRQ1_OUT); 9853bdae24SGregory CLEMENT MSCC_P(10, PTP2, TWI_SCL_M, SFP0); 9953bdae24SGregory CLEMENT MSCC_P(11, PTP3, TWI_SCL_M, SFP1); 10053bdae24SGregory CLEMENT MSCC_P(12, UART2, TWI_SCL_M, SFP2); 10153bdae24SGregory CLEMENT MSCC_P(13, UART2, TWI_SCL_M, SFP3); 10253bdae24SGregory CLEMENT MSCC_P(14, MIIM1, TWI_SCL_M, SFP4); 10353bdae24SGregory CLEMENT MSCC_P(15, MIIM1, TWI_SCL_M, SFP5); 10453bdae24SGregory CLEMENT MSCC_P(16, TWI, NONE, SI); 10553bdae24SGregory CLEMENT MSCC_P(17, TWI, TWI_SCL_M, SI); 10653bdae24SGregory CLEMENT MSCC_P(18, PTP0, TWI_SCL_M, NONE); 10753bdae24SGregory CLEMENT MSCC_P(19, PTP1, TWI_SCL_M, NONE); 10853bdae24SGregory CLEMENT MSCC_P(20, RECO_CLK0, TACHO, NONE); 10953bdae24SGregory CLEMENT MSCC_P(21, RECO_CLK1, PWM, NONE); 11053bdae24SGregory CLEMENT 11153bdae24SGregory CLEMENT #define OCELOT_PIN(n) { \ 11253bdae24SGregory CLEMENT .name = "GPIO_"#n, \ 11353bdae24SGregory CLEMENT .drv_data = &mscc_pin_##n \ 11453bdae24SGregory CLEMENT } 11553bdae24SGregory CLEMENT 11653bdae24SGregory CLEMENT static const struct mscc_pin_data ocelot_pins[] = { 11753bdae24SGregory CLEMENT OCELOT_PIN(0), 11853bdae24SGregory CLEMENT OCELOT_PIN(1), 11953bdae24SGregory CLEMENT OCELOT_PIN(2), 12053bdae24SGregory CLEMENT OCELOT_PIN(3), 12153bdae24SGregory CLEMENT OCELOT_PIN(4), 12253bdae24SGregory CLEMENT OCELOT_PIN(5), 12353bdae24SGregory CLEMENT OCELOT_PIN(6), 12453bdae24SGregory CLEMENT OCELOT_PIN(7), 12553bdae24SGregory CLEMENT OCELOT_PIN(8), 12653bdae24SGregory CLEMENT OCELOT_PIN(9), 12753bdae24SGregory CLEMENT OCELOT_PIN(10), 12853bdae24SGregory CLEMENT OCELOT_PIN(11), 12953bdae24SGregory CLEMENT OCELOT_PIN(12), 13053bdae24SGregory CLEMENT OCELOT_PIN(13), 13153bdae24SGregory CLEMENT OCELOT_PIN(14), 13253bdae24SGregory CLEMENT OCELOT_PIN(15), 13353bdae24SGregory CLEMENT OCELOT_PIN(16), 13453bdae24SGregory CLEMENT OCELOT_PIN(17), 13553bdae24SGregory CLEMENT OCELOT_PIN(18), 13653bdae24SGregory CLEMENT OCELOT_PIN(19), 13753bdae24SGregory CLEMENT OCELOT_PIN(20), 13853bdae24SGregory CLEMENT OCELOT_PIN(21), 13953bdae24SGregory CLEMENT }; 14053bdae24SGregory CLEMENT 141*051de9b3SHoratiu Vultur static const unsigned long ocelot_gpios[] = { 142*051de9b3SHoratiu Vultur [MSCC_GPIO_OUT_SET] = 0x00, 143*051de9b3SHoratiu Vultur [MSCC_GPIO_OUT_CLR] = 0x04, 144*051de9b3SHoratiu Vultur [MSCC_GPIO_OUT] = 0x08, 145*051de9b3SHoratiu Vultur [MSCC_GPIO_IN] = 0x0c, 146*051de9b3SHoratiu Vultur [MSCC_GPIO_OE] = 0x10, 147*051de9b3SHoratiu Vultur [MSCC_GPIO_INTR] = 0x14, 148*051de9b3SHoratiu Vultur [MSCC_GPIO_INTR_ENA] = 0x18, 149*051de9b3SHoratiu Vultur [MSCC_GPIO_INTR_IDENT] = 0x1c, 150*051de9b3SHoratiu Vultur [MSCC_GPIO_ALT0] = 0x20, 151*051de9b3SHoratiu Vultur [MSCC_GPIO_ALT1] = 0x24, 152*051de9b3SHoratiu Vultur }; 153*051de9b3SHoratiu Vultur 15453bdae24SGregory CLEMENT static int ocelot_gpio_probe(struct udevice *dev) 15553bdae24SGregory CLEMENT { 15653bdae24SGregory CLEMENT struct gpio_dev_priv *uc_priv; 15753bdae24SGregory CLEMENT 15853bdae24SGregory CLEMENT uc_priv = dev_get_uclass_priv(dev); 15953bdae24SGregory CLEMENT uc_priv->bank_name = "ocelot-gpio"; 16053bdae24SGregory CLEMENT uc_priv->gpio_count = ARRAY_SIZE(ocelot_pins); 16153bdae24SGregory CLEMENT 16253bdae24SGregory CLEMENT return 0; 16353bdae24SGregory CLEMENT } 16453bdae24SGregory CLEMENT 16553bdae24SGregory CLEMENT static struct driver ocelot_gpio_driver = { 16653bdae24SGregory CLEMENT .name = "ocelot-gpio", 16753bdae24SGregory CLEMENT .id = UCLASS_GPIO, 16853bdae24SGregory CLEMENT .probe = ocelot_gpio_probe, 16953bdae24SGregory CLEMENT .ops = &mscc_gpio_ops, 17053bdae24SGregory CLEMENT }; 17153bdae24SGregory CLEMENT 17253bdae24SGregory CLEMENT int ocelot_pinctrl_probe(struct udevice *dev) 17353bdae24SGregory CLEMENT { 17453bdae24SGregory CLEMENT int ret; 17553bdae24SGregory CLEMENT 17653bdae24SGregory CLEMENT ret = mscc_pinctrl_probe(dev, FUNC_MAX, ocelot_pins, 17753bdae24SGregory CLEMENT ARRAY_SIZE(ocelot_pins), 178*051de9b3SHoratiu Vultur ocelot_function_names, 179*051de9b3SHoratiu Vultur ocelot_gpios); 18053bdae24SGregory CLEMENT 18153bdae24SGregory CLEMENT if (ret) 18253bdae24SGregory CLEMENT return ret; 18353bdae24SGregory CLEMENT 18453bdae24SGregory CLEMENT ret = device_bind(dev, &ocelot_gpio_driver, "ocelot-gpio", NULL, 18553bdae24SGregory CLEMENT dev_of_offset(dev), NULL); 18653bdae24SGregory CLEMENT 18753bdae24SGregory CLEMENT return ret; 18853bdae24SGregory CLEMENT } 18953bdae24SGregory CLEMENT 19053bdae24SGregory CLEMENT static const struct udevice_id ocelot_pinctrl_of_match[] = { 19153bdae24SGregory CLEMENT {.compatible = "mscc,ocelot-pinctrl"}, 19253bdae24SGregory CLEMENT {}, 19353bdae24SGregory CLEMENT }; 19453bdae24SGregory CLEMENT 19553bdae24SGregory CLEMENT U_BOOT_DRIVER(ocelot_pinctrl) = { 19653bdae24SGregory CLEMENT .name = "ocelot-pinctrl", 19753bdae24SGregory CLEMENT .id = UCLASS_PINCTRL, 19853bdae24SGregory CLEMENT .of_match = of_match_ptr(ocelot_pinctrl_of_match), 19953bdae24SGregory CLEMENT .probe = ocelot_pinctrl_probe, 20053bdae24SGregory CLEMENT .priv_auto_alloc_size = sizeof(struct mscc_pinctrl), 20153bdae24SGregory CLEMENT .ops = &mscc_pinctrl_ops, 20253bdae24SGregory CLEMENT }; 203