1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2017 Sanechips Technology Co., Ltd. 4 * Copyright 2017 Linaro Ltd. 5 */ 6 7#include <linux/clk.h> 8#include <linux/err.h> 9#include <linux/io.h> 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/platform_device.h> 13#include <linux/pwm.h> 14#include <linux/slab.h> 15 16#define ZX_PWM_MODE 0x0 17#define ZX_PWM_CLKDIV_SHIFT 2 18#define ZX_PWM_CLKDIV_MASK GENMASK(11, 2) 19#define ZX_PWM_CLKDIV(x) (((x) << ZX_PWM_CLKDIV_SHIFT) & \ 20 ZX_PWM_CLKDIV_MASK) 21#define ZX_PWM_POLAR BIT(1) 22#define ZX_PWM_EN BIT(0) 23#define ZX_PWM_PERIOD 0x4 24#define ZX_PWM_DUTY 0x8 25 26#define ZX_PWM_CLKDIV_MAX 1023 27#define ZX_PWM_PERIOD_MAX 65535 28 29struct zx_pwm_chip { 30 struct pwm_chip chip; 31 struct clk *pclk; 32 struct clk *wclk; 33 void __iomem *base; 34}; 35 36static inline struct zx_pwm_chip *to_zx_pwm_chip(struct pwm_chip *chip) 37{ 38 return container_of(chip, struct zx_pwm_chip, chip); 39} 40 41static inline u32 zx_pwm_readl(struct zx_pwm_chip *zpc, unsigned int hwpwm, 42 unsigned int offset) 43{ 44 return readl(zpc->base + (hwpwm + 1) * 0x10 + offset); 45} 46 47static inline void zx_pwm_writel(struct zx_pwm_chip *zpc, unsigned int hwpwm, 48 unsigned int offset, u32 value) 49{ 50 writel(value, zpc->base + (hwpwm + 1) * 0x10 + offset); 51} 52 53static void zx_pwm_set_mask(struct zx_pwm_chip *zpc, unsigned int hwpwm, 54 unsigned int offset, u32 mask, u32 value) 55{ 56 u32 data; 57 58 data = zx_pwm_readl(zpc, hwpwm, offset); 59 data &= ~mask; 60 data |= value & mask; 61 zx_pwm_writel(zpc, hwpwm, offset, data); 62} 63 64static void zx_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, 65 struct pwm_state *state) 66{ 67 struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip); 68 unsigned long rate; 69 unsigned int div; 70 u32 value; 71 u64 tmp; 72 73 value = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_MODE); 74 75 if (value & ZX_PWM_POLAR) 76 state->polarity = PWM_POLARITY_NORMAL; 77 else 78 state->polarity = PWM_POLARITY_INVERSED; 79 80 if (value & ZX_PWM_EN) 81 state->enabled = true; 82 else 83 state->enabled = false; 84 85 div = (value & ZX_PWM_CLKDIV_MASK) >> ZX_PWM_CLKDIV_SHIFT; 86 rate = clk_get_rate(zpc->wclk); 87 88 tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_PERIOD); 89 tmp *= div * NSEC_PER_SEC; 90 state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate); 91 92 tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_DUTY); 93 tmp *= div * NSEC_PER_SEC; 94 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate); 95} 96 97static int zx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 98 unsigned int duty_ns, unsigned int period_ns) 99{ 100 struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip); 101 unsigned int period_cycles, duty_cycles; 102 unsigned long long c; 103 unsigned int div = 1; 104 unsigned long rate; 105 106 /* Find out the best divider */ 107 rate = clk_get_rate(zpc->wclk); 108 109 while (1) { 110 c = rate / div; 111 c = c * period_ns; 112 do_div(c, NSEC_PER_SEC); 113 114 if (c < ZX_PWM_PERIOD_MAX) 115 break; 116 117 div++; 118 119 if (div > ZX_PWM_CLKDIV_MAX) 120 return -ERANGE; 121 } 122 123 /* Calculate duty cycles */ 124 period_cycles = c; 125 c *= duty_ns; 126 do_div(c, period_ns); 127 duty_cycles = c; 128 129 /* 130 * If the PWM is being enabled, we have to temporarily disable it 131 * before configuring the registers. 132 */ 133 if (pwm_is_enabled(pwm)) 134 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_EN, 0); 135 136 /* Set up registers */ 137 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_CLKDIV_MASK, 138 ZX_PWM_CLKDIV(div)); 139 zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_PERIOD, period_cycles); 140 zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_DUTY, duty_cycles); 141 142 /* Re-enable the PWM if needed */ 143 if (pwm_is_enabled(pwm)) 144 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, 145 ZX_PWM_EN, ZX_PWM_EN); 146 147 return 0; 148} 149 150static int zx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 151 const struct pwm_state *state) 152{ 153 struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip); 154 struct pwm_state cstate; 155 int ret; 156 157 pwm_get_state(pwm, &cstate); 158 159 if (state->polarity != cstate.polarity) 160 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_POLAR, 161 (state->polarity == PWM_POLARITY_INVERSED) ? 162 0 : ZX_PWM_POLAR); 163 164 if (state->period != cstate.period || 165 state->duty_cycle != cstate.duty_cycle) { 166 ret = zx_pwm_config(chip, pwm, state->duty_cycle, 167 state->period); 168 if (ret) 169 return ret; 170 } 171 172 if (state->enabled != cstate.enabled) { 173 if (state->enabled) { 174 ret = clk_prepare_enable(zpc->wclk); 175 if (ret) 176 return ret; 177 178 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, 179 ZX_PWM_EN, ZX_PWM_EN); 180 } else { 181 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, 182 ZX_PWM_EN, 0); 183 clk_disable_unprepare(zpc->wclk); 184 } 185 } 186 187 return 0; 188} 189 190static const struct pwm_ops zx_pwm_ops = { 191 .apply = zx_pwm_apply, 192 .get_state = zx_pwm_get_state, 193 .owner = THIS_MODULE, 194}; 195 196static int zx_pwm_probe(struct platform_device *pdev) 197{ 198 struct zx_pwm_chip *zpc; 199 struct resource *res; 200 unsigned int i; 201 int ret; 202 203 zpc = devm_kzalloc(&pdev->dev, sizeof(*zpc), GFP_KERNEL); 204 if (!zpc) 205 return -ENOMEM; 206 207 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 208 zpc->base = devm_ioremap_resource(&pdev->dev, res); 209 if (IS_ERR(zpc->base)) 210 return PTR_ERR(zpc->base); 211 212 zpc->pclk = devm_clk_get(&pdev->dev, "pclk"); 213 if (IS_ERR(zpc->pclk)) 214 return PTR_ERR(zpc->pclk); 215 216 zpc->wclk = devm_clk_get(&pdev->dev, "wclk"); 217 if (IS_ERR(zpc->wclk)) 218 return PTR_ERR(zpc->wclk); 219 220 ret = clk_prepare_enable(zpc->pclk); 221 if (ret) 222 return ret; 223 224 zpc->chip.dev = &pdev->dev; 225 zpc->chip.ops = &zx_pwm_ops; 226 zpc->chip.base = -1; 227 zpc->chip.npwm = 4; 228 zpc->chip.of_xlate = of_pwm_xlate_with_flags; 229 zpc->chip.of_pwm_n_cells = 3; 230 231 /* 232 * PWM devices may be enabled by firmware, and let's disable all of 233 * them initially to save power. 234 */ 235 for (i = 0; i < zpc->chip.npwm; i++) 236 zx_pwm_set_mask(zpc, i, ZX_PWM_MODE, ZX_PWM_EN, 0); 237 238 ret = pwmchip_add(&zpc->chip); 239 if (ret < 0) { 240 dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); 241 clk_disable_unprepare(zpc->pclk); 242 return ret; 243 } 244 245 platform_set_drvdata(pdev, zpc); 246 247 return 0; 248} 249 250static int zx_pwm_remove(struct platform_device *pdev) 251{ 252 struct zx_pwm_chip *zpc = platform_get_drvdata(pdev); 253 int ret; 254 255 ret = pwmchip_remove(&zpc->chip); 256 clk_disable_unprepare(zpc->pclk); 257 258 return ret; 259} 260 261static const struct of_device_id zx_pwm_dt_ids[] = { 262 { .compatible = "zte,zx296718-pwm", }, 263 { /* sentinel */ } 264}; 265MODULE_DEVICE_TABLE(of, zx_pwm_dt_ids); 266 267static struct platform_driver zx_pwm_driver = { 268 .driver = { 269 .name = "zx-pwm", 270 .of_match_table = zx_pwm_dt_ids, 271 }, 272 .probe = zx_pwm_probe, 273 .remove = zx_pwm_remove, 274}; 275module_platform_driver(zx_pwm_driver); 276 277MODULE_ALIAS("platform:zx-pwm"); 278MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>"); 279MODULE_DESCRIPTION("ZTE ZX PWM Driver"); 280MODULE_LICENSE("GPL v2"); 281