From 9956819d558363c9e15560ec98850e47c66395d3 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Tue, 16 Feb 2021 09:46:45 -0800 Subject: [PATCH 1/6] Revert "disp: msm: dsi: reorder resource validation in probe" This reverts commit 23734fc29585cfcb03152875bd7805979bf82dd4. Reverting this change as it does not address all the below uses cases for Waipio - Supporting PROBE deferral based on dsi ctrl availability - Dual DSI path with optional single DSI node - Firmware DT blob parsing for single / dual dsi panels Change-Id: Ifc747befadd85eb76995b6cb1f72407fa5dccdbb Signed-off-by: Jeykumar Sankaran --- msm/dsi/dsi_display.c | 62 ++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index fc09f65af7..19f8d988d3 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -4048,7 +4048,7 @@ error: return rc; } -static int dsi_display_validate_resources(struct dsi_display *display) +static int dsi_display_res_init(struct dsi_display *display) { int rc = 0; int i; @@ -4061,7 +4061,7 @@ static int dsi_display_validate_resources(struct dsi_display *display) rc = PTR_ERR(ctrl->ctrl); DSI_ERR("failed to get dsi controller, rc=%d\n", rc); ctrl->ctrl = NULL; - goto error; + goto error_ctrl_put; } ctrl->phy = dsi_phy_get(ctrl->phy_of_node); @@ -4070,24 +4070,9 @@ static int dsi_display_validate_resources(struct dsi_display *display) DSI_ERR("failed to get phy controller, rc=%d\n", rc); dsi_ctrl_put(ctrl->ctrl); ctrl->phy = NULL; - goto error; + goto error_ctrl_put; } } - return rc; - -error: - for (i = i - 1; i >= 0; i--) { - ctrl = &display->ctrl[i]; - dsi_ctrl_put(ctrl->ctrl); - dsi_phy_put(ctrl->phy); - } - return -EPROBE_DEFER; -} - -static int dsi_display_res_init(struct dsi_display *display) -{ - int rc = 0; - int i; display->panel = dsi_panel_get(&display->pdev->dev, display->panel_node, @@ -4099,7 +4084,7 @@ static int dsi_display_res_init(struct dsi_display *display) rc = PTR_ERR(display->panel); DSI_ERR("failed to get panel, rc=%d\n", rc); display->panel = NULL; - goto error; + goto error_ctrl_put; } display_for_each_ctrl(i, display) { @@ -4122,13 +4107,13 @@ static int dsi_display_res_init(struct dsi_display *display) rc = dsi_display_parse_lane_map(display); if (rc) { DSI_ERR("Lane map not found, rc=%d\n", rc); - goto error; + goto error_ctrl_put; } rc = dsi_display_clocks_init(display); if (rc) { DSI_ERR("Failed to parse clock data, rc=%d\n", rc); - goto error; + goto error_ctrl_put; } /** @@ -4139,7 +4124,14 @@ static int dsi_display_res_init(struct dsi_display *display) display->is_active = false; else display->is_active = true; -error: + + return 0; +error_ctrl_put: + for (i = i - 1; i >= 0; i--) { + ctrl = &display->ctrl[i]; + dsi_ctrl_put(ctrl->ctrl); + dsi_phy_put(ctrl->phy); + } return rc; } @@ -5122,6 +5114,12 @@ static int _dsi_display_dev_init(struct dsi_display *display) display->parser, display->fw->data, display->fw->size); + rc = dsi_display_parse_dt(display); + if (rc) { + DSI_ERR("[%s] failed to parse dt, rc=%d\n", display->name, rc); + goto error; + } + rc = dsi_display_res_init(display); if (rc) { DSI_ERR("[%s] failed to initialize resources, rc=%d\n", @@ -5675,6 +5673,8 @@ static int dsi_display_init(struct dsi_display *display) int rc = 0; struct platform_device *pdev = display->pdev; + mutex_init(&display->display_lock); + rc = _dsi_display_dev_init(display); if (rc) { DSI_ERR("device init failed, rc=%d\n", rc); @@ -5756,7 +5756,6 @@ int dsi_display_dev_probe(struct platform_device *pdev) rc = -ENOMEM; goto end; } - mutex_init(&display->display_lock); display->dma_cmd_workq = create_singlethread_workqueue( "dsi_dma_cmd_workq"); @@ -5814,19 +5813,6 @@ int dsi_display_dev_probe(struct platform_device *pdev) platform_set_drvdata(pdev, display); - rc = dsi_display_parse_dt(display); - if (rc) { - DSI_ERR("[%s] failed to parse dt, rc=%d\n", display->name, rc); - goto end; - } - - rc = dsi_display_validate_resources(display); - if (rc) { - DSI_ERR("[%s] needed resources not probed yet, rc=%d\n", - display->name, rc); - goto end; - } - /* initialize display in firmware callback */ if (!boot_disp->boot_disp_en && IS_ENABLED(CONFIG_DSI_PARSER) && @@ -5852,10 +5838,8 @@ int dsi_display_dev_probe(struct platform_device *pdev) return 0; end: - if (display) { - mutex_destroy(&display->display_lock); + if (display) devm_kfree(&pdev->dev, display); - } return rc; } From 8b7ed7dc0cfee4b7145cae136bfa47c38544b720 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 10 Feb 2021 15:48:54 -0800 Subject: [PATCH 2/6] disp: msm: dsi: validate display probe dependencies early DSI display configuration can be either DT or firmware file driven. When probed with firmware path, asynchronous firmware file read callback function will be too late to check for dependencies and defer the probe when the dependencies are not met. Move all the dependency checks before the firmware file read request. Since the panel data will not be available before the DT/firmware read, this change limits the check to the dsi display layer. Change-Id: Ib26ed7839389027c2fe2dc15f70a572df3990ed9 Signed-off-by: Jeykumar Sankaran --- msm/dsi/dsi_display.c | 53 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 19f8d988d3..c2d6b64ed4 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -3966,6 +3966,37 @@ end: return rc; } +static int dsi_display_validate_res(struct dsi_display *display) +{ + struct device_node *of_node = display->pdev->dev.of_node; + struct of_phandle_iterator it; + struct dsi_ctrl *dsi_ctrl; + bool ctrl_avail = false; + + of_phandle_iterator_init(&it, of_node, "qcom,dsi-ctrl", NULL, 0); + while (of_phandle_iterator_next(&it) == 0) { + dsi_ctrl = dsi_ctrl_get(it.node); + if (IS_ERR(dsi_ctrl)) { + int rc = PTR_ERR(dsi_ctrl); + + if (rc == -EPROBE_DEFER) + return rc; + /* + * With dual display mode, the seconday display needs at least + * one ctrl to proceed through the probe. Exact ctrl match + * will be done after parsing the DT or firmware data. + */ + if (rc == -EBUSY) + ctrl_avail |= false; + } else { + dsi_ctrl_put(dsi_ctrl); + ctrl_avail = true; + } + } + + return ctrl_avail ? 0 : -EBUSY; +} + static int dsi_display_get_phandle_count(struct dsi_display *display, const char *propname) { @@ -5813,10 +5844,28 @@ int dsi_display_dev_probe(struct platform_device *pdev) platform_set_drvdata(pdev, display); + rc = dsi_display_validate_res(display); + if (rc) { + /* + * Display's bailing out without probe deferral must register its + * components to complete MDSS binding. Scheduled to be fixed in the future + * with dynamic component binding. + */ + if (rc == -EBUSY) { + int ret = component_add(&pdev->dev, + &dsi_display_comp_ops); + if (ret) + DSI_ERR( + "component add failed for display type: %s, rc=%d\n" + , display->type, ret); + } + + goto end; + } + /* initialize display in firmware callback */ if (!boot_disp->boot_disp_en && - IS_ENABLED(CONFIG_DSI_PARSER) && - !display->trusted_vm_env) { + IS_ENABLED(CONFIG_DSI_PARSER)) { if (!strcmp(display->display_type, "primary")) firm_req = !request_firmware_nowait( THIS_MODULE, 1, "dsi_prop", From 4339422849d83e8e74a866c04823e465d3a8eeb5 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 10 Feb 2021 13:14:27 -0800 Subject: [PATCH 3/6] disp: msm: dsi: expand dsi_parser hooks Implement and add additional dsi parser hooks for parsing firmware panel data. Change-Id: If06eb63b754ffce447b56ac6b22955f64e031779 Signed-off-by: Jeykumar Sankaran --- msm/dsi/dsi_parser.c | 45 +++++++++++++++++++++++++++++++++++++++++++- msm/dsi/dsi_parser.h | 23 +++++++++++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/msm/dsi/dsi_parser.c b/msm/dsi/dsi_parser.c index cef5fe70cf..b4c737d24a 100644 --- a/msm/dsi/dsi_parser.c +++ b/msm/dsi/dsi_parser.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include @@ -596,6 +596,49 @@ end: return rc; } +int dsi_parser_read_u32_index(const struct device_node *np, + const char *propname, u32 index, u32 *out_value) +{ + struct dsi_parser_node *node = (struct dsi_parser_node *)np; + struct dsi_parser_prop *prop; + char *property, *to_int, item[SZ_128]; + int rc = 0, base; + + prop = dsi_parser_search_property(node, propname); + if (!prop) { + DSI_DEBUG("%s not found\n", propname); + rc = -EINVAL; + goto end; + } + + if (index >= prop->len) { + rc = -EINVAL; + goto end; + } + + strlcpy(item, prop->items[index], SZ_128); + property = item; + to_int = strsep(&property, "x"); + + if (!property) { + property = to_int; + base = 10; + } else { + base = 16; + } + + rc = kstrtoint(property, base, out_value); + if (rc) { + DSI_ERR("prop=%s error(%d) converting %s, base=%d\n", + propname, rc, property, base); + goto end; + } + + DSI_DEBUG("%s=%d\n", propname, *out_value); +end: + return rc; +} + int dsi_parser_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz) diff --git a/msm/dsi/dsi_parser.h b/msm/dsi/dsi_parser.h index 949de1b4b0..7b7a251338 100644 --- a/msm/dsi/dsi_parser.h +++ b/msm/dsi/dsi_parser.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #ifndef _DSI_PARSER_H_ @@ -24,6 +24,8 @@ int dsi_parser_read_u64(const struct device_node *np, const char *propname, u64 *out_value); int dsi_parser_read_u32(const struct device_node *np, const char *propname, u32 *out_value); +int dsi_parser_read_u32_index(const struct device_node *np, + const char *propname, u32 index, u32 *out_value); int dsi_parser_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz); @@ -90,6 +92,12 @@ static inline int dsi_parser_read_u32(const struct device_node *np, return -ENODEV; } +int dsi_parser_read_u32_index(const struct device_node *np, + const char *propname, u32 index, u32 *out_value) +{ + return -ENODEV; +} + static inline int dsi_parser_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz) { @@ -170,12 +178,17 @@ struct dsi_parser_utils { const char *propname, u64 *out_value); int (*read_u32)(const struct device_node *np, const char *propname, u32 *out_value); + int (*read_u32_index)(const struct device_node *np, + const char *propname, u32 index, u32 *out_value); bool (*read_bool)(const struct device_node *np, const char *propname); int (*read_u32_array)(const struct device_node *np, const char *propname, u32 *out_values, size_t sz); int (*read_string)(const struct device_node *np, const char *propname, const char **out_string); + int (*read_string_index)(const struct device_node *np, + const char *propname, + int index, const char **output); struct device_node *(*get_child_by_name)( const struct device_node *node, const char *name); @@ -186,6 +199,8 @@ struct dsi_parser_utils { struct device_node *prev); int (*count_u32_elems)(const struct device_node *np, const char *propname); + int (*count_strings)(const struct device_node *np, + const char *propname); int (*get_named_gpio)(struct device_node *np, const char *propname, int index); int (*get_available_child_count)(const struct device_node *np); @@ -198,14 +213,17 @@ static inline struct dsi_parser_utils *dsi_parser_get_of_utils(void) .read_bool = of_property_read_bool, .read_u64 = of_property_read_u64, .read_u32 = of_property_read_u32, + .read_u32_index = of_property_read_u32_index, .read_u32_array = of_property_read_u32_array, .read_string = of_property_read_string, + .read_string_index = of_property_read_string_index, .get_child_by_name = of_get_child_by_name, .get_child_count = of_get_child_count, .get_available_child_count = of_get_available_child_count, .find_property = of_find_property, .get_next_child = of_get_next_child, .count_u32_elems = of_property_count_u32_elems, + .count_strings = of_property_count_strings, .get_named_gpio = of_get_named_gpio, }; @@ -219,14 +237,17 @@ static inline struct dsi_parser_utils *dsi_parser_get_parser_utils(void) .read_bool = dsi_parser_read_bool, .read_u64 = dsi_parser_read_u64, .read_u32 = dsi_parser_read_u32, + .read_u32_index = dsi_parser_read_u32_index, .read_u32_array = dsi_parser_read_u32_array, .read_string = dsi_parser_read_string, + .read_string_index = dsi_parser_read_string_index, .get_child_by_name = dsi_parser_get_child_by_name, .get_child_count = dsi_parser_get_child_count, .get_available_child_count = dsi_parser_get_child_count, .find_property = dsi_parser_find_property, .get_next_child = dsi_parser_get_next_child, .count_u32_elems = dsi_parser_count_u32_elems, + .count_strings = dsi_parser_count_strings, .get_named_gpio = dsi_parser_get_named_gpio, }; From c9ac265816f8a329f9424febf925d0336bd71dcd Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 10 Feb 2021 13:18:39 -0800 Subject: [PATCH 4/6] disp: msm: dsi: parse panel gpio's with dsi parser util Panel GPIO's pins can be provided through DT or firmware data. Use dsi parser util in consistent with other node parsings to read their values. Change-Id: I6dc687516aa0ce51fc56e54f4b5cbadc17f0dc1d Signed-off-by: Jeykumar Sankaran --- msm/dsi/dsi_panel.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index b19fce6c61..6c923938f0 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -2275,21 +2275,21 @@ static int dsi_panel_parse_tlmm_gpio(struct dsi_panel *panel) u32 base, size, pin; int pin_count, address_count, name_count, i; - address_count = of_property_count_u32_elems(utils->data, + 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; } - of_property_read_u32_index(utils->data, + utils->read_u32_index(utils->data, "qcom,dsi-panel-gpio-address", 0, &base); - of_property_read_u32_index(utils->data, + utils->read_u32_index(utils->data, "qcom,dsi-panel-gpio-address", 1, &size); - pin_count = of_property_count_u32_elems(utils->data, + pin_count = utils->count_u32_elems(utils->data, "qcom,dsi-panel-gpio-pins"); - name_count = of_property_count_strings(utils->data, + name_count = utils->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"); @@ -2303,13 +2303,13 @@ static int dsi_panel_parse_tlmm_gpio(struct dsi_panel *panel) panel->tlmm_gpio_count = pin_count; for (i = 0; i < pin_count; i++) { - of_property_read_u32_index(utils->data, + utils->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, + utils->read_string_index(utils->data, "qcom,dsi-panel-gpio-names", i, &(panel->tlmm_gpio[i].name)); } From 5960a1b8b5806ef2ff33a2a66624eb5302a18916 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Tue, 23 Mar 2021 22:28:56 -0700 Subject: [PATCH 5/6] disp: config: enable CONFIG_DRM_SDE_VM for waipio Enable CONFIG_DRM_SDE_VM to enable trusted VM support for waipio target. Change-Id: I4d70b3a84f7b612390f5a9925330cf77929b6e7b Signed-off-by: Jeykumar Sankaran --- config/gki_waipiodisp.conf | 1 + config/gki_waipiodispconf.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config/gki_waipiodisp.conf b/config/gki_waipiodisp.conf index 817b9ef5ee..c4327eba76 100644 --- a/config/gki_waipiodisp.conf +++ b/config/gki_waipiodisp.conf @@ -10,3 +10,4 @@ export CONFIG_DRM_SDE_RSC=y export CONFIG_DRM_SDE_WB=y export CONFIG_DRM_MSM_REGISTER_LOGGING=y export CONFIG_DISPLAY_BUILD=m +export CONFIG_DRM_SDE_VM=y diff --git a/config/gki_waipiodispconf.h b/config/gki_waipiodispconf.h index 8f0c0162da..d652a52892 100644 --- a/config/gki_waipiodispconf.h +++ b/config/gki_waipiodispconf.h @@ -17,4 +17,4 @@ #define CONFIG_QCOM_MDSS_PLL 1 #define CONFIG_GKI_DISPLAY 1 #define CONFIG_MSM_EXT_DISPLAY 1 - +#define CONFIG_DRM_SDE_VM 1 From c3959896c3d3ae99938e08c3267f9d89fe76e2d8 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Tue, 23 Mar 2021 22:30:30 -0700 Subject: [PATCH 6/6] disp: msm: sde: enable tui flag for waipio hw catalog Enable trusted vm flag for waipio HW catalog. Change-Id: I7cd5ba0354e2ed66a21f5f3b923c1855af1a0f14 Signed-off-by: Jeykumar Sankaran --- msm/sde/sde_hw_catalog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 766d702d91..c4d84b2a47 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -5123,6 +5123,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->has_fp16 = true; set_bit(SDE_MDP_PERIPH_TOP_0_REMOVED, &sde_cfg->mdp[0].features); sde_cfg->has_precise_vsync_ts = true; + sde_cfg->has_trusted_vm_support = true; } else { SDE_ERROR("unsupported chipset id:%X\n", hw_rev); sde_cfg->perf.min_prefill_lines = 0xffff;