287 lines · c
1/*2 * Marvell Berlin PWM driver3 *4 * Copyright (C) 2015 Marvell Technology Group Ltd.5 *6 * Author: Antoine Tenart <antoine.tenart@free-electrons.com>7 *8 * This file is licensed under the terms of the GNU General Public9 * License version 2. This program is licensed "as is" without any10 * warranty of any kind, whether express or implied.11 */12 13#include <linux/clk.h>14#include <linux/io.h>15#include <linux/kernel.h>16#include <linux/mod_devicetable.h>17#include <linux/module.h>18#include <linux/platform_device.h>19#include <linux/pwm.h>20#include <linux/slab.h>21 22#define BERLIN_PWM_EN 0x023#define BERLIN_PWM_ENABLE BIT(0)24#define BERLIN_PWM_CONTROL 0x425/*26 * The prescaler claims to support 8 different moduli, configured using the27 * low three bits of PWM_CONTROL. (Sequentially, they are 1, 4, 8, 16, 64,28 * 256, 1024, and 4096.) However, the moduli from 4 to 1024 appear to be29 * implemented by internally shifting TCNT left without adding additional30 * bits. So, the max TCNT that actually works for a modulus of 4 is 0x3fff;31 * for 8, 0x1fff; and so on. This means that those moduli are entirely32 * useless, as we could just do the shift ourselves. The 4096 modulus is33 * implemented with a real prescaler, so we do use that, but we treat it34 * as a flag instead of pretending the modulus is actually configurable.35 */36#define BERLIN_PWM_PRESCALE_4096 0x737#define BERLIN_PWM_INVERT_POLARITY BIT(3)38#define BERLIN_PWM_DUTY 0x839#define BERLIN_PWM_TCNT 0xc40#define BERLIN_PWM_MAX_TCNT 6553541 42#define BERLIN_PWM_NUMPWMS 443 44struct berlin_pwm_channel {45 u32 enable;46 u32 ctrl;47 u32 duty;48 u32 tcnt;49};50 51struct berlin_pwm_chip {52 struct clk *clk;53 void __iomem *base;54 struct berlin_pwm_channel channel[BERLIN_PWM_NUMPWMS];55};56 57static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip)58{59 return pwmchip_get_drvdata(chip);60}61 62static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *bpc,63 unsigned int channel, unsigned long offset)64{65 return readl_relaxed(bpc->base + channel * 0x10 + offset);66}67 68static inline void berlin_pwm_writel(struct berlin_pwm_chip *bpc,69 unsigned int channel, u32 value,70 unsigned long offset)71{72 writel_relaxed(value, bpc->base + channel * 0x10 + offset);73}74 75static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,76 u64 duty_ns, u64 period_ns)77{78 struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);79 bool prescale_4096 = false;80 u32 value, duty, period;81 u64 cycles;82 83 cycles = clk_get_rate(bpc->clk);84 cycles *= period_ns;85 do_div(cycles, NSEC_PER_SEC);86 87 if (cycles > BERLIN_PWM_MAX_TCNT) {88 prescale_4096 = true;89 cycles >>= 12; // Prescaled by 409690 91 if (cycles > BERLIN_PWM_MAX_TCNT)92 return -ERANGE;93 }94 95 period = cycles;96 cycles *= duty_ns;97 do_div(cycles, period_ns);98 duty = cycles;99 100 value = berlin_pwm_readl(bpc, pwm->hwpwm, BERLIN_PWM_CONTROL);101 if (prescale_4096)102 value |= BERLIN_PWM_PRESCALE_4096;103 else104 value &= ~BERLIN_PWM_PRESCALE_4096;105 berlin_pwm_writel(bpc, pwm->hwpwm, value, BERLIN_PWM_CONTROL);106 107 berlin_pwm_writel(bpc, pwm->hwpwm, duty, BERLIN_PWM_DUTY);108 berlin_pwm_writel(bpc, pwm->hwpwm, period, BERLIN_PWM_TCNT);109 110 return 0;111}112 113static int berlin_pwm_set_polarity(struct pwm_chip *chip,114 struct pwm_device *pwm,115 enum pwm_polarity polarity)116{117 struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);118 u32 value;119 120 value = berlin_pwm_readl(bpc, pwm->hwpwm, BERLIN_PWM_CONTROL);121 122 if (polarity == PWM_POLARITY_NORMAL)123 value &= ~BERLIN_PWM_INVERT_POLARITY;124 else125 value |= BERLIN_PWM_INVERT_POLARITY;126 127 berlin_pwm_writel(bpc, pwm->hwpwm, value, BERLIN_PWM_CONTROL);128 129 return 0;130}131 132static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)133{134 struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);135 u32 value;136 137 value = berlin_pwm_readl(bpc, pwm->hwpwm, BERLIN_PWM_EN);138 value |= BERLIN_PWM_ENABLE;139 berlin_pwm_writel(bpc, pwm->hwpwm, value, BERLIN_PWM_EN);140 141 return 0;142}143 144static void berlin_pwm_disable(struct pwm_chip *chip,145 struct pwm_device *pwm)146{147 struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);148 u32 value;149 150 value = berlin_pwm_readl(bpc, pwm->hwpwm, BERLIN_PWM_EN);151 value &= ~BERLIN_PWM_ENABLE;152 berlin_pwm_writel(bpc, pwm->hwpwm, value, BERLIN_PWM_EN);153}154 155static int berlin_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,156 const struct pwm_state *state)157{158 int err;159 bool enabled = pwm->state.enabled;160 161 if (state->polarity != pwm->state.polarity) {162 if (enabled) {163 berlin_pwm_disable(chip, pwm);164 enabled = false;165 }166 167 err = berlin_pwm_set_polarity(chip, pwm, state->polarity);168 if (err)169 return err;170 }171 172 if (!state->enabled) {173 if (enabled)174 berlin_pwm_disable(chip, pwm);175 return 0;176 }177 178 err = berlin_pwm_config(chip, pwm, state->duty_cycle, state->period);179 if (err)180 return err;181 182 if (!enabled)183 return berlin_pwm_enable(chip, pwm);184 185 return 0;186}187 188static const struct pwm_ops berlin_pwm_ops = {189 .apply = berlin_pwm_apply,190};191 192static const struct of_device_id berlin_pwm_match[] = {193 { .compatible = "marvell,berlin-pwm" },194 { },195};196MODULE_DEVICE_TABLE(of, berlin_pwm_match);197 198static int berlin_pwm_probe(struct platform_device *pdev)199{200 struct pwm_chip *chip;201 struct berlin_pwm_chip *bpc;202 int ret;203 204 chip = devm_pwmchip_alloc(&pdev->dev, BERLIN_PWM_NUMPWMS, sizeof(*bpc));205 if (IS_ERR(chip))206 return PTR_ERR(chip);207 bpc = to_berlin_pwm_chip(chip);208 209 bpc->base = devm_platform_ioremap_resource(pdev, 0);210 if (IS_ERR(bpc->base))211 return PTR_ERR(bpc->base);212 213 bpc->clk = devm_clk_get_enabled(&pdev->dev, NULL);214 if (IS_ERR(bpc->clk))215 return PTR_ERR(bpc->clk);216 217 chip->ops = &berlin_pwm_ops;218 219 ret = devm_pwmchip_add(&pdev->dev, chip);220 if (ret < 0)221 return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");222 223 platform_set_drvdata(pdev, chip);224 225 return 0;226}227 228static int berlin_pwm_suspend(struct device *dev)229{230 struct pwm_chip *chip = dev_get_drvdata(dev);231 struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);232 unsigned int i;233 234 for (i = 0; i < chip->npwm; i++) {235 struct berlin_pwm_channel *channel = &bpc->channel[i];236 237 channel->enable = berlin_pwm_readl(bpc, i, BERLIN_PWM_ENABLE);238 channel->ctrl = berlin_pwm_readl(bpc, i, BERLIN_PWM_CONTROL);239 channel->duty = berlin_pwm_readl(bpc, i, BERLIN_PWM_DUTY);240 channel->tcnt = berlin_pwm_readl(bpc, i, BERLIN_PWM_TCNT);241 }242 243 clk_disable_unprepare(bpc->clk);244 245 return 0;246}247 248static int berlin_pwm_resume(struct device *dev)249{250 struct pwm_chip *chip = dev_get_drvdata(dev);251 struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);252 unsigned int i;253 int ret;254 255 ret = clk_prepare_enable(bpc->clk);256 if (ret)257 return ret;258 259 for (i = 0; i < chip->npwm; i++) {260 struct berlin_pwm_channel *channel = &bpc->channel[i];261 262 berlin_pwm_writel(bpc, i, channel->ctrl, BERLIN_PWM_CONTROL);263 berlin_pwm_writel(bpc, i, channel->duty, BERLIN_PWM_DUTY);264 berlin_pwm_writel(bpc, i, channel->tcnt, BERLIN_PWM_TCNT);265 berlin_pwm_writel(bpc, i, channel->enable, BERLIN_PWM_ENABLE);266 }267 268 return 0;269}270 271static DEFINE_SIMPLE_DEV_PM_OPS(berlin_pwm_pm_ops, berlin_pwm_suspend,272 berlin_pwm_resume);273 274static struct platform_driver berlin_pwm_driver = {275 .probe = berlin_pwm_probe,276 .driver = {277 .name = "berlin-pwm",278 .of_match_table = berlin_pwm_match,279 .pm = pm_ptr(&berlin_pwm_pm_ops),280 },281};282module_platform_driver(berlin_pwm_driver);283 284MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");285MODULE_DESCRIPTION("Marvell Berlin PWM driver");286MODULE_LICENSE("GPL v2");287