⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock.c

📁 Sirf/Centrality公司GPS平台AtlasIII芯片AT640的Nboot源码
💻 C
字号:
#include "def.h"
#include "at4x0f.h"
#include "debug.h"
#include "nand.h"
#include "oem.h"
#include "cspregs.h"
#include <string.h>
#include "loader.h"
#include "nand.h"

#include "..\KERNEL\KERNLIBS\CLOCK\SYSCLK.C"

typedef void (*PFNLOCKCACHE)(DWORD dwAddr, DWORD dwSize, DWORD dwFlag);
DWORD	pfnLockCache;

extern TOC* g_pTOC; // made global because it's too big for our tiny stack
extern void XipClkSwitch(DWORD dwPllCfg, DWORD dwClkRat);
extern SYSTEMCLOCKINFO g_SysClock;
extern DWORD g_dwIoClk;
extern void LockCache(DWORD addr, DWORD dwNumWay, DWORD flags);
extern void FlushICache(void);

DWORD			g_dwCpuFreq;
SYSFREQRATIO	g_sysFreqRatio;

/*
#define PLL_SWITCH(dwPllCfg, dwClkRat) 	\
	if ( ((dwClkRat >> 12) & 0xf) == ((dwClkRat >> 8) & 0xf) )  { IOBG_ARB_CLKRATIO = 0x00; RISCINT_WIDTH = 0x00; } \
	else														{ IOBG_ARB_CLKRATIO = 0x01; RISCINT_WIDTH = 0x10; } \
	if (IS_DDR())   { XipClkSwitch (dwPllCfg, dwClkRat); } \
	else			{ SDRPllSwitch (dwPllCfg, dwClkRat); }
*/
void PllSwitch(DWORD dwPllCfg, DWORD dwClkRat)
{
	volatile int i;

	//switch to xtal
	PWR_CLK_SWITCH &= ~0x03;
	//PWR_CLK_SWITCH = 0x0;
	for(i=1;i<=100;i++);

	PWR_PLL1_CONFIG = dwPllCfg;
	PWR_CLK_RATIO = ((PWR_CLK_RATIO & 0xffff0000) | dwClkRat);
	for(i=1;i<=0x1000;i++);

	//switch to pll1
	PWR_CLK_SWITCH |= 0x01;
	//PWR_CLK_SWITCH = 0x01;
	for(i=1;i<=0x100;i++);
}

void ClkSwitch(DWORD dwPllCfg, DWORD dwClkRat)
{
	pfnLockCache = (DWORD) LockCache;

	pfnLockCache |= 0xC0000000;

	FlushICache();

	((PFNLOCKCACHE)pfnLockCache)(((DWORD)PllSwitch & ~0x1f), 1, 1);

	PllSwitch(dwPllCfg, dwClkRat);

	((PFNLOCKCACHE)pfnLockCache)(0, 0, 1);
}

__inline void PLL_SWITCH(DWORD dwPllCfg, DWORD dwClkRat)
{
	if(((dwClkRat >> 12) & 0xf) == ((dwClkRat >> 8) & 0xf))
	{
		IOBG_ARB_CLKRATIO = 0x00;
		RISCINT_WIDTH = 0x00;
	}
	else
	{
		IOBG_ARB_CLKRATIO = 0x01;
		RISCINT_WIDTH = 0x10;
	}

	ClkSwitch(dwPllCfg, dwClkRat);
}

__inline BOOL CheckValidClockSetting()
{
    DWORD   dwSysClk;

	g_dwCpuFreq -= (g_dwCpuFreq % 12);

	if (g_dwCpuFreq > 324 || g_dwCpuFreq < 192)
		return FALSE;

#if defined(HYNIX_75M) || defined(SAMSUNG_75M)
	if (IS_MDDR())
		return (g_dwCpuFreq == 300 && g_sysFreqRatio == SFR_CPU_DSP_SYS_IO_4_2_2_1);
#elif defined(SAMSUNG_HYNIX_50M)
	if (IS_MDDR())
		return (g_dwCpuFreq == 300 && g_sysFreqRatio == SFR_CPU_DSP_SYS_IO_6_4_2_1);
#endif

    switch (g_sysFreqRatio)
    {
	case SFR_CPU_DSP_SYS_IO_2_2_2_1:    dwSysClk = g_dwCpuFreq;     break;
	case SFR_CPU_DSP_SYS_IO_4_2_2_1:    dwSysClk = g_dwCpuFreq / 2; break;
	case SFR_CPU_DSP_SYS_IO_6_4_2_1:
	case SFR_CPU_DSP_SYS_IO_3_2_1_1:    dwSysClk = g_dwCpuFreq / 3; break;
    default:    return FALSE;
    }

	return IS_DDR() ? dwSysClk >= 150 : dwSysClk <= 166;
}

__inline void StartXipPllSwitch()
{
	DWORD dwPll1Cfg, dwClkRatioCfg;
    DWORD tmp = g_dwCpuFreq * 2 / 12;

    dwPll1Cfg = (g_dwCpuFreq >= 252 ? (tmp / 2) : (0x400 | tmp)) - 2;

	switch(g_sysFreqRatio)
	{
	case SFR_CPU_DSP_SYS_IO_2_2_2_1:
		dwClkRatioCfg = 0x4222;
		break;
	case SFR_CPU_DSP_SYS_IO_4_2_2_1:
		dwClkRatioCfg = 0x8442;
		break;
	case SFR_CPU_DSP_SYS_IO_6_4_2_1:
		dwClkRatioCfg = 0xc632;
		break;
	case SFR_CPU_DSP_SYS_IO_3_2_1_1:
		dwClkRatioCfg = 0x6632;
		break;
	}

    PLL_SWITCH (dwPll1Cfg, dwClkRatioCfg);
}

void CheckAndCfgClock(void)
{
	extern void GetCurrentSysClk(SYSTEMCLOCKINFO* pSysClk);

	if(!CheckValidClockSetting())
	{
		DbgPutString("Wrong Clock");
        g_pTOC->dwClockInfo = 0;    // marked as invalid clock info

		if(IS_DDR())
		{
			g_dwCpuFreq = 204;
			g_sysFreqRatio = SFR_CPU_DSP_SYS_IO_2_2_2_1;
		}
	#if defined(HYNIX_75M) || defined(SAMSUNG_75M)
		else if (IS_MDDR())
		{
			g_dwCpuFreq = 300;
			g_sysFreqRatio = SFR_CPU_DSP_SYS_IO_4_2_2_1;
		}
	#endif
		else
		{
			g_dwCpuFreq =  300;
			g_sysFreqRatio = SFR_CPU_DSP_SYS_IO_3_2_1_1;
		}
	}

    if (0 == g_pTOC->dwClockInfo)
    {
        g_pTOC->dwClockInfo = (((UINT)g_sysFreqRatio) << 16) | g_dwCpuFreq;
        NandWriteToc();
    }

    DbgFlush();

    StartXipPllSwitch ();

#if 0 // DEBUG ONLY
	DbgPutString ("\r\nPWR_PLL1_CONFIG=");
	DbgPutHex (PWR_PLL1_CONFIG);
	DbgPutString ("\r\nPWR_PLL2_CONFIG=");
	DbgPutHex (PWR_PLL2_CONFIG);
	DbgPutString ("\r\nPWR_CLK_SWITCH=");
	DbgPutHex (PWR_CLK_SWITCH);
	DbgPutString ("\r\nPWR_CLK_RATIO=");
	DbgPutHex (PWR_CLK_RATIO);
	DbgPutString ("\r\n");
#endif // DEBUG ONLY

	GetCurrentSysClk(&g_SysClock);

	DbgInit(DBG_BAUDRATE);
	FMD_Init();
}

int ChooseClockRatio(unsigned int c)
{
    g_sysFreqRatio = (SYSFREQRATIO) (c - '0');
    g_pTOC->dwClockInfo = 0;    // marked as invalid clock info
    CheckAndCfgClock ();
    return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -