blob: c74163e026a4f6d41f7860e96c5bd17042ea40a0 [file] [log] [blame]
Kever Yangd439a462017-02-23 15:37:53 +08001/*
2 * (C) Copyright 2016 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <errno.h>
10#include <syscon.h>
11#include <asm/arch/clock.h>
12#include <asm/arch/hardware.h>
13#include <asm/arch/grf_rk3328.h>
14#include <asm/arch/periph.h>
15#include <asm/io.h>
16#include <dm/pinctrl.h>
17
18DECLARE_GLOBAL_DATA_PTR;
19
20struct rk3328_pinctrl_priv {
21 struct rk3328_grf_regs *grf;
22};
23
Kever Yangd439a462017-02-23 15:37:53 +080024static void pinctrl_rk3328_pwm_config(struct rk3328_grf_regs *grf, int pwm_id)
25{
26 switch (pwm_id) {
27 case PERIPH_ID_PWM0:
28 rk_clrsetreg(&grf->gpio2a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +080029 GPIO2A4_SEL_MASK,
30 GPIO2A4_PWM_0 << GPIO2A4_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +080031 break;
32 case PERIPH_ID_PWM1:
33 rk_clrsetreg(&grf->gpio2a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +080034 GPIO2A5_SEL_MASK,
35 GPIO2A5_PWM_1 << GPIO2A5_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +080036 break;
37 case PERIPH_ID_PWM2:
38 rk_clrsetreg(&grf->gpio2a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +080039 GPIO2A6_SEL_MASK,
40 GPIO2A6_PWM_2 << GPIO2A6_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +080041 break;
42 case PERIPH_ID_PWM3:
43 rk_clrsetreg(&grf->gpio2a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +080044 GPIO2A2_SEL_MASK,
45 GPIO2A2_PWM_IR << GPIO2A2_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +080046 break;
47 default:
48 debug("pwm id = %d iomux error!\n", pwm_id);
49 break;
50 }
51}
52
53static void pinctrl_rk3328_i2c_config(struct rk3328_grf_regs *grf, int i2c_id)
54{
55 switch (i2c_id) {
56 case PERIPH_ID_I2C0:
57 rk_clrsetreg(&grf->gpio2d_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +080058 GPIO2D0_SEL_MASK | GPIO2D1_SEL_MASK,
59 GPIO2D0_I2C0_SCL << GPIO2D0_SEL_SHIFT |
60 GPIO2D1_I2C0_SDA << GPIO2D1_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +080061 break;
62 case PERIPH_ID_I2C1:
63 rk_clrsetreg(&grf->gpio2a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +080064 GPIO2A4_SEL_MASK | GPIO2A5_SEL_MASK,
65 GPIO2A5_I2C1_SCL << GPIO2A5_SEL_SHIFT |
66 GPIO2A4_I2C1_SDA << GPIO2A4_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +080067 break;
68 case PERIPH_ID_I2C2:
69 rk_clrsetreg(&grf->gpio2bl_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +080070 GPIO2BL5_SEL_MASK | GPIO2BL6_SEL_MASK,
71 GPIO2BL6_I2C2_SCL << GPIO2BL6_SEL_SHIFT |
72 GPIO2BL5_I2C2_SDA << GPIO2BL5_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +080073 break;
74 case PERIPH_ID_I2C3:
75 rk_clrsetreg(&grf->gpio0a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +080076 GPIO0A5_SEL_MASK | GPIO0A6_SEL_MASK,
77 GPIO0A5_I2C3_SCL << GPIO0A5_SEL_SHIFT |
78 GPIO0A6_I2C3_SDA << GPIO0A6_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +080079 break;
80 default:
81 debug("i2c id = %d iomux error!\n", i2c_id);
82 break;
83 }
84}
85
86static void pinctrl_rk3328_lcdc_config(struct rk3328_grf_regs *grf, int lcd_id)
87{
88 switch (lcd_id) {
89 case PERIPH_ID_LCDC0:
90 break;
91 default:
92 debug("lcdc id = %d iomux error!\n", lcd_id);
93 break;
94 }
95}
96
97static int pinctrl_rk3328_spi_config(struct rk3328_grf_regs *grf,
98 enum periph_id spi_id, int cs)
99{
Kever Yang077eb312017-05-17 11:44:44 +0800100 u32 com_iomux = readl(&grf->com_iomux);
101
102 if ((com_iomux & IOMUX_SEL_SPI_MASK) !=
103 IOMUX_SEL_SPI_M0 << IOMUX_SEL_SPI_SHIFT) {
104 debug("driver do not support iomux other than m0\n");
105 goto err;
106 }
Kever Yangd439a462017-02-23 15:37:53 +0800107
108 switch (spi_id) {
109 case PERIPH_ID_SPI0:
110 switch (cs) {
111 case 0:
112 rk_clrsetreg(&grf->gpio2bl_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +0800113 GPIO2BL3_SEL_MASK,
114 GPIO2BL3_SPI_CSN0_M0
115 << GPIO2BL3_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800116 break;
117 case 1:
118 rk_clrsetreg(&grf->gpio2bl_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +0800119 GPIO2BL4_SEL_MASK,
120 GPIO2BL4_SPI_CSN1_M0
121 << GPIO2BL4_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800122 break;
123 default:
124 goto err;
125 }
126 rk_clrsetreg(&grf->gpio2bl_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +0800127 GPIO2BL0_SEL_MASK,
128 GPIO2BL0_SPI_CLK_TX_RX_M0 << GPIO2BL0_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800129 break;
130 default:
131 goto err;
132 }
133
134 return 0;
135err:
136 debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
137 return -ENOENT;
138}
139
140static void pinctrl_rk3328_uart_config(struct rk3328_grf_regs *grf, int uart_id)
141{
Kever Yang077eb312017-05-17 11:44:44 +0800142 u32 com_iomux = readl(&grf->com_iomux);
143
Kever Yangd439a462017-02-23 15:37:53 +0800144 switch (uart_id) {
145 case PERIPH_ID_UART2:
146 break;
Kever Yang077eb312017-05-17 11:44:44 +0800147 if (com_iomux & IOMUX_SEL_UART2_MASK)
148 rk_clrsetreg(&grf->gpio2a_iomux,
149 GPIO2A0_SEL_MASK | GPIO2A1_SEL_MASK,
150 GPIO2A0_UART2_TX_M1 << GPIO2A0_SEL_SHIFT |
151 GPIO2A1_UART2_RX_M1 << GPIO2A1_SEL_SHIFT);
152
Kever Yangd439a462017-02-23 15:37:53 +0800153 break;
154 case PERIPH_ID_UART0:
155 case PERIPH_ID_UART1:
156 case PERIPH_ID_UART3:
157 case PERIPH_ID_UART4:
158 default:
159 debug("uart id = %d iomux error!\n", uart_id);
160 break;
161 }
162}
163
164static void pinctrl_rk3328_sdmmc_config(struct rk3328_grf_regs *grf,
165 int mmc_id)
166{
Kever Yang077eb312017-05-17 11:44:44 +0800167 u32 com_iomux = readl(&grf->com_iomux);
168
Kever Yangd439a462017-02-23 15:37:53 +0800169 switch (mmc_id) {
170 case PERIPH_ID_EMMC:
171 rk_clrsetreg(&grf->gpio0a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +0800172 GPIO0A7_SEL_MASK,
173 GPIO0A7_EMMC_DATA0 << GPIO0A7_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800174 rk_clrsetreg(&grf->gpio2d_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +0800175 GPIO2D4_SEL_MASK,
176 GPIO2D4_EMMC_DATA1234 << GPIO2D4_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800177 rk_clrsetreg(&grf->gpio3c_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +0800178 GPIO3C0_SEL_MASK,
179 GPIO3C0_EMMC_DATA567_PWR_CLK_RSTN_CMD
180 << GPIO3C0_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800181 break;
182 case PERIPH_ID_SDCARD:
Kever Yang077eb312017-05-17 11:44:44 +0800183 /* SDMMC_PWREN use GPIO and init as regulator-fiexed */
184 if (com_iomux & IOMUX_SEL_SDMMC_MASK)
185 rk_clrsetreg(&grf->gpio0d_iomux,
186 GPIO0D6_SEL_MASK,
Kever Yangfe450892017-06-08 15:32:04 +0800187 GPIO0D6_GPIO << GPIO0D6_SEL_SHIFT);
Kever Yang077eb312017-05-17 11:44:44 +0800188 else
189 rk_clrsetreg(&grf->gpio2a_iomux,
190 GPIO2A7_SEL_MASK,
Kever Yangfe450892017-06-08 15:32:04 +0800191 GPIO2A7_GPIO << GPIO2A7_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800192 rk_clrsetreg(&grf->gpio1a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +0800193 GPIO1A0_SEL_MASK,
194 GPIO1A0_CARD_DATA_CLK_CMD_DETN
195 << GPIO1A0_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800196 break;
197 default:
198 debug("mmc id = %d iomux error!\n", mmc_id);
199 break;
200 }
201}
202
203static int rk3328_pinctrl_request(struct udevice *dev, int func, int flags)
204{
205 struct rk3328_pinctrl_priv *priv = dev_get_priv(dev);
206
207 debug("%s: func=%x, flags=%x\n", __func__, func, flags);
208 switch (func) {
209 case PERIPH_ID_PWM0:
210 case PERIPH_ID_PWM1:
211 case PERIPH_ID_PWM2:
212 case PERIPH_ID_PWM3:
213 pinctrl_rk3328_pwm_config(priv->grf, func);
214 break;
215 case PERIPH_ID_I2C0:
216 case PERIPH_ID_I2C1:
217 case PERIPH_ID_I2C2:
218 case PERIPH_ID_I2C3:
219 pinctrl_rk3328_i2c_config(priv->grf, func);
220 break;
221 case PERIPH_ID_SPI0:
222 pinctrl_rk3328_spi_config(priv->grf, func, flags);
223 break;
224 case PERIPH_ID_UART0:
225 case PERIPH_ID_UART1:
226 case PERIPH_ID_UART2:
227 case PERIPH_ID_UART3:
228 case PERIPH_ID_UART4:
229 pinctrl_rk3328_uart_config(priv->grf, func);
230 break;
231 case PERIPH_ID_LCDC0:
232 case PERIPH_ID_LCDC1:
233 pinctrl_rk3328_lcdc_config(priv->grf, func);
234 break;
235 case PERIPH_ID_SDMMC0:
236 case PERIPH_ID_SDMMC1:
237 pinctrl_rk3328_sdmmc_config(priv->grf, func);
238 break;
239 default:
240 return -EINVAL;
241 }
242
243 return 0;
244}
245
246static int rk3328_pinctrl_get_periph_id(struct udevice *dev,
247 struct udevice *periph)
248{
249 u32 cell[3];
250 int ret;
251
Philipp Tomsich9f4f9142017-06-07 18:45:57 +0200252 ret = dev_read_u32_array(periph, "interrupts", cell, ARRAY_SIZE(cell));
Kever Yangd439a462017-02-23 15:37:53 +0800253 if (ret < 0)
254 return -EINVAL;
255
256 switch (cell[1]) {
257 case 49:
258 return PERIPH_ID_SPI0;
259 case 50:
260 return PERIPH_ID_PWM0;
261 case 36:
262 return PERIPH_ID_I2C0;
263 case 37: /* Note strange order */
264 return PERIPH_ID_I2C1;
265 case 38:
266 return PERIPH_ID_I2C2;
267 case 39:
268 return PERIPH_ID_I2C3;
269 case 12:
270 return PERIPH_ID_SDCARD;
271 case 14:
272 return PERIPH_ID_EMMC;
273 }
274
275 return -ENOENT;
276}
277
278static int rk3328_pinctrl_set_state_simple(struct udevice *dev,
279 struct udevice *periph)
280{
281 int func;
282
283 func = rk3328_pinctrl_get_periph_id(dev, periph);
284 if (func < 0)
285 return func;
286
287 return rk3328_pinctrl_request(dev, func, 0);
288}
289
290static struct pinctrl_ops rk3328_pinctrl_ops = {
291 .set_state_simple = rk3328_pinctrl_set_state_simple,
292 .request = rk3328_pinctrl_request,
293 .get_periph_id = rk3328_pinctrl_get_periph_id,
294};
295
296static int rk3328_pinctrl_probe(struct udevice *dev)
297{
298 struct rk3328_pinctrl_priv *priv = dev_get_priv(dev);
299 int ret = 0;
300
301 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
302 debug("%s: grf=%p\n", __func__, priv->grf);
303
304 return ret;
305}
306
307static const struct udevice_id rk3328_pinctrl_ids[] = {
308 { .compatible = "rockchip,rk3328-pinctrl" },
309 { }
310};
311
312U_BOOT_DRIVER(pinctrl_rk3328) = {
313 .name = "rockchip_rk3328_pinctrl",
314 .id = UCLASS_PINCTRL,
315 .of_match = rk3328_pinctrl_ids,
316 .priv_auto_alloc_size = sizeof(struct rk3328_pinctrl_priv),
317 .ops = &rk3328_pinctrl_ops,
318 .bind = dm_scan_fdt_dev,
319 .probe = rk3328_pinctrl_probe,
320};