diff --git a/libcpu/arm/s3c24x0/system_clock.c b/libcpu/arm/s3c24x0/system_clock.c new file mode 100644 index 0000000000..38ffa5d233 --- /dev/null +++ b/libcpu/arm/s3c24x0/system_clock.c @@ -0,0 +1,108 @@ +/* + * File : clock.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2008-04-25 Yi.qiu first version + */ + +#include +#include "s3c24x0.h" + +#define CONFIG_SYS_CLK_FREQ 12000000 // Fin = 12.00MHz + +#if CONFIG_SYS_CLK_FREQ == 12000000 + /* MPLL=2*12*100/6=400MHz */ + #define MPL_MIDV 92 /* m=MPL_MDIV+8=100 */ + #define MPL_PDIV 4 /* p=MPL_PDIV+2=6 */ + #define MPL_SDIV 0 /* s=MPL_SDIV=0 */ + /* UPLL=12*64/8=96MHz */ + #define UPL_MDIV 56 /* m=UPL_MDIV+8=64 */ + #define UPL_PDIV 2 /* p=UPL_PDIV+2=4 */ + #define UPL_SDIV 1 /* s=UPL_SDIV=1 */ + /* System clock divider FCLK:HCLK:PCLK=1:4:8 */ + #define DIVN_UPLL 0x1 /* UCLK = UPLL clock / 2 */ + #define HDIVN 0x2 /* HCLK = FCLK / 4 */ + #define PDIVN 0x1 /* PCLK = HCLK / 2 */ +#endif + +rt_uint32_t PCLK; +rt_uint32_t FCLK; +rt_uint32_t HCLK; +rt_uint32_t UCLK; + +void rt_hw_get_clock(void) +{ + rt_uint32_t val; + rt_uint8_t m, p, s; + + val = MPLLCON; + m = (val>>12)&0xff; + p = (val>>4)&0x3f; + s = val&3; + + FCLK = ((m+8)*(CONFIG_SYS_CLK_FREQ/100)*2)/((p+2)*(1<>1)&3; + p = val&1; + + switch (m) { + case 0: + HCLK = FCLK; + break; + case 1: + HCLK = FCLK>>1; + break; + case 2: + if(s&2) + HCLK = FCLK>>3; + else + HCLK = FCLK>>2; + break; + case 3: + if(s&1) + HCLK = FCLK/6; + else + HCLK = FCLK/3; + break; +} + + if(p) + PCLK = HCLK>>1; + else + PCLK = HCLK; +} + +void rt_hw_set_mpll_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv) +{ + MPLLCON = sdiv | (pdiv<<4) | (mdiv<<12); +} + +void rt_hw_set_upll_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv) +{ + UPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv; +} + +void rt_hw_set_divider(rt_uint8_t hdivn, rt_uint8_t pdivn) +{ + CLKDIVN = (hdivn<<1) | pdivn; +} + +/** + * @brief System Clock Configuration + */ +void rt_hw_clock_init(void) +{ + LOCKTIME = 0xFFFFFFFF; + rt_hw_set_divider(HDIVN, PDIVN); + rt_hw_set_upll_clock(UPL_SDIV, UPL_PDIV, UPL_MDIV); + rt_hw_set_mpll_clock(MPL_SDIV, MPL_PDIV, MPL_MIDV); +} +