Revert "Merge commit 'main-jb-2012.08.03-B4' into t114-0806"
[linux-2.6.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-2012, 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 <linux/io.h>
24 #include <linux/mutex.h>
25 #include <linux/wait.h>
26 #include <linux/fb.h>
27 #include <linux/clk.h>
28 #include <linux/completion.h>
29 #include <linux/switch.h>
30 #include <linux/nvhost.h>
31
32 #include <mach/dc.h>
33
34 #include <mach/tegra_dc_ext.h>
35 #include <mach/clk.h>
36
37 #include "dc_reg.h"
38
39 #define WIN_IS_TILED(win)       ((win)->flags & TEGRA_WIN_FLAG_TILED)
40 #define WIN_IS_ENABLED(win)     ((win)->flags & TEGRA_WIN_FLAG_ENABLED)
41
42 #define NEED_UPDATE_EMC_ON_EVERY_FRAME (windows_idle_detection_time == 0)
43
44 /* DDR: 8 bytes transfer per clock */
45 #define DDR_BW_TO_FREQ(bw) ((bw) / 8)
46
47 #if defined(CONFIG_TEGRA_EMC_TO_DDR_CLOCK)
48 #define EMC_BW_TO_FREQ(bw) (DDR_BW_TO_FREQ(bw) * CONFIG_TEGRA_EMC_TO_DDR_CLOCK)
49 #else
50 #define EMC_BW_TO_FREQ(bw) (DDR_BW_TO_FREQ(bw) * 2)
51 #endif
52
53 #ifndef CONFIG_TEGRA_FPGA_PLATFORM
54 #define ALL_UF_INT (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)
55 #else
56 /* ignore underflows when on simulation and fpga platform */
57 #define ALL_UF_INT (0)
58 #endif
59
60 struct tegra_dc;
61
62 struct tegra_dc_blend {
63         unsigned z[DC_N_WINDOWS];
64         unsigned flags[DC_N_WINDOWS];
65 };
66
67 struct tegra_dc_out_ops {
68         /* initialize output.  dc clocks are not on at this point */
69         int (*init)(struct tegra_dc *dc);
70         /* destroy output.  dc clocks are not on at this point */
71         void (*destroy)(struct tegra_dc *dc);
72         /* detect connected display.  can sleep.*/
73         bool (*detect)(struct tegra_dc *dc);
74         /* enable output.  dc clocks are on at this point */
75         void (*enable)(struct tegra_dc *dc);
76         /* disable output.  dc clocks are on at this point */
77         void (*disable)(struct tegra_dc *dc);
78         /* hold output.  keeps dc clocks on. */
79         void (*hold)(struct tegra_dc *dc);
80         /* release output.  dc clocks may turn off after this. */
81         void (*release)(struct tegra_dc *dc);
82         /* idle routine of output.  dc clocks may turn off after this. */
83         void (*idle)(struct tegra_dc *dc);
84         /* suspend output.  dc clocks are on at this point */
85         void (*suspend)(struct tegra_dc *dc);
86         /* resume output.  dc clocks are on at this point */
87         void (*resume)(struct tegra_dc *dc);
88         /* mode filter. to provide a list of supported modes*/
89         bool (*mode_filter)(const struct tegra_dc *dc,
90                         struct fb_videomode *mode);
91 };
92
93 struct tegra_dc {
94         struct nvhost_device            *ndev;
95         struct tegra_dc_platform_data   *pdata;
96
97         struct resource                 *base_res;
98         void __iomem                    *base;
99         int                             irq;
100
101         struct clk                      *clk;
102         struct clk                      *emc_clk;
103         int                             emc_clk_rate;
104         int                             new_emc_clk_rate;
105         u32                             shift_clk_div;
106
107         bool                            connected;
108         bool                            enabled;
109         bool                            suspended;
110
111         struct tegra_dc_out             *out;
112         struct tegra_dc_out_ops         *out_ops;
113         void                            *out_data;
114
115         struct tegra_dc_mode            mode;
116
117         struct tegra_dc_win             windows[DC_N_WINDOWS];
118         struct tegra_dc_blend           blend;
119         int                             n_windows;
120 #ifdef CONFIG_TEGRA_DC_CMU
121         struct tegra_dc_cmu             cmu;
122 #endif
123         wait_queue_head_t               wq;
124
125         struct mutex                    lock;
126         struct mutex                    one_shot_lock;
127
128         struct resource                 *fb_mem;
129         struct tegra_fb_info            *fb;
130
131         struct {
132                 u32                     id;
133                 u32                     min;
134                 u32                     max;
135         } syncpt[DC_N_WINDOWS];
136         u32                             vblank_syncpt;
137
138         unsigned long                   underflow_mask;
139         struct work_struct              reset_work;
140
141 #ifdef CONFIG_SWITCH
142         struct switch_dev               modeset_switch;
143 #endif
144
145         struct completion               frame_end_complete;
146
147         struct work_struct              vblank_work;
148         long                            vblank_ref_count;
149
150         struct {
151                 u64                     underflows;
152                 u64                     underflows_a;
153                 u64                     underflows_b;
154                 u64                     underflows_c;
155         } stats;
156
157         struct tegra_dc_ext             *ext;
158
159         struct tegra_dc_feature         *feature;
160         int                             gen1_blend_num;
161
162 #ifdef CONFIG_DEBUG_FS
163         struct dentry                   *debugdir;
164 #endif
165         struct tegra_dc_lut             fb_lut;
166         struct delayed_work             underflow_work;
167         u32                             one_shot_delay_ms;
168         struct delayed_work             one_shot_work;
169 };
170
171 #define print_mode_info(dc, mode) do {                                  \
172         trace_printk("%s:Mode settings: "                               \
173                         "ref_to_sync: H = %d V = %d, "                  \
174                         "sync_width: H = %d V = %d, "                   \
175                         "back_porch: H = %d V = %d, "                   \
176                         "active: H = %d V = %d, "                       \
177                         "front_porch: H = %d V = %d, "                  \
178                         "pclk = %d, stereo mode = %d\n",                \
179                         dc->ndev->name,                                 \
180                         mode.h_ref_to_sync, mode.v_ref_to_sync,         \
181                         mode.h_sync_width, mode.v_sync_width,           \
182                         mode.h_back_porch, mode.v_back_porch,           \
183                         mode.h_active, mode.v_active,                   \
184                         mode.h_front_porch, mode.v_front_porch,         \
185                         mode.pclk, mode.stereo_mode);                   \
186         } while (0)
187
188 static inline void tegra_dc_io_start(struct tegra_dc *dc)
189 {
190         nvhost_module_busy_ext(nvhost_get_parent(dc->ndev));
191 }
192
193 static inline void tegra_dc_io_end(struct tegra_dc *dc)
194 {
195         nvhost_module_idle_ext(nvhost_get_parent(dc->ndev));
196 }
197
198 static inline unsigned long tegra_dc_readl(struct tegra_dc *dc,
199                                            unsigned long reg)
200 {
201         unsigned long ret;
202
203         BUG_ON(!nvhost_module_powered_ext(to_nvhost_device(dc->ndev->dev.parent)));
204         if (!tegra_is_clk_enabled(dc->clk))
205                 WARN(1, "DC is clock-gated.\n");
206
207         ret = readl(dc->base + reg * 4);
208         trace_printk("readl %p=%#08lx\n", dc->base + reg * 4, ret);
209         return ret;
210 }
211
212 static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long val,
213                                    unsigned long reg)
214 {
215         BUG_ON(!nvhost_module_powered_ext(to_nvhost_device(dc->ndev->dev.parent)));
216         if (!tegra_is_clk_enabled(dc->clk))
217                 WARN(1, "DC is clock-gated.\n");
218
219         trace_printk("writel %p=%#08lx\n", dc->base + reg * 4, val);
220         writel(val, dc->base + reg * 4);
221 }
222
223 static inline void _tegra_dc_write_table(struct tegra_dc *dc, const u32 *table,
224                                          unsigned len)
225 {
226         int i;
227
228         for (i = 0; i < len; i++)
229                 tegra_dc_writel(dc, table[i * 2 + 1], table[i * 2]);
230 }
231
232 #define tegra_dc_write_table(dc, table)         \
233         _tegra_dc_write_table(dc, table, ARRAY_SIZE(table) / 2)
234
235 static inline void tegra_dc_set_outdata(struct tegra_dc *dc, void *data)
236 {
237         dc->out_data = data;
238 }
239
240 static inline void *tegra_dc_get_outdata(struct tegra_dc *dc)
241 {
242         return dc->out_data;
243 }
244
245 static inline unsigned long tegra_dc_get_default_emc_clk_rate(
246         struct tegra_dc *dc)
247 {
248         return dc->pdata->emc_clk_rate ? dc->pdata->emc_clk_rate : ULONG_MAX;
249 }
250
251 static inline int tegra_dc_fmt_bpp(int fmt)
252 {
253         switch (fmt) {
254         case TEGRA_WIN_FMT_P1:
255                 return 1;
256
257         case TEGRA_WIN_FMT_P2:
258                 return 2;
259
260         case TEGRA_WIN_FMT_P4:
261                 return 4;
262
263         case TEGRA_WIN_FMT_P8:
264                 return 8;
265
266         case TEGRA_WIN_FMT_B4G4R4A4:
267         case TEGRA_WIN_FMT_B5G5R5A:
268         case TEGRA_WIN_FMT_B5G6R5:
269         case TEGRA_WIN_FMT_AB5G5R5:
270                 return 16;
271
272         case TEGRA_WIN_FMT_B8G8R8A8:
273         case TEGRA_WIN_FMT_R8G8B8A8:
274         case TEGRA_WIN_FMT_B6x2G6x2R6x2A8:
275         case TEGRA_WIN_FMT_R6x2G6x2B6x2A8:
276                 return 32;
277
278         /* for planar formats, size of the Y plane, 8bit */
279         case TEGRA_WIN_FMT_YCbCr420P:
280         case TEGRA_WIN_FMT_YUV420P:
281         case TEGRA_WIN_FMT_YCbCr422P:
282         case TEGRA_WIN_FMT_YUV422P:
283         case TEGRA_WIN_FMT_YCbCr422R:
284         case TEGRA_WIN_FMT_YUV422R:
285         case TEGRA_WIN_FMT_YCbCr422RA:
286         case TEGRA_WIN_FMT_YUV422RA:
287                 return 8;
288
289         /* YUYV packed into 32-bits */
290         case TEGRA_WIN_FMT_YCbCr422:
291         case TEGRA_WIN_FMT_YUV422:
292                 return 16;
293         }
294         return 0;
295 }
296
297 static inline bool tegra_dc_is_yuv(int fmt)
298 {
299         switch (fmt) {
300         case TEGRA_WIN_FMT_YUV420P:
301         case TEGRA_WIN_FMT_YCbCr420P:
302         case TEGRA_WIN_FMT_YCbCr422P:
303         case TEGRA_WIN_FMT_YUV422P:
304         case TEGRA_WIN_FMT_YCbCr422:
305         case TEGRA_WIN_FMT_YUV422:
306         case TEGRA_WIN_FMT_YCbCr422R:
307         case TEGRA_WIN_FMT_YUV422R:
308         case TEGRA_WIN_FMT_YCbCr422RA:
309         case TEGRA_WIN_FMT_YUV422RA:
310                 return true;
311         }
312         return false;
313 }
314
315 static inline bool tegra_dc_is_yuv_planar(int fmt)
316 {
317         switch (fmt) {
318         case TEGRA_WIN_FMT_YUV420P:
319         case TEGRA_WIN_FMT_YCbCr420P:
320         case TEGRA_WIN_FMT_YCbCr422P:
321         case TEGRA_WIN_FMT_YUV422P:
322         case TEGRA_WIN_FMT_YCbCr422R:
323         case TEGRA_WIN_FMT_YUV422R:
324         case TEGRA_WIN_FMT_YCbCr422RA:
325         case TEGRA_WIN_FMT_YUV422RA:
326                 return true;
327         }
328         return false;
329 }
330
331 static inline void tegra_dc_unmask_interrupt(struct tegra_dc *dc, u32 int_val)
332 {
333         u32 val;
334
335         val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
336         val |= int_val;
337         tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
338 }
339
340 static inline void tegra_dc_mask_interrupt(struct tegra_dc *dc, u32 int_val)
341 {
342         u32 val;
343
344         val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
345         val &= ~int_val;
346         tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
347 }
348
349 static inline unsigned long tegra_dc_clk_get_rate(struct tegra_dc *dc)
350 {
351 #ifdef CONFIG_TEGRA_SILICON_PLATFORM
352         return clk_get_rate(dc->clk);
353 #else
354         return dc->mode.pclk;
355 #endif
356 }
357
358 extern struct tegra_dc_out_ops tegra_dc_rgb_ops;
359 extern struct tegra_dc_out_ops tegra_dc_hdmi_ops;
360 extern struct tegra_dc_out_ops tegra_dc_dsi_ops;
361
362 /* defined in dc_sysfs.c, used by dc.c */
363 void __devexit tegra_dc_remove_sysfs(struct device *dev);
364 void tegra_dc_create_sysfs(struct device *dev);
365
366 /* defined in dc.c, used by dc_sysfs.c */
367 void tegra_dc_stats_enable(struct tegra_dc *dc, bool enable);
368 bool tegra_dc_stats_get(struct tegra_dc *dc);
369
370 /* defined in dc.c, used by dc_sysfs.c */
371 u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc);
372 void tegra_dc_enable_crc(struct tegra_dc *dc);
373 void tegra_dc_disable_crc(struct tegra_dc *dc);
374
375 void tegra_dc_set_out_pin_polars(struct tegra_dc *dc,
376                                 const struct tegra_dc_out_pin *pins,
377                                 const unsigned int n_pins);
378 /* defined in dc.c, used in bandwidth.c */
379 unsigned int tegra_dc_has_multiple_dc(void);
380
381 /* defined in dc.c, used in dsi.c */
382 void tegra_dc_clk_enable(struct tegra_dc *dc);
383 void tegra_dc_clk_disable(struct tegra_dc *dc);
384
385 /* defined in dc.c, used in nvsd.c and dsi.c */
386 void tegra_dc_hold_dc_out(struct tegra_dc *dc);
387 void tegra_dc_release_dc_out(struct tegra_dc *dc);
388
389 /* defined in bandwidth.c, used in dc.c */
390 void tegra_dc_clear_bandwidth(struct tegra_dc *dc);
391 void tegra_dc_program_bandwidth(struct tegra_dc *dc, bool use_new);
392 int tegra_dc_set_dynamic_emc(struct tegra_dc_win *windows[], int n);
393
394 /* defined in mode.c, used in dc.c */
395 int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode);
396 int tegra_dc_calc_refresh(const struct tegra_dc_mode *m);
397
398 /* defined in clock.c, used in dc.c, dsi.c and hdmi.c */
399 void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk);
400 unsigned long tegra_dc_pclk_round_rate(struct tegra_dc *dc, int pclk);
401
402 /* defined in lut.c, used in dc.c */
403 void tegra_dc_init_lut_defaults(struct tegra_dc_lut *lut);
404 void tegra_dc_set_lut(struct tegra_dc *dc, struct tegra_dc_win *win);
405
406 /* defined in csc.c, used in dc.c */
407 void tegra_dc_init_csc_defaults(struct tegra_dc_csc *csc);
408 void tegra_dc_set_csc(struct tegra_dc *dc, struct tegra_dc_csc *csc);
409
410 /* defined in window.c, used in dc.c */
411 void tegra_dc_trigger_windows(struct tegra_dc *dc);
412
413 #endif