Wed Jan 27 02:00:02 2021 UTC ()
Use DEVICE_COMPAT_EOL.


(thorpej)
diff -r1.8 -r1.9 src/sys/arch/arm/rockchip/rk3399_iomux.c
diff -r1.8 -r1.9 src/sys/arch/arm/rockchip/rk_vop.c
diff -r1.5 -r1.6 src/sys/arch/arm/rockchip/rk_pwm.c
diff -r1.5 -r1.6 src/sys/arch/arm/rockchip/rk_v1crypto.c
diff -r1.10 -r1.11 src/sys/arch/arm/rockchip/rk_tsadc.c
diff -r1.9 -r1.10 src/sys/arch/arm/rockchip/rk_usb.c

cvs diff -r1.8 -r1.9 src/sys/arch/arm/rockchip/rk3399_iomux.c (switch to unified diff)

--- src/sys/arch/arm/rockchip/rk3399_iomux.c 2021/01/25 14:20:38 1.8
+++ src/sys/arch/arm/rockchip/rk3399_iomux.c 2021/01/27 02:00:02 1.9
@@ -1,527 +1,527 @@ @@ -1,527 +1,527 @@
1/* $NetBSD: rk3399_iomux.c,v 1.8 2021/01/25 14:20:38 thorpej Exp $ */ 1/* $NetBSD: rk3399_iomux.c,v 1.9 2021/01/27 02:00:02 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29//#define RK3399_IOMUX_DEBUG 29//#define RK3399_IOMUX_DEBUG
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: rk3399_iomux.c,v 1.8 2021/01/25 14:20:38 thorpej Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: rk3399_iomux.c,v 1.9 2021/01/27 02:00:02 thorpej Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/bus.h> 35#include <sys/bus.h>
36#include <sys/device.h> 36#include <sys/device.h>
37#include <sys/intr.h> 37#include <sys/intr.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/mutex.h> 39#include <sys/mutex.h>
40#include <sys/kmem.h> 40#include <sys/kmem.h>
41#include <sys/gpio.h> 41#include <sys/gpio.h>
42#include <sys/lwp.h> 42#include <sys/lwp.h>
43 43
44#include <dev/fdt/fdtvar.h> 44#include <dev/fdt/fdtvar.h>
45#include <dev/fdt/syscon.h> 45#include <dev/fdt/syscon.h>
46 46
47/* PU/PD control */ 47/* PU/PD control */
48#define GRF_GPIO_P_CTL(_idx) (0x3 << (((_idx) & 7) * 2)) 48#define GRF_GPIO_P_CTL(_idx) (0x3 << (((_idx) & 7) * 2))
49#define GRF_GPIO_P_WRITE_EN(_idx) (0x3 << (((_idx) & 7) * 2 + 16)) 49#define GRF_GPIO_P_WRITE_EN(_idx) (0x3 << (((_idx) & 7) * 2 + 16))
50/* Different bias value mapping based on pull type of pin */ 50/* Different bias value mapping based on pull type of pin */
51#define IO_DEF_GPIO_P_CTL_Z 0 51#define IO_DEF_GPIO_P_CTL_Z 0
52#define IO_DEF_GPIO_P_CTL_PULLUP 1 52#define IO_DEF_GPIO_P_CTL_PULLUP 1
53#define IO_DEF_GPIO_P_CTL_PULLDOWN 2 53#define IO_DEF_GPIO_P_CTL_PULLDOWN 2
54#define IO_DEF_GPIO_P_CTL_RESERVED 3 54#define IO_DEF_GPIO_P_CTL_RESERVED 3
55#define IO_1V8_GPIO_P_CTL_Z 0 55#define IO_1V8_GPIO_P_CTL_Z 0
56#define IO_1V8_GPIO_P_CTL_PULLDOWN 1 56#define IO_1V8_GPIO_P_CTL_PULLDOWN 1
57#define IO_1V8_GPIO_P_CTL_Z_ALT 2 57#define IO_1V8_GPIO_P_CTL_Z_ALT 2
58#define IO_1V8_GPIO_P_CTL_PULLUP 3 58#define IO_1V8_GPIO_P_CTL_PULLUP 3
59 59
60/* Drive strength control */ 60/* Drive strength control */
61/* Different drive strength value mapping for GRF and PMU registers */ 61/* Different drive strength value mapping for GRF and PMU registers */
62#define GRF_GPIO_E_CTL_2MA 0 62#define GRF_GPIO_E_CTL_2MA 0
63#define GRF_GPIO_E_CTL_4MA 1 63#define GRF_GPIO_E_CTL_4MA 1
64#define GRF_GPIO_E_CTL_8MA 2 64#define GRF_GPIO_E_CTL_8MA 2
65#define GRF_GPIO_E_CTL_12MA 3 65#define GRF_GPIO_E_CTL_12MA 3
66#define PMU_GPIO_E_CTL_5MA 0 66#define PMU_GPIO_E_CTL_5MA 0
67#define PMU_GPIO_E_CTL_10MA 1 67#define PMU_GPIO_E_CTL_10MA 1
68#define PMU_GPIO_E_CTL_15MA 2 68#define PMU_GPIO_E_CTL_15MA 2
69#define PMU_GPIO_E_CTL_20MA 3 69#define PMU_GPIO_E_CTL_20MA 3
70 70
71enum rk3399_drv_type { 71enum rk3399_drv_type {
72 RK3399_DRV_TYPE_IO_DEFAULT, 72 RK3399_DRV_TYPE_IO_DEFAULT,
73 RK3399_DRV_TYPE_IO_1V8_3V0, 73 RK3399_DRV_TYPE_IO_1V8_3V0,
74 RK3399_DRV_TYPE_IO_1V8, 74 RK3399_DRV_TYPE_IO_1V8,
75 RK3399_DRV_TYPE_IO_1V8_3V0_AUTO, 75 RK3399_DRV_TYPE_IO_1V8_3V0_AUTO,
76 RK3399_DRV_TYPE_IO_3V3, 76 RK3399_DRV_TYPE_IO_3V3,
77}; 77};
78 78
79static int rk3399_drv_strength[5][9] = { 79static int rk3399_drv_strength[5][9] = {
80 [RK3399_DRV_TYPE_IO_DEFAULT] = { 2, 4, 8, 12, -1 }, 80 [RK3399_DRV_TYPE_IO_DEFAULT] = { 2, 4, 8, 12, -1 },
81 [RK3399_DRV_TYPE_IO_1V8_3V0] = { 3, 6, 9, 12, -1 }, 81 [RK3399_DRV_TYPE_IO_1V8_3V0] = { 3, 6, 9, 12, -1 },
82 [RK3399_DRV_TYPE_IO_1V8] = { 5, 10, 15, 20, -1 }, 82 [RK3399_DRV_TYPE_IO_1V8] = { 5, 10, 15, 20, -1 },
83 [RK3399_DRV_TYPE_IO_1V8_3V0_AUTO] = { 4, 6, 8, 10, 12, 14, 16, 18, -1 }, 83 [RK3399_DRV_TYPE_IO_1V8_3V0_AUTO] = { 4, 6, 8, 10, 12, 14, 16, 18, -1 },
84 [RK3399_DRV_TYPE_IO_3V3] = { 4, 7, 10, 13, 16, 19, 22, 26, -1 }, 84 [RK3399_DRV_TYPE_IO_3V3] = { 4, 7, 10, 13, 16, 19, 22, 26, -1 },
85}; 85};
86 86
87enum rk3399_pull_type { 87enum rk3399_pull_type {
88 RK3399_PULL_TYPE_IO_DEFAULT, 88 RK3399_PULL_TYPE_IO_DEFAULT,
89 RK3399_PULL_TYPE_IO_1V8_ONLY, 89 RK3399_PULL_TYPE_IO_1V8_ONLY,
90}; 90};
91 91
92struct rk3399_iomux { 92struct rk3399_iomux {
93 enum rk3399_drv_type drv_type; 93 enum rk3399_drv_type drv_type;
94 enum rk3399_pull_type pull_type; 94 enum rk3399_pull_type pull_type;
95}; 95};
96 96
97struct rk3399_iomux_bank { 97struct rk3399_iomux_bank {
98 struct rk3399_iomux iomux[5]; 98 struct rk3399_iomux iomux[5];
99 u_int regs; 99 u_int regs;
100#define RK_IOMUX_REGS_GRF 0 100#define RK_IOMUX_REGS_GRF 0
101#define RK_IOMUX_REGS_PMU 1 101#define RK_IOMUX_REGS_PMU 1
102}; 102};
103 103
104static const struct rk3399_iomux_bank rk3399_iomux_banks[] = { 104static const struct rk3399_iomux_bank rk3399_iomux_banks[] = {
105 [0] = { 105 [0] = {
106 .regs = RK_IOMUX_REGS_PMU, 106 .regs = RK_IOMUX_REGS_PMU,
107 .iomux = { 107 .iomux = {
108 [0] = { .drv_type = RK3399_DRV_TYPE_IO_1V8, 108 [0] = { .drv_type = RK3399_DRV_TYPE_IO_1V8,
109 .pull_type = RK3399_PULL_TYPE_IO_1V8_ONLY }, 109 .pull_type = RK3399_PULL_TYPE_IO_1V8_ONLY },
110 [1] = { .drv_type = RK3399_DRV_TYPE_IO_1V8, 110 [1] = { .drv_type = RK3399_DRV_TYPE_IO_1V8,
111 .pull_type = RK3399_PULL_TYPE_IO_1V8_ONLY }, 111 .pull_type = RK3399_PULL_TYPE_IO_1V8_ONLY },
112 [2] = { .drv_type = RK3399_DRV_TYPE_IO_DEFAULT, 112 [2] = { .drv_type = RK3399_DRV_TYPE_IO_DEFAULT,
113 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 113 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
114 [3] = { .drv_type = RK3399_DRV_TYPE_IO_DEFAULT, 114 [3] = { .drv_type = RK3399_DRV_TYPE_IO_DEFAULT,
115 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 115 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
116 }, 116 },
117 }, 117 },
118 [1] = { 118 [1] = {
119 .regs = RK_IOMUX_REGS_PMU, 119 .regs = RK_IOMUX_REGS_PMU,
120 .iomux = { 120 .iomux = {
121 [0] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 121 [0] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
122 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 122 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
123 [1] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 123 [1] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
124 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 124 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
125 [2] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 125 [2] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
126 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 126 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
127 [3] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 127 [3] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
128 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 128 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
129 } 129 }
130 }, 130 },
131 [2] = { 131 [2] = {
132 .regs = RK_IOMUX_REGS_GRF, 132 .regs = RK_IOMUX_REGS_GRF,
133 .iomux = { 133 .iomux = {
134 [0] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 134 [0] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
135 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 135 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
136 [1] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 136 [1] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
137 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 137 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
138 [2] = { .drv_type = RK3399_DRV_TYPE_IO_1V8, 138 [2] = { .drv_type = RK3399_DRV_TYPE_IO_1V8,
139 .pull_type = RK3399_PULL_TYPE_IO_1V8_ONLY }, 139 .pull_type = RK3399_PULL_TYPE_IO_1V8_ONLY },
140 [3] = { .drv_type = RK3399_DRV_TYPE_IO_1V8, 140 [3] = { .drv_type = RK3399_DRV_TYPE_IO_1V8,
141 .pull_type = RK3399_PULL_TYPE_IO_1V8_ONLY }, 141 .pull_type = RK3399_PULL_TYPE_IO_1V8_ONLY },
142 }, 142 },
143 }, 143 },
144 [3] = { 144 [3] = {
145 .regs = RK_IOMUX_REGS_GRF, 145 .regs = RK_IOMUX_REGS_GRF,
146 .iomux = { 146 .iomux = {
147 [0] = { .drv_type = RK3399_DRV_TYPE_IO_3V3, 147 [0] = { .drv_type = RK3399_DRV_TYPE_IO_3V3,
148 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 148 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
149 [1] = { .drv_type = RK3399_DRV_TYPE_IO_3V3, 149 [1] = { .drv_type = RK3399_DRV_TYPE_IO_3V3,
150 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 150 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
151 [2] = { .drv_type = RK3399_DRV_TYPE_IO_3V3, 151 [2] = { .drv_type = RK3399_DRV_TYPE_IO_3V3,
152 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 152 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
153 [3] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 153 [3] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
154 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 154 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
155 }, 155 },
156 }, 156 },
157 [4] = { 157 [4] = {
158 .regs = RK_IOMUX_REGS_GRF, 158 .regs = RK_IOMUX_REGS_GRF,
159 .iomux = { 159 .iomux = {
160 [0] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 160 [0] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
161 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 161 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
162 [1] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0_AUTO, 162 [1] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0_AUTO,
163 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 163 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
164 [2] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 164 [2] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
165 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 165 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
166 [3] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0, 166 [3] = { .drv_type = RK3399_DRV_TYPE_IO_1V8_3V0,
167 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT }, 167 .pull_type = RK3399_PULL_TYPE_IO_DEFAULT },
168 }, 168 },
169 }, 169 },
170}; 170};
171 171
172#define RK3399_IOMUX_BANK_IS_PMU(_bank) (rk3399_iomux_banks[(_bank)].regs == RK_IOMUX_REGS_PMU) 172#define RK3399_IOMUX_BANK_IS_PMU(_bank) (rk3399_iomux_banks[(_bank)].regs == RK_IOMUX_REGS_PMU)
173 173
174struct rk3399_iomux_conf { 174struct rk3399_iomux_conf {
175 const struct rk3399_iomux_bank *banks; 175 const struct rk3399_iomux_bank *banks;
176 u_int nbanks; 176 u_int nbanks;
177}; 177};
178 178
179static const struct rk3399_iomux_conf rk3399_iomux_conf = { 179static const struct rk3399_iomux_conf rk3399_iomux_conf = {
180 .banks = rk3399_iomux_banks, 180 .banks = rk3399_iomux_banks,
181 .nbanks = __arraycount(rk3399_iomux_banks), 181 .nbanks = __arraycount(rk3399_iomux_banks),
182}; 182};
183 183
184static const struct device_compatible_entry compat_data[] = { 184static const struct device_compatible_entry compat_data[] = {
185 { .compat = "rockchip,rk3399-pinctrl", .data = &rk3399_iomux_conf }, 185 { .compat = "rockchip,rk3399-pinctrl", .data = &rk3399_iomux_conf },
186 { } 186 DEVICE_COMPAT_EOL
187}; 187};
188 188
189struct rk3399_iomux_softc { 189struct rk3399_iomux_softc {
190 device_t sc_dev; 190 device_t sc_dev;
191 struct syscon *sc_syscon[2]; 191 struct syscon *sc_syscon[2];
192 192
193 const struct rk3399_iomux_conf *sc_conf; 193 const struct rk3399_iomux_conf *sc_conf;
194}; 194};
195 195
196#define LOCK(syscon) \ 196#define LOCK(syscon) \
197 syscon_lock(syscon) 197 syscon_lock(syscon)
198#define UNLOCK(syscon) \ 198#define UNLOCK(syscon) \
199 syscon_unlock(syscon) 199 syscon_unlock(syscon)
200#define RD4(syscon, reg) \ 200#define RD4(syscon, reg) \
201 syscon_read_4(syscon, (reg)) 201 syscon_read_4(syscon, (reg))
202#define WR4(syscon, reg, val) \ 202#define WR4(syscon, reg, val) \
203 syscon_write_4(syscon, (reg), (val)) 203 syscon_write_4(syscon, (reg), (val))
204 204
205static int rk3399_iomux_match(device_t, cfdata_t, void *); 205static int rk3399_iomux_match(device_t, cfdata_t, void *);
206static void rk3399_iomux_attach(device_t, device_t, void *); 206static void rk3399_iomux_attach(device_t, device_t, void *);
207 207
208CFATTACH_DECL_NEW(rk3399_iomux, sizeof(struct rk3399_iomux_softc), 208CFATTACH_DECL_NEW(rk3399_iomux, sizeof(struct rk3399_iomux_softc),
209 rk3399_iomux_match, rk3399_iomux_attach, NULL, NULL); 209 rk3399_iomux_match, rk3399_iomux_attach, NULL, NULL);
210 210
211static void 211static void
212rk3399_iomux_set_bias(struct rk3399_iomux_softc *sc, u_int bank, u_int idx, int flags) 212rk3399_iomux_set_bias(struct rk3399_iomux_softc *sc, u_int bank, u_int idx, int flags)
213{ 213{
214 const struct rk3399_iomux_bank *banks = sc->sc_conf->banks; 214 const struct rk3399_iomux_bank *banks = sc->sc_conf->banks;
215 bus_size_t reg; 215 bus_size_t reg;
216 u_int bias; 216 u_int bias;
217 217
218 KASSERT(bank < sc->sc_conf->nbanks); 218 KASSERT(bank < sc->sc_conf->nbanks);
219 219
220 struct syscon * const syscon = sc->sc_syscon[banks[bank].regs]; 220 struct syscon * const syscon = sc->sc_syscon[banks[bank].regs];
221 if (RK3399_IOMUX_BANK_IS_PMU(bank)) { 221 if (RK3399_IOMUX_BANK_IS_PMU(bank)) {
222 reg = 0x00040 + (0x10 * bank); 222 reg = 0x00040 + (0x10 * bank);
223 } else { 223 } else {
224 reg = 0x0e040 + (0x10 * (bank - 2)); 224 reg = 0x0e040 + (0x10 * (bank - 2));
225 } 225 }
226 reg += 0x4 * (idx / 8); 226 reg += 0x4 * (idx / 8);
227 227
228 const int pull_type = banks[bank].iomux[idx / 8].pull_type; 228 const int pull_type = banks[bank].iomux[idx / 8].pull_type;
229 229
230 if (flags == GPIO_PIN_PULLUP) { 230 if (flags == GPIO_PIN_PULLUP) {
231 bias = pull_type == RK3399_PULL_TYPE_IO_DEFAULT ? 231 bias = pull_type == RK3399_PULL_TYPE_IO_DEFAULT ?
232 IO_DEF_GPIO_P_CTL_PULLUP : 232 IO_DEF_GPIO_P_CTL_PULLUP :
233 IO_1V8_GPIO_P_CTL_PULLUP; 233 IO_1V8_GPIO_P_CTL_PULLUP;
234 } else if (flags == GPIO_PIN_PULLDOWN) { 234 } else if (flags == GPIO_PIN_PULLDOWN) {
235 bias = pull_type == RK3399_PULL_TYPE_IO_DEFAULT ? 235 bias = pull_type == RK3399_PULL_TYPE_IO_DEFAULT ?
236 IO_DEF_GPIO_P_CTL_PULLDOWN : 236 IO_DEF_GPIO_P_CTL_PULLDOWN :
237 IO_1V8_GPIO_P_CTL_PULLDOWN; 237 IO_1V8_GPIO_P_CTL_PULLDOWN;
238 } else { 238 } else {
239 bias = pull_type == RK3399_PULL_TYPE_IO_DEFAULT ? 239 bias = pull_type == RK3399_PULL_TYPE_IO_DEFAULT ?
240 IO_DEF_GPIO_P_CTL_Z : 240 IO_DEF_GPIO_P_CTL_Z :
241 IO_1V8_GPIO_P_CTL_Z; 241 IO_1V8_GPIO_P_CTL_Z;
242 } 242 }
243 243
244 const uint32_t bias_val = __SHIFTIN(bias, GRF_GPIO_P_CTL(idx)); 244 const uint32_t bias_val = __SHIFTIN(bias, GRF_GPIO_P_CTL(idx));
245 const uint32_t bias_mask = GRF_GPIO_P_WRITE_EN(idx); 245 const uint32_t bias_mask = GRF_GPIO_P_WRITE_EN(idx);
246 246
247#ifdef RK3399_IOMUX_DEBUG 247#ifdef RK3399_IOMUX_DEBUG
248 printf("%s: bank %d idx %d flags %#x: %08x -> ", __func__, bank, idx, flags, RD4(syscon, reg)); 248 printf("%s: bank %d idx %d flags %#x: %08x -> ", __func__, bank, idx, flags, RD4(syscon, reg));
249#endif 249#endif
250 WR4(syscon, reg, bias_val | bias_mask); 250 WR4(syscon, reg, bias_val | bias_mask);
251#ifdef RK3399_IOMUX_DEBUG 251#ifdef RK3399_IOMUX_DEBUG
252 printf("%08x (reg %#lx)\n", RD4(syscon, reg), reg); 252 printf("%08x (reg %#lx)\n", RD4(syscon, reg), reg);
253#endif 253#endif
254} 254}
255 255
256static int 256static int
257rk3399_iomux_map_drive_strength(struct rk3399_iomux_softc *sc, enum rk3399_drv_type drv_type, u_int val) 257rk3399_iomux_map_drive_strength(struct rk3399_iomux_softc *sc, enum rk3399_drv_type drv_type, u_int val)
258{ 258{
259 for (int n = 0; rk3399_drv_strength[drv_type][n] != -1; n++) 259 for (int n = 0; rk3399_drv_strength[drv_type][n] != -1; n++)
260 if (rk3399_drv_strength[drv_type][n] == val) 260 if (rk3399_drv_strength[drv_type][n] == val)
261 return n; 261 return n;
262 return -1; 262 return -1;
263} 263}
264 264
265static int  265static int
266rk3399_iomux_set_drive_strength(struct rk3399_iomux_softc *sc, u_int bank, u_int idx, u_int val) 266rk3399_iomux_set_drive_strength(struct rk3399_iomux_softc *sc, u_int bank, u_int idx, u_int val)
267{ 267{
268 const struct rk3399_iomux_bank *banks = sc->sc_conf->banks; 268 const struct rk3399_iomux_bank *banks = sc->sc_conf->banks;
269 uint32_t drv_mask, drv_val; 269 uint32_t drv_mask, drv_val;
270 bus_size_t reg; 270 bus_size_t reg;
271 271
272 KASSERT(bank < sc->sc_conf->nbanks); 272 KASSERT(bank < sc->sc_conf->nbanks);
273 273
274 if (idx >= 32) 274 if (idx >= 32)
275 return EINVAL; 275 return EINVAL;
276 276
277 const int drv = rk3399_iomux_map_drive_strength(sc, banks[bank].iomux[idx / 8].drv_type, val); 277 const int drv = rk3399_iomux_map_drive_strength(sc, banks[bank].iomux[idx / 8].drv_type, val);
278 if (drv == -1) 278 if (drv == -1)
279 return EINVAL; 279 return EINVAL;
280 280
281 struct syscon * const syscon = sc->sc_syscon[banks[bank].regs]; 281 struct syscon * const syscon = sc->sc_syscon[banks[bank].regs];
282 switch (bank) { 282 switch (bank) {
283 case 0: 283 case 0:
284 case 1: 284 case 1:
285 reg = 0x00040 + (0x10 * bank) + 0x4 * (idx / 4); 285 reg = 0x00040 + (0x10 * bank) + 0x4 * (idx / 4);
286 drv_mask = 0x3 << ((idx & 7) * 2); 286 drv_mask = 0x3 << ((idx & 7) * 2);
287 break; 287 break;
288 case 2: 288 case 2:
289 reg = 0x0e100 + 0x4 * (idx / 4); 289 reg = 0x0e100 + 0x4 * (idx / 4);
290 drv_mask = 0x3 << ((idx & 7) * 2); 290 drv_mask = 0x3 << ((idx & 7) * 2);
291 break; 291 break;
292 case 3: 292 case 3:
293 switch (idx / 8) { 293 switch (idx / 8) {
294 case 0: 294 case 0:
295 case 1: 295 case 1:
296 case 2: 296 case 2:
297 reg = 0x0e110 + 0x8 * (idx / 4); 297 reg = 0x0e110 + 0x8 * (idx / 4);
298 drv_mask = 0x7 << ((idx & 7) * 3); 298 drv_mask = 0x7 << ((idx & 7) * 3);
299 break; 299 break;
300 case 3: 300 case 3:
301 reg = 0x0e128; 301 reg = 0x0e128;
302 drv_mask = 0x3 << ((idx & 7) * 2); 302 drv_mask = 0x3 << ((idx & 7) * 2);
303 break; 303 break;
304 default: 304 default:
305 return EINVAL; 305 return EINVAL;
306 } 306 }
307 break; 307 break;
308 case 4: 308 case 4:
309 switch (idx / 8) { 309 switch (idx / 8) {
310 case 0: 310 case 0:
311 reg = 0x0e12c; 311 reg = 0x0e12c;
312 drv_mask = 0x3 << ((idx & 7) * 2); 312 drv_mask = 0x3 << ((idx & 7) * 2);
313 break; 313 break;
314 case 1: 314 case 1:
315 reg = 0x0e130; 315 reg = 0x0e130;
316 drv_mask = 0x7 << ((idx & 7) * 3); 316 drv_mask = 0x7 << ((idx & 7) * 3);
317 break; 317 break;
318 case 2: 318 case 2:
319 reg = 0x0e138; 319 reg = 0x0e138;
320 drv_mask = 0x3 << ((idx & 7) * 2); 320 drv_mask = 0x3 << ((idx & 7) * 2);
321 break; 321 break;
322 case 3: 322 case 3:
323 reg = 0x0e13c; 323 reg = 0x0e13c;
324 drv_mask = 0x3 << ((idx & 7) * 2); 324 drv_mask = 0x3 << ((idx & 7) * 2);
325 break; 325 break;
326 default: 326 default:
327 return EINVAL; 327 return EINVAL;
328 }  328 }
329 break; 329 break;
330 default: 330 default:
331 return EINVAL; 331 return EINVAL;
332 } 332 }
333 drv_val = __SHIFTIN(val, drv_mask); 333 drv_val = __SHIFTIN(val, drv_mask);
334 334
335 while (drv_mask) { 335 while (drv_mask) {
336 const uint32_t write_val = drv_val & 0xffff; 336 const uint32_t write_val = drv_val & 0xffff;
337 const uint32_t write_mask = (drv_mask & 0xffff) << 16; 337 const uint32_t write_mask = (drv_mask & 0xffff) << 16;
338 if (write_mask) { 338 if (write_mask) {
339#ifdef RK3399_IOMUX_DEBUG 339#ifdef RK3399_IOMUX_DEBUG
340 printf("%s: bank %d idx %d val %d: %08x -> ", __func__, bank, idx, val, RD4(syscon, reg)); 340 printf("%s: bank %d idx %d val %d: %08x -> ", __func__, bank, idx, val, RD4(syscon, reg));
341#endif 341#endif
342 WR4(syscon, reg, write_val | write_mask); 342 WR4(syscon, reg, write_val | write_mask);
343#ifdef RK3399_IOMUX_DEBUG 343#ifdef RK3399_IOMUX_DEBUG
344 printf("%08x (reg %#lx)\n", RD4(syscon, reg), reg); 344 printf("%08x (reg %#lx)\n", RD4(syscon, reg), reg);
345#endif 345#endif
346 } 346 }
347 reg += 0x4; 347 reg += 0x4;
348 drv_val >>= 16; 348 drv_val >>= 16;
349 drv_mask >>= 16; 349 drv_mask >>= 16;
350 } 350 }
351 351
352 return 0; 352 return 0;
353} 353}
354 354
355static void 355static void
356rk3399_iomux_set_mux(struct rk3399_iomux_softc *sc, u_int bank, u_int idx, u_int mux) 356rk3399_iomux_set_mux(struct rk3399_iomux_softc *sc, u_int bank, u_int idx, u_int mux)
357{ 357{
358 const struct rk3399_iomux_bank *banks = sc->sc_conf->banks; 358 const struct rk3399_iomux_bank *banks = sc->sc_conf->banks;
359 bus_size_t reg; 359 bus_size_t reg;
360 uint32_t mask; 360 uint32_t mask;
361 361
362 KASSERT(bank < sc->sc_conf->nbanks); 362 KASSERT(bank < sc->sc_conf->nbanks);
363 363
364 struct syscon * const syscon = sc->sc_syscon[banks[bank].regs]; 364 struct syscon * const syscon = sc->sc_syscon[banks[bank].regs];
365 if (RK3399_IOMUX_BANK_IS_PMU(bank)) { 365 if (RK3399_IOMUX_BANK_IS_PMU(bank)) {
366 reg = 0x00000 + (0x10 * bank); 366 reg = 0x00000 + (0x10 * bank);
367 } else { 367 } else {
368 reg = 0x0e000 + (0x10 * (bank - 2)); 368 reg = 0x0e000 + (0x10 * (bank - 2));
369 } 369 }
370 reg += 0x4 * (idx / 8); 370 reg += 0x4 * (idx / 8);
371 mask = 3 << ((idx & 7) * 2); 371 mask = 3 << ((idx & 7) * 2);
372 372
373#ifdef RK3399_IOMUX_DEBUG 373#ifdef RK3399_IOMUX_DEBUG
374 printf("%s: bank %d idx %d mux %#x: %08x -> ", __func__, bank, idx, mux, RD4(syscon, reg)); 374 printf("%s: bank %d idx %d mux %#x: %08x -> ", __func__, bank, idx, mux, RD4(syscon, reg));
375#endif 375#endif
376 WR4(syscon, reg, (mask << 16) | __SHIFTIN(mux, mask)); 376 WR4(syscon, reg, (mask << 16) | __SHIFTIN(mux, mask));
377#ifdef RK3399_IOMUX_DEBUG 377#ifdef RK3399_IOMUX_DEBUG
378 printf("%08x (reg %#lx)\n", RD4(syscon, reg), reg); 378 printf("%08x (reg %#lx)\n", RD4(syscon, reg), reg);
379#endif 379#endif
380} 380}
381 381
382static int 382static int
383rk3399_iomux_config(struct rk3399_iomux_softc *sc, const int phandle, u_int bank, u_int idx, u_int mux) 383rk3399_iomux_config(struct rk3399_iomux_softc *sc, const int phandle, u_int bank, u_int idx, u_int mux)
384{ 384{
385 385
386 const int bias = fdtbus_pinctrl_parse_bias(phandle, NULL); 386 const int bias = fdtbus_pinctrl_parse_bias(phandle, NULL);
387 if (bias != -1) 387 if (bias != -1)
388 rk3399_iomux_set_bias(sc, bank, idx, bias); 388 rk3399_iomux_set_bias(sc, bank, idx, bias);
389 389
390 const int drv = fdtbus_pinctrl_parse_drive_strength(phandle); 390 const int drv = fdtbus_pinctrl_parse_drive_strength(phandle);
391 if (drv != -1 && 391 if (drv != -1 &&
392 rk3399_iomux_set_drive_strength(sc, bank, idx, drv) != 0) 392 rk3399_iomux_set_drive_strength(sc, bank, idx, drv) != 0)
393 return EINVAL; 393 return EINVAL;
394 394
395#if notyet 395#if notyet
396 int output_value; 396 int output_value;
397 const int direction = 397 const int direction =
398 fdtbus_pinctrl_parse_input_output(phandle, &output_value); 398 fdtbus_pinctrl_parse_input_output(phandle, &output_value);
399 if (direction != -1) { 399 if (direction != -1) {
400 rk3399_iomux_set_direction(sc, bank, idx, direction, 400 rk3399_iomux_set_direction(sc, bank, idx, direction,
401 output_value); 401 output_value);
402 } 402 }
403#endif 403#endif
404 404
405 rk3399_iomux_set_mux(sc, bank, idx, mux); 405 rk3399_iomux_set_mux(sc, bank, idx, mux);
406 406
407 return 0; 407 return 0;
408} 408}
409 409
410static int 410static int
411rk3399_iomux_pinctrl_set_config(device_t dev, const void *data, size_t len) 411rk3399_iomux_pinctrl_set_config(device_t dev, const void *data, size_t len)
412{ 412{
413 struct rk3399_iomux_softc * const sc = device_private(dev); 413 struct rk3399_iomux_softc * const sc = device_private(dev);
414 const struct rk3399_iomux_bank *banks = sc->sc_conf->banks; 414 const struct rk3399_iomux_bank *banks = sc->sc_conf->banks;
415 int pins_len; 415 int pins_len;
416 416
417 if (len != 4) 417 if (len != 4)
418 return -1; 418 return -1;
419 419
420 const int phandle = fdtbus_get_phandle_from_native(be32dec(data)); 420 const int phandle = fdtbus_get_phandle_from_native(be32dec(data));
421 const u_int *pins = fdtbus_get_prop(phandle, "rockchip,pins", &pins_len); 421 const u_int *pins = fdtbus_get_prop(phandle, "rockchip,pins", &pins_len);
422 422
423 while (pins_len >= 16) { 423 while (pins_len >= 16) {
424 const u_int bank = be32toh(pins[0]); 424 const u_int bank = be32toh(pins[0]);
425 const u_int idx = be32toh(pins[1]); 425 const u_int idx = be32toh(pins[1]);
426 const u_int mux = be32toh(pins[2]); 426 const u_int mux = be32toh(pins[2]);
427 const int cfg = fdtbus_get_phandle_from_native(be32toh(pins[3])); 427 const int cfg = fdtbus_get_phandle_from_native(be32toh(pins[3]));
428 428
429 struct syscon * const syscon = sc->sc_syscon[banks[bank].regs]; 429 struct syscon * const syscon = sc->sc_syscon[banks[bank].regs];
430 LOCK(syscon); 430 LOCK(syscon);
431 rk3399_iomux_config(sc, cfg, bank, idx, mux); 431 rk3399_iomux_config(sc, cfg, bank, idx, mux);
432 UNLOCK(syscon); 432 UNLOCK(syscon);
433 433
434 pins_len -= 16; 434 pins_len -= 16;
435 pins += 4; 435 pins += 4;
436 } 436 }
437 437
438 return 0; 438 return 0;
439} 439}
440 440
441static struct fdtbus_pinctrl_controller_func rk3399_iomux_pinctrl_funcs = { 441static struct fdtbus_pinctrl_controller_func rk3399_iomux_pinctrl_funcs = {
442 .set_config = rk3399_iomux_pinctrl_set_config, 442 .set_config = rk3399_iomux_pinctrl_set_config,
443}; 443};
444 444
445static int 445static int
446rk3399_iomux_match(device_t parent, cfdata_t cf, void *aux) 446rk3399_iomux_match(device_t parent, cfdata_t cf, void *aux)
447{ 447{
448 struct fdt_attach_args * const faa = aux; 448 struct fdt_attach_args * const faa = aux;
449 449
450 return of_match_compat_data(faa->faa_phandle, compat_data); 450 return of_match_compat_data(faa->faa_phandle, compat_data);
451} 451}
452 452
453#ifdef RK3399_IOMUX_FORCE_ENABLE_SWJ_DP 453#ifdef RK3399_IOMUX_FORCE_ENABLE_SWJ_DP
454/* 454/*
455 * This enables the SWJ-DP (Serial Wire JTAG Debug Port). 455 * This enables the SWJ-DP (Serial Wire JTAG Debug Port).
456 * If you enable this you must also disable sdhc due to pin conflicts. 456 * If you enable this you must also disable sdhc due to pin conflicts.
457 */ 457 */
458static void 458static void
459rk3399_iomux_force_enable_swj_dp(struct rk3399_iomux_softc * const sc) 459rk3399_iomux_force_enable_swj_dp(struct rk3399_iomux_softc * const sc)
460{ 460{
461 struct syscon * const syscon = sc->sc_syscon[RK_IOMUX_REGS_GRF]; 461 struct syscon * const syscon = sc->sc_syscon[RK_IOMUX_REGS_GRF];
462 uint32_t val; 462 uint32_t val;
463 463
464 aprint_normal_dev(sc->sc_dev, "enabling on-chip debugging\n"); 464 aprint_normal_dev(sc->sc_dev, "enabling on-chip debugging\n");
465#define GRF_GPIO4B_IOMUX 0xe024 465#define GRF_GPIO4B_IOMUX 0xe024
466#define GRF_GPIO4B_IOMUX_TCK __BITS(5,4) 466#define GRF_GPIO4B_IOMUX_TCK __BITS(5,4)
467#define GRF_GPIO4B_IOMUX_TMS __BITS(7,6) 467#define GRF_GPIO4B_IOMUX_TMS __BITS(7,6)
468#define GRF_SOC_CON7 0xe21c 468#define GRF_SOC_CON7 0xe21c
469#define GRF_SOC_CON7_FORCE_JTAG __BIT(12) 469#define GRF_SOC_CON7_FORCE_JTAG __BIT(12)
470 LOCK(syscon); 470 LOCK(syscon);
471 val = RD4(syscon, GRF_GPIO4B_IOMUX); 471 val = RD4(syscon, GRF_GPIO4B_IOMUX);
472 val &= ~(GRF_GPIO4B_IOMUX_TCK | GRF_GPIO4B_IOMUX_TMS); 472 val &= ~(GRF_GPIO4B_IOMUX_TCK | GRF_GPIO4B_IOMUX_TMS);
473 val |= __SHIFTIN(0x2, GRF_GPIO4B_IOMUX_TCK); 473 val |= __SHIFTIN(0x2, GRF_GPIO4B_IOMUX_TCK);
474 val |= __SHIFTIN(0x2, GRF_GPIO4B_IOMUX_TMS); 474 val |= __SHIFTIN(0x2, GRF_GPIO4B_IOMUX_TMS);
475 WR4(syscon, GRF_GPIO4B_IOMUX, val); 475 WR4(syscon, GRF_GPIO4B_IOMUX, val);
476 val = RD4(syscon, GRF_SOC_CON7); 476 val = RD4(syscon, GRF_SOC_CON7);
477 val |= GRF_SOC_CON7_FORCE_JTAG; 477 val |= GRF_SOC_CON7_FORCE_JTAG;
478 WR4(syscon, GRF_SOC_CON7, val); 478 WR4(syscon, GRF_SOC_CON7, val);
479 UNLOCK(syscon); 479 UNLOCK(syscon);
480} 480}
481#endif 481#endif
482 482
483static void 483static void
484rk3399_iomux_attach(device_t parent, device_t self, void *aux) 484rk3399_iomux_attach(device_t parent, device_t self, void *aux)
485{ 485{
486 struct rk3399_iomux_softc * const sc = device_private(self); 486 struct rk3399_iomux_softc * const sc = device_private(self);
487 struct fdt_attach_args * const faa = aux; 487 struct fdt_attach_args * const faa = aux;
488 const int phandle = faa->faa_phandle; 488 const int phandle = faa->faa_phandle;
489 int child, sub; 489 int child, sub;
490 490
491 sc->sc_dev = self; 491 sc->sc_dev = self;
492 sc->sc_syscon[RK_IOMUX_REGS_GRF] = fdtbus_syscon_acquire(phandle, "rockchip,grf"); 492 sc->sc_syscon[RK_IOMUX_REGS_GRF] = fdtbus_syscon_acquire(phandle, "rockchip,grf");
493 if (sc->sc_syscon[RK_IOMUX_REGS_GRF] == NULL) { 493 if (sc->sc_syscon[RK_IOMUX_REGS_GRF] == NULL) {
494 aprint_error(": couldn't acquire grf syscon\n"); 494 aprint_error(": couldn't acquire grf syscon\n");
495 return; 495 return;
496 } 496 }
497 sc->sc_syscon[RK_IOMUX_REGS_PMU] = fdtbus_syscon_acquire(phandle, "rockchip,pmu"); 497 sc->sc_syscon[RK_IOMUX_REGS_PMU] = fdtbus_syscon_acquire(phandle, "rockchip,pmu");
498 if (sc->sc_syscon[RK_IOMUX_REGS_PMU] == NULL) { 498 if (sc->sc_syscon[RK_IOMUX_REGS_PMU] == NULL) {
499 aprint_error(": couldn't acquire pmu syscon\n"); 499 aprint_error(": couldn't acquire pmu syscon\n");
500 return; 500 return;
501 } 501 }
502 sc->sc_conf = of_search_compatible(phandle, compat_data)->data; 502 sc->sc_conf = of_search_compatible(phandle, compat_data)->data;
503 503
504 aprint_naive("\n"); 504 aprint_naive("\n");
505 aprint_normal(": RK3399 IOMUX control\n"); 505 aprint_normal(": RK3399 IOMUX control\n");
506 506
507 for (child = OF_child(phandle); child; child = OF_peer(child)) { 507 for (child = OF_child(phandle); child; child = OF_peer(child)) {
508 for (sub = OF_child(child); sub; sub = OF_peer(sub)) { 508 for (sub = OF_child(child); sub; sub = OF_peer(sub)) {
509 if (!of_hasprop(sub, "rockchip,pins")) 509 if (!of_hasprop(sub, "rockchip,pins"))
510 continue; 510 continue;
511 fdtbus_register_pinctrl_config(self, sub, &rk3399_iomux_pinctrl_funcs); 511 fdtbus_register_pinctrl_config(self, sub, &rk3399_iomux_pinctrl_funcs);
512 } 512 }
513 } 513 }
514 514
515 for (child = OF_child(phandle); child; child = OF_peer(child)) { 515 for (child = OF_child(phandle); child; child = OF_peer(child)) {
516 struct fdt_attach_args cfaa = *faa; 516 struct fdt_attach_args cfaa = *faa;
517 cfaa.faa_phandle = child; 517 cfaa.faa_phandle = child;
518 cfaa.faa_name = fdtbus_get_string(child, "name"); 518 cfaa.faa_name = fdtbus_get_string(child, "name");
519 cfaa.faa_quiet = false; 519 cfaa.faa_quiet = false;
520 520
521 config_found(self, &cfaa, NULL); 521 config_found(self, &cfaa, NULL);
522 } 522 }
523 523
524#ifdef RK3399_IOMUX_FORCE_ENABLE_SWJ_DP 524#ifdef RK3399_IOMUX_FORCE_ENABLE_SWJ_DP
525 rk3399_iomux_force_enable_swj_dp(sc); 525 rk3399_iomux_force_enable_swj_dp(sc);
526#endif 526#endif
527} 527}

cvs diff -r1.8 -r1.9 src/sys/arch/arm/rockchip/rk_vop.c (switch to unified diff)

--- src/sys/arch/arm/rockchip/rk_vop.c 2021/01/25 14:20:38 1.8
+++ src/sys/arch/arm/rockchip/rk_vop.c 2021/01/27 02:00:02 1.9
@@ -1,605 +1,605 @@ @@ -1,605 +1,605 @@
1/* $NetBSD: rk_vop.c,v 1.8 2021/01/25 14:20:38 thorpej Exp $ */ 1/* $NetBSD: rk_vop.c,v 1.9 2021/01/27 02:00:02 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: rk_vop.c,v 1.8 2021/01/25 14:20:38 thorpej Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: rk_vop.c,v 1.9 2021/01/27 02:00:02 thorpej Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/bus.h> 33#include <sys/bus.h>
34#include <sys/device.h> 34#include <sys/device.h>
35#include <sys/intr.h> 35#include <sys/intr.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/conf.h> 38#include <sys/conf.h>
39#include <sys/sysctl.h> 39#include <sys/sysctl.h>
40 40
41#include <drm/drmP.h> 41#include <drm/drmP.h>
42#include <drm/drm_crtc.h> 42#include <drm/drm_crtc.h>
43#include <drm/drm_crtc_helper.h> 43#include <drm/drm_crtc_helper.h>
44#include <drm/drm_plane_helper.h> 44#include <drm/drm_plane_helper.h>
45 45
46#include <dev/fdt/fdtvar.h> 46#include <dev/fdt/fdtvar.h>
47#include <dev/fdt/fdt_port.h> 47#include <dev/fdt/fdt_port.h>
48 48
49#include <arm/rockchip/rk_drm.h> 49#include <arm/rockchip/rk_drm.h>
50 50
51#define VOP_REG_CFG_DONE 0x0000 51#define VOP_REG_CFG_DONE 0x0000
52#define REG_LOAD_EN __BIT(0) 52#define REG_LOAD_EN __BIT(0)
53#define VOP_SYS_CTRL 0x0008 53#define VOP_SYS_CTRL 0x0008
54#define VOP_STANDBY_EN __BIT(22) 54#define VOP_STANDBY_EN __BIT(22)
55#define MIPI_OUT_EN __BIT(15) 55#define MIPI_OUT_EN __BIT(15)
56#define EDP_OUT_EN __BIT(14) 56#define EDP_OUT_EN __BIT(14)
57#define HDMI_OUT_EN __BIT(13) 57#define HDMI_OUT_EN __BIT(13)
58#define RGB_OUT_EN __BIT(12) 58#define RGB_OUT_EN __BIT(12)
59#define VOP_DSP_CTRL0 0x0010 59#define VOP_DSP_CTRL0 0x0010
60#define DSP_OUT_MODE __BITS(3,0) 60#define DSP_OUT_MODE __BITS(3,0)
61#define DSP_OUT_MODE_RGB888 0 61#define DSP_OUT_MODE_RGB888 0
62#define DSP_OUT_MODE_RGBaaa 15 62#define DSP_OUT_MODE_RGBaaa 15
63#define VOP_DSP_CTRL1 0x0014 63#define VOP_DSP_CTRL1 0x0014
64#define VOP_WIN0_CTRL 0x0030 64#define VOP_WIN0_CTRL 0x0030
65#define WIN0_LB_MODE __BITS(7,5) 65#define WIN0_LB_MODE __BITS(7,5)
66#define WIN0_LB_MODE_RGB_3840X2 2 66#define WIN0_LB_MODE_RGB_3840X2 2
67#define WIN0_LB_MODE_RGB_2560X4 3 67#define WIN0_LB_MODE_RGB_2560X4 3
68#define WIN0_LB_MODE_RGB_1920X5 4 68#define WIN0_LB_MODE_RGB_1920X5 4
69#define WIN0_LB_MODE_RGB_1280X8 5 69#define WIN0_LB_MODE_RGB_1280X8 5
70#define WIN0_DATA_FMT __BITS(3,1) 70#define WIN0_DATA_FMT __BITS(3,1)
71#define WIN0_DATA_FMT_ARGB888 0 71#define WIN0_DATA_FMT_ARGB888 0
72#define WIN0_EN __BIT(0) 72#define WIN0_EN __BIT(0)
73#define VOP_WIN0_COLOR_KEY 0x0038 73#define VOP_WIN0_COLOR_KEY 0x0038
74#define VOP_WIN0_VIR 0x003c 74#define VOP_WIN0_VIR 0x003c
75#define WIN0_VIR_STRIDE __BITS(13,0) 75#define WIN0_VIR_STRIDE __BITS(13,0)
76#define VOP_WIN0_YRGB_MST 0x0040 76#define VOP_WIN0_YRGB_MST 0x0040
77#define VOP_WIN0_ACT_INFO 0x0048 77#define VOP_WIN0_ACT_INFO 0x0048
78#define WIN0_ACT_HEIGHT __BITS(28,16) 78#define WIN0_ACT_HEIGHT __BITS(28,16)
79#define WIN0_ACT_WIDTH __BITS(12,0) 79#define WIN0_ACT_WIDTH __BITS(12,0)
80#define VOP_WIN0_DSP_INFO 0x004c 80#define VOP_WIN0_DSP_INFO 0x004c
81#define WIN0_DSP_HEIGHT __BITS(27,16) 81#define WIN0_DSP_HEIGHT __BITS(27,16)
82#define WIN0_DSP_WIDTH __BITS(11,0) 82#define WIN0_DSP_WIDTH __BITS(11,0)
83#define VOP_WIN0_DSP_ST 0x0050 83#define VOP_WIN0_DSP_ST 0x0050
84#define WIN0_DSP_YST __BITS(28,16) 84#define WIN0_DSP_YST __BITS(28,16)
85#define WIN0_DSP_XST __BITS(12,0) 85#define WIN0_DSP_XST __BITS(12,0)
86#define VOP_POST_DSP_HACT_INFO 0x0170 86#define VOP_POST_DSP_HACT_INFO 0x0170
87#define DSP_HACT_ST_POST __BITS(28,16) 87#define DSP_HACT_ST_POST __BITS(28,16)
88#define DSP_HACT_END_POST __BITS(12,0) 88#define DSP_HACT_END_POST __BITS(12,0)
89#define VOP_POST_DSP_VACT_INFO 0x0174 89#define VOP_POST_DSP_VACT_INFO 0x0174
90#define DSP_VACT_ST_POST __BITS(28,16) 90#define DSP_VACT_ST_POST __BITS(28,16)
91#define DSP_VACT_END_POST __BITS(12,0) 91#define DSP_VACT_END_POST __BITS(12,0)
92#define VOP_DSP_HTOTAL_HS_END 0x0188 92#define VOP_DSP_HTOTAL_HS_END 0x0188
93#define DSP_HS_END __BITS(28,16) 93#define DSP_HS_END __BITS(28,16)
94#define DSP_HTOTAL __BITS(12,0) 94#define DSP_HTOTAL __BITS(12,0)
95#define VOP_DSP_HACT_ST_END 0x018c 95#define VOP_DSP_HACT_ST_END 0x018c
96#define DSP_HACT_ST __BITS(28,16) 96#define DSP_HACT_ST __BITS(28,16)
97#define DSP_HACT_END __BITS(12,0) 97#define DSP_HACT_END __BITS(12,0)
98#define VOP_DSP_VTOTAL_VS_END 0x0190 98#define VOP_DSP_VTOTAL_VS_END 0x0190
99#define DSP_VS_END __BITS(28,16) 99#define DSP_VS_END __BITS(28,16)
100#define DSP_VTOTAL __BITS(12,0) 100#define DSP_VTOTAL __BITS(12,0)
101#define VOP_DSP_VACT_ST_END 0x0194 101#define VOP_DSP_VACT_ST_END 0x0194
102#define DSP_VACT_ST __BITS(28,16) 102#define DSP_VACT_ST __BITS(28,16)
103#define DSP_VACT_END __BITS(12,0) 103#define DSP_VACT_END __BITS(12,0)
104 104
105/* 105/*
106 * Polarity fields are in different locations depending on SoC and output type, 106 * Polarity fields are in different locations depending on SoC and output type,
107 * but always in the same order. 107 * but always in the same order.
108 */ 108 */
109#define DSP_DCLK_POL __BIT(3) 109#define DSP_DCLK_POL __BIT(3)
110#define DSP_DEN_POL __BIT(2) 110#define DSP_DEN_POL __BIT(2)
111#define DSP_VSYNC_POL __BIT(1) 111#define DSP_VSYNC_POL __BIT(1)
112#define DSP_HSYNC_POL __BIT(0) 112#define DSP_HSYNC_POL __BIT(0)
113 113
114enum vop_ep_type { 114enum vop_ep_type {
115 VOP_EP_MIPI, 115 VOP_EP_MIPI,
116 VOP_EP_EDP, 116 VOP_EP_EDP,
117 VOP_EP_HDMI, 117 VOP_EP_HDMI,
118 VOP_EP_MIPI1, 118 VOP_EP_MIPI1,
119 VOP_EP_DP, 119 VOP_EP_DP,
120 VOP_NEP 120 VOP_NEP
121}; 121};
122 122
123struct rk_vop_softc; 123struct rk_vop_softc;
124struct rk_vop_config; 124struct rk_vop_config;
125 125
126struct rk_vop_crtc { 126struct rk_vop_crtc {
127 struct drm_crtc base; 127 struct drm_crtc base;
128 struct rk_vop_softc *sc; 128 struct rk_vop_softc *sc;
129}; 129};
130 130
131struct rk_vop_softc { 131struct rk_vop_softc {
132 device_t sc_dev; 132 device_t sc_dev;
133 bus_space_tag_t sc_bst; 133 bus_space_tag_t sc_bst;
134 bus_space_handle_t sc_bsh; 134 bus_space_handle_t sc_bsh;
135 int sc_phandle; 135 int sc_phandle;
136 136
137 struct clk *sc_dclk; 137 struct clk *sc_dclk;
138 138
139 struct rk_vop_crtc sc_crtc; 139 struct rk_vop_crtc sc_crtc;
140 140
141 struct fdt_device_ports sc_ports; 141 struct fdt_device_ports sc_ports;
142 142
143 const struct rk_vop_config *sc_conf; 143 const struct rk_vop_config *sc_conf;
144}; 144};
145 145
146#define to_rk_vop_crtc(x) container_of(x, struct rk_vop_crtc, base) 146#define to_rk_vop_crtc(x) container_of(x, struct rk_vop_crtc, base)
147 147
148#define RD4(sc, reg) \ 148#define RD4(sc, reg) \
149 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 149 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
150#define WR4(sc, reg, val) \ 150#define WR4(sc, reg, val) \
151 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 151 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
152 152
153struct rk_vop_config { 153struct rk_vop_config {
154 const char *descr; 154 const char *descr;
155 u_int out_mode; 155 u_int out_mode;
156 void (*init)(struct rk_vop_softc *); 156 void (*init)(struct rk_vop_softc *);
157 void (*set_polarity)(struct rk_vop_softc *, 157 void (*set_polarity)(struct rk_vop_softc *,
158 enum vop_ep_type, uint32_t); 158 enum vop_ep_type, uint32_t);
159}; 159};
160 160
161#define RK3399_VOP_MIPI_POL __BITS(31,28) 161#define RK3399_VOP_MIPI_POL __BITS(31,28)
162#define RK3399_VOP_EDP_POL __BITS(27,24) 162#define RK3399_VOP_EDP_POL __BITS(27,24)
163#define RK3399_VOP_HDMI_POL __BITS(23,20) 163#define RK3399_VOP_HDMI_POL __BITS(23,20)
164#define RK3399_VOP_DP_POL __BITS(19,16) 164#define RK3399_VOP_DP_POL __BITS(19,16)
165 165
166#define RK3399_VOP_SYS_CTRL_ENABLE __BIT(11) 166#define RK3399_VOP_SYS_CTRL_ENABLE __BIT(11)
167 167
168static void 168static void
169rk3399_vop_set_polarity(struct rk_vop_softc *sc, enum vop_ep_type ep_type, uint32_t pol) 169rk3399_vop_set_polarity(struct rk_vop_softc *sc, enum vop_ep_type ep_type, uint32_t pol)
170{ 170{
171 uint32_t mask, val; 171 uint32_t mask, val;
172 172
173 switch (ep_type) { 173 switch (ep_type) {
174 case VOP_EP_MIPI: 174 case VOP_EP_MIPI:
175 case VOP_EP_MIPI1: 175 case VOP_EP_MIPI1:
176 mask = RK3399_VOP_MIPI_POL; 176 mask = RK3399_VOP_MIPI_POL;
177 break; 177 break;
178 case VOP_EP_EDP: 178 case VOP_EP_EDP:
179 mask = RK3399_VOP_EDP_POL; 179 mask = RK3399_VOP_EDP_POL;
180 break; 180 break;
181 case VOP_EP_HDMI: 181 case VOP_EP_HDMI:
182 mask = RK3399_VOP_HDMI_POL; 182 mask = RK3399_VOP_HDMI_POL;
183 break; 183 break;
184 case VOP_EP_DP: 184 case VOP_EP_DP:
185 mask = RK3399_VOP_DP_POL; 185 mask = RK3399_VOP_DP_POL;
186 break; 186 break;
187 default: 187 default:
188 return; 188 return;
189 } 189 }
190 190
191 val = RD4(sc, VOP_DSP_CTRL1); 191 val = RD4(sc, VOP_DSP_CTRL1);
192 val &= ~mask; 192 val &= ~mask;
193 val |= __SHIFTIN(pol, mask); 193 val |= __SHIFTIN(pol, mask);
194 WR4(sc, VOP_DSP_CTRL1, val); 194 WR4(sc, VOP_DSP_CTRL1, val);
195} 195}
196 196
197static void 197static void
198rk3399_vop_init(struct rk_vop_softc *sc) 198rk3399_vop_init(struct rk_vop_softc *sc)
199{ 199{
200 uint32_t val; 200 uint32_t val;
201 201
202 val = RD4(sc, VOP_SYS_CTRL); 202 val = RD4(sc, VOP_SYS_CTRL);
203 val |= RK3399_VOP_SYS_CTRL_ENABLE; 203 val |= RK3399_VOP_SYS_CTRL_ENABLE;
204 WR4(sc, VOP_SYS_CTRL, val); 204 WR4(sc, VOP_SYS_CTRL, val);
205} 205}
206 206
207static const struct rk_vop_config rk3399_vop_lit_config = { 207static const struct rk_vop_config rk3399_vop_lit_config = {
208 .descr = "RK3399 VOPL", 208 .descr = "RK3399 VOPL",
209 .out_mode = DSP_OUT_MODE_RGB888, 209 .out_mode = DSP_OUT_MODE_RGB888,
210 .init = rk3399_vop_init, 210 .init = rk3399_vop_init,
211 .set_polarity = rk3399_vop_set_polarity, 211 .set_polarity = rk3399_vop_set_polarity,
212}; 212};
213 213
214static const struct rk_vop_config rk3399_vop_big_config = { 214static const struct rk_vop_config rk3399_vop_big_config = {
215 .descr = "RK3399 VOPB", 215 .descr = "RK3399 VOPB",
216 .out_mode = DSP_OUT_MODE_RGBaaa, 216 .out_mode = DSP_OUT_MODE_RGBaaa,
217 .init = rk3399_vop_init, 217 .init = rk3399_vop_init,
218 .set_polarity = rk3399_vop_set_polarity, 218 .set_polarity = rk3399_vop_set_polarity,
219}; 219};
220 220
221static const struct device_compatible_entry compat_data[] = { 221static const struct device_compatible_entry compat_data[] = {
222 { .compat = "rockchip,rk3399-vop-big", 222 { .compat = "rockchip,rk3399-vop-big",
223 .data = &rk3399_vop_big_config }, 223 .data = &rk3399_vop_big_config },
224 { .compat = "rockchip,rk3399-vop-lit", 224 { .compat = "rockchip,rk3399-vop-lit",
225 .data = &rk3399_vop_lit_config }, 225 .data = &rk3399_vop_lit_config },
226 226
227 { } 227 DEVICE_COMPAT_EOL
228}; 228};
229 229
230static int 230static int
231rk_vop_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, 231rk_vop_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb,
232 int x, int y, int atomic) 232 int x, int y, int atomic)
233{ 233{
234 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc); 234 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
235 struct rk_vop_softc * const sc = mixer_crtc->sc; 235 struct rk_vop_softc * const sc = mixer_crtc->sc;
236 struct rk_drm_framebuffer *sfb = atomic? 236 struct rk_drm_framebuffer *sfb = atomic?
237 to_rk_drm_framebuffer(fb) : 237 to_rk_drm_framebuffer(fb) :
238 to_rk_drm_framebuffer(crtc->primary->fb); 238 to_rk_drm_framebuffer(crtc->primary->fb);
239 239
240 uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr; 240 uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr;
241 241
242 242
243 paddr += y * sfb->base.pitches[0]; 243 paddr += y * sfb->base.pitches[0];
244 paddr += x * drm_format_plane_cpp(sfb->base.pixel_format, 0); 244 paddr += x * drm_format_plane_cpp(sfb->base.pixel_format, 0);
245 245
246 KASSERT((paddr & ~0xffffffff) == 0); 246 KASSERT((paddr & ~0xffffffff) == 0);
247 247
248 const uint32_t vir = __SHIFTIN(sfb->base.pitches[0] / 4, 248 const uint32_t vir = __SHIFTIN(sfb->base.pitches[0] / 4,
249 WIN0_VIR_STRIDE); 249 WIN0_VIR_STRIDE);
250 WR4(sc, VOP_WIN0_VIR, vir); 250 WR4(sc, VOP_WIN0_VIR, vir);
251 251
252 /* Framebuffer start address */ 252 /* Framebuffer start address */
253 WR4(sc, VOP_WIN0_YRGB_MST, (uint32_t)paddr); 253 WR4(sc, VOP_WIN0_YRGB_MST, (uint32_t)paddr);
254 254
255 return 0; 255 return 0;
256} 256}
257 257
258static void 258static void
259rk_vop_destroy(struct drm_crtc *crtc) 259rk_vop_destroy(struct drm_crtc *crtc)
260{ 260{
261 drm_crtc_cleanup(crtc); 261 drm_crtc_cleanup(crtc);
262} 262}
263 263
264static const struct drm_crtc_funcs rk_vop_crtc_funcs = { 264static const struct drm_crtc_funcs rk_vop_crtc_funcs = {
265 .set_config = drm_crtc_helper_set_config, 265 .set_config = drm_crtc_helper_set_config,
266 .destroy = rk_vop_destroy, 266 .destroy = rk_vop_destroy,
267}; 267};
268 268
269static void 269static void
270rk_vop_dpms(struct drm_crtc *crtc, int mode) 270rk_vop_dpms(struct drm_crtc *crtc, int mode)
271{ 271{
272 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc); 272 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
273 struct rk_vop_softc * const sc = mixer_crtc->sc; 273 struct rk_vop_softc * const sc = mixer_crtc->sc;
274 uint32_t val; 274 uint32_t val;
275 275
276 val = RD4(sc, VOP_SYS_CTRL); 276 val = RD4(sc, VOP_SYS_CTRL);
277 277
278 switch (mode) { 278 switch (mode) {
279 case DRM_MODE_DPMS_ON: 279 case DRM_MODE_DPMS_ON:
280 val &= ~VOP_STANDBY_EN; 280 val &= ~VOP_STANDBY_EN;
281 break; 281 break;
282 case DRM_MODE_DPMS_STANDBY: 282 case DRM_MODE_DPMS_STANDBY:
283 case DRM_MODE_DPMS_SUSPEND: 283 case DRM_MODE_DPMS_SUSPEND:
284 case DRM_MODE_DPMS_OFF: 284 case DRM_MODE_DPMS_OFF:
285 val |= VOP_STANDBY_EN; 285 val |= VOP_STANDBY_EN;
286 break; 286 break;
287 } 287 }
288 288
289 WR4(sc, VOP_SYS_CTRL, val); 289 WR4(sc, VOP_SYS_CTRL, val);
290 290
291 /* Commit settings */ 291 /* Commit settings */
292 WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN); 292 WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
293} 293}
294 294
295static bool 295static bool
296rk_vop_mode_fixup(struct drm_crtc *crtc, 296rk_vop_mode_fixup(struct drm_crtc *crtc,
297 const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) 297 const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
298{ 298{
299 return true; 299 return true;
300} 300}
301 301
302static int 302static int
303rk_vop_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, 303rk_vop_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
304 struct drm_display_mode *adjusted_mode, int x, int y, 304 struct drm_display_mode *adjusted_mode, int x, int y,
305 struct drm_framebuffer *old_fb) 305 struct drm_framebuffer *old_fb)
306{ 306{
307 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc); 307 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
308 struct rk_vop_softc * const sc = mixer_crtc->sc; 308 struct rk_vop_softc * const sc = mixer_crtc->sc;
309 uint32_t val; 309 uint32_t val;
310 u_int lb_mode; 310 u_int lb_mode;
311 int error; 311 int error;
312 u_int pol; 312 u_int pol;
313 int connector_type = 0; 313 int connector_type = 0;
314 struct drm_connector * connector; 314 struct drm_connector * connector;
315 315
316 const u_int hactive = adjusted_mode->hdisplay; 316 const u_int hactive = adjusted_mode->hdisplay;
317 const u_int hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start; 317 const u_int hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
318 const u_int hback_porch = adjusted_mode->htotal - adjusted_mode->hsync_end; 318 const u_int hback_porch = adjusted_mode->htotal - adjusted_mode->hsync_end;
319 const u_int hfront_porch = adjusted_mode->hsync_start - adjusted_mode->hdisplay; 319 const u_int hfront_porch = adjusted_mode->hsync_start - adjusted_mode->hdisplay;
320 320
321 const u_int vactive = adjusted_mode->vdisplay; 321 const u_int vactive = adjusted_mode->vdisplay;
322 const u_int vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start; 322 const u_int vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
323 const u_int vback_porch = adjusted_mode->vtotal - adjusted_mode->vsync_end; 323 const u_int vback_porch = adjusted_mode->vtotal - adjusted_mode->vsync_end;
324 const u_int vfront_porch = adjusted_mode->vsync_start - adjusted_mode->vdisplay; 324 const u_int vfront_porch = adjusted_mode->vsync_start - adjusted_mode->vdisplay;
325 325
326 error = clk_set_rate(sc->sc_dclk, adjusted_mode->clock * 1000); 326 error = clk_set_rate(sc->sc_dclk, adjusted_mode->clock * 1000);
327 if (error != 0) 327 if (error != 0)
328 DRM_ERROR("couldn't set pixel clock: %d\n", error); 328 DRM_ERROR("couldn't set pixel clock: %d\n", error);
329 329
330 val = __SHIFTIN(hactive - 1, WIN0_ACT_WIDTH) | 330 val = __SHIFTIN(hactive - 1, WIN0_ACT_WIDTH) |
331 __SHIFTIN(vactive - 1, WIN0_ACT_HEIGHT); 331 __SHIFTIN(vactive - 1, WIN0_ACT_HEIGHT);
332 WR4(sc, VOP_WIN0_ACT_INFO, val); 332 WR4(sc, VOP_WIN0_ACT_INFO, val);
333 333
334 val = __SHIFTIN(hactive - 1, WIN0_DSP_WIDTH) | 334 val = __SHIFTIN(hactive - 1, WIN0_DSP_WIDTH) |
335 __SHIFTIN(vactive - 1, WIN0_DSP_HEIGHT); 335 __SHIFTIN(vactive - 1, WIN0_DSP_HEIGHT);
336 WR4(sc, VOP_WIN0_DSP_INFO, val); 336 WR4(sc, VOP_WIN0_DSP_INFO, val);
337 337
338 val = __SHIFTIN(hsync_len + hback_porch, WIN0_DSP_XST) | 338 val = __SHIFTIN(hsync_len + hback_porch, WIN0_DSP_XST) |
339 __SHIFTIN(vsync_len + vback_porch, WIN0_DSP_YST); 339 __SHIFTIN(vsync_len + vback_porch, WIN0_DSP_YST);
340 WR4(sc, VOP_WIN0_DSP_ST, val); 340 WR4(sc, VOP_WIN0_DSP_ST, val);
341 341
342 WR4(sc, VOP_WIN0_COLOR_KEY, 0); 342 WR4(sc, VOP_WIN0_COLOR_KEY, 0);
343 343
344 if (adjusted_mode->hdisplay > 2560) 344 if (adjusted_mode->hdisplay > 2560)
345 lb_mode = WIN0_LB_MODE_RGB_3840X2; 345 lb_mode = WIN0_LB_MODE_RGB_3840X2;
346 else if (adjusted_mode->hdisplay > 1920) 346 else if (adjusted_mode->hdisplay > 1920)
347 lb_mode = WIN0_LB_MODE_RGB_2560X4; 347 lb_mode = WIN0_LB_MODE_RGB_2560X4;
348 else if (adjusted_mode->hdisplay > 1280) 348 else if (adjusted_mode->hdisplay > 1280)
349 lb_mode = WIN0_LB_MODE_RGB_1920X5; 349 lb_mode = WIN0_LB_MODE_RGB_1920X5;
350 else 350 else
351 lb_mode = WIN0_LB_MODE_RGB_1280X8; 351 lb_mode = WIN0_LB_MODE_RGB_1280X8;
352 352
353 val = __SHIFTIN(lb_mode, WIN0_LB_MODE) | 353 val = __SHIFTIN(lb_mode, WIN0_LB_MODE) |
354 __SHIFTIN(WIN0_DATA_FMT_ARGB888, WIN0_DATA_FMT) | 354 __SHIFTIN(WIN0_DATA_FMT_ARGB888, WIN0_DATA_FMT) |
355 WIN0_EN; 355 WIN0_EN;
356 WR4(sc, VOP_WIN0_CTRL, val); 356 WR4(sc, VOP_WIN0_CTRL, val);
357 357
358 rk_vop_mode_do_set_base(crtc, old_fb, x, y, 0); 358 rk_vop_mode_do_set_base(crtc, old_fb, x, y, 0);
359 359
360 pol = DSP_DCLK_POL; 360 pol = DSP_DCLK_POL;
361 if ((adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) != 0) 361 if ((adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) != 0)
362 pol |= DSP_HSYNC_POL; 362 pol |= DSP_HSYNC_POL;
363 if ((adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) != 0) 363 if ((adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) != 0)
364 pol |= DSP_VSYNC_POL; 364 pol |= DSP_VSYNC_POL;
365 365
366 drm_for_each_connector(connector, crtc->dev) { 366 drm_for_each_connector(connector, crtc->dev) {
367 if ((connector->encoder) == NULL) 367 if ((connector->encoder) == NULL)
368 continue; 368 continue;
369 if (connector->encoder->crtc == crtc) { 369 if (connector->encoder->crtc == crtc) {
370 connector_type = connector->connector_type; 370 connector_type = connector->connector_type;
371 break; 371 break;
372 } 372 }
373 } 373 }
374 374
375 switch (connector_type) { 375 switch (connector_type) {
376 case DRM_MODE_CONNECTOR_HDMIA: 376 case DRM_MODE_CONNECTOR_HDMIA:
377 sc->sc_conf->set_polarity(sc, VOP_EP_HDMI, pol); 377 sc->sc_conf->set_polarity(sc, VOP_EP_HDMI, pol);
378 break; 378 break;
379 case DRM_MODE_CONNECTOR_eDP: 379 case DRM_MODE_CONNECTOR_eDP:
380 sc->sc_conf->set_polarity(sc, VOP_EP_EDP, pol); 380 sc->sc_conf->set_polarity(sc, VOP_EP_EDP, pol);
381 break; 381 break;
382 } 382 }
383 383
384 val = RD4(sc, VOP_SYS_CTRL); 384 val = RD4(sc, VOP_SYS_CTRL);
385 val &= ~VOP_STANDBY_EN; 385 val &= ~VOP_STANDBY_EN;
386 val &= ~(MIPI_OUT_EN|EDP_OUT_EN|HDMI_OUT_EN|RGB_OUT_EN); 386 val &= ~(MIPI_OUT_EN|EDP_OUT_EN|HDMI_OUT_EN|RGB_OUT_EN);
387 387
388 switch (connector_type) { 388 switch (connector_type) {
389 case DRM_MODE_CONNECTOR_HDMIA: 389 case DRM_MODE_CONNECTOR_HDMIA:
390 val |= HDMI_OUT_EN; 390 val |= HDMI_OUT_EN;
391 break; 391 break;
392 case DRM_MODE_CONNECTOR_eDP: 392 case DRM_MODE_CONNECTOR_eDP:
393 val |= EDP_OUT_EN; 393 val |= EDP_OUT_EN;
394 break; 394 break;
395 } 395 }
396 WR4(sc, VOP_SYS_CTRL, val); 396 WR4(sc, VOP_SYS_CTRL, val);
397 397
398 val = RD4(sc, VOP_DSP_CTRL0); 398 val = RD4(sc, VOP_DSP_CTRL0);
399 val &= ~DSP_OUT_MODE; 399 val &= ~DSP_OUT_MODE;
400 val |= __SHIFTIN(sc->sc_conf->out_mode, DSP_OUT_MODE); 400 val |= __SHIFTIN(sc->sc_conf->out_mode, DSP_OUT_MODE);
401 WR4(sc, VOP_DSP_CTRL0, val); 401 WR4(sc, VOP_DSP_CTRL0, val);
402 402
403 val = __SHIFTIN(hsync_len + hback_porch, DSP_HACT_ST_POST) | 403 val = __SHIFTIN(hsync_len + hback_porch, DSP_HACT_ST_POST) |
404 __SHIFTIN(hsync_len + hback_porch + hactive, DSP_HACT_END_POST); 404 __SHIFTIN(hsync_len + hback_porch + hactive, DSP_HACT_END_POST);
405 WR4(sc, VOP_POST_DSP_HACT_INFO, val); 405 WR4(sc, VOP_POST_DSP_HACT_INFO, val);
406 406
407 val = __SHIFTIN(hsync_len + hback_porch, DSP_HACT_ST) | 407 val = __SHIFTIN(hsync_len + hback_porch, DSP_HACT_ST) |
408 __SHIFTIN(hsync_len + hback_porch + hactive, DSP_HACT_END); 408 __SHIFTIN(hsync_len + hback_porch + hactive, DSP_HACT_END);
409 WR4(sc, VOP_DSP_HACT_ST_END, val); 409 WR4(sc, VOP_DSP_HACT_ST_END, val);
410 410
411 val = __SHIFTIN(hsync_len, DSP_HTOTAL) | 411 val = __SHIFTIN(hsync_len, DSP_HTOTAL) |
412 __SHIFTIN(hsync_len + hback_porch + hactive + hfront_porch, DSP_HS_END); 412 __SHIFTIN(hsync_len + hback_porch + hactive + hfront_porch, DSP_HS_END);
413 WR4(sc, VOP_DSP_HTOTAL_HS_END, val); 413 WR4(sc, VOP_DSP_HTOTAL_HS_END, val);
414 414
415 val = __SHIFTIN(vsync_len + vback_porch, DSP_VACT_ST_POST) | 415 val = __SHIFTIN(vsync_len + vback_porch, DSP_VACT_ST_POST) |
416 __SHIFTIN(vsync_len + vback_porch + vactive, DSP_VACT_END_POST); 416 __SHIFTIN(vsync_len + vback_porch + vactive, DSP_VACT_END_POST);
417 WR4(sc, VOP_POST_DSP_VACT_INFO, val); 417 WR4(sc, VOP_POST_DSP_VACT_INFO, val);
418 418
419 val = __SHIFTIN(vsync_len + vback_porch, DSP_VACT_ST) | 419 val = __SHIFTIN(vsync_len + vback_porch, DSP_VACT_ST) |
420 __SHIFTIN(vsync_len + vback_porch + vactive, DSP_VACT_END); 420 __SHIFTIN(vsync_len + vback_porch + vactive, DSP_VACT_END);
421 WR4(sc, VOP_DSP_VACT_ST_END, val); 421 WR4(sc, VOP_DSP_VACT_ST_END, val);
422 422
423 val = __SHIFTIN(vsync_len, DSP_VTOTAL) | 423 val = __SHIFTIN(vsync_len, DSP_VTOTAL) |
424 __SHIFTIN(vsync_len + vback_porch + vactive + vfront_porch, DSP_VS_END); 424 __SHIFTIN(vsync_len + vback_porch + vactive + vfront_porch, DSP_VS_END);
425 WR4(sc, VOP_DSP_VTOTAL_VS_END, val); 425 WR4(sc, VOP_DSP_VTOTAL_VS_END, val);
426 426
427 return 0; 427 return 0;
428} 428}
429 429
430static int 430static int
431rk_vop_mode_set_base(struct drm_crtc *crtc, int x, int y, 431rk_vop_mode_set_base(struct drm_crtc *crtc, int x, int y,
432 struct drm_framebuffer *old_fb) 432 struct drm_framebuffer *old_fb)
433{ 433{
434 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc); 434 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
435 struct rk_vop_softc * const sc = mixer_crtc->sc; 435 struct rk_vop_softc * const sc = mixer_crtc->sc;
436 436
437 rk_vop_mode_do_set_base(crtc, old_fb, x, y, 0); 437 rk_vop_mode_do_set_base(crtc, old_fb, x, y, 0);
438 438
439 /* Commit settings */ 439 /* Commit settings */
440 WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN); 440 WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
441 441
442 return 0; 442 return 0;
443} 443}
444 444
445static int 445static int
446rk_vop_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, 446rk_vop_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
447 int x, int y, enum mode_set_atomic state) 447 int x, int y, enum mode_set_atomic state)
448{ 448{
449 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc); 449 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
450 struct rk_vop_softc * const sc = mixer_crtc->sc; 450 struct rk_vop_softc * const sc = mixer_crtc->sc;
451 451
452 rk_vop_mode_do_set_base(crtc, fb, x, y, 1); 452 rk_vop_mode_do_set_base(crtc, fb, x, y, 1);
453 453
454 /* Commit settings */ 454 /* Commit settings */
455 WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN); 455 WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
456 456
457 return 0; 457 return 0;
458} 458}
459 459
460static void 460static void
461rk_vop_disable(struct drm_crtc *crtc) 461rk_vop_disable(struct drm_crtc *crtc)
462{ 462{
463} 463}
464 464
465static void 465static void
466rk_vop_prepare(struct drm_crtc *crtc) 466rk_vop_prepare(struct drm_crtc *crtc)
467{ 467{
468} 468}
469 469
470static void 470static void
471rk_vop_commit(struct drm_crtc *crtc) 471rk_vop_commit(struct drm_crtc *crtc)
472{ 472{
473 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc); 473 struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
474 struct rk_vop_softc * const sc = mixer_crtc->sc; 474 struct rk_vop_softc * const sc = mixer_crtc->sc;
475 475
476 /* Commit settings */ 476 /* Commit settings */
477 WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN); 477 WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
478} 478}
479 479
480static const struct drm_crtc_helper_funcs rk_vop_crtc_helper_funcs = { 480static const struct drm_crtc_helper_funcs rk_vop_crtc_helper_funcs = {
481 .dpms = rk_vop_dpms, 481 .dpms = rk_vop_dpms,
482 .mode_fixup = rk_vop_mode_fixup, 482 .mode_fixup = rk_vop_mode_fixup,
483 .mode_set = rk_vop_mode_set, 483 .mode_set = rk_vop_mode_set,
484 .mode_set_base = rk_vop_mode_set_base, 484 .mode_set_base = rk_vop_mode_set_base,
485 .mode_set_base_atomic = rk_vop_mode_set_base_atomic, 485 .mode_set_base_atomic = rk_vop_mode_set_base_atomic,
486 .disable = rk_vop_disable, 486 .disable = rk_vop_disable,
487 .prepare = rk_vop_prepare, 487 .prepare = rk_vop_prepare,
488 .commit = rk_vop_commit, 488 .commit = rk_vop_commit,
489}; 489};
490 490
491static int 491static int
492rk_vop_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate) 492rk_vop_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate)
493{ 493{
494 struct rk_vop_softc * const sc = device_private(dev); 494 struct rk_vop_softc * const sc = device_private(dev);
495 struct drm_device *ddev; 495 struct drm_device *ddev;
496 496
497 if (!activate) 497 if (!activate)
498 return EINVAL; 498 return EINVAL;
499 499
500 ddev = rk_drm_port_device(&sc->sc_ports); 500 ddev = rk_drm_port_device(&sc->sc_ports);
501 if (ddev == NULL) { 501 if (ddev == NULL) {
502 DRM_ERROR("couldn't find DRM device\n"); 502 DRM_ERROR("couldn't find DRM device\n");
503 return ENXIO; 503 return ENXIO;
504 } 504 }
505 505
506 if (sc->sc_crtc.sc == NULL) { 506 if (sc->sc_crtc.sc == NULL) {
507 sc->sc_crtc.sc = sc; 507 sc->sc_crtc.sc = sc;
508 508
509 drm_crtc_init(ddev, &sc->sc_crtc.base, &rk_vop_crtc_funcs); 509 drm_crtc_init(ddev, &sc->sc_crtc.base, &rk_vop_crtc_funcs);
510 drm_crtc_helper_add(&sc->sc_crtc.base, &rk_vop_crtc_helper_funcs); 510 drm_crtc_helper_add(&sc->sc_crtc.base, &rk_vop_crtc_helper_funcs);
511 511
512 aprint_debug_dev(dev, "using CRTC %d for %s\n", 512 aprint_debug_dev(dev, "using CRTC %d for %s\n",
513 drm_crtc_index(&sc->sc_crtc.base), sc->sc_conf->descr); 513 drm_crtc_index(&sc->sc_crtc.base), sc->sc_conf->descr);
514 } 514 }
515 515
516 const u_int ep_index = fdt_endpoint_index(ep); 516 const u_int ep_index = fdt_endpoint_index(ep);
517 if (ep_index >= VOP_NEP) { 517 if (ep_index >= VOP_NEP) {
518 DRM_ERROR("endpoint index %d out of range\n", ep_index); 518 DRM_ERROR("endpoint index %d out of range\n", ep_index);
519 return ENXIO; 519 return ENXIO;
520 } 520 }
521 521
522 return fdt_endpoint_activate(ep, activate); 522 return fdt_endpoint_activate(ep, activate);
523} 523}
524 524
525static void * 525static void *
526rk_vop_ep_get_data(device_t dev, struct fdt_endpoint *ep) 526rk_vop_ep_get_data(device_t dev, struct fdt_endpoint *ep)
527{ 527{
528 struct rk_vop_softc * const sc = device_private(dev); 528 struct rk_vop_softc * const sc = device_private(dev);
529 529
530 return &sc->sc_crtc.base; 530 return &sc->sc_crtc.base;
531} 531}
532 532
533static int 533static int
534rk_vop_match(device_t parent, cfdata_t cf, void *aux) 534rk_vop_match(device_t parent, cfdata_t cf, void *aux)
535{ 535{
536 struct fdt_attach_args * const faa = aux; 536 struct fdt_attach_args * const faa = aux;
537 537
538 return of_match_compat_data(faa->faa_phandle, compat_data); 538 return of_match_compat_data(faa->faa_phandle, compat_data);
539} 539}
540 540
541static void 541static void
542rk_vop_attach(device_t parent, device_t self, void *aux) 542rk_vop_attach(device_t parent, device_t self, void *aux)
543{ 543{
544 struct rk_vop_softc * const sc = device_private(self); 544 struct rk_vop_softc * const sc = device_private(self);
545 struct fdt_attach_args * const faa = aux; 545 struct fdt_attach_args * const faa = aux;
546 const int phandle = faa->faa_phandle; 546 const int phandle = faa->faa_phandle;
547 const char * const reset_names[] = { "axi", "ahb", "dclk" }; 547 const char * const reset_names[] = { "axi", "ahb", "dclk" };
548 const char * const clock_names[] = { "aclk_vop", "hclk_vop" }; 548 const char * const clock_names[] = { "aclk_vop", "hclk_vop" };
549 struct fdtbus_reset *rst; 549 struct fdtbus_reset *rst;
550 bus_addr_t addr; 550 bus_addr_t addr;
551 bus_size_t size; 551 bus_size_t size;
552 u_int n; 552 u_int n;
553 553
554 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 554 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
555 aprint_error(": couldn't get registers\n"); 555 aprint_error(": couldn't get registers\n");
556 return; 556 return;
557 } 557 }
558 558
559 fdtbus_clock_assign(phandle); 559 fdtbus_clock_assign(phandle);
560 560
561 for (n = 0; n < __arraycount(reset_names); n++) { 561 for (n = 0; n < __arraycount(reset_names); n++) {
562 rst = fdtbus_reset_get(phandle, reset_names[n]); 562 rst = fdtbus_reset_get(phandle, reset_names[n]);
563 if (rst == NULL || fdtbus_reset_deassert(rst) != 0) { 563 if (rst == NULL || fdtbus_reset_deassert(rst) != 0) {
564 aprint_error(": couldn't de-assert reset %s\n", reset_names[n]); 564 aprint_error(": couldn't de-assert reset %s\n", reset_names[n]);
565 return; 565 return;
566 } 566 }
567 } 567 }
568 for (n = 0; n < __arraycount(clock_names); n++) { 568 for (n = 0; n < __arraycount(clock_names); n++) {
569 if (fdtbus_clock_enable(phandle, clock_names[n], true) != 0) { 569 if (fdtbus_clock_enable(phandle, clock_names[n], true) != 0) {
570 aprint_error(": couldn't enable clock %s\n", clock_names[n]); 570 aprint_error(": couldn't enable clock %s\n", clock_names[n]);
571 return; 571 return;
572 } 572 }
573 } 573 }
574 sc->sc_dclk = fdtbus_clock_get(phandle, "dclk_vop"); 574 sc->sc_dclk = fdtbus_clock_get(phandle, "dclk_vop");
575 if (sc->sc_dclk == NULL || clk_enable(sc->sc_dclk) != 0) { 575 if (sc->sc_dclk == NULL || clk_enable(sc->sc_dclk) != 0) {
576 aprint_error(": couldn't enable clock %s\n", "dclk_vop"); 576 aprint_error(": couldn't enable clock %s\n", "dclk_vop");
577 return; 577 return;
578 } 578 }
579 579
580 sc->sc_dev = self; 580 sc->sc_dev = self;
581 sc->sc_bst = faa->faa_bst; 581 sc->sc_bst = faa->faa_bst;
582 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 582 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
583 aprint_error(": couldn't map registers\n"); 583 aprint_error(": couldn't map registers\n");
584 return; 584 return;
585 } 585 }
586 sc->sc_phandle = faa->faa_phandle; 586 sc->sc_phandle = faa->faa_phandle;
587 sc->sc_conf = of_search_compatible(phandle, compat_data)->data; 587 sc->sc_conf = of_search_compatible(phandle, compat_data)->data;
588 588
589 aprint_naive("\n"); 589 aprint_naive("\n");
590 aprint_normal(": %s\n", sc->sc_conf->descr); 590 aprint_normal(": %s\n", sc->sc_conf->descr);
591 591
592 if (sc->sc_conf->init != NULL) 592 if (sc->sc_conf->init != NULL)
593 sc->sc_conf->init(sc); 593 sc->sc_conf->init(sc);
594 594
595 sc->sc_ports.dp_ep_activate = rk_vop_ep_activate; 595 sc->sc_ports.dp_ep_activate = rk_vop_ep_activate;
596 sc->sc_ports.dp_ep_get_data = rk_vop_ep_get_data; 596 sc->sc_ports.dp_ep_get_data = rk_vop_ep_get_data;
597 fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_CRTC); 597 fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_CRTC);
598 598
599 const int port_phandle = of_find_firstchild_byname(phandle, "port"); 599 const int port_phandle = of_find_firstchild_byname(phandle, "port");
600 if (port_phandle > 0) 600 if (port_phandle > 0)
601 rk_drm_register_port(port_phandle, &sc->sc_ports); 601 rk_drm_register_port(port_phandle, &sc->sc_ports);
602} 602}
603 603
604CFATTACH_DECL_NEW(rk_vop, sizeof(struct rk_vop_softc), 604CFATTACH_DECL_NEW(rk_vop, sizeof(struct rk_vop_softc),
605 rk_vop_match, rk_vop_attach, NULL, NULL); 605 rk_vop_match, rk_vop_attach, NULL, NULL);

cvs diff -r1.5 -r1.6 src/sys/arch/arm/rockchip/rk_pwm.c (switch to unified diff)

--- src/sys/arch/arm/rockchip/rk_pwm.c 2021/01/25 14:20:38 1.5
+++ src/sys/arch/arm/rockchip/rk_pwm.c 2021/01/27 02:00:02 1.6
@@ -1,249 +1,249 @@ @@ -1,249 +1,249 @@
1/* $NetBSD: rk_pwm.c,v 1.5 2021/01/25 14:20:38 thorpej Exp $ */ 1/* $NetBSD: rk_pwm.c,v 1.6 2021/01/27 02:00:02 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30 30
31__KERNEL_RCSID(1, "$NetBSD: rk_pwm.c,v 1.5 2021/01/25 14:20:38 thorpej Exp $"); 31__KERNEL_RCSID(1, "$NetBSD: rk_pwm.c,v 1.6 2021/01/27 02:00:02 thorpej Exp $");
32 32
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/bus.h> 34#include <sys/bus.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/intr.h> 36#include <sys/intr.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/time.h> 38#include <sys/time.h>
39 39
40#include <dev/pwm/pwmvar.h> 40#include <dev/pwm/pwmvar.h>
41 41
42#include <dev/fdt/fdtvar.h> 42#include <dev/fdt/fdtvar.h>
43 43
44#define PWM0_CNT 0x00 44#define PWM0_CNT 0x00
45#define PWM0_PERIOD_HPR 0x04 45#define PWM0_PERIOD_HPR 0x04
46#define PWM0_DUTY_LPR 0x08 46#define PWM0_DUTY_LPR 0x08
47#define PWM0_CTRL 0x0c 47#define PWM0_CTRL 0x0c
48#define CTRL_RPT __BITS(31,24) 48#define CTRL_RPT __BITS(31,24)
49#define CTRL_SCALE __BITS(23,16) 49#define CTRL_SCALE __BITS(23,16)
50#define CTRL_PRESCALE __BITS(14,12) 50#define CTRL_PRESCALE __BITS(14,12)
51#define CTRL_CLK_SEL __BIT(9) 51#define CTRL_CLK_SEL __BIT(9)
52#define CTRL_LP_EN __BIT(8) 52#define CTRL_LP_EN __BIT(8)
53#define CTRL_OUTPUT_MODE __BIT(5) 53#define CTRL_OUTPUT_MODE __BIT(5)
54#define CTRL_INACTIVE_POL __BIT(4) 54#define CTRL_INACTIVE_POL __BIT(4)
55#define CTRL_DUTY_POL __BIT(3) 55#define CTRL_DUTY_POL __BIT(3)
56#define CTRL_PWM_MODE __BITS(2,1) 56#define CTRL_PWM_MODE __BITS(2,1)
57#define CTRL_PWM_MODE_ONESHOT 0 57#define CTRL_PWM_MODE_ONESHOT 0
58#define CTRL_PWM_MODE_CONTINUOUS 1 58#define CTRL_PWM_MODE_CONTINUOUS 1
59#define CTRL_PWM_MODE_CAPTURE 2 59#define CTRL_PWM_MODE_CAPTURE 2
60#define CTRL_PWM_EN __BIT(0) 60#define CTRL_PWM_EN __BIT(0)
61 61
62enum rk_pwm_type { 62enum rk_pwm_type {
63 PWM_RK3288 = 1, 63 PWM_RK3288 = 1,
64}; 64};
65 65
66static const struct device_compatible_entry compat_data[] = { 66static const struct device_compatible_entry compat_data[] = {
67 { .compat = "rockchip,rk3288-pwm", .value = PWM_RK3288 }, 67 { .compat = "rockchip,rk3288-pwm", .value = PWM_RK3288 },
68 { } 68 DEVICE_COMPAT_EOL
69}; 69};
70 70
71struct rk_pwm_softc { 71struct rk_pwm_softc {
72 device_t sc_dev; 72 device_t sc_dev;
73 bus_space_tag_t sc_bst; 73 bus_space_tag_t sc_bst;
74 bus_space_handle_t sc_bsh; 74 bus_space_handle_t sc_bsh;
75 75
76 struct pwm_controller sc_pwm; 76 struct pwm_controller sc_pwm;
77 struct pwm_config sc_conf; 77 struct pwm_config sc_conf;
78 78
79 u_int sc_clkfreq; 79 u_int sc_clkfreq;
80}; 80};
81 81
82#define PWM_READ(sc, reg) \ 82#define PWM_READ(sc, reg) \
83 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 83 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
84#define PWM_WRITE(sc, reg, val) \ 84#define PWM_WRITE(sc, reg, val) \
85 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 85 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
86 86
87static pwm_tag_t 87static pwm_tag_t
88rk_pwm_get_tag(device_t dev, const void *data, size_t len) 88rk_pwm_get_tag(device_t dev, const void *data, size_t len)
89{ 89{
90 struct rk_pwm_softc * const sc = device_private(dev); 90 struct rk_pwm_softc * const sc = device_private(dev);
91 const u_int *pwm = data; 91 const u_int *pwm = data;
92 92
93 if (len != 16) 93 if (len != 16)
94 return NULL; 94 return NULL;
95 95
96 const u_int index = be32toh(pwm[1]); 96 const u_int index = be32toh(pwm[1]);
97 if (index != 0) 97 if (index != 0)
98 return NULL; 98 return NULL;
99 99
100 const u_int period = be32toh(pwm[2]); 100 const u_int period = be32toh(pwm[2]);
101 const u_int polarity = be32toh(pwm[3]); 101 const u_int polarity = be32toh(pwm[3]);
102 102
103 sc->sc_conf.period = period; 103 sc->sc_conf.period = period;
104 sc->sc_conf.polarity = polarity ? PWM_ACTIVE_LOW : PWM_ACTIVE_HIGH; 104 sc->sc_conf.polarity = polarity ? PWM_ACTIVE_LOW : PWM_ACTIVE_HIGH;
105 105
106 return &sc->sc_pwm; 106 return &sc->sc_pwm;
107} 107}
108 108
109static struct fdtbus_pwm_controller_func rk_pwm_funcs = { 109static struct fdtbus_pwm_controller_func rk_pwm_funcs = {
110 .get_tag = rk_pwm_get_tag 110 .get_tag = rk_pwm_get_tag
111}; 111};
112 112
113static int 113static int
114rk_pwm_enable(pwm_tag_t pwm, bool enable) 114rk_pwm_enable(pwm_tag_t pwm, bool enable)
115{ 115{
116 struct rk_pwm_softc * const sc = device_private(pwm->pwm_dev); 116 struct rk_pwm_softc * const sc = device_private(pwm->pwm_dev);
117 uint32_t ctrl, octrl; 117 uint32_t ctrl, octrl;
118 118
119 octrl = ctrl = PWM_READ(sc, PWM0_CTRL); 119 octrl = ctrl = PWM_READ(sc, PWM0_CTRL);
120 if (enable) 120 if (enable)
121 ctrl |= CTRL_PWM_EN; 121 ctrl |= CTRL_PWM_EN;
122 else 122 else
123 ctrl &= ~CTRL_PWM_EN; 123 ctrl &= ~CTRL_PWM_EN;
124 124
125 if (ctrl != octrl) 125 if (ctrl != octrl)
126 PWM_WRITE(sc, PWM0_CTRL, ctrl); 126 PWM_WRITE(sc, PWM0_CTRL, ctrl);
127 127
128 return 0; 128 return 0;
129} 129}
130 130
131static int 131static int
132rk_pwm_get_config(pwm_tag_t pwm, struct pwm_config *conf) 132rk_pwm_get_config(pwm_tag_t pwm, struct pwm_config *conf)
133{ 133{
134 struct rk_pwm_softc * const sc = device_private(pwm->pwm_dev); 134 struct rk_pwm_softc * const sc = device_private(pwm->pwm_dev);
135 135
136#if 0 136#if 0
137 /* XXX may be useful someday */ 137 /* XXX may be useful someday */
138 138
139 uint32_t ctrl, period, duty; 139 uint32_t ctrl, period, duty;
140 u_int div; 140 u_int div;
141 141
142 ctrl = PWM_READ(sc, PWM0_CTRL); 142 ctrl = PWM_READ(sc, PWM0_CTRL);
143 period = PWM_READ(sc, PWM0_PERIOD_HPR); 143 period = PWM_READ(sc, PWM0_PERIOD_HPR);
144 duty = PWM_READ(sc, PWM0_DUTY_LPR); 144 duty = PWM_READ(sc, PWM0_DUTY_LPR);
145 145
146 if (ctrl & CTRL_CLK_SEL) { 146 if (ctrl & CTRL_CLK_SEL) {
147 div = __SHIFTOUT(ctrl, CTRL_SCALE) * 2; 147 div = __SHIFTOUT(ctrl, CTRL_SCALE) * 2;
148 if (div == 0) 148 if (div == 0)
149 div = 512; 149 div = 512;
150 } else { 150 } else {
151 div = 1; 151 div = 1;
152 } 152 }
153 div /= (1 << __SHIFTOUT(ctrl, CTRL_PRESCALE)); 153 div /= (1 << __SHIFTOUT(ctrl, CTRL_PRESCALE));
154 154
155 const uint64_t rate = sc->sc_clkfreq / div; 155 const uint64_t rate = sc->sc_clkfreq / div;
156 156
157 conf->polarity = (ctrl & CTRL_DUTY_POL) ? PWM_ACTIVE_HIGH : PWM_ACTIVE_LOW; 157 conf->polarity = (ctrl & CTRL_DUTY_POL) ? PWM_ACTIVE_HIGH : PWM_ACTIVE_LOW;
158 conf->period = (u_int)(((uint64_t)period * 1000000000) / rate); 158 conf->period = (u_int)(((uint64_t)period * 1000000000) / rate);
159 conf->duty_cycle = (u_int)(((uint64_t)duty * 1000000000) / rate); 159 conf->duty_cycle = (u_int)(((uint64_t)duty * 1000000000) / rate);
160#else 160#else
161 *conf = sc->sc_conf; 161 *conf = sc->sc_conf;
162#endif 162#endif
163 163
164 return 0; 164 return 0;
165} 165}
166 166
167static int 167static int
168rk_pwm_set_config(pwm_tag_t pwm, const struct pwm_config *conf) 168rk_pwm_set_config(pwm_tag_t pwm, const struct pwm_config *conf)
169{ 169{
170 struct rk_pwm_softc * const sc = device_private(pwm->pwm_dev); 170 struct rk_pwm_softc * const sc = device_private(pwm->pwm_dev);
171 uint32_t ctrl; 171 uint32_t ctrl;
172 172
173 const uint64_t rate = sc->sc_clkfreq; 173 const uint64_t rate = sc->sc_clkfreq;
174 const uint32_t period = (u_int)((conf->period * rate) / 1000000000); 174 const uint32_t period = (u_int)((conf->period * rate) / 1000000000);
175 const uint32_t duty = (u_int)((conf->duty_cycle * rate) / 1000000000); 175 const uint32_t duty = (u_int)((conf->duty_cycle * rate) / 1000000000);
176 176
177 /* Preserve PWM_EN flag */ 177 /* Preserve PWM_EN flag */
178 ctrl = PWM_READ(sc, PWM0_CTRL) & CTRL_PWM_EN; 178 ctrl = PWM_READ(sc, PWM0_CTRL) & CTRL_PWM_EN;
179 179
180 ctrl |= __SHIFTIN(CTRL_PWM_MODE_CONTINUOUS, CTRL_PWM_MODE); 180 ctrl |= __SHIFTIN(CTRL_PWM_MODE_CONTINUOUS, CTRL_PWM_MODE);
181 if (conf->polarity == PWM_ACTIVE_HIGH) 181 if (conf->polarity == PWM_ACTIVE_HIGH)
182 ctrl |= CTRL_DUTY_POL; 182 ctrl |= CTRL_DUTY_POL;
183 else 183 else
184 ctrl |= CTRL_INACTIVE_POL; 184 ctrl |= CTRL_INACTIVE_POL;
185 185
186 PWM_WRITE(sc, PWM0_CTRL, 0); 186 PWM_WRITE(sc, PWM0_CTRL, 0);
187 PWM_WRITE(sc, PWM0_PERIOD_HPR, period); 187 PWM_WRITE(sc, PWM0_PERIOD_HPR, period);
188 PWM_WRITE(sc, PWM0_DUTY_LPR, duty); 188 PWM_WRITE(sc, PWM0_DUTY_LPR, duty);
189 PWM_WRITE(sc, PWM0_CTRL, ctrl); 189 PWM_WRITE(sc, PWM0_CTRL, ctrl);
190 190
191 sc->sc_conf = *conf; 191 sc->sc_conf = *conf;
192 192
193 return 0; 193 return 0;
194} 194}
195 195
196static int 196static int
197rk_pwm_match(device_t parent, cfdata_t cf, void *aux) 197rk_pwm_match(device_t parent, cfdata_t cf, void *aux)
198{ 198{
199 struct fdt_attach_args * const faa = aux; 199 struct fdt_attach_args * const faa = aux;
200 200
201 return of_match_compat_data(faa->faa_phandle, compat_data); 201 return of_match_compat_data(faa->faa_phandle, compat_data);
202} 202}
203 203
204static void 204static void
205rk_pwm_attach(device_t parent, device_t self, void *aux) 205rk_pwm_attach(device_t parent, device_t self, void *aux)
206{ 206{
207 struct rk_pwm_softc * const sc = device_private(self); 207 struct rk_pwm_softc * const sc = device_private(self);
208 struct fdt_attach_args * const faa = aux; 208 struct fdt_attach_args * const faa = aux;
209 const int phandle = faa->faa_phandle; 209 const int phandle = faa->faa_phandle;
210 struct clk *clk; 210 struct clk *clk;
211 bus_addr_t addr; 211 bus_addr_t addr;
212 bus_size_t size; 212 bus_size_t size;
213 int error; 213 int error;
214 214
215 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 215 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
216 aprint_error(": couldn't get registers\n"); 216 aprint_error(": couldn't get registers\n");
217 return; 217 return;
218 } 218 }
219 219
220 clk = fdtbus_clock_get_index(phandle, 0); 220 clk = fdtbus_clock_get_index(phandle, 0);
221 if (clk == NULL) { 221 if (clk == NULL) {
222 aprint_error(": couldn't get clock\n"); 222 aprint_error(": couldn't get clock\n");
223 return; 223 return;
224 } 224 }
225 225
226 sc->sc_dev = self; 226 sc->sc_dev = self;
227 sc->sc_clkfreq = clk_get_rate(clk); 227 sc->sc_clkfreq = clk_get_rate(clk);
228 sc->sc_bst = faa->faa_bst; 228 sc->sc_bst = faa->faa_bst;
229 error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); 229 error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
230 if (error) { 230 if (error) {
231 aprint_error(": couldn't map %#" PRIxBUSADDR ": %d", 231 aprint_error(": couldn't map %#" PRIxBUSADDR ": %d",
232 addr, error); 232 addr, error);
233 return; 233 return;
234 } 234 }
235 235
236 aprint_naive("\n"); 236 aprint_naive("\n");
237 aprint_normal(": PWM\n"); 237 aprint_normal(": PWM\n");
238 238
239 sc->sc_pwm.pwm_enable = rk_pwm_enable; 239 sc->sc_pwm.pwm_enable = rk_pwm_enable;
240 sc->sc_pwm.pwm_get_config = rk_pwm_get_config; 240 sc->sc_pwm.pwm_get_config = rk_pwm_get_config;
241 sc->sc_pwm.pwm_set_config = rk_pwm_set_config; 241 sc->sc_pwm.pwm_set_config = rk_pwm_set_config;
242 sc->sc_pwm.pwm_dev = self; 242 sc->sc_pwm.pwm_dev = self;
243 243
244 fdtbus_register_pwm_controller(self, phandle, 244 fdtbus_register_pwm_controller(self, phandle,
245 &rk_pwm_funcs); 245 &rk_pwm_funcs);
246} 246}
247 247
248CFATTACH_DECL_NEW(rk_pwm, sizeof(struct rk_pwm_softc), 248CFATTACH_DECL_NEW(rk_pwm, sizeof(struct rk_pwm_softc),
249 rk_pwm_match, rk_pwm_attach, NULL, NULL); 249 rk_pwm_match, rk_pwm_attach, NULL, NULL);

cvs diff -r1.5 -r1.6 src/sys/arch/arm/rockchip/rk_v1crypto.c (switch to unified diff)

--- src/sys/arch/arm/rockchip/rk_v1crypto.c 2021/01/25 14:20:38 1.5
+++ src/sys/arch/arm/rockchip/rk_v1crypto.c 2021/01/27 02:00:02 1.6
@@ -1,386 +1,386 @@ @@ -1,386 +1,386 @@
1/* $NetBSD: rk_v1crypto.c,v 1.5 2021/01/25 14:20:38 thorpej Exp $ */ 1/* $NetBSD: rk_v1crypto.c,v 1.6 2021/01/27 02:00:02 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell. 8 * by Taylor R. Campbell.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * rk_v1crypto -- Rockchip crypto v1 driver 33 * rk_v1crypto -- Rockchip crypto v1 driver
34 * 34 *
35 * This is just the RNG for now. 35 * This is just the RNG for now.
36 */ 36 */
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(1, "$NetBSD: rk_v1crypto.c,v 1.5 2021/01/25 14:20:38 thorpej Exp $"); 39__KERNEL_RCSID(1, "$NetBSD: rk_v1crypto.c,v 1.6 2021/01/27 02:00:02 thorpej Exp $");
40 40
41#include <sys/types.h> 41#include <sys/types.h>
42 42
43#include <sys/bus.h> 43#include <sys/bus.h>
44#include <sys/device.h> 44#include <sys/device.h>
45#include <sys/errno.h> 45#include <sys/errno.h>
46#include <sys/mutex.h> 46#include <sys/mutex.h>
47#include <sys/rndsource.h> 47#include <sys/rndsource.h>
48#include <sys/sysctl.h> 48#include <sys/sysctl.h>
49 49
50#include <dev/fdt/fdtvar.h> 50#include <dev/fdt/fdtvar.h>
51 51
52#include <arm/rockchip/rk_v1crypto.h> 52#include <arm/rockchip/rk_v1crypto.h>
53 53
54struct rk_v1crypto_softc { 54struct rk_v1crypto_softc {
55 device_t sc_dev; 55 device_t sc_dev;
56 bus_space_tag_t sc_bst; 56 bus_space_tag_t sc_bst;
57 bus_space_handle_t sc_bsh; 57 bus_space_handle_t sc_bsh;
58 kmutex_t sc_lock; 58 kmutex_t sc_lock;
59 struct krndsource sc_rndsource; 59 struct krndsource sc_rndsource;
60 struct rk_v1crypto_sysctl { 60 struct rk_v1crypto_sysctl {
61 struct sysctllog *cy_log; 61 struct sysctllog *cy_log;
62 const struct sysctlnode *cy_root_node; 62 const struct sysctlnode *cy_root_node;
63 } sc_sysctl; 63 } sc_sysctl;
64}; 64};
65 65
66static int rk_v1crypto_match(device_t, cfdata_t, void *); 66static int rk_v1crypto_match(device_t, cfdata_t, void *);
67static void rk_v1crypto_attach(device_t, device_t, void *); 67static void rk_v1crypto_attach(device_t, device_t, void *);
68static int rk_v1crypto_selftest(struct rk_v1crypto_softc *); 68static int rk_v1crypto_selftest(struct rk_v1crypto_softc *);
69static void rk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *); 69static void rk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *);
70static void rk_v1crypto_rng_get(size_t, void *); 70static void rk_v1crypto_rng_get(size_t, void *);
71static void rk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *); 71static void rk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *);
72static int rk_v1crypto_sysctl_rng(SYSCTLFN_ARGS); 72static int rk_v1crypto_sysctl_rng(SYSCTLFN_ARGS);
73static int rk_v1crypto_rng(struct rk_v1crypto_softc *, 73static int rk_v1crypto_rng(struct rk_v1crypto_softc *,
74 uint32_t[static RK_V1CRYPTO_TRNG_NOUT]); 74 uint32_t[static RK_V1CRYPTO_TRNG_NOUT]);
75 75
76static uint32_t 76static uint32_t
77RKC_READ(struct rk_v1crypto_softc *sc, bus_addr_t reg) 77RKC_READ(struct rk_v1crypto_softc *sc, bus_addr_t reg)
78{ 78{
79 return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg); 79 return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg);
80} 80}
81 81
82static void 82static void
83RKC_WRITE(struct rk_v1crypto_softc *sc, bus_addr_t reg, uint32_t v) 83RKC_WRITE(struct rk_v1crypto_softc *sc, bus_addr_t reg, uint32_t v)
84{ 84{
85 bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v); 85 bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v);
86} 86}
87 87
88static inline void 88static inline void
89RKC_CTRL(struct rk_v1crypto_softc *sc, uint16_t m, uint16_t v) 89RKC_CTRL(struct rk_v1crypto_softc *sc, uint16_t m, uint16_t v)
90{ 90{
91 uint32_t c = 0; 91 uint32_t c = 0;
92 92
93 c |= __SHIFTIN(m, RK_V1CRYPTO_CTRL_MASK); 93 c |= __SHIFTIN(m, RK_V1CRYPTO_CTRL_MASK);
94 c |= __SHIFTIN(v, m); 94 c |= __SHIFTIN(v, m);
95 RKC_WRITE(sc, RK_V1CRYPTO_CTRL, c); 95 RKC_WRITE(sc, RK_V1CRYPTO_CTRL, c);
96} 96}
97 97
98CFATTACH_DECL_NEW(rk_v1crypto, sizeof(struct rk_v1crypto_softc), 98CFATTACH_DECL_NEW(rk_v1crypto, sizeof(struct rk_v1crypto_softc),
99 rk_v1crypto_match, rk_v1crypto_attach, NULL, NULL); 99 rk_v1crypto_match, rk_v1crypto_attach, NULL, NULL);
100 100
101static const struct device_compatible_entry compat_data[] = { 101static const struct device_compatible_entry compat_data[] = {
102 { .compat = "rockchip,rk3288-crypto" }, 102 { .compat = "rockchip,rk3288-crypto" },
103 { } 103 DEVICE_COMPAT_EOL
104}; 104};
105 105
106static int 106static int
107rk_v1crypto_match(device_t parent, cfdata_t cf, void *aux) 107rk_v1crypto_match(device_t parent, cfdata_t cf, void *aux)
108{ 108{
109 const struct fdt_attach_args *const faa = aux; 109 const struct fdt_attach_args *const faa = aux;
110 110
111 return of_match_compat_data(faa->faa_phandle, compat_data); 111 return of_match_compat_data(faa->faa_phandle, compat_data);
112} 112}
113 113
114static void 114static void
115rk_v1crypto_attach(device_t parent, device_t self, void *aux) 115rk_v1crypto_attach(device_t parent, device_t self, void *aux)
116{ 116{
117 static const char *const clks[] = {"aclk", "hclk", "sclk", "apb_pclk"}; 117 static const char *const clks[] = {"aclk", "hclk", "sclk", "apb_pclk"};
118 struct rk_v1crypto_softc *const sc = device_private(self); 118 struct rk_v1crypto_softc *const sc = device_private(self);
119 const struct fdt_attach_args *const faa = aux; 119 const struct fdt_attach_args *const faa = aux;
120 bus_addr_t addr; 120 bus_addr_t addr;
121 bus_size_t size; 121 bus_size_t size;
122 const int phandle = faa->faa_phandle; 122 const int phandle = faa->faa_phandle;
123 struct fdtbus_reset *rst; 123 struct fdtbus_reset *rst;
124 unsigned i; 124 unsigned i;
125 uint32_t ctrl; 125 uint32_t ctrl;
126 126
127 fdtbus_clock_assign(phandle); 127 fdtbus_clock_assign(phandle);
128 128
129 sc->sc_dev = self; 129 sc->sc_dev = self;
130 sc->sc_bst = faa->faa_bst; 130 sc->sc_bst = faa->faa_bst;
131 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 131 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
132 132
133 /* Get and map device registers. */ 133 /* Get and map device registers. */
134 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 134 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
135 aprint_error(": couldn't get registers\n"); 135 aprint_error(": couldn't get registers\n");
136 return; 136 return;
137 } 137 }
138 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 138 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
139 aprint_error(": couldn't map registers\n"); 139 aprint_error(": couldn't map registers\n");
140 return; 140 return;
141 } 141 }
142 142
143 /* Enable the clocks. */ 143 /* Enable the clocks. */
144 for (i = 0; i < __arraycount(clks); i++) { 144 for (i = 0; i < __arraycount(clks); i++) {
145 if (fdtbus_clock_enable(phandle, clks[i], true) != 0) { 145 if (fdtbus_clock_enable(phandle, clks[i], true) != 0) {
146 aprint_error(": couldn't enable %s clock\n", clks[i]); 146 aprint_error(": couldn't enable %s clock\n", clks[i]);
147 return; 147 return;
148 } 148 }
149 } 149 }
150 150
151 /* Get a reset handle if we need and try to deassert it. */ 151 /* Get a reset handle if we need and try to deassert it. */
152 if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) { 152 if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) {
153 if (fdtbus_reset_deassert(rst) != 0) { 153 if (fdtbus_reset_deassert(rst) != 0) {
154 aprint_error(": couldn't de-assert reset\n"); 154 aprint_error(": couldn't de-assert reset\n");
155 return; 155 return;
156 } 156 }
157 } 157 }
158 158
159 aprint_naive("\n"); 159 aprint_naive("\n");
160 aprint_normal(": Crypto v1\n"); 160 aprint_normal(": Crypto v1\n");
161 161
162 /* 162 /*
163 * Enable ring oscillator to start gathering entropy, and set 163 * Enable ring oscillator to start gathering entropy, and set
164 * up the crypto clock to sample it once every 100 cycles. 164 * up the crypto clock to sample it once every 100 cycles.
165 * 165 *
166 * The ring oscillator can run even when the clock is gated or 166 * The ring oscillator can run even when the clock is gated or
167 * flush is asserted, and the longer we run it, the less it 167 * flush is asserted, and the longer we run it, the less it
168 * will be synchronized with the main clock owing to jitter 168 * will be synchronized with the main clock owing to jitter
169 * ideally from unpredictable thermal noise. 169 * ideally from unpredictable thermal noise.
170 */ 170 */
171 ctrl = RK_V1CRYPTO_TRNG_CTRL_OSC_ENABLE; 171 ctrl = RK_V1CRYPTO_TRNG_CTRL_OSC_ENABLE;
172 ctrl |= __SHIFTIN(100, RK_V1CRYPTO_TRNG_CTRL_CYCLES); 172 ctrl |= __SHIFTIN(100, RK_V1CRYPTO_TRNG_CTRL_CYCLES);
173 RKC_WRITE(sc, RK_V1CRYPTO_TRNG_CTRL, ctrl); 173 RKC_WRITE(sc, RK_V1CRYPTO_TRNG_CTRL, ctrl);
174 174
175 if (rk_v1crypto_selftest(sc)) 175 if (rk_v1crypto_selftest(sc))
176 return; 176 return;
177 rk_v1crypto_rndsource_attach(sc); 177 rk_v1crypto_rndsource_attach(sc);
178 rk_v1crypto_sysctl_attach(sc); 178 rk_v1crypto_sysctl_attach(sc);
179} 179}
180 180
181static int 181static int
182rk_v1crypto_selftest(struct rk_v1crypto_softc *sc) 182rk_v1crypto_selftest(struct rk_v1crypto_softc *sc)
183{ 183{
184 static const uint32_t key[4] = {0}; 184 static const uint32_t key[4] = {0};
185 static const uint32_t input[4] = {0}; 185 static const uint32_t input[4] = {0};
186 static const uint32_t expected[4] = { 186 static const uint32_t expected[4] = {
187 0x66e94bd4, 0xef8a2c3b, 0x884cfa59, 0xca342b2e, 187 0x66e94bd4, 0xef8a2c3b, 0x884cfa59, 0xca342b2e,
188 }; 188 };
189 uint32_t output[4]; 189 uint32_t output[4];
190 uint32_t ctrl; 190 uint32_t ctrl;
191 unsigned i, timo; 191 unsigned i, timo;
192 192
193 /* Program the key and input block. */ 193 /* Program the key and input block. */
194 for (i = 0; i < 4; i++) 194 for (i = 0; i < 4; i++)
195 RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), key[i]); 195 RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), key[i]);
196 for (i = 0; i < 4; i++) 196 for (i = 0; i < 4; i++)
197 RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), input[i]); 197 RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), input[i]);
198 198
199 /* 199 /*
200 * Set up the AES unit to do AES-128 `ECB' (i.e., just the raw 200 * Set up the AES unit to do AES-128 `ECB' (i.e., just the raw
201 * AES permutation) in the encryption direction. 201 * AES permutation) in the encryption direction.
202 */ 202 */
203 ctrl = 0; 203 ctrl = 0;
204 ctrl |= RK_V1CRYPTO_AES_CTRL_KEYCHANGE; 204 ctrl |= RK_V1CRYPTO_AES_CTRL_KEYCHANGE;
205 ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_MODE_ECB, 205 ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_MODE_ECB,
206 RK_V1CRYPTO_AES_CTRL_MODE); 206 RK_V1CRYPTO_AES_CTRL_MODE);
207 ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_KEYSIZE_128, 207 ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_KEYSIZE_128,
208 RK_V1CRYPTO_AES_CTRL_KEYSIZE); 208 RK_V1CRYPTO_AES_CTRL_KEYSIZE);
209 ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_DIR_ENC, 209 ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_DIR_ENC,
210 RK_V1CRYPTO_AES_CTRL_DIR); 210 RK_V1CRYPTO_AES_CTRL_DIR);
211 RKC_WRITE(sc, RK_V1CRYPTO_AES_CTRL, ctrl); 211 RKC_WRITE(sc, RK_V1CRYPTO_AES_CTRL, ctrl);
212 212
213 /* Kick it off. */ 213 /* Kick it off. */
214 RKC_CTRL(sc, RK_V1CRYPTO_CTRL_AES_START, 1); 214 RKC_CTRL(sc, RK_V1CRYPTO_CTRL_AES_START, 1);
215 215
216 /* Wait up to 1ms for it to complete. */ 216 /* Wait up to 1ms for it to complete. */
217 timo = 1000; 217 timo = 1000;
218 while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_AES_START) { 218 while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_AES_START) {
219 if (--timo == 0) { 219 if (--timo == 0) {
220 device_printf(sc->sc_dev, "AES self-test timed out\n"); 220 device_printf(sc->sc_dev, "AES self-test timed out\n");
221 return -1; 221 return -1;
222 } 222 }
223 DELAY(1); 223 DELAY(1);
224 } 224 }
225 225
226 /* Read the output. */ 226 /* Read the output. */
227 for (i = 0; i < 4; i++) 227 for (i = 0; i < 4; i++)
228 output[i] = RKC_READ(sc, RK_V1CRYPTO_AES_DOUT(i)); 228 output[i] = RKC_READ(sc, RK_V1CRYPTO_AES_DOUT(i));
229 229
230 /* Verify the output. */ 230 /* Verify the output. */
231 for (i = 0; i < 4; i++) { 231 for (i = 0; i < 4; i++) {
232 if (output[i] != expected[i]) { 232 if (output[i] != expected[i]) {
233 device_printf(sc->sc_dev, "AES self-test failed\n"); 233 device_printf(sc->sc_dev, "AES self-test failed\n");
234 return -1; 234 return -1;
235 } 235 }
236 } 236 }
237 237
238 /* Success! */ 238 /* Success! */
239 return 0; 239 return 0;
240} 240}
241 241
242static void 242static void
243rk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *sc) 243rk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *sc)
244{ 244{
245 device_t self = sc->sc_dev; 245 device_t self = sc->sc_dev;
246 246
247 rndsource_setcb(&sc->sc_rndsource, rk_v1crypto_rng_get, sc); 247 rndsource_setcb(&sc->sc_rndsource, rk_v1crypto_rng_get, sc);
248 rnd_attach_source(&sc->sc_rndsource, device_xname(self), 248 rnd_attach_source(&sc->sc_rndsource, device_xname(self),
249 RND_TYPE_RNG, RND_FLAG_DEFAULT|RND_FLAG_HASCB); 249 RND_TYPE_RNG, RND_FLAG_DEFAULT|RND_FLAG_HASCB);
250} 250}
251 251
252static void 252static void
253rk_v1crypto_rng_get(size_t nbytes, void *cookie) 253rk_v1crypto_rng_get(size_t nbytes, void *cookie)
254{ 254{
255 struct rk_v1crypto_softc *sc = cookie; 255 struct rk_v1crypto_softc *sc = cookie;
256 device_t self = sc->sc_dev; 256 device_t self = sc->sc_dev;
257 uint32_t buf[RK_V1CRYPTO_TRNG_NOUT]; 257 uint32_t buf[RK_V1CRYPTO_TRNG_NOUT];
258 uint32_t entropybits = NBBY*sizeof(buf)/2; /* be conservative */ 258 uint32_t entropybits = NBBY*sizeof(buf)/2; /* be conservative */
259 unsigned n = RK_V1CRYPTO_TRNG_NOUT; 259 unsigned n = RK_V1CRYPTO_TRNG_NOUT;
260 int error; 260 int error;
261 size_t nbits = NBBY*nbytes; 261 size_t nbits = NBBY*nbytes;
262 262
263 while (nbits) { 263 while (nbits) {
264 CTASSERT((RK_V1CRYPTO_TRNG_NOUT % 2) == 0); 264 CTASSERT((RK_V1CRYPTO_TRNG_NOUT % 2) == 0);
265 265
266 error = rk_v1crypto_rng(sc, buf); 266 error = rk_v1crypto_rng(sc, buf);
267 if (error) { 267 if (error) {
268 device_printf(self, "timed out\n"); 268 device_printf(self, "timed out\n");
269 break; 269 break;
270 } 270 }
271 if (consttime_memequal(buf, buf + n/2, n/2)) { 271 if (consttime_memequal(buf, buf + n/2, n/2)) {
272 device_printf(self, "failed repeated output test\n"); 272 device_printf(self, "failed repeated output test\n");
273 break; 273 break;
274 } 274 }
275 rnd_add_data_sync(&sc->sc_rndsource, buf, sizeof buf, 275 rnd_add_data_sync(&sc->sc_rndsource, buf, sizeof buf,
276 entropybits); 276 entropybits);
277 nbits -= MIN(nbits, MAX(1, entropybits)); 277 nbits -= MIN(nbits, MAX(1, entropybits));
278 } 278 }
279 explicit_memset(buf, 0, sizeof buf); 279 explicit_memset(buf, 0, sizeof buf);
280} 280}
281 281
282static void 282static void
283rk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *sc) 283rk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *sc)
284{ 284{
285 device_t self = sc->sc_dev; 285 device_t self = sc->sc_dev;
286 struct rk_v1crypto_sysctl *cy = &sc->sc_sysctl; 286 struct rk_v1crypto_sysctl *cy = &sc->sc_sysctl;
287 int error; 287 int error;
288 288
289 /* hw.rkv1cryptoN (node) */ 289 /* hw.rkv1cryptoN (node) */
290 error = sysctl_createv(&cy->cy_log, 0, NULL, &cy->cy_root_node, 290 error = sysctl_createv(&cy->cy_log, 0, NULL, &cy->cy_root_node,
291 CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(self), 291 CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(self),
292 SYSCTL_DESCR("rk crypto v1 engine knobs"), 292 SYSCTL_DESCR("rk crypto v1 engine knobs"),
293 NULL, 0, NULL, 0, 293 NULL, 0, NULL, 0,
294 CTL_HW, CTL_CREATE, CTL_EOL); 294 CTL_HW, CTL_CREATE, CTL_EOL);
295 if (error) { 295 if (error) {
296 aprint_error_dev(self, 296 aprint_error_dev(self,
297 "failed to set up sysctl hw.%s: %d\n", 297 "failed to set up sysctl hw.%s: %d\n",
298 device_xname(self), error); 298 device_xname(self), error);
299 return; 299 return;
300 } 300 }
301 301
302 /* hw.rkv1cryptoN.rng (`struct', 32-byte array) */ 302 /* hw.rkv1cryptoN.rng (`struct', 32-byte array) */
303 sysctl_createv(&cy->cy_log, 0, &cy->cy_root_node, NULL, 303 sysctl_createv(&cy->cy_log, 0, &cy->cy_root_node, NULL,
304 CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_STRUCT, 304 CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_STRUCT,
305 "rng", SYSCTL_DESCR("Read up to 32 bytes out of the TRNG"), 305 "rng", SYSCTL_DESCR("Read up to 32 bytes out of the TRNG"),
306 &rk_v1crypto_sysctl_rng, 0, sc, 0, CTL_CREATE, CTL_EOL); 306 &rk_v1crypto_sysctl_rng, 0, sc, 0, CTL_CREATE, CTL_EOL);
307 if (error) { 307 if (error) {
308 aprint_error_dev(self, 308 aprint_error_dev(self,
309 "failed to set up sysctl hw.%s.rng: %d\n", 309 "failed to set up sysctl hw.%s.rng: %d\n",
310 device_xname(self), error); 310 device_xname(self), error);
311 return; 311 return;
312 } 312 }
313} 313}
314 314
315static int 315static int
316rk_v1crypto_sysctl_rng(SYSCTLFN_ARGS) 316rk_v1crypto_sysctl_rng(SYSCTLFN_ARGS)
317{ 317{
318 uint32_t buf[RK_V1CRYPTO_TRNG_NOUT]; 318 uint32_t buf[RK_V1CRYPTO_TRNG_NOUT];
319 struct sysctlnode node = *rnode; 319 struct sysctlnode node = *rnode;
320 struct rk_v1crypto_softc *sc = node.sysctl_data; 320 struct rk_v1crypto_softc *sc = node.sysctl_data;
321 size_t size; 321 size_t size;
322 int error; 322 int error;
323 323
324 /* If oldp == NULL, the caller wants to learn the size. */ 324 /* If oldp == NULL, the caller wants to learn the size. */
325 if (oldp == NULL) { 325 if (oldp == NULL) {
326 *oldlenp = sizeof buf; 326 *oldlenp = sizeof buf;
327 return 0; 327 return 0;
328 } 328 }
329 329
330 /* Verify the output buffer size is reasonable. */ 330 /* Verify the output buffer size is reasonable. */
331 size = *oldlenp; 331 size = *oldlenp;
332 if (size > sizeof buf) /* size_t, so never negative */ 332 if (size > sizeof buf) /* size_t, so never negative */
333 return E2BIG; 333 return E2BIG;
334 if (size == 0) 334 if (size == 0)
335 return 0; /* nothing to do */ 335 return 0; /* nothing to do */
336 336
337 /* Generate data. */ 337 /* Generate data. */
338 error = rk_v1crypto_rng(sc, buf); 338 error = rk_v1crypto_rng(sc, buf);
339 if (error) 339 if (error)
340 return error; 340 return error;
341 341
342 /* Copy out the data. */ 342 /* Copy out the data. */
343 node.sysctl_data = buf; 343 node.sysctl_data = buf;
344 node.sysctl_size = size; 344 node.sysctl_size = size;
345 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 345 error = sysctl_lookup(SYSCTLFN_CALL(&node));
346 346
347 /* Clear the buffer. */ 347 /* Clear the buffer. */
348 explicit_memset(buf, 0, sizeof buf); 348 explicit_memset(buf, 0, sizeof buf);
349 349
350 /* Return the sysctl_lookup error, if any. */ 350 /* Return the sysctl_lookup error, if any. */
351 return error; 351 return error;
352} 352}
353 353
354static int 354static int
355rk_v1crypto_rng(struct rk_v1crypto_softc *sc, 355rk_v1crypto_rng(struct rk_v1crypto_softc *sc,
356 uint32_t buf[static RK_V1CRYPTO_TRNG_NOUT]) 356 uint32_t buf[static RK_V1CRYPTO_TRNG_NOUT])
357{ 357{
358 unsigned i, timo; 358 unsigned i, timo;
359 int error; 359 int error;
360 360
361 /* Acquire lock to serialize access to TRNG. */ 361 /* Acquire lock to serialize access to TRNG. */
362 mutex_enter(&sc->sc_lock); 362 mutex_enter(&sc->sc_lock);
363 363
364 /* 364 /*
365 * Query TRNG and wait up to 1ms for it to post. Empirically, 365 * Query TRNG and wait up to 1ms for it to post. Empirically,
366 * this takes around 120us. 366 * this takes around 120us.
367 */ 367 */
368 RKC_CTRL(sc, RK_V1CRYPTO_CTRL_TRNG_START, 1); 368 RKC_CTRL(sc, RK_V1CRYPTO_CTRL_TRNG_START, 1);
369 timo = 1000; 369 timo = 1000;
370 while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_TRNG_START) { 370 while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_TRNG_START) {
371 if (--timo == 0) { 371 if (--timo == 0) {
372 error = ETIMEDOUT; 372 error = ETIMEDOUT;
373 goto out; 373 goto out;
374 } 374 }
375 DELAY(1); 375 DELAY(1);
376 } 376 }
377 377
378 /* Read out the data. */ 378 /* Read out the data. */
379 for (i = 0; i < RK_V1CRYPTO_TRNG_NOUT; i++) 379 for (i = 0; i < RK_V1CRYPTO_TRNG_NOUT; i++)
380 buf[i] = RKC_READ(sc, RK_V1CRYPTO_TRNG_DOUT(i)); 380 buf[i] = RKC_READ(sc, RK_V1CRYPTO_TRNG_DOUT(i));
381 381
382 /* Success! */ 382 /* Success! */
383 error = 0; 383 error = 0;
384out: mutex_exit(&sc->sc_lock); 384out: mutex_exit(&sc->sc_lock);
385 return error; 385 return error;
386} 386}

cvs diff -r1.10 -r1.11 src/sys/arch/arm/rockchip/rk_tsadc.c (switch to unified diff)

--- src/sys/arch/arm/rockchip/rk_tsadc.c 2021/01/25 14:20:38 1.10
+++ src/sys/arch/arm/rockchip/rk_tsadc.c 2021/01/27 02:00:02 1.11
@@ -1,894 +1,894 @@ @@ -1,894 +1,894 @@
1/* $NetBSD: rk_tsadc.c,v 1.10 2021/01/25 14:20:38 thorpej Exp $ */ 1/* $NetBSD: rk_tsadc.c,v 1.11 2021/01/27 02:00:02 thorpej Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2019 Matthew R. Green 4 * Copyright (c) 2019 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products 15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission. 16 * derived from this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32 32
33__KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.10 2021/01/25 14:20:38 thorpej Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.11 2021/01/27 02:00:02 thorpej Exp $");
34 34
35/* 35/*
36 * Driver for the TSADC temperature sensor monitor in RK3328 and RK3399. 36 * Driver for the TSADC temperature sensor monitor in RK3328 and RK3399.
37 * 37 *
38 * TODO: 38 * TODO:
39 * - handle setting various temp values 39 * - handle setting various temp values
40 * - handle DT trips/temp value defaults 40 * - handle DT trips/temp value defaults
41 * - interrupts aren't triggered (test by lowering warn/crit values), and 41 * - interrupts aren't triggered (test by lowering warn/crit values), and
42 * once they work, make the interrupt do something 42 * once they work, make the interrupt do something
43 */ 43 */
44 44
45#include <sys/param.h> 45#include <sys/param.h>
46#include <sys/bus.h> 46#include <sys/bus.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/intr.h> 48#include <sys/intr.h>
49#include <sys/systm.h> 49#include <sys/systm.h>
50#include <sys/time.h> 50#include <sys/time.h>
51#include <sys/kmem.h> 51#include <sys/kmem.h>
52 52
53#include <dev/fdt/fdtvar.h> 53#include <dev/fdt/fdtvar.h>
54#include <dev/fdt/syscon.h> 54#include <dev/fdt/syscon.h>
55 55
56#include <dev/sysmon/sysmonvar.h> 56#include <dev/sysmon/sysmonvar.h>
57 57
58#ifdef RKTSADC_DEBUG 58#ifdef RKTSADC_DEBUG
59#define DPRINTF(fmt, ...) \ 59#define DPRINTF(fmt, ...) \
60 printf("%s:%d: " fmt "\n", __func__, __LINE__, ## __VA_ARGS__) 60 printf("%s:%d: " fmt "\n", __func__, __LINE__, ## __VA_ARGS__)
61#else 61#else
62#define DPRINTF(fmt, ...) 62#define DPRINTF(fmt, ...)
63#endif 63#endif
64 64
65/* Register definitions */ 65/* Register definitions */
66#define TSADC_USER_CON 0x00 66#define TSADC_USER_CON 0x00
67#define TSADC_USER_CON_ADC_STATUS __BIT(12) 67#define TSADC_USER_CON_ADC_STATUS __BIT(12)
68#define TSADC_USER_CON_INTER_PD_SOC __BITS(11,6) 68#define TSADC_USER_CON_INTER_PD_SOC __BITS(11,6)
69#define TSADC_USER_CON_START __BIT(5) 69#define TSADC_USER_CON_START __BIT(5)
70#define TSADC_USER_CON_START_MODE __BIT(4) 70#define TSADC_USER_CON_START_MODE __BIT(4)
71#define TSADC_USER_CON_ADC_POWER_CTRL __BIT(3) 71#define TSADC_USER_CON_ADC_POWER_CTRL __BIT(3)
72#define TSADC_USER_CON_ADC_INPUT_SRC_SEL __BITS(2,0) 72#define TSADC_USER_CON_ADC_INPUT_SRC_SEL __BITS(2,0)
73#define TSADC_AUTO_CON 0x04 73#define TSADC_AUTO_CON 0x04
74#define TSADC_AUTO_CON_LAST_TSHUT_2CRU __BIT(25) 74#define TSADC_AUTO_CON_LAST_TSHUT_2CRU __BIT(25)
75#define TSADC_AUTO_CON_LAST_TSHUT_2GPIO __BIT(24) 75#define TSADC_AUTO_CON_LAST_TSHUT_2GPIO __BIT(24)
76#define TSADC_AUTO_CON_SAMPLE_DLY_SEL __BIT(17) 76#define TSADC_AUTO_CON_SAMPLE_DLY_SEL __BIT(17)
77#define TSADC_AUTO_CON_AUTO_STATUS __BIT(16) 77#define TSADC_AUTO_CON_AUTO_STATUS __BIT(16)
78#define TSADC_AUTO_CON_SRC1_LT_EN __BIT(13) 78#define TSADC_AUTO_CON_SRC1_LT_EN __BIT(13)
79#define TSADC_AUTO_CON_SRC0_LT_EN __BIT(12) 79#define TSADC_AUTO_CON_SRC0_LT_EN __BIT(12)
80#define TSADC_AUTO_CON_TSHUT_POLARITY __BIT(8) 80#define TSADC_AUTO_CON_TSHUT_POLARITY __BIT(8)
81#define TSADC_AUTO_CON_SRC1_EN __BIT(5) 81#define TSADC_AUTO_CON_SRC1_EN __BIT(5)
82#define TSADC_AUTO_CON_SRC0_EN __BIT(4) 82#define TSADC_AUTO_CON_SRC0_EN __BIT(4)
83#define TSADC_AUTO_CON_Q_SEL __BIT(1) 83#define TSADC_AUTO_CON_Q_SEL __BIT(1)
84#define TSADC_AUTO_CON_AUTO_EN __BIT(0) 84#define TSADC_AUTO_CON_AUTO_EN __BIT(0)
85#define TSADC_INT_EN 0x08 85#define TSADC_INT_EN 0x08
86#define TSADC_INT_EN_EOC_INT_EN __BIT(16) 86#define TSADC_INT_EN_EOC_INT_EN __BIT(16)
87#define TSADC_INT_EN_LT_INTEN_SRC1 __BIT(13) 87#define TSADC_INT_EN_LT_INTEN_SRC1 __BIT(13)
88#define TSADC_INT_EN_LT_INTEN_SRC0 __BIT(12) 88#define TSADC_INT_EN_LT_INTEN_SRC0 __BIT(12)
89#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 __BIT(9) 89#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 __BIT(9)
90#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 __BIT(8) 90#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 __BIT(8)
91#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 __BIT(5) 91#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 __BIT(5)
92#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 __BIT(4) 92#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 __BIT(4)
93#define TSADC_INT_EN_HT_INTEN_SRC1 __BIT(1) 93#define TSADC_INT_EN_HT_INTEN_SRC1 __BIT(1)
94#define TSADC_INT_EN_HT_INTEN_SRC0 __BIT(0) 94#define TSADC_INT_EN_HT_INTEN_SRC0 __BIT(0)
95#define TSADC_INT_PD 0x0c 95#define TSADC_INT_PD 0x0c
96#define TSADC_INT_PD_EOC_INT_PD __BIT(16) 96#define TSADC_INT_PD_EOC_INT_PD __BIT(16)
97#define TSADC_INT_PD_LT_IRQ_SRC1 __BIT(13) 97#define TSADC_INT_PD_LT_IRQ_SRC1 __BIT(13)
98#define TSADC_INT_PD_LT_IRQ_SRC0 __BIT(12) 98#define TSADC_INT_PD_LT_IRQ_SRC0 __BIT(12)
99#define TSADC_INT_PD_TSHUT_O_SRC1 __BIT(5) 99#define TSADC_INT_PD_TSHUT_O_SRC1 __BIT(5)
100#define TSADC_INT_PD_TSHUT_O_SRC0 __BIT(4) 100#define TSADC_INT_PD_TSHUT_O_SRC0 __BIT(4)
101#define TSADC_INT_PD_HT_IRQ_SRC1 __BIT(1) 101#define TSADC_INT_PD_HT_IRQ_SRC1 __BIT(1)
102#define TSADC_INT_PD_HT_IRQ_SRC0 __BIT(0) 102#define TSADC_INT_PD_HT_IRQ_SRC0 __BIT(0)
103#define TSADC_DATA0 0x20 103#define TSADC_DATA0 0x20
104#define TSADC_DATA0_ADC_DATA __BITS(11,0) 104#define TSADC_DATA0_ADC_DATA __BITS(11,0)
105#define TSADC_DATA1 0x24 105#define TSADC_DATA1 0x24
106#define TSADC_DATA1_ADC_DATA __BITS(11,0) 106#define TSADC_DATA1_ADC_DATA __BITS(11,0)
107#define TSADC_COMP0_INT 0x30 107#define TSADC_COMP0_INT 0x30
108#define TSADC_COMP0_INT_COMP_SRC0 __BITS(11,0) 108#define TSADC_COMP0_INT_COMP_SRC0 __BITS(11,0)
109#define TSADC_COMP1_INT 0x34 109#define TSADC_COMP1_INT 0x34
110#define TSADC_COMP1_INT_COMP_SRC1 __BITS(11,0) 110#define TSADC_COMP1_INT_COMP_SRC1 __BITS(11,0)
111#define TSADC_COMP0_SHUT 0x40 111#define TSADC_COMP0_SHUT 0x40
112#define TSADC_COMP0_SHUT_COMP_SRC0 __BITS(11,0) 112#define TSADC_COMP0_SHUT_COMP_SRC0 __BITS(11,0)
113#define TSADC_COMP1_SHUT 0x44 113#define TSADC_COMP1_SHUT 0x44
114#define TSADC_COMP1_SHUT_COMP_SRC1 __BITS(11,0) 114#define TSADC_COMP1_SHUT_COMP_SRC1 __BITS(11,0)
115#define TSADC_HIGH_INT_DEBOUNCE 0x60 115#define TSADC_HIGH_INT_DEBOUNCE 0x60
116#define TSADC_HIGH_INT_DEBOUNCE_TEMP __BITS(7,0) 116#define TSADC_HIGH_INT_DEBOUNCE_TEMP __BITS(7,0)
117#define TSADC_HIGH_TSHUT_DEBOUNCE 0x64 117#define TSADC_HIGH_TSHUT_DEBOUNCE 0x64
118#define TSADC_HIGH_TSHUT_DEBOUNCE_TEMP __BITS(7,0) 118#define TSADC_HIGH_TSHUT_DEBOUNCE_TEMP __BITS(7,0)
119#define TSADC_AUTO_PERIOD 0x68 119#define TSADC_AUTO_PERIOD 0x68
120#define TSADC_AUTO_PERIOD_TEMP __BITS(31,0) 120#define TSADC_AUTO_PERIOD_TEMP __BITS(31,0)
121#define TSADC_AUTO_PERIOD_HT 0x6c 121#define TSADC_AUTO_PERIOD_HT 0x6c
122#define TSADC_AUTO_PERIOD_HT_TEMP __BITS(31,0) 122#define TSADC_AUTO_PERIOD_HT_TEMP __BITS(31,0)
123#define TSADC_COMP0_LOW_INT 0x80 123#define TSADC_COMP0_LOW_INT 0x80
124#define TSADC_COMP0_LOW_INT_COMP_SRC0 __BITS(11,0) 124#define TSADC_COMP0_LOW_INT_COMP_SRC0 __BITS(11,0)
125#define TSADC_COMP1_LOW_INT 0x84 125#define TSADC_COMP1_LOW_INT 0x84
126#define TSADC_COMP1_LOW_INT_COMP_SRC1 __BITS(11,0) 126#define TSADC_COMP1_LOW_INT_COMP_SRC1 __BITS(11,0)
127 127
128#define RK3328_TSADC_AUTO_PERIOD_TIME 250 /* 250ms */ 128#define RK3328_TSADC_AUTO_PERIOD_TIME 250 /* 250ms */
129#define RK3399_TSADC_AUTO_PERIOD_TIME 1875 /* 2.5ms */ 129#define RK3399_TSADC_AUTO_PERIOD_TIME 1875 /* 2.5ms */
130#define TSADC_HT_DEBOUNCE_COUNT 4 130#define TSADC_HT_DEBOUNCE_COUNT 4
131 131
132/* 132/*
133 * All this magic is taking from the Linux rockchip_thermal driver. 133 * All this magic is taking from the Linux rockchip_thermal driver.
134 * 134 *
135 * VCM means "voltage common mode", but the documentation for RK3399 135 * VCM means "voltage common mode", but the documentation for RK3399
136 * does not mention this and I don't know what any of this really 136 * does not mention this and I don't know what any of this really
137 * is for. 137 * is for.
138 */ 138 */
139#define RK3399_GRF_SARADC_TESTBIT 0xe644 139#define RK3399_GRF_SARADC_TESTBIT 0xe644
140#define RK3399_GRF_SARADC_TESTBIT_ON (0x10001 << 2) 140#define RK3399_GRF_SARADC_TESTBIT_ON (0x10001 << 2)
141#define RK3399_GRF_TSADC_TESTBIT_L 0xe648 141#define RK3399_GRF_TSADC_TESTBIT_L 0xe648
142#define RK3399_GRF_TSADC_TESTBIT_VCM_EN_L (0x10001 << 7) 142#define RK3399_GRF_TSADC_TESTBIT_VCM_EN_L (0x10001 << 7)
143#define RK3399_GRF_TSADC_TESTBIT_H 0xe64c 143#define RK3399_GRF_TSADC_TESTBIT_H 0xe64c
144#define RK3399_GRF_TSADC_TESTBIT_VCM_EN_H (0x10001 << 7) 144#define RK3399_GRF_TSADC_TESTBIT_VCM_EN_H (0x10001 << 7)
145#define RK3399_GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) 145#define RK3399_GRF_TSADC_TESTBIT_H_ON (0x10001 << 2)
146 146
147#define TEMP_uC_TO_uK 273150000 147#define TEMP_uC_TO_uK 273150000
148 148
149#define TSHUT_MODE_CPU 0 149#define TSHUT_MODE_CPU 0
150#define TSHUT_MODE_GPIO 1 150#define TSHUT_MODE_GPIO 1
151 151
152#define TSHUT_LOW_ACTIVE 0 152#define TSHUT_LOW_ACTIVE 0
153#define TSHUT_HIGH_ACTIVE 1 153#define TSHUT_HIGH_ACTIVE 1
154 154
155#define TSHUT_DEF_TEMP 95000 155#define TSHUT_DEF_TEMP 95000
156 156
157#define TSADC_DATA_MAX 0xfff 157#define TSADC_DATA_MAX 0xfff
158 158
159#define MAX_SENSORS 2 159#define MAX_SENSORS 2
160 160
161typedef struct rk_data_array { 161typedef struct rk_data_array {
162 uint32_t data; /* register value */ 162 uint32_t data; /* register value */
163 int temp; /* micro-degC */ 163 int temp; /* micro-degC */
164} rk_data_array; 164} rk_data_array;
165 165
166struct rk_tsadc_softc; 166struct rk_tsadc_softc;
167typedef struct rk_data { 167typedef struct rk_data {
168 const rk_data_array *rd_array; 168 const rk_data_array *rd_array;
169 size_t rd_size; 169 size_t rd_size;
170 void (*rd_init)(struct rk_tsadc_softc *, int, int); 170 void (*rd_init)(struct rk_tsadc_softc *, int, int);
171 bool rd_decr; /* lower values -> higher temp */ 171 bool rd_decr; /* lower values -> higher temp */
172 unsigned rd_min, rd_max; 172 unsigned rd_min, rd_max;
173 unsigned rd_auto_period; 173 unsigned rd_auto_period;
174 unsigned rd_num_sensors; 174 unsigned rd_num_sensors;
175} rk_data; 175} rk_data;
176 176
177/* Per-sensor data */ 177/* Per-sensor data */
178struct rk_tsadc_sensor { 178struct rk_tsadc_sensor {
179 envsys_data_t s_data; 179 envsys_data_t s_data;
180 bool s_attached; 180 bool s_attached;
181 /* TSADC register offsets for this sensor */ 181 /* TSADC register offsets for this sensor */
182 unsigned s_data_reg; 182 unsigned s_data_reg;
183 unsigned s_comp_tshut; 183 unsigned s_comp_tshut;
184 unsigned s_comp_int; 184 unsigned s_comp_int;
185 /* enable bit in AUTO_CON register */ 185 /* enable bit in AUTO_CON register */
186 unsigned s_comp_int_en; 186 unsigned s_comp_int_en;
187 /* warn/crit values in micro Kelvin */ 187 /* warn/crit values in micro Kelvin */
188 int s_warn; 188 int s_warn;
189 int s_tshut; 189 int s_tshut;
190}; 190};
191 191
192struct rk_tsadc_softc { 192struct rk_tsadc_softc {
193 device_t sc_dev; 193 device_t sc_dev;
194 int sc_phandle; 194 int sc_phandle;
195 bus_space_tag_t sc_bst; 195 bus_space_tag_t sc_bst;
196 bus_space_handle_t sc_bsh; 196 bus_space_handle_t sc_bsh;
197 size_t sc_size; 197 size_t sc_size;
198 uint32_t sc_data_mask; 198 uint32_t sc_data_mask;
199 void *sc_ih; 199 void *sc_ih;
200 200
201 struct sysmon_envsys *sc_sme; 201 struct sysmon_envsys *sc_sme;
202 struct rk_tsadc_sensor sc_sensors[MAX_SENSORS]; 202 struct rk_tsadc_sensor sc_sensors[MAX_SENSORS];
203 203
204 struct clk *sc_clock; 204 struct clk *sc_clock;
205 struct clk *sc_clockapb; 205 struct clk *sc_clockapb;
206 struct fdtbus_reset *sc_reset; 206 struct fdtbus_reset *sc_reset;
207 struct syscon *sc_syscon; 207 struct syscon *sc_syscon;
208 208
209 const rk_data *sc_rd; 209 const rk_data *sc_rd;
210}; 210};
211 211
212static int rk_tsadc_match(device_t, cfdata_t, void *); 212static int rk_tsadc_match(device_t, cfdata_t, void *);
213static void rk_tsadc_attach(device_t, device_t, void *); 213static void rk_tsadc_attach(device_t, device_t, void *);
214static int rk_tsadc_detach(device_t, int); 214static int rk_tsadc_detach(device_t, int);
215static int rk_tsadc_init_clocks(struct rk_tsadc_softc *); 215static int rk_tsadc_init_clocks(struct rk_tsadc_softc *);
216static void rk_tsadc_init_counts(struct rk_tsadc_softc *); 216static void rk_tsadc_init_counts(struct rk_tsadc_softc *);
217static void rk_tsadc_tshut_set(struct rk_tsadc_softc *s); 217static void rk_tsadc_tshut_set(struct rk_tsadc_softc *s);
218static void rk_tsadc_init_tshut(struct rk_tsadc_softc *, int, int); 218static void rk_tsadc_init_tshut(struct rk_tsadc_softc *, int, int);
219static void rk_tsadc_init_rk3328(struct rk_tsadc_softc *, int, int); 219static void rk_tsadc_init_rk3328(struct rk_tsadc_softc *, int, int);
220static void rk_tsadc_init_rk3399(struct rk_tsadc_softc *, int, int); 220static void rk_tsadc_init_rk3399(struct rk_tsadc_softc *, int, int);
221static void rk_tsadc_init_enable(struct rk_tsadc_softc *); 221static void rk_tsadc_init_enable(struct rk_tsadc_softc *);
222static void rk_tsadc_init(struct rk_tsadc_softc *, int, int); 222static void rk_tsadc_init(struct rk_tsadc_softc *, int, int);
223static void rk_tsadc_refresh(struct sysmon_envsys *, envsys_data_t *); 223static void rk_tsadc_refresh(struct sysmon_envsys *, envsys_data_t *);
224static void rk_tsadc_get_limits(struct sysmon_envsys *, envsys_data_t *, 224static void rk_tsadc_get_limits(struct sysmon_envsys *, envsys_data_t *,
225 sysmon_envsys_lim_t *, uint32_t *); 225 sysmon_envsys_lim_t *, uint32_t *);
226 226
227static int rk_tsadc_intr(void *); 227static int rk_tsadc_intr(void *);
228static int rk_tsadc_data_to_temp(struct rk_tsadc_softc *, uint32_t); 228static int rk_tsadc_data_to_temp(struct rk_tsadc_softc *, uint32_t);
229static uint32_t rk_tsadc_temp_to_data(struct rk_tsadc_softc *, int); 229static uint32_t rk_tsadc_temp_to_data(struct rk_tsadc_softc *, int);
230 230
231/* RK3328/RK3399 compatible sensors */ 231/* RK3328/RK3399 compatible sensors */
232static const struct rk_tsadc_sensor rk_tsadc_sensors[] = { 232static const struct rk_tsadc_sensor rk_tsadc_sensors[] = {
233 { 233 {
234 .s_data = { .desc = "CPU" }, 234 .s_data = { .desc = "CPU" },
235 .s_data_reg = TSADC_DATA0, 235 .s_data_reg = TSADC_DATA0,
236 .s_comp_tshut = TSADC_COMP0_SHUT, 236 .s_comp_tshut = TSADC_COMP0_SHUT,
237 .s_comp_int = TSADC_COMP0_INT, 237 .s_comp_int = TSADC_COMP0_INT,
238 .s_comp_int_en = TSADC_AUTO_CON_SRC0_EN, 238 .s_comp_int_en = TSADC_AUTO_CON_SRC0_EN,
239 /* 239 /*
240 * XXX DT has: 240 * XXX DT has:
241 * cpu_alert1: cpu_alert1 { 241 * cpu_alert1: cpu_alert1 {
242 * temperature = <75000>; 242 * temperature = <75000>;
243 * hysteresis = <2000>; 243 * hysteresis = <2000>;
244 * cpu_crit: cpu_crit { 244 * cpu_crit: cpu_crit {
245 * temperature = <95000>; 245 * temperature = <95000>;
246 * hysteresis = <2000>; 246 * hysteresis = <2000>;
247 * pull out of here? 247 * pull out of here?
248 * do something with hysteresis? put in debounce? 248 * do something with hysteresis? put in debounce?
249 *  249 *
250 * Note that tshut may be overriden by the board specific DT. 250 * Note that tshut may be overriden by the board specific DT.
251 */ 251 */
252 .s_warn = 75000000, 252 .s_warn = 75000000,
253 .s_tshut = 95000000, 253 .s_tshut = 95000000,
254 }, { 254 }, {
255 .s_data = { .desc = "GPU" }, 255 .s_data = { .desc = "GPU" },
256 .s_data_reg = TSADC_DATA1, 256 .s_data_reg = TSADC_DATA1,
257 .s_comp_tshut = TSADC_COMP1_SHUT, 257 .s_comp_tshut = TSADC_COMP1_SHUT,
258 .s_comp_int = TSADC_COMP1_INT, 258 .s_comp_int = TSADC_COMP1_INT,
259 .s_comp_int_en = TSADC_AUTO_CON_SRC1_EN, 259 .s_comp_int_en = TSADC_AUTO_CON_SRC1_EN,
260 .s_warn = 75000000, 260 .s_warn = 75000000,
261 .s_tshut = 95000000, 261 .s_tshut = 95000000,
262 }, 262 },
263}; 263};
264 264
265/* 265/*
266 * Table from RK3328 manual. Note that the manual lists valid numbers as 266 * Table from RK3328 manual. Note that the manual lists valid numbers as
267 * 4096 - number. This also means it is increasing not decreasing for 267 * 4096 - number. This also means it is increasing not decreasing for
268 * higher temps, and the min and max are also offset from 4096. 268 * higher temps, and the min and max are also offset from 4096.
269 */ 269 */
270#define RK3328_DATA_OFFSET (4096) 270#define RK3328_DATA_OFFSET (4096)
271static const rk_data_array rk3328_data_array[] = { 271static const rk_data_array rk3328_data_array[] = {
272#define ENTRY(d,C) \ 272#define ENTRY(d,C) \
273 { .data = RK3328_DATA_OFFSET - (d), .temp = (C) * 1000 * 1000, } 273 { .data = RK3328_DATA_OFFSET - (d), .temp = (C) * 1000 * 1000, }
274 ENTRY(TSADC_DATA_MAX, -40), 274 ENTRY(TSADC_DATA_MAX, -40),
275 ENTRY(3800, -40), 275 ENTRY(3800, -40),
276 ENTRY(3792, -35), 276 ENTRY(3792, -35),
277 ENTRY(3783, -30), 277 ENTRY(3783, -30),
278 ENTRY(3774, -25), 278 ENTRY(3774, -25),
279 ENTRY(3765, -20), 279 ENTRY(3765, -20),
280 ENTRY(3756, -15), 280 ENTRY(3756, -15),
281 ENTRY(3747, -10), 281 ENTRY(3747, -10),
282 ENTRY(3737, -5), 282 ENTRY(3737, -5),
283 ENTRY(3728, 0), 283 ENTRY(3728, 0),
284 ENTRY(3718, 5), 284 ENTRY(3718, 5),
285 ENTRY(3708, 10), 285 ENTRY(3708, 10),
286 ENTRY(3698, 15), 286 ENTRY(3698, 15),
287 ENTRY(3688, 20), 287 ENTRY(3688, 20),
288 ENTRY(3678, 25), 288 ENTRY(3678, 25),
289 ENTRY(3667, 30), 289 ENTRY(3667, 30),
290 ENTRY(3656, 35), 290 ENTRY(3656, 35),
291 ENTRY(3645, 40), 291 ENTRY(3645, 40),
292 ENTRY(3634, 45), 292 ENTRY(3634, 45),
293 ENTRY(3623, 50), 293 ENTRY(3623, 50),
294 ENTRY(3611, 55), 294 ENTRY(3611, 55),
295 ENTRY(3600, 60), 295 ENTRY(3600, 60),
296 ENTRY(3588, 65), 296 ENTRY(3588, 65),
297 ENTRY(3575, 70), 297 ENTRY(3575, 70),
298 ENTRY(3563, 75), 298 ENTRY(3563, 75),
299 ENTRY(3550, 80), 299 ENTRY(3550, 80),
300 ENTRY(3537, 85), 300 ENTRY(3537, 85),
301 ENTRY(3524, 90), 301 ENTRY(3524, 90),
302 ENTRY(3510, 95), 302 ENTRY(3510, 95),
303 ENTRY(3496, 100), 303 ENTRY(3496, 100),
304 ENTRY(3482, 105), 304 ENTRY(3482, 105),
305 ENTRY(3467, 110), 305 ENTRY(3467, 110),
306 ENTRY(3452, 115), 306 ENTRY(3452, 115),
307 ENTRY(3437, 120), 307 ENTRY(3437, 120),
308 ENTRY(3421, 125), 308 ENTRY(3421, 125),
309 ENTRY(0, 125), 309 ENTRY(0, 125),
310#undef ENTRY 310#undef ENTRY
311}; 311};
312 312
313/* Table from RK3399 manual */ 313/* Table from RK3399 manual */
314static const rk_data_array rk3399_data_array[] = { 314static const rk_data_array rk3399_data_array[] = {
315#define ENTRY(d,C) { .data = (d), .temp = (C) * 1000 * 1000, } 315#define ENTRY(d,C) { .data = (d), .temp = (C) * 1000 * 1000, }
316 ENTRY(0, -40), 316 ENTRY(0, -40),
317 ENTRY(402, -40), 317 ENTRY(402, -40),
318 ENTRY(410, -35), 318 ENTRY(410, -35),
319 ENTRY(419, -30), 319 ENTRY(419, -30),
320 ENTRY(427, -25), 320 ENTRY(427, -25),
321 ENTRY(436, -20), 321 ENTRY(436, -20),
322 ENTRY(444, -15), 322 ENTRY(444, -15),
323 ENTRY(453, -10), 323 ENTRY(453, -10),
324 ENTRY(461, -5), 324 ENTRY(461, -5),
325 ENTRY(470, 0), 325 ENTRY(470, 0),
326 ENTRY(478, 5), 326 ENTRY(478, 5),
327 ENTRY(487, 10), 327 ENTRY(487, 10),
328 ENTRY(496, 15), 328 ENTRY(496, 15),
329 ENTRY(504, 20), 329 ENTRY(504, 20),
330 ENTRY(513, 25), 330 ENTRY(513, 25),
331 ENTRY(521, 30), 331 ENTRY(521, 30),
332 ENTRY(530, 35), 332 ENTRY(530, 35),
333 ENTRY(538, 40), 333 ENTRY(538, 40),
334 ENTRY(547, 45), 334 ENTRY(547, 45),
335 ENTRY(555, 50), 335 ENTRY(555, 50),
336 ENTRY(564, 55), 336 ENTRY(564, 55),
337 ENTRY(573, 60), 337 ENTRY(573, 60),
338 ENTRY(581, 65), 338 ENTRY(581, 65),
339 ENTRY(590, 70), 339 ENTRY(590, 70),
340 ENTRY(599, 75), 340 ENTRY(599, 75),
341 ENTRY(607, 80), 341 ENTRY(607, 80),
342 ENTRY(616, 85), 342 ENTRY(616, 85),
343 ENTRY(624, 90), 343 ENTRY(624, 90),
344 ENTRY(633, 95), 344 ENTRY(633, 95),
345 ENTRY(642, 100), 345 ENTRY(642, 100),
346 ENTRY(650, 105), 346 ENTRY(650, 105),
347 ENTRY(659, 110), 347 ENTRY(659, 110),
348 ENTRY(668, 115), 348 ENTRY(668, 115),
349 ENTRY(677, 120), 349 ENTRY(677, 120),
350 ENTRY(685, 125), 350 ENTRY(685, 125),
351 ENTRY(TSADC_DATA_MAX, 125), 351 ENTRY(TSADC_DATA_MAX, 125),
352#undef ENTRY 352#undef ENTRY
353}; 353};
354 354
355static const rk_data rk3328_data_table = { 355static const rk_data rk3328_data_table = {
356 .rd_array = rk3328_data_array, 356 .rd_array = rk3328_data_array,
357 .rd_size = __arraycount(rk3328_data_array), 357 .rd_size = __arraycount(rk3328_data_array),
358 .rd_init = rk_tsadc_init_rk3328, 358 .rd_init = rk_tsadc_init_rk3328,
359 .rd_decr = false, 359 .rd_decr = false,
360 .rd_max = RK3328_DATA_OFFSET - 3420, 360 .rd_max = RK3328_DATA_OFFSET - 3420,
361 .rd_min = RK3328_DATA_OFFSET - 3801, 361 .rd_min = RK3328_DATA_OFFSET - 3801,
362 .rd_auto_period = RK3328_TSADC_AUTO_PERIOD_TIME, 362 .rd_auto_period = RK3328_TSADC_AUTO_PERIOD_TIME,
363 .rd_num_sensors = 1, 363 .rd_num_sensors = 1,
364}; 364};
365 365
366static const rk_data rk3399_data_table = { 366static const rk_data rk3399_data_table = {
367 .rd_array = rk3399_data_array, 367 .rd_array = rk3399_data_array,
368 .rd_size = __arraycount(rk3399_data_array), 368 .rd_size = __arraycount(rk3399_data_array),
369 .rd_init = rk_tsadc_init_rk3399, 369 .rd_init = rk_tsadc_init_rk3399,
370 .rd_decr = false, 370 .rd_decr = false,
371 .rd_max = 686, 371 .rd_max = 686,
372 .rd_min = 401, 372 .rd_min = 401,
373 .rd_auto_period = RK3399_TSADC_AUTO_PERIOD_TIME, 373 .rd_auto_period = RK3399_TSADC_AUTO_PERIOD_TIME,
374 .rd_num_sensors = 2, 374 .rd_num_sensors = 2,
375}; 375};
376 376
377static const struct device_compatible_entry compat_data[] = { 377static const struct device_compatible_entry compat_data[] = {
378 { .compat = "rockchip,rk3328-tsadc", .data = &rk3328_data_table }, 378 { .compat = "rockchip,rk3328-tsadc", .data = &rk3328_data_table },
379 { .compat = "rockchip,rk3399-tsadc", .data = &rk3399_data_table }, 379 { .compat = "rockchip,rk3399-tsadc", .data = &rk3399_data_table },
380 { } 380 DEVICE_COMPAT_EOL
381}; 381};
382 382
383#define TSADC_READ(sc, reg) \ 383#define TSADC_READ(sc, reg) \
384 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 384 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
385#define TSADC_WRITE(sc, reg, val) \ 385#define TSADC_WRITE(sc, reg, val) \
386 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 386 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
387 387
388CFATTACH_DECL3_NEW(rk_tsadc, sizeof(struct rk_tsadc_softc), 388CFATTACH_DECL3_NEW(rk_tsadc, sizeof(struct rk_tsadc_softc),
389 rk_tsadc_match, rk_tsadc_attach, rk_tsadc_detach, NULL, NULL, NULL, 389 rk_tsadc_match, rk_tsadc_attach, rk_tsadc_detach, NULL, NULL, NULL,
390 DVF_DETACH_SHUTDOWN); 390 DVF_DETACH_SHUTDOWN);
391 391
392/* init/teardown support */ 392/* init/teardown support */
393static int 393static int
394rk_tsadc_match(device_t parent, cfdata_t cf, void *aux) 394rk_tsadc_match(device_t parent, cfdata_t cf, void *aux)
395{ 395{
396 struct fdt_attach_args * const faa = aux; 396 struct fdt_attach_args * const faa = aux;
397 397
398 return of_match_compat_data(faa->faa_phandle, compat_data); 398 return of_match_compat_data(faa->faa_phandle, compat_data);
399} 399}
400 400
401static void 401static void
402rk_tsadc_attach(device_t parent, device_t self, void *aux) 402rk_tsadc_attach(device_t parent, device_t self, void *aux)
403{ 403{
404 struct rk_tsadc_softc * const sc = device_private(self); 404 struct rk_tsadc_softc * const sc = device_private(self);
405 struct fdt_attach_args * const faa = aux; 405 struct fdt_attach_args * const faa = aux;
406 char intrstr[128]; 406 char intrstr[128];
407 const int phandle = faa->faa_phandle; 407 const int phandle = faa->faa_phandle;
408 bus_addr_t addr; 408 bus_addr_t addr;
409 int mode, polarity, tshut_temp; 409 int mode, polarity, tshut_temp;
410 410
411 sc->sc_dev = self; 411 sc->sc_dev = self;
412 sc->sc_phandle = phandle; 412 sc->sc_phandle = phandle;
413 sc->sc_bst = faa->faa_bst; 413 sc->sc_bst = faa->faa_bst;
414 414
415 aprint_naive("\n"); 415 aprint_naive("\n");
416 aprint_normal(": RK3328/3399 Temperature Sensor ADC\n"); 416 aprint_normal(": RK3328/3399 Temperature Sensor ADC\n");
417 417
418 sc->sc_sme = sysmon_envsys_create(); 418 sc->sc_sme = sysmon_envsys_create();
419 419
420 sc->sc_sme->sme_name = device_xname(self); 420 sc->sc_sme->sme_name = device_xname(self);
421 sc->sc_sme->sme_cookie = sc; 421 sc->sc_sme->sme_cookie = sc;
422 sc->sc_sme->sme_refresh = rk_tsadc_refresh; 422 sc->sc_sme->sme_refresh = rk_tsadc_refresh;
423 sc->sc_sme->sme_get_limits = rk_tsadc_get_limits; 423 sc->sc_sme->sme_get_limits = rk_tsadc_get_limits;
424 sc->sc_data_mask = TSADC_DATA_MAX; 424 sc->sc_data_mask = TSADC_DATA_MAX;
425 425
426 pmf_device_register(self, NULL, NULL); 426 pmf_device_register(self, NULL, NULL);
427 427
428 sc->sc_rd = of_search_compatible(faa->faa_phandle, compat_data)->data; 428 sc->sc_rd = of_search_compatible(faa->faa_phandle, compat_data)->data;
429 429
430 /* Default to tshut via gpio and tshut low is active */ 430 /* Default to tshut via gpio and tshut low is active */
431 if (of_getprop_uint32(phandle, "rockchip,hw-tshut-mode", 431 if (of_getprop_uint32(phandle, "rockchip,hw-tshut-mode",
432 &mode) != 0) { 432 &mode) != 0) {
433 aprint_error(": could not get TSHUT mode, default to GPIO"); 433 aprint_error(": could not get TSHUT mode, default to GPIO");
434 mode = TSHUT_MODE_GPIO; 434 mode = TSHUT_MODE_GPIO;
435 } 435 }
436 if (mode != TSHUT_MODE_CPU && mode != TSHUT_MODE_GPIO) { 436 if (mode != TSHUT_MODE_CPU && mode != TSHUT_MODE_GPIO) {
437 aprint_error(": TSHUT mode should be 0 or 1\n"); 437 aprint_error(": TSHUT mode should be 0 or 1\n");
438 goto fail; 438 goto fail;
439 } 439 }
440 440
441 if (of_getprop_uint32(phandle, "rockchip,hw-tshut-polarity", 441 if (of_getprop_uint32(phandle, "rockchip,hw-tshut-polarity",
442 &polarity) != 0) { 442 &polarity) != 0) {
443 aprint_error(": could not get TSHUT polarity, default to low"); 443 aprint_error(": could not get TSHUT polarity, default to low");
444 polarity = TSHUT_LOW_ACTIVE; 444 polarity = TSHUT_LOW_ACTIVE;
445 } 445 }
446 if (of_getprop_uint32(phandle, 446 if (of_getprop_uint32(phandle,
447 "rockchip,hw-tshut-temp", &tshut_temp) != 0) { 447 "rockchip,hw-tshut-temp", &tshut_temp) != 0) {
448 aprint_error(": could not get TSHUT temperature, default to %u", 448 aprint_error(": could not get TSHUT temperature, default to %u",
449 TSHUT_DEF_TEMP); 449 TSHUT_DEF_TEMP);
450 tshut_temp = TSHUT_DEF_TEMP; 450 tshut_temp = TSHUT_DEF_TEMP;
451 } 451 }
452 tshut_temp *= 1000; /* convert fdt ms -> us */ 452 tshut_temp *= 1000; /* convert fdt ms -> us */
453 453
454 memcpy(sc->sc_sensors, rk_tsadc_sensors, sizeof(sc->sc_sensors)); 454 memcpy(sc->sc_sensors, rk_tsadc_sensors, sizeof(sc->sc_sensors));
455 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) { 455 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
456 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 456 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
457 457
458 rks->s_data.flags = ENVSYS_FMONLIMITS; 458 rks->s_data.flags = ENVSYS_FMONLIMITS;
459 rks->s_data.units = ENVSYS_STEMP; 459 rks->s_data.units = ENVSYS_STEMP;
460 rks->s_data.state = ENVSYS_SINVALID; 460 rks->s_data.state = ENVSYS_SINVALID;
461 461
462 if (sysmon_envsys_sensor_attach(sc->sc_sme, &rks->s_data)) 462 if (sysmon_envsys_sensor_attach(sc->sc_sme, &rks->s_data))
463 goto fail; 463 goto fail;
464 rks->s_attached = true; 464 rks->s_attached = true;
465 rks->s_tshut = tshut_temp; 465 rks->s_tshut = tshut_temp;
466#if 0 466#if 0
467 // testing 467 // testing
468 rks->s_tshut = 68000000; 468 rks->s_tshut = 68000000;
469 rks->s_warn = 61000000; 469 rks->s_warn = 61000000;
470#endif 470#endif
471 } 471 }
472 472
473 sc->sc_syscon = fdtbus_syscon_acquire(phandle, "rockchip,grf"); 473 sc->sc_syscon = fdtbus_syscon_acquire(phandle, "rockchip,grf");
474 if (sc->sc_syscon == NULL) { 474 if (sc->sc_syscon == NULL) {
475 aprint_error(": couldn't get grf syscon\n"); 475 aprint_error(": couldn't get grf syscon\n");
476 goto fail; 476 goto fail;
477 } 477 }
478 if (fdtbus_get_reg(phandle, 0, &addr, &sc->sc_size) != 0) { 478 if (fdtbus_get_reg(phandle, 0, &addr, &sc->sc_size) != 0) {
479 aprint_error(": couldn't get registers\n"); 479 aprint_error(": couldn't get registers\n");
480 sc->sc_size = 0; 480 sc->sc_size = 0;
481 goto fail; 481 goto fail;
482 } 482 }
483 if (bus_space_map(sc->sc_bst, addr, sc->sc_size, 0, &sc->sc_bsh) != 0) { 483 if (bus_space_map(sc->sc_bst, addr, sc->sc_size, 0, &sc->sc_bsh) != 0) {
484 aprint_error(": couldn't map registers\n"); 484 aprint_error(": couldn't map registers\n");
485 sc->sc_size = 0; 485 sc->sc_size = 0;
486 goto fail; 486 goto fail;
487 } 487 }
488 488
489 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 489 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
490 aprint_error(": failed to decode interrupt\n"); 490 aprint_error(": failed to decode interrupt\n");
491 goto fail; 491 goto fail;
492 } 492 }
493 493
494 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, FDT_INTR_MPSAFE, 494 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, FDT_INTR_MPSAFE,
495 rk_tsadc_intr, sc, device_xname(self)); 495 rk_tsadc_intr, sc, device_xname(self));
496 if (sc->sc_ih == NULL) { 496 if (sc->sc_ih == NULL) {
497 aprint_error_dev(self, "couldn't establish interrupt on %s\n", 497 aprint_error_dev(self, "couldn't establish interrupt on %s\n",
498 intrstr); 498 intrstr);
499 goto fail; 499 goto fail;
500 } 500 }
501 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 501 aprint_normal_dev(self, "interrupting on %s\n", intrstr);
502 502
503 if (rk_tsadc_init_clocks(sc)) { 503 if (rk_tsadc_init_clocks(sc)) {
504 aprint_error(": couldn't enable clocks\n"); 504 aprint_error(": couldn't enable clocks\n");
505 return; 505 return;
506 } 506 }
507 507
508 /* 508 /*
509 * Manual says to setup auto period (both), high temp (interrupt), 509 * Manual says to setup auto period (both), high temp (interrupt),
510 * high temp (shutdown), enable high temp resets (TSHUT to GPIO 510 * high temp (shutdown), enable high temp resets (TSHUT to GPIO
511 * or reset chip), set the debounce times, and, finally, enable the 511 * or reset chip), set the debounce times, and, finally, enable the
512 * controller iself. 512 * controller iself.
513 */ 513 */
514 rk_tsadc_init(sc, mode, polarity); 514 rk_tsadc_init(sc, mode, polarity);
515 515
516 return; 516 return;
517 517
518fail: 518fail:
519 rk_tsadc_detach(self, 0); 519 rk_tsadc_detach(self, 0);
520} 520}
521 521
522static int 522static int
523rk_tsadc_detach(device_t self, int flags) 523rk_tsadc_detach(device_t self, int flags)
524{ 524{
525 struct rk_tsadc_softc *sc = device_private(self); 525 struct rk_tsadc_softc *sc = device_private(self);
526 526
527 pmf_device_deregister(self); 527 pmf_device_deregister(self);
528 528
529 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) { 529 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
530 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 530 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
531 531
532 if (rks->s_attached) { 532 if (rks->s_attached) {
533 sysmon_envsys_sensor_detach(sc->sc_sme, &rks->s_data); 533 sysmon_envsys_sensor_detach(sc->sc_sme, &rks->s_data);
534 rks->s_attached = false; 534 rks->s_attached = false;
535 } 535 }
536 } 536 }
537 537
538 sysmon_envsys_unregister(sc->sc_sme); 538 sysmon_envsys_unregister(sc->sc_sme);
539 539
540 if (sc->sc_clockapb) 540 if (sc->sc_clockapb)
541 clk_disable(sc->sc_clockapb); 541 clk_disable(sc->sc_clockapb);
542 if (sc->sc_clock) 542 if (sc->sc_clock)
543 clk_disable(sc->sc_clock); 543 clk_disable(sc->sc_clock);
544 544
545 if (sc->sc_ih) 545 if (sc->sc_ih)
546 fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); 546 fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
547 547
548 if (sc->sc_size) 548 if (sc->sc_size)
549 bus_space_unmap(sc->sc_bst, sc->sc_bsh, sc->sc_size); 549 bus_space_unmap(sc->sc_bst, sc->sc_bsh, sc->sc_size);
550 550
551 sysmon_envsys_destroy(sc->sc_sme); 551 sysmon_envsys_destroy(sc->sc_sme);
552 552
553 return 0; 553 return 0;
554} 554}
555 555
556static int 556static int
557rk_tsadc_init_clocks(struct rk_tsadc_softc *sc) 557rk_tsadc_init_clocks(struct rk_tsadc_softc *sc)
558{ 558{
559 int error; 559 int error;
560 560
561 fdtbus_clock_assign(sc->sc_phandle); 561 fdtbus_clock_assign(sc->sc_phandle);
562 562
563 sc->sc_reset = fdtbus_reset_get(sc->sc_phandle, "tsadc-apb"); 563 sc->sc_reset = fdtbus_reset_get(sc->sc_phandle, "tsadc-apb");
564 sc->sc_clock = fdtbus_clock_get(sc->sc_phandle, "tsadc"); 564 sc->sc_clock = fdtbus_clock_get(sc->sc_phandle, "tsadc");
565 sc->sc_clockapb = fdtbus_clock_get(sc->sc_phandle, "apb_pclk"); 565 sc->sc_clockapb = fdtbus_clock_get(sc->sc_phandle, "apb_pclk");
566 if (sc->sc_reset == NULL || 566 if (sc->sc_reset == NULL ||
567 sc->sc_clock == NULL || 567 sc->sc_clock == NULL ||
568 sc->sc_clockapb == NULL) 568 sc->sc_clockapb == NULL)
569 return EINVAL; 569 return EINVAL;
570 570
571 fdtbus_reset_assert(sc->sc_reset); 571 fdtbus_reset_assert(sc->sc_reset);
572 572
573 error = clk_enable(sc->sc_clock); 573 error = clk_enable(sc->sc_clock);
574 if (error) { 574 if (error) {
575 fdtbus_reset_deassert(sc->sc_reset); 575 fdtbus_reset_deassert(sc->sc_reset);
576 return error; 576 return error;
577 } 577 }
578 578
579 error = clk_enable(sc->sc_clockapb); 579 error = clk_enable(sc->sc_clockapb);
580 580
581 DELAY(20); 581 DELAY(20);
582 fdtbus_reset_deassert(sc->sc_reset); 582 fdtbus_reset_deassert(sc->sc_reset);
583 583
584 return error; 584 return error;
585} 585}
586 586
587static void 587static void
588rk_tsadc_init_counts(struct rk_tsadc_softc *sc) 588rk_tsadc_init_counts(struct rk_tsadc_softc *sc)
589{ 589{
590 590
591 TSADC_WRITE(sc, TSADC_AUTO_PERIOD, sc->sc_rd->rd_auto_period); 591 TSADC_WRITE(sc, TSADC_AUTO_PERIOD, sc->sc_rd->rd_auto_period);
592 TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rd->rd_auto_period); 592 TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rd->rd_auto_period);
593 TSADC_WRITE(sc, TSADC_HIGH_INT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT); 593 TSADC_WRITE(sc, TSADC_HIGH_INT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
594 TSADC_WRITE(sc, TSADC_HIGH_TSHUT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT); 594 TSADC_WRITE(sc, TSADC_HIGH_TSHUT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
595} 595}
596 596
597/* Configure the hardware with the tshut setup. */ 597/* Configure the hardware with the tshut setup. */
598static void 598static void
599rk_tsadc_tshut_set(struct rk_tsadc_softc *sc) 599rk_tsadc_tshut_set(struct rk_tsadc_softc *sc)
600{ 600{
601 uint32_t val = TSADC_READ(sc, TSADC_AUTO_CON); 601 uint32_t val = TSADC_READ(sc, TSADC_AUTO_CON);
602 602
603 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) { 603 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
604 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 604 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
605 uint32_t data, warndata; 605 uint32_t data, warndata;
606 606
607 if (!rks->s_attached) 607 if (!rks->s_attached)
608 continue; 608 continue;
609 609
610 data = rk_tsadc_temp_to_data(sc, rks->s_tshut); 610 data = rk_tsadc_temp_to_data(sc, rks->s_tshut);
611 warndata = rk_tsadc_temp_to_data(sc, rks->s_warn); 611 warndata = rk_tsadc_temp_to_data(sc, rks->s_warn);
612 612
613 DPRINTF("(%s:%s): tshut/data %d/%u warn/data %d/%u", 613 DPRINTF("(%s:%s): tshut/data %d/%u warn/data %d/%u",
614 sc->sc_sme->sme_name, rks->s_data.desc, 614 sc->sc_sme->sme_name, rks->s_data.desc,
615 rks->s_tshut, data, 615 rks->s_tshut, data,
616 rks->s_warn, warndata); 616 rks->s_warn, warndata);
617 617
618 if (data == sc->sc_data_mask) { 618 if (data == sc->sc_data_mask) {
619 aprint_error_dev(sc->sc_dev, 619 aprint_error_dev(sc->sc_dev,
620 "Failed converting critical temp %u.%06u to code", 620 "Failed converting critical temp %u.%06u to code",
621 rks->s_tshut / 1000000, rks->s_tshut % 1000000); 621 rks->s_tshut / 1000000, rks->s_tshut % 1000000);
622 continue; 622 continue;
623 } 623 }
624 if (warndata == sc->sc_data_mask) { 624 if (warndata == sc->sc_data_mask) {
625 aprint_error_dev(sc->sc_dev, 625 aprint_error_dev(sc->sc_dev,
626 "Failed converting warn temp %u.%06u to code", 626 "Failed converting warn temp %u.%06u to code",
627 rks->s_warn / 1000000, rks->s_warn % 1000000); 627 rks->s_warn / 1000000, rks->s_warn % 1000000);
628 continue; 628 continue;
629 } 629 }
630 630
631 TSADC_WRITE(sc, rks->s_comp_tshut, data); 631 TSADC_WRITE(sc, rks->s_comp_tshut, data);
632 TSADC_WRITE(sc, rks->s_comp_int, warndata); 632 TSADC_WRITE(sc, rks->s_comp_int, warndata);
633 633
634 val |= rks->s_comp_int_en; 634 val |= rks->s_comp_int_en;
635 } 635 }
636 TSADC_WRITE(sc, TSADC_AUTO_CON, val); 636 TSADC_WRITE(sc, TSADC_AUTO_CON, val);
637} 637}
638 638
639static void 639static void
640rk_tsadc_init_tshut(struct rk_tsadc_softc *sc, int mode, int polarity) 640rk_tsadc_init_tshut(struct rk_tsadc_softc *sc, int mode, int polarity)
641{ 641{
642 uint32_t val; 642 uint32_t val;
643 643
644 /* Handle TSHUT temp setting. */ 644 /* Handle TSHUT temp setting. */
645 rk_tsadc_tshut_set(sc); 645 rk_tsadc_tshut_set(sc);
646 646
647 /* Handle TSHUT mode setting. */ 647 /* Handle TSHUT mode setting. */
648 val = TSADC_READ(sc, TSADC_INT_EN); 648 val = TSADC_READ(sc, TSADC_INT_EN);
649 if (mode == TSHUT_MODE_CPU) { 649 if (mode == TSHUT_MODE_CPU) {
650 val |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 | 650 val |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 |
651 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0; 651 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0;
652 val &= ~(TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 | 652 val &= ~(TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 |
653 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0); 653 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0);
654 } else { 654 } else {
655 KASSERT(mode == TSHUT_MODE_GPIO); 655 KASSERT(mode == TSHUT_MODE_GPIO);
656 val &= ~(TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 | 656 val &= ~(TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 |
657 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0); 657 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0);
658 val |= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 | 658 val |= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 |
659 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0; 659 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0;
660 } 660 }
661 TSADC_WRITE(sc, TSADC_INT_EN, val); 661 TSADC_WRITE(sc, TSADC_INT_EN, val);
662 662
663 /* Handle TSHUT polarity setting. */ 663 /* Handle TSHUT polarity setting. */
664 val = TSADC_READ(sc, TSADC_AUTO_CON); 664 val = TSADC_READ(sc, TSADC_AUTO_CON);
665 if (polarity == TSHUT_HIGH_ACTIVE) 665 if (polarity == TSHUT_HIGH_ACTIVE)
666 val |= TSADC_AUTO_CON_TSHUT_POLARITY; 666 val |= TSADC_AUTO_CON_TSHUT_POLARITY;
667 else 667 else
668 val &= ~TSADC_AUTO_CON_TSHUT_POLARITY; 668 val &= ~TSADC_AUTO_CON_TSHUT_POLARITY;
669 TSADC_WRITE(sc, TSADC_AUTO_CON, val); 669 TSADC_WRITE(sc, TSADC_AUTO_CON, val);
670} 670}
671 671
672static void 672static void
673rk_tsadc_init_rk3328(struct rk_tsadc_softc *sc, int mode, int polarity) 673rk_tsadc_init_rk3328(struct rk_tsadc_softc *sc, int mode, int polarity)
674{ 674{
675 675
676 rk_tsadc_init_tshut(sc, mode, polarity); 676 rk_tsadc_init_tshut(sc, mode, polarity);
677 rk_tsadc_init_counts(sc); 677 rk_tsadc_init_counts(sc);
678} 678}
679 679
680static void 680static void
681rk_tsadc_init_rk3399(struct rk_tsadc_softc *sc, int mode, int polarity) 681rk_tsadc_init_rk3399(struct rk_tsadc_softc *sc, int mode, int polarity)
682{ 682{
683 683
684 syscon_lock(sc->sc_syscon); 684 syscon_lock(sc->sc_syscon);
685 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_L, 685 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_L,
686 RK3399_GRF_TSADC_TESTBIT_VCM_EN_L); 686 RK3399_GRF_TSADC_TESTBIT_VCM_EN_L);
687 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H, 687 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H,
688 RK3399_GRF_TSADC_TESTBIT_VCM_EN_H); 688 RK3399_GRF_TSADC_TESTBIT_VCM_EN_H);
689 689
690 DELAY(20); 690 DELAY(20);
691 syscon_write_4(sc->sc_syscon, RK3399_GRF_SARADC_TESTBIT, 691 syscon_write_4(sc->sc_syscon, RK3399_GRF_SARADC_TESTBIT,
692 RK3399_GRF_SARADC_TESTBIT_ON); 692 RK3399_GRF_SARADC_TESTBIT_ON);
693 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H, 693 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H,
694 RK3399_GRF_TSADC_TESTBIT_H_ON); 694 RK3399_GRF_TSADC_TESTBIT_H_ON);
695 DELAY(100); 695 DELAY(100);
696 syscon_unlock(sc->sc_syscon); 696 syscon_unlock(sc->sc_syscon);
697 697
698 rk_tsadc_init_counts(sc); 698 rk_tsadc_init_counts(sc);
699 rk_tsadc_init_tshut(sc, mode, polarity); 699 rk_tsadc_init_tshut(sc, mode, polarity);
700} 700}
701 701
702static void 702static void
703rk_tsadc_init_enable(struct rk_tsadc_softc *sc) 703rk_tsadc_init_enable(struct rk_tsadc_softc *sc)
704{ 704{
705 uint32_t val; 705 uint32_t val;
706 706
707 val = TSADC_READ(sc, TSADC_AUTO_CON); 707 val = TSADC_READ(sc, TSADC_AUTO_CON);
708 val |= TSADC_AUTO_CON_AUTO_STATUS |  708 val |= TSADC_AUTO_CON_AUTO_STATUS |
709 TSADC_AUTO_CON_SRC1_LT_EN | TSADC_AUTO_CON_SRC0_LT_EN; 709 TSADC_AUTO_CON_SRC1_LT_EN | TSADC_AUTO_CON_SRC0_LT_EN;
710 TSADC_WRITE(sc, TSADC_AUTO_CON, val); 710 TSADC_WRITE(sc, TSADC_AUTO_CON, val);
711 711
712 /* Finally, register & enable the controller */ 712 /* Finally, register & enable the controller */
713 sysmon_envsys_register(sc->sc_sme); 713 sysmon_envsys_register(sc->sc_sme);
714 714
715 val = TSADC_READ(sc, TSADC_AUTO_CON); 715 val = TSADC_READ(sc, TSADC_AUTO_CON);
716 val |= TSADC_AUTO_CON_AUTO_EN | TSADC_AUTO_CON_Q_SEL; 716 val |= TSADC_AUTO_CON_AUTO_EN | TSADC_AUTO_CON_Q_SEL;
717 TSADC_WRITE(sc, TSADC_AUTO_CON, val); 717 TSADC_WRITE(sc, TSADC_AUTO_CON, val);
718} 718}
719 719
720static void 720static void
721rk_tsadc_init(struct rk_tsadc_softc *sc, int mode, int polarity) 721rk_tsadc_init(struct rk_tsadc_softc *sc, int mode, int polarity)
722{ 722{
723 723
724 (*sc->sc_rd->rd_init)(sc, mode, polarity); 724 (*sc->sc_rd->rd_init)(sc, mode, polarity);
725 rk_tsadc_init_enable(sc); 725 rk_tsadc_init_enable(sc);
726} 726}
727 727
728/* run time support */ 728/* run time support */
729 729
730/* given edata, find the matching rk sensor structure */ 730/* given edata, find the matching rk sensor structure */
731static struct rk_tsadc_sensor * 731static struct rk_tsadc_sensor *
732rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc, envsys_data_t *edata) 732rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc, envsys_data_t *edata)
733{ 733{
734 734
735 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) { 735 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
736 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 736 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
737 737
738 if (&rks->s_data == edata) 738 if (&rks->s_data == edata)
739 return rks; 739 return rks;
740 } 740 }
741 return NULL; 741 return NULL;
742} 742}
743 743
744static void 744static void
745rk_tsadc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 745rk_tsadc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
746{ 746{
747 struct rk_tsadc_softc * const sc = sme->sme_cookie; 747 struct rk_tsadc_softc * const sc = sme->sme_cookie;
748 struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata); 748 struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata);
749 unsigned data; 749 unsigned data;
750 int temp; 750 int temp;
751 751
752 if (rks == NULL) 752 if (rks == NULL)
753 return; 753 return;
754 754
755 data = TSADC_READ(sc, rks->s_data_reg) & sc->sc_data_mask; 755 data = TSADC_READ(sc, rks->s_data_reg) & sc->sc_data_mask;
756 temp = rk_tsadc_data_to_temp(sc, data); 756 temp = rk_tsadc_data_to_temp(sc, data);
757 757
758 DPRINTF("(%s:%s): temp/data %d/%u", 758 DPRINTF("(%s:%s): temp/data %d/%u",
759 sc->sc_sme->sme_name, rks->s_data.desc, 759 sc->sc_sme->sme_name, rks->s_data.desc,
760 temp, data); 760 temp, data);
761 761
762 if (temp == sc->sc_data_mask) { 762 if (temp == sc->sc_data_mask) {
763 edata->state = ENVSYS_SINVALID; 763 edata->state = ENVSYS_SINVALID;
764 } else { 764 } else {
765 edata->value_cur = temp + TEMP_uC_TO_uK; 765 edata->value_cur = temp + TEMP_uC_TO_uK;
766 edata->state = ENVSYS_SVALID; 766 edata->state = ENVSYS_SVALID;
767 } 767 }
768} 768}
769 769
770static void 770static void
771rk_tsadc_get_limits(struct sysmon_envsys *sme, 771rk_tsadc_get_limits(struct sysmon_envsys *sme,
772 envsys_data_t *edata, 772 envsys_data_t *edata,
773 sysmon_envsys_lim_t *lim, 773 sysmon_envsys_lim_t *lim,
774 uint32_t *props) 774 uint32_t *props)
775{ 775{
776 struct rk_tsadc_softc *sc = sme->sme_cookie; 776 struct rk_tsadc_softc *sc = sme->sme_cookie;
777 struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata); 777 struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata);
778 778
779 if (rks == NULL) 779 if (rks == NULL)
780 return; 780 return;
781 781
782 lim->sel_critmax = rks->s_tshut + TEMP_uC_TO_uK; 782 lim->sel_critmax = rks->s_tshut + TEMP_uC_TO_uK;
783 lim->sel_warnmax = rks->s_warn + TEMP_uC_TO_uK; 783 lim->sel_warnmax = rks->s_warn + TEMP_uC_TO_uK;
784 784
785 *props = PROP_CRITMAX | PROP_WARNMAX; 785 *props = PROP_CRITMAX | PROP_WARNMAX;
786} 786}
787 787
788/* XXX do something with interrupts that don't happen yet. */ 788/* XXX do something with interrupts that don't happen yet. */
789static int 789static int
790rk_tsadc_intr(void *arg) 790rk_tsadc_intr(void *arg)
791{ 791{
792 struct rk_tsadc_softc * const sc = arg; 792 struct rk_tsadc_softc * const sc = arg;
793 uint32_t val; 793 uint32_t val;
794 794
795 /* XXX */ 795 /* XXX */
796 DPRINTF("(%s): interrupted", sc->sc_sme->sme_name); 796 DPRINTF("(%s): interrupted", sc->sc_sme->sme_name);
797 for (unsigned n = 0; n < __arraycount(rk_tsadc_sensors); n++) { 797 for (unsigned n = 0; n < __arraycount(rk_tsadc_sensors); n++) {
798 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 798 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
799 799
800 rk_tsadc_refresh(sc->sc_sme, (envsys_data_t *)rks); 800 rk_tsadc_refresh(sc->sc_sme, (envsys_data_t *)rks);
801 } 801 }
802 802
803 /* ack interrupt */ 803 /* ack interrupt */
804 val = TSADC_READ(sc, TSADC_INT_PD); 804 val = TSADC_READ(sc, TSADC_INT_PD);
805 TSADC_WRITE(sc, TSADC_INT_PD, val & ~TSADC_INT_PD_EOC_INT_PD); 805 TSADC_WRITE(sc, TSADC_INT_PD, val & ~TSADC_INT_PD_EOC_INT_PD);
806 806
807 return 1; 807 return 1;
808} 808}
809 809
810/* 810/*
811 * Convert TDASC data codes to temp and reverse. The manual only has codes 811 * Convert TDASC data codes to temp and reverse. The manual only has codes
812 * and temperature values in 5 degC intervals, but says that interpolation 812 * and temperature values in 5 degC intervals, but says that interpolation
813 * can be done to achieve better resolution between these values, and that 813 * can be done to achieve better resolution between these values, and that
814 * the spacing is linear. 814 * the spacing is linear.
815 */ 815 */
816static int 816static int
817rk_tsadc_data_to_temp(struct rk_tsadc_softc *sc, uint32_t data) 817rk_tsadc_data_to_temp(struct rk_tsadc_softc *sc, uint32_t data)
818{ 818{
819 unsigned i; 819 unsigned i;
820 const rk_data *rd = sc->sc_rd; 820 const rk_data *rd = sc->sc_rd;
821 821
822 if (data > rd->rd_max || data < rd->rd_min) { 822 if (data > rd->rd_max || data < rd->rd_min) {
823 DPRINTF("data out of range (%u > %u || %u < %u)", 823 DPRINTF("data out of range (%u > %u || %u < %u)",
824 data, rd->rd_max, data, rd->rd_min); 824 data, rd->rd_max, data, rd->rd_min);
825 return sc->sc_data_mask; 825 return sc->sc_data_mask;
826 } 826 }
827 for (i = 1; i < rd->rd_size; i++) { 827 for (i = 1; i < rd->rd_size; i++) {
828 if (rd->rd_array[i].data >= data) { 828 if (rd->rd_array[i].data >= data) {
829 int temprange, offset; 829 int temprange, offset;
830 uint32_t datarange, datadiff; 830 uint32_t datarange, datadiff;
831 unsigned first, secnd; 831 unsigned first, secnd;
832 832
833 if (rd->rd_array[i].data == data) 833 if (rd->rd_array[i].data == data)
834 return rd->rd_array[i].temp; 834 return rd->rd_array[i].temp;
835 835
836 /* must interpolate */ 836 /* must interpolate */
837 if (rd->rd_decr) { 837 if (rd->rd_decr) {
838 first = i; 838 first = i;
839 secnd = i+1; 839 secnd = i+1;
840 } else { 840 } else {
841 first = i; 841 first = i;
842 secnd = i-1; 842 secnd = i-1;
843 } 843 }
844 844
845 temprange = rd->rd_array[first].temp - 845 temprange = rd->rd_array[first].temp -
846 rd->rd_array[secnd].temp; 846 rd->rd_array[secnd].temp;
847 datarange = rd->rd_array[first].data - 847 datarange = rd->rd_array[first].data -
848 rd->rd_array[secnd].data; 848 rd->rd_array[secnd].data;
849 datadiff = data - rd->rd_array[secnd].data; 849 datadiff = data - rd->rd_array[secnd].data;
850 850
851 offset = (temprange * datadiff) / datarange; 851 offset = (temprange * datadiff) / datarange;
852 return rd->rd_array[secnd].temp + offset; 852 return rd->rd_array[secnd].temp + offset;
853 } 853 }
854 } 854 }
855 panic("didn't find range"); 855 panic("didn't find range");
856} 856}
857 857
858static uint32_t 858static uint32_t
859rk_tsadc_temp_to_data(struct rk_tsadc_softc *sc, int temp) 859rk_tsadc_temp_to_data(struct rk_tsadc_softc *sc, int temp)
860{ 860{
861 unsigned i; 861 unsigned i;
862 const rk_data *rd = sc->sc_rd; 862 const rk_data *rd = sc->sc_rd;
863 863
864 for (i = 1; i < rd->rd_size; i++) { 864 for (i = 1; i < rd->rd_size; i++) {
865 if (rd->rd_array[i].temp >= temp) { 865 if (rd->rd_array[i].temp >= temp) {
866 int temprange, tempdiff; 866 int temprange, tempdiff;
867 uint32_t datarange, offset; 867 uint32_t datarange, offset;
868 unsigned first, secnd; 868 unsigned first, secnd;
869 869
870 if (rd->rd_array[i].temp == temp) 870 if (rd->rd_array[i].temp == temp)
871 return rd->rd_array[i].data; 871 return rd->rd_array[i].data;
872 872
873 /* must interpolate */ 873 /* must interpolate */
874 if (rd->rd_decr) { 874 if (rd->rd_decr) {
875 first = i; 875 first = i;
876 secnd = i+1; 876 secnd = i+1;
877 } else { 877 } else {
878 first = i; 878 first = i;
879 secnd = i-1; 879 secnd = i-1;
880 } 880 }
881 881
882 datarange = rd->rd_array[first].data - 882 datarange = rd->rd_array[first].data -
883 rd->rd_array[secnd].data; 883 rd->rd_array[secnd].data;
884 temprange = rd->rd_array[first].temp - 884 temprange = rd->rd_array[first].temp -
885 rd->rd_array[secnd].temp; 885 rd->rd_array[secnd].temp;
886 tempdiff = temp - rd->rd_array[secnd].temp; 886 tempdiff = temp - rd->rd_array[secnd].temp;
887 887
888 offset = (datarange * tempdiff) / temprange; 888 offset = (datarange * tempdiff) / temprange;
889 return rd->rd_array[secnd].data + offset; 889 return rd->rd_array[secnd].data + offset;
890 } 890 }
891 } 891 }
892 892
893 return sc->sc_data_mask; 893 return sc->sc_data_mask;
894} 894}

cvs diff -r1.9 -r1.10 src/sys/arch/arm/rockchip/rk_usb.c (switch to unified diff)

--- src/sys/arch/arm/rockchip/rk_usb.c 2021/01/25 14:20:38 1.9
+++ src/sys/arch/arm/rockchip/rk_usb.c 2021/01/27 02:00:02 1.10
@@ -1,428 +1,428 @@ @@ -1,428 +1,428 @@
1/* $NetBSD: rk_usb.c,v 1.9 2021/01/25 14:20:38 thorpej Exp $ */ 1/* $NetBSD: rk_usb.c,v 1.10 2021/01/27 02:00:02 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30 30
31__KERNEL_RCSID(0, "$NetBSD: rk_usb.c,v 1.9 2021/01/25 14:20:38 thorpej Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: rk_usb.c,v 1.10 2021/01/27 02:00:02 thorpej Exp $");
32 32
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/bus.h> 34#include <sys/bus.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/intr.h> 36#include <sys/intr.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/time.h> 38#include <sys/time.h>
39#include <sys/kmem.h> 39#include <sys/kmem.h>
40 40
41#include <dev/clk/clk_backend.h> 41#include <dev/clk/clk_backend.h>
42 42
43#include <dev/fdt/fdtvar.h> 43#include <dev/fdt/fdtvar.h>
44#include <dev/fdt/syscon.h> 44#include <dev/fdt/syscon.h>
45 45
46static int rk_usb_match(device_t, cfdata_t, void *); 46static int rk_usb_match(device_t, cfdata_t, void *);
47static void rk_usb_attach(device_t, device_t, void *); 47static void rk_usb_attach(device_t, device_t, void *);
48 48
49#define RK3328_CON0_REG 0x100 49#define RK3328_CON0_REG 0x100
50#define RK3328_CON1_REG 0x104 50#define RK3328_CON1_REG 0x104
51#define RK3328_CON2_REG 0x108 51#define RK3328_CON2_REG 0x108
52#define RK3328_USBPHY_COMMONONN __BIT(4) 52#define RK3328_USBPHY_COMMONONN __BIT(4)
53 53
54#define RK3399_GRF_USB20_PHY0_CON0_REG 0x0e450 54#define RK3399_GRF_USB20_PHY0_CON0_REG 0x0e450
55#define RK3399_GRF_USB20_PHY1_CON0_REG 0x0e460 55#define RK3399_GRF_USB20_PHY1_CON0_REG 0x0e460
56#define RK3399_USBPHY_COMMONONN __BIT(4) 56#define RK3399_USBPHY_COMMONONN __BIT(4)
57#define RK3399_GRF_USB20_PHY0_CON1_REG 0x0e454 57#define RK3399_GRF_USB20_PHY0_CON1_REG 0x0e454
58#define RK3399_GRF_USB20_PHY1_CON1_REG 0x0e464 58#define RK3399_GRF_USB20_PHY1_CON1_REG 0x0e464
59#define RK3399_GRF_USB20_PHY0_CON2_REG 0x0e458 59#define RK3399_GRF_USB20_PHY0_CON2_REG 0x0e458
60#define RK3399_GRF_USB20_PHY1_CON2_REG 0x0e468 60#define RK3399_GRF_USB20_PHY1_CON2_REG 0x0e468
61#define RK3399_USBPHY_SUSPEND_N __BIT(1) 61#define RK3399_USBPHY_SUSPEND_N __BIT(1)
62#define RK3399_USBPHY_UTMI_SEL __BIT(0) 62#define RK3399_USBPHY_UTMI_SEL __BIT(0)
63 63
64#define RK3399_PHY_NO(_sc) ((_sc)->sc_reg == 0xe450 ? 0 : 1) 64#define RK3399_PHY_NO(_sc) ((_sc)->sc_reg == 0xe450 ? 0 : 1)
65 65
66enum rk_usb_type { 66enum rk_usb_type {
67 USB_RK3328 = 1, 67 USB_RK3328 = 1,
68 USB_RK3399, 68 USB_RK3399,
69}; 69};
70 70
71static const struct device_compatible_entry compat_data[] = { 71static const struct device_compatible_entry compat_data[] = {
72 { .compat = "rockchip,rk3328-usb2phy", .value = USB_RK3328 }, 72 { .compat = "rockchip,rk3328-usb2phy", .value = USB_RK3328 },
73 { .compat = "rockchip,rk3399-usb2phy", .value = USB_RK3399 }, 73 { .compat = "rockchip,rk3399-usb2phy", .value = USB_RK3399 },
74 { } 74 DEVICE_COMPAT_EOL
75}; 75};
76 76
77struct rk_usb_clk { 77struct rk_usb_clk {
78 struct clk base; 78 struct clk base;
79}; 79};
80 80
81struct rk_usb_softc { 81struct rk_usb_softc {
82 device_t sc_dev; 82 device_t sc_dev;
83 struct syscon *sc_syscon; 83 struct syscon *sc_syscon;
84 enum rk_usb_type sc_type; 84 enum rk_usb_type sc_type;
85 85
86 struct clk_domain sc_clkdom; 86 struct clk_domain sc_clkdom;
87 struct rk_usb_clk sc_usbclk; 87 struct rk_usb_clk sc_usbclk;
88 88
89 bus_addr_t sc_reg; 89 bus_addr_t sc_reg;
90}; 90};
91 91
92CFATTACH_DECL_NEW(rk_usb, sizeof(struct rk_usb_softc), 92CFATTACH_DECL_NEW(rk_usb, sizeof(struct rk_usb_softc),
93 rk_usb_match, rk_usb_attach, NULL, NULL); 93 rk_usb_match, rk_usb_attach, NULL, NULL);
94 94
95static struct clk * 95static struct clk *
96rk_usb_clk_get(void *priv, const char *name) 96rk_usb_clk_get(void *priv, const char *name)
97{ 97{
98 struct rk_usb_softc * const sc = priv; 98 struct rk_usb_softc * const sc = priv;
99 99
100 if (strcmp(name, sc->sc_usbclk.base.name) != 0) 100 if (strcmp(name, sc->sc_usbclk.base.name) != 0)
101 return NULL; 101 return NULL;
102 102
103 return &sc->sc_usbclk.base; 103 return &sc->sc_usbclk.base;
104} 104}
105 105
106static void 106static void
107rk_usb_clk_put(void *priv, struct clk *clk) 107rk_usb_clk_put(void *priv, struct clk *clk)
108{ 108{
109} 109}
110 110
111static u_int 111static u_int
112rk_usb_clk_get_rate(void *priv, struct clk *clk) 112rk_usb_clk_get_rate(void *priv, struct clk *clk)
113{ 113{
114 return 480000000; 114 return 480000000;
115} 115}
116 116
117static int 117static int
118rk_usb_clk_enable(void *priv, struct clk *clk) 118rk_usb_clk_enable(void *priv, struct clk *clk)
119{ 119{
120 struct rk_usb_softc * const sc = priv; 120 struct rk_usb_softc * const sc = priv;
121 uint32_t reg, write_mask, write_val; 121 uint32_t reg, write_mask, write_val;
122 122
123 switch (sc->sc_type) { 123 switch (sc->sc_type) {
124 case USB_RK3328: 124 case USB_RK3328:
125 reg = RK3328_CON2_REG; 125 reg = RK3328_CON2_REG;
126 write_mask = RK3328_USBPHY_COMMONONN << 16; 126 write_mask = RK3328_USBPHY_COMMONONN << 16;
127 write_val = 0; 127 write_val = 0;
128 break; 128 break;
129 case USB_RK3399: 129 case USB_RK3399:
130 reg = RK3399_PHY_NO(sc) == 0 ? 130 reg = RK3399_PHY_NO(sc) == 0 ?
131 RK3399_GRF_USB20_PHY0_CON0_REG : 131 RK3399_GRF_USB20_PHY0_CON0_REG :
132 RK3399_GRF_USB20_PHY1_CON0_REG; 132 RK3399_GRF_USB20_PHY1_CON0_REG;
133 write_mask = RK3399_USBPHY_COMMONONN << 16; 133 write_mask = RK3399_USBPHY_COMMONONN << 16;
134 write_val = 0; 134 write_val = 0;
135 break; 135 break;
136 default: 136 default:
137 return ENXIO; 137 return ENXIO;
138 } 138 }
139 139
140 syscon_lock(sc->sc_syscon); 140 syscon_lock(sc->sc_syscon);
141 syscon_write_4(sc->sc_syscon, reg, write_mask | write_val); 141 syscon_write_4(sc->sc_syscon, reg, write_mask | write_val);
142 syscon_unlock(sc->sc_syscon); 142 syscon_unlock(sc->sc_syscon);
143 143
144 return 0; 144 return 0;
145} 145}
146 146
147static int 147static int
148rk_usb_clk_disable(void *priv, struct clk *clk) 148rk_usb_clk_disable(void *priv, struct clk *clk)
149{ 149{
150 struct rk_usb_softc * const sc = priv; 150 struct rk_usb_softc * const sc = priv;
151 uint32_t reg, write_mask, write_val; 151 uint32_t reg, write_mask, write_val;
152 152
153 switch (sc->sc_type) { 153 switch (sc->sc_type) {
154 case USB_RK3328: 154 case USB_RK3328:
155 reg = RK3328_CON2_REG; 155 reg = RK3328_CON2_REG;
156 write_mask = RK3328_USBPHY_COMMONONN << 16; 156 write_mask = RK3328_USBPHY_COMMONONN << 16;
157 write_val = RK3328_USBPHY_COMMONONN; 157 write_val = RK3328_USBPHY_COMMONONN;
158 break; 158 break;
159 case USB_RK3399: 159 case USB_RK3399:
160 reg = RK3399_PHY_NO(sc) == 0 ? 160 reg = RK3399_PHY_NO(sc) == 0 ?
161 RK3399_GRF_USB20_PHY0_CON0_REG : 161 RK3399_GRF_USB20_PHY0_CON0_REG :
162 RK3399_GRF_USB20_PHY1_CON0_REG; 162 RK3399_GRF_USB20_PHY1_CON0_REG;
163 write_mask = RK3399_USBPHY_COMMONONN << 16; 163 write_mask = RK3399_USBPHY_COMMONONN << 16;
164 write_val = RK3399_USBPHY_COMMONONN; 164 write_val = RK3399_USBPHY_COMMONONN;
165 break; 165 break;
166 default: 166 default:
167 return ENXIO; 167 return ENXIO;
168 } 168 }
169 169
170 syscon_lock(sc->sc_syscon); 170 syscon_lock(sc->sc_syscon);
171 syscon_write_4(sc->sc_syscon, reg, write_mask | write_val); 171 syscon_write_4(sc->sc_syscon, reg, write_mask | write_val);
172 syscon_unlock(sc->sc_syscon); 172 syscon_unlock(sc->sc_syscon);
173 173
174 return 0; 174 return 0;
175} 175}
176 176
177static const struct clk_funcs rk_usb_clk_funcs = { 177static const struct clk_funcs rk_usb_clk_funcs = {
178 .get = rk_usb_clk_get, 178 .get = rk_usb_clk_get,
179 .put = rk_usb_clk_put, 179 .put = rk_usb_clk_put,
180 .get_rate = rk_usb_clk_get_rate, 180 .get_rate = rk_usb_clk_get_rate,
181 .enable = rk_usb_clk_enable, 181 .enable = rk_usb_clk_enable,
182 .disable = rk_usb_clk_disable, 182 .disable = rk_usb_clk_disable,
183}; 183};
184 184
185static struct clk * 185static struct clk *
186rk_usb_fdt_decode(device_t dev, int cc_phandle, const void *data, size_t len) 186rk_usb_fdt_decode(device_t dev, int cc_phandle, const void *data, size_t len)
187{ 187{
188 struct rk_usb_softc * const sc = device_private(dev); 188 struct rk_usb_softc * const sc = device_private(dev);
189 189
190 if (len != 0) 190 if (len != 0)
191 return NULL; 191 return NULL;
192 192
193 return &sc->sc_usbclk.base; 193 return &sc->sc_usbclk.base;
194} 194}
195 195
196static const struct fdtbus_clock_controller_func rk_usb_fdt_funcs = { 196static const struct fdtbus_clock_controller_func rk_usb_fdt_funcs = {
197 .decode = rk_usb_fdt_decode 197 .decode = rk_usb_fdt_decode
198}; 198};
199 199
200static int 200static int
201rk_usb_match(device_t parent, cfdata_t cf, void *aux) 201rk_usb_match(device_t parent, cfdata_t cf, void *aux)
202{ 202{
203 struct fdt_attach_args * const faa = aux; 203 struct fdt_attach_args * const faa = aux;
204 204
205 return of_match_compat_data(faa->faa_phandle, compat_data); 205 return of_match_compat_data(faa->faa_phandle, compat_data);
206} 206}
207 207
208static void 208static void
209rk_usb_attach(device_t parent, device_t self, void *aux) 209rk_usb_attach(device_t parent, device_t self, void *aux)
210{ 210{
211 struct rk_usb_softc * const sc = device_private(self); 211 struct rk_usb_softc * const sc = device_private(self);
212 struct fdt_attach_args * const faa = aux; 212 struct fdt_attach_args * const faa = aux;
213 const int phandle = faa->faa_phandle; 213 const int phandle = faa->faa_phandle;
214 struct clk *clk; 214 struct clk *clk;
215 int child; 215 int child;
216 216
217 /* Cache the base address of this PHY so we know which instance we are */ 217 /* Cache the base address of this PHY so we know which instance we are */
218 if (fdtbus_get_reg(phandle, 0, &sc->sc_reg, NULL) != 0) { 218 if (fdtbus_get_reg(phandle, 0, &sc->sc_reg, NULL) != 0) {
219 aprint_error(": couldn't get registers\n"); 219 aprint_error(": couldn't get registers\n");
220 return; 220 return;
221 } 221 }
222 222
223 clk = fdtbus_clock_get(phandle, "phyclk"); 223 clk = fdtbus_clock_get(phandle, "phyclk");
224 if (clk && clk_enable(clk) != 0) { 224 if (clk && clk_enable(clk) != 0) {
225 aprint_error(": couldn't enable phy clock\n"); 225 aprint_error(": couldn't enable phy clock\n");
226 return; 226 return;
227 } 227 }
228 228
229 sc->sc_dev = self; 229 sc->sc_dev = self;
230 sc->sc_type = of_search_compatible(phandle, compat_data)->value; 230 sc->sc_type = of_search_compatible(phandle, compat_data)->value;
231 sc->sc_syscon = fdtbus_syscon_lookup(OF_parent(phandle)); 231 sc->sc_syscon = fdtbus_syscon_lookup(OF_parent(phandle));
232 if (sc->sc_syscon == NULL) { 232 if (sc->sc_syscon == NULL) {
233 aprint_error(": couldn't get grf syscon\n"); 233 aprint_error(": couldn't get grf syscon\n");
234 return; 234 return;
235 } 235 }
236 236
237 const char *clkname = fdtbus_get_string(phandle, "clock-output-names"); 237 const char *clkname = fdtbus_get_string(phandle, "clock-output-names");
238 if (clkname == NULL) 238 if (clkname == NULL)
239 clkname = faa->faa_name; 239 clkname = faa->faa_name;
240 240
241 sc->sc_clkdom.name = device_xname(self); 241 sc->sc_clkdom.name = device_xname(self);
242 sc->sc_clkdom.funcs = &rk_usb_clk_funcs; 242 sc->sc_clkdom.funcs = &rk_usb_clk_funcs;
243 sc->sc_clkdom.priv = sc; 243 sc->sc_clkdom.priv = sc;
244 sc->sc_usbclk.base.domain = &sc->sc_clkdom; 244 sc->sc_usbclk.base.domain = &sc->sc_clkdom;
245 sc->sc_usbclk.base.name = kmem_asprintf("%s", clkname); 245 sc->sc_usbclk.base.name = kmem_asprintf("%s", clkname);
246 clk_attach(&sc->sc_usbclk.base); 246 clk_attach(&sc->sc_usbclk.base);
247 247
248 aprint_naive("\n"); 248 aprint_naive("\n");
249 aprint_normal(": USB2 PHY\n"); 249 aprint_normal(": USB2 PHY\n");
250 250
251 fdtbus_register_clock_controller(self, phandle, &rk_usb_fdt_funcs); 251 fdtbus_register_clock_controller(self, phandle, &rk_usb_fdt_funcs);
252 252
253 for (child = OF_child(phandle); child; child = OF_peer(child)) { 253 for (child = OF_child(phandle); child; child = OF_peer(child)) {
254 if (!fdtbus_status_okay(child)) 254 if (!fdtbus_status_okay(child))
255 continue; 255 continue;
256 256
257 struct fdt_attach_args cfaa = *faa; 257 struct fdt_attach_args cfaa = *faa;
258 cfaa.faa_phandle = child; 258 cfaa.faa_phandle = child;
259 cfaa.faa_name = fdtbus_get_string(child, "name"); 259 cfaa.faa_name = fdtbus_get_string(child, "name");
260 cfaa.faa_quiet = false; 260 cfaa.faa_quiet = false;
261 261
262 config_found(self, &cfaa, NULL); 262 config_found(self, &cfaa, NULL);
263 } 263 }
264} 264}
265 265
266/* 266/*
267 * USB PHY 267 * USB PHY
268 */ 268 */
269 269
270static int rk_usbphy_match(device_t, cfdata_t, void *); 270static int rk_usbphy_match(device_t, cfdata_t, void *);
271static void rk_usbphy_attach(device_t, device_t, void *); 271static void rk_usbphy_attach(device_t, device_t, void *);
272 272
273struct rk_usbphy_softc { 273struct rk_usbphy_softc {
274 device_t sc_dev; 274 device_t sc_dev;
275 int sc_phandle; 275 int sc_phandle;
276 struct fdtbus_regulator *sc_supply; 276 struct fdtbus_regulator *sc_supply;
277}; 277};
278 278
279CFATTACH_DECL_NEW(rk_usbphy, sizeof(struct rk_usbphy_softc), 279CFATTACH_DECL_NEW(rk_usbphy, sizeof(struct rk_usbphy_softc),
280 rk_usbphy_match, rk_usbphy_attach, NULL, NULL); 280 rk_usbphy_match, rk_usbphy_attach, NULL, NULL);
281 281
282static void * 282static void *
283rk_usbphy_acquire(device_t dev, const void *data, size_t len) 283rk_usbphy_acquire(device_t dev, const void *data, size_t len)
284{ 284{
285 struct rk_usbphy_softc * const sc = device_private(dev); 285 struct rk_usbphy_softc * const sc = device_private(dev);
286 286
287 if (len != 0) 287 if (len != 0)
288 return NULL; 288 return NULL;
289 289
290 return sc; 290 return sc;
291} 291}
292 292
293static void 293static void
294rk_usbphy_release(device_t dev, void *priv) 294rk_usbphy_release(device_t dev, void *priv)
295{ 295{
296} 296}
297 297
298static int 298static int
299rk_usbphy_otg_enable(device_t dev, void *priv, bool enable) 299rk_usbphy_otg_enable(device_t dev, void *priv, bool enable)
300{ 300{
301 struct rk_usbphy_softc * const sc = device_private(dev); 301 struct rk_usbphy_softc * const sc = device_private(dev);
302 struct rk_usb_softc * const usb_sc = device_private(device_parent(dev)); 302 struct rk_usb_softc * const usb_sc = device_private(device_parent(dev));
303 uint32_t reg, write_mask, write_val; 303 uint32_t reg, write_mask, write_val;
304 int error; 304 int error;
305 305
306 switch (usb_sc->sc_type) { 306 switch (usb_sc->sc_type) {
307 case USB_RK3328: 307 case USB_RK3328:
308 reg = RK3328_CON0_REG; 308 reg = RK3328_CON0_REG;
309 write_mask = 0x1ffU << 16; 309 write_mask = 0x1ffU << 16;
310 write_val = enable ? 0 : 0x1d1; 310 write_val = enable ? 0 : 0x1d1;
311 break; 311 break;
312 case USB_RK3399: 312 case USB_RK3399:
313 reg = RK3399_PHY_NO(usb_sc) == 0 ? 313 reg = RK3399_PHY_NO(usb_sc) == 0 ?
314 RK3399_GRF_USB20_PHY0_CON1_REG : 314 RK3399_GRF_USB20_PHY0_CON1_REG :
315 RK3399_GRF_USB20_PHY1_CON1_REG; 315 RK3399_GRF_USB20_PHY1_CON1_REG;
316 write_mask = (RK3399_USBPHY_SUSPEND_N|RK3399_USBPHY_UTMI_SEL) << 16; 316 write_mask = (RK3399_USBPHY_SUSPEND_N|RK3399_USBPHY_UTMI_SEL) << 16;
317 write_val = enable ? 0 : RK3399_USBPHY_UTMI_SEL; 317 write_val = enable ? 0 : RK3399_USBPHY_UTMI_SEL;
318 break; 318 break;
319 default: 319 default:
320 return ENXIO; 320 return ENXIO;
321 } 321 }
322 322
323 if (sc->sc_supply) { 323 if (sc->sc_supply) {
324 error = enable ? fdtbus_regulator_enable(sc->sc_supply) : 324 error = enable ? fdtbus_regulator_enable(sc->sc_supply) :
325 fdtbus_regulator_disable(sc->sc_supply); 325 fdtbus_regulator_disable(sc->sc_supply);
326 if (error != 0) 326 if (error != 0)
327 return error; 327 return error;
328 } 328 }
329 329
330 syscon_lock(usb_sc->sc_syscon); 330 syscon_lock(usb_sc->sc_syscon);
331 syscon_write_4(usb_sc->sc_syscon, reg, write_mask | write_val); 331 syscon_write_4(usb_sc->sc_syscon, reg, write_mask | write_val);
332 syscon_unlock(usb_sc->sc_syscon); 332 syscon_unlock(usb_sc->sc_syscon);
333 333
334 return 0; 334 return 0;
335} 335}
336 336
337static int 337static int
338rk_usbphy_host_enable(device_t dev, void *priv, bool enable) 338rk_usbphy_host_enable(device_t dev, void *priv, bool enable)
339{ 339{
340 struct rk_usbphy_softc * const sc = device_private(dev); 340 struct rk_usbphy_softc * const sc = device_private(dev);
341 struct rk_usb_softc * const usb_sc = device_private(device_parent(dev)); 341 struct rk_usb_softc * const usb_sc = device_private(device_parent(dev));
342 uint32_t reg, write_mask, write_val; 342 uint32_t reg, write_mask, write_val;
343 int error; 343 int error;
344 344
345 switch (usb_sc->sc_type) { 345 switch (usb_sc->sc_type) {
346 case USB_RK3328: 346 case USB_RK3328:
347 reg = RK3328_CON1_REG; 347 reg = RK3328_CON1_REG;
348 write_mask = 0x1ffU << 16; 348 write_mask = 0x1ffU << 16;
349 write_val = enable ? 0 : 0x1d1; 349 write_val = enable ? 0 : 0x1d1;
350 break; 350 break;
351 case USB_RK3399: 351 case USB_RK3399:
352 reg = RK3399_PHY_NO(usb_sc) == 0 ? 352 reg = RK3399_PHY_NO(usb_sc) == 0 ?
353 RK3399_GRF_USB20_PHY0_CON2_REG : 353 RK3399_GRF_USB20_PHY0_CON2_REG :
354 RK3399_GRF_USB20_PHY1_CON2_REG; 354 RK3399_GRF_USB20_PHY1_CON2_REG;
355 write_mask = (RK3399_USBPHY_SUSPEND_N|RK3399_USBPHY_UTMI_SEL) << 16; 355 write_mask = (RK3399_USBPHY_SUSPEND_N|RK3399_USBPHY_UTMI_SEL) << 16;
356 write_val = enable ? 0 : RK3399_USBPHY_UTMI_SEL; 356 write_val = enable ? 0 : RK3399_USBPHY_UTMI_SEL;
357 break; 357 break;
358 default: 358 default:
359 return ENXIO; 359 return ENXIO;
360 } 360 }
361 361
362 if (sc->sc_supply) { 362 if (sc->sc_supply) {
363 error = enable ? fdtbus_regulator_enable(sc->sc_supply) : 363 error = enable ? fdtbus_regulator_enable(sc->sc_supply) :
364 fdtbus_regulator_disable(sc->sc_supply); 364 fdtbus_regulator_disable(sc->sc_supply);
365 if (error != 0) 365 if (error != 0)
366 return error; 366 return error;
367 } 367 }
368 368
369 syscon_lock(usb_sc->sc_syscon); 369 syscon_lock(usb_sc->sc_syscon);
370 syscon_write_4(usb_sc->sc_syscon, reg, write_mask | write_val); 370 syscon_write_4(usb_sc->sc_syscon, reg, write_mask | write_val);
371 syscon_unlock(usb_sc->sc_syscon); 371 syscon_unlock(usb_sc->sc_syscon);
372 372
373 return 0; 373 return 0;
374} 374}
375 375
376const struct fdtbus_phy_controller_func rk_usbphy_otg_funcs = { 376const struct fdtbus_phy_controller_func rk_usbphy_otg_funcs = {
377 .acquire = rk_usbphy_acquire, 377 .acquire = rk_usbphy_acquire,
378 .release = rk_usbphy_release, 378 .release = rk_usbphy_release,
379 .enable = rk_usbphy_otg_enable, 379 .enable = rk_usbphy_otg_enable,
380}; 380};
381 381
382const struct fdtbus_phy_controller_func rk_usbphy_host_funcs = { 382const struct fdtbus_phy_controller_func rk_usbphy_host_funcs = {
383 .acquire = rk_usbphy_acquire, 383 .acquire = rk_usbphy_acquire,
384 .release = rk_usbphy_release, 384 .release = rk_usbphy_release,
385 .enable = rk_usbphy_host_enable, 385 .enable = rk_usbphy_host_enable,
386}; 386};
387 387
388static int 388static int
389rk_usbphy_match(device_t parent, cfdata_t cf, void *aux) 389rk_usbphy_match(device_t parent, cfdata_t cf, void *aux)
390{ 390{
391 struct fdt_attach_args * const faa = aux; 391 struct fdt_attach_args * const faa = aux;
392 const int phandle = faa->faa_phandle; 392 const int phandle = faa->faa_phandle;
393 const char *name = fdtbus_get_string(phandle, "name"); 393 const char *name = fdtbus_get_string(phandle, "name");
394 394
395 if (strcmp(name, "otg-port") == 0 || strcmp(name, "host-port") == 0) 395 if (strcmp(name, "otg-port") == 0 || strcmp(name, "host-port") == 0)
396 return 1; 396 return 1;
397 397
398 return 0; 398 return 0;
399} 399}
400 400
401static void 401static void
402rk_usbphy_attach(device_t parent, device_t self, void *aux) 402rk_usbphy_attach(device_t parent, device_t self, void *aux)
403{ 403{
404 struct rk_usbphy_softc * const sc = device_private(self); 404 struct rk_usbphy_softc * const sc = device_private(self);
405 struct fdt_attach_args * const faa = aux; 405 struct fdt_attach_args * const faa = aux;
406 const int phandle = faa->faa_phandle; 406 const int phandle = faa->faa_phandle;
407 const char *name = fdtbus_get_string(phandle, "name"); 407 const char *name = fdtbus_get_string(phandle, "name");
408 408
409 sc->sc_dev = self; 409 sc->sc_dev = self;
410 sc->sc_phandle = phandle; 410 sc->sc_phandle = phandle;
411 if (of_hasprop(phandle, "phy-supply")) { 411 if (of_hasprop(phandle, "phy-supply")) {
412 sc->sc_supply = fdtbus_regulator_acquire(phandle, "phy-supply"); 412 sc->sc_supply = fdtbus_regulator_acquire(phandle, "phy-supply");
413 if (sc->sc_supply == NULL) { 413 if (sc->sc_supply == NULL) {
414 aprint_error(": couldn't acquire regulator\n"); 414 aprint_error(": couldn't acquire regulator\n");
415 return; 415 return;
416 } 416 }
417 } 417 }
418 418
419 aprint_naive("\n"); 419 aprint_naive("\n");
420 420
421 if (strcmp(name, "otg-port") == 0) { 421 if (strcmp(name, "otg-port") == 0) {
422 aprint_normal(": USB2 OTG port\n"); 422 aprint_normal(": USB2 OTG port\n");
423 fdtbus_register_phy_controller(self, phandle, &rk_usbphy_otg_funcs); 423 fdtbus_register_phy_controller(self, phandle, &rk_usbphy_otg_funcs);
424 } else if (strcmp(name, "host-port") == 0) { 424 } else if (strcmp(name, "host-port") == 0) {
425 aprint_normal(": USB2 host port\n"); 425 aprint_normal(": USB2 host port\n");
426 fdtbus_register_phy_controller(self, phandle, &rk_usbphy_host_funcs); 426 fdtbus_register_phy_controller(self, phandle, &rk_usbphy_host_funcs);
427 } 427 }
428} 428}