Skip to content

Commit

Permalink
drivers: serial: add support of hscif driver for RCar boards
Browse files Browse the repository at this point in the history
commit 448466a upstream

Add support of HSCIF UART driver for Renesas boards.

Signed-off-by: Mykola Kvach <[email protected]>
Acked-by: Dmytro Firsov <[email protected]>
  • Loading branch information
xakep-amatop authored and lorc committed Jul 10, 2024
1 parent 62fa552 commit ee2aa8f
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 41 deletions.
4 changes: 4 additions & 0 deletions drivers/clock_control/clock_control_r8a779f0_cpg_mssr.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,16 @@ static struct cpg_clk_info_table core_props[] = {
RCAR_CORE_CLK_INFO_ITEM(R8A779F0_CLK_SD0H, 0x0870, CLK_SDSRC, RCAR_CPG_NONE),
RCAR_CORE_CLK_INFO_ITEM(R8A779F0_CLK_SD0, 0x0870, R8A779F0_CLK_SD0H, RCAR_CPG_NONE),

RCAR_CORE_CLK_INFO_ITEM(R8A779F0_CLK_SASYNCPERD1, RCAR_CPG_NONE, RCAR_CPG_NONE,
266666666),

RCAR_CORE_CLK_INFO_ITEM(CLK_PLL5, RCAR_CPG_NONE, RCAR_CPG_NONE, RCAR_CPG_MHZ(3200)),
RCAR_CORE_CLK_INFO_ITEM(CLK_SDSRC, 0x08A4, CLK_PLL5, RCAR_CPG_NONE),
};

/* NOTE: the array MUST be sorted by module field */
static struct cpg_clk_info_table mod_props[] = {
RCAR_MOD_CLK_INFO_ITEM(514, R8A779F0_CLK_SASYNCPERD1),
RCAR_MOD_CLK_INFO_ITEM(702, R8A779F0_CLK_S0D12_PER),
RCAR_MOD_CLK_INFO_ITEM(704, R8A779F0_CLK_S0D12_PER),

Expand Down
2 changes: 1 addition & 1 deletion drivers/serial/Kconfig.rcar
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
config UART_RCAR
bool "Renesas R-Car UART Driver"
default y
depends on DT_HAS_RENESAS_RCAR_SCIF_ENABLED
depends on DT_HAS_RENESAS_RCAR_SCIF_ENABLED || DT_HAS_RENESAS_RCAR_HSCIF_ENABLED
select SERIAL_HAS_DRIVER
select SERIAL_SUPPORT_INTERRUPT
help
Expand Down
99 changes: 59 additions & 40 deletions drivers/serial/uart_rcar.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct uart_rcar_cfg {
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
void (*irq_config_func)(const struct device *dev);
#endif
bool is_hscif;
};

struct uart_rcar_data {
Expand All @@ -51,6 +52,7 @@ struct uart_rcar_data {
#define SCLSR 0x24 /* Line Status Register */
#define DL 0x30 /* Frequency Division Register */
#define CKS 0x34 /* Clock Select Register */
#define HSSRR 0x40 /* Sampling Rate Register */

/* SCSMR (Serial Mode Register) */
#define SCSMR_C_A BIT(7) /* Communication Mode */
Expand Down Expand Up @@ -104,6 +106,10 @@ struct uart_rcar_data {
#define SCLSR_TO BIT(2) /* Timeout */
#define SCLSR_ORER BIT(0) /* Overrun Error */

/* HSSRR (Sampling Rate Register) */
#define HSSRR_SRE BIT(15) /* Sampling Rate Register Enable */
#define HSSRR_SRCYC_DEF_VAL 0x7 /* Sampling rate default value */

static uint8_t uart_rcar_read_8(const struct device *dev, uint32_t offs)
{
return sys_read8(DEVICE_MMIO_GET(dev) + offs);
Expand Down Expand Up @@ -131,9 +137,14 @@ static void uart_rcar_set_baudrate(const struct device *dev,
uint32_t baud_rate)
{
struct uart_rcar_data *data = dev->data;
const struct uart_rcar_cfg *cfg = dev->config;
uint8_t reg_val;

reg_val = ((data->clk_rate + 16 * baud_rate) / (32 * baud_rate) - 1);
if (cfg->is_hscif) {
reg_val = data->clk_rate / (2 * (HSSRR_SRCYC_DEF_VAL + 1) * baud_rate) - 1;
} else {
reg_val = ((data->clk_rate + 16 * baud_rate) / (32 * baud_rate) - 1);
}
uart_rcar_write_8(dev, SCBRR, reg_val);
}

Expand Down Expand Up @@ -186,6 +197,7 @@ static int uart_rcar_configure(const struct device *dev,
const struct uart_config *cfg)
{
struct uart_rcar_data *data = dev->data;
const struct uart_rcar_cfg *cfg_drv = dev->config;

uint16_t reg_val;
k_spinlock_key_t key;
Expand Down Expand Up @@ -229,6 +241,11 @@ static int uart_rcar_configure(const struct device *dev,
SCSMR_CKS1 | SCSMR_CKS0);
uart_rcar_write_16(dev, SCSMR, reg_val);

if (cfg_drv->is_hscif) {
/* TODO: calculate the optimal sampling and bit rates based on error rate */
uart_rcar_write_16(dev, HSSRR, HSSRR_SRE | HSSRR_SRCYC_DEF_VAL);
}

/* Set baudrate */
uart_rcar_set_baudrate(dev, cfg->baudrate);

Expand Down Expand Up @@ -523,47 +540,44 @@ static const struct uart_driver_api uart_rcar_driver_api = {
};

/* Device Instantiation */
#define UART_RCAR_DECLARE_CFG(n, IRQ_FUNC_INIT) \
PINCTRL_DT_INST_DEFINE(n); \
static const struct uart_rcar_cfg uart_rcar_cfg_##n = { \
DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
.mod_clk.module = \
DT_INST_CLOCKS_CELL_BY_IDX(n, 0, module), \
.mod_clk.domain = \
DT_INST_CLOCKS_CELL_BY_IDX(n, 0, domain), \
.bus_clk.module = \
DT_INST_CLOCKS_CELL_BY_IDX(n, 1, module), \
.bus_clk.domain = \
DT_INST_CLOCKS_CELL_BY_IDX(n, 1, domain), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
IRQ_FUNC_INIT \
#define UART_RCAR_DECLARE_CFG(n, IRQ_FUNC_INIT, compat) \
PINCTRL_DT_INST_DEFINE(n); \
static const struct uart_rcar_cfg uart_rcar_cfg_##compat##n = { \
DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
.mod_clk.module = DT_INST_CLOCKS_CELL_BY_IDX(n, 0, module), \
.mod_clk.domain = DT_INST_CLOCKS_CELL_BY_IDX(n, 0, domain), \
.bus_clk.module = DT_INST_CLOCKS_CELL_BY_IDX(n, 1, module), \
.bus_clk.domain = DT_INST_CLOCKS_CELL_BY_IDX(n, 1, domain), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
.is_hscif = DT_NODE_HAS_COMPAT(DT_DRV_INST(n), renesas_rcar_hscif), \
IRQ_FUNC_INIT \
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
#define UART_RCAR_CONFIG_FUNC(n) \
static void irq_config_func_##n(const struct device *dev) \
{ \
IRQ_CONNECT(DT_INST_IRQN(n), \
DT_INST_IRQ(n, priority), \
uart_rcar_isr, \
DEVICE_DT_INST_GET(n), 0); \
\
irq_enable(DT_INST_IRQN(n)); \
#define UART_RCAR_CONFIG_FUNC(n, compat) \
static void irq_config_func_##compat##n(const struct device *dev) \
{ \
IRQ_CONNECT(DT_INST_IRQN(n), \
DT_INST_IRQ(n, priority), \
uart_rcar_isr, \
DEVICE_DT_INST_GET(n), 0); \
\
irq_enable(DT_INST_IRQN(n)); \
}
#define UART_RCAR_IRQ_CFG_FUNC_INIT(n) \
.irq_config_func = irq_config_func_##n
#define UART_RCAR_INIT_CFG(n) \
UART_RCAR_DECLARE_CFG(n, UART_RCAR_IRQ_CFG_FUNC_INIT(n))
#define UART_RCAR_IRQ_CFG_FUNC_INIT(n, compat) \
.irq_config_func = irq_config_func_##compat##n
#define UART_RCAR_INIT_CFG(n, compat) \
UART_RCAR_DECLARE_CFG(n, UART_RCAR_IRQ_CFG_FUNC_INIT(n, compat), compat)
#else
#define UART_RCAR_CONFIG_FUNC(n)
#define UART_RCAR_CONFIG_FUNC(n, compat)
#define UART_RCAR_IRQ_CFG_FUNC_INIT
#define UART_RCAR_INIT_CFG(n) \
UART_RCAR_DECLARE_CFG(n, UART_RCAR_IRQ_CFG_FUNC_INIT)
#define UART_RCAR_INIT_CFG(n, compat) \
UART_RCAR_DECLARE_CFG(n, UART_RCAR_IRQ_CFG_FUNC_INIT, compat)
#endif

#define UART_RCAR_INIT(n) \
static struct uart_rcar_data uart_rcar_data_##n = { \
#define UART_RCAR_INIT(n, compat) \
static struct uart_rcar_data uart_rcar_data_##compat##n = { \
.current_config = { \
.baudrate = DT_INST_PROP(n, current_speed), \
.parity = UART_CFG_PARITY_NONE, \
Expand All @@ -573,18 +587,23 @@ static const struct uart_driver_api uart_rcar_driver_api = {
}, \
}; \
\
static const struct uart_rcar_cfg uart_rcar_cfg_##n; \
static const struct uart_rcar_cfg uart_rcar_cfg_##compat##n; \
\
DEVICE_DT_INST_DEFINE(n, \
uart_rcar_init, \
NULL, \
&uart_rcar_data_##n, \
&uart_rcar_cfg_##n, \
&uart_rcar_data_##compat##n, \
&uart_rcar_cfg_##compat##n, \
PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
&uart_rcar_driver_api); \
\
UART_RCAR_CONFIG_FUNC(n) \
UART_RCAR_CONFIG_FUNC(n, compat) \
\
UART_RCAR_INIT_CFG(n);
UART_RCAR_INIT_CFG(n, compat);

DT_INST_FOREACH_STATUS_OKAY_VARGS(UART_RCAR_INIT, DT_DRV_COMPAT)

#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT renesas_rcar_hscif

DT_INST_FOREACH_STATUS_OKAY(UART_RCAR_INIT)
DT_INST_FOREACH_STATUS_OKAY_VARGS(UART_RCAR_INIT, DT_DRV_COMPAT)
18 changes: 18 additions & 0 deletions dts/bindings/serial/renesas,rcar-hscif.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) 2024, EPAM Systems
# SPDX-License-Identifier: Apache-2.0

description: Renesas R-Car HSCIF controller

compatible: "renesas,rcar-hscif"

include: [uart-controller.yaml, pinctrl-device.yaml]

properties:
reg:
required: true

clocks:
required: true

current-speed:
required: true

0 comments on commit ee2aa8f

Please sign in to comment.