-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ARM: S5P6440: Add Clock and PLL support
This patch adds clock and pll support for S5P6440. This patch are based on Harald Welte's patches and Ben's plat-samsung. Signed-off-by: Thomas Abraham <thomas.ab@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
- Loading branch information
Kukjin Kim
authored and
Ben Dooks
committed
Jan 15, 2010
1 parent
209fecd
commit 1a0e8a5
Showing
6 changed files
with
1,086 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* linux/arch/arm/mach-s5p6440/include/mach/regs-clock.h | ||
* | ||
* Copyright (c) 2009 Samsung Electronics Co., Ltd. | ||
* http://www.samsung.com/ | ||
* | ||
* S5P6440 - Clock register definitions | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#ifndef __ASM_ARCH_REGS_CLOCK_H | ||
#define __ASM_ARCH_REGS_CLOCK_H __FILE__ | ||
|
||
#include <mach/map.h> | ||
|
||
#define S5P_CLKREG(x) (S5P_VA_CLK + (x)) | ||
|
||
#define S5P_APLL_LOCK S5P_CLKREG(0x00) | ||
#define S5P_MPLL_LOCK S5P_CLKREG(0x04) | ||
#define S5P_EPLL_LOCK S5P_CLKREG(0x08) | ||
#define S5P_APLL_CON S5P_CLKREG(0x0C) | ||
#define S5P_MPLL_CON S5P_CLKREG(0x10) | ||
#define S5P_EPLL_CON S5P_CLKREG(0x14) | ||
#define S5P_EPLL_CON_K S5P_CLKREG(0x18) | ||
#define S5P_CLK_SRC0 S5P_CLKREG(0x1C) | ||
#define S5P_CLK_DIV0 S5P_CLKREG(0x20) | ||
#define S5P_CLK_DIV1 S5P_CLKREG(0x24) | ||
#define S5P_CLK_DIV2 S5P_CLKREG(0x28) | ||
#define S5P_CLK_OUT S5P_CLKREG(0x2C) | ||
#define S5P_CLK_GATE_HCLK0 S5P_CLKREG(0x30) | ||
#define S5P_CLK_GATE_PCLK S5P_CLKREG(0x34) | ||
#define S5P_CLK_GATE_SCLK0 S5P_CLKREG(0x38) | ||
#define S5P_CLK_GATE_MEM0 S5P_CLKREG(0x3C) | ||
#define S5P_CLK_DIV3 S5P_CLKREG(0x40) | ||
#define S5P_CLK_GATE_HCLK1 S5P_CLKREG(0x44) | ||
#define S5P_CLK_GATE_SCLK1 S5P_CLKREG(0x48) | ||
#define S5P_AHB_CON0 S5P_CLKREG(0x100) | ||
#define S5P_CLK_SRC1 S5P_CLKREG(0x10C) | ||
#define S5P_SWRESET S5P_CLKREG(0x114) | ||
#define S5P_SYS_ID S5P_CLKREG(0x118) | ||
#define S5P_SYS_OTHERS S5P_CLKREG(0x11C) | ||
#define S5P_MEM_CFG_STAT S5P_CLKREG(0x12C) | ||
#define S5P_PWR_CFG S5P_CLKREG(0x804) | ||
#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0x808) | ||
#define S5P_NORMAL_CFG S5P_CLKREG(0x810) | ||
#define S5P_STOP_CFG S5P_CLKREG(0x814) | ||
#define S5P_SLEEP_CFG S5P_CLKREG(0x818) | ||
#define S5P_OSC_FREQ S5P_CLKREG(0x820) | ||
#define S5P_OSC_STABLE S5P_CLKREG(0x824) | ||
#define S5P_PWR_STABLE S5P_CLKREG(0x828) | ||
#define S5P_MTC_STABLE S5P_CLKREG(0x830) | ||
#define S5P_OTHERS S5P_CLKREG(0x900) | ||
#define S5P_RST_STAT S5P_CLKREG(0x904) | ||
#define S5P_WAKEUP_STAT S5P_CLKREG(0x908) | ||
#define S5P_SLPEN S5P_CLKREG(0x930) | ||
#define S5P_INFORM0 S5P_CLKREG(0xA00) | ||
#define S5P_INFORM1 S5P_CLKREG(0xA04) | ||
#define S5P_INFORM2 S5P_CLKREG(0xA08) | ||
#define S5P_INFORM3 S5P_CLKREG(0xA0C) | ||
|
||
/* CLKDIV0 */ | ||
#define S5P_CLKDIV0_PCLK_MASK (0xf << 12) | ||
#define S5P_CLKDIV0_PCLK_SHIFT (12) | ||
#define S5P_CLKDIV0_HCLK_MASK (0xf << 8) | ||
#define S5P_CLKDIV0_HCLK_SHIFT (8) | ||
#define S5P_CLKDIV0_MPLL_MASK (0x1 << 4) | ||
#define S5P_CLKDIV0_ARM_MASK (0xf << 0) | ||
#define S5P_CLKDIV0_ARM_SHIFT (0) | ||
|
||
/* CLKDIV3 */ | ||
#define S5P_CLKDIV3_PCLK_LOW_MASK (0xf << 12) | ||
#define S5P_CLKDIV3_PCLK_LOW_SHIFT (12) | ||
#define S5P_CLKDIV3_HCLK_LOW_MASK (0xf << 8) | ||
#define S5P_CLKDIV3_HCLK_LOW_SHIFT (8) | ||
|
||
/* HCLK0 GATE Registers */ | ||
#define S5P_CLKCON_HCLK0_USB (1<<20) | ||
#define S5P_CLKCON_HCLK0_HSMMC2 (1<<19) | ||
#define S5P_CLKCON_HCLK0_HSMMC1 (1<<18) | ||
#define S5P_CLKCON_HCLK0_HSMMC0 (1<<17) | ||
#define S5P_CLKCON_HCLK0_POST0 (1<<5) | ||
|
||
/* HCLK1 GATE Registers */ | ||
#define S5P_CLKCON_HCLK1_DISPCON (1<<1) | ||
|
||
/* PCLK GATE Registers */ | ||
#define S5P_CLKCON_PCLK_IIS2 (1<<26) | ||
#define S5P_CLKCON_PCLK_SPI1 (1<<22) | ||
#define S5P_CLKCON_PCLK_SPI0 (1<<21) | ||
#define S5P_CLKCON_PCLK_GPIO (1<<18) | ||
#define S5P_CLKCON_PCLK_IIC0 (1<<17) | ||
#define S5P_CLKCON_PCLK_TSADC (1<<12) | ||
#define S5P_CLKCON_PCLK_PWM (1<<7) | ||
#define S5P_CLKCON_PCLK_RTC (1<<6) | ||
#define S5P_CLKCON_PCLK_WDT (1<<5) | ||
#define S5P_CLKCON_PCLK_UART3 (1<<4) | ||
#define S5P_CLKCON_PCLK_UART2 (1<<3) | ||
#define S5P_CLKCON_PCLK_UART1 (1<<2) | ||
#define S5P_CLKCON_PCLK_UART0 (1<<1) | ||
|
||
/* SCLK0 GATE Registers */ | ||
#define S5P_CLKCON_SCLK0_MMC2_48 (1<<29) | ||
#define S5P_CLKCON_SCLK0_MMC1_48 (1<<28) | ||
#define S5P_CLKCON_SCLK0_MMC0_48 (1<<27) | ||
#define S5P_CLKCON_SCLK0_MMC2 (1<<26) | ||
#define S5P_CLKCON_SCLK0_MMC1 (1<<25) | ||
#define S5P_CLKCON_SCLK0_MMC0 (1<<24) | ||
#define S5P_CLKCON_SCLK0_SPI1_48 (1<<23) | ||
#define S5P_CLKCON_SCLK0_SPI0_48 (1<<22) | ||
#define S5P_CLKCON_SCLK0_SPI1 (1<<21) | ||
#define S5P_CLKCON_SCLK0_SPI0 (1<<20) | ||
#define S5P_CLKCON_SCLK0_UART (1<<5) | ||
|
||
/* SCLK1 GATE Registers */ | ||
|
||
/* MEM0 GATE Registers */ | ||
#define S5P_CLKCON_MEM0_HCLK_NFCON (1<<2) | ||
|
||
/*OTHERS Resgister */ | ||
#define S5P_OTHERS_USB_SIG_MASK (1<<16) | ||
#define S5P_OTHERS_HCLK_LOW_SEL_MPLL (1<<6) | ||
|
||
/* Compatibility defines */ | ||
#define ARM_CLK_DIV S5P_CLK_DIV0 | ||
#define ARM_DIV_RATIO_SHIFT 0 | ||
#define ARM_DIV_MASK (0xf << ARM_DIV_RATIO_SHIFT) | ||
|
||
#endif /* __ASM_ARCH_REGS_CLOCK_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* linux/arch/arm/plat-s5p/clock.c | ||
* | ||
* Copyright 2009 Samsung Electronics Co., Ltd. | ||
* http://www.samsung.com/ | ||
* | ||
* S5P - Common clock support | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <linux/init.h> | ||
#include <linux/module.h> | ||
#include <linux/kernel.h> | ||
#include <linux/list.h> | ||
#include <linux/errno.h> | ||
#include <linux/err.h> | ||
#include <linux/clk.h> | ||
#include <linux/sysdev.h> | ||
#include <linux/io.h> | ||
#include <asm/div64.h> | ||
|
||
#include <plat/clock.h> | ||
#include <plat/clock-clksrc.h> | ||
#include <plat/s5p-clock.h> | ||
|
||
/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call | ||
* clk_ext_xtal_mux. | ||
*/ | ||
struct clk clk_ext_xtal_mux = { | ||
.name = "ext_xtal", | ||
.id = -1, | ||
}; | ||
|
||
/* 48MHz USB Phy clock output */ | ||
struct clk clk_48m = { | ||
.name = "clk_48m", | ||
.id = -1, | ||
.rate = 48000000, | ||
}; | ||
|
||
/* APLL clock output | ||
* No need .ctrlbit, this is always on | ||
*/ | ||
struct clk clk_fout_apll = { | ||
.name = "fout_apll", | ||
.id = -1, | ||
}; | ||
|
||
/* MPLL clock output | ||
* No need .ctrlbit, this is always on | ||
*/ | ||
struct clk clk_fout_mpll = { | ||
.name = "fout_mpll", | ||
.id = -1, | ||
}; | ||
|
||
/* EPLL clock output */ | ||
struct clk clk_fout_epll = { | ||
.name = "fout_epll", | ||
.id = -1, | ||
.ctrlbit = (1 << 31), | ||
}; | ||
|
||
/* ARM clock */ | ||
struct clk clk_arm = { | ||
.name = "armclk", | ||
.id = -1, | ||
.rate = 0, | ||
.ctrlbit = 0, | ||
}; | ||
|
||
/* Possible clock sources for APLL Mux */ | ||
static struct clk *clk_src_apll_list[] = { | ||
[0] = &clk_fin_apll, | ||
[1] = &clk_fout_apll, | ||
}; | ||
|
||
struct clksrc_sources clk_src_apll = { | ||
.sources = clk_src_apll_list, | ||
.nr_sources = ARRAY_SIZE(clk_src_apll_list), | ||
}; | ||
|
||
/* Possible clock sources for MPLL Mux */ | ||
static struct clk *clk_src_mpll_list[] = { | ||
[0] = &clk_fin_mpll, | ||
[1] = &clk_fout_mpll, | ||
}; | ||
|
||
struct clksrc_sources clk_src_mpll = { | ||
.sources = clk_src_mpll_list, | ||
.nr_sources = ARRAY_SIZE(clk_src_mpll_list), | ||
}; | ||
|
||
/* Possible clock sources for EPLL Mux */ | ||
static struct clk *clk_src_epll_list[] = { | ||
[0] = &clk_fin_epll, | ||
[1] = &clk_fout_epll, | ||
}; | ||
|
||
struct clksrc_sources clk_src_epll = { | ||
.sources = clk_src_epll_list, | ||
.nr_sources = ARRAY_SIZE(clk_src_epll_list), | ||
}; | ||
|
||
int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) | ||
{ | ||
unsigned int ctrlbit = clk->ctrlbit; | ||
u32 con; | ||
|
||
con = __raw_readl(reg); | ||
con = enable ? (con | ctrlbit) : (con & ~ctrlbit); | ||
__raw_writel(con, reg); | ||
return 0; | ||
} | ||
|
||
static struct clk *s5p_clks[] __initdata = { | ||
&clk_ext_xtal_mux, | ||
&clk_48m, | ||
&clk_fout_apll, | ||
&clk_fout_mpll, | ||
&clk_fout_epll, | ||
&clk_arm, | ||
}; | ||
|
||
void __init s5p_register_clocks(unsigned long xtal_freq) | ||
{ | ||
int ret; | ||
|
||
clk_ext_xtal_mux.rate = xtal_freq; | ||
|
||
ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks)); | ||
if (ret > 0) | ||
printk(KERN_ERR "Failed to register s5p clocks\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* arch/arm/plat-s5p/include/plat/pll.h | ||
* | ||
* Copyright (c) 2009 Samsung Electronics Co., Ltd. | ||
* http://www.samsung.com/ | ||
* | ||
* S5P PLL code | ||
* | ||
* Based on arch/arm/plat-s3c64xx/include/plat/pll.h | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#define PLL45XX_MDIV_MASK (0x3FF) | ||
#define PLL45XX_PDIV_MASK (0x3F) | ||
#define PLL45XX_SDIV_MASK (0x7) | ||
#define PLL45XX_MDIV_SHIFT (16) | ||
#define PLL45XX_PDIV_SHIFT (8) | ||
#define PLL45XX_SDIV_SHIFT (0) | ||
|
||
#include <asm/div64.h> | ||
|
||
enum pll45xx_type_t { | ||
pll_4500, | ||
pll_4502, | ||
pll_4508 | ||
}; | ||
|
||
static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con, | ||
enum pll45xx_type_t pll_type) | ||
{ | ||
u32 mdiv, pdiv, sdiv; | ||
u64 fvco = baseclk; | ||
|
||
mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK; | ||
pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK; | ||
sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK; | ||
|
||
if (pll_type == pll_4508) | ||
sdiv = sdiv - 1; | ||
|
||
fvco *= mdiv; | ||
do_div(fvco, (pdiv << sdiv)); | ||
|
||
return (unsigned long)fvco; | ||
} | ||
|
||
#define PLL90XX_MDIV_MASK (0xFF) | ||
#define PLL90XX_PDIV_MASK (0x3F) | ||
#define PLL90XX_SDIV_MASK (0x7) | ||
#define PLL90XX_KDIV_MASK (0xffff) | ||
#define PLL90XX_MDIV_SHIFT (16) | ||
#define PLL90XX_PDIV_SHIFT (8) | ||
#define PLL90XX_SDIV_SHIFT (0) | ||
#define PLL90XX_KDIV_SHIFT (0) | ||
|
||
static inline unsigned long s5p_get_pll90xx(unsigned long baseclk, | ||
u32 pll_con, u32 pll_conk) | ||
{ | ||
unsigned long result; | ||
u32 mdiv, pdiv, sdiv, kdiv; | ||
u64 tmp; | ||
|
||
mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK; | ||
pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK; | ||
sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK; | ||
kdiv = pll_conk & PLL90XX_KDIV_MASK; | ||
|
||
/* We need to multiple baseclk by mdiv (the integer part) and kdiv | ||
* which is in 2^16ths, so shift mdiv up (does not overflow) and | ||
* add kdiv before multiplying. The use of tmp is to avoid any | ||
* overflows before shifting bac down into result when multipling | ||
* by the mdiv and kdiv pair. | ||
*/ | ||
|
||
tmp = baseclk; | ||
tmp *= (mdiv << 16) + kdiv; | ||
do_div(tmp, (pdiv << sdiv)); | ||
result = tmp >> 16; | ||
|
||
return result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h | ||
* | ||
* Copyright 2009 Samsung Electronics Co., Ltd. | ||
* http://www.samsung.com/ | ||
* | ||
* Header file for s5p clock support | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#ifndef __ASM_PLAT_S5P_CLOCK_H | ||
#define __ASM_PLAT_S5P_CLOCK_H __FILE__ | ||
|
||
#include <linux/clk.h> | ||
|
||
#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) | ||
|
||
#define clk_fin_apll clk_ext_xtal_mux | ||
#define clk_fin_mpll clk_ext_xtal_mux | ||
#define clk_fin_epll clk_ext_xtal_mux | ||
|
||
extern struct clk clk_ext_xtal_mux; | ||
extern struct clk clk_48m; | ||
extern struct clk clk_fout_apll; | ||
extern struct clk clk_fout_mpll; | ||
extern struct clk clk_fout_epll; | ||
extern struct clk clk_arm; | ||
|
||
extern struct clksrc_sources clk_src_apll; | ||
extern struct clksrc_sources clk_src_mpll; | ||
extern struct clksrc_sources clk_src_epll; | ||
|
||
extern int s5p6440_clk48m_ctrl(struct clk *clk, int enable); | ||
extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); | ||
|
||
#endif /* __ASM_PLAT_S5P_CLOCK_H */ |
Oops, something went wrong.