This commit was manufactured by cvs2svn to create branch 'fedora'.
[linux-2.6.git] / arch / arm / mach-pxa / pxa27x.c
1 /*
2  *  linux/arch/arm/mach-pxa/pxa27x.c
3  *
4  *  Author:     Nicolas Pitre
5  *  Created:    Nov 05, 2002
6  *  Copyright:  MontaVista Software Inc.
7  *
8  * Code specific to PXA27x aka Bulverde.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14 #include <linux/config.h>
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/pm.h>
19
20 #include <asm/hardware.h>
21
22 #include "generic.h"
23
24 /* Crystal clock : 13-MHZ*/
25 #define BASE_CLK        13000000
26
27 /*
28  * Get the clock frequency as reflected by CCSR and the turbo flag.
29  * We assume these values have been applied via a fcs.
30  * If info is not 0 we also display the current settings.
31  *
32  * For more details, refer to Bulverde Manual, section 3.8.2.1
33  */
34 unsigned int get_clk_frequency_khz( int info)
35 {
36         unsigned long ccsr, turbo, b, ht;
37         unsigned int l, L, m, M, n2, N, S, cccra;
38
39         ccsr = CCSR;
40         cccra = CCCR & (0x1 << 25);
41
42         /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
43         asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) );
44         b = (turbo & (0x1 << 3));
45         ht = (turbo & (0x1 << 2));
46
47         l  = ccsr & 0x1f;
48         n2 = (ccsr>>7) & 0xf;
49         if (l == 31) {
50                 /* The calculation from the Yellow Book is incorrect:
51                    it says M=4 for L=21-30 (which is easy to calculate
52                    by subtracting 1 and then dividing by 10, but not
53                    with 31, so we'll do it manually */
54                 m = 1 << 2;
55         } else {
56                 m = 1 << ((l-1)/10);
57         }
58
59         L = l * BASE_CLK;
60         N = (n2 * L) / 2;
61         S = (b) ? L : (L/2);
62         if (cccra == 0)
63                 M = L/m;
64         else
65                 M = (b) ? L : (L/2);
66
67         if (info) {
68                 printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
69                         L / 1000000, (L % 1000000) / 10000, l );
70                 printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n",
71                         M / 1000000, (M % 1000000) / 10000, m );
72                 printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
73                         N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5,
74                         (turbo & 1) ? "" : "in" );
75                 printk( KERN_INFO "System bus clock: %d.%02dMHz \n",
76                         S / 1000000, (S % 1000000) / 10000 );
77         }
78
79         return (turbo & 1) ? (N/1000) : (L/1000);
80 }
81
82 /*
83  * Return the current mem clock frequency in units of 10kHz as
84  * reflected by CCCR[A], B, and L
85  */
86 unsigned int get_lclk_frequency_10khz(void)
87 {
88         unsigned long ccsr, clkcfg, b;
89         unsigned int l, L, m, M, cccra;
90
91         cccra = CCCR & (0x1 << 25);
92
93         /* Read clkcfg register to obtain b */
94         asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
95         b = (clkcfg & (0x1 << 3));
96
97         ccsr = CCSR;
98         l  =  ccsr & 0x1f;
99         if (l == 31) {
100                 /* The calculation from the Yellow Book is incorrect:
101                    it says M=4 for L=21-30 (which is easy to calculate
102                    by subtracting 1 and then dividing by 10, but not
103                    with 31, so we'll do it manually */
104                 m = 1 << 2;
105         } else {
106                 m = 1 << ((l-1)/10);
107         }
108
109         L = l * BASE_CLK;
110         if (cccra == 0)
111                 M = L/m;
112         else
113                 M = (b) ? L : L/2;
114
115         return (M / 10000);
116 }
117
118 EXPORT_SYMBOL(get_clk_frequency_khz);
119 EXPORT_SYMBOL(get_lclk_frequency_10khz);
120