blob: 033462d7bf571185a53b4337a124658556b078e3 [file] [log] [blame]
Padmanabhan Komanduru95bb8da2016-02-29 19:03:12 +05301/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
Dhaval Patel83e27fc2013-12-19 14:52:24 -08002 *
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
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -080015#include <linux/sde_io_util.h>
16#include <linux/clk-provider.h>
Dhaval Patel83e27fc2013-12-19 14:52:24 -080017#include <linux/io.h>
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -080018#include <linux/clk.h>
19#include <linux/clkdev.h>
20#include <linux/regmap.h>
21#include "../clk-regmap.h"
22#include "../clk-regmap-divider.h"
23#include "../clk-regmap-mux.h"
24
Dhaval Patel83e27fc2013-12-19 14:52:24 -080025
26#define MDSS_PLL_REG_W(base, offset, data) \
27 writel_relaxed((data), (base) + (offset))
Jeevan Shriram3287bab2014-08-19 09:07:48 -070028#define MDSS_PLL_REG_R(base, offset) readl_relaxed((base) + (offset))
29
30#define PLL_CALC_DATA(addr0, addr1, data0, data1) \
Jeevan Shriramd9bc2bf2015-08-23 14:33:59 -070031 (((data1) << 24) | ((((addr1) / 4) & 0xFF) << 16) | \
32 ((data0) << 8) | (((addr0) / 4) & 0xFF))
Jeevan Shriram3287bab2014-08-19 09:07:48 -070033
34#define MDSS_DYN_PLL_REG_W(base, offset, addr0, addr1, data0, data1) \
35 writel_relaxed(PLL_CALC_DATA(addr0, addr1, data0, data1), \
36 (base) + (offset))
Dhaval Patel83e27fc2013-12-19 14:52:24 -080037
38enum {
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -080039 MDSS_DSI_PLL_10NM,
Padmanabhan Komanduru6f0508d2017-04-28 16:38:57 -070040 MDSS_DP_PLL_10NM,
Dhaval Patel83e27fc2013-12-19 14:52:24 -080041 MDSS_UNKNOWN_PLL,
42};
43
Padmanabhan Komandurua7b90d12014-03-27 20:03:11 +053044enum {
Kuogee Hsieh6c9c1d92015-01-21 15:56:53 -080045 MDSS_PLL_TARGET_8996,
Padmanabhan Komandurua7b90d12014-03-27 20:03:11 +053046};
47
Padmanabhan Komanduru95bb8da2016-02-29 19:03:12 +053048#define DFPS_MAX_NUM_OF_FRAME_RATES 20
Jeevan Shriramd41c1b52015-07-02 11:34:05 -070049
50struct dfps_panel_info {
51 uint32_t enabled;
52 uint32_t frame_rate_cnt;
53 uint32_t frame_rate[DFPS_MAX_NUM_OF_FRAME_RATES]; /* hz */
54};
55
56struct dfps_pll_codes {
57 uint32_t pll_codes_1;
58 uint32_t pll_codes_2;
59};
60
61struct dfps_codes_info {
62 uint32_t is_valid;
63 uint32_t frame_rate; /* hz */
64 uint32_t clk_rate; /* hz */
65 struct dfps_pll_codes pll_codes;
66};
67
68struct dfps_info {
69 struct dfps_panel_info panel_dfps;
70 struct dfps_codes_info codes_dfps[DFPS_MAX_NUM_OF_FRAME_RATES];
71 void *dfps_fb_base;
72};
73
Dhaval Patel83e27fc2013-12-19 14:52:24 -080074struct mdss_pll_resources {
75
76 /* Pll specific resources like GPIO, power supply, clocks, etc*/
77 struct dss_module_power mp;
78
Jeevan Shriram6dd6b972014-08-19 22:43:46 -070079 /*
Veera Sundaram Sankaran23775f12014-11-13 14:28:25 -080080 * dsi/edp/hmdi plls' base register, phy, gdsc and dynamic refresh
Jeevan Shriram6dd6b972014-08-19 22:43:46 -070081 * register mapping
82 */
Dhaval Patel83e27fc2013-12-19 14:52:24 -080083 void __iomem *pll_base;
84 void __iomem *phy_base;
Padmanabhan Komanduru6f0508d2017-04-28 16:38:57 -070085 void __iomem *ln_tx0_base;
86 void __iomem *ln_tx1_base;
Veera Sundaram Sankaran23775f12014-11-13 14:28:25 -080087 void __iomem *gdsc_base;
Jeevan Shriram6dd6b972014-08-19 22:43:46 -070088 void __iomem *dyn_pll_base;
Dhaval Patel83e27fc2013-12-19 14:52:24 -080089
Huaibin Yangff625c02014-12-09 12:38:51 -080090 bool is_init_locked;
Huaibin Yangc5c6ad42014-11-26 15:18:39 -080091 s64 vco_current_rate;
Huaibin Yangff625c02014-12-09 12:38:51 -080092 s64 vco_locking_rate;
Huaibin Yangc5c6ad42014-11-26 15:18:39 -080093 s64 vco_ref_clk_rate;
94
Dhaval Patel83e27fc2013-12-19 14:52:24 -080095 /*
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;
Shashank Babu Chinta Venkata2182d622017-05-08 14:39:40 -0700100 u32 cached_cfg0;
101 u32 cached_cfg1;
Dhaval Patel83e27fc2013-12-19 14:52:24 -0800102
103 /* dsi/edp/hmdi pll interface type */
104 u32 pll_interface_type;
105
106 /*
Padmanabhan Komandurua7b90d12014-03-27 20:03:11 +0530107 * Target ID. Used in pll_register API for valid target check before
108 * registering the PLL clocks.
109 */
110 u32 target_id;
111
112 /* HW recommended delay during configuration of vco clock rate */
113 u32 vco_delay;
114
Padmanabhan Komanduru99fa0d72014-05-05 19:48:23 +0530115 /* Ref-count of the PLL resources */
116 u32 resource_ref_cnt;
117
Padmanabhan Komandurua7b90d12014-03-27 20:03:11 +0530118 /*
Dhaval Patel83e27fc2013-12-19 14:52:24 -0800119 * Keep track to resource status to avoid updating same status for the
120 * pll from different paths
121 */
122 bool resource_enable;
123
124 /*
125 * Certain plls' do not allow vco rate update if it is on. Keep track of
126 * status for them to turn on/off after set rate success.
127 */
128 bool pll_on;
129
130 /*
131 * handoff_status is true of pll is already enabled by bootloader with
132 * continuous splash enable case. Clock API will call the handoff API
133 * to enable the status. It is disabled if continuous splash
134 * feature is disabled.
135 */
136 bool handoff_resources;
Jeevan Shriram3287bab2014-08-19 09:07:48 -0700137
138 /*
139 * caching the pll trim codes in the case of dynamic refresh
140 */
Huaibin Yangc5c6ad42014-11-26 15:18:39 -0800141 int cache_pll_trim_codes[2];
Jeevan Shriram3287bab2014-08-19 09:07:48 -0700142
143 /*
144 * for maintaining the status of saving trim codes
145 */
146 bool reg_upd;
Siddhartha Agrawala91de842014-08-25 10:41:10 -0700147
148 /*
149 * Notifier callback for MDSS gdsc regulator events
150 */
151 struct notifier_block gdsc_cb;
152
153 /*
154 * Worker function to call PLL off event
155 */
156 struct work_struct pll_off;
157
Siddhartha Agrawal174bbb32014-09-05 10:44:54 -0700158 /*
159 * PLL index if multiple index are available. Eg. in case of
160 * DSI we have 2 plls.
161 */
162 uint32_t index;
163
Kuogee Hsieh1d230562015-05-29 09:38:54 -0700164 bool ssc_en; /* share pll with master */
165 bool ssc_center; /* default is down spread */
Padmanabhan Komanduru49538152015-12-16 17:35:13 +0530166 u32 ssc_freq;
167 u32 ssc_ppm;
Kuogee Hsieh1d230562015-05-29 09:38:54 -0700168
Kuogee Hsiehdf498542015-02-04 14:26:07 -0800169 struct mdss_pll_resources *slave;
170
Dhaval Patel0d49d472015-04-27 10:37:21 -0700171 /*
172 * target pll revision information
173 */
174 int revision;
175
Kuogee Hsieh6c9c1d92015-01-21 15:56:53 -0800176 void *priv;
Jeevan Shriramd41c1b52015-07-02 11:34:05 -0700177
178 /*
179 * dynamic refresh pll codes stored in this structure
180 */
181 struct dfps_info *dfps;
182
Jeevan Shriram3287bab2014-08-19 09:07:48 -0700183};
184
185struct mdss_pll_vco_calc {
186 s32 div_frac_start1;
187 s32 div_frac_start2;
188 s32 div_frac_start3;
189 s64 dec_start1;
190 s64 dec_start2;
191 s64 pll_plllock_cmp1;
192 s64 pll_plllock_cmp2;
193 s64 pll_plllock_cmp3;
Dhaval Patel83e27fc2013-12-19 14:52:24 -0800194};
195
Veera Sundaram Sankaran23775f12014-11-13 14:28:25 -0800196static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res)
197{
198 if (!pll_res->gdsc_base) {
199 WARN(1, "gdsc_base register is not defined\n");
200 return true;
201 }
Shashank Babu Chinta Venkata4302e8f2017-04-17 13:46:36 -0700202 return readl_relaxed(pll_res->gdsc_base) & BIT(31) ? false : true;
Veera Sundaram Sankaran23775f12014-11-13 14:28:25 -0800203}
204
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -0800205static inline int mdss_pll_div_prepare(struct clk_hw *hw)
Chandan Uddaraju16128f32016-02-22 16:43:23 -0800206{
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -0800207 struct clk_hw *parent_hw = clk_hw_get_parent(hw);
Chandan Uddaraju16128f32016-02-22 16:43:23 -0800208 /* Restore the divider's value */
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -0800209 return hw->init->ops->set_rate(hw, clk_hw_get_rate(hw),
210 clk_hw_get_rate(parent_hw));
Chandan Uddaraju16128f32016-02-22 16:43:23 -0800211}
212
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -0800213static inline int mdss_set_mux_sel(void *context, unsigned int reg,
214 unsigned int val)
Chandan Uddaraju16128f32016-02-22 16:43:23 -0800215{
216 return 0;
217}
218
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -0800219static inline int mdss_get_mux_sel(void *context, unsigned int reg,
220 unsigned int *val)
Chandan Uddaraju16128f32016-02-22 16:43:23 -0800221{
Shashank Babu Chinta Venkata704b93b2017-02-06 15:23:11 -0800222 *val = 0;
Chandan Uddaraju16128f32016-02-22 16:43:23 -0800223 return 0;
224}
225
Dhaval Patel83e27fc2013-12-19 14:52:24 -0800226int mdss_pll_resource_enable(struct mdss_pll_resources *pll_res, bool enable);
227int mdss_pll_util_resource_init(struct platform_device *pdev,
228 struct mdss_pll_resources *pll_res);
229void mdss_pll_util_resource_deinit(struct platform_device *pdev,
230 struct mdss_pll_resources *pll_res);
231void mdss_pll_util_resource_release(struct platform_device *pdev,
232 struct mdss_pll_resources *pll_res);
233int mdss_pll_util_resource_enable(struct mdss_pll_resources *pll_res,
234 bool enable);
235int mdss_pll_util_resource_parse(struct platform_device *pdev,
236 struct mdss_pll_resources *pll_res);
Siddhartha Agrawala91de842014-08-25 10:41:10 -0700237struct dss_vreg *mdss_pll_get_mp_by_reg_name(struct mdss_pll_resources *pll_res
238 , char *name);
Dhaval Patel83e27fc2013-12-19 14:52:24 -0800239#endif