Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions drivers/pinctrl/Kconfig.rcar
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ config PINCTRL_RCAR_PFC
depends on DT_HAS_RENESAS_RCAR_PFC_ENABLED
help
Enable pin controller driver for Renesas RCar SoC

config PINCTRL_RCAR_VOLTAGE_CONTROL
bool "Voltage control functionality of Renesas R-Car PFC driver"
default y if SOC_SERIES_RCAR_GEN3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

depends on PINCTRL_RCAR_PFC

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

depends on PINCTRL_RCAR_PFC
118 changes: 118 additions & 0 deletions drivers/pinctrl/pfc_rcar.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ static const uintptr_t reg_base[] = {
#error Unsupported SoC Series
#endif

#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
/* POC Control Register can control IO voltage level that is supplied to the pin */
struct pfc_pocctrl_reg {
uint32_t offset;
const uint16_t pins[32];
};
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */

/*
* Each drive step is either encoded in 2 or 3 bits.
* So based on a 24 mA maximum value each step is either
Expand Down Expand Up @@ -189,6 +197,110 @@ int pfc_rcar_set_bias(uintptr_t pfc_base, uint16_t pin, uint16_t flags)
return 0;
}

#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL

const struct pfc_pocctrl_reg pfc_r8a77951_r8a77961_volt_regs[] = {
{
.offset = 0x0380,
.pins = {
[0] = RCAR_GP_PIN(3, 0), /* SD0_CLK */
[1] = RCAR_GP_PIN(3, 1), /* SD0_CMD */
[2] = RCAR_GP_PIN(3, 2), /* SD0_DAT0 */
[3] = RCAR_GP_PIN(3, 3), /* SD0_DAT1 */
[4] = RCAR_GP_PIN(3, 4), /* SD0_DAT2 */
[5] = RCAR_GP_PIN(3, 5), /* SD0_DAT3 */
[6] = RCAR_GP_PIN(3, 6), /* SD1_CLK */
[7] = RCAR_GP_PIN(3, 7), /* SD1_CMD */
[8] = RCAR_GP_PIN(3, 8), /* SD1_DAT0 */
[9] = RCAR_GP_PIN(3, 9), /* SD1_DAT1 */
[10] = RCAR_GP_PIN(3, 10), /* SD1_DAT2 */
[11] = RCAR_GP_PIN(3, 11), /* SD1_DAT3 */
[12] = RCAR_GP_PIN(4, 0), /* SD2_CLK */
[13] = RCAR_GP_PIN(4, 1), /* SD2_CMD */
[14] = RCAR_GP_PIN(4, 2), /* SD2_DAT0 */
[15] = RCAR_GP_PIN(4, 3), /* SD2_DAT1 */
[16] = RCAR_GP_PIN(4, 4), /* SD2_DAT2 */
[17] = RCAR_GP_PIN(4, 5), /* SD2_DAT3 */
[18] = RCAR_GP_PIN(4, 6), /* SD2_DS */
[19] = RCAR_GP_PIN(4, 7), /* SD3_CLK */
[20] = RCAR_GP_PIN(4, 8), /* SD3_CMD */
[21] = RCAR_GP_PIN(4, 9), /* SD3_DAT0 */
[22] = RCAR_GP_PIN(4, 10), /* SD3_DAT1 */
[23] = RCAR_GP_PIN(4, 11), /* SD3_DAT2 */
[24] = RCAR_GP_PIN(4, 12), /* SD3_DAT3 */
[25] = RCAR_GP_PIN(4, 13), /* SD3_DAT4 */
[26] = RCAR_GP_PIN(4, 14), /* SD3_DAT5 */
[27] = RCAR_GP_PIN(4, 15), /* SD3_DAT6 */
[28] = RCAR_GP_PIN(4, 16), /* SD3_DAT7 */
[29] = RCAR_GP_PIN(4, 17), /* SD3_DS */
[30] = -1,
[31] = -1,
}
},
{ /* sentinel */ },
};

static const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void)
{
return pfc_r8a77951_r8a77961_volt_regs;
}

static const struct pfc_pocctrl_reg *pfc_rcar_get_pocctrl_reg(uint16_t pin, uint8_t *bit)
{
const struct pfc_pocctrl_reg *voltage_regs = pfc_rcar_get_io_voltage_regs();

BUILD_ASSERT(ARRAY_SIZE(voltage_regs->pins) < UINT8_MAX);

/* Loop around all the registers to find the bit for a given pin */
while (voltage_regs && voltage_regs->offset) {
uint8_t i;

for (i = 0U; i < ARRAY_SIZE(voltage_regs->pins); i++) {
if (voltage_regs->pins[i] == pin) {
*bit = i;
return voltage_regs;
}
}
voltage_regs++;
}

return NULL;
}

static void pfc_rcar_set_voltage(uintptr_t pfc_base, uint16_t pin, uint16_t voltage)
{
uint32_t val;
uint8_t bit;
const struct pfc_pocctrl_reg *voltage_reg;

voltage_reg = pfc_rcar_get_pocctrl_reg(pin, &bit);
if (!voltage_reg) {
return;
}

val = sys_read32(pfc_base + voltage_reg->offset);

switch (voltage) {
case PIN_VOLTAGE_1P8V:
if (!(val & BIT(bit))) {
return;
}
val &= ~BIT(bit);
break;
case PIN_VOLTAGE_3P3V:
if (val & BIT(bit)) {
return;
}
val |= BIT(bit);
break;
default:
break;
}

pfc_rcar_write(pfc_base, voltage_reg->offset, val);
}
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */

int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
{
int ret = 0;
Expand All @@ -214,6 +326,12 @@ int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
return -EINVAL;
}

#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
if (pin->voltage != PIN_VOLTAGE_NONE) {
pfc_rcar_set_voltage(pfc_base, pin->pin, pin->voltage);
}
#endif

/* Select function for pin */
if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) != 0U) {
pfc_rcar_set_ipsr(pfc_base, &pin->func);
Expand Down
2 changes: 2 additions & 0 deletions dts/bindings/pinctrl/renesas,rcar-pfc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ description: |
- bias-pull-down
- bias-pull-up
- drive-strength
- power-source

To link pin configurations with a device, use a pinctrl-N property for some
number N, like this example you could place in your board's DTS file:
Expand Down Expand Up @@ -82,6 +83,7 @@ child-binding:
- bias-pull-down
- bias-pull-up
- drive-strength
- power-source

properties:
pin:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,8 @@
#define IP2SR5(shift, func) IPnSR(2, 5, shift, func)
#define IP3SR5(shift, func) IPnSR(3, 5, shift, func)

#define PIN_VOLTAGE_NONE 0
#define PIN_VOLTAGE_1P8V 1
#define PIN_VOLTAGE_3P3V 2

#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RCAR_COMMON_H_ */
5 changes: 5 additions & 0 deletions soc/arm/renesas_rcar/common/pinctrl_rcar.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef struct pinctrl_soc_pin {
struct rcar_pin_func func;
uint8_t flags;
uint8_t drive_strength;
uint8_t voltage;
} pinctrl_soc_pin_t;

#define RCAR_IPSR(node_id) DT_PROP_BY_IDX(node_id, pin, 1)
Expand Down Expand Up @@ -66,6 +67,10 @@ typedef struct pinctrl_soc_pin {
.drive_strength = \
COND_CODE_1(DT_NODE_HAS_PROP(node_id, drive_strength), \
(DT_PROP(node_id, drive_strength)), (0)), \
.voltage = COND_CODE_1(DT_NODE_HAS_PROP(node_id, \
power_source), \
(DT_PROP(node_id, power_source)), \
(PIN_VOLTAGE_NONE)), \
},

/**
Expand Down
5 changes: 5 additions & 0 deletions soc/arm64/renesas_rcar/gen3/pinctrl_soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ typedef struct pinctrl_soc_pin {
struct rcar_pin_func func;
uint8_t flags;
uint8_t drive_strength;
uint8_t voltage;
} pinctrl_soc_pin_t;

#define RCAR_IPSR(node_id) DT_PROP_BY_IDX(node_id, pin, 1)
Expand Down Expand Up @@ -65,6 +66,10 @@ typedef struct pinctrl_soc_pin {
.drive_strength = \
COND_CODE_1(DT_NODE_HAS_PROP(node_id, drive_strength), \
(DT_PROP(node_id, drive_strength)), (0)), \
.voltage = COND_CODE_1(DT_NODE_HAS_PROP(node_id, \
power_source), \
(DT_PROP(node_id, power_source)), \
(PIN_VOLTAGE_NONE)), \
},

/**
Expand Down