Home | History | Annotate | Download | only in lpc32xx
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2011 Vladimir Zapolskiy <vz (at) mleia.com>
      4  */
      5 
      6 #include <common.h>
      7 #include <asm/arch/cpu.h>
      8 #include <asm/arch/clk.h>
      9 #include <asm/arch/timer.h>
     10 #include <asm/io.h>
     11 
     12 static struct timer_regs  *timer0 = (struct timer_regs *)TIMER0_BASE;
     13 static struct timer_regs  *timer1 = (struct timer_regs *)TIMER1_BASE;
     14 static struct clk_pm_regs *clk    = (struct clk_pm_regs *)CLK_PM_BASE;
     15 
     16 static void lpc32xx_timer_clock(u32 bit, int enable)
     17 {
     18 	if (enable)
     19 		setbits_le32(&clk->timclk_ctrl1, bit);
     20 	else
     21 		clrbits_le32(&clk->timclk_ctrl1, bit);
     22 }
     23 
     24 static void lpc32xx_timer_reset(struct timer_regs *timer, u32 freq)
     25 {
     26 	writel(TIMER_TCR_COUNTER_RESET,   &timer->tcr);
     27 	writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr);
     28 	writel(0, &timer->tc);
     29 	writel(0, &timer->pr);
     30 
     31 	/* Count mode is every rising PCLK edge */
     32 	writel(TIMER_CTCR_MODE_TIMER, &timer->ctcr);
     33 
     34 	/* Set prescale counter value */
     35 	writel((get_periph_clk_rate() / freq) - 1, &timer->pr);
     36 }
     37 
     38 static void lpc32xx_timer_count(struct timer_regs *timer, int enable)
     39 {
     40 	if (enable)
     41 		writel(TIMER_TCR_COUNTER_ENABLE,  &timer->tcr);
     42 	else
     43 		writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr);
     44 }
     45 
     46 int timer_init(void)
     47 {
     48 	lpc32xx_timer_clock(CLK_TIMCLK_TIMER0, 1);
     49 	lpc32xx_timer_reset(timer0, CONFIG_SYS_HZ);
     50 	lpc32xx_timer_count(timer0, 1);
     51 
     52 	return 0;
     53 }
     54 
     55 ulong get_timer(ulong base)
     56 {
     57 	return readl(&timer0->tc) - base;
     58 }
     59 
     60 void __udelay(unsigned long usec)
     61 {
     62 	lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 1);
     63 	lpc32xx_timer_reset(timer1, CONFIG_SYS_HZ * 1000);
     64 	lpc32xx_timer_count(timer1, 1);
     65 
     66 	while (readl(&timer1->tc) < usec)
     67 		/* NOP */;
     68 
     69 	lpc32xx_timer_count(timer1, 0);
     70 	lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 0);
     71 }
     72 
     73 unsigned long long get_ticks(void)
     74 {
     75 	return get_timer(0);
     76 }
     77 
     78 ulong get_tbclk(void)
     79 {
     80 	return CONFIG_SYS_HZ;
     81 }
     82