blob: a9894372d7ae1e5f549dba420e755e4a4926aca9 [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#ifndef __ARCH_ARM_MACH_MSM_CLOCK_RPM_H
15#define __ARCH_ARM_MACH_MSM_CLOCK_RPM_H
16
17#include <mach/rpm.h>
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070018#include <mach/rpm-smd.h>
Matt Wagantalld55b90f2012-02-23 23:27:44 -080019#include <mach/clk-provider.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070020
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -070021#define RPM_SMD_KEY_RATE 0x007A484B
22#define RPM_SMD_KEY_ENABLE 0x62616E45
Vikram Mulukutla0f63e002012-06-28 14:29:44 -070023#define RPM_SMD_KEY_STATE 0x54415453
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -070024
Vikram Mulukutla80b7ab52012-07-26 19:03:15 -070025#define RPM_CLK_BUFFER_A_REQ 0x616B6C63
26#define RPM_KEY_SOFTWARE_ENABLE 0x6E657773
27#define RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY 0x62636370
28
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029struct clk_ops;
Vikram Mulukutla0f44f922012-05-16 21:52:26 -070030struct clk_rpmrs_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070031extern struct clk_ops clk_ops_rpm;
Stephen Boyda6835112012-01-26 14:40:05 -080032extern struct clk_ops clk_ops_rpm_branch;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070033
34struct rpm_clk {
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070035 const int rpm_res_type;
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -070036 const int rpm_key;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070037 const int rpm_clk_id;
38 const int rpm_status_id;
39 const bool active_only;
40 unsigned last_set_khz;
41 /* 0 if active_only. Otherwise, same as last_set_khz. */
42 unsigned last_set_sleep_khz;
43 bool enabled;
Stephen Boyda6835112012-01-26 14:40:05 -080044 bool branch; /* true: RPM only accepts 1 for ON and 0 for OFF */
Stephen Boydc7fc3b12012-05-17 14:42:46 -070045 unsigned factor;
Vikram Mulukutla0f44f922012-05-16 21:52:26 -070046 struct clk_rpmrs_data *rpmrs_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070047
48 struct rpm_clk *peer;
49 struct clk c;
50};
51
52static inline struct rpm_clk *to_rpm_clk(struct clk *clk)
53{
54 return container_of(clk, struct rpm_clk, c);
55}
56
Vikram Mulukutla0f44f922012-05-16 21:52:26 -070057extern struct clk_rpmrs_data clk_rpmrs_data;
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070058extern struct clk_rpmrs_data clk_rpmrs_data_smd;
Vikram Mulukutla0f44f922012-05-16 21:52:26 -070059
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -070060#define __DEFINE_CLK_RPM(name, active, type, r_id, stat_id, dep, key, \
61 rpmrsdata) \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062 static struct rpm_clk active; \
63 static struct rpm_clk name = { \
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070064 .rpm_res_type = (type), \
65 .rpm_clk_id = (r_id), \
66 .rpm_status_id = (stat_id), \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -070067 .rpm_key = (key), \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070068 .peer = &active, \
Stephen Boydc7fc3b12012-05-17 14:42:46 -070069 .factor = 1000, \
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070070 .rpmrs_data = (rpmrsdata),\
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070071 .c = { \
72 .ops = &clk_ops_rpm, \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073 .dbg_name = #name, \
74 CLK_INIT(name.c), \
Matt Wagantall735f01a2011-08-12 12:40:28 -070075 .depends = dep, \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076 }, \
77 }; \
78 static struct rpm_clk active = { \
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070079 .rpm_res_type = (type), \
80 .rpm_clk_id = (r_id), \
81 .rpm_status_id = (stat_id), \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -070082 .rpm_key = (key), \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070083 .peer = &name, \
84 .active_only = true, \
Stephen Boydc7fc3b12012-05-17 14:42:46 -070085 .factor = 1000, \
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070086 .rpmrs_data = (rpmrsdata),\
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070087 .c = { \
88 .ops = &clk_ops_rpm, \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070089 .dbg_name = #active, \
90 CLK_INIT(active.c), \
Matt Wagantall735f01a2011-08-12 12:40:28 -070091 .depends = dep, \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070092 }, \
93 };
94
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070095#define __DEFINE_CLK_RPM_BRANCH(name, active, type, r_id, stat_id, r, \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -070096 key, rpmrsdata) \
Stephen Boyda6835112012-01-26 14:40:05 -080097 static struct rpm_clk active; \
98 static struct rpm_clk name = { \
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -070099 .rpm_res_type = (type), \
100 .rpm_clk_id = (r_id), \
101 .rpm_status_id = (stat_id), \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700102 .rpm_key = (key), \
Stephen Boyda6835112012-01-26 14:40:05 -0800103 .peer = &active, \
Stephen Boyd72a80352012-01-26 15:57:38 -0800104 .last_set_khz = ((r) / 1000), \
105 .last_set_sleep_khz = ((r) / 1000), \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700106 .factor = 1000, \
Stephen Boyda6835112012-01-26 14:40:05 -0800107 .branch = true, \
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700108 .rpmrs_data = (rpmrsdata),\
Stephen Boyda6835112012-01-26 14:40:05 -0800109 .c = { \
110 .ops = &clk_ops_rpm_branch, \
Stephen Boyda6835112012-01-26 14:40:05 -0800111 .dbg_name = #name, \
Stephen Boyd72a80352012-01-26 15:57:38 -0800112 .rate = (r), \
Stephen Boyda6835112012-01-26 14:40:05 -0800113 CLK_INIT(name.c), \
114 }, \
115 }; \
116 static struct rpm_clk active = { \
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700117 .rpm_res_type = (type), \
118 .rpm_clk_id = (r_id), \
119 .rpm_status_id = (stat_id), \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700120 .rpm_key = (key), \
Stephen Boyda6835112012-01-26 14:40:05 -0800121 .peer = &name, \
Stephen Boyd72a80352012-01-26 15:57:38 -0800122 .last_set_khz = ((r) / 1000), \
Stephen Boyda6835112012-01-26 14:40:05 -0800123 .active_only = true, \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700124 .factor = 1000, \
Stephen Boyda6835112012-01-26 14:40:05 -0800125 .branch = true, \
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700126 .rpmrs_data = (rpmrsdata),\
Stephen Boyda6835112012-01-26 14:40:05 -0800127 .c = { \
128 .ops = &clk_ops_rpm_branch, \
Stephen Boyda6835112012-01-26 14:40:05 -0800129 .dbg_name = #active, \
Stephen Boyd72a80352012-01-26 15:57:38 -0800130 .rate = (r), \
Stephen Boyda6835112012-01-26 14:40:05 -0800131 CLK_INIT(active.c), \
132 }, \
133 };
134
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700135#define __DEFINE_CLK_RPM_QDSS(name, active, type, r_id, stat_id, \
136 key, rpmrsdata) \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700137 static struct rpm_clk active; \
138 static struct rpm_clk name = { \
139 .rpm_res_type = (type), \
140 .rpm_clk_id = (r_id), \
141 .rpm_status_id = (stat_id), \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700142 .rpm_key = (key), \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700143 .peer = &active, \
144 .factor = 1, \
145 .rpmrs_data = (rpmrsdata),\
146 .c = { \
147 .ops = &clk_ops_rpm, \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700148 .dbg_name = #name, \
149 CLK_INIT(name.c), \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700150 }, \
151 }; \
152 static struct rpm_clk active = { \
153 .rpm_res_type = (type), \
154 .rpm_clk_id = (r_id), \
155 .rpm_status_id = (stat_id), \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700156 .rpm_key = (key), \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700157 .peer = &name, \
158 .active_only = true, \
159 .factor = 1, \
160 .rpmrs_data = (rpmrsdata),\
161 .c = { \
162 .ops = &clk_ops_rpm, \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700163 .dbg_name = #active, \
164 CLK_INIT(active.c), \
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700165 }, \
166 };
167
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700168#define DEFINE_CLK_RPM(name, active, r_id, dep) \
169 __DEFINE_CLK_RPM(name, active, 0, MSM_RPM_ID_##r_id##_CLK, \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700170 MSM_RPM_STATUS_ID_##r_id##_CLK, dep, 0, &clk_rpmrs_data)
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700171
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700172#define DEFINE_CLK_RPM_QDSS(name, active) \
173 __DEFINE_CLK_RPM_QDSS(name, active, 0, MSM_RPM_ID_QDSS_CLK, \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700174 MSM_RPM_STATUS_ID_QDSS_CLK, 0, &clk_rpmrs_data)
Stephen Boydc7fc3b12012-05-17 14:42:46 -0700175
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700176#define DEFINE_CLK_RPM_BRANCH(name, active, r_id, r) \
177 __DEFINE_CLK_RPM_BRANCH(name, active, 0, MSM_RPM_ID_##r_id##_CLK, \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700178 MSM_RPM_STATUS_ID_##r_id##_CLK, r, 0, &clk_rpmrs_data)
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700179
180#define DEFINE_CLK_RPM_SMD(name, active, type, r_id, dep) \
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700181 __DEFINE_CLK_RPM(name, active, type, r_id, 0, dep, \
182 RPM_SMD_KEY_RATE, &clk_rpmrs_data_smd)
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700183
Vikram Mulukutla4aba6c02012-07-10 11:12:05 -0700184#define DEFINE_CLK_RPM_SMD_BRANCH(name, active, type, r_id, r) \
185 __DEFINE_CLK_RPM_BRANCH(name, active, type, r_id, 0, r, \
186 RPM_SMD_KEY_ENABLE, &clk_rpmrs_data_smd)
Vikram Mulukutlaa085dc82012-05-18 11:21:44 -0700187
Vikram Mulukutla0f63e002012-06-28 14:29:44 -0700188#define DEFINE_CLK_RPM_SMD_QDSS(name, active, type, r_id) \
189 __DEFINE_CLK_RPM_QDSS(name, active, type, r_id, \
190 0, RPM_SMD_KEY_STATE, &clk_rpmrs_data_smd)
Vikram Mulukutla80b7ab52012-07-26 19:03:15 -0700191/*
192 * The RPM XO buffer clock management code aggregates votes for pin-control mode
193 * and software mode separately. Software-enable has higher priority over pin-
194 * control, and if the software-mode aggregation results in a 'disable', the
195 * buffer will be left in pin-control mode if a pin-control vote is in place.
196 */
197#define DEFINE_CLK_RPM_SMD_XO_BUFFER(name, active, r_id) \
198 __DEFINE_CLK_RPM_BRANCH(name, active, RPM_CLK_BUFFER_A_REQ, r_id, 0, \
199 1000, RPM_KEY_SOFTWARE_ENABLE, &clk_rpmrs_data_smd)
Vikram Mulukutla0f63e002012-06-28 14:29:44 -0700200
Vikram Mulukutla80b7ab52012-07-26 19:03:15 -0700201#define DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(name, active, r_id) \
202 __DEFINE_CLK_RPM_BRANCH(name, active, RPM_CLK_BUFFER_A_REQ, r_id, 0, \
203 1000, RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY, &clk_rpmrs_data_smd)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700204#endif