1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * PWM Controller Driver for HiSilicon BVT SoCs 4 * 5 * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 6 */ 7 8 #include <linux/bitops.h> 9 #include <linux/clk.h> 10 #include <linux/delay.h> 11 #include <linux/io.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/pwm.h> 16 #include <linux/reset.h> 17 18 #define PWM_CFG0_ADDR(x) (((x) * 0x20) + 0x0) 19 #define PWM_CFG1_ADDR(x) (((x) * 0x20) + 0x4) 20 #define PWM_CFG2_ADDR(x) (((x) * 0x20) + 0x8) 21 #define PWM_CTRL_ADDR(x) (((x) * 0x20) + 0xC) 22 23 #define PWM_ENABLE_SHIFT 0 24 #define PWM_ENABLE_MASK BIT(0) 25 26 #define PWM_POLARITY_SHIFT 1 27 #define PWM_POLARITY_MASK BIT(1) 28 29 #define PWM_KEEP_SHIFT 2 30 #define PWM_KEEP_MASK BIT(2) 31 32 #define PWM_PERIOD_MASK GENMASK(31, 0) 33 #define PWM_DUTY_MASK GENMASK(31, 0) 34 35 struct hibvt_pwm_chip { 36 struct clk *clk; 37 void __iomem *base; 38 struct reset_control *rstc; 39 const struct hibvt_pwm_soc *soc; 40 }; 41 42 struct hibvt_pwm_soc { 43 u32 num_pwms; 44 bool quirk_force_enable; 45 }; 46 47 static const struct hibvt_pwm_soc hi3516cv300_soc_info = { 48 .num_pwms = 4, 49 }; 50 51 static const struct hibvt_pwm_soc hi3519v100_soc_info = { 52 .num_pwms = 8, 53 }; 54 55 static const struct hibvt_pwm_soc hi3559v100_shub_soc_info = { 56 .num_pwms = 8, 57 .quirk_force_enable = true, 58 }; 59 60 static const struct hibvt_pwm_soc hi3559v100_soc_info = { 61 .num_pwms = 2, 62 .quirk_force_enable = true, 63 }; 64 65 static inline struct hibvt_pwm_chip *to_hibvt_pwm_chip(struct pwm_chip *chip) 66 { 67 return pwmchip_get_drvdata(chip); 68 } 69 70 static void hibvt_pwm_set_bits(void __iomem *base, u32 offset, 71 u32 mask, u32 data) 72 { 73 void __iomem *address = base + offset; 74 u32 value; 75 76 value = readl(address); 77 value &= ~mask; 78 value |= (data & mask); 79 writel(value, address); 80 } 81 82 static void hibvt_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 83 { 84 struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); 85 86 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), 87 PWM_ENABLE_MASK, 0x1); 88 } 89 90 static void hibvt_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 91 { 92 struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); 93 94 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), 95 PWM_ENABLE_MASK, 0x0); 96 } 97 98 static void hibvt_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 99 int duty_cycle_ns, int period_ns) 100 { 101 struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); 102 u32 freq, period, duty; 103 104 freq = div_u64(clk_get_rate(hi_pwm_chip->clk), 1000000); 105 106 period = div_u64(freq * period_ns, 1000); 107 duty = div_u64(period * duty_cycle_ns, period_ns); 108 109 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CFG0_ADDR(pwm->hwpwm), 110 PWM_PERIOD_MASK, period); 111 112 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CFG1_ADDR(pwm->hwpwm), 113 PWM_DUTY_MASK, duty); 114 } 115 116 static void hibvt_pwm_set_polarity(struct pwm_chip *chip, 117 struct pwm_device *pwm, 118 enum pwm_polarity polarity) 119 { 120 struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); 121 122 if (polarity == PWM_POLARITY_INVERSED) 123 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), 124 PWM_POLARITY_MASK, (0x1 << PWM_POLARITY_SHIFT)); 125 else 126 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), 127 PWM_POLARITY_MASK, (0x0 << PWM_POLARITY_SHIFT)); 128 } 129 130 static int hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, 131 struct pwm_state *state) 132 { 133 struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); 134 void __iomem *base; 135 u32 freq, value; 136 137 freq = div_u64(clk_get_rate(hi_pwm_chip->clk), 1000000); 138 base = hi_pwm_chip->base; 139 140 value = readl(base + PWM_CFG0_ADDR(pwm->hwpwm)); 141 state->period = div_u64(value * 1000, freq); 142 143 value = readl(base + PWM_CFG1_ADDR(pwm->hwpwm)); 144 state->duty_cycle = div_u64(value * 1000, freq); 145 146 value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm)); 147 state->enabled = (PWM_ENABLE_MASK & value); 148 state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; 149 150 return 0; 151 } 152 153 static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 154 const struct pwm_state *state) 155 { 156 struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); 157 158 if (state->polarity != pwm->state.polarity) 159 hibvt_pwm_set_polarity(chip, pwm, state->polarity); 160 161 if (state->period != pwm->state.period || 162 state->duty_cycle != pwm->state.duty_cycle) { 163 hibvt_pwm_config(chip, pwm, state->duty_cycle, state->period); 164 165 /* 166 * Some implementations require the PWM to be enabled twice 167 * each time the duty cycle is refreshed. 168 */ 169 if (hi_pwm_chip->soc->quirk_force_enable && state->enabled) 170 hibvt_pwm_enable(chip, pwm); 171 } 172 173 if (state->enabled != pwm->state.enabled) { 174 if (state->enabled) 175 hibvt_pwm_enable(chip, pwm); 176 else 177 hibvt_pwm_disable(chip, pwm); 178 } 179 180 return 0; 181 } 182 183 static const struct pwm_ops hibvt_pwm_ops = { 184 .get_state = hibvt_pwm_get_state, 185 .apply = hibvt_pwm_apply, 186 187 }; 188 189 static int hibvt_pwm_probe(struct platform_device *pdev) 190 { 191 const struct hibvt_pwm_soc *soc = 192 of_device_get_match_data(&pdev->dev); 193 struct pwm_chip *chip; 194 struct hibvt_pwm_chip *hi_pwm_chip; 195 int ret, i; 196 197 chip = devm_pwmchip_alloc(&pdev->dev, soc->num_pwms, sizeof(*hi_pwm_chip)); 198 if (IS_ERR(chip)) 199 return PTR_ERR(chip); 200 hi_pwm_chip = to_hibvt_pwm_chip(chip); 201 202 hi_pwm_chip->clk = devm_clk_get(&pdev->dev, NULL); 203 if (IS_ERR(hi_pwm_chip->clk)) { 204 dev_err(&pdev->dev, "getting clock failed with %ld\n", 205 PTR_ERR(hi_pwm_chip->clk)); 206 return PTR_ERR(hi_pwm_chip->clk); 207 } 208 209 chip->ops = &hibvt_pwm_ops; 210 hi_pwm_chip->soc = soc; 211 212 hi_pwm_chip->base = devm_platform_ioremap_resource(pdev, 0); 213 if (IS_ERR(hi_pwm_chip->base)) 214 return PTR_ERR(hi_pwm_chip->base); 215 216 ret = clk_prepare_enable(hi_pwm_chip->clk); 217 if (ret < 0) 218 return ret; 219 220 hi_pwm_chip->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); 221 if (IS_ERR(hi_pwm_chip->rstc)) { 222 clk_disable_unprepare(hi_pwm_chip->clk); 223 return PTR_ERR(hi_pwm_chip->rstc); 224 } 225 226 reset_control_assert(hi_pwm_chip->rstc); 227 msleep(30); 228 reset_control_deassert(hi_pwm_chip->rstc); 229 230 ret = pwmchip_add(chip); 231 if (ret < 0) { 232 clk_disable_unprepare(hi_pwm_chip->clk); 233 return ret; 234 } 235 236 for (i = 0; i < chip->npwm; i++) { 237 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(i), 238 PWM_KEEP_MASK, (0x1 << PWM_KEEP_SHIFT)); 239 } 240 241 platform_set_drvdata(pdev, chip); 242 243 return 0; 244 } 245 246 static void hibvt_pwm_remove(struct platform_device *pdev) 247 { 248 struct pwm_chip *chip = platform_get_drvdata(pdev); 249 struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); 250 251 pwmchip_remove(chip); 252 253 reset_control_assert(hi_pwm_chip->rstc); 254 msleep(30); 255 reset_control_deassert(hi_pwm_chip->rstc); 256 257 clk_disable_unprepare(hi_pwm_chip->clk); 258 } 259 260 static const struct of_device_id hibvt_pwm_of_match[] = { 261 { .compatible = "hisilicon,hi3516cv300-pwm", 262 .data = &hi3516cv300_soc_info }, 263 { .compatible = "hisilicon,hi3519v100-pwm", 264 .data = &hi3519v100_soc_info }, 265 { .compatible = "hisilicon,hi3559v100-shub-pwm", 266 .data = &hi3559v100_shub_soc_info }, 267 { .compatible = "hisilicon,hi3559v100-pwm", 268 .data = &hi3559v100_soc_info }, 269 { } 270 }; 271 MODULE_DEVICE_TABLE(of, hibvt_pwm_of_match); 272 273 static struct platform_driver hibvt_pwm_driver = { 274 .driver = { 275 .name = "hibvt-pwm", 276 .of_match_table = hibvt_pwm_of_match, 277 }, 278 .probe = hibvt_pwm_probe, 279 .remove_new = hibvt_pwm_remove, 280 }; 281 module_platform_driver(hibvt_pwm_driver); 282 283 MODULE_AUTHOR("Jian Yuan"); 284 MODULE_DESCRIPTION("HiSilicon BVT SoCs PWM driver"); 285 MODULE_LICENSE("GPL"); 286