blob: 9215d6c96e2752d2110b0072cc2e28f801da9825 [file] [log] [blame]
huang lin49ecaa92015-11-17 14:20:20 +08001/*
2 * Pinctrl driver for Rockchip 3036 SoCs
3 * (C) Copyright 2015 Rockchip Electronics Co., Ltd
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
9#include <dm.h>
10#include <errno.h>
11#include <syscon.h>
12#include <asm/io.h>
13#include <asm/arch/clock.h>
14#include <asm/arch/grf_rk3036.h>
15#include <asm/arch/hardware.h>
16#include <asm/arch/periph.h>
17#include <dm/pinctrl.h>
18
19DECLARE_GLOBAL_DATA_PTR;
20
21struct rk3036_pinctrl_priv {
22 struct rk3036_grf *grf;
23};
24
25static void pinctrl_rk3036_pwm_config(struct rk3036_grf *grf, int pwm_id)
26{
27 switch (pwm_id) {
28 case PERIPH_ID_PWM0:
Kever Yang3c421f62017-05-15 20:52:17 +080029 rk_clrsetreg(&grf->gpio0d_iomux, GPIO0D2_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080030 GPIO0D2_PWM0 << GPIO0D2_SHIFT);
31 break;
32 case PERIPH_ID_PWM1:
Kever Yang3c421f62017-05-15 20:52:17 +080033 rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A0_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080034 GPIO0A0_PWM1 << GPIO0A0_SHIFT);
35 break;
36 case PERIPH_ID_PWM2:
Kever Yang3c421f62017-05-15 20:52:17 +080037 rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A1_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080038 GPIO0A1_PWM2 << GPIO0A1_SHIFT);
39 break;
40 case PERIPH_ID_PWM3:
Kever Yang3c421f62017-05-15 20:52:17 +080041 rk_clrsetreg(&grf->gpio0a_iomux, GPIO0D3_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080042 GPIO0D3_PWM3 << GPIO0D3_SHIFT);
43 break;
44 default:
45 debug("pwm id = %d iomux error!\n", pwm_id);
46 break;
47 }
48}
49
50static void pinctrl_rk3036_i2c_config(struct rk3036_grf *grf, int i2c_id)
51{
52 switch (i2c_id) {
53 case PERIPH_ID_I2C0:
54 rk_clrsetreg(&grf->gpio0a_iomux,
Kever Yang3c421f62017-05-15 20:52:17 +080055 GPIO0A1_MASK | GPIO0A0_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080056 GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
57 GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
58
59 break;
60 case PERIPH_ID_I2C1:
61 rk_clrsetreg(&grf->gpio0a_iomux,
Kever Yang3c421f62017-05-15 20:52:17 +080062 GPIO0A3_MASK | GPIO0A2_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080063 GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
64 GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
65 break;
66 case PERIPH_ID_I2C2:
67 rk_clrsetreg(&grf->gpio2c_iomux,
Kever Yang3c421f62017-05-15 20:52:17 +080068 GPIO2C5_MASK | GPIO2C4_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080069 GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
70 GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
71
72 break;
73 }
74}
75
76static void pinctrl_rk3036_spi_config(struct rk3036_grf *grf, int cs)
77{
78 switch (cs) {
79 case 0:
Kever Yang3c421f62017-05-15 20:52:17 +080080 rk_clrsetreg(&grf->gpio1d_iomux, GPIO1D6_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080081 GPIO1D6_SPI_CSN0 << GPIO1D6_SHIFT);
82 break;
83 case 1:
Kever Yang3c421f62017-05-15 20:52:17 +080084 rk_clrsetreg(&grf->gpio1d_iomux, GPIO1D7_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080085 GPIO1D7_SPI_CSN1 << GPIO1D7_SHIFT);
86 break;
87 }
88 rk_clrsetreg(&grf->gpio1d_iomux,
Kever Yang3c421f62017-05-15 20:52:17 +080089 GPIO1D5_MASK | GPIO1D4_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080090 GPIO1D5_SPI_TXD << GPIO1D5_SHIFT |
91 GPIO1D4_SPI_RXD << GPIO1D4_SHIFT);
92
Kever Yang3c421f62017-05-15 20:52:17 +080093 rk_clrsetreg(&grf->gpio2a_iomux, GPIO2A0_MASK,
huang lin49ecaa92015-11-17 14:20:20 +080094 GPIO2A0_SPI_CLK << GPIO2A0_SHIFT);
95}
96
97static void pinctrl_rk3036_uart_config(struct rk3036_grf *grf, int uart_id)
98{
99 switch (uart_id) {
100 case PERIPH_ID_UART0:
101 rk_clrsetreg(&grf->gpio0c_iomux,
Kever Yang3c421f62017-05-15 20:52:17 +0800102 GPIO0C3_MASK | GPIO0C2_MASK |
103 GPIO0C1_MASK | GPIO0C0_MASK,
huang lin49ecaa92015-11-17 14:20:20 +0800104 GPIO0C3_UART0_CTSN << GPIO0C3_SHIFT |
105 GPIO0C2_UART0_RTSN << GPIO0C2_SHIFT |
106 GPIO0C1_UART0_SIN << GPIO0C1_SHIFT |
107 GPIO0C0_UART0_SOUT << GPIO0C0_SHIFT);
108 break;
109 case PERIPH_ID_UART1:
110 rk_clrsetreg(&grf->gpio2c_iomux,
Kever Yang3c421f62017-05-15 20:52:17 +0800111 GPIO2C7_MASK | GPIO2C6_MASK,
huang lin49ecaa92015-11-17 14:20:20 +0800112 GPIO2C7_UART1_SOUT << GPIO2C7_SHIFT |
113 GPIO2C6_UART1_SIN << GPIO2C6_SHIFT);
114 break;
115 case PERIPH_ID_UART2:
116 rk_clrsetreg(&grf->gpio1c_iomux,
Kever Yang3c421f62017-05-15 20:52:17 +0800117 GPIO1C3_MASK | GPIO1C2_MASK,
huang lin49ecaa92015-11-17 14:20:20 +0800118 GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
119 GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
120 break;
121 }
122}
123
124static void pinctrl_rk3036_sdmmc_config(struct rk3036_grf *grf, int mmc_id)
125{
126 switch (mmc_id) {
127 case PERIPH_ID_EMMC:
128 rk_clrsetreg(&grf->gpio1d_iomux, 0xffff,
129 GPIO1D7_EMMC_D7 << GPIO1D7_SHIFT |
130 GPIO1D6_EMMC_D6 << GPIO1D6_SHIFT |
131 GPIO1D5_EMMC_D5 << GPIO1D5_SHIFT |
132 GPIO1D4_EMMC_D4 << GPIO1D4_SHIFT |
133 GPIO1D3_EMMC_D3 << GPIO1D3_SHIFT |
134 GPIO1D2_EMMC_D2 << GPIO1D2_SHIFT |
135 GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
136 GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
137 rk_clrsetreg(&grf->gpio2a_iomux,
Kever Yang3c421f62017-05-15 20:52:17 +0800138 GPIO2A4_MASK | GPIO2A1_MASK,
huang lin49ecaa92015-11-17 14:20:20 +0800139 GPIO2A4_EMMC_CMD << GPIO2A4_SHIFT |
140 GPIO2A1_EMMC_CLKOUT << GPIO2A1_SHIFT);
141 break;
142 case PERIPH_ID_SDCARD:
143 rk_clrsetreg(&grf->gpio1c_iomux, 0xffff,
144 GPIO1C5_MMC0_D3 << GPIO1C5_SHIFT |
145 GPIO1C4_MMC0_D2 << GPIO1C4_SHIFT |
146 GPIO1C3_MMC0_D1 << GPIO1C3_SHIFT |
147 GPIO1C2_MMC0_D0 << GPIO1C2_SHIFT |
148 GPIO1C1_MMC0_DETN << GPIO1C1_SHIFT |
149 GPIO1C0_MMC0_CLKOUT << GPIO1C0_SHIFT);
150 break;
151 }
152}
153
154static int rk3036_pinctrl_request(struct udevice *dev, int func, int flags)
155{
156 struct rk3036_pinctrl_priv *priv = dev_get_priv(dev);
157
158 debug("%s: func=%x, flags=%x\n", __func__, func, flags);
159 switch (func) {
160 case PERIPH_ID_PWM0:
161 case PERIPH_ID_PWM1:
162 case PERIPH_ID_PWM2:
163 case PERIPH_ID_PWM3:
164 pinctrl_rk3036_pwm_config(priv->grf, func);
165 break;
166 case PERIPH_ID_I2C0:
167 case PERIPH_ID_I2C1:
168 case PERIPH_ID_I2C2:
169 pinctrl_rk3036_i2c_config(priv->grf, func);
170 break;
171 case PERIPH_ID_SPI0:
172 pinctrl_rk3036_spi_config(priv->grf, flags);
173 break;
174 case PERIPH_ID_UART0:
175 case PERIPH_ID_UART1:
176 case PERIPH_ID_UART2:
177 pinctrl_rk3036_uart_config(priv->grf, func);
178 break;
179 case PERIPH_ID_SDMMC0:
180 case PERIPH_ID_SDMMC1:
181 pinctrl_rk3036_sdmmc_config(priv->grf, func);
182 break;
183 default:
184 return -EINVAL;
185 }
186
187 return 0;
188}
189
190static int rk3036_pinctrl_get_periph_id(struct udevice *dev,
191 struct udevice *periph)
192{
193 u32 cell[3];
194 int ret;
195
Simon Glasse160f7d2017-01-17 16:52:55 -0700196 ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
huang lin49ecaa92015-11-17 14:20:20 +0800197 "interrupts", cell, ARRAY_SIZE(cell));
198 if (ret < 0)
199 return -EINVAL;
200
201 switch (cell[1]) {
202 case 14:
203 return PERIPH_ID_SDCARD;
204 case 16:
205 return PERIPH_ID_EMMC;
206 case 20:
207 return PERIPH_ID_UART0;
208 case 21:
209 return PERIPH_ID_UART1;
210 case 22:
211 return PERIPH_ID_UART2;
212 case 23:
213 return PERIPH_ID_SPI0;
214 case 24:
215 return PERIPH_ID_I2C0;
216 case 25:
217 return PERIPH_ID_I2C1;
218 case 26:
219 return PERIPH_ID_I2C2;
220 case 30:
221 return PERIPH_ID_PWM0;
222 }
223 return -ENOENT;
224}
225
226static int rk3036_pinctrl_set_state_simple(struct udevice *dev,
227 struct udevice *periph)
228{
229 int func;
230
231 func = rk3036_pinctrl_get_periph_id(dev, periph);
232 if (func < 0)
233 return func;
234 return rk3036_pinctrl_request(dev, func, 0);
235}
236
237static struct pinctrl_ops rk3036_pinctrl_ops = {
238 .set_state_simple = rk3036_pinctrl_set_state_simple,
239 .request = rk3036_pinctrl_request,
240 .get_periph_id = rk3036_pinctrl_get_periph_id,
241};
242
243static int rk3036_pinctrl_probe(struct udevice *dev)
244{
245 struct rk3036_pinctrl_priv *priv = dev_get_priv(dev);
246
247 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
248 debug("%s: grf=%p\n", __func__, priv->grf);
249 return 0;
250}
251
252static const struct udevice_id rk3036_pinctrl_ids[] = {
253 { .compatible = "rockchip,rk3036-pinctrl" },
254 { }
255};
256
257U_BOOT_DRIVER(pinctrl_rk3036) = {
258 .name = "pinctrl_rk3036",
259 .id = UCLASS_PINCTRL,
260 .of_match = rk3036_pinctrl_ids,
261 .priv_auto_alloc_size = sizeof(struct rk3036_pinctrl_priv),
262 .ops = &rk3036_pinctrl_ops,
Simon Glass91195482016-07-05 17:10:10 -0600263 .bind = dm_scan_fdt_dev,
huang lin49ecaa92015-11-17 14:20:20 +0800264 .probe = rk3036_pinctrl_probe,
265};