blob: 1fa5cffab6c2923c9ea252112af7bf766f77fdc2 [file] [log] [blame]
Sachin Bhayare5076e252018-01-18 14:56:45 +05301/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
Sachin Bhayarecf8460a2018-01-03 18:34:30 +05302 *
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
Sachin Bhayarecf8460a2018-01-03 18:34:30 +053049struct mdss_pll_resources {
50
51 /* Pll specific resources like GPIO, power supply, clocks, etc*/
Sachin Bhayare5076e252018-01-18 14:56:45 +053052 struct mdss_module_power mp;
Sachin Bhayarecf8460a2018-01-03 18:34:30 +053053
54 /*
55 * dsi/edp/hmdi plls' base register, phy, gdsc and dynamic refresh
56 * register mapping
57 */
58 void __iomem *pll_base;
59 void __iomem *phy_base;
60 void __iomem *gdsc_base;
61 void __iomem *dyn_pll_base;
62
63 bool is_init_locked;
64 s64 vco_current_rate;
65 s64 vco_locking_rate;
66 s64 vco_ref_clk_rate;
67
68 /*
69 * Certain pll's needs to update the same vco rate after resume in
70 * suspend/resume scenario. Cached the vco rate for such plls.
71 */
72 unsigned long vco_cached_rate;
73
74 /* dsi/edp/hmdi pll interface type */
75 u32 pll_interface_type;
76
77 /*
78 * Target ID. Used in pll_register API for valid target check before
79 * registering the PLL clocks.
80 */
81 u32 target_id;
82
83 /* HW recommended delay during configuration of vco clock rate */
84 u32 vco_delay;
85
86 /* Ref-count of the PLL resources */
87 u32 resource_ref_cnt;
88
89 /*
90 * Keep track to resource status to avoid updating same status for the
91 * pll from different paths
92 */
93 bool resource_enable;
94
95 /*
96 * Certain plls' do not allow vco rate update if it is on. Keep track of
97 * status for them to turn on/off after set rate success.
98 */
99 bool pll_on;
100
101 /*
102 * handoff_status is true of pll is already enabled by bootloader with
103 * continuous splash enable case. Clock API will call the handoff API
104 * to enable the status. It is disabled if continuous splash
105 * feature is disabled.
106 */
107 bool handoff_resources;
108
109 /*
110 * caching the pll trim codes in the case of dynamic refresh
111 * or cmd mode idle screen.
112 */
113 int cache_pll_trim_codes[2];
114
115 /*
116 * caching the pll trim codes rate
117 */
118 s64 cache_pll_trim_codes_rate;
119
120 /*
121 * for maintaining the status of saving trim codes
122 */
123 bool reg_upd;
124
125 /*
126 * Notifier callback for MDSS gdsc regulator events
127 */
128 struct notifier_block gdsc_cb;
129
130 /*
131 * Worker function to call PLL off event
132 */
133 struct work_struct pll_off;
134
135 /*
136 * PLL index if multiple index are available. Eg. in case of
137 * DSI we have 2 plls.
138 */
139 uint32_t index;
140
141 bool ssc_en; /* share pll with master */
142 bool ssc_center; /* default is down spread */
143 u32 ssc_freq;
144 u32 ssc_ppm;
145
146 struct mdss_pll_resources *slave;
147
148 /*
149 * target pll revision information
150 */
151 int revision;
152
153 void *priv;
154
155 /*
156 * dynamic refresh pll codes stored in this structure
157 */
158 struct dfps_info *dfps;
159
160};
161
162struct mdss_pll_vco_calc {
163 s32 div_frac_start1;
164 s32 div_frac_start2;
165 s32 div_frac_start3;
166 s64 dec_start1;
167 s64 dec_start2;
168 s64 pll_plllock_cmp1;
169 s64 pll_plllock_cmp2;
170 s64 pll_plllock_cmp3;
171};
172
173static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res)
174{
175 if (!pll_res->gdsc_base) {
176 WARN(1, "gdsc_base register is not defined\n");
177 return true;
178 }
179
180 return ((readl_relaxed(pll_res->gdsc_base + 0x4) & BIT(31)) &&
181 (!(readl_relaxed(pll_res->gdsc_base) & BIT(0)))) ? false : true;
182}
183
184int mdss_pll_resource_enable(struct mdss_pll_resources *pll_res, bool enable);
185int mdss_pll_util_resource_init(struct platform_device *pdev,
186 struct mdss_pll_resources *pll_res);
187void mdss_pll_util_resource_deinit(struct platform_device *pdev,
188 struct mdss_pll_resources *pll_res);
189void mdss_pll_util_resource_release(struct platform_device *pdev,
190 struct mdss_pll_resources *pll_res);
191int mdss_pll_util_resource_enable(struct mdss_pll_resources *pll_res,
192 bool enable);
193int mdss_pll_util_resource_parse(struct platform_device *pdev,
194 struct mdss_pll_resources *pll_res);
Sachin Bhayare5076e252018-01-18 14:56:45 +0530195struct mdss_vreg *mdss_pll_get_mp_by_reg_name(struct mdss_pll_resources *pll_res
Sachin Bhayarecf8460a2018-01-03 18:34:30 +0530196 , char *name);
197#endif