Forráskód Böngészése

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 <[email protected]>
Jeykumar Sankaran 4 éve
szülő
commit
7a112bb744
4 módosított fájl, 87 hozzáadás és 0 törlés
  1. 12 0
      msm/sde/sde_hw_catalog.c
  2. 7 0
      msm/sde/sde_hw_catalog.h
  3. 38 0
      msm/sde/sde_kms.c
  4. 30 0
      msm/sde_rsc.c

+ 12 - 0
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)

+ 7 - 0
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;

+ 38 - 0
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;
 }
 

+ 30 - 0
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 = {