|
@@ -0,0 +1,163 @@
|
|
|
+/* linux/arch/arm/mach-s5pv210/clock.c
|
|
|
+ *
|
|
|
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
|
|
|
+ * http://www.samsung.com/
|
|
|
+ *
|
|
|
+ * S5PV210 - 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/device.h>
|
|
|
+#include <linux/io.h>
|
|
|
+
|
|
|
+#include <mach/map.h>
|
|
|
+
|
|
|
+#include <plat/cpu-freq.h>
|
|
|
+#include <mach/regs-clock.h>
|
|
|
+#include <plat/clock.h>
|
|
|
+#include <plat/cpu.h>
|
|
|
+#include <plat/pll.h>
|
|
|
+#include <plat/s5p-clock.h>
|
|
|
+#include <plat/clock-clksrc.h>
|
|
|
+
|
|
|
+#include "common.h"
|
|
|
+
|
|
|
+static unsigned long xtal;
|
|
|
+
|
|
|
+static struct clksrc_clk clk_mout_apll = {
|
|
|
+ .clk = {
|
|
|
+ .name = "mout_apll",
|
|
|
+ },
|
|
|
+ .sources = &clk_src_apll,
|
|
|
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_mout_epll = {
|
|
|
+ .clk = {
|
|
|
+ .name = "mout_epll",
|
|
|
+ },
|
|
|
+ .sources = &clk_src_epll,
|
|
|
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_mout_mpll = {
|
|
|
+ .clk = {
|
|
|
+ .name = "mout_mpll",
|
|
|
+ },
|
|
|
+ .sources = &clk_src_mpll,
|
|
|
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk *clkset_armclk_list[] = {
|
|
|
+ [0] = &clk_mout_apll.clk,
|
|
|
+ [1] = &clk_mout_mpll.clk,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_sources clkset_armclk = {
|
|
|
+ .sources = clkset_armclk_list,
|
|
|
+ .nr_sources = ARRAY_SIZE(clkset_armclk_list),
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_armclk = {
|
|
|
+ .clk = {
|
|
|
+ .name = "armclk",
|
|
|
+ },
|
|
|
+ .sources = &clkset_armclk,
|
|
|
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
|
|
|
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_hclk_msys = {
|
|
|
+ .clk = {
|
|
|
+ .name = "hclk_msys",
|
|
|
+ .parent = &clk_armclk.clk,
|
|
|
+ },
|
|
|
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_pclk_msys = {
|
|
|
+ .clk = {
|
|
|
+ .name = "pclk_msys",
|
|
|
+ .parent = &clk_hclk_msys.clk,
|
|
|
+ },
|
|
|
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_sclk_a2m = {
|
|
|
+ .clk = {
|
|
|
+ .name = "sclk_a2m",
|
|
|
+ .parent = &clk_mout_apll.clk,
|
|
|
+ },
|
|
|
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk *clkset_hclk_sys_list[] = {
|
|
|
+ [0] = &clk_mout_mpll.clk,
|
|
|
+ [1] = &clk_sclk_a2m.clk,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_sources clkset_hclk_sys = {
|
|
|
+ .sources = clkset_hclk_sys_list,
|
|
|
+ .nr_sources = ARRAY_SIZE(clkset_hclk_sys_list),
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_hclk_dsys = {
|
|
|
+ .clk = {
|
|
|
+ .name = "hclk_dsys",
|
|
|
+ },
|
|
|
+ .sources = &clkset_hclk_sys,
|
|
|
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
|
|
|
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_pclk_dsys = {
|
|
|
+ .clk = {
|
|
|
+ .name = "pclk_dsys",
|
|
|
+ .parent = &clk_hclk_dsys.clk,
|
|
|
+ },
|
|
|
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_hclk_psys = {
|
|
|
+ .clk = {
|
|
|
+ .name = "hclk_psys",
|
|
|
+ },
|
|
|
+ .sources = &clkset_hclk_sys,
|
|
|
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
|
|
|
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clksrc_clk clk_pclk_psys = {
|
|
|
+ .clk = {
|
|
|
+ .name = "pclk_psys",
|
|
|
+ .parent = &clk_hclk_psys.clk,
|
|
|
+ },
|
|
|
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
|
|
|
+};
|
|
|
+
|
|
|
+static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
|
|
|
+{
|
|
|
+ return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
|
|
|
+}
|
|
|
+
|
|
|
+static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
|
|
|
+{
|
|
|
+ return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
|
|
|
+}
|
|
|
+
|
|
|
+static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
|
|
|
+{
|
|
|
+ return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
|
|
|
+}
|
|
|
+
|
|
|
+static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
|