Signed-off-by: Juergen Beisert <jbe@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
158 lines
3.6 KiB
C
158 lines
3.6 KiB
C
/*
|
|
* See file CREDITS for list of people who contributed to this
|
|
* project.
|
|
*
|
|
* 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.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <common.h>
|
|
#include <init.h>
|
|
#include <clock.h>
|
|
#include <io.h>
|
|
#include <mach/s3c-iomap.h>
|
|
#include <mach/s3c-generic.h>
|
|
#include <mach/s3c-clocks.h>
|
|
#include <mach/s3c-busctl.h>
|
|
|
|
/**
|
|
* Calculate the current M-PLL clock.
|
|
* @return Current frequency in Hz
|
|
*/
|
|
uint32_t s3c_get_mpllclk(void)
|
|
{
|
|
uint32_t m, p, s, reg_val;
|
|
|
|
reg_val = readl(S3C_MPLLCON);
|
|
m = ((reg_val & 0xFF000) >> 12) + 8;
|
|
p = ((reg_val & 0x003F0) >> 4) + 2;
|
|
s = reg_val & 0x3;
|
|
#ifdef CONFIG_CPU_S3C2410
|
|
return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
|
|
#endif
|
|
#ifdef CONFIG_CPU_S3C2440
|
|
return 2 * m * (S3C24XX_CLOCK_REFERENCE / (p << s));
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* Calculate the current U-PLL clock
|
|
* @return Current frequency in Hz
|
|
*/
|
|
uint32_t s3c_get_upllclk(void)
|
|
{
|
|
uint32_t m, p, s, reg_val;
|
|
|
|
reg_val = readl(S3C_UPLLCON);
|
|
m = ((reg_val & 0xFF000) >> 12) + 8;
|
|
p = ((reg_val & 0x003F0) >> 4) + 2;
|
|
s = reg_val & 0x3;
|
|
|
|
return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
|
|
}
|
|
|
|
/**
|
|
* Calculate the FCLK frequency used for the ARM CPU core
|
|
* @return Current frequency in Hz
|
|
*/
|
|
uint32_t s3c_get_fclk(void)
|
|
{
|
|
return s3c_get_mpllclk();
|
|
}
|
|
|
|
/**
|
|
* Calculate the HCLK frequency used for the AHB bus (CPU to main peripheral)
|
|
* @return Current frequency in Hz
|
|
*/
|
|
uint32_t s3c_get_hclk(void)
|
|
{
|
|
uint32_t f_clk;
|
|
|
|
f_clk = s3c_get_fclk();
|
|
#ifdef CONFIG_CPU_S3C2410
|
|
if (readl(S3C_CLKDIVN) & 0x02)
|
|
return f_clk >> 1;
|
|
#endif
|
|
#ifdef CONFIG_CPU_S3C2440
|
|
switch(readl(S3C_CLKDIVN) & 0x06) {
|
|
case 2:
|
|
return f_clk >> 1;
|
|
case 4:
|
|
return f_clk >> 2; /* TODO consider CAMDIVN */
|
|
case 6:
|
|
return f_clk / 3; /* TODO consider CAMDIVN */
|
|
}
|
|
#endif
|
|
return f_clk;
|
|
}
|
|
|
|
/**
|
|
* Calculate the PCLK frequency used for the slower peripherals
|
|
* @return Current frequency in Hz
|
|
*/
|
|
uint32_t s3c_get_pclk(void)
|
|
{
|
|
uint32_t p_clk;
|
|
|
|
p_clk = s3c_get_hclk();
|
|
if (readl(S3C_CLKDIVN) & 0x01)
|
|
return p_clk >> 1;
|
|
return p_clk;
|
|
}
|
|
|
|
/**
|
|
* Calculate the UCLK frequency used by the USB host device
|
|
* @return Current frequency in Hz
|
|
*/
|
|
uint32_t s3c24_get_uclk(void)
|
|
{
|
|
return s3c_get_upllclk();
|
|
}
|
|
|
|
/**
|
|
* Return correct UART frequency based on the UCON register
|
|
*/
|
|
unsigned s3c_get_uart_clk(unsigned src)
|
|
{
|
|
switch (src & 3) {
|
|
case 0:
|
|
case 2:
|
|
return s3c_get_pclk();
|
|
case 1:
|
|
return 0; /* TODO UEXTCLK */
|
|
case 3:
|
|
return 0; /* TODO FCLK/n */
|
|
}
|
|
return 0; /* not reached, to make compiler happy */
|
|
}
|
|
|
|
/**
|
|
* Show the user the current clock settings
|
|
*/
|
|
int s3c24xx_dump_clocks(void)
|
|
{
|
|
printf("refclk: %7d kHz\n", S3C24XX_CLOCK_REFERENCE / 1000);
|
|
printf("mpll: %7d kHz\n", s3c_get_mpllclk() / 1000);
|
|
printf("upll: %7d kHz\n", s3c_get_upllclk() / 1000);
|
|
printf("fclk: %7d kHz\n", s3c_get_fclk() / 1000);
|
|
printf("hclk: %7d kHz\n", s3c_get_hclk() / 1000);
|
|
printf("pclk: %7d kHz\n", s3c_get_pclk() / 1000);
|
|
printf("SDRAM1: CL%d@%dMHz\n", ((readl(S3C_BANKCON6) & 0xc) >> 2) + 2,
|
|
s3c_get_hclk() / 1000000);
|
|
if ((readl(S3C_BANKCON7) & (0x3 << 15)) == (0x3 << 15))
|
|
printf("SDRAM2: CL%d@%dMHz\n",
|
|
((readl(S3C_BANKCON7) & 0xc) >> 2) + 2,
|
|
s3c_get_hclk() / 1000000);
|
|
return 0;
|
|
}
|
|
|
|
late_initcall(s3c24xx_dump_clocks);
|