Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:49

0001 /*
0002  * Cogent CSB336 - MC9328MXL SBC startup code
0003  */
0004 
0005 /*
0006  * Copyright (c) 2004 by Cogent Computer Systems
0007  * Written by Jay Monkman <jtm@lopingdog.com>
0008  *
0009  * The license and distribution terms for this file may be
0010  * found in the file LICENSE in this distribution or at
0011  * http://www.rtems.org/license/LICENSE.
0012  */
0013 
0014 #include <bsp.h>
0015 #include <bsp/irq-generic.h>
0016 #include <rtems/bspIo.h>
0017 #include <mc9328mxl.h>
0018 #include <libcpu/mmu.h>
0019 
0020 /*
0021  * bsp_start_default - BSP initialization function
0022  *
0023  *   This function is called before RTEMS is initialized and used
0024  *   adjust the kernel's configuration.
0025  *
0026  *   This function also configures the CPU's memory protection unit.
0027  *
0028  * RESTRICTIONS/LIMITATIONS:
0029  *   Since RTEMS is not configured, no RTEMS functions can be called.
0030  *
0031  */
0032 static void bsp_start_default( void )
0033 {
0034   int i;
0035 
0036   /* Set the MCU prescaler to divide by 1 */
0037   MC9328MXL_PLL_CSCR &= ~MC9328MXL_PLL_CSCR_PRESC;
0038 
0039   /* Enable the MCU PLL */
0040   MC9328MXL_PLL_CSCR |= MC9328MXL_PLL_CSCR_MPEN;
0041 
0042   /* Delay to allow time for PLL to get going */
0043   for (i = 0; i < 100; i++) {
0044     __asm__ volatile ("nop\n");
0045   }
0046 
0047   /* Set the CPU to asynchrous clock mode, so it uses its fastest clock */
0048   mmu_set_cpu_async_mode();
0049 
0050   /* disable interrupts */
0051   MC9328MXL_AITC_INTENABLEL = 0;
0052   MC9328MXL_AITC_INTENABLEH = 0;
0053 
0054   /* Set interrupt priority to -1 (allow all priorities) */
0055   MC9328MXL_AITC_NIMASK = 0x1f;
0056 
0057   /*
0058    * Init rtems interrupt management
0059    */
0060   bsp_interrupt_initialize();
0061 } /* bsp_start */
0062 
0063 /* Calcuate the frequency for perclk1 */
0064 int get_perclk1_freq(void)
0065 {
0066   unsigned int fin;
0067   unsigned int fpll;
0068   unsigned int pd;
0069   unsigned int mfd;
0070   unsigned int mfi;
0071   unsigned int mfn;
0072   uint32_t reg;
0073   int perclk1;
0074 
0075   if (MC9328MXL_PLL_CSCR & MC9328MXL_PLL_CSCR_SYSSEL) {
0076     /* Use external oscillator */
0077     fin = BSP_OSC_FREQ;
0078   } else {
0079     /* Use scaled xtal freq */
0080     fin = BSP_XTAL_FREQ * 512;
0081   }
0082 
0083   /* calculate the output of the system PLL */
0084   reg = MC9328MXL_PLL_SPCTL0;
0085   pd = ((reg & MC9328MXL_PLL_SPCTL_PD_MASK) >>
0086         MC9328MXL_PLL_SPCTL_PD_SHIFT);
0087   mfd = ((reg & MC9328MXL_PLL_SPCTL_MFD_MASK) >>
0088          MC9328MXL_PLL_SPCTL_MFD_SHIFT);
0089   mfi = ((reg & MC9328MXL_PLL_SPCTL_MFI_MASK) >>
0090          MC9328MXL_PLL_SPCTL_MFI_SHIFT);
0091   mfn = ((reg & MC9328MXL_PLL_SPCTL_MFN_MASK) >>
0092          MC9328MXL_PLL_SPCTL_MFN_SHIFT);
0093 
0094 #if 0
0095   printk("fin = %d\n", fin);
0096   printk("pd = %d\n", pd);
0097   printk("mfd = %d\n", mfd);
0098   printk("mfi = %d\n", mfi);
0099   printk("mfn = %d\n", mfn);
0100   printk("rounded (fin * mfi) / (pd + 1) = %d\n", (fin * mfi) / (pd + 1));
0101   printk("rounded (fin * mfn) / ((pd + 1) * (mfd + 1)) = %d\n",
0102          ((long long)fin * mfn) / ((pd + 1) * (mfd + 1)));
0103 #endif
0104 
0105   fpll = 2 * ( ((fin * mfi  + (pd + 1) / 2) / (pd + 1)) +
0106                (((long long)fin * mfn + ((pd + 1) * (mfd + 1)) / 2) /
0107                ((pd + 1) * (mfd + 1))) );
0108 
0109   /* calculate the output of the PERCLK1 divider */
0110   reg = MC9328MXL_PLL_PCDR;
0111   perclk1 = fpll / (1 + ((reg & MC9328MXL_PLL_PCDR_PCLK1_MASK) >>
0112                          MC9328MXL_PLL_PCDR_PCLK1_SHIFT));
0113 
0114   return perclk1;
0115 }
0116 
0117 /*
0118  *  By making this a weak alias for bsp_start_default, a brave soul
0119  *  can override the actual bsp_start routine used.
0120  */
0121 void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
0122