aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s5pv210/clock.c
diff options
context:
space:
mode:
authorSeungwhan Youn <sw.youn@samsung.com>2010-10-13 21:39:28 -0400
committerKukjin Kim <kgene.kim@samsung.com>2010-10-25 03:06:09 -0400
commitc9fa7a08ccb40def56beb9986839b808646f579c (patch)
treeaa960006986f0770ccd17c4ccabe6fe08370df83 /arch/arm/mach-s5pv210/clock.c
parent42a6e20e4fd4755e6b4539891a4f20905af18dcd (diff)
ARM: S5PV210: Add EPLL clock operations
This patch adds EPLL specific clock get_rate/set_rate operations on S5PV210. Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> Acked-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm/mach-s5pv210/clock.c')
-rw-r--r--arch/arm/mach-s5pv210/clock.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 00a721771a43..156aa8af9072 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -1046,6 +1046,79 @@ static struct clksrc_clk *sysclks[] = {
1046 &clk_sclk_spdif, 1046 &clk_sclk_spdif,
1047}; 1047};
1048 1048
1049static u32 epll_div[][6] = {
1050 { 48000000, 0, 48, 3, 3, 0 },
1051 { 96000000, 0, 48, 3, 2, 0 },
1052 { 144000000, 1, 72, 3, 2, 0 },
1053 { 192000000, 0, 48, 3, 1, 0 },
1054 { 288000000, 1, 72, 3, 1, 0 },
1055 { 32750000, 1, 65, 3, 4, 35127 },
1056 { 32768000, 1, 65, 3, 4, 35127 },
1057 { 45158400, 0, 45, 3, 3, 10355 },
1058 { 45000000, 0, 45, 3, 3, 10355 },
1059 { 45158000, 0, 45, 3, 3, 10355 },
1060 { 49125000, 0, 49, 3, 3, 9961 },
1061 { 49152000, 0, 49, 3, 3, 9961 },
1062 { 67737600, 1, 67, 3, 3, 48366 },
1063 { 67738000, 1, 67, 3, 3, 48366 },
1064 { 73800000, 1, 73, 3, 3, 47710 },
1065 { 73728000, 1, 73, 3, 3, 47710 },
1066 { 36000000, 1, 32, 3, 4, 0 },
1067 { 60000000, 1, 60, 3, 3, 0 },
1068 { 72000000, 1, 72, 3, 3, 0 },
1069 { 80000000, 1, 80, 3, 3, 0 },
1070 { 84000000, 0, 42, 3, 2, 0 },
1071 { 50000000, 0, 50, 3, 3, 0 },
1072};
1073
1074static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
1075{
1076 unsigned int epll_con, epll_con_k;
1077 unsigned int i;
1078
1079 /* Return if nothing changed */
1080 if (clk->rate == rate)
1081 return 0;
1082
1083 epll_con = __raw_readl(S5P_EPLL_CON);
1084 epll_con_k = __raw_readl(S5P_EPLL_CON1);
1085
1086 epll_con_k &= ~PLL46XX_KDIV_MASK;
1087 epll_con &= ~(1 << 27 |
1088 PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
1089 PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
1090 PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1091
1092 for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1093 if (epll_div[i][0] == rate) {
1094 epll_con_k |= epll_div[i][5] << 0;
1095 epll_con |= (epll_div[i][1] << 27 |
1096 epll_div[i][2] << PLL46XX_MDIV_SHIFT |
1097 epll_div[i][3] << PLL46XX_PDIV_SHIFT |
1098 epll_div[i][4] << PLL46XX_SDIV_SHIFT);
1099 break;
1100 }
1101 }
1102
1103 if (i == ARRAY_SIZE(epll_div)) {
1104 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1105 __func__);
1106 return -EINVAL;
1107 }
1108
1109 __raw_writel(epll_con, S5P_EPLL_CON);
1110 __raw_writel(epll_con_k, S5P_EPLL_CON1);
1111
1112 clk->rate = rate;
1113
1114 return 0;
1115}
1116
1117static struct clk_ops s5pv210_epll_ops = {
1118 .set_rate = s5pv210_epll_set_rate,
1119 .get_rate = s5p_epll_get_rate,
1120};
1121
1049void __init_or_cpufreq s5pv210_setup_clocks(void) 1122void __init_or_cpufreq s5pv210_setup_clocks(void)
1050{ 1123{
1051 struct clk *xtal_clk; 1124 struct clk *xtal_clk;
@@ -1064,6 +1137,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
1064 unsigned int ptr; 1137 unsigned int ptr;
1065 u32 clkdiv0, clkdiv1; 1138 u32 clkdiv0, clkdiv1;
1066 1139
1140 /* Set functions for clk_fout_epll */
1141 clk_fout_epll.enable = s5p_epll_enable;
1142 clk_fout_epll.ops = &s5pv210_epll_ops;
1143
1067 printk(KERN_DEBUG "%s: registering clocks\n", __func__); 1144 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1068 1145
1069 clkdiv0 = __raw_readl(S5P_CLK_DIV0); 1146 clkdiv0 = __raw_readl(S5P_CLK_DIV0);