root/drivers/pwm/pwm-bcm-kona.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_kona_pwmc
  2. kona_pwmc_prepare_for_settings
  3. kona_pwmc_apply_settings
  4. kona_pwmc_config
  5. kona_pwmc_set_polarity
  6. kona_pwmc_enable
  7. kona_pwmc_disable
  8. kona_pwmc_probe
  9. kona_pwmc_remove

   1 /*
   2  * Copyright (C) 2014 Broadcom Corporation
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License as
   6  * published by the Free Software Foundation version 2.
   7  *
   8  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
   9  * kind, whether express or implied; without even the implied warranty
  10  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11  * GNU General Public License for more details.
  12  */
  13 
  14 #include <linux/clk.h>
  15 #include <linux/delay.h>
  16 #include <linux/err.h>
  17 #include <linux/io.h>
  18 #include <linux/ioport.h>
  19 #include <linux/math64.h>
  20 #include <linux/module.h>
  21 #include <linux/of.h>
  22 #include <linux/platform_device.h>
  23 #include <linux/pwm.h>
  24 #include <linux/slab.h>
  25 #include <linux/types.h>
  26 
  27 /*
  28  * The Kona PWM has some unusual characteristics.  Here are the main points.
  29  *
  30  * 1) There is no disable bit and the hardware docs advise programming a zero
  31  *    duty to achieve output equivalent to that of a normal disable operation.
  32  *
  33  * 2) Changes to prescale, duty, period, and polarity do not take effect until
  34  *    a subsequent rising edge of the trigger bit.
  35  *
  36  * 3) If the smooth bit and trigger bit are both low, the output is a constant
  37  *    high signal.  Otherwise, the earlier waveform continues to be output.
  38  *
  39  * 4) If the smooth bit is set on the rising edge of the trigger bit, output
  40  *    will transition to the new settings on a period boundary (which could be
  41  *    seconds away).  If the smooth bit is clear, new settings will be applied
  42  *    as soon as possible (the hardware always has a 400ns delay).
  43  *
  44  * 5) When the external clock that feeds the PWM is disabled, output is pegged
  45  *    high or low depending on its state at that exact instant.
  46  */
  47 
  48 #define PWM_CONTROL_OFFSET                      0x00000000
  49 #define PWM_CONTROL_SMOOTH_SHIFT(chan)          (24 + (chan))
  50 #define PWM_CONTROL_TYPE_SHIFT(chan)            (16 + (chan))
  51 #define PWM_CONTROL_POLARITY_SHIFT(chan)        (8 + (chan))
  52 #define PWM_CONTROL_TRIGGER_SHIFT(chan)         (chan)
  53 
  54 #define PRESCALE_OFFSET                         0x00000004
  55 #define PRESCALE_SHIFT(chan)                    ((chan) << 2)
  56 #define PRESCALE_MASK(chan)                     (0x7 << PRESCALE_SHIFT(chan))
  57 #define PRESCALE_MIN                            0x00000000
  58 #define PRESCALE_MAX                            0x00000007
  59 
  60 #define PERIOD_COUNT_OFFSET(chan)               (0x00000008 + ((chan) << 3))
  61 #define PERIOD_COUNT_MIN                        0x00000002
  62 #define PERIOD_COUNT_MAX                        0x00ffffff
  63 
  64 #define DUTY_CYCLE_HIGH_OFFSET(chan)            (0x0000000c + ((chan) << 3))
  65 #define DUTY_CYCLE_HIGH_MIN                     0x00000000
  66 #define DUTY_CYCLE_HIGH_MAX                     0x00ffffff
  67 
  68 struct kona_pwmc {
  69         struct pwm_chip chip;
  70         void __iomem *base;
  71         struct clk *clk;
  72 };
  73 
  74 static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *_chip)
  75 {
  76         return container_of(_chip, struct kona_pwmc, chip);
  77 }
  78 
  79 /*
  80  * Clear trigger bit but set smooth bit to maintain old output.
  81  */
  82 static void kona_pwmc_prepare_for_settings(struct kona_pwmc *kp,
  83         unsigned int chan)
  84 {
  85         unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
  86 
  87         value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
  88         value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
  89         writel(value, kp->base + PWM_CONTROL_OFFSET);
  90 
  91         /*
  92          * There must be a min 400ns delay between clearing trigger and setting
  93          * it. Failing to do this may result in no PWM signal.
  94          */
  95         ndelay(400);
  96 }
  97 
  98 static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
  99 {
 100         unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
 101 
 102         /* Set trigger bit and clear smooth bit to apply new settings */
 103         value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
 104         value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
 105         writel(value, kp->base + PWM_CONTROL_OFFSET);
 106 
 107         /* Trigger bit must be held high for at least 400 ns. */
 108         ndelay(400);
 109 }
 110 
 111 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 112                             int duty_ns, int period_ns)
 113 {
 114         struct kona_pwmc *kp = to_kona_pwmc(chip);
 115         u64 val, div, rate;
 116         unsigned long prescale = PRESCALE_MIN, pc, dc;
 117         unsigned int value, chan = pwm->hwpwm;
 118 
 119         /*
 120          * Find period count, duty count and prescale to suit duty_ns and
 121          * period_ns. This is done according to formulas described below:
 122          *
 123          * period_ns = 10^9 * (PRESCALE + 1) * PC / PWM_CLK_RATE
 124          * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
 125          *
 126          * PC = (PWM_CLK_RATE * period_ns) / (10^9 * (PRESCALE + 1))
 127          * DC = (PWM_CLK_RATE * duty_ns) / (10^9 * (PRESCALE + 1))
 128          */
 129 
 130         rate = clk_get_rate(kp->clk);
 131 
 132         while (1) {
 133                 div = 1000000000;
 134                 div *= 1 + prescale;
 135                 val = rate * period_ns;
 136                 pc = div64_u64(val, div);
 137                 val = rate * duty_ns;
 138                 dc = div64_u64(val, div);
 139 
 140                 /* If duty_ns or period_ns are not achievable then return */
 141                 if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
 142                         return -EINVAL;
 143 
 144                 /* If pc and dc are in bounds, the calculation is done */
 145                 if (pc <= PERIOD_COUNT_MAX && dc <= DUTY_CYCLE_HIGH_MAX)
 146                         break;
 147 
 148                 /* Otherwise, increase prescale and recalculate pc and dc */
 149                 if (++prescale > PRESCALE_MAX)
 150                         return -EINVAL;
 151         }
 152 
 153         /*
 154          * Don't apply settings if disabled. The period and duty cycle are
 155          * always calculated above to ensure the new values are
 156          * validated immediately instead of on enable.
 157          */
 158         if (pwm_is_enabled(pwm)) {
 159                 kona_pwmc_prepare_for_settings(kp, chan);
 160 
 161                 value = readl(kp->base + PRESCALE_OFFSET);
 162                 value &= ~PRESCALE_MASK(chan);
 163                 value |= prescale << PRESCALE_SHIFT(chan);
 164                 writel(value, kp->base + PRESCALE_OFFSET);
 165 
 166                 writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
 167 
 168                 writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
 169 
 170                 kona_pwmc_apply_settings(kp, chan);
 171         }
 172 
 173         return 0;
 174 }
 175 
 176 static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 177                                   enum pwm_polarity polarity)
 178 {
 179         struct kona_pwmc *kp = to_kona_pwmc(chip);
 180         unsigned int chan = pwm->hwpwm;
 181         unsigned int value;
 182         int ret;
 183 
 184         ret = clk_prepare_enable(kp->clk);
 185         if (ret < 0) {
 186                 dev_err(chip->dev, "failed to enable clock: %d\n", ret);
 187                 return ret;
 188         }
 189 
 190         kona_pwmc_prepare_for_settings(kp, chan);
 191 
 192         value = readl(kp->base + PWM_CONTROL_OFFSET);
 193 
 194         if (polarity == PWM_POLARITY_NORMAL)
 195                 value |= 1 << PWM_CONTROL_POLARITY_SHIFT(chan);
 196         else
 197                 value &= ~(1 << PWM_CONTROL_POLARITY_SHIFT(chan));
 198 
 199         writel(value, kp->base + PWM_CONTROL_OFFSET);
 200 
 201         kona_pwmc_apply_settings(kp, chan);
 202 
 203         clk_disable_unprepare(kp->clk);
 204 
 205         return 0;
 206 }
 207 
 208 static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 209 {
 210         struct kona_pwmc *kp = to_kona_pwmc(chip);
 211         int ret;
 212 
 213         ret = clk_prepare_enable(kp->clk);
 214         if (ret < 0) {
 215                 dev_err(chip->dev, "failed to enable clock: %d\n", ret);
 216                 return ret;
 217         }
 218 
 219         ret = kona_pwmc_config(chip, pwm, pwm_get_duty_cycle(pwm),
 220                                pwm_get_period(pwm));
 221         if (ret < 0) {
 222                 clk_disable_unprepare(kp->clk);
 223                 return ret;
 224         }
 225 
 226         return 0;
 227 }
 228 
 229 static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 230 {
 231         struct kona_pwmc *kp = to_kona_pwmc(chip);
 232         unsigned int chan = pwm->hwpwm;
 233         unsigned int value;
 234 
 235         kona_pwmc_prepare_for_settings(kp, chan);
 236 
 237         /* Simulate a disable by configuring for zero duty */
 238         writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
 239         writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 240 
 241         /* Set prescale to 0 for this channel */
 242         value = readl(kp->base + PRESCALE_OFFSET);
 243         value &= ~PRESCALE_MASK(chan);
 244         writel(value, kp->base + PRESCALE_OFFSET);
 245 
 246         kona_pwmc_apply_settings(kp, chan);
 247 
 248         clk_disable_unprepare(kp->clk);
 249 }
 250 
 251 static const struct pwm_ops kona_pwm_ops = {
 252         .config = kona_pwmc_config,
 253         .set_polarity = kona_pwmc_set_polarity,
 254         .enable = kona_pwmc_enable,
 255         .disable = kona_pwmc_disable,
 256         .owner = THIS_MODULE,
 257 };
 258 
 259 static int kona_pwmc_probe(struct platform_device *pdev)
 260 {
 261         struct kona_pwmc *kp;
 262         struct resource *res;
 263         unsigned int chan;
 264         unsigned int value = 0;
 265         int ret = 0;
 266 
 267         kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL);
 268         if (kp == NULL)
 269                 return -ENOMEM;
 270 
 271         platform_set_drvdata(pdev, kp);
 272 
 273         kp->chip.dev = &pdev->dev;
 274         kp->chip.ops = &kona_pwm_ops;
 275         kp->chip.base = -1;
 276         kp->chip.npwm = 6;
 277         kp->chip.of_xlate = of_pwm_xlate_with_flags;
 278         kp->chip.of_pwm_n_cells = 3;
 279 
 280         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 281         kp->base = devm_ioremap_resource(&pdev->dev, res);
 282         if (IS_ERR(kp->base))
 283                 return PTR_ERR(kp->base);
 284 
 285         kp->clk = devm_clk_get(&pdev->dev, NULL);
 286         if (IS_ERR(kp->clk)) {
 287                 dev_err(&pdev->dev, "failed to get clock: %ld\n",
 288                         PTR_ERR(kp->clk));
 289                 return PTR_ERR(kp->clk);
 290         }
 291 
 292         ret = clk_prepare_enable(kp->clk);
 293         if (ret < 0) {
 294                 dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
 295                 return ret;
 296         }
 297 
 298         /* Set push/pull for all channels */
 299         for (chan = 0; chan < kp->chip.npwm; chan++)
 300                 value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan));
 301 
 302         writel(value, kp->base + PWM_CONTROL_OFFSET);
 303 
 304         clk_disable_unprepare(kp->clk);
 305 
 306         ret = pwmchip_add_with_polarity(&kp->chip, PWM_POLARITY_INVERSED);
 307         if (ret < 0)
 308                 dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
 309 
 310         return ret;
 311 }
 312 
 313 static int kona_pwmc_remove(struct platform_device *pdev)
 314 {
 315         struct kona_pwmc *kp = platform_get_drvdata(pdev);
 316         unsigned int chan;
 317 
 318         for (chan = 0; chan < kp->chip.npwm; chan++)
 319                 if (pwm_is_enabled(&kp->chip.pwms[chan]))
 320                         clk_disable_unprepare(kp->clk);
 321 
 322         return pwmchip_remove(&kp->chip);
 323 }
 324 
 325 static const struct of_device_id bcm_kona_pwmc_dt[] = {
 326         { .compatible = "brcm,kona-pwm" },
 327         { },
 328 };
 329 MODULE_DEVICE_TABLE(of, bcm_kona_pwmc_dt);
 330 
 331 static struct platform_driver kona_pwmc_driver = {
 332         .driver = {
 333                 .name = "bcm-kona-pwm",
 334                 .of_match_table = bcm_kona_pwmc_dt,
 335         },
 336         .probe = kona_pwmc_probe,
 337         .remove = kona_pwmc_remove,
 338 };
 339 module_platform_driver(kona_pwmc_driver);
 340 
 341 MODULE_AUTHOR("Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>");
 342 MODULE_AUTHOR("Tim Kryger <tkryger@broadcom.com>");
 343 MODULE_DESCRIPTION("Broadcom Kona PWM driver");
 344 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */