Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b25f51c authored by Vikash Garodia's avatar Vikash Garodia
Browse files

msm: vidc: Add support to align with legacy SMMU driver



This change adds support to parse iommu domains, if present
in legacy DT binding format. Create device pointer for each
context bank to keep track of mapping information.
Add the bus client entries in target dtsi file as per the
format parsed by video driver.

Change-Id: Ibcc5e0bf4e0ed801acdc809a036f7d220c64dfe4
Signed-off-by: default avatarVikash Garodia <vgarodia@codeaurora.org>
parent 90c540cd
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -87,6 +87,25 @@ Optional properties:
- qcom,hfi-version = The hfi packetization version supported by venus firmware.
  If hfi version is not specified, then packetization type will default to
  legacy.
- qcom,vidc-iommu-domains = node containing individual domain nodes, each with:
     - a unique domain name for the domain node (e.g vidc,domain-ns)
     - qcom,vidc-domain-phandle: phandle for the domain as defined in
       <target>-iommu-domains.dtsi (e.g msm8974-v1-iommu-domains.dtsi)
     - qcom,vidc-buffer-types: bitmap of buffer types that can be mapped into each
       IOMMU domain.
       - Buffer types are defined as the following:
           input = 0x1
           output = 0x2
           output2 = 0x4
           extradata input = 0x8
           extradata output = 0x10
           extradata output2 = 0x20
           internal scratch = 0x40
           internal scratch1 = 0x80
           internal scratch2 = 0x100
           internal persist = 0x200
           internal persist1 = 0x400
           internal cmd queue = 0x800

[Second level nodes]
Context Banks
+20 −56
Original line number Diff line number Diff line
@@ -1535,73 +1535,37 @@
		qcom,vidc-iommu-domains {
			qcom,domain-ns {
				qcom,vidc-domain-phandle = <&venus_domain_ns>;
				qcom,vidc-partition-buffer-types = <0xfff>;
				qcom,vidc-buffer-types = <0xfff>;
			};
			qcom,domain-sec-bs {
				qcom,vidc-domain-phandle = <&venus_domain_sec_bitstream>;
				qcom,vidc-partition-buffer-types = <0x241>;
				qcom,vidc-buffer-types = <0x241>;
			};
			qcom,domain-sec-px {
				qcom,vidc-domain-phandle = <&venus_domain_sec_pixel>;
				qcom,vidc-partition-buffer-types = <0x106>;
				qcom,vidc-buffer-types = <0x106>;
			};
			qcom,domain-sec-np {
				qcom,vidc-domain-phandle = <&venus_domain_sec_non_pixel>;
				qcom,vidc-partition-buffer-types = <0x480>;
				qcom,vidc-buffer-types = <0x480>;
			};
		};
		qcom,msm-bus-clients {
			qcom,msm-bus-client@0 {
				qcom,msm-bus,name = "venc-ddr";
				qcom,msm-bus,num-cases = <6>;
				qcom,msm-bus,num-paths = <1>;
				qcom,msm-bus,vectors-KBps =
					<63 512 0 0>,
					<63 512 136806 0>, /* VGA 30 fps */
					<63 512 350208 0>, /* VGA 60 fps */
					<63 512 350208 0>, /* 720p 30 fps */
					<63 512 787456 0>, /* 720p 60 fps */
					<63 512 787456 0>; /* 1080p 30 fps */
				qcom,bus-configs = <0x01000414>;
			};
			qcom,msm-bus-client@1 {
				qcom,msm-bus,name = "vdec-core0-ddr";
				qcom,msm-bus,num-cases = <7>;
				qcom,msm-bus,num-paths = <1>;
				qcom,msm-bus,vectors-KBps =
					<63 512 0 0>,
					<63 512 118784 0>,
					<63 512 233472 0>,
					<63 512 314368 0>,
					<63 512 618496 0>,
					<63 512 615424 0>,
					<63 512 1205248 0>;
				qcom,bus-configs = <0x030fcfff>;
			};
			qcom,msm-bus-client@2 {
				qcom,msm-bus,name = "vdec-core1-ddr";
				qcom,msm-bus,num-cases = <7>;
				qcom,msm-bus,num-paths = <1>;
				qcom,msm-bus,vectors-KBps =
					<63 512 0 0>,
					<63 512 111616 0>,
					<63 512 221184 0>,
					<63 512 294912 0>,
					<63 512 580608 0>,
					<63 512 571392 0>,
					<63 512 1117184 0>;
				qcom,bus-configs = <0x0c000000>;
			};
			qcom,msm-bus-client@3 {
				qcom,msm-bus,name = "venus-arm9-ddr";
				qcom,msm-bus,num-cases = <2>;
				qcom,msm-bus,num-paths = <1>;
				qcom,msm-bus,vectors-KBps =
					<63 512 0 0>,
					<63 512 1000 1000>;
				qcom,bus-configs = <0x00000000>;
				qcom,bus-passive;
		venus_bus_ddr {
			compatible = "qcom,msm-vidc,bus";
			label = "venus-ddr";
			qcom,bus-master = <MSM_BUS_MASTER_VIDEO_P0>;
			qcom,bus-slave = <MSM_BUS_SLAVE_EBI_CH0>;
			qcom,bus-governor = "msm-vidc-ddr";
			qcom,bus-range-kbps = <1000 1205248>;
		};

		arm9_bus_ddr {
			compatible = "qcom,msm-vidc,bus";
			label = "venus-arm9-ddr";
			qcom,bus-master = <MSM_BUS_MASTER_VIDEO_P0>;
			qcom,bus-slave = <MSM_BUS_SLAVE_EBI_CH0>;
			qcom,bus-governor = "performance";
			qcom,bus-range-kbps = <1 1>;
		};
	};

+120 −3
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@

#include <asm/dma-iommu.h>
#include <linux/iommu.h>
#include <linux/qcom_iommu.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/sort.h>
@@ -25,6 +26,8 @@
enum clock_properties {
	CLOCK_PROP_HAS_SCALING = 1 << 0,
};
static int msm_vidc_populate_legacy_context_bank(
			struct msm_vidc_platform_resources *res);

static size_t get_u32_array_num_elements(struct platform_device *pdev,
					char *name)
@@ -716,6 +719,13 @@ int read_platform_resources_from_dt(
		goto err_load_max_hw_load;
	}

	rc = msm_vidc_populate_legacy_context_bank(res);
	if (rc) {
		dprintk(VIDC_ERR,
			"Failed to setup context banks %d\n", rc);
		goto err_setup_legacy_cb;
	}

	res->use_non_secure_pil = of_property_read_bool(pdev->dev.of_node,
			"qcom,use-non-secure-pil");

@@ -736,6 +746,8 @@ int read_platform_resources_from_dt(
			"qcom,never-unload-fw");

	return rc;

err_setup_legacy_cb:
err_load_max_hw_load:
	msm_vidc_free_clock_table(res);
err_load_clock_table:
@@ -771,17 +783,24 @@ static int msm_vidc_setup_context_bank(struct context_bank_info *cb,
	int rc = 0;
	int disable_htw = 1;
	int secure_vmid = VMID_INVAL;
	struct bus_type *bus;

	if (!dev || !cb) {
		dprintk(VIDC_ERR,
			"%s: Invalid Input params\n", __func__);
		return -EINVAL;
	}

	cb->dev = dev;
	cb->mapping = arm_iommu_create_mapping(&platform_bus_type,
			cb->addr_range.start, cb->addr_range.size);

	bus = msm_iommu_get_bus(cb->dev);
	if (IS_ERR_OR_NULL(bus)) {
		dprintk(VIDC_ERR, "%s - failed to get bus type\n", __func__);
		rc = PTR_ERR(bus) ?: -ENODEV;
		goto remove_cb;
	}

	cb->mapping = arm_iommu_create_mapping(bus, cb->addr_range.start,
					cb->addr_range.size);
	if (IS_ERR_OR_NULL(cb->mapping)) {
		dprintk(VIDC_ERR, "%s - failed to create mapping\n", __func__);
		rc = PTR_ERR(cb->mapping) ?: -ENODEV;
@@ -897,6 +916,104 @@ err_setup_cb:
	return rc;
}

static int msm_vidc_populate_legacy_context_bank(
			struct msm_vidc_platform_resources *res)
{
	int rc = 0;
	struct platform_device *pdev = NULL;
	struct device_node *domains_parent_node = NULL;
	struct device_node *domains_child_node = NULL;
	struct device_node *ctx_node = NULL;
	struct context_bank_info *cb;

	if (!res || !res->pdev) {
		dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__);
		return -EINVAL;
	}
	pdev = res->pdev;

	domains_parent_node = of_find_node_by_name(pdev->dev.of_node,
			"qcom,vidc-iommu-domains");
	if (!domains_parent_node) {
		dprintk(VIDC_DBG,
			"%s legacy iommu domains not present\n", __func__);
		return 0;
	}

	/* set up each context bank for legacy DT bindings*/
	for_each_child_of_node(domains_parent_node,
		domains_child_node) {
		cb = devm_kzalloc(&pdev->dev, sizeof(*cb), GFP_KERNEL);
		if (!cb) {
			dprintk(VIDC_ERR,
				"%s - Failed to allocate cb\n", __func__);
			return -ENOMEM;
		}
		INIT_LIST_HEAD(&cb->list);
		list_add_tail(&cb->list, &res->context_banks);

		ctx_node = of_parse_phandle(domains_child_node,
				"qcom,vidc-domain-phandle", 0);
		if (!ctx_node) {
			dprintk(VIDC_ERR,
				"%s Unable to parse pHandle\n", __func__);
			rc = -EBADHANDLE;
			goto err_setup_cb;
		}

		rc = of_property_read_string(ctx_node, "label", &(cb->name));
		if (rc) {
			dprintk(VIDC_ERR,
				"%s Could not find label\n", __func__);
			goto err_setup_cb;
		}

		rc = of_property_read_u32_array(ctx_node,
			"qcom,virtual-addr-pool", (u32 *)&cb->addr_range, 2);
		if (rc) {
			dprintk(VIDC_ERR,
				"%s Could not read addr pool for group : %s (%d)\n",
				__func__, cb->name, rc);
			goto err_setup_cb;
		}

		cb->is_secure =
			of_property_read_bool(ctx_node, "qcom,secure-domain");

		rc = of_property_read_u32(domains_child_node,
				"qcom,vidc-buffer-types", &cb->buffer_type);
		if (rc) {
			dprintk(VIDC_ERR,
				"%s Could not read buffer type (%d)\n",
				__func__, rc);
			goto err_setup_cb;
		}

		cb->dev = msm_iommu_get_ctx(cb->name);
		if (IS_ERR_OR_NULL(cb->dev)) {
			dprintk(VIDC_ERR, "%s could not get device for cb %s\n",
					__func__, cb->name);
			rc = -ENOENT;
			goto err_setup_cb;
		}

		rc = msm_vidc_setup_context_bank(cb, cb->dev);
		if (rc) {
			dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc);
			goto err_setup_cb;
		}
		dprintk(VIDC_DBG,
			"%s: context bank %s secure %d addr start = %#x addr size = %#x buffer_type = %#x\n",
			__func__, cb->name, cb->is_secure, cb->addr_range.start,
			cb->addr_range.size, cb->buffer_type);
	}
	return rc;

err_setup_cb:
	list_del(&cb->list);
	return rc;
}

int read_context_bank_resources_from_dt(struct platform_device *pdev)
{
	struct msm_vidc_core *core;