Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2019 Spreadtrum Communications Inc.
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/err.h>
0008 #include <linux/io.h>
0009 #include <linux/math64.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/pwm.h>
0013 
0014 #define SPRD_PWM_PRESCALE   0x0
0015 #define SPRD_PWM_MOD        0x4
0016 #define SPRD_PWM_DUTY       0x8
0017 #define SPRD_PWM_ENABLE     0x18
0018 
0019 #define SPRD_PWM_MOD_MAX    GENMASK(7, 0)
0020 #define SPRD_PWM_DUTY_MSK   GENMASK(15, 0)
0021 #define SPRD_PWM_PRESCALE_MSK   GENMASK(7, 0)
0022 #define SPRD_PWM_ENABLE_BIT BIT(0)
0023 
0024 #define SPRD_PWM_CHN_NUM    4
0025 #define SPRD_PWM_REGS_SHIFT 5
0026 #define SPRD_PWM_CHN_CLKS_NUM   2
0027 #define SPRD_PWM_CHN_OUTPUT_CLK 1
0028 
0029 struct sprd_pwm_chn {
0030     struct clk_bulk_data clks[SPRD_PWM_CHN_CLKS_NUM];
0031     u32 clk_rate;
0032 };
0033 
0034 struct sprd_pwm_chip {
0035     void __iomem *base;
0036     struct device *dev;
0037     struct pwm_chip chip;
0038     int num_pwms;
0039     struct sprd_pwm_chn chn[SPRD_PWM_CHN_NUM];
0040 };
0041 
0042 /*
0043  * The list of clocks required by PWM channels, and each channel has 2 clocks:
0044  * enable clock and pwm clock.
0045  */
0046 static const char * const sprd_pwm_clks[] = {
0047     "enable0", "pwm0",
0048     "enable1", "pwm1",
0049     "enable2", "pwm2",
0050     "enable3", "pwm3",
0051 };
0052 
0053 static u32 sprd_pwm_read(struct sprd_pwm_chip *spc, u32 hwid, u32 reg)
0054 {
0055     u32 offset = reg + (hwid << SPRD_PWM_REGS_SHIFT);
0056 
0057     return readl_relaxed(spc->base + offset);
0058 }
0059 
0060 static void sprd_pwm_write(struct sprd_pwm_chip *spc, u32 hwid,
0061                u32 reg, u32 val)
0062 {
0063     u32 offset = reg + (hwid << SPRD_PWM_REGS_SHIFT);
0064 
0065     writel_relaxed(val, spc->base + offset);
0066 }
0067 
0068 static void sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
0069                    struct pwm_state *state)
0070 {
0071     struct sprd_pwm_chip *spc =
0072         container_of(chip, struct sprd_pwm_chip, chip);
0073     struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm];
0074     u32 val, duty, prescale;
0075     u64 tmp;
0076     int ret;
0077 
0078     /*
0079      * The clocks to PWM channel has to be enabled first before
0080      * reading to the registers.
0081      */
0082     ret = clk_bulk_prepare_enable(SPRD_PWM_CHN_CLKS_NUM, chn->clks);
0083     if (ret) {
0084         dev_err(spc->dev, "failed to enable pwm%u clocks\n",
0085             pwm->hwpwm);
0086         return;
0087     }
0088 
0089     val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_ENABLE);
0090     if (val & SPRD_PWM_ENABLE_BIT)
0091         state->enabled = true;
0092     else
0093         state->enabled = false;
0094 
0095     /*
0096      * The hardware provides a counter that is feed by the source clock.
0097      * The period length is (PRESCALE + 1) * MOD counter steps.
0098      * The duty cycle length is (PRESCALE + 1) * DUTY counter steps.
0099      * Thus the period_ns and duty_ns calculation formula should be:
0100      * period_ns = NSEC_PER_SEC * (prescale + 1) * mod / clk_rate
0101      * duty_ns = NSEC_PER_SEC * (prescale + 1) * duty / clk_rate
0102      */
0103     val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_PRESCALE);
0104     prescale = val & SPRD_PWM_PRESCALE_MSK;
0105     tmp = (prescale + 1) * NSEC_PER_SEC * SPRD_PWM_MOD_MAX;
0106     state->period = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate);
0107 
0108     val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_DUTY);
0109     duty = val & SPRD_PWM_DUTY_MSK;
0110     tmp = (prescale + 1) * NSEC_PER_SEC * duty;
0111     state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate);
0112 
0113     /* Disable PWM clocks if the PWM channel is not in enable state. */
0114     if (!state->enabled)
0115         clk_bulk_disable_unprepare(SPRD_PWM_CHN_CLKS_NUM, chn->clks);
0116 }
0117 
0118 static int sprd_pwm_config(struct sprd_pwm_chip *spc, struct pwm_device *pwm,
0119                int duty_ns, int period_ns)
0120 {
0121     struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm];
0122     u32 prescale, duty;
0123     u64 tmp;
0124 
0125     /*
0126      * The hardware provides a counter that is feed by the source clock.
0127      * The period length is (PRESCALE + 1) * MOD counter steps.
0128      * The duty cycle length is (PRESCALE + 1) * DUTY counter steps.
0129      *
0130      * To keep the maths simple we're always using MOD = SPRD_PWM_MOD_MAX.
0131      * The value for PRESCALE is selected such that the resulting period
0132      * gets the maximal length not bigger than the requested one with the
0133      * given settings (MOD = SPRD_PWM_MOD_MAX and input clock).
0134      */
0135     duty = duty_ns * SPRD_PWM_MOD_MAX / period_ns;
0136 
0137     tmp = (u64)chn->clk_rate * period_ns;
0138     do_div(tmp, NSEC_PER_SEC);
0139     prescale = DIV_ROUND_CLOSEST_ULL(tmp, SPRD_PWM_MOD_MAX) - 1;
0140     if (prescale > SPRD_PWM_PRESCALE_MSK)
0141         prescale = SPRD_PWM_PRESCALE_MSK;
0142 
0143     /*
0144      * Note: Writing DUTY triggers the hardware to actually apply the
0145      * values written to MOD and DUTY to the output, so must keep writing
0146      * DUTY last.
0147      *
0148      * The hardware can ensures that current running period is completed
0149      * before changing a new configuration to avoid mixed settings.
0150      */
0151     sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_PRESCALE, prescale);
0152     sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_MOD, SPRD_PWM_MOD_MAX);
0153     sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_DUTY, duty);
0154 
0155     return 0;
0156 }
0157 
0158 static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0159               const struct pwm_state *state)
0160 {
0161     struct sprd_pwm_chip *spc =
0162         container_of(chip, struct sprd_pwm_chip, chip);
0163     struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm];
0164     struct pwm_state *cstate = &pwm->state;
0165     int ret;
0166 
0167     if (state->polarity != PWM_POLARITY_NORMAL)
0168         return -EINVAL;
0169 
0170     if (state->enabled) {
0171         if (!cstate->enabled) {
0172             /*
0173              * The clocks to PWM channel has to be enabled first
0174              * before writing to the registers.
0175              */
0176             ret = clk_bulk_prepare_enable(SPRD_PWM_CHN_CLKS_NUM,
0177                               chn->clks);
0178             if (ret) {
0179                 dev_err(spc->dev,
0180                     "failed to enable pwm%u clocks\n",
0181                     pwm->hwpwm);
0182                 return ret;
0183             }
0184         }
0185 
0186         ret = sprd_pwm_config(spc, pwm, state->duty_cycle,
0187                       state->period);
0188         if (ret)
0189             return ret;
0190 
0191         sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 1);
0192     } else if (cstate->enabled) {
0193         /*
0194          * Note: After setting SPRD_PWM_ENABLE to zero, the controller
0195          * will not wait for current period to be completed, instead it
0196          * will stop the PWM channel immediately.
0197          */
0198         sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 0);
0199 
0200         clk_bulk_disable_unprepare(SPRD_PWM_CHN_CLKS_NUM, chn->clks);
0201     }
0202 
0203     return 0;
0204 }
0205 
0206 static const struct pwm_ops sprd_pwm_ops = {
0207     .apply = sprd_pwm_apply,
0208     .get_state = sprd_pwm_get_state,
0209     .owner = THIS_MODULE,
0210 };
0211 
0212 static int sprd_pwm_clk_init(struct sprd_pwm_chip *spc)
0213 {
0214     struct clk *clk_pwm;
0215     int ret, i;
0216 
0217     for (i = 0; i < SPRD_PWM_CHN_NUM; i++) {
0218         struct sprd_pwm_chn *chn = &spc->chn[i];
0219         int j;
0220 
0221         for (j = 0; j < SPRD_PWM_CHN_CLKS_NUM; ++j)
0222             chn->clks[j].id =
0223                 sprd_pwm_clks[i * SPRD_PWM_CHN_CLKS_NUM + j];
0224 
0225         ret = devm_clk_bulk_get(spc->dev, SPRD_PWM_CHN_CLKS_NUM,
0226                     chn->clks);
0227         if (ret) {
0228             if (ret == -ENOENT)
0229                 break;
0230 
0231             return dev_err_probe(spc->dev, ret,
0232                          "failed to get channel clocks\n");
0233         }
0234 
0235         clk_pwm = chn->clks[SPRD_PWM_CHN_OUTPUT_CLK].clk;
0236         chn->clk_rate = clk_get_rate(clk_pwm);
0237     }
0238 
0239     if (!i) {
0240         dev_err(spc->dev, "no available PWM channels\n");
0241         return -ENODEV;
0242     }
0243 
0244     spc->num_pwms = i;
0245 
0246     return 0;
0247 }
0248 
0249 static int sprd_pwm_probe(struct platform_device *pdev)
0250 {
0251     struct sprd_pwm_chip *spc;
0252     int ret;
0253 
0254     spc = devm_kzalloc(&pdev->dev, sizeof(*spc), GFP_KERNEL);
0255     if (!spc)
0256         return -ENOMEM;
0257 
0258     spc->base = devm_platform_ioremap_resource(pdev, 0);
0259     if (IS_ERR(spc->base))
0260         return PTR_ERR(spc->base);
0261 
0262     spc->dev = &pdev->dev;
0263     platform_set_drvdata(pdev, spc);
0264 
0265     ret = sprd_pwm_clk_init(spc);
0266     if (ret)
0267         return ret;
0268 
0269     spc->chip.dev = &pdev->dev;
0270     spc->chip.ops = &sprd_pwm_ops;
0271     spc->chip.npwm = spc->num_pwms;
0272 
0273     ret = pwmchip_add(&spc->chip);
0274     if (ret)
0275         dev_err(&pdev->dev, "failed to add PWM chip\n");
0276 
0277     return ret;
0278 }
0279 
0280 static int sprd_pwm_remove(struct platform_device *pdev)
0281 {
0282     struct sprd_pwm_chip *spc = platform_get_drvdata(pdev);
0283 
0284     pwmchip_remove(&spc->chip);
0285 
0286     return 0;
0287 }
0288 
0289 static const struct of_device_id sprd_pwm_of_match[] = {
0290     { .compatible = "sprd,ums512-pwm", },
0291     { },
0292 };
0293 MODULE_DEVICE_TABLE(of, sprd_pwm_of_match);
0294 
0295 static struct platform_driver sprd_pwm_driver = {
0296     .driver = {
0297         .name = "sprd-pwm",
0298         .of_match_table = sprd_pwm_of_match,
0299     },
0300     .probe = sprd_pwm_probe,
0301     .remove = sprd_pwm_remove,
0302 };
0303 
0304 module_platform_driver(sprd_pwm_driver);
0305 
0306 MODULE_DESCRIPTION("Spreadtrum PWM Driver");
0307 MODULE_LICENSE("GPL v2");