]>
Commit | Line | Data |
---|---|---|
b1170c42 JH |
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> | |
060f03e9 | 13 | #include <linux/mod_devicetable.h> |
b1170c42 | 14 | #include <linux/module.h> |
b1170c42 JH |
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 | ||
64061b67 HF |
34 | #define JH7110_AON_REGS_NUM 37 |
35 | ||
b1170c42 JH |
36 | /* registers */ |
37 | #define JH7110_AON_DOEN 0x0 | |
38 | #define JH7110_AON_DOUT 0x4 | |
39 | #define JH7110_AON_GPI 0x8 | |
40 | #define JH7110_AON_GPIOIN 0x2c | |
41 | ||
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 | |
50 | ||
51 | #define JH7110_AON_GPO_PDA_0_5_CFG 0x30 | |
52 | ||
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"), | |
74 | }; | |
75 | ||
76 | static int jh7110_aon_set_one_pin_mux(struct jh7110_pinctrl *sfp, | |
77 | unsigned int pin, | |
78 | unsigned int din, u32 dout, | |
79 | u32 doen, u32 func) | |
80 | { | |
81 | if (pin < sfp->gc.ngpio && func == 0) | |
82 | jh7110_set_gpiomux(sfp, pin, din, dout, doen); | |
83 | ||
84 | return 0; | |
85 | } | |
86 | ||
87 | static int jh7110_aon_get_padcfg_base(struct jh7110_pinctrl *sfp, | |
88 | unsigned int pin) | |
89 | { | |
90 | if (pin < PAD_GMAC0_MDC) | |
91 | return JH7110_AON_GPO_PDA_0_5_CFG; | |
92 | ||
93 | return -1; | |
94 | } | |
95 | ||
96 | static void jh7110_aon_irq_handler(struct irq_desc *desc) | |
97 | { | |
98 | struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc); | |
99 | struct irq_chip *chip = irq_desc_get_chip(desc); | |
100 | unsigned long mis; | |
101 | unsigned int pin; | |
102 | ||
103 | chained_irq_enter(chip, desc); | |
104 | ||
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); | |
108 | ||
109 | chained_irq_exit(chip, desc); | |
110 | } | |
111 | ||
112 | static int jh7110_aon_init_hw(struct gpio_chip *gc) | |
113 | { | |
114 | struct jh7110_pinctrl *sfp = container_of(gc, | |
115 | struct jh7110_pinctrl, gc); | |
116 | ||
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); | |
124 | return 0; | |
125 | } | |
126 | ||
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, | |
135 | }; | |
136 | ||
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, | |
64061b67 | 150 | .nsaved_regs = JH7110_AON_REGS_NUM, |
b1170c42 JH |
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, | |
155 | }; | |
156 | ||
157 | static const struct of_device_id jh7110_aon_pinctrl_of_match[] = { | |
158 | { | |
159 | .compatible = "starfive,jh7110-aon-pinctrl", | |
160 | .data = &jh7110_aon_pinctrl_info, | |
161 | }, | |
162 | { /* sentinel */ } | |
163 | }; | |
164 | MODULE_DEVICE_TABLE(of, jh7110_aon_pinctrl_of_match); | |
165 | ||
166 | static struct platform_driver jh7110_aon_pinctrl_driver = { | |
167 | .probe = jh7110_pinctrl_probe, | |
168 | .driver = { | |
169 | .name = "starfive-jh7110-aon-pinctrl", | |
170 | .of_match_table = jh7110_aon_pinctrl_of_match, | |
64061b67 | 171 | .pm = pm_sleep_ptr(&jh7110_pinctrl_pm_ops), |
b1170c42 JH |
172 | }, |
173 | }; | |
174 | module_platform_driver(jh7110_aon_pinctrl_driver); | |
175 | ||
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"); |