11/*
2- * Copyright (c) 2021 IoT.bzh
2+ * Copyright (c) 2021-2023 IoT.bzh
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
1010#include <zephyr/arch/cpu.h>
1111#include <zephyr/devicetree.h>
1212#include <zephyr/drivers/pinctrl.h>
13+ #include <rcar_pfc_defs.h>
1314#include <soc.h>
1415#include <zephyr/sys/util.h>
1516
16- #define PFC_REG_BASE DT_INST_REG_ADDR(0)
1717#define PFC_RCAR_PMMR 0x0
18- #define PFC_RCAR_GPSR 0x100
19- #define PFC_RCAR_IPSR 0x200
18+
19+ /* Gen3 only has one base address, Gen4 has one per GPIO controller */
20+ #if defined(CONFIG_SOC_SERIES_RCAR_GEN3 )
21+ static const uint32_t reg_base [] = {DT_INST_REG_ADDR (0 )};
22+ #elif defined(CONFIG_SOC_SERIES_RCAR_GEN4 )
23+ /* swap both arguments */
24+ #define PFC_REG_ADDRESS (idx , node_id ) DT_REG_ADDR_BY_IDX(node_id, idx)
25+ static const uint32_t reg_base [] = {
26+ LISTIFY (DT_NUM_REGS (DT_DRV_INST (0 )), PFC_REG_ADDRESS , (,), DT_DRV_INST (0 ))
27+ };
28+ #else
29+ #error Unsupported SoC Series
30+ #endif
2031
2132/*
2233 * Each drive step is either encoded in 2 or 3 bits.
3041/* Some registers such as IPSR GPSR or DRVCTRL are protected and
3142 * must be preceded to a write to PMMR with the inverse value.
3243 */
33- static void pfc_rcar_write (uint32_t offs , uint32_t val )
44+ static void pfc_rcar_write (uint32_t pfc_base , uint32_t offs , uint32_t val )
3445{
35- sys_write32 (~val , PFC_REG_BASE + PFC_RCAR_PMMR );
36- sys_write32 (val , PFC_REG_BASE + offs );
46+ sys_write32 (~val , pfc_base + PFC_RCAR_PMMR );
47+ sys_write32 (val , pfc_base + offs );
3748}
3849
3950/* Set the pin either in gpio or peripheral */
40- static void pfc_rcar_set_gpsr (uint16_t pin , bool peripheral )
51+ static void pfc_rcar_set_gpsr (uint32_t pfc_base ,
52+ uint16_t pin , bool peripheral )
4153{
54+ #if defined(CONFIG_SOC_SERIES_RCAR_GEN3 )
55+ /* On Gen3 we have multiple GPSR at one base address */
4256 uint8_t bank = pin / 32 ;
57+ #elif defined(CONFIG_SOC_SERIES_RCAR_GEN4 )
58+ /* On Gen4 we have one GPSR at multiple base address */
59+ uint8_t bank = 0 ;
60+ #endif
4361 uint8_t bit = pin % 32 ;
44- uint32_t val = sys_read32 (PFC_REG_BASE + PFC_RCAR_GPSR +
62+ uint32_t val = sys_read32 (pfc_base + PFC_RCAR_GPSR +
4563 bank * sizeof (uint32_t ));
4664
4765 if (peripheral ) {
4866 val |= BIT (bit );
4967 } else {
5068 val &= ~BIT (bit );
5169 }
52- pfc_rcar_write (PFC_RCAR_GPSR + bank * sizeof (uint32_t ), val );
70+ pfc_rcar_write (pfc_base , PFC_RCAR_GPSR + bank * sizeof (uint32_t ), val );
5371}
5472
5573/* Set peripheral function */
56- static void pfc_rcar_set_ipsr (const struct rcar_pin_func * rcar_func )
74+ static void pfc_rcar_set_ipsr (uint32_t pfc_base ,
75+ const struct rcar_pin_func * rcar_func )
5776{
5877 uint16_t reg_offs = PFC_RCAR_IPSR + rcar_func -> bank * sizeof (uint32_t );
59- uint32_t val = sys_read32 (PFC_REG_BASE + reg_offs );
78+ uint32_t val = sys_read32 (pfc_base + reg_offs );
6079
6180 val &= ~(0xFU << rcar_func -> shift );
6281 val |= (rcar_func -> func << rcar_func -> shift );
63- pfc_rcar_write (reg_offs , val );
82+ pfc_rcar_write (pfc_base , reg_offs , val );
6483}
6584
6685static uint32_t pfc_rcar_get_drive_reg (uint16_t pin , uint8_t * offset ,
@@ -87,7 +106,8 @@ static uint32_t pfc_rcar_get_drive_reg(uint16_t pin, uint8_t *offset,
87106 * using DRVCTRLx registers, some pins have 8 steps (3 bits size encoded)
88107 * some have 4 steps (2 bits size encoded).
89108 */
90- static int pfc_rcar_set_drive_strength (uint16_t pin , uint8_t strength )
109+ static int pfc_rcar_set_drive_strength (uint32_t pfc_base , uint16_t pin ,
110+ uint8_t strength )
91111{
92112 uint8_t offset , size , step ;
93113 uint32_t reg , val ;
@@ -107,11 +127,11 @@ static int pfc_rcar_set_drive_strength(uint16_t pin, uint8_t strength)
107127 */
108128 strength = (strength / step ) - 1U ;
109129 /* clear previous drive strength value */
110- val = sys_read32 (PFC_REG_BASE + reg );
130+ val = sys_read32 (pfc_base + reg );
111131 val &= ~GENMASK (offset + size - 1U , offset );
112132 val |= strength << offset ;
113133
114- pfc_rcar_write (reg , val );
134+ pfc_rcar_write (pfc_base , reg , val );
115135
116136 return 0 ;
117137}
@@ -135,7 +155,7 @@ static const struct pfc_bias_reg *pfc_rcar_get_bias_reg(uint16_t pin,
135155 return NULL ;
136156}
137157
138- int pfc_rcar_set_bias (uint16_t pin , uint16_t flags )
158+ int pfc_rcar_set_bias (uint32_t pfc_base , uint16_t pin , uint16_t flags )
139159{
140160 uint32_t val ;
141161 uint8_t bit ;
@@ -146,53 +166,66 @@ int pfc_rcar_set_bias(uint16_t pin, uint16_t flags)
146166 }
147167
148168 /* pull enable/disable*/
149- val = sys_read32 (PFC_REG_BASE + bias_reg -> puen );
169+ val = sys_read32 (pfc_base + bias_reg -> puen );
150170 if ((flags & RCAR_PIN_FLAGS_PUEN ) == 0U ) {
151- sys_write32 (val & ~BIT (bit ), PFC_REG_BASE + bias_reg -> puen );
171+ sys_write32 (val & ~BIT (bit ), pfc_base + bias_reg -> puen );
152172 return 0 ;
153173 }
154- sys_write32 (val | BIT (bit ), PFC_REG_BASE + bias_reg -> puen );
174+ sys_write32 (val | BIT (bit ), pfc_base + bias_reg -> puen );
155175
156176 /* pull - up/down */
157- val = sys_read32 (PFC_REG_BASE + bias_reg -> pud );
177+ val = sys_read32 (pfc_base + bias_reg -> pud );
158178 if (flags & RCAR_PIN_FLAGS_PUD ) {
159- sys_write32 (val | BIT (bit ), PFC_REG_BASE + bias_reg -> pud );
179+ sys_write32 (val | BIT (bit ), pfc_base + bias_reg -> pud );
160180 } else {
161- sys_write32 (val & ~BIT (bit ), PFC_REG_BASE + bias_reg -> pud );
181+ sys_write32 (val & ~BIT (bit ), pfc_base + bias_reg -> pud );
162182 }
163183 return 0 ;
164184}
165185
166186int pinctrl_configure_pin (const pinctrl_soc_pin_t * pin )
167187{
168188 int ret = 0 ;
189+ uint8_t reg_index ;
190+ uint32_t pfc_base ;
191+
192+ ret = pfc_rcar_get_reg_index (pin -> pin , & reg_index );
193+ if (ret ) {
194+ return ret ;
195+ }
196+
197+ if (reg_index >= ARRAY_SIZE (reg_base )) {
198+ return - EINVAL ;
199+ }
200+
201+ pfc_base = reg_base [reg_index ];
169202
170203 /* Set pin as GPIO if capable */
171204 if (RCAR_IS_GP_PIN (pin -> pin )) {
172- pfc_rcar_set_gpsr (pin -> pin , false);
205+ pfc_rcar_set_gpsr (pfc_base , pin -> pin , false);
173206 } else if ((pin -> flags & RCAR_PIN_FLAGS_FUNC_SET ) == 0U ) {
174207 /* A function must be set for non GPIO capable pin */
175208 return - EINVAL ;
176209 }
177210
178211 /* Select function for pin */
179212 if ((pin -> flags & RCAR_PIN_FLAGS_FUNC_SET ) != 0U ) {
180- pfc_rcar_set_ipsr (& pin -> func );
213+ pfc_rcar_set_ipsr (pfc_base , & pin -> func );
181214
182215 if (RCAR_IS_GP_PIN (pin -> pin )) {
183- pfc_rcar_set_gpsr (pin -> pin , true);
216+ pfc_rcar_set_gpsr (pfc_base , pin -> pin , true);
184217 }
185218
186219 if ((pin -> flags & RCAR_PIN_FLAGS_PULL_SET ) != 0U ) {
187- ret = pfc_rcar_set_bias (pin -> pin , pin -> flags );
220+ ret = pfc_rcar_set_bias (pfc_base , pin -> pin , pin -> flags );
188221 if (ret < 0 ) {
189222 return ret ;
190223 }
191224 }
192225 }
193226
194227 if (pin -> drive_strength != 0U ) {
195- ret = pfc_rcar_set_drive_strength (pin -> pin ,
228+ ret = pfc_rcar_set_drive_strength (pfc_base , pin -> pin ,
196229 pin -> drive_strength );
197230 }
198231
0 commit comments