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