blob: 155ddd922c17f1b30a4f52aa3d3a51a2334360cb [file] [log] [blame]
Tony Lindgren3179a012005-11-10 14:26:48 +00001/*
2 * linux/arch/arm/mach-omap1/clock.h
3 *
Paul Walmsley52650502009-12-08 16:29:38 -07004 * Copyright (C) 2004 - 2005, 2009 Nokia corporation
Tony Lindgren3179a012005-11-10 14:26:48 +00005 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
14#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
15
Paul Walmsley52650502009-12-08 16:29:38 -070016#include <linux/clk.h>
Paul Walmsleya135eaa2012-09-27 10:33:34 -060017#include <linux/list.h>
Tony Lindgren3179a012005-11-10 14:26:48 +000018
Paul Walmsleya135eaa2012-09-27 10:33:34 -060019struct module;
20struct clk;
21
22/* Temporary, needed during the common clock framework conversion */
23#define __clk_get_name(clk) (clk->name)
24#define __clk_get_parent(clk) (clk->parent)
25#define __clk_get_rate(clk) (clk->rate)
26
27/**
28 * struct clkops - some clock function pointers
29 * @enable: fn ptr that enables the current clock in hardware
30 * @disable: fn ptr that enables the current clock in hardware
31 * @find_idlest: function returning the IDLEST register for the clock's IP blk
32 * @find_companion: function returning the "companion" clk reg for the clock
33 * @allow_idle: fn ptr that enables autoidle for the current clock in hardware
34 * @deny_idle: fn ptr that disables autoidle for the current clock in hardware
35 *
36 * A "companion" clk is an accompanying clock to the one being queried
37 * that must be enabled for the IP module connected to the clock to
38 * become accessible by the hardware. Neither @find_idlest nor
39 * @find_companion should be needed; that information is IP
40 * block-specific; the hwmod code has been created to handle this, but
41 * until hwmod data is ready and drivers have been converted to use PM
42 * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
43 * @find_companion must, unfortunately, remain.
44 */
45struct clkops {
46 int (*enable)(struct clk *);
47 void (*disable)(struct clk *);
48 void (*find_idlest)(struct clk *, void __iomem **,
49 u8 *, u8 *);
50 void (*find_companion)(struct clk *, void __iomem **,
51 u8 *);
52 void (*allow_idle)(struct clk *);
53 void (*deny_idle)(struct clk *);
54};
55
56/*
57 * struct clk.flags possibilities
58 *
59 * XXX document the rest of the clock flags here
60 *
61 * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL
62 * bits share the same register. This flag allows the
63 * omap4_dpllmx*() code to determine which GATE_CTRL bit field
64 * should be used. This is a temporary solution - a better approach
65 * would be to associate clock type-specific data with the clock,
66 * similar to the struct dpll_data approach.
67 */
68#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
69#define CLOCK_IDLE_CONTROL (1 << 1)
70#define CLOCK_NO_IDLE_PARENT (1 << 2)
71#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
72#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
73#define CLOCK_CLKOUTX2 (1 << 5)
74
75/**
76 * struct clk - OMAP struct clk
77 * @node: list_head connecting this clock into the full clock list
78 * @ops: struct clkops * for this clock
79 * @name: the name of the clock in the hardware (used in hwmod data and debug)
80 * @parent: pointer to this clock's parent struct clk
81 * @children: list_head connecting to the child clks' @sibling list_heads
82 * @sibling: list_head connecting this clk to its parent clk's @children
83 * @rate: current clock rate
84 * @enable_reg: register to write to enable the clock (see @enable_bit)
85 * @recalc: fn ptr that returns the clock's current rate
86 * @set_rate: fn ptr that can change the clock's current rate
87 * @round_rate: fn ptr that can round the clock's current rate
88 * @init: fn ptr to do clock-specific initialization
89 * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
90 * @usecount: number of users that have requested this clock to be enabled
91 * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
92 * @flags: see "struct clk.flags possibilities" above
93 * @rate_offset: bitshift for rate selection bitfield (OMAP1 only)
94 * @src_offset: bitshift for source selection bitfield (OMAP1 only)
95 *
96 * XXX @rate_offset, @src_offset should probably be removed and OMAP1
97 * clock code converted to use clksel.
98 *
99 * XXX @usecount is poorly named. It should be "enable_count" or
100 * something similar. "users" in the description refers to kernel
101 * code (core code or drivers) that have called clk_enable() and not
102 * yet called clk_disable(); the usecount of parent clocks is also
103 * incremented by the clock code when clk_enable() is called on child
104 * clocks and decremented by the clock code when clk_disable() is
105 * called on child clocks.
106 *
107 * XXX @clkdm, @usecount, @children, @sibling should be marked for
108 * internal use only.
109 *
110 * @children and @sibling are used to optimize parent-to-child clock
111 * tree traversals. (child-to-parent traversals use @parent.)
112 *
113 * XXX The notion of the clock's current rate probably needs to be
114 * separated from the clock's target rate.
115 */
116struct clk {
117 struct list_head node;
118 const struct clkops *ops;
119 const char *name;
120 struct clk *parent;
121 struct list_head children;
122 struct list_head sibling; /* node for children */
123 unsigned long rate;
124 void __iomem *enable_reg;
125 unsigned long (*recalc)(struct clk *);
126 int (*set_rate)(struct clk *, unsigned long);
127 long (*round_rate)(struct clk *, unsigned long);
128 void (*init)(struct clk *);
129 u8 enable_bit;
130 s8 usecount;
131 u8 fixed_div;
132 u8 flags;
133 u8 rate_offset;
134 u8 src_offset;
135#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
136 struct dentry *dent; /* For visible tree hierarchy */
137#endif
138};
139
140struct clk_functions {
141 int (*clk_enable)(struct clk *clk);
142 void (*clk_disable)(struct clk *clk);
143 long (*clk_round_rate)(struct clk *clk, unsigned long rate);
144 int (*clk_set_rate)(struct clk *clk, unsigned long rate);
145 int (*clk_set_parent)(struct clk *clk, struct clk *parent);
146 void (*clk_allow_idle)(struct clk *clk);
147 void (*clk_deny_idle)(struct clk *clk);
148 void (*clk_disable_unused)(struct clk *clk);
149};
150
151extern int mpurate;
152
153extern int clk_init(struct clk_functions *custom_clocks);
154extern void clk_preinit(struct clk *clk);
155extern int clk_register(struct clk *clk);
156extern void clk_reparent(struct clk *child, struct clk *parent);
157extern void clk_unregister(struct clk *clk);
158extern void propagate_rate(struct clk *clk);
159extern void recalculate_root_clocks(void);
160extern unsigned long followparent_recalc(struct clk *clk);
161extern void clk_enable_init_clocks(void);
162unsigned long omap_fixed_divisor_recalc(struct clk *clk);
163extern struct clk *omap_clk_get_by_name(const char *name);
164extern int omap_clk_enable_autoidle_all(void);
165extern int omap_clk_disable_autoidle_all(void);
166
167extern const struct clkops clkops_null;
168
169extern struct clk dummy_ck;
Russell Kingd5e60722009-02-08 16:07:46 +0000170
Tony Lindgrene9b70862011-11-11 10:15:11 -0800171int omap1_clk_init(void);
172void omap1_clk_late_init(void);
Paul Walmsley52650502009-12-08 16:29:38 -0700173extern int omap1_clk_enable(struct clk *clk);
174extern void omap1_clk_disable(struct clk *clk);
175extern long omap1_clk_round_rate(struct clk *clk, unsigned long rate);
176extern int omap1_clk_set_rate(struct clk *clk, unsigned long rate);
177extern unsigned long omap1_ckctl_recalc(struct clk *clk);
178extern int omap1_set_sossi_rate(struct clk *clk, unsigned long rate);
179extern unsigned long omap1_sossi_recalc(struct clk *clk);
180extern unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk);
181extern int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate);
182extern int omap1_set_uart_rate(struct clk *clk, unsigned long rate);
183extern unsigned long omap1_uart_recalc(struct clk *clk);
184extern int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate);
185extern long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate);
186extern void omap1_init_ext_clk(struct clk *clk);
187extern int omap1_select_table_rate(struct clk *clk, unsigned long rate);
188extern long omap1_round_to_table_rate(struct clk *clk, unsigned long rate);
189extern int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
190extern long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
191extern unsigned long omap1_watchdog_recalc(struct clk *clk);
192
193#ifdef CONFIG_OMAP_RESET_CLOCKS
Felipe Balbi5838bb62010-05-20 12:31:04 -0600194extern void omap1_clk_disable_unused(struct clk *clk);
Paul Walmsley52650502009-12-08 16:29:38 -0700195#else
196#define omap1_clk_disable_unused NULL
197#endif
Tony Lindgren3179a012005-11-10 14:26:48 +0000198
199struct uart_clk {
200 struct clk clk;
201 unsigned long sysc_addr;
202};
203
204/* Provide a method for preventing idling some ARM IDLECT clocks */
205struct arm_idlect1_clk {
206 struct clk clk;
207 unsigned long no_idle_count;
208 __u8 idlect_shift;
209};
210
211/* ARM_CKCTL bit shifts */
212#define CKCTL_PERDIV_OFFSET 0
213#define CKCTL_LCDDIV_OFFSET 2
214#define CKCTL_ARMDIV_OFFSET 4
215#define CKCTL_DSPDIV_OFFSET 6
216#define CKCTL_TCDIV_OFFSET 8
217#define CKCTL_DSPMMUDIV_OFFSET 10
218/*#define ARM_TIMXO 12*/
219#define EN_DSPCK 13
220/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
221/* DSP_CKCTL bit shifts */
222#define CKCTL_DSPPERDIV_OFFSET 0
223
224/* ARM_IDLECT2 bit shifts */
225#define EN_WDTCK 0
226#define EN_XORPCK 1
227#define EN_PERCK 2
228#define EN_LCDCK 3
229#define EN_LBCK 4 /* Not on 1610/1710 */
230/*#define EN_HSABCK 5*/
231#define EN_APICK 6
232#define EN_TIMCK 7
233#define DMACK_REQ 8
234#define EN_GPIOCK 9 /* Not on 1610/1710 */
235/*#define EN_LBFREECK 10*/
236#define EN_CKOUT_ARM 11
237
238/* ARM_IDLECT3 bit shifts */
239#define EN_OCPI_CK 0
240#define EN_TC1_CK 2
241#define EN_TC2_CK 4
242
243/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
244#define EN_DSPTIMCK 5
245
246/* Various register defines for clock controls scattered around OMAP chip */
Tony Lindgren90afd5c2006-09-25 13:27:20 +0300247#define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */
Tony Lindgren3179a012005-11-10 14:26:48 +0000248#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
249#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
250#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
251#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
252#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
253#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
254#define SOFT_REQ_REG 0xfffe0834
255#define SOFT_REQ_REG2 0xfffe0880
256
Paul Walmsley52650502009-12-08 16:29:38 -0700257extern __u32 arm_idlect1_mask;
258extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
Tony Lindgren3179a012005-11-10 14:26:48 +0000259
Paul Walmsley52650502009-12-08 16:29:38 -0700260extern const struct clkops clkops_dspck;
261extern const struct clkops clkops_dummy;
Paul Walmsleyfb2fc922010-07-26 16:34:28 -0600262extern const struct clkops clkops_uart_16xx;
Paul Walmsley52650502009-12-08 16:29:38 -0700263extern const struct clkops clkops_generic;
Tony Lindgren90afd5c2006-09-25 13:27:20 +0300264
Janusz Krzysztofik24ce2702011-12-08 18:01:41 -0800265/* used for passing SoC type to omap1_{select,round_to}_table_rate() */
266extern u32 cpu_mask;
267
Tony Lindgren3179a012005-11-10 14:26:48 +0000268#endif