|
@@ -1219,8 +1219,15 @@ static int dsi_panel_parse_qsync_caps(struct dsi_panel *panel,
|
|
|
struct device_node *of_node)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
- u32 val = 0;
|
|
|
+ u32 val = 0, i;
|
|
|
+ struct dsi_qsync_capabilities *qsync_caps = &panel->qsync_caps;
|
|
|
+ struct dsi_parser_utils *utils = &panel->utils;
|
|
|
+ const char *name = panel->name;
|
|
|
|
|
|
+ /**
|
|
|
+ * "mdss-dsi-qsync-min-refresh-rate" is defined in cmd mode and
|
|
|
+ * video mode when there is only one qsync min fps present.
|
|
|
+ */
|
|
|
rc = of_property_read_u32(of_node,
|
|
|
"qcom,mdss-dsi-qsync-min-refresh-rate",
|
|
|
&val);
|
|
@@ -1228,8 +1235,75 @@ static int dsi_panel_parse_qsync_caps(struct dsi_panel *panel,
|
|
|
DSI_DEBUG("[%s] qsync min fps not defined rc:%d\n",
|
|
|
panel->name, rc);
|
|
|
|
|
|
- panel->qsync_min_fps = val;
|
|
|
+ qsync_caps->qsync_min_fps = val;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * "dsi-supported-qsync-min-fps-list" may be defined in video
|
|
|
+ * mode, only in dfps case when "qcom,dsi-supported-dfps-list"
|
|
|
+ * is defined.
|
|
|
+ */
|
|
|
+ qsync_caps->qsync_min_fps_list_len = utils->count_u32_elems(utils->data,
|
|
|
+ "qcom,dsi-supported-qsync-min-fps-list");
|
|
|
+ if (qsync_caps->qsync_min_fps_list_len < 1)
|
|
|
+ goto qsync_support;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * qcom,dsi-supported-qsync-min-fps-list cannot be defined
|
|
|
+ * along with qcom,mdss-dsi-qsync-min-refresh-rate.
|
|
|
+ */
|
|
|
+ if (qsync_caps->qsync_min_fps_list_len >= 1 &&
|
|
|
+ qsync_caps->qsync_min_fps) {
|
|
|
+ DSI_ERR("[%s] Both qsync nodes are defined\n",
|
|
|
+ name);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (panel->dfps_caps.dfps_list_len !=
|
|
|
+ qsync_caps->qsync_min_fps_list_len) {
|
|
|
+ DSI_ERR("[%s] Qsync min fps list mismatch with dfps\n", name);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
+ qsync_caps->qsync_min_fps_list =
|
|
|
+ kcalloc(qsync_caps->qsync_min_fps_list_len, sizeof(u32),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!qsync_caps->qsync_min_fps_list) {
|
|
|
+ rc = -ENOMEM;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = utils->read_u32_array(utils->data,
|
|
|
+ "qcom,dsi-supported-qsync-min-fps-list",
|
|
|
+ qsync_caps->qsync_min_fps_list,
|
|
|
+ qsync_caps->qsync_min_fps_list_len);
|
|
|
+ if (rc) {
|
|
|
+ DSI_ERR("[%s] Qsync min fps list parse failed\n", name);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
+ qsync_caps->qsync_min_fps = qsync_caps->qsync_min_fps_list[0];
|
|
|
|
|
|
+ for (i = 1; i < qsync_caps->qsync_min_fps_list_len; i++) {
|
|
|
+ if (qsync_caps->qsync_min_fps_list[i] <
|
|
|
+ qsync_caps->qsync_min_fps)
|
|
|
+ qsync_caps->qsync_min_fps =
|
|
|
+ qsync_caps->qsync_min_fps_list[i];
|
|
|
+ }
|
|
|
+
|
|
|
+qsync_support:
|
|
|
+ /* allow qsync support only if DFPS is with VFP approach */
|
|
|
+ if ((panel->dfps_caps.dfps_support) &&
|
|
|
+ !(panel->dfps_caps.type == DSI_DFPS_IMMEDIATE_VFP))
|
|
|
+ panel->qsync_caps.qsync_min_fps = 0;
|
|
|
+
|
|
|
+error:
|
|
|
+ if (rc < 0) {
|
|
|
+ qsync_caps->qsync_min_fps = 0;
|
|
|
+ qsync_caps->qsync_min_fps_list_len = 0;
|
|
|
+ }
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -3396,11 +3470,6 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
|
|
|
if (rc)
|
|
|
DSI_DEBUG("failed to parse qsync features, rc=%d\n", rc);
|
|
|
|
|
|
- /* allow qsync support only if DFPS is with VFP approach */
|
|
|
- if ((panel->dfps_caps.dfps_support) &&
|
|
|
- !(panel->dfps_caps.type == DSI_DFPS_IMMEDIATE_VFP))
|
|
|
- panel->qsync_min_fps = 0;
|
|
|
-
|
|
|
rc = dsi_panel_parse_dyn_clk_caps(panel);
|
|
|
if (rc)
|
|
|
DSI_ERR("failed to parse dynamic clk config, rc=%d\n", rc);
|