Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright 2018-2019 NXP.
0004  *
0005  * Limitations:
0006  * - The TPM counter and period counter are shared between
0007  *   multiple channels, so all channels should use same period
0008  *   settings.
0009  * - Changes to polarity cannot be latched at the time of the
0010  *   next period start.
0011  * - Changing period and duty cycle together isn't atomic,
0012  *   with the wrong timing it might happen that a period is
0013  *   produced with old duty cycle but new period settings.
0014  */
0015 
0016 #include <linux/bitfield.h>
0017 #include <linux/bitops.h>
0018 #include <linux/clk.h>
0019 #include <linux/err.h>
0020 #include <linux/io.h>
0021 #include <linux/module.h>
0022 #include <linux/of.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/pwm.h>
0025 #include <linux/slab.h>
0026 
0027 #define PWM_IMX_TPM_PARAM   0x4
0028 #define PWM_IMX_TPM_GLOBAL  0x8
0029 #define PWM_IMX_TPM_SC      0x10
0030 #define PWM_IMX_TPM_CNT     0x14
0031 #define PWM_IMX_TPM_MOD     0x18
0032 #define PWM_IMX_TPM_CnSC(n) (0x20 + (n) * 0x8)
0033 #define PWM_IMX_TPM_CnV(n)  (0x24 + (n) * 0x8)
0034 
0035 #define PWM_IMX_TPM_PARAM_CHAN          GENMASK(7, 0)
0036 
0037 #define PWM_IMX_TPM_SC_PS           GENMASK(2, 0)
0038 #define PWM_IMX_TPM_SC_CMOD         GENMASK(4, 3)
0039 #define PWM_IMX_TPM_SC_CMOD_INC_EVERY_CLK   FIELD_PREP(PWM_IMX_TPM_SC_CMOD, 1)
0040 #define PWM_IMX_TPM_SC_CPWMS            BIT(5)
0041 
0042 #define PWM_IMX_TPM_CnSC_CHF    BIT(7)
0043 #define PWM_IMX_TPM_CnSC_MSB    BIT(5)
0044 #define PWM_IMX_TPM_CnSC_MSA    BIT(4)
0045 
0046 /*
0047  * The reference manual describes this field as two separate bits. The
0048  * semantic of the two bits isn't orthogonal though, so they are treated
0049  * together as a 2-bit field here.
0050  */
0051 #define PWM_IMX_TPM_CnSC_ELS    GENMASK(3, 2)
0052 #define PWM_IMX_TPM_CnSC_ELS_INVERSED   FIELD_PREP(PWM_IMX_TPM_CnSC_ELS, 1)
0053 #define PWM_IMX_TPM_CnSC_ELS_NORMAL FIELD_PREP(PWM_IMX_TPM_CnSC_ELS, 2)
0054 
0055 
0056 #define PWM_IMX_TPM_MOD_WIDTH   16
0057 #define PWM_IMX_TPM_MOD_MOD GENMASK(PWM_IMX_TPM_MOD_WIDTH - 1, 0)
0058 
0059 struct imx_tpm_pwm_chip {
0060     struct pwm_chip chip;
0061     struct clk *clk;
0062     void __iomem *base;
0063     struct mutex lock;
0064     u32 user_count;
0065     u32 enable_count;
0066     u32 real_period;
0067 };
0068 
0069 struct imx_tpm_pwm_param {
0070     u8 prescale;
0071     u32 mod;
0072     u32 val;
0073 };
0074 
0075 static inline struct imx_tpm_pwm_chip *
0076 to_imx_tpm_pwm_chip(struct pwm_chip *chip)
0077 {
0078     return container_of(chip, struct imx_tpm_pwm_chip, chip);
0079 }
0080 
0081 /*
0082  * This function determines for a given pwm_state *state that a consumer
0083  * might request the pwm_state *real_state that eventually is implemented
0084  * by the hardware and the necessary register values (in *p) to achieve
0085  * this.
0086  */
0087 static int pwm_imx_tpm_round_state(struct pwm_chip *chip,
0088                    struct imx_tpm_pwm_param *p,
0089                    struct pwm_state *real_state,
0090                    const struct pwm_state *state)
0091 {
0092     struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip);
0093     u32 rate, prescale, period_count, clock_unit;
0094     u64 tmp;
0095 
0096     rate = clk_get_rate(tpm->clk);
0097     tmp = (u64)state->period * rate;
0098     clock_unit = DIV_ROUND_CLOSEST_ULL(tmp, NSEC_PER_SEC);
0099     if (clock_unit <= PWM_IMX_TPM_MOD_MOD)
0100         prescale = 0;
0101     else
0102         prescale = ilog2(clock_unit) + 1 - PWM_IMX_TPM_MOD_WIDTH;
0103 
0104     if ((!FIELD_FIT(PWM_IMX_TPM_SC_PS, prescale)))
0105         return -ERANGE;
0106     p->prescale = prescale;
0107 
0108     period_count = (clock_unit + ((1 << prescale) >> 1)) >> prescale;
0109     p->mod = period_count;
0110 
0111     /* calculate real period HW can support */
0112     tmp = (u64)period_count << prescale;
0113     tmp *= NSEC_PER_SEC;
0114     real_state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate);
0115 
0116     /*
0117      * if eventually the PWM output is inactive, either
0118      * duty cycle is 0 or status is disabled, need to
0119      * make sure the output pin is inactive.
0120      */
0121     if (!state->enabled)
0122         real_state->duty_cycle = 0;
0123     else
0124         real_state->duty_cycle = state->duty_cycle;
0125 
0126     tmp = (u64)p->mod * real_state->duty_cycle;
0127     p->val = DIV64_U64_ROUND_CLOSEST(tmp, real_state->period);
0128 
0129     real_state->polarity = state->polarity;
0130     real_state->enabled = state->enabled;
0131 
0132     return 0;
0133 }
0134 
0135 static void pwm_imx_tpm_get_state(struct pwm_chip *chip,
0136                   struct pwm_device *pwm,
0137                   struct pwm_state *state)
0138 {
0139     struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip);
0140     u32 rate, val, prescale;
0141     u64 tmp;
0142 
0143     /* get period */
0144     state->period = tpm->real_period;
0145 
0146     /* get duty cycle */
0147     rate = clk_get_rate(tpm->clk);
0148     val = readl(tpm->base + PWM_IMX_TPM_SC);
0149     prescale = FIELD_GET(PWM_IMX_TPM_SC_PS, val);
0150     tmp = readl(tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm));
0151     tmp = (tmp << prescale) * NSEC_PER_SEC;
0152     state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
0153 
0154     /* get polarity */
0155     val = readl(tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm));
0156     if ((val & PWM_IMX_TPM_CnSC_ELS) == PWM_IMX_TPM_CnSC_ELS_INVERSED)
0157         state->polarity = PWM_POLARITY_INVERSED;
0158     else
0159         /*
0160          * Assume reserved values (2b00 and 2b11) to yield
0161          * normal polarity.
0162          */
0163         state->polarity = PWM_POLARITY_NORMAL;
0164 
0165     /* get channel status */
0166     state->enabled = FIELD_GET(PWM_IMX_TPM_CnSC_ELS, val) ? true : false;
0167 }
0168 
0169 /* this function is supposed to be called with mutex hold */
0170 static int pwm_imx_tpm_apply_hw(struct pwm_chip *chip,
0171                 struct imx_tpm_pwm_param *p,
0172                 struct pwm_state *state,
0173                 struct pwm_device *pwm)
0174 {
0175     struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip);
0176     bool period_update = false;
0177     bool duty_update = false;
0178     u32 val, cmod, cur_prescale;
0179     unsigned long timeout;
0180     struct pwm_state c;
0181 
0182     if (state->period != tpm->real_period) {
0183         /*
0184          * TPM counter is shared by multiple channels, so
0185          * prescale and period can NOT be modified when
0186          * there are multiple channels in use with different
0187          * period settings.
0188          */
0189         if (tpm->user_count > 1)
0190             return -EBUSY;
0191 
0192         val = readl(tpm->base + PWM_IMX_TPM_SC);
0193         cmod = FIELD_GET(PWM_IMX_TPM_SC_CMOD, val);
0194         cur_prescale = FIELD_GET(PWM_IMX_TPM_SC_PS, val);
0195         if (cmod && cur_prescale != p->prescale)
0196             return -EBUSY;
0197 
0198         /* set TPM counter prescale */
0199         val &= ~PWM_IMX_TPM_SC_PS;
0200         val |= FIELD_PREP(PWM_IMX_TPM_SC_PS, p->prescale);
0201         writel(val, tpm->base + PWM_IMX_TPM_SC);
0202 
0203         /*
0204          * set period count:
0205          * if the PWM is disabled (CMOD[1:0] = 2b00), then MOD register
0206          * is updated when MOD register is written.
0207          *
0208          * if the PWM is enabled (CMOD[1:0] ≠ 2b00), the period length
0209          * is latched into hardware when the next period starts.
0210          */
0211         writel(p->mod, tpm->base + PWM_IMX_TPM_MOD);
0212         tpm->real_period = state->period;
0213         period_update = true;
0214     }
0215 
0216     pwm_imx_tpm_get_state(chip, pwm, &c);
0217 
0218     /* polarity is NOT allowed to be changed if PWM is active */
0219     if (c.enabled && c.polarity != state->polarity)
0220         return -EBUSY;
0221 
0222     if (state->duty_cycle != c.duty_cycle) {
0223         /*
0224          * set channel value:
0225          * if the PWM is disabled (CMOD[1:0] = 2b00), then CnV register
0226          * is updated when CnV register is written.
0227          *
0228          * if the PWM is enabled (CMOD[1:0] ≠ 2b00), the duty length
0229          * is latched into hardware when the next period starts.
0230          */
0231         writel(p->val, tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm));
0232         duty_update = true;
0233     }
0234 
0235     /* make sure MOD & CnV registers are updated */
0236     if (period_update || duty_update) {
0237         timeout = jiffies + msecs_to_jiffies(tpm->real_period /
0238                              NSEC_PER_MSEC + 1);
0239         while (readl(tpm->base + PWM_IMX_TPM_MOD) != p->mod
0240                || readl(tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm))
0241                != p->val) {
0242             if (time_after(jiffies, timeout))
0243                 return -ETIME;
0244             cpu_relax();
0245         }
0246     }
0247 
0248     /*
0249      * polarity settings will enabled/disable output status
0250      * immediately, so if the channel is disabled, need to
0251      * make sure MSA/MSB/ELS are set to 0 which means channel
0252      * disabled.
0253      */
0254     val = readl(tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm));
0255     val &= ~(PWM_IMX_TPM_CnSC_ELS | PWM_IMX_TPM_CnSC_MSA |
0256          PWM_IMX_TPM_CnSC_MSB);
0257     if (state->enabled) {
0258         /*
0259          * set polarity (for edge-aligned PWM modes)
0260          *
0261          * ELS[1:0] = 2b10 yields normal polarity behaviour,
0262          * ELS[1:0] = 2b01 yields inversed polarity.
0263          * The other values are reserved.
0264          */
0265         val |= PWM_IMX_TPM_CnSC_MSB;
0266         val |= (state->polarity == PWM_POLARITY_NORMAL) ?
0267             PWM_IMX_TPM_CnSC_ELS_NORMAL :
0268             PWM_IMX_TPM_CnSC_ELS_INVERSED;
0269     }
0270     writel(val, tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm));
0271 
0272     /* control the counter status */
0273     if (state->enabled != c.enabled) {
0274         val = readl(tpm->base + PWM_IMX_TPM_SC);
0275         if (state->enabled) {
0276             if (++tpm->enable_count == 1)
0277                 val |= PWM_IMX_TPM_SC_CMOD_INC_EVERY_CLK;
0278         } else {
0279             if (--tpm->enable_count == 0)
0280                 val &= ~PWM_IMX_TPM_SC_CMOD;
0281         }
0282         writel(val, tpm->base + PWM_IMX_TPM_SC);
0283     }
0284 
0285     return 0;
0286 }
0287 
0288 static int pwm_imx_tpm_apply(struct pwm_chip *chip,
0289                  struct pwm_device *pwm,
0290                  const struct pwm_state *state)
0291 {
0292     struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip);
0293     struct imx_tpm_pwm_param param;
0294     struct pwm_state real_state;
0295     int ret;
0296 
0297     ret = pwm_imx_tpm_round_state(chip, &param, &real_state, state);
0298     if (ret)
0299         return ret;
0300 
0301     mutex_lock(&tpm->lock);
0302     ret = pwm_imx_tpm_apply_hw(chip, &param, &real_state, pwm);
0303     mutex_unlock(&tpm->lock);
0304 
0305     return ret;
0306 }
0307 
0308 static int pwm_imx_tpm_request(struct pwm_chip *chip, struct pwm_device *pwm)
0309 {
0310     struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip);
0311 
0312     mutex_lock(&tpm->lock);
0313     tpm->user_count++;
0314     mutex_unlock(&tpm->lock);
0315 
0316     return 0;
0317 }
0318 
0319 static void pwm_imx_tpm_free(struct pwm_chip *chip, struct pwm_device *pwm)
0320 {
0321     struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip);
0322 
0323     mutex_lock(&tpm->lock);
0324     tpm->user_count--;
0325     mutex_unlock(&tpm->lock);
0326 }
0327 
0328 static const struct pwm_ops imx_tpm_pwm_ops = {
0329     .request = pwm_imx_tpm_request,
0330     .free = pwm_imx_tpm_free,
0331     .get_state = pwm_imx_tpm_get_state,
0332     .apply = pwm_imx_tpm_apply,
0333     .owner = THIS_MODULE,
0334 };
0335 
0336 static int pwm_imx_tpm_probe(struct platform_device *pdev)
0337 {
0338     struct imx_tpm_pwm_chip *tpm;
0339     int ret;
0340     u32 val;
0341 
0342     tpm = devm_kzalloc(&pdev->dev, sizeof(*tpm), GFP_KERNEL);
0343     if (!tpm)
0344         return -ENOMEM;
0345 
0346     platform_set_drvdata(pdev, tpm);
0347 
0348     tpm->base = devm_platform_ioremap_resource(pdev, 0);
0349     if (IS_ERR(tpm->base))
0350         return PTR_ERR(tpm->base);
0351 
0352     tpm->clk = devm_clk_get(&pdev->dev, NULL);
0353     if (IS_ERR(tpm->clk))
0354         return dev_err_probe(&pdev->dev, PTR_ERR(tpm->clk),
0355                      "failed to get PWM clock\n");
0356 
0357     ret = clk_prepare_enable(tpm->clk);
0358     if (ret) {
0359         dev_err(&pdev->dev,
0360             "failed to prepare or enable clock: %d\n", ret);
0361         return ret;
0362     }
0363 
0364     tpm->chip.dev = &pdev->dev;
0365     tpm->chip.ops = &imx_tpm_pwm_ops;
0366 
0367     /* get number of channels */
0368     val = readl(tpm->base + PWM_IMX_TPM_PARAM);
0369     tpm->chip.npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val);
0370 
0371     mutex_init(&tpm->lock);
0372 
0373     ret = pwmchip_add(&tpm->chip);
0374     if (ret) {
0375         dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
0376         clk_disable_unprepare(tpm->clk);
0377     }
0378 
0379     return ret;
0380 }
0381 
0382 static int pwm_imx_tpm_remove(struct platform_device *pdev)
0383 {
0384     struct imx_tpm_pwm_chip *tpm = platform_get_drvdata(pdev);
0385 
0386     pwmchip_remove(&tpm->chip);
0387 
0388     clk_disable_unprepare(tpm->clk);
0389 
0390     return 0;
0391 }
0392 
0393 static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev)
0394 {
0395     struct imx_tpm_pwm_chip *tpm = dev_get_drvdata(dev);
0396 
0397     if (tpm->enable_count > 0)
0398         return -EBUSY;
0399 
0400     clk_disable_unprepare(tpm->clk);
0401 
0402     return 0;
0403 }
0404 
0405 static int __maybe_unused pwm_imx_tpm_resume(struct device *dev)
0406 {
0407     struct imx_tpm_pwm_chip *tpm = dev_get_drvdata(dev);
0408     int ret = 0;
0409 
0410     ret = clk_prepare_enable(tpm->clk);
0411     if (ret)
0412         dev_err(dev, "failed to prepare or enable clock: %d\n", ret);
0413 
0414     return ret;
0415 }
0416 
0417 static SIMPLE_DEV_PM_OPS(imx_tpm_pwm_pm,
0418              pwm_imx_tpm_suspend, pwm_imx_tpm_resume);
0419 
0420 static const struct of_device_id imx_tpm_pwm_dt_ids[] = {
0421     { .compatible = "fsl,imx7ulp-pwm", },
0422     { /* sentinel */ }
0423 };
0424 MODULE_DEVICE_TABLE(of, imx_tpm_pwm_dt_ids);
0425 
0426 static struct platform_driver imx_tpm_pwm_driver = {
0427     .driver = {
0428         .name = "imx7ulp-tpm-pwm",
0429         .of_match_table = imx_tpm_pwm_dt_ids,
0430         .pm = &imx_tpm_pwm_pm,
0431     },
0432     .probe  = pwm_imx_tpm_probe,
0433     .remove = pwm_imx_tpm_remove,
0434 };
0435 module_platform_driver(imx_tpm_pwm_driver);
0436 
0437 MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
0438 MODULE_DESCRIPTION("i.MX TPM PWM Driver");
0439 MODULE_LICENSE("GPL v2");