]>
Commit | Line | Data |
---|---|---|
64fdf452 SB |
1 | /* |
2 | * (C) Copyright 2007 | |
3 | * Sascha Hauer, Pengutronix | |
4 | * | |
5 | * (C) Copyright 2009 Freescale Semiconductor, Inc. | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
64fdf452 SB |
8 | */ |
9 | ||
10 | #include <common.h> | |
11 | #include <asm/io.h> | |
782bb0d2 | 12 | #include <div64.h> |
64fdf452 | 13 | #include <asm/arch/imx-regs.h> |
833b6435 | 14 | #include <asm/arch/clock.h> |
1a1f7950 | 15 | #include <asm/arch/sys_proto.h> |
64fdf452 SB |
16 | |
17 | /* General purpose timers registers */ | |
18 | struct mxc_gpt { | |
19 | unsigned int control; | |
20 | unsigned int prescaler; | |
21 | unsigned int status; | |
22 | unsigned int nouse[6]; | |
23 | unsigned int counter; | |
24 | }; | |
25 | ||
26 | static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; | |
27 | ||
28 | /* General purpose timers bitfields */ | |
18936ee2 | 29 | #define GPTCR_SWR (1 << 15) /* Software reset */ |
1a1f7950 | 30 | #define GPTCR_24MEN (1 << 10) /* Enable 24MHz clock input */ |
18936ee2 | 31 | #define GPTCR_FRR (1 << 9) /* Freerun / restart */ |
1a1f7950 YL |
32 | #define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source 32khz */ |
33 | #define GPTCR_CLKSOURCE_OSC (5 << 6) /* Clock source OSC */ | |
34 | #define GPTCR_CLKSOURCE_PRE (1 << 6) /* Clock source PRECLK */ | |
35 | #define GPTCR_CLKSOURCE_MASK (0x7 << 6) | |
18936ee2 | 36 | #define GPTCR_TEN 1 /* Timer enable */ |
64fdf452 | 37 | |
1a1f7950 YL |
38 | #define GPTPR_PRESCALER24M_SHIFT 12 |
39 | #define GPTPR_PRESCALER24M_MASK (0xF << GPTPR_PRESCALER24M_SHIFT) | |
40 | ||
db106ef7 SB |
41 | DECLARE_GLOBAL_DATA_PTR; |
42 | ||
1a1f7950 YL |
43 | static inline int gpt_has_clk_source_osc(void) |
44 | { | |
45 | #if defined(CONFIG_MX6) | |
27cd0da4 | 46 | if (((is_mx6dq()) && (soc_rev() > CHIP_REV_1_0)) || |
988acd2d PF |
47 | is_mx6dqp() || is_mx6sdl() || is_mx6sx() || is_mx6ul() || |
48 | is_mx6ull()) | |
1a1f7950 YL |
49 | return 1; |
50 | ||
51 | return 0; | |
52 | #else | |
53 | return 0; | |
54 | #endif | |
55 | } | |
56 | ||
57 | static inline ulong gpt_get_clk(void) | |
58 | { | |
59 | #ifdef CONFIG_MXC_GPT_HCLK | |
60 | if (gpt_has_clk_source_osc()) | |
61 | return MXC_HCLK >> 3; | |
62 | else | |
63 | return mxc_get_clock(MXC_IPG_PERCLK); | |
64 | #else | |
65 | return MXC_CLK32; | |
66 | #endif | |
67 | } | |
782bb0d2 | 68 | |
64fdf452 SB |
69 | int timer_init(void) |
70 | { | |
71 | int i; | |
72 | ||
73 | /* setup GP Timer 1 */ | |
74 | __raw_writel(GPTCR_SWR, &cur_gpt->control); | |
75 | ||
76 | /* We have no udelay by now */ | |
77 | for (i = 0; i < 100; i++) | |
78 | __raw_writel(0, &cur_gpt->control); | |
79 | ||
64fdf452 | 80 | i = __raw_readl(&cur_gpt->control); |
1a1f7950 YL |
81 | i &= ~GPTCR_CLKSOURCE_MASK; |
82 | ||
83 | #ifdef CONFIG_MXC_GPT_HCLK | |
84 | if (gpt_has_clk_source_osc()) { | |
85 | i |= GPTCR_CLKSOURCE_OSC | GPTCR_TEN; | |
86 | ||
988acd2d PF |
87 | /* For DL/S, SX, UL, ULL set 24Mhz OSC Enable bit and prescaler */ |
88 | if (is_mx6sdl() || is_mx6sx() || is_mx6ul() || is_mx6ull()) { | |
1a1f7950 YL |
89 | i |= GPTCR_24MEN; |
90 | ||
91 | /* Produce 3Mhz clock */ | |
92 | __raw_writel((7 << GPTPR_PRESCALER24M_SHIFT), | |
93 | &cur_gpt->prescaler); | |
94 | } | |
95 | } else { | |
96 | i |= GPTCR_CLKSOURCE_PRE | GPTCR_TEN; | |
97 | } | |
98 | #else | |
99 | __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ | |
100 | i |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; | |
101 | #endif | |
102 | __raw_writel(i, &cur_gpt->control); | |
64fdf452 | 103 | |
982a3c41 KW |
104 | gd->arch.tbl = __raw_readl(&cur_gpt->counter); |
105 | gd->arch.tbu = 0; | |
17659d7d GR |
106 | |
107 | return 0; | |
64fdf452 SB |
108 | } |
109 | ||
2bb01482 | 110 | unsigned long timer_read_counter(void) |
64fdf452 | 111 | { |
2bb01482 | 112 | return __raw_readl(&cur_gpt->counter); /* current tick value */ |
782bb0d2 | 113 | } |
64fdf452 | 114 | |
782bb0d2 SB |
115 | /* |
116 | * This function is derived from PowerPC code (timebase clock frequency). | |
117 | * On ARM it returns the number of timer ticks per second. | |
118 | */ | |
119 | ulong get_tbclk(void) | |
120 | { | |
1a1f7950 | 121 | return gpt_get_clk(); |
64fdf452 | 122 | } |