1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _MDSS_DSI_CLK_H_
#define _MDSS_DSI_CLK_H_
#include <linux/mdss_io_util.h>
#include <linux/list.h>
#define DSI_CLK_NAME_LEN 20
#define MDSS_DSI_CLK_UPDATE_CLK_RATE_AT_ON 0x1
enum mdss_dsi_clk_state {
MDSS_DSI_CLK_OFF,
MDSS_DSI_CLK_ON,
MDSS_DSI_CLK_EARLY_GATE,
};
enum dsi_clk_req_client {
DSI_CLK_REQ_MDP_CLIENT = 0,
DSI_CLK_REQ_DSI_CLIENT,
};
enum mdss_dsi_link_clk_type {
MDSS_DSI_LINK_ESC_CLK,
MDSS_DSI_LINK_BYTE_CLK,
MDSS_DSI_LINK_PIX_CLK,
MDSS_DSI_LINK_BYTE_INTF_CLK,
MDSS_DSI_LINK_CLK_MAX,
};
enum mdss_dsi_clk_type {
MDSS_DSI_CORE_CLK = BIT(0),
MDSS_DSI_LINK_CLK = BIT(1),
MDSS_DSI_ALL_CLKS = (BIT(0) | BIT(1)),
MDSS_DSI_CLKS_MAX = BIT(2),
};
/**
* typedef *pre_clockoff_cb() - Callback before clock is turned off
* @priv: private data pointer.
* @clk_type: clock which is being turned off.
* @new_state: next state for the clock.
*
* @return: error code.
*/
typedef int (*pre_clockoff_cb)(void *priv,
enum mdss_dsi_clk_type clk_type,
enum mdss_dsi_clk_state new_state);
/**
* typedef *post_clockoff_cb() - Callback after clock is turned off
* @priv: private data pointer.
* @clk_type: clock which was turned off.
* @curr_state: current state for the clock.
*
* @return: error code.
*/
typedef int (*post_clockoff_cb)(void *priv,
enum mdss_dsi_clk_type clk_type,
enum mdss_dsi_clk_state curr_state);
/**
* typedef *post_clockon_cb() - Callback after clock is turned on
* @priv: private data pointer.
* @clk_type: clock which was turned on.
* @curr_state: current state for the clock.
*
* @return: error code.
*/
typedef int (*post_clockon_cb)(void *priv,
enum mdss_dsi_clk_type clk_type,
enum mdss_dsi_clk_state curr_state);
/**
* typedef *pre_clockon_cb() - Callback before clock is turned on
* @priv: private data pointer.
* @clk_type: clock which is being turned on.
* @new_state: next state for the clock.
*
* @return: error code.
*/
typedef int (*pre_clockon_cb)(void *priv,
enum mdss_dsi_clk_type clk_type,
enum mdss_dsi_clk_state new_state);
struct mdss_dsi_core_clk_info {
struct clk *mdp_core_clk;
struct clk *mnoc_clk;
struct clk *ahb_clk;
struct clk *axi_clk;
struct clk *mmss_misc_ahb_clk;
};
struct mdss_dsi_link_clk_info {
struct clk *esc_clk;
struct clk *byte_clk;
struct clk *pixel_clk;
struct clk *byte_intf_clk;
};
struct dsi_panel_clk_ctrl {
enum mdss_dsi_clk_state state;
enum dsi_clk_req_client client;
};
/**
* struct mdss_dsi_clk_info - clock information to initialize manager
* @name: name for the clocks to identify debug logs.
* @core_clks: core clock information.
* @link_clks: link clock information.
* @pre_clkoff_cb: callback before a clock is turned off.
* @post_clkoff_cb: callback after a clock is turned off.
* @pre_clkon_cb: callback before a clock is turned on.
* @post_clkon_cb: callback after a clock is turned on.
* @priv_data: pointer to private data passed to callbacks.
*/
struct mdss_dsi_clk_info {
char name[DSI_CLK_NAME_LEN];
struct mdss_dsi_core_clk_info core_clks;
struct mdss_dsi_link_clk_info link_clks;
pre_clockoff_cb pre_clkoff_cb;
post_clockoff_cb post_clkoff_cb;
post_clockon_cb post_clkon_cb;
pre_clockon_cb pre_clkon_cb;
void *priv_data;
};
struct mdss_dsi_clk_client {
char *client_name;
};
/**
* mdss_dsi_clk_init() - Initializes clock manager
* @info: Clock information to be managed by the clock manager.
*
* The Init API should be called during probe of the dsi driver. DSI driver
* provides the clock handles to the core clocks and link clocks that will be
* managed by the clock manager.
*
* returns handle or an error value.
*/
void *mdss_dsi_clk_init(struct mdss_dsi_clk_info *info);
/**
* mdss_dsi_clk_deinit() - Deinitializes the clock manager
* @mngr: handle returned by mdss_dsi_clk_init().
*
* Deinit will turn off all the clocks and release all the resources acquired
* by mdss_dsi_clk_init().
*
* @return: error code.
*/
int mdss_dsi_clk_deinit(void *mngr);
/**
* mdss_dsi_clk_register() - Register a client to control clock state
* @mngr: handle returned by mdss_dsi_clk_init().
* @client: client information.
*
* Register allows clients for DSI clock manager to acquire a handle which can
* be used to request a specific clock state. The clock manager maintains a
* reference count of the clock states requested by each client. Client has to
* ensure that ON and OFF/EARLY_GATE calls are balanced properly.
*
* Requesting a particular clock state does not guarantee that physical clock
* state. Physical clock state is determined by the states requested by all
* clients.
*
* @return: handle or error code.
*/
void *mdss_dsi_clk_register(void *mngr, struct mdss_dsi_clk_client *client);
/**
* mdss_dsi_clk_deregister() - Deregister a registered client.
* @client: client handle returned by mdss_dsi_clk_register().
*
* Deregister releases all resources acquired by mdss_dsi_clk_register().
*
* @return: error code.
*/
int mdss_dsi_clk_deregister(void *client);
/**
* mdss_dsi_clk_req_state() - Request a specific clock state
* @client: client handle.
* @clk: Type of clock requested (enum mdss_dsi_clk_type).
* @state: clock state requested.
* @index: controller index.
*
* This routine is used to request a new clock state for a specific clock. If
* turning ON the clocks, this guarantees that clocks will be on before
* returning. Valid state transitions are ON -> EARLY GATE, ON -> OFF,
* EARLY GATE -> OFF, EARLY GATE -> ON and OFF -> ON.
*
* @return: error code.
*/
int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
enum mdss_dsi_clk_state state, u32 index);
/**
* mdss_dsi_clk_set_link_rate() - set clock rate for link clocks
* @client: client handle.
* @clk: type of clock.
* @rate: clock rate in Hz.
* @flags: flags.
*
* This routine is used to request a specific clock rate. It supports an
* additional flags argument which can change the behavior of the routine. If
* MDSS_DSI_CLK_UPDATE_CLK_RATE_AT_ON flag is set, the routine caches the new
* clock rate and applies it next time when the clock is turned on.
*
* @return: error code.
*/
int mdss_dsi_clk_set_link_rate(void *client, enum mdss_dsi_link_clk_type clk,
u32 rate, u32 flags);
/**
* mdss_dsi_clk_force_toggle() - Turn off and turn on clocks
* @client: client handle.
* @clk: clock type.
*
* This routine has to be used in cases where clocks have to be toggled
* irrespecitive of the refcount. This API bypasses the refcount and turns off
* and turns on the clocks. This will fail if the clocks are in OFF state
* already.
*
* @return:error code.
*/
int mdss_dsi_clk_force_toggle(void *client, u32 clk);
/**
* is_dsi_clk_in_ecg_state() - Checks the current state of clocks
* @client: client handle.
*
* This routine returns checks the clocks status for client and return
* success code based on it.
*
* @return:true: if clocks are in ECG state
* false: for all other cases
*/
bool is_dsi_clk_in_ecg_state(void *client);
#endif /* _MDSS_DSI_CLK_H_ */
|