Commit | Line | Data |
---|---|---|
f76ee892 TV |
1 | /* |
2 | * linux/drivers/video/omap2/dss/dss.h | |
3 | * | |
4 | * Copyright (C) 2009 Nokia Corporation | |
5 | * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | |
6 | * | |
7 | * Some code and ideas taken from drivers/video/omap/ driver | |
8 | * by Imre Deak. | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify it | |
11 | * under the terms of the GNU General Public License version 2 as published by | |
12 | * the Free Software Foundation. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
17 | * more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License along with | |
20 | * this program. If not, see <http://www.gnu.org/licenses/>. | |
21 | */ | |
22 | ||
23 | #ifndef __OMAP2_DSS_H | |
24 | #define __OMAP2_DSS_H | |
25 | ||
26 | #include <linux/interrupt.h> | |
27 | ||
28 | #ifdef pr_fmt | |
29 | #undef pr_fmt | |
30 | #endif | |
31 | ||
32 | #ifdef DSS_SUBSYS_NAME | |
33 | #define pr_fmt(fmt) DSS_SUBSYS_NAME ": " fmt | |
34 | #else | |
35 | #define pr_fmt(fmt) fmt | |
36 | #endif | |
37 | ||
38 | #define DSSDBG(format, ...) \ | |
39 | pr_debug(format, ## __VA_ARGS__) | |
40 | ||
41 | #ifdef DSS_SUBSYS_NAME | |
42 | #define DSSERR(format, ...) \ | |
43 | printk(KERN_ERR "omapdss " DSS_SUBSYS_NAME " error: " format, \ | |
44 | ## __VA_ARGS__) | |
45 | #else | |
46 | #define DSSERR(format, ...) \ | |
47 | printk(KERN_ERR "omapdss error: " format, ## __VA_ARGS__) | |
48 | #endif | |
49 | ||
50 | #ifdef DSS_SUBSYS_NAME | |
51 | #define DSSINFO(format, ...) \ | |
52 | printk(KERN_INFO "omapdss " DSS_SUBSYS_NAME ": " format, \ | |
53 | ## __VA_ARGS__) | |
54 | #else | |
55 | #define DSSINFO(format, ...) \ | |
56 | printk(KERN_INFO "omapdss: " format, ## __VA_ARGS__) | |
57 | #endif | |
58 | ||
59 | #ifdef DSS_SUBSYS_NAME | |
60 | #define DSSWARN(format, ...) \ | |
61 | printk(KERN_WARNING "omapdss " DSS_SUBSYS_NAME ": " format, \ | |
62 | ## __VA_ARGS__) | |
63 | #else | |
64 | #define DSSWARN(format, ...) \ | |
65 | printk(KERN_WARNING "omapdss: " format, ## __VA_ARGS__) | |
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 | ||
76 | enum dss_io_pad_mode { | |
77 | DSS_IO_PAD_MODE_RESET, | |
78 | DSS_IO_PAD_MODE_RFBI, | |
79 | DSS_IO_PAD_MODE_BYPASS, | |
80 | }; | |
81 | ||
82 | enum dss_hdmi_venc_clk_source_select { | |
83 | DSS_VENC_TV_CLK = 0, | |
84 | DSS_HDMI_M_PCLK = 1, | |
85 | }; | |
86 | ||
87 | enum dss_dsi_content_type { | |
88 | DSS_DSI_CONTENT_DCS, | |
89 | DSS_DSI_CONTENT_GENERIC, | |
90 | }; | |
91 | ||
92 | enum dss_writeback_channel { | |
93 | DSS_WB_LCD1_MGR = 0, | |
94 | DSS_WB_LCD2_MGR = 1, | |
95 | DSS_WB_TV_MGR = 2, | |
96 | DSS_WB_OVL0 = 3, | |
97 | DSS_WB_OVL1 = 4, | |
98 | DSS_WB_OVL2 = 5, | |
99 | DSS_WB_OVL3 = 6, | |
100 | DSS_WB_LCD3_MGR = 7, | |
101 | }; | |
102 | ||
103 | enum dss_pll_id { | |
104 | DSS_PLL_DSI1, | |
105 | DSS_PLL_DSI2, | |
106 | DSS_PLL_HDMI, | |
107 | DSS_PLL_VIDEO1, | |
108 | DSS_PLL_VIDEO2, | |
109 | }; | |
110 | ||
111 | struct dss_pll; | |
112 | ||
113 | #define DSS_PLL_MAX_HSDIVS 4 | |
114 | ||
115 | /* | |
116 | * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7. | |
117 | * Type-B PLLs: clkout[0] refers to m2. | |
118 | */ | |
119 | struct dss_pll_clock_info { | |
120 | /* rates that we get with dividers below */ | |
121 | unsigned long fint; | |
122 | unsigned long clkdco; | |
123 | unsigned long clkout[DSS_PLL_MAX_HSDIVS]; | |
124 | ||
125 | /* dividers */ | |
126 | u16 n; | |
127 | u16 m; | |
128 | u32 mf; | |
129 | u16 mX[DSS_PLL_MAX_HSDIVS]; | |
130 | u16 sd; | |
131 | }; | |
132 | ||
133 | struct dss_pll_ops { | |
134 | int (*enable)(struct dss_pll *pll); | |
135 | void (*disable)(struct dss_pll *pll); | |
136 | int (*set_config)(struct dss_pll *pll, | |
137 | const struct dss_pll_clock_info *cinfo); | |
138 | }; | |
139 | ||
140 | struct dss_pll_hw { | |
141 | unsigned n_max; | |
142 | unsigned m_min; | |
143 | unsigned m_max; | |
144 | unsigned mX_max; | |
145 | ||
146 | unsigned long fint_min, fint_max; | |
147 | unsigned long clkdco_min, clkdco_low, clkdco_max; | |
148 | ||
149 | u8 n_msb, n_lsb; | |
150 | u8 m_msb, m_lsb; | |
151 | u8 mX_msb[DSS_PLL_MAX_HSDIVS], mX_lsb[DSS_PLL_MAX_HSDIVS]; | |
152 | ||
153 | bool has_stopmode; | |
154 | bool has_freqsel; | |
155 | bool has_selfreqdco; | |
156 | bool has_refsel; | |
157 | }; | |
158 | ||
159 | struct dss_pll { | |
160 | const char *name; | |
161 | enum dss_pll_id id; | |
162 | ||
163 | struct clk *clkin; | |
164 | struct regulator *regulator; | |
165 | ||
166 | void __iomem *base; | |
167 | ||
168 | const struct dss_pll_hw *hw; | |
169 | ||
170 | const struct dss_pll_ops *ops; | |
171 | ||
172 | struct dss_pll_clock_info cinfo; | |
173 | }; | |
174 | ||
175 | struct dispc_clock_info { | |
176 | /* rates that we get with dividers below */ | |
177 | unsigned long lck; | |
178 | unsigned long pck; | |
179 | ||
180 | /* dividers */ | |
181 | u16 lck_div; | |
182 | u16 pck_div; | |
183 | }; | |
184 | ||
185 | struct dss_lcd_mgr_config { | |
186 | enum dss_io_pad_mode io_pad_mode; | |
187 | ||
188 | bool stallmode; | |
189 | bool fifohandcheck; | |
190 | ||
191 | struct dispc_clock_info clock_info; | |
192 | ||
193 | int video_port_width; | |
194 | ||
195 | int lcden_sig_polarity; | |
196 | }; | |
197 | ||
198 | struct seq_file; | |
199 | struct platform_device; | |
200 | ||
201 | /* core */ | |
202 | struct platform_device *dss_get_core_pdev(void); | |
203 | int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask); | |
204 | void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); | |
205 | int dss_set_min_bus_tput(struct device *dev, unsigned long tput); | |
206 | int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); | |
207 | ||
208 | /* display */ | |
209 | int dss_suspend_all_devices(void); | |
210 | int dss_resume_all_devices(void); | |
211 | void dss_disable_all_devices(void); | |
212 | ||
213 | int display_init_sysfs(struct platform_device *pdev); | |
214 | void display_uninit_sysfs(struct platform_device *pdev); | |
215 | ||
216 | /* manager */ | |
217 | int dss_init_overlay_managers(void); | |
218 | void dss_uninit_overlay_managers(void); | |
219 | int dss_init_overlay_managers_sysfs(struct platform_device *pdev); | |
220 | void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev); | |
221 | int dss_mgr_simple_check(struct omap_overlay_manager *mgr, | |
222 | const struct omap_overlay_manager_info *info); | |
223 | int dss_mgr_check_timings(struct omap_overlay_manager *mgr, | |
224 | const struct omap_video_timings *timings); | |
225 | int dss_mgr_check(struct omap_overlay_manager *mgr, | |
226 | struct omap_overlay_manager_info *info, | |
227 | const struct omap_video_timings *mgr_timings, | |
228 | const struct dss_lcd_mgr_config *config, | |
229 | struct omap_overlay_info **overlay_infos); | |
230 | ||
231 | static inline bool dss_mgr_is_lcd(enum omap_channel id) | |
232 | { | |
233 | if (id == OMAP_DSS_CHANNEL_LCD || id == OMAP_DSS_CHANNEL_LCD2 || | |
234 | id == OMAP_DSS_CHANNEL_LCD3) | |
235 | return true; | |
236 | else | |
237 | return false; | |
238 | } | |
239 | ||
240 | int dss_manager_kobj_init(struct omap_overlay_manager *mgr, | |
241 | struct platform_device *pdev); | |
242 | void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr); | |
243 | ||
244 | /* overlay */ | |
245 | void dss_init_overlays(struct platform_device *pdev); | |
246 | void dss_uninit_overlays(struct platform_device *pdev); | |
247 | void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr); | |
248 | int dss_ovl_simple_check(struct omap_overlay *ovl, | |
249 | const struct omap_overlay_info *info); | |
250 | int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, | |
251 | const struct omap_video_timings *mgr_timings); | |
252 | bool dss_ovl_use_replication(struct dss_lcd_mgr_config config, | |
253 | enum omap_color_mode mode); | |
254 | int dss_overlay_kobj_init(struct omap_overlay *ovl, | |
255 | struct platform_device *pdev); | |
256 | void dss_overlay_kobj_uninit(struct omap_overlay *ovl); | |
257 | ||
258 | /* DSS */ | |
259 | int dss_init_platform_driver(void) __init; | |
260 | void dss_uninit_platform_driver(void); | |
261 | ||
262 | int dss_runtime_get(void); | |
263 | void dss_runtime_put(void); | |
264 | ||
265 | unsigned long dss_get_dispc_clk_rate(void); | |
266 | int dss_dpi_select_source(int port, enum omap_channel channel); | |
267 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); | |
268 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); | |
269 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); | |
270 | void dss_dump_clocks(struct seq_file *s); | |
271 | ||
272 | /* DSS VIDEO PLL */ | |
273 | struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id, | |
274 | struct regulator *regulator); | |
275 | void dss_video_pll_uninit(struct dss_pll *pll); | |
276 | ||
277 | /* dss-of */ | |
278 | struct device_node *dss_of_port_get_parent_device(struct device_node *port); | |
279 | u32 dss_of_port_get_port_number(struct device_node *port); | |
280 | ||
35b522cf | 281 | #if defined(CONFIG_FB_OMAP2_DSS_DEBUGFS) |
f76ee892 TV |
282 | void dss_debug_dump_clocks(struct seq_file *s); |
283 | #endif | |
284 | ||
285 | void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable); | |
286 | void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id, | |
287 | enum omap_channel channel); | |
288 | ||
289 | void dss_sdi_init(int datapairs); | |
290 | int dss_sdi_enable(void); | |
291 | void dss_sdi_disable(void); | |
292 | ||
293 | void dss_select_dsi_clk_source(int dsi_module, | |
294 | enum omap_dss_clk_source clk_src); | |
295 | void dss_select_lcd_clk_source(enum omap_channel channel, | |
296 | enum omap_dss_clk_source clk_src); | |
297 | enum omap_dss_clk_source dss_get_dispc_clk_source(void); | |
298 | enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module); | |
299 | enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); | |
300 | ||
301 | void dss_set_venc_output(enum omap_dss_venc_type type); | |
302 | void dss_set_dac_pwrdn_bgz(bool enable); | |
303 | ||
304 | int dss_set_fck_rate(unsigned long rate); | |
305 | ||
306 | typedef bool (*dss_div_calc_func)(unsigned long fck, void *data); | |
307 | bool dss_div_calc(unsigned long pck, unsigned long fck_min, | |
308 | dss_div_calc_func func, void *data); | |
309 | ||
310 | /* SDI */ | |
311 | int sdi_init_platform_driver(void) __init; | |
312 | void sdi_uninit_platform_driver(void); | |
313 | ||
35b522cf | 314 | #ifdef CONFIG_FB_OMAP2_DSS_SDI |
f76ee892 TV |
315 | int sdi_init_port(struct platform_device *pdev, struct device_node *port); |
316 | void sdi_uninit_port(struct device_node *port); | |
317 | #else | |
318 | static inline int sdi_init_port(struct platform_device *pdev, | |
319 | struct device_node *port) | |
320 | { | |
321 | return 0; | |
322 | } | |
323 | static inline void sdi_uninit_port(struct device_node *port) | |
324 | { | |
325 | } | |
326 | #endif | |
327 | ||
328 | /* DSI */ | |
329 | ||
35b522cf | 330 | #ifdef CONFIG_FB_OMAP2_DSS_DSI |
f76ee892 TV |
331 | |
332 | struct dentry; | |
333 | struct file_operations; | |
334 | ||
335 | int dsi_init_platform_driver(void) __init; | |
336 | void dsi_uninit_platform_driver(void); | |
337 | ||
338 | void dsi_dump_clocks(struct seq_file *s); | |
339 | ||
340 | void dsi_irq_handler(void); | |
341 | u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); | |
342 | ||
343 | #else | |
344 | static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) | |
345 | { | |
346 | WARN(1, "%s: DSI not compiled in, returning pixel_size as 0\n", | |
347 | __func__); | |
348 | return 0; | |
349 | } | |
350 | #endif | |
351 | ||
352 | /* DPI */ | |
353 | int dpi_init_platform_driver(void) __init; | |
354 | void dpi_uninit_platform_driver(void); | |
355 | ||
35b522cf | 356 | #ifdef CONFIG_FB_OMAP2_DSS_DPI |
f76ee892 TV |
357 | int dpi_init_port(struct platform_device *pdev, struct device_node *port); |
358 | void dpi_uninit_port(struct device_node *port); | |
359 | #else | |
360 | static inline int dpi_init_port(struct platform_device *pdev, | |
361 | struct device_node *port) | |
362 | { | |
363 | return 0; | |
364 | } | |
365 | static inline void dpi_uninit_port(struct device_node *port) | |
366 | { | |
367 | } | |
368 | #endif | |
369 | ||
370 | /* DISPC */ | |
371 | int dispc_init_platform_driver(void) __init; | |
372 | void dispc_uninit_platform_driver(void); | |
373 | void dispc_dump_clocks(struct seq_file *s); | |
374 | ||
375 | void dispc_enable_sidle(void); | |
376 | void dispc_disable_sidle(void); | |
377 | ||
378 | void dispc_lcd_enable_signal(bool enable); | |
379 | void dispc_pck_free_enable(bool enable); | |
380 | void dispc_enable_fifomerge(bool enable); | |
381 | void dispc_enable_gamma_table(bool enable); | |
382 | ||
383 | typedef bool (*dispc_div_calc_func)(int lckd, int pckd, unsigned long lck, | |
384 | unsigned long pck, void *data); | |
385 | bool dispc_div_calc(unsigned long dispc, | |
386 | unsigned long pck_min, unsigned long pck_max, | |
387 | dispc_div_calc_func func, void *data); | |
388 | ||
389 | bool dispc_mgr_timings_ok(enum omap_channel channel, | |
390 | const struct omap_video_timings *timings); | |
391 | int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, | |
392 | struct dispc_clock_info *cinfo); | |
393 | ||
394 | ||
395 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); | |
396 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | |
397 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, | |
398 | bool manual_update); | |
399 | ||
400 | void dispc_mgr_set_clock_div(enum omap_channel channel, | |
401 | const struct dispc_clock_info *cinfo); | |
402 | int dispc_mgr_get_clock_div(enum omap_channel channel, | |
403 | struct dispc_clock_info *cinfo); | |
404 | void dispc_set_tv_pclk(unsigned long pclk); | |
405 | ||
406 | u32 dispc_wb_get_framedone_irq(void); | |
407 | bool dispc_wb_go_busy(void); | |
408 | void dispc_wb_go(void); | |
409 | void dispc_wb_enable(bool enable); | |
410 | bool dispc_wb_is_enabled(void); | |
411 | void dispc_wb_set_channel_in(enum dss_writeback_channel channel); | |
412 | int dispc_wb_setup(const struct omap_dss_writeback_info *wi, | |
413 | bool mem_to_mem, const struct omap_video_timings *timings); | |
414 | ||
35a339ac TV |
415 | u32 dispc_read_irqstatus(void); |
416 | void dispc_clear_irqstatus(u32 mask); | |
417 | u32 dispc_read_irqenable(void); | |
418 | void dispc_write_irqenable(u32 mask); | |
419 | ||
420 | int dispc_request_irq(irq_handler_t handler, void *dev_id); | |
421 | void dispc_free_irq(void *dev_id); | |
422 | ||
423 | int dispc_runtime_get(void); | |
424 | void dispc_runtime_put(void); | |
425 | ||
426 | void dispc_mgr_enable(enum omap_channel channel, bool enable); | |
427 | bool dispc_mgr_is_enabled(enum omap_channel channel); | |
428 | u32 dispc_mgr_get_vsync_irq(enum omap_channel channel); | |
429 | u32 dispc_mgr_get_framedone_irq(enum omap_channel channel); | |
430 | u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel); | |
431 | bool dispc_mgr_go_busy(enum omap_channel channel); | |
432 | void dispc_mgr_go(enum omap_channel channel); | |
433 | void dispc_mgr_set_lcd_config(enum omap_channel channel, | |
434 | const struct dss_lcd_mgr_config *config); | |
435 | void dispc_mgr_set_timings(enum omap_channel channel, | |
436 | const struct omap_video_timings *timings); | |
437 | void dispc_mgr_setup(enum omap_channel channel, | |
438 | const struct omap_overlay_manager_info *info); | |
439 | ||
440 | int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel, | |
441 | const struct omap_overlay_info *oi, | |
442 | const struct omap_video_timings *timings, | |
443 | int *x_predecim, int *y_predecim); | |
444 | ||
445 | int dispc_ovl_enable(enum omap_plane plane, bool enable); | |
446 | bool dispc_ovl_enabled(enum omap_plane plane); | |
447 | void dispc_ovl_set_channel_out(enum omap_plane plane, | |
448 | enum omap_channel channel); | |
449 | int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, | |
450 | bool replication, const struct omap_video_timings *mgr_timings, | |
451 | bool mem_to_mem); | |
452 | ||
f76ee892 TV |
453 | /* VENC */ |
454 | int venc_init_platform_driver(void) __init; | |
455 | void venc_uninit_platform_driver(void); | |
456 | ||
457 | /* HDMI */ | |
458 | int hdmi4_init_platform_driver(void) __init; | |
459 | void hdmi4_uninit_platform_driver(void); | |
460 | ||
461 | int hdmi5_init_platform_driver(void) __init; | |
462 | void hdmi5_uninit_platform_driver(void); | |
463 | ||
464 | /* RFBI */ | |
465 | int rfbi_init_platform_driver(void) __init; | |
466 | void rfbi_uninit_platform_driver(void); | |
467 | ||
468 | ||
35b522cf | 469 | #ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS |
f76ee892 TV |
470 | static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) |
471 | { | |
472 | int b; | |
473 | for (b = 0; b < 32; ++b) { | |
474 | if (irqstatus & (1 << b)) | |
475 | irq_arr[b]++; | |
476 | } | |
477 | } | |
478 | #endif | |
479 | ||
480 | /* PLL */ | |
481 | typedef bool (*dss_pll_calc_func)(int n, int m, unsigned long fint, | |
482 | unsigned long clkdco, void *data); | |
483 | typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc, | |
484 | void *data); | |
485 | ||
486 | int dss_pll_register(struct dss_pll *pll); | |
487 | void dss_pll_unregister(struct dss_pll *pll); | |
488 | struct dss_pll *dss_pll_find(const char *name); | |
489 | int dss_pll_enable(struct dss_pll *pll); | |
490 | void dss_pll_disable(struct dss_pll *pll); | |
491 | int dss_pll_set_config(struct dss_pll *pll, | |
492 | const struct dss_pll_clock_info *cinfo); | |
493 | ||
494 | bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco, | |
495 | unsigned long out_min, unsigned long out_max, | |
496 | dss_hsdiv_calc_func func, void *data); | |
497 | bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin, | |
498 | unsigned long pll_min, unsigned long pll_max, | |
499 | dss_pll_calc_func func, void *data); | |
500 | int dss_pll_write_config_type_a(struct dss_pll *pll, | |
501 | const struct dss_pll_clock_info *cinfo); | |
502 | int dss_pll_write_config_type_b(struct dss_pll *pll, | |
503 | const struct dss_pll_clock_info *cinfo); | |
504 | int dss_pll_wait_reset_done(struct dss_pll *pll); | |
505 | ||
506 | #endif |