rockchip: pinctrl: rk3368: add support for configuring the MMC pins
[platform/kernel/u-boot.git] / drivers / pinctrl / rockchip / pinctrl_rk3368.c
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  * Author: Andy Yan <andy.yan@rock-chips.com>
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <syscon.h>
10 #include <asm/io.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/hardware.h>
13 #include <asm/arch/grf_rk3368.h>
14 #include <asm/arch/periph.h>
15 #include <dm/pinctrl.h>
16
17 DECLARE_GLOBAL_DATA_PTR;
18
19 struct rk3368_pinctrl_priv {
20         struct rk3368_grf *grf;
21         struct rk3368_pmu_grf *pmugrf;
22 };
23
24 static void pinctrl_rk3368_uart_config(struct rk3368_pinctrl_priv *priv,
25                                        int uart_id)
26 {
27         struct rk3368_grf *grf = priv->grf;
28         struct rk3368_pmu_grf *pmugrf = priv->pmugrf;
29
30         switch (uart_id) {
31         case PERIPH_ID_UART2:
32                 rk_clrsetreg(&grf->gpio2a_iomux,
33                              GPIO2A6_MASK | GPIO2A5_MASK,
34                              GPIO2A6_UART2_SIN | GPIO2A5_UART2_SOUT);
35                 break;
36         case PERIPH_ID_UART0:
37                 break;
38         case PERIPH_ID_UART1:
39                 break;
40         case PERIPH_ID_UART3:
41                 break;
42         case PERIPH_ID_UART4:
43                 rk_clrsetreg(&pmugrf->gpio0d_iomux,
44                              GPIO0D0_MASK | GPIO0D1_MASK |
45                              GPIO0D2_MASK | GPIO0D3_MASK,
46                              GPIO0D0_GPIO | GPIO0D1_GPIO |
47                              GPIO0D2_UART4_SOUT | GPIO0D3_UART4_SIN);
48                 break;
49         default:
50                 debug("uart id = %d iomux error!\n", uart_id);
51                 break;
52         }
53 }
54
55 #if CONFIG_IS_ENABLED(GMAC_ROCKCHIP)
56 static void pinctrl_rk3368_gmac_config(struct rk3368_grf *grf, int gmac_id)
57 {
58         rk_clrsetreg(&grf->gpio3b_iomux,
59                      GPIO3B0_MASK | GPIO3B1_MASK |
60                      GPIO3B2_MASK | GPIO3B5_MASK |
61                      GPIO3B6_MASK | GPIO3B7_MASK,
62                      GPIO3B0_MAC_TXD0 | GPIO3B1_MAC_TXD1 |
63                      GPIO3B2_MAC_TXD2 | GPIO3B5_MAC_TXEN |
64                      GPIO3B6_MAC_TXD3 | GPIO3B7_MAC_RXD0);
65         rk_clrsetreg(&grf->gpio3c_iomux,
66                      GPIO3C0_MASK | GPIO3C1_MASK |
67                      GPIO3C2_MASK | GPIO3C3_MASK |
68                      GPIO3C4_MASK | GPIO3C5_MASK |
69                      GPIO3C6_MASK,
70                      GPIO3C0_MAC_RXD1 | GPIO3C1_MAC_RXD2 |
71                      GPIO3C2_MAC_RXD3 | GPIO3C3_MAC_MDC |
72                      GPIO3C4_MAC_RXDV | GPIO3C5_MAC_RXEN |
73                      GPIO3C6_MAC_CLK);
74         rk_clrsetreg(&grf->gpio3d_iomux,
75                      GPIO3D0_MASK | GPIO3D1_MASK |
76                      GPIO3D4_MASK,
77                      GPIO3D0_MAC_MDIO | GPIO3D1_MAC_RXCLK |
78                      GPIO3D4_MAC_TXCLK);
79 }
80 #endif
81
82 static void pinctrl_rk3368_sdmmc_config(struct rk3368_grf *grf, int mmc_id)
83 {
84         switch (mmc_id) {
85         case PERIPH_ID_EMMC:
86                 debug("mmc id = %d setting registers!\n", mmc_id);
87                 rk_clrsetreg(&grf->gpio1c_iomux,
88                              GPIO1C2_MASK | GPIO1C3_MASK |
89                              GPIO1C4_MASK | GPIO1C5_MASK |
90                              GPIO1C6_MASK | GPIO1C7_MASK,
91                              GPIO1C2_EMMC_DATA0 |
92                              GPIO1C3_EMMC_DATA1 |
93                              GPIO1C4_EMMC_DATA2 |
94                              GPIO1C5_EMMC_DATA3 |
95                              GPIO1C6_EMMC_DATA4 |
96                              GPIO1C7_EMMC_DATA5);
97                 rk_clrsetreg(&grf->gpio1d_iomux,
98                              GPIO1D0_MASK | GPIO1D1_MASK |
99                              GPIO1D2_MASK | GPIO1D3_MASK,
100                              GPIO1D0_EMMC_DATA6 |
101                              GPIO1D1_EMMC_DATA7 |
102                              GPIO1D2_EMMC_CMD |
103                              GPIO1D3_EMMC_PWREN);
104                 rk_clrsetreg(&grf->gpio2a_iomux,
105                              GPIO2A3_MASK | GPIO2A4_MASK,
106                              GPIO2A3_EMMC_RSTNOUT |
107                              GPIO2A4_EMMC_CLKOUT);
108                 break;
109         case PERIPH_ID_SDCARD:
110                 /*
111                  * We assume that the BROM has already set this up
112                  * correctly for us and that there's nothing to do
113                  * here.
114                  */
115                 break;
116         default:
117                 debug("mmc id = %d iomux error!\n", mmc_id);
118                 break;
119         }
120 }
121
122 static int rk3368_pinctrl_request(struct udevice *dev, int func, int flags)
123 {
124         struct rk3368_pinctrl_priv *priv = dev_get_priv(dev);
125
126         debug("%s: func=%d, flags=%x\n", __func__, func, flags);
127         switch (func) {
128         case PERIPH_ID_UART0:
129         case PERIPH_ID_UART1:
130         case PERIPH_ID_UART2:
131         case PERIPH_ID_UART3:
132         case PERIPH_ID_UART4:
133                 pinctrl_rk3368_uart_config(priv, func);
134                 break;
135         case PERIPH_ID_EMMC:
136         case PERIPH_ID_SDCARD:
137                 pinctrl_rk3368_sdmmc_config(priv->grf, func);
138                 break;
139 #if CONFIG_IS_ENABLED(GMAC_ROCKCHIP)
140         case PERIPH_ID_GMAC:
141                 pinctrl_rk3368_gmac_config(priv->grf, func);
142                 break;
143 #endif
144         default:
145                 return -EINVAL;
146         }
147
148         return 0;
149 }
150
151 static int rk3368_pinctrl_get_periph_id(struct udevice *dev,
152                                         struct udevice *periph)
153 {
154         u32 cell[3];
155         int ret;
156
157         ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
158                                    "interrupts", cell, ARRAY_SIZE(cell));
159         if (ret < 0)
160                 return -EINVAL;
161
162         switch (cell[1]) {
163         case 59:
164                 return PERIPH_ID_UART4;
165         case 58:
166                 return PERIPH_ID_UART3;
167         case 57:
168                 return PERIPH_ID_UART2;
169         case 56:
170                 return PERIPH_ID_UART1;
171         case 55:
172                 return PERIPH_ID_UART0;
173         case 35:
174                 return PERIPH_ID_EMMC;
175         case 32:
176                 return PERIPH_ID_SDCARD;
177 #if CONFIG_IS_ENABLED(GMAC_ROCKCHIP)
178         case 27:
179                 return PERIPH_ID_GMAC;
180 #endif
181         }
182
183         return -ENOENT;
184 }
185
186 static int rk3368_pinctrl_set_state_simple(struct udevice *dev,
187                                            struct udevice *periph)
188 {
189         int func;
190
191         func = rk3368_pinctrl_get_periph_id(dev, periph);
192         if (func < 0)
193                 return func;
194
195         return rk3368_pinctrl_request(dev, func, 0);
196 }
197
198 static struct pinctrl_ops rk3368_pinctrl_ops = {
199         .set_state_simple       = rk3368_pinctrl_set_state_simple,
200         .request        = rk3368_pinctrl_request,
201         .get_periph_id  = rk3368_pinctrl_get_periph_id,
202 };
203
204 static int rk3368_pinctrl_probe(struct udevice *dev)
205 {
206         struct rk3368_pinctrl_priv *priv = dev_get_priv(dev);
207         int ret = 0;
208
209         priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
210         priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
211
212         debug("%s: grf=%p pmugrf:%p\n", __func__, priv->grf, priv->pmugrf);
213
214         return ret;
215 }
216
217 static const struct udevice_id rk3368_pinctrl_ids[] = {
218         { .compatible = "rockchip,rk3368-pinctrl" },
219         { }
220 };
221
222 U_BOOT_DRIVER(pinctrl_rk3368) = {
223         .name           = "rockchip_rk3368_pinctrl",
224         .id             = UCLASS_PINCTRL,
225         .of_match       = rk3368_pinctrl_ids,
226         .priv_auto_alloc_size = sizeof(struct rk3368_pinctrl_priv),
227         .ops            = &rk3368_pinctrl_ops,
228         .bind           = dm_scan_fdt_dev,
229         .probe          = rk3368_pinctrl_probe,
230 };