1
0
Fork 0

MLK-18379 pwm: fsl-tpm: updates to support i.mx8qm

The TPM IP block on i.MX8QM has the following changes:
1) The IPG clock has to be enabled before access any registers
2) The extra bits in FTM_SC register are added to enable the PWM mode.

This patch updates the driver according to these changes, and it
can support the TPM PWM module on i.MX8QM.

Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
pull/10/head
Shenwei Wang 2018-05-22 11:46:16 -05:00 committed by Jason Liu
parent cbb10995a9
commit d93ab4b67d
1 changed files with 43 additions and 6 deletions

View File

@ -86,7 +86,9 @@ struct fsl_pwm_chip {
struct regmap *regmap;
int period_ns;
bool has_pwmen;
struct clk *ipg_clk;
struct clk *clk[FSL_PWM_CLK_MAX];
};
@ -95,18 +97,39 @@ static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
return container_of(chip, struct fsl_pwm_chip, chip);
}
static inline int fsl_pwm_mode_enable(struct fsl_pwm_chip *fpc)
{
if (!fpc)
return -ENODEV;
if (fpc->ipg_clk)
clk_prepare_enable(fpc->ipg_clk);
return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
}
static inline void fsl_pwm_mode_disable(struct fsl_pwm_chip *fpc)
{
if (!fpc)
return;
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
if (fpc->ipg_clk)
clk_disable_unprepare(fpc->ipg_clk);
}
static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
return fsl_pwm_mode_enable(fpc);
}
static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
fsl_pwm_mode_disable(fpc);
}
static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc,
@ -323,6 +346,9 @@ static int fsl_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
mutex_lock(&fpc->lock);
regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm), 0);
if (fpc->has_pwmen)
regmap_update_bits(fpc->regmap, FTM_SC,
BIT(pwm->hwpwm + 16), BIT(pwm->hwpwm + 16));
ret = fsl_counter_clock_enable(fpc);
mutex_unlock(&fpc->lock);
@ -336,6 +362,10 @@ static void fsl_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
u32 val;
mutex_lock(&fpc->lock);
if (fpc->has_pwmen)
regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16), 0);
regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm),
BIT(pwm->hwpwm));
@ -363,7 +393,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
{
int ret;
ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
ret = fsl_pwm_mode_enable(fpc);
if (ret)
return ret;
@ -371,7 +401,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
fsl_pwm_mode_disable(fpc);
return 0;
}
@ -422,7 +452,12 @@ static int fsl_pwm_probe(struct platform_device *pdev)
return PTR_ERR(fpc->regmap);
}
fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(fpc->ipg_clk))
fpc->ipg_clk = 0;
fpc->clk[FSL_PWM_CLK_SYS] = devm_clk_get(&pdev->dev, "ftm_sys");
if (IS_ERR(fpc->clk[FSL_PWM_CLK_SYS])) {
dev_err(&pdev->dev, "failed to get \"ftm_sys\" clock\n");
return PTR_ERR(fpc->clk[FSL_PWM_CLK_SYS]);
@ -446,6 +481,8 @@ static int fsl_pwm_probe(struct platform_device *pdev)
fpc->chip.of_pwm_n_cells = 3;
fpc->chip.base = -1;
fpc->chip.npwm = 8;
fpc->has_pwmen = of_property_read_bool(pdev->dev.of_node,
"ftm-has-pwmen-bits");
ret = pwmchip_add(&fpc->chip);
if (ret < 0) {
@ -480,7 +517,7 @@ static int fsl_pwm_suspend(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
fsl_pwm_mode_disable(fpc);
if (!pwm_is_enabled(pwm))
continue;
@ -503,7 +540,7 @@ static int fsl_pwm_resume(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;
clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
fsl_pwm_mode_enable(fpc);
if (!pwm_is_enabled(pwm))
continue;