1 /* 2 * Copyright (c) 2015 Neil Armstrong <narmstrong@baylibre.com> 3 * Copyright (c) 2014 Joachim Eastwood <manabian@gmail.com> 4 * Copyright (c) 2012 NeilBrown <neilb@suse.de> 5 * Heavily based on earlier code which is: 6 * Copyright (c) 2010 Grant Erickson <marathon96@gmail.com> 7 * 8 * Also based on pwm-samsung.c 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * version 2 as published by the Free Software Foundation. 13 * 14 * Description: 15 * This file is the core OMAP support for the generic, Linux 16 * PWM driver / controller, using the OMAP's dual-mode timers. 17 */ 18 19 #include <linux/clk.h> 20 #include <linux/err.h> 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/mutex.h> 24 #include <linux/of.h> 25 #include <linux/of_platform.h> 26 #include <linux/platform_data/pwm_omap_dmtimer.h> 27 #include <linux/platform_device.h> 28 #include <linux/pm_runtime.h> 29 #include <linux/pwm.h> 30 #include <linux/slab.h> 31 #include <linux/time.h> 32 33 #define DM_TIMER_LOAD_MIN 0xfffffffe 34 35 struct pwm_omap_dmtimer_chip { 36 struct pwm_chip chip; 37 struct mutex mutex; 38 pwm_omap_dmtimer *dm_timer; 39 struct pwm_omap_dmtimer_pdata *pdata; 40 struct platform_device *dm_timer_pdev; 41 }; 42 43 static inline struct pwm_omap_dmtimer_chip * 44 to_pwm_omap_dmtimer_chip(struct pwm_chip *chip) 45 { 46 return container_of(chip, struct pwm_omap_dmtimer_chip, chip); 47 } 48 49 static int pwm_omap_dmtimer_calc_value(unsigned long clk_rate, int ns) 50 { 51 u64 c = (u64)clk_rate * ns; 52 53 do_div(c, NSEC_PER_SEC); 54 55 return DM_TIMER_LOAD_MIN - c; 56 } 57 58 static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap) 59 { 60 /* 61 * According to OMAP 4 TRM section 22.2.4.10 the counter should be 62 * started at 0xFFFFFFFE when overflow and match is used to ensure 63 * that the PWM line is toggled on the first event. 64 * 65 * Note that omap_dm_timer_enable/disable is for register access and 66 * not the timer counter itself. 67 */ 68 omap->pdata->enable(omap->dm_timer); 69 omap->pdata->write_counter(omap->dm_timer, DM_TIMER_LOAD_MIN); 70 omap->pdata->disable(omap->dm_timer); 71 72 omap->pdata->start(omap->dm_timer); 73 } 74 75 static int pwm_omap_dmtimer_enable(struct pwm_chip *chip, 76 struct pwm_device *pwm) 77 { 78 struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); 79 80 mutex_lock(&omap->mutex); 81 pwm_omap_dmtimer_start(omap); 82 mutex_unlock(&omap->mutex); 83 84 return 0; 85 } 86 87 static void pwm_omap_dmtimer_disable(struct pwm_chip *chip, 88 struct pwm_device *pwm) 89 { 90 struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); 91 92 mutex_lock(&omap->mutex); 93 omap->pdata->stop(omap->dm_timer); 94 mutex_unlock(&omap->mutex); 95 } 96 97 static int pwm_omap_dmtimer_config(struct pwm_chip *chip, 98 struct pwm_device *pwm, 99 int duty_ns, int period_ns) 100 { 101 struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); 102 int load_value, match_value; 103 struct clk *fclk; 104 unsigned long clk_rate; 105 bool timer_active; 106 107 dev_dbg(chip->dev, "duty cycle: %d, period %d\n", duty_ns, period_ns); 108 109 mutex_lock(&omap->mutex); 110 if (duty_ns == pwm_get_duty_cycle(pwm) && 111 period_ns == pwm_get_period(pwm)) { 112 /* No change - don't cause any transients. */ 113 mutex_unlock(&omap->mutex); 114 return 0; 115 } 116 117 fclk = omap->pdata->get_fclk(omap->dm_timer); 118 if (!fclk) { 119 dev_err(chip->dev, "invalid pmtimer fclk\n"); 120 mutex_unlock(&omap->mutex); 121 return -EINVAL; 122 } 123 124 clk_rate = clk_get_rate(fclk); 125 if (!clk_rate) { 126 dev_err(chip->dev, "invalid pmtimer fclk rate\n"); 127 mutex_unlock(&omap->mutex); 128 return -EINVAL; 129 } 130 131 dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate); 132 133 /* 134 * Calculate the appropriate load and match values based on the 135 * specified period and duty cycle. The load value determines the 136 * cycle time and the match value determines the duty cycle. 137 */ 138 load_value = pwm_omap_dmtimer_calc_value(clk_rate, period_ns); 139 match_value = pwm_omap_dmtimer_calc_value(clk_rate, 140 period_ns - duty_ns); 141 142 /* 143 * We MUST stop the associated dual-mode timer before attempting to 144 * write its registers, but calls to omap_dm_timer_start/stop must 145 * be balanced so check if timer is active before calling timer_stop. 146 */ 147 timer_active = pm_runtime_active(&omap->dm_timer_pdev->dev); 148 if (timer_active) 149 omap->pdata->stop(omap->dm_timer); 150 151 omap->pdata->set_load(omap->dm_timer, true, load_value); 152 omap->pdata->set_match(omap->dm_timer, true, match_value); 153 154 dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n", 155 load_value, load_value, match_value, match_value); 156 157 omap->pdata->set_pwm(omap->dm_timer, 158 pwm->polarity == PWM_POLARITY_INVERSED, 159 true, 160 PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); 161 162 /* If config was called while timer was running it must be reenabled. */ 163 if (timer_active) 164 pwm_omap_dmtimer_start(omap); 165 166 mutex_unlock(&omap->mutex); 167 168 return 0; 169 } 170 171 static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip, 172 struct pwm_device *pwm, 173 enum pwm_polarity polarity) 174 { 175 struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); 176 177 /* 178 * PWM core will not call set_polarity while PWM is enabled so it's 179 * safe to reconfigure the timer here without stopping it first. 180 */ 181 mutex_lock(&omap->mutex); 182 omap->pdata->set_pwm(omap->dm_timer, 183 polarity == PWM_POLARITY_INVERSED, 184 true, 185 PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); 186 mutex_unlock(&omap->mutex); 187 188 return 0; 189 } 190 191 static const struct pwm_ops pwm_omap_dmtimer_ops = { 192 .enable = pwm_omap_dmtimer_enable, 193 .disable = pwm_omap_dmtimer_disable, 194 .config = pwm_omap_dmtimer_config, 195 .set_polarity = pwm_omap_dmtimer_set_polarity, 196 .owner = THIS_MODULE, 197 }; 198 199 static int pwm_omap_dmtimer_probe(struct platform_device *pdev) 200 { 201 struct device_node *np = pdev->dev.of_node; 202 struct device_node *timer; 203 struct pwm_omap_dmtimer_chip *omap; 204 struct pwm_omap_dmtimer_pdata *pdata; 205 pwm_omap_dmtimer *dm_timer; 206 u32 prescaler; 207 int status; 208 209 pdata = dev_get_platdata(&pdev->dev); 210 if (!pdata) { 211 dev_err(&pdev->dev, "Missing dmtimer platform data\n"); 212 return -EINVAL; 213 } 214 215 if (!pdata->request_by_node || 216 !pdata->free || 217 !pdata->enable || 218 !pdata->disable || 219 !pdata->get_fclk || 220 !pdata->start || 221 !pdata->stop || 222 !pdata->set_load || 223 !pdata->set_match || 224 !pdata->set_pwm || 225 !pdata->set_prescaler || 226 !pdata->write_counter) { 227 dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); 228 return -EINVAL; 229 } 230 231 timer = of_parse_phandle(np, "ti,timers", 0); 232 if (!timer) 233 return -ENODEV; 234 235 if (!of_get_property(timer, "ti,timer-pwm", NULL)) { 236 dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); 237 return -ENODEV; 238 } 239 240 dm_timer = pdata->request_by_node(timer); 241 if (!dm_timer) 242 return -EPROBE_DEFER; 243 244 omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); 245 if (!omap) { 246 pdata->free(dm_timer); 247 return -ENOMEM; 248 } 249 250 omap->pdata = pdata; 251 omap->dm_timer = dm_timer; 252 253 omap->dm_timer_pdev = of_find_device_by_node(timer); 254 if (!omap->dm_timer_pdev) { 255 dev_err(&pdev->dev, "Unable to find timer pdev\n"); 256 omap->pdata->free(dm_timer); 257 return -EINVAL; 258 } 259 260 /* 261 * Ensure that the timer is stopped before we allow PWM core to call 262 * pwm_enable. 263 */ 264 if (pm_runtime_active(&omap->dm_timer_pdev->dev)) 265 omap->pdata->stop(omap->dm_timer); 266 267 /* setup dmtimer prescaler */ 268 if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", 269 &prescaler)) 270 omap->pdata->set_prescaler(omap->dm_timer, prescaler); 271 272 omap->chip.dev = &pdev->dev; 273 omap->chip.ops = &pwm_omap_dmtimer_ops; 274 omap->chip.base = -1; 275 omap->chip.npwm = 1; 276 omap->chip.of_xlate = of_pwm_xlate_with_flags; 277 omap->chip.of_pwm_n_cells = 3; 278 279 mutex_init(&omap->mutex); 280 281 status = pwmchip_add(&omap->chip); 282 if (status < 0) { 283 dev_err(&pdev->dev, "failed to register PWM\n"); 284 omap->pdata->free(omap->dm_timer); 285 return status; 286 } 287 288 platform_set_drvdata(pdev, omap); 289 290 return 0; 291 } 292 293 static int pwm_omap_dmtimer_remove(struct platform_device *pdev) 294 { 295 struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev); 296 297 if (pm_runtime_active(&omap->dm_timer_pdev->dev)) 298 omap->pdata->stop(omap->dm_timer); 299 300 omap->pdata->free(omap->dm_timer); 301 302 mutex_destroy(&omap->mutex); 303 304 return pwmchip_remove(&omap->chip); 305 } 306 307 static const struct of_device_id pwm_omap_dmtimer_of_match[] = { 308 {.compatible = "ti,omap-dmtimer-pwm"}, 309 {} 310 }; 311 MODULE_DEVICE_TABLE(of, pwm_omap_dmtimer_of_match); 312 313 static struct platform_driver pwm_omap_dmtimer_driver = { 314 .driver = { 315 .name = "omap-dmtimer-pwm", 316 .of_match_table = of_match_ptr(pwm_omap_dmtimer_of_match), 317 }, 318 .probe = pwm_omap_dmtimer_probe, 319 .remove = pwm_omap_dmtimer_remove, 320 }; 321 module_platform_driver(pwm_omap_dmtimer_driver); 322 323 MODULE_AUTHOR("Grant Erickson <marathon96@gmail.com>"); 324 MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); 325 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 326 MODULE_LICENSE("GPL v2"); 327 MODULE_DESCRIPTION("OMAP PWM Driver using Dual-mode Timers"); 328