]>
Commit | Line | Data |
---|---|---|
559d6701 | 1 | /* |
559d6701 TV |
2 | * Copyright (C) 2009 Nokia Corporation |
3 | * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | |
4 | * | |
5 | * Some code and ideas taken from drivers/video/omap/ driver | |
6 | * by Imre Deak. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License version 2 as published by | |
10 | * the Free Software Foundation. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 | * more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License along with | |
18 | * this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | */ | |
20 | ||
21 | #ifndef __OMAP2_DSS_H | |
22 | #define __OMAP2_DSS_H | |
23 | ||
96e2e637 TV |
24 | #include <linux/interrupt.h> |
25 | ||
35a339ac TV |
26 | #include "omapdss.h" |
27 | ||
d874b3a7 LP |
28 | #define MAX_DSS_LCD_MANAGERS 3 |
29 | #define MAX_NUM_DSI 2 | |
30 | ||
702d267e CM |
31 | #ifdef pr_fmt |
32 | #undef pr_fmt | |
559d6701 TV |
33 | #endif |
34 | ||
702d267e CM |
35 | #ifdef DSS_SUBSYS_NAME |
36 | #define pr_fmt(fmt) DSS_SUBSYS_NAME ": " fmt | |
37 | #else | |
38 | #define pr_fmt(fmt) fmt | |
559d6701 TV |
39 | #endif |
40 | ||
702d267e CM |
41 | #define DSSDBG(format, ...) \ |
42 | pr_debug(format, ## __VA_ARGS__) | |
559d6701 TV |
43 | |
44 | #ifdef DSS_SUBSYS_NAME | |
45 | #define DSSERR(format, ...) \ | |
8dfe162a | 46 | pr_err("omapdss " DSS_SUBSYS_NAME " error: " format, ##__VA_ARGS__) |
559d6701 TV |
47 | #else |
48 | #define DSSERR(format, ...) \ | |
8dfe162a | 49 | pr_err("omapdss error: " format, ##__VA_ARGS__) |
559d6701 TV |
50 | #endif |
51 | ||
52 | #ifdef DSS_SUBSYS_NAME | |
53 | #define DSSINFO(format, ...) \ | |
8dfe162a | 54 | pr_info("omapdss " DSS_SUBSYS_NAME ": " format, ##__VA_ARGS__) |
559d6701 TV |
55 | #else |
56 | #define DSSINFO(format, ...) \ | |
8dfe162a | 57 | pr_info("omapdss: " format, ## __VA_ARGS__) |
559d6701 TV |
58 | #endif |
59 | ||
60 | #ifdef DSS_SUBSYS_NAME | |
61 | #define DSSWARN(format, ...) \ | |
8dfe162a | 62 | pr_warn("omapdss " DSS_SUBSYS_NAME ": " format, ##__VA_ARGS__) |
559d6701 TV |
63 | #else |
64 | #define DSSWARN(format, ...) \ | |
8dfe162a | 65 | pr_warn("omapdss: " format, ##__VA_ARGS__) |
559d6701 TV |
66 | #endif |
67 | ||
68 | /* OMAP TRM gives bitfields as start:end, where start is the higher bit | |
69 | number. For example 7:0 */ | |
70 | #define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) | |
71 | #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) | |
72 | #define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end)) | |
73 | #define FLD_MOD(orig, val, start, end) \ | |
74 | (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) | |
75 | ||
b8dab2bd LP |
76 | enum dss_model { |
77 | DSS_MODEL_OMAP2, | |
78 | DSS_MODEL_OMAP3, | |
79 | DSS_MODEL_OMAP4, | |
80 | DSS_MODEL_OMAP5, | |
81 | DSS_MODEL_DRA7, | |
82 | }; | |
83 | ||
569969d6 AT |
84 | enum dss_io_pad_mode { |
85 | DSS_IO_PAD_MODE_RESET, | |
86 | DSS_IO_PAD_MODE_RFBI, | |
87 | DSS_IO_PAD_MODE_BYPASS, | |
559d6701 TV |
88 | }; |
89 | ||
7ed024aa M |
90 | enum dss_hdmi_venc_clk_source_select { |
91 | DSS_VENC_TV_CLK = 0, | |
92 | DSS_HDMI_M_PCLK = 1, | |
93 | }; | |
94 | ||
6ff8aa31 AT |
95 | enum dss_dsi_content_type { |
96 | DSS_DSI_CONTENT_DCS, | |
97 | DSS_DSI_CONTENT_GENERIC, | |
98 | }; | |
99 | ||
d9ac773c AT |
100 | enum dss_writeback_channel { |
101 | DSS_WB_LCD1_MGR = 0, | |
102 | DSS_WB_LCD2_MGR = 1, | |
103 | DSS_WB_TV_MGR = 2, | |
104 | DSS_WB_OVL0 = 3, | |
105 | DSS_WB_OVL1 = 4, | |
106 | DSS_WB_OVL2 = 5, | |
107 | DSS_WB_OVL3 = 6, | |
108 | DSS_WB_LCD3_MGR = 7, | |
109 | }; | |
110 | ||
dc0352d1 | 111 | enum dss_clk_source { |
3b63ca75 TV |
112 | DSS_CLK_SRC_FCK = 0, |
113 | ||
114 | DSS_CLK_SRC_PLL1_1, | |
115 | DSS_CLK_SRC_PLL1_2, | |
b5d8c757 | 116 | DSS_CLK_SRC_PLL1_3, |
3b63ca75 TV |
117 | |
118 | DSS_CLK_SRC_PLL2_1, | |
119 | DSS_CLK_SRC_PLL2_2, | |
b5d8c757 TV |
120 | DSS_CLK_SRC_PLL2_3, |
121 | ||
122 | DSS_CLK_SRC_HDMI_PLL, | |
be5d7319 TV |
123 | }; |
124 | ||
64e22ffd TV |
125 | enum dss_pll_id { |
126 | DSS_PLL_DSI1, | |
127 | DSS_PLL_DSI2, | |
128 | DSS_PLL_HDMI, | |
6d817880 TV |
129 | DSS_PLL_VIDEO1, |
130 | DSS_PLL_VIDEO2, | |
64e22ffd TV |
131 | }; |
132 | ||
0a20170a TV |
133 | struct dss_pll; |
134 | ||
135 | #define DSS_PLL_MAX_HSDIVS 4 | |
136 | ||
06ede3dd TV |
137 | enum dss_pll_type { |
138 | DSS_PLL_TYPE_A, | |
139 | DSS_PLL_TYPE_B, | |
140 | }; | |
141 | ||
0a20170a TV |
142 | /* |
143 | * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7. | |
144 | * Type-B PLLs: clkout[0] refers to m2. | |
145 | */ | |
146 | struct dss_pll_clock_info { | |
147 | /* rates that we get with dividers below */ | |
148 | unsigned long fint; | |
149 | unsigned long clkdco; | |
150 | unsigned long clkout[DSS_PLL_MAX_HSDIVS]; | |
151 | ||
152 | /* dividers */ | |
153 | u16 n; | |
154 | u16 m; | |
155 | u32 mf; | |
156 | u16 mX[DSS_PLL_MAX_HSDIVS]; | |
157 | u16 sd; | |
158 | }; | |
159 | ||
160 | struct dss_pll_ops { | |
161 | int (*enable)(struct dss_pll *pll); | |
162 | void (*disable)(struct dss_pll *pll); | |
163 | int (*set_config)(struct dss_pll *pll, | |
164 | const struct dss_pll_clock_info *cinfo); | |
165 | }; | |
166 | ||
167 | struct dss_pll_hw { | |
06ede3dd TV |
168 | enum dss_pll_type type; |
169 | ||
d11e5c82 LP |
170 | unsigned int n_max; |
171 | unsigned int m_min; | |
172 | unsigned int m_max; | |
173 | unsigned int mX_max; | |
0a20170a TV |
174 | |
175 | unsigned long fint_min, fint_max; | |
176 | unsigned long clkdco_min, clkdco_low, clkdco_max; | |
177 | ||
178 | u8 n_msb, n_lsb; | |
179 | u8 m_msb, m_lsb; | |
180 | u8 mX_msb[DSS_PLL_MAX_HSDIVS], mX_lsb[DSS_PLL_MAX_HSDIVS]; | |
181 | ||
182 | bool has_stopmode; | |
183 | bool has_freqsel; | |
184 | bool has_selfreqdco; | |
185 | bool has_refsel; | |
0c43f1e0 TV |
186 | |
187 | /* DRA7 errata i886: use high N & M to avoid jitter */ | |
188 | bool errata_i886; | |
0a20170a TV |
189 | }; |
190 | ||
191 | struct dss_pll { | |
192 | const char *name; | |
64e22ffd | 193 | enum dss_pll_id id; |
0a20170a TV |
194 | |
195 | struct clk *clkin; | |
196 | struct regulator *regulator; | |
197 | ||
198 | void __iomem *base; | |
199 | ||
200 | const struct dss_pll_hw *hw; | |
201 | ||
202 | const struct dss_pll_ops *ops; | |
203 | ||
204 | struct dss_pll_clock_info cinfo; | |
205 | }; | |
206 | ||
6d85d4ad LP |
207 | /* Defines a generic omap register field */ |
208 | struct dss_reg_field { | |
209 | u8 start, end; | |
210 | }; | |
211 | ||
559d6701 TV |
212 | struct dispc_clock_info { |
213 | /* rates that we get with dividers below */ | |
214 | unsigned long lck; | |
215 | unsigned long pck; | |
216 | ||
217 | /* dividers */ | |
218 | u16 lck_div; | |
219 | u16 pck_div; | |
220 | }; | |
221 | ||
c56fb3ef AT |
222 | struct dss_lcd_mgr_config { |
223 | enum dss_io_pad_mode io_pad_mode; | |
224 | ||
225 | bool stallmode; | |
226 | bool fifohandcheck; | |
227 | ||
228 | struct dispc_clock_info clock_info; | |
229 | ||
230 | int video_port_width; | |
231 | ||
232 | int lcden_sig_polarity; | |
233 | }; | |
234 | ||
559d6701 TV |
235 | struct seq_file; |
236 | struct platform_device; | |
237 | ||
238 | /* core */ | |
493b683b LP |
239 | static inline int dss_set_min_bus_tput(struct device *dev, unsigned long tput) |
240 | { | |
241 | /* To be implemented when the OMAP platform will provide this feature */ | |
242 | return 0; | |
243 | } | |
244 | ||
f476ae9d AT |
245 | static inline bool dss_mgr_is_lcd(enum omap_channel id) |
246 | { | |
247 | if (id == OMAP_DSS_CHANNEL_LCD || id == OMAP_DSS_CHANNEL_LCD2 || | |
248 | id == OMAP_DSS_CHANNEL_LCD3) | |
249 | return true; | |
250 | else | |
251 | return false; | |
252 | } | |
253 | ||
559d6701 | 254 | /* DSS */ |
11765d16 LP |
255 | #if defined(CONFIG_OMAP2_DSS_DEBUGFS) |
256 | int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); | |
257 | #else | |
258 | static inline int dss_debugfs_create_file(const char *name, | |
259 | void (*write)(struct seq_file *)) | |
260 | { | |
261 | return 0; | |
262 | } | |
263 | #endif /* CONFIG_OMAP2_DSS_DEBUGFS */ | |
264 | ||
99767548 TV |
265 | int dss_runtime_get(void); |
266 | void dss_runtime_put(void); | |
267 | ||
5aaee69d | 268 | unsigned long dss_get_dispc_clk_rate(void); |
9f0fbaea | 269 | unsigned long dss_get_max_fck_rate(void); |
51919572 | 270 | enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel); |
064c2a47 | 271 | int dss_dpi_select_source(int port, enum omap_channel channel); |
7ed024aa | 272 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); |
407bd564 | 273 | const char *dss_get_clk_source_name(enum dss_clk_source clk_src); |
559d6701 | 274 | |
99767548 TV |
275 | /* DSS VIDEO PLL */ |
276 | struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id, | |
277 | struct regulator *regulator); | |
278 | void dss_video_pll_uninit(struct dss_pll *pll); | |
279 | ||
be40eecf | 280 | void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable); |
be40eecf | 281 | |
889b4fd7 | 282 | void dss_sdi_init(int datapairs); |
559d6701 TV |
283 | int dss_sdi_enable(void); |
284 | void dss_sdi_disable(void); | |
285 | ||
5a8b572d | 286 | void dss_select_dsi_clk_source(int dsi_module, |
dc0352d1 | 287 | enum dss_clk_source clk_src); |
ea75159e | 288 | void dss_select_lcd_clk_source(enum omap_channel channel, |
dc0352d1 TV |
289 | enum dss_clk_source clk_src); |
290 | enum dss_clk_source dss_get_dispc_clk_source(void); | |
291 | enum dss_clk_source dss_get_dsi_clk_source(int dsi_module); | |
292 | enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); | |
2f18c4d8 | 293 | |
559d6701 TV |
294 | void dss_set_venc_output(enum omap_dss_venc_type type); |
295 | void dss_set_dac_pwrdn_bgz(bool enable); | |
296 | ||
d0f58bd3 | 297 | int dss_set_fck_rate(unsigned long rate); |
559d6701 | 298 | |
d0f58bd3 | 299 | typedef bool (*dss_div_calc_func)(unsigned long fck, void *data); |
688af02d TV |
300 | bool dss_div_calc(unsigned long pck, unsigned long fck_min, |
301 | dss_div_calc_func func, void *data); | |
43417823 | 302 | |
559d6701 | 303 | /* SDI */ |
387ce9f2 | 304 | #ifdef CONFIG_OMAP2_DSS_SDI |
ede92695 TV |
305 | int sdi_init_port(struct platform_device *pdev, struct device_node *port); |
306 | void sdi_uninit_port(struct device_node *port); | |
387ce9f2 | 307 | #else |
ede92695 | 308 | static inline int sdi_init_port(struct platform_device *pdev, |
387ce9f2 AT |
309 | struct device_node *port) |
310 | { | |
311 | return 0; | |
312 | } | |
ede92695 | 313 | static inline void sdi_uninit_port(struct device_node *port) |
387ce9f2 AT |
314 | { |
315 | } | |
316 | #endif | |
2ecef246 | 317 | |
559d6701 | 318 | /* DSI */ |
989c79a8 | 319 | |
368a148e | 320 | #ifdef CONFIG_OMAP2_DSS_DSI |
5a8b572d AT |
321 | |
322 | struct dentry; | |
323 | struct file_operations; | |
324 | ||
559d6701 | 325 | void dsi_dump_clocks(struct seq_file *s); |
559d6701 | 326 | |
559d6701 | 327 | void dsi_irq_handler(void); |
a3b3cc2b | 328 | |
368a148e | 329 | #endif |
559d6701 TV |
330 | |
331 | /* DPI */ | |
387ce9f2 | 332 | #ifdef CONFIG_OMAP2_DSS_DPI |
b8dab2bd LP |
333 | int dpi_init_port(struct platform_device *pdev, struct device_node *port, |
334 | enum dss_model dss_model); | |
ede92695 | 335 | void dpi_uninit_port(struct device_node *port); |
387ce9f2 | 336 | #else |
ede92695 | 337 | static inline int dpi_init_port(struct platform_device *pdev, |
b8dab2bd | 338 | struct device_node *port, enum dss_model dss_model) |
387ce9f2 AT |
339 | { |
340 | return 0; | |
341 | } | |
ede92695 | 342 | static inline void dpi_uninit_port(struct device_node *port) |
387ce9f2 AT |
343 | { |
344 | } | |
345 | #endif | |
2ecef246 | 346 | |
559d6701 | 347 | /* DISPC */ |
559d6701 | 348 | void dispc_dump_clocks(struct seq_file *s); |
559d6701 | 349 | |
5034b1fa TV |
350 | int dispc_runtime_get(void); |
351 | void dispc_runtime_put(void); | |
352 | ||
559d6701 TV |
353 | void dispc_enable_sidle(void); |
354 | void dispc_disable_sidle(void); | |
355 | ||
559d6701 TV |
356 | void dispc_lcd_enable_signal(bool enable); |
357 | void dispc_pck_free_enable(bool enable); | |
cd295aeb | 358 | void dispc_enable_fifomerge(bool enable); |
cd295aeb | 359 | |
7c284e6e TV |
360 | typedef bool (*dispc_div_calc_func)(int lckd, int pckd, unsigned long lck, |
361 | unsigned long pck, void *data); | |
362 | bool dispc_div_calc(unsigned long dispc, | |
363 | unsigned long pck_min, unsigned long pck_max, | |
364 | dispc_div_calc_func func, void *data); | |
365 | ||
da11bbbb | 366 | bool dispc_mgr_timings_ok(enum omap_channel channel, const struct videomode *vm); |
cd295aeb TV |
367 | int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, |
368 | struct dispc_clock_info *cinfo); | |
369 | ||
370 | ||
864050c7 JS |
371 | void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low, |
372 | u32 high); | |
373 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane, | |
3568f2a4 TV |
374 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, |
375 | bool manual_update); | |
348be69d | 376 | |
f0d08f89 | 377 | void dispc_mgr_set_clock_div(enum omap_channel channel, |
a8f3fcd1 | 378 | const struct dispc_clock_info *cinfo); |
26d9dd0d | 379 | int dispc_mgr_get_clock_div(enum omap_channel channel, |
ff1b2cde | 380 | struct dispc_clock_info *cinfo); |
5391e87d | 381 | void dispc_set_tv_pclk(unsigned long pclk); |
559d6701 | 382 | |
0b23e5b8 AT |
383 | u32 dispc_wb_get_framedone_irq(void); |
384 | bool dispc_wb_go_busy(void); | |
385 | void dispc_wb_go(void); | |
d9ac773c | 386 | void dispc_wb_set_channel_in(enum dss_writeback_channel channel); |
749feffa | 387 | int dispc_wb_setup(const struct omap_dss_writeback_info *wi, |
da11bbbb | 388 | bool mem_to_mem, const struct videomode *vm); |
d9ac773c | 389 | |
dfc0fd8d | 390 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
d11e5c82 | 391 | static inline void dss_collect_irq_stats(u32 irqstatus, unsigned int *irq_arr) |
dfc0fd8d TV |
392 | { |
393 | int b; | |
394 | for (b = 0; b < 32; ++b) { | |
395 | if (irqstatus & (1 << b)) | |
396 | irq_arr[b]++; | |
397 | } | |
398 | } | |
399 | #endif | |
400 | ||
0a20170a TV |
401 | /* PLL */ |
402 | typedef bool (*dss_pll_calc_func)(int n, int m, unsigned long fint, | |
403 | unsigned long clkdco, void *data); | |
404 | typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc, | |
405 | void *data); | |
406 | ||
407 | int dss_pll_register(struct dss_pll *pll); | |
408 | void dss_pll_unregister(struct dss_pll *pll); | |
409 | struct dss_pll *dss_pll_find(const char *name); | |
5670bd72 | 410 | struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src); |
d11e5c82 | 411 | unsigned int dss_pll_get_clkout_idx_for_src(enum dss_clk_source src); |
0a20170a TV |
412 | int dss_pll_enable(struct dss_pll *pll); |
413 | void dss_pll_disable(struct dss_pll *pll); | |
414 | int dss_pll_set_config(struct dss_pll *pll, | |
415 | const struct dss_pll_clock_info *cinfo); | |
416 | ||
cd0715ff | 417 | bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco, |
0a20170a TV |
418 | unsigned long out_min, unsigned long out_max, |
419 | dss_hsdiv_calc_func func, void *data); | |
cd0715ff | 420 | bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin, |
0a20170a TV |
421 | unsigned long pll_min, unsigned long pll_max, |
422 | dss_pll_calc_func func, void *data); | |
c17dc0e3 TV |
423 | |
424 | bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin, | |
c107751d | 425 | unsigned long target_clkout, struct dss_pll_clock_info *cinfo); |
c17dc0e3 | 426 | |
0a20170a TV |
427 | int dss_pll_write_config_type_a(struct dss_pll *pll, |
428 | const struct dss_pll_clock_info *cinfo); | |
429 | int dss_pll_write_config_type_b(struct dss_pll *pll, | |
430 | const struct dss_pll_clock_info *cinfo); | |
eb30199b | 431 | int dss_pll_wait_reset_done(struct dss_pll *pll); |
0a20170a | 432 | |
d66c36a3 AD |
433 | extern struct platform_driver omap_dsshw_driver; |
434 | extern struct platform_driver omap_dispchw_driver; | |
435 | #ifdef CONFIG_OMAP2_DSS_DSI | |
436 | extern struct platform_driver omap_dsihw_driver; | |
437 | #endif | |
438 | #ifdef CONFIG_OMAP2_DSS_VENC | |
439 | extern struct platform_driver omap_venchw_driver; | |
440 | #endif | |
441 | #ifdef CONFIG_OMAP4_DSS_HDMI | |
442 | extern struct platform_driver omapdss_hdmi4hw_driver; | |
443 | #endif | |
444 | #ifdef CONFIG_OMAP5_DSS_HDMI | |
445 | extern struct platform_driver omapdss_hdmi5hw_driver; | |
446 | #endif | |
447 | ||
559d6701 | 448 | #endif |