Loading Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +3 −1 Original line number Diff line number Diff line Loading @@ -279,7 +279,8 @@ Optional properties: as below: --> Reset GPIO value --> Sleep value (in ms) - qcom,partial-update-enabled: Boolean used to enable partial panel update for command mode panels. Note, if a given optional qcom,* binding is not present, then the driver will configure the default values specified. Loading Loading @@ -378,5 +379,6 @@ Example: qcom,mdss-tear-check-rd-ptr-trigger-intr = <1281>; qcom,mdss-tear-check-frame-rate = <6000>; qcom,mdss-dsi-reset-sequence = <1 2>, <0 10>, <1 10>; qcom,partial-update-enabled; }; }; drivers/video/msm/mdss/mdss_dsi.c +41 −1 Original line number Diff line number Diff line Loading @@ -662,6 +662,43 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) return rc; } static int mdss_dsi_ctl_partial_update(struct mdss_panel_data *pdata) { int rc = -EINVAL; u32 data; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); /* DSI_COMMAND_MODE_MDP_STREAM_CTRL */ data = (((pdata->panel_info.roi_w * 3) + 1) << 16) | (pdata->panel_info.mipi.vc << 8) | DTYPE_DCS_LWRITE; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x60, data); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x58, data); /* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */ data = pdata->panel_info.roi_h << 16 | pdata->panel_info.roi_w; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x64, data); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x5C, data); if (ctrl_pdata->partial_update_fnc) rc = ctrl_pdata->partial_update_fnc(pdata); if (rc) { pr_err("%s: unable to initialize the panel\n", __func__); return rc; } return rc; } static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, int event, void *arg) { Loading Loading @@ -729,6 +766,9 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, rc = mdss_dsi_blank(pdata); } break; case MDSS_EVENT_ENABLE_PARTIAL_UPDATE: rc = mdss_dsi_ctl_partial_update(pdata); break; default: pr_debug("%s: unhandled event=%d\n", __func__, event); break; Loading drivers/video/msm/mdss/mdss_dsi.h +1 −0 Original line number Diff line number Diff line Loading @@ -315,6 +315,7 @@ struct mdss_dsi_ctrl_pdata { int ndx; /* panel_num */ int (*on) (struct mdss_panel_data *pdata); int (*off) (struct mdss_panel_data *pdata); int (*partial_update_fnc) (struct mdss_panel_data *pdata); struct mdss_panel_data panel_data; unsigned char *ctrl_base; int reg_size; Loading drivers/video/msm/mdss/mdss_dsi_panel.c +68 −0 Original line number Diff line number Diff line Loading @@ -231,6 +231,61 @@ void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) } } static char caset[] = {0x2a, 0x00, 0x00, 0x03, 0x00}; /* DTYPE_DCS_LWRITE */ static char paset[] = {0x2b, 0x00, 0x00, 0x05, 0x00}; /* DTYPE_DCS_LWRITE */ static struct dsi_cmd_desc partial_update_enable_cmd[] = { {{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(caset)}, caset}, {{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(paset)}, paset}, }; static int mdss_dsi_panel_partial_update(struct mdss_panel_data *pdata) { struct mipi_panel_info *mipi; struct mdss_dsi_ctrl_pdata *ctrl = NULL; struct dcs_cmd_req cmdreq; int rc = 0; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); mipi = &pdata->panel_info.mipi; pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); caset[1] = (((pdata->panel_info.roi_x) & 0xFF00) >> 8); caset[2] = (((pdata->panel_info.roi_x) & 0xFF)); caset[3] = (((pdata->panel_info.roi_x - 1 + pdata->panel_info.roi_w) & 0xFF00) >> 8); caset[4] = (((pdata->panel_info.roi_x - 1 + pdata->panel_info.roi_w) & 0xFF)); partial_update_enable_cmd[0].payload = caset; paset[1] = (((pdata->panel_info.roi_y) & 0xFF00) >> 8); paset[2] = (((pdata->panel_info.roi_y) & 0xFF)); paset[3] = (((pdata->panel_info.roi_y - 1 + pdata->panel_info.roi_h) & 0xFF00) >> 8); paset[4] = (((pdata->panel_info.roi_y - 1 + pdata->panel_info.roi_h) & 0xFF)); partial_update_enable_cmd[1].payload = paset; pr_debug("%s: enabling partial update\n", __func__); memset(&cmdreq, 0, sizeof(cmdreq)); cmdreq.cmds = partial_update_enable_cmd; cmdreq.cmds_cnt = 2; cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL; cmdreq.rlen = 0; cmdreq.cb = NULL; mdss_dsi_cmdlist_put(ctrl, &cmdreq); return rc; } static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, u32 bl_level) { Loading Loading @@ -850,6 +905,7 @@ int mdss_dsi_panel_init(struct device_node *node, int rc = 0; static const char *panel_name; bool cont_splash_enabled; bool partial_update_enabled; if (!node) { pr_err("%s: no panel node\n", __func__); Loading Loading @@ -886,6 +942,18 @@ int mdss_dsi_panel_init(struct device_node *node, ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1; } partial_update_enabled = of_property_read_bool(node, "qcom,partial-update-enabled"); if (partial_update_enabled) { pr_info("%s: Partial update enabled.\n", __func__); ctrl_pdata->panel_data.panel_info.partial_update_enabled = 1; ctrl_pdata->partial_update_fnc = mdss_dsi_panel_partial_update; } else { pr_info("%s: Partial update disabled.\n", __func__); ctrl_pdata->panel_data.panel_info.partial_update_enabled = 0; ctrl_pdata->partial_update_fnc = NULL; } ctrl_pdata->on = mdss_dsi_panel_on; ctrl_pdata->off = mdss_dsi_panel_off; ctrl_pdata->panel_data.set_backlight = mdss_dsi_panel_bl_ctrl; Loading drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +21 −0 Original line number Diff line number Diff line Loading @@ -431,10 +431,28 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) return rc; } static int mdss_mdp_cmd_set_partial_roi(struct mdss_mdp_ctl *ctl, struct mdss_mdp_img_rect *roi) { int rc = 0; if (roi->w && roi->h && ctl->panel_data->panel_info.partial_update_enabled) { ctl->panel_data->panel_info.roi_x = roi->x; ctl->panel_data->panel_info.roi_y = roi->y; ctl->panel_data->panel_info.roi_w = roi->w; ctl->panel_data->panel_info.roi_h = roi->h; rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_ENABLE_PARTIAL_UPDATE, NULL); } return rc; } int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_cmd_ctx *ctx; unsigned long flags; struct mdss_mdp_img_rect roi; int rc; ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data; Loading @@ -453,6 +471,9 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc); } roi = (struct mdss_mdp_img_rect){0, 0, ctl->width, ctl->height}; mdss_mdp_cmd_set_partial_roi(ctl, &roi); /* * tx dcs command if had any */ Loading Loading
Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +3 −1 Original line number Diff line number Diff line Loading @@ -279,7 +279,8 @@ Optional properties: as below: --> Reset GPIO value --> Sleep value (in ms) - qcom,partial-update-enabled: Boolean used to enable partial panel update for command mode panels. Note, if a given optional qcom,* binding is not present, then the driver will configure the default values specified. Loading Loading @@ -378,5 +379,6 @@ Example: qcom,mdss-tear-check-rd-ptr-trigger-intr = <1281>; qcom,mdss-tear-check-frame-rate = <6000>; qcom,mdss-dsi-reset-sequence = <1 2>, <0 10>, <1 10>; qcom,partial-update-enabled; }; };
drivers/video/msm/mdss/mdss_dsi.c +41 −1 Original line number Diff line number Diff line Loading @@ -662,6 +662,43 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) return rc; } static int mdss_dsi_ctl_partial_update(struct mdss_panel_data *pdata) { int rc = -EINVAL; u32 data; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); /* DSI_COMMAND_MODE_MDP_STREAM_CTRL */ data = (((pdata->panel_info.roi_w * 3) + 1) << 16) | (pdata->panel_info.mipi.vc << 8) | DTYPE_DCS_LWRITE; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x60, data); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x58, data); /* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */ data = pdata->panel_info.roi_h << 16 | pdata->panel_info.roi_w; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x64, data); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x5C, data); if (ctrl_pdata->partial_update_fnc) rc = ctrl_pdata->partial_update_fnc(pdata); if (rc) { pr_err("%s: unable to initialize the panel\n", __func__); return rc; } return rc; } static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, int event, void *arg) { Loading Loading @@ -729,6 +766,9 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, rc = mdss_dsi_blank(pdata); } break; case MDSS_EVENT_ENABLE_PARTIAL_UPDATE: rc = mdss_dsi_ctl_partial_update(pdata); break; default: pr_debug("%s: unhandled event=%d\n", __func__, event); break; Loading
drivers/video/msm/mdss/mdss_dsi.h +1 −0 Original line number Diff line number Diff line Loading @@ -315,6 +315,7 @@ struct mdss_dsi_ctrl_pdata { int ndx; /* panel_num */ int (*on) (struct mdss_panel_data *pdata); int (*off) (struct mdss_panel_data *pdata); int (*partial_update_fnc) (struct mdss_panel_data *pdata); struct mdss_panel_data panel_data; unsigned char *ctrl_base; int reg_size; Loading
drivers/video/msm/mdss/mdss_dsi_panel.c +68 −0 Original line number Diff line number Diff line Loading @@ -231,6 +231,61 @@ void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) } } static char caset[] = {0x2a, 0x00, 0x00, 0x03, 0x00}; /* DTYPE_DCS_LWRITE */ static char paset[] = {0x2b, 0x00, 0x00, 0x05, 0x00}; /* DTYPE_DCS_LWRITE */ static struct dsi_cmd_desc partial_update_enable_cmd[] = { {{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(caset)}, caset}, {{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(paset)}, paset}, }; static int mdss_dsi_panel_partial_update(struct mdss_panel_data *pdata) { struct mipi_panel_info *mipi; struct mdss_dsi_ctrl_pdata *ctrl = NULL; struct dcs_cmd_req cmdreq; int rc = 0; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); mipi = &pdata->panel_info.mipi; pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); caset[1] = (((pdata->panel_info.roi_x) & 0xFF00) >> 8); caset[2] = (((pdata->panel_info.roi_x) & 0xFF)); caset[3] = (((pdata->panel_info.roi_x - 1 + pdata->panel_info.roi_w) & 0xFF00) >> 8); caset[4] = (((pdata->panel_info.roi_x - 1 + pdata->panel_info.roi_w) & 0xFF)); partial_update_enable_cmd[0].payload = caset; paset[1] = (((pdata->panel_info.roi_y) & 0xFF00) >> 8); paset[2] = (((pdata->panel_info.roi_y) & 0xFF)); paset[3] = (((pdata->panel_info.roi_y - 1 + pdata->panel_info.roi_h) & 0xFF00) >> 8); paset[4] = (((pdata->panel_info.roi_y - 1 + pdata->panel_info.roi_h) & 0xFF)); partial_update_enable_cmd[1].payload = paset; pr_debug("%s: enabling partial update\n", __func__); memset(&cmdreq, 0, sizeof(cmdreq)); cmdreq.cmds = partial_update_enable_cmd; cmdreq.cmds_cnt = 2; cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL; cmdreq.rlen = 0; cmdreq.cb = NULL; mdss_dsi_cmdlist_put(ctrl, &cmdreq); return rc; } static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, u32 bl_level) { Loading Loading @@ -850,6 +905,7 @@ int mdss_dsi_panel_init(struct device_node *node, int rc = 0; static const char *panel_name; bool cont_splash_enabled; bool partial_update_enabled; if (!node) { pr_err("%s: no panel node\n", __func__); Loading Loading @@ -886,6 +942,18 @@ int mdss_dsi_panel_init(struct device_node *node, ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1; } partial_update_enabled = of_property_read_bool(node, "qcom,partial-update-enabled"); if (partial_update_enabled) { pr_info("%s: Partial update enabled.\n", __func__); ctrl_pdata->panel_data.panel_info.partial_update_enabled = 1; ctrl_pdata->partial_update_fnc = mdss_dsi_panel_partial_update; } else { pr_info("%s: Partial update disabled.\n", __func__); ctrl_pdata->panel_data.panel_info.partial_update_enabled = 0; ctrl_pdata->partial_update_fnc = NULL; } ctrl_pdata->on = mdss_dsi_panel_on; ctrl_pdata->off = mdss_dsi_panel_off; ctrl_pdata->panel_data.set_backlight = mdss_dsi_panel_bl_ctrl; Loading
drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +21 −0 Original line number Diff line number Diff line Loading @@ -431,10 +431,28 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) return rc; } static int mdss_mdp_cmd_set_partial_roi(struct mdss_mdp_ctl *ctl, struct mdss_mdp_img_rect *roi) { int rc = 0; if (roi->w && roi->h && ctl->panel_data->panel_info.partial_update_enabled) { ctl->panel_data->panel_info.roi_x = roi->x; ctl->panel_data->panel_info.roi_y = roi->y; ctl->panel_data->panel_info.roi_w = roi->w; ctl->panel_data->panel_info.roi_h = roi->h; rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_ENABLE_PARTIAL_UPDATE, NULL); } return rc; } int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_cmd_ctx *ctx; unsigned long flags; struct mdss_mdp_img_rect roi; int rc; ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data; Loading @@ -453,6 +471,9 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc); } roi = (struct mdss_mdp_img_rect){0, 0, ctl->width, ctl->height}; mdss_mdp_cmd_set_partial_roi(ctl, &roi); /* * tx dcs command if had any */ Loading