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

Commit 7e9613a3 authored by Chandan Uddaraju's avatar Chandan Uddaraju
Browse files

drm/msm/dsi-staging: update topology parsing logic



The kernel command-line string is changed and the
parsing will be done in DSI display module. Add
support to enable topology parsing in DSI
display module.

Change-Id: I4864bedf69724c746224eedc064b6144b61ded50
Signed-off-by: default avatarChandan Uddaraju <chandanu@codeaurora.org>
parent ded9c568
Loading
Loading
Loading
Loading
+46 −12
Original line number Diff line number Diff line
@@ -28,11 +28,12 @@
#include "dsi_pwr.h"

#define to_dsi_display(x) container_of(x, struct dsi_display, host)
#define INT_BASE_10 10

static DEFINE_MUTEX(dsi_display_list_lock);
static LIST_HEAD(dsi_display_list);
static char dsi_display_primary[DSI_DISPLAY_MAX_LEN];
static char dsi_display_secondary[DSI_DISPLAY_MAX_LEN];
static char dsi_display_primary[MAX_CMDLINE_PARAM_LEN];
static char dsi_display_secondary[MAX_CMDLINE_PARAM_LEN];
static struct dsi_display_boot_param boot_displays[MAX_DSI_ACTIVE_DISPLAY];
static struct device_node *default_active_node;
static const struct of_device_id dsi_display_dt_match[] = {
@@ -557,6 +558,31 @@ static int dsi_display_ctrl_power_off(struct dsi_display *display)
	return rc;
}

static int dsi_display_parse_cmdline_topology(unsigned int display_type)
{
	char *str = NULL;
	int top_index = -1;

	if (display_type >= MAX_DSI_ACTIVE_DISPLAY) {
		pr_err("display_type=%d not supported\n", display_type);
		return -EINVAL;
	}
	if (display_type == DSI_PRIMARY)
		str = strnstr(dsi_display_primary,
			":config", strlen(dsi_display_primary));
	else
		str = strnstr(dsi_display_secondary,
			":config", strlen(dsi_display_secondary));
	if (!str)
		return -EINVAL;

	if (kstrtol(str + strlen(":config"), INT_BASE_10,
				(unsigned long *)&top_index))
		return -EINVAL;

	return top_index;
}

/**
 * dsi_display_name_compare()- compare whether DSI display name matches.
 * @node:	Pointer to device node structure
@@ -589,7 +615,7 @@ static bool dsi_display_name_compare(struct device_node *node,
static int dsi_display_parse_boot_display_selection(void)
{
	char *pos = NULL;
	char disp_buf[DSI_DISPLAY_MAX_LEN] = {'\0'};
	char disp_buf[MAX_CMDLINE_PARAM_LEN] = {'\0'};
	int i, j, num_displays;

	if (strlen(dsi_display_primary) == 0)
@@ -1955,7 +1981,8 @@ static int dsi_display_res_init(struct dsi_display *display)
		}
	}

	display->panel = dsi_panel_get(&display->pdev->dev, display->panel_of);
	display->panel = dsi_panel_get(&display->pdev->dev, display->panel_of,
						display->cmdline_topology);
	if (IS_ERR_OR_NULL(display->panel)) {
		rc = PTR_ERR(display->panel);
		pr_err("failed to get panel, rc=%d\n", rc);
@@ -2742,7 +2769,8 @@ int dsi_display_dev_probe(struct platform_device *pdev)
		boot_displays_parsed = true;
	}


	/* Initialize cmdline_topology to use default topology */
	display->cmdline_topology = -1;
	if ((!display_from_cmdline) &&
			(boot_displays[DSI_PRIMARY].boot_disp_en)) {
		display->is_active = dsi_display_name_compare(pdev->dev.of_node,
@@ -2765,6 +2793,8 @@ int dsi_display_dev_probe(struct platform_device *pdev)
			pr_debug("cmdline primary dsi: %s\n",
						display->name);
			display_from_cmdline = true;
			display->cmdline_topology =
				dsi_display_parse_cmdline_topology(DSI_PRIMARY);
			primary_np = pdev->dev.of_node;
		}
	}
@@ -2777,15 +2807,19 @@ int dsi_display_dev_probe(struct platform_device *pdev)
							display->name);
				secondary_np = pdev->dev.of_node;
				if (primary_np) {
					if (validate_dsi_display_selection())
					if (validate_dsi_display_selection()) {
					display->is_active = true;
					else
					display->cmdline_topology =
					dsi_display_parse_cmdline_topology
							(DSI_SECONDARY);
					} else {
						boot_displays[DSI_SECONDARY]
							.boot_disp_en = false;
					}
				}
			}
		}
	}
	display->display_type = of_get_property(pdev->dev.of_node,
						"qcom,display-type", NULL);
	if (!display->display_type)
@@ -3669,13 +3703,13 @@ static void __exit dsi_display_unregister(void)
	dsi_ctrl_drv_unregister();
	dsi_phy_drv_unregister();
}
module_param_string(dsi_display0, dsi_display_primary, DSI_DISPLAY_MAX_LEN,
module_param_string(dsi_display0, dsi_display_primary, MAX_CMDLINE_PARAM_LEN,
								0600);
MODULE_PARM_DESC(dsi_display0,
	"msm_drm.dsi_display0=<display node>: where <display node> is 'primary dsi display node name'");
module_param_string(dsi_display1, dsi_display_secondary, DSI_DISPLAY_MAX_LEN,
	"msm_drm.dsi_display0=<display node>:<configX> where <display node> is 'primary dsi display node name' and <configX> where x represents index in the topology list");
module_param_string(dsi_display1, dsi_display_secondary, MAX_CMDLINE_PARAM_LEN,
								0600);
MODULE_PARM_DESC(dsi_display1,
	"msm_drm.dsi_display1=<display node>: where <display node> is 'Secondary dsi display node name'");
	"msm_drm.dsi_display1=<display node>:<configX> where <display node> is 'secondary dsi display node name' and <configX> where x represents index in the topology list");
module_init(dsi_display_register);
module_exit(dsi_display_unregister);
+6 −3
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@

#define MAX_DSI_CTRLS_PER_DISPLAY             2
#define DSI_CLIENT_NAME_SIZE		20
#define DSI_DISPLAY_MAX_LEN	 512
#define MAX_CMDLINE_PARAM_LEN	 512
/*
 * DSI Validate Mode modifiers
 * @DSI_VALIDATE_FLAG_ALLOW_ADJUST:	Allow mode validation to also do fixup
@@ -97,14 +97,15 @@ struct dsi_display_ctrl {
 * @boot_disp_en:bool to indicate dtsi availability of display node
 * @is_primary:bool to indicate whether current display is primary display
 * @length:length of DSI display.
 * @cmdline_topology: Display topology shared from kernel command line.
 */
struct dsi_display_boot_param {
	char name[DSI_DISPLAY_MAX_LEN];
	char name[MAX_CMDLINE_PARAM_LEN];
	bool boot_disp_en;
	bool is_primary;
	int length;
	struct device_node *node;

	int cmdline_topology;
};

/**
@@ -141,6 +142,7 @@ struct dsi_display_clk_info {
 * @config:           DSI host configuration information.
 * @lane_map:         Lane mapping between DSI host and Panel.
 * @num_of_modes:     Number of modes supported by display.
 * @cmdline_topology: Display topology shared from kernel command line.
 * @is_tpg_enabled:   TPG state.
 * @ulps_enabled:     ulps state.
 * @clamp_enabled:    clamp state.
@@ -179,6 +181,7 @@ struct dsi_display {
	struct dsi_host_config config;
	struct dsi_lane_map lane_map;
	u32 num_of_modes;
	int cmdline_topology;
	bool is_tpg_enabled;
	bool ulps_enabled;
	bool clamp_enabled;
+12 −39
Original line number Diff line number Diff line
@@ -22,9 +22,6 @@
#include "dsi_panel.h"
#include "dsi_ctrl_hw.h"

#define MAX_CMDLINE_PARAM_LEN 256
static char display_config[MAX_CMDLINE_PARAM_LEN];

/**
 * topology is currently defined by a set of following 3 values:
 * 1. num of layer mixers
@@ -32,7 +29,6 @@ static char display_config[MAX_CMDLINE_PARAM_LEN];
 * 3. num of interfaces
 */
#define TOPOLOGY_SET_LEN 3
#define INT_BASE_10 10
#define MAX_TOPOLOGY 5

#define DSI_PANEL_DEFAULT_LABEL  "Default dsi panel"
@@ -2078,31 +2074,9 @@ static int dsi_panel_parse_hdr_config(struct dsi_panel *panel,
	return 0;
}

static int dsi_get_cmdline_top_override(void)
{
	char *str = display_config;
	int top_index = -1;

	/*
	 * This module need to be updated with needed cmd line argument parsing
	 * for other dsi parameters.
	 */
	if (strlcat(str, "\0", sizeof(str)) > sizeof(str))
		return -EINVAL;

	str = strnstr(display_config, "config", strlen(display_config));
	if (!str)
		return -EINVAL;

	if (kstrtol(str + strlen("config"), INT_BASE_10,
				(unsigned long *)&top_index))
		return -EINVAL;

	return top_index;
}

static int dsi_panel_parse_topology(struct dsi_panel *panel,
		struct device_node *of_node)
				struct device_node *of_node,
				int topology_override)
{
	struct msm_display_topology *topology;
	u32 top_count, top_sel, *array = NULL;
@@ -2143,12 +2117,13 @@ static int dsi_panel_parse_topology(struct dsi_panel *panel,
		top->num_intf = array[i * TOPOLOGY_SET_LEN + 2];
	};

	top_sel = dsi_get_cmdline_top_override();
	if (top_sel >= 0 && top_sel < top_count) {
		pr_info("overidden topology: lm: %d comp_enc:%d intf: %d\n",
			topology[top_sel].num_lm,
			topology[top_sel].num_enc,
			topology[top_sel].num_intf);
	if (topology_override >= 0 && topology_override < top_count) {
		pr_info("override topology: cfg:%d lm:%d comp_enc:%d intf:%d\n",
			topology_override,
			topology[topology_override].num_lm,
			topology[topology_override].num_enc,
			topology[topology_override].num_intf);
		top_sel = topology_override;
		goto parse_done;
	}

@@ -2266,7 +2241,8 @@ static int dsi_panel_parse_partial_update_caps(struct dsi_panel *panel,
}

struct dsi_panel *dsi_panel_get(struct device *parent,
				struct device_node *of_node)
				struct device_node *of_node,
				int topology_override)
{
	struct dsi_panel *panel;
	const char *data;
@@ -2323,7 +2299,7 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
				    DSI_V_TOTAL(&panel->mode.timing) *
				    panel->mode.timing.refresh_rate) / 1000;

	rc = dsi_panel_parse_topology(panel, of_node);
	rc = dsi_panel_parse_topology(panel, of_node, topology_override);
	if (rc) {
		pr_err("failed to parse panel topology, rc=%d\n", rc);
		goto error;
@@ -2970,6 +2946,3 @@ int dsi_panel_post_unprepare(struct dsi_panel *panel)
	mutex_unlock(&panel->panel_lock);
	return rc;
}

module_param_string(display_param, display_config, MAX_CMDLINE_PARAM_LEN, 0600);
MODULE_PARM_DESC(display_param, "format: configx - x indexes the selected topology from the display topology list. Index 0 corresponds to the first topology in the list");
+2 −1
Original line number Diff line number Diff line
@@ -205,7 +205,8 @@ static inline bool dsi_panel_initialized(struct dsi_panel *panel)
}

struct dsi_panel *dsi_panel_get(struct device *parent,
				struct device_node *of_node);
				struct device_node *of_node,
				int topology_override);
void dsi_panel_put(struct dsi_panel *panel);

int dsi_panel_drv_init(struct dsi_panel *panel, struct mipi_dsi_host *host);