Lines Matching +full:clk +full:- +full:pwm

1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas RZ/G2L MTU3a PWM Timer driver
8 …* https://www.renesas.com/eu/en/document/mah/rzg2l-group-rzg2lc-group-users-manual-hardware-0?lang…
11 * - When PWM is disabled, the output is driven to Hi-Z.
12 * - While the hardware supports both polarities, the driver (for now)
14 * - HW uses one counter and two match components to configure duty_cycle
16 * - Multi-Function Timer Pulse Unit (a.k.a MTU) has 7 HW channels for PWM
18 * - MTU{1, 2} channels have a single IO, whereas all other HW channels have
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 the
27 #include <linux/clk.h>
29 #include <linux/mfd/rz-mtu3.h>
33 #include <linux/pwm.h>
40 * struct rz_mtu3_channel_io_map - MTU3 pwm channel map
42 * @base_pwm_number: First PWM of a channel
51 * struct rz_mtu3_pwm_channel - MTU3 pwm channel data
54 * @map: MTU3 pwm channel map
62 * struct rz_mtu3_pwm_chip - MTU3 pwm private data
64 * @clk: MTU3 module clock
70 * @channel_data: MTU3 pwm channel data
74 struct clk *clk; member
100 *pv_val = rz_mtu3_16bit_ch_read(priv->mtu, reg_pv_offset); in rz_mtu3_pwm_read_tgr_registers()
101 *dc_val = rz_mtu3_16bit_ch_read(priv->mtu, reg_dc_offset); in rz_mtu3_pwm_read_tgr_registers()
108 rz_mtu3_16bit_ch_write(priv->mtu, reg_pv_offset, pv_val); in rz_mtu3_pwm_write_tgr_registers()
109 rz_mtu3_16bit_ch_write(priv->mtu, reg_dc_offset, dc_val); in rz_mtu3_pwm_write_tgr_registers()
134 struct rz_mtu3_pwm_channel *priv = rz_mtu3_pwm->channel_data; in rz_mtu3_get_channel()
138 if (priv->map->base_pwm_number + priv->map->num_channel_ios > hwpwm) in rz_mtu3_get_channel()
153 is_channel_en = rz_mtu3_is_enabled(priv->mtu); in rz_mtu3_pwm_is_ch_enabled()
157 if (priv->map->base_pwm_number == hwpwm) in rz_mtu3_pwm_is_ch_enabled()
158 val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TIORH); in rz_mtu3_pwm_is_ch_enabled()
160 val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TIORL); in rz_mtu3_pwm_is_ch_enabled()
165 static int rz_mtu3_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) in rz_mtu3_pwm_request() argument
172 priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm); in rz_mtu3_pwm_request()
173 ch = priv - rz_mtu3_pwm->channel_data; in rz_mtu3_pwm_request()
175 mutex_lock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_request()
181 if (!rz_mtu3_pwm->user_count[ch]) { in rz_mtu3_pwm_request()
182 is_mtu3_channel_available = rz_mtu3_request_channel(priv->mtu); in rz_mtu3_pwm_request()
184 mutex_unlock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_request()
185 return -EBUSY; in rz_mtu3_pwm_request()
189 rz_mtu3_pwm->user_count[ch]++; in rz_mtu3_pwm_request()
190 mutex_unlock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_request()
195 static void rz_mtu3_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) in rz_mtu3_pwm_free() argument
201 priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm); in rz_mtu3_pwm_free()
202 ch = priv - rz_mtu3_pwm->channel_data; in rz_mtu3_pwm_free()
204 mutex_lock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_free()
205 rz_mtu3_pwm->user_count[ch]--; in rz_mtu3_pwm_free()
206 if (!rz_mtu3_pwm->user_count[ch]) in rz_mtu3_pwm_free()
207 rz_mtu3_release_channel(priv->mtu); in rz_mtu3_pwm_free()
209 mutex_unlock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_free()
212 static int rz_mtu3_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) in rz_mtu3_pwm_enable() argument
224 priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm); in rz_mtu3_pwm_enable()
225 ch = priv - rz_mtu3_pwm->channel_data; in rz_mtu3_pwm_enable()
228 rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_MD_PWMMODE1); in rz_mtu3_pwm_enable()
229 if (priv->map->base_pwm_number == pwm->hwpwm) in rz_mtu3_pwm_enable()
230 rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORH, val); in rz_mtu3_pwm_enable()
232 rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORL, val); in rz_mtu3_pwm_enable()
234 mutex_lock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_enable()
235 if (!rz_mtu3_pwm->enable_count[ch]) in rz_mtu3_pwm_enable()
236 rz_mtu3_enable(priv->mtu); in rz_mtu3_pwm_enable()
238 rz_mtu3_pwm->enable_count[ch]++; in rz_mtu3_pwm_enable()
239 mutex_unlock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_enable()
244 static void rz_mtu3_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) in rz_mtu3_pwm_disable() argument
250 priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm); in rz_mtu3_pwm_disable()
251 ch = priv - rz_mtu3_pwm->channel_data; in rz_mtu3_pwm_disable()
254 if (priv->map->base_pwm_number == pwm->hwpwm) in rz_mtu3_pwm_disable()
255 rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORH, RZ_MTU3_TIOR_OC_RETAIN); in rz_mtu3_pwm_disable()
257 rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TIORL, RZ_MTU3_TIOR_OC_RETAIN); in rz_mtu3_pwm_disable()
259 mutex_lock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_disable()
260 rz_mtu3_pwm->enable_count[ch]--; in rz_mtu3_pwm_disable()
261 if (!rz_mtu3_pwm->enable_count[ch]) in rz_mtu3_pwm_disable()
262 rz_mtu3_disable(priv->mtu); in rz_mtu3_pwm_disable()
264 mutex_unlock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_disable()
269 static int rz_mtu3_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, in rz_mtu3_pwm_get_state() argument
279 state->enabled = rz_mtu3_pwm_is_ch_enabled(rz_mtu3_pwm, pwm->hwpwm); in rz_mtu3_pwm_get_state()
280 if (state->enabled) { in rz_mtu3_pwm_get_state()
286 priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm); in rz_mtu3_pwm_get_state()
287 if (priv->map->base_pwm_number == pwm->hwpwm) in rz_mtu3_pwm_get_state()
294 val = rz_mtu3_8bit_ch_read(priv->mtu, RZ_MTU3_TCR); in rz_mtu3_pwm_get_state()
299 state->period = DIV_ROUND_UP_ULL(tmp, rz_mtu3_pwm->rate); in rz_mtu3_pwm_get_state()
301 state->duty_cycle = DIV_ROUND_UP_ULL(tmp, rz_mtu3_pwm->rate); in rz_mtu3_pwm_get_state()
303 if (state->duty_cycle > state->period) in rz_mtu3_pwm_get_state()
304 state->duty_cycle = state->period; in rz_mtu3_pwm_get_state()
307 state->polarity = PWM_POLARITY_NORMAL; in rz_mtu3_pwm_get_state()
318 static int rz_mtu3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, in rz_mtu3_pwm_config() argument
330 priv = rz_mtu3_get_channel(rz_mtu3_pwm, pwm->hwpwm); in rz_mtu3_pwm_config()
331 ch = priv - rz_mtu3_pwm->channel_data; in rz_mtu3_pwm_config()
333 period_cycles = mul_u64_u32_div(state->period, rz_mtu3_pwm->rate, in rz_mtu3_pwm_config()
340 * different settings. Modify prescalar if other PWM is off or handle in rz_mtu3_pwm_config()
343 if (rz_mtu3_pwm->enable_count[ch] > 1) { in rz_mtu3_pwm_config()
344 if (rz_mtu3_pwm->prescale[ch] > prescale) in rz_mtu3_pwm_config()
345 return -EBUSY; in rz_mtu3_pwm_config()
347 prescale = rz_mtu3_pwm->prescale[ch]; in rz_mtu3_pwm_config()
352 duty_cycles = mul_u64_u32_div(state->duty_cycle, rz_mtu3_pwm->rate, in rz_mtu3_pwm_config()
357 * If the PWM channel is disabled, make sure to turn on the clock in rz_mtu3_pwm_config()
360 if (!pwm->state.enabled) { in rz_mtu3_pwm_config()
371 if (rz_mtu3_pwm->prescale[ch] != prescale && rz_mtu3_pwm->enable_count[ch]) in rz_mtu3_pwm_config()
372 rz_mtu3_disable(priv->mtu); in rz_mtu3_pwm_config()
374 if (priv->map->base_pwm_number == pwm->hwpwm) { in rz_mtu3_pwm_config()
375 rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TCR, in rz_mtu3_pwm_config()
380 rz_mtu3_8bit_ch_write(priv->mtu, RZ_MTU3_TCR, in rz_mtu3_pwm_config()
386 if (rz_mtu3_pwm->prescale[ch] != prescale) { in rz_mtu3_pwm_config()
392 rz_mtu3_pwm->prescale[ch] = prescale; in rz_mtu3_pwm_config()
394 if (rz_mtu3_pwm->enable_count[ch]) in rz_mtu3_pwm_config()
395 rz_mtu3_enable(priv->mtu); in rz_mtu3_pwm_config()
398 /* If the PWM is not enabled, turn the clock off again to save power. */ in rz_mtu3_pwm_config()
399 if (!pwm->state.enabled) in rz_mtu3_pwm_config()
405 static int rz_mtu3_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in rz_mtu3_pwm_apply() argument
409 bool enabled = pwm->state.enabled; in rz_mtu3_pwm_apply()
412 if (state->polarity != PWM_POLARITY_NORMAL) in rz_mtu3_pwm_apply()
413 return -EINVAL; in rz_mtu3_pwm_apply()
415 if (!state->enabled) { in rz_mtu3_pwm_apply()
417 rz_mtu3_pwm_disable(chip, pwm); in rz_mtu3_pwm_apply()
422 mutex_lock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_apply()
423 ret = rz_mtu3_pwm_config(chip, pwm, state); in rz_mtu3_pwm_apply()
424 mutex_unlock(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_apply()
429 ret = rz_mtu3_pwm_enable(chip, pwm); in rz_mtu3_pwm_apply()
446 clk_disable_unprepare(rz_mtu3_pwm->clk); in rz_mtu3_pwm_pm_runtime_suspend()
456 return clk_prepare_enable(rz_mtu3_pwm->clk); in rz_mtu3_pwm_pm_runtime_resume()
468 clk_rate_exclusive_put(rz_mtu3_pwm->clk); in rz_mtu3_pwm_pm_disable()
475 struct rz_mtu3 *parent_ddata = dev_get_drvdata(pdev->dev.parent); in rz_mtu3_pwm_probe()
478 struct device *dev = &pdev->dev; in rz_mtu3_pwm_probe()
482 chip = devm_pwmchip_alloc(&pdev->dev, RZ_MTU3_MAX_PWM_CHANNELS, in rz_mtu3_pwm_probe()
488 rz_mtu3_pwm->clk = parent_ddata->clk; in rz_mtu3_pwm_probe()
494 rz_mtu3_pwm->channel_data[j].mtu = &parent_ddata->channels[i]; in rz_mtu3_pwm_probe()
495 rz_mtu3_pwm->channel_data[j].mtu->dev = dev; in rz_mtu3_pwm_probe()
496 rz_mtu3_pwm->channel_data[j].map = &channel_map[j]; in rz_mtu3_pwm_probe()
500 mutex_init(&rz_mtu3_pwm->lock); in rz_mtu3_pwm_probe()
502 ret = clk_prepare_enable(rz_mtu3_pwm->clk); in rz_mtu3_pwm_probe()
506 clk_rate_exclusive_get(rz_mtu3_pwm->clk); in rz_mtu3_pwm_probe()
508 rz_mtu3_pwm->rate = clk_get_rate(rz_mtu3_pwm->clk); in rz_mtu3_pwm_probe()
510 * Refuse clk rates > 1 GHz to prevent overflow later for computing in rz_mtu3_pwm_probe()
513 if (rz_mtu3_pwm->rate > NSEC_PER_SEC) { in rz_mtu3_pwm_probe()
514 ret = -EINVAL; in rz_mtu3_pwm_probe()
515 clk_rate_exclusive_put(rz_mtu3_pwm->clk); in rz_mtu3_pwm_probe()
519 pm_runtime_set_active(&pdev->dev); in rz_mtu3_pwm_probe()
520 pm_runtime_enable(&pdev->dev); in rz_mtu3_pwm_probe()
521 ret = devm_add_action_or_reset(&pdev->dev, rz_mtu3_pwm_pm_disable, in rz_mtu3_pwm_probe()
526 chip->ops = &rz_mtu3_pwm_ops; in rz_mtu3_pwm_probe()
527 ret = devm_pwmchip_add(&pdev->dev, chip); in rz_mtu3_pwm_probe()
529 return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); in rz_mtu3_pwm_probe()
531 pm_runtime_idle(&pdev->dev); in rz_mtu3_pwm_probe()
536 clk_disable_unprepare(rz_mtu3_pwm->clk); in rz_mtu3_pwm_probe()
542 .name = "pwm-rz-mtu3",
550 MODULE_ALIAS("platform:pwm-rz-mtu3");
551 MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a PWM Timer Driver");