]>
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) | |
46 | if (((is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) && | |
b65d9d86 | 47 | (soc_rev() > CHIP_REV_1_0)) || is_cpu_type(MXC_CPU_MX6DL) || |
35d5e543 PF |
48 | is_cpu_type(MXC_CPU_MX6SOLO) || is_cpu_type(MXC_CPU_MX6SX) || |
49 | is_cpu_type(MXC_CPU_MX6UL)) | |
1a1f7950 YL |
50 | return 1; |
51 | ||
52 | return 0; | |
53 | #else | |
54 | return 0; | |
55 | #endif | |
56 | } | |
57 | ||
58 | static inline ulong gpt_get_clk(void) | |
59 | { | |
60 | #ifdef CONFIG_MXC_GPT_HCLK | |
61 | if (gpt_has_clk_source_osc()) | |
62 | return MXC_HCLK >> 3; | |
63 | else | |
64 | return mxc_get_clock(MXC_IPG_PERCLK); | |
65 | #else | |
66 | return MXC_CLK32; | |
67 | #endif | |
68 | } | |
782bb0d2 | 69 | |
64fdf452 SB |
70 | int timer_init(void) |
71 | { | |
72 | int i; | |
73 | ||
74 | /* setup GP Timer 1 */ | |
75 | __raw_writel(GPTCR_SWR, &cur_gpt->control); | |
76 | ||
77 | /* We have no udelay by now */ | |
78 | for (i = 0; i < 100; i++) | |
79 | __raw_writel(0, &cur_gpt->control); | |
80 | ||
64fdf452 | 81 | i = __raw_readl(&cur_gpt->control); |
1a1f7950 YL |
82 | i &= ~GPTCR_CLKSOURCE_MASK; |
83 | ||
84 | #ifdef CONFIG_MXC_GPT_HCLK | |
85 | if (gpt_has_clk_source_osc()) { | |
86 | i |= GPTCR_CLKSOURCE_OSC | GPTCR_TEN; | |
87 | ||
35d5e543 | 88 | /* For DL/S, SX, UL, set 24Mhz OSC Enable bit and prescaler */ |
1a1f7950 YL |
89 | if (is_cpu_type(MXC_CPU_MX6DL) || |
90 | is_cpu_type(MXC_CPU_MX6SOLO) || | |
35d5e543 PF |
91 | is_cpu_type(MXC_CPU_MX6SX) || |
92 | is_cpu_type(MXC_CPU_MX6UL)) { | |
1a1f7950 YL |
93 | i |= GPTCR_24MEN; |
94 | ||
95 | /* Produce 3Mhz clock */ | |
96 | __raw_writel((7 << GPTPR_PRESCALER24M_SHIFT), | |
97 | &cur_gpt->prescaler); | |
98 | } | |
99 | } else { | |
100 | i |= GPTCR_CLKSOURCE_PRE | GPTCR_TEN; | |
101 | } | |
102 | #else | |
103 | __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ | |
104 | i |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; | |
105 | #endif | |
106 | __raw_writel(i, &cur_gpt->control); | |
64fdf452 | 107 | |
982a3c41 KW |
108 | gd->arch.tbl = __raw_readl(&cur_gpt->counter); |
109 | gd->arch.tbu = 0; | |
17659d7d GR |
110 | |
111 | return 0; | |
64fdf452 SB |
112 | } |
113 | ||
2bb01482 | 114 | unsigned long timer_read_counter(void) |
64fdf452 | 115 | { |
2bb01482 | 116 | return __raw_readl(&cur_gpt->counter); /* current tick value */ |
782bb0d2 | 117 | } |
64fdf452 | 118 | |
782bb0d2 SB |
119 | /* |
120 | * This function is derived from PowerPC code (timebase clock frequency). | |
121 | * On ARM it returns the number of timer ticks per second. | |
122 | */ | |
123 | ulong get_tbclk(void) | |
124 | { | |
1a1f7950 | 125 | return gpt_get_clk(); |
64fdf452 | 126 | } |