blob: d0ffeb1f0447d68c999fa2217e33b860894a1809 [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,
187 GPIO0D6_SDMMC0_PWRENM1
188 << GPIO0D6_SEL_SHIFT);
189 else
190 rk_clrsetreg(&grf->gpio2a_iomux,
191 GPIO2A7_SEL_MASK,
192 GPIO2A7_SDMMC0_PWRENM0
193 << GPIO2A7_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800194 rk_clrsetreg(&grf->gpio1a_iomux,
Kever Yang6f0c1232017-05-17 11:44:43 +0800195 GPIO1A0_SEL_MASK,
196 GPIO1A0_CARD_DATA_CLK_CMD_DETN
197 << GPIO1A0_SEL_SHIFT);
Kever Yangd439a462017-02-23 15:37:53 +0800198 break;
199 default:
200 debug("mmc id = %d iomux error!\n", mmc_id);
201 break;
202 }
203}
204
205static int rk3328_pinctrl_request(struct udevice *dev, int func, int flags)
206{
207 struct rk3328_pinctrl_priv *priv = dev_get_priv(dev);
208
209 debug("%s: func=%x, flags=%x\n", __func__, func, flags);
210 switch (func) {
211 case PERIPH_ID_PWM0:
212 case PERIPH_ID_PWM1:
213 case PERIPH_ID_PWM2:
214 case PERIPH_ID_PWM3:
215 pinctrl_rk3328_pwm_config(priv->grf, func);
216 break;
217 case PERIPH_ID_I2C0:
218 case PERIPH_ID_I2C1:
219 case PERIPH_ID_I2C2:
220 case PERIPH_ID_I2C3:
221 pinctrl_rk3328_i2c_config(priv->grf, func);
222 break;
223 case PERIPH_ID_SPI0:
224 pinctrl_rk3328_spi_config(priv->grf, func, flags);
225 break;
226 case PERIPH_ID_UART0:
227 case PERIPH_ID_UART1:
228 case PERIPH_ID_UART2:
229 case PERIPH_ID_UART3:
230 case PERIPH_ID_UART4:
231 pinctrl_rk3328_uart_config(priv->grf, func);
232 break;
233 case PERIPH_ID_LCDC0:
234 case PERIPH_ID_LCDC1:
235 pinctrl_rk3328_lcdc_config(priv->grf, func);
236 break;
237 case PERIPH_ID_SDMMC0:
238 case PERIPH_ID_SDMMC1:
239 pinctrl_rk3328_sdmmc_config(priv->grf, func);
240 break;
241 default:
242 return -EINVAL;
243 }
244
245 return 0;
246}
247
248static int rk3328_pinctrl_get_periph_id(struct udevice *dev,
249 struct udevice *periph)
250{
251 u32 cell[3];
252 int ret;
253
Simon Glassda409cc2017-05-17 17:18:09 -0600254 ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
Kever Yangd439a462017-02-23 15:37:53 +0800255 "interrupts", cell, ARRAY_SIZE(cell));
256 if (ret < 0)
257 return -EINVAL;
258
259 switch (cell[1]) {
260 case 49:
261 return PERIPH_ID_SPI0;
262 case 50:
263 return PERIPH_ID_PWM0;
264 case 36:
265 return PERIPH_ID_I2C0;
266 case 37: /* Note strange order */
267 return PERIPH_ID_I2C1;
268 case 38:
269 return PERIPH_ID_I2C2;
270 case 39:
271 return PERIPH_ID_I2C3;
272 case 12:
273 return PERIPH_ID_SDCARD;
274 case 14:
275 return PERIPH_ID_EMMC;
276 }
277
278 return -ENOENT;
279}
280
281static int rk3328_pinctrl_set_state_simple(struct udevice *dev,
282 struct udevice *periph)
283{
284 int func;
285
286 func = rk3328_pinctrl_get_periph_id(dev, periph);
287 if (func < 0)
288 return func;
289
290 return rk3328_pinctrl_request(dev, func, 0);
291}
292
293static struct pinctrl_ops rk3328_pinctrl_ops = {
294 .set_state_simple = rk3328_pinctrl_set_state_simple,
295 .request = rk3328_pinctrl_request,
296 .get_periph_id = rk3328_pinctrl_get_periph_id,
297};
298
299static int rk3328_pinctrl_probe(struct udevice *dev)
300{
301 struct rk3328_pinctrl_priv *priv = dev_get_priv(dev);
302 int ret = 0;
303
304 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
305 debug("%s: grf=%p\n", __func__, priv->grf);
306
307 return ret;
308}
309
310static const struct udevice_id rk3328_pinctrl_ids[] = {
311 { .compatible = "rockchip,rk3328-pinctrl" },
312 { }
313};
314
315U_BOOT_DRIVER(pinctrl_rk3328) = {
316 .name = "rockchip_rk3328_pinctrl",
317 .id = UCLASS_PINCTRL,
318 .of_match = rk3328_pinctrl_ids,
319 .priv_auto_alloc_size = sizeof(struct rk3328_pinctrl_priv),
320 .ops = &rk3328_pinctrl_ops,
321 .bind = dm_scan_fdt_dev,
322 .probe = rk3328_pinctrl_probe,
323};