]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/video/tegra/dc/dc_priv.h
f488dcdc497d52db1a5fdbd18299beef1a94a5fe
[sojka/nv-tegra/linux-3.10.git] / drivers / video / tegra / dc / dc_priv.h
1 /*
2  * drivers/video/tegra/dc/dc_priv.h
3  *
4  * Copyright (C) 2010 Google, Inc.
5  * Author: Erik Gilling <konkers@android.com>
6  *
7  * Copyright (c) 2010-2014, NVIDIA CORPORATION, All rights reserved.
8  *
9  * This software is licensed under the terms of the GNU General Public
10  * License version 2, as published by the Free Software Foundation, and
11  * may be copied, distributed, and modified under those terms.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  */
19
20 #ifndef __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_H
21 #define __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_H
22
23 #include "dc_priv_defs.h"
24 #ifndef CREATE_TRACE_POINTS
25 # include <trace/events/display.h>
26 #define WIN_IS_BLOCKLINEAR(win) ((win)->flags & TEGRA_WIN_FLAG_BLOCKLINEAR)
27 #endif
28 #include <linux/tegra-powergate.h>
29 #include <video/tegra_dc_ext.h>
30
31
32 #define WIN_IS_TILED(win)       ((win)->flags & TEGRA_WIN_FLAG_TILED)
33 #define WIN_IS_ENABLED(win)     ((win)->flags & TEGRA_WIN_FLAG_ENABLED)
34 #define WIN_IS_FB(win)          ((win)->flags & TEGRA_WIN_FLAG_FB)
35
36 #define WIN_IS_INTERLACE(win) ((win)->flags & TEGRA_WIN_FLAG_INTERLACE)
37
38 #if defined(CONFIG_ARCH_TEGRA_14x_SOC)
39 #define WIN_ALL_ACT_REQ (WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | \
40         WIN_D_ACT_REQ | WIN_H_ACT_REQ)
41 #else
42 #define WIN_ALL_ACT_REQ (WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ)
43 #endif
44
45 static inline int tegra_dc_io_start(struct tegra_dc *dc)
46 {
47         return nvhost_module_busy_ext(dc->ndev);
48 }
49
50 static inline void tegra_dc_io_end(struct tegra_dc *dc)
51 {
52         nvhost_module_idle_ext(dc->ndev);
53 }
54
55 static inline unsigned long tegra_dc_readl(struct tegra_dc *dc,
56                                            unsigned long reg)
57 {
58         unsigned long ret;
59
60         BUG_ON(!nvhost_module_powered_ext(dc->ndev));
61
62         if (WARN(!tegra_is_clk_enabled(dc->clk), "DC is clock-gated.\n") ||
63                 WARN(!tegra_powergate_is_powered(dc->powergate_id),
64                         "DC is power-gated.\n"))
65                 return 0;
66
67         ret = readl(dc->base + reg * 4);
68         trace_display_readl(dc, ret, dc->base + reg * 4);
69         return ret;
70 }
71
72 static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long val,
73                                    unsigned long reg)
74 {
75         BUG_ON(!nvhost_module_powered_ext(dc->ndev));
76
77         if (WARN(!tegra_is_clk_enabled(dc->clk), "DC is clock-gated.\n") ||
78                 WARN(!tegra_powergate_is_powered(dc->powergate_id),
79                         "DC is power-gated.\n"))
80                 return;
81
82         trace_display_writel(dc, val, dc->base + reg * 4);
83         writel(val, dc->base + reg * 4);
84 }
85
86 static inline void tegra_dc_power_on(struct tegra_dc *dc)
87 {
88         tegra_dc_writel(dc, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
89                                         PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
90                                         DC_CMD_DISPLAY_POWER_CONTROL);
91 }
92
93 static inline void _tegra_dc_write_table(struct tegra_dc *dc, const u32 *table,
94                                          unsigned len)
95 {
96         int i;
97
98         for (i = 0; i < len; i++)
99                 tegra_dc_writel(dc, table[i * 2 + 1], table[i * 2]);
100 }
101
102 #define tegra_dc_write_table(dc, table)         \
103         _tegra_dc_write_table(dc, table, ARRAY_SIZE(table) / 2)
104
105 static inline void tegra_dc_set_outdata(struct tegra_dc *dc, void *data)
106 {
107         dc->out_data = data;
108 }
109
110 static inline void *tegra_dc_get_outdata(struct tegra_dc *dc)
111 {
112         return dc->out_data;
113 }
114
115 static inline unsigned long tegra_dc_get_default_emc_clk_rate(
116         struct tegra_dc *dc)
117 {
118         return dc->pdata->emc_clk_rate ? dc->pdata->emc_clk_rate : ULONG_MAX;
119 }
120
121 /* return the color format field */
122 static inline int tegra_dc_fmt(int fmt)
123 {
124         return (fmt & TEGRA_DC_EXT_FMT_MASK) >> TEGRA_DC_EXT_FMT_SHIFT;
125 }
126
127 /* return the byte swap field */
128 static inline int tegra_dc_fmt_byteorder(int fmt)
129 {
130         return (fmt & TEGRA_DC_EXT_FMT_BYTEORDER_MASK) >>
131                 TEGRA_DC_EXT_FMT_BYTEORDER_SHIFT;
132 }
133
134 static inline int tegra_dc_fmt_bpp(int fmt)
135 {
136         switch (tegra_dc_fmt(fmt)) {
137         case TEGRA_WIN_FMT_P1:
138                 return 1;
139
140         case TEGRA_WIN_FMT_P2:
141                 return 2;
142
143         case TEGRA_WIN_FMT_P4:
144                 return 4;
145
146         case TEGRA_WIN_FMT_P8:
147                 return 8;
148
149         case TEGRA_WIN_FMT_B4G4R4A4:
150         case TEGRA_WIN_FMT_B5G5R5A:
151         case TEGRA_WIN_FMT_B5G6R5:
152         case TEGRA_WIN_FMT_AB5G5R5:
153                 return 16;
154
155         case TEGRA_WIN_FMT_B8G8R8A8:
156         case TEGRA_WIN_FMT_R8G8B8A8:
157         case TEGRA_WIN_FMT_B6x2G6x2R6x2A8:
158         case TEGRA_WIN_FMT_R6x2G6x2B6x2A8:
159                 return 32;
160
161         /* for planar formats, size of the Y plane, 8bit */
162         case TEGRA_WIN_FMT_YCbCr420P:
163         case TEGRA_WIN_FMT_YUV420P:
164         case TEGRA_WIN_FMT_YCbCr422P:
165         case TEGRA_WIN_FMT_YUV422P:
166         case TEGRA_WIN_FMT_YCbCr422R:
167         case TEGRA_WIN_FMT_YUV422R:
168         case TEGRA_WIN_FMT_YCbCr422RA:
169         case TEGRA_WIN_FMT_YUV422RA:
170         case TEGRA_WIN_FMT_YCbCr444P:
171         case TEGRA_WIN_FMT_YUV444P:
172         case TEGRA_WIN_FMT_YUV422SP:
173         case TEGRA_WIN_FMT_YUV420SP:
174         case TEGRA_WIN_FMT_YCbCr420SP:
175         case TEGRA_WIN_FMT_YCbCr422SP:
176                 return 8;
177
178         /* YUYV packed into 32-bits */
179         case TEGRA_WIN_FMT_YCbCr422:
180         case TEGRA_WIN_FMT_YUV422:
181                 return 16;
182         }
183         return 0;
184 }
185
186 static inline bool tegra_dc_is_yuv(int fmt)
187 {
188         switch (tegra_dc_fmt(fmt)) {
189         case TEGRA_WIN_FMT_YUV420P:
190         case TEGRA_WIN_FMT_YCbCr420P:
191         case TEGRA_WIN_FMT_YCbCr422P:
192         case TEGRA_WIN_FMT_YUV422P:
193         case TEGRA_WIN_FMT_YCbCr422:
194         case TEGRA_WIN_FMT_YUV422:
195         case TEGRA_WIN_FMT_YCbCr422R:
196         case TEGRA_WIN_FMT_YUV422R:
197         case TEGRA_WIN_FMT_YCbCr422RA:
198         case TEGRA_WIN_FMT_YUV422RA:
199         case TEGRA_WIN_FMT_YCbCr444P:
200         case TEGRA_WIN_FMT_YUV444P:
201         case TEGRA_WIN_FMT_YUV422SP:
202         case TEGRA_WIN_FMT_YCbCr422SP:
203         case TEGRA_WIN_FMT_YCbCr420SP:
204         case TEGRA_WIN_FMT_YUV420SP:
205                 return true;
206         }
207         return false;
208 }
209
210 static inline bool tegra_dc_is_yuv_planar(int fmt)
211 {
212         switch (tegra_dc_fmt(fmt)) {
213         case TEGRA_WIN_FMT_YUV420P:
214         case TEGRA_WIN_FMT_YCbCr420P:
215         case TEGRA_WIN_FMT_YCbCr422P:
216         case TEGRA_WIN_FMT_YUV422P:
217         case TEGRA_WIN_FMT_YCbCr422R:
218         case TEGRA_WIN_FMT_YUV422R:
219         case TEGRA_WIN_FMT_YCbCr422RA:
220         case TEGRA_WIN_FMT_YUV422RA:
221         case TEGRA_WIN_FMT_YCbCr444P:
222         case TEGRA_WIN_FMT_YUV444P:
223                 return true;
224         }
225         return false;
226 }
227
228 static inline bool tegra_dc_is_yuv_full_planar(int fmt)
229 {
230         switch (fmt) {
231         case TEGRA_WIN_FMT_YCbCr444P:
232         case TEGRA_WIN_FMT_YUV444P:
233                 return true;
234         }
235         return false;
236 }
237
238 static inline bool tegra_dc_is_yuv_semi_planar(int fmt)
239 {
240         switch (fmt) {
241         case TEGRA_WIN_FMT_YUV420SP:
242         case TEGRA_WIN_FMT_YCbCr420SP:
243         case TEGRA_WIN_FMT_YCbCr422SP:
244         case TEGRA_WIN_FMT_YUV422SP:
245                 return true;
246         }
247         return false;
248 }
249
250 static inline u32 tegra_dc_unmask_interrupt(struct tegra_dc *dc, u32 int_val)
251 {
252         u32 val;
253
254         val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
255         tegra_dc_writel(dc, val | int_val, DC_CMD_INT_MASK);
256         return val;
257 }
258
259 static inline u32 tegra_dc_flush_interrupt(struct tegra_dc *dc, u32 int_val)
260 {
261         u32 val;
262         unsigned long flag;
263
264         local_irq_save(flag);
265
266         val = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
267         tegra_dc_writel(dc, (val | int_val), DC_CMD_INT_STATUS);
268
269         local_irq_restore(flag);
270
271         return val;
272 }
273
274 static inline u32 tegra_dc_mask_interrupt(struct tegra_dc *dc, u32 int_val)
275 {
276         u32 val;
277
278         val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
279         tegra_dc_writel(dc, val & ~int_val, DC_CMD_INT_MASK);
280         return val;
281 }
282
283 static inline void tegra_dc_restore_interrupt(struct tegra_dc *dc, u32 val)
284 {
285         tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
286 }
287
288 static inline unsigned long tegra_dc_clk_get_rate(struct tegra_dc *dc)
289 {
290         if (!tegra_platform_is_silicon())
291                 return dc->mode.pclk;
292
293         return clk_get_rate(dc->clk);
294 }
295
296 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
297 static inline void tegra_dc_powergate_locked(struct tegra_dc *dc)
298 {
299         tegra_powergate_partition(dc->powergate_id);
300 }
301
302 static inline void tegra_dc_unpowergate_locked(struct tegra_dc *dc)
303 {
304         int ret;
305         ret = tegra_unpowergate_partition(dc->powergate_id);
306         if (ret < 0)
307                 dev_err(&dc->ndev->dev, "%s: could not unpowergate %d\n",
308                                                         __func__, ret);
309 }
310
311 static inline bool tegra_dc_is_powered(struct tegra_dc *dc)
312 {
313         return tegra_powergate_is_powered(dc->powergate_id);
314 }
315
316 static inline void tegra_dc_set_edid(struct tegra_dc *dc,
317         struct tegra_edid *edid)
318 {
319         dc->edid = edid;
320 }
321
322 void tegra_dc_powergate_locked(struct tegra_dc *dc);
323 void tegra_dc_unpowergate_locked(struct tegra_dc *dc);
324 #else
325 static inline void tegra_dc_powergate_locked(struct tegra_dc *dc) { }
326 static inline void tegra_dc_unpowergate_locked(struct tegra_dc *dc) { }
327 static inline bool tegra_dc_is_powered(struct tegra_dc *dc)
328 {
329         return true;
330 }
331 #endif
332
333 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
334 static inline u32 tegra_dc_reg_l32(dma_addr_t v)
335 {
336         return v & 0xffffffff;
337 }
338
339 static inline u32 tegra_dc_reg_h32(dma_addr_t v)
340 {
341         return v >> 32;
342 }
343 #else
344 static inline u32 tegra_dc_reg_l32(dma_addr_t v)
345 {
346         return v;
347 }
348
349 static inline u32 tegra_dc_reg_h32(dma_addr_t v)
350 {
351         return 0;
352 }
353 #endif
354 extern struct tegra_dc_out_ops tegra_dc_rgb_ops;
355 extern struct tegra_dc_out_ops tegra_dc_hdmi_ops;
356 extern struct tegra_dc_out_ops tegra_dc_dsi_ops;
357 #ifdef CONFIG_TEGRA_DP
358 extern struct tegra_dc_out_ops tegra_dc_dp_ops;
359 #endif
360 #ifdef CONFIG_TEGRA_LVDS
361 extern struct tegra_dc_out_ops tegra_dc_lvds_ops;
362 #endif
363 #ifdef CONFIG_TEGRA_NVSR
364 extern struct tegra_dc_out_ops tegra_dc_nvsr_ops;
365 #endif
366
367 /* defined in dc_sysfs.c, used by dc.c */
368 void tegra_dc_remove_sysfs(struct device *dev);
369 void tegra_dc_create_sysfs(struct device *dev);
370
371 /* defined in dc.c, used by dc_sysfs.c */
372 void tegra_dc_stats_enable(struct tegra_dc *dc, bool enable);
373 bool tegra_dc_stats_get(struct tegra_dc *dc);
374
375 /* defined in dc.c, used by dc_sysfs.c */
376 u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc);
377 void tegra_dc_enable_crc(struct tegra_dc *dc);
378 void tegra_dc_disable_crc(struct tegra_dc *dc);
379
380 void tegra_dc_set_out_pin_polars(struct tegra_dc *dc,
381                                 const struct tegra_dc_out_pin *pins,
382                                 const unsigned int n_pins);
383 /* defined in dc.c, used in bandwidth.c and ext/dev.c */
384 unsigned int tegra_dc_has_multiple_dc(void);
385
386 /* defined in dc.c, used in dsi.c */
387 void tegra_dc_clk_enable(struct tegra_dc *dc);
388 void tegra_dc_clk_disable(struct tegra_dc *dc);
389
390 /* defined in dc.c, used in nvsd.c and dsi.c */
391 void tegra_dc_get(struct tegra_dc *dc);
392 void tegra_dc_put(struct tegra_dc *dc);
393
394 /* defined in dc.c, used in window.c */
395 void tegra_dc_hold_dc_out(struct tegra_dc *dc);
396 void tegra_dc_release_dc_out(struct tegra_dc *dc);
397
398 /* defined in bandwidth.c, used in dc.c */
399 void tegra_dc_clear_bandwidth(struct tegra_dc *dc);
400 void tegra_dc_program_bandwidth(struct tegra_dc *dc, bool use_new);
401 int tegra_dc_set_dynamic_emc(struct tegra_dc *dc);
402 #ifdef CONFIG_TEGRA_ISOMGR
403 int tegra_dc_bandwidth_negotiate_bw(struct tegra_dc *dc,
404                         struct tegra_dc_win *windows[], int n);
405 void tegra_dc_bandwidth_renegotiate(void *p, u32 avail_bw);
406 #endif
407 long tegra_dc_calc_min_bandwidth(struct tegra_dc *dc);
408
409 /* defined in mode.c, used in dc.c and window.c */
410 int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode);
411 int tegra_dc_calc_refresh(const struct tegra_dc_mode *m);
412 int tegra_dc_update_mode(struct tegra_dc *dc);
413
414 /* defined in clock.c, used in dc.c, rgb.c, dsi.c and hdmi.c */
415 void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk);
416 unsigned long tegra_dc_pclk_round_rate(struct tegra_dc *dc, int pclk);
417 unsigned long tegra_dc_pclk_predict_rate(struct clk *parent, int pclk);
418
419 /* defined in lut.c, used in dc.c */
420 void tegra_dc_init_lut_defaults(struct tegra_dc_lut *lut);
421 void tegra_dc_set_lut(struct tegra_dc *dc, struct tegra_dc_win *win);
422
423 /* defined in csc.c, used in dc.c */
424 void tegra_dc_init_csc_defaults(struct tegra_dc_csc *csc);
425 void tegra_dc_set_csc(struct tegra_dc *dc, struct tegra_dc_csc *csc);
426
427 /* defined in window.c, used in dc.c */
428 void tegra_dc_trigger_windows(struct tegra_dc *dc);
429
430 void tegra_dc_set_color_control(struct tegra_dc *dc);
431 #ifdef CONFIG_TEGRA_DC_CMU
432 void tegra_dc_cmu_enable(struct tegra_dc *dc, bool cmu_enable);
433 int tegra_dc_update_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu);
434 #endif
435
436 struct tegra_dc_platform_data
437         *of_dc_parse_platform_data(struct platform_device *ndev);
438
439 #endif