diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index fe163162c9..ec8c941515 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 61256b139c..c1fef54e12 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 a6020506c0..7be4982f92 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 790592dc4a..afe39256d4 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 = {