|
@@ -0,0 +1,163 @@
|
|
|
+/*
|
|
|
+ * OMAP3 clock data
|
|
|
+ *
|
|
|
+ * Copyright (C) 2007-2012 Texas Instruments, Inc.
|
|
|
+ * Copyright (C) 2007-2011 Nokia Corporation
|
|
|
+ *
|
|
|
+ * Written by Paul Walmsley
|
|
|
+ * Updated to COMMON clk data format by Rajendra Nayak <rnayak@ti.com>
|
|
|
+ * With many device clock fixes by Kevin Hilman and Jouni Högander
|
|
|
+ * DPLL bypass clock support added by Roman Tereshonkov
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * Virtual clocks are introduced as convenient tools.
|
|
|
+ * They are sources for other clocks and not supposed
|
|
|
+ * to be requested from drivers directly.
|
|
|
+ */
|
|
|
+
|
|
|
+#include <linux/kernel.h>
|
|
|
+#include <linux/clk.h>
|
|
|
+#include <linux/clk-private.h>
|
|
|
+#include <linux/list.h>
|
|
|
+#include <linux/io.h>
|
|
|
+
|
|
|
+#include "soc.h"
|
|
|
+#include "iomap.h"
|
|
|
+#include "clock.h"
|
|
|
+#include "clock3xxx.h"
|
|
|
+#include "clock34xx.h"
|
|
|
+#include "clock36xx.h"
|
|
|
+#include "clock3517.h"
|
|
|
+#include "cm3xxx.h"
|
|
|
+#include "cm-regbits-34xx.h"
|
|
|
+#include "prm3xxx.h"
|
|
|
+#include "prm-regbits-34xx.h"
|
|
|
+#include "control.h"
|
|
|
+
|
|
|
+/*
|
|
|
+ * clocks
|
|
|
+ */
|
|
|
+
|
|
|
+#define OMAP_CM_REGADDR OMAP34XX_CM_REGADDR
|
|
|
+
|
|
|
+/* Maximum DPLL multiplier, divider values for OMAP3 */
|
|
|
+#define OMAP3_MAX_DPLL_MULT 2047
|
|
|
+#define OMAP3630_MAX_JTYPE_DPLL_MULT 4095
|
|
|
+#define OMAP3_MAX_DPLL_DIV 128
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(dummy_apb_pclk, CLK_IS_ROOT, 0x0, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(mcbsp_clks, CLK_IS_ROOT, 0x0, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(omap_32k_fck, CLK_IS_ROOT, 32768, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(pclk_ck, CLK_IS_ROOT, 27000000, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(rmii_ck, CLK_IS_ROOT, 50000000, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(secure_32k_fck, CLK_IS_ROOT, 32768, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(sys_altclk, CLK_IS_ROOT, 0x0, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(virt_12m_ck, CLK_IS_ROOT, 12000000, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(virt_13m_ck, CLK_IS_ROOT, 13000000, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(virt_16_8m_ck, CLK_IS_ROOT, 16800000, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0);
|
|
|
+
|
|
|
+DEFINE_CLK_FIXED_RATE(virt_38_4m_ck, CLK_IS_ROOT, 38400000, 0x0);
|
|
|
+
|
|
|
+static const char *osc_sys_ck_parent_names[] = {
|
|
|
+ "virt_12m_ck", "virt_13m_ck", "virt_19200000_ck", "virt_26000000_ck",
|
|
|
+ "virt_38_4m_ck", "virt_16_8m_ck",
|
|
|
+};
|
|
|
+
|
|
|
+DEFINE_CLK_MUX(osc_sys_ck, osc_sys_ck_parent_names, NULL, 0x0,
|
|
|
+ OMAP3430_PRM_CLKSEL, OMAP3430_SYS_CLKIN_SEL_SHIFT,
|
|
|
+ OMAP3430_SYS_CLKIN_SEL_WIDTH, 0x0, NULL);
|
|
|
+
|
|
|
+DEFINE_CLK_DIVIDER(sys_ck, "osc_sys_ck", &osc_sys_ck, 0x0,
|
|
|
+ OMAP3430_PRM_CLKSRC_CTRL, OMAP_SYSCLKDIV_SHIFT,
|
|
|
+ OMAP_SYSCLKDIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
|
|
|
+
|
|
|
+static struct dpll_data dpll3_dd = {
|
|
|
+ .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
|
|
|
+ .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK,
|
|
|
+ .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK,
|
|
|
+ .clk_bypass = &sys_ck,
|
|
|
+ .clk_ref = &sys_ck,
|
|
|
+ .freqsel_mask = OMAP3430_CORE_DPLL_FREQSEL_MASK,
|
|
|
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
|
|
|
+ .enable_mask = OMAP3430_EN_CORE_DPLL_MASK,
|
|
|
+ .auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
|
|
|
+ .recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
|
|
|
+ .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT,
|
|
|
+ .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
|
|
|
+ .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK,
|
|
|
+ .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
|
|
|
+ .idlest_mask = OMAP3430_ST_CORE_CLK_MASK,
|
|
|
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
|
|
|
+ .min_divider = 1,
|
|
|
+ .max_divider = OMAP3_MAX_DPLL_DIV,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk dpll3_ck;
|
|
|
+
|
|
|
+static const char *dpll3_ck_parent_names[] = {
|
|
|
+ "sys_ck",
|
|
|
+};
|
|
|
+
|
|
|
+static const struct clk_ops dpll3_ck_ops = {
|
|
|
+ .init = &omap2_init_clk_clkdm,
|
|
|
+ .get_parent = &omap2_init_dpll_parent,
|
|
|
+ .recalc_rate = &omap3_dpll_recalc,
|
|
|
+ .round_rate = &omap2_dpll_round_rate,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk_hw_omap dpll3_ck_hw = {
|
|
|
+ .hw = {
|
|
|
+ .clk = &dpll3_ck,
|
|
|
+ },
|
|
|
+ .ops = &clkhwops_omap3_dpll,
|
|
|
+ .dpll_data = &dpll3_dd,
|
|
|
+ .clkdm_name = "dpll3_clkdm",
|
|
|
+};
|
|
|
+
|
|
|
+DEFINE_STRUCT_CLK(dpll3_ck, dpll3_ck_parent_names, dpll3_ck_ops);
|
|
|
+
|
|
|
+DEFINE_CLK_DIVIDER(dpll3_m2_ck, "dpll3_ck", &dpll3_ck, 0x0,
|
|
|
+ OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
|
|
|
+ OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT,
|
|
|
+ OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH,
|
|
|
+ CLK_DIVIDER_ONE_BASED, NULL);
|
|
|
+
|
|
|
+static struct clk core_ck;
|
|
|
+
|
|
|
+static const char *core_ck_parent_names[] = {
|
|
|
+ "dpll3_m2_ck",
|
|
|
+};
|
|
|
+
|
|
|
+static const struct clk_ops core_ck_ops = {};
|
|
|
+
|
|
|
+DEFINE_STRUCT_CLK_HW_OMAP(core_ck, NULL);
|
|
|
+DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops);
|
|
|
+
|
|
|
+DEFINE_CLK_DIVIDER(l3_ick, "core_ck", &core_ck, 0x0,
|
|
|
+ OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
|
|
|
+ OMAP3430_CLKSEL_L3_SHIFT, OMAP3430_CLKSEL_L3_WIDTH,
|
|
|
+ CLK_DIVIDER_ONE_BASED, NULL);
|
|
|
+
|
|
|
+DEFINE_CLK_DIVIDER(l4_ick, "l3_ick", &l3_ick, 0x0,
|
|
|
+ OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
|
|
|
+ OMAP3430_CLKSEL_L4_SHIFT, OMAP3430_CLKSEL_L4_WIDTH,
|
|
|
+ CLK_DIVIDER_ONE_BASED, NULL);
|
|
|
+
|
|
|
+static struct clk security_l4_ick2;
|
|
|
+
|
|
|
+static const char *security_l4_ick2_parent_names[] = {
|