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

Commit ee89d210 authored by Padmanabhan Komanduru's avatar Padmanabhan Komanduru Committed by Gerrit - the friendly Code Review server
Browse files

drm: msm: dsi-staging: add support to specify DSI PHY timings in panel dtsi



Some DSI panels require non-standard values of DSI PHY timings for
certain parameters for correct operation. The auto-calculated values
of DSI PHY timings in these cases can show some corruption issues on
the panel. Add support to pass DSI PHY timing parameters from the panel
dtsi in such cases. These value will supersede the PHY timing calculation
logic which is present in the DSI PHY driver.

CRs-Fixed: 2008002
Change-Id: I4a9f7b3352c488070e54f455b30bcc45851f1286
Signed-off-by: default avatarPadmanabhan Komanduru <pkomandu@codeaurora.org>
Signed-off-by: default avatarShashank Babu Chinta Venkata <sbchin@codeaurora.org>
parent edfe6ffb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -79,6 +79,10 @@ then 3 options can be tried.

Optional properties:
- qcom,mdss-dsi-panel-name:		A string used as a descriptive name of the panel
- qcom,mdss-dsi-panel-phy-timings:	An array of length 'n' char that specifies the DSI PHY lane
					timing settings for the panel. This is specific to SDE DRM driver.
					The value of 'n' depends on the DSI PHY h/w revision and parsing this
					property properly will be taken care in the DSI PHY DRM driver.
- qcom,cmd-sync-wait-broadcast:		Boolean used to broadcast dcs command to panels.
- qcom,mdss-dsi-fbc-enable:		Boolean used to enable frame buffer compression mode.
- qcom,mdss-dsi-fbc-slice-height:	Slice height(in lines) of compressed block.
+2 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ static void dsi_catalog_phy_2_0_init(struct dsi_phy_hw *phy)
	phy->ops.phy_idle_off = dsi_phy_hw_v2_0_idle_off;
	phy->ops.calculate_timing_params =
		dsi_phy_hw_calculate_timing_params;
	phy->ops.phy_timing_val = dsi_phy_hw_timing_val_v2_0;
}

/**
@@ -166,6 +167,7 @@ static void dsi_catalog_phy_3_0_init(struct dsi_phy_hw *phy)
		dsi_phy_hw_v3_0_ulps_exit;
	phy->ops.ulps_ops.get_lanes_in_ulps =
		dsi_phy_hw_v3_0_get_lanes_in_ulps;
	phy->ops.phy_timing_val = dsi_phy_hw_timing_val_v3_0;
}

/**
+5 −0
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ void dsi_phy_hw_v2_0_enable(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg);
void dsi_phy_hw_v2_0_disable(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg);
void dsi_phy_hw_v2_0_idle_on(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg);
void dsi_phy_hw_v2_0_idle_off(struct dsi_phy_hw *phy);
int dsi_phy_hw_timing_val_v2_0(struct dsi_phy_per_lane_cfgs *timing_cfg,
		u32 *timing_val, u32 size);

/* Definitions for 10nm PHY hardware driver */
void dsi_phy_hw_v3_0_regulator_enable(struct dsi_phy_hw *phy,
@@ -95,6 +97,9 @@ void dsi_phy_hw_v3_0_ulps_request(struct dsi_phy_hw *phy,
void dsi_phy_hw_v3_0_ulps_exit(struct dsi_phy_hw *phy,
			struct dsi_phy_cfg *cfg, u32 lanes);
u32 dsi_phy_hw_v3_0_get_lanes_in_ulps(struct dsi_phy_hw *phy);
int dsi_phy_hw_timing_val_v3_0(struct dsi_phy_per_lane_cfgs *timing_cfg,
		u32 *timing_val, u32 size);

/* DSI controller common ops */
u32 dsi_ctrl_hw_cmn_get_interrupt_status(struct dsi_ctrl_hw *ctrl);
void dsi_ctrl_hw_cmn_clear_interrupt_status(struct dsi_ctrl_hw *ctrl, u32 ints);
+11 −0
Original line number Diff line number Diff line
@@ -1698,6 +1698,17 @@ static int dsi_display_res_init(struct dsi_display *display)
		goto error_ctrl_put;
	}

	if (display->panel->phy_timing_len) {
		for (i = 0; i < display->ctrl_count; i++) {
			ctrl = &display->ctrl[i];
			 rc = dsi_phy_set_timing_params(ctrl->phy,
				display->panel->phy_timing_val,
				display->panel->phy_timing_len);
			if (rc)
				pr_err("failed to add DSI PHY timing params");
		}
	}

	rc = dsi_display_parse_lane_map(display);
	if (rc) {
		pr_err("Lane map not found, rc=%d\n", rc);
+21 −0
Original line number Diff line number Diff line
@@ -1562,6 +1562,8 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
				struct device_node *of_node)
{
	struct dsi_panel *panel;
	const char *data;
	u32 len = 0;
	int rc = 0;

	panel = kzalloc(sizeof(*panel), GFP_KERNEL);
@@ -1579,6 +1581,25 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
		goto error;
	}

	data = of_get_property(of_node,
		"qcom,mdss-dsi-panel-phy-timings", &len);
	if (!data) {
		pr_debug("%s:%d, Unable to read Phy timing settings",
		       __func__, __LINE__);
	} else {
		int i = 0;

		panel->phy_timing_val = kzalloc((sizeof(u32) * len),
			GFP_KERNEL);
		if (!panel->phy_timing_val) {
			kfree(panel);
			return ERR_PTR(-ENOMEM);
		}
		for (i = 0; i < len; i++)
			panel->phy_timing_val[i] = data[i];
	}
	panel->phy_timing_len = len;

	panel->mode.pixel_clk_khz = (DSI_H_TOTAL(&panel->mode.timing) *
				    DSI_V_TOTAL(&panel->mode.timing) *
				    panel->mode.timing.refresh_rate) / 1000;
Loading