0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <linux/bitfield.h>
0031 #include <linux/bits.h>
0032 #include <linux/clk.h>
0033 #include <linux/clk-provider.h>
0034 #include <linux/err.h>
0035 #include <linux/io.h>
0036 #include <linux/kernel.h>
0037 #include <linux/math64.h>
0038 #include <linux/module.h>
0039 #include <linux/of.h>
0040 #include <linux/of_device.h>
0041 #include <linux/platform_device.h>
0042 #include <linux/pwm.h>
0043 #include <linux/slab.h>
0044 #include <linux/spinlock.h>
0045
0046 #define REG_PWM_A 0x0
0047 #define REG_PWM_B 0x4
0048 #define PWM_LOW_MASK GENMASK(15, 0)
0049 #define PWM_HIGH_MASK GENMASK(31, 16)
0050
0051 #define REG_MISC_AB 0x8
0052 #define MISC_B_CLK_EN BIT(23)
0053 #define MISC_A_CLK_EN BIT(15)
0054 #define MISC_CLK_DIV_MASK 0x7f
0055 #define MISC_B_CLK_DIV_SHIFT 16
0056 #define MISC_A_CLK_DIV_SHIFT 8
0057 #define MISC_B_CLK_SEL_SHIFT 6
0058 #define MISC_A_CLK_SEL_SHIFT 4
0059 #define MISC_CLK_SEL_MASK 0x3
0060 #define MISC_B_EN BIT(1)
0061 #define MISC_A_EN BIT(0)
0062
0063 #define MESON_NUM_PWMS 2
0064
0065 static struct meson_pwm_channel_data {
0066 u8 reg_offset;
0067 u8 clk_sel_shift;
0068 u8 clk_div_shift;
0069 u32 clk_en_mask;
0070 u32 pwm_en_mask;
0071 } meson_pwm_per_channel_data[MESON_NUM_PWMS] = {
0072 {
0073 .reg_offset = REG_PWM_A,
0074 .clk_sel_shift = MISC_A_CLK_SEL_SHIFT,
0075 .clk_div_shift = MISC_A_CLK_DIV_SHIFT,
0076 .clk_en_mask = MISC_A_CLK_EN,
0077 .pwm_en_mask = MISC_A_EN,
0078 },
0079 {
0080 .reg_offset = REG_PWM_B,
0081 .clk_sel_shift = MISC_B_CLK_SEL_SHIFT,
0082 .clk_div_shift = MISC_B_CLK_DIV_SHIFT,
0083 .clk_en_mask = MISC_B_CLK_EN,
0084 .pwm_en_mask = MISC_B_EN,
0085 }
0086 };
0087
0088 struct meson_pwm_channel {
0089 unsigned int hi;
0090 unsigned int lo;
0091 u8 pre_div;
0092
0093 struct clk *clk_parent;
0094 struct clk_mux mux;
0095 struct clk *clk;
0096 };
0097
0098 struct meson_pwm_data {
0099 const char * const *parent_names;
0100 unsigned int num_parents;
0101 };
0102
0103 struct meson_pwm {
0104 struct pwm_chip chip;
0105 const struct meson_pwm_data *data;
0106 struct meson_pwm_channel channels[MESON_NUM_PWMS];
0107 void __iomem *base;
0108
0109
0110
0111
0112 spinlock_t lock;
0113 };
0114
0115 static inline struct meson_pwm *to_meson_pwm(struct pwm_chip *chip)
0116 {
0117 return container_of(chip, struct meson_pwm, chip);
0118 }
0119
0120 static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
0121 {
0122 struct meson_pwm *meson = to_meson_pwm(chip);
0123 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
0124 struct device *dev = chip->dev;
0125 int err;
0126
0127 if (channel->clk_parent) {
0128 err = clk_set_parent(channel->clk, channel->clk_parent);
0129 if (err < 0) {
0130 dev_err(dev, "failed to set parent %s for %s: %d\n",
0131 __clk_get_name(channel->clk_parent),
0132 __clk_get_name(channel->clk), err);
0133 return err;
0134 }
0135 }
0136
0137 err = clk_prepare_enable(channel->clk);
0138 if (err < 0) {
0139 dev_err(dev, "failed to enable clock %s: %d\n",
0140 __clk_get_name(channel->clk), err);
0141 return err;
0142 }
0143
0144 return 0;
0145 }
0146
0147 static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
0148 {
0149 struct meson_pwm *meson = to_meson_pwm(chip);
0150 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
0151
0152 clk_disable_unprepare(channel->clk);
0153 }
0154
0155 static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
0156 const struct pwm_state *state)
0157 {
0158 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
0159 unsigned int duty, period, pre_div, cnt, duty_cnt;
0160 unsigned long fin_freq;
0161
0162 duty = state->duty_cycle;
0163 period = state->period;
0164
0165 if (state->polarity == PWM_POLARITY_INVERSED)
0166 duty = period - duty;
0167
0168 fin_freq = clk_get_rate(channel->clk);
0169 if (fin_freq == 0) {
0170 dev_err(meson->chip.dev, "invalid source clock frequency\n");
0171 return -EINVAL;
0172 }
0173
0174 dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq);
0175
0176 pre_div = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * 0xffffLL);
0177 if (pre_div > MISC_CLK_DIV_MASK) {
0178 dev_err(meson->chip.dev, "unable to get period pre_div\n");
0179 return -EINVAL;
0180 }
0181
0182 cnt = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * (pre_div + 1));
0183 if (cnt > 0xffff) {
0184 dev_err(meson->chip.dev, "unable to get period cnt\n");
0185 return -EINVAL;
0186 }
0187
0188 dev_dbg(meson->chip.dev, "period=%u pre_div=%u cnt=%u\n", period,
0189 pre_div, cnt);
0190
0191 if (duty == period) {
0192 channel->pre_div = pre_div;
0193 channel->hi = cnt;
0194 channel->lo = 0;
0195 } else if (duty == 0) {
0196 channel->pre_div = pre_div;
0197 channel->hi = 0;
0198 channel->lo = cnt;
0199 } else {
0200
0201 duty_cnt = div64_u64(fin_freq * (u64)duty,
0202 NSEC_PER_SEC * (pre_div + 1));
0203 if (duty_cnt > 0xffff) {
0204 dev_err(meson->chip.dev, "unable to get duty cycle\n");
0205 return -EINVAL;
0206 }
0207
0208 dev_dbg(meson->chip.dev, "duty=%u pre_div=%u duty_cnt=%u\n",
0209 duty, pre_div, duty_cnt);
0210
0211 channel->pre_div = pre_div;
0212 channel->hi = duty_cnt;
0213 channel->lo = cnt - duty_cnt;
0214 }
0215
0216 return 0;
0217 }
0218
0219 static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
0220 {
0221 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
0222 struct meson_pwm_channel_data *channel_data;
0223 unsigned long flags;
0224 u32 value;
0225
0226 channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
0227
0228 spin_lock_irqsave(&meson->lock, flags);
0229
0230 value = readl(meson->base + REG_MISC_AB);
0231 value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
0232 value |= channel->pre_div << channel_data->clk_div_shift;
0233 value |= channel_data->clk_en_mask;
0234 writel(value, meson->base + REG_MISC_AB);
0235
0236 value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |
0237 FIELD_PREP(PWM_LOW_MASK, channel->lo);
0238 writel(value, meson->base + channel_data->reg_offset);
0239
0240 value = readl(meson->base + REG_MISC_AB);
0241 value |= channel_data->pwm_en_mask;
0242 writel(value, meson->base + REG_MISC_AB);
0243
0244 spin_unlock_irqrestore(&meson->lock, flags);
0245 }
0246
0247 static void meson_pwm_disable(struct meson_pwm *meson, struct pwm_device *pwm)
0248 {
0249 unsigned long flags;
0250 u32 value;
0251
0252 spin_lock_irqsave(&meson->lock, flags);
0253
0254 value = readl(meson->base + REG_MISC_AB);
0255 value &= ~meson_pwm_per_channel_data[pwm->hwpwm].pwm_en_mask;
0256 writel(value, meson->base + REG_MISC_AB);
0257
0258 spin_unlock_irqrestore(&meson->lock, flags);
0259 }
0260
0261 static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0262 const struct pwm_state *state)
0263 {
0264 struct meson_pwm *meson = to_meson_pwm(chip);
0265 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
0266 int err = 0;
0267
0268 if (!state->enabled) {
0269 if (state->polarity == PWM_POLARITY_INVERSED) {
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282 channel->pre_div = 0;
0283 channel->hi = ~0;
0284 channel->lo = 0;
0285
0286 meson_pwm_enable(meson, pwm);
0287 } else {
0288 meson_pwm_disable(meson, pwm);
0289 }
0290 } else {
0291 err = meson_pwm_calc(meson, pwm, state);
0292 if (err < 0)
0293 return err;
0294
0295 meson_pwm_enable(meson, pwm);
0296 }
0297
0298 return 0;
0299 }
0300
0301 static unsigned int meson_pwm_cnt_to_ns(struct pwm_chip *chip,
0302 struct pwm_device *pwm, u32 cnt)
0303 {
0304 struct meson_pwm *meson = to_meson_pwm(chip);
0305 struct meson_pwm_channel *channel;
0306 unsigned long fin_freq;
0307 u32 fin_ns;
0308
0309
0310 channel = &meson->channels[pwm->hwpwm];
0311
0312 fin_freq = clk_get_rate(channel->clk);
0313 if (fin_freq == 0)
0314 return 0;
0315
0316 fin_ns = div_u64(NSEC_PER_SEC, fin_freq);
0317
0318 return cnt * fin_ns * (channel->pre_div + 1);
0319 }
0320
0321 static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
0322 struct pwm_state *state)
0323 {
0324 struct meson_pwm *meson = to_meson_pwm(chip);
0325 struct meson_pwm_channel_data *channel_data;
0326 struct meson_pwm_channel *channel;
0327 u32 value, tmp;
0328
0329 if (!state)
0330 return;
0331
0332 channel = &meson->channels[pwm->hwpwm];
0333 channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
0334
0335 value = readl(meson->base + REG_MISC_AB);
0336
0337 tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
0338 state->enabled = (value & tmp) == tmp;
0339
0340 tmp = value >> channel_data->clk_div_shift;
0341 channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
0342
0343 value = readl(meson->base + channel_data->reg_offset);
0344
0345 channel->lo = FIELD_GET(PWM_LOW_MASK, value);
0346 channel->hi = FIELD_GET(PWM_HIGH_MASK, value);
0347
0348 if (channel->lo == 0) {
0349 state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
0350 state->duty_cycle = state->period;
0351 } else if (channel->lo >= channel->hi) {
0352 state->period = meson_pwm_cnt_to_ns(chip, pwm,
0353 channel->lo + channel->hi);
0354 state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm,
0355 channel->hi);
0356 } else {
0357 state->period = 0;
0358 state->duty_cycle = 0;
0359 }
0360 }
0361
0362 static const struct pwm_ops meson_pwm_ops = {
0363 .request = meson_pwm_request,
0364 .free = meson_pwm_free,
0365 .apply = meson_pwm_apply,
0366 .get_state = meson_pwm_get_state,
0367 .owner = THIS_MODULE,
0368 };
0369
0370 static const char * const pwm_meson8b_parent_names[] = {
0371 "xtal", "vid_pll", "fclk_div4", "fclk_div3"
0372 };
0373
0374 static const struct meson_pwm_data pwm_meson8b_data = {
0375 .parent_names = pwm_meson8b_parent_names,
0376 .num_parents = ARRAY_SIZE(pwm_meson8b_parent_names),
0377 };
0378
0379 static const char * const pwm_gxbb_parent_names[] = {
0380 "xtal", "hdmi_pll", "fclk_div4", "fclk_div3"
0381 };
0382
0383 static const struct meson_pwm_data pwm_gxbb_data = {
0384 .parent_names = pwm_gxbb_parent_names,
0385 .num_parents = ARRAY_SIZE(pwm_gxbb_parent_names),
0386 };
0387
0388
0389
0390
0391
0392 static const char * const pwm_gxbb_ao_parent_names[] = {
0393 "xtal", "clk81"
0394 };
0395
0396 static const struct meson_pwm_data pwm_gxbb_ao_data = {
0397 .parent_names = pwm_gxbb_ao_parent_names,
0398 .num_parents = ARRAY_SIZE(pwm_gxbb_ao_parent_names),
0399 };
0400
0401 static const char * const pwm_axg_ee_parent_names[] = {
0402 "xtal", "fclk_div5", "fclk_div4", "fclk_div3"
0403 };
0404
0405 static const struct meson_pwm_data pwm_axg_ee_data = {
0406 .parent_names = pwm_axg_ee_parent_names,
0407 .num_parents = ARRAY_SIZE(pwm_axg_ee_parent_names),
0408 };
0409
0410 static const char * const pwm_axg_ao_parent_names[] = {
0411 "aoclk81", "xtal", "fclk_div4", "fclk_div5"
0412 };
0413
0414 static const struct meson_pwm_data pwm_axg_ao_data = {
0415 .parent_names = pwm_axg_ao_parent_names,
0416 .num_parents = ARRAY_SIZE(pwm_axg_ao_parent_names),
0417 };
0418
0419 static const char * const pwm_g12a_ao_ab_parent_names[] = {
0420 "xtal", "aoclk81", "fclk_div4", "fclk_div5"
0421 };
0422
0423 static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
0424 .parent_names = pwm_g12a_ao_ab_parent_names,
0425 .num_parents = ARRAY_SIZE(pwm_g12a_ao_ab_parent_names),
0426 };
0427
0428 static const char * const pwm_g12a_ao_cd_parent_names[] = {
0429 "xtal", "aoclk81",
0430 };
0431
0432 static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
0433 .parent_names = pwm_g12a_ao_cd_parent_names,
0434 .num_parents = ARRAY_SIZE(pwm_g12a_ao_cd_parent_names),
0435 };
0436
0437 static const char * const pwm_g12a_ee_parent_names[] = {
0438 "xtal", "hdmi_pll", "fclk_div4", "fclk_div3"
0439 };
0440
0441 static const struct meson_pwm_data pwm_g12a_ee_data = {
0442 .parent_names = pwm_g12a_ee_parent_names,
0443 .num_parents = ARRAY_SIZE(pwm_g12a_ee_parent_names),
0444 };
0445
0446 static const struct of_device_id meson_pwm_matches[] = {
0447 {
0448 .compatible = "amlogic,meson8b-pwm",
0449 .data = &pwm_meson8b_data
0450 },
0451 {
0452 .compatible = "amlogic,meson-gxbb-pwm",
0453 .data = &pwm_gxbb_data
0454 },
0455 {
0456 .compatible = "amlogic,meson-gxbb-ao-pwm",
0457 .data = &pwm_gxbb_ao_data
0458 },
0459 {
0460 .compatible = "amlogic,meson-axg-ee-pwm",
0461 .data = &pwm_axg_ee_data
0462 },
0463 {
0464 .compatible = "amlogic,meson-axg-ao-pwm",
0465 .data = &pwm_axg_ao_data
0466 },
0467 {
0468 .compatible = "amlogic,meson-g12a-ee-pwm",
0469 .data = &pwm_g12a_ee_data
0470 },
0471 {
0472 .compatible = "amlogic,meson-g12a-ao-pwm-ab",
0473 .data = &pwm_g12a_ao_ab_data
0474 },
0475 {
0476 .compatible = "amlogic,meson-g12a-ao-pwm-cd",
0477 .data = &pwm_g12a_ao_cd_data
0478 },
0479 {},
0480 };
0481 MODULE_DEVICE_TABLE(of, meson_pwm_matches);
0482
0483 static int meson_pwm_init_channels(struct meson_pwm *meson)
0484 {
0485 struct device *dev = meson->chip.dev;
0486 struct clk_init_data init;
0487 unsigned int i;
0488 char name[255];
0489 int err;
0490
0491 for (i = 0; i < meson->chip.npwm; i++) {
0492 struct meson_pwm_channel *channel = &meson->channels[i];
0493
0494 snprintf(name, sizeof(name), "%s#mux%u", dev_name(dev), i);
0495
0496 init.name = name;
0497 init.ops = &clk_mux_ops;
0498 init.flags = 0;
0499 init.parent_names = meson->data->parent_names;
0500 init.num_parents = meson->data->num_parents;
0501
0502 channel->mux.reg = meson->base + REG_MISC_AB;
0503 channel->mux.shift =
0504 meson_pwm_per_channel_data[i].clk_sel_shift;
0505 channel->mux.mask = MISC_CLK_SEL_MASK;
0506 channel->mux.flags = 0;
0507 channel->mux.lock = &meson->lock;
0508 channel->mux.table = NULL;
0509 channel->mux.hw.init = &init;
0510
0511 channel->clk = devm_clk_register(dev, &channel->mux.hw);
0512 if (IS_ERR(channel->clk)) {
0513 err = PTR_ERR(channel->clk);
0514 dev_err(dev, "failed to register %s: %d\n", name, err);
0515 return err;
0516 }
0517
0518 snprintf(name, sizeof(name), "clkin%u", i);
0519
0520 channel->clk_parent = devm_clk_get_optional(dev, name);
0521 if (IS_ERR(channel->clk_parent))
0522 return PTR_ERR(channel->clk_parent);
0523 }
0524
0525 return 0;
0526 }
0527
0528 static int meson_pwm_probe(struct platform_device *pdev)
0529 {
0530 struct meson_pwm *meson;
0531 int err;
0532
0533 meson = devm_kzalloc(&pdev->dev, sizeof(*meson), GFP_KERNEL);
0534 if (!meson)
0535 return -ENOMEM;
0536
0537 meson->base = devm_platform_ioremap_resource(pdev, 0);
0538 if (IS_ERR(meson->base))
0539 return PTR_ERR(meson->base);
0540
0541 spin_lock_init(&meson->lock);
0542 meson->chip.dev = &pdev->dev;
0543 meson->chip.ops = &meson_pwm_ops;
0544 meson->chip.npwm = MESON_NUM_PWMS;
0545
0546 meson->data = of_device_get_match_data(&pdev->dev);
0547
0548 err = meson_pwm_init_channels(meson);
0549 if (err < 0)
0550 return err;
0551
0552 err = devm_pwmchip_add(&pdev->dev, &meson->chip);
0553 if (err < 0) {
0554 dev_err(&pdev->dev, "failed to register PWM chip: %d\n", err);
0555 return err;
0556 }
0557
0558 return 0;
0559 }
0560
0561 static struct platform_driver meson_pwm_driver = {
0562 .driver = {
0563 .name = "meson-pwm",
0564 .of_match_table = meson_pwm_matches,
0565 },
0566 .probe = meson_pwm_probe,
0567 };
0568 module_platform_driver(meson_pwm_driver);
0569
0570 MODULE_DESCRIPTION("Amlogic Meson PWM Generator driver");
0571 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
0572 MODULE_LICENSE("Dual BSD/GPL");