1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Pinctrl / GPIO driver for StarFive JH7110 SoC aon controller 4 * 5 * Copyright (C) 2022 StarFive Technology Co., Ltd. 6 */ 7 8 #include <linux/err.h> 9 #include <linux/gpio/driver.h> 10 #include <linux/init.h> 11 #include <linux/interrupt.h> 12 #include <linux/io.h> 13 #include <linux/mod_devicetable.h> 14 #include <linux/module.h> 15 #include <linux/pinctrl/pinconf.h> 16 #include <linux/pinctrl/pinconf-generic.h> 17 #include <linux/pinctrl/pinctrl.h> 18 #include <linux/pinctrl/pinmux.h> 19 #include <linux/platform_device.h> 20 #include <linux/pm_runtime.h> 21 #include <linux/regmap.h> 22 #include <linux/slab.h> 23 24 #include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h> 25 26 #include "../core.h" 27 #include "../pinconf.h" 28 #include "../pinmux.h" 29 #include "pinctrl-starfive-jh7110.h" 30 31 #define JH7110_AON_NGPIO 4 32 #define JH7110_AON_GC_BASE 64 33 34 /* registers */ 35 #define JH7110_AON_DOEN 0x0 36 #define JH7110_AON_DOUT 0x4 37 #define JH7110_AON_GPI 0x8 38 #define JH7110_AON_GPIOIN 0x2c 39 40 #define JH7110_AON_GPIOEN 0xc 41 #define JH7110_AON_GPIOIS 0x10 42 #define JH7110_AON_GPIOIC 0x14 43 #define JH7110_AON_GPIOIBE 0x18 44 #define JH7110_AON_GPIOIEV 0x1c 45 #define JH7110_AON_GPIOIE 0x20 46 #define JH7110_AON_GPIORIS 0x28 47 #define JH7110_AON_GPIOMIS 0x28 48 49 #define JH7110_AON_GPO_PDA_0_5_CFG 0x30 50 51 static const struct pinctrl_pin_desc jh7110_aon_pins[] = { 52 PINCTRL_PIN(PAD_TESTEN, "TESTEN"), 53 PINCTRL_PIN(PAD_RGPIO0, "RGPIO0"), 54 PINCTRL_PIN(PAD_RGPIO1, "RGPIO1"), 55 PINCTRL_PIN(PAD_RGPIO2, "RGPIO2"), 56 PINCTRL_PIN(PAD_RGPIO3, "RGPIO3"), 57 PINCTRL_PIN(PAD_RSTN, "RSTN"), 58 PINCTRL_PIN(PAD_GMAC0_MDC, "GMAC0_MDC"), 59 PINCTRL_PIN(PAD_GMAC0_MDIO, "GMAC0_MDIO"), 60 PINCTRL_PIN(PAD_GMAC0_RXD0, "GMAC0_RXD0"), 61 PINCTRL_PIN(PAD_GMAC0_RXD1, "GMAC0_RXD1"), 62 PINCTRL_PIN(PAD_GMAC0_RXD2, "GMAC0_RXD2"), 63 PINCTRL_PIN(PAD_GMAC0_RXD3, "GMAC0_RXD3"), 64 PINCTRL_PIN(PAD_GMAC0_RXDV, "GMAC0_RXDV"), 65 PINCTRL_PIN(PAD_GMAC0_RXC, "GMAC0_RXC"), 66 PINCTRL_PIN(PAD_GMAC0_TXD0, "GMAC0_TXD0"), 67 PINCTRL_PIN(PAD_GMAC0_TXD1, "GMAC0_TXD1"), 68 PINCTRL_PIN(PAD_GMAC0_TXD2, "GMAC0_TXD2"), 69 PINCTRL_PIN(PAD_GMAC0_TXD3, "GMAC0_TXD3"), 70 PINCTRL_PIN(PAD_GMAC0_TXEN, "GMAC0_TXEN"), 71 PINCTRL_PIN(PAD_GMAC0_TXC, "GMAC0_TXC"), 72 }; 73 74 static int jh7110_aon_set_one_pin_mux(struct jh7110_pinctrl *sfp, 75 unsigned int pin, 76 unsigned int din, u32 dout, 77 u32 doen, u32 func) 78 { 79 if (pin < sfp->gc.ngpio && func == 0) 80 jh7110_set_gpiomux(sfp, pin, din, dout, doen); 81 82 return 0; 83 } 84 85 static int jh7110_aon_get_padcfg_base(struct jh7110_pinctrl *sfp, 86 unsigned int pin) 87 { 88 if (pin < PAD_GMAC0_MDC) 89 return JH7110_AON_GPO_PDA_0_5_CFG; 90 91 return -1; 92 } 93 94 static void jh7110_aon_irq_handler(struct irq_desc *desc) 95 { 96 struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc); 97 struct irq_chip *chip = irq_desc_get_chip(desc); 98 unsigned long mis; 99 unsigned int pin; 100 101 chained_irq_enter(chip, desc); 102 103 mis = readl_relaxed(sfp->base + JH7110_AON_GPIOMIS); 104 for_each_set_bit(pin, &mis, JH7110_AON_NGPIO) 105 generic_handle_domain_irq(sfp->gc.irq.domain, pin); 106 107 chained_irq_exit(chip, desc); 108 } 109 110 static int jh7110_aon_init_hw(struct gpio_chip *gc) 111 { 112 struct jh7110_pinctrl *sfp = container_of(gc, 113 struct jh7110_pinctrl, gc); 114 115 /* mask all GPIO interrupts */ 116 writel_relaxed(0, sfp->base + JH7110_AON_GPIOIE); 117 /* clear edge interrupt flags */ 118 writel_relaxed(0, sfp->base + JH7110_AON_GPIOIC); 119 writel_relaxed(0x0f, sfp->base + JH7110_AON_GPIOIC); 120 /* enable GPIO interrupts */ 121 writel_relaxed(1, sfp->base + JH7110_AON_GPIOEN); 122 return 0; 123 } 124 125 static const struct jh7110_gpio_irq_reg jh7110_aon_irq_reg = { 126 .is_reg_base = JH7110_AON_GPIOIS, 127 .ic_reg_base = JH7110_AON_GPIOIC, 128 .ibe_reg_base = JH7110_AON_GPIOIBE, 129 .iev_reg_base = JH7110_AON_GPIOIEV, 130 .ie_reg_base = JH7110_AON_GPIOIE, 131 .ris_reg_base = JH7110_AON_GPIORIS, 132 .mis_reg_base = JH7110_AON_GPIOMIS, 133 }; 134 135 static const struct jh7110_pinctrl_soc_info jh7110_aon_pinctrl_info = { 136 .pins = jh7110_aon_pins, 137 .npins = ARRAY_SIZE(jh7110_aon_pins), 138 .ngpios = JH7110_AON_NGPIO, 139 .gc_base = JH7110_AON_GC_BASE, 140 .dout_reg_base = JH7110_AON_DOUT, 141 .dout_mask = GENMASK(3, 0), 142 .doen_reg_base = JH7110_AON_DOEN, 143 .doen_mask = GENMASK(2, 0), 144 .gpi_reg_base = JH7110_AON_GPI, 145 .gpi_mask = GENMASK(3, 0), 146 .gpioin_reg_base = JH7110_AON_GPIOIN, 147 .irq_reg = &jh7110_aon_irq_reg, 148 .jh7110_set_one_pin_mux = jh7110_aon_set_one_pin_mux, 149 .jh7110_get_padcfg_base = jh7110_aon_get_padcfg_base, 150 .jh7110_gpio_irq_handler = jh7110_aon_irq_handler, 151 .jh7110_gpio_init_hw = jh7110_aon_init_hw, 152 }; 153 154 static const struct of_device_id jh7110_aon_pinctrl_of_match[] = { 155 { 156 .compatible = "starfive,jh7110-aon-pinctrl", 157 .data = &jh7110_aon_pinctrl_info, 158 }, 159 { /* sentinel */ } 160 }; 161 MODULE_DEVICE_TABLE(of, jh7110_aon_pinctrl_of_match); 162 163 static struct platform_driver jh7110_aon_pinctrl_driver = { 164 .probe = jh7110_pinctrl_probe, 165 .driver = { 166 .name = "starfive-jh7110-aon-pinctrl", 167 .of_match_table = jh7110_aon_pinctrl_of_match, 168 }, 169 }; 170 module_platform_driver(jh7110_aon_pinctrl_driver); 171 172 MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC aon controller"); 173 MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>"); 174 MODULE_LICENSE("GPL"); 175