Commit e425382e authored by Ben Dooks's avatar Ben Dooks

[ARM] S3C24XX: Update clock data on resume

Update the clock settings on resume for suspend/resume
support so that if the boot loader changes anything or
the system's PLL is reset then we return with the correct
settings.
Signed-off-by: default avatarBen Dooks <ben-linux@fluff.org>
parent c3391e36
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/clk.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -28,6 +29,8 @@ ...@@ -28,6 +29,8 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <plat/cpu-freq.h>
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
...@@ -65,13 +68,19 @@ void __init s3c2410_map_io(void) ...@@ -65,13 +68,19 @@ void __init s3c2410_map_io(void)
iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
} }
void __init s3c2410_init_clocks(int xtal) void __init_or_cpufreq s3c2410_setup_clocks(void)
{ {
struct clk *xtal_clk;
unsigned long tmp; unsigned long tmp;
unsigned long xtal;
unsigned long fclk; unsigned long fclk;
unsigned long hclk; unsigned long hclk;
unsigned long pclk; unsigned long pclk;
xtal_clk = clk_get(NULL, "xtal");
xtal = clk_get_rate(xtal_clk);
clk_put(xtal_clk);
/* now we've got our machine bits initialised, work out what /* now we've got our machine bits initialised, work out what
* clocks we've got */ * clocks we've got */
...@@ -93,7 +102,13 @@ void __init s3c2410_init_clocks(int xtal) ...@@ -93,7 +102,13 @@ void __init s3c2410_init_clocks(int xtal)
* console to use them * console to use them
*/ */
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); s3c24xx_setup_clocks(fclk, hclk, pclk);
}
void __init s3c2410_init_clocks(int xtal)
{
s3c24xx_register_baseclocks(xtal);
s3c2410_setup_clocks();
s3c2410_baseclk_add(); s3c2410_baseclk_add();
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
...@@ -33,6 +34,8 @@ ...@@ -33,6 +34,8 @@
#include <mach/reset.h> #include <mach/reset.h>
#include <mach/idle.h> #include <mach/idle.h>
#include <plat/cpu-freq.h>
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-power.h> #include <mach/regs-power.h>
...@@ -156,17 +159,23 @@ void __init s3c2412_map_io(void) ...@@ -156,17 +159,23 @@ void __init s3c2412_map_io(void)
iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc)); iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
} }
void __init s3c2412_init_clocks(int xtal) void __init_or_cpufreq s3c2412_setup_clocks(void)
{ {
struct clk *xtal_clk;
unsigned long tmp; unsigned long tmp;
unsigned long xtal;
unsigned long fclk; unsigned long fclk;
unsigned long hclk; unsigned long hclk;
unsigned long pclk; unsigned long pclk;
xtal_clk = clk_get(NULL, "xtal");
xtal = clk_get_rate(xtal_clk);
clk_put(xtal_clk);
/* now we've got our machine bits initialised, work out what /* now we've got our machine bits initialised, work out what
* clocks we've got */ * clocks we've got */
fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2); fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal * 2);
clk_mpll.rate = fclk; clk_mpll.rate = fclk;
...@@ -183,11 +192,17 @@ void __init s3c2412_init_clocks(int xtal) ...@@ -183,11 +192,17 @@ void __init s3c2412_init_clocks(int xtal)
printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n", printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
print_mhz(fclk), print_mhz(hclk), print_mhz(pclk)); print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
s3c24xx_setup_clocks(fclk, hclk, pclk);
}
void __init s3c2412_init_clocks(int xtal)
{
/* initialise the clocks here, to allow other things like the /* initialise the clocks here, to allow other things like the
* console to use them * console to use them
*/ */
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); s3c24xx_register_baseclocks(xtal);
s3c2412_setup_clocks();
s3c2412_baseclk_add(); s3c2412_baseclk_add();
} }
......
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
#include <mach/regs-s3c2443-clock.h> #include <mach/regs-s3c2443-clock.h>
#include <plat/cpu-freq.h>
#include <plat/s3c2443.h> #include <plat/s3c2443.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
...@@ -1011,22 +1013,20 @@ static struct clk *clks[] __initdata = { ...@@ -1011,22 +1013,20 @@ static struct clk *clks[] __initdata = {
&clk_prediv, &clk_prediv,
}; };
void __init s3c2443_init_clocks(int xtal) void __init_or_cpufreq s3c2443_setup_clocks(void)
{ {
unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
struct clk *xtal_clk;
unsigned long xtal;
unsigned long pll; unsigned long pll;
unsigned long fclk; unsigned long fclk;
unsigned long hclk; unsigned long hclk;
unsigned long pclk; unsigned long pclk;
struct clk *clkp;
int ret;
int ptr;
/* s3c2443 parents h and p clocks from prediv */ xtal_clk = clk_get(NULL, "xtal");
clk_h.parent = &clk_prediv; xtal = clk_get_rate(xtal_clk);
clk_p.parent = &clk_prediv; clk_put(xtal_clk);
pll = s3c2443_get_mpll(mpllcon, xtal); pll = s3c2443_get_mpll(mpllcon, xtal);
clk_msysclk.rate = pll; clk_msysclk.rate = pll;
...@@ -1036,13 +1036,29 @@ void __init s3c2443_init_clocks(int xtal) ...@@ -1036,13 +1036,29 @@ void __init s3c2443_init_clocks(int xtal)
hclk /= s3c2443_get_hdiv(clkdiv0); hclk /= s3c2443_get_hdiv(clkdiv0);
pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); s3c24xx_setup_clocks(fclk, hclk, pclk);
printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
(mpllcon & S3C2443_PLLCON_OFF) ? "off":"on", (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
print_mhz(pll), print_mhz(fclk), print_mhz(pll), print_mhz(fclk),
print_mhz(hclk), print_mhz(pclk)); print_mhz(hclk), print_mhz(pclk));
s3c24xx_setup_clocks(fclk, hclk, pclk);
}
void __init s3c2443_init_clocks(int xtal)
{
struct clk *clkp;
unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
int ret;
int ptr;
/* s3c2443 parents h and p clocks from prediv */
clk_h.parent = &clk_prediv;
clk_p.parent = &clk_prediv;
s3c24xx_register_baseclocks(xtal);
s3c2443_setup_clocks();
s3c2443_clk_initparents(); s3c2443_clk_initparents();
for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
...@@ -1056,7 +1072,6 @@ void __init s3c2443_init_clocks(int xtal) ...@@ -1056,7 +1072,6 @@ void __init s3c2443_init_clocks(int xtal)
} }
clk_epll.rate = s3c2443_get_epll(epllcon, xtal); clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
clk_usb_bus.parent = &clk_usb_bus_host; clk_usb_bus.parent = &clk_usb_bus_host;
/* ensure usb bus clock is within correct rate of 48MHz */ /* ensure usb bus clock is within correct rate of 48MHz */
......
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <plat/cpu-freq.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/pll.h> #include <plat/pll.h>
...@@ -327,24 +329,24 @@ int s3c24xx_register_clocks(struct clk **clks, int nr_clks) ...@@ -327,24 +329,24 @@ int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
/* initalise all the clocks */ /* initalise all the clocks */
int __init s3c24xx_setup_clocks(unsigned long xtal, void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
unsigned long fclk, unsigned long hclk,
unsigned long hclk, unsigned long pclk)
unsigned long pclk)
{ {
printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n"); clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON),
clk_xtal.rate);
/* initialise the main system clocks */
clk_xtal.rate = xtal;
clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
clk_mpll.rate = fclk; clk_mpll.rate = fclk;
clk_h.rate = hclk; clk_h.rate = hclk;
clk_p.rate = pclk; clk_p.rate = pclk;
clk_f.rate = fclk; clk_f.rate = fclk;
}
/* assume uart clocks are correctly setup */ int __init s3c24xx_register_baseclocks(unsigned long xtal)
{
printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
clk_xtal.rate = xtal;
/* register our clocks */ /* register our clocks */
...@@ -368,3 +370,4 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, ...@@ -368,3 +370,4 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
return 0; return 0;
} }
...@@ -60,7 +60,14 @@ extern int s3c2410_clkcon_enable(struct clk *clk, int enable); ...@@ -60,7 +60,14 @@ extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
extern int s3c24xx_register_clock(struct clk *clk); extern int s3c24xx_register_clock(struct clk *clk);
extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks); extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
extern int s3c24xx_setup_clocks(unsigned long xtal, extern int s3c24xx_register_baseclocks(unsigned long xtal);
unsigned long fclk,
unsigned long hclk, extern void s3c24xx_setup_clocks(unsigned long fclk,
unsigned long pclk); unsigned long hclk,
unsigned long pclk);
extern void s3c2410_setup_clocks(void);
extern void s3c2412_setup_clocks(void);
extern void s3c244x_setup_clocks(void);
extern void s3c2443_setup_clocks(void);
...@@ -76,11 +76,13 @@ static struct sleep_save core_save[] = { ...@@ -76,11 +76,13 @@ static struct sleep_save core_save[] = {
SAVE_ITEM(S3C2410_BANKCON4), SAVE_ITEM(S3C2410_BANKCON4),
SAVE_ITEM(S3C2410_BANKCON5), SAVE_ITEM(S3C2410_BANKCON5),
#ifndef CONFIG_CPU_FREQ
SAVE_ITEM(S3C2410_CLKDIVN), SAVE_ITEM(S3C2410_CLKDIVN),
SAVE_ITEM(S3C2410_MPLLCON), SAVE_ITEM(S3C2410_MPLLCON),
SAVE_ITEM(S3C2410_REFRESH),
#endif
SAVE_ITEM(S3C2410_UPLLCON), SAVE_ITEM(S3C2410_UPLLCON),
SAVE_ITEM(S3C2410_CLKSLOW), SAVE_ITEM(S3C2410_CLKSLOW),
SAVE_ITEM(S3C2410_REFRESH),
}; };
static struct gpio_sleep { static struct gpio_sleep {
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <plat/cpu-freq.h>
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
...@@ -71,15 +73,18 @@ void __init s3c244x_map_io(void) ...@@ -71,15 +73,18 @@ void __init s3c244x_map_io(void)
s3c_device_usbgadget.name = "s3c2440-usbgadget"; s3c_device_usbgadget.name = "s3c2440-usbgadget";
} }
void __init s3c244x_init_clocks(int xtal) void __init_or_cpufreq s3c244x_setup_clocks(void)
{ {
struct clk *xtal_clk;
unsigned long clkdiv; unsigned long clkdiv;
unsigned long camdiv; unsigned long camdiv;
unsigned long xtal;
unsigned long hclk, fclk, pclk; unsigned long hclk, fclk, pclk;
int hdiv = 1; int hdiv = 1;
/* now we've got our machine bits initialised, work out what xtal_clk = clk_get(NULL, "xtal");
* clocks we've got */ xtal = clk_get_rate(xtal_clk);
clk_put(xtal_clk);
fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2; fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
...@@ -107,18 +112,24 @@ void __init s3c244x_init_clocks(int xtal) ...@@ -107,18 +112,24 @@ void __init s3c244x_init_clocks(int xtal)
} }
hclk = fclk / hdiv; hclk = fclk / hdiv;
pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1); pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
/* print brief summary of clocks, etc */ /* print brief summary of clocks, etc */
printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n", printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
print_mhz(fclk), print_mhz(hclk), print_mhz(pclk)); print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
s3c24xx_setup_clocks(fclk, hclk, pclk);
}
void __init s3c244x_init_clocks(int xtal)
{
/* initialise the clocks here, to allow other things like the /* initialise the clocks here, to allow other things like the
* console to use them, and to add new ones after the initialisation * console to use them, and to add new ones after the initialisation
*/ */
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); s3c24xx_register_baseclocks(xtal);
s3c244x_setup_clocks();
s3c2410_baseclk_add(); s3c2410_baseclk_add();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment