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

Commit 7ca9e4ca authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

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

parents f025bc59 15e4a355
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);
			}
@@ -1033,6 +1038,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);

@@ -1148,11 +1156,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);
@@ -1206,8 +1220,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