Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 1 | /* arch/arm/plat-s3c/include/plat/cpu-freq.h |
| 2 | * |
Ben Dooks | e02f866 | 2009-11-13 22:54:13 +0000 | [diff] [blame] | 3 | * Copyright (c) 2006-2007 Simtec Electronics |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 4 | * http://armlinux.simtec.co.uk/ |
| 5 | * Ben Dooks <ben@simtec.co.uk> |
| 6 | * |
| 7 | * S3C CPU frequency scaling support - driver and board |
| 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 <linux/cpufreq.h> |
| 15 | |
| 16 | struct s3c_cpufreq_info; |
| 17 | struct s3c_cpufreq_board; |
| 18 | struct s3c_iotimings; |
| 19 | |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 20 | /** |
| 21 | * struct s3c_freq - frequency information (mainly for core drivers) |
| 22 | * @fclk: The FCLK frequency in Hz. |
| 23 | * @armclk: The ARMCLK frequency in Hz. |
| 24 | * @hclk_tns: HCLK cycle time in 10ths of nano-seconds. |
| 25 | * @hclk: The HCLK frequency in Hz. |
| 26 | * @pclk: The PCLK frequency in Hz. |
| 27 | * |
| 28 | * This contains the frequency information about the current configuration |
| 29 | * mainly for the core drivers to ensure we do not end up passing about |
| 30 | * a large number of parameters. |
| 31 | * |
| 32 | * The @hclk_tns field is a useful cache for the parts of the drivers that |
| 33 | * need to calculate IO timings and suchlike. |
| 34 | */ |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 35 | struct s3c_freq { |
| 36 | unsigned long fclk; |
| 37 | unsigned long armclk; |
| 38 | unsigned long hclk_tns; /* in 10ths of ns */ |
| 39 | unsigned long hclk; |
| 40 | unsigned long pclk; |
| 41 | }; |
| 42 | |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 43 | /** |
| 44 | * struct s3c_cpufreq_freqs - s3c cpufreq notification information. |
| 45 | * @freqs: The cpufreq setting information. |
| 46 | * @old: The old clock settings. |
| 47 | * @new: The new clock settings. |
| 48 | * @pll_changing: Set if the PLL is changing. |
| 49 | * |
| 50 | * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 51 | * notification can use this information that is not provided by just |
| 52 | * having the core frequency alone. |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 53 | * |
| 54 | * The pll_changing flag is used to indicate if the PLL itself is |
| 55 | * being set during this change. This is important as the clocks |
| 56 | * will temporarily be set to the XTAL clock during this time, so |
| 57 | * drivers may want to close down their output during this time. |
| 58 | * |
| 59 | * Note, this is not being used by any current drivers and therefore |
| 60 | * may be removed in the future. |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 61 | */ |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 62 | struct s3c_cpufreq_freqs { |
| 63 | struct cpufreq_freqs freqs; |
| 64 | struct s3c_freq old; |
| 65 | struct s3c_freq new; |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 66 | |
| 67 | unsigned int pll_changing:1; |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 68 | }; |
| 69 | |
| 70 | #define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs) |
| 71 | |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 72 | /** |
| 73 | * struct s3c_clkdivs - clock divisor information |
| 74 | * @p_divisor: Divisor from FCLK to PCLK. |
| 75 | * @h_divisor: Divisor from FCLK to HCLK. |
| 76 | * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs). |
| 77 | * @dvs: Non-zero if using DVS mode for ARMCLK. |
| 78 | * |
| 79 | * Divisor settings for the core clocks. |
| 80 | */ |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 81 | struct s3c_clkdivs { |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 82 | int p_divisor; |
| 83 | int h_divisor; |
| 84 | int arm_divisor; |
| 85 | unsigned char dvs; |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 86 | }; |
| 87 | |
| 88 | #define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s)) |
| 89 | |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 90 | /** |
| 91 | * struct s3c_pllval - PLL value entry. |
| 92 | * @freq: The frequency for this entry in Hz. |
| 93 | * @pll_reg: The PLL register setting for this PLL value. |
| 94 | */ |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 95 | struct s3c_pllval { |
| 96 | unsigned long freq; |
| 97 | unsigned long pll_reg; |
| 98 | }; |
| 99 | |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 100 | /** |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 101 | * struct s3c_cpufreq_board - per-board cpu frequency informatin |
| 102 | * @refresh: The SDRAM refresh period in nanoseconds. |
| 103 | * @auto_io: Set if the IO timing settings should be generated from the |
| 104 | * initialisation time hardware registers. |
| 105 | * @need_io: Set if the board has external IO on any of the chipselect |
| 106 | * lines that will require the hardware timing registers to be |
| 107 | * updated on a clock change. |
| 108 | * @max: The maxium frequency limits for the system. Any field that |
| 109 | * is left at zero will use the CPU's settings. |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 110 | * |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 111 | * This contains the board specific settings that affect how the CPU |
| 112 | * drivers chose settings. These include the memory refresh and IO |
| 113 | * timing information. |
| 114 | * |
| 115 | * Registration depends on the driver being used, the ARMCLK only |
| 116 | * implementation does not currently need this but the older style |
| 117 | * driver requires this to be available. |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 118 | */ |
| 119 | struct s3c_cpufreq_board { |
Ben Dooks | ea5fe9a | 2009-07-30 23:23:22 +0100 | [diff] [blame] | 120 | unsigned int refresh; |
Ben Dooks | 7f565ec | 2008-10-21 14:06:21 +0100 | [diff] [blame] | 121 | unsigned int auto_io:1; /* automatically init io timings. */ |
| 122 | unsigned int need_io:1; /* set if needs io timing support. */ |
| 123 | |
| 124 | /* any non-zero field in here is taken as an upper limit. */ |
| 125 | struct s3c_freq max; /* frequency limits */ |
| 126 | }; |
| 127 | |
| 128 | /* Things depending on frequency scaling. */ |
| 129 | #ifdef CONFIG_CPU_FREQ_S3C |
| 130 | #define __init_or_cpufreq |
| 131 | #else |
| 132 | #define __init_or_cpufreq __init |
| 133 | #endif |
| 134 | |
| 135 | /* Board functions */ |
| 136 | |
| 137 | #ifdef CONFIG_CPU_FREQ_S3C |
| 138 | extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board); |
| 139 | #else |
| 140 | |
| 141 | static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) |
| 142 | { |
| 143 | return 0; |
| 144 | } |
| 145 | #endif /* CONFIG_CPU_FREQ_S3C */ |