aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2014-06-18 07:21:44 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-07-04 04:17:58 -0400
commitab0aee9526988a5f254ce58b59dbcb6a2ae42fd6 (patch)
treeb0ea21cd1188d4b76116dfdee4aa853da7908aa3 /drivers/video
parentc9d2c799447c2f51866fb1e7e88eb5061d11ac43 (diff)
OMAPDSS: HDMI4: add support to set infoframe & HDMI mode
Instead of using hardcoded AVI infoframe, and a custom HDMI/DVI mode selection based in internal videomode tables, add support to set the infoframe and HDMI/DVI mode. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c53
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.c62
2 files changed, 41 insertions, 74 deletions
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 626aad2bef46..6a8550cf43e5 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -281,29 +281,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
281static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 281static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
282 struct omap_video_timings *timings) 282 struct omap_video_timings *timings)
283{ 283{
284 struct hdmi_cm cm;
285 const struct hdmi_config *t;
286
287 mutex_lock(&hdmi.lock); 284 mutex_lock(&hdmi.lock);
288 285
289 cm = hdmi_get_code(timings); 286 hdmi.cfg.timings = *timings;
290 hdmi.cfg.cm = cm;
291
292 t = hdmi_get_timings(cm.mode, cm.code);
293 if (t != NULL) {
294 hdmi.cfg = *t;
295
296 dispc_set_tv_pclk(t->timings.pixelclock);
297 } else {
298 hdmi.cfg.timings = *timings;
299 hdmi.cfg.cm.code = 0;
300 hdmi.cfg.cm.mode = HDMI_DVI;
301
302 dispc_set_tv_pclk(timings->pixelclock);
303 }
304 287
305 DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? 288 dispc_set_tv_pclk(timings->pixelclock);
306 "DVI" : "HDMI", hdmi.cfg.cm.code);
307 289
308 mutex_unlock(&hdmi.lock); 290 mutex_unlock(&hdmi.lock);
309} 291}
@@ -311,14 +293,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
311static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 293static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
312 struct omap_video_timings *timings) 294 struct omap_video_timings *timings)
313{ 295{
314 const struct hdmi_config *cfg; 296 *timings = hdmi.cfg.timings;
315 struct hdmi_cm cm = hdmi.cfg.cm;
316
317 cfg = hdmi_get_timings(cm.mode, cm.code);
318 if (cfg == NULL)
319 cfg = hdmi_default_timing();
320
321 memcpy(timings, &cfg->timings, sizeof(cfg->timings));
322} 297}
323 298
324static void hdmi_dump_regs(struct seq_file *s) 299static void hdmi_dump_regs(struct seq_file *s)
@@ -516,7 +491,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev)
516 491
517 mutex_lock(&hdmi.lock); 492 mutex_lock(&hdmi.lock);
518 493
519 if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { 494 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
520 r = -EPERM; 495 r = -EPERM;
521 goto err; 496 goto err;
522 } 497 }
@@ -554,7 +529,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
554 529
555 mutex_lock(&hdmi.lock); 530 mutex_lock(&hdmi.lock);
556 531
557 r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); 532 r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
558 533
559 mutex_unlock(&hdmi.lock); 534 mutex_unlock(&hdmi.lock);
560 return r; 535 return r;
@@ -568,7 +543,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
568 543
569 mutex_lock(&hdmi.lock); 544 mutex_lock(&hdmi.lock);
570 545
571 if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { 546 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
572 r = -EPERM; 547 r = -EPERM;
573 goto err; 548 goto err;
574 } 549 }
@@ -615,6 +590,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
615} 590}
616#endif 591#endif
617 592
593static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
594 const struct hdmi_avi_infoframe *avi)
595{
596 hdmi.cfg.infoframe = *avi;
597 return 0;
598}
599
600static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
601 bool hdmi_mode)
602{
603 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
604 return 0;
605}
606
618static const struct omapdss_hdmi_ops hdmi_ops = { 607static const struct omapdss_hdmi_ops hdmi_ops = {
619 .connect = hdmi_connect, 608 .connect = hdmi_connect,
620 .disconnect = hdmi_disconnect, 609 .disconnect = hdmi_disconnect,
@@ -627,6 +616,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
627 .get_timings = hdmi_display_get_timings, 616 .get_timings = hdmi_display_get_timings,
628 617
629 .read_edid = hdmi_read_edid, 618 .read_edid = hdmi_read_edid,
619 .set_infoframe = hdmi_set_infoframe,
620 .set_hdmi_mode = hdmi_set_hdmi_mode,
630 621
631 .audio_enable = hdmi_audio_enable, 622 .audio_enable = hdmi_audio_enable,
632 .audio_disable = hdmi_audio_disable, 623 .audio_disable = hdmi_audio_disable,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index dbdbc5836d51..4ad39cfce254 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
@@ -197,8 +197,7 @@ int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len)
197 return l; 197 return l;
198} 198}
199 199
200static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, 200static void hdmi_core_init(struct hdmi_core_video_config *video_cfg)
201 struct hdmi_core_packet_enable_repeat *repeat_cfg)
202{ 201{
203 DSSDBG("Enter hdmi_core_init\n"); 202 DSSDBG("Enter hdmi_core_init\n");
204 203
@@ -209,16 +208,6 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
209 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; 208 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
210 video_cfg->hdmi_dvi = HDMI_DVI; 209 video_cfg->hdmi_dvi = HDMI_DVI;
211 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; 210 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
212
213 /* packet enable and repeat */
214 repeat_cfg->audio_pkt = 0;
215 repeat_cfg->audio_pkt_repeat = 0;
216 repeat_cfg->avi_infoframe = 0;
217 repeat_cfg->avi_infoframe_repeat = 0;
218 repeat_cfg->gen_cntrl_pkt = 0;
219 repeat_cfg->gen_cntrl_pkt_repeat = 0;
220 repeat_cfg->generic_pkt = 0;
221 repeat_cfg->generic_pkt_repeat = 0;
222} 211}
223 212
224static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) 213static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
@@ -283,15 +272,18 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,
283 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); 272 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
284} 273}
285 274
286static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) 275static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
276 struct hdmi_avi_infoframe *frame)
287{ 277{
288 void __iomem *av_base = hdmi_av_base(core); 278 void __iomem *av_base = hdmi_av_base(core);
289 struct hdmi_avi_infoframe *frame = &core->avi_infoframe;
290 u8 data[HDMI_INFOFRAME_SIZE(AVI)]; 279 u8 data[HDMI_INFOFRAME_SIZE(AVI)];
291 int i; 280 int i;
292 281
293 hdmi_avi_infoframe_pack(frame, data, sizeof(data)); 282 hdmi_avi_infoframe_pack(frame, data, sizeof(data));
294 283
284 print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
285 HDMI_INFOFRAME_SIZE(AVI), false);
286
295 for (i = 0; i < sizeof(data); ++i) { 287 for (i = 0; i < sizeof(data); ++i) {
296 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4, 288 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4,
297 data[i]); 289 data[i]);
@@ -324,10 +316,9 @@ void hdmi4_configure(struct hdmi_core_data *core,
324 struct hdmi_video_format video_format; 316 struct hdmi_video_format video_format;
325 /* HDMI core */ 317 /* HDMI core */
326 struct hdmi_core_video_config v_core_cfg; 318 struct hdmi_core_video_config v_core_cfg;
327 struct hdmi_core_packet_enable_repeat repeat_cfg; 319 struct hdmi_core_packet_enable_repeat repeat_cfg = { 0 };
328 struct hdmi_avi_infoframe *avi_infoframe = &core->avi_infoframe;
329 320
330 hdmi_core_init(&v_core_cfg, &repeat_cfg); 321 hdmi_core_init(&v_core_cfg);
331 322
332 hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); 323 hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
333 324
@@ -350,39 +341,24 @@ void hdmi4_configure(struct hdmi_core_data *core,
350 hdmi_core_powerdown_disable(core); 341 hdmi_core_powerdown_disable(core);
351 342
352 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; 343 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
353 v_core_cfg.hdmi_dvi = cfg->cm.mode; 344 v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode;
354 345
355 hdmi_core_video_config(core, &v_core_cfg); 346 hdmi_core_video_config(core, &v_core_cfg);
356 347
357 /* release software reset in the core */ 348 /* release software reset in the core */
358 hdmi_core_swreset_release(core); 349 hdmi_core_swreset_release(core);
359 350
360 /* 351 if (cfg->hdmi_dvi_mode == HDMI_HDMI) {
361 * configure packet 352 hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
362 * info frame video see doc CEA861-D page 65 353
363 */ 354 /* enable/repeat the infoframe */
364 hdmi_avi_infoframe_init(avi_infoframe); 355 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
365 avi_infoframe->colorspace = HDMI_COLORSPACE_RGB; 356 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
366 avi_infoframe->scan_mode = HDMI_SCAN_MODE_NONE; 357 /* wakeup */
367 avi_infoframe->colorimetry = HDMI_COLORIMETRY_NONE; 358 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
368 avi_infoframe->picture_aspect = HDMI_PICTURE_ASPECT_NONE; 359 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
369 avi_infoframe->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; 360 }
370 avi_infoframe->itc = 0;
371 avi_infoframe->extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
372 avi_infoframe->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
373 avi_infoframe->nups = HDMI_NUPS_UNKNOWN;
374 avi_infoframe->video_code = cfg->cm.code;
375 avi_infoframe->ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
376 avi_infoframe->content_type = HDMI_CONTENT_TYPE_NONE;
377 avi_infoframe->pixel_repeat = 0;
378 hdmi_core_aux_infoframe_avi_config(core);
379 361
380 /* enable/repeat the infoframe */
381 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
382 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
383 /* wakeup */
384 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
385 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
386 hdmi_core_av_packet_config(core, repeat_cfg); 362 hdmi_core_av_packet_config(core, repeat_cfg);
387} 363}
388 364