|
@@ -0,0 +1,182 @@
|
|
|
+/*
|
|
|
+ * linux/arch/arm/mach-omap2/clock.h
|
|
|
+ *
|
|
|
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
|
|
|
+ * Copyright (C) 2004-2011 Nokia Corporation
|
|
|
+ *
|
|
|
+ * Contacts:
|
|
|
+ * Richard Woodruff <r-woodruff2@ti.com>
|
|
|
+ * Paul Walmsley
|
|
|
+ *
|
|
|
+ * 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 __ARCH_ARM_MACH_OMAP2_CLOCK_H
|
|
|
+#define __ARCH_ARM_MACH_OMAP2_CLOCK_H
|
|
|
+
|
|
|
+#include <linux/kernel.h>
|
|
|
+#include <linux/list.h>
|
|
|
+
|
|
|
+#include <linux/clkdev.h>
|
|
|
+#include <linux/clk-provider.h>
|
|
|
+
|
|
|
+struct omap_clk {
|
|
|
+ u16 cpu;
|
|
|
+ struct clk_lookup lk;
|
|
|
+};
|
|
|
+
|
|
|
+#define CLK(dev, con, ck, cp) \
|
|
|
+ { \
|
|
|
+ .cpu = cp, \
|
|
|
+ .lk = { \
|
|
|
+ .dev_id = dev, \
|
|
|
+ .con_id = con, \
|
|
|
+ .clk = ck, \
|
|
|
+ }, \
|
|
|
+ }
|
|
|
+
|
|
|
+/* Platform flags for the clkdev-OMAP integration code */
|
|
|
+#define CK_242X (1 << 0)
|
|
|
+#define CK_243X (1 << 1) /* 243x, 253x */
|
|
|
+#define CK_3430ES1 (1 << 2) /* 34xxES1 only */
|
|
|
+#define CK_3430ES2PLUS (1 << 3) /* 34xxES2, ES3, non-Sitara 35xx only */
|
|
|
+#define CK_AM35XX (1 << 4) /* Sitara AM35xx */
|
|
|
+#define CK_36XX (1 << 5) /* 36xx/37xx-specific clocks */
|
|
|
+#define CK_443X (1 << 6)
|
|
|
+#define CK_TI816X (1 << 7)
|
|
|
+#define CK_446X (1 << 8)
|
|
|
+#define CK_AM33XX (1 << 9) /* AM33xx specific clocks */
|
|
|
+
|
|
|
+
|
|
|
+#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS)
|
|
|
+#define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX)
|
|
|
+
|
|
|
+struct clockdomain;
|
|
|
+#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
|
|
|
+
|
|
|
+#define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \
|
|
|
+ static struct clk _name = { \
|
|
|
+ .name = #_name, \
|
|
|
+ .hw = &_name##_hw.hw, \
|
|
|
+ .parent_names = _parent_array_name, \
|
|
|
+ .num_parents = ARRAY_SIZE(_parent_array_name), \
|
|
|
+ .ops = &_clkops_name, \
|
|
|
+ };
|
|
|
+
|
|
|
+#define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \
|
|
|
+ static struct clk_hw_omap _name##_hw = { \
|
|
|
+ .hw = { \
|
|
|
+ .clk = &_name, \
|
|
|
+ }, \
|
|
|
+ .clkdm_name = _clkdm_name, \
|
|
|
+ };
|
|
|
+
|
|
|
+#define DEFINE_CLK_OMAP_MUX(_name, _clkdm_name, _clksel, \
|
|
|
+ _clksel_reg, _clksel_mask, \
|
|
|
+ _parent_names, _ops) \
|
|
|
+ static struct clk _name; \
|
|
|
+ static struct clk_hw_omap _name##_hw = { \
|
|
|
+ .hw = { \
|
|
|
+ .clk = &_name, \
|
|
|
+ }, \
|
|
|
+ .clksel = _clksel, \
|
|
|
+ .clksel_reg = _clksel_reg, \
|
|
|
+ .clksel_mask = _clksel_mask, \
|
|
|
+ .clkdm_name = _clkdm_name, \
|
|
|
+ }; \
|
|
|
+ DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
|
|
|
+
|
|
|
+#define DEFINE_CLK_OMAP_MUX_GATE(_name, _clkdm_name, _clksel, \
|
|
|
+ _clksel_reg, _clksel_mask, \
|
|
|
+ _enable_reg, _enable_bit, \
|
|
|
+ _hwops, _parent_names, _ops) \
|
|
|
+ static struct clk _name; \
|
|
|
+ static struct clk_hw_omap _name##_hw = { \
|
|
|
+ .hw = { \
|
|
|
+ .clk = &_name, \
|
|
|
+ }, \
|
|
|
+ .ops = _hwops, \
|
|
|
+ .enable_reg = _enable_reg, \
|
|
|
+ .enable_bit = _enable_bit, \
|
|
|
+ .clksel = _clksel, \
|
|
|
+ .clksel_reg = _clksel_reg, \
|
|
|
+ .clksel_mask = _clksel_mask, \
|
|
|
+ .clkdm_name = _clkdm_name, \
|
|
|
+ }; \
|
|
|
+ DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
|
|
|
+
|
|
|
+#define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name, \
|
|
|
+ _parent_ptr, _flags, \
|
|
|
+ _clksel_reg, _clksel_mask) \
|
|
|
+ static const struct clksel _name##_div[] = { \
|
|
|
+ { \
|
|
|
+ .parent = _parent_ptr, \
|
|
|
+ .rates = div31_1to31_rates \
|
|
|
+ }, \
|
|
|
+ { .parent = NULL }, \
|
|
|
+ }; \
|
|
|
+ static struct clk _name; \
|
|
|
+ static const char *_name##_parent_names[] = { \
|
|
|
+ _parent_name, \
|
|
|
+ }; \
|
|
|
+ static struct clk_hw_omap _name##_hw = { \
|
|
|
+ .hw = { \
|
|
|
+ .clk = &_name, \
|
|
|
+ }, \
|
|
|
+ .clksel = _name##_div, \
|
|
|
+ .clksel_reg = _clksel_reg, \
|
|
|
+ .clksel_mask = _clksel_mask, \
|
|
|
+ .ops = &clkhwops_omap4_dpllmx, \
|
|
|
+ }; \
|
|
|
+ DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops);
|
|
|
+
|
|
|
+/* struct clksel_rate.flags possibilities */
|
|
|
+#define RATE_IN_242X (1 << 0)
|
|
|
+#define RATE_IN_243X (1 << 1)
|
|
|
+#define RATE_IN_3430ES1 (1 << 2) /* 3430ES1 rates only */
|
|
|
+#define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */
|
|
|
+#define RATE_IN_36XX (1 << 4)
|
|
|
+#define RATE_IN_4430 (1 << 5)
|
|
|
+#define RATE_IN_TI816X (1 << 6)
|
|
|
+#define RATE_IN_4460 (1 << 7)
|
|
|
+#define RATE_IN_AM33XX (1 << 8)
|
|
|
+#define RATE_IN_TI814X (1 << 9)
|
|
|
+
|
|
|
+#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
|
|
|
+#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
|
|
|
+#define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX)
|
|
|
+#define RATE_IN_44XX (RATE_IN_4430 | RATE_IN_4460)
|
|
|
+
|
|
|
+/* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */
|
|
|
+#define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX)
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * struct clksel_rate - register bitfield values corresponding to clk divisors
|
|
|
+ * @val: register bitfield value (shifted to bit 0)
|
|
|
+ * @div: clock divisor corresponding to @val
|
|
|
+ * @flags: (see "struct clksel_rate.flags possibilities" above)
|
|
|
+ *
|
|
|
+ * @val should match the value of a read from struct clk.clksel_reg
|
|
|
+ * AND'ed with struct clk.clksel_mask, shifted right to bit 0.
|
|
|
+ *
|
|
|
+ * @div is the divisor that should be applied to the parent clock's rate
|
|
|
+ * to produce the current clock's rate.
|
|
|
+ */
|
|
|
+struct clksel_rate {
|
|
|
+ u32 val;
|
|
|
+ u8 div;
|
|
|
+ u16 flags;
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * struct clksel - available parent clocks, and a pointer to their divisors
|
|
|
+ * @parent: struct clk * to a possible parent clock
|
|
|
+ * @rates: available divisors for this parent clock
|
|
|
+ *
|
|
|
+ * A struct clksel is always associated with one or more struct clks
|
|
|
+ * and one or more struct clksel_rates.
|
|
|
+ */
|
|
|
+struct clksel {
|