2 * (C) Copyright 2003 Intracom S.A.
3 * Pantelis Antoniou <panto@intracom.gr>
5 * This little program makes an exhaustive search for the
6 * correct terms of pdf, mfi, mfn, mfd, s, dbrmo, in PLPRCR.
7 * The goal is to produce a gclk2 from a xin input, while respecting
8 * all the restrictions on their combination.
10 * Generaly you select the first row of the produced table.
12 * See file CREDITS for list of people who contributed to this
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
35 #define DPREF_MIN 10000000
36 #define DPREF_MAX 32000000
38 #define DPGDCK_MAX 320000000
39 #define DPGDCK_MIN 160000000
59 #define GCLK2_MAX 150000000
61 static int calculate (int xin
, int target_clock
,
62 int ppm
, int pdf
, int mfi
, int mfn
, int mfd
, int s
,
63 int *dprefp
, int *dpgdckp
, int *jdbckp
,
64 int *gclk2p
, int *dbrmop
)
66 unsigned int dpref
, dpgdck
, jdbck
, gclk2
, t1
, t2
, dbrmo
;
72 /* valid num, denum? */
73 if (mfn
> 0 && mfn
>= mfd
)
76 dpref
= xin
/ (pdf
+ 1);
79 if (dpref
< DPREF_MIN
|| dpref
> DPREF_MAX
)
83 dpgdck
= (2 * mfi
* xin
) / (pdf
+ 1) ;
86 /* 5 <= mfi + (mfn / mfd + 1) <= 15 */
89 if ( MF_MIN
* t1
> t2
|| MF_MAX
* t1
< t2
)
92 dpgdck
= (unsigned int)(2 * (mfi
* mfd
+ mfi
+ mfn
) *
94 ((mfd
+ 1) * (pdf
+ 1));
96 dbrmo
= 10 * mfn
< (mfd
+ 1);
100 if (dpgdck
< DPGDCK_MIN
|| dpgdck
> DPGDCK_MAX
)
107 if (gclk2
> GCLK2_MAX
)
110 t1
= abs(gclk2
- target_clock
);
112 /* XXX max 1MHz dev. in clock */
116 /* dev within range (XXX gclk2 scaled to avoid overflow) */
117 if (t1
* 1000 > (unsigned int)ppm
* (gclk2
/ 1000))
129 int conf_clock(int xin
, int target_clock
, int ppm
)
131 int pdf
, s
, mfn
, mfd
, mfi
;
132 int dpref
, dpgdck
, jdbck
, gclk2
, xout
, dbrmo
;
135 /* integer multipliers */
136 for (pdf
= PDF_MIN
; pdf
<= PDF_MAX
; pdf
++) {
137 for (mfi
= MFI_MIN
; mfi
<= MFI_MAX
; mfi
++) {
138 for (s
= 0; s
<= S_MAX
; s
++) {
139 xout
= calculate(xin
, target_clock
,
140 ppm
, pdf
, mfi
, 0, 0, s
,
141 &dpref
, &dpgdck
, &jdbck
,
147 printf("pdf mfi mfn mfd s dbrmo dpref dpgdck jdbck gclk2 exact?\n");
148 printf("--- --- --- --- - ----- ----- ------ ----- ----- ------\n");
151 printf("%3d %3d --- --- %1d %5d %9d %9d %9d %9d%s\n",
153 dpref
, dpgdck
, jdbck
, gclk2
,
154 gclk2
== target_clock
? " YES" : "");
161 /* fractional multipliers */
162 for (pdf
= PDF_MIN
; pdf
<= PDF_MAX
; pdf
++) {
163 for (mfi
= MFI_MIN
; mfi
<= MFI_MAX
; mfi
++) {
164 for (mfn
= 1; mfn
<= MFN_MAX
; mfn
++) {
165 for (mfd
= 1; mfd
<= MFD_MAX
; mfd
++) {
166 for (s
= 0; s
<= S_MAX
; s
++) {
167 xout
= calculate(xin
, target_clock
,
168 ppm
, pdf
, mfi
, mfn
, mfd
, s
,
169 &dpref
, &dpgdck
, &jdbck
,
175 printf("pdf mfi mfn mfd s dbrmo dpref dpgdck jdbck gclk2 exact?\n");
176 printf("--- --- --- --- - ----- ----- ------ ----- ----- ------\n");
179 printf("%3d %3d %3d %3d %1d %5d %9d %9d %9d %9d%s\n",
180 pdf
, mfi
, mfn
, mfd
, s
,
181 dbrmo
, dpref
, dpgdck
, jdbck
, gclk2
,
182 gclk2
== target_clock
? " YES" : "");
195 int main(int argc
, char *argv
[])
197 int xin
, want_gclk2
, found
, ppm
= 100;
200 fprintf(stderr
, "usage: mpc86x_clk <xin> <want_gclk2> [ppm]\n");
201 fprintf(stderr
, " default ppm is 100\n");
206 want_gclk2
= atoi(argv
[2]);
210 found
= conf_clock(xin
, want_gclk2
, ppm
);
212 fprintf(stderr
, "cannot produce gclk2 %d from xin %d\n",