static void serial_divs (int baudrate, unsigned long *pudiv, unsigned short *pbdiv) { sys_info_t sysinfo; unsigned long div; /* total divisor udiv * bdiv */ unsigned long umin; /* minimum udiv */ unsigned short diff; /* smallest diff */ unsigned long udiv; /* best udiv */ unsigned short idiff; /* current diff */ unsigned short ibdiv; /* current bdiv */ unsigned long i; unsigned long est; /* current estimate */ unsigned long plloutb; unsigned long cpr_pllc; u32 reg; /* check the pll feedback source */ mfcpr(cprpllc, cpr_pllc); get_sys_info(&sysinfo); plloutb = ((CONFIG_SYS_CLK_FREQ * ((cpr_pllc & PLLC_SRC_MASK) ? sysinfo.pllFwdDivB : sysinfo.pllFwdDiv) * sysinfo.pllFbkDiv) / sysinfo.pllFwdDivB); udiv = 256; /* Assume lowest possible serial clk */ div = plloutb / (16 * baudrate); /* total divisor */ umin = (plloutb / get_OPB_freq()) << 1; /* 2 x OPB divisor */ diff = 256; /* highest possible */ /* i is the test udiv value -- start with the largest * possible (256) to minimize serial clock and constrain * search to umin. */ for (i = 256; i > umin; i--) { ibdiv = div / i; est = i * ibdiv; idiff = (est > div) ? (est-div) : (div-est); if (idiff == 0) { udiv = i; break; /* can't do better */ } else if (idiff < diff) { udiv = i; /* best so far */ diff = idiff; /* update lowest diff*/ } } *pudiv = udiv; mfcpr(cprperd0, reg); reg &= ~0x0000ffff; reg |= ((udiv - 0) << 8) | (udiv - 0); mtcpr(cprperd0, reg); *pbdiv = div / udiv; }
static void reset_with_rli(void) { u32 reg; /* * Set reload inhibit so configuration will persist across * processor resets */ mfcpr(CPR0_ICFG, reg); reg |= CPR0_ICFG_RLI_MASK; mtcpr(CPR0_ICFG, reg); /* Reset processor if configuration changed */ __asm__ __volatile__ ("sync; isync"); mtspr(SPRN_DBCR0, 0x20000000); }
int board_early_init_f(void) { #ifdef BOOTSTRAP_OPTION_A_ACTIVE /* Booting with Bootstrap Option A * First boot, with CPR0_ICFG_RLI_MASK == 0 * no we setup varios boot strapping register, * then we do reset the PPC440 using a chip reset * Unfortunately, we cannot use this option, as Nto1 is not set * with Bootstrap Option A and cannot be changed later on by SW * There are no other possible boostrap options with a 8 bit ROM * See Errata (Version 1.04) CHIP_9 */ u32 cpr0icfg; u32 dbcr; mfcpr(CPR0_ICFG, cpr0icfg); if (!(cpr0icfg & CPR0_ICFG_RLI_MASK)) { mtcpr(CPR0_MALD, 0x02000000); mtcpr(CPR0_OPBD, 0x02000000); mtcpr(CPR0_PERD, 0x05000000); /* 1:5 */ mtcpr(CPR0_PLLC, 0x40000238); mtcpr(CPR0_PLLD, 0x01010414); mtcpr(CPR0_PRIMAD, 0x01000000); mtcpr(CPR0_PRIMBD, 0x01000000); mtcpr(CPR0_SPCID, 0x03000000); mtsdr(SDR0_PFC0, 0x00003E00); /* [CTE] = 0 */ mtsdr(SDR0_CP440, 0x0EAAEA02); /* [Nto1] = 1*/ mtcpr(CPR0_ICFG, cpr0icfg | CPR0_ICFG_RLI_MASK); /* * Initiate system reset in debug control register DBCR */ dbcr = mfspr(SPRN_DBCR0); mtspr(SPRN_DBCR0, dbcr | CHIP_RESET); } mtsdr(SDR0_CP440, 0x0EAAEA02); /* [Nto1] = 1*/ #endif mtdcr(EBC0_CFGADDR, EBC0_CFG); mtdcr(EBC0_CFGDATA, 0xb8400000); /* * Setup the GPIO pins */ out32(GPIO0_OR, 0x00000000); out32(GPIO0_TCR, 0x7C2FF1CF); out32(GPIO0_OSRL, 0x40055000); out32(GPIO0_OSRH, 0x00000000); out32(GPIO0_TSRL, 0x40055000); out32(GPIO0_TSRH, 0x00000400); out32(GPIO0_ISR1L, 0x40000000); out32(GPIO0_ISR1H, 0x00000000); out32(GPIO0_ISR2L, 0x00000000); out32(GPIO0_ISR2H, 0x00000000); out32(GPIO0_ISR3L, 0x00000000); out32(GPIO0_ISR3H, 0x00000000); out32(GPIO1_OR, 0x00000000); out32(GPIO1_TCR, 0xC6007FFF); out32(GPIO1_OSRL, 0x00140000); out32(GPIO1_OSRH, 0x00000000); out32(GPIO1_TSRL, 0x00000000); out32(GPIO1_TSRH, 0x00000000); out32(GPIO1_ISR1L, 0x05415555); out32(GPIO1_ISR1H, 0x40000000); out32(GPIO1_ISR2L, 0x00000000); out32(GPIO1_ISR2H, 0x00000000); out32(GPIO1_ISR3L, 0x00000000); out32(GPIO1_ISR3H, 0x00000000); /* * Setup the interrupt controller polarities, triggers, etc. */ mtdcr(UIC0SR, 0xffffffff); /* clear all */ mtdcr(UIC0ER, 0x00000000); /* disable all */ mtdcr(UIC0CR, 0x00000005); /* ATI & UIC1 crit are critical */ mtdcr(UIC0PR, 0xfffff7ff); /* per ref-board manual */ mtdcr(UIC0TR, 0x00000000); /* per ref-board manual */ mtdcr(UIC0VR, 0x00000000); /* int31 highest, base=0x000 */ mtdcr(UIC0SR, 0xffffffff); /* clear all */ mtdcr(UIC1SR, 0xffffffff); /* clear all */ mtdcr(UIC1ER, 0x00000000); /* disable all */ mtdcr(UIC1CR, 0x00000000); /* all non-critical */ mtdcr(UIC1PR, 0xffffffff); /* per ref-board manual */ mtdcr(UIC1TR, 0x00000000); /* per ref-board manual */ mtdcr(UIC1VR, 0x00000000); /* int31 highest, base=0x000 */ mtdcr(UIC1SR, 0xffffffff); /* clear all */ mtdcr(UIC2SR, 0xffffffff); /* clear all */ mtdcr(UIC2ER, 0x00000000); /* disable all */ mtdcr(UIC2CR, 0x00000000); /* all non-critical */ mtdcr(UIC2PR, 0xffffffff); /* per ref-board manual */ mtdcr(UIC2TR, 0x00000000); /* per ref-board manual */ mtdcr(UIC2VR, 0x00000000); /* int31 highest, base=0x000 */ mtdcr(UIC2SR, 0xffffffff); /* clear all */ mtsdr(SDR0_PFC0, 0x00003E00); /* Pin function: */ mtsdr(SDR0_PFC1, 0x00848000); /* Pin function: UART0 has 4 pins */ /* setup BOOT FLASH */ mtsdr(SDR0_CUST0, 0xC0082350); return 0; }
void reconfigure_pll(u32 new_cpu_freq) { #if defined(CONFIG_440EPX) int reset_needed = 0; u32 reg, temp; u32 prbdv0, target_prbdv0, /* CLK_PRIMBD */ fwdva, target_fwdva, fwdvb, target_fwdvb, /* CLK_PLLD */ fbdv, target_fbdv, lfbdv, target_lfbdv, perdv0, target_perdv0, /* CLK_PERD */ spcid0, target_spcid0; /* CLK_SPCID */ /* Reconfigure clocks if necessary. * See PPC440EPx User's Manual, sections 8.2 and 14 */ if (new_cpu_freq == 667) { target_prbdv0 = 2; target_fwdva = 2; target_fwdvb = 4; target_fbdv = 20; target_lfbdv = 1; target_perdv0 = 4; target_spcid0 = 4; mfcpr(clk_primbd, reg); temp = (reg & PRBDV_MASK) >> 24; prbdv0 = temp ? temp : 8; if (prbdv0 != target_prbdv0) { reg &= ~PRBDV_MASK; reg |= ((target_prbdv0 == 8 ? 0 : target_prbdv0) << 24); mtcpr(clk_primbd, reg); reset_needed = 1; } mfcpr(clk_plld, reg); temp = (reg & PLLD_FWDVA_MASK) >> 16; fwdva = temp ? temp : 16; temp = (reg & PLLD_FWDVB_MASK) >> 8; fwdvb = temp ? temp : 8; temp = (reg & PLLD_FBDV_MASK) >> 24; fbdv = temp ? temp : 32; temp = (reg & PLLD_LFBDV_MASK); lfbdv = temp ? temp : 64; if (fwdva != target_fwdva || fbdv != target_fbdv || lfbdv != target_lfbdv) { reg &= ~(PLLD_FWDVA_MASK | PLLD_FWDVB_MASK | PLLD_FBDV_MASK | PLLD_LFBDV_MASK); reg |= ((target_fwdva == 16 ? 0 : target_fwdva) << 16) | ((target_fwdvb == 8 ? 0 : target_fwdvb) << 8) | ((target_fbdv == 32 ? 0 : target_fbdv) << 24) | (target_lfbdv == 64 ? 0 : target_lfbdv); mtcpr(clk_plld, reg); reset_needed = 1; } mfcpr(clk_perd, reg); perdv0 = (reg & CPR0_PERD_PERDV0_MASK) >> 24; if (perdv0 != target_perdv0) { reg &= ~CPR0_PERD_PERDV0_MASK; reg |= (target_perdv0 << 24); mtcpr(clk_perd, reg); reset_needed = 1; } mfcpr(clk_spcid, reg); temp = (reg & CPR0_SPCID_SPCIDV0_MASK) >> 24; spcid0 = temp ? temp : 4; if (spcid0 != target_spcid0) { reg &= ~CPR0_SPCID_SPCIDV0_MASK; reg |= ((target_spcid0 == 4 ? 0 : target_spcid0) << 24); mtcpr(clk_spcid, reg); reset_needed = 1; } /* Set reload inhibit so configuration will persist across * processor resets */ mfcpr(clk_icfg, reg); reg &= ~CPR0_ICFG_RLI_MASK; reg |= 1 << 31; mtcpr(clk_icfg, reg); }