Merge branch 'master' of git://git.denx.de/u-boot-samsung
[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 << GPIO2A6_SHIFT |
35                              GPIO2A5_UART2_SOUT << GPIO2A5_SHIFT);
36                 break;
37         case PERIPH_ID_UART0:
38                 break;
39         case PERIPH_ID_UART1:
40                 break;
41         case PERIPH_ID_UART3:
42                 break;
43         case PERIPH_ID_UART4:
44                 rk_clrsetreg(&pmugrf->gpio0d_iomux,
45                              GPIO0D0_MASK | GPIO0D1_MASK |
46                              GPIO0D2_MASK | GPIO0D3_MASK,
47                              GPIO0D0_GPIO << GPIO0D0_SHIFT |
48                              GPIO0D1_GPIO << GPIO0D1_SHIFT |
49                              GPIO0D2_UART4_SOUT << GPIO0D2_SHIFT |
50                              GPIO0D3_UART4_SIN << GPIO0D3_SHIFT);
51                 break;
52         default:
53                 debug("uart id = %d iomux error!\n", uart_id);
54                 break;
55         }
56 }
57
58 static int rk3368_pinctrl_request(struct udevice *dev, int func, int flags)
59 {
60         struct rk3368_pinctrl_priv *priv = dev_get_priv(dev);
61
62         debug("%s: func=%d, flags=%x\n", __func__, func, flags);
63         switch (func) {
64         case PERIPH_ID_UART0:
65         case PERIPH_ID_UART1:
66         case PERIPH_ID_UART2:
67         case PERIPH_ID_UART3:
68         case PERIPH_ID_UART4:
69                 pinctrl_rk3368_uart_config(priv, func);
70                 break;
71         default:
72                 return -EINVAL;
73         }
74
75         return 0;
76 }
77
78 static int rk3368_pinctrl_get_periph_id(struct udevice *dev,
79                                         struct udevice *periph)
80 {
81         u32 cell[3];
82         int ret;
83
84         ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
85                                    "interrupts", cell, ARRAY_SIZE(cell));
86         if (ret < 0)
87                 return -EINVAL;
88
89         switch (cell[1]) {
90         case 59:
91                 return PERIPH_ID_UART4;
92         case 58:
93                 return PERIPH_ID_UART3;
94         case 57:
95                 return PERIPH_ID_UART2;
96         case 56:
97                 return PERIPH_ID_UART1;
98         case 55:
99                 return PERIPH_ID_UART0;
100         }
101
102         return -ENOENT;
103 }
104
105 static int rk3368_pinctrl_set_state_simple(struct udevice *dev,
106                                            struct udevice *periph)
107 {
108         int func;
109
110         func = rk3368_pinctrl_get_periph_id(dev, periph);
111         if (func < 0)
112                 return func;
113
114         return rk3368_pinctrl_request(dev, func, 0);
115 }
116
117 static struct pinctrl_ops rk3368_pinctrl_ops = {
118         .set_state_simple       = rk3368_pinctrl_set_state_simple,
119         .request        = rk3368_pinctrl_request,
120         .get_periph_id  = rk3368_pinctrl_get_periph_id,
121 };
122
123 static int rk3368_pinctrl_probe(struct udevice *dev)
124 {
125         struct rk3368_pinctrl_priv *priv = dev_get_priv(dev);
126         int ret = 0;
127
128         priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
129         priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
130
131         debug("%s: grf=%p pmugrf:%p\n", __func__, priv->grf, priv->pmugrf);
132
133         return ret;
134 }
135
136 static const struct udevice_id rk3368_pinctrl_ids[] = {
137         { .compatible = "rockchip,rk3368-pinctrl" },
138         { }
139 };
140
141 U_BOOT_DRIVER(pinctrl_rk3368) = {
142         .name           = "rockchip_rk3368_pinctrl",
143         .id             = UCLASS_PINCTRL,
144         .of_match       = rk3368_pinctrl_ids,
145         .priv_auto_alloc_size = sizeof(struct rk3368_pinctrl_priv),
146         .ops            = &rk3368_pinctrl_ops,
147         .bind           = dm_scan_fdt_dev,
148         .probe          = rk3368_pinctrl_probe,
149 };