drivers: pinctrl: add RZT2M driver

This adds a new driver for Renesas RZ/T2M.
The driver allows configuration of pin direction,
pull up/down resistors, drive strength and slew rate,
and selection of function for a pin.

Signed-off-by: Wojciech Sipak <wsipak@antmicro.com>
This commit is contained in:
Wojciech Sipak 2023-10-04 15:38:30 +02:00 committed by Carles Cufí
parent 4e35d0e354
commit 9e44f59e9a
11 changed files with 287 additions and 1 deletions

View file

@ -5,6 +5,7 @@
*/
/dts-v1/;
#include <dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h>
#include <arm/renesas/rzt2m.dtsi>
/ {
@ -18,10 +19,36 @@
};
};
&pinctrl {
uart0_default: uart0_default {
group1 {
pinmux = <UART0TX_P16_5>;
};
group2 {
pinmux = <UART0RX_P16_6>;
input-enable;
};
};
uart3_default: uart3_default {
group1 {
pinmux = <UART3TX_P18_0>;
};
group2 {
pinmux = <UART3RX_P17_7>;
input-enable;
};
};
};
&uart0 {
status = "okay";
pinctrl-0 = <&uart0_default>;
pinctrl-names = "default";
};
&uart3 {
status = "okay";
pinctrl-0 = <&uart3_default>;
pinctrl-names = "default";
};

View file

@ -37,3 +37,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RA pinctrl_ra.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCU pinctrl_imx_scu.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RZT2M pinctrl_rzt2m.c)

View file

@ -65,5 +65,6 @@ source "drivers/pinctrl/Kconfig.ti_cc32xx"
source "drivers/pinctrl/Kconfig.numaker"
source "drivers/pinctrl/Kconfig.eos_s3"
source "drivers/pinctrl/Kconfig.ra"
source "drivers/pinctrl/Kconfig.rzt2m"
endif # PINCTRL

View file

@ -0,0 +1,9 @@
# Copyright (c) 2023 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: Apache-2.0
config PINCTRL_RZT2M
bool "Renesas RZ/T2M pin controller driver"
default y
depends on DT_HAS_RENESAS_RZT2M_PINCTRL_ENABLED
help
Renesas RZ/T2M pinctrl driver

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 Antmicro <www.antmicro.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT renesas_rzt2m_pinctrl
#include <zephyr/arch/cpu.h>
#include <zephyr/drivers/pinctrl.h>
#include <soc.h>
#define PORT_NSR DT_INST_REG_ADDR_BY_NAME(0, port_nsr)
#define PTADR DT_INST_REG_ADDR_BY_NAME(0, ptadr)
/* Port m mode control register */
#define PMC(port) (PORT_NSR + 0x400 + port)
/* Port m function control register */
#define PFC(port) (PORT_NSR + 0x600 + (0x4 * port))
/* IO Buffer m function switching register */
#define DRCTL(port, pin) (PORT_NSR + 0xa00 + (0x8 * port) + pin)
/* Port m region select register */
#define RSELP(port) (PTADR + port)
#define DRCTL_DRIVE_STRENGTH(val) (val & 0x3)
#define DRCTL_PULL_UP_DOWN(val) ((val & 0x3) << 2)
#define DRCTL_SCHMITT(val) ((val & 0x1) << 4)
#define DRCTL_SLEW_RATE(val) ((val & 0x1) << 5)
#define DRCTL_CONFIG(drive, pull, schmitt, slew) \
(DRCTL_DRIVE_STRENGTH(drive) | DRCTL_PULL_UP_DOWN(pull) | DRCTL_SCHMITT(schmitt) | \
DRCTL_SLEW_RATE(slew))
#define PFC_FUNC_MASK(pin) (0xf << (pin * 4))
static void pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
{
uint8_t rselp = sys_read8(RSELP(pin->port));
uint32_t pfc = sys_read32(PFC(pin->port)) & ~(PFC_FUNC_MASK(pin->pin));
uint8_t pmc = sys_read8(PMC(pin->port));
/* Set proper bit in the RSELP register to use as non-safety domain. */
sys_write8(rselp | BIT(pin->pin), RSELP(pin->port));
sys_write8(DRCTL_CONFIG(
pin->drive_strength, (pin->pull_up == 1 ? 1U : (pin->pull_down == 1 ? 2U : 0)),
pin->schmitt_enable, pin->slew_rate),
DRCTL(pin->port, pin->pin));
/* Select function for the pin. */
sys_write32(pfc | pin->func << (pin->pin * 4), PFC(pin->port));
/* Set proper bit in the PMC register to use the pin as a peripheral IO. */
sys_write8(pmc | BIT(pin->pin), PMC(pin->port));
}
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
{
ARG_UNUSED(reg);
for (uint8_t i = 0U; i < pin_cnt; i++) {
pinctrl_configure_pin(pins++);
}
return 0;
}

View file

@ -7,5 +7,6 @@ config UART_RZT2M
depends on DT_HAS_RENESAS_RZT2M_UART_ENABLED
select SERIAL_HAS_DRIVER
select SERIAL_SUPPORT_INTERRUPT
select PINCTRL
help
Enable Renesas RZ/T2M UART Driver.

View file

@ -8,6 +8,7 @@
#include "zephyr/spinlock.h"
#include "zephyr/sys/printk.h"
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/sys/util.h>
#include <zephyr/irq.h>
#include <stdint.h>
@ -20,6 +21,7 @@ LOG_MODULE_REGISTER(uart_renesas_rzt2m, CONFIG_UART_LOG_LEVEL);
struct rzt2m_device_config {
mm_reg_t base;
const struct pinctrl_dev_config *pin_config;
uart_irq_config_func_t irq_config_func;
};
@ -297,6 +299,12 @@ static int rzt2m_uart_init(const struct device *dev)
*CCR3(config->base) = CCR3_DEFAULT_VALUE;
*CCR4(config->base) = CCR4_DEFAULT_VALUE;
/* Configure pinmuxes */
ret = pinctrl_apply_state(config->pin_config, PINCTRL_STATE_DEFAULT);
if (ret) {
return ret;
}
*CFCLR(config->base) = CFCLR_ALL_FLAG_CLEAR;
*FFCLR(config->base) = FFCLR_MASK_DRC;
@ -414,6 +422,7 @@ static void uart_rzt2m_isr(const struct device *dev)
}
#define UART_RZT2M_INIT(n) \
PINCTRL_DT_INST_DEFINE(n); \
static struct rzt2m_device_data rzt2m_uart_##n##data = { \
.uart_cfg = \
{ \
@ -427,7 +436,9 @@ static void uart_rzt2m_isr(const struct device *dev)
}; \
UART_RZT2M_CONFIG_FUNC(n); \
static const struct rzt2m_device_config rzt2m_uart_##n##_config = { \
.base = DT_INST_REG_ADDR(n), .irq_config_func = uart##n##_rzt2m_irq_config}; \
.base = DT_INST_REG_ADDR(n), \
.irq_config_func = uart##n##_rzt2m_irq_config, \
.pin_config = PINCTRL_DT_INST_DEV_CONFIG_GET(n)}; \
DEVICE_DT_INST_DEFINE(n, &rzt2m_uart_init, NULL, &rzt2m_uart_##n##data, \
&rzt2m_uart_##n##_config, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
&rzt2m_uart_api);

View file

@ -113,5 +113,10 @@
status = "disabled";
};
pinctrl: pinctrl@800a0000 {
compatible = "renesas,rzt2m-pinctrl";
reg = <0x800a0000 0x1000 0x81030c00 0x1000>;
reg-names = "port_nsr", "ptadr";
};
};
};

View file

@ -0,0 +1,93 @@
# Copyright (c) 2023 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: Apache-2.0
description: |
The Renesas RZ/T2M pin controller is a node responsible for controlling
pin function selection and pin properties, such as routing the TX and RX of UART0
to pin 5 and pin 6 of port 16.
The node has the 'pinctrl' node label set in your SoC's devicetree,
so you can modify it like this:
&pinctrl {
/* your modifications go here */
};
All device pin configurations should be placed in child nodes of the
'pinctrl' node, as shown in this example:
/* You can put this in places like a board-pinctrl.dtsi file in
* your board directory, or a devicetree overlay in your application.
*/
/* include pre-defined combinations for the SoC variant used by the board */
#include <dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h>
&pinctrl {
uart0_default: uart0_default {
group1 {
pinmux = <UART0TX_P16_5>;
};
group2 {
pinmux = <UART0RX_P16_6>;
input-enable;
};
};
};
The 'uart0_default' child node encodes the pin configurations for a
particular state of a device; in this case, the default (that is, active)
state.
As shown, pin configurations are organized in groups within each child node.
Each group can specify a list of pin function selections in the 'pinmux'
property.
A group can also specify shared pin properties common to all the specified
pins, such as the 'input-enable' property in group 2.
compatible: "renesas,rzt2m-pinctrl"
include: base.yaml
child-binding:
description: |
Definitions for a pinctrl state.
child-binding:
include:
- name: pincfg-node.yaml
property-allowlist:
- input-enable
- bias-pull-up
- bias-pull-down
- bias-high-impedance
- input-schmitt-enable
properties:
pinmux:
required: true
type: array
description: |
An array of pins sharing the same group properties. Each
element of the array is an integer constructed from the
pin number and the alternative function of the pin.
drive-strength:
type: string
enum:
- "low"
- "middle"
- "high"
- "ultrahigh"
default: "low"
description: |
The drive strength of a pin, relative to full-driver strength.
The default value is "low", which is the reset value.
slew-rate:
type: string
enum:
- "slow"
- "fast"
default: "slow"
description: |
Select slew rate for a pin. The default is slow, which is the reset value.

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2023 Antmicro <www.antmicro.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __RENESAS_RZT2M_PINCTRL_H__
#define __RENESAS_RZT2M_PINCTRL_H__
#define RZT2M_PINMUX(port, pin, func) ((port << 16) | (pin << 8) | func)
#define UART0TX_P16_5 RZT2M_PINMUX(16, 5, 1)
#define UART0RX_P16_6 RZT2M_PINMUX(16, 6, 2)
#define UART3TX_P18_0 RZT2M_PINMUX(18, 0, 4)
#define UART3RX_P17_7 RZT2M_PINMUX(17, 7, 4)
#endif /* __RENESAS_RZT2M_PINCTRL_H__ */

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2023 Antmicro <www.antmicro.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_
#define ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_
#include <zephyr/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct pinctrl_soc_pin_t {
uint32_t port;
uint32_t pin;
uint32_t func;
uint32_t input_enable: 1;
uint32_t output_enable: 1;
uint32_t pull_up: 1;
uint32_t pull_down: 1;
uint32_t high_impedance: 1;
uint32_t slew_rate: 2;
uint8_t drive_strength;
uint32_t schmitt_enable: 1;
} pinctrl_soc_pin_t;
#define RZT2M_GET_PORT(pinctrl) ((pinctrl >> 16) & 0xff)
#define RZT2M_GET_PIN(pinctrl) ((pinctrl >> 8) & 0xff)
#define RZT2M_GET_FUNC(pinctrl) (pinctrl & 0xff)
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \
{ \
.port = RZT2M_GET_PORT(DT_PROP_BY_IDX(node_id, prop, idx)), \
.pin = RZT2M_GET_PIN(DT_PROP_BY_IDX(node_id, prop, idx)), \
.func = RZT2M_GET_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \
.input_enable = DT_PROP(node_id, input_enable), \
.pull_up = DT_PROP(node_id, bias_pull_up), \
.pull_down = DT_PROP(node_id, bias_pull_down), \
.high_impedance = DT_PROP(node_id, bias_high_impedance), \
.slew_rate = DT_ENUM_IDX(node_id, slew_rate), \
.drive_strength = DT_ENUM_IDX(node_id, drive_strength), \
.schmitt_enable = DT_PROP(node_id, input_schmitt_enable), \
},
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
{DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \
DT_FOREACH_PROP_ELEM, pinmux, \
Z_PINCTRL_STATE_PIN_INIT)}
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_ */