Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+41 -74
+22 -31
drivers/video/fbdev/omap2/dss/hdmi4.c
··· 281 281 static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 282 282 struct omap_video_timings *timings) 283 283 { 284 - struct hdmi_cm cm; 285 - const struct hdmi_config *t; 286 - 287 284 mutex_lock(&hdmi.lock); 288 285 289 - cm = hdmi_get_code(timings); 290 - hdmi.cfg.cm = cm; 286 + hdmi.cfg.timings = *timings; 291 287 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 - 305 - DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? 306 - "DVI" : "HDMI", hdmi.cfg.cm.code); 288 + dispc_set_tv_pclk(timings->pixelclock); 307 289 308 290 mutex_unlock(&hdmi.lock); 309 291 } ··· 293 311 static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 294 312 struct omap_video_timings *timings) 295 313 { 296 - const struct hdmi_config *cfg; 297 - struct hdmi_cm cm = hdmi.cfg.cm; 298 - 299 - cfg = hdmi_get_timings(cm.mode, cm.code); 300 - if (cfg == NULL) 301 - cfg = hdmi_default_timing(); 302 - 303 - memcpy(timings, &cfg->timings, sizeof(cfg->timings)); 314 + *timings = hdmi.cfg.timings; 304 315 } 305 316 306 317 static void hdmi_dump_regs(struct seq_file *s) ··· 491 516 492 517 mutex_lock(&hdmi.lock); 493 518 494 - if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { 519 + if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) { 495 520 r = -EPERM; 496 521 goto err; 497 522 } ··· 529 554 530 555 mutex_lock(&hdmi.lock); 531 556 532 - r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); 557 + r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode); 533 558 534 559 mutex_unlock(&hdmi.lock); 535 560 return r; ··· 543 568 544 569 mutex_lock(&hdmi.lock); 545 570 546 - if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { 571 + if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) { 547 572 r = -EPERM; 548 573 goto err; 549 574 } ··· 590 615 } 591 616 #endif 592 617 618 + static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 619 + const struct hdmi_avi_infoframe *avi) 620 + { 621 + hdmi.cfg.infoframe = *avi; 622 + return 0; 623 + } 624 + 625 + static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, 626 + bool hdmi_mode) 627 + { 628 + hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; 629 + return 0; 630 + } 631 + 593 632 static const struct omapdss_hdmi_ops hdmi_ops = { 594 633 .connect = hdmi_connect, 595 634 .disconnect = hdmi_disconnect, ··· 616 627 .get_timings = hdmi_display_get_timings, 617 628 618 629 .read_edid = hdmi_read_edid, 630 + .set_infoframe = hdmi_set_infoframe, 631 + .set_hdmi_mode = hdmi_set_hdmi_mode, 619 632 620 633 .audio_enable = hdmi_audio_enable, 621 634 .audio_disable = hdmi_audio_disable,
+19 -43
drivers/video/fbdev/omap2/dss/hdmi4_core.c
··· 197 197 return l; 198 198 } 199 199 200 - static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, 201 - struct hdmi_core_packet_enable_repeat *repeat_cfg) 200 + static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) 202 201 { 203 202 DSSDBG("Enter hdmi_core_init\n"); 204 203 ··· 208 209 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; 209 210 video_cfg->hdmi_dvi = HDMI_DVI; 210 211 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; 211 - 212 - /* packet enable and repeat */ 213 - repeat_cfg->audio_pkt = 0; 214 - repeat_cfg->audio_pkt_repeat = 0; 215 - repeat_cfg->avi_infoframe = 0; 216 - repeat_cfg->avi_infoframe_repeat = 0; 217 - repeat_cfg->gen_cntrl_pkt = 0; 218 - repeat_cfg->gen_cntrl_pkt_repeat = 0; 219 - repeat_cfg->generic_pkt = 0; 220 - repeat_cfg->generic_pkt_repeat = 0; 221 212 } 222 213 223 214 static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) ··· 272 283 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); 273 284 } 274 285 275 - static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) 286 + static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core, 287 + struct hdmi_avi_infoframe *frame) 276 288 { 277 289 void __iomem *av_base = hdmi_av_base(core); 278 - struct hdmi_avi_infoframe *frame = &core->avi_infoframe; 279 290 u8 data[HDMI_INFOFRAME_SIZE(AVI)]; 280 291 int i; 281 292 282 293 hdmi_avi_infoframe_pack(frame, data, sizeof(data)); 294 + 295 + print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data, 296 + HDMI_INFOFRAME_SIZE(AVI), false); 283 297 284 298 for (i = 0; i < sizeof(data); ++i) { 285 299 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4, ··· 316 324 struct hdmi_video_format video_format; 317 325 /* HDMI core */ 318 326 struct hdmi_core_video_config v_core_cfg; 319 - struct hdmi_core_packet_enable_repeat repeat_cfg; 320 - struct hdmi_avi_infoframe *avi_infoframe = &core->avi_infoframe; 327 + struct hdmi_core_packet_enable_repeat repeat_cfg = { 0 }; 321 328 322 - hdmi_core_init(&v_core_cfg, &repeat_cfg); 329 + hdmi_core_init(&v_core_cfg); 323 330 324 331 hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); 325 332 ··· 341 350 hdmi_core_powerdown_disable(core); 342 351 343 352 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; 344 - v_core_cfg.hdmi_dvi = cfg->cm.mode; 353 + v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode; 345 354 346 355 hdmi_core_video_config(core, &v_core_cfg); 347 356 348 357 /* release software reset in the core */ 349 358 hdmi_core_swreset_release(core); 350 359 351 - /* 352 - * configure packet 353 - * info frame video see doc CEA861-D page 65 354 - */ 355 - hdmi_avi_infoframe_init(avi_infoframe); 356 - avi_infoframe->colorspace = HDMI_COLORSPACE_RGB; 357 - avi_infoframe->scan_mode = HDMI_SCAN_MODE_NONE; 358 - avi_infoframe->colorimetry = HDMI_COLORIMETRY_NONE; 359 - avi_infoframe->picture_aspect = HDMI_PICTURE_ASPECT_NONE; 360 - avi_infoframe->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; 361 - avi_infoframe->itc = 0; 362 - avi_infoframe->extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; 363 - avi_infoframe->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT; 364 - avi_infoframe->nups = HDMI_NUPS_UNKNOWN; 365 - avi_infoframe->video_code = cfg->cm.code; 366 - avi_infoframe->ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED; 367 - avi_infoframe->content_type = HDMI_CONTENT_TYPE_NONE; 368 - avi_infoframe->pixel_repeat = 0; 369 - hdmi_core_aux_infoframe_avi_config(core); 360 + if (cfg->hdmi_dvi_mode == HDMI_HDMI) { 361 + hdmi_core_write_avi_infoframe(core, &cfg->infoframe); 370 362 371 - /* enable/repeat the infoframe */ 372 - repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; 373 - repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; 374 - /* wakeup */ 375 - repeat_cfg.audio_pkt = HDMI_PACKETENABLE; 376 - repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; 363 + /* enable/repeat the infoframe */ 364 + repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; 365 + repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; 366 + /* wakeup */ 367 + repeat_cfg.audio_pkt = HDMI_PACKETENABLE; 368 + repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; 369 + } 370 + 377 371 hdmi_core_av_packet_config(core, repeat_cfg); 378 372 } 379 373