From febbeeed2a60c9229c3b202e52c3e5d542fb5542 Mon Sep 17 00:00:00 2001 From: Julien Massot Date: Tue, 29 Jun 2021 11:45:29 +0200 Subject: [PATCH] soc: arm: renesas_rcar: add pinmux driver Allow to set an alternate function for a given pin configuration, GPSR register allow to set a pin to GPIO or peripheral, IPSR allows to choose an alternate function. Other pin configurations such as pull-up are not supported at the moment, but could be added later if useful. Signed-off-by: Julien Massot --- soc/arm/renesas_rcar/gen3/CMakeLists.txt | 1 + soc/arm/renesas_rcar/gen3/Kconfig.series | 7 +++ soc/arm/renesas_rcar/gen3/pinmux-rcar.h | 67 ++++++++++++++++++++++++ soc/arm/renesas_rcar/gen3/pinmux_rcar.c | 62 ++++++++++++++++++++++ soc/arm/renesas_rcar/gen3/soc.h | 2 + 5 files changed, 139 insertions(+) create mode 100644 soc/arm/renesas_rcar/gen3/pinmux-rcar.h create mode 100644 soc/arm/renesas_rcar/gen3/pinmux_rcar.c diff --git a/soc/arm/renesas_rcar/gen3/CMakeLists.txt b/soc/arm/renesas_rcar/gen3/CMakeLists.txt index 012dd5d392cc01..3fb2ec1ad44c24 100644 --- a/soc/arm/renesas_rcar/gen3/CMakeLists.txt +++ b/soc/arm/renesas_rcar/gen3/CMakeLists.txt @@ -3,4 +3,5 @@ zephyr_sources( soc.c + pinmux_rcar.c ) diff --git a/soc/arm/renesas_rcar/gen3/Kconfig.series b/soc/arm/renesas_rcar/gen3/Kconfig.series index 966bbbb30e0b2a..330ef23a8e605a 100644 --- a/soc/arm/renesas_rcar/gen3/Kconfig.series +++ b/soc/arm/renesas_rcar/gen3/Kconfig.series @@ -10,5 +10,12 @@ config SOC_SERIES_RCAR_GEN3 select CPU_HAS_DCLS select SOC_FAMILY_RCAR select CLOCK_CONTROL_RCAR_CPG_MSSR if CLOCK_CONTROL + select PINMUX_RCAR if PINMUX help Enable support for Renesas RCar Gen3 SoC series + +config PINMUX_RCAR + bool "Renesas RCar Gen3 pinmux driver" + depends on SOC_SERIES_RCAR_GEN3 + help + Enable the Renesas RCar Gen3 pinmux driver. diff --git a/soc/arm/renesas_rcar/gen3/pinmux-rcar.h b/soc/arm/renesas_rcar/gen3/pinmux-rcar.h new file mode 100644 index 00000000000000..0bc50ec13f7854 --- /dev/null +++ b/soc/arm/renesas_rcar/gen3/pinmux-rcar.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 IoT.bzh + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef _PINMUX_RCAR__H_ +#define _PINMUX_RCAR__H_ +#include +#include +#include +#include + +struct rcar_pin { + /* select pin function */ + uint8_t ipsr_bank; /* bank number 0 - 18 */ + uint8_t ipsr_shift; /* bit shift 0 - 28 */ + uint8_t ipsr_val; /* choice from 0x0 to 0xF */ + /* Select gpio or function */ + uint8_t gpsr_bank; /* bank number 0 - 7 */ + uint8_t gpsr_num; /* pin index < 32 */ + bool gpsr_val; /* gpio:false, peripheral:true */ +}; + +void pinmux_rcar_set_pingroup(const struct rcar_pin *pins, size_t num_pins); + +/* Get PIN associated with pinctrl-0 pin at index 'i' */ +#define RCAR_IPSR(node_id, i) \ + DT_PROP_BY_IDX(DT_PINCTRL_0(node_id, i), renesas_rcar_pins, 0) + +/* Get PIN associated with pinctrl-0 pin at index 'i' */ +#define RCAR_GPSR(node_id, i) \ + DT_PROP_BY_IDX(DT_PINCTRL_0(node_id, i), renesas_rcar_pins, 1) + +#define RCAR_DT_PIN(node_id, idx) \ + { \ + ((RCAR_IPSR(node_id, idx) >> 10) & 0x1F), \ + (((RCAR_IPSR(node_id, idx) >> 4) & 0x7) * 4), \ + ((RCAR_IPSR(node_id, idx) & 0xF)), \ + ((RCAR_GPSR(node_id, idx) >> 7) & 0x7), \ + ((RCAR_GPSR(node_id, idx) >> 1) & 0x1F), \ + ((RCAR_GPSR(node_id, idx) & 0x1)), \ + } + +#define RCAR_DT_INST_PIN(inst, idx) \ + RCAR_DT_PIN(DT_DRV_INST(inst), idx) + +/* Get the number of pins for pinctrl-0 */ +#define RCAR_DT_NUM_PINS(node_id) DT_NUM_PINCTRLS_BY_IDX(node_id, 0) + +#define RCAR_DT_INST_NUM_PINS(inst) \ + RCAR_DT_NUM_PINS(DT_DRV_INST(inst)) + +/* internal macro to structure things for use with UTIL_LISTIFY */ +#define RCAR_DT_PIN_ELEM(idx, node_id) RCAR_DT_PIN(node_id, idx), + +/* Construct an array intializer for rcar_pin for a device instance */ +#define RCAR_DT_PINS(node_id) \ + { UTIL_LISTIFY(RCAR_DT_NUM_PINS(node_id), \ + RCAR_DT_PIN_ELEM, node_id) \ + } + +#define RCAR_DT_INST_PINS(inst) \ + RCAR_DT_PINS(DT_DRV_INST(inst)) + +#endif /* _PINMUX_RCAR__H_ */ diff --git a/soc/arm/renesas_rcar/gen3/pinmux_rcar.c b/soc/arm/renesas_rcar/gen3/pinmux_rcar.c new file mode 100644 index 00000000000000..37f7e0a9dd812a --- /dev/null +++ b/soc/arm/renesas_rcar/gen3/pinmux_rcar.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 IoT.bzh + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rcar_pinmux + +#include +#include +#include + +#define PINMUX_REG_BASE DT_INST_REG_ADDR(0) +#define PINMUX_RCAR_PMMR 0x0 +#define PINMUX_RCAR_GPSR 0x100 +#define PINMUX_RCAR_IPSR 0x200 + +/* Any write to IPSR or GPSR must be precede to a write to PMMR with + * the inverse value. + */ +static void pinmux_rcar_write(uint32_t offs, uint32_t val) +{ + sys_write32(~val, PINMUX_REG_BASE + PINMUX_RCAR_PMMR); + sys_write32(val, PINMUX_REG_BASE + offs); +} + +/* Set the pin either in gpio or peripheral */ +static void pinmux_rcar_set_gpsr(uint8_t bank, uint8_t pos, bool peripheral) +{ + uint32_t reg = sys_read32(PINMUX_REG_BASE + PINMUX_RCAR_GPSR + + bank * sizeof(uint32_t)); + + if (peripheral) { + reg |= BIT(pos); + } else { + reg &= ~BIT(pos); + } + pinmux_rcar_write(PINMUX_RCAR_GPSR + bank * sizeof(uint32_t), reg); +} + +/* Set peripheral function */ +static void pinmux_rcar_set_ipsr(uint8_t bank, uint8_t shift, uint8_t val) +{ + uint32_t reg = sys_read32(PINMUX_REG_BASE + PINMUX_RCAR_IPSR + + bank * sizeof(uint32_t)); + + reg &= ~(0xF << shift); + reg |= (val << shift); + pinmux_rcar_write(PINMUX_RCAR_IPSR + bank * sizeof(uint32_t), reg); +} + +void pinmux_rcar_set_pingroup(const struct rcar_pin *pins, size_t num_pins) +{ + size_t i; + + for (i = 0; i < num_pins; i++, pins++) { + pinmux_rcar_set_gpsr(pins->gpsr_bank, pins->gpsr_num, + pins->gpsr_val); + pinmux_rcar_set_ipsr(pins->ipsr_bank, pins->ipsr_shift, + pins->ipsr_val); + } +} diff --git a/soc/arm/renesas_rcar/gen3/soc.h b/soc/arm/renesas_rcar/gen3/soc.h index bedd66f5172041..badbecc70b694d 100644 --- a/soc/arm/renesas_rcar/gen3/soc.h +++ b/soc/arm/renesas_rcar/gen3/soc.h @@ -15,4 +15,6 @@ #define __GIC_PRESENT 0 #define __TIM_PRESENT 0 +#include "pinmux-rcar.h" + #endif /* _SOC__H_ */