/*
 * PPC440GP system library
 *
 * Matt Porter <mporter@mvista.com>
 * Copyright 2002-2003 MontaVista Software Inc.
 *
 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 * 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 <linux/config.h>
#include <linux/types.h>
#include <asm/reg.h>
#include <asm/ibm44x.h>
#include <asm/mmu.h>

/*
 * 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 = ((cpc0_sys0 >> 10) & 0x3) + 1;
	u32 epdv = ((cpc0_sys0 >> 8) & 0x3) + 1;

	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;
	}

	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;
	}
}
