1 // SPDX-License-Identifier: GPL-2.0
3 * Pinctrl / GPIO driver for StarFive JH7110 SoC aon controller
5 * Copyright (C) 2022 StarFive Technology Co., Ltd.
9 #include <linux/gpio/driver.h>
10 #include <linux/init.h>
11 #include <linux/interrupt.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>
24 #include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
27 #include "../pinconf.h"
28 #include "../pinmux.h"
29 #include "pinctrl-starfive-jh7110.h"
31 #define JH7110_AON_NGPIO 4
32 #define JH7110_AON_GC_BASE 64
34 #define JH7110_AON_REGS_NUM 37
37 #define JH7110_AON_DOEN 0x0
38 #define JH7110_AON_DOUT 0x4
39 #define JH7110_AON_GPI 0x8
40 #define JH7110_AON_GPIOIN 0x2c
42 #define JH7110_AON_GPIOEN 0xc
43 #define JH7110_AON_GPIOIS 0x10
44 #define JH7110_AON_GPIOIC 0x14
45 #define JH7110_AON_GPIOIBE 0x18
46 #define JH7110_AON_GPIOIEV 0x1c
47 #define JH7110_AON_GPIOIE 0x20
48 #define JH7110_AON_GPIORIS 0x28
49 #define JH7110_AON_GPIOMIS 0x28
51 #define JH7110_AON_GPO_PDA_0_5_CFG 0x30
53 static const struct pinctrl_pin_desc jh7110_aon_pins
[] = {
54 PINCTRL_PIN(PAD_TESTEN
, "TESTEN"),
55 PINCTRL_PIN(PAD_RGPIO0
, "RGPIO0"),
56 PINCTRL_PIN(PAD_RGPIO1
, "RGPIO1"),
57 PINCTRL_PIN(PAD_RGPIO2
, "RGPIO2"),
58 PINCTRL_PIN(PAD_RGPIO3
, "RGPIO3"),
59 PINCTRL_PIN(PAD_RSTN
, "RSTN"),
60 PINCTRL_PIN(PAD_GMAC0_MDC
, "GMAC0_MDC"),
61 PINCTRL_PIN(PAD_GMAC0_MDIO
, "GMAC0_MDIO"),
62 PINCTRL_PIN(PAD_GMAC0_RXD0
, "GMAC0_RXD0"),
63 PINCTRL_PIN(PAD_GMAC0_RXD1
, "GMAC0_RXD1"),
64 PINCTRL_PIN(PAD_GMAC0_RXD2
, "GMAC0_RXD2"),
65 PINCTRL_PIN(PAD_GMAC0_RXD3
, "GMAC0_RXD3"),
66 PINCTRL_PIN(PAD_GMAC0_RXDV
, "GMAC0_RXDV"),
67 PINCTRL_PIN(PAD_GMAC0_RXC
, "GMAC0_RXC"),
68 PINCTRL_PIN(PAD_GMAC0_TXD0
, "GMAC0_TXD0"),
69 PINCTRL_PIN(PAD_GMAC0_TXD1
, "GMAC0_TXD1"),
70 PINCTRL_PIN(PAD_GMAC0_TXD2
, "GMAC0_TXD2"),
71 PINCTRL_PIN(PAD_GMAC0_TXD3
, "GMAC0_TXD3"),
72 PINCTRL_PIN(PAD_GMAC0_TXEN
, "GMAC0_TXEN"),
73 PINCTRL_PIN(PAD_GMAC0_TXC
, "GMAC0_TXC"),
76 static int jh7110_aon_set_one_pin_mux(struct jh7110_pinctrl
*sfp
,
78 unsigned int din
, u32 dout
,
81 if (pin
< sfp
->gc
.ngpio
&& func
== 0)
82 jh7110_set_gpiomux(sfp
, pin
, din
, dout
, doen
);
87 static int jh7110_aon_get_padcfg_base(struct jh7110_pinctrl
*sfp
,
90 if (pin
< PAD_GMAC0_MDC
)
91 return JH7110_AON_GPO_PDA_0_5_CFG
;
96 static void jh7110_aon_irq_handler(struct irq_desc
*desc
)
98 struct jh7110_pinctrl
*sfp
= jh7110_from_irq_desc(desc
);
99 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
103 chained_irq_enter(chip
, desc
);
105 mis
= readl_relaxed(sfp
->base
+ JH7110_AON_GPIOMIS
);
106 for_each_set_bit(pin
, &mis
, JH7110_AON_NGPIO
)
107 generic_handle_domain_irq(sfp
->gc
.irq
.domain
, pin
);
109 chained_irq_exit(chip
, desc
);
112 static int jh7110_aon_init_hw(struct gpio_chip
*gc
)
114 struct jh7110_pinctrl
*sfp
= container_of(gc
,
115 struct jh7110_pinctrl
, gc
);
117 /* mask all GPIO interrupts */
118 writel_relaxed(0, sfp
->base
+ JH7110_AON_GPIOIE
);
119 /* clear edge interrupt flags */
120 writel_relaxed(0, sfp
->base
+ JH7110_AON_GPIOIC
);
121 writel_relaxed(0x0f, sfp
->base
+ JH7110_AON_GPIOIC
);
122 /* enable GPIO interrupts */
123 writel_relaxed(1, sfp
->base
+ JH7110_AON_GPIOEN
);
127 static const struct jh7110_gpio_irq_reg jh7110_aon_irq_reg
= {
128 .is_reg_base
= JH7110_AON_GPIOIS
,
129 .ic_reg_base
= JH7110_AON_GPIOIC
,
130 .ibe_reg_base
= JH7110_AON_GPIOIBE
,
131 .iev_reg_base
= JH7110_AON_GPIOIEV
,
132 .ie_reg_base
= JH7110_AON_GPIOIE
,
133 .ris_reg_base
= JH7110_AON_GPIORIS
,
134 .mis_reg_base
= JH7110_AON_GPIOMIS
,
137 static const struct jh7110_pinctrl_soc_info jh7110_aon_pinctrl_info
= {
138 .pins
= jh7110_aon_pins
,
139 .npins
= ARRAY_SIZE(jh7110_aon_pins
),
140 .ngpios
= JH7110_AON_NGPIO
,
141 .gc_base
= JH7110_AON_GC_BASE
,
142 .dout_reg_base
= JH7110_AON_DOUT
,
143 .dout_mask
= GENMASK(3, 0),
144 .doen_reg_base
= JH7110_AON_DOEN
,
145 .doen_mask
= GENMASK(2, 0),
146 .gpi_reg_base
= JH7110_AON_GPI
,
147 .gpi_mask
= GENMASK(3, 0),
148 .gpioin_reg_base
= JH7110_AON_GPIOIN
,
149 .irq_reg
= &jh7110_aon_irq_reg
,
150 .nsaved_regs
= JH7110_AON_REGS_NUM
,
151 .jh7110_set_one_pin_mux
= jh7110_aon_set_one_pin_mux
,
152 .jh7110_get_padcfg_base
= jh7110_aon_get_padcfg_base
,
153 .jh7110_gpio_irq_handler
= jh7110_aon_irq_handler
,
154 .jh7110_gpio_init_hw
= jh7110_aon_init_hw
,
157 static const struct of_device_id jh7110_aon_pinctrl_of_match
[] = {
159 .compatible
= "starfive,jh7110-aon-pinctrl",
160 .data
= &jh7110_aon_pinctrl_info
,
164 MODULE_DEVICE_TABLE(of
, jh7110_aon_pinctrl_of_match
);
166 static struct platform_driver jh7110_aon_pinctrl_driver
= {
167 .probe
= jh7110_pinctrl_probe
,
169 .name
= "starfive-jh7110-aon-pinctrl",
170 .of_match_table
= jh7110_aon_pinctrl_of_match
,
171 .pm
= pm_sleep_ptr(&jh7110_pinctrl_pm_ops
),
174 module_platform_driver(jh7110_aon_pinctrl_driver
);
176 MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC aon controller");
177 MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
178 MODULE_LICENSE("GPL");