~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/arch/powerpc/cpu/ppc4xx/cpu_init.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2000-2007
 
3
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
4
 *
 
5
 * SPDX-License-Identifier:     GPL-2.0+
 
6
 */
 
7
 
 
8
#include <common.h>
 
9
#include <watchdog.h>
 
10
#include <asm/ppc4xx-emac.h>
 
11
#include <asm/processor.h>
 
12
#include <asm/ppc4xx-gpio.h>
 
13
#include <asm/ppc4xx.h>
 
14
 
 
15
#if defined(CONFIG_405GP)  || defined(CONFIG_405EP)
 
16
DECLARE_GLOBAL_DATA_PTR;
 
17
#endif
 
18
 
 
19
#ifndef CONFIG_SYS_PLL_RECONFIG
 
20
#define CONFIG_SYS_PLL_RECONFIG 0
 
21
#endif
 
22
 
 
23
#if defined(CONFIG_440EPX) || \
 
24
    defined(CONFIG_460EX) || defined(CONFIG_460GT)
 
25
static void reset_with_rli(void)
 
26
{
 
27
        u32 reg;
 
28
 
 
29
        /*
 
30
         * Set reload inhibit so configuration will persist across
 
31
         * processor resets
 
32
         */
 
33
        mfcpr(CPR0_ICFG, reg);
 
34
        reg |= CPR0_ICFG_RLI_MASK;
 
35
        mtcpr(CPR0_ICFG, reg);
 
36
 
 
37
        /* Reset processor if configuration changed */
 
38
        __asm__ __volatile__ ("sync; isync");
 
39
        mtspr(SPRN_DBCR0, 0x20000000);
 
40
}
 
41
#endif
 
42
 
 
43
void reconfigure_pll(u32 new_cpu_freq)
 
44
{
 
45
#if defined(CONFIG_440EPX)
 
46
        int     reset_needed = 0;
 
47
        u32     reg, temp;
 
48
        u32     prbdv0, target_prbdv0,                          /* CLK_PRIMBD */
 
49
                fwdva, target_fwdva, fwdvb, target_fwdvb,       /* CLK_PLLD */
 
50
                fbdv, target_fbdv, lfbdv, target_lfbdv,
 
51
                perdv0, target_perdv0,                          /* CLK_PERD */
 
52
                spcid0, target_spcid0;                          /* CLK_SPCID */
 
53
 
 
54
        /* Reconfigure clocks if necessary.
 
55
         * See PPC440EPx User's Manual, sections 8.2 and 14 */
 
56
        if (new_cpu_freq == 667) {
 
57
                target_prbdv0 = 2;
 
58
                target_fwdva = 2;
 
59
                target_fwdvb = 4;
 
60
                target_fbdv = 20;
 
61
                target_lfbdv = 1;
 
62
                target_perdv0 = 4;
 
63
                target_spcid0 = 4;
 
64
 
 
65
                mfcpr(CPR0_PRIMBD0, reg);
 
66
                temp = (reg & PRBDV_MASK) >> 24;
 
67
                prbdv0 = temp ? temp : 8;
 
68
                if (prbdv0 != target_prbdv0) {
 
69
                        reg &= ~PRBDV_MASK;
 
70
                        reg |= ((target_prbdv0 == 8 ? 0 : target_prbdv0) << 24);
 
71
                        mtcpr(CPR0_PRIMBD0, reg);
 
72
                        reset_needed = 1;
 
73
                }
 
74
 
 
75
                mfcpr(CPR0_PLLD, reg);
 
76
 
 
77
                temp = (reg & PLLD_FWDVA_MASK) >> 16;
 
78
                fwdva = temp ? temp : 16;
 
79
 
 
80
                temp = (reg & PLLD_FWDVB_MASK) >> 8;
 
81
                fwdvb = temp ? temp : 8;
 
82
 
 
83
                temp = (reg & PLLD_FBDV_MASK) >> 24;
 
84
                fbdv = temp ? temp : 32;
 
85
 
 
86
                temp = (reg & PLLD_LFBDV_MASK);
 
87
                lfbdv = temp ? temp : 64;
 
88
 
 
89
                if (fwdva != target_fwdva || fbdv != target_fbdv || lfbdv != target_lfbdv) {
 
90
                        reg &= ~(PLLD_FWDVA_MASK | PLLD_FWDVB_MASK |
 
91
                                 PLLD_FBDV_MASK | PLLD_LFBDV_MASK);
 
92
                        reg |= ((target_fwdva == 16 ? 0 : target_fwdva) << 16) |
 
93
                                ((target_fwdvb == 8 ? 0 : target_fwdvb) << 8) |
 
94
                                ((target_fbdv == 32 ? 0 : target_fbdv) << 24) |
 
95
                                (target_lfbdv == 64 ? 0 : target_lfbdv);
 
96
                        mtcpr(CPR0_PLLD, reg);
 
97
                        reset_needed = 1;
 
98
                }
 
99
 
 
100
                mfcpr(CPR0_PERD, reg);
 
101
                perdv0 = (reg & CPR0_PERD_PERDV0_MASK) >> 24;
 
102
                if (perdv0 != target_perdv0) {
 
103
                        reg &= ~CPR0_PERD_PERDV0_MASK;
 
104
                        reg |= (target_perdv0 << 24);
 
105
                        mtcpr(CPR0_PERD, reg);
 
106
                        reset_needed = 1;
 
107
                }
 
108
 
 
109
                mfcpr(CPR0_SPCID, reg);
 
110
                temp = (reg & CPR0_SPCID_SPCIDV0_MASK) >> 24;
 
111
                spcid0 = temp ? temp : 4;
 
112
                if (spcid0 != target_spcid0) {
 
113
                        reg &= ~CPR0_SPCID_SPCIDV0_MASK;
 
114
                        reg |= ((target_spcid0 == 4 ? 0 : target_spcid0) << 24);
 
115
                        mtcpr(CPR0_SPCID, reg);
 
116
                        reset_needed = 1;
 
117
                }
 
118
        }
 
119
 
 
120
        /* Get current value of FWDVA.*/
 
121
        mfcpr(CPR0_PLLD, reg);
 
122
        temp = (reg & PLLD_FWDVA_MASK) >> 16;
 
123
 
 
124
        /*
 
125
         * Check to see if FWDVA has been set to value of 1. if it has we must
 
126
         * modify it.
 
127
         */
 
128
        if (temp == 1) {
 
129
                /*
 
130
                 * Load register that contains current boot strapping option.
 
131
                 */
 
132
                mfcpr(CPR0_ICFG, reg);
 
133
                /*
 
134
                 * Strapping option bits (ICS) are already in correct position,
 
135
                 * only masking needed.
 
136
                 */
 
137
                reg &= CPR0_ICFG_ICS_MASK;
 
138
 
 
139
                if ((reg == BOOT_STRAP_OPTION_A) || (reg == BOOT_STRAP_OPTION_B) ||
 
140
                    (reg == BOOT_STRAP_OPTION_D) || (reg == BOOT_STRAP_OPTION_E)) {
 
141
                        mfcpr(CPR0_PLLD, reg);
 
142
 
 
143
                        /* Get current value of fbdv.  */
 
144
                        temp = (reg & PLLD_FBDV_MASK) >> 24;
 
145
                        fbdv = temp ? temp : 32;
 
146
 
 
147
                        /* Get current value of lfbdv. */
 
148
                        temp = (reg & PLLD_LFBDV_MASK);
 
149
                        lfbdv = temp ? temp : 64;
 
150
 
 
151
                        /*
 
152
                         * Get current value of FWDVA. Assign current FWDVA to
 
153
                         * new FWDVB.
 
154
                         */
 
155
                        mfcpr(CPR0_PLLD, reg);
 
156
                        target_fwdvb = (reg & PLLD_FWDVA_MASK) >> 16;
 
157
                        fwdvb = target_fwdvb ? target_fwdvb : 8;
 
158
 
 
159
                        /*
 
160
                         * Get current value of FWDVB. Assign current FWDVB to
 
161
                         * new FWDVA.
 
162
                         */
 
163
                        target_fwdva = (reg & PLLD_FWDVB_MASK) >> 8;
 
164
                        fwdva = target_fwdva ? target_fwdva : 16;
 
165
 
 
166
                        /*
 
167
                         * Update CPR0_PLLD with switched FWDVA and FWDVB.
 
168
                         */
 
169
                        reg &= ~(PLLD_FWDVA_MASK | PLLD_FWDVB_MASK |
 
170
                                PLLD_FBDV_MASK | PLLD_LFBDV_MASK);
 
171
                        reg |= ((fwdva == 16 ? 0 : fwdva) << 16) |
 
172
                                ((fwdvb == 8 ? 0 : fwdvb) << 8) |
 
173
                                ((fbdv == 32 ? 0 : fbdv) << 24) |
 
174
                                (lfbdv == 64 ? 0 : lfbdv);
 
175
                        mtcpr(CPR0_PLLD, reg);
 
176
 
 
177
                        /* Acknowledge that a reset is required. */
 
178
                        reset_needed = 1;
 
179
                }
 
180
        }
 
181
 
 
182
        /* Now reset the CPU if needed */
 
183
        if (reset_needed)
 
184
                reset_with_rli();
 
185
#endif
 
186
 
 
187
#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
 
188
        u32 reg;
 
189
 
 
190
        /*
 
191
         * See "9.2.1.1 Booting with Option E" in the 460EX/GT
 
192
         * users manual
 
193
         */
 
194
        mfcpr(CPR0_PLLC, reg);
 
195
        if ((reg & (CPR0_PLLC_RST | CPR0_PLLC_ENG)) == CPR0_PLLC_RST) {
 
196
                /*
 
197
                 * Set engage bit
 
198
                 */
 
199
                reg = (reg & ~CPR0_PLLC_RST) | CPR0_PLLC_ENG;
 
200
                mtcpr(CPR0_PLLC, reg);
 
201
 
 
202
                /* Now reset the CPU */
 
203
                reset_with_rli();
 
204
        }
 
205
#endif
 
206
}
 
207
 
 
208
#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA
 
209
void
 
210
chip_21_errata(void)
 
211
{
 
212
        /*
 
213
         * See rev 1.09 of the 405EX/405EXr errata.  CHIP_21 says that
 
214
         * sometimes reading the PVR and/or SDR0_ECID results in incorrect
 
215
         * values.  Since the rev-D chip uses the SDR0_ECID bits to control
 
216
         * internal features, that means the second PCIe or ethernet of an EX
 
217
         * variant could fail to work.  Also, security features of both EX and
 
218
         * EXr might be incorrectly disabled.
 
219
         *
 
220
         * The suggested workaround is as follows (covering rev-C and rev-D):
 
221
         *
 
222
         * 1.Read the PVR and SDR0_ECID3.
 
223
         *
 
224
         * 2.If the PVR matches an expected Revision C PVR value AND if
 
225
         * SDR0_ECID3[12:15] is different from PVR[28:31], then processor is
 
226
         * Revision C: continue executing the initialization code (no reset
 
227
         * required).  else go to step 3.
 
228
         *
 
229
         * 3.If the PVR matches an expected Revision D PVR value AND if
 
230
         * SDR0_ECID3[10:11] matches its expected value, then continue
 
231
         * executing initialization code, no reset required.  else write
 
232
         * DBCR0[RST] = 0b11 to generate a SysReset.
 
233
         */
 
234
 
 
235
        u32 pvr;
 
236
        u32 pvr_28_31;
 
237
        u32 ecid3;
 
238
        u32 ecid3_10_11;
 
239
        u32 ecid3_12_15;
 
240
 
 
241
        /* Step 1: */
 
242
        pvr = get_pvr();
 
243
        mfsdr(SDR0_ECID3, ecid3);
 
244
 
 
245
        /* Step 2: */
 
246
        pvr_28_31 = pvr & 0xf;
 
247
        ecid3_10_11 = (ecid3 >> 20) & 0x3;
 
248
        ecid3_12_15 = (ecid3 >> 16) & 0xf;
 
249
        if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_C) &&
 
250
                        (pvr_28_31 != ecid3_12_15)) {
 
251
                /* No reset required. */
 
252
                return;
 
253
        }
 
254
 
 
255
        /* Step 3: */
 
256
        if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_D) &&
 
257
                        (ecid3_10_11 == CONFIG_405EX_CHIP21_ECID3_REV_D)) {
 
258
                /* No reset required. */
 
259
                return;
 
260
        }
 
261
 
 
262
        /* Reset required. */
 
263
        __asm__ __volatile__ ("sync; isync");
 
264
        mtspr(SPRN_DBCR0, 0x30000000);
 
265
}
 
266
#endif
 
267
 
 
268
/*
 
269
 * Breath some life into the CPU...
 
270
 *
 
271
 * Reconfigure PLL if necessary,
 
272
 * set up the memory map,
 
273
 * initialize a bunch of registers
 
274
 */
 
275
void
 
276
cpu_init_f (void)
 
277
{
 
278
#if defined(CONFIG_WATCHDOG) || defined(CONFIG_440GX) || defined(CONFIG_460EX)
 
279
        u32 val;
 
280
#endif
 
281
 
 
282
#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA
 
283
        chip_21_errata();
 
284
#endif
 
285
 
 
286
        reconfigure_pll(CONFIG_SYS_PLL_RECONFIG);
 
287
 
 
288
#if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && \
 
289
    !defined(CONFIG_APM821XX) &&!defined(CONFIG_SYS_4xx_GPIO_TABLE)
 
290
        /*
 
291
         * GPIO0 setup (select GPIO or alternate function)
 
292
         */
 
293
#if defined(CONFIG_SYS_GPIO0_OR)
 
294
        out32(GPIO0_OR, CONFIG_SYS_GPIO0_OR);           /* set initial state of output pins     */
 
295
#endif
 
296
#if defined(CONFIG_SYS_GPIO0_ODR)
 
297
        out32(GPIO0_ODR, CONFIG_SYS_GPIO0_ODR); /* open-drain select                    */
 
298
#endif
 
299
        out32(GPIO0_OSRH, CONFIG_SYS_GPIO0_OSRH);       /* output select                        */
 
300
        out32(GPIO0_OSRL, CONFIG_SYS_GPIO0_OSRL);
 
301
        out32(GPIO0_ISR1H, CONFIG_SYS_GPIO0_ISR1H);     /* input select                         */
 
302
        out32(GPIO0_ISR1L, CONFIG_SYS_GPIO0_ISR1L);
 
303
        out32(GPIO0_TSRH, CONFIG_SYS_GPIO0_TSRH);       /* three-state select                   */
 
304
        out32(GPIO0_TSRL, CONFIG_SYS_GPIO0_TSRL);
 
305
#if defined(CONFIG_SYS_GPIO0_ISR2H)
 
306
        out32(GPIO0_ISR2H, CONFIG_SYS_GPIO0_ISR2H);
 
307
        out32(GPIO0_ISR2L, CONFIG_SYS_GPIO0_ISR2L);
 
308
#endif
 
309
#if defined (CONFIG_SYS_GPIO0_TCR)
 
310
        out32(GPIO0_TCR, CONFIG_SYS_GPIO0_TCR); /* enable output driver for outputs     */
 
311
#endif
 
312
#endif /* CONFIG_405EP ... && !CONFIG_SYS_4xx_GPIO_TABLE */
 
313
 
 
314
#if defined (CONFIG_405EP)
 
315
        /*
 
316
         * Set EMAC noise filter bits
 
317
         */
 
318
        mtdcr(CPC0_EPCTL, CPC0_EPCTL_E0NFE | CPC0_EPCTL_E1NFE);
 
319
#endif /* CONFIG_405EP */
 
320
 
 
321
#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
 
322
        gpio_set_chip_configuration();
 
323
#endif /* CONFIG_SYS_4xx_GPIO_TABLE */
 
324
 
 
325
        /*
 
326
         * External Bus Controller (EBC) Setup
 
327
         */
 
328
#if (defined(CONFIG_SYS_EBC_PB0AP) && defined(CONFIG_SYS_EBC_PB0CR))
 
329
#if (defined(CONFIG_405GP) || \
 
330
     defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
 
331
     defined(CONFIG_405EX) || defined(CONFIG_405))
 
332
        /*
 
333
         * Move the next instructions into icache, since these modify the flash
 
334
         * we are running from!
 
335
         */
 
336
        asm volatile("  bl      0f"             ::: "lr");
 
337
        asm volatile("0:        mflr    3"              ::: "r3");
 
338
        asm volatile("  addi    4, 0, 14"       ::: "r4");
 
339
        asm volatile("  mtctr   4"              ::: "ctr");
 
340
        asm volatile("1:        icbt    0, 3");
 
341
        asm volatile("  addi    3, 3, 32"       ::: "r3");
 
342
        asm volatile("  bdnz    1b"             ::: "ctr", "cr0");
 
343
        asm volatile("  addis   3, 0, 0x0"      ::: "r3");
 
344
        asm volatile("  ori     3, 3, 0xA000"   ::: "r3");
 
345
        asm volatile("  mtctr   3"              ::: "ctr");
 
346
        asm volatile("2:        bdnz    2b"             ::: "ctr", "cr0");
 
347
#endif
 
348
 
 
349
        mtebc(PB0AP, CONFIG_SYS_EBC_PB0AP);
 
350
        mtebc(PB0CR, CONFIG_SYS_EBC_PB0CR);
 
351
#endif
 
352
 
 
353
#if (defined(CONFIG_SYS_EBC_PB1AP) && defined(CONFIG_SYS_EBC_PB1CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 1))
 
354
        mtebc(PB1AP, CONFIG_SYS_EBC_PB1AP);
 
355
        mtebc(PB1CR, CONFIG_SYS_EBC_PB1CR);
 
356
#endif
 
357
 
 
358
#if (defined(CONFIG_SYS_EBC_PB2AP) && defined(CONFIG_SYS_EBC_PB2CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 2))
 
359
        mtebc(PB2AP, CONFIG_SYS_EBC_PB2AP);
 
360
        mtebc(PB2CR, CONFIG_SYS_EBC_PB2CR);
 
361
#endif
 
362
 
 
363
#if (defined(CONFIG_SYS_EBC_PB3AP) && defined(CONFIG_SYS_EBC_PB3CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 3))
 
364
        mtebc(PB3AP, CONFIG_SYS_EBC_PB3AP);
 
365
        mtebc(PB3CR, CONFIG_SYS_EBC_PB3CR);
 
366
#endif
 
367
 
 
368
#if (defined(CONFIG_SYS_EBC_PB4AP) && defined(CONFIG_SYS_EBC_PB4CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 4))
 
369
        mtebc(PB4AP, CONFIG_SYS_EBC_PB4AP);
 
370
        mtebc(PB4CR, CONFIG_SYS_EBC_PB4CR);
 
371
#endif
 
372
 
 
373
#if (defined(CONFIG_SYS_EBC_PB5AP) && defined(CONFIG_SYS_EBC_PB5CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 5))
 
374
        mtebc(PB5AP, CONFIG_SYS_EBC_PB5AP);
 
375
        mtebc(PB5CR, CONFIG_SYS_EBC_PB5CR);
 
376
#endif
 
377
 
 
378
#if (defined(CONFIG_SYS_EBC_PB6AP) && defined(CONFIG_SYS_EBC_PB6CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 6))
 
379
        mtebc(PB6AP, CONFIG_SYS_EBC_PB6AP);
 
380
        mtebc(PB6CR, CONFIG_SYS_EBC_PB6CR);
 
381
#endif
 
382
 
 
383
#if (defined(CONFIG_SYS_EBC_PB7AP) && defined(CONFIG_SYS_EBC_PB7CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 7))
 
384
        mtebc(PB7AP, CONFIG_SYS_EBC_PB7AP);
 
385
        mtebc(PB7CR, CONFIG_SYS_EBC_PB7CR);
 
386
#endif
 
387
 
 
388
#if defined (CONFIG_SYS_EBC_CFG)
 
389
        mtebc(EBC0_CFG, CONFIG_SYS_EBC_CFG);
 
390
#endif
 
391
 
 
392
#if defined(CONFIG_WATCHDOG)
 
393
        val = mfspr(SPRN_TCR);
 
394
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
 
395
        val |= 0xb8000000;      /* generate system reset after 1.34 seconds */
 
396
#elif defined(CONFIG_440EPX)
 
397
        val |= 0xb0000000;      /* generate system reset after 1.34 seconds */
 
398
#else
 
399
        val |= 0xf0000000;      /* generate system reset after 2.684 seconds */
 
400
#endif
 
401
#if defined(CONFIG_SYS_4xx_RESET_TYPE)
 
402
        val &= ~0x30000000;                     /* clear WRC bits */
 
403
        val |= CONFIG_SYS_4xx_RESET_TYPE << 28; /* set board specific WRC type */
 
404
#endif
 
405
        mtspr(SPRN_TCR, val);
 
406
 
 
407
        val = mfspr(SPRN_TSR);
 
408
        val |= 0x80000000;      /* enable watchdog timer */
 
409
        mtspr(SPRN_TSR, val);
 
410
 
 
411
        reset_4xx_watchdog();
 
412
#endif /* CONFIG_WATCHDOG */
 
413
 
 
414
#if defined(CONFIG_440GX)
 
415
        /* Take the GX out of compatibility mode
 
416
         * Travis Sawyer, 9 Mar 2004
 
417
         * NOTE: 440gx user manual inconsistency here
 
418
         *       Compatibility mode and Ethernet Clock select are not
 
419
         *       correct in the manual
 
420
         */
 
421
        mfsdr(SDR0_MFR, val);
 
422
        val &= ~0x10000000;
 
423
        mtsdr(SDR0_MFR,val);
 
424
#endif /* CONFIG_440GX */
 
425
 
 
426
#if defined(CONFIG_460EX)
 
427
        /*
 
428
         * Set SDR0_AHB_CFG[A2P_INCR4] (bit 24) and
 
429
         * clear SDR0_AHB_CFG[A2P_PROT2] (bit 25) for a new 460EX errata
 
430
         * regarding concurrent use of AHB USB OTG, USB 2.0 host and SATA
 
431
         */
 
432
        mfsdr(SDR0_AHB_CFG, val);
 
433
        val |= 0x80;
 
434
        val &= ~0x40;
 
435
        mtsdr(SDR0_AHB_CFG, val);
 
436
        mfsdr(SDR0_USB2HOST_CFG, val);
 
437
        val &= ~0xf00;
 
438
        val |= 0x400;
 
439
        mtsdr(SDR0_USB2HOST_CFG, val);
 
440
#endif /* CONFIG_460EX */
 
441
 
 
442
#if defined(CONFIG_405EX) || \
 
443
    defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
 
444
    defined(CONFIG_460EX) || defined(CONFIG_460GT)  || \
 
445
    defined(CONFIG_460SX) || defined(CONFIG_APM821XX)
 
446
        /*
 
447
         * Set PLB4 arbiter (Segment 0 and 1) to 4 deep pipeline read
 
448
         */
 
449
        mtdcr(PLB4A0_ACR, (mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_RDP_MASK) |
 
450
              PLB4Ax_ACR_RDP_4DEEP);
 
451
        mtdcr(PLB4A1_ACR, (mfdcr(PLB4A1_ACR) & ~PLB4Ax_ACR_RDP_MASK) |
 
452
              PLB4Ax_ACR_RDP_4DEEP);
 
453
#endif /* CONFIG_440SP/SPE || CONFIG_460EX/GT || CONFIG_405EX */
 
454
}
 
455
 
 
456
/*
 
457
 * initialize higher level parts of CPU like time base and timers
 
458
 */
 
459
int cpu_init_r (void)
 
460
{
 
461
#if defined(CONFIG_405GP)
 
462
        uint pvr = get_pvr();
 
463
 
 
464
        /*
 
465
         * Set edge conditioning circuitry on PPC405GPr
 
466
         * for compatibility to existing PPC405GP designs.
 
467
         */
 
468
        if ((pvr & 0xfffffff0) == (PVR_405GPR_RB & 0xfffffff0)) {
 
469
                mtdcr(CPC0_ECR, 0x60606000);
 
470
        }
 
471
#endif  /* defined(CONFIG_405GP) */
 
472
 
 
473
        return 0;
 
474
}
 
475
 
 
476
#if defined(CONFIG_PCI) && \
 
477
        (defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
 
478
         defined(CONFIG_440GR) || defined(CONFIG_440GRX))
 
479
/*
 
480
 * 440EP(x)/GR(x) PCI async/sync clocking restriction:
 
481
 *
 
482
 * In asynchronous PCI mode, the synchronous PCI clock must meet
 
483
 * certain requirements. The following equation describes the
 
484
 * relationship that must be maintained between the asynchronous PCI
 
485
 * clock and synchronous PCI clock. Select an appropriate PCI:PLB
 
486
 * ratio to maintain the relationship:
 
487
 *
 
488
 * AsyncPCIClk - 1MHz <= SyncPCIclock <= (2 * AsyncPCIClk) - 1MHz
 
489
 */
 
490
static int ppc4xx_pci_sync_clock_ok(u32 sync, u32 async)
 
491
{
 
492
        if (((async - 1000000) > sync) || (sync > ((2 * async) - 1000000)))
 
493
                return 0;
 
494
        else
 
495
                return 1;
 
496
}
 
497
 
 
498
int ppc4xx_pci_sync_clock_config(u32 async)
 
499
{
 
500
        sys_info_t sys_info;
 
501
        u32 sync;
 
502
        int div;
 
503
        u32 reg;
 
504
        u32 spcid_val[] = {
 
505
                CPR0_SPCID_SPCIDV0_DIV1, CPR0_SPCID_SPCIDV0_DIV2,
 
506
                CPR0_SPCID_SPCIDV0_DIV3, CPR0_SPCID_SPCIDV0_DIV4 };
 
507
 
 
508
        get_sys_info(&sys_info);
 
509
        sync = sys_info.freqPCI;
 
510
 
 
511
        /*
 
512
         * First check if the equation above is met
 
513
         */
 
514
        if (!ppc4xx_pci_sync_clock_ok(sync, async)) {
 
515
                /*
 
516
                 * Reconfigure PCI sync clock to meet the equation.
 
517
                 * Start with highest possible PCI sync frequency
 
518
                 * (divider 1).
 
519
                 */
 
520
                for (div = 1; div <= 4; div++) {
 
521
                        sync = sys_info.freqPLB / div;
 
522
                        if (ppc4xx_pci_sync_clock_ok(sync, async))
 
523
                            break;
 
524
                }
 
525
 
 
526
                if (div <= 4) {
 
527
                        mtcpr(CPR0_SPCID, spcid_val[div]);
 
528
 
 
529
                        mfcpr(CPR0_ICFG, reg);
 
530
                        reg |= CPR0_ICFG_RLI_MASK;
 
531
                        mtcpr(CPR0_ICFG, reg);
 
532
 
 
533
                        /* do chip reset */
 
534
                        mtspr(SPRN_DBCR0, 0x20000000);
 
535
                } else {
 
536
                        /* Impossible to configure the PCI sync clock */
 
537
                        return -1;
 
538
                }
 
539
        }
 
540
 
 
541
        return 0;
 
542
}
 
543
#endif