1bc1ce713SSean Anderson // SPDX-License-Identifier: GPL-2.0+ 2bc1ce713SSean Anderson /* 3bc1ce713SSean Anderson * Copyright (C) 2021 Sean Anderson <sean.anderson@seco.com> 4bc1ce713SSean Anderson * 5bc1ce713SSean Anderson * Limitations: 6bc1ce713SSean Anderson * - When changing both duty cycle and period, we may end up with one cycle 7bc1ce713SSean Anderson * with the old duty cycle and the new period. This is because the counters 8bc1ce713SSean Anderson * may only be reloaded by first stopping them, or by letting them be 9bc1ce713SSean Anderson * automatically reloaded at the end of a cycle. If this automatic reload 10bc1ce713SSean Anderson * happens after we set TLR0 but before we set TLR1 then we will have a 11bc1ce713SSean Anderson * bad cycle. This could probably be fixed by reading TCR0 just before 12bc1ce713SSean Anderson * reprogramming, but I think it would add complexity for little gain. 13bc1ce713SSean Anderson * - Cannot produce 100% duty cycle by configuring the TLRs. This might be 14bc1ce713SSean Anderson * possible by stopping the counters at an appropriate point in the cycle, 15bc1ce713SSean Anderson * but this is not (yet) implemented. 16bc1ce713SSean Anderson * - Only produces "normal" output. 17bc1ce713SSean Anderson * - Always produces low output if disabled. 18bc1ce713SSean Anderson */ 19bc1ce713SSean Anderson 20bc1ce713SSean Anderson #include <clocksource/timer-xilinx.h> 21bc1ce713SSean Anderson #include <linux/clk.h> 22bc1ce713SSean Anderson #include <linux/clk-provider.h> 23bc1ce713SSean Anderson #include <linux/device.h> 24bc1ce713SSean Anderson #include <linux/module.h> 25bc1ce713SSean Anderson #include <linux/of.h> 26bc1ce713SSean Anderson #include <linux/platform_device.h> 27bc1ce713SSean Anderson #include <linux/pwm.h> 28bc1ce713SSean Anderson #include <linux/regmap.h> 29bc1ce713SSean Anderson 30bc1ce713SSean Anderson /* 31bc1ce713SSean Anderson * The following functions are "common" to drivers for this device, and may be 32bc1ce713SSean Anderson * exported at a future date. 33bc1ce713SSean Anderson */ 34bc1ce713SSean Anderson u32 xilinx_timer_tlr_cycles(struct xilinx_timer_priv *priv, u32 tcsr, 35bc1ce713SSean Anderson u64 cycles) 36bc1ce713SSean Anderson { 37bc1ce713SSean Anderson WARN_ON(cycles < 2 || cycles - 2 > priv->max); 38bc1ce713SSean Anderson 39bc1ce713SSean Anderson if (tcsr & TCSR_UDT) 40bc1ce713SSean Anderson return cycles - 2; 41bc1ce713SSean Anderson return priv->max - cycles + 2; 42bc1ce713SSean Anderson } 43bc1ce713SSean Anderson 44bc1ce713SSean Anderson unsigned int xilinx_timer_get_period(struct xilinx_timer_priv *priv, 45bc1ce713SSean Anderson u32 tlr, u32 tcsr) 46bc1ce713SSean Anderson { 47bc1ce713SSean Anderson u64 cycles; 48bc1ce713SSean Anderson 49bc1ce713SSean Anderson if (tcsr & TCSR_UDT) 50bc1ce713SSean Anderson cycles = tlr + 2; 51bc1ce713SSean Anderson else 52bc1ce713SSean Anderson cycles = (u64)priv->max - tlr + 2; 53bc1ce713SSean Anderson 54bc1ce713SSean Anderson /* cycles has a max of 2^32 + 2, so we can't overflow */ 55bc1ce713SSean Anderson return DIV64_U64_ROUND_UP(cycles * NSEC_PER_SEC, 56bc1ce713SSean Anderson clk_get_rate(priv->clk)); 57bc1ce713SSean Anderson } 58bc1ce713SSean Anderson 59bc1ce713SSean Anderson /* 60bc1ce713SSean Anderson * The idea here is to capture whether the PWM is actually running (e.g. 61bc1ce713SSean Anderson * because we or the bootloader set it up) and we need to be careful to ensure 62bc1ce713SSean Anderson * we don't cause a glitch. According to the data sheet, to enable the PWM we 63bc1ce713SSean Anderson * need to 64bc1ce713SSean Anderson * 65bc1ce713SSean Anderson * - Set both timers to generate mode (MDT=1) 66bc1ce713SSean Anderson * - Set both timers to PWM mode (PWMA=1) 67bc1ce713SSean Anderson * - Enable the generate out signals (GENT=1) 68bc1ce713SSean Anderson * 69bc1ce713SSean Anderson * In addition, 70bc1ce713SSean Anderson * 71bc1ce713SSean Anderson * - The timer must be running (ENT=1) 72bc1ce713SSean Anderson * - The timer must auto-reload TLR into TCR (ARHT=1) 73bc1ce713SSean Anderson * - We must not be in the process of loading TLR into TCR (LOAD=0) 74bc1ce713SSean Anderson * - Cascade mode must be disabled (CASC=0) 75bc1ce713SSean Anderson * 76bc1ce713SSean Anderson * If any of these differ from usual, then the PWM is either disabled, or is 77bc1ce713SSean Anderson * running in a mode that this driver does not support. 78bc1ce713SSean Anderson */ 79bc1ce713SSean Anderson #define TCSR_PWM_SET (TCSR_GENT | TCSR_ARHT | TCSR_ENT | TCSR_PWMA) 80bc1ce713SSean Anderson #define TCSR_PWM_CLEAR (TCSR_MDT | TCSR_LOAD) 81bc1ce713SSean Anderson #define TCSR_PWM_MASK (TCSR_PWM_SET | TCSR_PWM_CLEAR) 82bc1ce713SSean Anderson 83bc1ce713SSean Anderson struct xilinx_pwm_device { 84bc1ce713SSean Anderson struct pwm_chip chip; 85bc1ce713SSean Anderson struct xilinx_timer_priv priv; 86bc1ce713SSean Anderson }; 87bc1ce713SSean Anderson 88bc1ce713SSean Anderson static inline struct xilinx_timer_priv 89bc1ce713SSean Anderson *xilinx_pwm_chip_to_priv(struct pwm_chip *chip) 90bc1ce713SSean Anderson { 91bc1ce713SSean Anderson return &container_of(chip, struct xilinx_pwm_device, chip)->priv; 92bc1ce713SSean Anderson } 93bc1ce713SSean Anderson 94bc1ce713SSean Anderson static bool xilinx_timer_pwm_enabled(u32 tcsr0, u32 tcsr1) 95bc1ce713SSean Anderson { 96bc1ce713SSean Anderson return ((TCSR_PWM_MASK | TCSR_CASC) & tcsr0) == TCSR_PWM_SET && 97bc1ce713SSean Anderson (TCSR_PWM_MASK & tcsr1) == TCSR_PWM_SET; 98bc1ce713SSean Anderson } 99bc1ce713SSean Anderson 100bc1ce713SSean Anderson static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused, 101bc1ce713SSean Anderson const struct pwm_state *state) 102bc1ce713SSean Anderson { 103bc1ce713SSean Anderson struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip); 104bc1ce713SSean Anderson u32 tlr0, tlr1, tcsr0, tcsr1; 105bc1ce713SSean Anderson u64 period_cycles, duty_cycles; 106bc1ce713SSean Anderson unsigned long rate; 107bc1ce713SSean Anderson 108bc1ce713SSean Anderson if (state->polarity != PWM_POLARITY_NORMAL) 109bc1ce713SSean Anderson return -EINVAL; 110bc1ce713SSean Anderson 111bc1ce713SSean Anderson /* 112bc1ce713SSean Anderson * To be representable by TLR, cycles must be between 2 and 113bc1ce713SSean Anderson * priv->max + 2. To enforce this we can reduce the cycles, but we may 114bc1ce713SSean Anderson * not increase them. Caveat emptor: while this does result in more 115bc1ce713SSean Anderson * predictable rounding, it may also result in a completely different 116bc1ce713SSean Anderson * duty cycle (% high time) than what was requested. 117bc1ce713SSean Anderson */ 118bc1ce713SSean Anderson rate = clk_get_rate(priv->clk); 119bc1ce713SSean Anderson /* Avoid overflow */ 120bc1ce713SSean Anderson period_cycles = min_t(u64, state->period, U32_MAX * NSEC_PER_SEC); 121bc1ce713SSean Anderson period_cycles = mul_u64_u32_div(period_cycles, rate, NSEC_PER_SEC); 122bc1ce713SSean Anderson period_cycles = min_t(u64, period_cycles, priv->max + 2); 123bc1ce713SSean Anderson if (period_cycles < 2) 124bc1ce713SSean Anderson return -ERANGE; 125bc1ce713SSean Anderson 126bc1ce713SSean Anderson /* Same thing for duty cycles */ 127bc1ce713SSean Anderson duty_cycles = min_t(u64, state->duty_cycle, U32_MAX * NSEC_PER_SEC); 128bc1ce713SSean Anderson duty_cycles = mul_u64_u32_div(duty_cycles, rate, NSEC_PER_SEC); 129bc1ce713SSean Anderson duty_cycles = min_t(u64, duty_cycles, priv->max + 2); 130bc1ce713SSean Anderson 131bc1ce713SSean Anderson /* 132bc1ce713SSean Anderson * If we specify 100% duty cycle, we will get 0% instead, so decrease 133bc1ce713SSean Anderson * the duty cycle count by one. 134bc1ce713SSean Anderson */ 135bc1ce713SSean Anderson if (duty_cycles >= period_cycles) 136bc1ce713SSean Anderson duty_cycles = period_cycles - 1; 137bc1ce713SSean Anderson 138bc1ce713SSean Anderson /* Round down to 0% duty cycle for unrepresentable duty cycles */ 139bc1ce713SSean Anderson if (duty_cycles < 2) 140bc1ce713SSean Anderson duty_cycles = period_cycles; 141bc1ce713SSean Anderson 142bc1ce713SSean Anderson regmap_read(priv->map, TCSR0, &tcsr0); 143bc1ce713SSean Anderson regmap_read(priv->map, TCSR1, &tcsr1); 144bc1ce713SSean Anderson tlr0 = xilinx_timer_tlr_cycles(priv, tcsr0, period_cycles); 145bc1ce713SSean Anderson tlr1 = xilinx_timer_tlr_cycles(priv, tcsr1, duty_cycles); 146bc1ce713SSean Anderson regmap_write(priv->map, TLR0, tlr0); 147bc1ce713SSean Anderson regmap_write(priv->map, TLR1, tlr1); 148bc1ce713SSean Anderson 149bc1ce713SSean Anderson if (state->enabled) { 150bc1ce713SSean Anderson /* 151bc1ce713SSean Anderson * If the PWM is already running, then the counters will be 152bc1ce713SSean Anderson * reloaded at the end of the current cycle. 153bc1ce713SSean Anderson */ 154bc1ce713SSean Anderson if (!xilinx_timer_pwm_enabled(tcsr0, tcsr1)) { 155bc1ce713SSean Anderson /* Load TLR into TCR */ 156bc1ce713SSean Anderson regmap_write(priv->map, TCSR0, tcsr0 | TCSR_LOAD); 157bc1ce713SSean Anderson regmap_write(priv->map, TCSR1, tcsr1 | TCSR_LOAD); 158bc1ce713SSean Anderson /* Enable timers all at once with ENALL */ 159bc1ce713SSean Anderson tcsr0 = (TCSR_PWM_SET & ~TCSR_ENT) | (tcsr0 & TCSR_UDT); 160bc1ce713SSean Anderson tcsr1 = TCSR_PWM_SET | TCSR_ENALL | (tcsr1 & TCSR_UDT); 161bc1ce713SSean Anderson regmap_write(priv->map, TCSR0, tcsr0); 162bc1ce713SSean Anderson regmap_write(priv->map, TCSR1, tcsr1); 163bc1ce713SSean Anderson } 164bc1ce713SSean Anderson } else { 165bc1ce713SSean Anderson regmap_write(priv->map, TCSR0, 0); 166bc1ce713SSean Anderson regmap_write(priv->map, TCSR1, 0); 167bc1ce713SSean Anderson } 168bc1ce713SSean Anderson 169bc1ce713SSean Anderson return 0; 170bc1ce713SSean Anderson } 171bc1ce713SSean Anderson 172*6c452cffSUwe Kleine-König static int xilinx_pwm_get_state(struct pwm_chip *chip, 173bc1ce713SSean Anderson struct pwm_device *unused, 174bc1ce713SSean Anderson struct pwm_state *state) 175bc1ce713SSean Anderson { 176bc1ce713SSean Anderson struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip); 177bc1ce713SSean Anderson u32 tlr0, tlr1, tcsr0, tcsr1; 178bc1ce713SSean Anderson 179bc1ce713SSean Anderson regmap_read(priv->map, TLR0, &tlr0); 180bc1ce713SSean Anderson regmap_read(priv->map, TLR1, &tlr1); 181bc1ce713SSean Anderson regmap_read(priv->map, TCSR0, &tcsr0); 182bc1ce713SSean Anderson regmap_read(priv->map, TCSR1, &tcsr1); 183bc1ce713SSean Anderson state->period = xilinx_timer_get_period(priv, tlr0, tcsr0); 184bc1ce713SSean Anderson state->duty_cycle = xilinx_timer_get_period(priv, tlr1, tcsr1); 185bc1ce713SSean Anderson state->enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1); 186bc1ce713SSean Anderson state->polarity = PWM_POLARITY_NORMAL; 187bc1ce713SSean Anderson 188bc1ce713SSean Anderson /* 189bc1ce713SSean Anderson * 100% duty cycle results in constant low output. This may be (very) 190bc1ce713SSean Anderson * wrong if rate > 1 GHz, so fix this if you have such hardware :) 191bc1ce713SSean Anderson */ 192bc1ce713SSean Anderson if (state->period == state->duty_cycle) 193bc1ce713SSean Anderson state->duty_cycle = 0; 194*6c452cffSUwe Kleine-König 195*6c452cffSUwe Kleine-König return 0; 196bc1ce713SSean Anderson } 197bc1ce713SSean Anderson 198bc1ce713SSean Anderson static const struct pwm_ops xilinx_pwm_ops = { 199bc1ce713SSean Anderson .apply = xilinx_pwm_apply, 200bc1ce713SSean Anderson .get_state = xilinx_pwm_get_state, 201bc1ce713SSean Anderson .owner = THIS_MODULE, 202bc1ce713SSean Anderson }; 203bc1ce713SSean Anderson 204bc1ce713SSean Anderson static const struct regmap_config xilinx_pwm_regmap_config = { 205bc1ce713SSean Anderson .reg_bits = 32, 206bc1ce713SSean Anderson .reg_stride = 4, 207bc1ce713SSean Anderson .val_bits = 32, 208bc1ce713SSean Anderson .val_format_endian = REGMAP_ENDIAN_LITTLE, 209bc1ce713SSean Anderson .max_register = TCR1, 210bc1ce713SSean Anderson }; 211bc1ce713SSean Anderson 212bc1ce713SSean Anderson static int xilinx_pwm_probe(struct platform_device *pdev) 213bc1ce713SSean Anderson { 214bc1ce713SSean Anderson int ret; 215bc1ce713SSean Anderson struct device *dev = &pdev->dev; 216bc1ce713SSean Anderson struct device_node *np = dev->of_node; 217bc1ce713SSean Anderson struct xilinx_timer_priv *priv; 218bc1ce713SSean Anderson struct xilinx_pwm_device *xilinx_pwm; 219bc1ce713SSean Anderson u32 pwm_cells, one_timer, width; 220bc1ce713SSean Anderson void __iomem *regs; 221bc1ce713SSean Anderson 222bc1ce713SSean Anderson /* If there are no PWM cells, this binding is for a timer */ 223bc1ce713SSean Anderson ret = of_property_read_u32(np, "#pwm-cells", &pwm_cells); 224bc1ce713SSean Anderson if (ret == -EINVAL) 225bc1ce713SSean Anderson return -ENODEV; 226bc1ce713SSean Anderson if (ret) 227bc1ce713SSean Anderson return dev_err_probe(dev, ret, "could not read #pwm-cells\n"); 228bc1ce713SSean Anderson 229bc1ce713SSean Anderson xilinx_pwm = devm_kzalloc(dev, sizeof(*xilinx_pwm), GFP_KERNEL); 230bc1ce713SSean Anderson if (!xilinx_pwm) 231bc1ce713SSean Anderson return -ENOMEM; 232bc1ce713SSean Anderson platform_set_drvdata(pdev, xilinx_pwm); 233bc1ce713SSean Anderson priv = &xilinx_pwm->priv; 234bc1ce713SSean Anderson 235bc1ce713SSean Anderson regs = devm_platform_ioremap_resource(pdev, 0); 236bc1ce713SSean Anderson if (IS_ERR(regs)) 237bc1ce713SSean Anderson return PTR_ERR(regs); 238bc1ce713SSean Anderson 239bc1ce713SSean Anderson priv->map = devm_regmap_init_mmio(dev, regs, 240bc1ce713SSean Anderson &xilinx_pwm_regmap_config); 241bc1ce713SSean Anderson if (IS_ERR(priv->map)) 242bc1ce713SSean Anderson return dev_err_probe(dev, PTR_ERR(priv->map), 243bc1ce713SSean Anderson "Could not create regmap\n"); 244bc1ce713SSean Anderson 245bc1ce713SSean Anderson ret = of_property_read_u32(np, "xlnx,one-timer-only", &one_timer); 246bc1ce713SSean Anderson if (ret) 247bc1ce713SSean Anderson return dev_err_probe(dev, ret, 248bc1ce713SSean Anderson "Could not read xlnx,one-timer-only\n"); 249bc1ce713SSean Anderson 250bc1ce713SSean Anderson if (one_timer) 251bc1ce713SSean Anderson return dev_err_probe(dev, -EINVAL, 252bc1ce713SSean Anderson "Two timers required for PWM mode\n"); 253bc1ce713SSean Anderson 254bc1ce713SSean Anderson ret = of_property_read_u32(np, "xlnx,count-width", &width); 255bc1ce713SSean Anderson if (ret == -EINVAL) 256bc1ce713SSean Anderson width = 32; 257bc1ce713SSean Anderson else if (ret) 258bc1ce713SSean Anderson return dev_err_probe(dev, ret, 259bc1ce713SSean Anderson "Could not read xlnx,count-width\n"); 260bc1ce713SSean Anderson 261bc1ce713SSean Anderson if (width != 8 && width != 16 && width != 32) 262bc1ce713SSean Anderson return dev_err_probe(dev, -EINVAL, 263bc1ce713SSean Anderson "Invalid counter width %d\n", width); 264bc1ce713SSean Anderson priv->max = BIT_ULL(width) - 1; 265bc1ce713SSean Anderson 266bc1ce713SSean Anderson /* 267bc1ce713SSean Anderson * The polarity of the Generate Out signals must be active high for PWM 268bc1ce713SSean Anderson * mode to work. We could determine this from the device tree, but 269bc1ce713SSean Anderson * alas, such properties are not allowed to be used. 270bc1ce713SSean Anderson */ 271bc1ce713SSean Anderson 272bc1ce713SSean Anderson priv->clk = devm_clk_get(dev, "s_axi_aclk"); 273bc1ce713SSean Anderson if (IS_ERR(priv->clk)) 274bc1ce713SSean Anderson return dev_err_probe(dev, PTR_ERR(priv->clk), 275bc1ce713SSean Anderson "Could not get clock\n"); 276bc1ce713SSean Anderson 277bc1ce713SSean Anderson ret = clk_prepare_enable(priv->clk); 278bc1ce713SSean Anderson if (ret) 279bc1ce713SSean Anderson return dev_err_probe(dev, ret, "Clock enable failed\n"); 280bc1ce713SSean Anderson clk_rate_exclusive_get(priv->clk); 281bc1ce713SSean Anderson 282bc1ce713SSean Anderson xilinx_pwm->chip.dev = dev; 283bc1ce713SSean Anderson xilinx_pwm->chip.ops = &xilinx_pwm_ops; 284bc1ce713SSean Anderson xilinx_pwm->chip.npwm = 1; 285bc1ce713SSean Anderson ret = pwmchip_add(&xilinx_pwm->chip); 286bc1ce713SSean Anderson if (ret) { 287bc1ce713SSean Anderson clk_rate_exclusive_put(priv->clk); 288bc1ce713SSean Anderson clk_disable_unprepare(priv->clk); 289bc1ce713SSean Anderson return dev_err_probe(dev, ret, "Could not register PWM chip\n"); 290bc1ce713SSean Anderson } 291bc1ce713SSean Anderson 292bc1ce713SSean Anderson return 0; 293bc1ce713SSean Anderson } 294bc1ce713SSean Anderson 295bc1ce713SSean Anderson static int xilinx_pwm_remove(struct platform_device *pdev) 296bc1ce713SSean Anderson { 297bc1ce713SSean Anderson struct xilinx_pwm_device *xilinx_pwm = platform_get_drvdata(pdev); 298bc1ce713SSean Anderson 299bc1ce713SSean Anderson pwmchip_remove(&xilinx_pwm->chip); 300bc1ce713SSean Anderson clk_rate_exclusive_put(xilinx_pwm->priv.clk); 301bc1ce713SSean Anderson clk_disable_unprepare(xilinx_pwm->priv.clk); 302bc1ce713SSean Anderson return 0; 303bc1ce713SSean Anderson } 304bc1ce713SSean Anderson 305bc1ce713SSean Anderson static const struct of_device_id xilinx_pwm_of_match[] = { 306bc1ce713SSean Anderson { .compatible = "xlnx,xps-timer-1.00.a", }, 307bc1ce713SSean Anderson {}, 308bc1ce713SSean Anderson }; 309bc1ce713SSean Anderson MODULE_DEVICE_TABLE(of, xilinx_pwm_of_match); 310bc1ce713SSean Anderson 311bc1ce713SSean Anderson static struct platform_driver xilinx_pwm_driver = { 312bc1ce713SSean Anderson .probe = xilinx_pwm_probe, 313bc1ce713SSean Anderson .remove = xilinx_pwm_remove, 314bc1ce713SSean Anderson .driver = { 315bc1ce713SSean Anderson .name = "xilinx-pwm", 316bc1ce713SSean Anderson .of_match_table = of_match_ptr(xilinx_pwm_of_match), 317bc1ce713SSean Anderson }, 318bc1ce713SSean Anderson }; 319bc1ce713SSean Anderson module_platform_driver(xilinx_pwm_driver); 320bc1ce713SSean Anderson 321bc1ce713SSean Anderson MODULE_ALIAS("platform:xilinx-pwm"); 322bc1ce713SSean Anderson MODULE_DESCRIPTION("PWM driver for Xilinx LogiCORE IP AXI Timer"); 323bc1ce713SSean Anderson MODULE_LICENSE("GPL"); 324