/* * arch/ppc/syslib/ibm440gp_common.c * * PPC440GP system library * * Matt Porter * Copyright 2002-2003 MontaVista Software Inc. * * Eugene Surovegin or * Copyright (c) 2003 Zultys Technologies * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include #include #include #include #include #include /* * Calculate 440GP clocks */ void __init ibm440gp_get_clocks(struct ibm44x_clocks* p, unsigned int sys_clk, unsigned int ser_clk) { u32 cpc0_sys0 = mfdcr(DCRN_CPC0_SYS0); u32 cpc0_cr0 = mfdcr(DCRN_CPC0_CR0); u32 opdv, epdv; if (cpc0_sys0 & 0x2){ /* Bypass system PLL */ p->cpu = p->plb = sys_clk; } else { u32 fbdv, fwdva, fwdvb, m, vco; fbdv = (cpc0_sys0 >> 18) & 0x0f; if (!fbdv) fbdv = 16; fwdva = 8 - ((cpc0_sys0 >> 15) & 0x7); fwdvb = 8 - ((cpc0_sys0 >> 12) & 0x7); /* Feedback path */ if (cpc0_sys0 & 0x00000080){ /* PerClk */ m = fwdvb * opdv * epdv; } else { /* CPU clock */ m = fbdv * fwdva; } vco = sys_clk * m; p->cpu = vco / fwdva; p->plb = vco / fwdvb; } opdv = ((cpc0_sys0 >> 10) & 0x3) + 1; epdv = ((cpc0_sys0 >> 8) & 0x3) + 1; p->opb = p->plb / opdv; p->ebc = p->opb / epdv; if (cpc0_cr0 & 0x00400000){ /* External UART clock */ p->uart0 = p->uart1 = ser_clk; } else { /* Internal UART clock */ u32 uart_div = ((cpc0_cr0 >> 16) & 0x1f) + 1; p->uart0 = p->uart1 = p->plb / uart_div; } }