summaryrefslogtreecommitdiffstats
path: root/bsps/arm/csb336/start/bspstart.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/csb336/start/bspstart.c')
-rw-r--r--bsps/arm/csb336/start/bspstart.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/bsps/arm/csb336/start/bspstart.c b/bsps/arm/csb336/start/bspstart.c
new file mode 100644
index 0000000000..8970dfbe4a
--- /dev/null
+++ b/bsps/arm/csb336/start/bspstart.c
@@ -0,0 +1,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")));
+