162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Renesas RZ/G2L MTU3a PWM Timer driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2023 Renesas Electronics Corporation
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Hardware manual for this IP can be found here
862306a36Sopenharmony_ci * https://www.renesas.com/eu/en/document/mah/rzg2l-group-rzg2lc-group-users-manual-hardware-0?language=en
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Limitations:
1162306a36Sopenharmony_ci * - When PWM is disabled, the output is driven to Hi-Z.
1262306a36Sopenharmony_ci * - While the hardware supports both polarities, the driver (for now)
1362306a36Sopenharmony_ci *   only handles normal polarity.
1462306a36Sopenharmony_ci * - HW uses one counter and two match components to configure duty_cycle
1562306a36Sopenharmony_ci *   and period.
1662306a36Sopenharmony_ci * - Multi-Function Timer Pulse Unit (a.k.a MTU) has 7 HW channels for PWM
1762306a36Sopenharmony_ci *   operations. (The channels are MTU{0..4, 6, 7}.)
1862306a36Sopenharmony_ci * - MTU{1, 2} channels have a single IO, whereas all other HW channels have
1962306a36Sopenharmony_ci *   2 IOs.
2062306a36Sopenharmony_ci * - Each IO is modelled as an independent PWM channel.
2162306a36Sopenharmony_ci * - rz_mtu3_channel_io_map table is used to map the PWM channel to the
2262306a36Sopenharmony_ci *   corresponding HW channel as there are difference in number of IOs
2362306a36Sopenharmony_ci *   between HW channels.
2462306a36Sopenharmony_ci */
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#include <linux/bitfield.h>
2762306a36Sopenharmony_ci#include <linux/clk.h>
2862306a36Sopenharmony_ci#include <linux/limits.h>
2962306a36Sopenharmony_ci#include <linux/mfd/rz-mtu3.h>
3062306a36Sopenharmony_ci#include <linux/module.h>
3162306a36Sopenharmony_ci#include <linux/platform_device.h>
3262306a36Sopenharmony_ci#include <linux/pm_runtime.h>
3362306a36Sopenharmony_ci#include <linux/pwm.h>
3462306a36Sopenharmony_ci#include <linux/time.h>
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define RZ_MTU3_MAX_PWM_CHANNELS	12
3762306a36Sopenharmony_ci#define RZ_MTU3_MAX_HW_CHANNELS		7
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/**
4062306a36Sopenharmony_ci * struct rz_mtu3_channel_io_map - MTU3 pwm channel map
4162306a36Sopenharmony_ci *
4262306a36Sopenharmony_ci * @base_pwm_number: First PWM of a channel
4362306a36Sopenharmony_ci * @num_channel_ios: number of IOs on the HW channel.
4462306a36Sopenharmony_ci */
4562306a36Sopenharmony_cistruct rz_mtu3_channel_io_map {
4662306a36Sopenharmony_ci	u8 base_pwm_number;
4762306a36Sopenharmony_ci	u8 num_channel_ios;
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/**
5162306a36Sopenharmony_ci * struct rz_mtu3_pwm_channel - MTU3 pwm channel data
5262306a36Sopenharmony_ci *
5362306a36Sopenharmony_ci * @mtu: MTU3 channel data
5462306a36Sopenharmony_ci * @map: MTU3 pwm channel map
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_cistruct rz_mtu3_pwm_channel {
5762306a36Sopenharmony_ci	struct rz_mtu3_channel *mtu;
5862306a36Sopenharmony_ci	const struct rz_mtu3_channel_io_map *map;
5962306a36Sopenharmony_ci};
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/**
6262306a36Sopenharmony_ci * struct rz_mtu3_pwm_chip - MTU3 pwm private data
6362306a36Sopenharmony_ci *
6462306a36Sopenharmony_ci * @chip: MTU3 pwm chip data
6562306a36Sopenharmony_ci * @clk: MTU3 module clock
6662306a36Sopenharmony_ci * @lock: Lock to prevent concurrent access for usage count
6762306a36Sopenharmony_ci * @rate: MTU3 clock rate
6862306a36Sopenharmony_ci * @user_count: MTU3 usage count
6962306a36Sopenharmony_ci * @enable_count: MTU3 enable count
7062306a36Sopenharmony_ci * @prescale: MTU3 prescale
7162306a36Sopenharmony_ci * @channel_data: MTU3 pwm channel data
7262306a36Sopenharmony_ci */
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistruct rz_mtu3_pwm_chip {
7562306a36Sopenharmony_ci	struct pwm_chip chip;
7662306a36Sopenharmony_ci	struct clk *clk;
7762306a36Sopenharmony_ci	struct mutex lock;
7862306a36Sopenharmony_ci	unsigned long rate;
7962306a36Sopenharmony_ci	u32 user_count[RZ_MTU3_MAX_HW_CHANNELS];
8062306a36Sopenharmony_ci	u32 enable_count[RZ_MTU3_MAX_HW_CHANNELS];
8162306a36Sopenharmony_ci	u8 prescale[RZ_MTU3_MAX_HW_CHANNELS];
8262306a36Sopenharmony_ci	struct rz_mtu3_pwm_channel channel_data[RZ_MTU3_MAX_HW_CHANNELS];
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/*
8662306a36Sopenharmony_ci * The MTU channels are {0..4, 6, 7} and the number of IO on MTU1
8762306a36Sopenharmony_ci * and MTU2 channel is 1 compared to 2 on others.
8862306a36Sopenharmony_ci */
8962306a36Sopenharmony_cistatic const struct rz_mtu3_channel_io_map channel_map[] = {
9062306a36Sopenharmony_ci	{ 0, 2 }, { 2, 1 }, { 3, 1 }, { 4, 2 }, { 6, 2 }, { 8, 2 }, { 10, 2 }
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic inline struct rz_mtu3_pwm_chip *to_rz_mtu3_pwm_chip(struct pwm_chip *chip)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	return container_of(chip, struct rz_mtu3_pwm_chip, chip);
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic void rz_mtu3_pwm_read_tgr_registers(struct rz_mtu3_pwm_channel *priv,
9962306a36Sopenharmony_ci					   u16 reg_pv_offset, u16 *pv_val,
10062306a36Sopenharmony_ci					   u16 reg_dc_offset, u16 *dc_val)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	*pv_val = rz_mtu3_16bit_ch_read(priv->mtu, reg_pv_offset);
10362306a36Sopenharmony_ci	*dc_val = rz_mtu3_16bit_ch_read(priv->mtu, reg_dc_offset);
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic void rz_mtu3_pwm_write_tgr_registers(struct rz_mtu3_pwm_channel *priv,
10762306a36Sopenharmony_ci					    u16 reg_pv_offset, u16 pv_val,
10862306a36Sopenharmony_ci					    u16 reg_dc_offset, u16 dc_val)
10962306a36Sopenharmony_ci{
11062306a36Sopenharmony_ci	rz_mtu3_16bit_ch_write(priv->mtu, reg_pv_offset, pv_val);
11162306a36Sopenharmony_ci	rz_mtu3_16bit_ch_write(priv->mtu, reg_dc_offset, dc_val);
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistatic u8 rz_mtu3_pwm_calculate_prescale(struct rz_mtu3_pwm_chip *rz_mtu3,
11562306a36Sopenharmony_ci					 u64 period_cycles)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	u32 prescaled_period_cycles;
11862306a36Sopenharmony_ci	u8 prescale;
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	/*
12162306a36Sopenharmony_ci	 * Supported prescale values are 1, 4, 16 and 64.
12262306a36Sopenharmony_ci	 * TODO: Support prescale values 2, 8, 32, 256 and 1024.
12362306a36Sopenharmony_ci	 */
12462306a36Sopenharmony_ci	prescaled_period_cycles = period_cycles >> 16;
12562306a36Sopenharmony_ci	if (prescaled_period_cycles >= 16)
12662306a36Sopenharmony_ci		prescale = 3;
12762306a36Sopenharmony_ci	else
12862306a36Sopenharmony_ci		prescale = (fls(prescaled_period_cycles) + 1) / 2;
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	return prescale;
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic struct rz_mtu3_pwm_channel *
13462306a36Sopenharmony_cirz_mtu3_get_channel(struct rz_mtu3_pwm_chip *rz_mtu3_pwm, u32 hwpwm)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	struct rz_mtu3_pwm_channel *priv = rz_mtu3_pwm->channel_data;
13762306a36Sopenharmony_ci	unsigned int ch;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	for (ch = 0; ch < RZ_MTU3_MAX_HW_CHANNELS; ch++, priv++) {
14062306a36Sopenharmony_ci		if (priv->map->base_pwm_number + priv->map->num_channel_ios > hwpwm)
14162306a36Sopenharmony_ci			break;
14262306a36Sopenharmony_ci	}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	return priv;
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic bool rz_mtu3_pwm_is_ch_enabled(struct rz_mtu3_pwm_chip *rz_mtu3_pwm,
14862306a36Sopenharmony_ci				      u32 hwpwm)
14962306a36Sopenharmony_ci{
15062306a36Sopenharmony_ci	struct rz_mtu3_pwm_channel *priv;
15162306a36Sopenharmony_ci	bool is_channel_en;
15262306a36Sopenharmony_ci	u8 val;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	priv = rz_mtu3_get_channel(rz_mtu3_pwm, hwpwm);
15562306a36Sopenharmony_ci	is_channel_en = rz_mtu3_is_enabled(priv->mtu);
15662306a36Sopenharmony_ci	if (!is_channel_en)
15762306a36Sopenharmony_ci		return false;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	if (priv->map->base_pwm_number == hwpwm)
16062306a36Sopenharmony_ci		val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TIORH);
16162306a36Sopenharmony_ci	else
16262306a36Sopenharmony_ci		val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TIORL);
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	return val & RZ_MTU3_TIOR_IOA;
16562306a36Sopenharmony_ci}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic int rz_mtu3_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);
17062306a36Sopenharmony_ci	struct rz_mtu3_pwm_channel *priv;
17162306a36Sopenharmony_ci	bool is_mtu3_channel_available;
17262306a36Sopenharmony_ci	u32 ch;
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);
17562306a36Sopenharmony_ci	ch = priv - rz_mtu3_pwm->channel_data;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	mutex_lock(&rz_mtu3_pwm->lock);
17862306a36Sopenharmony_ci	/*
17962306a36Sopenharmony_ci	 * Each channel must be requested only once, so if the channel
18062306a36Sopenharmony_ci	 * serves two PWMs and the other is already requested, skip over
18162306a36Sopenharmony_ci	 * rz_mtu3_request_channel()
18262306a36Sopenharmony_ci	 */
18362306a36Sopenharmony_ci	if (!rz_mtu3_pwm->user_count[ch]) {
18462306a36Sopenharmony_ci		is_mtu3_channel_available = rz_mtu3_request_channel(priv->mtu);
18562306a36Sopenharmony_ci		if (!is_mtu3_channel_available) {
18662306a36Sopenharmony_ci			mutex_unlock(&rz_mtu3_pwm->lock);
18762306a36Sopenharmony_ci			return -EBUSY;
18862306a36Sopenharmony_ci		}
18962306a36Sopenharmony_ci	}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	rz_mtu3_pwm->user_count[ch]++;
19262306a36Sopenharmony_ci	mutex_unlock(&rz_mtu3_pwm->lock);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	return 0;
19562306a36Sopenharmony_ci}
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_cistatic void rz_mtu3_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
19862306a36Sopenharmony_ci{
19962306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);
20062306a36Sopenharmony_ci	struct rz_mtu3_pwm_channel *priv;
20162306a36Sopenharmony_ci	u32 ch;
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);
20462306a36Sopenharmony_ci	ch = priv - rz_mtu3_pwm->channel_data;
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	mutex_lock(&rz_mtu3_pwm->lock);
20762306a36Sopenharmony_ci	rz_mtu3_pwm->user_count[ch]--;
20862306a36Sopenharmony_ci	if (!rz_mtu3_pwm->user_count[ch])
20962306a36Sopenharmony_ci		rz_mtu3_release_channel(priv->mtu);
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	mutex_unlock(&rz_mtu3_pwm->lock);
21262306a36Sopenharmony_ci}
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_cistatic int rz_mtu3_pwm_enable(struct rz_mtu3_pwm_chip *rz_mtu3_pwm,
21562306a36Sopenharmony_ci			      struct pwm_device *pwm)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	struct rz_mtu3_pwm_channel *priv;
21862306a36Sopenharmony_ci	u32 ch;
21962306a36Sopenharmony_ci	u8 val;
22062306a36Sopenharmony_ci	int rc;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	rc = pm_runtime_resume_and_get(rz_mtu3_pwm->chip.dev);
22362306a36Sopenharmony_ci	if (rc)
22462306a36Sopenharmony_ci		return rc;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);
22762306a36Sopenharmony_ci	ch = priv - rz_mtu3_pwm->channel_data;
22862306a36Sopenharmony_ci	val = RZ_MTU3_TIOR_OC_IOB_TOGGLE | RZ_MTU3_TIOR_OC_IOA_H_COMP_MATCH;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_MD_PWMMODE1);
23162306a36Sopenharmony_ci	if (priv->map->base_pwm_number == pwm->hwpwm)
23262306a36Sopenharmony_ci		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORH, val);
23362306a36Sopenharmony_ci	else
23462306a36Sopenharmony_ci		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORL, val);
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	mutex_lock(&rz_mtu3_pwm->lock);
23762306a36Sopenharmony_ci	if (!rz_mtu3_pwm->enable_count[ch])
23862306a36Sopenharmony_ci		rz_mtu3_enable(priv->mtu);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	rz_mtu3_pwm->enable_count[ch]++;
24162306a36Sopenharmony_ci	mutex_unlock(&rz_mtu3_pwm->lock);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	return 0;
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_cistatic void rz_mtu3_pwm_disable(struct rz_mtu3_pwm_chip *rz_mtu3_pwm,
24762306a36Sopenharmony_ci				struct pwm_device *pwm)
24862306a36Sopenharmony_ci{
24962306a36Sopenharmony_ci	struct rz_mtu3_pwm_channel *priv;
25062306a36Sopenharmony_ci	u32 ch;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);
25362306a36Sopenharmony_ci	ch = priv - rz_mtu3_pwm->channel_data;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	/* Disable output pins of MTU3 channel */
25662306a36Sopenharmony_ci	if (priv->map->base_pwm_number == pwm->hwpwm)
25762306a36Sopenharmony_ci		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORH, RZ_MTU3_TIOR_OC_RETAIN);
25862306a36Sopenharmony_ci	else
25962306a36Sopenharmony_ci		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORL, RZ_MTU3_TIOR_OC_RETAIN);
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	mutex_lock(&rz_mtu3_pwm->lock);
26262306a36Sopenharmony_ci	rz_mtu3_pwm->enable_count[ch]--;
26362306a36Sopenharmony_ci	if (!rz_mtu3_pwm->enable_count[ch])
26462306a36Sopenharmony_ci		rz_mtu3_disable(priv->mtu);
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	mutex_unlock(&rz_mtu3_pwm->lock);
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	pm_runtime_put_sync(rz_mtu3_pwm->chip.dev);
26962306a36Sopenharmony_ci}
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_cistatic int rz_mtu3_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
27262306a36Sopenharmony_ci				 struct pwm_state *state)
27362306a36Sopenharmony_ci{
27462306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);
27562306a36Sopenharmony_ci	int rc;
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	rc = pm_runtime_resume_and_get(chip->dev);
27862306a36Sopenharmony_ci	if (rc)
27962306a36Sopenharmony_ci		return rc;
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	state->enabled = rz_mtu3_pwm_is_ch_enabled(rz_mtu3_pwm, pwm->hwpwm);
28262306a36Sopenharmony_ci	if (state->enabled) {
28362306a36Sopenharmony_ci		struct rz_mtu3_pwm_channel *priv;
28462306a36Sopenharmony_ci		u8 prescale, val;
28562306a36Sopenharmony_ci		u16 dc, pv;
28662306a36Sopenharmony_ci		u64 tmp;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci		priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);
28962306a36Sopenharmony_ci		if (priv->map->base_pwm_number == pwm->hwpwm)
29062306a36Sopenharmony_ci			rz_mtu3_pwm_read_tgr_registers(priv, RZ_MTU3_TGRA, &pv,
29162306a36Sopenharmony_ci						       RZ_MTU3_TGRB, &dc);
29262306a36Sopenharmony_ci		else
29362306a36Sopenharmony_ci			rz_mtu3_pwm_read_tgr_registers(priv, RZ_MTU3_TGRC, &pv,
29462306a36Sopenharmony_ci						       RZ_MTU3_TGRD, &dc);
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci		val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TCR);
29762306a36Sopenharmony_ci		prescale = FIELD_GET(RZ_MTU3_TCR_TPCS, val);
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci		/* With prescale <= 7 and pv <= 0xffff this doesn't overflow. */
30062306a36Sopenharmony_ci		tmp = NSEC_PER_SEC * (u64)pv << (2 * prescale);
30162306a36Sopenharmony_ci		state->period = DIV_ROUND_UP_ULL(tmp, rz_mtu3_pwm->rate);
30262306a36Sopenharmony_ci		tmp = NSEC_PER_SEC * (u64)dc << (2 * prescale);
30362306a36Sopenharmony_ci		state->duty_cycle = DIV_ROUND_UP_ULL(tmp, rz_mtu3_pwm->rate);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci		if (state->duty_cycle > state->period)
30662306a36Sopenharmony_ci			state->duty_cycle = state->period;
30762306a36Sopenharmony_ci	}
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	state->polarity = PWM_POLARITY_NORMAL;
31062306a36Sopenharmony_ci	pm_runtime_put(chip->dev);
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	return 0;
31362306a36Sopenharmony_ci}
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_cistatic u16 rz_mtu3_pwm_calculate_pv_or_dc(u64 period_or_duty_cycle, u8 prescale)
31662306a36Sopenharmony_ci{
31762306a36Sopenharmony_ci	return min(period_or_duty_cycle >> (2 * prescale), (u64)U16_MAX);
31862306a36Sopenharmony_ci}
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_cistatic int rz_mtu3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
32162306a36Sopenharmony_ci			      const struct pwm_state *state)
32262306a36Sopenharmony_ci{
32362306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);
32462306a36Sopenharmony_ci	struct rz_mtu3_pwm_channel *priv;
32562306a36Sopenharmony_ci	u64 period_cycles;
32662306a36Sopenharmony_ci	u64 duty_cycles;
32762306a36Sopenharmony_ci	u8 prescale;
32862306a36Sopenharmony_ci	u16 pv, dc;
32962306a36Sopenharmony_ci	u8 val;
33062306a36Sopenharmony_ci	u32 ch;
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);
33362306a36Sopenharmony_ci	ch = priv - rz_mtu3_pwm->channel_data;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	period_cycles = mul_u64_u32_div(state->period, rz_mtu3_pwm->rate,
33662306a36Sopenharmony_ci					NSEC_PER_SEC);
33762306a36Sopenharmony_ci	prescale = rz_mtu3_pwm_calculate_prescale(rz_mtu3_pwm, period_cycles);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	/*
34062306a36Sopenharmony_ci	 * Prescalar is shared by multiple channels, so prescale can
34162306a36Sopenharmony_ci	 * NOT be modified when there are multiple channels in use with
34262306a36Sopenharmony_ci	 * different settings. Modify prescalar if other PWM is off or handle
34362306a36Sopenharmony_ci	 * it, if current prescale value is less than the one we want to set.
34462306a36Sopenharmony_ci	 */
34562306a36Sopenharmony_ci	if (rz_mtu3_pwm->enable_count[ch] > 1) {
34662306a36Sopenharmony_ci		if (rz_mtu3_pwm->prescale[ch] > prescale)
34762306a36Sopenharmony_ci			return -EBUSY;
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci		prescale = rz_mtu3_pwm->prescale[ch];
35062306a36Sopenharmony_ci	}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	pv = rz_mtu3_pwm_calculate_pv_or_dc(period_cycles, prescale);
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	duty_cycles = mul_u64_u32_div(state->duty_cycle, rz_mtu3_pwm->rate,
35562306a36Sopenharmony_ci				      NSEC_PER_SEC);
35662306a36Sopenharmony_ci	dc = rz_mtu3_pwm_calculate_pv_or_dc(duty_cycles, prescale);
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	/*
35962306a36Sopenharmony_ci	 * If the PWM channel is disabled, make sure to turn on the clock
36062306a36Sopenharmony_ci	 * before writing the register.
36162306a36Sopenharmony_ci	 */
36262306a36Sopenharmony_ci	if (!pwm->state.enabled) {
36362306a36Sopenharmony_ci		int rc;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci		rc = pm_runtime_resume_and_get(chip->dev);
36662306a36Sopenharmony_ci		if (rc)
36762306a36Sopenharmony_ci			return rc;
36862306a36Sopenharmony_ci	}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	val = RZ_MTU3_TCR_CKEG_RISING | prescale;
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	/* Counter must be stopped while updating TCR register */
37362306a36Sopenharmony_ci	if (rz_mtu3_pwm->prescale[ch] != prescale && rz_mtu3_pwm->enable_count[ch])
37462306a36Sopenharmony_ci		rz_mtu3_disable(priv->mtu);
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	if (priv->map->base_pwm_number == pwm->hwpwm) {
37762306a36Sopenharmony_ci		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TCR,
37862306a36Sopenharmony_ci				      RZ_MTU3_TCR_CCLR_TGRA | val);
37962306a36Sopenharmony_ci		rz_mtu3_pwm_write_tgr_registers(priv, RZ_MTU3_TGRA, pv,
38062306a36Sopenharmony_ci						RZ_MTU3_TGRB, dc);
38162306a36Sopenharmony_ci	} else {
38262306a36Sopenharmony_ci		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TCR,
38362306a36Sopenharmony_ci				      RZ_MTU3_TCR_CCLR_TGRC | val);
38462306a36Sopenharmony_ci		rz_mtu3_pwm_write_tgr_registers(priv, RZ_MTU3_TGRC, pv,
38562306a36Sopenharmony_ci						RZ_MTU3_TGRD, dc);
38662306a36Sopenharmony_ci	}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	if (rz_mtu3_pwm->prescale[ch] != prescale) {
38962306a36Sopenharmony_ci		/*
39062306a36Sopenharmony_ci		 * Prescalar is shared by multiple channels, we cache the
39162306a36Sopenharmony_ci		 * prescalar value from first enabled channel and use the same
39262306a36Sopenharmony_ci		 * value for both channels.
39362306a36Sopenharmony_ci		 */
39462306a36Sopenharmony_ci		rz_mtu3_pwm->prescale[ch] = prescale;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci		if (rz_mtu3_pwm->enable_count[ch])
39762306a36Sopenharmony_ci			rz_mtu3_enable(priv->mtu);
39862306a36Sopenharmony_ci	}
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	/* If the PWM is not enabled, turn the clock off again to save power. */
40162306a36Sopenharmony_ci	if (!pwm->state.enabled)
40262306a36Sopenharmony_ci		pm_runtime_put(chip->dev);
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	return 0;
40562306a36Sopenharmony_ci}
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_cistatic int rz_mtu3_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
40862306a36Sopenharmony_ci			     const struct pwm_state *state)
40962306a36Sopenharmony_ci{
41062306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);
41162306a36Sopenharmony_ci	bool enabled = pwm->state.enabled;
41262306a36Sopenharmony_ci	int ret;
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci	if (state->polarity != PWM_POLARITY_NORMAL)
41562306a36Sopenharmony_ci		return -EINVAL;
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	if (!state->enabled) {
41862306a36Sopenharmony_ci		if (enabled)
41962306a36Sopenharmony_ci			rz_mtu3_pwm_disable(rz_mtu3_pwm, pwm);
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci		return 0;
42262306a36Sopenharmony_ci	}
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	mutex_lock(&rz_mtu3_pwm->lock);
42562306a36Sopenharmony_ci	ret = rz_mtu3_pwm_config(chip, pwm, state);
42662306a36Sopenharmony_ci	mutex_unlock(&rz_mtu3_pwm->lock);
42762306a36Sopenharmony_ci	if (ret)
42862306a36Sopenharmony_ci		return ret;
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci	if (!enabled)
43162306a36Sopenharmony_ci		ret = rz_mtu3_pwm_enable(rz_mtu3_pwm, pwm);
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	return ret;
43462306a36Sopenharmony_ci}
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_cistatic const struct pwm_ops rz_mtu3_pwm_ops = {
43762306a36Sopenharmony_ci	.request = rz_mtu3_pwm_request,
43862306a36Sopenharmony_ci	.free = rz_mtu3_pwm_free,
43962306a36Sopenharmony_ci	.get_state = rz_mtu3_pwm_get_state,
44062306a36Sopenharmony_ci	.apply = rz_mtu3_pwm_apply,
44162306a36Sopenharmony_ci	.owner = THIS_MODULE,
44262306a36Sopenharmony_ci};
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistatic int rz_mtu3_pwm_pm_runtime_suspend(struct device *dev)
44562306a36Sopenharmony_ci{
44662306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = dev_get_drvdata(dev);
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	clk_disable_unprepare(rz_mtu3_pwm->clk);
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	return 0;
45162306a36Sopenharmony_ci}
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_cistatic int rz_mtu3_pwm_pm_runtime_resume(struct device *dev)
45462306a36Sopenharmony_ci{
45562306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = dev_get_drvdata(dev);
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	return clk_prepare_enable(rz_mtu3_pwm->clk);
45862306a36Sopenharmony_ci}
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_cistatic DEFINE_RUNTIME_DEV_PM_OPS(rz_mtu3_pwm_pm_ops,
46162306a36Sopenharmony_ci				 rz_mtu3_pwm_pm_runtime_suspend,
46262306a36Sopenharmony_ci				 rz_mtu3_pwm_pm_runtime_resume, NULL);
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_cistatic void rz_mtu3_pwm_pm_disable(void *data)
46562306a36Sopenharmony_ci{
46662306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = data;
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci	clk_rate_exclusive_put(rz_mtu3_pwm->clk);
46962306a36Sopenharmony_ci	pm_runtime_disable(rz_mtu3_pwm->chip.dev);
47062306a36Sopenharmony_ci	pm_runtime_set_suspended(rz_mtu3_pwm->chip.dev);
47162306a36Sopenharmony_ci}
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_cistatic int rz_mtu3_pwm_probe(struct platform_device *pdev)
47462306a36Sopenharmony_ci{
47562306a36Sopenharmony_ci	struct rz_mtu3 *parent_ddata = dev_get_drvdata(pdev->dev.parent);
47662306a36Sopenharmony_ci	struct rz_mtu3_pwm_chip *rz_mtu3_pwm;
47762306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
47862306a36Sopenharmony_ci	unsigned int i, j = 0;
47962306a36Sopenharmony_ci	int ret;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	rz_mtu3_pwm = devm_kzalloc(&pdev->dev, sizeof(*rz_mtu3_pwm), GFP_KERNEL);
48262306a36Sopenharmony_ci	if (!rz_mtu3_pwm)
48362306a36Sopenharmony_ci		return -ENOMEM;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	rz_mtu3_pwm->clk = parent_ddata->clk;
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	for (i = 0; i < RZ_MTU_NUM_CHANNELS; i++) {
48862306a36Sopenharmony_ci		if (i == RZ_MTU3_CHAN_5 || i == RZ_MTU3_CHAN_8)
48962306a36Sopenharmony_ci			continue;
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci		rz_mtu3_pwm->channel_data[j].mtu = &parent_ddata->channels[i];
49262306a36Sopenharmony_ci		rz_mtu3_pwm->channel_data[j].mtu->dev = dev;
49362306a36Sopenharmony_ci		rz_mtu3_pwm->channel_data[j].map = &channel_map[j];
49462306a36Sopenharmony_ci		j++;
49562306a36Sopenharmony_ci	}
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	mutex_init(&rz_mtu3_pwm->lock);
49862306a36Sopenharmony_ci	platform_set_drvdata(pdev, rz_mtu3_pwm);
49962306a36Sopenharmony_ci	ret = clk_prepare_enable(rz_mtu3_pwm->clk);
50062306a36Sopenharmony_ci	if (ret)
50162306a36Sopenharmony_ci		return dev_err_probe(dev, ret, "Clock enable failed\n");
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	clk_rate_exclusive_get(rz_mtu3_pwm->clk);
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci	rz_mtu3_pwm->rate = clk_get_rate(rz_mtu3_pwm->clk);
50662306a36Sopenharmony_ci	/*
50762306a36Sopenharmony_ci	 * Refuse clk rates > 1 GHz to prevent overflow later for computing
50862306a36Sopenharmony_ci	 * period and duty cycle.
50962306a36Sopenharmony_ci	 */
51062306a36Sopenharmony_ci	if (rz_mtu3_pwm->rate > NSEC_PER_SEC) {
51162306a36Sopenharmony_ci		ret = -EINVAL;
51262306a36Sopenharmony_ci		clk_rate_exclusive_put(rz_mtu3_pwm->clk);
51362306a36Sopenharmony_ci		goto disable_clock;
51462306a36Sopenharmony_ci	}
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	pm_runtime_set_active(&pdev->dev);
51762306a36Sopenharmony_ci	pm_runtime_enable(&pdev->dev);
51862306a36Sopenharmony_ci	rz_mtu3_pwm->chip.dev = &pdev->dev;
51962306a36Sopenharmony_ci	ret = devm_add_action_or_reset(&pdev->dev, rz_mtu3_pwm_pm_disable,
52062306a36Sopenharmony_ci				       rz_mtu3_pwm);
52162306a36Sopenharmony_ci	if (ret < 0)
52262306a36Sopenharmony_ci		return ret;
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	rz_mtu3_pwm->chip.ops = &rz_mtu3_pwm_ops;
52562306a36Sopenharmony_ci	rz_mtu3_pwm->chip.npwm = RZ_MTU3_MAX_PWM_CHANNELS;
52662306a36Sopenharmony_ci	ret = devm_pwmchip_add(&pdev->dev, &rz_mtu3_pwm->chip);
52762306a36Sopenharmony_ci	if (ret)
52862306a36Sopenharmony_ci		return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	pm_runtime_idle(&pdev->dev);
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	return 0;
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_cidisable_clock:
53562306a36Sopenharmony_ci	clk_disable_unprepare(rz_mtu3_pwm->clk);
53662306a36Sopenharmony_ci	return ret;
53762306a36Sopenharmony_ci}
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_cistatic struct platform_driver rz_mtu3_pwm_driver = {
54062306a36Sopenharmony_ci	.driver = {
54162306a36Sopenharmony_ci		.name = "pwm-rz-mtu3",
54262306a36Sopenharmony_ci		.pm = pm_ptr(&rz_mtu3_pwm_pm_ops),
54362306a36Sopenharmony_ci	},
54462306a36Sopenharmony_ci	.probe = rz_mtu3_pwm_probe,
54562306a36Sopenharmony_ci};
54662306a36Sopenharmony_cimodule_platform_driver(rz_mtu3_pwm_driver);
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ciMODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
54962306a36Sopenharmony_ciMODULE_ALIAS("platform:pwm-rz-mtu3");
55062306a36Sopenharmony_ciMODULE_DESCRIPTION("Renesas RZ/G2L MTU3a PWM Timer Driver");
55162306a36Sopenharmony_ciMODULE_LICENSE("GPL");
552