blob: 8970dfbe4a06f686b07156e18b8857ab97efe70e (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*
* Cogent CSB336 - MC9328MXL SBC startup code
*/
/*
* Copyright (c) 2004 by Cogent Computer Systems
* Written by Jay Monkman <jtm@lopingdog.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/bspIo.h>
#include <mc9328mxl.h>
#include <libcpu/mmu.h>
/*
* bsp_start_default - BSP initialization function
*
* This function is called before RTEMS is initialized and used
* adjust the kernel's configuration.
*
* This function also configures the CPU's memory protection unit.
*
* RESTRICTIONS/LIMITATIONS:
* Since RTEMS is not configured, no RTEMS functions can be called.
*
*/
static void bsp_start_default( void )
{
int i;
/* Set the MCU prescaler to divide by 1 */
MC9328MXL_PLL_CSCR &= ~MC9328MXL_PLL_CSCR_PRESC;
/* Enable the MCU PLL */
MC9328MXL_PLL_CSCR |= MC9328MXL_PLL_CSCR_MPEN;
/* Delay to allow time for PLL to get going */
for (i = 0; i < 100; i++) {
__asm__ volatile ("nop\n");
}
/* Set the CPU to asynchrous clock mode, so it uses its fastest clock */
mmu_set_cpu_async_mode();
/* disable interrupts */
MC9328MXL_AITC_INTENABLEL = 0;
MC9328MXL_AITC_INTENABLEH = 0;
/* Set interrupt priority to -1 (allow all priorities) */
MC9328MXL_AITC_NIMASK = 0x1f;
/*
* Init rtems interrupt management
*/
bsp_interrupt_initialize();
} /* bsp_start */
/* Calcuate the frequency for perclk1 */
int get_perclk1_freq(void)
{
unsigned int fin;
unsigned int fpll;
unsigned int pd;
unsigned int mfd;
unsigned int mfi;
unsigned int mfn;
uint32_t reg;
int perclk1;
if (MC9328MXL_PLL_CSCR & MC9328MXL_PLL_CSCR_SYSSEL) {
/* Use external oscillator */
fin = BSP_OSC_FREQ;
} else {
/* Use scaled xtal freq */
fin = BSP_XTAL_FREQ * 512;
}
/* calculate the output of the system PLL */
reg = MC9328MXL_PLL_SPCTL0;
pd = ((reg & MC9328MXL_PLL_SPCTL_PD_MASK) >>
MC9328MXL_PLL_SPCTL_PD_SHIFT);
mfd = ((reg & MC9328MXL_PLL_SPCTL_MFD_MASK) >>
MC9328MXL_PLL_SPCTL_MFD_SHIFT);
mfi = ((reg & MC9328MXL_PLL_SPCTL_MFI_MASK) >>
MC9328MXL_PLL_SPCTL_MFI_SHIFT);
mfn = ((reg & MC9328MXL_PLL_SPCTL_MFN_MASK) >>
MC9328MXL_PLL_SPCTL_MFN_SHIFT);
#if 0
printk("fin = %d\n", fin);
printk("pd = %d\n", pd);
printk("mfd = %d\n", mfd);
printk("mfi = %d\n", mfi);
printk("mfn = %d\n", mfn);
printk("rounded (fin * mfi) / (pd + 1) = %d\n", (fin * mfi) / (pd + 1));
printk("rounded (fin * mfn) / ((pd + 1) * (mfd + 1)) = %d\n",
((long long)fin * mfn) / ((pd + 1) * (mfd + 1)));
#endif
fpll = 2 * ( ((fin * mfi + (pd + 1) / 2) / (pd + 1)) +
(((long long)fin * mfn + ((pd + 1) * (mfd + 1)) / 2) /
((pd + 1) * (mfd + 1))) );
/* calculate the output of the PERCLK1 divider */
reg = MC9328MXL_PLL_PCDR;
perclk1 = fpll / (1 + ((reg & MC9328MXL_PLL_PCDR_PCLK1_MASK) >>
MC9328MXL_PLL_PCDR_PCLK1_SHIFT));
return perclk1;
}
/*
* By making this a weak alias for bsp_start_default, a brave soul
* can override the actual bsp_start routine used.
*/
void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
|