Skip to content

Commit 12a7967

Browse files
committed
drivers: pinctrl: pfc_rcar: add support of voltage control to pfc driver
Add support of voltage control to Renesas PFC driver. Voltage register mappings have been added to r8a77951 and r8a77961 SoCs. Allow 'power-source' property for 'renesas,rcar-pfc' node. This property will be used for configuring IO voltage on appropriate pin. For now it is possible to have only two voltages: 1.8 and 3.3. Note: it is possible to change voltage only for SD/MMC pins on r8a77951 and r8a77961 SoCs. Signed-off-by: Mykola Kvach <[email protected]>
1 parent 169d35d commit 12a7967

File tree

9 files changed

+250
-0
lines changed

9 files changed

+250
-0
lines changed

drivers/pinctrl/Kconfig.rcar

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,11 @@ config PINCTRL_RCAR_PFC
77
depends on DT_HAS_RENESAS_RCAR_PFC_ENABLED
88
help
99
Enable pin controller driver for Renesas RCar SoC
10+
11+
if PINCTRL_RCAR_PFC
12+
13+
config PINCTRL_RCAR_VOLTAGE_CONTROL
14+
bool "Voltage control functionality of Renesas R-Car PFC driver"
15+
default y if SOC_SERIES_RCAR_GEN3
16+
17+
endif

drivers/pinctrl/pfc_rcar.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,63 @@ int pfc_rcar_set_bias(uint16_t pin, uint16_t flags)
165165
return 0;
166166
}
167167

168+
#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
169+
static const struct pfc_pocctrl_reg *pfc_rcar_get_pocctrl_reg(uint16_t pin, uint8_t *bit)
170+
{
171+
const struct pfc_pocctrl_reg *voltage_regs = pfc_rcar_get_io_voltage_regs();
172+
173+
BUILD_ASSERT(ARRAY_SIZE(voltage_regs->pins) < UINT8_MAX);
174+
175+
/* Loop around all the registers to find the bit for a given pin */
176+
while (voltage_regs && voltage_regs->offset) {
177+
uint8_t i;
178+
179+
for (i = 0U; i < ARRAY_SIZE(voltage_regs->pins); i++) {
180+
if (voltage_regs->pins[i] == pin) {
181+
*bit = i;
182+
return voltage_regs;
183+
}
184+
}
185+
voltage_regs++;
186+
}
187+
188+
return NULL;
189+
}
190+
191+
static void pfc_rcar_set_voltage(uint16_t pin, uint16_t voltage)
192+
{
193+
uint32_t val;
194+
uint8_t bit;
195+
const struct pfc_pocctrl_reg *voltage_reg;
196+
197+
voltage_reg = pfc_rcar_get_pocctrl_reg(pin, &bit);
198+
if (!voltage_reg) {
199+
return;
200+
}
201+
202+
val = sys_read32(PFC_REG_BASE + voltage_reg->offset);
203+
204+
switch (voltage) {
205+
case PIN_VOLTAGE_1P8V:
206+
if (!(val & BIT(bit))) {
207+
return;
208+
}
209+
val &= ~BIT(bit);
210+
break;
211+
case PIN_VOLTAGE_3P3V:
212+
if (val & BIT(bit)) {
213+
return;
214+
}
215+
val |= BIT(bit);
216+
break;
217+
default:
218+
break;
219+
}
220+
221+
pfc_rcar_write(voltage_reg->offset, val);
222+
}
223+
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */
224+
168225
int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
169226
{
170227
int ret = 0;
@@ -177,6 +234,12 @@ int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
177234
return -EINVAL;
178235
}
179236

237+
#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
238+
if (pin->voltage != PIN_VOLTAGE_NONE) {
239+
pfc_rcar_set_voltage(pin->pin, pin->voltage);
240+
}
241+
#endif
242+
180243
/* Select function for pin */
181244
if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) != 0U) {
182245
pfc_rcar_set_ipsr(&pin->func);

dts/bindings/pinctrl/renesas,rcar-pfc.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ description: |
5151
- bias-pull-down
5252
- bias-pull-up
5353
- drive-strength
54+
- power-source
5455
5556
To link pin configurations with a device, use a pinctrl-N property for some
5657
number N, like this example you could place in your board's DTS file:
@@ -82,6 +83,7 @@ child-binding:
8283
- bias-pull-down
8384
- bias-pull-up
8485
- drive-strength
86+
- power-source
8587

8688
properties:
8789
pin:

include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rcar-common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,8 @@
4040
*/
4141
#define RCAR_NOGP_PIN(pin) (PIN_NOGPSR_START + pin)
4242

43+
#define PIN_VOLTAGE_NONE 0
44+
#define PIN_VOLTAGE_1P8V 1
45+
#define PIN_VOLTAGE_3P3V 2
46+
4347
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RCAR_COMMON_H_ */

soc/arm/renesas_rcar/gen3/pfc_r8a77951.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,55 @@ const struct pfc_bias_reg pfc_bias_regs[] = {
528528
} },
529529
{ /* sentinel */ },
530530
};
531+
532+
#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
533+
const struct pfc_pocctrl_reg pfc_io_voltage_regs[] = {
534+
{
535+
.offset = 0x0380,
536+
.pins = {
537+
[0] = RCAR_GP_PIN(3, 0), /* SD0_CLK */
538+
[1] = RCAR_GP_PIN(3, 1), /* SD0_CMD */
539+
[2] = RCAR_GP_PIN(3, 2), /* SD0_DAT0 */
540+
[3] = RCAR_GP_PIN(3, 3), /* SD0_DAT1 */
541+
[4] = RCAR_GP_PIN(3, 4), /* SD0_DAT2 */
542+
[5] = RCAR_GP_PIN(3, 5), /* SD0_DAT3 */
543+
[6] = RCAR_GP_PIN(3, 6), /* SD1_CLK */
544+
[7] = RCAR_GP_PIN(3, 7), /* SD1_CMD */
545+
[8] = RCAR_GP_PIN(3, 8), /* SD1_DAT0 */
546+
[9] = RCAR_GP_PIN(3, 9), /* SD1_DAT1 */
547+
[10] = RCAR_GP_PIN(3, 10), /* SD1_DAT2 */
548+
[11] = RCAR_GP_PIN(3, 11), /* SD1_DAT3 */
549+
[12] = RCAR_GP_PIN(4, 0), /* SD2_CLK */
550+
[13] = RCAR_GP_PIN(4, 1), /* SD2_CMD */
551+
[14] = RCAR_GP_PIN(4, 2), /* SD2_DAT0 */
552+
[15] = RCAR_GP_PIN(4, 3), /* SD2_DAT1 */
553+
[16] = RCAR_GP_PIN(4, 4), /* SD2_DAT2 */
554+
[17] = RCAR_GP_PIN(4, 5), /* SD2_DAT3 */
555+
[18] = RCAR_GP_PIN(4, 6), /* SD2_DS */
556+
[19] = RCAR_GP_PIN(4, 7), /* SD3_CLK */
557+
[20] = RCAR_GP_PIN(4, 8), /* SD3_CMD */
558+
[21] = RCAR_GP_PIN(4, 9), /* SD3_DAT0 */
559+
[22] = RCAR_GP_PIN(4, 10), /* SD3_DAT1 */
560+
[23] = RCAR_GP_PIN(4, 11), /* SD3_DAT2 */
561+
[24] = RCAR_GP_PIN(4, 12), /* SD3_DAT3 */
562+
[25] = RCAR_GP_PIN(4, 13), /* SD3_DAT4 */
563+
[26] = RCAR_GP_PIN(4, 14), /* SD3_DAT5 */
564+
[27] = RCAR_GP_PIN(4, 15), /* SD3_DAT6 */
565+
[28] = RCAR_GP_PIN(4, 16), /* SD3_DAT7 */
566+
[29] = RCAR_GP_PIN(4, 17), /* SD3_DS */
567+
[30] = PIN_NONE,
568+
[31] = PIN_NONE,
569+
}
570+
},
571+
{ /* sentinel */ },
572+
};
573+
574+
const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void)
575+
{
576+
return pfc_io_voltage_regs;
577+
}
578+
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */
579+
531580
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void)
532581
{
533582
return pfc_bias_regs;

soc/arm/renesas_rcar/gen3/pinctrl_soc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ typedef struct pinctrl_soc_pin {
3737
struct rcar_pin_func func;
3838
uint8_t flags;
3939
uint8_t drive_strength;
40+
uint8_t voltage;
4041
} pinctrl_soc_pin_t;
4142

4243
#define RCAR_IPSR(node_id) DT_PROP_BY_IDX(node_id, pin, 1)
@@ -103,6 +104,16 @@ struct pfc_bias_reg {
103104
const uint16_t pins[32];
104105
};
105106

107+
#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
108+
/* POC Control Register can control IO voltage level that is supplied to the pin */
109+
struct pfc_pocctrl_reg {
110+
uint32_t offset;
111+
const uint16_t pins[32];
112+
};
113+
114+
const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void);
115+
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */
116+
106117
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void);
107118
const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void);
108119

soc/arm64/renesas_rcar/gen3/pfc_r8a77951.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,55 @@ const struct pfc_bias_reg pfc_bias_regs[] = {
528528
} },
529529
{ /* sentinel */ },
530530
};
531+
532+
#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
533+
const struct pfc_pocctrl_reg pfc_io_voltage_regs[] = {
534+
{
535+
.offset = 0x0380,
536+
.pins = {
537+
[0] = RCAR_GP_PIN(3, 0), /* SD0_CLK */
538+
[1] = RCAR_GP_PIN(3, 1), /* SD0_CMD */
539+
[2] = RCAR_GP_PIN(3, 2), /* SD0_DAT0 */
540+
[3] = RCAR_GP_PIN(3, 3), /* SD0_DAT1 */
541+
[4] = RCAR_GP_PIN(3, 4), /* SD0_DAT2 */
542+
[5] = RCAR_GP_PIN(3, 5), /* SD0_DAT3 */
543+
[6] = RCAR_GP_PIN(3, 6), /* SD1_CLK */
544+
[7] = RCAR_GP_PIN(3, 7), /* SD1_CMD */
545+
[8] = RCAR_GP_PIN(3, 8), /* SD1_DAT0 */
546+
[9] = RCAR_GP_PIN(3, 9), /* SD1_DAT1 */
547+
[10] = RCAR_GP_PIN(3, 10), /* SD1_DAT2 */
548+
[11] = RCAR_GP_PIN(3, 11), /* SD1_DAT3 */
549+
[12] = RCAR_GP_PIN(4, 0), /* SD2_CLK */
550+
[13] = RCAR_GP_PIN(4, 1), /* SD2_CMD */
551+
[14] = RCAR_GP_PIN(4, 2), /* SD2_DAT0 */
552+
[15] = RCAR_GP_PIN(4, 3), /* SD2_DAT1 */
553+
[16] = RCAR_GP_PIN(4, 4), /* SD2_DAT2 */
554+
[17] = RCAR_GP_PIN(4, 5), /* SD2_DAT3 */
555+
[18] = RCAR_GP_PIN(4, 6), /* SD2_DS */
556+
[19] = RCAR_GP_PIN(4, 7), /* SD3_CLK */
557+
[20] = RCAR_GP_PIN(4, 8), /* SD3_CMD */
558+
[21] = RCAR_GP_PIN(4, 9), /* SD3_DAT0 */
559+
[22] = RCAR_GP_PIN(4, 10), /* SD3_DAT1 */
560+
[23] = RCAR_GP_PIN(4, 11), /* SD3_DAT2 */
561+
[24] = RCAR_GP_PIN(4, 12), /* SD3_DAT3 */
562+
[25] = RCAR_GP_PIN(4, 13), /* SD3_DAT4 */
563+
[26] = RCAR_GP_PIN(4, 14), /* SD3_DAT5 */
564+
[27] = RCAR_GP_PIN(4, 15), /* SD3_DAT6 */
565+
[28] = RCAR_GP_PIN(4, 16), /* SD3_DAT7 */
566+
[29] = RCAR_GP_PIN(4, 17), /* SD3_DS */
567+
[30] = PIN_NONE,
568+
[31] = PIN_NONE,
569+
}
570+
},
571+
{ /* sentinel */ },
572+
};
573+
574+
const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void)
575+
{
576+
return pfc_io_voltage_regs;
577+
}
578+
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */
579+
531580
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void)
532581
{
533582
return pfc_bias_regs;

soc/arm64/renesas_rcar/gen3/pfc_r8a77961.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,55 @@ const struct pfc_bias_reg pfc_bias_regs[] = {
136136
} },
137137
{ /* sentinel */ },
138138
};
139+
140+
#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
141+
const struct pfc_pocctrl_reg pfc_io_voltage_regs[] = {
142+
{
143+
.offset = 0x0380,
144+
.pins = {
145+
[0] = RCAR_GP_PIN(3, 0), /* SD0_CLK */
146+
[1] = RCAR_GP_PIN(3, 1), /* SD0_CMD */
147+
[2] = RCAR_GP_PIN(3, 2), /* SD0_DAT0 */
148+
[3] = RCAR_GP_PIN(3, 3), /* SD0_DAT1 */
149+
[4] = RCAR_GP_PIN(3, 4), /* SD0_DAT2 */
150+
[5] = RCAR_GP_PIN(3, 5), /* SD0_DAT3 */
151+
[6] = RCAR_GP_PIN(3, 6), /* SD1_CLK */
152+
[7] = RCAR_GP_PIN(3, 7), /* SD1_CMD */
153+
[8] = RCAR_GP_PIN(3, 8), /* SD1_DAT0 */
154+
[9] = RCAR_GP_PIN(3, 9), /* SD1_DAT1 */
155+
[10] = RCAR_GP_PIN(3, 10), /* SD1_DAT2 */
156+
[11] = RCAR_GP_PIN(3, 11), /* SD1_DAT3 */
157+
[12] = RCAR_GP_PIN(4, 0), /* SD2_CLK */
158+
[13] = RCAR_GP_PIN(4, 1), /* SD2_CMD */
159+
[14] = RCAR_GP_PIN(4, 2), /* SD2_DAT0 */
160+
[15] = RCAR_GP_PIN(4, 3), /* SD2_DAT1 */
161+
[16] = RCAR_GP_PIN(4, 4), /* SD2_DAT2 */
162+
[17] = RCAR_GP_PIN(4, 5), /* SD2_DAT3 */
163+
[18] = RCAR_GP_PIN(4, 6), /* SD2_DS */
164+
[19] = RCAR_GP_PIN(4, 7), /* SD3_CLK */
165+
[20] = RCAR_GP_PIN(4, 8), /* SD3_CMD */
166+
[21] = RCAR_GP_PIN(4, 9), /* SD3_DAT0 */
167+
[22] = RCAR_GP_PIN(4, 10), /* SD3_DAT1 */
168+
[23] = RCAR_GP_PIN(4, 11), /* SD3_DAT2 */
169+
[24] = RCAR_GP_PIN(4, 12), /* SD3_DAT3 */
170+
[25] = RCAR_GP_PIN(4, 13), /* SD3_DAT4 */
171+
[26] = RCAR_GP_PIN(4, 14), /* SD3_DAT5 */
172+
[27] = RCAR_GP_PIN(4, 15), /* SD3_DAT6 */
173+
[28] = RCAR_GP_PIN(4, 16), /* SD3_DAT7 */
174+
[29] = RCAR_GP_PIN(4, 17), /* SD3_DS */
175+
[30] = PIN_NONE,
176+
[31] = PIN_NONE,
177+
}
178+
},
179+
{ /* sentinel */ },
180+
};
181+
182+
const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void)
183+
{
184+
return pfc_io_voltage_regs;
185+
}
186+
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */
187+
139188
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void)
140189
{
141190
return pfc_bias_regs;

soc/arm64/renesas_rcar/gen3/pinctrl_soc.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ typedef struct pinctrl_soc_pin {
3737
struct rcar_pin_func func;
3838
uint8_t flags;
3939
uint8_t drive_strength;
40+
uint8_t voltage;
4041
} pinctrl_soc_pin_t;
4142

4243
#define RCAR_IPSR(node_id) DT_PROP_BY_IDX(node_id, pin, 1)
@@ -65,6 +66,10 @@ typedef struct pinctrl_soc_pin {
6566
.drive_strength = \
6667
COND_CODE_1(DT_NODE_HAS_PROP(node_id, drive_strength), \
6768
(DT_PROP(node_id, drive_strength)), (0)), \
69+
.voltage = COND_CODE_1(DT_NODE_HAS_PROP(node_id, \
70+
power_source), \
71+
(DT_PROP(node_id, power_source)), \
72+
(PIN_VOLTAGE_NONE)), \
6873
},
6974

7075
/**
@@ -103,6 +108,16 @@ struct pfc_bias_reg {
103108
const uint16_t pins[32];
104109
};
105110

111+
#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
112+
/* POC Control Register can control IO voltage level that is supplied to the pin */
113+
struct pfc_pocctrl_reg {
114+
uint32_t offset;
115+
const uint16_t pins[32];
116+
};
117+
118+
const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void);
119+
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */
120+
106121
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void);
107122
const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void);
108123

0 commit comments

Comments
 (0)