ac3a5d341e18daa2af3570fdbd49617cdcdfd476
[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  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #ifndef __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_H
19 #define __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_H
20
21 #include <linux/io.h>
22 #include <linux/mutex.h>
23 #include <linux/wait.h>
24 #include <linux/fb.h>
25 #include <linux/completion.h>
26 #include <linux/switch.h>
27
28 #include <mach/dc.h>
29
30 #include "../host/nvhost_acm.h"
31
32 #include <mach/tegra_dc_ext.h>
33 #include <mach/clk.h>
34
35 #define WIN_IS_TILED(win)       ((win)->flags & TEGRA_WIN_FLAG_TILED)
36 #define WIN_IS_ENABLED(win)     ((win)->flags & TEGRA_WIN_FLAG_ENABLED)
37
38 #define NEED_UPDATE_EMC_ON_EVERY_FRAME (windows_idle_detection_time == 0)
39
40 /* DDR: 8 bytes transfer per clock */
41 #define DDR_BW_TO_FREQ(bw) ((bw) / 8)
42
43 #if defined(CONFIG_TEGRA_EMC_TO_DDR_CLOCK)
44 #define EMC_BW_TO_FREQ(bw) (DDR_BW_TO_FREQ(bw) * CONFIG_TEGRA_EMC_TO_DDR_CLOCK)
45 #else
46 #define EMC_BW_TO_FREQ(bw) (DDR_BW_TO_FREQ(bw) * 2)
47 #endif
48
49 struct tegra_dc;
50
51 struct tegra_dc_blend {
52         unsigned z[DC_N_WINDOWS];
53         unsigned flags[DC_N_WINDOWS];
54 };
55
56 struct tegra_dc_out_ops {
57         /* initialize output.  dc clocks are not on at this point */
58         int (*init)(struct tegra_dc *dc);
59         /* destroy output.  dc clocks are not on at this point */
60         void (*destroy)(struct tegra_dc *dc);
61         /* detect connected display.  can sleep.*/
62         bool (*detect)(struct tegra_dc *dc);
63         /* enable output.  dc clocks are on at this point */
64         void (*enable)(struct tegra_dc *dc);
65         /* disable output.  dc clocks are on at this point */
66         void (*disable)(struct tegra_dc *dc);
67         /* suspend output.  dc clocks are on at this point */
68         void (*suspend)(struct tegra_dc *dc);
69         /* resume output.  dc clocks are on at this point */
70         void (*resume)(struct tegra_dc *dc);
71         /* mode filter. to provide a list of supported modes*/
72         bool (*mode_filter)(const struct tegra_dc *dc,
73                         struct fb_videomode *mode);
74 };
75
76 struct tegra_dc {
77         struct nvhost_device            *ndev;
78         struct tegra_dc_platform_data   *pdata;
79
80         struct resource                 *base_res;
81         void __iomem                    *base;
82         int                             irq;
83
84         struct clk                      *clk;
85         struct clk                      *emc_clk;
86         int                             emc_clk_rate;
87         int                             new_emc_clk_rate;
88         u32                             shift_clk_div;
89
90         bool                            connected;
91         bool                            enabled;
92         bool                            suspended;
93
94         struct tegra_dc_out             *out;
95         struct tegra_dc_out_ops         *out_ops;
96         void                            *out_data;
97
98         struct tegra_dc_mode            mode;
99
100         struct tegra_dc_win             windows[DC_N_WINDOWS];
101         struct tegra_dc_blend           blend;
102         int                             n_windows;
103
104         wait_queue_head_t               wq;
105
106         struct mutex                    lock;
107         struct mutex                    one_shot_lock;
108
109         struct resource                 *fb_mem;
110         struct tegra_fb_info            *fb;
111
112         struct {
113                 u32                     id;
114                 u32                     min;
115                 u32                     max;
116         } syncpt[DC_N_WINDOWS];
117         u32                             vblank_syncpt;
118
119         unsigned long                   underflow_mask;
120         struct work_struct              reset_work;
121
122 #ifdef CONFIG_SWITCH
123         struct switch_dev               modeset_switch;
124 #endif
125
126         struct completion               frame_end_complete;
127
128         struct work_struct              vblank_work;
129         long                            vblank_ref_count;
130
131         struct {
132                 u64                     underflows;
133                 u64                     underflows_a;
134                 u64                     underflows_b;
135                 u64                     underflows_c;
136         } stats;
137
138         struct tegra_dc_ext             *ext;
139
140         struct tegra_dc_feature         *feature;
141
142 #ifdef CONFIG_DEBUG_FS
143         struct dentry                   *debugdir;
144 #endif
145         struct tegra_dc_lut             fb_lut;
146         struct delayed_work             underflow_work;
147         u32                             one_shot_delay_ms;
148         struct delayed_work             one_shot_work;
149 };
150
151 static inline void tegra_dc_io_start(struct tegra_dc *dc)
152 {
153         nvhost_module_busy(to_nvhost_device(dc->ndev->dev.parent));
154 }
155
156 static inline void tegra_dc_io_end(struct tegra_dc *dc)
157 {
158         nvhost_module_idle(to_nvhost_device(dc->ndev->dev.parent));
159 }
160
161 static inline unsigned long tegra_dc_readl(struct tegra_dc *dc,
162                                            unsigned long reg)
163 {
164         unsigned long ret;
165
166         BUG_ON(!nvhost_module_powered(to_nvhost_device(dc->ndev->dev.parent)));
167         if (!tegra_is_clk_enabled(dc->clk))
168                 WARN(1, "DC is clock-gated.\n");
169
170         ret = readl(dc->base + reg * 4);
171         trace_printk("readl %p=%#08lx\n", dc->base + reg * 4, ret);
172         return ret;
173 }
174
175 static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long val,
176                                    unsigned long reg)
177 {
178         BUG_ON(!nvhost_module_powered(to_nvhost_device(dc->ndev->dev.parent)));
179         if (!tegra_is_clk_enabled(dc->clk))
180                 WARN(1, "DC is clock-gated.\n");
181
182         trace_printk("writel %p=%#08lx\n", dc->base + reg * 4, val);
183         writel(val, dc->base + reg * 4);
184 }
185
186 static inline void _tegra_dc_write_table(struct tegra_dc *dc, const u32 *table,
187                                          unsigned len)
188 {
189         int i;
190
191         for (i = 0; i < len; i++)
192                 tegra_dc_writel(dc, table[i * 2 + 1], table[i * 2]);
193 }
194
195 #define tegra_dc_write_table(dc, table)         \
196         _tegra_dc_write_table(dc, table, ARRAY_SIZE(table) / 2)
197
198 static inline void tegra_dc_set_outdata(struct tegra_dc *dc, void *data)
199 {
200         dc->out_data = data;
201 }
202
203 static inline void *tegra_dc_get_outdata(struct tegra_dc *dc)
204 {
205         return dc->out_data;
206 }
207
208 static inline unsigned long tegra_dc_get_default_emc_clk_rate(
209                                                         struct tegra_dc *dc)
210 {
211         return dc->pdata->emc_clk_rate ? dc->pdata->emc_clk_rate : ULONG_MAX;
212 }
213
214 static inline int tegra_dc_fmt_bpp(int fmt)
215 {
216         switch (fmt) {
217         case TEGRA_WIN_FMT_P1:
218                 return 1;
219
220         case TEGRA_WIN_FMT_P2:
221                 return 2;
222
223         case TEGRA_WIN_FMT_P4:
224                 return 4;
225
226         case TEGRA_WIN_FMT_P8:
227                 return 8;
228
229         case TEGRA_WIN_FMT_B4G4R4A4:
230         case TEGRA_WIN_FMT_B5G5R5A:
231         case TEGRA_WIN_FMT_B5G6R5:
232         case TEGRA_WIN_FMT_AB5G5R5:
233                 return 16;
234
235         case TEGRA_WIN_FMT_B8G8R8A8:
236         case TEGRA_WIN_FMT_R8G8B8A8:
237         case TEGRA_WIN_FMT_B6x2G6x2R6x2A8:
238         case TEGRA_WIN_FMT_R6x2G6x2B6x2A8:
239                 return 32;
240
241         /* for planar formats, size of the Y plane, 8bit */
242         case TEGRA_WIN_FMT_YCbCr420P:
243         case TEGRA_WIN_FMT_YUV420P:
244         case TEGRA_WIN_FMT_YCbCr422P:
245         case TEGRA_WIN_FMT_YUV422P:
246         case TEGRA_WIN_FMT_YCbCr422R:
247         case TEGRA_WIN_FMT_YUV422R:
248         case TEGRA_WIN_FMT_YCbCr422RA:
249         case TEGRA_WIN_FMT_YUV422RA:
250                 return 8;
251
252         /* YUYV packed into 32-bits */
253         case TEGRA_WIN_FMT_YCbCr422:
254         case TEGRA_WIN_FMT_YUV422:
255                 return 16;
256         }
257         return 0;
258 }
259
260 static inline bool tegra_dc_is_yuv(int fmt)
261 {
262         switch (fmt) {
263         case TEGRA_WIN_FMT_YUV420P:
264         case TEGRA_WIN_FMT_YCbCr420P:
265         case TEGRA_WIN_FMT_YCbCr422P:
266         case TEGRA_WIN_FMT_YUV422P:
267         case TEGRA_WIN_FMT_YCbCr422:
268         case TEGRA_WIN_FMT_YUV422:
269         case TEGRA_WIN_FMT_YCbCr422R:
270         case TEGRA_WIN_FMT_YUV422R:
271         case TEGRA_WIN_FMT_YCbCr422RA:
272         case TEGRA_WIN_FMT_YUV422RA:
273                 return true;
274         }
275         return false;
276 }
277
278 static inline bool tegra_dc_is_yuv_planar(int fmt)
279 {
280         switch (fmt) {
281         case TEGRA_WIN_FMT_YUV420P:
282         case TEGRA_WIN_FMT_YCbCr420P:
283         case TEGRA_WIN_FMT_YCbCr422P:
284         case TEGRA_WIN_FMT_YUV422P:
285         case TEGRA_WIN_FMT_YCbCr422R:
286         case TEGRA_WIN_FMT_YUV422R:
287         case TEGRA_WIN_FMT_YCbCr422RA:
288         case TEGRA_WIN_FMT_YUV422RA:
289                 return true;
290         }
291         return false;
292 }
293
294 static inline void tegra_dc_unmask_interrupt(struct tegra_dc *dc, u32 int_val);
295 static inline void tegra_dc_mask_interrupt(struct tegra_dc *dc, u32 int_val);
296 static bool tegra_dc_windows_are_dirty(struct tegra_dc *dc);
297
298 void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk);
299
300 extern struct tegra_dc_out_ops tegra_dc_rgb_ops;
301 extern struct tegra_dc_out_ops tegra_dc_hdmi_ops;
302 extern struct tegra_dc_out_ops tegra_dc_dsi_ops;
303
304 /* defined in dc_sysfs.c, used by dc.c */
305 void __devexit tegra_dc_remove_sysfs(struct device *dev);
306 void tegra_dc_create_sysfs(struct device *dev);
307
308 /* defined in dc.c, used by dc_sysfs.c */
309 void tegra_dc_stats_enable(struct tegra_dc *dc, bool enable);
310 bool tegra_dc_stats_get(struct tegra_dc *dc);
311
312 /* defined in dc.c, used by dc_sysfs.c */
313 u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc);
314 void tegra_dc_enable_crc(struct tegra_dc *dc);
315 void tegra_dc_disable_crc(struct tegra_dc *dc);
316
317 void tegra_dc_set_out_pin_polars(struct tegra_dc *dc,
318                                 const struct tegra_dc_out_pin *pins,
319                                 const unsigned int n_pins);
320 /* defined in dc.c, used in bandwidth.c */
321 unsigned int tegra_dc_has_multiple_dc(void);
322
323 /* defined in bandwidth.c, used in dc.c */
324 void tegra_dc_clear_bandwidth(struct tegra_dc *dc);
325 void tegra_dc_program_bandwidth(struct tegra_dc *dc, bool use_new);
326 int tegra_dc_set_dynamic_emc(struct tegra_dc_win *windows[], int n);
327 #endif