brintos

brintos / linux-shallow public Read only

0
0
Text · 14.9 KiB · ab39bd3 Raw
553 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Renesas RZ/G2L MTU3a PWM Timer driver4 *5 * Copyright (C) 2023 Renesas Electronics Corporation6 *7 * Hardware manual for this IP can be found here8 * https://www.renesas.com/eu/en/document/mah/rzg2l-group-rzg2lc-group-users-manual-hardware-0?language=en9 *10 * Limitations:11 * - When PWM is disabled, the output is driven to Hi-Z.12 * - While the hardware supports both polarities, the driver (for now)13 *   only handles normal polarity.14 * - HW uses one counter and two match components to configure duty_cycle15 *   and period.16 * - Multi-Function Timer Pulse Unit (a.k.a MTU) has 7 HW channels for PWM17 *   operations. (The channels are MTU{0..4, 6, 7}.)18 * - MTU{1, 2} channels have a single IO, whereas all other HW channels have19 *   2 IOs.20 * - Each IO is modelled as an independent PWM channel.21 * - rz_mtu3_channel_io_map table is used to map the PWM channel to the22 *   corresponding HW channel as there are difference in number of IOs23 *   between HW channels.24 */25 26#include <linux/bitfield.h>27#include <linux/clk.h>28#include <linux/limits.h>29#include <linux/mfd/rz-mtu3.h>30#include <linux/module.h>31#include <linux/platform_device.h>32#include <linux/pm_runtime.h>33#include <linux/pwm.h>34#include <linux/time.h>35 36#define RZ_MTU3_MAX_PWM_CHANNELS	1237#define RZ_MTU3_MAX_HW_CHANNELS		738 39/**40 * struct rz_mtu3_channel_io_map - MTU3 pwm channel map41 *42 * @base_pwm_number: First PWM of a channel43 * @num_channel_ios: number of IOs on the HW channel.44 */45struct rz_mtu3_channel_io_map {46	u8 base_pwm_number;47	u8 num_channel_ios;48};49 50/**51 * struct rz_mtu3_pwm_channel - MTU3 pwm channel data52 *53 * @mtu: MTU3 channel data54 * @map: MTU3 pwm channel map55 */56struct rz_mtu3_pwm_channel {57	struct rz_mtu3_channel *mtu;58	const struct rz_mtu3_channel_io_map *map;59};60 61/**62 * struct rz_mtu3_pwm_chip - MTU3 pwm private data63 *64 * @clk: MTU3 module clock65 * @lock: Lock to prevent concurrent access for usage count66 * @rate: MTU3 clock rate67 * @user_count: MTU3 usage count68 * @enable_count: MTU3 enable count69 * @prescale: MTU3 prescale70 * @channel_data: MTU3 pwm channel data71 */72 73struct rz_mtu3_pwm_chip {74	struct clk *clk;75	struct mutex lock;76	unsigned long rate;77	u32 user_count[RZ_MTU3_MAX_HW_CHANNELS];78	u32 enable_count[RZ_MTU3_MAX_HW_CHANNELS];79	u8 prescale[RZ_MTU3_MAX_HW_CHANNELS];80	struct rz_mtu3_pwm_channel channel_data[RZ_MTU3_MAX_HW_CHANNELS];81};82 83/*84 * The MTU channels are {0..4, 6, 7} and the number of IO on MTU185 * and MTU2 channel is 1 compared to 2 on others.86 */87static const struct rz_mtu3_channel_io_map channel_map[] = {88	{ 0, 2 }, { 2, 1 }, { 3, 1 }, { 4, 2 }, { 6, 2 }, { 8, 2 }, { 10, 2 }89};90 91static inline struct rz_mtu3_pwm_chip *to_rz_mtu3_pwm_chip(struct pwm_chip *chip)92{93	return pwmchip_get_drvdata(chip);94}95 96static void rz_mtu3_pwm_read_tgr_registers(struct rz_mtu3_pwm_channel *priv,97					   u16 reg_pv_offset, u16 *pv_val,98					   u16 reg_dc_offset, u16 *dc_val)99{100	*pv_val = rz_mtu3_16bit_ch_read(priv->mtu, reg_pv_offset);101	*dc_val = rz_mtu3_16bit_ch_read(priv->mtu, reg_dc_offset);102}103 104static void rz_mtu3_pwm_write_tgr_registers(struct rz_mtu3_pwm_channel *priv,105					    u16 reg_pv_offset, u16 pv_val,106					    u16 reg_dc_offset, u16 dc_val)107{108	rz_mtu3_16bit_ch_write(priv->mtu, reg_pv_offset, pv_val);109	rz_mtu3_16bit_ch_write(priv->mtu, reg_dc_offset, dc_val);110}111 112static u8 rz_mtu3_pwm_calculate_prescale(struct rz_mtu3_pwm_chip *rz_mtu3,113					 u64 period_cycles)114{115	u32 prescaled_period_cycles;116	u8 prescale;117 118	/*119	 * Supported prescale values are 1, 4, 16 and 64.120	 * TODO: Support prescale values 2, 8, 32, 256 and 1024.121	 */122	prescaled_period_cycles = period_cycles >> 16;123	if (prescaled_period_cycles >= 16)124		prescale = 3;125	else126		prescale = (fls(prescaled_period_cycles) + 1) / 2;127 128	return prescale;129}130 131static struct rz_mtu3_pwm_channel *132rz_mtu3_get_channel(struct rz_mtu3_pwm_chip *rz_mtu3_pwm, u32 hwpwm)133{134	struct rz_mtu3_pwm_channel *priv = rz_mtu3_pwm->channel_data;135	unsigned int ch;136 137	for (ch = 0; ch < RZ_MTU3_MAX_HW_CHANNELS; ch++, priv++) {138		if (priv->map->base_pwm_number + priv->map->num_channel_ios > hwpwm)139			break;140	}141 142	return priv;143}144 145static bool rz_mtu3_pwm_is_ch_enabled(struct rz_mtu3_pwm_chip *rz_mtu3_pwm,146				      u32 hwpwm)147{148	struct rz_mtu3_pwm_channel *priv;149	bool is_channel_en;150	u8 val;151 152	priv = rz_mtu3_get_channel(rz_mtu3_pwm, hwpwm);153	is_channel_en = rz_mtu3_is_enabled(priv->mtu);154	if (!is_channel_en)155		return false;156 157	if (priv->map->base_pwm_number == hwpwm)158		val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TIORH);159	else160		val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TIORL);161 162	return val & RZ_MTU3_TIOR_IOA;163}164 165static int rz_mtu3_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)166{167	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);168	struct rz_mtu3_pwm_channel *priv;169	bool is_mtu3_channel_available;170	u32 ch;171 172	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);173	ch = priv - rz_mtu3_pwm->channel_data;174 175	mutex_lock(&rz_mtu3_pwm->lock);176	/*177	 * Each channel must be requested only once, so if the channel178	 * serves two PWMs and the other is already requested, skip over179	 * rz_mtu3_request_channel()180	 */181	if (!rz_mtu3_pwm->user_count[ch]) {182		is_mtu3_channel_available = rz_mtu3_request_channel(priv->mtu);183		if (!is_mtu3_channel_available) {184			mutex_unlock(&rz_mtu3_pwm->lock);185			return -EBUSY;186		}187	}188 189	rz_mtu3_pwm->user_count[ch]++;190	mutex_unlock(&rz_mtu3_pwm->lock);191 192	return 0;193}194 195static void rz_mtu3_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)196{197	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);198	struct rz_mtu3_pwm_channel *priv;199	u32 ch;200 201	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);202	ch = priv - rz_mtu3_pwm->channel_data;203 204	mutex_lock(&rz_mtu3_pwm->lock);205	rz_mtu3_pwm->user_count[ch]--;206	if (!rz_mtu3_pwm->user_count[ch])207		rz_mtu3_release_channel(priv->mtu);208 209	mutex_unlock(&rz_mtu3_pwm->lock);210}211 212static int rz_mtu3_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)213{214	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);215	struct rz_mtu3_pwm_channel *priv;216	u32 ch;217	u8 val;218	int rc;219 220	rc = pm_runtime_resume_and_get(pwmchip_parent(chip));221	if (rc)222		return rc;223 224	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);225	ch = priv - rz_mtu3_pwm->channel_data;226	val = RZ_MTU3_TIOR_OC_IOB_TOGGLE | RZ_MTU3_TIOR_OC_IOA_H_COMP_MATCH;227 228	rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_MD_PWMMODE1);229	if (priv->map->base_pwm_number == pwm->hwpwm)230		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORH, val);231	else232		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORL, val);233 234	mutex_lock(&rz_mtu3_pwm->lock);235	if (!rz_mtu3_pwm->enable_count[ch])236		rz_mtu3_enable(priv->mtu);237 238	rz_mtu3_pwm->enable_count[ch]++;239	mutex_unlock(&rz_mtu3_pwm->lock);240 241	return 0;242}243 244static void rz_mtu3_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)245{246	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);247	struct rz_mtu3_pwm_channel *priv;248	u32 ch;249 250	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);251	ch = priv - rz_mtu3_pwm->channel_data;252 253	/* Disable output pins of MTU3 channel */254	if (priv->map->base_pwm_number == pwm->hwpwm)255		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORH, RZ_MTU3_TIOR_OC_RETAIN);256	else257		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORL, RZ_MTU3_TIOR_OC_RETAIN);258 259	mutex_lock(&rz_mtu3_pwm->lock);260	rz_mtu3_pwm->enable_count[ch]--;261	if (!rz_mtu3_pwm->enable_count[ch])262		rz_mtu3_disable(priv->mtu);263 264	mutex_unlock(&rz_mtu3_pwm->lock);265 266	pm_runtime_put_sync(pwmchip_parent(chip));267}268 269static int rz_mtu3_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,270				 struct pwm_state *state)271{272	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);273	int rc;274 275	rc = pm_runtime_resume_and_get(pwmchip_parent(chip));276	if (rc)277		return rc;278 279	state->enabled = rz_mtu3_pwm_is_ch_enabled(rz_mtu3_pwm, pwm->hwpwm);280	if (state->enabled) {281		struct rz_mtu3_pwm_channel *priv;282		u8 prescale, val;283		u16 dc, pv;284		u64 tmp;285 286		priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);287		if (priv->map->base_pwm_number == pwm->hwpwm)288			rz_mtu3_pwm_read_tgr_registers(priv, RZ_MTU3_TGRA, &pv,289						       RZ_MTU3_TGRB, &dc);290		else291			rz_mtu3_pwm_read_tgr_registers(priv, RZ_MTU3_TGRC, &pv,292						       RZ_MTU3_TGRD, &dc);293 294		val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TCR);295		prescale = FIELD_GET(RZ_MTU3_TCR_TPCS, val);296 297		/* With prescale <= 7 and pv <= 0xffff this doesn't overflow. */298		tmp = NSEC_PER_SEC * (u64)pv << (2 * prescale);299		state->period = DIV_ROUND_UP_ULL(tmp, rz_mtu3_pwm->rate);300		tmp = NSEC_PER_SEC * (u64)dc << (2 * prescale);301		state->duty_cycle = DIV_ROUND_UP_ULL(tmp, rz_mtu3_pwm->rate);302 303		if (state->duty_cycle > state->period)304			state->duty_cycle = state->period;305	}306 307	state->polarity = PWM_POLARITY_NORMAL;308	pm_runtime_put(pwmchip_parent(chip));309 310	return 0;311}312 313static u16 rz_mtu3_pwm_calculate_pv_or_dc(u64 period_or_duty_cycle, u8 prescale)314{315	return min(period_or_duty_cycle >> (2 * prescale), (u64)U16_MAX);316}317 318static int rz_mtu3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,319			      const struct pwm_state *state)320{321	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);322	struct rz_mtu3_pwm_channel *priv;323	u64 period_cycles;324	u64 duty_cycles;325	u8 prescale;326	u16 pv, dc;327	u8 val;328	u32 ch;329 330	priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm);331	ch = priv - rz_mtu3_pwm->channel_data;332 333	period_cycles = mul_u64_u32_div(state->period, rz_mtu3_pwm->rate,334					NSEC_PER_SEC);335	prescale = rz_mtu3_pwm_calculate_prescale(rz_mtu3_pwm, period_cycles);336 337	/*338	 * Prescalar is shared by multiple channels, so prescale can339	 * NOT be modified when there are multiple channels in use with340	 * different settings. Modify prescalar if other PWM is off or handle341	 * it, if current prescale value is less than the one we want to set.342	 */343	if (rz_mtu3_pwm->enable_count[ch] > 1) {344		if (rz_mtu3_pwm->prescale[ch] > prescale)345			return -EBUSY;346 347		prescale = rz_mtu3_pwm->prescale[ch];348	}349 350	pv = rz_mtu3_pwm_calculate_pv_or_dc(period_cycles, prescale);351 352	duty_cycles = mul_u64_u32_div(state->duty_cycle, rz_mtu3_pwm->rate,353				      NSEC_PER_SEC);354	dc = rz_mtu3_pwm_calculate_pv_or_dc(duty_cycles, prescale);355 356	/*357	 * If the PWM channel is disabled, make sure to turn on the clock358	 * before writing the register.359	 */360	if (!pwm->state.enabled) {361		int rc;362 363		rc = pm_runtime_resume_and_get(pwmchip_parent(chip));364		if (rc)365			return rc;366	}367 368	val = RZ_MTU3_TCR_CKEG_RISING | prescale;369 370	/* Counter must be stopped while updating TCR register */371	if (rz_mtu3_pwm->prescale[ch] != prescale && rz_mtu3_pwm->enable_count[ch])372		rz_mtu3_disable(priv->mtu);373 374	if (priv->map->base_pwm_number == pwm->hwpwm) {375		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TCR,376				      RZ_MTU3_TCR_CCLR_TGRA | val);377		rz_mtu3_pwm_write_tgr_registers(priv, RZ_MTU3_TGRA, pv,378						RZ_MTU3_TGRB, dc);379	} else {380		rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TCR,381				      RZ_MTU3_TCR_CCLR_TGRC | val);382		rz_mtu3_pwm_write_tgr_registers(priv, RZ_MTU3_TGRC, pv,383						RZ_MTU3_TGRD, dc);384	}385 386	if (rz_mtu3_pwm->prescale[ch] != prescale) {387		/*388		 * Prescalar is shared by multiple channels, we cache the389		 * prescalar value from first enabled channel and use the same390		 * value for both channels.391		 */392		rz_mtu3_pwm->prescale[ch] = prescale;393 394		if (rz_mtu3_pwm->enable_count[ch])395			rz_mtu3_enable(priv->mtu);396	}397 398	/* If the PWM is not enabled, turn the clock off again to save power. */399	if (!pwm->state.enabled)400		pm_runtime_put(pwmchip_parent(chip));401 402	return 0;403}404 405static int rz_mtu3_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,406			     const struct pwm_state *state)407{408	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);409	bool enabled = pwm->state.enabled;410	int ret;411 412	if (state->polarity != PWM_POLARITY_NORMAL)413		return -EINVAL;414 415	if (!state->enabled) {416		if (enabled)417			rz_mtu3_pwm_disable(chip, pwm);418 419		return 0;420	}421 422	mutex_lock(&rz_mtu3_pwm->lock);423	ret = rz_mtu3_pwm_config(chip, pwm, state);424	mutex_unlock(&rz_mtu3_pwm->lock);425	if (ret)426		return ret;427 428	if (!enabled)429		ret = rz_mtu3_pwm_enable(chip, pwm);430 431	return ret;432}433 434static const struct pwm_ops rz_mtu3_pwm_ops = {435	.request = rz_mtu3_pwm_request,436	.free = rz_mtu3_pwm_free,437	.get_state = rz_mtu3_pwm_get_state,438	.apply = rz_mtu3_pwm_apply,439};440 441static int rz_mtu3_pwm_pm_runtime_suspend(struct device *dev)442{443	struct pwm_chip *chip = dev_get_drvdata(dev);444	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);445 446	clk_disable_unprepare(rz_mtu3_pwm->clk);447 448	return 0;449}450 451static int rz_mtu3_pwm_pm_runtime_resume(struct device *dev)452{453	struct pwm_chip *chip = dev_get_drvdata(dev);454	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);455 456	return clk_prepare_enable(rz_mtu3_pwm->clk);457}458 459static DEFINE_RUNTIME_DEV_PM_OPS(rz_mtu3_pwm_pm_ops,460				 rz_mtu3_pwm_pm_runtime_suspend,461				 rz_mtu3_pwm_pm_runtime_resume, NULL);462 463static void rz_mtu3_pwm_pm_disable(void *data)464{465	struct pwm_chip *chip = data;466	struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);467 468	clk_rate_exclusive_put(rz_mtu3_pwm->clk);469	pm_runtime_disable(pwmchip_parent(chip));470	pm_runtime_set_suspended(pwmchip_parent(chip));471}472 473static int rz_mtu3_pwm_probe(struct platform_device *pdev)474{475	struct rz_mtu3 *parent_ddata = dev_get_drvdata(pdev->dev.parent);476	struct rz_mtu3_pwm_chip *rz_mtu3_pwm;477	struct pwm_chip *chip;478	struct device *dev = &pdev->dev;479	unsigned int i, j = 0;480	int ret;481 482	chip = devm_pwmchip_alloc(&pdev->dev, RZ_MTU3_MAX_PWM_CHANNELS,483				  sizeof(*rz_mtu3_pwm));484	if (IS_ERR(chip))485		return PTR_ERR(chip);486	rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip);487 488	rz_mtu3_pwm->clk = parent_ddata->clk;489 490	for (i = 0; i < RZ_MTU_NUM_CHANNELS; i++) {491		if (i == RZ_MTU3_CHAN_5 || i == RZ_MTU3_CHAN_8)492			continue;493 494		rz_mtu3_pwm->channel_data[j].mtu = &parent_ddata->channels[i];495		rz_mtu3_pwm->channel_data[j].mtu->dev = dev;496		rz_mtu3_pwm->channel_data[j].map = &channel_map[j];497		j++;498	}499 500	mutex_init(&rz_mtu3_pwm->lock);501	platform_set_drvdata(pdev, chip);502	ret = clk_prepare_enable(rz_mtu3_pwm->clk);503	if (ret)504		return dev_err_probe(dev, ret, "Clock enable failed\n");505 506	clk_rate_exclusive_get(rz_mtu3_pwm->clk);507 508	rz_mtu3_pwm->rate = clk_get_rate(rz_mtu3_pwm->clk);509	/*510	 * Refuse clk rates > 1 GHz to prevent overflow later for computing511	 * period and duty cycle.512	 */513	if (rz_mtu3_pwm->rate > NSEC_PER_SEC) {514		ret = -EINVAL;515		clk_rate_exclusive_put(rz_mtu3_pwm->clk);516		goto disable_clock;517	}518 519	pm_runtime_set_active(&pdev->dev);520	pm_runtime_enable(&pdev->dev);521	ret = devm_add_action_or_reset(&pdev->dev, rz_mtu3_pwm_pm_disable,522				       chip);523	if (ret < 0)524		return ret;525 526	chip->ops = &rz_mtu3_pwm_ops;527	ret = devm_pwmchip_add(&pdev->dev, chip);528	if (ret)529		return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");530 531	pm_runtime_idle(&pdev->dev);532 533	return 0;534 535disable_clock:536	clk_disable_unprepare(rz_mtu3_pwm->clk);537	return ret;538}539 540static struct platform_driver rz_mtu3_pwm_driver = {541	.driver = {542		.name = "pwm-rz-mtu3",543		.pm = pm_ptr(&rz_mtu3_pwm_pm_ops),544	},545	.probe = rz_mtu3_pwm_probe,546};547module_platform_driver(rz_mtu3_pwm_driver);548 549MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");550MODULE_ALIAS("platform:pwm-rz-mtu3");551MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a PWM Timer Driver");552MODULE_LICENSE("GPL");553