Commit 654c293e authored by Biju Das's avatar Biju Das Committed by Lee Jones

mfd: Add Renesas RZ/G2L MTU3a core driver

The RZ/G2L multi-function timer pulse unit 3 (MTU3a) is embedded in
the Renesas RZ/G2L family SoCs. It consists of eight 16-bit timer
channels and one 32-bit timer channel. It supports the following
functions
 - Counter
 - Timer
 - PWM

The 8/16/32 bit registers are mixed in each channel.

Add MTU3a core driver for RZ/G2L SoC. The core driver shares the
clk and channel register access for the other child devices like
Counter, PWM and Clock event.
Signed-off-by: default avatarBiju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: default avatarLee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230330111632.169434-3-biju.das.jz@bp.renesas.com
parent 0a9d6b54
......@@ -1315,6 +1315,16 @@ config MFD_SC27XX_PMIC
This driver provides common support for accessing the SC27xx PMICs,
and it also adds the irq_chip parts for handling the PMIC chip events.
config RZ_MTU3
bool "Renesas RZ/G2L MTU3a core driver"
depends on (ARCH_RZG2L && OF) || COMPILE_TEST
help
Select this option to enable Renesas RZ/G2L MTU3a core driver for
the Multi-Function Timer Pulse Unit 3 (MTU3a) hardware available
on SoCs from Renesas. The core driver shares the clk and channel
register access for the other child devices like Counter, PWM,
Clock Source, and Clock event.
config ABX500_CORE
bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
depends on ARCH_U8500 || COMPILE_TEST
......
......@@ -174,6 +174,7 @@ pcf50633-objs := pcf50633-core.o pcf50633-irq.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
obj-$(CONFIG_RZ_MTU3) += rz-mtu3.o
obj-$(CONFIG_ABX500_CORE) += abx500-core.o
obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
# ab8500-core need to come after db8500-prcmu (which provides the channel)
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* MFD internals for Renesas RZ/G2L MTU3 Core driver
*
* Copyright (C) 2023 Renesas Electronics Corporation
*/
#ifndef RZ_MTU3_MFD_H
#define RZ_MTU3_MFD_H
#define MTU_8BIT_CH_0(_tier, _nfcr, _tcr, _tcr2, _tmdr1, _tiorh, _tiorl, _tbtm) \
{ \
[RZ_MTU3_TIER] = _tier, \
[RZ_MTU3_NFCR] = _nfcr, \
[RZ_MTU3_TCR] = _tcr, \
[RZ_MTU3_TCR2] = _tcr2, \
[RZ_MTU3_TMDR1] = _tmdr1, \
[RZ_MTU3_TIORH] = _tiorh, \
[RZ_MTU3_TIORL] = _tiorl, \
[RZ_MTU3_TBTM] = _tbtm \
}
#define MTU_8BIT_CH_1_2(_tier, _nfcr, _tsr, _tcr, _tcr2, _tmdr1, _tior) \
{ \
[RZ_MTU3_TIER] = _tier, \
[RZ_MTU3_NFCR] = _nfcr, \
[RZ_MTU3_TSR] = _tsr, \
[RZ_MTU3_TCR] = _tcr, \
[RZ_MTU3_TCR2] = _tcr2, \
[RZ_MTU3_TMDR1] = _tmdr1, \
[RZ_MTU3_TIOR] = _tior \
} \
#define MTU_8BIT_CH_3_4_6_7(_tier, _nfcr, _tsr, _tcr, _tcr2, _tmdr1, _tiorh, _tiorl, _tbtm) \
{ \
[RZ_MTU3_TIER] = _tier, \
[RZ_MTU3_NFCR] = _nfcr, \
[RZ_MTU3_TSR] = _tsr, \
[RZ_MTU3_TCR] = _tcr, \
[RZ_MTU3_TCR2] = _tcr2, \
[RZ_MTU3_TMDR1] = _tmdr1, \
[RZ_MTU3_TIORH] = _tiorh, \
[RZ_MTU3_TIORL] = _tiorl, \
[RZ_MTU3_TBTM] = _tbtm \
} \
#define MTU_8BIT_CH_5(_tier, _nfcr, _tstr, _tcntcmpclr, _tcru, _tcr2u, _tioru, \
_tcrv, _tcr2v, _tiorv, _tcrw, _tcr2w, _tiorw) \
{ \
[RZ_MTU3_TIER] = _tier, \
[RZ_MTU3_NFCR] = _nfcr, \
[RZ_MTU3_TSTR] = _tstr, \
[RZ_MTU3_TCNTCMPCLR] = _tcntcmpclr, \
[RZ_MTU3_TCRU] = _tcru, \
[RZ_MTU3_TCR2U] = _tcr2u, \
[RZ_MTU3_TIORU] = _tioru, \
[RZ_MTU3_TCRV] = _tcrv, \
[RZ_MTU3_TCR2V] = _tcr2v, \
[RZ_MTU3_TIORV] = _tiorv, \
[RZ_MTU3_TCRW] = _tcrw, \
[RZ_MTU3_TCR2W] = _tcr2w, \
[RZ_MTU3_TIORW] = _tiorw \
} \
#define MTU_8BIT_CH_8(_tier, _nfcr, _tcr, _tcr2, _tmdr1, _tiorh, _tiorl) \
{ \
[RZ_MTU3_TIER] = _tier, \
[RZ_MTU3_NFCR] = _nfcr, \
[RZ_MTU3_TCR] = _tcr, \
[RZ_MTU3_TCR2] = _tcr2, \
[RZ_MTU3_TMDR1] = _tmdr1, \
[RZ_MTU3_TIORH] = _tiorh, \
[RZ_MTU3_TIORL] = _tiorl \
} \
#define MTU_16BIT_CH_0(_tcnt, _tgra, _tgrb, _tgrc, _tgrd, _tgre, _tgrf) \
{ \
[RZ_MTU3_TCNT] = _tcnt, \
[RZ_MTU3_TGRA] = _tgra, \
[RZ_MTU3_TGRB] = _tgrb, \
[RZ_MTU3_TGRC] = _tgrc, \
[RZ_MTU3_TGRD] = _tgrd, \
[RZ_MTU3_TGRE] = _tgre, \
[RZ_MTU3_TGRF] = _tgrf \
}
#define MTU_16BIT_CH_1_2(_tcnt, _tgra, _tgrb) \
{ \
[RZ_MTU3_TCNT] = _tcnt, \
[RZ_MTU3_TGRA] = _tgra, \
[RZ_MTU3_TGRB] = _tgrb \
}
#define MTU_16BIT_CH_3_6(_tcnt, _tgra, _tgrb, _tgrc, _tgrd, _tgre) \
{ \
[RZ_MTU3_TCNT] = _tcnt, \
[RZ_MTU3_TGRA] = _tgra, \
[RZ_MTU3_TGRB] = _tgrb, \
[RZ_MTU3_TGRC] = _tgrc, \
[RZ_MTU3_TGRD] = _tgrd, \
[RZ_MTU3_TGRE] = _tgre \
}
#define MTU_16BIT_CH_4_7(_tcnt, _tgra, _tgrb, _tgrc, _tgrd, _tgre, _tgrf, \
_tadcr, _tadcora, _tadcorb, _tadcobra, _tadcobrb) \
{ \
[RZ_MTU3_TCNT] = _tcnt, \
[RZ_MTU3_TGRA] = _tgra, \
[RZ_MTU3_TGRB] = _tgrb, \
[RZ_MTU3_TGRC] = _tgrc, \
[RZ_MTU3_TGRD] = _tgrd, \
[RZ_MTU3_TGRE] = _tgre, \
[RZ_MTU3_TGRF] = _tgrf, \
[RZ_MTU3_TADCR] = _tadcr, \
[RZ_MTU3_TADCORA] = _tadcora, \
[RZ_MTU3_TADCORB] = _tadcorb, \
[RZ_MTU3_TADCOBRA] = _tadcobra, \
[RZ_MTU3_TADCOBRB] = _tadcobrb \
}
#define MTU_16BIT_CH_5(_tcntu, _tgru, _tcntv, _tgrv, _tcntw, _tgrw) \
{ \
[RZ_MTU3_TCNTU] = _tcntu, \
[RZ_MTU3_TGRU] = _tgru, \
[RZ_MTU3_TCNTV] = _tcntv, \
[RZ_MTU3_TGRV] = _tgrv, \
[RZ_MTU3_TCNTW] = _tcntw, \
[RZ_MTU3_TGRW] = _tgrw \
}
#define MTU_32BIT_CH_1(_tcntlw, _tgralw, _tgrblw) \
{ \
[RZ_MTU3_TCNTLW] = _tcntlw, \
[RZ_MTU3_TGRALW] = _tgralw, \
[RZ_MTU3_TGRBLW] = _tgrblw \
}
#define MTU_32BIT_CH_8(_tcnt, _tgra, _tgrb, _tgrc, _tgrd) \
{ \
[RZ_MTU3_TCNT] = _tcnt, \
[RZ_MTU3_TGRA] = _tgra, \
[RZ_MTU3_TGRB] = _tgrb, \
[RZ_MTU3_TGRC] = _tgrc, \
[RZ_MTU3_TGRD] = _tgrd \
}
#endif
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2022 Renesas Electronics Corporation
*/
#ifndef __MFD_RZ_MTU3_H__
#define __MFD_RZ_MTU3_H__
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/mutex.h>
/* 8-bit shared register offsets macros */
#define RZ_MTU3_TSTRA 0x080 /* Timer start register A */
#define RZ_MTU3_TSTRB 0x880 /* Timer start register B */
/* 16-bit shared register offset macros */
#define RZ_MTU3_TDDRA 0x016 /* Timer dead time data register A */
#define RZ_MTU3_TDDRB 0x816 /* Timer dead time data register B */
#define RZ_MTU3_TCDRA 0x014 /* Timer cycle data register A */
#define RZ_MTU3_TCDRB 0x814 /* Timer cycle data register B */
#define RZ_MTU3_TCBRA 0x022 /* Timer cycle buffer register A */
#define RZ_MTU3_TCBRB 0x822 /* Timer cycle buffer register B */
#define RZ_MTU3_TCNTSA 0x020 /* Timer subcounter A */
#define RZ_MTU3_TCNTSB 0x820 /* Timer subcounter B */
/*
* MTU5 contains 3 timer counter registers and is totaly different
* from other channels, so we must separate its offset
*/
/* 8-bit register offset macros of MTU3 channels except MTU5 */
#define RZ_MTU3_TIER 0 /* Timer interrupt register */
#define RZ_MTU3_NFCR 1 /* Noise filter control register */
#define RZ_MTU3_TSR 2 /* Timer status register */
#define RZ_MTU3_TCR 3 /* Timer control register */
#define RZ_MTU3_TCR2 4 /* Timer control register 2 */
/* Timer mode register 1 */
#define RZ_MTU3_TMDR1 5
#define RZ_MTU3_TMDR1_MD GENMASK(3, 0)
#define RZ_MTU3_TMDR1_MD_NORMAL FIELD_PREP(RZ_MTU3_TMDR1_MD, 0)
#define RZ_MTU3_TMDR1_MD_PWMMODE1 FIELD_PREP(RZ_MTU3_TMDR1_MD, 2)
#define RZ_MTU3_TIOR 6 /* Timer I/O control register */
#define RZ_MTU3_TIORH 6 /* Timer I/O control register H */
#define RZ_MTU3_TIORL 7 /* Timer I/O control register L */
/* Only MTU3/4/6/7 have TBTM registers */
#define RZ_MTU3_TBTM 8 /* Timer buffer operation transfer mode register */
/* 8-bit MTU5 register offset macros */
#define RZ_MTU3_TSTR 2 /* MTU5 Timer start register */
#define RZ_MTU3_TCNTCMPCLR 3 /* MTU5 Timer compare match clear register */
#define RZ_MTU3_TCRU 4 /* Timer control register U */
#define RZ_MTU3_TCR2U 5 /* Timer control register 2U */
#define RZ_MTU3_TIORU 6 /* Timer I/O control register U */
#define RZ_MTU3_TCRV 7 /* Timer control register V */
#define RZ_MTU3_TCR2V 8 /* Timer control register 2V */
#define RZ_MTU3_TIORV 9 /* Timer I/O control register V */
#define RZ_MTU3_TCRW 10 /* Timer control register W */
#define RZ_MTU3_TCR2W 11 /* Timer control register 2W */
#define RZ_MTU3_TIORW 12 /* Timer I/O control register W */
/* 16-bit register offset macros of MTU3 channels except MTU5 */
#define RZ_MTU3_TCNT 0 /* Timer counter */
#define RZ_MTU3_TGRA 1 /* Timer general register A */
#define RZ_MTU3_TGRB 2 /* Timer general register B */
#define RZ_MTU3_TGRC 3 /* Timer general register C */
#define RZ_MTU3_TGRD 4 /* Timer general register D */
#define RZ_MTU3_TGRE 5 /* Timer general register E */
#define RZ_MTU3_TGRF 6 /* Timer general register F */
/* Timer A/D converter start request registers */
#define RZ_MTU3_TADCR 7 /* control register */
#define RZ_MTU3_TADCORA 8 /* cycle set register A */
#define RZ_MTU3_TADCORB 9 /* cycle set register B */
#define RZ_MTU3_TADCOBRA 10 /* cycle set buffer register A */
#define RZ_MTU3_TADCOBRB 11 /* cycle set buffer register B */
/* 16-bit MTU5 register offset macros */
#define RZ_MTU3_TCNTU 0 /* MTU5 Timer counter U */
#define RZ_MTU3_TGRU 1 /* MTU5 Timer general register U */
#define RZ_MTU3_TCNTV 2 /* MTU5 Timer counter V */
#define RZ_MTU3_TGRV 3 /* MTU5 Timer general register V */
#define RZ_MTU3_TCNTW 4 /* MTU5 Timer counter W */
#define RZ_MTU3_TGRW 5 /* MTU5 Timer general register W */
/* 32-bit register offset */
#define RZ_MTU3_TCNTLW 0 /* Timer longword counter */
#define RZ_MTU3_TGRALW 1 /* Timer longword general register A */
#define RZ_MTU3_TGRBLW 2 /* Timer longowrd general register B */
#define RZ_MTU3_TMDR3 0x191 /* MTU1 Timer Mode Register 3 */
/* Macros for setting registers */
#define RZ_MTU3_TCR_CCLR GENMASK(7, 5)
#define RZ_MTU3_TCR_CKEG GENMASK(4, 3)
#define RZ_MTU3_TCR_TPCS GENMASK(2, 0)
#define RZ_MTU3_TCR_CCLR_TGRA BIT(5)
#define RZ_MTU3_TCR_CCLR_TGRC FIELD_PREP(RZ_MTU3_TCR_CCLR, 5)
#define RZ_MTU3_TCR_CKEG_RISING FIELD_PREP(RZ_MTU3_TCR_CKEG, 0)
#define RZ_MTU3_TIOR_IOB GENMASK(7, 4)
#define RZ_MTU3_TIOR_IOA GENMASK(3, 0)
#define RZ_MTU3_TIOR_OC_RETAIN 0
#define RZ_MTU3_TIOR_OC_INIT_OUT_LO_HI_OUT 2
#define RZ_MTU3_TIOR_OC_INIT_OUT_HI_TOGGLE_OUT 7
#define RZ_MTU3_TIOR_OC_IOA_H_COMP_MATCH \
FIELD_PREP(RZ_MTU3_TIOR_IOA, RZ_MTU3_TIOR_OC_INIT_OUT_LO_HI_OUT)
#define RZ_MTU3_TIOR_OC_IOB_TOGGLE \
FIELD_PREP(RZ_MTU3_TIOR_IOB, RZ_MTU3_TIOR_OC_INIT_OUT_HI_TOGGLE_OUT)
enum rz_mtu3_channels {
RZ_MTU3_CHAN_0,
RZ_MTU3_CHAN_1,
RZ_MTU3_CHAN_2,
RZ_MTU3_CHAN_3,
RZ_MTU3_CHAN_4,
RZ_MTU3_CHAN_5,
RZ_MTU3_CHAN_6,
RZ_MTU3_CHAN_7,
RZ_MTU3_CHAN_8,
RZ_MTU_NUM_CHANNELS
};
/**
* struct rz_mtu3_channel - MTU3 channel private data
*
* @dev: device handle
* @channel_number: channel number
* @lock: Lock to protect channel state
* @is_busy: channel state
*/
struct rz_mtu3_channel {
struct device *dev;
unsigned int channel_number;
struct mutex lock;
bool is_busy;
};
/**
* struct rz_mtu3 - MTU3 core private data
*
* @clk: MTU3 module clock
* @rz_mtu3_channel: HW channels
* @priv_data: MTU3 core driver private data
*/
struct rz_mtu3 {
struct clk *clk;
struct rz_mtu3_channel channels[RZ_MTU_NUM_CHANNELS];
void *priv_data;
};
#if IS_ENABLED(CONFIG_RZ_MTU3)
static inline bool rz_mtu3_request_channel(struct rz_mtu3_channel *ch)
{
mutex_lock(&ch->lock);
if (ch->is_busy) {
mutex_unlock(&ch->lock);
return false;
}
ch->is_busy = true;
mutex_unlock(&ch->lock);
return true;
}
static inline void rz_mtu3_release_channel(struct rz_mtu3_channel *ch)
{
mutex_lock(&ch->lock);
ch->is_busy = false;
mutex_unlock(&ch->lock);
}
bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch);
void rz_mtu3_disable(struct rz_mtu3_channel *ch);
int rz_mtu3_enable(struct rz_mtu3_channel *ch);
u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 off);
u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 off);
u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 off);
u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 off);
void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u8 val);
void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u16 val);
void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u32 val);
void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 off, u16 val);
void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch, u16 off,
u16 pos, u8 val);
#else
static inline bool rz_mtu3_request_channel(struct rz_mtu3_channel *ch)
{
return false;
}
static inline void rz_mtu3_release_channel(struct rz_mtu3_channel *ch)
{
}
static inline bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch)
{
return false;
}
static inline void rz_mtu3_disable(struct rz_mtu3_channel *ch)
{
}
static inline int rz_mtu3_enable(struct rz_mtu3_channel *ch)
{
return 0;
}
static inline u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 off)
{
return 0;
}
static inline u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 off)
{
return 0;
}
static inline u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 off)
{
return 0;
}
static inline u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 off)
{
return 0;
}
static inline void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u8 val)
{
}
static inline void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u16 val)
{
}
static inline void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u32 val)
{
}
static inline void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 off, u16 val)
{
}
static inline void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch,
u16 off, u16 pos, u8 val)
{
}
#endif
#endif /* __MFD_RZ_MTU3_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment