]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/arm1176/s3c64xx/speed.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / cpu / arm1176 / s3c64xx / speed.c
1 /*
2  * (C) Copyright 2001-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2002
6  * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27 /*
28  * This code should work for both the S3C2400 and the S3C2410
29  * as they seem to have the same PLL and clock machinery inside.
30  * The different address mapping is handled by the s3c24xx.h files below.
31  */
32
33 #include <common.h>
34 #include <asm/arch/s3c6400.h>
35
36 #define APLL 0
37 #define MPLL 1
38 #define EPLL 2
39
40 /* ------------------------------------------------------------------------- */
41 /*
42  * NOTE: This describes the proper use of this file.
43  *
44  * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
45  *
46  * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
47  * the specified bus in HZ.
48  */
49 /* ------------------------------------------------------------------------- */
50
51 static ulong get_PLLCLK(int pllreg)
52 {
53         ulong r, m, p, s;
54
55         switch (pllreg) {
56         case APLL:
57                 r = APLL_CON_REG;
58                 break;
59         case MPLL:
60                 r = MPLL_CON_REG;
61                 break;
62         case EPLL:
63                 r = EPLL_CON0_REG;
64                 break;
65         default:
66                 hang();
67         }
68
69         m = (r >> 16) & 0x3ff;
70         p = (r >> 8) & 0x3f;
71         s = r & 0x7;
72
73         return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s)));
74 }
75
76 /* return ARMCORE frequency */
77 ulong get_ARMCLK(void)
78 {
79         ulong div;
80
81         div = CLK_DIV0_REG;
82
83         return get_PLLCLK(APLL) / ((div & 0x7) + 1);
84 }
85
86 /* return FCLK frequency */
87 ulong get_FCLK(void)
88 {
89         return get_PLLCLK(APLL);
90 }
91
92 /* return HCLK frequency */
93 ulong get_HCLK(void)
94 {
95         ulong fclk;
96
97         uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
98         uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1;
99
100         /*
101          * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on
102          * s3c6400 and is always 0, and it is indeed running in ASYNC mode
103          */
104         if (OTHERS_REG & 0x80)
105                 fclk = get_FCLK();              /* SYNC Mode    */
106         else
107                 fclk = get_PLLCLK(MPLL);        /* ASYNC Mode   */
108
109         return fclk / (hclk_div * hclkx2_div);
110 }
111
112 /* return PCLK frequency */
113 ulong get_PCLK(void)
114 {
115         ulong fclk;
116         uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
117         uint pre_div = ((CLK_DIV0_REG >> 12) & 0xf) + 1;
118
119         if (OTHERS_REG & 0x80)
120                 fclk = get_FCLK();              /* SYNC Mode    */
121         else
122                 fclk = get_PLLCLK(MPLL);        /* ASYNC Mode   */
123
124         return fclk / (hclkx2_div * pre_div);
125 }
126
127 /* return UCLK frequency */
128 ulong get_UCLK(void)
129 {
130         return get_PLLCLK(EPLL);
131 }
132
133 int print_cpuinfo(void)
134 {
135         printf("\nCPU:     S3C6400@%luMHz\n", get_ARMCLK() / 1000000);
136         printf("         Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ",
137                get_FCLK() / 1000000, get_HCLK() / 1000000,
138                get_PCLK() / 1000000);
139
140         if (OTHERS_REG & 0x80)
141                 printf("(SYNC Mode) \n");
142         else
143                 printf("(ASYNC Mode) \n");
144         return 0;
145 }