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

Commit c1f60e0e authored by Shivendra Kakrania's avatar Shivendra Kakrania
Browse files

msm: vidc: Replace vmem with system cache in video driver



This change is to replace support of vmem (onchip video memory) with
system cache (last level cache (LLC)). These driver changes will configure
LLC & provide this resource info to venus fw for usage.
Also, this change handles LLC bus bw configuration & votes LLC BW
for video decoder/encoder session.

CRs-Fixed: 2045519
Change-Id: Iae2f1df5c9da95716c0fd23a51b6c3b9b0b79885
Signed-off-by: default avatarShivendra Kakrania <shiven@codeaurora.org>
parent 8a19ef97
Loading
Loading
Loading
Loading
+0 −42
Original line number Diff line number Diff line
* Qualcomm Technologies Inc MSM VIDC VMEM

Required properties:
- compatible : "qcom,msm-vmem".
- interrupts : Contains the interrupt that maps to the VMEM module.
- reg : A set of 2 start address and size pairs that describe the hardware
register address space and mappable memory address space.
- reg-names : Strings that describe the pairs in "reg".  The register address
space should be called "reg-base" and the memory space should be called "mem-base".
- clocks : A set of clocks that correspond to the AHB and MAXI clocks that the
hardware uses.
- clock-names : A string that describes the "clocks" property.  The AHB clock
should be named "ahb" and the MAXI clock should be named "maxi".
- qcom,bank-size : The size of each memory bank, in bytes.
- vdd-supply: phandle to a regulator that is considered to be the footswitch for vmem.
- qcom,msm-bus,(name|num-cases,num-paths,vectors-KBps) - Bus to be voted for prior to
  issuing any IO transactions to vmem.  Refer to Documentation/devicetree/bindings/arm/\
  msm/msm_bus_adhoc.txt for further details.

Example:

qcom,vmem@880000 {
	compatible = "qcom,msm-vmem";
	interrupts = <0 429 0>;
	reg = <0x880000 0x800>,
	    <0x6800000 0x100000>;
	reg-names = "reg-base", "mem-base";

	vdd-supply = <&gdsc_mmagic_video>;
	clocks = <&clock_mmss clk_vmem_ahb_clk>,
	       <&clock_mmss clk_vmem_maxi_clk>;
	clock-names = "ahb", "maxi";

	qcom,bank-size = <131072>;

	qcom,msm-bus,name = "vmem";
	qcom,msm-bus,num-cases = <2>;
	qcom,msm-bus,num-paths = <1>;
	qcom,msm-bus,vectors-KBps =
	        <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VMEM_CFG   0   0>,
	        <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VMEM_CFG 500 800>;
};
+4 −1
Original line number Diff line number Diff line
@@ -104,6 +104,9 @@ value is typically max(latencies of every cluster at all power levels) + 1
  memory, performance etc.
- qcom,debug-timeout = A bool indicating that FW errors such as SYS_ERROR,
  SESSION_ERROR and timeouts will be treated as Fatal.
- cache-slice-names = An array of supported cache slice names by llcc
- cache-slices = An array of supported cache slice ids corresponding
  to cache-slice-names by llcc

[Second level nodes]
Context Banks
@@ -149,7 +152,7 @@ Required properties:
Optional properties:
- qcom,bus-governor : governor to use when scaling bus, generally any commonly
  found devfreq governor might be used.  In addition to those governors, the
  custom Venus governors, "msm-vidc-ddr" or "msm-vidc-vmem" are also
  custom Venus governors, "msm-vidc-ddr" or "msm-vidc-llcc" are also
  acceptable values.
  In the absence of this property the "performance" governor is used.
- qcom,bus-rage-kbps : an array of two items (<min max>) that indicate the
+0 −1
Original line number Diff line number Diff line
@@ -7,5 +7,4 @@ menuconfig MSM_VIDC_V4L2
		depends on ARCH_QCOM && VIDEO_V4L2
		select VIDEOBUF2_CORE

source "drivers/media/platform/msm/vidc/vmem/Kconfig"
source "drivers/media/platform/msm/vidc/governors/Kconfig"
+5 −52
Original line number Diff line number Diff line
@@ -22,8 +22,7 @@ module_param(debug, bool, 0644);

enum governor_mode {
	GOVERNOR_DDR,
	GOVERNOR_VMEM,
	GOVERNOR_VMEM_PLUS,
	GOVERNOR_LLCC,
};

struct governor {
@@ -275,38 +274,6 @@ static int __bpp(enum hal_uncompressed_format f)
	}
}

static unsigned long __calculate_vmem_plus_ab(struct vidc_bus_vote_data *d)
{
	unsigned long i = 0, vmem_plus = 0;

	if (!d->imem_ab_tbl || !d->imem_ab_tbl_size) {
		vmem_plus = 1; /* Vote for the min ab value */
		goto exit;
	}

	/* Pick up vmem frequency based on venus core frequency */
	for (i = 0; i < d->imem_ab_tbl_size; i++) {
		if (d->imem_ab_tbl[i].core_freq == d->core_freq) {
			vmem_plus = d->imem_ab_tbl[i].imem_ab;
			break;
		}
	}

	/*
	 * Incase we get an unsupported freq throw a warning
	 * and set ab to the minimum value.
	 */
	if (!vmem_plus) {
		vmem_plus = 1;
		dprintk(VIDC_WARN,
			"could not calculate vmem ab value due to core freq mismatch\n");
		WARN_ON(1);
	}

exit:
	return vmem_plus;
}

static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d,
		enum governor_mode gm) {
	/*
@@ -611,12 +578,9 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d,
	case GOVERNOR_DDR:
		ret = kbps(fp_round(ddr.total));
		break;
	case GOVERNOR_VMEM:
	case GOVERNOR_LLCC:
		ret = kbps(fp_round(vmem.total));
		break;
	case GOVERNOR_VMEM_PLUS:
		ret = __calculate_vmem_plus_ab(d);
		break;
	default:
		dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__);
	}
@@ -1016,12 +980,9 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
	case GOVERNOR_DDR:
		ret = kbps(fp_round(ddr.total));
		break;
	case GOVERNOR_VMEM:
	case GOVERNOR_LLCC:
		ret = kbps(fp_round(vmem.total));
		break;
	case GOVERNOR_VMEM_PLUS:
		ret = __calculate_vmem_plus_ab(d);
		break;
	default:
		dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__);
	}
@@ -1107,17 +1068,9 @@ static struct governor governors[] = {
		},
	},
	{
		.mode = GOVERNOR_VMEM,
		.devfreq_gov = {
			.name = "msm-vidc-vmem",
			.get_target_freq = __get_target_freq,
			.event_handler = __event_handler,
		},
	},
	{
		.mode = GOVERNOR_VMEM_PLUS,
		.mode = GOVERNOR_LLCC,
		.devfreq_gov = {
			.name = "msm-vidc-vmem+",
			.name = "msm-vidc-llcc",
			.get_target_freq = __get_target_freq,
			.event_handler = __event_handler,
		},
+62 −28
Original line number Diff line number Diff line
@@ -332,37 +332,56 @@ int create_pkt_cmd_sys_coverage_config(

int create_pkt_cmd_sys_set_resource(
		struct hfi_cmd_sys_set_resource_packet *pkt,
		struct vidc_resource_hdr *resource_hdr,
		void *resource_value)
		struct vidc_resource_hdr *res_hdr,
		void *res_value)
{
	int rc = 0;
	u32 i = 0;

	if (!pkt || !resource_hdr || !resource_value)
	if (!pkt || !res_hdr || !res_value) {
		dprintk(VIDC_ERR,
			"Invalid paramas pkt %pK res_hdr %pK res_value %pK\n",
				pkt, res_hdr, res_value);
		return -EINVAL;
	}

	pkt->packet_type = HFI_CMD_SYS_SET_RESOURCE;
	pkt->size = sizeof(struct hfi_cmd_sys_set_resource_packet);
	pkt->resource_handle = hash32_ptr(resource_hdr->resource_handle);
	pkt->resource_handle = hash32_ptr(res_hdr->resource_handle);

	switch (resource_hdr->resource_id) {
	case VIDC_RESOURCE_OCMEM:
	case VIDC_RESOURCE_VMEM:
	switch (res_hdr->resource_id) {
	case VIDC_RESOURCE_SYSCACHE:
	{
		struct hfi_resource_ocmem *hfioc_mem =
			(struct hfi_resource_ocmem *)
		struct hfi_resource_syscache_info_type *res_sc_info =
			(struct hfi_resource_syscache_info_type *) res_value;
		struct hfi_resource_subcache_type *res_sc =
			(struct hfi_resource_subcache_type *)
				&(res_sc_info->rg_subcache_entries[0]);

		struct hfi_resource_syscache_info_type *hfi_sc_info =
			(struct hfi_resource_syscache_info_type *)
				&pkt->rg_resource_data[0];

		phys_addr_t imem_addr = (phys_addr_t)resource_value;
		struct hfi_resource_subcache_type *hfi_sc =
			(struct hfi_resource_subcache_type *)
			&(hfi_sc_info->rg_subcache_entries[0]);

		pkt->resource_type = HFI_RESOURCE_SYSCACHE;
		hfi_sc_info->num_entries = res_sc_info->num_entries;

		pkt->size += (sizeof(struct hfi_resource_subcache_type))
				 * hfi_sc_info->num_entries;

		pkt->resource_type = HFI_RESOURCE_OCMEM;
		pkt->size += sizeof(struct hfi_resource_ocmem) - sizeof(u32);
		hfioc_mem->size = (u32)resource_hdr->size;
		hfioc_mem->mem = imem_addr;
		for (i = 0; i < hfi_sc_info->num_entries; i++) {
			hfi_sc[i] = res_sc[i];
		dprintk(VIDC_DBG, "entry hfi#%d, sc_id %d, size %d\n",
				 i, hfi_sc[i].sc_id, hfi_sc[i].size);
		}
		break;
	}
	default:
		dprintk(VIDC_ERR, "Invalid resource_id %d\n",
					resource_hdr->resource_id);
		dprintk(VIDC_ERR,
			"Invalid resource_id %d\n", res_hdr->resource_id);
		rc = -ENOTSUPP;
	}

@@ -371,28 +390,35 @@ int create_pkt_cmd_sys_set_resource(

int create_pkt_cmd_sys_release_resource(
		struct hfi_cmd_sys_release_resource_packet *pkt,
		struct vidc_resource_hdr *resource_hdr)
		struct vidc_resource_hdr *res_hdr)
{
	int rc = 0;

	if (!pkt)
	if (!pkt || !res_hdr) {
		dprintk(VIDC_ERR,
			"Invalid paramas pkt %pK res_hdr %pK\n",
				pkt, res_hdr);
		return -EINVAL;
	}

	pkt->size = sizeof(struct hfi_cmd_sys_release_resource_packet);
	pkt->packet_type = HFI_CMD_SYS_RELEASE_RESOURCE;
	pkt->resource_handle = hash32_ptr(resource_hdr->resource_handle);
	pkt->resource_handle = hash32_ptr(res_hdr->resource_handle);

	switch (resource_hdr->resource_id) {
	case VIDC_RESOURCE_OCMEM:
	case VIDC_RESOURCE_VMEM:
		pkt->resource_type = HFI_RESOURCE_OCMEM;
	switch (res_hdr->resource_id) {
	case VIDC_RESOURCE_SYSCACHE:
		pkt->resource_type = HFI_RESOURCE_SYSCACHE;
		break;
	default:
		dprintk(VIDC_ERR, "Invalid resource_id %d\n",
					resource_hdr->resource_id);
		dprintk(VIDC_ERR,
			 "Invalid resource_id %d\n", res_hdr->resource_id);
		rc = -ENOTSUPP;
	}

	dprintk(VIDC_DBG,
		"rel_res: pkt_type 0x%x res_type 0x%x prepared\n",
		pkt->packet_type, pkt->resource_type);

	return rc;
}

@@ -1837,6 +1863,14 @@ int create_pkt_cmd_session_set_property(
		pkt->size += sizeof(u32) + sizeof(*work_mode);
		break;
	}
	case HAL_PARAM_USE_SYS_CACHE:
	{
		create_pkt_enable(pkt->rg_property_data,
			HFI_PROPERTY_PARAM_USE_SYS_CACHE,
			(((struct hal_enable *) pdata)->enable));
		pkt->size += sizeof(u32) * 2;
		break;
	}
	/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
	case HAL_CONFIG_BUFFER_REQUIREMENTS:
	case HAL_CONFIG_PRIORITY:
Loading