Lines Matching +full:timer +full:- +full:pwm

1 // SPDX-License-Identifier: GPL-2.0-only
6 * samsung - Common hr-timer support (s3c and s5p)
79 static struct samsung_pwm_clocksource pwm; variable
92 reg = readl(pwm.base + REG_TCFG0); in samsung_timer_set_prescale()
94 reg |= (prescale - 1) << shift; in samsung_timer_set_prescale()
95 writel(reg, pwm.base + REG_TCFG0); in samsung_timer_set_prescale()
107 bits = (fls(divisor) - 1) - pwm.variant.div_base; in samsung_timer_set_divisor()
111 reg = readl(pwm.base + REG_TCFG1); in samsung_timer_set_divisor()
114 writel(reg, pwm.base + REG_TCFG1); in samsung_timer_set_divisor()
129 tcon = readl_relaxed(pwm.base + REG_TCON); in samsung_time_stop()
131 writel_relaxed(tcon, pwm.base + REG_TCON); in samsung_time_stop()
147 tcon = readl_relaxed(pwm.base + REG_TCON); in samsung_time_setup()
152 writel_relaxed(tcnt, pwm.base + REG_TCNTB(channel)); in samsung_time_setup()
153 writel_relaxed(tcnt, pwm.base + REG_TCMPB(channel)); in samsung_time_setup()
154 writel_relaxed(tcon, pwm.base + REG_TCON); in samsung_time_setup()
169 tcon = readl_relaxed(pwm.base + REG_TCON); in samsung_time_start()
179 writel_relaxed(tcon, pwm.base + REG_TCON); in samsung_time_start()
191 * timer interrupt and hang the system. in samsung_set_next_event()
200 samsung_time_setup(pwm.event_id, cycles); in samsung_set_next_event()
201 samsung_time_start(pwm.event_id, false); in samsung_set_next_event()
208 samsung_time_stop(pwm.event_id); in samsung_shutdown()
214 samsung_time_stop(pwm.event_id); in samsung_set_periodic()
215 samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1); in samsung_set_periodic()
216 samsung_time_start(pwm.event_id, true); in samsung_set_periodic()
222 samsung_timer_set_prescale(pwm.event_id, pwm.tscaler_div); in samsung_clockevent_resume()
223 samsung_timer_set_divisor(pwm.event_id, pwm.tdiv); in samsung_clockevent_resume()
225 if (pwm.variant.has_tint_cstat) { in samsung_clockevent_resume()
226 u32 mask = (1 << pwm.event_id); in samsung_clockevent_resume()
228 writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT); in samsung_clockevent_resume()
249 if (pwm.variant.has_tint_cstat) { in samsung_clock_event_isr()
250 u32 mask = (1 << pwm.event_id); in samsung_clock_event_isr()
252 writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT); in samsung_clock_event_isr()
255 evt->event_handler(evt); in samsung_clock_event_isr()
266 pclk = clk_get_rate(pwm.timerclk); in samsung_clockevent_init()
268 samsung_timer_set_prescale(pwm.event_id, pwm.tscaler_div); in samsung_clockevent_init()
269 samsung_timer_set_divisor(pwm.event_id, pwm.tdiv); in samsung_clockevent_init()
271 clock_rate = pclk / (pwm.tscaler_div * pwm.tdiv); in samsung_clockevent_init()
272 pwm.clock_count_per_tick = clock_rate / HZ; in samsung_clockevent_init()
276 clock_rate, 1, pwm.tcnt_max); in samsung_clockevent_init()
278 irq_number = pwm.irq[pwm.event_id]; in samsung_clockevent_init()
284 if (pwm.variant.has_tint_cstat) { in samsung_clockevent_init()
285 u32 mask = (1 << pwm.event_id); in samsung_clockevent_init()
287 writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT); in samsung_clockevent_init()
293 samsung_time_stop(pwm.source_id); in samsung_clocksource_suspend()
298 samsung_timer_set_prescale(pwm.source_id, pwm.tscaler_div); in samsung_clocksource_resume()
299 samsung_timer_set_divisor(pwm.source_id, pwm.tdiv); in samsung_clocksource_resume()
301 samsung_time_setup(pwm.source_id, pwm.tcnt_max); in samsung_clocksource_resume()
302 samsung_time_start(pwm.source_id, true); in samsung_clocksource_resume()
307 return ~readl_relaxed(pwm.source_reg); in samsung_clocksource_read()
336 pclk = clk_get_rate(pwm.timerclk); in samsung_clocksource_init()
338 samsung_timer_set_prescale(pwm.source_id, pwm.tscaler_div); in samsung_clocksource_init()
339 samsung_timer_set_divisor(pwm.source_id, pwm.tdiv); in samsung_clocksource_init()
341 clock_rate = pclk / (pwm.tscaler_div * pwm.tdiv); in samsung_clocksource_init()
343 samsung_time_setup(pwm.source_id, pwm.tcnt_max); in samsung_clocksource_init()
344 samsung_time_start(pwm.source_id, true); in samsung_clocksource_init()
346 if (pwm.source_id == 4) in samsung_clocksource_init()
347 pwm.source_reg = pwm.base + 0x40; in samsung_clocksource_init()
349 pwm.source_reg = pwm.base + pwm.source_id * 0x0c + 0x14; in samsung_clocksource_init()
352 pwm.variant.bits, clock_rate); in samsung_clocksource_init()
354 samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits); in samsung_clocksource_init()
360 clk_prepare_enable(pwm.timerclk); in samsung_timer_resources()
362 pwm.tcnt_max = (1UL << pwm.variant.bits) - 1; in samsung_timer_resources()
363 if (pwm.variant.bits == 16) { in samsung_timer_resources()
364 pwm.tscaler_div = 25; in samsung_timer_resources()
365 pwm.tdiv = 2; in samsung_timer_resources()
367 pwm.tscaler_div = 2; in samsung_timer_resources()
368 pwm.tdiv = 1; in samsung_timer_resources()
373 * PWM master driver
380 mask = ~pwm.variant.output_mask & ((1 << SAMSUNG_PWM_NUM) - 1); in _samsung_pwm_clocksource_init()
381 channel = fls(mask) - 1; in _samsung_pwm_clocksource_init()
383 pr_crit("failed to find PWM channel for clocksource\n"); in _samsung_pwm_clocksource_init()
384 return -EINVAL; in _samsung_pwm_clocksource_init()
386 pwm.source_id = channel; in _samsung_pwm_clocksource_init()
389 channel = fls(mask) - 1; in _samsung_pwm_clocksource_init()
391 pr_crit("failed to find PWM channel for clock event\n"); in _samsung_pwm_clocksource_init()
392 return -EINVAL; in _samsung_pwm_clocksource_init()
394 pwm.event_id = channel; in _samsung_pwm_clocksource_init()
406 pwm.base = base; in samsung_pwm_clocksource_init()
407 memcpy(&pwm.variant, variant, sizeof(pwm.variant)); in samsung_pwm_clocksource_init()
408 memcpy(pwm.irq, irqs, SAMSUNG_PWM_NUM * sizeof(*irqs)); in samsung_pwm_clocksource_init()
410 pwm.timerclk = clk_get(NULL, "timers"); in samsung_pwm_clocksource_init()
411 if (IS_ERR(pwm.timerclk)) in samsung_pwm_clocksource_init()
412 panic("failed to get timers clock for timer"); in samsung_pwm_clocksource_init()
424 memcpy(&pwm.variant, variant, sizeof(pwm.variant)); in samsung_pwm_alloc()
426 pwm.irq[i] = irq_of_parse_and_map(np, i); in samsung_pwm_alloc()
428 of_property_for_each_u32(np, "samsung,pwm-outputs", val) { in samsung_pwm_alloc()
430 pr_warn("%s: invalid channel index in samsung,pwm-outputs property\n", __func__); in samsung_pwm_alloc()
433 pwm.variant.output_mask |= 1 << val; in samsung_pwm_alloc()
436 pwm.base = of_iomap(np, 0); in samsung_pwm_alloc()
437 if (!pwm.base) { in samsung_pwm_alloc()
438 pr_err("%s: failed to map PWM registers\n", __func__); in samsung_pwm_alloc()
439 return -ENXIO; in samsung_pwm_alloc()
442 pwm.timerclk = of_clk_get_by_name(np, "timers"); in samsung_pwm_alloc()
443 if (IS_ERR(pwm.timerclk)) { in samsung_pwm_alloc()
444 pr_crit("failed to get timers clock for timer\n"); in samsung_pwm_alloc()
445 ret = PTR_ERR(pwm.timerclk); in samsung_pwm_alloc()
456 clk_put(pwm.timerclk); in samsung_pwm_alloc()
457 pwm.timerclk = NULL; in samsung_pwm_alloc()
459 iounmap(pwm.base); in samsung_pwm_alloc()
460 pwm.base = NULL; in samsung_pwm_alloc()
476 TIMER_OF_DECLARE(s3c2410_pwm, "samsung,s3c2410-pwm", s3c2410_pwm_clocksource_init);
489 TIMER_OF_DECLARE(s3c6400_pwm, "samsung,s3c6400-pwm", s3c64xx_pwm_clocksource_init);
502 TIMER_OF_DECLARE(s5p6440_pwm, "samsung,s5p6440-pwm", s5p64x0_pwm_clocksource_init);
515 TIMER_OF_DECLARE(s5pc100_pwm, "samsung,s5pc100-pwm", s5p_pwm_clocksource_init);