]>
Commit | Line | Data |
---|---|---|
3776801d A |
1 | /* |
2 | * Program for finding M & N values for DPLLs | |
3 | * To be run on Host PC | |
4 | * | |
5 | * (C) Copyright 2010 | |
6 | * Texas Instruments, <www.ti.com> | |
7 | * | |
8 | * Aneesh V <aneesh@ti.com> | |
9 | * | |
10 | * See file CREDITS for list of people who contributed to this | |
11 | * project. | |
12 | * | |
13 | * This program is free software; you can redistribute it and/or | |
14 | * modify it under the terms of the GNU General Public License as | |
15 | * published by the Free Software Foundation; either version 2 of | |
16 | * the License, or (at your option) any later version. | |
17 | * | |
18 | * This program is distributed in the hope that it will be useful, | |
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | * GNU General Public License for more details. | |
22 | * | |
23 | * You should have received a copy of the GNU General Public License | |
24 | * along with this program; if not, write to the Free Software | |
25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
26 | * MA 02111-1307 USA | |
27 | */ | |
28 | #include <stdlib.h> | |
29 | #include <stdio.h> | |
30 | typedef unsigned int u32; | |
31 | #define MAX_N 127 | |
32 | ||
33 | /* | |
34 | * get_m_n_optimized() - Finds optimal DPLL multiplier(M) and divider(N) | |
35 | * values based on the reference frequency, required output frequency, | |
36 | * maximum tolerance for output frequency etc. | |
37 | * | |
38 | * target_freq_khz - output frequency required in KHz | |
39 | * ref_freq_khz - reference(input) frequency in KHz | |
40 | * m - pointer to computed M value | |
41 | * n - pointer to computed N value | |
42 | * tolerance_khz - tolerance for the output frequency. When the algorithm | |
43 | * succeeds in finding vialble M and N values the corresponding output | |
44 | * frequency will be in the range: | |
45 | * [target_freq_khz - tolerance_khz, target_freq_khz] | |
46 | * | |
47 | * Formula: | |
48 | * Fdpll = (2 * M * Fref) / (N + 1) | |
49 | * | |
50 | * Considerations for lock-time: | |
51 | * - Smaller the N, better lock-time, especially lock-time will be | |
52 | * - For acceptable lock-times: | |
53 | * Fref / (M + 1) >= 1 MHz | |
54 | * | |
55 | * Considerations for power: | |
56 | * - The difference in power for different N values giving the same | |
57 | * output is negligible. So, we optimize for lock-time | |
58 | * | |
59 | * Hard-constraints: | |
60 | * - N can not be greater than 127(7 bit field for representing N) | |
61 | * | |
62 | * Usage: | |
63 | * $ gcc clocks_get_m_n.c | |
64 | * $ ./a.out | |
65 | */ | |
66 | int get_m_n_optimized(u32 target_freq_khz, u32 ref_freq_khz, u32 *m, u32 *n, | |
67 | u32 tolerance_khz) | |
68 | { | |
69 | u32 min_freq = target_freq_khz - tolerance_khz; | |
70 | u32 max_freq = target_freq_khz; | |
71 | u32 freq, freq_old; | |
72 | *n = 1; | |
73 | while (1) { | |
74 | *m = min_freq / ref_freq_khz / 2 * (*n) ; | |
75 | freq_old = 0; | |
76 | while (1) { | |
77 | freq = ref_freq_khz * 2 * (*m) / (*n); | |
78 | if (abs(target_freq_khz - freq_old) <= | |
79 | abs(target_freq_khz - freq)) { | |
80 | freq = freq_old; | |
81 | (*m)--; | |
82 | break; | |
83 | } | |
84 | (*m)++; | |
85 | freq_old = freq; | |
86 | } | |
87 | if (freq >= min_freq && freq <= max_freq) | |
88 | break; | |
89 | (*n)++; | |
90 | if ((*n) > MAX_N + 1) { | |
91 | printf("ref %d m %d n %d target %d : ", | |
92 | ref_freq_khz, *m, *n, target_freq_khz); | |
93 | printf("can not find m & n - please consider" | |
94 | " increasing tolerance\n"); | |
95 | return -1; | |
96 | } | |
97 | } | |
98 | (*n)--; | |
99 | printf("ref %d m %d n %d target %d locked %d\n", | |
100 | ref_freq_khz, *m, *n, target_freq_khz, freq); | |
101 | if ((ref_freq_khz / (*n + 1)) < 1000) { | |
102 | printf("\tREFCLK - CLKINP/(N+1) is less than 1 MHz - less than" | |
103 | " ideal, locking time will be high!\n"); | |
104 | } | |
105 | return 0; | |
106 | } | |
107 | ||
108 | void main(void) | |
109 | { | |
110 | u32 m, n; | |
111 | printf("\nMPU - 2000000\n"); | |
112 | get_m_n_optimized(2000000, 12000, &m, &n, 0); | |
113 | get_m_n_optimized(2000000, 13000, &m, &n, 0); | |
114 | get_m_n_optimized(2000000, 16800, &m, &n, 800); | |
115 | get_m_n_optimized(2000000, 19200, &m, &n, 0); | |
116 | get_m_n_optimized(2000000, 26000, &m, &n, 0); | |
117 | get_m_n_optimized(2000000, 27000, &m, &n, 0); | |
118 | get_m_n_optimized(2000000, 38400, &m, &n, 0); | |
119 | ||
120 | printf("\nMPU - 1200000\n"); | |
121 | get_m_n_optimized(1200000, 12000, &m, &n, 0); | |
122 | get_m_n_optimized(1200000, 13000, &m, &n, 0); | |
123 | get_m_n_optimized(1200000, 16800, &m, &n, 800); | |
124 | get_m_n_optimized(1200000, 19200, &m, &n, 0); | |
125 | get_m_n_optimized(1200000, 26000, &m, &n, 0); | |
126 | get_m_n_optimized(1200000, 27000, &m, &n, 0); | |
127 | get_m_n_optimized(1200000, 38400, &m, &n, 0); | |
128 | ||
129 | printf("\nMPU - 1584000\n"); | |
130 | get_m_n_optimized(1584000, 12000, &m, &n, 0); | |
131 | get_m_n_optimized(1584000, 13000, &m, &n, 0); | |
132 | get_m_n_optimized(1584000, 16800, &m, &n, 400); | |
133 | get_m_n_optimized(1584000, 19200, &m, &n, 0); | |
134 | get_m_n_optimized(1584000, 26000, &m, &n, 0); | |
135 | get_m_n_optimized(1584000, 27000, &m, &n, 0); | |
136 | get_m_n_optimized(1584000, 38400, &m, &n, 0); | |
137 | ||
138 | printf("\nCore 1600000\n"); | |
139 | get_m_n_optimized(1600000, 12000, &m, &n, 0); | |
140 | get_m_n_optimized(1600000, 13000, &m, &n, 0); | |
141 | get_m_n_optimized(1600000, 16800, &m, &n, 200); | |
142 | get_m_n_optimized(1600000, 19200, &m, &n, 0); | |
143 | get_m_n_optimized(1600000, 26000, &m, &n, 0); | |
144 | get_m_n_optimized(1600000, 27000, &m, &n, 0); | |
145 | get_m_n_optimized(1600000, 38400, &m, &n, 0); | |
146 | ||
147 | printf("\nPER 1536000\n"); | |
148 | get_m_n_optimized(1536000, 12000, &m, &n, 0); | |
149 | get_m_n_optimized(1536000, 13000, &m, &n, 0); | |
150 | get_m_n_optimized(1536000, 16800, &m, &n, 0); | |
151 | get_m_n_optimized(1536000, 19200, &m, &n, 0); | |
152 | get_m_n_optimized(1536000, 26000, &m, &n, 0); | |
153 | get_m_n_optimized(1536000, 27000, &m, &n, 0); | |
154 | get_m_n_optimized(1536000, 38400, &m, &n, 0); | |
155 | ||
156 | printf("\nIVA 1862000\n"); | |
157 | get_m_n_optimized(1862000, 12000, &m, &n, 0); | |
158 | get_m_n_optimized(1862000, 13000, &m, &n, 0); | |
159 | get_m_n_optimized(1862000, 16800, &m, &n, 0); | |
160 | get_m_n_optimized(1862000, 19200, &m, &n, 900); | |
161 | get_m_n_optimized(1862000, 26000, &m, &n, 0); | |
162 | get_m_n_optimized(1862000, 27000, &m, &n, 0); | |
163 | get_m_n_optimized(1862000, 38400, &m, &n, 800); | |
164 | ||
165 | printf("\nABE 196608 sys clk\n"); | |
166 | get_m_n_optimized(196608, 12000, &m, &n, 700); | |
167 | get_m_n_optimized(196608, 13000, &m, &n, 200); | |
168 | get_m_n_optimized(196608, 16800, &m, &n, 700); | |
169 | get_m_n_optimized(196608, 19200, &m, &n, 400); | |
170 | get_m_n_optimized(196608, 26000, &m, &n, 200); | |
171 | get_m_n_optimized(196608, 27000, &m, &n, 900); | |
172 | get_m_n_optimized(196608, 38400, &m, &n, 0); | |
173 | ||
174 | printf("\nABE 196608 32K\n"); | |
175 | get_m_n_optimized(196608000/4, 32768, &m, &n, 0); | |
176 | ||
177 | printf("\nUSB 1920000\n"); | |
178 | get_m_n_optimized(1920000, 12000, &m, &n, 0); | |
179 | get_m_n_optimized(1920000, 13000, &m, &n, 0); | |
180 | get_m_n_optimized(1920000, 16800, &m, &n, 0); | |
181 | get_m_n_optimized(1920000, 19200, &m, &n, 0); | |
182 | get_m_n_optimized(1920000, 26000, &m, &n, 0); | |
183 | get_m_n_optimized(1920000, 27000, &m, &n, 0); | |
184 | get_m_n_optimized(1920000, 38400, &m, &n, 0); | |
185 | ||
186 | printf("\nCore ES1 1523712\n"); | |
187 | get_m_n_optimized(1524000, 12000, &m, &n, 100); | |
188 | get_m_n_optimized(1524000, 13000, &m, &n, 0); | |
189 | get_m_n_optimized(1524000, 16800, &m, &n, 0); | |
190 | get_m_n_optimized(1524000, 19200, &m, &n, 0); | |
191 | get_m_n_optimized(1524000, 26000, &m, &n, 0); | |
192 | get_m_n_optimized(1524000, 27000, &m, &n, 0); | |
193 | ||
194 | /* exact recommendation for SDPs */ | |
195 | get_m_n_optimized(1523712, 38400, &m, &n, 0); | |
196 | ||
197 | } |