From 7a112bb7440cec43ca5378d346a6465b02cf7152 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Sat, 29 May 2021 00:25:07 -0700 Subject: [PATCH] disp: msm: sde: add explicit sub-driver mappings for TVM TUI clients are the display sub-drivers that participate during the TUI transition. They register with the display TUI notification framework with a list of callbacks functions that will be invoked during pre/post transitions and for quering I/O memory that need to be access controlled. This change adds RSC to the TUI client list. In Trusted VM, all the sub-drivers are not enabled to avoid any re-configuration of respective module registers. But the TUI framework need to know the sub-driver I/O memory ranges in order to accept the I/O memory list lent by the HLOS VM. So, SDE provides them ranges by reading from a custom devicetree property. Change-Id: I2c4b254d539d04771339ae4a7bf4d296b7a7f91a Signed-off-by: Jeykumar Sankaran --- msm/sde/sde_hw_catalog.c | 12 ++++++++++++ msm/sde/sde_hw_catalog.h | 7 +++++++ msm/sde/sde_kms.c | 38 ++++++++++++++++++++++++++++++++++++++ msm/sde_rsc.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index fe163162..ec8c9415 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -210,6 +210,7 @@ enum sde_prop { BASE_LAYER, TRUSTED_VM_ENV, MAX_TRUSTED_VM_DISPLAYS, + TVM_INCLUDE_REG, SDE_PROP_MAX, }; @@ -598,6 +599,7 @@ static struct sde_prop_type sde_prop[] = { {TRUSTED_VM_ENV, "qcom,sde-trusted-vm-env", false, PROP_TYPE_BOOL}, {MAX_TRUSTED_VM_DISPLAYS, "qcom,sde-max-trusted-vm-displays", false, PROP_TYPE_U32}, + {TVM_INCLUDE_REG, "qcom,tvm-include-reg", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type sde_perf_prop[] = { @@ -3965,6 +3967,16 @@ static void _sde_top_parse_dt_helper(struct sde_mdss_cfg *cfg, 0); cfg->max_trusted_vm_displays = PROP_VALUE_ACCESS(props->values, MAX_TRUSTED_VM_DISPLAYS, 0); + if (props->exists[TVM_INCLUDE_REG]) { + cfg->tvm_reg_count = props->counts[TVM_INCLUDE_REG] / 2; + for (i = 0; i < cfg->tvm_reg_count; i++) { + cfg->tvm_reg[i].start = PROP_VALUE_ACCESS(props->values, + TVM_INCLUDE_REG, i * 2); + cfg->tvm_reg[i].end = cfg->tvm_reg[i].start + + PROP_VALUE_ACCESS(props->values, TVM_INCLUDE_REG, + i * 2 + 1); + } + } } static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 61256b13..c1fef54e 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -19,6 +19,7 @@ * based on current design */ #define MAX_BLOCKS 12 +#define MAX_REG_SIZE_ENTRIES 14 #define SDE_HW_VER(MAJOR, MINOR, STEP) ((u32)((MAJOR & 0xF) << 28) |\ ((MINOR & 0xFFF) << 16) |\ @@ -1472,6 +1473,10 @@ struct sde_perf_cfg { * the trusted VM. false, otherwise. * @max_trusted_vm_displays maximum number of concurrent trusted * vm displays supported. + * @tvm_reg_count number of sub-driver register ranges that need to be included + * for trusted vm for accepting the resources + * @tvm_reg array of sub-driver register ranges entries that need to be + * included * @max_sspp_linewidth max source pipe line width support. * @vig_sspp_linewidth max vig source pipe line width support. * @scaling_linewidth max vig source pipe linewidth for scaling usecases @@ -1561,6 +1566,8 @@ struct sde_mdss_cfg { u32 hwversion; bool trusted_vm_env; u32 max_trusted_vm_displays; + u32 tvm_reg_count; + struct resource tvm_reg[MAX_REG_SIZE_ENTRIES]; u32 max_sspp_linewidth; u32 vig_sspp_linewidth; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index a6020506..7be4982f 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -4583,6 +4583,38 @@ power_error: return rc; } +int _sde_kms_get_tvm_inclusion_mem(struct sde_mdss_cfg *catalog, struct list_head *mem_list) +{ + struct list_head temp_head; + struct msm_io_mem_entry *io_mem; + int rc, i = 0; + + INIT_LIST_HEAD(&temp_head); + + for (i = 0; i < catalog->tvm_reg_count; i++) { + struct resource *res = &catalog->tvm_reg[i]; + + io_mem = kzalloc(sizeof(struct msm_io_mem_entry), GFP_KERNEL); + if (!io_mem) { + rc = -ENOMEM; + goto parse_fail; + } + + io_mem->base = res->start; + io_mem->size = resource_size(res); + + list_add(&io_mem->list, &temp_head); + } + + list_splice(&temp_head, mem_list); + + return 0; +parse_fail: + msm_dss_clean_io_mem(&temp_head); + + return rc; +} + int sde_kms_get_io_resources(struct sde_kms *sde_kms, struct msm_io_res *io_res) { struct platform_device *pdev = to_platform_device(sde_kms->dev->dev); @@ -4606,6 +4638,12 @@ int sde_kms_get_io_resources(struct sde_kms *sde_kms, struct msm_io_res *io_res) return rc; } + rc = _sde_kms_get_tvm_inclusion_mem(sde_kms->catalog, &io_res->mem); + if (rc) { + SDE_ERROR("failed to get tvm inclusion mem ranges"); + return rc; + } + return rc; } diff --git a/msm/sde_rsc.c b/msm/sde_rsc.c index 790592dc..afe39256 100644 --- a/msm/sde_rsc.c +++ b/msm/sde_rsc.c @@ -1597,6 +1597,28 @@ static void sde_rsc_deinit(struct platform_device *pdev, kfree(rsc); } +/** + * sde_rsc_get_io_resources - collect register ranges for the device to + * perform access control on TUI transition + * @io_res: io resource list + * @data: payload data provided during msm_register_vm_event + * Returns: zero on success + */ +static int sde_rsc_get_io_resources(struct msm_io_res *io_res, void *data) +{ + int rc = 0; + struct sde_rsc_priv *rsc = (struct sde_rsc_priv *)data; + struct platform_device *pdev = to_platform_device(rsc->dev); + + rc = msm_dss_get_io_mem(pdev, &io_res->mem); + if (rc) { + pr_err("failed to get rsc io mem, rc = %d\n", rc); + return rc; + } + + return 0; +} + /** * sde_rsc_bind - bind rsc device with controlling device * @dev: Pointer to base of platform device @@ -1611,6 +1633,9 @@ static int sde_rsc_bind(struct device *dev, struct sde_rsc_priv *rsc; struct drm_device *drm; struct platform_device *pdev = to_platform_device(dev); + struct msm_vm_ops vm_event_ops = { + .vm_get_io_resources = sde_rsc_get_io_resources, + }; if (!dev || !pdev || !master) { pr_err("invalid param(s), dev %pK, pdev %pK, master %pK\n", @@ -1630,6 +1655,9 @@ static int sde_rsc_bind(struct device *dev, rsc->drv_io.len, msm_get_phys_addr(pdev, "drv"), SDE_DBG_RSC); sde_dbg_reg_register_base(SDE_RSC_WRAPPER_DBG_NAME, rsc->wrapper_io.base, rsc->wrapper_io.len, msm_get_phys_addr(pdev, "wrapper"), SDE_DBG_RSC); + + msm_register_vm_event(master, dev, &vm_event_ops, (void *)rsc); + return 0; } @@ -1655,6 +1683,8 @@ static void sde_rsc_unbind(struct device *dev, pr_err("invalid display rsc\n"); return; } + + msm_unregister_vm_event(master, dev); } static const struct component_ops sde_rsc_comp_ops = {