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

Commit 15e4a355 authored by Tatenda Chipeperekwa's avatar Tatenda Chipeperekwa
Browse files

drm/msm/dp: add support to force HDCP 2.2 encryption



The HDCP 2.2 TrustZone application on sm8150 will only enable
encryption based on the content being played back. Add debug
support to force HDCP 2.2 encryption for DisplayPort in order
to pass compliance testing.

CRs-Fixed: 2284465
Change-Id: I84e29000f49237babd5804982986b02063f30673
Signed-off-by: default avatarTatenda Chipeperekwa <tatendac@codeaurora.org>
parent df433782
Loading
Loading
Loading
Loading
+24 −16
Original line number Diff line number Diff line
@@ -1366,6 +1366,7 @@ static int dp_debug_init(struct dp_debug *dp_debug)
		rc = PTR_ERR(file);
		pr_err("[%s] debugfs max_bw_code failed, rc=%d\n",
		       DEBUG_NAME, rc);
		goto error_remove_dir;
	}

	file = debugfs_create_file("mst_sideband_mode", 0644, dir,
@@ -1374,6 +1375,7 @@ static int dp_debug_init(struct dp_debug *dp_debug)
		rc = PTR_ERR(file);
		pr_err("[%s] debugfs max_bw_code failed, rc=%d\n",
		       DEBUG_NAME, rc);
		goto error_remove_dir;
	}

	file = debugfs_create_file("max_pclk_khz", 0644, dir,
@@ -1382,6 +1384,16 @@ static int dp_debug_init(struct dp_debug *dp_debug)
		rc = PTR_ERR(file);
		pr_err("[%s] debugfs max_pclk_khz failed, rc=%d\n",
		       DEBUG_NAME, rc);
		goto error_remove_dir;
	}

	file = debugfs_create_bool("force_encryption", 0644, dir,
			&debug->dp_debug.force_encryption);
	if (IS_ERR_OR_NULL(file)) {
		rc = PTR_ERR(file);
		pr_err("[%s] debugfs force_encryption failed, rc=%d\n",
		       DEBUG_NAME, rc);
		goto error_remove_dir;
	}

	return 0;
@@ -1406,37 +1418,33 @@ u8 *dp_debug_get_edid(struct dp_debug *dp_debug)
	return debug->edid;
}

struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
			struct dp_hpd *hpd, struct dp_link *link,
			struct dp_aux *aux, struct drm_connector **connector,
			struct dp_catalog *catalog,
			struct dp_parser *parser)
struct dp_debug *dp_debug_get(struct dp_debug_in *in)
{
	int rc = 0;
	struct dp_debug_private *debug;
	struct dp_debug *dp_debug;

	if (!dev || !panel || !hpd || !link || !catalog) {
	if (!in->dev || !in->panel || !in->hpd || !in->link || !in->catalog) {
		pr_err("invalid input\n");
		rc = -EINVAL;
		goto error;
	}

	debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
	debug = devm_kzalloc(in->dev, sizeof(*debug), GFP_KERNEL);
	if (!debug) {
		rc = -ENOMEM;
		goto error;
	}

	debug->dp_debug.debug_en = false;
	debug->hpd = hpd;
	debug->link = link;
	debug->panel = panel;
	debug->aux = aux;
	debug->dev = dev;
	debug->connector = connector;
	debug->catalog = catalog;
	debug->parser = parser;
	debug->hpd = in->hpd;
	debug->link = in->link;
	debug->panel = in->panel;
	debug->aux = in->aux;
	debug->dev = in->dev;
	debug->connector = in->connector;
	debug->catalog = in->catalog;
	debug->parser = in->parser;

	dp_debug = &debug->dp_debug;
	dp_debug->vdisplay = 0;
@@ -1445,7 +1453,7 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,

	rc = dp_debug_init(dp_debug);
	if (rc) {
		devm_kfree(dev, debug);
		devm_kfree(in->dev, debug);
		goto error;
	}

+22 −7
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
 * @vrefresh: used to filter out vrefresh value
 * @tpg_state: specifies whether tpg feature is enabled
 * @max_pclk_khz: max pclk supported
 * @force_encryption: enable/disable forced encryption for HDCP 2.2
 */
struct dp_debug {
	bool debug_en;
@@ -39,30 +40,44 @@ struct dp_debug {
	int vrefresh;
	bool tpg_state;
	u32 max_pclk_khz;
	bool force_encryption;

	u8 *(*get_edid)(struct dp_debug *dp_debug);
};

/**
 * dp_debug_get() - configure and get the DisplayPlot debug module data
 *
 * struct dp_debug_in
 * @dev: device instance of the caller
 * @panel: instance of panel module
 * @hpd: instance of hpd module
 * @link: instance of link module
 * @aux: instance of aux module
 * @connector: double pointer to display connector
 * @catalog: instance of catalog module
 * @parser: instance of parser module
 */
struct dp_debug_in {
	struct device *dev;
	struct dp_panel *panel;
	struct dp_hpd *hpd;
	struct dp_link *link;
	struct dp_aux *aux;
	struct drm_connector **connector;
	struct dp_catalog *catalog;
	struct dp_parser *parser;
};

/**
 * dp_debug_get() - configure and get the DisplayPlot debug module data
 *
 * @in: input structure containing data to initialize the debug module
 * return: pointer to allocated debug module data
 *
 * This function sets up the debug module and provides a way
 * for debugfs input to be communicated with existing modules
 */
struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
			struct dp_hpd *hpd, struct dp_link *link,
			struct dp_aux *aux, struct drm_connector **connector,
			struct dp_catalog *catalog,
			struct dp_parser *parser);
struct dp_debug *dp_debug_get(struct dp_debug_in *in);

/**
 * dp_debug_put()
 *
+20 −8
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ static void dp_display_hdcp_cb_work(struct work_struct *work)
	struct dp_display_private *dp;
	struct delayed_work *dw = to_delayed_work(work);
	struct sde_hdcp_ops *ops;
	void *data;
	int rc = 0;
	u32 hdcp_auth_state;

@@ -180,20 +181,24 @@ static void dp_display_hdcp_cb_work(struct work_struct *work)
	}

	ops = dp->hdcp.ops;
	data = dp->hdcp.data;

	pr_debug("%s: %s\n",
		sde_hdcp_version(dp->link->hdcp_status.hdcp_version),
		sde_hdcp_state_name(dp->link->hdcp_status.hdcp_state));

	if (dp->debug->force_encryption && ops && ops->force_encryption)
		ops->force_encryption(data, dp->debug->force_encryption);

	switch (dp->link->hdcp_status.hdcp_state) {
	case HDCP_STATE_AUTHENTICATING:
		if (dp->hdcp.ops && dp->hdcp.ops->authenticate)
			rc = dp->hdcp.ops->authenticate(dp->hdcp.data);
			rc = dp->hdcp.ops->authenticate(data);
		break;
	case HDCP_STATE_AUTH_FAIL:
		if (dp_display_is_ready(dp) && dp->power_on) {
			if (ops && ops->reauthenticate) {
				rc = ops->reauthenticate(dp->hdcp.data);
				rc = ops->reauthenticate(data);
				if (rc)
					pr_err("failed rc=%d\n", rc);
			}
@@ -1028,6 +1033,9 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
	struct dp_panel_in panel_in = {
		.dev = dev,
	};
	struct dp_debug_in debug_in = {
		.dev = dev,
	};

	mutex_init(&dp->session_lock);

@@ -1143,11 +1151,17 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
		goto error_hpd;
	}

	dp->debug = dp_debug_get(dev, dp->panel, dp->hpd,
				dp->link, dp->aux,
				&dp->dp_display.base_connector,
				dp->catalog, dp->parser);
	dp_display_initialize_hdcp(dp);

	debug_in.panel = dp->panel;
	debug_in.hpd = dp->hpd;
	debug_in.link = dp->link;
	debug_in.aux = dp->aux;
	debug_in.connector = &dp->dp_display.base_connector;
	debug_in.catalog = dp->catalog;
	debug_in.parser = dp->parser;

	dp->debug = dp_debug_get(&debug_in);
	if (IS_ERR(dp->debug)) {
		rc = PTR_ERR(dp->debug);
		pr_err("failed to initialize debug, rc = %d\n", rc);
@@ -1201,8 +1215,6 @@ static int dp_display_post_init(struct dp_display *dp_display)
	if (rc)
		goto end;

	dp_display_initialize_hdcp(dp);

	dp_display->post_init = NULL;
end:
	pr_debug("%s\n", rc ? "failed" : "success");
+21 −0
Original line number Diff line number Diff line
@@ -438,6 +438,26 @@ static bool dp_hdcp2p2_feature_supported(void *input)
	return supported;
}

static void dp_hdcp2p2_force_encryption(void *data, bool enable)
{
	struct dp_hdcp2p2_ctrl *ctrl = data;
	struct sde_hdcp_2x_ops *lib = NULL;

	if (!ctrl) {
		pr_err("invalid input\n");
		return;
	}

	lib = ctrl->lib;
	if (!lib) {
		pr_err("invalid lib ops data\n");
		return;
	}

	if (lib->force_encryption)
		lib->force_encryption(ctrl->lib_ctx, enable);
}

static void dp_hdcp2p2_send_msg_work(struct kthread_work *work)
{
	int rc = 0;
@@ -788,6 +808,7 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
		.reauthenticate = dp_hdcp2p2_reauthenticate,
		.authenticate = dp_hdcp2p2_authenticate,
		.feature_supported = dp_hdcp2p2_feature_supported,
		.force_encryption = dp_hdcp2p2_force_encryption,
		.off = dp_hdcp2p2_off,
		.cp_irq = dp_hdcp2p2_cp_irq,
	};
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct sde_hdcp_ops {
	int (*reauthenticate)(void *input);
	int (*authenticate)(void *hdcp_ctrl);
	bool (*feature_supported)(void *input);
	void (*force_encryption)(void *input, bool enable);
	void (*off)(void *hdcp_ctrl);
};

Loading