From f1b5511a2320451cdb8e0b8e6fd06cf8702e5fcc Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Tue, 15 Apr 2025 01:55:07 +0000 Subject: [PATCH] drivers: pinctrl: Add initial support for RZ/A2M Add pinctrl support for RZ/A2M Signed-off-by: Hieu Nguyen Signed-off-by: Binh Nguyen Signed-off-by: Hoang Nguyen --- .../renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi | 16 + drivers/pinctrl/renesas/CMakeLists.txt | 3 +- drivers/pinctrl/renesas/rz/Kconfig | 7 + .../renesas/rz/pinctrl_renesas_rza2m.c | 520 ++++++++++++++++++ dts/arm/renesas/rz/rza/r7s9210.dtsi | 5 + .../pinctrl/renesas,rza2m-pinctrl.yaml | 59 ++ .../pinctrl/renesas/pinctrl-rza2m.h | 51 ++ soc/renesas/rz/rza2m/pinctrl_soc.h | 60 ++ 8 files changed, 720 insertions(+), 1 deletion(-) create mode 100644 boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi create mode 100644 drivers/pinctrl/renesas/rz/pinctrl_renesas_rza2m.c create mode 100644 dts/bindings/pinctrl/renesas,rza2m-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rza2m.h create mode 100644 soc/renesas/rz/rza2m/pinctrl_soc.h diff --git a/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi b/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi new file mode 100644 index 00000000000..8d076ece20e --- /dev/null +++ b/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&pinctrl { + /omit-if-no-ref/ scif4_default: scif4_default { + scif4-pinmux { + pinmux = , /* TXD */ + ; /* RXD */ + }; + }; +}; diff --git a/drivers/pinctrl/renesas/CMakeLists.txt b/drivers/pinctrl/renesas/CMakeLists.txt index 4d420529178..0382b0be253 100644 --- a/drivers/pinctrl/renesas/CMakeLists.txt +++ b/drivers/pinctrl/renesas/CMakeLists.txt @@ -1,10 +1,11 @@ # Copyright (c) 2024 EPAM Systems -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_PINCTRL_RENESAS_RA_PFS ra/pinctrl_ra.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RZT2M rz/pinctrl_rzt2m.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SMARTBOND smartbond/pinctrl_smartbond.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RENESAS_RZ rz/pinctrl_renesas_rz.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_RENESAS_RZA2M rz/pinctrl_renesas_rza2m.c) add_subdirectory_ifdef(CONFIG_PINCTRL_RCAR_PFC rcar) diff --git a/drivers/pinctrl/renesas/rz/Kconfig b/drivers/pinctrl/renesas/rz/Kconfig index 42fa2b4d7c5..0d18fc64e73 100644 --- a/drivers/pinctrl/renesas/rz/Kconfig +++ b/drivers/pinctrl/renesas/rz/Kconfig @@ -20,3 +20,10 @@ config PINCTRL_RENESAS_RZ select USE_RZ_FSP_IOPORT help Enable Renesas RZ pinctrl driver. + +config PINCTRL_RENESAS_RZA2M + bool "Renesas RZA2M pin controller driver" + default y + depends on DT_HAS_RENESAS_RZA2M_PINCTRL_ENABLED + help + Enable Renesas RZ pinctrl driver. diff --git a/drivers/pinctrl/renesas/rz/pinctrl_renesas_rza2m.c b/drivers/pinctrl/renesas/rz/pinctrl_renesas_rza2m.c new file mode 100644 index 00000000000..0f54a6242bc --- /dev/null +++ b/drivers/pinctrl/renesas/rz/pinctrl_renesas_rza2m.c @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rza2m_pinctrl + +#include +#include +#include +#include + +#define RZA2M_PINCTRL_REG DT_REG_ADDR(DT_NODELABEL(pinctrl)) +#define RZA2M_PINCTRL_SIZE DT_REG_SIZE(DT_NODELABEL(pinctrl)) + +static struct rza2m_pinctrl_data { + mm_reg_t base_addr; + struct k_mutex lock; +} rza2m_pinctrl_data; + +#define RZA2M_PDR(port) (rza2m_pinctrl_data.base_addr + 0x0000 + (port) * 2) +#define RZA2M_PMR(port) (rza2m_pinctrl_data.base_addr + 0x0080 + (port)) +#define RZA2M_DSCR(port) (rza2m_pinctrl_data.base_addr + 0x0140 + (port * 2)) +#define RZA2M_PFS(port, pin) (rza2m_pinctrl_data.base_addr + 0x0200 + ((port) * 8) + (pin)) +#define RZA2M_PPOC (rza2m_pinctrl_data.base_addr + 0x0900) +#define RZA2M_PSDMMC0 (rza2m_pinctrl_data.base_addr + 0x0920) +#define RZA2M_PSDMMC1 (rza2m_pinctrl_data.base_addr + 0x0930) +#define RZA2M_PSDMMC2 (rza2m_pinctrl_data.base_addr + 0x0940) +#define RZA2M_PSPIBSC (rza2m_pinctrl_data.base_addr + 0x0960) +#define RZA2M_PCKIO (rza2m_pinctrl_data.base_addr + 0x09D0) +#define RZA2M_PWPR (rza2m_pinctrl_data.base_addr + 0x02FF) + +#define RZA2M_PWPR_PFSWE BIT(6) /* PFSWE Bit Enable */ +#define RZA2M_PWPR_B0WI BIT(7) /* PFSWE Bit Disable */ + +#define RZA2M_PDR_INPUT (0x02) +#define RZA2M_PDR_OUTPUT (0x03) +#define RZA2M_PDR_MASK (0x03) + +#define RZA2M_DSCR_PIN_DRV_MASK (0x03) + +#define RZA2M_PSDMMC0_MASK (0x3FFF) +#define RZA2M_PSDMMC1_MASK (0x7FF) +#define RZA2M_PSDMMC2_MASK (0x3FFF) + +#define RZA2M_PIN_CURRENT_2mA (0u) +#define RZA2M_PIN_CURRENT_8mA (1u) +#define RZA2M_PIN_CURRENT_12mA (2u) + +#define RZA2M_PPOC_POC0 (0x00000001u) +#define RZA2M_PPOC_POC0_SHIFT (0u) +#define RZA2M_PPOC_POC2 (0x00000004u) +#define RZA2M_PPOC_POC2_SHIFT (2u) +#define RZA2M_PPOC_POC3 (0x00000008u) +#define RZA2M_PPOC_POC3_SHIFT (3u) +#define RZA2M_PPOC_POCSEL0 (0x00000100u) +#define RZA2M_PPOC_POCSEL0_SHIFT (8u) + +/* Implemented pins */ +static const uint8_t valid_gpio_support[] = {0x7F, 0x1F, 0x0F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x7F, 0xFF, + 0xFF, 0x7F, 0xFF, 0x3F, 0x1F, 0x03}; + +/* DSCR supported pins for 8mA */ +static const uint8_t valid_gpio_dscr_8ma_support[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x7F, 0x00, 0x00, 0x00}; + +/* DSCR supported pins for 2mA */ +static const uint8_t valid_gpio_dscr_2ma_support[] = { + 0x7F, 0x1F, 0x0F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x3F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0x3F, 0x1F, 0x00}; + +static bool rza2m_pin_function_check(const uint8_t *check_array, uint8_t port, uint8_t pin) +{ + bool ret; + + ret = true; + if ((check_array[port] & (1u << pin)) == 0) { + ret = false; + } + + return (ret); +} + +static int rza2m_set_output_current_pin(const pinctrl_soc_pin_t pin) +{ + uint16_t reg_16; + uint16_t dscr; + + dscr = 0; + + if (!rza2m_pin_function_check(valid_gpio_support, pin.port, pin.pin)) { + return -EINVAL; + } + + if (pin.drive_strength == RZA2M_PIN_CURRENT_2mA) { + if (!rza2m_pin_function_check(valid_gpio_dscr_2ma_support, pin.port, pin.pin)) { + return -EINVAL; + } + dscr = 1; + } else if (pin.drive_strength == RZA2M_PIN_CURRENT_8mA) { + if (!rza2m_pin_function_check(valid_gpio_dscr_8ma_support, pin.port, pin.pin)) { + return -EINVAL; + } + dscr = 3; + } else { + return -EINVAL; + } + + /* Write to DCSR */ + reg_16 = sys_read16(RZA2M_DSCR(pin.port)); + reg_16 &= ~(RZA2M_DSCR_PIN_DRV_MASK << (pin.pin * 2)); + reg_16 |= (dscr << pin.pin * 2); + sys_write16(reg_16, RZA2M_DSCR(pin.port)); + + return 0; +} + +static int rza2m_set_output_current_ckio(uint8_t drive_strength) +{ + uint8_t ckio_drv; + + if (drive_strength == RZA2M_PIN_CURRENT_8mA) { + ckio_drv = 1; + } else if (drive_strength == RZA2M_PIN_CURRENT_12mA) { + ckio_drv = 2; + } else { + return -EINVAL; + } + + sys_write8(ckio_drv, RZA2M_PCKIO); + + return 0; +} + +static void rza2m_update_pspibsc(void) +{ + uint32_t pocsel0_poc0; + uint32_t reg_32; + + pocsel0_poc0 = sys_read32(RZA2M_PPOC); + pocsel0_poc0 &= (RZA2M_PPOC_POCSEL0 | RZA2M_PPOC_POC0); + + if (pocsel0_poc0 == (RZA2M_PPOC_POCSEL0 | RZA2M_PPOC_POC0)) { + /* 3.3v */ + reg_32 = 0x5555555; + } else { + /* 1.8v */ + reg_32 = 0xFFFFFFF; + } + + sys_write32(reg_32, RZA2M_PSPIBSC); +} + +static void rza2m_update_drv_sdmmc0(void) +{ + uint32_t reg_32; + uint32_t poc2; + uint32_t psdmmc0_val; + uint32_t psdmmc1_val; + + poc2 = sys_read32(RZA2M_PPOC); + poc2 &= RZA2M_PPOC_POC2; + + if (poc2 == RZA2M_PPOC_POC2) { + /* 3.3 V */ + /* TDSEL = 0b11, other fields = 0b10 */ + psdmmc0_val = 0x3AAA; + psdmmc1_val = 0x2AA; + } else { + /* 1.8 V */ + /* TDSEL = 0b01, other fields = 0b11 */ + psdmmc0_val = 0x1FFF; + psdmmc1_val = 0x3FF; + } + + /* Read and write PSDMMC0 */ + reg_32 = sys_read32(RZA2M_PSDMMC0); + reg_32 &= ~(RZA2M_PSDMMC0_MASK); + reg_32 |= psdmmc0_val; + sys_write32(reg_32, RZA2M_PSDMMC0); + + /* Read and write PSDMMC1 */ + reg_32 = sys_read32(RZA2M_PSDMMC1); + reg_32 &= ~(RZA2M_PSDMMC1_MASK); + reg_32 |= psdmmc1_val; + sys_write32(reg_32, RZA2M_PSDMMC1); +} + +static void rza2m_update_drv_sdmmc1(void) +{ + uint32_t reg_32; + uint32_t poc3; + uint32_t psdmmc2_val; + + poc3 = sys_read32(RZA2M_PPOC); + poc3 &= RZA2M_PPOC_POC3; + + if (poc3 == RZA2M_PPOC_POC3) { + /* 3.3 V */ + /* TDSEL = 0b11, other fields = 0b10 */ + psdmmc2_val = 0x3AAA; + } else { + /* 1.8 V */ + /* TDSEL = 0b01, other fields = 0b11 */ + psdmmc2_val = 0x1FFF; + } + + /* Read and write PSDMMC2 */ + reg_32 = sys_read32(RZA2M_PSDMMC2); + reg_32 &= ~(RZA2M_PSDMMC2_MASK); + reg_32 |= psdmmc2_val; + sys_write32(reg_32, RZA2M_PSDMMC2); +} + +static int rza2m_set_ppoc(const pinctrl_soc_pin_t pin) +{ + uint32_t reg_32; + uint32_t ppoc_val; + int ret; + + ret = 0; + k_mutex_lock(&rza2m_pinctrl_data.lock, K_FOREVER); + + switch (pin.pin) { + case PIN_POSEL: + ppoc_val = ((pin.func & 0x1) << RZA2M_PPOC_POC0_SHIFT) | + (((pin.func & 0x2) >> 1) << RZA2M_PPOC_POCSEL0_SHIFT); + + /* Set POC0 and POCSEL0 */ + reg_32 = sys_read32(RZA2M_PPOC); + reg_32 &= ~(RZA2M_PPOC_POC0 & RZA2M_PPOC_POCSEL0); + reg_32 |= ppoc_val; + sys_write32(reg_32, RZA2M_PPOC); + + rza2m_update_pspibsc(); + break; + + case PIN_POC2: + ppoc_val = ((pin.func & 0x1) << RZA2M_PPOC_POC2_SHIFT); + + /* Set POC2 */ + reg_32 = sys_read32(RZA2M_PPOC); + reg_32 &= ~(RZA2M_PPOC_POC2); + reg_32 |= ppoc_val; + sys_write32(reg_32, RZA2M_PPOC); + + rza2m_update_drv_sdmmc0(); + break; + + case PIN_POC3: + ppoc_val = ((pin.func & 0x1) << RZA2M_PPOC_POC3_SHIFT); + + /* Set POC3 */ + reg_32 = sys_read32(RZA2M_PPOC); + reg_32 &= ~(RZA2M_PPOC_POC3); + reg_32 |= ppoc_val; + sys_write32(reg_32, RZA2M_PPOC); + + rza2m_update_drv_sdmmc1(); + break; + + default: + ret = -EINVAL; + } + + k_mutex_unlock(&rza2m_pinctrl_data.lock); + + return ret; +} + +/* PFS Register Write Protect : OFF */ +static void rza2m_unprotect_pin_mux(void) +{ + uint8_t reg_8; + + /* Set B0WI to 0 */ + reg_8 = sys_read8(RZA2M_PWPR); + reg_8 &= ~RZA2M_PWPR_B0WI; + sys_write8(reg_8, RZA2M_PWPR); + + /* Set PFSWE to 1 */ + reg_8 = sys_read8(RZA2M_PWPR); + reg_8 |= RZA2M_PWPR_PFSWE; + sys_write8(reg_8, RZA2M_PWPR); +} + +/* PFS Register Write Protect : ON */ +static void rza2m_protect_pin_mux(void) +{ + uint8_t reg_8; + + /* Set PFSWE to 0 */ + reg_8 = sys_read8(RZA2M_PWPR); + reg_8 &= ~RZA2M_PWPR_PFSWE; + sys_write8(reg_8, RZA2M_PWPR); + + /* Set B0WI to 1 */ + reg_8 = sys_read8(RZA2M_PWPR); + reg_8 |= RZA2M_PWPR_B0WI; + sys_write8(reg_8, RZA2M_PWPR); +} + +static int rza2m_set_pin_hiz(uint8_t port, uint8_t pin) +{ + uint16_t mask_16; + uint16_t reg_16; + uint8_t reg_8; + + if (!rza2m_pin_function_check(valid_gpio_support, port, pin)) { + return -EINVAL; + } + + k_mutex_lock(&rza2m_pinctrl_data.lock, K_FOREVER); + + /* Set pin to Hi-z input protection */ + reg_16 = sys_read16(RZA2M_PDR(port)); + mask_16 = RZA2M_PDR_MASK << (pin * 2); + reg_16 &= ~mask_16; + sys_write16(reg_16, RZA2M_PDR(port)); + + rza2m_unprotect_pin_mux(); + + /* Set Pin function to 0 */ + reg_8 = sys_read8(RZA2M_PFS(port, pin)); + reg_8 &= ~(RZA2M_MUX_FUNC_MAX); + sys_write8(reg_8, RZA2M_PFS(port, pin)); + + rza2m_protect_pin_mux(); + + /* Switch to GPIO */ + reg_8 = sys_read8(RZA2M_PMR(port)); + reg_8 &= ~BIT(pin); + sys_write8(reg_8, RZA2M_PMR(port)); + + k_mutex_unlock(&rza2m_pinctrl_data.lock); + + return 0; +} + +static int rza2m_pin_to_gpio(uint8_t port, uint8_t pin, uint8_t dir) +{ + uint16_t mask_16; + uint16_t reg_16; + uint8_t reg_8; + + if (!rza2m_pin_function_check(valid_gpio_support, port, pin)) { + return -EINVAL; + } + + k_mutex_lock(&rza2m_pinctrl_data.lock, K_FOREVER); + + /* Set pin to Hi-z input protection */ + reg_16 = sys_read16(RZA2M_PDR(port)); + mask_16 = RZA2M_PDR_MASK << (pin * 2); + reg_16 &= ~mask_16; + sys_write16(reg_16, RZA2M_PDR(port)); + + /* Use the pin as a general I/O pin */ + reg_8 = sys_read8(RZA2M_PMR(port)); + reg_8 &= ~BIT(pin); + sys_write8(reg_8, RZA2M_PMR(port)); + + /* Set pin direction */ + reg_16 = sys_read16(RZA2M_PDR(port)); + mask_16 = RZA2M_PDR_MASK << (pin * 2); + reg_16 &= ~mask_16; + reg_16 |= dir << (pin * 2); + sys_write16(reg_16, RZA2M_PDR(port)); + + k_mutex_unlock(&rza2m_pinctrl_data.lock); + + return 0; +} + +static int rza2m_set_pin_function(uint8_t port, uint8_t pin, uint8_t func) +{ + uint16_t mask_16; + uint16_t reg_16; + uint8_t reg_8; + + if (!rza2m_pin_function_check(valid_gpio_support, port, pin)) { + return -EINVAL; + } + + k_mutex_lock(&rza2m_pinctrl_data.lock, K_FOREVER); + + /* Set pin to Hi-z input protection */ + reg_16 = sys_read16(RZA2M_PDR(port)); + mask_16 = RZA2M_PDR_MASK << (pin * 2); + reg_16 &= ~mask_16; + sys_write16(reg_16, RZA2M_PDR(port)); + + /* Temporarily switch to GPIO */ + reg_8 = sys_read8(RZA2M_PMR(port)); + reg_8 &= ~BIT(pin); + sys_write8(reg_8, RZA2M_PMR(port)); + + rza2m_unprotect_pin_mux(); + + /* Set Pin function */ + reg_8 = sys_read8(RZA2M_PFS(port, pin)); + reg_8 |= (func & RZA2M_MUX_FUNC_MAX); + sys_write8(reg_8, RZA2M_PFS(port, pin)); + + rza2m_protect_pin_mux(); + + /* Port Mode : Peripheral module pin functions */ + reg_8 = sys_read8(RZA2M_PMR(port)); + reg_8 |= BIT(pin); + sys_write8(reg_8, RZA2M_PMR(port)); + + k_mutex_unlock(&rza2m_pinctrl_data.lock); + + return 0; +} + +static int rza2m_set_gpio_int(uint8_t port, uint8_t pin, bool int_en) +{ + uint8_t reg_8; + + if (!rza2m_pin_function_check(valid_gpio_support, port, pin)) { + return -EINVAL; + } + + rza2m_unprotect_pin_mux(); + + reg_8 = sys_read8(RZA2M_PFS(port, pin)); + if (int_en) { + /* Enable interrupt, ISEL = 1 */ + reg_8 |= BIT(6); + } else { + /* Disable interrupt, ISEL = 0 */ + reg_8 &= ~BIT(6); + } + sys_write8(reg_8, RZA2M_PFS(port, pin)); + + rza2m_protect_pin_mux(); + + return 0; +} + +static int pinctrl_configure_pin(const pinctrl_soc_pin_t pin) +{ + int ret; + + ret = 0; + + /* Some pins of PORT_G and PORT_J can be set to 8mA */ + /* Use PORT_CKIO to configure current for the CKIO pin */ + /* Use PORT_PPOC to configure voltage for SPI or SD/MMC interface, after that: + * - If configure voltage for SPI, PSPIBSC need to be updated + * - If configure voltage for SD/MMC, PSDMMC0, PSDMMC1 or PSDMMC2 need to be updated + */ + if (pin.port == PORT_G || pin.port == PORT_J) { + ret = rza2m_set_output_current_pin(pin); + } else if (pin.port == PORT_CKIO) { + ret = rza2m_set_output_current_ckio(pin.drive_strength); + } else if (pin.port == PORT_PPOC) { + ret = rza2m_set_ppoc(pin); + } + + if (ret) { + return ret; + } + + /* Configure pin to HiZ, input, output and peripheral */ + if (pin.func & RZA2M_FUNC_GPIO_HIZ) { + ret = rza2m_set_pin_hiz(pin.port, pin.pin); + } else if (pin.func & RZA2M_FUNC_GPIO_INPUT) { + ret = rza2m_pin_to_gpio(pin.port, pin.pin, RZA2M_PDR_INPUT); + } else if (pin.func & RZA2M_FUNC_GPIO_OUTPUT) { + ret = rza2m_pin_to_gpio(pin.port, pin.pin, RZA2M_PDR_OUTPUT); + } else { + ret = rza2m_set_pin_function(pin.port, pin.pin, (pin.func & RZA2M_MUX_FUNC_MAX)); + } + + if (ret) { + return ret; + } + + /* Set TINT */ + if (pin.func & RZA2M_FUNC_GPIO_INT_EN) { + ret = rza2m_set_gpio_int(pin.port, pin.pin, true); + } else if (pin.func & RZA2M_FUNC_GPIO_INT_DIS) { + ret = rza2m_set_gpio_int(pin.port, pin.pin, false); + } + + return ret; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + int ret; + + ret = 0; + ARG_UNUSED(reg); + while (pin_cnt-- > 0U) { + ret = pinctrl_configure_pin(*pins++); + if (ret < 0) { + break; + } + } + + return ret; +} + +__boot_func static int pinctrl_rza2m_driver_init(void) +{ + device_map(&rza2m_pinctrl_data.base_addr, RZA2M_PINCTRL_REG, RZA2M_PINCTRL_SIZE, + K_MEM_CACHE_NONE); + + k_mutex_init(&rza2m_pinctrl_data.lock); + + return 0; +} + +SYS_INIT(pinctrl_rza2m_driver_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/dts/arm/renesas/rz/rza/r7s9210.dtsi b/dts/arm/renesas/rz/rza/r7s9210.dtsi index aec931375ce..6872a5301da 100644 --- a/dts/arm/renesas/rz/rza/r7s9210.dtsi +++ b/dts/arm/renesas/rz/rza/r7s9210.dtsi @@ -97,5 +97,10 @@ clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_OSTM2, RZA2M_CLK_P1C)>; status = "disabled"; }; + + pinctrl: pin-controller@fcffe000 { + compatible = "renesas,rza2m-pinctrl"; + reg = <0xfcffe000 0x1000>; + }; }; }; diff --git a/dts/bindings/pinctrl/renesas,rza2m-pinctrl.yaml b/dts/bindings/pinctrl/renesas,rza2m-pinctrl.yaml new file mode 100644 index 00000000000..a9fb8aeebb2 --- /dev/null +++ b/dts/bindings/pinctrl/renesas,rza2m-pinctrl.yaml @@ -0,0 +1,59 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + Renesas RZ/A2M pin controller + + The Renesas RZ/A2M pin controller is a node responsible for controlling + pin function selection and pin properties, such as routing the TX and RX of UART4 + to pin 0 and pin 1 of port 9. + + #include + example_pins: device_pin { + device-pinmux { + pinmux = , /* TXD */ + ; /* RXD */ + }; + }; + +compatible: "renesas,rza2m-pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + This RZA2M pins mux/cfg nodes description. + + child-binding: + description: | + The RZA2M pinmux/pincfg configuration nodes description. + + include: + - name: pincfg-node.yaml + + properties: + pinmux: + type: array + required: true + description: | + Pinmux configuration node. + Values are constructed from GPIO port number, pin number, and + alternate function configuration number using the RZA2M_PINMUX() + helper macro in pinctrl-rza2m.h + + drive-strength: + type: int + enum: + - 0 # 2 mA + - 1 # 8 mA + - 2 # 12 mA + description: | + The DSCR register controls driving ability of the ports. + The PCKIO register controls driving ability of the CKIO pin. + The PSDMMC(0/1/2) registers specify the driving ability of the pins of the SD/MMC. + The PSPIBSC register specifies the driving ability of the pins + of the SPI multi I/O bus controller. diff --git a/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rza2m.h b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rza2m.h new file mode 100644 index 00000000000..37468be63f0 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rza2m.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZA2M_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZA2M_H_ + +#define RZA2M_PIN_NUM_IN_PORT 8 + +/* Port names as labeled in the Hardware Manual */ +#define PORT_00 0 +#define PORT_01 1 +#define PORT_02 2 +#define PORT_03 3 +#define PORT_04 4 +#define PORT_05 5 +#define PORT_06 6 +#define PORT_07 7 +#define PORT_08 8 +#define PORT_09 9 +#define PORT_A 10 +#define PORT_B 11 +#define PORT_C 12 +#define PORT_D 13 +#define PORT_E 14 +#define PORT_F 15 +#define PORT_G 16 +#define PORT_H 17 +/* No I */ +#define PORT_J 18 +#define PORT_K 19 +#define PORT_L 20 +#define PORT_M 21 /* Pins PM_0/1 are labeled JP_0/1 in HW manual */ + +#define PORT_CKIO 22 +#define PORT_PPOC 23 /* Select between 1.8V and 3.3V for SPI and SD/MMC */ + +#define PIN_POSEL 0 /* Sets function for POSEL0 bits. 00, 01, 10 - 1.8v, 11 - 3.3v */ +#define PIN_POC2 1 /* Sets function for SSD host 0, 0 - 1.8v 1 - 3.3v */ +#define PIN_POC3 2 /* Sets function for SSD host 1, 0 - 1.8v 1 - 3.3v */ + +/* + * Create the pin index from its bank and position numbers and store in + * the upper 16 bits the alternate function identifier + */ +#define RZA2M_PINMUX(b, p, f) ((b) * RZA2M_PIN_NUM_IN_PORT + (p) | (f << 16)) + +#define CKIO_DRV RZA2M_PINMUX(PORT_CKIO, 0, 0) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZA2M_H_ */ diff --git a/soc/renesas/rz/rza2m/pinctrl_soc.h b/soc/renesas/rz/rza2m/pinctrl_soc.h new file mode 100644 index 00000000000..e8673745828 --- /dev/null +++ b/soc/renesas/rz/rza2m/pinctrl_soc.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef ZEPHYR_SOC_RENESAS_RZA2M_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RZA2M_PINCTRL_SOC_H_ + +#include + +typedef struct pinctrl_soc_pin { + uint8_t port; + uint8_t pin; + uint8_t func; + uint8_t drive_strength; +} pinctrl_soc_pin_t; + +#define RZA2M_PINS_PER_PORT 8 + +#define RZA2M_MUX_FUNC_MAX (BIT(0) | BIT(1) | BIT(2)) +#define RZA2M_FUNC_GPIO_INPUT BIT(3) /* Pin as input */ +#define RZA2M_FUNC_GPIO_OUTPUT BIT(4) /* Pin as output */ +#define RZA2M_FUNC_GPIO_INT_EN BIT(5) /* Enable interrupt for gpio */ +#define RZA2M_FUNC_GPIO_INT_DIS BIT(6) /* Disable interrupt for gpio */ +#define RZA2M_FUNC_GPIO_HIZ BIT(7) /* Hi-Z mode */ +/* + * Use 16 lower bits [15:0] for pin identifier + * Use 16 higher bits [31:16] for pin mux function + */ +#define RZA2M_MUX_PIN_ID_MASK GENMASK(15, 0) +#define RZA2M_MUX_FUNC_MASK GENMASK(31, 16) +#define RZA2M_MUX_FUNC_OFFS 16 +#define RZA2M_FUNC(prop) ((prop & RZA2M_MUX_FUNC_MASK) >> RZA2M_MUX_FUNC_OFFS) +#define RZA2M_PINCODE(prop) (prop & RZA2M_MUX_PIN_ID_MASK) +#define RZA2M_PORT(prop) ((RZA2M_PINCODE(prop)) / RZA2M_PINS_PER_PORT) +#define RZA2M_PIN(prop) ((RZA2M_PINCODE(prop)) % RZA2M_PINS_PER_PORT) + +#define Z_PINCTRL_PINMUX_INIT(node_id, state_prop, idx) \ + { \ + .port = RZA2M_PORT(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ + .pin = RZA2M_PIN(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ + .func = RZA2M_FUNC(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ + .drive_strength = DT_PROP_OR(node_id, drive_strength, 0), \ + }, + +#define Z_PINCTRL_STATE_PIN_CHILD_INIT(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, pinmux), \ + (DT_FOREACH_PROP_ELEM(node_id, pinmux, Z_PINCTRL_PINMUX_INIT)), \ + ()) + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, state_prop, idx) \ + DT_FOREACH_CHILD(DT_PHANDLE_BY_IDX(node_id, state_prop, idx), \ + Z_PINCTRL_STATE_PIN_CHILD_INIT) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_PROP_ELEM_SEP(node_id, prop, Z_PINCTRL_STATE_PIN_INIT, ())}; + +#endif /* ZEPHYR_SOC_RENESAS_RZA2M_PINCTRL_SOC_H_ */