diff options
author | Sandor Yu <R01008@freescale.com> | 2013-08-05 04:12:53 -0400 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:00:56 -0400 |
commit | 92bfbb00fe6f172183ba172771dc647d435ec756 (patch) | |
tree | de6631a23fcc7c962aaad2e57ed110b10497645a | |
parent | 686f8a205419109ab0d38d1eb1d6af57442ba36e (diff) |
ENGR00273848-02 iMX6Q/DL HDMI: Enable HDMI function
Add MX6Q/DL HDMI core and video driver source code.
Add MXC edid data read and parse source code.
Signed-off-by: Sandor Yu <R01008@freescale.com>
-rw-r--r-- | drivers/mfd/Kconfig | 8 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mfd/mxc-hdmi-core.c | 785 | ||||
-rw-r--r-- | drivers/video/mxc/Kconfig | 14 | ||||
-rw-r--r-- | drivers/video/mxc/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_edid.c | 762 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_hdmi.c | 2971 | ||||
-rw-r--r-- | include/linux/mfd/mxc-hdmi-core.h | 65 | ||||
-rwxr-xr-x | include/video/mxc_edid.h | 105 | ||||
-rw-r--r-- | include/video/mxc_hdmi.h | 1095 |
10 files changed, 5808 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d54e985748b7..043901b09dca 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -1148,3 +1148,11 @@ config VEXPRESS_CONFIG | |||
1148 | help | 1148 | help |
1149 | Platform configuration infrastructure for the ARM Ltd. | 1149 | Platform configuration infrastructure for the ARM Ltd. |
1150 | Versatile Express. | 1150 | Versatile Express. |
1151 | |||
1152 | config MFD_MXC_HDMI | ||
1153 | tristate "MXC HDMI Core" | ||
1154 | select MFD_CORE | ||
1155 | default y | ||
1156 | help | ||
1157 | This is the core driver for the i.MX on-chip HDMI. This MFD | ||
1158 | driver connects with the video and audio drivers for HDMI. | ||
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 718e94a2a9a7..41ab2b45e188 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -155,3 +155,4 @@ obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o | |||
155 | obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o | 155 | obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o |
156 | obj-$(CONFIG_MFD_RETU) += retu-mfd.o | 156 | obj-$(CONFIG_MFD_RETU) += retu-mfd.o |
157 | obj-$(CONFIG_MFD_AS3711) += as3711.o | 157 | obj-$(CONFIG_MFD_AS3711) += as3711.o |
158 | obj-$(CONFIG_MFD_MXC_HDMI) += mxc-hdmi-core.o | ||
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c new file mode 100644 index 000000000000..7da0bf6d003e --- /dev/null +++ b/drivers/mfd/mxc-hdmi-core.c | |||
@@ -0,0 +1,785 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | */ | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/device.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | |||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/regulator/machine.h> | ||
33 | #include <asm/mach-types.h> | ||
34 | |||
35 | #include <video/mxc_hdmi.h> | ||
36 | #include <linux/ipu-v3.h> | ||
37 | #include <video/mxc_edid.h> | ||
38 | #include "../mxc/ipu3/ipu_prv.h" | ||
39 | #include <linux/mfd/mxc-hdmi-core.h> | ||
40 | #include <linux/of_device.h> | ||
41 | #include <linux/mod_devicetable.h> | ||
42 | #include <linux/mfd/mxc-hdmi-core.h> | ||
43 | |||
44 | struct mxc_hdmi_data { | ||
45 | struct platform_device *pdev; | ||
46 | unsigned long __iomem *reg_base; | ||
47 | unsigned long reg_phys_base; | ||
48 | struct device *dev; | ||
49 | }; | ||
50 | |||
51 | static void __iomem *hdmi_base; | ||
52 | static struct clk *isfr_clk; | ||
53 | static struct clk *iahb_clk; | ||
54 | static spinlock_t irq_spinlock; | ||
55 | static spinlock_t edid_spinlock; | ||
56 | static unsigned int sample_rate; | ||
57 | static unsigned long pixel_clk_rate; | ||
58 | static struct clk *pixel_clk; | ||
59 | static int hdmi_ratio; | ||
60 | int mxc_hdmi_ipu_id; | ||
61 | int mxc_hdmi_disp_id; | ||
62 | static struct mxc_edid_cfg hdmi_core_edid_cfg; | ||
63 | static int hdmi_core_init; | ||
64 | static unsigned int hdmi_dma_running; | ||
65 | static struct snd_pcm_substream *hdmi_audio_stream_playback; | ||
66 | static unsigned int hdmi_cable_state; | ||
67 | static unsigned int hdmi_blank_state; | ||
68 | static spinlock_t hdmi_audio_lock, hdmi_blank_state_lock, hdmi_cable_state_lock; | ||
69 | |||
70 | unsigned int hdmi_set_cable_state(unsigned int state) | ||
71 | { | ||
72 | unsigned long flags; | ||
73 | struct snd_pcm_substream *substream = hdmi_audio_stream_playback; | ||
74 | |||
75 | spin_lock_irqsave(&hdmi_cable_state_lock, flags); | ||
76 | hdmi_cable_state = state; | ||
77 | spin_unlock_irqrestore(&hdmi_cable_state_lock, flags); | ||
78 | |||
79 | if (check_hdmi_state() && substream) | ||
80 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START); | ||
81 | return 0; | ||
82 | } | ||
83 | EXPORT_SYMBOL(hdmi_set_cable_state); | ||
84 | |||
85 | unsigned int hdmi_set_blank_state(unsigned int state) | ||
86 | { | ||
87 | unsigned long flags; | ||
88 | struct snd_pcm_substream *substream = hdmi_audio_stream_playback; | ||
89 | |||
90 | spin_lock_irqsave(&hdmi_blank_state_lock, flags); | ||
91 | hdmi_blank_state = state; | ||
92 | spin_unlock_irqrestore(&hdmi_blank_state_lock, flags); | ||
93 | |||
94 | if (check_hdmi_state() && substream) | ||
95 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | EXPORT_SYMBOL(hdmi_set_blank_state); | ||
100 | |||
101 | static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream) | ||
102 | { | ||
103 | unsigned long flags; | ||
104 | |||
105 | snd_pcm_stream_lock_irqsave(substream, flags); | ||
106 | |||
107 | if (snd_pcm_running(substream)) | ||
108 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); | ||
109 | |||
110 | snd_pcm_stream_unlock_irqrestore(substream, flags); | ||
111 | } | ||
112 | |||
113 | int mxc_hdmi_abort_stream(void) | ||
114 | { | ||
115 | unsigned long flags; | ||
116 | spin_lock_irqsave(&hdmi_audio_lock, flags); | ||
117 | if (hdmi_audio_stream_playback) | ||
118 | hdmi_audio_abort_stream(hdmi_audio_stream_playback); | ||
119 | spin_unlock_irqrestore(&hdmi_audio_lock, flags); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | EXPORT_SYMBOL(mxc_hdmi_abort_stream); | ||
124 | |||
125 | int check_hdmi_state(void) | ||
126 | { | ||
127 | unsigned long flags1, flags2; | ||
128 | unsigned int ret; | ||
129 | |||
130 | spin_lock_irqsave(&hdmi_cable_state_lock, flags1); | ||
131 | spin_lock_irqsave(&hdmi_blank_state_lock, flags2); | ||
132 | |||
133 | ret = hdmi_cable_state && hdmi_blank_state; | ||
134 | |||
135 | spin_unlock_irqrestore(&hdmi_blank_state_lock, flags2); | ||
136 | spin_unlock_irqrestore(&hdmi_cable_state_lock, flags1); | ||
137 | |||
138 | return ret; | ||
139 | } | ||
140 | EXPORT_SYMBOL(check_hdmi_state); | ||
141 | |||
142 | int mxc_hdmi_register_audio(struct snd_pcm_substream *substream) | ||
143 | { | ||
144 | unsigned long flags, flags1; | ||
145 | int ret = 0; | ||
146 | |||
147 | snd_pcm_stream_lock_irqsave(substream, flags); | ||
148 | |||
149 | if (substream && check_hdmi_state()) { | ||
150 | spin_lock_irqsave(&hdmi_audio_lock, flags1); | ||
151 | if (hdmi_audio_stream_playback) { | ||
152 | pr_err("%s unconsist hdmi auido stream!\n", __func__); | ||
153 | ret = -EINVAL; | ||
154 | } | ||
155 | hdmi_audio_stream_playback = substream; | ||
156 | spin_unlock_irqrestore(&hdmi_audio_lock, flags1); | ||
157 | } else | ||
158 | ret = -EINVAL; | ||
159 | |||
160 | snd_pcm_stream_unlock_irqrestore(substream, flags); | ||
161 | |||
162 | return ret; | ||
163 | } | ||
164 | EXPORT_SYMBOL(mxc_hdmi_register_audio); | ||
165 | |||
166 | void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream) | ||
167 | { | ||
168 | unsigned long flags; | ||
169 | |||
170 | spin_lock_irqsave(&hdmi_audio_lock, flags); | ||
171 | hdmi_audio_stream_playback = NULL; | ||
172 | spin_unlock_irqrestore(&hdmi_audio_lock, flags); | ||
173 | } | ||
174 | EXPORT_SYMBOL(mxc_hdmi_unregister_audio); | ||
175 | |||
176 | u8 hdmi_readb(unsigned int reg) | ||
177 | { | ||
178 | u8 value; | ||
179 | |||
180 | value = __raw_readb(hdmi_base + reg); | ||
181 | |||
182 | return value; | ||
183 | } | ||
184 | EXPORT_SYMBOL(hdmi_readb); | ||
185 | |||
186 | #ifdef DEBUG | ||
187 | static bool overflow_lo; | ||
188 | static bool overflow_hi; | ||
189 | |||
190 | bool hdmi_check_overflow(void) | ||
191 | { | ||
192 | u8 val, lo, hi; | ||
193 | |||
194 | val = hdmi_readb(HDMI_IH_FC_STAT2); | ||
195 | lo = (val & HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW) != 0; | ||
196 | hi = (val & HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW) != 0; | ||
197 | |||
198 | if ((lo != overflow_lo) || (hi != overflow_hi)) { | ||
199 | pr_debug("%s LowPriority=%d HighPriority=%d <=======================\n", | ||
200 | __func__, lo, hi); | ||
201 | overflow_lo = lo; | ||
202 | overflow_hi = hi; | ||
203 | return true; | ||
204 | } | ||
205 | return false; | ||
206 | } | ||
207 | #else | ||
208 | bool hdmi_check_overflow(void) | ||
209 | { | ||
210 | return false; | ||
211 | } | ||
212 | #endif | ||
213 | EXPORT_SYMBOL(hdmi_check_overflow); | ||
214 | |||
215 | void hdmi_writeb(u8 value, unsigned int reg) | ||
216 | { | ||
217 | hdmi_check_overflow(); | ||
218 | __raw_writeb(value, hdmi_base + reg); | ||
219 | hdmi_check_overflow(); | ||
220 | } | ||
221 | EXPORT_SYMBOL(hdmi_writeb); | ||
222 | |||
223 | void hdmi_mask_writeb(u8 data, unsigned int reg, u8 shift, u8 mask) | ||
224 | { | ||
225 | u8 value = hdmi_readb(reg) & ~mask; | ||
226 | value |= (data << shift) & mask; | ||
227 | hdmi_writeb(value, reg); | ||
228 | } | ||
229 | EXPORT_SYMBOL(hdmi_mask_writeb); | ||
230 | |||
231 | unsigned int hdmi_read4(unsigned int reg) | ||
232 | { | ||
233 | /* read a four byte address from registers */ | ||
234 | return (hdmi_readb(reg + 3) << 24) | | ||
235 | (hdmi_readb(reg + 2) << 16) | | ||
236 | (hdmi_readb(reg + 1) << 8) | | ||
237 | hdmi_readb(reg); | ||
238 | } | ||
239 | EXPORT_SYMBOL(hdmi_read4); | ||
240 | |||
241 | void hdmi_write4(unsigned int value, unsigned int reg) | ||
242 | { | ||
243 | /* write a four byte address to hdmi regs */ | ||
244 | hdmi_writeb(value & 0xff, reg); | ||
245 | hdmi_writeb((value >> 8) & 0xff, reg + 1); | ||
246 | hdmi_writeb((value >> 16) & 0xff, reg + 2); | ||
247 | hdmi_writeb((value >> 24) & 0xff, reg + 3); | ||
248 | } | ||
249 | EXPORT_SYMBOL(hdmi_write4); | ||
250 | |||
251 | static void initialize_hdmi_ih_mutes(void) | ||
252 | { | ||
253 | u8 ih_mute; | ||
254 | |||
255 | /* | ||
256 | * Boot up defaults are: | ||
257 | * HDMI_IH_MUTE = 0x03 (disabled) | ||
258 | * HDMI_IH_MUTE_* = 0x00 (enabled) | ||
259 | */ | ||
260 | |||
261 | /* Disable top level interrupt bits in HDMI block */ | ||
262 | ih_mute = hdmi_readb(HDMI_IH_MUTE) | | ||
263 | HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | | ||
264 | HDMI_IH_MUTE_MUTE_ALL_INTERRUPT; | ||
265 | |||
266 | hdmi_writeb(ih_mute, HDMI_IH_MUTE); | ||
267 | |||
268 | /* by default mask all interrupts */ | ||
269 | hdmi_writeb(0xff, HDMI_VP_MASK); | ||
270 | hdmi_writeb(0xff, HDMI_FC_MASK0); | ||
271 | hdmi_writeb(0xff, HDMI_FC_MASK1); | ||
272 | hdmi_writeb(0xff, HDMI_FC_MASK2); | ||
273 | hdmi_writeb(0xff, HDMI_PHY_MASK0); | ||
274 | hdmi_writeb(0xff, HDMI_PHY_I2CM_INT_ADDR); | ||
275 | hdmi_writeb(0xff, HDMI_PHY_I2CM_CTLINT_ADDR); | ||
276 | hdmi_writeb(0xff, HDMI_AUD_INT); | ||
277 | hdmi_writeb(0xff, HDMI_AUD_SPDIFINT); | ||
278 | hdmi_writeb(0xff, HDMI_AUD_HBR_MASK); | ||
279 | hdmi_writeb(0xff, HDMI_GP_MASK); | ||
280 | hdmi_writeb(0xff, HDMI_A_APIINTMSK); | ||
281 | hdmi_writeb(0xff, HDMI_CEC_MASK); | ||
282 | hdmi_writeb(0xff, HDMI_I2CM_INT); | ||
283 | hdmi_writeb(0xff, HDMI_I2CM_CTLINT); | ||
284 | |||
285 | /* Disable interrupts in the IH_MUTE_* registers */ | ||
286 | hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT0); | ||
287 | hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT1); | ||
288 | hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT2); | ||
289 | hdmi_writeb(0xff, HDMI_IH_MUTE_AS_STAT0); | ||
290 | hdmi_writeb(0xff, HDMI_IH_MUTE_PHY_STAT0); | ||
291 | hdmi_writeb(0xff, HDMI_IH_MUTE_I2CM_STAT0); | ||
292 | hdmi_writeb(0xff, HDMI_IH_MUTE_CEC_STAT0); | ||
293 | hdmi_writeb(0xff, HDMI_IH_MUTE_VP_STAT0); | ||
294 | hdmi_writeb(0xff, HDMI_IH_MUTE_I2CMPHY_STAT0); | ||
295 | hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0); | ||
296 | |||
297 | /* Enable top level interrupt bits in HDMI block */ | ||
298 | ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | | ||
299 | HDMI_IH_MUTE_MUTE_ALL_INTERRUPT); | ||
300 | hdmi_writeb(ih_mute, HDMI_IH_MUTE); | ||
301 | } | ||
302 | |||
303 | static void hdmi_set_clock_regenerator_n(unsigned int value) | ||
304 | { | ||
305 | u8 val; | ||
306 | |||
307 | if (!hdmi_dma_running) { | ||
308 | hdmi_writeb(value & 0xff, HDMI_AUD_N1); | ||
309 | hdmi_writeb(0, HDMI_AUD_N2); | ||
310 | hdmi_writeb(0, HDMI_AUD_N3); | ||
311 | } | ||
312 | |||
313 | hdmi_writeb(value & 0xff, HDMI_AUD_N1); | ||
314 | hdmi_writeb((value >> 8) & 0xff, HDMI_AUD_N2); | ||
315 | hdmi_writeb((value >> 16) & 0x0f, HDMI_AUD_N3); | ||
316 | |||
317 | /* nshift factor = 0 */ | ||
318 | val = hdmi_readb(HDMI_AUD_CTS3); | ||
319 | val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK; | ||
320 | hdmi_writeb(val, HDMI_AUD_CTS3); | ||
321 | } | ||
322 | |||
323 | static void hdmi_set_clock_regenerator_cts(unsigned int cts) | ||
324 | { | ||
325 | u8 val; | ||
326 | |||
327 | if (!hdmi_dma_running) { | ||
328 | hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1); | ||
329 | hdmi_writeb(0, HDMI_AUD_CTS2); | ||
330 | hdmi_writeb(0, HDMI_AUD_CTS3); | ||
331 | } | ||
332 | |||
333 | /* Must be set/cleared first */ | ||
334 | val = hdmi_readb(HDMI_AUD_CTS3); | ||
335 | val &= ~HDMI_AUD_CTS3_CTS_MANUAL; | ||
336 | hdmi_writeb(val, HDMI_AUD_CTS3); | ||
337 | |||
338 | hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1); | ||
339 | hdmi_writeb((cts >> 8) & 0xff, HDMI_AUD_CTS2); | ||
340 | hdmi_writeb(((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | | ||
341 | HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); | ||
342 | } | ||
343 | |||
344 | static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk, | ||
345 | unsigned int ratio) | ||
346 | { | ||
347 | unsigned int n = (128 * freq) / 1000; | ||
348 | |||
349 | switch (freq) { | ||
350 | case 32000: | ||
351 | if (pixel_clk == 25174000) | ||
352 | n = (ratio == 150) ? 9152 : 4576; | ||
353 | else if (pixel_clk == 27020000) | ||
354 | n = (ratio == 150) ? 8192 : 4096; | ||
355 | else if (pixel_clk == 74170000 || pixel_clk == 148350000) | ||
356 | n = 11648; | ||
357 | else if (pixel_clk == 297000000) | ||
358 | n = (ratio == 150) ? 6144 : 3072; | ||
359 | else | ||
360 | n = 4096; | ||
361 | break; | ||
362 | |||
363 | case 44100: | ||
364 | if (pixel_clk == 25174000) | ||
365 | n = 7007; | ||
366 | else if (pixel_clk == 74170000) | ||
367 | n = 17836; | ||
368 | else if (pixel_clk == 148350000) | ||
369 | n = (ratio == 150) ? 17836 : 8918; | ||
370 | else if (pixel_clk == 297000000) | ||
371 | n = (ratio == 150) ? 9408 : 4704; | ||
372 | else | ||
373 | n = 6272; | ||
374 | break; | ||
375 | |||
376 | case 48000: | ||
377 | if (pixel_clk == 25174000) | ||
378 | n = (ratio == 150) ? 9152 : 6864; | ||
379 | else if (pixel_clk == 27020000) | ||
380 | n = (ratio == 150) ? 8192 : 6144; | ||
381 | else if (pixel_clk == 74170000) | ||
382 | n = 11648; | ||
383 | else if (pixel_clk == 148350000) | ||
384 | n = (ratio == 150) ? 11648 : 5824; | ||
385 | else if (pixel_clk == 297000000) | ||
386 | n = (ratio == 150) ? 10240 : 5120; | ||
387 | else | ||
388 | n = 6144; | ||
389 | break; | ||
390 | |||
391 | case 88200: | ||
392 | n = hdmi_compute_n(44100, pixel_clk, ratio) * 2; | ||
393 | break; | ||
394 | |||
395 | case 96000: | ||
396 | n = hdmi_compute_n(48000, pixel_clk, ratio) * 2; | ||
397 | break; | ||
398 | |||
399 | case 176400: | ||
400 | n = hdmi_compute_n(44100, pixel_clk, ratio) * 4; | ||
401 | break; | ||
402 | |||
403 | case 192000: | ||
404 | n = hdmi_compute_n(48000, pixel_clk, ratio) * 4; | ||
405 | break; | ||
406 | |||
407 | default: | ||
408 | break; | ||
409 | } | ||
410 | |||
411 | return n; | ||
412 | } | ||
413 | |||
414 | static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, | ||
415 | unsigned int ratio) | ||
416 | { | ||
417 | unsigned int cts = 0; | ||
418 | switch (freq) { | ||
419 | case 32000: | ||
420 | if (pixel_clk == 297000000) { | ||
421 | cts = 222750; | ||
422 | break; | ||
423 | } else if (pixel_clk == 25174000) { | ||
424 | cts = 28125; | ||
425 | break; | ||
426 | } | ||
427 | case 48000: | ||
428 | case 96000: | ||
429 | case 192000: | ||
430 | switch (pixel_clk) { | ||
431 | case 25200000: | ||
432 | case 27000000: | ||
433 | case 54000000: | ||
434 | case 74250000: | ||
435 | case 148500000: | ||
436 | cts = pixel_clk / 1000; | ||
437 | break; | ||
438 | case 297000000: | ||
439 | cts = 247500; | ||
440 | break; | ||
441 | case 25174000: | ||
442 | cts = 28125l; | ||
443 | break; | ||
444 | /* | ||
445 | * All other TMDS clocks are not supported by | ||
446 | * DWC_hdmi_tx. The TMDS clocks divided or | ||
447 | * multiplied by 1,001 coefficients are not | ||
448 | * supported. | ||
449 | */ | ||
450 | default: | ||
451 | break; | ||
452 | } | ||
453 | break; | ||
454 | case 44100: | ||
455 | case 88200: | ||
456 | case 176400: | ||
457 | switch (pixel_clk) { | ||
458 | case 25200000: | ||
459 | cts = 28000; | ||
460 | break; | ||
461 | case 25174000: | ||
462 | cts = 31250; | ||
463 | break; | ||
464 | case 27000000: | ||
465 | cts = 30000; | ||
466 | break; | ||
467 | case 54000000: | ||
468 | cts = 60000; | ||
469 | break; | ||
470 | case 74250000: | ||
471 | cts = 82500; | ||
472 | break; | ||
473 | case 148500000: | ||
474 | cts = 165000; | ||
475 | break; | ||
476 | case 297000000: | ||
477 | cts = 247500; | ||
478 | break; | ||
479 | default: | ||
480 | break; | ||
481 | } | ||
482 | break; | ||
483 | default: | ||
484 | break; | ||
485 | } | ||
486 | if (ratio == 100) | ||
487 | return cts; | ||
488 | else | ||
489 | return (cts * ratio) / 100; | ||
490 | } | ||
491 | |||
492 | static void hdmi_set_clk_regenerator(void) | ||
493 | { | ||
494 | unsigned int clk_n, clk_cts; | ||
495 | |||
496 | clk_n = hdmi_compute_n(sample_rate, pixel_clk_rate, hdmi_ratio); | ||
497 | clk_cts = hdmi_compute_cts(sample_rate, pixel_clk_rate, hdmi_ratio); | ||
498 | |||
499 | if (clk_cts == 0) { | ||
500 | pr_debug("%s: pixel clock not supported: %d\n", | ||
501 | __func__, (int)pixel_clk_rate); | ||
502 | return; | ||
503 | } | ||
504 | |||
505 | pr_debug("%s: samplerate=%d ratio=%d pixelclk=%d N=%d cts=%d\n", | ||
506 | __func__, sample_rate, hdmi_ratio, (int)pixel_clk_rate, | ||
507 | clk_n, clk_cts); | ||
508 | |||
509 | hdmi_set_clock_regenerator_cts(clk_cts); | ||
510 | hdmi_set_clock_regenerator_n(clk_n); | ||
511 | } | ||
512 | |||
513 | static int hdmi_core_get_of_property(struct platform_device *pdev) | ||
514 | { | ||
515 | struct device_node *np = pdev->dev.of_node; | ||
516 | int err; | ||
517 | int ipu_id, disp_id; | ||
518 | |||
519 | err = of_property_read_u32(np, "ipu_id", &ipu_id); | ||
520 | if (err) { | ||
521 | dev_dbg(&pdev->dev, "get of property ipu_id fail\n"); | ||
522 | return err; | ||
523 | } | ||
524 | err = of_property_read_u32(np, "disp_id", &disp_id); | ||
525 | if (err) { | ||
526 | dev_dbg(&pdev->dev, "get of property disp_id fail\n"); | ||
527 | return err; | ||
528 | } | ||
529 | |||
530 | mxc_hdmi_ipu_id = ipu_id; | ||
531 | mxc_hdmi_disp_id = disp_id; | ||
532 | |||
533 | return err; | ||
534 | } | ||
535 | /* | ||
536 | unsigned int hdmi_SDMA_check(void) | ||
537 | { | ||
538 | |||
539 | return (imx6q_revision() > IMX_CHIP_REVISION_1_1) || | ||
540 | (imx6dl_revision() > IMX_CHIP_REVISION_1_0); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | EXPORT_SYMBOL(hdmi_SDMA_check); | ||
545 | */ | ||
546 | /* Need to run this before phy is enabled the first time to prevent | ||
547 | * overflow condition in HDMI_IH_FC_STAT2 */ | ||
548 | void hdmi_init_clk_regenerator(void) | ||
549 | { | ||
550 | if (pixel_clk_rate == 0) { | ||
551 | pixel_clk_rate = 74250000; | ||
552 | hdmi_set_clk_regenerator(); | ||
553 | } | ||
554 | } | ||
555 | EXPORT_SYMBOL(hdmi_init_clk_regenerator); | ||
556 | |||
557 | void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock) | ||
558 | { | ||
559 | |||
560 | /* Translate pixel clock in ps (pico seconds) to Hz */ | ||
561 | pixel_clk_rate = PICOS2KHZ(pixclock) * 1000UL; | ||
562 | hdmi_set_clk_regenerator(); | ||
563 | } | ||
564 | EXPORT_SYMBOL(hdmi_clk_regenerator_update_pixel_clock); | ||
565 | |||
566 | void hdmi_set_dma_mode(unsigned int dma_running) | ||
567 | { | ||
568 | hdmi_dma_running = dma_running; | ||
569 | hdmi_set_clk_regenerator(); | ||
570 | } | ||
571 | EXPORT_SYMBOL(hdmi_set_dma_mode); | ||
572 | |||
573 | void hdmi_set_sample_rate(unsigned int rate) | ||
574 | { | ||
575 | sample_rate = rate; | ||
576 | } | ||
577 | EXPORT_SYMBOL(hdmi_set_sample_rate); | ||
578 | |||
579 | void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg) | ||
580 | { | ||
581 | unsigned long flags; | ||
582 | |||
583 | spin_lock_irqsave(&edid_spinlock, flags); | ||
584 | memcpy(&hdmi_core_edid_cfg, cfg, sizeof(struct mxc_edid_cfg)); | ||
585 | spin_unlock_irqrestore(&edid_spinlock, flags); | ||
586 | } | ||
587 | EXPORT_SYMBOL(hdmi_set_edid_cfg); | ||
588 | |||
589 | void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg) | ||
590 | { | ||
591 | unsigned long flags; | ||
592 | |||
593 | spin_lock_irqsave(&edid_spinlock, flags); | ||
594 | memcpy(cfg, &hdmi_core_edid_cfg, sizeof(struct mxc_edid_cfg)); | ||
595 | spin_unlock_irqrestore(&edid_spinlock, flags); | ||
596 | } | ||
597 | EXPORT_SYMBOL(hdmi_get_edid_cfg); | ||
598 | |||
599 | void hdmi_set_registered(int registered) | ||
600 | { | ||
601 | hdmi_core_init = registered; | ||
602 | } | ||
603 | EXPORT_SYMBOL(hdmi_set_registered); | ||
604 | |||
605 | int hdmi_get_registered(void) | ||
606 | { | ||
607 | return hdmi_core_init; | ||
608 | } | ||
609 | EXPORT_SYMBOL(hdmi_get_registered); | ||
610 | |||
611 | static int mxc_hdmi_core_probe(struct platform_device *pdev) | ||
612 | { | ||
613 | struct mxc_hdmi_data *hdmi_data; | ||
614 | struct resource *res; | ||
615 | unsigned long flags; | ||
616 | int ret = 0; | ||
617 | |||
618 | #ifdef DEBUG | ||
619 | overflow_lo = false; | ||
620 | overflow_hi = false; | ||
621 | #endif | ||
622 | |||
623 | hdmi_core_init = 0; | ||
624 | hdmi_dma_running = 0; | ||
625 | |||
626 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
627 | if (!res) | ||
628 | return -ENOENT; | ||
629 | |||
630 | ret = hdmi_core_get_of_property(pdev); | ||
631 | if (ret < 0) { | ||
632 | dev_err(&pdev->dev, "get hdmi of property fail\n"); | ||
633 | return -ENOENT; | ||
634 | } | ||
635 | |||
636 | hdmi_data = devm_kzalloc(&pdev->dev, sizeof(struct mxc_hdmi_data), GFP_KERNEL); | ||
637 | if (!hdmi_data) { | ||
638 | dev_err(&pdev->dev, "Couldn't allocate mxc hdmi mfd device\n"); | ||
639 | return -ENOMEM; | ||
640 | } | ||
641 | hdmi_data->pdev = pdev; | ||
642 | |||
643 | pixel_clk = NULL; | ||
644 | sample_rate = 48000; | ||
645 | pixel_clk_rate = 0; | ||
646 | hdmi_ratio = 100; | ||
647 | |||
648 | spin_lock_init(&irq_spinlock); | ||
649 | spin_lock_init(&edid_spinlock); | ||
650 | |||
651 | |||
652 | spin_lock_init(&hdmi_cable_state_lock); | ||
653 | spin_lock_init(&hdmi_blank_state_lock); | ||
654 | spin_lock_init(&hdmi_audio_lock); | ||
655 | |||
656 | spin_lock_irqsave(&hdmi_cable_state_lock, flags); | ||
657 | hdmi_cable_state = 0; | ||
658 | spin_unlock_irqrestore(&hdmi_cable_state_lock, flags); | ||
659 | |||
660 | spin_lock_irqsave(&hdmi_blank_state_lock, flags); | ||
661 | hdmi_blank_state = 0; | ||
662 | spin_unlock_irqrestore(&hdmi_blank_state_lock, flags); | ||
663 | |||
664 | spin_lock_irqsave(&hdmi_audio_lock, flags); | ||
665 | hdmi_audio_stream_playback = NULL; | ||
666 | spin_unlock_irqrestore(&hdmi_audio_lock, flags); | ||
667 | |||
668 | isfr_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_isfr"); | ||
669 | if (IS_ERR(isfr_clk)) { | ||
670 | ret = PTR_ERR(isfr_clk); | ||
671 | dev_err(&hdmi_data->pdev->dev, | ||
672 | "Unable to get HDMI isfr clk: %d\n", ret); | ||
673 | goto eclkg; | ||
674 | } | ||
675 | |||
676 | ret = clk_prepare_enable(isfr_clk); | ||
677 | if (ret < 0) { | ||
678 | dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret); | ||
679 | goto eclke; | ||
680 | } | ||
681 | |||
682 | pr_debug("%s isfr_clk:%d\n", __func__, | ||
683 | (int)clk_get_rate(isfr_clk)); | ||
684 | |||
685 | iahb_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_iahb"); | ||
686 | if (IS_ERR(iahb_clk)) { | ||
687 | ret = PTR_ERR(iahb_clk); | ||
688 | dev_err(&hdmi_data->pdev->dev, | ||
689 | "Unable to get HDMI iahb clk: %d\n", ret); | ||
690 | goto eclkg2; | ||
691 | } | ||
692 | |||
693 | ret = clk_prepare_enable(iahb_clk); | ||
694 | if (ret < 0) { | ||
695 | dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret); | ||
696 | goto eclke2; | ||
697 | } | ||
698 | |||
699 | hdmi_data->reg_phys_base = res->start; | ||
700 | if (!request_mem_region(res->start, resource_size(res), | ||
701 | dev_name(&pdev->dev))) { | ||
702 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
703 | ret = -EBUSY; | ||
704 | goto emem; | ||
705 | } | ||
706 | |||
707 | hdmi_data->reg_base = ioremap(res->start, resource_size(res)); | ||
708 | if (!hdmi_data->reg_base) { | ||
709 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
710 | ret = -ENOMEM; | ||
711 | goto eirq; | ||
712 | } | ||
713 | hdmi_base = hdmi_data->reg_base; | ||
714 | |||
715 | pr_debug("\n%s hdmi hw base = 0x%08x\n\n", __func__, (int)res->start); | ||
716 | |||
717 | initialize_hdmi_ih_mutes(); | ||
718 | |||
719 | /* Disable HDMI clocks until video/audio sub-drivers are initialized */ | ||
720 | clk_disable_unprepare(isfr_clk); | ||
721 | clk_disable_unprepare(iahb_clk); | ||
722 | |||
723 | /* Replace platform data coming in with a local struct */ | ||
724 | platform_set_drvdata(pdev, hdmi_data); | ||
725 | |||
726 | return ret; | ||
727 | |||
728 | eirq: | ||
729 | release_mem_region(res->start, resource_size(res)); | ||
730 | emem: | ||
731 | clk_disable_unprepare(iahb_clk); | ||
732 | eclke2: | ||
733 | clk_put(iahb_clk); | ||
734 | eclkg2: | ||
735 | clk_disable_unprepare(isfr_clk); | ||
736 | eclke: | ||
737 | clk_put(isfr_clk); | ||
738 | eclkg: | ||
739 | return ret; | ||
740 | } | ||
741 | |||
742 | |||
743 | static int __exit mxc_hdmi_core_remove(struct platform_device *pdev) | ||
744 | { | ||
745 | struct mxc_hdmi_data *hdmi_data = platform_get_drvdata(pdev); | ||
746 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
747 | |||
748 | iounmap(hdmi_data->reg_base); | ||
749 | release_mem_region(res->start, resource_size(res)); | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static const struct of_device_id imx_hdmi_dt_ids[] = { | ||
755 | { .compatible = "fsl,imx6q-hdmi-core", }, | ||
756 | { .compatible = "fsl,imx6dl-hdmi-core", }, | ||
757 | { /* sentinel */ } | ||
758 | }; | ||
759 | |||
760 | static struct platform_driver mxc_hdmi_core_driver = { | ||
761 | .driver = { | ||
762 | .name = "mxc_hdmi_core", | ||
763 | .of_match_table = imx_hdmi_dt_ids, | ||
764 | .owner = THIS_MODULE, | ||
765 | }, | ||
766 | .remove = __exit_p(mxc_hdmi_core_remove), | ||
767 | }; | ||
768 | |||
769 | static int __init mxc_hdmi_core_init(void) | ||
770 | { | ||
771 | return platform_driver_probe(&mxc_hdmi_core_driver, | ||
772 | mxc_hdmi_core_probe); | ||
773 | } | ||
774 | |||
775 | static void __exit mxc_hdmi_core_exit(void) | ||
776 | { | ||
777 | platform_driver_unregister(&mxc_hdmi_core_driver); | ||
778 | } | ||
779 | |||
780 | subsys_initcall(mxc_hdmi_core_init); | ||
781 | module_exit(mxc_hdmi_core_exit); | ||
782 | |||
783 | MODULE_DESCRIPTION("Core driver for Freescale i.Mx on-chip HDMI"); | ||
784 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
785 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/mxc/Kconfig b/drivers/video/mxc/Kconfig index 0b4eaa97e094..3e4dcb1a6dea 100644 --- a/drivers/video/mxc/Kconfig +++ b/drivers/video/mxc/Kconfig | |||
@@ -22,3 +22,17 @@ config FB_MXC_LDB | |||
22 | tristate "MXC LDB" | 22 | tristate "MXC LDB" |
23 | depends on FB_MXC_SYNC_PANEL | 23 | depends on FB_MXC_SYNC_PANEL |
24 | depends on MXC_IPU_V3 | 24 | depends on MXC_IPU_V3 |
25 | |||
26 | config FB_MXC_HDMI | ||
27 | depends on FB_MXC_SYNC_PANEL | ||
28 | depends on MXC_IPU_V3 | ||
29 | depends on I2C | ||
30 | tristate "MXC HDMI driver support" | ||
31 | select MFD_MXC_HDMI | ||
32 | help | ||
33 | Driver for the on-chip MXC HDMI controller. | ||
34 | |||
35 | config FB_MXC_EDID | ||
36 | depends on FB_MXC && I2C | ||
37 | tristate "MXC EDID support" | ||
38 | default y | ||
diff --git a/drivers/video/mxc/Makefile b/drivers/video/mxc/Makefile index 5fc36bbf6ef3..b6148e81ca72 100644 --- a/drivers/video/mxc/Makefile +++ b/drivers/video/mxc/Makefile | |||
@@ -1,2 +1,4 @@ | |||
1 | obj-$(CONFIG_FB_MXC_LDB) += ldb.o | 1 | obj-$(CONFIG_FB_MXC_LDB) += ldb.o |
2 | obj-$(CONFIG_FB_MXC_HDMI) += mxc_hdmi.o | ||
3 | obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o | ||
2 | obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_dispdrv.o mxc_lcdif.o mxc_ipuv3_fb.o | 4 | obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_dispdrv.o mxc_lcdif.o mxc_ipuv3_fb.o |
diff --git a/drivers/video/mxc/mxc_edid.c b/drivers/video/mxc/mxc_edid.c new file mode 100644 index 000000000000..88b52682d99b --- /dev/null +++ b/drivers/video/mxc/mxc_edid.c | |||
@@ -0,0 +1,762 @@ | |||
1 | /* | ||
2 | * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * The code contained herein is licensed under the GNU General Public | ||
7 | * License. You may obtain a copy of the GNU General Public License | ||
8 | * Version 2 or later at the following locations: | ||
9 | * | ||
10 | * http://www.opensource.org/licenses/gpl-license.html | ||
11 | * http://www.gnu.org/copyleft/gpl.html | ||
12 | */ | ||
13 | |||
14 | /*! | ||
15 | * @defgroup Framebuffer Framebuffer Driver for SDC and ADC. | ||
16 | */ | ||
17 | |||
18 | /*! | ||
19 | * @file mxc_edid.c | ||
20 | * | ||
21 | * @brief MXC EDID driver | ||
22 | * | ||
23 | * @ingroup Framebuffer | ||
24 | */ | ||
25 | |||
26 | /*! | ||
27 | * Include files | ||
28 | */ | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/fb.h> | ||
31 | #include <video/mxc_edid.h> | ||
32 | #include "../edid.h" | ||
33 | |||
34 | #undef DEBUG /* define this for verbose EDID parsing output */ | ||
35 | #ifdef DEBUG | ||
36 | #define DPRINTK(fmt, args...) printk(fmt, ## args) | ||
37 | #else | ||
38 | #define DPRINTK(fmt, args...) | ||
39 | #endif | ||
40 | |||
41 | const struct fb_videomode mxc_cea_mode[64] = { | ||
42 | /* #1: 640x480p@59.94/60Hz 4:3 */ | ||
43 | [1] = { | ||
44 | NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0, | ||
45 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0, | ||
46 | }, | ||
47 | /* #2: 720x480p@59.94/60Hz 4:3 */ | ||
48 | [2] = { | ||
49 | NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0, | ||
50 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0, | ||
51 | }, | ||
52 | /* #3: 720x480p@59.94/60Hz 16:9 */ | ||
53 | [3] = { | ||
54 | NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0, | ||
55 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
56 | }, | ||
57 | /* #4: 1280x720p@59.94/60Hz 16:9 */ | ||
58 | [4] = { | ||
59 | NULL, 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5, | ||
60 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
61 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0 | ||
62 | }, | ||
63 | /* #5: 1920x1080i@59.94/60Hz 16:9 */ | ||
64 | [5] = { | ||
65 | NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5, | ||
66 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
67 | FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
68 | }, | ||
69 | /* #6: 720(1440)x480iH@59.94/60Hz 4:3 */ | ||
70 | [6] = { | ||
71 | NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0, | ||
72 | FB_VMODE_INTERLACED | FB_VMODE_ASPECT_4_3, 0, | ||
73 | }, | ||
74 | /* #7: 720(1440)x480iH@59.94/60Hz 16:9 */ | ||
75 | [7] = { | ||
76 | NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0, | ||
77 | FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
78 | }, | ||
79 | /* #8: 720(1440)x240pH@59.94/60Hz 4:3 */ | ||
80 | [8] = { | ||
81 | NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0, | ||
82 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0, | ||
83 | }, | ||
84 | /* #9: 720(1440)x240pH@59.94/60Hz 16:9 */ | ||
85 | [9] = { | ||
86 | NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0, | ||
87 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
88 | }, | ||
89 | /* #14: 1440x480p@59.94/60Hz 4:3 */ | ||
90 | [14] = { | ||
91 | NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0, | ||
92 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0, | ||
93 | }, | ||
94 | /* #15: 1440x480p@59.94/60Hz 16:9 */ | ||
95 | [15] = { | ||
96 | NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0, | ||
97 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
98 | }, | ||
99 | /* #16: 1920x1080p@60Hz 16:9 */ | ||
100 | [16] = { | ||
101 | NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5, | ||
102 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
103 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
104 | }, | ||
105 | /* #17: 720x576pH@50Hz 4:3 */ | ||
106 | [17] = { | ||
107 | NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0, | ||
108 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0, | ||
109 | }, | ||
110 | /* #18: 720x576pH@50Hz 16:9 */ | ||
111 | [18] = { | ||
112 | NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0, | ||
113 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
114 | }, | ||
115 | /* #19: 1280x720p@50Hz */ | ||
116 | [19] = { | ||
117 | NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5, | ||
118 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
119 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
120 | }, | ||
121 | /* #20: 1920x1080i@50Hz */ | ||
122 | [20] = { | ||
123 | NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5, | ||
124 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
125 | FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
126 | }, | ||
127 | /* #23: 720(1440)x288pH@50Hz 4:3 */ | ||
128 | [23] = { | ||
129 | NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0, | ||
130 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0, | ||
131 | }, | ||
132 | /* #24: 720(1440)x288pH@50Hz 16:9 */ | ||
133 | [24] = { | ||
134 | NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0, | ||
135 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
136 | }, | ||
137 | /* #29: 720(1440)x576pH@50Hz 4:3 */ | ||
138 | [29] = { | ||
139 | NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0, | ||
140 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0, | ||
141 | }, | ||
142 | /* #30: 720(1440)x576pH@50Hz 16:9 */ | ||
143 | [30] = { | ||
144 | NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0, | ||
145 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
146 | }, | ||
147 | /* #31: 1920x1080p@50Hz */ | ||
148 | [31] = { | ||
149 | NULL, 50, 1920, 1080, 6734, 148, 528, 36, 4, 44, 5, | ||
150 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
151 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
152 | }, | ||
153 | /* #32: 1920x1080p@23.98/24Hz */ | ||
154 | [32] = { | ||
155 | NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5, | ||
156 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
157 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
158 | }, | ||
159 | /* #33: 1920x1080p@25Hz */ | ||
160 | [33] = { | ||
161 | NULL, 25, 1920, 1080, 13468, 148, 528, 36, 4, 44, 5, | ||
162 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
163 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
164 | }, | ||
165 | /* #34: 1920x1080p@30Hz */ | ||
166 | [34] = { | ||
167 | NULL, 30, 1920, 1080, 13468, 148, 88, 36, 4, 44, 5, | ||
168 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
169 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0, | ||
170 | }, | ||
171 | /* #41: 1280x720p@100Hz 16:9 */ | ||
172 | [41] = { | ||
173 | NULL, 100, 1280, 720, 6734, 220, 440, 20, 5, 40, 5, | ||
174 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
175 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0 | ||
176 | }, | ||
177 | /* #47: 1280x720p@119.88/120Hz 16:9 */ | ||
178 | [47] = { | ||
179 | NULL, 120, 1280, 720, 6734, 220, 110, 20, 5, 40, 5, | ||
180 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
181 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0 | ||
182 | }, | ||
183 | }; | ||
184 | |||
185 | /* | ||
186 | * We have a special version of fb_mode_is_equal that ignores | ||
187 | * pixclock, since for many CEA modes, 2 frequencies are supported | ||
188 | * e.g. 640x480 @ 60Hz or 59.94Hz | ||
189 | */ | ||
190 | int mxc_edid_fb_mode_is_equal(bool use_aspect, | ||
191 | const struct fb_videomode *mode1, | ||
192 | const struct fb_videomode *mode2) | ||
193 | { | ||
194 | u32 mask; | ||
195 | |||
196 | if (use_aspect) | ||
197 | mask = ~0; | ||
198 | else | ||
199 | mask = ~FB_VMODE_ASPECT_MASK; | ||
200 | |||
201 | return (mode1->xres == mode2->xres && | ||
202 | mode1->yres == mode2->yres && | ||
203 | mode1->hsync_len == mode2->hsync_len && | ||
204 | mode1->vsync_len == mode2->vsync_len && | ||
205 | mode1->left_margin == mode2->left_margin && | ||
206 | mode1->right_margin == mode2->right_margin && | ||
207 | mode1->upper_margin == mode2->upper_margin && | ||
208 | mode1->lower_margin == mode2->lower_margin && | ||
209 | mode1->sync == mode2->sync && | ||
210 | /* refresh check, 59.94Hz and 60Hz have the same parameter | ||
211 | * in struct of mxc_cea_mode */ | ||
212 | abs(mode1->refresh - mode2->refresh) <= 1 && | ||
213 | (mode1->vmode & mask) == (mode2->vmode & mask)); | ||
214 | } | ||
215 | |||
216 | static void get_detailed_timing(unsigned char *block, | ||
217 | struct fb_videomode *mode) | ||
218 | { | ||
219 | mode->xres = H_ACTIVE; | ||
220 | mode->yres = V_ACTIVE; | ||
221 | mode->pixclock = PIXEL_CLOCK; | ||
222 | mode->pixclock /= 1000; | ||
223 | mode->pixclock = KHZ2PICOS(mode->pixclock); | ||
224 | mode->right_margin = H_SYNC_OFFSET; | ||
225 | mode->left_margin = (H_ACTIVE + H_BLANKING) - | ||
226 | (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); | ||
227 | mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - | ||
228 | V_SYNC_WIDTH; | ||
229 | mode->lower_margin = V_SYNC_OFFSET; | ||
230 | mode->hsync_len = H_SYNC_WIDTH; | ||
231 | mode->vsync_len = V_SYNC_WIDTH; | ||
232 | if (HSYNC_POSITIVE) | ||
233 | mode->sync |= FB_SYNC_HOR_HIGH_ACT; | ||
234 | if (VSYNC_POSITIVE) | ||
235 | mode->sync |= FB_SYNC_VERT_HIGH_ACT; | ||
236 | mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) * | ||
237 | (V_ACTIVE + V_BLANKING)); | ||
238 | if (INTERLACED) { | ||
239 | mode->yres *= 2; | ||
240 | mode->upper_margin *= 2; | ||
241 | mode->lower_margin *= 2; | ||
242 | mode->vsync_len *= 2; | ||
243 | mode->vmode |= FB_VMODE_INTERLACED; | ||
244 | } | ||
245 | mode->flag = FB_MODE_IS_DETAILED; | ||
246 | |||
247 | if ((H_SIZE / 16) == (V_SIZE / 9)) | ||
248 | mode->vmode |= FB_VMODE_ASPECT_16_9; | ||
249 | else if ((H_SIZE / 4) == (V_SIZE / 3)) | ||
250 | mode->vmode |= FB_VMODE_ASPECT_4_3; | ||
251 | else if ((mode->xres / 16) == (mode->yres / 9)) | ||
252 | mode->vmode |= FB_VMODE_ASPECT_16_9; | ||
253 | else if ((mode->xres / 4) == (mode->yres / 3)) | ||
254 | mode->vmode |= FB_VMODE_ASPECT_4_3; | ||
255 | |||
256 | if (mode->vmode & FB_VMODE_ASPECT_16_9) | ||
257 | DPRINTK("Aspect ratio: 16:9\n"); | ||
258 | if (mode->vmode & FB_VMODE_ASPECT_4_3) | ||
259 | DPRINTK("Aspect ratio: 4:3\n"); | ||
260 | DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000); | ||
261 | DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET, | ||
262 | H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING); | ||
263 | DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET, | ||
264 | V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING); | ||
265 | DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-", | ||
266 | (VSYNC_POSITIVE) ? "+" : "-"); | ||
267 | } | ||
268 | |||
269 | int mxc_edid_parse_ext_blk(unsigned char *edid, | ||
270 | struct mxc_edid_cfg *cfg, | ||
271 | struct fb_monspecs *specs) | ||
272 | { | ||
273 | char detail_timing_desc_offset; | ||
274 | struct fb_videomode *mode, *m; | ||
275 | unsigned char index = 0x0; | ||
276 | unsigned char *block; | ||
277 | int i, num = 0, revision; | ||
278 | |||
279 | if (edid[index++] != 0x2) /* only support cea ext block now */ | ||
280 | return -1; | ||
281 | revision = edid[index++]; | ||
282 | DPRINTK("cea extent revision %d\n", revision); | ||
283 | mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); | ||
284 | if (mode == NULL) | ||
285 | return -1; | ||
286 | |||
287 | detail_timing_desc_offset = edid[index++]; | ||
288 | |||
289 | if (revision >= 2) { | ||
290 | cfg->cea_underscan = (edid[index] >> 7) & 0x1; | ||
291 | cfg->cea_basicaudio = (edid[index] >> 6) & 0x1; | ||
292 | cfg->cea_ycbcr444 = (edid[index] >> 5) & 0x1; | ||
293 | cfg->cea_ycbcr422 = (edid[index] >> 4) & 0x1; | ||
294 | |||
295 | DPRINTK("CEA underscan %d\n", cfg->cea_underscan); | ||
296 | DPRINTK("CEA basicaudio %d\n", cfg->cea_basicaudio); | ||
297 | DPRINTK("CEA ycbcr444 %d\n", cfg->cea_ycbcr444); | ||
298 | DPRINTK("CEA ycbcr422 %d\n", cfg->cea_ycbcr422); | ||
299 | } | ||
300 | |||
301 | if (revision >= 3) { | ||
302 | /* short desc */ | ||
303 | DPRINTK("CEA Short desc timmings\n"); | ||
304 | index++; | ||
305 | while (index < detail_timing_desc_offset) { | ||
306 | unsigned char tagcode, blklen; | ||
307 | |||
308 | tagcode = (edid[index] >> 5) & 0x7; | ||
309 | blklen = (edid[index]) & 0x1f; | ||
310 | |||
311 | DPRINTK("Tagcode %x Len %d\n", tagcode, blklen); | ||
312 | |||
313 | switch (tagcode) { | ||
314 | case 0x2: /*Video data block*/ | ||
315 | { | ||
316 | int cea_idx; | ||
317 | i = 0; | ||
318 | while (i < blklen) { | ||
319 | index++; | ||
320 | cea_idx = edid[index] & 0x7f; | ||
321 | if (cea_idx < ARRAY_SIZE(mxc_cea_mode) && | ||
322 | (mxc_cea_mode[cea_idx].xres)) { | ||
323 | DPRINTK("Support CEA Format #%d\n", cea_idx); | ||
324 | mode[num] = mxc_cea_mode[cea_idx]; | ||
325 | mode[num].flag |= FB_MODE_IS_STANDARD; | ||
326 | num++; | ||
327 | } | ||
328 | i++; | ||
329 | } | ||
330 | break; | ||
331 | } | ||
332 | case 0x3: /*Vendor specific data*/ | ||
333 | { | ||
334 | unsigned char IEEE_reg_iden[3]; | ||
335 | unsigned char deep_color; | ||
336 | unsigned char latency_present; | ||
337 | unsigned char I_latency_present; | ||
338 | unsigned char hdmi_video_present; | ||
339 | unsigned char hdmi_3d_present; | ||
340 | unsigned char hdmi_3d_multi_present; | ||
341 | unsigned char hdmi_vic_len; | ||
342 | unsigned char hdmi_3d_len; | ||
343 | unsigned char index_inc = 0; | ||
344 | unsigned char vsd_end; | ||
345 | |||
346 | vsd_end = index + blklen; | ||
347 | |||
348 | IEEE_reg_iden[0] = edid[index+1]; | ||
349 | IEEE_reg_iden[1] = edid[index+2]; | ||
350 | IEEE_reg_iden[2] = edid[index+3]; | ||
351 | cfg->physical_address[0] = (edid[index+4] & 0xf0) >> 4; | ||
352 | cfg->physical_address[1] = (edid[index+4] & 0x0f); | ||
353 | cfg->physical_address[2] = (edid[index+5] & 0xf0) >> 4; | ||
354 | cfg->physical_address[3] = (edid[index+5] & 0x0f); | ||
355 | |||
356 | if ((IEEE_reg_iden[0] == 0x03) && | ||
357 | (IEEE_reg_iden[1] == 0x0c) && | ||
358 | (IEEE_reg_iden[2] == 0x00)) | ||
359 | cfg->hdmi_cap = 1; | ||
360 | |||
361 | if (blklen > 5) { | ||
362 | deep_color = edid[index+6]; | ||
363 | if (deep_color & 0x80) | ||
364 | cfg->vsd_support_ai = true; | ||
365 | if (deep_color & 0x40) | ||
366 | cfg->vsd_dc_48bit = true; | ||
367 | if (deep_color & 0x20) | ||
368 | cfg->vsd_dc_36bit = true; | ||
369 | if (deep_color & 0x10) | ||
370 | cfg->vsd_dc_30bit = true; | ||
371 | if (deep_color & 0x08) | ||
372 | cfg->vsd_dc_y444 = true; | ||
373 | if (deep_color & 0x01) | ||
374 | cfg->vsd_dvi_dual = true; | ||
375 | } | ||
376 | |||
377 | DPRINTK("VSD hdmi capability %d\n", cfg->hdmi_cap); | ||
378 | DPRINTK("VSD support ai %d\n", cfg->vsd_support_ai); | ||
379 | DPRINTK("VSD support deep color 48bit %d\n", cfg->vsd_dc_48bit); | ||
380 | DPRINTK("VSD support deep color 36bit %d\n", cfg->vsd_dc_36bit); | ||
381 | DPRINTK("VSD support deep color 30bit %d\n", cfg->vsd_dc_30bit); | ||
382 | DPRINTK("VSD support deep color y444 %d\n", cfg->vsd_dc_y444); | ||
383 | DPRINTK("VSD support dvi dual %d\n", cfg->vsd_dvi_dual); | ||
384 | |||
385 | if (blklen > 6) | ||
386 | cfg->vsd_max_tmdsclk_rate = edid[index+7] * 5; | ||
387 | DPRINTK("VSD MAX TMDS CLOCK RATE %d\n", cfg->vsd_max_tmdsclk_rate); | ||
388 | |||
389 | if (blklen > 7) { | ||
390 | latency_present = edid[index+8] >> 7; | ||
391 | I_latency_present = (edid[index+8] & 0x40) >> 6; | ||
392 | hdmi_video_present = (edid[index+8] & 0x20) >> 5; | ||
393 | cfg->vsd_cnc3 = (edid[index+8] & 0x8) >> 3; | ||
394 | cfg->vsd_cnc2 = (edid[index+8] & 0x4) >> 2; | ||
395 | cfg->vsd_cnc1 = (edid[index+8] & 0x2) >> 1; | ||
396 | cfg->vsd_cnc0 = edid[index+8] & 0x1; | ||
397 | |||
398 | DPRINTK("VSD cnc0 %d\n", cfg->vsd_cnc0); | ||
399 | DPRINTK("VSD cnc1 %d\n", cfg->vsd_cnc1); | ||
400 | DPRINTK("VSD cnc2 %d\n", cfg->vsd_cnc2); | ||
401 | DPRINTK("VSD cnc3 %d\n", cfg->vsd_cnc3); | ||
402 | DPRINTK("latency_present %d\n", latency_present); | ||
403 | DPRINTK("I_latency_present %d\n", I_latency_present); | ||
404 | DPRINTK("hdmi_video_present %d\n", hdmi_video_present); | ||
405 | |||
406 | } else { | ||
407 | index += blklen; | ||
408 | break; | ||
409 | } | ||
410 | |||
411 | index += 9; | ||
412 | |||
413 | /*latency present */ | ||
414 | if (latency_present) { | ||
415 | cfg->vsd_video_latency = edid[index++]; | ||
416 | cfg->vsd_audio_latency = edid[index++]; | ||
417 | |||
418 | if (I_latency_present) { | ||
419 | cfg->vsd_I_video_latency = edid[index++]; | ||
420 | cfg->vsd_I_audio_latency = edid[index++]; | ||
421 | } else { | ||
422 | cfg->vsd_I_video_latency = cfg->vsd_video_latency; | ||
423 | cfg->vsd_I_audio_latency = cfg->vsd_audio_latency; | ||
424 | } | ||
425 | |||
426 | DPRINTK("VSD latency video_latency %d\n", cfg->vsd_video_latency); | ||
427 | DPRINTK("VSD latency audio_latency %d\n", cfg->vsd_audio_latency); | ||
428 | DPRINTK("VSD latency I_video_latency %d\n", cfg->vsd_I_video_latency); | ||
429 | DPRINTK("VSD latency I_audio_latency %d\n", cfg->vsd_I_audio_latency); | ||
430 | } | ||
431 | |||
432 | if (hdmi_video_present) { | ||
433 | hdmi_3d_present = edid[index] >> 7; | ||
434 | hdmi_3d_multi_present = (edid[index] & 0x60) >> 5; | ||
435 | index++; | ||
436 | hdmi_vic_len = (edid[index] & 0xe0) >> 5; | ||
437 | hdmi_3d_len = edid[index] & 0x1f; | ||
438 | index++; | ||
439 | |||
440 | DPRINTK("hdmi_3d_present %d\n", hdmi_3d_present); | ||
441 | DPRINTK("hdmi_3d_multi_present %d\n", hdmi_3d_multi_present); | ||
442 | DPRINTK("hdmi_vic_len %d\n", hdmi_vic_len); | ||
443 | DPRINTK("hdmi_3d_len %d\n", hdmi_3d_len); | ||
444 | |||
445 | if (hdmi_vic_len > 0) { | ||
446 | for (i = 0; i < hdmi_vic_len; i++) { | ||
447 | cfg->hdmi_vic[i] = edid[index++]; | ||
448 | DPRINTK("HDMI_vic=%d\n", cfg->hdmi_vic[i]); | ||
449 | } | ||
450 | } | ||
451 | |||
452 | if (hdmi_3d_len > 0) { | ||
453 | if (hdmi_3d_present) { | ||
454 | if (hdmi_3d_multi_present == 0x1) { | ||
455 | cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1]; | ||
456 | index_inc = 2; | ||
457 | } else if (hdmi_3d_multi_present == 0x2) { | ||
458 | cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1]; | ||
459 | cfg->hdmi_3d_mask_all = (edid[index+2] << 8) | edid[index+3]; | ||
460 | index_inc = 4; | ||
461 | } else | ||
462 | index_inc = 0; | ||
463 | } | ||
464 | |||
465 | DPRINTK("HDMI 3d struct all =0x%x\n", cfg->hdmi_3d_struct_all); | ||
466 | DPRINTK("HDMI 3d mask all =0x%x\n", cfg->hdmi_3d_mask_all); | ||
467 | |||
468 | /* Read 2D vic 3D_struct */ | ||
469 | if ((hdmi_3d_len - index_inc) > 0) { | ||
470 | DPRINTK("Support 3D video format\n"); | ||
471 | i = 0; | ||
472 | while ((hdmi_3d_len - index_inc) > 0) { | ||
473 | |||
474 | cfg->hdmi_3d_format[i].vic_order_2d = edid[index+index_inc] >> 4; | ||
475 | cfg->hdmi_3d_format[i].struct_3d = edid[index+index_inc] & 0x0f; | ||
476 | index_inc++; | ||
477 | |||
478 | if (cfg->hdmi_3d_format[i].struct_3d == 8) { | ||
479 | cfg->hdmi_3d_format[i].detail_3d = edid[index+index_inc] >> 4; | ||
480 | index_inc++; | ||
481 | } else if (cfg->hdmi_3d_format[i].struct_3d > 8) { | ||
482 | cfg->hdmi_3d_format[i].detail_3d = 0; | ||
483 | index_inc++; | ||
484 | } | ||
485 | |||
486 | DPRINTK("vic_order_2d=%d, 3d_struct=%d, 3d_detail=0x%x\n", | ||
487 | cfg->hdmi_3d_format[i].vic_order_2d, | ||
488 | cfg->hdmi_3d_format[i].struct_3d, | ||
489 | cfg->hdmi_3d_format[i].detail_3d); | ||
490 | i++; | ||
491 | } | ||
492 | } | ||
493 | index += index_inc; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | index = vsd_end; | ||
498 | |||
499 | break; | ||
500 | } | ||
501 | case 0x1: /*Audio data block*/ | ||
502 | { | ||
503 | u8 audio_format, max_ch, byte1, byte2, byte3; | ||
504 | |||
505 | i = 0; | ||
506 | cfg->max_channels = 0; | ||
507 | cfg->sample_rates = 0; | ||
508 | cfg->sample_sizes = 0; | ||
509 | |||
510 | while (i < blklen) { | ||
511 | byte1 = edid[index + 1]; | ||
512 | byte2 = edid[index + 2]; | ||
513 | byte3 = edid[index + 3]; | ||
514 | index += 3; | ||
515 | i += 3; | ||
516 | |||
517 | audio_format = byte1 >> 3; | ||
518 | max_ch = (byte1 & 0x07) + 1; | ||
519 | |||
520 | DPRINTK("Audio Format Descriptor : %2d\n", audio_format); | ||
521 | DPRINTK("Max Number of Channels : %2d\n", max_ch); | ||
522 | DPRINTK("Sample Rates : %02x\n", byte2); | ||
523 | |||
524 | /* ALSA can't specify specific compressed | ||
525 | * formats, so only care about PCM for now. */ | ||
526 | if (audio_format == AUDIO_CODING_TYPE_LPCM) { | ||
527 | if (max_ch > cfg->max_channels) | ||
528 | cfg->max_channels = max_ch; | ||
529 | |||
530 | cfg->sample_rates |= byte2; | ||
531 | cfg->sample_sizes |= byte3 & 0x7; | ||
532 | DPRINTK("Sample Sizes : %02x\n", | ||
533 | byte3 & 0x7); | ||
534 | } | ||
535 | } | ||
536 | break; | ||
537 | } | ||
538 | case 0x4: /*Speaker allocation block*/ | ||
539 | { | ||
540 | i = 0; | ||
541 | while (i < blklen) { | ||
542 | cfg->speaker_alloc = edid[index + 1]; | ||
543 | index += 3; | ||
544 | i += 3; | ||
545 | DPRINTK("Speaker Alloc : %02x\n", cfg->speaker_alloc); | ||
546 | } | ||
547 | break; | ||
548 | } | ||
549 | case 0x7: /*User extended block*/ | ||
550 | default: | ||
551 | /* skip */ | ||
552 | DPRINTK("Not handle block, tagcode = 0x%x\n", tagcode); | ||
553 | index += blklen; | ||
554 | break; | ||
555 | } | ||
556 | |||
557 | index++; | ||
558 | } | ||
559 | } | ||
560 | |||
561 | /* long desc */ | ||
562 | DPRINTK("CEA long desc timmings\n"); | ||
563 | index = detail_timing_desc_offset; | ||
564 | block = edid + index; | ||
565 | while (index < (EDID_LENGTH - DETAILED_TIMING_DESCRIPTION_SIZE)) { | ||
566 | if (!(block[0] == 0x00 && block[1] == 0x00)) { | ||
567 | get_detailed_timing(block, &mode[num]); | ||
568 | num++; | ||
569 | } | ||
570 | block += DETAILED_TIMING_DESCRIPTION_SIZE; | ||
571 | index += DETAILED_TIMING_DESCRIPTION_SIZE; | ||
572 | } | ||
573 | |||
574 | if (!num) { | ||
575 | kfree(mode); | ||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | m = kmalloc((num + specs->modedb_len) * | ||
580 | sizeof(struct fb_videomode), GFP_KERNEL); | ||
581 | if (!m) | ||
582 | return 0; | ||
583 | |||
584 | if (specs->modedb_len) { | ||
585 | memmove(m, specs->modedb, | ||
586 | specs->modedb_len * sizeof(struct fb_videomode)); | ||
587 | kfree(specs->modedb); | ||
588 | } | ||
589 | memmove(m+specs->modedb_len, mode, | ||
590 | num * sizeof(struct fb_videomode)); | ||
591 | kfree(mode); | ||
592 | |||
593 | specs->modedb_len += num; | ||
594 | specs->modedb = m; | ||
595 | |||
596 | return 0; | ||
597 | } | ||
598 | EXPORT_SYMBOL(mxc_edid_parse_ext_blk); | ||
599 | |||
600 | static int mxc_edid_readblk(struct i2c_adapter *adp, | ||
601 | unsigned short addr, unsigned char *edid) | ||
602 | { | ||
603 | int ret = 0, extblknum = 0; | ||
604 | unsigned char regaddr = 0x0; | ||
605 | struct i2c_msg msg[2] = { | ||
606 | { | ||
607 | .addr = addr, | ||
608 | .flags = 0, | ||
609 | .len = 1, | ||
610 | .buf = ®addr, | ||
611 | }, { | ||
612 | .addr = addr, | ||
613 | .flags = I2C_M_RD, | ||
614 | .len = EDID_LENGTH, | ||
615 | .buf = edid, | ||
616 | }, | ||
617 | }; | ||
618 | |||
619 | ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg)); | ||
620 | if (ret != ARRAY_SIZE(msg)) { | ||
621 | DPRINTK("unable to read EDID block\n"); | ||
622 | return -EIO; | ||
623 | } | ||
624 | |||
625 | if (edid[1] == 0x00) | ||
626 | return -ENOENT; | ||
627 | |||
628 | extblknum = edid[0x7E]; | ||
629 | |||
630 | if (extblknum) { | ||
631 | regaddr = 128; | ||
632 | msg[1].buf = edid + EDID_LENGTH; | ||
633 | |||
634 | ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg)); | ||
635 | if (ret != ARRAY_SIZE(msg)) { | ||
636 | DPRINTK("unable to read EDID ext block\n"); | ||
637 | return -EIO; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | return extblknum; | ||
642 | } | ||
643 | |||
644 | static int mxc_edid_readsegblk(struct i2c_adapter *adp, unsigned short addr, | ||
645 | unsigned char *edid, int seg_num) | ||
646 | { | ||
647 | int ret = 0; | ||
648 | unsigned char segment = 0x1, regaddr = 0; | ||
649 | struct i2c_msg msg[3] = { | ||
650 | { | ||
651 | .addr = 0x30, | ||
652 | .flags = 0, | ||
653 | .len = 1, | ||
654 | .buf = &segment, | ||
655 | }, { | ||
656 | .addr = addr, | ||
657 | .flags = 0, | ||
658 | .len = 1, | ||
659 | .buf = ®addr, | ||
660 | }, { | ||
661 | .addr = addr, | ||
662 | .flags = I2C_M_RD, | ||
663 | .len = EDID_LENGTH, | ||
664 | .buf = edid, | ||
665 | }, | ||
666 | }; | ||
667 | |||
668 | ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg)); | ||
669 | if (ret != ARRAY_SIZE(msg)) { | ||
670 | DPRINTK("unable to read EDID block\n"); | ||
671 | return -EIO; | ||
672 | } | ||
673 | |||
674 | if (seg_num == 2) { | ||
675 | regaddr = 128; | ||
676 | msg[2].buf = edid + EDID_LENGTH; | ||
677 | |||
678 | ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg)); | ||
679 | if (ret != ARRAY_SIZE(msg)) { | ||
680 | DPRINTK("unable to read EDID block\n"); | ||
681 | return -EIO; | ||
682 | } | ||
683 | } | ||
684 | |||
685 | return ret; | ||
686 | } | ||
687 | |||
688 | int mxc_edid_var_to_vic(struct fb_var_screeninfo *var) | ||
689 | { | ||
690 | int i; | ||
691 | struct fb_videomode m; | ||
692 | |||
693 | for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) { | ||
694 | fb_var_to_videomode(&m, var); | ||
695 | if (mxc_edid_fb_mode_is_equal(false, &m, &mxc_cea_mode[i])) | ||
696 | break; | ||
697 | } | ||
698 | |||
699 | if (i == ARRAY_SIZE(mxc_cea_mode)) | ||
700 | return 0; | ||
701 | |||
702 | return i; | ||
703 | } | ||
704 | EXPORT_SYMBOL(mxc_edid_var_to_vic); | ||
705 | |||
706 | int mxc_edid_mode_to_vic(const struct fb_videomode *mode) | ||
707 | { | ||
708 | int i; | ||
709 | bool use_aspect = (mode->vmode & FB_VMODE_ASPECT_MASK); | ||
710 | |||
711 | for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) { | ||
712 | if (mxc_edid_fb_mode_is_equal(use_aspect, mode, &mxc_cea_mode[i])) | ||
713 | break; | ||
714 | } | ||
715 | |||
716 | if (i == ARRAY_SIZE(mxc_cea_mode)) | ||
717 | return 0; | ||
718 | |||
719 | return i; | ||
720 | } | ||
721 | EXPORT_SYMBOL(mxc_edid_mode_to_vic); | ||
722 | |||
723 | /* make sure edid has 512 bytes*/ | ||
724 | int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr, | ||
725 | unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi) | ||
726 | { | ||
727 | int ret = 0, extblknum; | ||
728 | if (!adp || !edid || !cfg || !fbi) | ||
729 | return -EINVAL; | ||
730 | |||
731 | memset(edid, 0, EDID_LENGTH*4); | ||
732 | memset(cfg, 0, sizeof(struct mxc_edid_cfg)); | ||
733 | |||
734 | extblknum = mxc_edid_readblk(adp, addr, edid); | ||
735 | if (extblknum < 0) | ||
736 | return extblknum; | ||
737 | |||
738 | /* edid first block parsing */ | ||
739 | memset(&fbi->monspecs, 0, sizeof(fbi->monspecs)); | ||
740 | fb_edid_to_monspecs(edid, &fbi->monspecs); | ||
741 | |||
742 | if (extblknum) { | ||
743 | int i; | ||
744 | |||
745 | /* need read segment block? */ | ||
746 | if (extblknum > 1) { | ||
747 | ret = mxc_edid_readsegblk(adp, addr, | ||
748 | edid + EDID_LENGTH*2, extblknum - 1); | ||
749 | if (ret < 0) | ||
750 | return ret; | ||
751 | } | ||
752 | |||
753 | for (i = 1; i <= extblknum; i++) | ||
754 | /* edid ext block parsing */ | ||
755 | mxc_edid_parse_ext_blk(edid + i*EDID_LENGTH, | ||
756 | cfg, &fbi->monspecs); | ||
757 | } | ||
758 | |||
759 | return 0; | ||
760 | } | ||
761 | EXPORT_SYMBOL(mxc_edid_read); | ||
762 | |||
diff --git a/drivers/video/mxc/mxc_hdmi.c b/drivers/video/mxc/mxc_hdmi.c new file mode 100644 index 000000000000..6c0d422d669a --- /dev/null +++ b/drivers/video/mxc/mxc_hdmi.c | |||
@@ -0,0 +1,2971 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | */ | ||
19 | /* | ||
20 | * SH-Mobile High-Definition Multimedia Interface (HDMI) driver | ||
21 | * for SLISHDMI13T and SLIPHDMIT IP cores | ||
22 | * | ||
23 | * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
24 | * | ||
25 | * This program is free software; you can redistribute it and/or modify | ||
26 | * it under the terms of the GNU General Public License version 2 as | ||
27 | * published by the Free Software Foundation. | ||
28 | */ | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/input.h> | ||
34 | #include <linux/interrupt.h> | ||
35 | #include <linux/irq.h> | ||
36 | #include <linux/io.h> | ||
37 | #include <linux/fb.h> | ||
38 | #include <linux/init.h> | ||
39 | #include <linux/list.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/dma-mapping.h> | ||
42 | #include <linux/err.h> | ||
43 | #include <linux/clk.h> | ||
44 | #include <linux/uaccess.h> | ||
45 | #include <linux/cpufreq.h> | ||
46 | #include <linux/firmware.h> | ||
47 | #include <linux/kthread.h> | ||
48 | #include <linux/regulator/driver.h> | ||
49 | #include <linux/fsl_devices.h> | ||
50 | #include <linux/ipu.h> | ||
51 | #include <linux/regmap.h> | ||
52 | #include <linux/pinctrl/consumer.h> | ||
53 | #include <linux/of_device.h> | ||
54 | |||
55 | #include <linux/console.h> | ||
56 | #include <linux/types.h> | ||
57 | |||
58 | #include "../edid.h" | ||
59 | #include <video/mxc_edid.h> | ||
60 | #include <video/mxc_hdmi.h> | ||
61 | #include "mxc_dispdrv.h" | ||
62 | |||
63 | #include <linux/mfd/mxc-hdmi-core.h> | ||
64 | |||
65 | #define DISPDRV_HDMI "hdmi" | ||
66 | #define HDMI_EDID_LEN 512 | ||
67 | |||
68 | /* status codes for reading edid */ | ||
69 | #define HDMI_EDID_SUCCESS 0 | ||
70 | #define HDMI_EDID_FAIL -1 | ||
71 | #define HDMI_EDID_SAME -2 | ||
72 | #define HDMI_EDID_NO_MODES -3 | ||
73 | |||
74 | #define NUM_CEA_VIDEO_MODES 64 | ||
75 | #define DEFAULT_VIDEO_MODE 16 /* 1080P */ | ||
76 | |||
77 | #define RGB 0 | ||
78 | #define YCBCR444 1 | ||
79 | #define YCBCR422_16BITS 2 | ||
80 | #define YCBCR422_8BITS 3 | ||
81 | #define XVYCC444 4 | ||
82 | |||
83 | /* | ||
84 | * We follow a flowchart which is in the "Synopsys DesignWare Courses | ||
85 | * HDMI Transmitter Controller User Guide, 1.30a", section 3.1 | ||
86 | * (dwc_hdmi_tx_user.pdf) | ||
87 | * | ||
88 | * Below are notes that say "HDMI Initialization Step X" | ||
89 | * These correspond to the flowchart. | ||
90 | */ | ||
91 | |||
92 | /* | ||
93 | * We are required to configure VGA mode before reading edid | ||
94 | * in HDMI Initialization Step B | ||
95 | */ | ||
96 | static const struct fb_videomode vga_mode = { | ||
97 | /* 640x480 @ 60 Hz, 31.5 kHz hsync */ | ||
98 | NULL, 60, 640, 480, 39721, 48, 16, 33, 10, 96, 2, 0, | ||
99 | FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, FB_MODE_IS_VESA, | ||
100 | }; | ||
101 | |||
102 | static const struct fb_videomode xga_mode = { | ||
103 | /* 13 1024x768-60 VESA */ | ||
104 | NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6, | ||
105 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA | ||
106 | }; | ||
107 | |||
108 | static const struct fb_videomode sxga_mode = { | ||
109 | /* 20 1280x1024-60 VESA */ | ||
110 | NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, | ||
111 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
112 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA | ||
113 | }; | ||
114 | |||
115 | enum hdmi_datamap { | ||
116 | RGB444_8B = 0x01, | ||
117 | RGB444_10B = 0x03, | ||
118 | RGB444_12B = 0x05, | ||
119 | RGB444_16B = 0x07, | ||
120 | YCbCr444_8B = 0x09, | ||
121 | YCbCr444_10B = 0x0B, | ||
122 | YCbCr444_12B = 0x0D, | ||
123 | YCbCr444_16B = 0x0F, | ||
124 | YCbCr422_8B = 0x16, | ||
125 | YCbCr422_10B = 0x14, | ||
126 | YCbCr422_12B = 0x12, | ||
127 | }; | ||
128 | |||
129 | enum hdmi_colorimetry { | ||
130 | eITU601, | ||
131 | eITU709, | ||
132 | }; | ||
133 | |||
134 | struct hdmi_vmode { | ||
135 | bool mDVI; | ||
136 | bool mHSyncPolarity; | ||
137 | bool mVSyncPolarity; | ||
138 | bool mInterlaced; | ||
139 | bool mDataEnablePolarity; | ||
140 | |||
141 | unsigned int mPixelClock; | ||
142 | unsigned int mPixelRepetitionInput; | ||
143 | unsigned int mPixelRepetitionOutput; | ||
144 | }; | ||
145 | |||
146 | struct hdmi_data_info { | ||
147 | unsigned int enc_in_format; | ||
148 | unsigned int enc_out_format; | ||
149 | unsigned int enc_color_depth; | ||
150 | unsigned int colorimetry; | ||
151 | unsigned int pix_repet_factor; | ||
152 | unsigned int hdcp_enable; | ||
153 | unsigned int rgb_out_enable; | ||
154 | struct hdmi_vmode video_mode; | ||
155 | }; | ||
156 | |||
157 | struct hdmi_phy_reg_config { | ||
158 | /* HDMI PHY register config for pass HCT */ | ||
159 | u16 reg_vlev; | ||
160 | u16 reg_cksymtx; | ||
161 | }; | ||
162 | |||
163 | struct mxc_hdmi { | ||
164 | struct platform_device *pdev; | ||
165 | struct platform_device *core_pdev; | ||
166 | struct mxc_dispdrv_handle *disp_mxc_hdmi; | ||
167 | struct fb_info *fbi; | ||
168 | struct clk *hdmi_isfr_clk; | ||
169 | struct clk *hdmi_iahb_clk; | ||
170 | struct delayed_work hotplug_work; | ||
171 | struct delayed_work hdcp_hdp_work; | ||
172 | |||
173 | struct notifier_block nb; | ||
174 | |||
175 | struct hdmi_data_info hdmi_data; | ||
176 | int vic; | ||
177 | struct mxc_edid_cfg edid_cfg; | ||
178 | u8 edid[HDMI_EDID_LEN]; | ||
179 | bool fb_reg; | ||
180 | bool cable_plugin; | ||
181 | u8 blank; | ||
182 | bool dft_mode_set; | ||
183 | char *dft_mode_str; | ||
184 | int default_bpp; | ||
185 | u8 latest_intr_stat; | ||
186 | bool irq_enabled; | ||
187 | spinlock_t irq_lock; | ||
188 | bool phy_enabled; | ||
189 | struct fb_videomode previous_mode; | ||
190 | struct fb_videomode previous_non_vga_mode; | ||
191 | bool requesting_vga_for_initialization; | ||
192 | |||
193 | int *gpr_base; | ||
194 | int *gpr_hdmi_base; | ||
195 | int *gpr_sdma_base; | ||
196 | int cpu_type; | ||
197 | int cpu_version; | ||
198 | struct hdmi_phy_reg_config phy_config; | ||
199 | |||
200 | struct pinctrl *pinctrl; | ||
201 | struct pinctrl_state *pins_hdcp; | ||
202 | struct pinctrl_state *pins_cec; | ||
203 | }; | ||
204 | |||
205 | enum imx_hdmim_type { | ||
206 | IMX6DL_HDMI, | ||
207 | IMX6Q_HDMI, | ||
208 | }; | ||
209 | |||
210 | static int hdmi_major; | ||
211 | static struct class *hdmi_class; | ||
212 | |||
213 | |||
214 | struct i2c_client *hdmi_i2c; | ||
215 | struct mxc_hdmi *g_hdmi; | ||
216 | |||
217 | static bool hdmi_inited; | ||
218 | |||
219 | extern const struct fb_videomode mxc_cea_mode[64]; | ||
220 | extern void mxc_hdmi_cec_handle(u16 cec_stat); | ||
221 | |||
222 | static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event); | ||
223 | |||
224 | static struct platform_device_id imx_hdmi_devtype[] = { | ||
225 | { | ||
226 | .name = "hdmi-imx6DL", | ||
227 | .driver_data = IMX6DL_HDMI, | ||
228 | }, { | ||
229 | .name = "hdmi-imx6Q", | ||
230 | .driver_data = IMX6Q_HDMI, | ||
231 | }, { | ||
232 | /* sentinel */ | ||
233 | } | ||
234 | }; | ||
235 | MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype); | ||
236 | |||
237 | static const struct of_device_id imx_hdmi_dt_ids[] = { | ||
238 | { .compatible = "fsl,imx6dl-hdmi-video", .data = &imx_hdmi_devtype[IMX6DL_HDMI], }, | ||
239 | { .compatible = "fsl,imx6q-hdmi-video", .data = &imx_hdmi_devtype[IMX6Q_HDMI], }, | ||
240 | { /* sentinel */ } | ||
241 | }; | ||
242 | MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids); | ||
243 | |||
244 | static inline int cpu_is_imx6dl(struct mxc_hdmi *hdmi) | ||
245 | { | ||
246 | return hdmi->cpu_type == IMX6DL_HDMI; | ||
247 | } | ||
248 | #ifdef DEBUG | ||
249 | static void dump_fb_videomode(struct fb_videomode *m) | ||
250 | { | ||
251 | pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n", | ||
252 | m->refresh, m->xres, m->yres, m->pixclock, m->left_margin, | ||
253 | m->right_margin, m->upper_margin, m->lower_margin, | ||
254 | m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag); | ||
255 | } | ||
256 | #else | ||
257 | static void dump_fb_videomode(struct fb_videomode *m) | ||
258 | {} | ||
259 | #endif | ||
260 | |||
261 | static int hdcp_init; | ||
262 | static int __init early_init_hdcp(char *p) | ||
263 | { | ||
264 | hdcp_init = 1; | ||
265 | return 0; | ||
266 | } | ||
267 | early_param("hdcp", early_init_hdcp); | ||
268 | |||
269 | static ssize_t mxc_hdmi_show_name(struct device *dev, | ||
270 | struct device_attribute *attr, char *buf) | ||
271 | { | ||
272 | struct mxc_hdmi *hdmi = dev_get_drvdata(dev); | ||
273 | |||
274 | strcpy(buf, hdmi->fbi->fix.id); | ||
275 | sprintf(buf+strlen(buf), "\n"); | ||
276 | |||
277 | return strlen(buf); | ||
278 | } | ||
279 | |||
280 | static DEVICE_ATTR(fb_name, S_IRUGO, mxc_hdmi_show_name, NULL); | ||
281 | |||
282 | static ssize_t mxc_hdmi_show_state(struct device *dev, | ||
283 | struct device_attribute *attr, char *buf) | ||
284 | { | ||
285 | struct mxc_hdmi *hdmi = dev_get_drvdata(dev); | ||
286 | |||
287 | if (hdmi->cable_plugin == false) | ||
288 | strcpy(buf, "plugout\n"); | ||
289 | else | ||
290 | strcpy(buf, "plugin\n"); | ||
291 | |||
292 | return strlen(buf); | ||
293 | } | ||
294 | |||
295 | static DEVICE_ATTR(cable_state, S_IRUGO, mxc_hdmi_show_state, NULL); | ||
296 | |||
297 | static ssize_t mxc_hdmi_show_edid(struct device *dev, | ||
298 | struct device_attribute *attr, char *buf) | ||
299 | { | ||
300 | struct mxc_hdmi *hdmi = dev_get_drvdata(dev); | ||
301 | int i, j, len = 0; | ||
302 | |||
303 | for (j = 0; j < HDMI_EDID_LEN/16; j++) { | ||
304 | for (i = 0; i < 16; i++) | ||
305 | len += sprintf(buf+len, "0x%02X ", | ||
306 | hdmi->edid[j*16 + i]); | ||
307 | len += sprintf(buf+len, "\n"); | ||
308 | } | ||
309 | |||
310 | return len; | ||
311 | } | ||
312 | |||
313 | static DEVICE_ATTR(edid, S_IRUGO, mxc_hdmi_show_edid, NULL); | ||
314 | |||
315 | static ssize_t mxc_hdmi_show_rgb_out_enable(struct device *dev, | ||
316 | struct device_attribute *attr, char *buf) | ||
317 | { | ||
318 | struct mxc_hdmi *hdmi = dev_get_drvdata(dev); | ||
319 | |||
320 | if (hdmi->hdmi_data.rgb_out_enable == true) | ||
321 | strcpy(buf, "RGB out\n"); | ||
322 | else | ||
323 | strcpy(buf, "YCbCr out\n"); | ||
324 | |||
325 | return strlen(buf); | ||
326 | } | ||
327 | |||
328 | static ssize_t mxc_hdmi_store_rgb_out_enable(struct device *dev, | ||
329 | struct device_attribute *attr, const char *buf, size_t count) | ||
330 | { | ||
331 | struct mxc_hdmi *hdmi = dev_get_drvdata(dev); | ||
332 | unsigned long value; | ||
333 | int ret; | ||
334 | |||
335 | ret = strict_strtoul(buf, 10, &value); | ||
336 | if (ret) | ||
337 | return ret; | ||
338 | |||
339 | hdmi->hdmi_data.rgb_out_enable = value; | ||
340 | |||
341 | /* Reconfig HDMI for output color space change */ | ||
342 | mxc_hdmi_setup(hdmi, 0); | ||
343 | |||
344 | return count; | ||
345 | } | ||
346 | |||
347 | static DEVICE_ATTR(rgb_out_enable, S_IRUGO | S_IWUSR, | ||
348 | mxc_hdmi_show_rgb_out_enable, | ||
349 | mxc_hdmi_store_rgb_out_enable); | ||
350 | |||
351 | static ssize_t mxc_hdmi_show_hdcp_enable(struct device *dev, | ||
352 | struct device_attribute *attr, char *buf) | ||
353 | { | ||
354 | struct mxc_hdmi *hdmi = dev_get_drvdata(dev); | ||
355 | |||
356 | if (hdmi->hdmi_data.hdcp_enable == false) | ||
357 | strcpy(buf, "hdcp disable\n"); | ||
358 | else | ||
359 | strcpy(buf, "hdcp enable\n"); | ||
360 | |||
361 | return strlen(buf); | ||
362 | |||
363 | } | ||
364 | |||
365 | static ssize_t mxc_hdmi_store_hdcp_enable(struct device *dev, | ||
366 | struct device_attribute *attr, const char *buf, size_t count) | ||
367 | { | ||
368 | struct mxc_hdmi *hdmi = dev_get_drvdata(dev); | ||
369 | char event_string[32]; | ||
370 | char *envp[] = { event_string, NULL }; | ||
371 | unsigned long value; | ||
372 | int ret; | ||
373 | |||
374 | ret = strict_strtoul(buf, 10, &value); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | |||
378 | hdmi->hdmi_data.hdcp_enable = value; | ||
379 | |||
380 | /* Reconfig HDMI for HDCP */ | ||
381 | mxc_hdmi_setup(hdmi, 0); | ||
382 | |||
383 | if (hdmi->hdmi_data.hdcp_enable == false) { | ||
384 | sprintf(event_string, "EVENT=hdcpdisable"); | ||
385 | kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp); | ||
386 | } else { | ||
387 | sprintf(event_string, "EVENT=hdcpenable"); | ||
388 | kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp); | ||
389 | } | ||
390 | |||
391 | return count; | ||
392 | |||
393 | } | ||
394 | |||
395 | static DEVICE_ATTR(hdcp_enable, S_IRUGO | S_IWUSR, | ||
396 | mxc_hdmi_show_hdcp_enable, mxc_hdmi_store_hdcp_enable); | ||
397 | |||
398 | /*! | ||
399 | * this submodule is responsible for the video data synchronization. | ||
400 | * for example, for RGB 4:4:4 input, the data map is defined as | ||
401 | * pin{47~40} <==> R[7:0] | ||
402 | * pin{31~24} <==> G[7:0] | ||
403 | * pin{15~8} <==> B[7:0] | ||
404 | */ | ||
405 | static void hdmi_video_sample(struct mxc_hdmi *hdmi) | ||
406 | { | ||
407 | int color_format = 0; | ||
408 | u8 val; | ||
409 | |||
410 | if (hdmi->hdmi_data.enc_in_format == RGB) { | ||
411 | if (hdmi->hdmi_data.enc_color_depth == 8) | ||
412 | color_format = 0x01; | ||
413 | else if (hdmi->hdmi_data.enc_color_depth == 10) | ||
414 | color_format = 0x03; | ||
415 | else if (hdmi->hdmi_data.enc_color_depth == 12) | ||
416 | color_format = 0x05; | ||
417 | else if (hdmi->hdmi_data.enc_color_depth == 16) | ||
418 | color_format = 0x07; | ||
419 | else | ||
420 | return; | ||
421 | } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { | ||
422 | if (hdmi->hdmi_data.enc_color_depth == 8) | ||
423 | color_format = 0x09; | ||
424 | else if (hdmi->hdmi_data.enc_color_depth == 10) | ||
425 | color_format = 0x0B; | ||
426 | else if (hdmi->hdmi_data.enc_color_depth == 12) | ||
427 | color_format = 0x0D; | ||
428 | else if (hdmi->hdmi_data.enc_color_depth == 16) | ||
429 | color_format = 0x0F; | ||
430 | else | ||
431 | return; | ||
432 | } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) { | ||
433 | if (hdmi->hdmi_data.enc_color_depth == 8) | ||
434 | color_format = 0x16; | ||
435 | else if (hdmi->hdmi_data.enc_color_depth == 10) | ||
436 | color_format = 0x14; | ||
437 | else if (hdmi->hdmi_data.enc_color_depth == 12) | ||
438 | color_format = 0x12; | ||
439 | else | ||
440 | return; | ||
441 | } | ||
442 | |||
443 | val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE | | ||
444 | ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) & | ||
445 | HDMI_TX_INVID0_VIDEO_MAPPING_MASK); | ||
446 | hdmi_writeb(val, HDMI_TX_INVID0); | ||
447 | |||
448 | /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */ | ||
449 | val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE | | ||
450 | HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE | | ||
451 | HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE; | ||
452 | hdmi_writeb(val, HDMI_TX_INSTUFFING); | ||
453 | hdmi_writeb(0x0, HDMI_TX_GYDATA0); | ||
454 | hdmi_writeb(0x0, HDMI_TX_GYDATA1); | ||
455 | hdmi_writeb(0x0, HDMI_TX_RCRDATA0); | ||
456 | hdmi_writeb(0x0, HDMI_TX_RCRDATA1); | ||
457 | hdmi_writeb(0x0, HDMI_TX_BCBDATA0); | ||
458 | hdmi_writeb(0x0, HDMI_TX_BCBDATA1); | ||
459 | } | ||
460 | |||
461 | static int isColorSpaceConversion(struct mxc_hdmi *hdmi) | ||
462 | { | ||
463 | return (hdmi->hdmi_data.enc_in_format != | ||
464 | hdmi->hdmi_data.enc_out_format); | ||
465 | } | ||
466 | |||
467 | static int isColorSpaceDecimation(struct mxc_hdmi *hdmi) | ||
468 | { | ||
469 | return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) && | ||
470 | (hdmi->hdmi_data.enc_in_format == RGB || | ||
471 | hdmi->hdmi_data.enc_in_format == YCBCR444)); | ||
472 | } | ||
473 | |||
474 | static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi) | ||
475 | { | ||
476 | return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) && | ||
477 | (hdmi->hdmi_data.enc_out_format == RGB | ||
478 | || hdmi->hdmi_data.enc_out_format == YCBCR444)); | ||
479 | } | ||
480 | |||
481 | /*! | ||
482 | * update the color space conversion coefficients. | ||
483 | */ | ||
484 | static void update_csc_coeffs(struct mxc_hdmi *hdmi) | ||
485 | { | ||
486 | unsigned short csc_coeff[3][4]; | ||
487 | unsigned int csc_scale = 1; | ||
488 | u8 val; | ||
489 | bool coeff_selected = false; | ||
490 | |||
491 | if (isColorSpaceConversion(hdmi)) { /* csc needed */ | ||
492 | if (hdmi->hdmi_data.enc_out_format == RGB) { | ||
493 | if (hdmi->hdmi_data.colorimetry == eITU601) { | ||
494 | csc_coeff[0][0] = 0x2000; | ||
495 | csc_coeff[0][1] = 0x6926; | ||
496 | csc_coeff[0][2] = 0x74fd; | ||
497 | csc_coeff[0][3] = 0x010e; | ||
498 | |||
499 | csc_coeff[1][0] = 0x2000; | ||
500 | csc_coeff[1][1] = 0x2cdd; | ||
501 | csc_coeff[1][2] = 0x0000; | ||
502 | csc_coeff[1][3] = 0x7e9a; | ||
503 | |||
504 | csc_coeff[2][0] = 0x2000; | ||
505 | csc_coeff[2][1] = 0x0000; | ||
506 | csc_coeff[2][2] = 0x38b4; | ||
507 | csc_coeff[2][3] = 0x7e3b; | ||
508 | |||
509 | csc_scale = 1; | ||
510 | coeff_selected = true; | ||
511 | } else if (hdmi->hdmi_data.colorimetry == eITU709) { | ||
512 | csc_coeff[0][0] = 0x2000; | ||
513 | csc_coeff[0][1] = 0x7106; | ||
514 | csc_coeff[0][2] = 0x7a02; | ||
515 | csc_coeff[0][3] = 0x00a7; | ||
516 | |||
517 | csc_coeff[1][0] = 0x2000; | ||
518 | csc_coeff[1][1] = 0x3264; | ||
519 | csc_coeff[1][2] = 0x0000; | ||
520 | csc_coeff[1][3] = 0x7e6d; | ||
521 | |||
522 | csc_coeff[2][0] = 0x2000; | ||
523 | csc_coeff[2][1] = 0x0000; | ||
524 | csc_coeff[2][2] = 0x3b61; | ||
525 | csc_coeff[2][3] = 0x7e25; | ||
526 | |||
527 | csc_scale = 1; | ||
528 | coeff_selected = true; | ||
529 | } | ||
530 | } else if (hdmi->hdmi_data.enc_in_format == RGB) { | ||
531 | if (hdmi->hdmi_data.colorimetry == eITU601) { | ||
532 | csc_coeff[0][0] = 0x2591; | ||
533 | csc_coeff[0][1] = 0x1322; | ||
534 | csc_coeff[0][2] = 0x074b; | ||
535 | csc_coeff[0][3] = 0x0000; | ||
536 | |||
537 | csc_coeff[1][0] = 0x6535; | ||
538 | csc_coeff[1][1] = 0x2000; | ||
539 | csc_coeff[1][2] = 0x7acc; | ||
540 | csc_coeff[1][3] = 0x0200; | ||
541 | |||
542 | csc_coeff[2][0] = 0x6acd; | ||
543 | csc_coeff[2][1] = 0x7534; | ||
544 | csc_coeff[2][2] = 0x2000; | ||
545 | csc_coeff[2][3] = 0x0200; | ||
546 | |||
547 | csc_scale = 0; | ||
548 | coeff_selected = true; | ||
549 | } else if (hdmi->hdmi_data.colorimetry == eITU709) { | ||
550 | csc_coeff[0][0] = 0x2dc5; | ||
551 | csc_coeff[0][1] = 0x0d9b; | ||
552 | csc_coeff[0][2] = 0x049e; | ||
553 | csc_coeff[0][3] = 0x0000; | ||
554 | |||
555 | csc_coeff[1][0] = 0x62f0; | ||
556 | csc_coeff[1][1] = 0x2000; | ||
557 | csc_coeff[1][2] = 0x7d11; | ||
558 | csc_coeff[1][3] = 0x0200; | ||
559 | |||
560 | csc_coeff[2][0] = 0x6756; | ||
561 | csc_coeff[2][1] = 0x78ab; | ||
562 | csc_coeff[2][2] = 0x2000; | ||
563 | csc_coeff[2][3] = 0x0200; | ||
564 | |||
565 | csc_scale = 0; | ||
566 | coeff_selected = true; | ||
567 | } | ||
568 | } | ||
569 | } | ||
570 | |||
571 | if (!coeff_selected) { | ||
572 | csc_coeff[0][0] = 0x2000; | ||
573 | csc_coeff[0][1] = 0x0000; | ||
574 | csc_coeff[0][2] = 0x0000; | ||
575 | csc_coeff[0][3] = 0x0000; | ||
576 | |||
577 | csc_coeff[1][0] = 0x0000; | ||
578 | csc_coeff[1][1] = 0x2000; | ||
579 | csc_coeff[1][2] = 0x0000; | ||
580 | csc_coeff[1][3] = 0x0000; | ||
581 | |||
582 | csc_coeff[2][0] = 0x0000; | ||
583 | csc_coeff[2][1] = 0x0000; | ||
584 | csc_coeff[2][2] = 0x2000; | ||
585 | csc_coeff[2][3] = 0x0000; | ||
586 | |||
587 | csc_scale = 1; | ||
588 | } | ||
589 | |||
590 | /* Update CSC parameters in HDMI CSC registers */ | ||
591 | hdmi_writeb((unsigned char)(csc_coeff[0][0] & 0xFF), | ||
592 | HDMI_CSC_COEF_A1_LSB); | ||
593 | hdmi_writeb((unsigned char)(csc_coeff[0][0] >> 8), | ||
594 | HDMI_CSC_COEF_A1_MSB); | ||
595 | hdmi_writeb((unsigned char)(csc_coeff[0][1] & 0xFF), | ||
596 | HDMI_CSC_COEF_A2_LSB); | ||
597 | hdmi_writeb((unsigned char)(csc_coeff[0][1] >> 8), | ||
598 | HDMI_CSC_COEF_A2_MSB); | ||
599 | hdmi_writeb((unsigned char)(csc_coeff[0][2] & 0xFF), | ||
600 | HDMI_CSC_COEF_A3_LSB); | ||
601 | hdmi_writeb((unsigned char)(csc_coeff[0][2] >> 8), | ||
602 | HDMI_CSC_COEF_A3_MSB); | ||
603 | hdmi_writeb((unsigned char)(csc_coeff[0][3] & 0xFF), | ||
604 | HDMI_CSC_COEF_A4_LSB); | ||
605 | hdmi_writeb((unsigned char)(csc_coeff[0][3] >> 8), | ||
606 | HDMI_CSC_COEF_A4_MSB); | ||
607 | |||
608 | hdmi_writeb((unsigned char)(csc_coeff[1][0] & 0xFF), | ||
609 | HDMI_CSC_COEF_B1_LSB); | ||
610 | hdmi_writeb((unsigned char)(csc_coeff[1][0] >> 8), | ||
611 | HDMI_CSC_COEF_B1_MSB); | ||
612 | hdmi_writeb((unsigned char)(csc_coeff[1][1] & 0xFF), | ||
613 | HDMI_CSC_COEF_B2_LSB); | ||
614 | hdmi_writeb((unsigned char)(csc_coeff[1][1] >> 8), | ||
615 | HDMI_CSC_COEF_B2_MSB); | ||
616 | hdmi_writeb((unsigned char)(csc_coeff[1][2] & 0xFF), | ||
617 | HDMI_CSC_COEF_B3_LSB); | ||
618 | hdmi_writeb((unsigned char)(csc_coeff[1][2] >> 8), | ||
619 | HDMI_CSC_COEF_B3_MSB); | ||
620 | hdmi_writeb((unsigned char)(csc_coeff[1][3] & 0xFF), | ||
621 | HDMI_CSC_COEF_B4_LSB); | ||
622 | hdmi_writeb((unsigned char)(csc_coeff[1][3] >> 8), | ||
623 | HDMI_CSC_COEF_B4_MSB); | ||
624 | |||
625 | hdmi_writeb((unsigned char)(csc_coeff[2][0] & 0xFF), | ||
626 | HDMI_CSC_COEF_C1_LSB); | ||
627 | hdmi_writeb((unsigned char)(csc_coeff[2][0] >> 8), | ||
628 | HDMI_CSC_COEF_C1_MSB); | ||
629 | hdmi_writeb((unsigned char)(csc_coeff[2][1] & 0xFF), | ||
630 | HDMI_CSC_COEF_C2_LSB); | ||
631 | hdmi_writeb((unsigned char)(csc_coeff[2][1] >> 8), | ||
632 | HDMI_CSC_COEF_C2_MSB); | ||
633 | hdmi_writeb((unsigned char)(csc_coeff[2][2] & 0xFF), | ||
634 | HDMI_CSC_COEF_C3_LSB); | ||
635 | hdmi_writeb((unsigned char)(csc_coeff[2][2] >> 8), | ||
636 | HDMI_CSC_COEF_C3_MSB); | ||
637 | hdmi_writeb((unsigned char)(csc_coeff[2][3] & 0xFF), | ||
638 | HDMI_CSC_COEF_C4_LSB); | ||
639 | hdmi_writeb((unsigned char)(csc_coeff[2][3] >> 8), | ||
640 | HDMI_CSC_COEF_C4_MSB); | ||
641 | |||
642 | val = hdmi_readb(HDMI_CSC_SCALE); | ||
643 | val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK; | ||
644 | val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK; | ||
645 | hdmi_writeb(val, HDMI_CSC_SCALE); | ||
646 | } | ||
647 | |||
648 | static void hdmi_video_csc(struct mxc_hdmi *hdmi) | ||
649 | { | ||
650 | int color_depth = 0; | ||
651 | int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE; | ||
652 | int decimation = 0; | ||
653 | u8 val; | ||
654 | |||
655 | /* YCC422 interpolation to 444 mode */ | ||
656 | if (isColorSpaceInterpolation(hdmi)) | ||
657 | interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1; | ||
658 | else if (isColorSpaceDecimation(hdmi)) | ||
659 | decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; | ||
660 | |||
661 | if (hdmi->hdmi_data.enc_color_depth == 8) | ||
662 | color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; | ||
663 | else if (hdmi->hdmi_data.enc_color_depth == 10) | ||
664 | color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP; | ||
665 | else if (hdmi->hdmi_data.enc_color_depth == 12) | ||
666 | color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP; | ||
667 | else if (hdmi->hdmi_data.enc_color_depth == 16) | ||
668 | color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP; | ||
669 | else | ||
670 | return; | ||
671 | |||
672 | /*configure the CSC registers */ | ||
673 | hdmi_writeb(interpolation | decimation, HDMI_CSC_CFG); | ||
674 | val = hdmi_readb(HDMI_CSC_SCALE); | ||
675 | val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK; | ||
676 | val |= color_depth; | ||
677 | hdmi_writeb(val, HDMI_CSC_SCALE); | ||
678 | |||
679 | update_csc_coeffs(hdmi); | ||
680 | } | ||
681 | |||
682 | /*! | ||
683 | * HDMI video packetizer is used to packetize the data. | ||
684 | * for example, if input is YCC422 mode or repeater is used, | ||
685 | * data should be repacked this module can be bypassed. | ||
686 | */ | ||
687 | static void hdmi_video_packetize(struct mxc_hdmi *hdmi) | ||
688 | { | ||
689 | unsigned int color_depth = 0; | ||
690 | unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit; | ||
691 | unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP; | ||
692 | struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; | ||
693 | u8 val; | ||
694 | |||
695 | if (hdmi_data->enc_out_format == RGB | ||
696 | || hdmi_data->enc_out_format == YCBCR444) { | ||
697 | if (hdmi_data->enc_color_depth == 0) | ||
698 | output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; | ||
699 | else if (hdmi_data->enc_color_depth == 8) { | ||
700 | color_depth = 4; | ||
701 | output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; | ||
702 | } else if (hdmi_data->enc_color_depth == 10) | ||
703 | color_depth = 5; | ||
704 | else if (hdmi_data->enc_color_depth == 12) | ||
705 | color_depth = 6; | ||
706 | else if (hdmi_data->enc_color_depth == 16) | ||
707 | color_depth = 7; | ||
708 | else | ||
709 | return; | ||
710 | } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { | ||
711 | if (hdmi_data->enc_color_depth == 0 || | ||
712 | hdmi_data->enc_color_depth == 8) | ||
713 | remap_size = HDMI_VP_REMAP_YCC422_16bit; | ||
714 | else if (hdmi_data->enc_color_depth == 10) | ||
715 | remap_size = HDMI_VP_REMAP_YCC422_20bit; | ||
716 | else if (hdmi_data->enc_color_depth == 12) | ||
717 | remap_size = HDMI_VP_REMAP_YCC422_24bit; | ||
718 | else | ||
719 | return; | ||
720 | output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; | ||
721 | } else | ||
722 | return; | ||
723 | |||
724 | /* HDMI not support deep color, | ||
725 | * because IPU MAX support color depth is 24bit */ | ||
726 | color_depth = 0; | ||
727 | |||
728 | /* set the packetizer registers */ | ||
729 | val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & | ||
730 | HDMI_VP_PR_CD_COLOR_DEPTH_MASK) | | ||
731 | ((hdmi_data->pix_repet_factor << | ||
732 | HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) & | ||
733 | HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK); | ||
734 | hdmi_writeb(val, HDMI_VP_PR_CD); | ||
735 | |||
736 | val = hdmi_readb(HDMI_VP_STUFF); | ||
737 | val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK; | ||
738 | val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE; | ||
739 | hdmi_writeb(val, HDMI_VP_STUFF); | ||
740 | |||
741 | /* Data from pixel repeater block */ | ||
742 | if (hdmi_data->pix_repet_factor > 1) { | ||
743 | val = hdmi_readb(HDMI_VP_CONF); | ||
744 | val &= ~(HDMI_VP_CONF_PR_EN_MASK | | ||
745 | HDMI_VP_CONF_BYPASS_SELECT_MASK); | ||
746 | val |= HDMI_VP_CONF_PR_EN_ENABLE | | ||
747 | HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; | ||
748 | hdmi_writeb(val, HDMI_VP_CONF); | ||
749 | } else { /* data from packetizer block */ | ||
750 | val = hdmi_readb(HDMI_VP_CONF); | ||
751 | val &= ~(HDMI_VP_CONF_PR_EN_MASK | | ||
752 | HDMI_VP_CONF_BYPASS_SELECT_MASK); | ||
753 | val |= HDMI_VP_CONF_PR_EN_DISABLE | | ||
754 | HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER; | ||
755 | hdmi_writeb(val, HDMI_VP_CONF); | ||
756 | } | ||
757 | |||
758 | val = hdmi_readb(HDMI_VP_STUFF); | ||
759 | val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK; | ||
760 | val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET; | ||
761 | hdmi_writeb(val, HDMI_VP_STUFF); | ||
762 | |||
763 | hdmi_writeb(remap_size, HDMI_VP_REMAP); | ||
764 | |||
765 | if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) { | ||
766 | val = hdmi_readb(HDMI_VP_CONF); | ||
767 | val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | | ||
768 | HDMI_VP_CONF_PP_EN_ENMASK | | ||
769 | HDMI_VP_CONF_YCC422_EN_MASK); | ||
770 | val |= HDMI_VP_CONF_BYPASS_EN_DISABLE | | ||
771 | HDMI_VP_CONF_PP_EN_ENABLE | | ||
772 | HDMI_VP_CONF_YCC422_EN_DISABLE; | ||
773 | hdmi_writeb(val, HDMI_VP_CONF); | ||
774 | } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) { | ||
775 | val = hdmi_readb(HDMI_VP_CONF); | ||
776 | val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | | ||
777 | HDMI_VP_CONF_PP_EN_ENMASK | | ||
778 | HDMI_VP_CONF_YCC422_EN_MASK); | ||
779 | val |= HDMI_VP_CONF_BYPASS_EN_DISABLE | | ||
780 | HDMI_VP_CONF_PP_EN_DISABLE | | ||
781 | HDMI_VP_CONF_YCC422_EN_ENABLE; | ||
782 | hdmi_writeb(val, HDMI_VP_CONF); | ||
783 | } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) { | ||
784 | val = hdmi_readb(HDMI_VP_CONF); | ||
785 | val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | | ||
786 | HDMI_VP_CONF_PP_EN_ENMASK | | ||
787 | HDMI_VP_CONF_YCC422_EN_MASK); | ||
788 | val |= HDMI_VP_CONF_BYPASS_EN_ENABLE | | ||
789 | HDMI_VP_CONF_PP_EN_DISABLE | | ||
790 | HDMI_VP_CONF_YCC422_EN_DISABLE; | ||
791 | hdmi_writeb(val, HDMI_VP_CONF); | ||
792 | } else { | ||
793 | return; | ||
794 | } | ||
795 | |||
796 | val = hdmi_readb(HDMI_VP_STUFF); | ||
797 | val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK | | ||
798 | HDMI_VP_STUFF_YCC422_STUFFING_MASK); | ||
799 | val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | | ||
800 | HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE; | ||
801 | hdmi_writeb(val, HDMI_VP_STUFF); | ||
802 | |||
803 | val = hdmi_readb(HDMI_VP_CONF); | ||
804 | val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK; | ||
805 | val |= output_select; | ||
806 | hdmi_writeb(val, HDMI_VP_CONF); | ||
807 | } | ||
808 | |||
809 | #if 0 | ||
810 | /* Force a fixed color screen */ | ||
811 | static void hdmi_video_force_output(struct mxc_hdmi *hdmi, unsigned char force) | ||
812 | { | ||
813 | u8 val; | ||
814 | |||
815 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
816 | |||
817 | if (force) { | ||
818 | hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */ | ||
819 | hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */ | ||
820 | hdmi_writeb(0xFF, HDMI_FC_DBGTMDS0); /* B */ | ||
821 | val = hdmi_readb(HDMI_FC_DBGFORCE); | ||
822 | val |= HDMI_FC_DBGFORCE_FORCEVIDEO; | ||
823 | hdmi_writeb(val, HDMI_FC_DBGFORCE); | ||
824 | } else { | ||
825 | val = hdmi_readb(HDMI_FC_DBGFORCE); | ||
826 | val &= ~HDMI_FC_DBGFORCE_FORCEVIDEO; | ||
827 | hdmi_writeb(val, HDMI_FC_DBGFORCE); | ||
828 | hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */ | ||
829 | hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */ | ||
830 | hdmi_writeb(0x00, HDMI_FC_DBGTMDS0); /* B */ | ||
831 | } | ||
832 | } | ||
833 | #endif | ||
834 | |||
835 | static inline void hdmi_phy_test_clear(struct mxc_hdmi *hdmi, | ||
836 | unsigned char bit) | ||
837 | { | ||
838 | u8 val = hdmi_readb(HDMI_PHY_TST0); | ||
839 | val &= ~HDMI_PHY_TST0_TSTCLR_MASK; | ||
840 | val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) & | ||
841 | HDMI_PHY_TST0_TSTCLR_MASK; | ||
842 | hdmi_writeb(val, HDMI_PHY_TST0); | ||
843 | } | ||
844 | |||
845 | static inline void hdmi_phy_test_enable(struct mxc_hdmi *hdmi, | ||
846 | unsigned char bit) | ||
847 | { | ||
848 | u8 val = hdmi_readb(HDMI_PHY_TST0); | ||
849 | val &= ~HDMI_PHY_TST0_TSTEN_MASK; | ||
850 | val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) & | ||
851 | HDMI_PHY_TST0_TSTEN_MASK; | ||
852 | hdmi_writeb(val, HDMI_PHY_TST0); | ||
853 | } | ||
854 | |||
855 | static inline void hdmi_phy_test_clock(struct mxc_hdmi *hdmi, | ||
856 | unsigned char bit) | ||
857 | { | ||
858 | u8 val = hdmi_readb(HDMI_PHY_TST0); | ||
859 | val &= ~HDMI_PHY_TST0_TSTCLK_MASK; | ||
860 | val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) & | ||
861 | HDMI_PHY_TST0_TSTCLK_MASK; | ||
862 | hdmi_writeb(val, HDMI_PHY_TST0); | ||
863 | } | ||
864 | |||
865 | static inline void hdmi_phy_test_din(struct mxc_hdmi *hdmi, | ||
866 | unsigned char bit) | ||
867 | { | ||
868 | hdmi_writeb(bit, HDMI_PHY_TST1); | ||
869 | } | ||
870 | |||
871 | static inline void hdmi_phy_test_dout(struct mxc_hdmi *hdmi, | ||
872 | unsigned char bit) | ||
873 | { | ||
874 | hdmi_writeb(bit, HDMI_PHY_TST2); | ||
875 | } | ||
876 | |||
877 | static bool hdmi_phy_wait_i2c_done(struct mxc_hdmi *hdmi, int msec) | ||
878 | { | ||
879 | unsigned char val = 0; | ||
880 | val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3; | ||
881 | while (val == 0) { | ||
882 | udelay(1000); | ||
883 | if (msec-- == 0) | ||
884 | return false; | ||
885 | val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3; | ||
886 | } | ||
887 | return true; | ||
888 | } | ||
889 | |||
890 | static void hdmi_phy_i2c_write(struct mxc_hdmi *hdmi, unsigned short data, | ||
891 | unsigned char addr) | ||
892 | { | ||
893 | hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0); | ||
894 | hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR); | ||
895 | hdmi_writeb((unsigned char)(data >> 8), | ||
896 | HDMI_PHY_I2CM_DATAO_1_ADDR); | ||
897 | hdmi_writeb((unsigned char)(data >> 0), | ||
898 | HDMI_PHY_I2CM_DATAO_0_ADDR); | ||
899 | hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, | ||
900 | HDMI_PHY_I2CM_OPERATION_ADDR); | ||
901 | hdmi_phy_wait_i2c_done(hdmi, 1000); | ||
902 | } | ||
903 | |||
904 | #if 0 | ||
905 | static unsigned short hdmi_phy_i2c_read(struct mxc_hdmi *hdmi, | ||
906 | unsigned char addr) | ||
907 | { | ||
908 | unsigned short data; | ||
909 | unsigned char msb = 0, lsb = 0; | ||
910 | hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0); | ||
911 | hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR); | ||
912 | hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_READ, | ||
913 | HDMI_PHY_I2CM_OPERATION_ADDR); | ||
914 | hdmi_phy_wait_i2c_done(hdmi, 1000); | ||
915 | msb = hdmi_readb(HDMI_PHY_I2CM_DATAI_1_ADDR); | ||
916 | lsb = hdmi_readb(HDMI_PHY_I2CM_DATAI_0_ADDR); | ||
917 | data = (msb << 8) | lsb; | ||
918 | return data; | ||
919 | } | ||
920 | |||
921 | static int hdmi_phy_i2c_write_verify(struct mxc_hdmi *hdmi, unsigned short data, | ||
922 | unsigned char addr) | ||
923 | { | ||
924 | unsigned short val = 0; | ||
925 | hdmi_phy_i2c_write(hdmi, data, addr); | ||
926 | val = hdmi_phy_i2c_read(hdmi, addr); | ||
927 | return (val == data); | ||
928 | } | ||
929 | #endif | ||
930 | |||
931 | static bool hdmi_edid_wait_i2c_done(struct mxc_hdmi *hdmi, int msec) | ||
932 | { | ||
933 | unsigned char val = 0; | ||
934 | val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2; | ||
935 | while (val == 0) { | ||
936 | |||
937 | udelay(1000); | ||
938 | if (msec-- == 0) { | ||
939 | dev_dbg(&hdmi->pdev->dev, | ||
940 | "HDMI EDID i2c operation time out!!\n"); | ||
941 | return false; | ||
942 | } | ||
943 | val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2; | ||
944 | } | ||
945 | return true; | ||
946 | } | ||
947 | |||
948 | static u8 hdmi_edid_i2c_read(struct mxc_hdmi *hdmi, | ||
949 | u8 addr, u8 blockno) | ||
950 | { | ||
951 | u8 spointer = blockno / 2; | ||
952 | u8 edidaddress = ((blockno % 2) * 0x80) + addr; | ||
953 | u8 data; | ||
954 | |||
955 | hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0); | ||
956 | hdmi_writeb(edidaddress, HDMI_I2CM_ADDRESS); | ||
957 | hdmi_writeb(spointer, HDMI_I2CM_SEGADDR); | ||
958 | if (spointer == 0) | ||
959 | hdmi_writeb(HDMI_I2CM_OPERATION_READ, | ||
960 | HDMI_I2CM_OPERATION); | ||
961 | else | ||
962 | hdmi_writeb(HDMI_I2CM_OPERATION_READ_EXT, | ||
963 | HDMI_I2CM_OPERATION); | ||
964 | |||
965 | hdmi_edid_wait_i2c_done(hdmi, 1000); | ||
966 | data = hdmi_readb(HDMI_I2CM_DATAI); | ||
967 | hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0); | ||
968 | return data; | ||
969 | } | ||
970 | |||
971 | |||
972 | /* "Power-down enable (active low)" | ||
973 | * That mean that power up == 1! */ | ||
974 | static void mxc_hdmi_phy_enable_power(u8 enable) | ||
975 | { | ||
976 | hdmi_mask_writeb(enable, HDMI_PHY_CONF0, | ||
977 | HDMI_PHY_CONF0_PDZ_OFFSET, | ||
978 | HDMI_PHY_CONF0_PDZ_MASK); | ||
979 | } | ||
980 | |||
981 | static void mxc_hdmi_phy_enable_tmds(u8 enable) | ||
982 | { | ||
983 | hdmi_mask_writeb(enable, HDMI_PHY_CONF0, | ||
984 | HDMI_PHY_CONF0_ENTMDS_OFFSET, | ||
985 | HDMI_PHY_CONF0_ENTMDS_MASK); | ||
986 | } | ||
987 | |||
988 | static void mxc_hdmi_phy_gen2_pddq(u8 enable) | ||
989 | { | ||
990 | hdmi_mask_writeb(enable, HDMI_PHY_CONF0, | ||
991 | HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, | ||
992 | HDMI_PHY_CONF0_GEN2_PDDQ_MASK); | ||
993 | } | ||
994 | |||
995 | static void mxc_hdmi_phy_gen2_txpwron(u8 enable) | ||
996 | { | ||
997 | hdmi_mask_writeb(enable, HDMI_PHY_CONF0, | ||
998 | HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, | ||
999 | HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); | ||
1000 | } | ||
1001 | |||
1002 | #if 0 | ||
1003 | static void mxc_hdmi_phy_gen2_enhpdrxsense(u8 enable) | ||
1004 | { | ||
1005 | hdmi_mask_writeb(enable, HDMI_PHY_CONF0, | ||
1006 | HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET, | ||
1007 | HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK); | ||
1008 | } | ||
1009 | #endif | ||
1010 | |||
1011 | static void mxc_hdmi_phy_sel_data_en_pol(u8 enable) | ||
1012 | { | ||
1013 | hdmi_mask_writeb(enable, HDMI_PHY_CONF0, | ||
1014 | HDMI_PHY_CONF0_SELDATAENPOL_OFFSET, | ||
1015 | HDMI_PHY_CONF0_SELDATAENPOL_MASK); | ||
1016 | } | ||
1017 | |||
1018 | static void mxc_hdmi_phy_sel_interface_control(u8 enable) | ||
1019 | { | ||
1020 | hdmi_mask_writeb(enable, HDMI_PHY_CONF0, | ||
1021 | HDMI_PHY_CONF0_SELDIPIF_OFFSET, | ||
1022 | HDMI_PHY_CONF0_SELDIPIF_MASK); | ||
1023 | } | ||
1024 | |||
1025 | static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep, | ||
1026 | unsigned char cRes, int cscOn) | ||
1027 | { | ||
1028 | u8 val; | ||
1029 | u8 msec; | ||
1030 | |||
1031 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1032 | |||
1033 | /* color resolution 0 is 8 bit colour depth */ | ||
1034 | if (cRes == 0) | ||
1035 | cRes = 8; | ||
1036 | |||
1037 | if (pRep != 0) | ||
1038 | return false; | ||
1039 | else if (cRes != 8 && cRes != 12) | ||
1040 | return false; | ||
1041 | |||
1042 | /* Enable csc path */ | ||
1043 | if (cscOn) | ||
1044 | val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH; | ||
1045 | else | ||
1046 | val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS; | ||
1047 | |||
1048 | hdmi_writeb(val, HDMI_MC_FLOWCTRL); | ||
1049 | |||
1050 | /* gen2 tx power off */ | ||
1051 | mxc_hdmi_phy_gen2_txpwron(0); | ||
1052 | |||
1053 | /* gen2 pddq */ | ||
1054 | mxc_hdmi_phy_gen2_pddq(1); | ||
1055 | |||
1056 | /* PHY reset */ | ||
1057 | hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ); | ||
1058 | hdmi_writeb(HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ); | ||
1059 | |||
1060 | hdmi_writeb(HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); | ||
1061 | |||
1062 | hdmi_phy_test_clear(hdmi, 1); | ||
1063 | hdmi_writeb(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, | ||
1064 | HDMI_PHY_I2CM_SLAVE_ADDR); | ||
1065 | hdmi_phy_test_clear(hdmi, 0); | ||
1066 | |||
1067 | if (hdmi->hdmi_data.video_mode.mPixelClock < 0) { | ||
1068 | dev_dbg(&hdmi->pdev->dev, "Pixel clock (%d) must be positive\n", | ||
1069 | hdmi->hdmi_data.video_mode.mPixelClock); | ||
1070 | return false; | ||
1071 | } | ||
1072 | |||
1073 | if (hdmi->hdmi_data.video_mode.mPixelClock <= 45250000) { | ||
1074 | switch (cRes) { | ||
1075 | case 8: | ||
1076 | /* PLL/MPLL Cfg */ | ||
1077 | hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06); | ||
1078 | hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */ | ||
1079 | break; | ||
1080 | case 10: | ||
1081 | hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06); | ||
1082 | hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); | ||
1083 | break; | ||
1084 | case 12: | ||
1085 | hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06); | ||
1086 | hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); | ||
1087 | break; | ||
1088 | default: | ||
1089 | return false; | ||
1090 | } | ||
1091 | } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 92500000) { | ||
1092 | switch (cRes) { | ||
1093 | case 8: | ||
1094 | hdmi_phy_i2c_write(hdmi, 0x0140, 0x06); | ||
1095 | hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); | ||
1096 | break; | ||
1097 | case 10: | ||
1098 | hdmi_phy_i2c_write(hdmi, 0x2141, 0x06); | ||
1099 | hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); | ||
1100 | break; | ||
1101 | case 12: | ||
1102 | hdmi_phy_i2c_write(hdmi, 0x4142, 0x06); | ||
1103 | hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); | ||
1104 | default: | ||
1105 | return false; | ||
1106 | } | ||
1107 | } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 148500000) { | ||
1108 | switch (cRes) { | ||
1109 | case 8: | ||
1110 | hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06); | ||
1111 | hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); | ||
1112 | break; | ||
1113 | case 10: | ||
1114 | hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06); | ||
1115 | hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); | ||
1116 | break; | ||
1117 | case 12: | ||
1118 | hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06); | ||
1119 | hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); | ||
1120 | default: | ||
1121 | return false; | ||
1122 | } | ||
1123 | } else { | ||
1124 | switch (cRes) { | ||
1125 | case 8: | ||
1126 | hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06); | ||
1127 | hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); | ||
1128 | break; | ||
1129 | case 10: | ||
1130 | hdmi_phy_i2c_write(hdmi, 0x2001, 0x06); | ||
1131 | hdmi_phy_i2c_write(hdmi, 0x000f, 0x15); | ||
1132 | break; | ||
1133 | case 12: | ||
1134 | hdmi_phy_i2c_write(hdmi, 0x4002, 0x06); | ||
1135 | hdmi_phy_i2c_write(hdmi, 0x000f, 0x15); | ||
1136 | default: | ||
1137 | return false; | ||
1138 | } | ||
1139 | } | ||
1140 | |||
1141 | if (hdmi->hdmi_data.video_mode.mPixelClock <= 54000000) { | ||
1142 | switch (cRes) { | ||
1143 | case 8: | ||
1144 | hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */ | ||
1145 | break; | ||
1146 | case 10: | ||
1147 | hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); | ||
1148 | break; | ||
1149 | case 12: | ||
1150 | hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); | ||
1151 | break; | ||
1152 | default: | ||
1153 | return false; | ||
1154 | } | ||
1155 | } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 58400000) { | ||
1156 | switch (cRes) { | ||
1157 | case 8: | ||
1158 | hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); | ||
1159 | break; | ||
1160 | case 10: | ||
1161 | hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); | ||
1162 | break; | ||
1163 | case 12: | ||
1164 | hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); | ||
1165 | break; | ||
1166 | default: | ||
1167 | return false; | ||
1168 | } | ||
1169 | } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 72000000) { | ||
1170 | switch (cRes) { | ||
1171 | case 8: | ||
1172 | hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); | ||
1173 | break; | ||
1174 | case 10: | ||
1175 | hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); | ||
1176 | break; | ||
1177 | case 12: | ||
1178 | hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); | ||
1179 | break; | ||
1180 | default: | ||
1181 | return false; | ||
1182 | } | ||
1183 | } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 74250000) { | ||
1184 | switch (cRes) { | ||
1185 | case 8: | ||
1186 | hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); | ||
1187 | break; | ||
1188 | case 10: | ||
1189 | hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10); | ||
1190 | break; | ||
1191 | case 12: | ||
1192 | hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); | ||
1193 | break; | ||
1194 | default: | ||
1195 | return false; | ||
1196 | } | ||
1197 | } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 118800000) { | ||
1198 | switch (cRes) { | ||
1199 | case 8: | ||
1200 | hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); | ||
1201 | break; | ||
1202 | case 10: | ||
1203 | hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); | ||
1204 | break; | ||
1205 | case 12: | ||
1206 | hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); | ||
1207 | break; | ||
1208 | default: | ||
1209 | return false; | ||
1210 | } | ||
1211 | } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 216000000) { | ||
1212 | switch (cRes) { | ||
1213 | case 8: | ||
1214 | hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); | ||
1215 | break; | ||
1216 | case 10: | ||
1217 | hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10); | ||
1218 | break; | ||
1219 | case 12: | ||
1220 | hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); | ||
1221 | break; | ||
1222 | default: | ||
1223 | return false; | ||
1224 | } | ||
1225 | } else { | ||
1226 | dev_err(&hdmi->pdev->dev, | ||
1227 | "Pixel clock %d - unsupported by HDMI\n", | ||
1228 | hdmi->hdmi_data.video_mode.mPixelClock); | ||
1229 | return false; | ||
1230 | } | ||
1231 | |||
1232 | hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */ | ||
1233 | hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); | ||
1234 | /* RESISTANCE TERM 133Ohm Cfg */ | ||
1235 | hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */ | ||
1236 | /* PREEMP Cgf 0.00 */ | ||
1237 | hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */ | ||
1238 | /* TX/CK LVL 10 */ | ||
1239 | hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */ | ||
1240 | |||
1241 | /* Board specific setting for PHY register 0x09, 0x0e to pass HCT */ | ||
1242 | if (hdmi->phy_config.reg_cksymtx != 0) | ||
1243 | hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_cksymtx, 0x09); | ||
1244 | |||
1245 | if (hdmi->phy_config.reg_vlev != 0) | ||
1246 | hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_vlev, 0x0E); | ||
1247 | |||
1248 | /* REMOVE CLK TERM */ | ||
1249 | hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */ | ||
1250 | |||
1251 | if (hdmi->hdmi_data.video_mode.mPixelClock > 148500000) { | ||
1252 | hdmi_phy_i2c_write(hdmi, 0x800b, 0x09); | ||
1253 | hdmi_phy_i2c_write(hdmi, 0x0129, 0x0E); | ||
1254 | } | ||
1255 | |||
1256 | mxc_hdmi_phy_enable_power(1); | ||
1257 | |||
1258 | /* toggle TMDS enable */ | ||
1259 | mxc_hdmi_phy_enable_tmds(0); | ||
1260 | mxc_hdmi_phy_enable_tmds(1); | ||
1261 | |||
1262 | /* gen2 tx power on */ | ||
1263 | mxc_hdmi_phy_gen2_txpwron(1); | ||
1264 | mxc_hdmi_phy_gen2_pddq(0); | ||
1265 | |||
1266 | /*Wait for PHY PLL lock */ | ||
1267 | msec = 4; | ||
1268 | val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; | ||
1269 | while (val == 0) { | ||
1270 | udelay(1000); | ||
1271 | if (msec-- == 0) { | ||
1272 | dev_dbg(&hdmi->pdev->dev, "PHY PLL not locked\n"); | ||
1273 | return false; | ||
1274 | } | ||
1275 | val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; | ||
1276 | } | ||
1277 | |||
1278 | return true; | ||
1279 | } | ||
1280 | |||
1281 | static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi) | ||
1282 | { | ||
1283 | int i; | ||
1284 | bool cscon = false; | ||
1285 | |||
1286 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1287 | |||
1288 | /* Never do phy init if pixel clock is gated. | ||
1289 | * Otherwise HDMI PHY will get messed up and generate an overflow | ||
1290 | * interrupt that can't be cleared or detected by accessing the | ||
1291 | * status register. */ | ||
1292 | if (!hdmi->fb_reg || !hdmi->cable_plugin | ||
1293 | || (hdmi->blank != FB_BLANK_UNBLANK)) | ||
1294 | return; | ||
1295 | |||
1296 | /*check csc whether needed activated in HDMI mode */ | ||
1297 | cscon = (isColorSpaceConversion(hdmi) && | ||
1298 | !hdmi->hdmi_data.video_mode.mDVI); | ||
1299 | |||
1300 | /* HDMI Phy spec says to do the phy initialization sequence twice */ | ||
1301 | for (i = 0 ; i < 2 ; i++) { | ||
1302 | mxc_hdmi_phy_sel_data_en_pol(1); | ||
1303 | mxc_hdmi_phy_sel_interface_control(0); | ||
1304 | mxc_hdmi_phy_enable_tmds(0); | ||
1305 | mxc_hdmi_phy_enable_power(0); | ||
1306 | |||
1307 | /* Enable CSC */ | ||
1308 | hdmi_phy_configure(hdmi, 0, 8, cscon); | ||
1309 | } | ||
1310 | |||
1311 | hdmi->phy_enabled = true; | ||
1312 | } | ||
1313 | |||
1314 | static void hdmi_tx_hdcp_config(struct mxc_hdmi *hdmi) | ||
1315 | { | ||
1316 | #if 0 | ||
1317 | if (hdmi->hdmi_data.hdcp_enable) { | ||
1318 | /* Enable HDMI DDC pin */ | ||
1319 | mxc_hdmi_enable_pins(hdmi); | ||
1320 | } else { | ||
1321 | /* Disable HDMI DDC pin */ | ||
1322 | mxc_hdmi_disable_pins(hdmi); | ||
1323 | } | ||
1324 | #endif | ||
1325 | } | ||
1326 | |||
1327 | static void hdmi_config_AVI(struct mxc_hdmi *hdmi) | ||
1328 | { | ||
1329 | u8 val; | ||
1330 | u8 pix_fmt; | ||
1331 | u8 under_scan; | ||
1332 | u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry; | ||
1333 | struct fb_videomode mode; | ||
1334 | const struct fb_videomode *edid_mode; | ||
1335 | bool aspect_16_9; | ||
1336 | |||
1337 | dev_dbg(&hdmi->pdev->dev, "set up AVI frame\n"); | ||
1338 | |||
1339 | fb_var_to_videomode(&mode, &hdmi->fbi->var); | ||
1340 | /* Use mode from list extracted from EDID to get aspect ratio */ | ||
1341 | if (!list_empty(&hdmi->fbi->modelist)) { | ||
1342 | edid_mode = fb_find_nearest_mode(&mode, &hdmi->fbi->modelist); | ||
1343 | if (edid_mode->vmode & FB_VMODE_ASPECT_16_9) | ||
1344 | aspect_16_9 = true; | ||
1345 | else | ||
1346 | aspect_16_9 = false; | ||
1347 | } else | ||
1348 | aspect_16_9 = false; | ||
1349 | |||
1350 | /******************************************** | ||
1351 | * AVI Data Byte 1 | ||
1352 | ********************************************/ | ||
1353 | if (hdmi->hdmi_data.enc_out_format == YCBCR444) | ||
1354 | pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444; | ||
1355 | else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) | ||
1356 | pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422; | ||
1357 | else | ||
1358 | pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB; | ||
1359 | |||
1360 | if (hdmi->edid_cfg.cea_underscan) | ||
1361 | under_scan = HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN; | ||
1362 | else | ||
1363 | under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA; | ||
1364 | |||
1365 | /* | ||
1366 | * Active format identification data is present in the AVI InfoFrame. | ||
1367 | * Under scan info, no bar data | ||
1368 | */ | ||
1369 | val = pix_fmt | under_scan | | ||
1370 | HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT | | ||
1371 | HDMI_FC_AVICONF0_BAR_DATA_NO_DATA; | ||
1372 | |||
1373 | hdmi_writeb(val, HDMI_FC_AVICONF0); | ||
1374 | |||
1375 | /******************************************** | ||
1376 | * AVI Data Byte 2 | ||
1377 | ********************************************/ | ||
1378 | |||
1379 | /* Set the Aspect Ratio */ | ||
1380 | if (aspect_16_9) { | ||
1381 | act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9; | ||
1382 | coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9; | ||
1383 | } else { | ||
1384 | act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3; | ||
1385 | coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3; | ||
1386 | } | ||
1387 | |||
1388 | /* Set up colorimetry */ | ||
1389 | if (hdmi->hdmi_data.enc_out_format == XVYCC444) { | ||
1390 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO; | ||
1391 | if (hdmi->hdmi_data.colorimetry == eITU601) | ||
1392 | ext_colorimetry = | ||
1393 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; | ||
1394 | else /* hdmi->hdmi_data.colorimetry == eITU709 */ | ||
1395 | ext_colorimetry = | ||
1396 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709; | ||
1397 | } else if (hdmi->hdmi_data.enc_out_format != RGB) { | ||
1398 | if (hdmi->hdmi_data.colorimetry == eITU601) | ||
1399 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE; | ||
1400 | else /* hdmi->hdmi_data.colorimetry == eITU709 */ | ||
1401 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR; | ||
1402 | ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; | ||
1403 | } else { /* Carries no data */ | ||
1404 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA; | ||
1405 | ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; | ||
1406 | } | ||
1407 | |||
1408 | val = colorimetry | coded_ratio | act_ratio; | ||
1409 | hdmi_writeb(val, HDMI_FC_AVICONF1); | ||
1410 | |||
1411 | /******************************************** | ||
1412 | * AVI Data Byte 3 | ||
1413 | ********************************************/ | ||
1414 | |||
1415 | val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry | | ||
1416 | HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT | | ||
1417 | HDMI_FC_AVICONF2_SCALING_NONE; | ||
1418 | hdmi_writeb(val, HDMI_FC_AVICONF2); | ||
1419 | |||
1420 | /******************************************** | ||
1421 | * AVI Data Byte 4 | ||
1422 | ********************************************/ | ||
1423 | hdmi_writeb(hdmi->vic, HDMI_FC_AVIVID); | ||
1424 | |||
1425 | /******************************************** | ||
1426 | * AVI Data Byte 5 | ||
1427 | ********************************************/ | ||
1428 | |||
1429 | /* Set up input and output pixel repetition */ | ||
1430 | val = (((hdmi->hdmi_data.video_mode.mPixelRepetitionInput + 1) << | ||
1431 | HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) & | ||
1432 | HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) | | ||
1433 | ((hdmi->hdmi_data.video_mode.mPixelRepetitionOutput << | ||
1434 | HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) & | ||
1435 | HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK); | ||
1436 | hdmi_writeb(val, HDMI_FC_PRCONF); | ||
1437 | |||
1438 | /* IT Content and quantization range = don't care */ | ||
1439 | val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS | | ||
1440 | HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED; | ||
1441 | hdmi_writeb(val, HDMI_FC_AVICONF3); | ||
1442 | |||
1443 | /******************************************** | ||
1444 | * AVI Data Bytes 6-13 | ||
1445 | ********************************************/ | ||
1446 | hdmi_writeb(0, HDMI_FC_AVIETB0); | ||
1447 | hdmi_writeb(0, HDMI_FC_AVIETB1); | ||
1448 | hdmi_writeb(0, HDMI_FC_AVISBB0); | ||
1449 | hdmi_writeb(0, HDMI_FC_AVISBB1); | ||
1450 | hdmi_writeb(0, HDMI_FC_AVIELB0); | ||
1451 | hdmi_writeb(0, HDMI_FC_AVIELB1); | ||
1452 | hdmi_writeb(0, HDMI_FC_AVISRB0); | ||
1453 | hdmi_writeb(0, HDMI_FC_AVISRB1); | ||
1454 | } | ||
1455 | |||
1456 | /*! | ||
1457 | * this submodule is responsible for the video/audio data composition. | ||
1458 | */ | ||
1459 | static void hdmi_av_composer(struct mxc_hdmi *hdmi) | ||
1460 | { | ||
1461 | u8 inv_val; | ||
1462 | struct fb_info *fbi = hdmi->fbi; | ||
1463 | struct fb_videomode fb_mode; | ||
1464 | struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; | ||
1465 | int hblank, vblank; | ||
1466 | |||
1467 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1468 | |||
1469 | fb_var_to_videomode(&fb_mode, &fbi->var); | ||
1470 | |||
1471 | vmode->mHSyncPolarity = ((fb_mode.sync & FB_SYNC_HOR_HIGH_ACT) != 0); | ||
1472 | vmode->mVSyncPolarity = ((fb_mode.sync & FB_SYNC_VERT_HIGH_ACT) != 0); | ||
1473 | vmode->mInterlaced = ((fb_mode.vmode & FB_VMODE_INTERLACED) != 0); | ||
1474 | vmode->mPixelClock = (fb_mode.xres + fb_mode.left_margin + | ||
1475 | fb_mode.right_margin + fb_mode.hsync_len) * (fb_mode.yres + | ||
1476 | fb_mode.upper_margin + fb_mode.lower_margin + | ||
1477 | fb_mode.vsync_len) * fb_mode.refresh; | ||
1478 | |||
1479 | dev_dbg(&hdmi->pdev->dev, "final pixclk = %d\n", vmode->mPixelClock); | ||
1480 | |||
1481 | /* Set up HDMI_FC_INVIDCONF */ | ||
1482 | inv_val = (hdmi->hdmi_data.hdcp_enable ? | ||
1483 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : | ||
1484 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); | ||
1485 | |||
1486 | inv_val |= (vmode->mVSyncPolarity ? | ||
1487 | HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH : | ||
1488 | HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW); | ||
1489 | |||
1490 | inv_val |= (vmode->mHSyncPolarity ? | ||
1491 | HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH : | ||
1492 | HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW); | ||
1493 | |||
1494 | inv_val |= (vmode->mDataEnablePolarity ? | ||
1495 | HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH : | ||
1496 | HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW); | ||
1497 | |||
1498 | if (hdmi->vic == 39) | ||
1499 | inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH; | ||
1500 | else | ||
1501 | inv_val |= (vmode->mInterlaced ? | ||
1502 | HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH : | ||
1503 | HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW); | ||
1504 | |||
1505 | inv_val |= (vmode->mInterlaced ? | ||
1506 | HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : | ||
1507 | HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE); | ||
1508 | |||
1509 | inv_val |= (vmode->mDVI ? | ||
1510 | HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE : | ||
1511 | HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE); | ||
1512 | |||
1513 | hdmi_writeb(inv_val, HDMI_FC_INVIDCONF); | ||
1514 | |||
1515 | /* Set up horizontal active pixel region width */ | ||
1516 | hdmi_writeb(fb_mode.xres >> 8, HDMI_FC_INHACTV1); | ||
1517 | hdmi_writeb(fb_mode.xres, HDMI_FC_INHACTV0); | ||
1518 | |||
1519 | /* Set up vertical blanking pixel region width */ | ||
1520 | hdmi_writeb(fb_mode.yres >> 8, HDMI_FC_INVACTV1); | ||
1521 | hdmi_writeb(fb_mode.yres, HDMI_FC_INVACTV0); | ||
1522 | |||
1523 | /* Set up horizontal blanking pixel region width */ | ||
1524 | hblank = fb_mode.left_margin + fb_mode.right_margin + | ||
1525 | fb_mode.hsync_len; | ||
1526 | hdmi_writeb(hblank >> 8, HDMI_FC_INHBLANK1); | ||
1527 | hdmi_writeb(hblank, HDMI_FC_INHBLANK0); | ||
1528 | |||
1529 | /* Set up vertical blanking pixel region width */ | ||
1530 | vblank = fb_mode.upper_margin + fb_mode.lower_margin + | ||
1531 | fb_mode.vsync_len; | ||
1532 | hdmi_writeb(vblank, HDMI_FC_INVBLANK); | ||
1533 | |||
1534 | /* Set up HSYNC active edge delay width (in pixel clks) */ | ||
1535 | hdmi_writeb(fb_mode.right_margin >> 8, HDMI_FC_HSYNCINDELAY1); | ||
1536 | hdmi_writeb(fb_mode.right_margin, HDMI_FC_HSYNCINDELAY0); | ||
1537 | |||
1538 | /* Set up VSYNC active edge delay (in pixel clks) */ | ||
1539 | hdmi_writeb(fb_mode.lower_margin, HDMI_FC_VSYNCINDELAY); | ||
1540 | |||
1541 | /* Set up HSYNC active pulse width (in pixel clks) */ | ||
1542 | hdmi_writeb(fb_mode.hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); | ||
1543 | hdmi_writeb(fb_mode.hsync_len, HDMI_FC_HSYNCINWIDTH0); | ||
1544 | |||
1545 | /* Set up VSYNC active edge delay (in pixel clks) */ | ||
1546 | hdmi_writeb(fb_mode.vsync_len, HDMI_FC_VSYNCINWIDTH); | ||
1547 | |||
1548 | dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__); | ||
1549 | } | ||
1550 | |||
1551 | static int mxc_edid_read_internal(struct mxc_hdmi *hdmi, unsigned char *edid, | ||
1552 | struct mxc_edid_cfg *cfg, struct fb_info *fbi) | ||
1553 | { | ||
1554 | int extblknum; | ||
1555 | int i, j, ret; | ||
1556 | unsigned char *ediddata = edid; | ||
1557 | unsigned char tmpedid[EDID_LENGTH]; | ||
1558 | |||
1559 | dev_info(&hdmi->pdev->dev, "%s\n", __func__); | ||
1560 | |||
1561 | if (!edid || !cfg || !fbi) | ||
1562 | return -EINVAL; | ||
1563 | |||
1564 | /* init HDMI I2CM for read edid*/ | ||
1565 | hdmi_writeb(0x0, HDMI_I2CM_DIV); | ||
1566 | hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_HCNT_1_ADDR); | ||
1567 | hdmi_writeb(0x79, HDMI_I2CM_SS_SCL_HCNT_0_ADDR); | ||
1568 | hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_LCNT_1_ADDR); | ||
1569 | hdmi_writeb(0x91, HDMI_I2CM_SS_SCL_LCNT_0_ADDR); | ||
1570 | |||
1571 | hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_HCNT_1_ADDR); | ||
1572 | hdmi_writeb(0x0F, HDMI_I2CM_FS_SCL_HCNT_0_ADDR); | ||
1573 | hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_LCNT_1_ADDR); | ||
1574 | hdmi_writeb(0x21, HDMI_I2CM_FS_SCL_LCNT_0_ADDR); | ||
1575 | |||
1576 | hdmi_writeb(0x50, HDMI_I2CM_SLAVE); | ||
1577 | hdmi_writeb(0x30, HDMI_I2CM_SEGADDR); | ||
1578 | |||
1579 | /* Umask edid interrupt */ | ||
1580 | hdmi_writeb(HDMI_I2CM_INT_DONE_POL, | ||
1581 | HDMI_I2CM_INT); | ||
1582 | |||
1583 | hdmi_writeb(HDMI_I2CM_CTLINT_NAC_POL | | ||
1584 | HDMI_I2CM_CTLINT_ARBITRATION_POL, | ||
1585 | HDMI_I2CM_CTLINT); | ||
1586 | |||
1587 | /* reset edid data zero */ | ||
1588 | memset(edid, 0, EDID_LENGTH*4); | ||
1589 | memset(cfg, 0, sizeof(struct mxc_edid_cfg)); | ||
1590 | |||
1591 | /* Check first three byte of EDID head */ | ||
1592 | if (!(hdmi_edid_i2c_read(hdmi, 0, 0) == 0x00) || | ||
1593 | !(hdmi_edid_i2c_read(hdmi, 1, 0) == 0xFF) || | ||
1594 | !(hdmi_edid_i2c_read(hdmi, 2, 0) == 0xFF)) { | ||
1595 | dev_info(&hdmi->pdev->dev, "EDID head check failed!"); | ||
1596 | return -ENOENT; | ||
1597 | } | ||
1598 | |||
1599 | for (i = 0; i < 128; i++) { | ||
1600 | *ediddata = hdmi_edid_i2c_read(hdmi, i, 0); | ||
1601 | ediddata++; | ||
1602 | } | ||
1603 | |||
1604 | extblknum = edid[0x7E]; | ||
1605 | if (extblknum < 0) | ||
1606 | return extblknum; | ||
1607 | |||
1608 | if (extblknum) { | ||
1609 | ediddata = edid + EDID_LENGTH; | ||
1610 | for (i = 0; i < 128; i++) { | ||
1611 | *ediddata = hdmi_edid_i2c_read(hdmi, i, 1); | ||
1612 | ediddata++; | ||
1613 | } | ||
1614 | } | ||
1615 | |||
1616 | /* edid first block parsing */ | ||
1617 | memset(&fbi->monspecs, 0, sizeof(fbi->monspecs)); | ||
1618 | fb_edid_to_monspecs(edid, &fbi->monspecs); | ||
1619 | |||
1620 | ret = mxc_edid_parse_ext_blk(edid + EDID_LENGTH, | ||
1621 | cfg, &fbi->monspecs); | ||
1622 | if (ret < 0) | ||
1623 | return -ENOENT; | ||
1624 | |||
1625 | /* need read segment block? */ | ||
1626 | if (extblknum > 1) { | ||
1627 | for (j = 1; j <= extblknum; j++) { | ||
1628 | for (i = 0; i < 128; i++) | ||
1629 | *(tmpedid + 1) = hdmi_edid_i2c_read(hdmi, i, j); | ||
1630 | |||
1631 | /* edid ext block parsing */ | ||
1632 | ret = mxc_edid_parse_ext_blk(tmpedid + EDID_LENGTH, | ||
1633 | cfg, &fbi->monspecs); | ||
1634 | if (ret < 0) | ||
1635 | return -ENOENT; | ||
1636 | } | ||
1637 | } | ||
1638 | |||
1639 | return 0; | ||
1640 | } | ||
1641 | |||
1642 | static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi) | ||
1643 | { | ||
1644 | int ret; | ||
1645 | u8 edid_old[HDMI_EDID_LEN]; | ||
1646 | u8 clkdis; | ||
1647 | |||
1648 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1649 | |||
1650 | /* save old edid */ | ||
1651 | memcpy(edid_old, hdmi->edid, HDMI_EDID_LEN); | ||
1652 | |||
1653 | /* Read EDID via HDMI DDC when HDCP Enable */ | ||
1654 | if (!hdcp_init) | ||
1655 | ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr, | ||
1656 | hdmi->edid, &hdmi->edid_cfg, hdmi->fbi); | ||
1657 | else { | ||
1658 | |||
1659 | /* Disable HDCP clk */ | ||
1660 | if (hdmi->hdmi_data.hdcp_enable) { | ||
1661 | clkdis = hdmi_readb(HDMI_MC_CLKDIS); | ||
1662 | clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE; | ||
1663 | hdmi_writeb(clkdis, HDMI_MC_CLKDIS); | ||
1664 | } | ||
1665 | |||
1666 | ret = mxc_edid_read_internal(hdmi, hdmi->edid, | ||
1667 | &hdmi->edid_cfg, hdmi->fbi); | ||
1668 | |||
1669 | /* Enable HDCP clk */ | ||
1670 | if (hdmi->hdmi_data.hdcp_enable) { | ||
1671 | clkdis = hdmi_readb(HDMI_MC_CLKDIS); | ||
1672 | clkdis &= ~HDMI_MC_CLKDIS_HDCPCLK_DISABLE; | ||
1673 | hdmi_writeb(clkdis, HDMI_MC_CLKDIS); | ||
1674 | } | ||
1675 | |||
1676 | } | ||
1677 | if (ret < 0) | ||
1678 | return HDMI_EDID_FAIL; | ||
1679 | |||
1680 | /* Save edid cfg for audio driver */ | ||
1681 | hdmi_set_edid_cfg(&hdmi->edid_cfg); | ||
1682 | |||
1683 | if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN)) { | ||
1684 | dev_info(&hdmi->pdev->dev, "same edid\n"); | ||
1685 | return HDMI_EDID_SAME; | ||
1686 | } | ||
1687 | |||
1688 | if (hdmi->fbi->monspecs.modedb_len == 0) { | ||
1689 | dev_info(&hdmi->pdev->dev, "No modes read from edid\n"); | ||
1690 | return HDMI_EDID_NO_MODES; | ||
1691 | } | ||
1692 | |||
1693 | return HDMI_EDID_SUCCESS; | ||
1694 | } | ||
1695 | |||
1696 | #if 0 | ||
1697 | static void mxc_hdmi_enable_pins(struct mxc_hdmi *hdmi) | ||
1698 | { | ||
1699 | |||
1700 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1701 | |||
1702 | } | ||
1703 | |||
1704 | static void mxc_hdmi_disable_pins(struct mxc_hdmi *hdmi) | ||
1705 | { | ||
1706 | |||
1707 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1708 | |||
1709 | } | ||
1710 | #endif | ||
1711 | |||
1712 | static void mxc_hdmi_phy_disable(struct mxc_hdmi *hdmi) | ||
1713 | { | ||
1714 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1715 | |||
1716 | if (!hdmi->phy_enabled) | ||
1717 | return; | ||
1718 | |||
1719 | /* Setting PHY to reset status */ | ||
1720 | hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ); | ||
1721 | |||
1722 | /* Power down PHY */ | ||
1723 | mxc_hdmi_phy_enable_tmds(0); | ||
1724 | mxc_hdmi_phy_enable_power(0); | ||
1725 | mxc_hdmi_phy_gen2_txpwron(0); | ||
1726 | mxc_hdmi_phy_gen2_pddq(1); | ||
1727 | |||
1728 | hdmi->phy_enabled = false; | ||
1729 | dev_dbg(&hdmi->pdev->dev, "%s - exit\n", __func__); | ||
1730 | } | ||
1731 | |||
1732 | /* HDMI Initialization Step B.4 */ | ||
1733 | static void mxc_hdmi_enable_video_path(struct mxc_hdmi *hdmi) | ||
1734 | { | ||
1735 | u8 clkdis; | ||
1736 | |||
1737 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1738 | |||
1739 | /* control period minimum duration */ | ||
1740 | hdmi_writeb(12, HDMI_FC_CTRLDUR); | ||
1741 | hdmi_writeb(32, HDMI_FC_EXCTRLDUR); | ||
1742 | hdmi_writeb(1, HDMI_FC_EXCTRLSPAC); | ||
1743 | |||
1744 | /* Set to fill TMDS data channels */ | ||
1745 | hdmi_writeb(0x0B, HDMI_FC_CH0PREAM); | ||
1746 | hdmi_writeb(0x16, HDMI_FC_CH1PREAM); | ||
1747 | hdmi_writeb(0x21, HDMI_FC_CH2PREAM); | ||
1748 | |||
1749 | /* Enable pixel clock and tmds data path */ | ||
1750 | clkdis = 0x7F; | ||
1751 | clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; | ||
1752 | hdmi_writeb(clkdis, HDMI_MC_CLKDIS); | ||
1753 | |||
1754 | clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; | ||
1755 | hdmi_writeb(clkdis, HDMI_MC_CLKDIS); | ||
1756 | |||
1757 | /* Enable csc path */ | ||
1758 | if (isColorSpaceConversion(hdmi)) { | ||
1759 | clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; | ||
1760 | hdmi_writeb(clkdis, HDMI_MC_CLKDIS); | ||
1761 | } | ||
1762 | } | ||
1763 | |||
1764 | static void hdmi_enable_audio_clk(struct mxc_hdmi *hdmi) | ||
1765 | { | ||
1766 | u8 clkdis; | ||
1767 | |||
1768 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1769 | |||
1770 | clkdis = hdmi_readb(HDMI_MC_CLKDIS); | ||
1771 | clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; | ||
1772 | hdmi_writeb(clkdis, HDMI_MC_CLKDIS); | ||
1773 | } | ||
1774 | |||
1775 | /* Workaround to clear the overflow condition */ | ||
1776 | static void mxc_hdmi_clear_overflow(struct mxc_hdmi *hdmi) | ||
1777 | { | ||
1778 | int count; | ||
1779 | u8 val; | ||
1780 | |||
1781 | /* TMDS software reset */ | ||
1782 | hdmi_writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); | ||
1783 | |||
1784 | val = hdmi_readb(HDMI_FC_INVIDCONF); | ||
1785 | |||
1786 | if (cpu_is_imx6dl(hdmi)) { | ||
1787 | hdmi_writeb(val, HDMI_FC_INVIDCONF); | ||
1788 | return; | ||
1789 | } | ||
1790 | |||
1791 | for (count = 0 ; count < 5 ; count++) | ||
1792 | hdmi_writeb(val, HDMI_FC_INVIDCONF); | ||
1793 | } | ||
1794 | |||
1795 | static void hdmi_enable_overflow_interrupts(void) | ||
1796 | { | ||
1797 | pr_debug("%s\n", __func__); | ||
1798 | hdmi_writeb(0, HDMI_FC_MASK2); | ||
1799 | hdmi_writeb(0, HDMI_IH_MUTE_FC_STAT2); | ||
1800 | } | ||
1801 | |||
1802 | static void hdmi_disable_overflow_interrupts(void) | ||
1803 | { | ||
1804 | pr_debug("%s\n", __func__); | ||
1805 | hdmi_writeb(HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, | ||
1806 | HDMI_IH_MUTE_FC_STAT2); | ||
1807 | hdmi_writeb(0xff, HDMI_FC_MASK2); | ||
1808 | } | ||
1809 | |||
1810 | static void mxc_hdmi_notify_fb(struct mxc_hdmi *hdmi) | ||
1811 | { | ||
1812 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1813 | |||
1814 | /* Don't notify if we aren't registered yet */ | ||
1815 | WARN_ON(!hdmi->fb_reg); | ||
1816 | |||
1817 | /* disable the phy before ipu changes mode */ | ||
1818 | mxc_hdmi_phy_disable(hdmi); | ||
1819 | |||
1820 | /* | ||
1821 | * Note that fb_set_var will block. During this time, | ||
1822 | * FB_EVENT_MODE_CHANGE callback will happen. | ||
1823 | * So by the end of this function, mxc_hdmi_setup() | ||
1824 | * will be done. | ||
1825 | */ | ||
1826 | hdmi->fbi->var.activate |= FB_ACTIVATE_FORCE; | ||
1827 | console_lock(); | ||
1828 | hdmi->fbi->flags |= FBINFO_MISC_USEREVENT; | ||
1829 | fb_set_var(hdmi->fbi, &hdmi->fbi->var); | ||
1830 | hdmi->fbi->flags &= ~FBINFO_MISC_USEREVENT; | ||
1831 | console_unlock(); | ||
1832 | |||
1833 | dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__); | ||
1834 | } | ||
1835 | |||
1836 | static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi) | ||
1837 | { | ||
1838 | int i; | ||
1839 | struct fb_videomode *mode; | ||
1840 | |||
1841 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1842 | |||
1843 | console_lock(); | ||
1844 | |||
1845 | fb_destroy_modelist(&hdmi->fbi->modelist); | ||
1846 | fb_add_videomode(&vga_mode, &hdmi->fbi->modelist); | ||
1847 | |||
1848 | for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) { | ||
1849 | /* | ||
1850 | * We might check here if mode is supported by HDMI. | ||
1851 | * We do not currently support interlaced modes. | ||
1852 | * And add CEA modes in the modelist. | ||
1853 | */ | ||
1854 | mode = &hdmi->fbi->monspecs.modedb[i]; | ||
1855 | |||
1856 | if (!(mode->vmode & FB_VMODE_INTERLACED) && | ||
1857 | (mxc_edid_mode_to_vic(mode) != 0)) { | ||
1858 | |||
1859 | dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i); | ||
1860 | dev_dbg(&hdmi->pdev->dev, | ||
1861 | "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n", | ||
1862 | hdmi->fbi->monspecs.modedb[i].xres, | ||
1863 | hdmi->fbi->monspecs.modedb[i].yres, | ||
1864 | hdmi->fbi->monspecs.modedb[i].refresh, | ||
1865 | hdmi->fbi->monspecs.modedb[i].vmode, | ||
1866 | hdmi->fbi->monspecs.modedb[i].flag); | ||
1867 | |||
1868 | fb_add_videomode(mode, &hdmi->fbi->modelist); | ||
1869 | } | ||
1870 | } | ||
1871 | |||
1872 | console_unlock(); | ||
1873 | } | ||
1874 | |||
1875 | static void mxc_hdmi_default_edid_cfg(struct mxc_hdmi *hdmi) | ||
1876 | { | ||
1877 | /* Default setting HDMI working in HDMI mode */ | ||
1878 | hdmi->edid_cfg.hdmi_cap = true; | ||
1879 | } | ||
1880 | |||
1881 | static void mxc_hdmi_default_modelist(struct mxc_hdmi *hdmi) | ||
1882 | { | ||
1883 | u32 i; | ||
1884 | const struct fb_videomode *mode; | ||
1885 | |||
1886 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1887 | |||
1888 | /* If not EDID data read, set up default modelist */ | ||
1889 | dev_info(&hdmi->pdev->dev, "No modes read from edid\n"); | ||
1890 | dev_info(&hdmi->pdev->dev, "create default modelist\n"); | ||
1891 | |||
1892 | console_lock(); | ||
1893 | |||
1894 | fb_destroy_modelist(&hdmi->fbi->modelist); | ||
1895 | |||
1896 | /*Add XGA and SXGA to default modelist */ | ||
1897 | fb_add_videomode(&vga_mode, &hdmi->fbi->modelist); | ||
1898 | fb_add_videomode(&xga_mode, &hdmi->fbi->modelist); | ||
1899 | fb_add_videomode(&sxga_mode, &hdmi->fbi->modelist); | ||
1900 | |||
1901 | /*Add all no interlaced CEA mode to default modelist */ | ||
1902 | for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) { | ||
1903 | mode = &mxc_cea_mode[i]; | ||
1904 | if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0)) | ||
1905 | fb_add_videomode(mode, &hdmi->fbi->modelist); | ||
1906 | } | ||
1907 | |||
1908 | console_unlock(); | ||
1909 | } | ||
1910 | |||
1911 | static void mxc_hdmi_set_mode_to_vga_dvi(struct mxc_hdmi *hdmi) | ||
1912 | { | ||
1913 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1914 | |||
1915 | hdmi_disable_overflow_interrupts(); | ||
1916 | |||
1917 | fb_videomode_to_var(&hdmi->fbi->var, &vga_mode); | ||
1918 | |||
1919 | hdmi->requesting_vga_for_initialization = true; | ||
1920 | mxc_hdmi_notify_fb(hdmi); | ||
1921 | hdmi->requesting_vga_for_initialization = false; | ||
1922 | } | ||
1923 | |||
1924 | static void mxc_hdmi_set_mode(struct mxc_hdmi *hdmi) | ||
1925 | { | ||
1926 | const struct fb_videomode *mode; | ||
1927 | struct fb_videomode m; | ||
1928 | struct fb_var_screeninfo var; | ||
1929 | |||
1930 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1931 | |||
1932 | /* Set the default mode only once. */ | ||
1933 | if (!hdmi->dft_mode_set) { | ||
1934 | dev_dbg(&hdmi->pdev->dev, "%s: setting to default=%s bpp=%d\n", | ||
1935 | __func__, hdmi->dft_mode_str, hdmi->default_bpp); | ||
1936 | |||
1937 | fb_find_mode(&var, hdmi->fbi, | ||
1938 | hdmi->dft_mode_str, NULL, 0, NULL, | ||
1939 | hdmi->default_bpp); | ||
1940 | |||
1941 | hdmi->dft_mode_set = true; | ||
1942 | } else | ||
1943 | fb_videomode_to_var(&var, &hdmi->previous_non_vga_mode); | ||
1944 | |||
1945 | fb_var_to_videomode(&m, &var); | ||
1946 | dump_fb_videomode(&m); | ||
1947 | |||
1948 | mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist); | ||
1949 | if (!mode) { | ||
1950 | pr_err("%s: could not find mode in modelist\n", __func__); | ||
1951 | return; | ||
1952 | } | ||
1953 | |||
1954 | /* If video mode same as previous, init HDMI again */ | ||
1955 | if (fb_mode_is_equal(&hdmi->previous_non_vga_mode, mode)) { | ||
1956 | dev_dbg(&hdmi->pdev->dev, | ||
1957 | "%s: Video mode same as previous\n", __func__); | ||
1958 | /* update fbi mode in case modelist is updated */ | ||
1959 | hdmi->fbi->mode = (struct fb_videomode *)mode; | ||
1960 | /* update hdmi setting in case EDID data updated */ | ||
1961 | mxc_hdmi_setup(hdmi, 0); | ||
1962 | } else { | ||
1963 | dev_dbg(&hdmi->pdev->dev, "%s: New video mode\n", __func__); | ||
1964 | mxc_hdmi_set_mode_to_vga_dvi(hdmi); | ||
1965 | fb_videomode_to_var(&hdmi->fbi->var, mode); | ||
1966 | dump_fb_videomode((struct fb_videomode *)mode); | ||
1967 | mxc_hdmi_notify_fb(hdmi); | ||
1968 | } | ||
1969 | |||
1970 | } | ||
1971 | |||
1972 | static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi) | ||
1973 | { | ||
1974 | int edid_status; | ||
1975 | |||
1976 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
1977 | |||
1978 | hdmi->cable_plugin = true; | ||
1979 | |||
1980 | /* HDMI Initialization Step C */ | ||
1981 | edid_status = mxc_hdmi_read_edid(hdmi); | ||
1982 | |||
1983 | /* Read EDID again if first EDID read failed */ | ||
1984 | if (edid_status == HDMI_EDID_NO_MODES || | ||
1985 | edid_status == HDMI_EDID_FAIL) { | ||
1986 | dev_info(&hdmi->pdev->dev, "Read EDID again\n"); | ||
1987 | edid_status = mxc_hdmi_read_edid(hdmi); | ||
1988 | } | ||
1989 | |||
1990 | /* HDMI Initialization Steps D, E, F */ | ||
1991 | switch (edid_status) { | ||
1992 | case HDMI_EDID_SUCCESS: | ||
1993 | mxc_hdmi_edid_rebuild_modelist(hdmi); | ||
1994 | break; | ||
1995 | |||
1996 | /* Nothing to do if EDID same */ | ||
1997 | case HDMI_EDID_SAME: | ||
1998 | break; | ||
1999 | |||
2000 | case HDMI_EDID_FAIL: | ||
2001 | mxc_hdmi_default_edid_cfg(hdmi); | ||
2002 | /* No break here */ | ||
2003 | case HDMI_EDID_NO_MODES: | ||
2004 | default: | ||
2005 | mxc_hdmi_default_modelist(hdmi); | ||
2006 | break; | ||
2007 | } | ||
2008 | |||
2009 | /* Setting video mode */ | ||
2010 | mxc_hdmi_set_mode(hdmi); | ||
2011 | |||
2012 | dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__); | ||
2013 | } | ||
2014 | |||
2015 | static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp) | ||
2016 | { | ||
2017 | struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp); | ||
2018 | mxc_hdmi_phy_init(hdmi); | ||
2019 | return 0; | ||
2020 | } | ||
2021 | |||
2022 | static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp) | ||
2023 | { | ||
2024 | struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp); | ||
2025 | mxc_hdmi_phy_disable(hdmi); | ||
2026 | } | ||
2027 | |||
2028 | static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi) | ||
2029 | { | ||
2030 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
2031 | |||
2032 | /* Disable All HDMI clock */ | ||
2033 | hdmi_writeb(0xff, HDMI_MC_CLKDIS); | ||
2034 | |||
2035 | mxc_hdmi_phy_disable(hdmi); | ||
2036 | |||
2037 | hdmi_disable_overflow_interrupts(); | ||
2038 | |||
2039 | hdmi->cable_plugin = false; | ||
2040 | } | ||
2041 | |||
2042 | static void hotplug_worker(struct work_struct *work) | ||
2043 | { | ||
2044 | struct delayed_work *delay_work = to_delayed_work(work); | ||
2045 | struct mxc_hdmi *hdmi = | ||
2046 | container_of(delay_work, struct mxc_hdmi, hotplug_work); | ||
2047 | u32 phy_int_stat, phy_int_pol, phy_int_mask; | ||
2048 | u8 val; | ||
2049 | unsigned long flags; | ||
2050 | char event_string[32]; | ||
2051 | char *envp[] = { event_string, NULL }; | ||
2052 | |||
2053 | phy_int_stat = hdmi->latest_intr_stat; | ||
2054 | phy_int_pol = hdmi_readb(HDMI_PHY_POL0); | ||
2055 | |||
2056 | dev_dbg(&hdmi->pdev->dev, "phy_int_stat=0x%x, phy_int_pol=0x%x\n", | ||
2057 | phy_int_stat, phy_int_pol); | ||
2058 | |||
2059 | /* check cable status */ | ||
2060 | if (phy_int_stat & HDMI_IH_PHY_STAT0_HPD) { | ||
2061 | /* cable connection changes */ | ||
2062 | if (phy_int_pol & HDMI_PHY_HPD) { | ||
2063 | /* Plugin event */ | ||
2064 | dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n"); | ||
2065 | mxc_hdmi_cable_connected(hdmi); | ||
2066 | |||
2067 | /* Make HPD intr active low to capture unplug event */ | ||
2068 | val = hdmi_readb(HDMI_PHY_POL0); | ||
2069 | val &= ~HDMI_PHY_HPD; | ||
2070 | hdmi_writeb(val, HDMI_PHY_POL0); | ||
2071 | |||
2072 | sprintf(event_string, "EVENT=plugin"); | ||
2073 | kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp); | ||
2074 | #ifdef CONFIG_MXC_HDMI_CEC | ||
2075 | mxc_hdmi_cec_handle(0x80); | ||
2076 | #endif | ||
2077 | hdmi_set_cable_state(1); | ||
2078 | |||
2079 | } else if (!(phy_int_pol & HDMI_PHY_HPD)) { | ||
2080 | /* Plugout event */ | ||
2081 | dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n"); | ||
2082 | hdmi_set_cable_state(0); | ||
2083 | mxc_hdmi_abort_stream(); | ||
2084 | mxc_hdmi_cable_disconnected(hdmi); | ||
2085 | |||
2086 | /* Make HPD intr active high to capture plugin event */ | ||
2087 | val = hdmi_readb(HDMI_PHY_POL0); | ||
2088 | val |= HDMI_PHY_HPD; | ||
2089 | hdmi_writeb(val, HDMI_PHY_POL0); | ||
2090 | |||
2091 | sprintf(event_string, "EVENT=plugout"); | ||
2092 | kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp); | ||
2093 | #ifdef CONFIG_MXC_HDMI_CEC | ||
2094 | mxc_hdmi_cec_handle(0x100); | ||
2095 | #endif | ||
2096 | |||
2097 | } else | ||
2098 | dev_dbg(&hdmi->pdev->dev, "EVENT=none?\n"); | ||
2099 | } | ||
2100 | |||
2101 | /* Lock here to ensure full powerdown sequence | ||
2102 | * completed before next interrupt processed */ | ||
2103 | spin_lock_irqsave(&hdmi->irq_lock, flags); | ||
2104 | |||
2105 | /* Re-enable HPD interrupts */ | ||
2106 | phy_int_mask = hdmi_readb(HDMI_PHY_MASK0); | ||
2107 | phy_int_mask &= ~HDMI_PHY_HPD; | ||
2108 | hdmi_writeb(phy_int_mask, HDMI_PHY_MASK0); | ||
2109 | |||
2110 | /* Unmute interrupts */ | ||
2111 | hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); | ||
2112 | |||
2113 | if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK) | ||
2114 | mxc_hdmi_clear_overflow(hdmi); | ||
2115 | |||
2116 | spin_unlock_irqrestore(&hdmi->irq_lock, flags); | ||
2117 | } | ||
2118 | |||
2119 | static void hdcp_hdp_worker(struct work_struct *work) | ||
2120 | { | ||
2121 | struct delayed_work *delay_work = to_delayed_work(work); | ||
2122 | struct mxc_hdmi *hdmi = | ||
2123 | container_of(delay_work, struct mxc_hdmi, hdcp_hdp_work); | ||
2124 | char event_string[32]; | ||
2125 | char *envp[] = { event_string, NULL }; | ||
2126 | |||
2127 | /* HDCP interrupt */ | ||
2128 | sprintf(event_string, "EVENT=hdcpint"); | ||
2129 | kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp); | ||
2130 | |||
2131 | /* Unmute interrupts in HDCP application*/ | ||
2132 | } | ||
2133 | |||
2134 | static irqreturn_t mxc_hdmi_hotplug(int irq, void *data) | ||
2135 | { | ||
2136 | struct mxc_hdmi *hdmi = data; | ||
2137 | u8 val, intr_stat; | ||
2138 | unsigned long flags; | ||
2139 | |||
2140 | spin_lock_irqsave(&hdmi->irq_lock, flags); | ||
2141 | |||
2142 | /* Check and clean packet overflow interrupt.*/ | ||
2143 | if (hdmi_readb(HDMI_IH_FC_STAT2) & | ||
2144 | HDMI_IH_FC_STAT2_OVERFLOW_MASK) { | ||
2145 | mxc_hdmi_clear_overflow(hdmi); | ||
2146 | |||
2147 | dev_dbg(&hdmi->pdev->dev, "Overflow interrupt received\n"); | ||
2148 | /* clear irq status */ | ||
2149 | hdmi_writeb(HDMI_IH_FC_STAT2_OVERFLOW_MASK, | ||
2150 | HDMI_IH_FC_STAT2); | ||
2151 | } | ||
2152 | |||
2153 | /* | ||
2154 | * We could not disable the irq. Probably the audio driver | ||
2155 | * has enabled it. Masking off the HDMI interrupts using | ||
2156 | * HDMI registers. | ||
2157 | */ | ||
2158 | /* Capture status - used in hotplug_worker ISR */ | ||
2159 | intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0); | ||
2160 | |||
2161 | if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { | ||
2162 | |||
2163 | dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n"); | ||
2164 | hdmi->latest_intr_stat = intr_stat; | ||
2165 | |||
2166 | /* Mute interrupts until handled */ | ||
2167 | |||
2168 | val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0); | ||
2169 | val |= HDMI_IH_MUTE_PHY_STAT0_HPD; | ||
2170 | hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0); | ||
2171 | |||
2172 | val = hdmi_readb(HDMI_PHY_MASK0); | ||
2173 | val |= HDMI_PHY_HPD; | ||
2174 | hdmi_writeb(val, HDMI_PHY_MASK0); | ||
2175 | |||
2176 | /* Clear Hotplug interrupts */ | ||
2177 | hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); | ||
2178 | |||
2179 | schedule_delayed_work(&(hdmi->hotplug_work), msecs_to_jiffies(20)); | ||
2180 | } | ||
2181 | |||
2182 | /* Check HDCP interrupt state */ | ||
2183 | if (hdmi->hdmi_data.hdcp_enable) { | ||
2184 | val = hdmi_readb(HDMI_A_APIINTSTAT); | ||
2185 | if (val != 0) { | ||
2186 | /* Mute interrupts until interrupt handled */ | ||
2187 | val = 0xFF; | ||
2188 | hdmi_writeb(val, HDMI_A_APIINTMSK); | ||
2189 | schedule_delayed_work(&(hdmi->hdcp_hdp_work), msecs_to_jiffies(50)); | ||
2190 | } | ||
2191 | } | ||
2192 | |||
2193 | spin_unlock_irqrestore(&hdmi->irq_lock, flags); | ||
2194 | return IRQ_HANDLED; | ||
2195 | } | ||
2196 | |||
2197 | static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event) | ||
2198 | { | ||
2199 | struct fb_videomode m; | ||
2200 | const struct fb_videomode *edid_mode; | ||
2201 | |||
2202 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
2203 | |||
2204 | fb_var_to_videomode(&m, &hdmi->fbi->var); | ||
2205 | dump_fb_videomode(&m); | ||
2206 | |||
2207 | dev_dbg(&hdmi->pdev->dev, "%s - video mode changed\n", __func__); | ||
2208 | |||
2209 | /* Save mode as 'previous_mode' so that we can know if mode changed. */ | ||
2210 | memcpy(&hdmi->previous_mode, &m, sizeof(struct fb_videomode)); | ||
2211 | |||
2212 | hdmi->vic = 0; | ||
2213 | if (!hdmi->requesting_vga_for_initialization) { | ||
2214 | /* Save mode if this isn't the result of requesting | ||
2215 | * vga default. */ | ||
2216 | memcpy(&hdmi->previous_non_vga_mode, &m, | ||
2217 | sizeof(struct fb_videomode)); | ||
2218 | if (!list_empty(&hdmi->fbi->modelist)) { | ||
2219 | edid_mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist); | ||
2220 | pr_debug("edid mode "); | ||
2221 | dump_fb_videomode((struct fb_videomode *)edid_mode); | ||
2222 | hdmi->vic = mxc_edid_mode_to_vic(edid_mode); | ||
2223 | } | ||
2224 | } | ||
2225 | |||
2226 | hdmi_disable_overflow_interrupts(); | ||
2227 | |||
2228 | dev_dbg(&hdmi->pdev->dev, "CEA mode used vic=%d\n", hdmi->vic); | ||
2229 | if (hdmi->edid_cfg.hdmi_cap) | ||
2230 | hdmi->hdmi_data.video_mode.mDVI = false; | ||
2231 | else { | ||
2232 | dev_dbg(&hdmi->pdev->dev, "CEA mode vic=%d work in DVI\n", hdmi->vic); | ||
2233 | hdmi->hdmi_data.video_mode.mDVI = true; | ||
2234 | } | ||
2235 | |||
2236 | if ((hdmi->vic == 6) || (hdmi->vic == 7) || | ||
2237 | (hdmi->vic == 21) || (hdmi->vic == 22) || | ||
2238 | (hdmi->vic == 2) || (hdmi->vic == 3) || | ||
2239 | (hdmi->vic == 17) || (hdmi->vic == 18)) | ||
2240 | hdmi->hdmi_data.colorimetry = eITU601; | ||
2241 | else | ||
2242 | hdmi->hdmi_data.colorimetry = eITU709; | ||
2243 | |||
2244 | if ((hdmi->vic == 10) || (hdmi->vic == 11) || | ||
2245 | (hdmi->vic == 12) || (hdmi->vic == 13) || | ||
2246 | (hdmi->vic == 14) || (hdmi->vic == 15) || | ||
2247 | (hdmi->vic == 25) || (hdmi->vic == 26) || | ||
2248 | (hdmi->vic == 27) || (hdmi->vic == 28) || | ||
2249 | (hdmi->vic == 29) || (hdmi->vic == 30) || | ||
2250 | (hdmi->vic == 35) || (hdmi->vic == 36) || | ||
2251 | (hdmi->vic == 37) || (hdmi->vic == 38)) | ||
2252 | hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 1; | ||
2253 | else | ||
2254 | hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 0; | ||
2255 | |||
2256 | hdmi->hdmi_data.video_mode.mPixelRepetitionInput = 0; | ||
2257 | |||
2258 | /* TODO: Get input format from IPU (via FB driver iface) */ | ||
2259 | hdmi->hdmi_data.enc_in_format = RGB; | ||
2260 | |||
2261 | hdmi->hdmi_data.enc_out_format = RGB; | ||
2262 | |||
2263 | /* YCbCr only enabled in HDMI mode */ | ||
2264 | if (!hdmi->hdmi_data.video_mode.mDVI && | ||
2265 | !hdmi->hdmi_data.rgb_out_enable) { | ||
2266 | if (hdmi->edid_cfg.cea_ycbcr444) | ||
2267 | hdmi->hdmi_data.enc_out_format = YCBCR444; | ||
2268 | else if (hdmi->edid_cfg.cea_ycbcr422) | ||
2269 | hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS; | ||
2270 | } | ||
2271 | |||
2272 | /* IPU not support depth color output */ | ||
2273 | hdmi->hdmi_data.enc_color_depth = 8; | ||
2274 | hdmi->hdmi_data.pix_repet_factor = 0; | ||
2275 | hdmi->hdmi_data.video_mode.mDataEnablePolarity = true; | ||
2276 | |||
2277 | /* HDMI Initialization Step B.1 */ | ||
2278 | hdmi_av_composer(hdmi); | ||
2279 | |||
2280 | /* HDMI Initializateion Step B.2 */ | ||
2281 | mxc_hdmi_phy_init(hdmi); | ||
2282 | |||
2283 | /* HDMI Initialization Step B.3 */ | ||
2284 | mxc_hdmi_enable_video_path(hdmi); | ||
2285 | |||
2286 | /* not for DVI mode */ | ||
2287 | if (hdmi->hdmi_data.video_mode.mDVI) | ||
2288 | dev_dbg(&hdmi->pdev->dev, "%s DVI mode\n", __func__); | ||
2289 | else { | ||
2290 | dev_dbg(&hdmi->pdev->dev, "%s CEA mode\n", __func__); | ||
2291 | |||
2292 | /* HDMI Initialization Step E - Configure audio */ | ||
2293 | hdmi_clk_regenerator_update_pixel_clock(hdmi->fbi->var.pixclock); | ||
2294 | hdmi_enable_audio_clk(hdmi); | ||
2295 | |||
2296 | /* HDMI Initialization Step F - Configure AVI InfoFrame */ | ||
2297 | hdmi_config_AVI(hdmi); | ||
2298 | } | ||
2299 | |||
2300 | hdmi_video_packetize(hdmi); | ||
2301 | hdmi_video_csc(hdmi); | ||
2302 | hdmi_video_sample(hdmi); | ||
2303 | hdmi_tx_hdcp_config(hdmi); | ||
2304 | |||
2305 | mxc_hdmi_clear_overflow(hdmi); | ||
2306 | |||
2307 | if (!hdmi->hdmi_data.video_mode.mDVI) | ||
2308 | hdmi_enable_overflow_interrupts(); | ||
2309 | |||
2310 | dev_dbg(&hdmi->pdev->dev, "%s exit\n\n", __func__); | ||
2311 | |||
2312 | } | ||
2313 | |||
2314 | /* Wait until we are registered to enable interrupts */ | ||
2315 | static void mxc_hdmi_fb_registered(struct mxc_hdmi *hdmi) | ||
2316 | { | ||
2317 | unsigned long flags; | ||
2318 | |||
2319 | if (hdmi->fb_reg) | ||
2320 | return; | ||
2321 | |||
2322 | spin_lock_irqsave(&hdmi->irq_lock, flags); | ||
2323 | |||
2324 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
2325 | |||
2326 | hdmi_writeb(HDMI_PHY_I2CM_INT_ADDR_DONE_POL, | ||
2327 | HDMI_PHY_I2CM_INT_ADDR); | ||
2328 | |||
2329 | hdmi_writeb(HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL | | ||
2330 | HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL, | ||
2331 | HDMI_PHY_I2CM_CTLINT_ADDR); | ||
2332 | |||
2333 | /* enable cable hot plug irq */ | ||
2334 | hdmi_writeb((u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0); | ||
2335 | |||
2336 | /* Clear Hotplug interrupts */ | ||
2337 | hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); | ||
2338 | |||
2339 | /* Unmute interrupts */ | ||
2340 | hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); | ||
2341 | |||
2342 | hdmi->fb_reg = true; | ||
2343 | |||
2344 | spin_unlock_irqrestore(&hdmi->irq_lock, flags); | ||
2345 | |||
2346 | } | ||
2347 | |||
2348 | static int mxc_hdmi_fb_event(struct notifier_block *nb, | ||
2349 | unsigned long val, void *v) | ||
2350 | { | ||
2351 | struct fb_event *event = v; | ||
2352 | struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb); | ||
2353 | |||
2354 | if (strcmp(event->info->fix.id, hdmi->fbi->fix.id)) | ||
2355 | return 0; | ||
2356 | |||
2357 | switch (val) { | ||
2358 | case FB_EVENT_FB_REGISTERED: | ||
2359 | dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_REGISTERED\n"); | ||
2360 | mxc_hdmi_fb_registered(hdmi); | ||
2361 | hdmi_set_registered(1); | ||
2362 | break; | ||
2363 | |||
2364 | case FB_EVENT_FB_UNREGISTERED: | ||
2365 | dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_UNREGISTERED\n"); | ||
2366 | hdmi->fb_reg = false; | ||
2367 | hdmi_set_registered(0); | ||
2368 | break; | ||
2369 | |||
2370 | case FB_EVENT_MODE_CHANGE: | ||
2371 | dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_MODE_CHANGE\n"); | ||
2372 | if (hdmi->fb_reg) | ||
2373 | mxc_hdmi_setup(hdmi, val); | ||
2374 | break; | ||
2375 | |||
2376 | case FB_EVENT_BLANK: | ||
2377 | if ((*((int *)event->data) == FB_BLANK_UNBLANK) && | ||
2378 | (*((int *)event->data) != hdmi->blank)) { | ||
2379 | dev_dbg(&hdmi->pdev->dev, | ||
2380 | "event=FB_EVENT_BLANK - UNBLANK\n"); | ||
2381 | |||
2382 | hdmi->blank = *((int *)event->data); | ||
2383 | |||
2384 | if (hdmi->fb_reg && hdmi->cable_plugin) | ||
2385 | mxc_hdmi_setup(hdmi, val); | ||
2386 | hdmi_set_blank_state(1); | ||
2387 | |||
2388 | } else if (*((int *)event->data) != hdmi->blank) { | ||
2389 | dev_dbg(&hdmi->pdev->dev, | ||
2390 | "event=FB_EVENT_BLANK - BLANK\n"); | ||
2391 | hdmi_set_blank_state(0); | ||
2392 | mxc_hdmi_abort_stream(); | ||
2393 | |||
2394 | mxc_hdmi_phy_disable(hdmi); | ||
2395 | |||
2396 | hdmi->blank = *((int *)event->data); | ||
2397 | } else | ||
2398 | dev_dbg(&hdmi->pdev->dev, | ||
2399 | "FB BLANK state no changed!\n"); | ||
2400 | |||
2401 | break; | ||
2402 | |||
2403 | case FB_EVENT_SUSPEND: | ||
2404 | dev_dbg(&hdmi->pdev->dev, | ||
2405 | "event=FB_EVENT_SUSPEND\n"); | ||
2406 | |||
2407 | if (hdmi->blank == FB_BLANK_UNBLANK) { | ||
2408 | mxc_hdmi_phy_disable(hdmi); | ||
2409 | clk_disable(hdmi->hdmi_iahb_clk); | ||
2410 | clk_disable(hdmi->hdmi_isfr_clk); | ||
2411 | } | ||
2412 | break; | ||
2413 | |||
2414 | case FB_EVENT_RESUME: | ||
2415 | dev_dbg(&hdmi->pdev->dev, | ||
2416 | "event=FB_EVENT_RESUME\n"); | ||
2417 | |||
2418 | if (hdmi->blank == FB_BLANK_UNBLANK) { | ||
2419 | clk_enable(hdmi->hdmi_iahb_clk); | ||
2420 | clk_enable(hdmi->hdmi_isfr_clk); | ||
2421 | mxc_hdmi_phy_init(hdmi); | ||
2422 | } | ||
2423 | break; | ||
2424 | |||
2425 | } | ||
2426 | return 0; | ||
2427 | } | ||
2428 | |||
2429 | static void hdmi_init_route(struct mxc_hdmi *hdmi) | ||
2430 | { | ||
2431 | uint32_t hdmi_mux_setting, reg; | ||
2432 | int ipu_id, disp_id; | ||
2433 | |||
2434 | ipu_id = mxc_hdmi_ipu_id; | ||
2435 | disp_id = mxc_hdmi_disp_id; | ||
2436 | |||
2437 | if ((ipu_id > 1) || (ipu_id < 0)) { | ||
2438 | pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id); | ||
2439 | ipu_id = 0; | ||
2440 | } | ||
2441 | |||
2442 | if ((disp_id > 1) || (disp_id < 0)) { | ||
2443 | pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id); | ||
2444 | disp_id = 0; | ||
2445 | } | ||
2446 | |||
2447 | reg = readl(hdmi->gpr_hdmi_base); | ||
2448 | |||
2449 | /* Configure the connection between IPU1/2 and HDMI */ | ||
2450 | hdmi_mux_setting = 2*ipu_id + disp_id; | ||
2451 | |||
2452 | /* GPR3, bits 2-3 = HDMI_MUX_CTL */ | ||
2453 | reg &= ~0xd; | ||
2454 | reg |= hdmi_mux_setting << 2; | ||
2455 | |||
2456 | writel(reg, hdmi->gpr_hdmi_base); | ||
2457 | |||
2458 | /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */ | ||
2459 | /* | ||
2460 | if (hdmi_SDMA_check()) { | ||
2461 | reg = readl(hdmi->gpr_sdma_base); | ||
2462 | reg |= 0x1; | ||
2463 | writel(reg, hdmi->gpr_sdma_base); | ||
2464 | } | ||
2465 | */ | ||
2466 | } | ||
2467 | |||
2468 | static void hdmi_get_of_property(struct mxc_hdmi *hdmi) | ||
2469 | { | ||
2470 | struct platform_device *pdev = hdmi->pdev; | ||
2471 | struct device_node *np = pdev->dev.of_node; | ||
2472 | const struct of_device_id *of_id = | ||
2473 | of_match_device(imx_hdmi_dt_ids, &pdev->dev); | ||
2474 | int ret; | ||
2475 | u32 phy_reg_vlev = 0, phy_reg_cksymtx = 0; | ||
2476 | |||
2477 | if (of_id) { | ||
2478 | pdev->id_entry = of_id->data; | ||
2479 | hdmi->cpu_type = pdev->id_entry->driver_data; | ||
2480 | } | ||
2481 | |||
2482 | /* HDMI PHY register vlev and cksymtx preperty is optional. | ||
2483 | * It is for specific board to pass HCT electrical part. | ||
2484 | * Default value will been setting in HDMI PHY config function | ||
2485 | * if it is not define in device tree. | ||
2486 | */ | ||
2487 | ret = of_property_read_u32(np, "phy_reg_vlev", &phy_reg_vlev); | ||
2488 | if (ret) | ||
2489 | dev_dbg(&pdev->dev, "No board specific HDMI PHY vlev\n"); | ||
2490 | |||
2491 | ret = of_property_read_u32(np, "phy_reg_cksymtx", &phy_reg_cksymtx); | ||
2492 | if (ret) | ||
2493 | dev_dbg(&pdev->dev, "No board specific HDMI PHY cksymtx\n"); | ||
2494 | |||
2495 | /* Specific phy config */ | ||
2496 | hdmi->phy_config.reg_cksymtx = phy_reg_cksymtx; | ||
2497 | hdmi->phy_config.reg_vlev = phy_reg_vlev; | ||
2498 | |||
2499 | } | ||
2500 | |||
2501 | /* HDMI Initialization Step A */ | ||
2502 | static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp, | ||
2503 | struct mxc_dispdrv_setting *setting) | ||
2504 | { | ||
2505 | int ret = 0; | ||
2506 | u32 i; | ||
2507 | const struct fb_videomode *mode; | ||
2508 | struct fb_videomode m; | ||
2509 | struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp); | ||
2510 | int irq = platform_get_irq(hdmi->pdev, 0); | ||
2511 | |||
2512 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
2513 | |||
2514 | /* Check hdmi disp init once */ | ||
2515 | if (hdmi_inited) { | ||
2516 | dev_err(&hdmi->pdev->dev, | ||
2517 | "Error only one HDMI output support now!\n"); | ||
2518 | return -1; | ||
2519 | } | ||
2520 | |||
2521 | hdmi_get_of_property(hdmi); | ||
2522 | |||
2523 | if (irq < 0) | ||
2524 | return -ENODEV; | ||
2525 | |||
2526 | hdmi->dft_mode_set = false; | ||
2527 | |||
2528 | /* Setting HDMI default to blank state */ | ||
2529 | hdmi->blank = FB_BLANK_POWERDOWN; | ||
2530 | |||
2531 | setting->dev_id = mxc_hdmi_ipu_id; | ||
2532 | setting->disp_id = mxc_hdmi_disp_id; | ||
2533 | setting->if_fmt = IPU_PIX_FMT_RGB24; | ||
2534 | |||
2535 | hdmi->dft_mode_str = setting->dft_mode_str; | ||
2536 | hdmi->default_bpp = setting->default_bpp; | ||
2537 | dev_dbg(&hdmi->pdev->dev, "%s - default mode %s bpp=%d\n", | ||
2538 | __func__, hdmi->dft_mode_str, hdmi->default_bpp); | ||
2539 | |||
2540 | hdmi->fbi = setting->fbi; | ||
2541 | |||
2542 | hdmi_init_route(hdmi); | ||
2543 | |||
2544 | hdmi->hdmi_isfr_clk = clk_get(&hdmi->pdev->dev, "hdmi_isfr"); | ||
2545 | if (IS_ERR(hdmi->hdmi_isfr_clk)) { | ||
2546 | ret = PTR_ERR(hdmi->hdmi_isfr_clk); | ||
2547 | dev_err(&hdmi->pdev->dev, | ||
2548 | "Unable to get HDMI clk: %d\n", ret); | ||
2549 | goto egetclk1; | ||
2550 | } | ||
2551 | |||
2552 | ret = clk_prepare_enable(hdmi->hdmi_isfr_clk); | ||
2553 | if (ret < 0) { | ||
2554 | dev_err(&hdmi->pdev->dev, | ||
2555 | "Cannot enable HDMI isfr clock: %d\n", ret); | ||
2556 | goto erate1; | ||
2557 | } | ||
2558 | |||
2559 | hdmi->hdmi_iahb_clk = clk_get(&hdmi->pdev->dev, "hdmi_iahb"); | ||
2560 | if (IS_ERR(hdmi->hdmi_iahb_clk)) { | ||
2561 | ret = PTR_ERR(hdmi->hdmi_iahb_clk); | ||
2562 | dev_err(&hdmi->pdev->dev, | ||
2563 | "Unable to get HDMI clk: %d\n", ret); | ||
2564 | goto egetclk2; | ||
2565 | } | ||
2566 | |||
2567 | ret = clk_prepare_enable(hdmi->hdmi_iahb_clk); | ||
2568 | if (ret < 0) { | ||
2569 | dev_err(&hdmi->pdev->dev, | ||
2570 | "Cannot enable HDMI iahb clock: %d\n", ret); | ||
2571 | goto erate2; | ||
2572 | } | ||
2573 | |||
2574 | dev_dbg(&hdmi->pdev->dev, "Enabled HDMI clocks\n"); | ||
2575 | |||
2576 | /* Init DDC pins for HDCP */ | ||
2577 | if (hdcp_init) { | ||
2578 | hdmi->pinctrl = devm_pinctrl_get_select_default(&hdmi->pdev->dev); | ||
2579 | if (IS_ERR(hdmi->pinctrl)) { | ||
2580 | dev_err(&hdmi->pdev->dev, "can't get/select DDC pinctrl\n"); | ||
2581 | goto erate2; | ||
2582 | } | ||
2583 | } | ||
2584 | |||
2585 | /* Product and revision IDs */ | ||
2586 | dev_info(&hdmi->pdev->dev, | ||
2587 | "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", | ||
2588 | hdmi_readb(HDMI_DESIGN_ID), | ||
2589 | hdmi_readb(HDMI_REVISION_ID), | ||
2590 | hdmi_readb(HDMI_PRODUCT_ID0), | ||
2591 | hdmi_readb(HDMI_PRODUCT_ID1)); | ||
2592 | |||
2593 | /* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator | ||
2594 | * N and cts values before enabling phy */ | ||
2595 | hdmi_init_clk_regenerator(); | ||
2596 | |||
2597 | INIT_LIST_HEAD(&hdmi->fbi->modelist); | ||
2598 | |||
2599 | spin_lock_init(&hdmi->irq_lock); | ||
2600 | |||
2601 | /* Set the default mode and modelist when disp init. */ | ||
2602 | fb_find_mode(&hdmi->fbi->var, hdmi->fbi, | ||
2603 | hdmi->dft_mode_str, NULL, 0, NULL, | ||
2604 | hdmi->default_bpp); | ||
2605 | |||
2606 | console_lock(); | ||
2607 | |||
2608 | fb_destroy_modelist(&hdmi->fbi->modelist); | ||
2609 | |||
2610 | /*Add all no interlaced CEA mode to default modelist */ | ||
2611 | for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) { | ||
2612 | mode = &mxc_cea_mode[i]; | ||
2613 | if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0)) | ||
2614 | fb_add_videomode(mode, &hdmi->fbi->modelist); | ||
2615 | } | ||
2616 | |||
2617 | /*Add XGA and SXGA to default modelist */ | ||
2618 | fb_add_videomode(&xga_mode, &hdmi->fbi->modelist); | ||
2619 | fb_add_videomode(&sxga_mode, &hdmi->fbi->modelist); | ||
2620 | |||
2621 | console_unlock(); | ||
2622 | |||
2623 | /* Find a nearest mode in default modelist */ | ||
2624 | fb_var_to_videomode(&m, &hdmi->fbi->var); | ||
2625 | dump_fb_videomode(&m); | ||
2626 | |||
2627 | mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist); | ||
2628 | if (!mode) { | ||
2629 | pr_err("%s: could not find mode in modelist\n", __func__); | ||
2630 | return -1; | ||
2631 | } | ||
2632 | |||
2633 | fb_videomode_to_var(&hdmi->fbi->var, mode); | ||
2634 | |||
2635 | /* Default setting HDMI working in HDMI mode*/ | ||
2636 | hdmi->edid_cfg.hdmi_cap = true; | ||
2637 | |||
2638 | INIT_DELAYED_WORK(&hdmi->hotplug_work, hotplug_worker); | ||
2639 | INIT_DELAYED_WORK(&hdmi->hdcp_hdp_work, hdcp_hdp_worker); | ||
2640 | |||
2641 | /* Configure registers related to HDMI interrupt | ||
2642 | * generation before registering IRQ. */ | ||
2643 | hdmi_writeb(HDMI_PHY_HPD, HDMI_PHY_POL0); | ||
2644 | |||
2645 | /* Clear Hotplug interrupts */ | ||
2646 | hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); | ||
2647 | |||
2648 | hdmi->nb.notifier_call = mxc_hdmi_fb_event; | ||
2649 | ret = fb_register_client(&hdmi->nb); | ||
2650 | if (ret < 0) | ||
2651 | goto efbclient; | ||
2652 | |||
2653 | memset(&hdmi->hdmi_data, 0, sizeof(struct hdmi_data_info)); | ||
2654 | |||
2655 | /* Default HDMI working in RGB mode */ | ||
2656 | hdmi->hdmi_data.rgb_out_enable = true; | ||
2657 | |||
2658 | ret = devm_request_irq(&hdmi->pdev->dev, irq, mxc_hdmi_hotplug, IRQF_SHARED, | ||
2659 | dev_name(&hdmi->pdev->dev), hdmi); | ||
2660 | if (ret < 0) { | ||
2661 | dev_err(&hdmi->pdev->dev, | ||
2662 | "Unable to request irq: %d\n", ret); | ||
2663 | goto ereqirq; | ||
2664 | } | ||
2665 | |||
2666 | ret = device_create_file(&hdmi->pdev->dev, &dev_attr_fb_name); | ||
2667 | if (ret < 0) | ||
2668 | dev_warn(&hdmi->pdev->dev, | ||
2669 | "cound not create sys node for fb name\n"); | ||
2670 | ret = device_create_file(&hdmi->pdev->dev, &dev_attr_cable_state); | ||
2671 | if (ret < 0) | ||
2672 | dev_warn(&hdmi->pdev->dev, | ||
2673 | "cound not create sys node for cable state\n"); | ||
2674 | ret = device_create_file(&hdmi->pdev->dev, &dev_attr_edid); | ||
2675 | if (ret < 0) | ||
2676 | dev_warn(&hdmi->pdev->dev, | ||
2677 | "cound not create sys node for edid\n"); | ||
2678 | |||
2679 | ret = device_create_file(&hdmi->pdev->dev, &dev_attr_rgb_out_enable); | ||
2680 | if (ret < 0) | ||
2681 | dev_warn(&hdmi->pdev->dev, | ||
2682 | "cound not create sys node for rgb out enable\n"); | ||
2683 | |||
2684 | ret = device_create_file(&hdmi->pdev->dev, &dev_attr_hdcp_enable); | ||
2685 | if (ret < 0) | ||
2686 | dev_warn(&hdmi->pdev->dev, | ||
2687 | "cound not create sys node for hdcp enable\n"); | ||
2688 | |||
2689 | dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__); | ||
2690 | |||
2691 | hdmi_inited = true; | ||
2692 | |||
2693 | return ret; | ||
2694 | |||
2695 | efbclient: | ||
2696 | free_irq(irq, hdmi); | ||
2697 | ereqirq: | ||
2698 | clk_disable_unprepare(hdmi->hdmi_iahb_clk); | ||
2699 | erate2: | ||
2700 | clk_put(hdmi->hdmi_iahb_clk); | ||
2701 | egetclk2: | ||
2702 | clk_disable_unprepare(hdmi->hdmi_isfr_clk); | ||
2703 | erate1: | ||
2704 | clk_put(hdmi->hdmi_isfr_clk); | ||
2705 | egetclk1: | ||
2706 | dev_dbg(&hdmi->pdev->dev, "%s error exit\n", __func__); | ||
2707 | |||
2708 | return ret; | ||
2709 | } | ||
2710 | |||
2711 | static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_handle *disp) | ||
2712 | { | ||
2713 | struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp); | ||
2714 | |||
2715 | dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); | ||
2716 | |||
2717 | fb_unregister_client(&hdmi->nb); | ||
2718 | |||
2719 | clk_disable_unprepare(hdmi->hdmi_isfr_clk); | ||
2720 | clk_put(hdmi->hdmi_isfr_clk); | ||
2721 | clk_disable_unprepare(hdmi->hdmi_iahb_clk); | ||
2722 | clk_put(hdmi->hdmi_iahb_clk); | ||
2723 | |||
2724 | platform_device_unregister(hdmi->pdev); | ||
2725 | |||
2726 | hdmi_inited = false; | ||
2727 | } | ||
2728 | |||
2729 | static struct mxc_dispdrv_driver mxc_hdmi_drv = { | ||
2730 | .name = DISPDRV_HDMI, | ||
2731 | .init = mxc_hdmi_disp_init, | ||
2732 | .deinit = mxc_hdmi_disp_deinit, | ||
2733 | .enable = mxc_hdmi_power_on, | ||
2734 | .disable = mxc_hdmi_power_off, | ||
2735 | }; | ||
2736 | |||
2737 | |||
2738 | static int mxc_hdmi_open(struct inode *inode, struct file *file) | ||
2739 | { | ||
2740 | return 0; | ||
2741 | } | ||
2742 | |||
2743 | static long mxc_hdmi_ioctl(struct file *file, | ||
2744 | unsigned int cmd, unsigned long arg) | ||
2745 | { | ||
2746 | int __user *argp = (void __user *)arg; | ||
2747 | int ret = 0; | ||
2748 | |||
2749 | switch (cmd) { | ||
2750 | case HDMI_IOC_GET_RESOURCE: | ||
2751 | ret = copy_to_user(argp, &g_hdmi->hdmi_data, | ||
2752 | sizeof(g_hdmi->hdmi_data)) ? -EFAULT : 0; | ||
2753 | break; | ||
2754 | case HDMI_IOC_GET_CPU_TYPE: | ||
2755 | *argp = g_hdmi->cpu_type; | ||
2756 | break; | ||
2757 | default: | ||
2758 | pr_debug("Unsupport cmd %d\n", cmd); | ||
2759 | break; | ||
2760 | } | ||
2761 | return ret; | ||
2762 | } | ||
2763 | |||
2764 | static int mxc_hdmi_release(struct inode *inode, struct file *file) | ||
2765 | { | ||
2766 | return 0; | ||
2767 | } | ||
2768 | |||
2769 | static const struct file_operations mxc_hdmi_fops = { | ||
2770 | .owner = THIS_MODULE, | ||
2771 | .open = mxc_hdmi_open, | ||
2772 | .release = mxc_hdmi_release, | ||
2773 | .unlocked_ioctl = mxc_hdmi_ioctl, | ||
2774 | }; | ||
2775 | |||
2776 | |||
2777 | static int mxc_hdmi_probe(struct platform_device *pdev) | ||
2778 | { | ||
2779 | struct mxc_hdmi *hdmi; | ||
2780 | struct device *temp_class; | ||
2781 | struct resource *res; | ||
2782 | int ret = 0; | ||
2783 | |||
2784 | /* Check that I2C driver is loaded and available */ | ||
2785 | /* Skip I2C driver available check when HDCP enable */ | ||
2786 | if (!hdmi_i2c && !hdcp_init) | ||
2787 | return -ENODEV; | ||
2788 | |||
2789 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2790 | if (!res) | ||
2791 | return -ENOENT; | ||
2792 | |||
2793 | hdmi = devm_kzalloc(&pdev->dev, | ||
2794 | sizeof(struct mxc_hdmi), | ||
2795 | GFP_KERNEL); | ||
2796 | if (!hdmi) { | ||
2797 | dev_err(&pdev->dev, "Cannot allocate device data\n"); | ||
2798 | ret = -ENOMEM; | ||
2799 | goto ealloc; | ||
2800 | } | ||
2801 | g_hdmi = hdmi; | ||
2802 | |||
2803 | hdmi_major = register_chrdev(hdmi_major, "mxc_hdmi", &mxc_hdmi_fops); | ||
2804 | if (hdmi_major < 0) { | ||
2805 | printk(KERN_ERR "HDMI: unable to get a major for HDMI\n"); | ||
2806 | ret = -EBUSY; | ||
2807 | goto ealloc; | ||
2808 | } | ||
2809 | |||
2810 | hdmi_class = class_create(THIS_MODULE, "mxc_hdmi"); | ||
2811 | if (IS_ERR(hdmi_class)) { | ||
2812 | ret = PTR_ERR(hdmi_class); | ||
2813 | goto err_out_chrdev; | ||
2814 | } | ||
2815 | |||
2816 | temp_class = device_create(hdmi_class, NULL, MKDEV(hdmi_major, 0), | ||
2817 | NULL, "mxc_hdmi"); | ||
2818 | if (IS_ERR(temp_class)) { | ||
2819 | ret = PTR_ERR(temp_class); | ||
2820 | goto err_out_class; | ||
2821 | } | ||
2822 | |||
2823 | hdmi->pdev = pdev; | ||
2824 | |||
2825 | hdmi->core_pdev = platform_device_alloc("mxc_hdmi_core", -1); | ||
2826 | if (!hdmi->core_pdev) { | ||
2827 | pr_err("%s failed platform_device_alloc for hdmi core\n", | ||
2828 | __func__); | ||
2829 | ret = -ENOMEM; | ||
2830 | goto ecore; | ||
2831 | } | ||
2832 | |||
2833 | hdmi->gpr_base = ioremap(res->start, resource_size(res)); | ||
2834 | if (!hdmi->gpr_base) { | ||
2835 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
2836 | ret = -ENOMEM; | ||
2837 | goto eiomap; | ||
2838 | } | ||
2839 | |||
2840 | hdmi->gpr_hdmi_base = hdmi->gpr_base + 3; | ||
2841 | hdmi->gpr_sdma_base = hdmi->gpr_base; | ||
2842 | |||
2843 | hdmi_inited = false; | ||
2844 | |||
2845 | hdmi->disp_mxc_hdmi = mxc_dispdrv_register(&mxc_hdmi_drv); | ||
2846 | if (IS_ERR(hdmi->disp_mxc_hdmi)) { | ||
2847 | dev_err(&pdev->dev, "Failed to register dispdrv - 0x%x\n", | ||
2848 | (int)hdmi->disp_mxc_hdmi); | ||
2849 | ret = (int)hdmi->disp_mxc_hdmi; | ||
2850 | goto edispdrv; | ||
2851 | } | ||
2852 | mxc_dispdrv_setdata(hdmi->disp_mxc_hdmi, hdmi); | ||
2853 | |||
2854 | platform_set_drvdata(pdev, hdmi); | ||
2855 | |||
2856 | return 0; | ||
2857 | edispdrv: | ||
2858 | iounmap(hdmi->gpr_base); | ||
2859 | eiomap: | ||
2860 | platform_device_put(hdmi->core_pdev); | ||
2861 | ecore: | ||
2862 | kfree(hdmi); | ||
2863 | err_out_class: | ||
2864 | device_destroy(hdmi_class, MKDEV(hdmi_major, 0)); | ||
2865 | class_destroy(hdmi_class); | ||
2866 | err_out_chrdev: | ||
2867 | unregister_chrdev(hdmi_major, "mxc_hdmi"); | ||
2868 | ealloc: | ||
2869 | return ret; | ||
2870 | } | ||
2871 | |||
2872 | static int mxc_hdmi_remove(struct platform_device *pdev) | ||
2873 | { | ||
2874 | struct mxc_hdmi *hdmi = platform_get_drvdata(pdev); | ||
2875 | int irq = platform_get_irq(pdev, 0); | ||
2876 | |||
2877 | fb_unregister_client(&hdmi->nb); | ||
2878 | |||
2879 | mxc_dispdrv_puthandle(hdmi->disp_mxc_hdmi); | ||
2880 | mxc_dispdrv_unregister(hdmi->disp_mxc_hdmi); | ||
2881 | iounmap(hdmi->gpr_base); | ||
2882 | /* No new work will be scheduled, wait for running ISR */ | ||
2883 | free_irq(irq, hdmi); | ||
2884 | kfree(hdmi); | ||
2885 | g_hdmi = NULL; | ||
2886 | |||
2887 | return 0; | ||
2888 | } | ||
2889 | |||
2890 | static struct platform_driver mxc_hdmi_driver = { | ||
2891 | .probe = mxc_hdmi_probe, | ||
2892 | .remove = mxc_hdmi_remove, | ||
2893 | .driver = { | ||
2894 | .name = "mxc_hdmi", | ||
2895 | .of_match_table = imx_hdmi_dt_ids, | ||
2896 | .owner = THIS_MODULE, | ||
2897 | }, | ||
2898 | }; | ||
2899 | |||
2900 | static int __init mxc_hdmi_init(void) | ||
2901 | { | ||
2902 | return platform_driver_register(&mxc_hdmi_driver); | ||
2903 | } | ||
2904 | module_init(mxc_hdmi_init); | ||
2905 | |||
2906 | static void __exit mxc_hdmi_exit(void) | ||
2907 | { | ||
2908 | if (hdmi_major > 0) { | ||
2909 | device_destroy(hdmi_class, MKDEV(hdmi_major, 0)); | ||
2910 | class_destroy(hdmi_class); | ||
2911 | unregister_chrdev(hdmi_major, "mxc_hdmi"); | ||
2912 | hdmi_major = 0; | ||
2913 | } | ||
2914 | |||
2915 | platform_driver_unregister(&mxc_hdmi_driver); | ||
2916 | } | ||
2917 | module_exit(mxc_hdmi_exit); | ||
2918 | |||
2919 | static int mxc_hdmi_i2c_probe(struct i2c_client *client, | ||
2920 | const struct i2c_device_id *id) | ||
2921 | { | ||
2922 | if (!i2c_check_functionality(client->adapter, | ||
2923 | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) | ||
2924 | return -ENODEV; | ||
2925 | |||
2926 | hdmi_i2c = client; | ||
2927 | |||
2928 | return 0; | ||
2929 | } | ||
2930 | |||
2931 | static int mxc_hdmi_i2c_remove(struct i2c_client *client) | ||
2932 | { | ||
2933 | hdmi_i2c = NULL; | ||
2934 | return 0; | ||
2935 | } | ||
2936 | |||
2937 | static const struct of_device_id imx_hdmi_i2c_match[] = { | ||
2938 | { .compatible = "fsl,imx6-hdmi-i2c", }, | ||
2939 | { /* sentinel */ } | ||
2940 | }; | ||
2941 | |||
2942 | static const struct i2c_device_id mxc_hdmi_i2c_id[] = { | ||
2943 | { "mxc_hdmi_i2c", 0 }, | ||
2944 | {}, | ||
2945 | }; | ||
2946 | MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id); | ||
2947 | |||
2948 | static struct i2c_driver mxc_hdmi_i2c_driver = { | ||
2949 | .driver = { | ||
2950 | .name = "mxc_hdmi_i2c", | ||
2951 | .of_match_table = imx_hdmi_i2c_match, | ||
2952 | }, | ||
2953 | .probe = mxc_hdmi_i2c_probe, | ||
2954 | .remove = mxc_hdmi_i2c_remove, | ||
2955 | .id_table = mxc_hdmi_i2c_id, | ||
2956 | }; | ||
2957 | |||
2958 | static int __init mxc_hdmi_i2c_init(void) | ||
2959 | { | ||
2960 | return i2c_add_driver(&mxc_hdmi_i2c_driver); | ||
2961 | } | ||
2962 | |||
2963 | static void __exit mxc_hdmi_i2c_exit(void) | ||
2964 | { | ||
2965 | i2c_del_driver(&mxc_hdmi_i2c_driver); | ||
2966 | } | ||
2967 | |||
2968 | module_init(mxc_hdmi_i2c_init); | ||
2969 | module_exit(mxc_hdmi_i2c_exit); | ||
2970 | |||
2971 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h new file mode 100644 index 000000000000..f5524987eb30 --- /dev/null +++ b/include/linux/mfd/mxc-hdmi-core.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | */ | ||
19 | #ifndef __LINUX_MXC_HDMI_CORE_H_ | ||
20 | #define __LINUX_MXC_HDMI_CORE_H_ | ||
21 | |||
22 | #include <video/mxc_edid.h> | ||
23 | |||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/soc.h> | ||
28 | |||
29 | #define IRQ_DISABLE_SUCCEED 0 | ||
30 | #define IRQ_DISABLE_FAIL 1 | ||
31 | |||
32 | bool hdmi_check_overflow(void); | ||
33 | |||
34 | u8 hdmi_readb(unsigned int reg); | ||
35 | void hdmi_writeb(u8 value, unsigned int reg); | ||
36 | void hdmi_mask_writeb(u8 data, unsigned int addr, u8 shift, u8 mask); | ||
37 | unsigned int hdmi_read4(unsigned int reg); | ||
38 | void hdmi_write4(unsigned int value, unsigned int reg); | ||
39 | |||
40 | void hdmi_irq_init(void); | ||
41 | void hdmi_irq_enable(int irq); | ||
42 | unsigned int hdmi_irq_disable(int irq); | ||
43 | |||
44 | void hdmi_set_sample_rate(unsigned int rate); | ||
45 | void hdmi_set_dma_mode(unsigned int dma_running); | ||
46 | void hdmi_init_clk_regenerator(void); | ||
47 | void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock); | ||
48 | |||
49 | void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg); | ||
50 | void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg); | ||
51 | |||
52 | extern int mxc_hdmi_ipu_id; | ||
53 | extern int mxc_hdmi_disp_id; | ||
54 | |||
55 | void hdmi_set_registered(int registered); | ||
56 | int hdmi_get_registered(void); | ||
57 | unsigned int hdmi_SDMA_check(void); | ||
58 | int mxc_hdmi_abort_stream(void); | ||
59 | int mxc_hdmi_register_audio(struct snd_pcm_substream *substream); | ||
60 | void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream); | ||
61 | unsigned int hdmi_set_cable_state(unsigned int state); | ||
62 | unsigned int hdmi_set_blank_state(unsigned int state); | ||
63 | int check_hdmi_state(void); | ||
64 | |||
65 | #endif | ||
diff --git a/include/video/mxc_edid.h b/include/video/mxc_edid.h new file mode 100755 index 000000000000..34e797cc80b4 --- /dev/null +++ b/include/video/mxc_edid.h | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * The code contained herein is licensed under the GNU General Public | ||
7 | * License. You may obtain a copy of the GNU General Public License | ||
8 | * Version 2 or later at the following locations: | ||
9 | * | ||
10 | * http://www.opensource.org/licenses/gpl-license.html | ||
11 | * http://www.gnu.org/copyleft/gpl.html | ||
12 | */ | ||
13 | |||
14 | /*! | ||
15 | * @defgroup Framebuffer Framebuffer Driver for SDC and ADC. | ||
16 | */ | ||
17 | |||
18 | /*! | ||
19 | * @file mxc_edid.h | ||
20 | * | ||
21 | * @brief MXC EDID tools | ||
22 | * | ||
23 | * @ingroup Framebuffer | ||
24 | */ | ||
25 | |||
26 | #ifndef MXC_EDID_H | ||
27 | #define MXC_EDID_H | ||
28 | |||
29 | #include <linux/fb.h> | ||
30 | |||
31 | #define FB_VMODE_ASPECT_4_3 0x10 | ||
32 | #define FB_VMODE_ASPECT_16_9 0x20 | ||
33 | #define FB_VMODE_ASPECT_MASK (FB_VMODE_ASPECT_4_3 | FB_VMODE_ASPECT_16_9) | ||
34 | |||
35 | enum cea_audio_coding_types { | ||
36 | AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, | ||
37 | AUDIO_CODING_TYPE_LPCM = 1, | ||
38 | AUDIO_CODING_TYPE_AC3 = 2, | ||
39 | AUDIO_CODING_TYPE_MPEG1 = 3, | ||
40 | AUDIO_CODING_TYPE_MP3 = 4, | ||
41 | AUDIO_CODING_TYPE_MPEG2 = 5, | ||
42 | AUDIO_CODING_TYPE_AACLC = 6, | ||
43 | AUDIO_CODING_TYPE_DTS = 7, | ||
44 | AUDIO_CODING_TYPE_ATRAC = 8, | ||
45 | AUDIO_CODING_TYPE_SACD = 9, | ||
46 | AUDIO_CODING_TYPE_EAC3 = 10, | ||
47 | AUDIO_CODING_TYPE_DTS_HD = 11, | ||
48 | AUDIO_CODING_TYPE_MLP = 12, | ||
49 | AUDIO_CODING_TYPE_DST = 13, | ||
50 | AUDIO_CODING_TYPE_WMAPRO = 14, | ||
51 | AUDIO_CODING_TYPE_RESERVED = 15, | ||
52 | }; | ||
53 | |||
54 | struct mxc_hdmi_3d_format { | ||
55 | unsigned char vic_order_2d; | ||
56 | unsigned char struct_3d; | ||
57 | unsigned char detail_3d; | ||
58 | unsigned char reserved; | ||
59 | }; | ||
60 | |||
61 | struct mxc_edid_cfg { | ||
62 | bool cea_underscan; | ||
63 | bool cea_basicaudio; | ||
64 | bool cea_ycbcr444; | ||
65 | bool cea_ycbcr422; | ||
66 | bool hdmi_cap; | ||
67 | |||
68 | /*VSD*/ | ||
69 | bool vsd_support_ai; | ||
70 | bool vsd_dc_48bit; | ||
71 | bool vsd_dc_36bit; | ||
72 | bool vsd_dc_30bit; | ||
73 | bool vsd_dc_y444; | ||
74 | bool vsd_dvi_dual; | ||
75 | |||
76 | bool vsd_cnc0; | ||
77 | bool vsd_cnc1; | ||
78 | bool vsd_cnc2; | ||
79 | bool vsd_cnc3; | ||
80 | |||
81 | u8 vsd_video_latency; | ||
82 | u8 vsd_audio_latency; | ||
83 | u8 vsd_I_video_latency; | ||
84 | u8 vsd_I_audio_latency; | ||
85 | |||
86 | u8 physical_address[4]; | ||
87 | u8 hdmi_vic[64]; | ||
88 | struct mxc_hdmi_3d_format hdmi_3d_format[64]; | ||
89 | u16 hdmi_3d_mask_all; | ||
90 | u16 hdmi_3d_struct_all; | ||
91 | u32 vsd_max_tmdsclk_rate; | ||
92 | |||
93 | u8 max_channels; | ||
94 | u8 sample_sizes; | ||
95 | u8 sample_rates; | ||
96 | u8 speaker_alloc; | ||
97 | }; | ||
98 | |||
99 | int mxc_edid_var_to_vic(struct fb_var_screeninfo *var); | ||
100 | int mxc_edid_mode_to_vic(const struct fb_videomode *mode); | ||
101 | int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr, | ||
102 | unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi); | ||
103 | int mxc_edid_parse_ext_blk(unsigned char *edid, struct mxc_edid_cfg *cfg, | ||
104 | struct fb_monspecs *specs); | ||
105 | #endif | ||
diff --git a/include/video/mxc_hdmi.h b/include/video/mxc_hdmi.h new file mode 100644 index 000000000000..94f76380caf6 --- /dev/null +++ b/include/video/mxc_hdmi.h | |||
@@ -0,0 +1,1095 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
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 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MXC_HDMI_H__ | ||
22 | #define __MXC_HDMI_H__ | ||
23 | |||
24 | /* | ||
25 | * Hdmi controller registers | ||
26 | */ | ||
27 | |||
28 | /* Identification Registers */ | ||
29 | #define HDMI_DESIGN_ID 0x0000 | ||
30 | #define HDMI_REVISION_ID 0x0001 | ||
31 | #define HDMI_PRODUCT_ID0 0x0002 | ||
32 | #define HDMI_PRODUCT_ID1 0x0003 | ||
33 | #define HDMI_CONFIG0_ID 0x0004 | ||
34 | #define HDMI_CONFIG1_ID 0x0005 | ||
35 | #define HDMI_CONFIG2_ID 0x0006 | ||
36 | #define HDMI_CONFIG3_ID 0x0007 | ||
37 | |||
38 | /* Interrupt Registers */ | ||
39 | #define HDMI_IH_FC_STAT0 0x0100 | ||
40 | #define HDMI_IH_FC_STAT1 0x0101 | ||
41 | #define HDMI_IH_FC_STAT2 0x0102 | ||
42 | #define HDMI_IH_AS_STAT0 0x0103 | ||
43 | #define HDMI_IH_PHY_STAT0 0x0104 | ||
44 | #define HDMI_IH_I2CM_STAT0 0x0105 | ||
45 | #define HDMI_IH_CEC_STAT0 0x0106 | ||
46 | #define HDMI_IH_VP_STAT0 0x0107 | ||
47 | #define HDMI_IH_I2CMPHY_STAT0 0x0108 | ||
48 | #define HDMI_IH_AHBDMAAUD_STAT0 0x0109 | ||
49 | |||
50 | #define HDMI_IH_MUTE_FC_STAT0 0x0180 | ||
51 | #define HDMI_IH_MUTE_FC_STAT1 0x0181 | ||
52 | #define HDMI_IH_MUTE_FC_STAT2 0x0182 | ||
53 | #define HDMI_IH_MUTE_AS_STAT0 0x0183 | ||
54 | #define HDMI_IH_MUTE_PHY_STAT0 0x0184 | ||
55 | #define HDMI_IH_MUTE_I2CM_STAT0 0x0185 | ||
56 | #define HDMI_IH_MUTE_CEC_STAT0 0x0186 | ||
57 | #define HDMI_IH_MUTE_VP_STAT0 0x0187 | ||
58 | #define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188 | ||
59 | #define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189 | ||
60 | #define HDMI_IH_MUTE 0x01FF | ||
61 | |||
62 | /* Video Sample Registers */ | ||
63 | #define HDMI_TX_INVID0 0x0200 | ||
64 | #define HDMI_TX_INSTUFFING 0x0201 | ||
65 | #define HDMI_TX_GYDATA0 0x0202 | ||
66 | #define HDMI_TX_GYDATA1 0x0203 | ||
67 | #define HDMI_TX_RCRDATA0 0x0204 | ||
68 | #define HDMI_TX_RCRDATA1 0x0205 | ||
69 | #define HDMI_TX_BCBDATA0 0x0206 | ||
70 | #define HDMI_TX_BCBDATA1 0x0207 | ||
71 | |||
72 | /* Video Packetizer Registers */ | ||
73 | #define HDMI_VP_STATUS 0x0800 | ||
74 | #define HDMI_VP_PR_CD 0x0801 | ||
75 | #define HDMI_VP_STUFF 0x0802 | ||
76 | #define HDMI_VP_REMAP 0x0803 | ||
77 | #define HDMI_VP_CONF 0x0804 | ||
78 | #define HDMI_VP_STAT 0x0805 | ||
79 | #define HDMI_VP_INT 0x0806 | ||
80 | #define HDMI_VP_MASK 0x0807 | ||
81 | #define HDMI_VP_POL 0x0808 | ||
82 | |||
83 | /* Frame Composer Registers */ | ||
84 | #define HDMI_FC_INVIDCONF 0x1000 | ||
85 | #define HDMI_FC_INHACTV0 0x1001 | ||
86 | #define HDMI_FC_INHACTV1 0x1002 | ||
87 | #define HDMI_FC_INHBLANK0 0x1003 | ||
88 | #define HDMI_FC_INHBLANK1 0x1004 | ||
89 | #define HDMI_FC_INVACTV0 0x1005 | ||
90 | #define HDMI_FC_INVACTV1 0x1006 | ||
91 | #define HDMI_FC_INVBLANK 0x1007 | ||
92 | #define HDMI_FC_HSYNCINDELAY0 0x1008 | ||
93 | #define HDMI_FC_HSYNCINDELAY1 0x1009 | ||
94 | #define HDMI_FC_HSYNCINWIDTH0 0x100A | ||
95 | #define HDMI_FC_HSYNCINWIDTH1 0x100B | ||
96 | #define HDMI_FC_VSYNCINDELAY 0x100C | ||
97 | #define HDMI_FC_VSYNCINWIDTH 0x100D | ||
98 | #define HDMI_FC_INFREQ0 0x100E | ||
99 | #define HDMI_FC_INFREQ1 0x100F | ||
100 | #define HDMI_FC_INFREQ2 0x1010 | ||
101 | #define HDMI_FC_CTRLDUR 0x1011 | ||
102 | #define HDMI_FC_EXCTRLDUR 0x1012 | ||
103 | #define HDMI_FC_EXCTRLSPAC 0x1013 | ||
104 | #define HDMI_FC_CH0PREAM 0x1014 | ||
105 | #define HDMI_FC_CH1PREAM 0x1015 | ||
106 | #define HDMI_FC_CH2PREAM 0x1016 | ||
107 | #define HDMI_FC_AVICONF3 0x1017 | ||
108 | #define HDMI_FC_GCP 0x1018 | ||
109 | #define HDMI_FC_AVICONF0 0x1019 | ||
110 | #define HDMI_FC_AVICONF1 0x101A | ||
111 | #define HDMI_FC_AVICONF2 0x101B | ||
112 | #define HDMI_FC_AVIVID 0x101C | ||
113 | #define HDMI_FC_AVIETB0 0x101D | ||
114 | #define HDMI_FC_AVIETB1 0x101E | ||
115 | #define HDMI_FC_AVISBB0 0x101F | ||
116 | #define HDMI_FC_AVISBB1 0x1020 | ||
117 | #define HDMI_FC_AVIELB0 0x1021 | ||
118 | #define HDMI_FC_AVIELB1 0x1022 | ||
119 | #define HDMI_FC_AVISRB0 0x1023 | ||
120 | #define HDMI_FC_AVISRB1 0x1024 | ||
121 | #define HDMI_FC_AUDICONF0 0x1025 | ||
122 | #define HDMI_FC_AUDICONF1 0x1026 | ||
123 | #define HDMI_FC_AUDICONF2 0x1027 | ||
124 | #define HDMI_FC_AUDICONF3 0x1028 | ||
125 | #define HDMI_FC_VSDIEEEID0 0x1029 | ||
126 | #define HDMI_FC_VSDSIZE 0x102A | ||
127 | #define HDMI_FC_VSDIEEEID1 0x1030 | ||
128 | #define HDMI_FC_VSDIEEEID2 0x1031 | ||
129 | #define HDMI_FC_VSDPAYLOAD0 0x1032 | ||
130 | #define HDMI_FC_VSDPAYLOAD1 0x1033 | ||
131 | #define HDMI_FC_VSDPAYLOAD2 0x1034 | ||
132 | #define HDMI_FC_VSDPAYLOAD3 0x1035 | ||
133 | #define HDMI_FC_VSDPAYLOAD4 0x1036 | ||
134 | #define HDMI_FC_VSDPAYLOAD5 0x1037 | ||
135 | #define HDMI_FC_VSDPAYLOAD6 0x1038 | ||
136 | #define HDMI_FC_VSDPAYLOAD7 0x1039 | ||
137 | #define HDMI_FC_VSDPAYLOAD8 0x103A | ||
138 | #define HDMI_FC_VSDPAYLOAD9 0x103B | ||
139 | #define HDMI_FC_VSDPAYLOAD10 0x103C | ||
140 | #define HDMI_FC_VSDPAYLOAD11 0x103D | ||
141 | #define HDMI_FC_VSDPAYLOAD12 0x103E | ||
142 | #define HDMI_FC_VSDPAYLOAD13 0x103F | ||
143 | #define HDMI_FC_VSDPAYLOAD14 0x1040 | ||
144 | #define HDMI_FC_VSDPAYLOAD15 0x1041 | ||
145 | #define HDMI_FC_VSDPAYLOAD16 0x1042 | ||
146 | #define HDMI_FC_VSDPAYLOAD17 0x1043 | ||
147 | #define HDMI_FC_VSDPAYLOAD18 0x1044 | ||
148 | #define HDMI_FC_VSDPAYLOAD19 0x1045 | ||
149 | #define HDMI_FC_VSDPAYLOAD20 0x1046 | ||
150 | #define HDMI_FC_VSDPAYLOAD21 0x1047 | ||
151 | #define HDMI_FC_VSDPAYLOAD22 0x1048 | ||
152 | #define HDMI_FC_VSDPAYLOAD23 0x1049 | ||
153 | #define HDMI_FC_SPDVENDORNAME0 0x104A | ||
154 | #define HDMI_FC_SPDVENDORNAME1 0x104B | ||
155 | #define HDMI_FC_SPDVENDORNAME2 0x104C | ||
156 | #define HDMI_FC_SPDVENDORNAME3 0x104D | ||
157 | #define HDMI_FC_SPDVENDORNAME4 0x104E | ||
158 | #define HDMI_FC_SPDVENDORNAME5 0x104F | ||
159 | #define HDMI_FC_SPDVENDORNAME6 0x1050 | ||
160 | #define HDMI_FC_SPDVENDORNAME7 0x1051 | ||
161 | #define HDMI_FC_SDPPRODUCTNAME0 0x1052 | ||
162 | #define HDMI_FC_SDPPRODUCTNAME1 0x1053 | ||
163 | #define HDMI_FC_SDPPRODUCTNAME2 0x1054 | ||
164 | #define HDMI_FC_SDPPRODUCTNAME3 0x1055 | ||
165 | #define HDMI_FC_SDPPRODUCTNAME4 0x1056 | ||
166 | #define HDMI_FC_SDPPRODUCTNAME5 0x1057 | ||
167 | #define HDMI_FC_SDPPRODUCTNAME6 0x1058 | ||
168 | #define HDMI_FC_SDPPRODUCTNAME7 0x1059 | ||
169 | #define HDMI_FC_SDPPRODUCTNAME8 0x105A | ||
170 | #define HDMI_FC_SDPPRODUCTNAME9 0x105B | ||
171 | #define HDMI_FC_SDPPRODUCTNAME10 0x105C | ||
172 | #define HDMI_FC_SDPPRODUCTNAME11 0x105D | ||
173 | #define HDMI_FC_SDPPRODUCTNAME12 0x105E | ||
174 | #define HDMI_FC_SDPPRODUCTNAME13 0x105F | ||
175 | #define HDMI_FC_SDPPRODUCTNAME14 0x1060 | ||
176 | #define HDMI_FC_SPDPRODUCTNAME15 0x1061 | ||
177 | #define HDMI_FC_SPDDEVICEINF 0x1062 | ||
178 | #define HDMI_FC_AUDSCONF 0x1063 | ||
179 | #define HDMI_FC_AUDSSTAT 0x1064 | ||
180 | #define HDMI_FC_DATACH0FILL 0x1070 | ||
181 | #define HDMI_FC_DATACH1FILL 0x1071 | ||
182 | #define HDMI_FC_DATACH2FILL 0x1072 | ||
183 | #define HDMI_FC_CTRLQHIGH 0x1073 | ||
184 | #define HDMI_FC_CTRLQLOW 0x1074 | ||
185 | #define HDMI_FC_ACP0 0x1075 | ||
186 | #define HDMI_FC_ACP28 0x1076 | ||
187 | #define HDMI_FC_ACP27 0x1077 | ||
188 | #define HDMI_FC_ACP26 0x1078 | ||
189 | #define HDMI_FC_ACP25 0x1079 | ||
190 | #define HDMI_FC_ACP24 0x107A | ||
191 | #define HDMI_FC_ACP23 0x107B | ||
192 | #define HDMI_FC_ACP22 0x107C | ||
193 | #define HDMI_FC_ACP21 0x107D | ||
194 | #define HDMI_FC_ACP20 0x107E | ||
195 | #define HDMI_FC_ACP19 0x107F | ||
196 | #define HDMI_FC_ACP18 0x1080 | ||
197 | #define HDMI_FC_ACP17 0x1081 | ||
198 | #define HDMI_FC_ACP16 0x1082 | ||
199 | #define HDMI_FC_ACP15 0x1083 | ||
200 | #define HDMI_FC_ACP14 0x1084 | ||
201 | #define HDMI_FC_ACP13 0x1085 | ||
202 | #define HDMI_FC_ACP12 0x1086 | ||
203 | #define HDMI_FC_ACP11 0x1087 | ||
204 | #define HDMI_FC_ACP10 0x1088 | ||
205 | #define HDMI_FC_ACP9 0x1089 | ||
206 | #define HDMI_FC_ACP8 0x108A | ||
207 | #define HDMI_FC_ACP7 0x108B | ||
208 | #define HDMI_FC_ACP6 0x108C | ||
209 | #define HDMI_FC_ACP5 0x108D | ||
210 | #define HDMI_FC_ACP4 0x108E | ||
211 | #define HDMI_FC_ACP3 0x108F | ||
212 | #define HDMI_FC_ACP2 0x1090 | ||
213 | #define HDMI_FC_ACP1 0x1091 | ||
214 | #define HDMI_FC_ISCR1_0 0x1092 | ||
215 | #define HDMI_FC_ISCR1_16 0x1093 | ||
216 | #define HDMI_FC_ISCR1_15 0x1094 | ||
217 | #define HDMI_FC_ISCR1_14 0x1095 | ||
218 | #define HDMI_FC_ISCR1_13 0x1096 | ||
219 | #define HDMI_FC_ISCR1_12 0x1097 | ||
220 | #define HDMI_FC_ISCR1_11 0x1098 | ||
221 | #define HDMI_FC_ISCR1_10 0x1099 | ||
222 | #define HDMI_FC_ISCR1_9 0x109A | ||
223 | #define HDMI_FC_ISCR1_8 0x109B | ||
224 | #define HDMI_FC_ISCR1_7 0x109C | ||
225 | #define HDMI_FC_ISCR1_6 0x109D | ||
226 | #define HDMI_FC_ISCR1_5 0x109E | ||
227 | #define HDMI_FC_ISCR1_4 0x109F | ||
228 | #define HDMI_FC_ISCR1_3 0x10A0 | ||
229 | #define HDMI_FC_ISCR1_2 0x10A1 | ||
230 | #define HDMI_FC_ISCR1_1 0x10A2 | ||
231 | #define HDMI_FC_ISCR2_15 0x10A3 | ||
232 | #define HDMI_FC_ISCR2_14 0x10A4 | ||
233 | #define HDMI_FC_ISCR2_13 0x10A5 | ||
234 | #define HDMI_FC_ISCR2_12 0x10A6 | ||
235 | #define HDMI_FC_ISCR2_11 0x10A7 | ||
236 | #define HDMI_FC_ISCR2_10 0x10A8 | ||
237 | #define HDMI_FC_ISCR2_9 0x10A9 | ||
238 | #define HDMI_FC_ISCR2_8 0x10AA | ||
239 | #define HDMI_FC_ISCR2_7 0x10AB | ||
240 | #define HDMI_FC_ISCR2_6 0x10AC | ||
241 | #define HDMI_FC_ISCR2_5 0x10AD | ||
242 | #define HDMI_FC_ISCR2_4 0x10AE | ||
243 | #define HDMI_FC_ISCR2_3 0x10AF | ||
244 | #define HDMI_FC_ISCR2_2 0x10B0 | ||
245 | #define HDMI_FC_ISCR2_1 0x10B1 | ||
246 | #define HDMI_FC_ISCR2_0 0x10B2 | ||
247 | #define HDMI_FC_DATAUTO0 0x10B3 | ||
248 | #define HDMI_FC_DATAUTO1 0x10B4 | ||
249 | #define HDMI_FC_DATAUTO2 0x10B5 | ||
250 | #define HDMI_FC_DATMAN 0x10B6 | ||
251 | #define HDMI_FC_DATAUTO3 0x10B7 | ||
252 | #define HDMI_FC_RDRB0 0x10B8 | ||
253 | #define HDMI_FC_RDRB1 0x10B9 | ||
254 | #define HDMI_FC_RDRB2 0x10BA | ||
255 | #define HDMI_FC_RDRB3 0x10BB | ||
256 | #define HDMI_FC_RDRB4 0x10BC | ||
257 | #define HDMI_FC_RDRB5 0x10BD | ||
258 | #define HDMI_FC_RDRB6 0x10BE | ||
259 | #define HDMI_FC_RDRB7 0x10BF | ||
260 | #define HDMI_FC_STAT0 0x10D0 | ||
261 | #define HDMI_FC_INT0 0x10D1 | ||
262 | #define HDMI_FC_MASK0 0x10D2 | ||
263 | #define HDMI_FC_POL0 0x10D3 | ||
264 | #define HDMI_FC_STAT1 0x10D4 | ||
265 | #define HDMI_FC_INT1 0x10D5 | ||
266 | #define HDMI_FC_MASK1 0x10D6 | ||
267 | #define HDMI_FC_POL1 0x10D7 | ||
268 | #define HDMI_FC_STAT2 0x10D8 | ||
269 | #define HDMI_FC_INT2 0x10D9 | ||
270 | #define HDMI_FC_MASK2 0x10DA | ||
271 | #define HDMI_FC_POL2 0x10DB | ||
272 | #define HDMI_FC_PRCONF 0x10E0 | ||
273 | |||
274 | #define HDMI_FC_GMD_STAT 0x1100 | ||
275 | #define HDMI_FC_GMD_EN 0x1101 | ||
276 | #define HDMI_FC_GMD_UP 0x1102 | ||
277 | #define HDMI_FC_GMD_CONF 0x1103 | ||
278 | #define HDMI_FC_GMD_HB 0x1104 | ||
279 | #define HDMI_FC_GMD_PB0 0x1105 | ||
280 | #define HDMI_FC_GMD_PB1 0x1106 | ||
281 | #define HDMI_FC_GMD_PB2 0x1107 | ||
282 | #define HDMI_FC_GMD_PB3 0x1108 | ||
283 | #define HDMI_FC_GMD_PB4 0x1109 | ||
284 | #define HDMI_FC_GMD_PB5 0x110A | ||
285 | #define HDMI_FC_GMD_PB6 0x110B | ||
286 | #define HDMI_FC_GMD_PB7 0x110C | ||
287 | #define HDMI_FC_GMD_PB8 0x110D | ||
288 | #define HDMI_FC_GMD_PB9 0x110E | ||
289 | #define HDMI_FC_GMD_PB10 0x110F | ||
290 | #define HDMI_FC_GMD_PB11 0x1110 | ||
291 | #define HDMI_FC_GMD_PB12 0x1111 | ||
292 | #define HDMI_FC_GMD_PB13 0x1112 | ||
293 | #define HDMI_FC_GMD_PB14 0x1113 | ||
294 | #define HDMI_FC_GMD_PB15 0x1114 | ||
295 | #define HDMI_FC_GMD_PB16 0x1115 | ||
296 | #define HDMI_FC_GMD_PB17 0x1116 | ||
297 | #define HDMI_FC_GMD_PB18 0x1117 | ||
298 | #define HDMI_FC_GMD_PB19 0x1118 | ||
299 | #define HDMI_FC_GMD_PB20 0x1119 | ||
300 | #define HDMI_FC_GMD_PB21 0x111A | ||
301 | #define HDMI_FC_GMD_PB22 0x111B | ||
302 | #define HDMI_FC_GMD_PB23 0x111C | ||
303 | #define HDMI_FC_GMD_PB24 0x111D | ||
304 | #define HDMI_FC_GMD_PB25 0x111E | ||
305 | #define HDMI_FC_GMD_PB26 0x111F | ||
306 | #define HDMI_FC_GMD_PB27 0x1120 | ||
307 | |||
308 | #define HDMI_FC_DBGFORCE 0x1200 | ||
309 | #define HDMI_FC_DBGAUD0CH0 0x1201 | ||
310 | #define HDMI_FC_DBGAUD1CH0 0x1202 | ||
311 | #define HDMI_FC_DBGAUD2CH0 0x1203 | ||
312 | #define HDMI_FC_DBGAUD0CH1 0x1204 | ||
313 | #define HDMI_FC_DBGAUD1CH1 0x1205 | ||
314 | #define HDMI_FC_DBGAUD2CH1 0x1206 | ||
315 | #define HDMI_FC_DBGAUD0CH2 0x1207 | ||
316 | #define HDMI_FC_DBGAUD1CH2 0x1208 | ||
317 | #define HDMI_FC_DBGAUD2CH2 0x1209 | ||
318 | #define HDMI_FC_DBGAUD0CH3 0x120A | ||
319 | #define HDMI_FC_DBGAUD1CH3 0x120B | ||
320 | #define HDMI_FC_DBGAUD2CH3 0x120C | ||
321 | #define HDMI_FC_DBGAUD0CH4 0x120D | ||
322 | #define HDMI_FC_DBGAUD1CH4 0x120E | ||
323 | #define HDMI_FC_DBGAUD2CH4 0x120F | ||
324 | #define HDMI_FC_DBGAUD0CH5 0x1210 | ||
325 | #define HDMI_FC_DBGAUD1CH5 0x1211 | ||
326 | #define HDMI_FC_DBGAUD2CH5 0x1212 | ||
327 | #define HDMI_FC_DBGAUD0CH6 0x1213 | ||
328 | #define HDMI_FC_DBGAUD1CH6 0x1214 | ||
329 | #define HDMI_FC_DBGAUD2CH6 0x1215 | ||
330 | #define HDMI_FC_DBGAUD0CH7 0x1216 | ||
331 | #define HDMI_FC_DBGAUD1CH7 0x1217 | ||
332 | #define HDMI_FC_DBGAUD2CH7 0x1218 | ||
333 | #define HDMI_FC_DBGTMDS0 0x1219 | ||
334 | #define HDMI_FC_DBGTMDS1 0x121A | ||
335 | #define HDMI_FC_DBGTMDS2 0x121B | ||
336 | |||
337 | /* HDMI Source PHY Registers */ | ||
338 | #define HDMI_PHY_CONF0 0x3000 | ||
339 | #define HDMI_PHY_TST0 0x3001 | ||
340 | #define HDMI_PHY_TST1 0x3002 | ||
341 | #define HDMI_PHY_TST2 0x3003 | ||
342 | #define HDMI_PHY_STAT0 0x3004 | ||
343 | #define HDMI_PHY_INT0 0x3005 | ||
344 | #define HDMI_PHY_MASK0 0x3006 | ||
345 | #define HDMI_PHY_POL0 0x3007 | ||
346 | |||
347 | /* HDMI Master PHY Registers */ | ||
348 | #define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020 | ||
349 | #define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021 | ||
350 | #define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022 | ||
351 | #define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023 | ||
352 | #define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024 | ||
353 | #define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025 | ||
354 | #define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026 | ||
355 | #define HDMI_PHY_I2CM_INT_ADDR 0x3027 | ||
356 | #define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028 | ||
357 | #define HDMI_PHY_I2CM_DIV_ADDR 0x3029 | ||
358 | #define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a | ||
359 | #define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b | ||
360 | #define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c | ||
361 | #define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d | ||
362 | #define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e | ||
363 | #define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f | ||
364 | #define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030 | ||
365 | #define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031 | ||
366 | #define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032 | ||
367 | |||
368 | /* Audio Sampler Registers */ | ||
369 | #define HDMI_AUD_CONF0 0x3100 | ||
370 | #define HDMI_AUD_CONF1 0x3101 | ||
371 | #define HDMI_AUD_INT 0x3102 | ||
372 | #define HDMI_AUD_CONF2 0x3103 | ||
373 | #define HDMI_AUD_N1 0x3200 | ||
374 | #define HDMI_AUD_N2 0x3201 | ||
375 | #define HDMI_AUD_N3 0x3202 | ||
376 | #define HDMI_AUD_CTS1 0x3203 | ||
377 | #define HDMI_AUD_CTS2 0x3204 | ||
378 | #define HDMI_AUD_CTS3 0x3205 | ||
379 | #define HDMI_AUD_INPUTCLKFS 0x3206 | ||
380 | #define HDMI_AUD_SPDIFINT 0x3302 | ||
381 | #define HDMI_AUD_CONF0_HBR 0x3400 | ||
382 | #define HDMI_AUD_HBR_STATUS 0x3401 | ||
383 | #define HDMI_AUD_HBR_INT 0x3402 | ||
384 | #define HDMI_AUD_HBR_POL 0x3403 | ||
385 | #define HDMI_AUD_HBR_MASK 0x3404 | ||
386 | |||
387 | /* Generic Parallel Audio Interface Registers */ | ||
388 | /* Not used as GPAUD interface is not enabled in hw */ | ||
389 | #define HDMI_GP_CONF0 0x3500 | ||
390 | #define HDMI_GP_CONF1 0x3501 | ||
391 | #define HDMI_GP_CONF2 0x3502 | ||
392 | #define HDMI_GP_STAT 0x3503 | ||
393 | #define HDMI_GP_INT 0x3504 | ||
394 | #define HDMI_GP_MASK 0x3505 | ||
395 | #define HDMI_GP_POL 0x3506 | ||
396 | |||
397 | /* Audio DMA Registers */ | ||
398 | #define HDMI_AHB_DMA_CONF0 0x3600 | ||
399 | #define HDMI_AHB_DMA_START 0x3601 | ||
400 | #define HDMI_AHB_DMA_STOP 0x3602 | ||
401 | #define HDMI_AHB_DMA_THRSLD 0x3603 | ||
402 | #define HDMI_AHB_DMA_STRADDR0 0x3604 | ||
403 | #define HDMI_AHB_DMA_STRADDR1 0x3605 | ||
404 | #define HDMI_AHB_DMA_STRADDR2 0x3606 | ||
405 | #define HDMI_AHB_DMA_STRADDR3 0x3607 | ||
406 | #define HDMI_AHB_DMA_STPADDR0 0x3608 | ||
407 | #define HDMI_AHB_DMA_STPADDR1 0x3609 | ||
408 | #define HDMI_AHB_DMA_STPADDR2 0x360a | ||
409 | #define HDMI_AHB_DMA_STPADDR3 0x360b | ||
410 | #define HDMI_AHB_DMA_BSTADDR0 0x360c | ||
411 | #define HDMI_AHB_DMA_BSTADDR1 0x360d | ||
412 | #define HDMI_AHB_DMA_BSTADDR2 0x360e | ||
413 | #define HDMI_AHB_DMA_BSTADDR3 0x360f | ||
414 | #define HDMI_AHB_DMA_MBLENGTH0 0x3610 | ||
415 | #define HDMI_AHB_DMA_MBLENGTH1 0x3611 | ||
416 | #define HDMI_AHB_DMA_STAT 0x3612 | ||
417 | #define HDMI_AHB_DMA_INT 0x3613 | ||
418 | #define HDMI_AHB_DMA_MASK 0x3614 | ||
419 | #define HDMI_AHB_DMA_POL 0x3615 | ||
420 | #define HDMI_AHB_DMA_CONF1 0x3616 | ||
421 | #define HDMI_AHB_DMA_BUFFSTAT 0x3617 | ||
422 | #define HDMI_AHB_DMA_BUFFINT 0x3618 | ||
423 | #define HDMI_AHB_DMA_BUFFMASK 0x3619 | ||
424 | #define HDMI_AHB_DMA_BUFFPOL 0x361a | ||
425 | |||
426 | /* Main Controller Registers */ | ||
427 | #define HDMI_MC_SFRDIV 0x4000 | ||
428 | #define HDMI_MC_CLKDIS 0x4001 | ||
429 | #define HDMI_MC_SWRSTZ 0x4002 | ||
430 | #define HDMI_MC_OPCTRL 0x4003 | ||
431 | #define HDMI_MC_FLOWCTRL 0x4004 | ||
432 | #define HDMI_MC_PHYRSTZ 0x4005 | ||
433 | #define HDMI_MC_LOCKONCLOCK 0x4006 | ||
434 | #define HDMI_MC_HEACPHY_RST 0x4007 | ||
435 | |||
436 | /* Color Space Converter Registers */ | ||
437 | #define HDMI_CSC_CFG 0x4100 | ||
438 | #define HDMI_CSC_SCALE 0x4101 | ||
439 | #define HDMI_CSC_COEF_A1_MSB 0x4102 | ||
440 | #define HDMI_CSC_COEF_A1_LSB 0x4103 | ||
441 | #define HDMI_CSC_COEF_A2_MSB 0x4104 | ||
442 | #define HDMI_CSC_COEF_A2_LSB 0x4105 | ||
443 | #define HDMI_CSC_COEF_A3_MSB 0x4106 | ||
444 | #define HDMI_CSC_COEF_A3_LSB 0x4107 | ||
445 | #define HDMI_CSC_COEF_A4_MSB 0x4108 | ||
446 | #define HDMI_CSC_COEF_A4_LSB 0x4109 | ||
447 | #define HDMI_CSC_COEF_B1_MSB 0x410A | ||
448 | #define HDMI_CSC_COEF_B1_LSB 0x410B | ||
449 | #define HDMI_CSC_COEF_B2_MSB 0x410C | ||
450 | #define HDMI_CSC_COEF_B2_LSB 0x410D | ||
451 | #define HDMI_CSC_COEF_B3_MSB 0x410E | ||
452 | #define HDMI_CSC_COEF_B3_LSB 0x410F | ||
453 | #define HDMI_CSC_COEF_B4_MSB 0x4110 | ||
454 | #define HDMI_CSC_COEF_B4_LSB 0x4111 | ||
455 | #define HDMI_CSC_COEF_C1_MSB 0x4112 | ||
456 | #define HDMI_CSC_COEF_C1_LSB 0x4113 | ||
457 | #define HDMI_CSC_COEF_C2_MSB 0x4114 | ||
458 | #define HDMI_CSC_COEF_C2_LSB 0x4115 | ||
459 | #define HDMI_CSC_COEF_C3_MSB 0x4116 | ||
460 | #define HDMI_CSC_COEF_C3_LSB 0x4117 | ||
461 | #define HDMI_CSC_COEF_C4_MSB 0x4118 | ||
462 | #define HDMI_CSC_COEF_C4_LSB 0x4119 | ||
463 | |||
464 | /* HDCP Encryption Engine Registers */ | ||
465 | #define HDMI_A_HDCPCFG0 0x5000 | ||
466 | #define HDMI_A_HDCPCFG1 0x5001 | ||
467 | #define HDMI_A_HDCPOBS0 0x5002 | ||
468 | #define HDMI_A_HDCPOBS1 0x5003 | ||
469 | #define HDMI_A_HDCPOBS2 0x5004 | ||
470 | #define HDMI_A_HDCPOBS3 0x5005 | ||
471 | #define HDMI_A_APIINTCLR 0x5006 | ||
472 | #define HDMI_A_APIINTSTAT 0x5007 | ||
473 | #define HDMI_A_APIINTMSK 0x5008 | ||
474 | #define HDMI_A_VIDPOLCFG 0x5009 | ||
475 | #define HDMI_A_OESSWCFG 0x500A | ||
476 | #define HDMI_A_TIMER1SETUP0 0x500B | ||
477 | #define HDMI_A_TIMER1SETUP1 0x500C | ||
478 | #define HDMI_A_TIMER2SETUP0 0x500D | ||
479 | #define HDMI_A_TIMER2SETUP1 0x500E | ||
480 | #define HDMI_A_100MSCFG 0x500F | ||
481 | #define HDMI_A_2SCFG0 0x5010 | ||
482 | #define HDMI_A_2SCFG1 0x5011 | ||
483 | #define HDMI_A_5SCFG0 0x5012 | ||
484 | #define HDMI_A_5SCFG1 0x5013 | ||
485 | #define HDMI_A_SRMVERLSB 0x5014 | ||
486 | #define HDMI_A_SRMVERMSB 0x5015 | ||
487 | #define HDMI_A_SRMCTRL 0x5016 | ||
488 | #define HDMI_A_SFRSETUP 0x5017 | ||
489 | #define HDMI_A_I2CHSETUP 0x5018 | ||
490 | #define HDMI_A_INTSETUP 0x5019 | ||
491 | #define HDMI_A_PRESETUP 0x501A | ||
492 | #define HDMI_A_SRM_BASE 0x5020 | ||
493 | |||
494 | /* CEC Engine Registers */ | ||
495 | #define HDMI_CEC_CTRL 0x7D00 | ||
496 | #define HDMI_CEC_STAT 0x7D01 | ||
497 | #define HDMI_CEC_MASK 0x7D02 | ||
498 | #define HDMI_CEC_POLARITY 0x7D03 | ||
499 | #define HDMI_CEC_INT 0x7D04 | ||
500 | #define HDMI_CEC_ADDR_L 0x7D05 | ||
501 | #define HDMI_CEC_ADDR_H 0x7D06 | ||
502 | #define HDMI_CEC_TX_CNT 0x7D07 | ||
503 | #define HDMI_CEC_RX_CNT 0x7D08 | ||
504 | #define HDMI_CEC_TX_DATA0 0x7D10 | ||
505 | #define HDMI_CEC_TX_DATA1 0x7D11 | ||
506 | #define HDMI_CEC_TX_DATA2 0x7D12 | ||
507 | #define HDMI_CEC_TX_DATA3 0x7D13 | ||
508 | #define HDMI_CEC_TX_DATA4 0x7D14 | ||
509 | #define HDMI_CEC_TX_DATA5 0x7D15 | ||
510 | #define HDMI_CEC_TX_DATA6 0x7D16 | ||
511 | #define HDMI_CEC_TX_DATA7 0x7D17 | ||
512 | #define HDMI_CEC_TX_DATA8 0x7D18 | ||
513 | #define HDMI_CEC_TX_DATA9 0x7D19 | ||
514 | #define HDMI_CEC_TX_DATA10 0x7D1a | ||
515 | #define HDMI_CEC_TX_DATA11 0x7D1b | ||
516 | #define HDMI_CEC_TX_DATA12 0x7D1c | ||
517 | #define HDMI_CEC_TX_DATA13 0x7D1d | ||
518 | #define HDMI_CEC_TX_DATA14 0x7D1e | ||
519 | #define HDMI_CEC_TX_DATA15 0x7D1f | ||
520 | #define HDMI_CEC_RX_DATA0 0x7D20 | ||
521 | #define HDMI_CEC_RX_DATA1 0x7D21 | ||
522 | #define HDMI_CEC_RX_DATA2 0x7D22 | ||
523 | #define HDMI_CEC_RX_DATA3 0x7D23 | ||
524 | #define HDMI_CEC_RX_DATA4 0x7D24 | ||
525 | #define HDMI_CEC_RX_DATA5 0x7D25 | ||
526 | #define HDMI_CEC_RX_DATA6 0x7D26 | ||
527 | #define HDMI_CEC_RX_DATA7 0x7D27 | ||
528 | #define HDMI_CEC_RX_DATA8 0x7D28 | ||
529 | #define HDMI_CEC_RX_DATA9 0x7D29 | ||
530 | #define HDMI_CEC_RX_DATA10 0x7D2a | ||
531 | #define HDMI_CEC_RX_DATA11 0x7D2b | ||
532 | #define HDMI_CEC_RX_DATA12 0x7D2c | ||
533 | #define HDMI_CEC_RX_DATA13 0x7D2d | ||
534 | #define HDMI_CEC_RX_DATA14 0x7D2e | ||
535 | #define HDMI_CEC_RX_DATA15 0x7D2f | ||
536 | #define HDMI_CEC_LOCK 0x7D30 | ||
537 | #define HDMI_CEC_WKUPCTRL 0x7D31 | ||
538 | |||
539 | /* I2C Master Registers (E-DDC) */ | ||
540 | #define HDMI_I2CM_SLAVE 0x7E00 | ||
541 | #define HDMI_I2CM_ADDRESS 0x7E01 | ||
542 | #define HDMI_I2CM_DATAO 0x7E02 | ||
543 | #define HDMI_I2CM_DATAI 0x7E03 | ||
544 | #define HDMI_I2CM_OPERATION 0x7E04 | ||
545 | #define HDMI_I2CM_INT 0x7E05 | ||
546 | #define HDMI_I2CM_CTLINT 0x7E06 | ||
547 | #define HDMI_I2CM_DIV 0x7E07 | ||
548 | #define HDMI_I2CM_SEGADDR 0x7E08 | ||
549 | #define HDMI_I2CM_SOFTRSTZ 0x7E09 | ||
550 | #define HDMI_I2CM_SEGPTR 0x7E0A | ||
551 | #define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B | ||
552 | #define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C | ||
553 | #define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D | ||
554 | #define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E | ||
555 | #define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F | ||
556 | #define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10 | ||
557 | #define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11 | ||
558 | #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 | ||
559 | |||
560 | /* Random Number Generator Registers (RNG) */ | ||
561 | #define HDMI_RNG_BASE 0x8000 | ||
562 | |||
563 | |||
564 | /* | ||
565 | * Register field definitions | ||
566 | */ | ||
567 | enum { | ||
568 | /* IH_FC_INT2 field values */ | ||
569 | HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, | ||
570 | HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, | ||
571 | HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, | ||
572 | |||
573 | /* IH_FC_STAT2 field values */ | ||
574 | HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03, | ||
575 | HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, | ||
576 | HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, | ||
577 | |||
578 | /* IH_PHY_STAT0 field values */ | ||
579 | HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20, | ||
580 | HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10, | ||
581 | HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8, | ||
582 | HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4, | ||
583 | HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2, | ||
584 | HDMI_IH_PHY_STAT0_HPD = 0x1, | ||
585 | |||
586 | /* IH_CEC_STAT0 field values */ | ||
587 | HDMI_IH_CEC_STAT0_WAKEUP = 0x40, | ||
588 | HDMI_IH_CEC_STAT0_ERROR_FOLL = 0x20, | ||
589 | HDMI_IH_CEC_STAT0_ERROR_INIT = 0x10, | ||
590 | HDMI_IH_CEC_STAT0_ARB_LOST = 0x8, | ||
591 | HDMI_IH_CEC_STAT0_NACK = 0x4, | ||
592 | HDMI_IH_CEC_STAT0_EOM = 0x2, | ||
593 | HDMI_IH_CEC_STAT0_DONE = 0x1, | ||
594 | |||
595 | |||
596 | /* IH_MUTE_I2CMPHY_STAT0 field values */ | ||
597 | HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2, | ||
598 | HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1, | ||
599 | |||
600 | /* IH_PHY_STAT0 field values */ | ||
601 | HDMI_IH_MUTE_PHY_STAT0_RX_SENSE3 = 0x20, | ||
602 | HDMI_IH_MUTE_PHY_STAT0_RX_SENSE2 = 0x10, | ||
603 | HDMI_IH_MUTE_PHY_STAT0_RX_SENSE1 = 0x8, | ||
604 | HDMI_IH_MUTE_PHY_STAT0_RX_SENSE0 = 0x4, | ||
605 | HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2, | ||
606 | HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1, | ||
607 | |||
608 | /* IH_AHBDMAAUD_STAT0 field values */ | ||
609 | HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20, | ||
610 | HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10, | ||
611 | HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08, | ||
612 | HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04, | ||
613 | HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02, | ||
614 | HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, | ||
615 | |||
616 | /* IH_MUTE_FC_STAT2 field values */ | ||
617 | HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03, | ||
618 | HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, | ||
619 | HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, | ||
620 | |||
621 | /* IH_MUTE_AHBDMAAUD_STAT0 field values */ | ||
622 | HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20, | ||
623 | HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10, | ||
624 | HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08, | ||
625 | HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04, | ||
626 | HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02, | ||
627 | HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, | ||
628 | |||
629 | /* IH_MUTE field values */ | ||
630 | HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2, | ||
631 | HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1, | ||
632 | |||
633 | /* TX_INVID0 field values */ | ||
634 | HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80, | ||
635 | HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80, | ||
636 | HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00, | ||
637 | HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F, | ||
638 | HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0, | ||
639 | |||
640 | /* TX_INSTUFFING field values */ | ||
641 | HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4, | ||
642 | HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4, | ||
643 | HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0, | ||
644 | HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2, | ||
645 | HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2, | ||
646 | HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0, | ||
647 | HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1, | ||
648 | HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1, | ||
649 | HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0, | ||
650 | |||
651 | /* VP_PR_CD field values */ | ||
652 | HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0, | ||
653 | HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4, | ||
654 | HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F, | ||
655 | HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0, | ||
656 | |||
657 | /* VP_STUFF field values */ | ||
658 | HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20, | ||
659 | HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5, | ||
660 | HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10, | ||
661 | HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4, | ||
662 | HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8, | ||
663 | HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3, | ||
664 | HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4, | ||
665 | HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4, | ||
666 | HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0, | ||
667 | HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2, | ||
668 | HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2, | ||
669 | HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0, | ||
670 | HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1, | ||
671 | HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1, | ||
672 | HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0, | ||
673 | |||
674 | /* VP_CONF field values */ | ||
675 | HDMI_VP_CONF_BYPASS_EN_MASK = 0x40, | ||
676 | HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40, | ||
677 | HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00, | ||
678 | HDMI_VP_CONF_PP_EN_ENMASK = 0x20, | ||
679 | HDMI_VP_CONF_PP_EN_ENABLE = 0x20, | ||
680 | HDMI_VP_CONF_PP_EN_DISABLE = 0x00, | ||
681 | HDMI_VP_CONF_PR_EN_MASK = 0x10, | ||
682 | HDMI_VP_CONF_PR_EN_ENABLE = 0x10, | ||
683 | HDMI_VP_CONF_PR_EN_DISABLE = 0x00, | ||
684 | HDMI_VP_CONF_YCC422_EN_MASK = 0x8, | ||
685 | HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8, | ||
686 | HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0, | ||
687 | HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4, | ||
688 | HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4, | ||
689 | HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0, | ||
690 | HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3, | ||
691 | HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3, | ||
692 | HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1, | ||
693 | HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0, | ||
694 | |||
695 | /* VP_REMAP field values */ | ||
696 | HDMI_VP_REMAP_MASK = 0x3, | ||
697 | HDMI_VP_REMAP_YCC422_24bit = 0x2, | ||
698 | HDMI_VP_REMAP_YCC422_20bit = 0x1, | ||
699 | HDMI_VP_REMAP_YCC422_16bit = 0x0, | ||
700 | |||
701 | /* FC_INVIDCONF field values */ | ||
702 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80, | ||
703 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80, | ||
704 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00, | ||
705 | HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40, | ||
706 | HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40, | ||
707 | HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, | ||
708 | HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20, | ||
709 | HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20, | ||
710 | HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, | ||
711 | HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10, | ||
712 | HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10, | ||
713 | HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00, | ||
714 | HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8, | ||
715 | HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8, | ||
716 | HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0, | ||
717 | HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2, | ||
718 | HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2, | ||
719 | HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0, | ||
720 | HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1, | ||
721 | HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1, | ||
722 | HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0, | ||
723 | |||
724 | /* FC_AUDICONF0 field values */ | ||
725 | HDMI_FC_AUDICONF0_CC_OFFSET = 4, | ||
726 | HDMI_FC_AUDICONF0_CC_MASK = 0x70, | ||
727 | HDMI_FC_AUDICONF0_CT_OFFSET = 0, | ||
728 | HDMI_FC_AUDICONF0_CT_MASK = 0xF, | ||
729 | |||
730 | /* FC_AUDICONF1 field values */ | ||
731 | HDMI_FC_AUDICONF1_SS_OFFSET = 3, | ||
732 | HDMI_FC_AUDICONF1_SS_MASK = 0x18, | ||
733 | HDMI_FC_AUDICONF1_SF_OFFSET = 0, | ||
734 | HDMI_FC_AUDICONF1_SF_MASK = 0x7, | ||
735 | |||
736 | /* FC_AUDICONF3 field values */ | ||
737 | HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5, | ||
738 | HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60, | ||
739 | HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4, | ||
740 | HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10, | ||
741 | HDMI_FC_AUDICONF3_LSV_OFFSET = 0, | ||
742 | HDMI_FC_AUDICONF3_LSV_MASK = 0xF, | ||
743 | |||
744 | /* FC_AUDSCHNLS0 field values */ | ||
745 | HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4, | ||
746 | HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30, | ||
747 | HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0, | ||
748 | HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01, | ||
749 | |||
750 | /* FC_AUDSCHNLS3-6 field values */ | ||
751 | HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0, | ||
752 | HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f, | ||
753 | HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4, | ||
754 | HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0, | ||
755 | HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0, | ||
756 | HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f, | ||
757 | HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4, | ||
758 | HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0, | ||
759 | |||
760 | HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0, | ||
761 | HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f, | ||
762 | HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4, | ||
763 | HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0, | ||
764 | HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0, | ||
765 | HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f, | ||
766 | HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4, | ||
767 | HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0, | ||
768 | |||
769 | /* HDMI_FC_AUDSCHNLS7 field values */ | ||
770 | HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4, | ||
771 | HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30, | ||
772 | |||
773 | /* HDMI_FC_AUDSCHNLS8 field values */ | ||
774 | HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0, | ||
775 | HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4, | ||
776 | HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f, | ||
777 | HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0, | ||
778 | |||
779 | /* FC_AUDSCONF field values */ | ||
780 | HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0, | ||
781 | HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4, | ||
782 | HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1, | ||
783 | HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0, | ||
784 | HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1, | ||
785 | HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0, | ||
786 | |||
787 | /* FC_STAT2 field values */ | ||
788 | HDMI_FC_STAT2_OVERFLOW_MASK = 0x03, | ||
789 | HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, | ||
790 | HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, | ||
791 | |||
792 | /* FC_INT2 field values */ | ||
793 | HDMI_FC_INT2_OVERFLOW_MASK = 0x03, | ||
794 | HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, | ||
795 | HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, | ||
796 | |||
797 | /* FC_MASK2 field values */ | ||
798 | HDMI_FC_MASK2_OVERFLOW_MASK = 0x03, | ||
799 | HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02, | ||
800 | HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01, | ||
801 | |||
802 | /* FC_PRCONF field values */ | ||
803 | HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0, | ||
804 | HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4, | ||
805 | HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F, | ||
806 | HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0, | ||
807 | |||
808 | /* FC_AVICONF0-FC_AVICONF3 field values */ | ||
809 | HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03, | ||
810 | HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00, | ||
811 | HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01, | ||
812 | HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02, | ||
813 | HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40, | ||
814 | HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40, | ||
815 | HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00, | ||
816 | HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C, | ||
817 | HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00, | ||
818 | HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04, | ||
819 | HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08, | ||
820 | HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C, | ||
821 | HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30, | ||
822 | HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10, | ||
823 | HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20, | ||
824 | HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00, | ||
825 | |||
826 | HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F, | ||
827 | HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08, | ||
828 | HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09, | ||
829 | HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A, | ||
830 | HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B, | ||
831 | HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30, | ||
832 | HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00, | ||
833 | HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10, | ||
834 | HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20, | ||
835 | HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0, | ||
836 | HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00, | ||
837 | HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40, | ||
838 | HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80, | ||
839 | HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0, | ||
840 | |||
841 | HDMI_FC_AVICONF2_SCALING_MASK = 0x03, | ||
842 | HDMI_FC_AVICONF2_SCALING_NONE = 0x00, | ||
843 | HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01, | ||
844 | HDMI_FC_AVICONF2_SCALING_VERT = 0x02, | ||
845 | HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03, | ||
846 | HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C, | ||
847 | HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00, | ||
848 | HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04, | ||
849 | HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08, | ||
850 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70, | ||
851 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00, | ||
852 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10, | ||
853 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20, | ||
854 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30, | ||
855 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40, | ||
856 | HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80, | ||
857 | HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00, | ||
858 | HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80, | ||
859 | |||
860 | HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03, | ||
861 | HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00, | ||
862 | HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01, | ||
863 | HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02, | ||
864 | HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03, | ||
865 | HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C, | ||
866 | HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00, | ||
867 | HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04, | ||
868 | |||
869 | /* FC_DBGFORCE field values */ | ||
870 | HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, | ||
871 | HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, | ||
872 | |||
873 | /* PHY_CONF0 field values */ | ||
874 | HDMI_PHY_CONF0_PDZ_MASK = 0x80, | ||
875 | HDMI_PHY_CONF0_PDZ_OFFSET = 7, | ||
876 | HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, | ||
877 | HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, | ||
878 | HDMI_PHY_CONF0_SPARECTRL = 0x20, | ||
879 | HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, | ||
880 | HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, | ||
881 | HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, | ||
882 | HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3, | ||
883 | HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4, | ||
884 | HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2, | ||
885 | HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2, | ||
886 | HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1, | ||
887 | HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1, | ||
888 | HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0, | ||
889 | |||
890 | /* PHY_TST0 field values */ | ||
891 | HDMI_PHY_TST0_TSTCLR_MASK = 0x20, | ||
892 | HDMI_PHY_TST0_TSTCLR_OFFSET = 5, | ||
893 | HDMI_PHY_TST0_TSTEN_MASK = 0x10, | ||
894 | HDMI_PHY_TST0_TSTEN_OFFSET = 4, | ||
895 | HDMI_PHY_TST0_TSTCLK_MASK = 0x1, | ||
896 | HDMI_PHY_TST0_TSTCLK_OFFSET = 0, | ||
897 | |||
898 | /* PHY_STAT0 field values */ | ||
899 | HDMI_PHY_RX_SENSE3 = 0x80, | ||
900 | HDMI_PHY_RX_SENSE2 = 0x40, | ||
901 | HDMI_PHY_RX_SENSE1 = 0x20, | ||
902 | HDMI_PHY_RX_SENSE0 = 0x10, | ||
903 | HDMI_PHY_HPD = 0x02, | ||
904 | HDMI_PHY_TX_PHY_LOCK = 0x01, | ||
905 | |||
906 | /* PHY_I2CM_SLAVE_ADDR field values */ | ||
907 | HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69, | ||
908 | HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49, | ||
909 | |||
910 | /* PHY_I2CM_OPERATION_ADDR field values */ | ||
911 | HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10, | ||
912 | HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1, | ||
913 | |||
914 | /* HDMI_PHY_I2CM_INT_ADDR */ | ||
915 | HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08, | ||
916 | HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04, | ||
917 | |||
918 | /* HDMI_PHY_I2CM_CTLINT_ADDR */ | ||
919 | HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80, | ||
920 | HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40, | ||
921 | HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08, | ||
922 | HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04, | ||
923 | |||
924 | /* AUD_CTS3 field values */ | ||
925 | HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5, | ||
926 | HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0, | ||
927 | HDMI_AUD_CTS3_N_SHIFT_1 = 0, | ||
928 | HDMI_AUD_CTS3_N_SHIFT_16 = 0x20, | ||
929 | HDMI_AUD_CTS3_N_SHIFT_32 = 0x40, | ||
930 | HDMI_AUD_CTS3_N_SHIFT_64 = 0x60, | ||
931 | HDMI_AUD_CTS3_N_SHIFT_128 = 0x80, | ||
932 | HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0, | ||
933 | /* note that the CTS3 MANUAL bit has been removed | ||
934 | from our part. Can't set it, will read as 0. */ | ||
935 | HDMI_AUD_CTS3_CTS_MANUAL = 0x10, | ||
936 | HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f, | ||
937 | |||
938 | /* AHB_DMA_CONF0 field values */ | ||
939 | HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7, | ||
940 | HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80, | ||
941 | HDMI_AHB_DMA_CONF0_HBR = 0x10, | ||
942 | HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3, | ||
943 | HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08, | ||
944 | HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1, | ||
945 | HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06, | ||
946 | HDMI_AHB_DMA_CONF0_INCR4 = 0x0, | ||
947 | HDMI_AHB_DMA_CONF0_INCR8 = 0x2, | ||
948 | HDMI_AHB_DMA_CONF0_INCR16 = 0x4, | ||
949 | HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1, | ||
950 | |||
951 | /* HDMI_AHB_DMA_START field values */ | ||
952 | HDMI_AHB_DMA_START_START_OFFSET = 0, | ||
953 | HDMI_AHB_DMA_START_START_MASK = 0x01, | ||
954 | |||
955 | /* HDMI_AHB_DMA_STOP field values */ | ||
956 | HDMI_AHB_DMA_STOP_STOP_OFFSET = 0, | ||
957 | HDMI_AHB_DMA_STOP_STOP_MASK = 0x01, | ||
958 | |||
959 | /* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */ | ||
960 | HDMI_AHB_DMA_DONE = 0x80, | ||
961 | HDMI_AHB_DMA_RETRY_SPLIT = 0x40, | ||
962 | HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20, | ||
963 | HDMI_AHB_DMA_ERROR = 0x10, | ||
964 | HDMI_AHB_DMA_FIFO_THREMPTY = 0x04, | ||
965 | HDMI_AHB_DMA_FIFO_FULL = 0x02, | ||
966 | HDMI_AHB_DMA_FIFO_EMPTY = 0x01, | ||
967 | |||
968 | /* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT, AHB_DMA_BUFFMASK, AHB_DMA_BUFFPOL field values */ | ||
969 | HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02, | ||
970 | HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01, | ||
971 | |||
972 | /* MC_CLKDIS field values */ | ||
973 | HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40, | ||
974 | HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20, | ||
975 | HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10, | ||
976 | HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8, | ||
977 | HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4, | ||
978 | HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2, | ||
979 | HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1, | ||
980 | |||
981 | /* MC_SWRSTZ field values */ | ||
982 | HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02, | ||
983 | |||
984 | /* MC_FLOWCTRL field values */ | ||
985 | HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1, | ||
986 | HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1, | ||
987 | HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, | ||
988 | |||
989 | /* MC_PHYRSTZ field values */ | ||
990 | HDMI_MC_PHYRSTZ_ASSERT = 0x0, | ||
991 | HDMI_MC_PHYRSTZ_DEASSERT = 0x1, | ||
992 | |||
993 | /* MC_HEACPHY_RST field values */ | ||
994 | HDMI_MC_HEACPHY_RST_ASSERT = 0x1, | ||
995 | HDMI_MC_HEACPHY_RST_DEASSERT = 0x0, | ||
996 | |||
997 | /* CSC_CFG field values */ | ||
998 | HDMI_CSC_CFG_INTMODE_MASK = 0x30, | ||
999 | HDMI_CSC_CFG_INTMODE_OFFSET = 4, | ||
1000 | HDMI_CSC_CFG_INTMODE_DISABLE = 0x00, | ||
1001 | HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10, | ||
1002 | HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20, | ||
1003 | HDMI_CSC_CFG_DECMODE_MASK = 0x3, | ||
1004 | HDMI_CSC_CFG_DECMODE_OFFSET = 0, | ||
1005 | HDMI_CSC_CFG_DECMODE_DISABLE = 0x0, | ||
1006 | HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1, | ||
1007 | HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2, | ||
1008 | HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3, | ||
1009 | |||
1010 | /* CSC_SCALE field values */ | ||
1011 | HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0, | ||
1012 | HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00, | ||
1013 | HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50, | ||
1014 | HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60, | ||
1015 | HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70, | ||
1016 | HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03, | ||
1017 | |||
1018 | /* A_HDCPCFG0 field values */ | ||
1019 | HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80, | ||
1020 | HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80, | ||
1021 | HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00, | ||
1022 | HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40, | ||
1023 | HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40, | ||
1024 | HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00, | ||
1025 | HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20, | ||
1026 | HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20, | ||
1027 | HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00, | ||
1028 | HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10, | ||
1029 | HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10, | ||
1030 | HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00, | ||
1031 | HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8, | ||
1032 | HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8, | ||
1033 | HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0, | ||
1034 | HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4, | ||
1035 | HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4, | ||
1036 | HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0, | ||
1037 | HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2, | ||
1038 | HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2, | ||
1039 | HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0, | ||
1040 | HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1, | ||
1041 | HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1, | ||
1042 | HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0, | ||
1043 | |||
1044 | /* A_HDCPCFG1 field values */ | ||
1045 | HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8, | ||
1046 | HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8, | ||
1047 | HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0, | ||
1048 | HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4, | ||
1049 | HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4, | ||
1050 | HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0, | ||
1051 | HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2, | ||
1052 | HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2, | ||
1053 | HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0, | ||
1054 | HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1, | ||
1055 | HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0, | ||
1056 | |||
1057 | /* A_VIDPOLCFG field values */ | ||
1058 | HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60, | ||
1059 | HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5, | ||
1060 | HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10, | ||
1061 | HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10, | ||
1062 | HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0, | ||
1063 | HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8, | ||
1064 | HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8, | ||
1065 | HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0, | ||
1066 | HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2, | ||
1067 | HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2, | ||
1068 | HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0, | ||
1069 | |||
1070 | |||
1071 | /* I2CM_OPERATION field values */ | ||
1072 | HDMI_I2CM_OPERATION_WRITE = 0x10, | ||
1073 | HDMI_I2CM_OPERATION_READ_EXT = 0x2, | ||
1074 | HDMI_I2CM_OPERATION_READ = 0x1, | ||
1075 | |||
1076 | /* HDMI_I2CM_INT */ | ||
1077 | HDMI_I2CM_INT_DONE_POL = 0x08, | ||
1078 | HDMI_I2CM_INT_DONE_MASK = 0x04, | ||
1079 | |||
1080 | /* HDMI_I2CM_CTLINT */ | ||
1081 | HDMI_I2CM_CTLINT_NAC_POL = 0x80, | ||
1082 | HDMI_I2CM_CTLINT_NAC_MASK = 0x40, | ||
1083 | HDMI_I2CM_CTLINT_ARBITRATION_POL = 0x08, | ||
1084 | HDMI_I2CM_CTLINT_ARBITRATION_MASK = 0x04, | ||
1085 | |||
1086 | }; | ||
1087 | |||
1088 | /* IOCTL commands */ | ||
1089 | #define HDMI_IOC_MAGIC 'H' | ||
1090 | |||
1091 | #define HDMI_IOC_GET_RESOURCE _IO(HDMI_IOC_MAGIC, 0) | ||
1092 | #define HDMI_IOC_GET_CPU_TYPE _IO(HDMI_IOC_MAGIC, 1) | ||
1093 | |||
1094 | |||
1095 | #endif /* __MXC_HDMI_H__ */ | ||