Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be53b222 authored by Abhinav Kumar's avatar Abhinav Kumar Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm: add HDCP 2.2 module for DRM HDMI



Add the HDCP 2.2 module for DRM HDMI.

Call the HDCP 2.2 APIs from the SDE HDMI driver and
also invoke the HDCP 2.2 ISR routine from the parent
ISR routine of the SDE HDMI driver.

Change-Id: Ib9a427e5712c827fa93b91fc3a416af61ea83745
Signed-off-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
parent 9342afef
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ msm_drm-$(CONFIG_DRM_SDE_HDMI) += \
	hdmi-staging/sde_hdmi.o \
	hdmi-staging/sde_hdmi_bridge.o \
	hdmi-staging/sde_hdmi_audio.o \
	hdmi-staging/sde_hdmi_hdcp2p2.o \

msm_drm-$(CONFIG_DRM_MSM_DSI_PLL) += dsi/pll/dsi_pll.o \
				dsi/pll/dsi_pll_28nm.o
+37 −13
Original line number Diff line number Diff line
@@ -1036,6 +1036,7 @@ static void _sde_hdmi_cec_update_phys_addr(struct sde_hdmi *display)
static void _sde_hdmi_init_ddc(struct sde_hdmi *display, struct hdmi *hdmi)
{
	display->ddc_ctrl.io = &display->io[HDMI_TX_CORE_IO];
	init_completion(&display->ddc_ctrl.rx_status_done);
}

static void _sde_hdmi_map_regs(struct sde_hdmi *display, struct hdmi *hdmi)
@@ -1124,32 +1125,39 @@ static void _sde_hdmi_cec_irq(struct sde_hdmi *sde_hdmi)

static irqreturn_t _sde_hdmi_irq(int irq, void *dev_id)
{
	struct sde_hdmi *sde_hdmi = dev_id;
	struct sde_hdmi *display = dev_id;
	struct hdmi *hdmi;

	if (!sde_hdmi || !sde_hdmi->ctrl.ctrl) {
		SDE_ERROR("sde_hdmi=%p or hdmi is NULL\n", sde_hdmi);
	if (!display || !display->ctrl.ctrl) {
		SDE_ERROR("sde_hdmi=%pK or hdmi is NULL\n", display);
		return IRQ_NONE;
	}
	hdmi = sde_hdmi->ctrl.ctrl;

	hdmi = display->ctrl.ctrl;
	/* Process HPD: */
	_sde_hdmi_connector_irq(sde_hdmi);
	_sde_hdmi_connector_irq(display);

	/* Process Scrambling ISR */
	sde_hdmi_ddc_scrambling_isr((void *)display);

	/* Process DDC2 */
	sde_hdmi_ddc_hdcp2p2_isr((void *)display);

	/* Process DDC: */
	hdmi_i2c_irq(hdmi->i2c);

	/* Process HDCP: */
	if (sde_hdmi->hdcp_ops && sde_hdmi->hdcp_data) {
		if (sde_hdmi->hdcp_ops->isr) {
			if (sde_hdmi->hdcp_ops->isr(
				sde_hdmi->hdcp_data))
	if (display->hdcp_ops && display->hdcp_data) {
		if (display->hdcp_ops->isr) {
			if (display->hdcp_ops->isr(
				display->hdcp_data))
				DEV_ERR("%s: hdcp_1x_isr failed\n",
						__func__);
		}
	}

	/* Process CEC: */
	_sde_hdmi_cec_irq(sde_hdmi);
	_sde_hdmi_cec_irq(display);

	return IRQ_HANDLED;
}
@@ -1714,11 +1722,22 @@ static int _sde_hdmi_init_hdcp(struct sde_hdmi *hdmi_ctrl)
			kfree(hdcp_data);
			goto end;
		} else {
			hdmi_ctrl->hdcp_feature_data[SDE_HDCP_1x] = hdcp_data;
			hdmi_ctrl->hdcp_feat_data[SDE_HDCP_1x] = hdcp_data;
			SDE_HDMI_DEBUG("%s: HDCP 1.4 initialized\n", __func__);
		}
	}

	hdcp_data = sde_hdmi_hdcp2p2_init(&hdcp_init_data);

	if (IS_ERR_OR_NULL(hdcp_data)) {
		DEV_ERR("%s: hdcp 2.2 init failed\n", __func__);
		rc = -EINVAL;
		goto end;
	} else {
		hdmi_ctrl->hdcp_feat_data[SDE_HDCP_2P2] = hdcp_data;
		SDE_HDMI_DEBUG("%s: HDCP 2.2 initialized\n", __func__);
	}

end:
	return rc;
}
@@ -1902,8 +1921,11 @@ int sde_hdmi_dev_deinit(struct sde_hdmi *display)
		SDE_ERROR("Invalid params\n");
		return -EINVAL;
	}
	if (display->hdcp_feature_data[SDE_HDCP_1x])
		sde_hdcp_1x_deinit(display->hdcp_feature_data[SDE_HDCP_1x]);
	if (display->hdcp_feat_data[SDE_HDCP_1x])
		sde_hdcp_1x_deinit(display->hdcp_feat_data[SDE_HDCP_1x]);

	if (display->hdcp_feat_data[SDE_HDCP_2P2])
		sde_hdmi_hdcp2p2_deinit(display->hdcp_feat_data[SDE_HDCP_2P2]);

	return 0;
}
@@ -1990,6 +2012,8 @@ static int sde_hdmi_bind(struct device *dev, struct device *master, void *data)
	_sde_hdmi_map_regs(display, priv->hdmi);
	_sde_hdmi_init_ddc(display, priv->hdmi);

	display->enc_lvl = HDCP_STATE_AUTH_ENC_NONE;

	INIT_DELAYED_WORK(&display->hdcp_cb_work,
					  sde_hdmi_tx_hdcp_cb_work);
	mutex_init(&display->hdcp_mutex);
+1 −1
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ struct sde_hdmi {
	 */
	void *hdcp_data;
	/*hold hdcp init data*/
	void *hdcp_feature_data[2];
	void *hdcp_feat_data[2];
	struct sde_hdcp_ops *hdcp_ops;
	struct sde_hdmi_tx_ddc_ctrl ddc_ctrl;
	struct work_struct hpd_work;
+12 −2
Original line number Diff line number Diff line
@@ -380,13 +380,23 @@ static void sde_hdmi_update_hdcp_info(struct drm_connector *connector)
		return;
	}

	/* check first if hdcp2p2 is supported */
	fd = display->hdcp_feat_data[SDE_HDCP_2P2];
	if (fd)
		ops = sde_hdmi_hdcp2p2_start(fd);

	if (ops && ops->feature_supported)
		display->hdcp22_present = ops->feature_supported(fd);
	else
		display->hdcp22_present = false;

	if (!display->hdcp22_present) {
		if (display->hdcp1_use_sw_keys) {
			display->hdcp14_present =
				hdcp1_check_if_supported_load_app();
		}
		if (display->hdcp14_present) {
			fd = display->hdcp_feature_data[SDE_HDCP_1x];
			fd = display->hdcp_feat_data[SDE_HDCP_1x];
			if (fd)
				ops = sde_hdcp_1x_start(fd);
		}
@@ -638,9 +648,9 @@ static void _sde_hdmi_bridge_mode_set(struct drm_bridge *bridge,
		_sde_hdmi_bridge_set_spd_infoframe(hdmi, mode);
		DRM_DEBUG("hdmi setup info frame\n");
	}
	_sde_hdmi_bridge_setup_scrambler(hdmi, mode);

	_sde_hdmi_save_mode(hdmi, mode);
	_sde_hdmi_bridge_setup_scrambler(hdmi, mode);
}

static const struct drm_bridge_funcs _sde_hdmi_bridge_funcs = {
+955 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading