| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 |  * PPC440GP system library | 
 | 3 |  * | 
 | 4 |  * Matt Porter <mporter@mvista.com> | 
 | 5 |  * Copyright 2002-2003 MontaVista Software Inc. | 
 | 6 |  * | 
 | 7 |  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | 
 | 8 |  * Copyright (c) 2003 Zultys Technologies | 
 | 9 |  * | 
 | 10 |  * This program is free software; you can redistribute  it and/or modify it | 
 | 11 |  * under  the terms of  the GNU General  Public License as published by the | 
 | 12 |  * Free Software Foundation;  either version 2 of the  License, or (at your | 
 | 13 |  * option) any later version. | 
 | 14 |  * | 
 | 15 |  */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 16 | #include <linux/types.h> | 
 | 17 | #include <asm/reg.h> | 
 | 18 | #include <asm/ibm44x.h> | 
 | 19 | #include <asm/mmu.h> | 
 | 20 |  | 
 | 21 | /* | 
 | 22 |  * Calculate 440GP clocks | 
 | 23 |  */ | 
 | 24 | void __init ibm440gp_get_clocks(struct ibm44x_clocks* p, | 
 | 25 | 				unsigned int sys_clk, | 
 | 26 | 				unsigned int ser_clk) | 
 | 27 | { | 
 | 28 | 	u32 cpc0_sys0 = mfdcr(DCRN_CPC0_SYS0); | 
 | 29 | 	u32 cpc0_cr0 = mfdcr(DCRN_CPC0_CR0); | 
 | 30 | 	u32 opdv = ((cpc0_sys0 >> 10) & 0x3) + 1; | 
 | 31 | 	u32 epdv = ((cpc0_sys0 >> 8) & 0x3) + 1; | 
 | 32 |  | 
 | 33 | 	if (cpc0_sys0 & 0x2){ | 
 | 34 | 		/* Bypass system PLL */ | 
 | 35 | 		p->cpu = p->plb = sys_clk; | 
 | 36 | 	} | 
 | 37 | 	else { | 
 | 38 | 		u32 fbdv, fwdva, fwdvb, m, vco; | 
 | 39 |  | 
 | 40 | 		fbdv = (cpc0_sys0 >> 18) & 0x0f; | 
 | 41 | 		if (!fbdv) | 
 | 42 | 			fbdv = 16; | 
 | 43 |  | 
 | 44 | 		fwdva = 8 - ((cpc0_sys0 >> 15) & 0x7); | 
 | 45 | 		fwdvb = 8 - ((cpc0_sys0 >> 12) & 0x7); | 
 | 46 |  | 
 | 47 |     		/* Feedback path */	 | 
 | 48 | 		if (cpc0_sys0 & 0x00000080){ | 
 | 49 | 			/* PerClk */ | 
 | 50 | 			m = fwdvb * opdv * epdv; | 
 | 51 | 		} | 
 | 52 | 		else { | 
 | 53 | 			/* CPU clock */ | 
 | 54 | 			m = fbdv * fwdva; | 
 | 55 |     		} | 
 | 56 | 		vco = sys_clk * m; | 
 | 57 | 		p->cpu = vco / fwdva; | 
 | 58 | 		p->plb = vco / fwdvb; | 
 | 59 | 	} | 
 | 60 |  | 
 | 61 | 	p->opb = p->plb / opdv; | 
 | 62 | 	p->ebc = p->opb / epdv; | 
 | 63 |  | 
 | 64 | 	if (cpc0_cr0 & 0x00400000){ | 
 | 65 | 		/* External UART clock */ | 
 | 66 | 		p->uart0 = p->uart1 = ser_clk; | 
 | 67 | 	} | 
 | 68 | 	else { | 
 | 69 | 		/* Internal UART clock */ | 
 | 70 |     		u32 uart_div = ((cpc0_cr0 >> 16) & 0x1f) + 1; | 
 | 71 | 		p->uart0 = p->uart1 = p->plb / uart_div; | 
 | 72 | 	} | 
 | 73 | } |