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

Commit 8cafdb1b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/dsi-staging: Add a new bridge DTS property support" into dev/msm-4.14-display

parents d32ced0b 3ff92672
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@
#include <drm/drm_mipi_dsi.h>
#include "msm_drv.h"

#define MAX_EXT_BRIDGE_PORT_CONFIG             16
#define MAX_DSI_CTRLS_PER_DISPLAY             2

#define DSI_H_TOTAL(t) (((t)->h_active) + ((t)->h_back_porch) + \
			((t)->h_sync_width) + ((t)->h_front_porch))

@@ -452,7 +455,9 @@ struct dsi_split_link_config {
 * @ignore_rx_eot:       Ignore Rx EOT packets if set to true.
 * @append_tx_eot:       Append EOT packets for forward transmissions if set to
 *                       true.
 * @ext_bridge_mode:     External bridge is connected.
 * @ext_bridge_num:      Connected external bridge count.
 * @ext_bridge_map:      External bridge config reg needs to match with the port
 *                       reg config.
 * @force_hs_clk_lane:   Send continuous clock to the panel.
 * @dsi_split_link_config:  Split Link Configuration.
 */
@@ -473,7 +478,8 @@ struct dsi_host_common_cfg {
	u32 t_clk_pre;
	bool ignore_rx_eot;
	bool append_tx_eot;
	bool ext_bridge_mode;
	u32 ext_bridge_num;
	u32 ext_bridge_map[MAX_DSI_CTRLS_PER_DISPLAY];
	bool force_hs_clk_lane;
	struct dsi_split_link_config split_link;
};
+30 −35
Original line number Diff line number Diff line
@@ -3606,13 +3606,11 @@ static int dsi_display_parse_dt(struct dsi_display *display)
	/* Parse TE data */
	dsi_display_parse_te_data(display);

	/* Parse all external bridges from port 0 */
	display_for_each_ctrl(i, display) {
	/* Parse all external bridges config, endpoint0 */
	for (i = 0; i < MAX_EXT_BRIDGE_PORT_CONFIG; i++) {
		display->ext_bridge[i].node_of =
			of_graph_get_remote_node(of_node, 0, i);
		if (display->ext_bridge[i].node_of)
			display->ext_bridge_cnt++;
		else
		if (!display->ext_bridge[i].node_of)
			break;
	}

@@ -4898,7 +4896,7 @@ static int dsi_display_bind(struct device *dev,
	char *client1 = "dsi_clk_client";
	char *client2 = "mdp_event_client";
	char dsi_client_name[DSI_CLIENT_NAME_SIZE];
	int i, rc = 0;
	int i, j, rc = 0;

	if (!dev || !pdev || !master) {
		pr_err("invalid param(s), dev %pK, pdev %pK, master %pK\n",
@@ -4919,14 +4917,17 @@ static int dsi_display_bind(struct device *dev,
		return 0;

	/* defer bind if ext bridge driver is not loaded */
	if (display->panel && display->panel->host_config.ext_bridge_mode) {
		for (i = 0; i < display->ext_bridge_cnt; i++) {
			if (!of_drm_find_bridge(
					display->ext_bridge[i].node_of)) {
				pr_debug("defer for bridge[%d] %s\n", i,
				  display->ext_bridge[i].node_of->full_name);
				return -EPROBE_DEFER;
	for (i = 0; i < display->panel->host_config.ext_bridge_num; i++) {
		j = display->panel->host_config.ext_bridge_map[i];
		if (!display->ext_bridge[j].node_of) {
			pr_err("invalid ext bridge node\n");
			return -EINVAL;
		}

		if (!of_drm_find_bridge(display->ext_bridge[j].node_of)) {
			pr_debug("defer for bridge[%d] %s\n", j,
				display->ext_bridge[j].node_of->full_name);
			return -EPROBE_DEFER;
		}
	}

@@ -5585,11 +5586,9 @@ static struct dsi_display_ext_bridge *dsi_display_ext_get_bridge(
{
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	struct list_head *connector_list;
	struct drm_connector *conn_iter;
	struct sde_connector *sde_conn;
	struct dsi_display *display;
	int i;
	int i, j, k;
	u32 bridge_num;

	if (!bridge || !bridge->encoder) {
		SDE_ERROR("invalid argument\n");
@@ -5598,16 +5597,14 @@ static struct dsi_display_ext_bridge *dsi_display_ext_get_bridge(

	priv = bridge->dev->dev_private;
	sde_kms = to_sde_kms(priv->kms);
	connector_list = &sde_kms->dev->mode_config.connector_list;

	list_for_each_entry(conn_iter, connector_list, head) {
		sde_conn = to_sde_connector(conn_iter);
		if (sde_conn->encoder == bridge->encoder) {
			display = sde_conn->display;
			display_for_each_ctrl(i, display) {
				if (display->ext_bridge[i].bridge == bridge)
					return &display->ext_bridge[i];
			}
	for (i = 0; i < sde_kms->dsi_display_count; i++) {
		display = sde_kms->dsi_displays[i];
		bridge_num = display->panel->host_config.ext_bridge_num;
		for (j = 0; j < bridge_num; j++) {
			k = display->panel->host_config.ext_bridge_map[j];
			if (display->ext_bridge[k].bridge == bridge)
				return &display->ext_bridge[k];
		}
	}

@@ -5771,12 +5768,10 @@ int dsi_display_drm_ext_bridge_init(struct dsi_display *display,
	struct drm_bridge *prev_bridge = bridge;
	int rc = 0, i;

	if (display->panel && !display->panel->host_config.ext_bridge_mode)
		return 0;

	for (i = 0; i < display->ext_bridge_cnt; i++) {
	for (i = 0; i < display->panel->host_config.ext_bridge_num; i++) {
		int j = display->panel->host_config.ext_bridge_map[i];
		struct dsi_display_ext_bridge *ext_bridge_info =
				&display->ext_bridge[i];
				&display->ext_bridge[j];

		/* return if ext bridge is already initialized */
		if (ext_bridge_info->bridge)
@@ -5790,7 +5785,7 @@ int dsi_display_drm_ext_bridge_init(struct dsi_display *display,
		}

		/* override functions for mode adjustment */
		if (display->ext_bridge_cnt > 1) {
		if (display->panel->host_config.ext_bridge_num > 1) {
			ext_bridge_info->bridge_funcs = *ext_bridge->funcs;
			if (ext_bridge->funcs->mode_fixup)
				ext_bridge_info->bridge_funcs.mode_fixup =
@@ -5835,7 +5830,7 @@ int dsi_display_drm_ext_bridge_init(struct dsi_display *display,
		if (!display->ext_conn ||
		    !display->ext_conn->funcs ||
		    !display->ext_conn->helper_private ||
		    display->ext_bridge_cnt > 1) {
		    display->panel->host_config.ext_bridge_num > 1) {
			display->ext_conn = NULL;
			continue;
		}
+1 −4
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@
#include "dsi_phy.h"
#include "dsi_panel.h"

#define MAX_DSI_CTRLS_PER_DISPLAY             2
#define DSI_CLIENT_NAME_SIZE		20
#define MAX_CMDLINE_PARAM_LEN	 512
#define MAX_CMD_PAYLOAD_SIZE	256
@@ -160,7 +159,6 @@ struct dsi_display_ext_bridge {
 * @panel:            Handle to DSI panel.
 * @panel_of:         pHandle to DSI panel.
 * @ext_bridge:       External bridge information for DSI display.
 * @ext_bridge_cnt:   Number of external bridges
 * @modes:            Array of probed DSI modes
 * @type:             DSI display type.
 * @clk_master_idx:   The master controller for controlling clocks. This is an
@@ -216,8 +214,7 @@ struct dsi_display {
	struct device_node *parser_node;

	/* external bridge */
	struct dsi_display_ext_bridge ext_bridge[MAX_DSI_CTRLS_PER_DISPLAY];
	u32 ext_bridge_cnt;
	struct dsi_display_ext_bridge ext_bridge[MAX_EXT_BRIDGE_PORT_CONFIG];

	struct dsi_display_mode *modes;

+64 −15
Original line number Diff line number Diff line
@@ -414,7 +414,7 @@ static int dsi_panel_set_pinctrl_state(struct dsi_panel *panel, bool enable)
	int rc = 0;
	struct pinctrl_state *state;

	if (panel->host_config.ext_bridge_mode)
	if (panel->host_config.ext_bridge_num)
		return 0;

	if (enable)
@@ -548,7 +548,7 @@ static int dsi_panel_pinctrl_deinit(struct dsi_panel *panel)
{
	int rc = 0;

	if (panel->host_config.ext_bridge_mode)
	if (panel->host_config.ext_bridge_num)
		return 0;

	devm_pinctrl_put(panel->pinctrl.pinctrl);
@@ -560,7 +560,7 @@ static int dsi_panel_pinctrl_init(struct dsi_panel *panel)
{
	int rc = 0;

	if (panel->host_config.ext_bridge_mode)
	if (panel->host_config.ext_bridge_num)
		return 0;

	/* TODO:  pinctrl is defined in dsi dt node */
@@ -683,7 +683,7 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl)
	int rc = 0;
	struct dsi_backlight_config *bl = &panel->bl_config;

	if (panel->host_config.ext_bridge_mode)
	if (panel->host_config.ext_bridge_num)
		return 0;

	pr_debug("backlight type:%d lvl:%d\n", bl->type, bl_lvl);
@@ -764,7 +764,7 @@ static int dsi_panel_bl_register(struct dsi_panel *panel)
	int rc = 0;
	struct dsi_backlight_config *bl = &panel->bl_config;

	if (panel->host_config.ext_bridge_mode)
	if (panel->host_config.ext_bridge_num)
		return 0;

	switch (bl->type) {
@@ -800,7 +800,7 @@ static int dsi_panel_bl_unregister(struct dsi_panel *panel)
	int rc = 0;
	struct dsi_backlight_config *bl = &panel->bl_config;

	if (panel->host_config.ext_bridge_mode)
	if (panel->host_config.ext_bridge_num)
		return 0;

	switch (bl->type) {
@@ -1134,6 +1134,51 @@ static int dsi_panel_parse_triggers(struct dsi_host_common_cfg *host,
	return rc;
}

static int dsi_panel_parse_ext_bridge_config(struct dsi_host_common_cfg *host,
					    struct dsi_parser_utils *utils,
					    const char *name)
{
	u32 len = 0, i = 0;
	int rc = 0;

	host->ext_bridge_num = 0;

	len = utils->count_u32_elems(utils->data, "qcom,mdss-dsi-ext-bridge");

	if (len > MAX_DSI_CTRLS_PER_DISPLAY) {
		pr_debug("[%s] Invalid ext bridge count set\n", name);
		return -EINVAL;
	}

	if (len == 0) {
		pr_debug("[%s] It's a DSI panel, not bridge\n", name);
		return rc;
	}

	rc = utils->read_u32_array(utils->data, "qcom,mdss-dsi-ext-bridge",
			host->ext_bridge_map,
			len);

	if (rc) {
		pr_debug("[%s] Did not get ext bridge set\n", name);
		return rc;
	}

	for (i = 0; i < len; i++) {
		if (host->ext_bridge_map[i] >= MAX_EXT_BRIDGE_PORT_CONFIG) {
			pr_debug("[%s] Invalid bridge port value %d\n",
				name, host->ext_bridge_map[i]);
			return -EINVAL;
		}
	}

	host->ext_bridge_num = len;

	pr_debug("[%s] ext bridge count is %d\n", name, host->ext_bridge_num);

	return rc;
}

static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host,
					    struct dsi_parser_utils *utils,
					    const char *name)
@@ -1160,9 +1205,6 @@ static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host,
	host->append_tx_eot = utils->read_bool(utils->data,
						"qcom,mdss-dsi-tx-eot-append");

	host->ext_bridge_mode = utils->read_bool(utils->data,
					"qcom,mdss-dsi-ext-bridge-mode");

	host->force_hs_clk_lane = utils->read_bool(utils->data,
					"qcom,mdss-dsi-force-clock-lane-hs");
	return 0;
@@ -1251,6 +1293,13 @@ static int dsi_panel_parse_host_config(struct dsi_panel *panel)
		goto error;
	}

	dsi_panel_parse_ext_bridge_config(&panel->host_config, utils,
					      panel->name);
	if (rc) {
		pr_err("[%s] failed to parse ext bridge config, rc=%d\n",
		       panel->name, rc);
	}

	dsi_panel_parse_split_link_config(&panel->host_config, utils,
						panel->name);

@@ -1893,7 +1942,7 @@ static int dsi_panel_parse_reset_sequence(struct dsi_panel *panel)
	struct dsi_parser_utils *utils = &panel->utils;
	struct dsi_reset_seq *seq;

	if (panel->host_config.ext_bridge_mode)
	if (panel->host_config.ext_bridge_num)
		return 0;

	arr = utils->get_property(utils->data,
@@ -2030,7 +2079,7 @@ static int dsi_panel_parse_power_cfg(struct dsi_panel *panel)
	int rc = 0;
	char *supply_name;

	if (panel->host_config.ext_bridge_mode)
	if (panel->host_config.ext_bridge_num)
		return 0;

	if (!strcmp(panel->type, "primary"))
@@ -2067,7 +2116,7 @@ static int dsi_panel_parse_gpios(struct dsi_panel *panel)
	panel->reset_config.reset_gpio = utils->get_named_gpio(utils->data,
					      reset_gpio_name, 0);
	if (!gpio_is_valid(panel->reset_config.reset_gpio) &&
		!panel->host_config.ext_bridge_mode) {
		!panel->host_config.ext_bridge_num) {
		rc = panel->reset_config.reset_gpio;
		pr_err("[%s] failed get reset gpio, rc=%d\n", panel->name, rc);
		goto error;
@@ -3392,14 +3441,14 @@ int dsi_panel_get_mode_count(struct dsi_panel *panel)

	timings_np = utils->get_child_by_name(utils->data,
			"qcom,mdss-dsi-display-timings");
	if (!timings_np && !panel->host_config.ext_bridge_mode) {
	if (!timings_np && !panel->host_config.ext_bridge_num) {
		pr_err("no display timing nodes defined\n");
		rc = -EINVAL;
		goto error;
	}

	count = utils->get_child_count(timings_np);
	if ((!count && !panel->host_config.ext_bridge_mode) ||
	if ((!count && !panel->host_config.ext_bridge_num) ||
		count > DSI_MODE_MAX) {
		pr_err("invalid count of timing nodes: %d\n", count);
		rc = -EINVAL;
@@ -3408,7 +3457,7 @@ int dsi_panel_get_mode_count(struct dsi_panel *panel)

	/* No multiresolution support is available for video mode panels */
	if (panel->panel_mode != DSI_OP_CMD_MODE &&
		!panel->host_config.ext_bridge_mode)
		!panel->host_config.ext_bridge_num)
		count = SINGLE_MODE_SUPPORT;

	panel->num_timing_nodes = count;