ARM: S3C24XX: CPUFREQ: Add core support.
[safe/jmp/linux-2.6] / arch / arm / plat-s3c24xx / include / plat / cpu-freq-core.h
1 /* arch/arm/plat-s3c/include/plat/cpu-freq.h
2  *
3  * Copyright (c) 2006,2007,2009 Simtec Electronics
4  *      http://armlinux.simtec.co.uk/
5  *      Ben Dooks <ben@simtec.co.uk>
6  *
7  * S3C CPU frequency scaling support - core support
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12 */
13
14 #include <plat/cpu-freq.h>
15
16 #define MAX_BANKS (8)
17 #define S3C2412_MAX_IO  (8)
18
19 /**
20  * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings
21  * @bankcon: The cached version of settings in this structure.
22  * @tacp:
23  * @tacs: Time from address valid to nCS asserted.
24  * @tcos: Time from nCS asserted to nOE or nWE asserted.
25  * @tacc: Time that nOE or nWE is asserted.
26  * @tcoh: Time nCS is held after nOE or nWE are released.
27  * @tcah: Time address is held for after
28  * @nwait_en: Whether nWAIT is enabled for this bank.
29  *
30  * This structure represents the IO timings for a S3C2410 style IO bank
31  * used by the CPU frequency support if it needs to change the settings
32  * of the IO.
33  */
34 struct s3c2410_iobank_timing {
35         unsigned long   bankcon;
36         unsigned int    tacp;
37         unsigned int    tacs;
38         unsigned int    tcos;
39         unsigned int    tacc;
40         unsigned int    tcoh;           /* nCS hold afrer nOE/nWE */
41         unsigned int    tcah;           /* Address hold after nCS */
42         unsigned char   nwait_en;       /* nWait enabled for bank. */
43 };
44
45 union s3c_iobank {
46           struct s3c2410_iobank_timing  *io_2410;
47 };
48
49 /**
50  * struct s3c_iotimings - Chip IO timings holder
51  * @bank: The timings for each IO bank.
52  */
53 struct s3c_iotimings {
54         union s3c_iobank        bank[MAX_BANKS];
55 };
56
57 /**
58  * struct s3c_plltab - PLL table information.
59  * @vals: List of PLL values.
60  * @size: Size of the PLL table @vals.
61  */
62 struct s3c_plltab {
63         struct s3c_pllval       *vals;
64         int                      size;
65 };
66
67 /**
68  * struct s3c_cpufreq_info - Information for the CPU frequency driver.
69  * @name: The name of this implementation.
70  * @max: The maximum frequencies for the system.
71  * @latency: Transition latency to give to cpufreq.
72  * @locktime_m: The lock-time in uS for the MPLL.
73  * @locktime_u: The lock-time in uS for the UPLL.
74  * @locttime_bits: The number of bits each LOCKTIME field.
75  * @need_pll: Set if this driver needs to change the PLL values to acheive
76  *      any frequency changes. This is really only need by devices like the
77  *      S3C2410 where there is no or limited divider between the PLL and the
78  *      ARMCLK.
79  * @resume_clocks: Update the clocks on resume.
80  * @get_iotiming: Get the current IO timing data, mainly for use at start.
81  * @set_iotiming: Update the IO timings from the cached copies calculated
82  *      from the @calc_iotiming entry when changing the frequency.
83  * @calc_iotiming: Calculate and update the cached copies of the IO timings
84  *      from the newly calculated frequencies.
85  * @calc_freqtable: Calculate (fill in) the given frequency table from the
86  *      current frequency configuration. If the table passed in is NULL,
87  *      then the return is the number of elements to be filled for allocation
88  *      of the table.
89  * @set_refresh: Set the memory refresh configuration.
90  * @set_fvco: Set the PLL frequencies.
91  * @set_divs: Update the clock divisors.
92  * @calc_divs: Calculate the clock divisors.
93  */
94 struct s3c_cpufreq_info {
95         const char              *name;
96         struct s3c_freq         max;
97
98         unsigned int            latency;
99
100         unsigned int            locktime_m;
101         unsigned int            locktime_u;
102         unsigned char           locktime_bits;
103
104         unsigned int            need_pll:1;
105
106         /* driver routines */
107
108         void            (*resume_clocks)(void);
109
110         int             (*get_iotiming)(struct s3c_cpufreq_config *cfg,
111                                         struct s3c_iotimings *timings);
112
113         void            (*set_iotiming)(struct s3c_cpufreq_config *cfg,
114                                         struct s3c_iotimings *timings);
115
116         int             (*calc_iotiming)(struct s3c_cpufreq_config *cfg,
117                                          struct s3c_iotimings *timings);
118
119         int             (*calc_freqtable)(struct s3c_cpufreq_config *cfg,
120                                           struct cpufreq_frequency_table *t,
121                                           size_t table_size);
122
123         void            (*set_refresh)(struct s3c_cpufreq_config *cfg);
124         void            (*set_fvco)(struct s3c_cpufreq_config *cfg);
125         void            (*set_divs)(struct s3c_cpufreq_config *cfg);
126         int             (*calc_divs)(struct s3c_cpufreq_config *cfg);
127 };
128
129 extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
130
131 extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no);
132
133 /* Useful utility functions. */
134
135 extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
136
137 /* S3C2410 and compatible exported functions */
138
139 extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
140
141 extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
142                                  struct s3c_iotimings *iot);
143
144 extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
145                                 struct s3c_iotimings *timings);
146
147 extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
148                                  struct s3c_iotimings *iot);
149
150 extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
151
152 #ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
153 #define s3c_freq_dbg(x...) printk(KERN_INFO x)
154 #else
155 #define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
156 #endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
157
158 #ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
159 #define s3c_freq_iodbg(x...) printk(KERN_INFO x)
160 #else
161 #define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
162 #endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
163
164 static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
165                                       int index, size_t table_size,
166                                       unsigned int freq)
167 {
168         if (index < 0)
169                 return index;
170
171         if (table) {
172                 if (index >= table_size)
173                         return -ENOMEM;
174
175                 s3c_freq_dbg("%s: { %d = %u kHz }\n",
176                              __func__, index, freq);
177
178                 table[index].index = index;
179                 table[index].frequency = freq;
180         }
181
182         return index + 1;
183 }