/*******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2007 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
********************************************************************************
*
* File Name:  occs.c
*
* $Date:      Feb-5-2007$
*
* $Version:   2.3.12.0$
*
* Description: Source file for the On-chip Clock Synthesis driver
*
*****************************************************************************/

#include "qs.h"
#include "occs.h"
#include "initconfig.h"

#ifdef __cplusplus
extern "C" {
#endif

void occsInit(void)
{
	/* Note: The PLL is setup early in the startup.c code */
}


/* calculate core (=peripheral bus) frequency */

#if OCCS_VERSION == 1

UWord32 occsGetIPBusFreq(UWord32 oscFreq)
{
	UWord16 divBy, scaler;

	divBy = periphMemRead(&ArchIO.Pll.plldb);
	scaler = divBy>>8;
	scaler &= 0x0003;	/* ==prescaler */

	/* prescaler frequency */
	oscFreq >>= ++scaler;
	
	/* Postscaler Output ? (otherwise assume prescaler output) */
	if (periphBitTest(OCCS_PLLCR_ZSRC_POSTSCALER, &ArchIO.Pll.pllcr))
	{
		scaler = divBy>>10;
		divBy &= 0x007F;
		scaler &= 0x0003; 	/* ==postscaler */
		
		oscFreq *= ++divBy;
		oscFreq >>= ++scaler;
	}
	
	return oscFreq;
}

#else /* OCCS_VERSION >= 2 */

/* Fixed PLL OCCS */
UWord32 occsGetIPBusFreq(UWord32 oscFreq)
{
	UWord16 scaler;

	/* Postscaler Output ? */
	if (periphBitTest(OCCS_PLLCR_ZSRC_POSTSCALER, &ArchIO.Pll.pllcr))
	{
		scaler = periphMemRead(&ArchIO.Pll.plldb);
		scaler = (scaler>>8) & 0x7;

		if(scaler > 5)
			scaler = 5;		
		
		oscFreq *= 24/3;		/* fixed PLL / fixed divider for sys_clk2x */
		oscFreq >>= scaler;		/* postscaler */
	}

	/* sys_clk2x --> sys_clk */
	oscFreq >>= 1;
	return oscFreq;
}

#endif

#ifdef __cplusplus
}
#endif

