diff options
author | Archit Taneja <archit@ti.com> | 2013-09-17 02:13:15 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2013-10-09 05:42:37 -0400 |
commit | 08d83e4e172176f8a66697ffb26eaa5ac5c2ef03 (patch) | |
tree | 700c97cdcc56188e8aa1c0aca2b7663f2100ba3d /drivers/video/omap2 | |
parent | c8a0d959b776f6799b995941ee0c2f8c67110fe8 (diff) |
omapdss: HDMI: move common functions to a separate file
The OMAP4 HDMI encoder driver(hdmi4.c) contains timings tables, and helper
functions which can be used as is by the OMAP5/DRA7x encoder driver. Move these
to hdmi_common.c so that it's not replicated in the future.
Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/dss/Makefile | 4 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi.h | 11 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi4.c | 438 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi4_core.c | 4 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi4_core.h | 2 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi_common.c | 423 |
6 files changed, 447 insertions, 435 deletions
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index f87ca3216a1f..d3aa91bdd6a8 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile | |||
@@ -10,6 +10,6 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o | |||
10 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o | 10 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o |
11 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o | 11 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o |
12 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o | 12 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o |
13 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi_wp.o hdmi_pll.o hdmi_phy.o \ | 13 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi_common.o hdmi_wp.o hdmi_pll.o \ |
14 | hdmi4_core.o | 14 | hdmi_phy.o hdmi4_core.o |
15 | ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG | 15 | ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG |
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h index b92d981063dc..b0493768a5d7 100644 --- a/drivers/video/omap2/dss/hdmi.h +++ b/drivers/video/omap2/dss/hdmi.h | |||
@@ -423,13 +423,22 @@ void hdmi_phy_disable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp); | |||
423 | void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s); | 423 | void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s); |
424 | int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy); | 424 | int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy); |
425 | 425 | ||
426 | /* HDMI common funcs */ | ||
427 | const struct hdmi_config *hdmi_default_timing(void); | ||
428 | const struct hdmi_config *hdmi_get_timings(int mode, int code); | ||
429 | struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing); | ||
430 | |||
426 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | 431 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
427 | int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); | 432 | int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts); |
428 | int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); | 433 | int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); |
429 | int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); | 434 | int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); |
430 | void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, | 435 | void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, |
431 | struct hdmi_audio_format *aud_fmt); | 436 | struct hdmi_audio_format *aud_fmt); |
432 | void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, | 437 | void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, |
433 | struct hdmi_audio_dma *aud_dma); | 438 | struct hdmi_audio_dma *aud_dma); |
439 | static inline bool hdmi_mode_has_audio(int mode) | ||
440 | { | ||
441 | return mode == HDMI_HDMI ? true : false; | ||
442 | } | ||
434 | #endif | 443 | #endif |
435 | #endif | 444 | #endif |
diff --git a/drivers/video/omap2/dss/hdmi4.c b/drivers/video/omap2/dss/hdmi4.c index ab43069c10ed..e14009614338 100644 --- a/drivers/video/omap2/dss/hdmi4.c +++ b/drivers/video/omap2/dss/hdmi4.c | |||
@@ -57,237 +57,6 @@ static struct { | |||
57 | struct omap_dss_device output; | 57 | struct omap_dss_device output; |
58 | } hdmi; | 58 | } hdmi; |
59 | 59 | ||
60 | /* | ||
61 | * Logic for the below structure : | ||
62 | * user enters the CEA or VESA timings by specifying the HDMI/DVI code. | ||
63 | * There is a correspondence between CEA/VESA timing and code, please | ||
64 | * refer to section 6.3 in HDMI 1.3 specification for timing code. | ||
65 | * | ||
66 | * In the below structure, cea_vesa_timings corresponds to all OMAP4 | ||
67 | * supported CEA and VESA timing values.code_cea corresponds to the CEA | ||
68 | * code, It is used to get the timing from cea_vesa_timing array.Similarly | ||
69 | * with code_vesa. Code_index is used for back mapping, that is once EDID | ||
70 | * is read from the TV, EDID is parsed to find the timing values and then | ||
71 | * map it to corresponding CEA or VESA index. | ||
72 | */ | ||
73 | |||
74 | static const struct hdmi_config cea_timings[] = { | ||
75 | { | ||
76 | { 640, 480, 25200, 96, 16, 48, 2, 10, 33, | ||
77 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
78 | false, }, | ||
79 | { 1, HDMI_HDMI }, | ||
80 | }, | ||
81 | { | ||
82 | { 720, 480, 27027, 62, 16, 60, 6, 9, 30, | ||
83 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
84 | false, }, | ||
85 | { 2, HDMI_HDMI }, | ||
86 | }, | ||
87 | { | ||
88 | { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, | ||
89 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
90 | false, }, | ||
91 | { 4, HDMI_HDMI }, | ||
92 | }, | ||
93 | { | ||
94 | { 1920, 540, 74250, 44, 88, 148, 5, 2, 15, | ||
95 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
96 | true, }, | ||
97 | { 5, HDMI_HDMI }, | ||
98 | }, | ||
99 | { | ||
100 | { 1440, 240, 27027, 124, 38, 114, 3, 4, 15, | ||
101 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
102 | true, }, | ||
103 | { 6, HDMI_HDMI }, | ||
104 | }, | ||
105 | { | ||
106 | { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36, | ||
107 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
108 | false, }, | ||
109 | { 16, HDMI_HDMI }, | ||
110 | }, | ||
111 | { | ||
112 | { 720, 576, 27000, 64, 12, 68, 5, 5, 39, | ||
113 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
114 | false, }, | ||
115 | { 17, HDMI_HDMI }, | ||
116 | }, | ||
117 | { | ||
118 | { 1280, 720, 74250, 40, 440, 220, 5, 5, 20, | ||
119 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
120 | false, }, | ||
121 | { 19, HDMI_HDMI }, | ||
122 | }, | ||
123 | { | ||
124 | { 1920, 540, 74250, 44, 528, 148, 5, 2, 15, | ||
125 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
126 | true, }, | ||
127 | { 20, HDMI_HDMI }, | ||
128 | }, | ||
129 | { | ||
130 | { 1440, 288, 27000, 126, 24, 138, 3, 2, 19, | ||
131 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
132 | true, }, | ||
133 | { 21, HDMI_HDMI }, | ||
134 | }, | ||
135 | { | ||
136 | { 1440, 576, 54000, 128, 24, 136, 5, 5, 39, | ||
137 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
138 | false, }, | ||
139 | { 29, HDMI_HDMI }, | ||
140 | }, | ||
141 | { | ||
142 | { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36, | ||
143 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
144 | false, }, | ||
145 | { 31, HDMI_HDMI }, | ||
146 | }, | ||
147 | { | ||
148 | { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36, | ||
149 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
150 | false, }, | ||
151 | { 32, HDMI_HDMI }, | ||
152 | }, | ||
153 | { | ||
154 | { 2880, 480, 108108, 248, 64, 240, 6, 9, 30, | ||
155 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
156 | false, }, | ||
157 | { 35, HDMI_HDMI }, | ||
158 | }, | ||
159 | { | ||
160 | { 2880, 576, 108000, 256, 48, 272, 5, 5, 39, | ||
161 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
162 | false, }, | ||
163 | { 37, HDMI_HDMI }, | ||
164 | }, | ||
165 | }; | ||
166 | |||
167 | static const struct hdmi_config vesa_timings[] = { | ||
168 | /* VESA From Here */ | ||
169 | { | ||
170 | { 640, 480, 25175, 96, 16, 48, 2, 11, 31, | ||
171 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
172 | false, }, | ||
173 | { 4, HDMI_DVI }, | ||
174 | }, | ||
175 | { | ||
176 | { 800, 600, 40000, 128, 40, 88, 4, 1, 23, | ||
177 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
178 | false, }, | ||
179 | { 9, HDMI_DVI }, | ||
180 | }, | ||
181 | { | ||
182 | { 848, 480, 33750, 112, 16, 112, 8, 6, 23, | ||
183 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
184 | false, }, | ||
185 | { 0xE, HDMI_DVI }, | ||
186 | }, | ||
187 | { | ||
188 | { 1280, 768, 79500, 128, 64, 192, 7, 3, 20, | ||
189 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
190 | false, }, | ||
191 | { 0x17, HDMI_DVI }, | ||
192 | }, | ||
193 | { | ||
194 | { 1280, 800, 83500, 128, 72, 200, 6, 3, 22, | ||
195 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
196 | false, }, | ||
197 | { 0x1C, HDMI_DVI }, | ||
198 | }, | ||
199 | { | ||
200 | { 1360, 768, 85500, 112, 64, 256, 6, 3, 18, | ||
201 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
202 | false, }, | ||
203 | { 0x27, HDMI_DVI }, | ||
204 | }, | ||
205 | { | ||
206 | { 1280, 960, 108000, 112, 96, 312, 3, 1, 36, | ||
207 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
208 | false, }, | ||
209 | { 0x20, HDMI_DVI }, | ||
210 | }, | ||
211 | { | ||
212 | { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38, | ||
213 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
214 | false, }, | ||
215 | { 0x23, HDMI_DVI }, | ||
216 | }, | ||
217 | { | ||
218 | { 1024, 768, 65000, 136, 24, 160, 6, 3, 29, | ||
219 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
220 | false, }, | ||
221 | { 0x10, HDMI_DVI }, | ||
222 | }, | ||
223 | { | ||
224 | { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32, | ||
225 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
226 | false, }, | ||
227 | { 0x2A, HDMI_DVI }, | ||
228 | }, | ||
229 | { | ||
230 | { 1440, 900, 106500, 152, 80, 232, 6, 3, 25, | ||
231 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
232 | false, }, | ||
233 | { 0x2F, HDMI_DVI }, | ||
234 | }, | ||
235 | { | ||
236 | { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, | ||
237 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
238 | false, }, | ||
239 | { 0x3A, HDMI_DVI }, | ||
240 | }, | ||
241 | { | ||
242 | { 1366, 768, 85500, 143, 70, 213, 3, 3, 24, | ||
243 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
244 | false, }, | ||
245 | { 0x51, HDMI_DVI }, | ||
246 | }, | ||
247 | { | ||
248 | { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36, | ||
249 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
250 | false, }, | ||
251 | { 0x52, HDMI_DVI }, | ||
252 | }, | ||
253 | { | ||
254 | { 1280, 768, 68250, 32, 48, 80, 7, 3, 12, | ||
255 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
256 | false, }, | ||
257 | { 0x16, HDMI_DVI }, | ||
258 | }, | ||
259 | { | ||
260 | { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23, | ||
261 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
262 | false, }, | ||
263 | { 0x29, HDMI_DVI }, | ||
264 | }, | ||
265 | { | ||
266 | { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21, | ||
267 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
268 | false, }, | ||
269 | { 0x39, HDMI_DVI }, | ||
270 | }, | ||
271 | { | ||
272 | { 1280, 800, 79500, 32, 48, 80, 6, 3, 14, | ||
273 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
274 | false, }, | ||
275 | { 0x1B, HDMI_DVI }, | ||
276 | }, | ||
277 | { | ||
278 | { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, | ||
279 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
280 | false, }, | ||
281 | { 0x55, HDMI_DVI }, | ||
282 | }, | ||
283 | { | ||
284 | { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26, | ||
285 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
286 | false, }, | ||
287 | { 0x44, HDMI_DVI }, | ||
288 | }, | ||
289 | }; | ||
290 | |||
291 | static int hdmi_runtime_get(void) | 60 | static int hdmi_runtime_get(void) |
292 | { | 61 | { |
293 | int r; | 62 | int r; |
@@ -335,86 +104,6 @@ static int hdmi_init_regulator(void) | |||
335 | return 0; | 104 | return 0; |
336 | } | 105 | } |
337 | 106 | ||
338 | static const struct hdmi_config *hdmi_find_timing( | ||
339 | const struct hdmi_config *timings_arr, | ||
340 | int len) | ||
341 | { | ||
342 | int i; | ||
343 | |||
344 | for (i = 0; i < len; i++) { | ||
345 | if (timings_arr[i].cm.code == hdmi.cfg.cm.code) | ||
346 | return &timings_arr[i]; | ||
347 | } | ||
348 | return NULL; | ||
349 | } | ||
350 | |||
351 | static const struct hdmi_config *hdmi_get_timings(void) | ||
352 | { | ||
353 | const struct hdmi_config *arr; | ||
354 | int len; | ||
355 | |||
356 | if (hdmi.cfg.cm.mode == HDMI_DVI) { | ||
357 | arr = vesa_timings; | ||
358 | len = ARRAY_SIZE(vesa_timings); | ||
359 | } else { | ||
360 | arr = cea_timings; | ||
361 | len = ARRAY_SIZE(cea_timings); | ||
362 | } | ||
363 | |||
364 | return hdmi_find_timing(arr, len); | ||
365 | } | ||
366 | |||
367 | static bool hdmi_timings_compare(struct omap_video_timings *timing1, | ||
368 | const struct omap_video_timings *timing2) | ||
369 | { | ||
370 | int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; | ||
371 | |||
372 | if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) == | ||
373 | DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) && | ||
374 | (timing2->x_res == timing1->x_res) && | ||
375 | (timing2->y_res == timing1->y_res)) { | ||
376 | |||
377 | timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; | ||
378 | timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; | ||
379 | timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; | ||
380 | timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp; | ||
381 | |||
382 | DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ | ||
383 | "timing2_hsync = %d timing2_vsync = %d\n", | ||
384 | timing1_hsync, timing1_vsync, | ||
385 | timing2_hsync, timing2_vsync); | ||
386 | |||
387 | if ((timing1_hsync == timing2_hsync) && | ||
388 | (timing1_vsync == timing2_vsync)) { | ||
389 | return true; | ||
390 | } | ||
391 | } | ||
392 | return false; | ||
393 | } | ||
394 | |||
395 | static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) | ||
396 | { | ||
397 | int i; | ||
398 | struct hdmi_cm cm = {-1}; | ||
399 | DSSDBG("hdmi_get_code\n"); | ||
400 | |||
401 | for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { | ||
402 | if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { | ||
403 | cm = cea_timings[i].cm; | ||
404 | goto end; | ||
405 | } | ||
406 | } | ||
407 | for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { | ||
408 | if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { | ||
409 | cm = vesa_timings[i].cm; | ||
410 | goto end; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | end: return cm; | ||
415 | |||
416 | } | ||
417 | |||
418 | static int hdmi_power_on_core(struct omap_dss_device *dssdev) | 107 | static int hdmi_power_on_core(struct omap_dss_device *dssdev) |
419 | { | 108 | { |
420 | int r; | 109 | int r; |
@@ -550,7 +239,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev, | |||
550 | cm = hdmi_get_code(timings); | 239 | cm = hdmi_get_code(timings); |
551 | hdmi.cfg.cm = cm; | 240 | hdmi.cfg.cm = cm; |
552 | 241 | ||
553 | t = hdmi_get_timings(); | 242 | t = hdmi_get_timings(cm.mode, cm.code); |
554 | if (t != NULL) { | 243 | if (t != NULL) { |
555 | hdmi.cfg = *t; | 244 | hdmi.cfg = *t; |
556 | 245 | ||
@@ -564,10 +253,11 @@ static void hdmi_display_get_timings(struct omap_dss_device *dssdev, | |||
564 | struct omap_video_timings *timings) | 253 | struct omap_video_timings *timings) |
565 | { | 254 | { |
566 | const struct hdmi_config *cfg; | 255 | const struct hdmi_config *cfg; |
256 | struct hdmi_cm cm = hdmi.cfg.cm; | ||
567 | 257 | ||
568 | cfg = hdmi_get_timings(); | 258 | cfg = hdmi_get_timings(cm.mode, cm.code); |
569 | if (cfg == NULL) | 259 | if (cfg == NULL) |
570 | cfg = &vesa_timings[0]; | 260 | cfg = hdmi_default_timing(); |
571 | 261 | ||
572 | memcpy(timings, &cfg->timings, sizeof(cfg->timings)); | 262 | memcpy(timings, &cfg->timings, sizeof(cfg->timings)); |
573 | } | 263 | } |
@@ -695,117 +385,6 @@ static int hdmi_get_clocks(struct platform_device *pdev) | |||
695 | return 0; | 385 | return 0; |
696 | } | 386 | } |
697 | 387 | ||
698 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
699 | int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts) | ||
700 | { | ||
701 | u32 deep_color; | ||
702 | bool deep_color_correct = false; | ||
703 | u32 pclk = hdmi.cfg.timings.pixel_clock; | ||
704 | |||
705 | if (n == NULL || cts == NULL) | ||
706 | return -EINVAL; | ||
707 | |||
708 | /* TODO: When implemented, query deep color mode here. */ | ||
709 | deep_color = 100; | ||
710 | |||
711 | /* | ||
712 | * When using deep color, the default N value (as in the HDMI | ||
713 | * specification) yields to an non-integer CTS. Hence, we | ||
714 | * modify it while keeping the restrictions described in | ||
715 | * section 7.2.1 of the HDMI 1.4a specification. | ||
716 | */ | ||
717 | switch (sample_freq) { | ||
718 | case 32000: | ||
719 | case 48000: | ||
720 | case 96000: | ||
721 | case 192000: | ||
722 | if (deep_color == 125) | ||
723 | if (pclk == 27027 || pclk == 74250) | ||
724 | deep_color_correct = true; | ||
725 | if (deep_color == 150) | ||
726 | if (pclk == 27027) | ||
727 | deep_color_correct = true; | ||
728 | break; | ||
729 | case 44100: | ||
730 | case 88200: | ||
731 | case 176400: | ||
732 | if (deep_color == 125) | ||
733 | if (pclk == 27027) | ||
734 | deep_color_correct = true; | ||
735 | break; | ||
736 | default: | ||
737 | return -EINVAL; | ||
738 | } | ||
739 | |||
740 | if (deep_color_correct) { | ||
741 | switch (sample_freq) { | ||
742 | case 32000: | ||
743 | *n = 8192; | ||
744 | break; | ||
745 | case 44100: | ||
746 | *n = 12544; | ||
747 | break; | ||
748 | case 48000: | ||
749 | *n = 8192; | ||
750 | break; | ||
751 | case 88200: | ||
752 | *n = 25088; | ||
753 | break; | ||
754 | case 96000: | ||
755 | *n = 16384; | ||
756 | break; | ||
757 | case 176400: | ||
758 | *n = 50176; | ||
759 | break; | ||
760 | case 192000: | ||
761 | *n = 32768; | ||
762 | break; | ||
763 | default: | ||
764 | return -EINVAL; | ||
765 | } | ||
766 | } else { | ||
767 | switch (sample_freq) { | ||
768 | case 32000: | ||
769 | *n = 4096; | ||
770 | break; | ||
771 | case 44100: | ||
772 | *n = 6272; | ||
773 | break; | ||
774 | case 48000: | ||
775 | *n = 6144; | ||
776 | break; | ||
777 | case 88200: | ||
778 | *n = 12544; | ||
779 | break; | ||
780 | case 96000: | ||
781 | *n = 12288; | ||
782 | break; | ||
783 | case 176400: | ||
784 | *n = 25088; | ||
785 | break; | ||
786 | case 192000: | ||
787 | *n = 24576; | ||
788 | break; | ||
789 | default: | ||
790 | return -EINVAL; | ||
791 | } | ||
792 | } | ||
793 | /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ | ||
794 | *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); | ||
795 | |||
796 | return 0; | ||
797 | } | ||
798 | |||
799 | static bool hdmi_mode_has_audio(void) | ||
800 | { | ||
801 | if (hdmi.cfg.cm.mode == HDMI_HDMI) | ||
802 | return true; | ||
803 | else | ||
804 | return false; | ||
805 | } | ||
806 | |||
807 | #endif | ||
808 | |||
809 | static int hdmi_connect(struct omap_dss_device *dssdev, | 388 | static int hdmi_connect(struct omap_dss_device *dssdev, |
810 | struct omap_dss_device *dst) | 389 | struct omap_dss_device *dst) |
811 | { | 390 | { |
@@ -878,7 +457,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev) | |||
878 | 457 | ||
879 | mutex_lock(&hdmi.lock); | 458 | mutex_lock(&hdmi.lock); |
880 | 459 | ||
881 | if (!hdmi_mode_has_audio()) { | 460 | if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { |
882 | r = -EPERM; | 461 | r = -EPERM; |
883 | goto err; | 462 | goto err; |
884 | } | 463 | } |
@@ -916,7 +495,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev) | |||
916 | 495 | ||
917 | mutex_lock(&hdmi.lock); | 496 | mutex_lock(&hdmi.lock); |
918 | 497 | ||
919 | r = hdmi_mode_has_audio(); | 498 | r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); |
920 | 499 | ||
921 | mutex_unlock(&hdmi.lock); | 500 | mutex_unlock(&hdmi.lock); |
922 | return r; | 501 | return r; |
@@ -926,15 +505,16 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev, | |||
926 | struct omap_dss_audio *audio) | 505 | struct omap_dss_audio *audio) |
927 | { | 506 | { |
928 | int r; | 507 | int r; |
508 | u32 pclk = hdmi.cfg.timings.pixel_clock; | ||
929 | 509 | ||
930 | mutex_lock(&hdmi.lock); | 510 | mutex_lock(&hdmi.lock); |
931 | 511 | ||
932 | if (!hdmi_mode_has_audio()) { | 512 | if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { |
933 | r = -EPERM; | 513 | r = -EPERM; |
934 | goto err; | 514 | goto err; |
935 | } | 515 | } |
936 | 516 | ||
937 | r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, audio); | 517 | r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, audio, pclk); |
938 | if (r) | 518 | if (r) |
939 | goto err; | 519 | goto err; |
940 | 520 | ||
diff --git a/drivers/video/omap2/dss/hdmi4_core.c b/drivers/video/omap2/dss/hdmi4_core.c index 3f7fc572be10..5dd5e5489b41 100644 --- a/drivers/video/omap2/dss/hdmi4_core.c +++ b/drivers/video/omap2/dss/hdmi4_core.c | |||
@@ -789,7 +789,7 @@ static void hdmi_core_audio_infoframe_cfg(struct hdmi_core_data *core, | |||
789 | } | 789 | } |
790 | 790 | ||
791 | int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, | 791 | int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, |
792 | struct omap_dss_audio *audio) | 792 | struct omap_dss_audio *audio, u32 pclk) |
793 | { | 793 | { |
794 | struct hdmi_audio_format audio_format; | 794 | struct hdmi_audio_format audio_format; |
795 | struct hdmi_audio_dma audio_dma; | 795 | struct hdmi_audio_dma audio_dma; |
@@ -856,7 +856,7 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, | |||
856 | return -EINVAL; | 856 | return -EINVAL; |
857 | } | 857 | } |
858 | 858 | ||
859 | err = hdmi_compute_acr(fs_nr, &n, &cts); | 859 | err = hdmi_compute_acr(pclk, fs_nr, &n, &cts); |
860 | 860 | ||
861 | /* Audio clock regeneration settings */ | 861 | /* Audio clock regeneration settings */ |
862 | acore.n = n; | 862 | acore.n = n; |
diff --git a/drivers/video/omap2/dss/hdmi4_core.h b/drivers/video/omap2/dss/hdmi4_core.h index 1181b4c1a068..bb646896fa82 100644 --- a/drivers/video/omap2/dss/hdmi4_core.h +++ b/drivers/video/omap2/dss/hdmi4_core.h | |||
@@ -269,7 +269,7 @@ int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core); | |||
269 | int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp); | 269 | int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp); |
270 | void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp); | 270 | void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp); |
271 | int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, | 271 | int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, |
272 | struct omap_dss_audio *audio); | 272 | struct omap_dss_audio *audio, u32 pclk); |
273 | int hdmi4_audio_get_dma_port(u32 *offset, u32 *size); | 273 | int hdmi4_audio_get_dma_port(u32 *offset, u32 *size); |
274 | #endif | 274 | #endif |
275 | 275 | ||
diff --git a/drivers/video/omap2/dss/hdmi_common.c b/drivers/video/omap2/dss/hdmi_common.c new file mode 100644 index 000000000000..6f727c858857 --- /dev/null +++ b/drivers/video/omap2/dss/hdmi_common.c | |||
@@ -0,0 +1,423 @@ | |||
1 | |||
2 | /* | ||
3 | * Logic for the below structure : | ||
4 | * user enters the CEA or VESA timings by specifying the HDMI/DVI code. | ||
5 | * There is a correspondence between CEA/VESA timing and code, please | ||
6 | * refer to section 6.3 in HDMI 1.3 specification for timing code. | ||
7 | * | ||
8 | * In the below structure, cea_vesa_timings corresponds to all OMAP4 | ||
9 | * supported CEA and VESA timing values.code_cea corresponds to the CEA | ||
10 | * code, It is used to get the timing from cea_vesa_timing array.Similarly | ||
11 | * with code_vesa. Code_index is used for back mapping, that is once EDID | ||
12 | * is read from the TV, EDID is parsed to find the timing values and then | ||
13 | * map it to corresponding CEA or VESA index. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <video/omapdss.h> | ||
19 | |||
20 | #include "hdmi.h" | ||
21 | |||
22 | static const struct hdmi_config cea_timings[] = { | ||
23 | { | ||
24 | { 640, 480, 25200, 96, 16, 48, 2, 10, 33, | ||
25 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
26 | false, }, | ||
27 | { 1, HDMI_HDMI }, | ||
28 | }, | ||
29 | { | ||
30 | { 720, 480, 27027, 62, 16, 60, 6, 9, 30, | ||
31 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
32 | false, }, | ||
33 | { 2, HDMI_HDMI }, | ||
34 | }, | ||
35 | { | ||
36 | { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, | ||
37 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
38 | false, }, | ||
39 | { 4, HDMI_HDMI }, | ||
40 | }, | ||
41 | { | ||
42 | { 1920, 540, 74250, 44, 88, 148, 5, 2, 15, | ||
43 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
44 | true, }, | ||
45 | { 5, HDMI_HDMI }, | ||
46 | }, | ||
47 | { | ||
48 | { 1440, 240, 27027, 124, 38, 114, 3, 4, 15, | ||
49 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
50 | true, }, | ||
51 | { 6, HDMI_HDMI }, | ||
52 | }, | ||
53 | { | ||
54 | { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36, | ||
55 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
56 | false, }, | ||
57 | { 16, HDMI_HDMI }, | ||
58 | }, | ||
59 | { | ||
60 | { 720, 576, 27000, 64, 12, 68, 5, 5, 39, | ||
61 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
62 | false, }, | ||
63 | { 17, HDMI_HDMI }, | ||
64 | }, | ||
65 | { | ||
66 | { 1280, 720, 74250, 40, 440, 220, 5, 5, 20, | ||
67 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
68 | false, }, | ||
69 | { 19, HDMI_HDMI }, | ||
70 | }, | ||
71 | { | ||
72 | { 1920, 540, 74250, 44, 528, 148, 5, 2, 15, | ||
73 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
74 | true, }, | ||
75 | { 20, HDMI_HDMI }, | ||
76 | }, | ||
77 | { | ||
78 | { 1440, 288, 27000, 126, 24, 138, 3, 2, 19, | ||
79 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
80 | true, }, | ||
81 | { 21, HDMI_HDMI }, | ||
82 | }, | ||
83 | { | ||
84 | { 1440, 576, 54000, 128, 24, 136, 5, 5, 39, | ||
85 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
86 | false, }, | ||
87 | { 29, HDMI_HDMI }, | ||
88 | }, | ||
89 | { | ||
90 | { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36, | ||
91 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
92 | false, }, | ||
93 | { 31, HDMI_HDMI }, | ||
94 | }, | ||
95 | { | ||
96 | { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36, | ||
97 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
98 | false, }, | ||
99 | { 32, HDMI_HDMI }, | ||
100 | }, | ||
101 | { | ||
102 | { 2880, 480, 108108, 248, 64, 240, 6, 9, 30, | ||
103 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
104 | false, }, | ||
105 | { 35, HDMI_HDMI }, | ||
106 | }, | ||
107 | { | ||
108 | { 2880, 576, 108000, 256, 48, 272, 5, 5, 39, | ||
109 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
110 | false, }, | ||
111 | { 37, HDMI_HDMI }, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | static const struct hdmi_config vesa_timings[] = { | ||
116 | /* VESA From Here */ | ||
117 | { | ||
118 | { 640, 480, 25175, 96, 16, 48, 2, 11, 31, | ||
119 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
120 | false, }, | ||
121 | { 4, HDMI_DVI }, | ||
122 | }, | ||
123 | { | ||
124 | { 800, 600, 40000, 128, 40, 88, 4, 1, 23, | ||
125 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
126 | false, }, | ||
127 | { 9, HDMI_DVI }, | ||
128 | }, | ||
129 | { | ||
130 | { 848, 480, 33750, 112, 16, 112, 8, 6, 23, | ||
131 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
132 | false, }, | ||
133 | { 0xE, HDMI_DVI }, | ||
134 | }, | ||
135 | { | ||
136 | { 1280, 768, 79500, 128, 64, 192, 7, 3, 20, | ||
137 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
138 | false, }, | ||
139 | { 0x17, HDMI_DVI }, | ||
140 | }, | ||
141 | { | ||
142 | { 1280, 800, 83500, 128, 72, 200, 6, 3, 22, | ||
143 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
144 | false, }, | ||
145 | { 0x1C, HDMI_DVI }, | ||
146 | }, | ||
147 | { | ||
148 | { 1360, 768, 85500, 112, 64, 256, 6, 3, 18, | ||
149 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
150 | false, }, | ||
151 | { 0x27, HDMI_DVI }, | ||
152 | }, | ||
153 | { | ||
154 | { 1280, 960, 108000, 112, 96, 312, 3, 1, 36, | ||
155 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
156 | false, }, | ||
157 | { 0x20, HDMI_DVI }, | ||
158 | }, | ||
159 | { | ||
160 | { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38, | ||
161 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
162 | false, }, | ||
163 | { 0x23, HDMI_DVI }, | ||
164 | }, | ||
165 | { | ||
166 | { 1024, 768, 65000, 136, 24, 160, 6, 3, 29, | ||
167 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
168 | false, }, | ||
169 | { 0x10, HDMI_DVI }, | ||
170 | }, | ||
171 | { | ||
172 | { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32, | ||
173 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
174 | false, }, | ||
175 | { 0x2A, HDMI_DVI }, | ||
176 | }, | ||
177 | { | ||
178 | { 1440, 900, 106500, 152, 80, 232, 6, 3, 25, | ||
179 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
180 | false, }, | ||
181 | { 0x2F, HDMI_DVI }, | ||
182 | }, | ||
183 | { | ||
184 | { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, | ||
185 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
186 | false, }, | ||
187 | { 0x3A, HDMI_DVI }, | ||
188 | }, | ||
189 | { | ||
190 | { 1366, 768, 85500, 143, 70, 213, 3, 3, 24, | ||
191 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
192 | false, }, | ||
193 | { 0x51, HDMI_DVI }, | ||
194 | }, | ||
195 | { | ||
196 | { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36, | ||
197 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
198 | false, }, | ||
199 | { 0x52, HDMI_DVI }, | ||
200 | }, | ||
201 | { | ||
202 | { 1280, 768, 68250, 32, 48, 80, 7, 3, 12, | ||
203 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
204 | false, }, | ||
205 | { 0x16, HDMI_DVI }, | ||
206 | }, | ||
207 | { | ||
208 | { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23, | ||
209 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
210 | false, }, | ||
211 | { 0x29, HDMI_DVI }, | ||
212 | }, | ||
213 | { | ||
214 | { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21, | ||
215 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
216 | false, }, | ||
217 | { 0x39, HDMI_DVI }, | ||
218 | }, | ||
219 | { | ||
220 | { 1280, 800, 79500, 32, 48, 80, 6, 3, 14, | ||
221 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
222 | false, }, | ||
223 | { 0x1B, HDMI_DVI }, | ||
224 | }, | ||
225 | { | ||
226 | { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, | ||
227 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
228 | false, }, | ||
229 | { 0x55, HDMI_DVI }, | ||
230 | }, | ||
231 | { | ||
232 | { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26, | ||
233 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
234 | false, }, | ||
235 | { 0x44, HDMI_DVI }, | ||
236 | }, | ||
237 | }; | ||
238 | |||
239 | const struct hdmi_config *hdmi_default_timing(void) | ||
240 | { | ||
241 | return &vesa_timings[0]; | ||
242 | } | ||
243 | |||
244 | static const struct hdmi_config *hdmi_find_timing(int code, | ||
245 | const struct hdmi_config *timings_arr, int len) | ||
246 | { | ||
247 | int i; | ||
248 | |||
249 | for (i = 0; i < len; i++) { | ||
250 | if (timings_arr[i].cm.code == code) | ||
251 | return &timings_arr[i]; | ||
252 | } | ||
253 | |||
254 | return NULL; | ||
255 | } | ||
256 | |||
257 | const struct hdmi_config *hdmi_get_timings(int mode, int code) | ||
258 | { | ||
259 | const struct hdmi_config *arr; | ||
260 | int len; | ||
261 | |||
262 | if (mode == HDMI_DVI) { | ||
263 | arr = vesa_timings; | ||
264 | len = ARRAY_SIZE(vesa_timings); | ||
265 | } else { | ||
266 | arr = cea_timings; | ||
267 | len = ARRAY_SIZE(cea_timings); | ||
268 | } | ||
269 | |||
270 | return hdmi_find_timing(code, arr, len); | ||
271 | } | ||
272 | |||
273 | static bool hdmi_timings_compare(struct omap_video_timings *timing1, | ||
274 | const struct omap_video_timings *timing2) | ||
275 | { | ||
276 | int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; | ||
277 | |||
278 | if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) == | ||
279 | DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) && | ||
280 | (timing2->x_res == timing1->x_res) && | ||
281 | (timing2->y_res == timing1->y_res)) { | ||
282 | |||
283 | timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; | ||
284 | timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; | ||
285 | timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; | ||
286 | timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp; | ||
287 | |||
288 | DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ | ||
289 | "timing2_hsync = %d timing2_vsync = %d\n", | ||
290 | timing1_hsync, timing1_vsync, | ||
291 | timing2_hsync, timing2_vsync); | ||
292 | |||
293 | if ((timing1_hsync == timing2_hsync) && | ||
294 | (timing1_vsync == timing2_vsync)) { | ||
295 | return true; | ||
296 | } | ||
297 | } | ||
298 | return false; | ||
299 | } | ||
300 | |||
301 | struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) | ||
302 | { | ||
303 | int i; | ||
304 | struct hdmi_cm cm = {-1}; | ||
305 | DSSDBG("hdmi_get_code\n"); | ||
306 | |||
307 | for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { | ||
308 | if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { | ||
309 | cm = cea_timings[i].cm; | ||
310 | goto end; | ||
311 | } | ||
312 | } | ||
313 | for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { | ||
314 | if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { | ||
315 | cm = vesa_timings[i].cm; | ||
316 | goto end; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | end: | ||
321 | return cm; | ||
322 | } | ||
323 | |||
324 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
325 | int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts) | ||
326 | { | ||
327 | u32 deep_color; | ||
328 | bool deep_color_correct = false; | ||
329 | |||
330 | if (n == NULL || cts == NULL) | ||
331 | return -EINVAL; | ||
332 | |||
333 | /* TODO: When implemented, query deep color mode here. */ | ||
334 | deep_color = 100; | ||
335 | |||
336 | /* | ||
337 | * When using deep color, the default N value (as in the HDMI | ||
338 | * specification) yields to an non-integer CTS. Hence, we | ||
339 | * modify it while keeping the restrictions described in | ||
340 | * section 7.2.1 of the HDMI 1.4a specification. | ||
341 | */ | ||
342 | switch (sample_freq) { | ||
343 | case 32000: | ||
344 | case 48000: | ||
345 | case 96000: | ||
346 | case 192000: | ||
347 | if (deep_color == 125) | ||
348 | if (pclk == 27027 || pclk == 74250) | ||
349 | deep_color_correct = true; | ||
350 | if (deep_color == 150) | ||
351 | if (pclk == 27027) | ||
352 | deep_color_correct = true; | ||
353 | break; | ||
354 | case 44100: | ||
355 | case 88200: | ||
356 | case 176400: | ||
357 | if (deep_color == 125) | ||
358 | if (pclk == 27027) | ||
359 | deep_color_correct = true; | ||
360 | break; | ||
361 | default: | ||
362 | return -EINVAL; | ||
363 | } | ||
364 | |||
365 | if (deep_color_correct) { | ||
366 | switch (sample_freq) { | ||
367 | case 32000: | ||
368 | *n = 8192; | ||
369 | break; | ||
370 | case 44100: | ||
371 | *n = 12544; | ||
372 | break; | ||
373 | case 48000: | ||
374 | *n = 8192; | ||
375 | break; | ||
376 | case 88200: | ||
377 | *n = 25088; | ||
378 | break; | ||
379 | case 96000: | ||
380 | *n = 16384; | ||
381 | break; | ||
382 | case 176400: | ||
383 | *n = 50176; | ||
384 | break; | ||
385 | case 192000: | ||
386 | *n = 32768; | ||
387 | break; | ||
388 | default: | ||
389 | return -EINVAL; | ||
390 | } | ||
391 | } else { | ||
392 | switch (sample_freq) { | ||
393 | case 32000: | ||
394 | *n = 4096; | ||
395 | break; | ||
396 | case 44100: | ||
397 | *n = 6272; | ||
398 | break; | ||
399 | case 48000: | ||
400 | *n = 6144; | ||
401 | break; | ||
402 | case 88200: | ||
403 | *n = 12544; | ||
404 | break; | ||
405 | case 96000: | ||
406 | *n = 12288; | ||
407 | break; | ||
408 | case 176400: | ||
409 | *n = 25088; | ||
410 | break; | ||
411 | case 192000: | ||
412 | *n = 24576; | ||
413 | break; | ||
414 | default: | ||
415 | return -EINVAL; | ||
416 | } | ||
417 | } | ||
418 | /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ | ||
419 | *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); | ||
420 | |||
421 | return 0; | ||
422 | } | ||
423 | #endif | ||