int get_sys_clock(void) { int divider; /* Test to see if device is in LIMP mode */ if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) { divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF); return (FREF/(2 << divider)); } else return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4)); }
/********************************************************************* * 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; }
int clock_limp(int div) { u32 temp; /* Check bounds of divider */ if (div < MIN_LPD) div = MIN_LPD; if (div > MAX_LPD) div = MAX_LPD; /* Save of the current value of the SSIDIV so we don't overwrite the value*/ temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF); /* Apply the divider to the system clock */ writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR); writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR); return (FREF/(3*(1 << div))); }