Commit 769dcb11 authored by Tomi Valkeinen's avatar Tomi Valkeinen
Browse files

OMAPDSS: HDMI5: 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: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent ab0aee95
Loading
Loading
Loading
Loading
+22 −31
Original line number Original line Diff line number Diff line
@@ -299,29 +299,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
		struct omap_video_timings *timings)
		struct omap_video_timings *timings)
{
{
	struct hdmi_cm cm;
	const struct hdmi_config *t;

	mutex_lock(&hdmi.lock);
	mutex_lock(&hdmi.lock);


	cm = hdmi_get_code(timings);
	hdmi.cfg.cm = cm;

	t = hdmi_get_timings(cm.mode, cm.code);
	if (t != NULL) {
		hdmi.cfg = *t;

		dispc_set_tv_pclk(t->timings.pixelclock);
	} else {
	hdmi.cfg.timings = *timings;
	hdmi.cfg.timings = *timings;
		hdmi.cfg.cm.code = 0;
		hdmi.cfg.cm.mode = HDMI_DVI;


	dispc_set_tv_pclk(timings->pixelclock);
	dispc_set_tv_pclk(timings->pixelclock);
	}

	DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
			"DVI" : "HDMI", hdmi.cfg.cm.code);


	mutex_unlock(&hdmi.lock);
	mutex_unlock(&hdmi.lock);
}
}
@@ -329,14 +311,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
		struct omap_video_timings *timings)
		struct omap_video_timings *timings)
{
{
	const struct hdmi_config *cfg;
	*timings = hdmi.cfg.timings;
	struct hdmi_cm cm = hdmi.cfg.cm;

	cfg = hdmi_get_timings(cm.mode, cm.code);
	if (cfg == NULL)
		cfg = hdmi_default_timing();

	memcpy(timings, &cfg->timings, sizeof(cfg->timings));
}
}


static void hdmi_dump_regs(struct seq_file *s)
static void hdmi_dump_regs(struct seq_file *s)
@@ -541,7 +516,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev)


	mutex_lock(&hdmi.lock);
	mutex_lock(&hdmi.lock);


	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
	if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
		r = -EPERM;
		r = -EPERM;
		goto err;
		goto err;
	}
	}
@@ -579,7 +554,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev)


	mutex_lock(&hdmi.lock);
	mutex_lock(&hdmi.lock);


	r = hdmi_mode_has_audio(hdmi.cfg.cm.mode);
	r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);


	mutex_unlock(&hdmi.lock);
	mutex_unlock(&hdmi.lock);
	return r;
	return r;
@@ -593,7 +568,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,


	mutex_lock(&hdmi.lock);
	mutex_lock(&hdmi.lock);


	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
	if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
		r = -EPERM;
		r = -EPERM;
		goto err;
		goto err;
	}
	}
@@ -640,6 +615,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
}
}
#endif
#endif


static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
		const struct hdmi_avi_infoframe *avi)
{
	hdmi.cfg.infoframe = *avi;
	return 0;
}

static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
		bool hdmi_mode)
{
	hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
	return 0;
}

static const struct omapdss_hdmi_ops hdmi_ops = {
static const struct omapdss_hdmi_ops hdmi_ops = {
	.connect		= hdmi_connect,
	.connect		= hdmi_connect,
	.disconnect		= hdmi_disconnect,
	.disconnect		= hdmi_disconnect,
@@ -652,6 +641,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
	.get_timings		= hdmi_display_get_timings,
	.get_timings		= hdmi_display_get_timings,


	.read_edid		= hdmi_read_edid,
	.read_edid		= hdmi_read_edid,
	.set_infoframe		= hdmi_set_infoframe,
	.set_hdmi_mode		= hdmi_set_hdmi_mode,


	.audio_enable		= hdmi_audio_enable,
	.audio_enable		= hdmi_audio_enable,
	.audio_disable		= hdmi_audio_disable,
	.audio_disable		= hdmi_audio_disable,
+11 −25
Original line number Original line Diff line number Diff line
@@ -311,7 +311,7 @@ static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
	video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */
	video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */
	video_cfg->vblank = cfg->timings.vsw +
	video_cfg->vblank = cfg->timings.vsw +
				cfg->timings.vfp + cfg->timings.vbp;
				cfg->timings.vfp + cfg->timings.vbp;
	video_cfg->v_fc_config.cm.mode = cfg->cm.mode;
	video_cfg->v_fc_config.hdmi_dvi_mode = cfg->hdmi_dvi_mode;
	video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace;
	video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace;
}
}


@@ -378,7 +378,7 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,


	/* select DVI mode */
	/* select DVI mode */
	REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF,
	REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF,
			cfg->v_fc_config.cm.mode, 3, 3);
			cfg->v_fc_config.hdmi_dvi_mode, 3, 3);
}
}


static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core)
static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core)
@@ -418,9 +418,9 @@ static void hdmi_core_config_video_sampler(struct hdmi_core_data *core)
	REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0);
	REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0);
}
}


static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)
static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
	struct hdmi_avi_infoframe *frame)
{
{
	struct hdmi_avi_infoframe *frame = &core->avi_infoframe;
	void __iomem *base = core->base;
	void __iomem *base = core->base;
	u8 data[HDMI_INFOFRAME_SIZE(AVI)];
	u8 data[HDMI_INFOFRAME_SIZE(AVI)];
	u8 *ptr;
	u8 *ptr;
@@ -432,6 +432,9 @@ static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)


	hdmi_avi_infoframe_pack(frame, data, sizeof(data));
	hdmi_avi_infoframe_pack(frame, data, sizeof(data));


	print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
		HDMI_INFOFRAME_SIZE(AVI), false);

	ptr = data + HDMI_INFOFRAME_HEADER_SIZE;
	ptr = data + HDMI_INFOFRAME_HEADER_SIZE;


	y = (ptr[0] >> 5) & 0x3;
	y = (ptr[0] >> 5) & 0x3;
@@ -510,10 +513,8 @@ static void hdmi_core_configure_range(struct hdmi_core_data *core)


	/* support limited range with 24 bit color depth for now */
	/* support limited range with 24 bit color depth for now */
	csc_coeff = csc_table_deepcolor[0];
	csc_coeff = csc_table_deepcolor[0];
	core->avi_infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED;


	hdmi_core_csc_config(core, csc_coeff);
	hdmi_core_csc_config(core, csc_coeff);
	hdmi_core_aux_infoframe_avi_config(core);
}
}


static void hdmi_core_enable_video_path(struct hdmi_core_data *core)
static void hdmi_core_enable_video_path(struct hdmi_core_data *core)
@@ -604,7 +605,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
	struct omap_video_timings video_timing;
	struct omap_video_timings video_timing;
	struct hdmi_video_format video_format;
	struct hdmi_video_format video_format;
	struct hdmi_core_vid_config v_core_cfg;
	struct hdmi_core_vid_config v_core_cfg;
	struct hdmi_avi_infoframe *avi_infoframe = &core->avi_infoframe;


	hdmi_core_mask_interrupts(core);
	hdmi_core_mask_interrupts(core);


@@ -621,7 +621,9 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,


	hdmi_wp_video_config_interface(wp, &video_timing);
	hdmi_wp_video_config_interface(wp, &video_timing);


	/* support limited range with 24 bit color depth for now */
	hdmi_core_configure_range(core);
	hdmi_core_configure_range(core);
	cfg->infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED;


	/*
	/*
	 * configure core video part, set software reset in the core
	 * configure core video part, set software reset in the core
@@ -634,24 +636,8 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
	hdmi_core_config_csc(core);
	hdmi_core_config_csc(core);
	hdmi_core_config_video_sampler(core);
	hdmi_core_config_video_sampler(core);


	/*
	if (cfg->hdmi_dvi_mode == HDMI_HDMI)
	 * configure packet info frame video see doc CEA861-D page 65
		hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
	 */
	hdmi_avi_infoframe_init(avi_infoframe);
	avi_infoframe->colorspace = HDMI_COLORSPACE_RGB;
	avi_infoframe->scan_mode = HDMI_SCAN_MODE_NONE;
	avi_infoframe->colorimetry = HDMI_COLORIMETRY_NONE;
	avi_infoframe->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
	avi_infoframe->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
	avi_infoframe->itc = 0;
	avi_infoframe->extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
	avi_infoframe->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
	avi_infoframe->nups = HDMI_NUPS_UNKNOWN;
	avi_infoframe->video_code = cfg->cm.code;
	avi_infoframe->ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
	avi_infoframe->content_type = HDMI_CONTENT_TYPE_NONE;
	avi_infoframe->pixel_repeat = 0;
	hdmi_core_aux_infoframe_avi_config(core);


	hdmi_core_enable_video_path(core);
	hdmi_core_enable_video_path(core);