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

Commit 3ee40801 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Changes to handle fw_bias and device addresses"

parents 643825db e3153f7d
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -92,6 +92,9 @@ Optional properties:
  The bitmap is defined as:
  scalable = 0x1 (if the driver should vary the clock's frequency based on load)
  power collapsible = 0x2 (if the driver should disable the clock if no load)
- qcom,use-non-secure-pil = A bool indicating which type of pil to use to load
  the fw.
- qcom,fw-bias = The address at which venus fw is loaded (manually).

Example:

@@ -153,5 +156,6 @@ Example:
							<0x7c1>;
			};
		};

		qcom,use-non-secure-pil;
		qcom,fw-bias = <0xe000000>;
	};
+9 −6
Original line number Diff line number Diff line
@@ -67,13 +67,16 @@ static int get_device_address(struct smem_client *smem_client,
		return -EINVAL;
	}

	rc = msm_smem_get_domain_partition(smem_client, flags, buffer_type,
			&domain, &partition);
	if (is_iommu_present(smem_client->res)) {
		rc = msm_smem_get_domain_partition(smem_client, flags,
				buffer_type, &domain, &partition);
		if (rc) {
		dprintk(VIDC_ERR, "Failed to get domain and partition: %d\n",
			dprintk(VIDC_ERR,
					"Failed to get domain and partition: %d\n",
					rc);
			goto mem_domain_get_failed;
		}
	}

	if (flags & SMEM_SECURE) {
		rc = msm_ion_secure_buffer(clnt, hndl,
+12 −1
Original line number Diff line number Diff line
@@ -637,13 +637,14 @@ int read_platform_resources_from_dt(
	struct platform_device *pdev = res->pdev;
	struct resource *kres = NULL;
	int rc = 0;
	uint32_t firmware_base = 0;

	if (!pdev->dev.of_node) {
		dprintk(VIDC_ERR, "DT node not found\n");
		return -ENOENT;
	}

	res->firmware_base = 0x0;
	res->firmware_base = (phys_addr_t)firmware_base;

	kres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	res->register_base = kres ? kres->start : -1;
@@ -703,6 +704,16 @@ int read_platform_resources_from_dt(
		goto err_load_max_hw_load;
	}

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

	if (!is_iommu_present(res)) {
		of_property_read_u32(pdev->dev.of_node, "qcom,fw-bias",
				&firmware_base);
		res->firmware_base = (phys_addr_t)firmware_base;
		dprintk(VIDC_DBG,
				"Using fw-bias : %pa", &res->firmware_base);
	}
	return rc;
err_load_max_hw_load:
	msm_vidc_free_clock_table(res);
+1 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ struct msm_vidc_platform_resources {
	struct regulator_set regulator_set;
	struct clock_set clock_set;
	struct bus_set bus_set;
	bool use_non_secure_pil;
};

static inline int is_iommu_present(struct msm_vidc_platform_resources *res)
+80 −77
Original line number Diff line number Diff line
@@ -34,9 +34,6 @@
#define FIRMWARE_SIZE			0X00A00000
#define REG_ADDR_OFFSET_BITMASK	0x000FFFFF

/*Workaround for simulator */
#define HFI_SIM_FW_BIAS		0x0

#define SHARED_QSIZE 0x1000000

static struct hal_device_data hal_ctxt;
@@ -106,14 +103,16 @@ static void venus_hfi_sim_modify_cmd_packet(u8 *packet,
	struct hfi_cmd_sys_session_init_packet *sys_init;
	struct hal_session *session = NULL;
	u8 i;
	phys_addr_t fw_bias = 0;

	if (!device || !packet) {
		dprintk(VIDC_ERR, "Invalid Param\n");
		return;
	} else if (HFI_SIM_FW_BIAS == 0) {
	} else if (device->hal_data->firmware_base == 0) {
		return;
	}

	fw_bias = device->hal_data->firmware_base;
	sys_init = (struct hfi_cmd_sys_session_init_packet *)packet;
	if (&device->session_lock) {
		mutex_lock(&device->session_lock);
@@ -133,21 +132,21 @@ static void venus_hfi_sim_modify_cmd_packet(u8 *packet,
			*pkt = (struct
			hfi_cmd_session_empty_buffer_compressed_packet
			*) packet;
			pkt->packet_buffer -= HFI_SIM_FW_BIAS;
			pkt->packet_buffer -= fw_bias;
		} else {
			struct
			hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
			*pkt = (struct
			hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
			*) packet;
			pkt->packet_buffer -= HFI_SIM_FW_BIAS;
			pkt->packet_buffer -= fw_bias;
		}
		break;
	case HFI_CMD_SESSION_FILL_BUFFER:
	{
		struct hfi_cmd_session_fill_buffer_packet *pkt =
			(struct hfi_cmd_session_fill_buffer_packet *)packet;
		pkt->packet_buffer -= HFI_SIM_FW_BIAS;
		pkt->packet_buffer -= fw_bias;
		break;
	}
	case HFI_CMD_SESSION_SET_BUFFERS:
@@ -158,12 +157,12 @@ static void venus_hfi_sim_modify_cmd_packet(u8 *packet,
			(pkt->buffer_type == HFI_BUFFER_OUTPUT2)) {
			struct hfi_buffer_info *buff;
			buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
			buff->buffer_addr -= HFI_SIM_FW_BIAS;
			if (buff->extra_data_addr >= HFI_SIM_FW_BIAS)
				buff->extra_data_addr -= HFI_SIM_FW_BIAS;
			buff->buffer_addr -= fw_bias;
			if (buff->extra_data_addr >= fw_bias)
				buff->extra_data_addr -= fw_bias;
		} else {
			for (i = 0; i < pkt->num_buffers; i++)
				pkt->rg_buffer_info[i] -= HFI_SIM_FW_BIAS;
				pkt->rg_buffer_info[i] -= fw_bias;
		}
		break;
	}
@@ -175,11 +174,11 @@ static void venus_hfi_sim_modify_cmd_packet(u8 *packet,
			(pkt->buffer_type == HFI_BUFFER_OUTPUT2)) {
			struct hfi_buffer_info *buff;
			buff = (struct hfi_buffer_info *) pkt->rg_buffer_info;
			buff->buffer_addr -= HFI_SIM_FW_BIAS;
			buff->extra_data_addr -= HFI_SIM_FW_BIAS;
			buff->buffer_addr -= fw_bias;
			buff->extra_data_addr -= fw_bias;
		} else {
			for (i = 0; i < pkt->num_buffers; i++)
				pkt->rg_buffer_info[i] -= HFI_SIM_FW_BIAS;
				pkt->rg_buffer_info[i] -= fw_bias;
		}
		break;
	}
@@ -188,7 +187,7 @@ static void venus_hfi_sim_modify_cmd_packet(u8 *packet,
		struct hfi_cmd_session_parse_sequence_header_packet *pkt =
			(struct hfi_cmd_session_parse_sequence_header_packet *)
		packet;
		pkt->packet_buffer -= HFI_SIM_FW_BIAS;
		pkt->packet_buffer -= fw_bias;
		break;
	}
	case HFI_CMD_SESSION_GET_SEQUENCE_HEADER:
@@ -196,7 +195,7 @@ static void venus_hfi_sim_modify_cmd_packet(u8 *packet,
		struct hfi_cmd_session_get_sequence_header_packet *pkt =
			(struct hfi_cmd_session_get_sequence_header_packet *)
		packet;
		pkt->packet_buffer -= HFI_SIM_FW_BIAS;
		pkt->packet_buffer -= fw_bias;
		break;
	}
	default:
@@ -317,14 +316,16 @@ static void venus_hfi_hal_sim_modify_msg_packet(u8 *packet,
{
	struct hfi_msg_sys_session_init_done_packet *sys_idle;
	struct hal_session *session = NULL;
	phys_addr_t fw_bias = 0;

	if (!device || !packet) {
		dprintk(VIDC_ERR, "Invalid Param\n");
		return;
	} else if (HFI_SIM_FW_BIAS == 0) {
	} else if (device->hal_data->firmware_base == 0) {
		return;
	}

	fw_bias = device->hal_data->firmware_base;
	sys_idle = (struct hfi_msg_sys_session_init_done_packet *)packet;
	if (&device->session_lock) {
		mutex_lock(&device->session_lock);
@@ -345,21 +346,21 @@ static void venus_hfi_hal_sim_modify_msg_packet(u8 *packet,
			*pkt_uc = (struct
			hfi_msg_session_fbd_uncompressed_plane0_packet
			*) packet;
			pkt_uc->packet_buffer += HFI_SIM_FW_BIAS;
			pkt_uc->packet_buffer += fw_bias;
		} else {
			struct
			hfi_msg_session_fill_buffer_done_compressed_packet
			*pkt = (struct
			hfi_msg_session_fill_buffer_done_compressed_packet
			*) packet;
			pkt->packet_buffer += HFI_SIM_FW_BIAS;
			pkt->packet_buffer += fw_bias;
		}
		break;
	case HFI_MSG_SESSION_EMPTY_BUFFER_DONE:
	{
		struct hfi_msg_session_empty_buffer_done_packet *pkt =
		(struct hfi_msg_session_empty_buffer_done_packet *)packet;
		pkt->packet_buffer += HFI_SIM_FW_BIAS;
		pkt->packet_buffer += fw_bias;
		break;
	}
	case HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE:
@@ -369,7 +370,7 @@ static void venus_hfi_hal_sim_modify_msg_packet(u8 *packet,
		*pkt =
		(struct hfi_msg_session_get_sequence_header_done_packet *)
		packet;
		pkt->sequence_header += HFI_SIM_FW_BIAS;
		pkt->sequence_header += fw_bias;
		break;
	}
	default:
@@ -526,24 +527,6 @@ static void venus_hfi_write_register(struct venus_hfi_device *device, u32 reg,
		return;
	}

	reg &= REG_ADDR_OFFSET_BITMASK;
	if (reg == (u32)VIDC_CPU_CS_SCIACMDARG2) {
		/* workaround to offset of FW bias */
		struct hfi_queue_header *qhdr;
		struct hfi_queue_table_header *qtbl_hdr =
			(struct hfi_queue_table_header *)vaddr;

		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 0);
		qhdr->qhdr_start_addr -= HFI_SIM_FW_BIAS;

		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 1);
		qhdr->qhdr_start_addr -= HFI_SIM_FW_BIAS;

		qhdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(qtbl_hdr, 2);
		qhdr->qhdr_start_addr -= HFI_SIM_FW_BIAS;
		value -= HFI_SIM_FW_BIAS;
	}

	base_addr = device->hal_data->register_base;
	dprintk(VIDC_DBG, "Base addr: 0x%p, written to: 0x%x, Value: 0x%x...\n",
		base_addr, hwiosymaddr, value);
@@ -1414,7 +1397,7 @@ static void venus_hfi_interface_queues_release(struct venus_hfi_device *device)
	struct hfi_mem_map_table *qdss;
	struct hfi_mem_map *mem_map;
	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));
	int domain, partition;
	int domain = -1, partition = -1;
	unsigned long mem_map_table_base_addr;

	mutex_lock(&device->write_lock);
@@ -1437,10 +1420,13 @@ static void venus_hfi_interface_queues_release(struct venus_hfi_device *device)
		mem_map = (struct hfi_mem_map *)(qdss + 1);
		msm_smem_get_domain_partition(device->hal_client, 0,
			HAL_BUFFER_INTERNAL_CMD_QUEUE, &domain, &partition);
		if (domain >= 0 && partition >= 0) {
			for (i = 0; i < num_entries; i++) {
				msm_iommu_unmap_contig_buffer(
				(unsigned long)(mem_map[i].virtual_addr),
				domain, partition, SZ_4K);
					(unsigned long)
					(mem_map[i].virtual_addr), domain,
					partition, SZ_4K);
			}
		}
		venus_hfi_free(device, device->qdss.mem_data);
	}
@@ -1483,9 +1469,10 @@ static int venus_hfi_get_qdss_iommu_virtual_addr(struct hfi_mem_map *mem_map,
	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));

	for (i = 0; i < num_entries; i++) {
		rc = msm_iommu_map_contig_buffer(venus_qdss_entries[i][0],
			domain, partition, venus_qdss_entries[i][1],
			SZ_4K, 0, &iova);
		if (domain >= 0 && partition >= 0) {
			rc = msm_iommu_map_contig_buffer(
				venus_qdss_entries[i][0], domain, partition,
				venus_qdss_entries[i][1], SZ_4K, 0, &iova);
			if (rc) {
				dprintk(VIDC_ERR,
						"IOMMU QDSS mapping failed for addr 0x%x\n",
@@ -1493,6 +1480,9 @@ static int venus_hfi_get_qdss_iommu_virtual_addr(struct hfi_mem_map *mem_map,
				rc = -ENOMEM;
				break;
			}
		} else {
			iova =  venus_qdss_entries[i][0];
		}
		mem_map[i].virtual_addr = iova;
		mem_map[i].physical_addr = venus_qdss_entries[i][0];
		mem_map[i].size = venus_qdss_entries[i][1];
@@ -1501,10 +1491,14 @@ static int venus_hfi_get_qdss_iommu_virtual_addr(struct hfi_mem_map *mem_map,
	if (i < num_entries) {
		dprintk(VIDC_ERR,
			"IOMMU QDSS mapping failed, Freeing entries %d\n", i);

		if (domain >= 0 && partition >= 0) {
			for (--i; i >= 0; i--) {
				msm_iommu_unmap_contig_buffer(
				(unsigned long)(mem_map[i].virtual_addr),
				domain, partition, SZ_4K);
					(unsigned long)
					(mem_map[i].virtual_addr), domain,
					partition, SZ_4K);
			}
		}
	}
	return rc;
@@ -1523,11 +1517,13 @@ static int venus_hfi_interface_queues_init(struct venus_hfi_device *dev)
	struct vidc_mem_addr *mem_addr;
	int offset = 0;
	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));
	int domain, partition;
	int domain = -1, partition = -1;
	u32 value = 0;
	unsigned long mem_map_table_base_addr;
	phys_addr_t fw_bias = 0;

	mem_addr = &dev->mem_addr;
	fw_bias = dev->hal_data->firmware_base;
	rc = venus_hfi_alloc(dev, (void *) mem_addr,
			QUEUE_SIZE, 1, 0,
			HAL_BUFFER_INTERNAL_CMD_QUEUE);
@@ -1536,15 +1532,16 @@ static int venus_hfi_interface_queues_init(struct venus_hfi_device *dev)
		goto fail_alloc_queue;
	}
	dev->iface_q_table.align_virtual_addr = mem_addr->align_virtual_addr;
	dev->iface_q_table.align_device_addr = mem_addr->align_device_addr;
	dev->iface_q_table.align_device_addr = mem_addr->align_device_addr -
					fw_bias;
	dev->iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE;
	dev->iface_q_table.mem_data = mem_addr->mem_data;
	offset += dev->iface_q_table.mem_size;

	for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
		iface_q = &dev->iface_queues[i];
		iface_q->q_array.align_device_addr =
			mem_addr->align_device_addr + offset;
		iface_q->q_array.align_device_addr = mem_addr->align_device_addr
			+ offset - fw_bias;
		iface_q->q_array.align_virtual_addr =
			mem_addr->align_virtual_addr + offset;
		iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE;
@@ -1564,7 +1561,7 @@ static int venus_hfi_interface_queues_init(struct venus_hfi_device *dev)
			dev->qdss.align_device_addr = 0;
		} else {
			dev->qdss.align_device_addr =
				mem_addr->align_device_addr;
				mem_addr->align_device_addr - fw_bias;
			dev->qdss.align_virtual_addr =
				mem_addr->align_virtual_addr;
			dev->qdss.mem_size = QDSS_SIZE;
@@ -1578,7 +1575,8 @@ static int venus_hfi_interface_queues_init(struct venus_hfi_device *dev)
		dprintk(VIDC_WARN, "sfr_alloc_fail: SFR not will work\n");
		dev->sfr.align_device_addr = 0;
	} else {
		dev->sfr.align_device_addr = mem_addr->align_device_addr;
		dev->sfr.align_device_addr = mem_addr->align_device_addr -
					fw_bias;
		dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr;
		dev->sfr.mem_size = SFR_SIZE;
		dev->sfr.mem_data = mem_addr->mem_data;
@@ -3613,9 +3611,11 @@ static int venus_hfi_load_fw(void *dev)
		goto fail_enable_gdsc;
	}

	if (!device->resources.fw.cookie) {
	if ((!device->res->use_non_secure_pil && !device->res->firmware_base)
			|| (device->res->use_non_secure_pil)) {

		if (!device->resources.fw.cookie)
			device->resources.fw.cookie = subsystem_get("venus");
	}

		if (IS_ERR_OR_NULL(device->resources.fw.cookie)) {
			dprintk(VIDC_ERR, "Failed to download firmware\n");
@@ -3623,7 +3623,7 @@ static int venus_hfi_load_fw(void *dev)
			mutex_unlock(&device->clk_pwr_lock);
			goto fail_load_fw;
		}

	}
	device->power_enabled = 1;
	mutex_unlock(&device->clk_pwr_lock);

@@ -3638,16 +3638,19 @@ static int venus_hfi_load_fw(void *dev)
	/* Hand off control of regulators to h/w _after_ enabling clocks */
	venus_hfi_enable_hw_power_collapse(device);

	if (!device->res->use_non_secure_pil && !device->res->firmware_base) {
		rc = protect_cp_mem(device);
		if (rc) {
			dprintk(VIDC_ERR, "Failed to protect memory\n");
			goto fail_protect_mem;
		}
	}

	return rc;
fail_protect_mem:
	venus_hfi_disable_clks(device);
fail_enable_clks:
	if (device->resources.fw.cookie)
		subsystem_put(device->resources.fw.cookie);
fail_load_fw:
	mutex_lock(&device->clk_pwr_lock);