Loading Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +25 −0 Original line number Diff line number Diff line Loading @@ -307,6 +307,27 @@ Optional properties: left, top, width, height alignments and minimum width and height values - qcom,esd-check-enabled: Boolean used to enable ESD recovery feature. - qcom,mdss-dsi-panel-status-command: A byte stream formed by multiple dcs packets based on qcom dsi controller protocol, to read the panel status. This value is used to kick in the ESD recovery. byte 0: dcs data type byte 1: set to indicate this is an individual packet (no chain) byte 2: virtual channel number byte 3: expect ack from client (dcs read command) byte 4: wait number of specified ms after dcs command transmitted byte 5, 6: 16 bits length in network byte order byte 7 and beyond: number byte of payload - qcom,mdss-dsi-panel-status-command-mode: String that specifies the ctrl state for reading the panel status. "dsi_lp_mode" = DSI low power mode "dsi_hs_mode" = DSI high speed mode - qcom,mdss-dsi-panel-status-check-mode:Specifies the panel status check method for ESD recovery. "bta_check" = Uses BTA to check the panel status "reg_read" = Reads panel status register to check the panel status - qcom,mdss-dsi-panel-status-value: Specifies the value of the panel status register when the panel is in good state. Note, if a given optional qcom,* binding is not present, then the driver will configure the default values specified. Loading Loading @@ -414,5 +435,9 @@ Example: qcom,ulps-enabled; qcom,panel-roi-alignment = <4 4 2 2 20 20>; qcom,esd-check-enabled; qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08]; qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode"; qcom,mdss-dsi-panel-status-check-mode = "reg_read"; qcom,mdss-dsi-panel-status-value = <0x9c>; }; }; drivers/video/msm/mdss/dsi_status_6g.c +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval) mutex_unlock(&mdp5_data->ov_lock); if (ctl->shared_lock) mutex_unlock(ctl->shared_lock); pr_err("%s: DSI turning off, avoiding BTA status check\n", pr_err("%s: DSI turning off, avoiding panel status check\n", __func__); return; } Loading drivers/video/msm/mdss/mdss_dsi.c +9 −1 Original line number Diff line number Diff line Loading @@ -1680,8 +1680,16 @@ int dsi_panel_device_register(struct device_node *pan_node, } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; if (ctrl_pdata->status_mode == ESD_REG) ctrl_pdata->check_status = mdss_dsi_reg_status_check; else if (ctrl_pdata->status_mode == ESD_BTA) ctrl_pdata->check_status = mdss_dsi_bta_status_check; if (ctrl_pdata->status_mode == ESD_MAX) { pr_err("%s: Using default BTA for ESD check\n", __func__); ctrl_pdata->check_status = mdss_dsi_bta_status_check; } if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); Loading drivers/video/msm/mdss/mdss_dsi.h +11 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,12 @@ enum dsi_panel_bl_ctrl { UNKNOWN_CTRL, }; enum dsi_panel_status_mode { ESD_BTA, ESD_REG, ESD_MAX, }; enum dsi_ctrl_op_mode { DSI_LP_MODE, DSI_HS_MODE, Loading Loading @@ -292,6 +298,8 @@ struct mdss_dsi_ctrl_pdata { struct dsi_panel_cmds on_cmds; struct dsi_panel_cmds off_cmds; struct dsi_panel_cmds status_cmds; u32 status_value; struct dcs_cmd_list cmdlist; struct completion dma_comp; Loading @@ -308,6 +316,8 @@ struct mdss_dsi_ctrl_pdata { struct dsi_buf tx_buf; struct dsi_buf rx_buf; struct dsi_buf status_buf; int status_mode; struct dsi_pinctrl_res pin_res; }; Loading Loading @@ -369,6 +379,7 @@ void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl); int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp); void mdss_dsi_cmdlist_kickoff(int intf); int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl); int mdss_dsi_reg_status_check(struct mdss_dsi_ctrl_pdata *ctrl); bool __mdss_dsi_clk_enabled(struct mdss_dsi_ctrl_pdata *ctrl, u8 clk_type); int mdss_dsi_panel_init(struct device_node *node, Loading drivers/video/msm/mdss/mdss_dsi_host.c +77 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev, mutex_init(&ctrl->cmd_mutex); mdss_dsi_buf_alloc(ctrl_dev, &ctrl->tx_buf, SZ_4K); mdss_dsi_buf_alloc(ctrl_dev, &ctrl->rx_buf, SZ_4K); mdss_dsi_buf_alloc(ctrl_dev, &ctrl->status_buf, SZ_4K); ctrl->cmdlist_commit = mdss_dsi_cmdlist_commit; Loading Loading @@ -613,6 +614,82 @@ void mdss_dsi_cmd_bta_sw_trigger(struct mdss_panel_data *pdata) pr_debug("%s: BTA done, status = %d\n", __func__, status); } static int mdss_dsi_read_status(struct mdss_dsi_ctrl_pdata *ctrl) { struct dcs_cmd_req cmdreq; memset(&cmdreq, 0, sizeof(cmdreq)); cmdreq.cmds = ctrl->status_cmds.cmds; cmdreq.cmds_cnt = ctrl->status_cmds.cmd_cnt; cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL | CMD_REQ_RX; cmdreq.rlen = 0; cmdreq.cb = NULL; cmdreq.rbuf = ctrl->status_buf.data; return mdss_dsi_cmdlist_put(ctrl, &cmdreq); } /** * mdss_dsi_reg_status_check() - Check dsi panel status through reg read * @ctrl_pdata: pointer to the dsi controller structure * * This function can be used to check the panel status through reading the * status register from the panel. * * Return: positive value if the panel is in good state, negative value or * zero otherwise. */ int mdss_dsi_reg_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata) { int ret = 0; if (ctrl_pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return 0; } pr_debug("%s: Checking Register status\n", __func__); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); if (ctrl_pdata->status_cmds.link_state == DSI_HS_MODE) mdss_dsi_set_tx_power_mode(0, &ctrl_pdata->panel_data); ret = mdss_dsi_read_status(ctrl_pdata); if (ctrl_pdata->status_cmds.link_state == DSI_HS_MODE) mdss_dsi_set_tx_power_mode(1, &ctrl_pdata->panel_data); if (ret == 0) { if (ctrl_pdata->status_buf.data[0] != ctrl_pdata->status_value) { pr_err("%s: Read back value from panel is incorrect\n", __func__); ret = -EINVAL; } else { ret = 1; } } else { pr_err("%s: Read status register returned error\n", __func__); } mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); pr_debug("%s: Read register done with ret: %d\n", __func__, ret); return ret; } /** * mdss_dsi_bta_status_check() - Check dsi panel status through bta check * @ctrl_pdata: pointer to the dsi controller structure * * This function can be used to check status of the panel using bta check * for the panel. * * Return: positive value if the panel is in good state, negative value or * zero otherwise. */ int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata) { int ret = 0; Loading Loading
Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +25 −0 Original line number Diff line number Diff line Loading @@ -307,6 +307,27 @@ Optional properties: left, top, width, height alignments and minimum width and height values - qcom,esd-check-enabled: Boolean used to enable ESD recovery feature. - qcom,mdss-dsi-panel-status-command: A byte stream formed by multiple dcs packets based on qcom dsi controller protocol, to read the panel status. This value is used to kick in the ESD recovery. byte 0: dcs data type byte 1: set to indicate this is an individual packet (no chain) byte 2: virtual channel number byte 3: expect ack from client (dcs read command) byte 4: wait number of specified ms after dcs command transmitted byte 5, 6: 16 bits length in network byte order byte 7 and beyond: number byte of payload - qcom,mdss-dsi-panel-status-command-mode: String that specifies the ctrl state for reading the panel status. "dsi_lp_mode" = DSI low power mode "dsi_hs_mode" = DSI high speed mode - qcom,mdss-dsi-panel-status-check-mode:Specifies the panel status check method for ESD recovery. "bta_check" = Uses BTA to check the panel status "reg_read" = Reads panel status register to check the panel status - qcom,mdss-dsi-panel-status-value: Specifies the value of the panel status register when the panel is in good state. Note, if a given optional qcom,* binding is not present, then the driver will configure the default values specified. Loading Loading @@ -414,5 +435,9 @@ Example: qcom,ulps-enabled; qcom,panel-roi-alignment = <4 4 2 2 20 20>; qcom,esd-check-enabled; qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08]; qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode"; qcom,mdss-dsi-panel-status-check-mode = "reg_read"; qcom,mdss-dsi-panel-status-value = <0x9c>; }; };
drivers/video/msm/mdss/dsi_status_6g.c +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval) mutex_unlock(&mdp5_data->ov_lock); if (ctl->shared_lock) mutex_unlock(ctl->shared_lock); pr_err("%s: DSI turning off, avoiding BTA status check\n", pr_err("%s: DSI turning off, avoiding panel status check\n", __func__); return; } Loading
drivers/video/msm/mdss/mdss_dsi.c +9 −1 Original line number Diff line number Diff line Loading @@ -1680,8 +1680,16 @@ int dsi_panel_device_register(struct device_node *pan_node, } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; if (ctrl_pdata->status_mode == ESD_REG) ctrl_pdata->check_status = mdss_dsi_reg_status_check; else if (ctrl_pdata->status_mode == ESD_BTA) ctrl_pdata->check_status = mdss_dsi_bta_status_check; if (ctrl_pdata->status_mode == ESD_MAX) { pr_err("%s: Using default BTA for ESD check\n", __func__); ctrl_pdata->check_status = mdss_dsi_bta_status_check; } if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); Loading
drivers/video/msm/mdss/mdss_dsi.h +11 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,12 @@ enum dsi_panel_bl_ctrl { UNKNOWN_CTRL, }; enum dsi_panel_status_mode { ESD_BTA, ESD_REG, ESD_MAX, }; enum dsi_ctrl_op_mode { DSI_LP_MODE, DSI_HS_MODE, Loading Loading @@ -292,6 +298,8 @@ struct mdss_dsi_ctrl_pdata { struct dsi_panel_cmds on_cmds; struct dsi_panel_cmds off_cmds; struct dsi_panel_cmds status_cmds; u32 status_value; struct dcs_cmd_list cmdlist; struct completion dma_comp; Loading @@ -308,6 +316,8 @@ struct mdss_dsi_ctrl_pdata { struct dsi_buf tx_buf; struct dsi_buf rx_buf; struct dsi_buf status_buf; int status_mode; struct dsi_pinctrl_res pin_res; }; Loading Loading @@ -369,6 +379,7 @@ void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl); int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp); void mdss_dsi_cmdlist_kickoff(int intf); int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl); int mdss_dsi_reg_status_check(struct mdss_dsi_ctrl_pdata *ctrl); bool __mdss_dsi_clk_enabled(struct mdss_dsi_ctrl_pdata *ctrl, u8 clk_type); int mdss_dsi_panel_init(struct device_node *node, Loading
drivers/video/msm/mdss/mdss_dsi_host.c +77 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev, mutex_init(&ctrl->cmd_mutex); mdss_dsi_buf_alloc(ctrl_dev, &ctrl->tx_buf, SZ_4K); mdss_dsi_buf_alloc(ctrl_dev, &ctrl->rx_buf, SZ_4K); mdss_dsi_buf_alloc(ctrl_dev, &ctrl->status_buf, SZ_4K); ctrl->cmdlist_commit = mdss_dsi_cmdlist_commit; Loading Loading @@ -613,6 +614,82 @@ void mdss_dsi_cmd_bta_sw_trigger(struct mdss_panel_data *pdata) pr_debug("%s: BTA done, status = %d\n", __func__, status); } static int mdss_dsi_read_status(struct mdss_dsi_ctrl_pdata *ctrl) { struct dcs_cmd_req cmdreq; memset(&cmdreq, 0, sizeof(cmdreq)); cmdreq.cmds = ctrl->status_cmds.cmds; cmdreq.cmds_cnt = ctrl->status_cmds.cmd_cnt; cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL | CMD_REQ_RX; cmdreq.rlen = 0; cmdreq.cb = NULL; cmdreq.rbuf = ctrl->status_buf.data; return mdss_dsi_cmdlist_put(ctrl, &cmdreq); } /** * mdss_dsi_reg_status_check() - Check dsi panel status through reg read * @ctrl_pdata: pointer to the dsi controller structure * * This function can be used to check the panel status through reading the * status register from the panel. * * Return: positive value if the panel is in good state, negative value or * zero otherwise. */ int mdss_dsi_reg_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata) { int ret = 0; if (ctrl_pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return 0; } pr_debug("%s: Checking Register status\n", __func__); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); if (ctrl_pdata->status_cmds.link_state == DSI_HS_MODE) mdss_dsi_set_tx_power_mode(0, &ctrl_pdata->panel_data); ret = mdss_dsi_read_status(ctrl_pdata); if (ctrl_pdata->status_cmds.link_state == DSI_HS_MODE) mdss_dsi_set_tx_power_mode(1, &ctrl_pdata->panel_data); if (ret == 0) { if (ctrl_pdata->status_buf.data[0] != ctrl_pdata->status_value) { pr_err("%s: Read back value from panel is incorrect\n", __func__); ret = -EINVAL; } else { ret = 1; } } else { pr_err("%s: Read status register returned error\n", __func__); } mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); pr_debug("%s: Read register done with ret: %d\n", __func__, ret); return ret; } /** * mdss_dsi_bta_status_check() - Check dsi panel status through bta check * @ctrl_pdata: pointer to the dsi controller structure * * This function can be used to check status of the panel using bta check * for the panel. * * Return: positive value if the panel is in good state, negative value or * zero otherwise. */ int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata) { int ret = 0; Loading