2 * drivers/video/tegra/dc/dc_priv.h
4 * Copyright (C) 2010 Google, Inc.
5 * Author: Erik Gilling <konkers@android.com>
7 * Copyright (c) 2010-2012, NVIDIA CORPORATION, All rights reserved.
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.
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.
20 #ifndef __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_H
21 #define __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_H
24 #include <linux/mutex.h>
25 #include <linux/wait.h>
27 #include <linux/clk.h>
28 #include <linux/completion.h>
29 #include <linux/switch.h>
30 #include <linux/nvhost.h>
34 #include <mach/tegra_dc_ext.h>
39 #define WIN_IS_TILED(win) ((win)->flags & TEGRA_WIN_FLAG_TILED)
40 #define WIN_IS_ENABLED(win) ((win)->flags & TEGRA_WIN_FLAG_ENABLED)
42 #define NEED_UPDATE_EMC_ON_EVERY_FRAME (windows_idle_detection_time == 0)
44 /* DDR: 8 bytes transfer per clock */
45 #define DDR_BW_TO_FREQ(bw) ((bw) / 8)
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)
50 #define EMC_BW_TO_FREQ(bw) (DDR_BW_TO_FREQ(bw) * 2)
53 #ifndef CONFIG_TEGRA_FPGA_PLATFORM
54 #define ALL_UF_INT (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)
56 /* ignore underflows when on simulation and fpga platform */
57 #define ALL_UF_INT (0)
62 struct tegra_dc_blend {
63 unsigned z[DC_N_WINDOWS];
64 unsigned flags[DC_N_WINDOWS];
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);
94 struct nvhost_device *ndev;
95 struct tegra_dc_platform_data *pdata;
97 struct resource *base_res;
104 int new_emc_clk_rate;
111 struct tegra_dc_out *out;
112 struct tegra_dc_out_ops *out_ops;
115 struct tegra_dc_mode mode;
117 struct tegra_dc_win windows[DC_N_WINDOWS];
118 struct tegra_dc_blend blend;
121 wait_queue_head_t wq;
124 struct mutex one_shot_lock;
126 struct resource *fb_mem;
127 struct tegra_fb_info *fb;
133 } syncpt[DC_N_WINDOWS];
136 unsigned long underflow_mask;
137 struct work_struct reset_work;
140 struct switch_dev modeset_switch;
143 struct completion frame_end_complete;
145 struct work_struct vblank_work;
146 long vblank_ref_count;
155 struct tegra_dc_ext *ext;
157 struct tegra_dc_feature *feature;
159 #ifdef CONFIG_DEBUG_FS
160 struct dentry *debugdir;
162 struct tegra_dc_lut fb_lut;
163 struct delayed_work underflow_work;
164 u32 one_shot_delay_ms;
165 struct delayed_work one_shot_work;
168 #define print_mode_info(dc, mode) do { \
169 trace_printk("%s:Mode settings: " \
170 "ref_to_sync: H = %d V = %d, " \
171 "sync_width: H = %d V = %d, " \
172 "back_porch: H = %d V = %d, " \
173 "active: H = %d V = %d, " \
174 "front_porch: H = %d V = %d, " \
175 "pclk = %d, stereo mode = %d\n", \
177 mode.h_ref_to_sync, mode.v_ref_to_sync, \
178 mode.h_sync_width, mode.v_sync_width, \
179 mode.h_back_porch, mode.v_back_porch, \
180 mode.h_active, mode.v_active, \
181 mode.h_front_porch, mode.v_front_porch, \
182 mode.pclk, mode.stereo_mode); \
185 static inline void tegra_dc_io_start(struct tegra_dc *dc)
187 nvhost_module_busy_ext(nvhost_get_parent(dc->ndev));
190 static inline void tegra_dc_io_end(struct tegra_dc *dc)
192 nvhost_module_idle_ext(nvhost_get_parent(dc->ndev));
195 static inline unsigned long tegra_dc_readl(struct tegra_dc *dc,
200 BUG_ON(!nvhost_module_powered_ext(nvhost_get_parent(dc->ndev)));
201 if (!tegra_is_clk_enabled(dc->clk))
202 WARN(1, "DC is clock-gated.\n");
204 ret = readl(dc->base + reg * 4);
205 trace_printk("readl %p=%#08lx\n", dc->base + reg * 4, ret);
209 static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long val,
212 BUG_ON(!nvhost_module_powered_ext(nvhost_get_parent(dc->ndev)));
213 if (!tegra_is_clk_enabled(dc->clk))
214 WARN(1, "DC is clock-gated.\n");
216 trace_printk("writel %p=%#08lx\n", dc->base + reg * 4, val);
217 writel(val, dc->base + reg * 4);
220 static inline void _tegra_dc_write_table(struct tegra_dc *dc, const u32 *table,
225 for (i = 0; i < len; i++)
226 tegra_dc_writel(dc, table[i * 2 + 1], table[i * 2]);
229 #define tegra_dc_write_table(dc, table) \
230 _tegra_dc_write_table(dc, table, ARRAY_SIZE(table) / 2)
232 static inline void tegra_dc_set_outdata(struct tegra_dc *dc, void *data)
237 static inline void *tegra_dc_get_outdata(struct tegra_dc *dc)
242 static inline unsigned long tegra_dc_get_default_emc_clk_rate(
245 return dc->pdata->emc_clk_rate ? dc->pdata->emc_clk_rate : ULONG_MAX;
248 static inline int tegra_dc_fmt_bpp(int fmt)
251 case TEGRA_WIN_FMT_P1:
254 case TEGRA_WIN_FMT_P2:
257 case TEGRA_WIN_FMT_P4:
260 case TEGRA_WIN_FMT_P8:
263 case TEGRA_WIN_FMT_B4G4R4A4:
264 case TEGRA_WIN_FMT_B5G5R5A:
265 case TEGRA_WIN_FMT_B5G6R5:
266 case TEGRA_WIN_FMT_AB5G5R5:
269 case TEGRA_WIN_FMT_B8G8R8A8:
270 case TEGRA_WIN_FMT_R8G8B8A8:
271 case TEGRA_WIN_FMT_B6x2G6x2R6x2A8:
272 case TEGRA_WIN_FMT_R6x2G6x2B6x2A8:
275 /* for planar formats, size of the Y plane, 8bit */
276 case TEGRA_WIN_FMT_YCbCr420P:
277 case TEGRA_WIN_FMT_YUV420P:
278 case TEGRA_WIN_FMT_YCbCr422P:
279 case TEGRA_WIN_FMT_YUV422P:
280 case TEGRA_WIN_FMT_YCbCr422R:
281 case TEGRA_WIN_FMT_YUV422R:
282 case TEGRA_WIN_FMT_YCbCr422RA:
283 case TEGRA_WIN_FMT_YUV422RA:
286 /* YUYV packed into 32-bits */
287 case TEGRA_WIN_FMT_YCbCr422:
288 case TEGRA_WIN_FMT_YUV422:
294 static inline bool tegra_dc_is_yuv(int fmt)
297 case TEGRA_WIN_FMT_YUV420P:
298 case TEGRA_WIN_FMT_YCbCr420P:
299 case TEGRA_WIN_FMT_YCbCr422P:
300 case TEGRA_WIN_FMT_YUV422P:
301 case TEGRA_WIN_FMT_YCbCr422:
302 case TEGRA_WIN_FMT_YUV422:
303 case TEGRA_WIN_FMT_YCbCr422R:
304 case TEGRA_WIN_FMT_YUV422R:
305 case TEGRA_WIN_FMT_YCbCr422RA:
306 case TEGRA_WIN_FMT_YUV422RA:
312 static inline bool tegra_dc_is_yuv_planar(int fmt)
315 case TEGRA_WIN_FMT_YUV420P:
316 case TEGRA_WIN_FMT_YCbCr420P:
317 case TEGRA_WIN_FMT_YCbCr422P:
318 case TEGRA_WIN_FMT_YUV422P:
319 case TEGRA_WIN_FMT_YCbCr422R:
320 case TEGRA_WIN_FMT_YUV422R:
321 case TEGRA_WIN_FMT_YCbCr422RA:
322 case TEGRA_WIN_FMT_YUV422RA:
328 static inline void tegra_dc_unmask_interrupt(struct tegra_dc *dc, u32 int_val)
332 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
334 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
337 static inline void tegra_dc_mask_interrupt(struct tegra_dc *dc, u32 int_val)
341 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
343 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
346 static inline unsigned long tegra_dc_clk_get_rate(struct tegra_dc *dc)
348 #ifdef CONFIG_TEGRA_SILICON_PLATFORM
349 return clk_get_rate(dc->clk);
351 return dc->mode.pclk;
355 extern struct tegra_dc_out_ops tegra_dc_rgb_ops;
356 extern struct tegra_dc_out_ops tegra_dc_hdmi_ops;
357 extern struct tegra_dc_out_ops tegra_dc_dsi_ops;
359 /* defined in dc_sysfs.c, used by dc.c */
360 void __devexit tegra_dc_remove_sysfs(struct device *dev);
361 void tegra_dc_create_sysfs(struct device *dev);
363 /* defined in dc.c, used by dc_sysfs.c */
364 void tegra_dc_stats_enable(struct tegra_dc *dc, bool enable);
365 bool tegra_dc_stats_get(struct tegra_dc *dc);
367 /* defined in dc.c, used by dc_sysfs.c */
368 u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc);
369 void tegra_dc_enable_crc(struct tegra_dc *dc);
370 void tegra_dc_disable_crc(struct tegra_dc *dc);
372 void tegra_dc_set_out_pin_polars(struct tegra_dc *dc,
373 const struct tegra_dc_out_pin *pins,
374 const unsigned int n_pins);
375 /* defined in dc.c, used in bandwidth.c and ext/dev.c */
376 unsigned int tegra_dc_has_multiple_dc(void);
378 /* defined in dc.c, used in dsi.c */
379 void tegra_dc_clk_enable(struct tegra_dc *dc);
380 void tegra_dc_clk_disable(struct tegra_dc *dc);
382 /* defined in dc.c, used in nvsd.c and dsi.c */
383 void tegra_dc_hold_dc_out(struct tegra_dc *dc);
384 void tegra_dc_release_dc_out(struct tegra_dc *dc);
386 /* defined in bandwidth.c, used in dc.c */
387 void tegra_dc_clear_bandwidth(struct tegra_dc *dc);
388 void tegra_dc_program_bandwidth(struct tegra_dc *dc, bool use_new);
389 int tegra_dc_set_dynamic_emc(struct tegra_dc_win *windows[], int n);
391 /* defined in mode.c, used in dc.c */
392 int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode);
393 int tegra_dc_calc_refresh(const struct tegra_dc_mode *m);
395 /* defined in clock.c, used in dc.c, dsi.c and hdmi.c */
396 void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk);
397 unsigned long tegra_dc_pclk_round_rate(struct tegra_dc *dc, int pclk);
399 /* defined in lut.c, used in dc.c */
400 void tegra_dc_init_lut_defaults(struct tegra_dc_lut *lut);
401 void tegra_dc_set_lut(struct tegra_dc *dc, struct tegra_dc_win *win);
403 /* defined in csc.c, used in dc.c */
404 void tegra_dc_init_csc_defaults(struct tegra_dc_csc *csc);
405 void tegra_dc_set_csc(struct tegra_dc *dc, struct tegra_dc_csc *csc);
407 /* defined in window.c, used in dc.c */
408 void tegra_dc_trigger_windows(struct tegra_dc *dc);