0001
0002
0003
0004 #include <linux/clk.h>
0005 #include <linux/delay.h>
0006 #include <linux/err.h>
0007 #include <linux/io.h>
0008 #include <linux/math64.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/pwm.h>
0013
0014 #define IPROC_PWM_CTRL_OFFSET 0x00
0015 #define IPROC_PWM_CTRL_TYPE_SHIFT(ch) (15 + (ch))
0016 #define IPROC_PWM_CTRL_POLARITY_SHIFT(ch) (8 + (ch))
0017 #define IPROC_PWM_CTRL_EN_SHIFT(ch) (ch)
0018
0019 #define IPROC_PWM_PERIOD_OFFSET(ch) (0x04 + ((ch) << 3))
0020 #define IPROC_PWM_PERIOD_MIN 0x02
0021 #define IPROC_PWM_PERIOD_MAX 0xffff
0022
0023 #define IPROC_PWM_DUTY_CYCLE_OFFSET(ch) (0x08 + ((ch) << 3))
0024 #define IPROC_PWM_DUTY_CYCLE_MIN 0x00
0025 #define IPROC_PWM_DUTY_CYCLE_MAX 0xffff
0026
0027 #define IPROC_PWM_PRESCALE_OFFSET 0x24
0028 #define IPROC_PWM_PRESCALE_BITS 0x06
0029 #define IPROC_PWM_PRESCALE_SHIFT(ch) ((3 - (ch)) * \
0030 IPROC_PWM_PRESCALE_BITS)
0031 #define IPROC_PWM_PRESCALE_MASK(ch) (IPROC_PWM_PRESCALE_MAX << \
0032 IPROC_PWM_PRESCALE_SHIFT(ch))
0033 #define IPROC_PWM_PRESCALE_MIN 0x00
0034 #define IPROC_PWM_PRESCALE_MAX 0x3f
0035
0036 struct iproc_pwmc {
0037 struct pwm_chip chip;
0038 void __iomem *base;
0039 struct clk *clk;
0040 };
0041
0042 static inline struct iproc_pwmc *to_iproc_pwmc(struct pwm_chip *chip)
0043 {
0044 return container_of(chip, struct iproc_pwmc, chip);
0045 }
0046
0047 static void iproc_pwmc_enable(struct iproc_pwmc *ip, unsigned int channel)
0048 {
0049 u32 value;
0050
0051 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
0052 value |= 1 << IPROC_PWM_CTRL_EN_SHIFT(channel);
0053 writel(value, ip->base + IPROC_PWM_CTRL_OFFSET);
0054
0055
0056 ndelay(400);
0057 }
0058
0059 static void iproc_pwmc_disable(struct iproc_pwmc *ip, unsigned int channel)
0060 {
0061 u32 value;
0062
0063 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
0064 value &= ~(1 << IPROC_PWM_CTRL_EN_SHIFT(channel));
0065 writel(value, ip->base + IPROC_PWM_CTRL_OFFSET);
0066
0067
0068 ndelay(400);
0069 }
0070
0071 static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
0072 struct pwm_state *state)
0073 {
0074 struct iproc_pwmc *ip = to_iproc_pwmc(chip);
0075 u64 tmp, multi, rate;
0076 u32 value, prescale;
0077
0078 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
0079
0080 if (value & BIT(IPROC_PWM_CTRL_EN_SHIFT(pwm->hwpwm)))
0081 state->enabled = true;
0082 else
0083 state->enabled = false;
0084
0085 if (value & BIT(IPROC_PWM_CTRL_POLARITY_SHIFT(pwm->hwpwm)))
0086 state->polarity = PWM_POLARITY_NORMAL;
0087 else
0088 state->polarity = PWM_POLARITY_INVERSED;
0089
0090 rate = clk_get_rate(ip->clk);
0091 if (rate == 0) {
0092 state->period = 0;
0093 state->duty_cycle = 0;
0094 return;
0095 }
0096
0097 value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET);
0098 prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm);
0099 prescale &= IPROC_PWM_PRESCALE_MAX;
0100
0101 multi = NSEC_PER_SEC * (prescale + 1);
0102
0103 value = readl(ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm));
0104 tmp = (value & IPROC_PWM_PERIOD_MAX) * multi;
0105 state->period = div64_u64(tmp, rate);
0106
0107 value = readl(ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm));
0108 tmp = (value & IPROC_PWM_PERIOD_MAX) * multi;
0109 state->duty_cycle = div64_u64(tmp, rate);
0110 }
0111
0112 static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0113 const struct pwm_state *state)
0114 {
0115 unsigned long prescale = IPROC_PWM_PRESCALE_MIN;
0116 struct iproc_pwmc *ip = to_iproc_pwmc(chip);
0117 u32 value, period, duty;
0118 u64 rate;
0119
0120 rate = clk_get_rate(ip->clk);
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 while (1) {
0133 u64 value, div;
0134
0135 div = NSEC_PER_SEC * (prescale + 1);
0136 value = rate * state->period;
0137 period = div64_u64(value, div);
0138 value = rate * state->duty_cycle;
0139 duty = div64_u64(value, div);
0140
0141 if (period < IPROC_PWM_PERIOD_MIN)
0142 return -EINVAL;
0143
0144 if (period <= IPROC_PWM_PERIOD_MAX &&
0145 duty <= IPROC_PWM_DUTY_CYCLE_MAX)
0146 break;
0147
0148
0149 if (++prescale > IPROC_PWM_PRESCALE_MAX)
0150 return -EINVAL;
0151 }
0152
0153 iproc_pwmc_disable(ip, pwm->hwpwm);
0154
0155
0156 value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET);
0157 value &= ~IPROC_PWM_PRESCALE_MASK(pwm->hwpwm);
0158 value |= prescale << IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm);
0159 writel(value, ip->base + IPROC_PWM_PRESCALE_OFFSET);
0160
0161
0162 writel(period, ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm));
0163 writel(duty, ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm));
0164
0165
0166 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
0167
0168 if (state->polarity == PWM_POLARITY_NORMAL)
0169 value |= 1 << IPROC_PWM_CTRL_POLARITY_SHIFT(pwm->hwpwm);
0170 else
0171 value &= ~(1 << IPROC_PWM_CTRL_POLARITY_SHIFT(pwm->hwpwm));
0172
0173 writel(value, ip->base + IPROC_PWM_CTRL_OFFSET);
0174
0175 if (state->enabled)
0176 iproc_pwmc_enable(ip, pwm->hwpwm);
0177
0178 return 0;
0179 }
0180
0181 static const struct pwm_ops iproc_pwm_ops = {
0182 .apply = iproc_pwmc_apply,
0183 .get_state = iproc_pwmc_get_state,
0184 .owner = THIS_MODULE,
0185 };
0186
0187 static int iproc_pwmc_probe(struct platform_device *pdev)
0188 {
0189 struct iproc_pwmc *ip;
0190 unsigned int i;
0191 u32 value;
0192 int ret;
0193
0194 ip = devm_kzalloc(&pdev->dev, sizeof(*ip), GFP_KERNEL);
0195 if (!ip)
0196 return -ENOMEM;
0197
0198 platform_set_drvdata(pdev, ip);
0199
0200 ip->chip.dev = &pdev->dev;
0201 ip->chip.ops = &iproc_pwm_ops;
0202 ip->chip.npwm = 4;
0203
0204 ip->base = devm_platform_ioremap_resource(pdev, 0);
0205 if (IS_ERR(ip->base))
0206 return PTR_ERR(ip->base);
0207
0208 ip->clk = devm_clk_get(&pdev->dev, NULL);
0209 if (IS_ERR(ip->clk)) {
0210 dev_err(&pdev->dev, "failed to get clock: %ld\n",
0211 PTR_ERR(ip->clk));
0212 return PTR_ERR(ip->clk);
0213 }
0214
0215 ret = clk_prepare_enable(ip->clk);
0216 if (ret < 0) {
0217 dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
0218 return ret;
0219 }
0220
0221
0222 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
0223
0224 for (i = 0; i < ip->chip.npwm; i++) {
0225 value &= ~(1 << IPROC_PWM_CTRL_TYPE_SHIFT(i));
0226 value |= 1 << IPROC_PWM_CTRL_POLARITY_SHIFT(i);
0227 }
0228
0229 writel(value, ip->base + IPROC_PWM_CTRL_OFFSET);
0230
0231 ret = pwmchip_add(&ip->chip);
0232 if (ret < 0) {
0233 dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
0234 clk_disable_unprepare(ip->clk);
0235 }
0236
0237 return ret;
0238 }
0239
0240 static int iproc_pwmc_remove(struct platform_device *pdev)
0241 {
0242 struct iproc_pwmc *ip = platform_get_drvdata(pdev);
0243
0244 pwmchip_remove(&ip->chip);
0245
0246 clk_disable_unprepare(ip->clk);
0247
0248 return 0;
0249 }
0250
0251 static const struct of_device_id bcm_iproc_pwmc_dt[] = {
0252 { .compatible = "brcm,iproc-pwm" },
0253 { },
0254 };
0255 MODULE_DEVICE_TABLE(of, bcm_iproc_pwmc_dt);
0256
0257 static struct platform_driver iproc_pwmc_driver = {
0258 .driver = {
0259 .name = "bcm-iproc-pwm",
0260 .of_match_table = bcm_iproc_pwmc_dt,
0261 },
0262 .probe = iproc_pwmc_probe,
0263 .remove = iproc_pwmc_remove,
0264 };
0265 module_platform_driver(iproc_pwmc_driver);
0266
0267 MODULE_AUTHOR("Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>");
0268 MODULE_DESCRIPTION("Broadcom iProc PWM driver");
0269 MODULE_LICENSE("GPL v2");