blob: 35d8c74d543fce4ed881df02d16217693786bab0 [file] [log] [blame]
Sachin Bhayarecf8460a2018-01-03 18:34:30 +05301/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
2 *
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#ifndef __MDSS_PLL_H
14#define __MDSS_PLL_H
15
16#include <linux/mdss_io_util.h>
17#include <linux/io.h>
18
19#define MDSS_PLL_REG_W(base, offset, data) \
20 writel_relaxed((data), (base) + (offset))
21#define MDSS_PLL_REG_R(base, offset) readl_relaxed((base) + (offset))
22
23#define PLL_CALC_DATA(addr0, addr1, data0, data1) \
24 (((data1) << 24) | ((((addr1) / 4) & 0xFF) << 16) | \
25 ((data0) << 8) | (((addr0) / 4) & 0xFF))
26
27#define MDSS_DYN_PLL_REG_W(base, offset, addr0, addr1, data0, data1) \
28 writel_relaxed(PLL_CALC_DATA(addr0, addr1, data0, data1), \
29 (base) + (offset))
30
31enum {
32 MDSS_DSI_PLL_LPM,
33 MDSS_DSI_PLL_8996,
34 MDSS_HDMI_PLL_8996,
35 MDSS_HDMI_PLL_8996_V2,
36 MDSS_HDMI_PLL_8996_V3,
37 MDSS_HDMI_PLL_8996_V3_1_8,
38 MDSS_UNKNOWN_PLL,
39};
40
41enum {
42 MDSS_PLL_TARGET_8996,
43 MDSS_PLL_TARGET_8952,
44 MDSS_PLL_TARGET_8937,
45 MDSS_PLL_TARGET_8953,
46 MDSS_PLL_TARGET_8909,
47};
48
49#define DFPS_MAX_NUM_OF_FRAME_RATES 20
50
51struct dfps_panel_info {
52 uint32_t enabled;
53 uint32_t frame_rate_cnt;
54 uint32_t frame_rate[DFPS_MAX_NUM_OF_FRAME_RATES]; /* hz */
55};
56
57struct dfps_pll_codes {
58 uint32_t pll_codes_1;
59 uint32_t pll_codes_2;
60};
61
62struct dfps_codes_info {
63 uint32_t is_valid;
64 uint32_t frame_rate; /* hz */
65 uint32_t clk_rate; /* hz */
66 struct dfps_pll_codes pll_codes;
67};
68
69struct dfps_info {
70 struct dfps_panel_info panel_dfps;
71 struct dfps_codes_info codes_dfps[DFPS_MAX_NUM_OF_FRAME_RATES];
72 void *dfps_fb_base;
73 uint32_t chip_serial;
74};
75
76struct mdss_pll_resources {
77
78 /* Pll specific resources like GPIO, power supply, clocks, etc*/
79 struct dss_module_power mp;
80
81 /*
82 * dsi/edp/hmdi plls' base register, phy, gdsc and dynamic refresh
83 * register mapping
84 */
85 void __iomem *pll_base;
86 void __iomem *phy_base;
87 void __iomem *gdsc_base;
88 void __iomem *dyn_pll_base;
89
90 bool is_init_locked;
91 s64 vco_current_rate;
92 s64 vco_locking_rate;
93 s64 vco_ref_clk_rate;
94
95 /*
96 * Certain pll's needs to update the same vco rate after resume in
97 * suspend/resume scenario. Cached the vco rate for such plls.
98 */
99 unsigned long vco_cached_rate;
100
101 /* dsi/edp/hmdi pll interface type */
102 u32 pll_interface_type;
103
104 /*
105 * Target ID. Used in pll_register API for valid target check before
106 * registering the PLL clocks.
107 */
108 u32 target_id;
109
110 /* HW recommended delay during configuration of vco clock rate */
111 u32 vco_delay;
112
113 /* Ref-count of the PLL resources */
114 u32 resource_ref_cnt;
115
116 /*
117 * Keep track to resource status to avoid updating same status for the
118 * pll from different paths
119 */
120 bool resource_enable;
121
122 /*
123 * Certain plls' do not allow vco rate update if it is on. Keep track of
124 * status for them to turn on/off after set rate success.
125 */
126 bool pll_on;
127
128 /*
129 * handoff_status is true of pll is already enabled by bootloader with
130 * continuous splash enable case. Clock API will call the handoff API
131 * to enable the status. It is disabled if continuous splash
132 * feature is disabled.
133 */
134 bool handoff_resources;
135
136 /*
137 * caching the pll trim codes in the case of dynamic refresh
138 * or cmd mode idle screen.
139 */
140 int cache_pll_trim_codes[2];
141
142 /*
143 * caching the pll trim codes rate
144 */
145 s64 cache_pll_trim_codes_rate;
146
147 /*
148 * for maintaining the status of saving trim codes
149 */
150 bool reg_upd;
151
152 /*
153 * Notifier callback for MDSS gdsc regulator events
154 */
155 struct notifier_block gdsc_cb;
156
157 /*
158 * Worker function to call PLL off event
159 */
160 struct work_struct pll_off;
161
162 /*
163 * PLL index if multiple index are available. Eg. in case of
164 * DSI we have 2 plls.
165 */
166 uint32_t index;
167
168 bool ssc_en; /* share pll with master */
169 bool ssc_center; /* default is down spread */
170 u32 ssc_freq;
171 u32 ssc_ppm;
172
173 struct mdss_pll_resources *slave;
174
175 /*
176 * target pll revision information
177 */
178 int revision;
179
180 void *priv;
181
182 /*
183 * dynamic refresh pll codes stored in this structure
184 */
185 struct dfps_info *dfps;
186
187};
188
189struct mdss_pll_vco_calc {
190 s32 div_frac_start1;
191 s32 div_frac_start2;
192 s32 div_frac_start3;
193 s64 dec_start1;
194 s64 dec_start2;
195 s64 pll_plllock_cmp1;
196 s64 pll_plllock_cmp2;
197 s64 pll_plllock_cmp3;
198};
199
200static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res)
201{
202 if (!pll_res->gdsc_base) {
203 WARN(1, "gdsc_base register is not defined\n");
204 return true;
205 }
206
207 return ((readl_relaxed(pll_res->gdsc_base + 0x4) & BIT(31)) &&
208 (!(readl_relaxed(pll_res->gdsc_base) & BIT(0)))) ? false : true;
209}
210
211int mdss_pll_resource_enable(struct mdss_pll_resources *pll_res, bool enable);
212int mdss_pll_util_resource_init(struct platform_device *pdev,
213 struct mdss_pll_resources *pll_res);
214void mdss_pll_util_resource_deinit(struct platform_device *pdev,
215 struct mdss_pll_resources *pll_res);
216void mdss_pll_util_resource_release(struct platform_device *pdev,
217 struct mdss_pll_resources *pll_res);
218int mdss_pll_util_resource_enable(struct mdss_pll_resources *pll_res,
219 bool enable);
220int mdss_pll_util_resource_parse(struct platform_device *pdev,
221 struct mdss_pll_resources *pll_res);
222struct dss_vreg *mdss_pll_get_mp_by_reg_name(struct mdss_pll_resources *pll_res
223 , char *name);
224#endif