1 /*
2  * Copyright (c) 2021-2023 IoT.bzh
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  */
7 
8 #define DT_DRV_COMPAT renesas_rcar_pfc
9 
10 #include "pfc_rcar.h"
11 #include <zephyr/arch/cpu.h>
12 #include <zephyr/devicetree.h>
13 #include <zephyr/drivers/pinctrl.h>
14 #include <zephyr/init.h>
15 #include <zephyr/sys/util.h>
16 #include <zephyr/sys/device_mmio.h>
17 
18 #define PFC_RCAR_PMMR 0x0
19 
20 /* Gen3 only has one base address, Gen4 has one per GPIO controller */
21 #if defined(CONFIG_SOC_SERIES_RCAR_GEN3)
22 #define PFC_RCAR_GPSR 0x100
23 #define PFC_RCAR_IPSR 0x200
24 #elif defined(CONFIG_SOC_SERIES_RCAR_GEN4)
25 #define PFC_RCAR_GPSR 0x040
26 #define PFC_RCAR_IPSR 0x060
27 #else
28 #error Unsupported SoC Series
29 #endif
30 
31 /* swap both arguments */
32 #define PFC_REG_ADDRESS(idx, inst) DT_INST_REG_ADDR_BY_IDX(inst, idx)
33 static uintptr_t reg_base[] = {
34 	LISTIFY(DT_NUM_REGS(DT_DRV_INST(0)), PFC_REG_ADDRESS, (,), 0)
35 };
36 
37 #define PFC_REG_SIZE(idx, inst) DT_INST_REG_SIZE_BY_IDX(inst, idx)
38 static const uintptr_t __maybe_unused reg_sizes[] = {
39 	LISTIFY(DT_NUM_REGS(DT_DRV_INST(0)), PFC_REG_SIZE, (,), 0)
40 };
41 
42 #ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
43 /* POC Control Register can control IO voltage level that is supplied to the pin */
44 struct pfc_pocctrl_reg {
45 	uint32_t offset;
46 	const uint16_t pins[32];
47 };
48 #endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */
49 
50 /*
51  * Each drive step is either encoded in 2 or 3 bits.
52  * So based on a 24 mA maximum value each step is either
53  * 24/4 mA or 24/8 mA.
54  */
55 #define PFC_RCAR_DRIVE_MAX 24U
56 #define PFC_RCAR_DRIVE_STEP(size) \
57 	(size == 2 ? PFC_RCAR_DRIVE_MAX / 4 : PFC_RCAR_DRIVE_MAX / 8)
58 
59 /* Some registers such as IPSR GPSR or DRVCTRL are protected and
60  * must be preceded to a write to PMMR with the inverse value.
61  */
pfc_rcar_write(uintptr_t pfc_base,uint32_t offs,uint32_t val)62 static void pfc_rcar_write(uintptr_t pfc_base, uint32_t offs, uint32_t val)
63 {
64 	sys_write32(~val, pfc_base + PFC_RCAR_PMMR);
65 	sys_write32(val, pfc_base + offs);
66 }
67 
68 /* Set the pin either in gpio or peripheral */
pfc_rcar_set_gpsr(uintptr_t pfc_base,uint16_t pin,bool peripheral)69 static void pfc_rcar_set_gpsr(uintptr_t pfc_base,
70 			      uint16_t pin, bool peripheral)
71 {
72 #if defined(CONFIG_SOC_SERIES_RCAR_GEN3)
73 	/* On Gen3 we have multiple GPSR at one base address */
74 	uint8_t bank = pin / 32;
75 #elif defined(CONFIG_SOC_SERIES_RCAR_GEN4)
76 	/* On Gen4 we have one GPSR at multiple base address */
77 	uint8_t bank = 0;
78 #endif
79 	uint8_t bit = pin % 32;
80 	uint32_t val = sys_read32(pfc_base + PFC_RCAR_GPSR +
81 				  bank * sizeof(uint32_t));
82 
83 	if (peripheral) {
84 		val |= BIT(bit);
85 	} else {
86 		val &= ~BIT(bit);
87 	}
88 	pfc_rcar_write(pfc_base, PFC_RCAR_GPSR + bank * sizeof(uint32_t), val);
89 }
90 
91 /* Set peripheral function */
pfc_rcar_set_ipsr(uintptr_t pfc_base,const struct rcar_pin_func * rcar_func)92 static void pfc_rcar_set_ipsr(uintptr_t pfc_base,
93 			      const struct rcar_pin_func *rcar_func)
94 {
95 	uint16_t reg_offs = PFC_RCAR_IPSR + rcar_func->bank * sizeof(uint32_t);
96 	uint32_t val = sys_read32(pfc_base + reg_offs);
97 
98 	val &= ~(0xFU << rcar_func->shift);
99 	val |= (rcar_func->func << rcar_func->shift);
100 	pfc_rcar_write(pfc_base, reg_offs, val);
101 }
102 
pfc_rcar_get_drive_reg(uint16_t pin,uint8_t * offset,uint8_t * size)103 static uint32_t pfc_rcar_get_drive_reg(uint16_t pin, uint8_t *offset,
104 				       uint8_t *size)
105 {
106 	const struct pfc_drive_reg *drive_regs = pfc_rcar_get_drive_regs();
107 
108 	while (drive_regs->reg != 0U) {
109 		for (size_t i = 0U; i < ARRAY_SIZE(drive_regs->fields); i++) {
110 			if (drive_regs->fields[i].pin == pin) {
111 				*offset = drive_regs->fields[i].offset;
112 				*size = drive_regs->fields[i].size;
113 				return drive_regs->reg;
114 			}
115 		}
116 		drive_regs++;
117 	}
118 
119 	return 0;
120 }
121 
122 /*
123  * Maximum drive strength is 24mA. This value can be lowered
124  * using DRVCTRLx registers, some pins have 8 steps (3 bits size encoded)
125  * some have 4 steps (2 bits size encoded).
126  */
pfc_rcar_set_drive_strength(uintptr_t pfc_base,uint16_t pin,uint8_t strength)127 static int pfc_rcar_set_drive_strength(uintptr_t pfc_base, uint16_t pin,
128 				       uint8_t strength)
129 {
130 	uint8_t offset, size, step;
131 	uint32_t reg, val;
132 
133 	reg = pfc_rcar_get_drive_reg(pin, &offset, &size);
134 	if (reg == 0U) {
135 		return -EINVAL;
136 	}
137 
138 	step = PFC_RCAR_DRIVE_STEP(size);
139 	if ((strength < step) || (strength > PFC_RCAR_DRIVE_MAX)) {
140 		return -EINVAL;
141 	}
142 
143 	/* Convert the value from mA based on a full drive strength
144 	 * value of 24mA.
145 	 */
146 	strength = (strength / step) - 1U;
147 	/* clear previous drive strength value */
148 	val = sys_read32(pfc_base + reg);
149 	val &= ~GENMASK(offset + size - 1U, offset);
150 	val |= strength << offset;
151 
152 	pfc_rcar_write(pfc_base, reg, val);
153 
154 	return 0;
155 }
156 
pfc_rcar_get_bias_reg(uint16_t pin,uint8_t * bit)157 static const struct pfc_bias_reg *pfc_rcar_get_bias_reg(uint16_t pin,
158 							uint8_t *bit)
159 {
160 	const struct pfc_bias_reg *bias_regs = pfc_rcar_get_bias_regs();
161 
162 	/* Loop around all the registers to find the bit for a given pin */
163 	while (bias_regs->puen && bias_regs->pud) {
164 		for (size_t i = 0U; i < ARRAY_SIZE(bias_regs->pins); i++) {
165 			if (bias_regs->pins[i] == pin) {
166 				*bit = i;
167 				return bias_regs;
168 			}
169 		}
170 		bias_regs++;
171 	}
172 
173 	return NULL;
174 }
175 
pfc_rcar_set_bias(uintptr_t pfc_base,uint16_t pin,uint16_t flags)176 int pfc_rcar_set_bias(uintptr_t pfc_base, uint16_t pin, uint16_t flags)
177 {
178 	uint32_t val;
179 	uint8_t bit;
180 	const struct pfc_bias_reg *bias_reg = pfc_rcar_get_bias_reg(pin, &bit);
181 
182 	if (bias_reg == NULL) {
183 		return -EINVAL;
184 	}
185 
186 	/* pull enable/disable*/
187 	val = sys_read32(pfc_base + bias_reg->puen);
188 	if ((flags & RCAR_PIN_FLAGS_PUEN) == 0U) {
189 		sys_write32(val & ~BIT(bit), pfc_base + bias_reg->puen);
190 		return 0;
191 	}
192 	sys_write32(val | BIT(bit), pfc_base + bias_reg->puen);
193 
194 	/* pull - up/down */
195 	val = sys_read32(pfc_base + bias_reg->pud);
196 	if (flags & RCAR_PIN_FLAGS_PUD) {
197 		sys_write32(val | BIT(bit), pfc_base + bias_reg->pud);
198 	} else {
199 		sys_write32(val & ~BIT(bit), pfc_base + bias_reg->pud);
200 	}
201 	return 0;
202 }
203 
204 #ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
205 
206 const struct pfc_pocctrl_reg pfc_r8a77951_r8a77961_volt_regs[] = {
207 	{
208 		.offset = 0x0380,
209 		.pins = {
210 			[0]  = RCAR_GP_PIN(3,  0),    /* SD0_CLK  */
211 			[1]  = RCAR_GP_PIN(3,  1),    /* SD0_CMD  */
212 			[2]  = RCAR_GP_PIN(3,  2),    /* SD0_DAT0 */
213 			[3]  = RCAR_GP_PIN(3,  3),    /* SD0_DAT1 */
214 			[4]  = RCAR_GP_PIN(3,  4),    /* SD0_DAT2 */
215 			[5]  = RCAR_GP_PIN(3,  5),    /* SD0_DAT3 */
216 			[6]  = RCAR_GP_PIN(3,  6),    /* SD1_CLK  */
217 			[7]  = RCAR_GP_PIN(3,  7),    /* SD1_CMD  */
218 			[8]  = RCAR_GP_PIN(3,  8),    /* SD1_DAT0 */
219 			[9]  = RCAR_GP_PIN(3,  9),    /* SD1_DAT1 */
220 			[10] = RCAR_GP_PIN(3,  10),   /* SD1_DAT2 */
221 			[11] = RCAR_GP_PIN(3,  11),   /* SD1_DAT3 */
222 			[12] = RCAR_GP_PIN(4,  0),    /* SD2_CLK  */
223 			[13] = RCAR_GP_PIN(4,  1),    /* SD2_CMD  */
224 			[14] = RCAR_GP_PIN(4,  2),    /* SD2_DAT0 */
225 			[15] = RCAR_GP_PIN(4,  3),    /* SD2_DAT1 */
226 			[16] = RCAR_GP_PIN(4,  4),    /* SD2_DAT2 */
227 			[17] = RCAR_GP_PIN(4,  5),    /* SD2_DAT3 */
228 			[18] = RCAR_GP_PIN(4,  6),    /* SD2_DS   */
229 			[19] = RCAR_GP_PIN(4,  7),    /* SD3_CLK  */
230 			[20] = RCAR_GP_PIN(4,  8),    /* SD3_CMD  */
231 			[21] = RCAR_GP_PIN(4,  9),    /* SD3_DAT0 */
232 			[22] = RCAR_GP_PIN(4,  10),   /* SD3_DAT1 */
233 			[23] = RCAR_GP_PIN(4,  11),   /* SD3_DAT2 */
234 			[24] = RCAR_GP_PIN(4,  12),   /* SD3_DAT3 */
235 			[25] = RCAR_GP_PIN(4,  13),   /* SD3_DAT4 */
236 			[26] = RCAR_GP_PIN(4,  14),   /* SD3_DAT5 */
237 			[27] = RCAR_GP_PIN(4,  15),   /* SD3_DAT6 */
238 			[28] = RCAR_GP_PIN(4,  16),   /* SD3_DAT7 */
239 			[29] = RCAR_GP_PIN(4,  17),   /* SD3_DS   */
240 			[30] = -1,
241 			[31] = -1,
242 		}
243 	},
244 	{ /* sentinel */ },
245 };
246 
pfc_rcar_get_io_voltage_regs(void)247 static const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void)
248 {
249 	return pfc_r8a77951_r8a77961_volt_regs;
250 }
251 
pfc_rcar_get_pocctrl_reg(uint16_t pin,uint8_t * bit)252 static const struct pfc_pocctrl_reg *pfc_rcar_get_pocctrl_reg(uint16_t pin, uint8_t *bit)
253 {
254 	const struct pfc_pocctrl_reg *voltage_regs = pfc_rcar_get_io_voltage_regs();
255 
256 	BUILD_ASSERT(ARRAY_SIZE(voltage_regs->pins) < UINT8_MAX);
257 
258 	/* Loop around all the registers to find the bit for a given pin */
259 	while (voltage_regs && voltage_regs->offset) {
260 		uint8_t i;
261 
262 		for (i = 0U; i < ARRAY_SIZE(voltage_regs->pins); i++) {
263 			if (voltage_regs->pins[i] == pin) {
264 				*bit = i;
265 				return voltage_regs;
266 			}
267 		}
268 		voltage_regs++;
269 	}
270 
271 	return NULL;
272 }
273 
pfc_rcar_set_voltage(uintptr_t pfc_base,uint16_t pin,uint16_t voltage)274 static void pfc_rcar_set_voltage(uintptr_t pfc_base, uint16_t pin, uint16_t voltage)
275 {
276 	uint32_t val;
277 	uint8_t bit;
278 	const struct pfc_pocctrl_reg *voltage_reg;
279 
280 	voltage_reg = pfc_rcar_get_pocctrl_reg(pin, &bit);
281 	if (!voltage_reg) {
282 		return;
283 	}
284 
285 	val = sys_read32(pfc_base + voltage_reg->offset);
286 
287 	switch (voltage) {
288 	case PIN_VOLTAGE_1P8V:
289 		if (!(val & BIT(bit))) {
290 			return;
291 		}
292 		val &= ~BIT(bit);
293 		break;
294 	case PIN_VOLTAGE_3P3V:
295 		if (val & BIT(bit)) {
296 			return;
297 		}
298 		val |= BIT(bit);
299 		break;
300 	default:
301 		break;
302 	}
303 
304 	pfc_rcar_write(pfc_base, voltage_reg->offset, val);
305 }
306 #endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */
307 
pinctrl_configure_pin(const pinctrl_soc_pin_t * pin)308 int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
309 {
310 	int ret = 0;
311 	uint8_t reg_index;
312 	uintptr_t pfc_base;
313 
314 	ret = pfc_rcar_get_reg_index(pin->pin, &reg_index);
315 	if (ret) {
316 		return ret;
317 	}
318 
319 	if (reg_index >= ARRAY_SIZE(reg_base)) {
320 		return -EINVAL;
321 	}
322 
323 	pfc_base = reg_base[reg_index];
324 
325 	/* Set pin as GPIO if capable */
326 	if (RCAR_IS_GP_PIN(pin->pin)) {
327 		pfc_rcar_set_gpsr(pfc_base, pin->pin, false);
328 	} else if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) == 0U) {
329 		/* A function must be set for non GPIO capable pin */
330 		return -EINVAL;
331 	}
332 
333 #ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
334 	if (pin->voltage != PIN_VOLTAGE_NONE) {
335 		pfc_rcar_set_voltage(pfc_base, pin->pin, pin->voltage);
336 	}
337 #endif
338 
339 	/* Select function for pin */
340 	if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) != 0U) {
341 
342 		if ((pin->flags & RCAR_PIN_FLAGS_FUNC_DUMMY) == 0U) {
343 			pfc_rcar_set_ipsr(pfc_base, &pin->func);
344 		}
345 
346 		if (RCAR_IS_GP_PIN(pin->pin)) {
347 			pfc_rcar_set_gpsr(pfc_base, pin->pin, true);
348 		}
349 
350 		if ((pin->flags & RCAR_PIN_FLAGS_PULL_SET) != 0U) {
351 			ret = pfc_rcar_set_bias(pfc_base, pin->pin, pin->flags);
352 			if (ret < 0) {
353 				return ret;
354 			}
355 		}
356 	}
357 
358 	if (pin->drive_strength != 0U) {
359 		ret = pfc_rcar_set_drive_strength(pfc_base, pin->pin,
360 						  pin->drive_strength);
361 	}
362 
363 	return ret;
364 }
365 
pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)366 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
367 			   uintptr_t reg)
368 {
369 	int ret = 0;
370 
371 	ARG_UNUSED(reg);
372 	while (pin_cnt-- > 0U) {
373 		ret = pinctrl_configure_pin(pins++);
374 		if (ret < 0) {
375 			break;
376 		}
377 	}
378 
379 	return ret;
380 }
381 
382 #if defined(DEVICE_MMIO_IS_IN_RAM)
pfc_rcar_driver_init(void)383 __boot_func static int pfc_rcar_driver_init(void)
384 {
385 	for (unsigned int i = 0; i < ARRAY_SIZE(reg_base); i++) {
386 		device_map(reg_base + i, reg_base[i], reg_sizes[i], K_MEM_CACHE_NONE);
387 	}
388 	return 0;
389 }
390 
391 SYS_INIT(pfc_rcar_driver_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
392 #endif
393