From 6dd2c3cd872c6157bf4d7f78d40319d0e60f62de Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Wed, 4 Nov 2020 15:22:01 -0800 Subject: [PATCH 1/3] disp: msm: dsi: parse & store gpio registers used by the host & panel Parse all the GPIO pins used by the DSI host and the display panel along with its register ranges and store it in panel struct. This avoids parsing the device-tree everytime during transitions between trusted and primary vm. Change-Id: Ibbb646358c0409703afda1c4f758f044fc8c0001 Signed-off-by: Veera Sundaram Sankaran --- msm/dsi/dsi_panel.c | 109 ++++++++++++++++++++++++-------------------- msm/dsi/dsi_panel.h | 10 ++++ 2 files changed, 69 insertions(+), 50 deletions(-) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index a7daa639e426..04026770c435 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -2130,63 +2130,19 @@ int dsi_panel_get_io_resources(struct dsi_panel *panel, struct list_head temp_head; struct msm_io_mem_entry *io_mem, *pos, *tmp; struct list_head *mem_list = &io_res->mem; - int i, rc = 0, address_count, pin_count; - u32 *pins = NULL, *address = NULL; - u32 base, size; - struct dsi_parser_utils *utils = &panel->utils; + int i, rc = 0; INIT_LIST_HEAD(&temp_head); - address_count = utils->count_u32_elems(utils->data, - "qcom,dsi-panel-gpio-address"); - if (address_count != 2) { - DSI_DEBUG("panel gpio address not defined\n"); - return 0; - } - - address = kzalloc(sizeof(u32) * address_count, GFP_KERNEL); - if (!address) - return -ENOMEM; - - rc = utils->read_u32_array(utils->data, "qcom,dsi-panel-gpio-address", - address, address_count); - if (rc) { - DSI_ERR("panel gpio address not defined correctly\n"); - goto end; - } - base = address[0]; - size = address[1]; - - pin_count = utils->count_u32_elems(utils->data, - "qcom,dsi-panel-gpio-pins"); - if (pin_count < 0) { - DSI_ERR("panel gpio pins not defined\n"); - rc = pin_count; - goto end; - } - - pins = kzalloc(sizeof(u32) * pin_count, GFP_KERNEL); - if (!pins) { - rc = -ENOMEM; - goto end; - } - - rc = utils->read_u32_array(utils->data, "qcom,dsi-panel-gpio-pins", - pins, pin_count); - if (rc) { - DSI_ERR("panel gpio pins not defined correctly\n"); - goto end; - } - - for (i = 0; i < pin_count; i++) { + for (i = 0; i < panel->tlmm_gpio_count; i++) { io_mem = kzalloc(sizeof(*io_mem), GFP_KERNEL); if (!io_mem) { rc = -ENOMEM; goto parse_fail; } - io_mem->base = base + (pins[i] * size); - io_mem->size = size; + io_mem->base = panel->tlmm_gpio[i].addr; + io_mem->size = panel->tlmm_gpio[i].size; list_add(&io_mem->list, &temp_head); } @@ -2200,8 +2156,6 @@ parse_fail: kzfree(pos); } end: - kzfree(pins); - kzfree(address); return rc; } @@ -2290,6 +2244,54 @@ error: return rc; } +static int dsi_panel_parse_tlmm_gpio(struct dsi_panel *panel) +{ + struct dsi_parser_utils *utils = &panel->utils; + u32 base, size, pin; + int pin_count, address_count, name_count, i; + + address_count = of_property_count_u32_elems(utils->data, + "qcom,dsi-panel-gpio-address"); + if (address_count != 2) { + DSI_DEBUG("panel gpio address not defined\n"); + return 0; + } + + of_property_read_u32_index(utils->data, + "qcom,dsi-panel-gpio-address", 0, &base); + of_property_read_u32_index(utils->data, + "qcom,dsi-panel-gpio-address", 1, &size); + + pin_count = of_property_count_u32_elems(utils->data, + "qcom,dsi-panel-gpio-pins"); + name_count = of_property_count_strings(utils->data, + "qcom,dsi-panel-gpio-names"); + if ((pin_count < 0) || (name_count < 0) || (pin_count != name_count)) { + DSI_ERR("invalid gpio pins/names\n"); + return -EINVAL; + } + + panel->tlmm_gpio = kcalloc(pin_count, + sizeof(struct dsi_tlmm_gpio), GFP_KERNEL); + if (!panel->tlmm_gpio) + return -ENOMEM; + + panel->tlmm_gpio_count = pin_count; + for (i = 0; i < pin_count; i++) { + of_property_read_u32_index(utils->data, + "qcom,dsi-panel-gpio-pins", i, &pin); + panel->tlmm_gpio[i].num = pin; + panel->tlmm_gpio[i].addr = base + (pin * size); + panel->tlmm_gpio[i].size = size; + + of_property_read_string_index(utils->data, + "qcom,dsi-panel-gpio-names", i, + &(panel->tlmm_gpio[i].name)); + } + + return 0; +} + static int dsi_panel_parse_bl_pwm_config(struct dsi_panel *panel) { int rc = 0; @@ -3487,6 +3489,12 @@ struct dsi_panel *dsi_panel_get(struct device *parent, goto error; } + rc = dsi_panel_parse_tlmm_gpio(panel); + if (rc) { + DSI_ERR("failed to parse panel tlmm gpios, rc=%d\n", rc); + goto error; + } + rc = dsi_panel_parse_power_cfg(panel); if (rc) DSI_ERR("failed to parse power config, rc=%d\n", rc); @@ -3645,6 +3653,7 @@ int dsi_panel_drv_deinit(struct dsi_panel *panel) if (rc) DSI_ERR("[%s] failed to put regs, rc=%d\n", panel->name, rc); + kfree(panel->tlmm_gpio); panel->host = NULL; memset(&panel->mipi_device, 0x0, sizeof(panel->mipi_device)); diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index 02f04bb32dc5..8bda41ad8b99 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -182,6 +182,13 @@ struct dsi_panel_spr_info { enum msm_display_spr_pack_type pack_type; }; +struct dsi_tlmm_gpio { + u32 num; + u32 addr; + u32 size; + const char *name; +}; + struct dsi_panel; struct dsi_panel_ops { @@ -253,6 +260,9 @@ struct dsi_panel { int power_mode; enum dsi_panel_physical_type panel_type; + struct dsi_tlmm_gpio *tlmm_gpio; + u32 tlmm_gpio_count; + struct dsi_panel_ops panel_ops; }; From c99f3fd6ae04ee46e2dfb0a617b9349c9776741e Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Fri, 6 Nov 2020 14:09:10 -0800 Subject: [PATCH 2/3] disp: msm: dsi: enable ESD trigger through debugfs in trsuted-vm Add support to trigger ESD through debugfs by directly modifying the reset GPIOs TLMM register in trusted-vm as GPIO driver support is not enabled. Change-Id: I859affe69c13dbe115a48b0a63a600a57027db58 Signed-off-by: Veera Sundaram Sankaran --- msm/dsi/dsi_display.c | 3 ++- msm/dsi/dsi_panel.c | 53 +++++++++++++++++++++++++++++++------------ msm/dsi/dsi_panel.h | 2 +- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index b32a066b0bdb..d7e734526ea4 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -1529,7 +1529,8 @@ static ssize_t debugfs_esd_trigger_check(struct file *file, if (display->esd_trigger) { DSI_INFO("ESD attack triggered by user\n"); - rc = dsi_panel_trigger_esd_attack(display->panel); + rc = dsi_panel_trigger_esd_attack(display->panel, + display->trusted_vm_env); if (rc) { DSI_ERR("Failed to trigger ESD attack\n"); goto error; diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 04026770c435..f21eae125e99 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -191,29 +191,52 @@ static int dsi_panel_gpio_release(struct dsi_panel *panel) return rc; } -int dsi_panel_trigger_esd_attack(struct dsi_panel *panel) +int dsi_panel_trigger_esd_attack(struct dsi_panel *panel, bool trusted_vm_env) { - struct dsi_panel_reset_config *r_config; - if (!panel) { DSI_ERR("Invalid panel param\n"); return -EINVAL; } - r_config = &panel->reset_config; - if (!r_config) { - DSI_ERR("Invalid panel reset configuration\n"); - return -EINVAL; + /* toggle reset-gpio by writing directly to register in trusted-vm */ + if (trusted_vm_env) { + struct dsi_tlmm_gpio *gpio = NULL; + void __iomem *io; + u32 offset = 0x4; + int i; + + for (i = 0; i < panel->tlmm_gpio_count; i++) + if (!strcmp(panel->tlmm_gpio[i].name, "reset-gpio")) + gpio = &panel->tlmm_gpio[i]; + + if (!gpio) { + DSI_ERR("reset gpio not found\n"); + return -EINVAL; + } + + io = ioremap(gpio->addr, gpio->size); + writel_relaxed(0, io + offset); + iounmap(io); + + } else { + struct dsi_panel_reset_config *r_config = &panel->reset_config; + + if (!r_config) { + DSI_ERR("Invalid panel reset configuration\n"); + return -EINVAL; + } + + if (!gpio_is_valid(r_config->reset_gpio)) { + DSI_ERR("failed to pull down gpio\n"); + return -EINVAL; + } + gpio_set_value(r_config->reset_gpio, 0); } - if (gpio_is_valid(r_config->reset_gpio)) { - gpio_set_value(r_config->reset_gpio, 0); - SDE_EVT32(SDE_EVTLOG_FUNC_CASE1); - DSI_INFO("GPIO pulled low to simulate ESD\n"); - return 0; - } - DSI_ERR("failed to pull down gpio\n"); - return -EINVAL; + SDE_EVT32(SDE_EVTLOG_FUNC_CASE1); + DSI_INFO("GPIO pulled low to simulate ESD\n"); + + return 0; } static int dsi_panel_reset(struct dsi_panel *panel) diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index 8bda41ad8b99..994b23fc8f26 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -298,7 +298,7 @@ struct dsi_panel *dsi_panel_get(struct device *parent, int topology_override, bool trusted_vm_env); -int dsi_panel_trigger_esd_attack(struct dsi_panel *panel); +int dsi_panel_trigger_esd_attack(struct dsi_panel *panel, bool trusted_vm_env); void dsi_panel_put(struct dsi_panel *panel); From 899b201a0a24cb9703321510917d98a61fde834b Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Thu, 5 Nov 2020 15:05:48 -0800 Subject: [PATCH 3/3] disp: msm: dsi: avoid TE-based panel status check in Trusted-vm Add check to avoid the dsi panel status check with TE method as the GPIO support is not available in Trusted-vm. Change-Id: I5ad6e7b77b189b5150302ab34767dfc4d97aaf61 Signed-off-by: Veera Sundaram Sankaran --- msm/dsi/dsi_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index d7e734526ea4..19227042ce26 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -858,7 +858,8 @@ int dsi_display_check_status(struct drm_connector *connector, void *display, if (te_check_override) te_rechecks = MAX_TE_RECHECKS; - if (panel->panel_mode == DSI_OP_VIDEO_MODE) + if ((dsi_display->trusted_vm_env) || + (panel->panel_mode == DSI_OP_VIDEO_MODE)) te_rechecks = 0; ret = dsi_display_clk_ctrl(dsi_display->dsi_clk_handle,