1 /* arch/arm/plat-s3c/include/plat/cpu-freq.h
3 * Copyright (c) 2006,2007,2009 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
7 * S3C CPU frequency scaling support - core support
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.
14 #include <plat/cpu-freq.h>
17 #define S3C2412_MAX_IO (8)
20 * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings
21 * @bankcon: The cached version of settings in this structure.
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.
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
34 struct s3c2410_iobank_timing {
35 unsigned long bankcon;
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. */
46 struct s3c2410_iobank_timing *io_2410;
50 * struct s3c_iotimings - Chip IO timings holder
51 * @bank: The timings for each IO bank.
53 struct s3c_iotimings {
54 union s3c_iobank bank[MAX_BANKS];
58 * struct s3c_plltab - PLL table information.
59 * @vals: List of PLL values.
60 * @size: Size of the PLL table @vals.
63 struct s3c_pllval *vals;
68 * struct s3c_cpufreq_config - current cpu frequency configuration
69 * @freq: The current settings for the core clocks.
70 * @max: Maxium settings, derived from core, board and user settings.
71 * @pll: The PLL table entry for the current PLL settings.
72 * @divs: The divisor settings for the core clocks.
73 * @info: The current core driver information.
74 * @board: The information for the board we are running on.
75 * @lock_pll: Set if the PLL settings cannot be changed.
77 * This is for the core drivers that need to know information about
78 * the current settings and values. It should not be needed by any
81 struct s3c_cpufreq_config {
84 struct cpufreq_frequency_table pll;
85 struct s3c_clkdivs divs;
86 struct s3c_cpufreq_info *info; /* for core, not drivers */
87 struct s3c_cpufreq_board *board;
89 unsigned int lock_pll:1;
93 * struct s3c_cpufreq_info - Information for the CPU frequency driver.
94 * @name: The name of this implementation.
95 * @max: The maximum frequencies for the system.
96 * @latency: Transition latency to give to cpufreq.
97 * @locktime_m: The lock-time in uS for the MPLL.
98 * @locktime_u: The lock-time in uS for the UPLL.
99 * @locttime_bits: The number of bits each LOCKTIME field.
100 * @need_pll: Set if this driver needs to change the PLL values to acheive
101 * any frequency changes. This is really only need by devices like the
102 * S3C2410 where there is no or limited divider between the PLL and the
104 * @resume_clocks: Update the clocks on resume.
105 * @get_iotiming: Get the current IO timing data, mainly for use at start.
106 * @set_iotiming: Update the IO timings from the cached copies calculated
107 * from the @calc_iotiming entry when changing the frequency.
108 * @calc_iotiming: Calculate and update the cached copies of the IO timings
109 * from the newly calculated frequencies.
110 * @calc_freqtable: Calculate (fill in) the given frequency table from the
111 * current frequency configuration. If the table passed in is NULL,
112 * then the return is the number of elements to be filled for allocation
114 * @set_refresh: Set the memory refresh configuration.
115 * @set_fvco: Set the PLL frequencies.
116 * @set_divs: Update the clock divisors.
117 * @calc_divs: Calculate the clock divisors.
119 struct s3c_cpufreq_info {
123 unsigned int latency;
125 unsigned int locktime_m;
126 unsigned int locktime_u;
127 unsigned char locktime_bits;
129 unsigned int need_pll:1;
131 /* driver routines */
133 void (*resume_clocks)(void);
135 int (*get_iotiming)(struct s3c_cpufreq_config *cfg,
136 struct s3c_iotimings *timings);
138 void (*set_iotiming)(struct s3c_cpufreq_config *cfg,
139 struct s3c_iotimings *timings);
141 int (*calc_iotiming)(struct s3c_cpufreq_config *cfg,
142 struct s3c_iotimings *timings);
144 int (*calc_freqtable)(struct s3c_cpufreq_config *cfg,
145 struct cpufreq_frequency_table *t,
148 void (*set_refresh)(struct s3c_cpufreq_config *cfg);
149 void (*set_fvco)(struct s3c_cpufreq_config *cfg);
150 void (*set_divs)(struct s3c_cpufreq_config *cfg);
151 int (*calc_divs)(struct s3c_cpufreq_config *cfg);
154 extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
156 extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no);
158 /* Useful utility functions. */
160 extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
162 /* S3C2410 and compatible exported functions */
164 extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
166 extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
167 struct s3c_iotimings *iot);
169 extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
170 struct s3c_iotimings *timings);
172 extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
173 struct s3c_iotimings *iot);
175 extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
177 #ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
178 #define s3c_freq_dbg(x...) printk(KERN_INFO x)
180 #define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
181 #endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
183 #ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
184 #define s3c_freq_iodbg(x...) printk(KERN_INFO x)
186 #define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
187 #endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
189 static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
190 int index, size_t table_size,
197 if (index >= table_size)
200 s3c_freq_dbg("%s: { %d = %u kHz }\n",
201 __func__, index, freq);
203 table[index].index = index;
204 table[index].frequency = freq;