/*********************************************************************
* init_clock_config - Clock Module                                   *
**********************************************************************/
void init_clock_config(void)
{
  /* Clock module uses normal PLL mode with 16.0000 MHz external reference
     Bus clock frequency = 80.00 MHz
     Processor clock frequency = 3 x bus clock = 240.00 MHz
     Dithering disabled
   */

  /* Check to see if the SDRAM has already been initialized
     by a run control tool. If it has, put SDRAM into self-refresh mode before
     initializing the PLL
   */
  if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
    MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;

  /* Temporarily switch to LIMP mode
     NOTE: Ensure that this code is not executing from SDRAM, since the
     SDRAM Controller is disabled in LIMP mode
   */
  MCF_CCM_CDR = (MCF_CCM_CDR & 0xf0ff) | MCF_CCM_CDR_LPDIV(0x2);
  MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;

  /* Configure the PLL settings */
  MCF_PLL_PODR = MCF_PLL_PODR_CPUDIV(0x2) | MCF_PLL_PODR_BUSDIV(0x6);
  MCF_PLL_PFDR = MCF_PLL_PFDR_MFD(0x78);
  MCF_PLL_PLLCR = 0;
  MCF_PLL_PMDR = 0;

  /* Enable PLL and wait for lock */
  MCF_CCM_MISCCR &= ~MCF_CCM_MISCCR_LIMP;
  while ((MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK) == 0) ;

  /* From the Device Errata:

     "After exiting LIMP mode, the value of 0x40000000 should be written
     to address 0xFC0B8080 before attempting to initialize the SDRAMC
     or exit the SDRAM from self-refresh mode."
   */
  *(vuint32 *) 0xfc0b8080 = 0x40000000;

  /* If we put the SDRAM into self-refresh mode earlier, restore mode now */
  if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
    MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
}
Esempio n. 2
0
int clock_pll(int fsys, int flags)
{
	int fref, temp, fout, mfd;
	u32 i;

	fref = FREF;
        
	if (fsys == 0) {
		/* Return current PLL output */
		mfd = MCF_PLL_PFDR;

		return (fref * mfd / (BUSDIV * 4));
	}

	/* Check bounds of requested system clock */
	if (fsys > MAX_FSYS)
		fsys = MAX_FSYS;
	if (fsys < MIN_FSYS)
		fsys = MIN_FSYS;

	/* Multiplying by 100 when calculating the temp value,
	   and then dividing by 100 to calculate the mfd allows
	   for exact values without needing to include floating
	   point libraries. */
	temp = 100 * fsys / fref;
	mfd = 4 * BUSDIV * temp / 100;
    	    	    	
	/* Determine the output frequency for selected values */
	fout = (fref * mfd / (BUSDIV * 4));

	/*
	 * Check to see if the SDRAM has already been initialized.
	 * If it has then the SDRAM needs to be put into self refresh
	 * mode before reprogramming the PLL.
	 */
	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
		/* Put SDRAM into self refresh mode */
		MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;

	/*
	 * Initialize the PLL to generate the new system clock frequency.
	 * The device must be put into LIMP mode to reprogram the PLL.
	 */

	/* Enter LIMP mode */
	clock_limp(DEFAULT_LPD);
     					
	/* Reprogram PLL for desired fsys */
	MCF_PLL_PODR = (0
		| MCF_PLL_PODR_CPUDIV(BUSDIV/3)
		| MCF_PLL_PODR_BUSDIV(BUSDIV));
						
	MCF_PLL_PFDR = mfd;
		
	/* Exit LIMP mode */
	clock_exit_limp();
	
	/*
	 * Return the SDRAM to normal operation if it is in use.
	 */
	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
		/* Exit self refresh mode */
		MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;

	/* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
	MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;

	/* wait for DQS logic to relock */
	for (i = 0; i < 0x200; i++)
		;

	return fout;
}