Skip to content

Commit 289e15b

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 r8a7795, r8a7796 and r8a779f 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 r8a7795 and r8a7796 SoCs, r8a779f supports more pins for configuring voltage, but only SD/MMC pins have been added to the array. Signed-off-by: Mykola Kvach <[email protected]>
1 parent d83b7a2 commit 289e15b

File tree

9 files changed

+233
-0
lines changed

9 files changed

+233
-0
lines changed

drivers/pinctrl/pfc_rcar.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,63 @@ int pfc_rcar_set_bias(uint16_t pin, uint16_t flags)
176176
return 0;
177177
}
178178

179+
#ifdef CONFIG_PIN_VOLTAGE_CONTROL
180+
static const struct pfc_pocctrl_reg *pfc_rcar_get_pocctrl_reg(uint16_t pin, uint8_t *bit)
181+
{
182+
const struct pfc_pocctrl_reg *voltage_regs = pfc_rcar_get_io_voltage_regs();
183+
184+
BUILD_ASSERT(ARRAY_SIZE(voltage_regs->pins) < UINT8_MAX);
185+
186+
/* Loop around all the registers to find the bit for a given pin */
187+
while (voltage_regs && voltage_regs->offset) {
188+
uint8_t i;
189+
190+
for (i = 0U; i < ARRAY_SIZE(voltage_regs->pins); i++) {
191+
if (voltage_regs->pins[i] == pin) {
192+
*bit = i;
193+
return voltage_regs;
194+
}
195+
}
196+
voltage_regs++;
197+
}
198+
199+
return NULL;
200+
}
201+
202+
static void pfc_rcar_set_voltage(uint16_t pin, uint16_t voltage)
203+
{
204+
uint32_t val;
205+
uint8_t bit;
206+
const struct pfc_pocctrl_reg *voltage_reg;
207+
208+
voltage_reg = pfc_rcar_get_pocctrl_reg(pin, &bit);
209+
if (!voltage_reg) {
210+
return;
211+
}
212+
213+
val = sys_read32(PFC_REG_BASE + voltage_reg->offset);
214+
215+
switch (voltage) {
216+
case PIN_VOLTAGE_1P8V:
217+
if (!(val & BIT(bit))) {
218+
return;
219+
}
220+
val &= ~BIT(bit);
221+
break;
222+
case PIN_VOLTAGE_3P3V:
223+
if (val & BIT(bit)) {
224+
return;
225+
}
226+
val |= BIT(bit);
227+
break;
228+
default:
229+
break;
230+
}
231+
232+
pfc_rcar_write(voltage_reg->offset, val);
233+
}
234+
#endif /* CONFIG_PIN_VOLTAGE_CONTROL */
235+
179236
int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
180237
{
181238
int ret = 0;
@@ -188,6 +245,12 @@ int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
188245
return -EINVAL;
189246
}
190247

248+
#ifdef CONFIG_PIN_VOLTAGE_CONTROL
249+
if (pin->voltage != PIN_VOLTAGE_NONE) {
250+
pfc_rcar_set_voltage(pin->pin, pin->voltage);
251+
}
252+
#endif
253+
191254
/* Select function for pin */
192255
if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) != 0U) {
193256
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/arm64/renesas_rcar/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ config SOC_FAMILY
1212
string
1313
default "renesas_rcar"
1414

15+
config PIN_VOLTAGE_CONTROL
16+
bool
17+
default y
18+
1519
source "soc/arm64/renesas_rcar/*/Kconfig.soc"
1620

1721
endif # SOC_FAMILY_RCAR

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_PIN_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_PIN_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_PIN_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_PIN_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_PIN_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_PIN_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

soc/arm64/renesas_rcar/gen4/pfc_r8a779f.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,37 @@ const struct pfc_bias_reg pfc_bias_regs[] = {
6161
{ /* sentinel */ },
6262
};
6363

64+
#ifdef CONFIG_PIN_VOLTAGE_CONTROL
65+
const struct pfc_pocctrl_reg pfc_io_voltage_regs[] = {
66+
{
67+
.offset = 0x08a0, /* POC1 */
68+
.pins = {
69+
[0 ... 11] = PIN_NONE,
70+
[12] = PIN_MMC_SD_CLK,
71+
[13] = PIN_MMC_SD_D0,
72+
[14] = PIN_MMC_SD_D1,
73+
[15] = PIN_MMC_SD_D2,
74+
[16] = PIN_MMC_SD_D3,
75+
[17] = PIN_MMC_D5,
76+
[18] = PIN_MMC_D4,
77+
[19] = PIN_MMC_D6,
78+
[20] = PIN_MMC_DS,
79+
[21] = PIN_MMC_D7,
80+
[22] = PIN_MMC_SD_CMD,
81+
[23] = PIN_SD_CD,
82+
[24] = PIN_SD_WP,
83+
[25 ... 31] = PIN_NONE,
84+
},
85+
},
86+
{ /* sentinel */ },
87+
};
88+
89+
const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void)
90+
{
91+
return pfc_io_voltage_regs;
92+
}
93+
#endif /* CONFIG_PIN_VOLTAGE_CONTROL */
94+
6495
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void)
6596
{
6697
return pfc_bias_regs;

soc/arm64/renesas_rcar/gen4/pinctrl_soc.h

Lines changed: 16 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,17 @@ struct pfc_bias_reg {
103108
const uint16_t pins[32];
104109
};
105110

111+
#ifdef CONFIG_PIN_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+
120+
#endif /* CONFIG_PIN_VOLTAGE_CONTROL */
121+
106122
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void);
107123
const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void);
108124

0 commit comments

Comments
 (0)