blob: 475b483b6b68878ab2a8b2b681437e30ab87c986 [file] [log] [blame]
Matt Wagantall33d01f52012-02-23 23:27:44 -08001/*
2 * Copyright (C) 2007 Google, Inc.
Saravana Kannanc85ecf92013-01-21 17:58:35 -08003 * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
Matt Wagantall33d01f52012-02-23 23:27:44 -08004 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef __MACH_CLK_PROVIDER_H
17#define __MACH_CLK_PROVIDER_H
18
19#include <linux/types.h>
20#include <linux/list.h>
21#include <linux/clkdev.h>
22#include <linux/spinlock.h>
Stephen Boyda1f610a2012-09-22 00:40:37 -070023#include <linux/mutex.h>
Matt Wagantall33d01f52012-02-23 23:27:44 -080024#include <mach/clk.h>
25
26/*
27 * Bit manipulation macros
28 */
29#define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb)
30#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb))
31
32/*
33 * Halt/Status Checking Mode Macros
34 */
35#define HALT 0 /* Bit pol: 1 = halted */
36#define NOCHECK 1 /* No bit to check, do nothing */
37#define HALT_VOTED 2 /* Bit pol: 1 = halted; delay on disable */
38#define ENABLE 3 /* Bit pol: 1 = running */
39#define ENABLE_VOTED 4 /* Bit pol: 1 = running; delay on disable */
40#define DELAY 5 /* No bit to check, just delay */
41
Matt Wagantall33d01f52012-02-23 23:27:44 -080042/**
43 * struct clk_vdd_class - Voltage scaling class
44 * @class_name: name of the class
45 * @set_vdd: function to call when applying a new voltage setting
46 * @level_votes: array of votes for each level
47 * @cur_level: the currently set voltage level
48 * @lock: lock to protect this struct
49 */
50struct clk_vdd_class {
51 const char *class_name;
52 int (*set_vdd)(struct clk_vdd_class *v_class, int level);
Saravana Kannan55e959d2012-10-15 22:16:04 -070053 int *level_votes;
54 int num_levels;
Matt Wagantall33d01f52012-02-23 23:27:44 -080055 unsigned long cur_level;
Stephen Boyda1f610a2012-09-22 00:40:37 -070056 struct mutex lock;
Matt Wagantall33d01f52012-02-23 23:27:44 -080057};
58
Saravana Kannan55e959d2012-10-15 22:16:04 -070059#define DEFINE_VDD_CLASS(_name, _set_vdd, _num_levels) \
Matt Wagantall33d01f52012-02-23 23:27:44 -080060 struct clk_vdd_class _name = { \
61 .class_name = #_name, \
62 .set_vdd = _set_vdd, \
Saravana Kannan55e959d2012-10-15 22:16:04 -070063 .level_votes = (int [_num_levels]) {}, \
64 .num_levels = _num_levels, \
65 .cur_level = _num_levels, \
Stephen Boyda1f610a2012-09-22 00:40:37 -070066 .lock = __MUTEX_INITIALIZER(_name.lock) \
Matt Wagantall33d01f52012-02-23 23:27:44 -080067 }
68
69enum handoff {
70 HANDOFF_ENABLED_CLK,
71 HANDOFF_DISABLED_CLK,
Matt Wagantall33d01f52012-02-23 23:27:44 -080072};
73
74struct clk_ops {
75 int (*prepare)(struct clk *clk);
76 int (*enable)(struct clk *clk);
77 void (*disable)(struct clk *clk);
78 void (*unprepare)(struct clk *clk);
79 void (*enable_hwcg)(struct clk *clk);
80 void (*disable_hwcg)(struct clk *clk);
81 int (*in_hwcg_mode)(struct clk *clk);
82 enum handoff (*handoff)(struct clk *clk);
83 int (*reset)(struct clk *clk, enum clk_reset_action action);
84 int (*set_rate)(struct clk *clk, unsigned long rate);
85 int (*set_max_rate)(struct clk *clk, unsigned long rate);
86 int (*set_flags)(struct clk *clk, unsigned flags);
87 unsigned long (*get_rate)(struct clk *clk);
88 int (*list_rate)(struct clk *clk, unsigned n);
89 int (*is_enabled)(struct clk *clk);
90 long (*round_rate)(struct clk *clk, unsigned long rate);
91 int (*set_parent)(struct clk *clk, struct clk *parent);
92 struct clk *(*get_parent)(struct clk *clk);
93 bool (*is_local)(struct clk *clk);
94};
95
96/**
97 * struct clk
98 * @prepare_count: prepare refcount
99 * @prepare_lock: protects clk_prepare()/clk_unprepare() path and @prepare_count
100 * @count: enable refcount
101 * @lock: protects clk_enable()/clk_disable() path and @count
102 * @depends: non-direct parent of clock to enable when this clock is enabled
103 * @vdd_class: voltage scaling requirement class
104 * @fmax: maximum frequency in Hz supported at each voltage level
Saravana Kannan7a6532e2012-10-18 20:51:13 -0700105 * @parent: the current source of this clock
Matt Wagantall33d01f52012-02-23 23:27:44 -0800106 */
107struct clk {
108 uint32_t flags;
109 struct clk_ops *ops;
110 const char *dbg_name;
111 struct clk *depends;
112 struct clk_vdd_class *vdd_class;
Saravana Kannan55e959d2012-10-15 22:16:04 -0700113 unsigned long *fmax;
114 int num_fmax;
Matt Wagantall33d01f52012-02-23 23:27:44 -0800115 unsigned long rate;
Saravana Kannan7a6532e2012-10-18 20:51:13 -0700116 struct clk *parent;
Matt Wagantall33d01f52012-02-23 23:27:44 -0800117
118 struct list_head children;
119 struct list_head siblings;
120
121 unsigned count;
122 spinlock_t lock;
123 unsigned prepare_count;
124 struct mutex prepare_lock;
125};
126
127#define CLK_INIT(name) \
128 .lock = __SPIN_LOCK_UNLOCKED((name).lock), \
129 .prepare_lock = __MUTEX_INITIALIZER((name).prepare_lock), \
130 .children = LIST_HEAD_INIT((name).children), \
131 .siblings = LIST_HEAD_INIT((name).siblings)
132
133int vote_vdd_level(struct clk_vdd_class *vdd_class, int level);
134int unvote_vdd_level(struct clk_vdd_class *vdd_class, int level);
135
136/* Register clocks with the MSM clock driver */
137int msm_clock_register(struct clk_lookup *table, size_t size);
138
139extern struct clk dummy_clk;
140
141#define CLK_DUMMY(clk_name, clk_id, clk_dev, flags) { \
142 .con_id = clk_name, \
143 .dev_id = clk_dev, \
144 .clk = &dummy_clk, \
145 }
146
147#define CLK_LOOKUP(con, c, dev) { .con_id = con, .clk = &c, .dev_id = dev }
148
149#endif