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

Commit dde33368 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt
Browse files

msm: kgsl: Add memalloc hfi support



Allocate gpu globals based on memalloc hfi requests. Map
them in gmu as well.

Change-Id: I43ecfedf5be92e39fd079a00f8311fe6aca7191b
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent 9e3803d6
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -618,10 +618,10 @@ static int find_vma_block(struct a6xx_gmu_device *gmu, u32 addr, u32 size)
	return -ENOENT;
}

static struct iommu_domain *get_gmu_domain(struct a6xx_gmu_device *gmu,
	struct gmu_memdesc *md)
struct iommu_domain *a6xx_get_gmu_domain(struct a6xx_gmu_device *gmu,
	u32 gmuaddr, u32 size)
{
	u32 vma_id = find_vma_block(gmu, md->gmuaddr, md->size);
	u32 vma_id = find_vma_block(gmu, gmuaddr, size);

	if (vma_id == GMU_NONCACHED_USER)
		return a6xx_gmu_ctx[GMU_CONTEXT_USER].domain;
@@ -1390,8 +1390,8 @@ struct gmu_memdesc *reserve_gmu_kernel_block(struct a6xx_gmu_device *gmu,

	md->gmuaddr = addr;

	ret = iommu_map(get_gmu_domain(gmu, md), addr, md->physaddr, md->size,
		IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV);
	ret = iommu_map(a6xx_get_gmu_domain(gmu, md->gmuaddr, md->size), addr,
		md->physaddr, md->size, IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV);
	if (ret) {
		dev_err(&gmu->pdev->dev,
			"Unable to map GMU kernel block: addr:0x%08x size:0x%x :%d\n",
@@ -2393,7 +2393,8 @@ static void a6xx_free_gmu_globals(struct a6xx_gmu_device *gmu)
		if (!md->gmuaddr)
			continue;

		iommu_unmap(get_gmu_domain(gmu, md), md->gmuaddr, md->size);
		iommu_unmap(a6xx_get_gmu_domain(gmu, md->gmuaddr, md->size),
			md->gmuaddr, md->size);

		dma_free_attrs(&gmu->pdev->dev, (size_t) md->size,
				(void *)md->hostptr, md->physaddr, 0);
+14 −0
Original line number Diff line number Diff line
@@ -524,4 +524,18 @@ int a6xx_gmu_enable_clks(struct adreno_device *adreno_dev);
 * Return: 0 on success or negative error on failure
 */
int a6xx_gmu_enable_gdsc(struct adreno_device *adreno_dev);

/**
 * a6xx_get_gmu_domain - Get the gmu iommu domain for a gmu memory block
 * @gmu: Pointer to the a6xx gmu device
 * @gmuaddr: Address of the memory block
 * @size: Size in bytes of the memory block
 *
 * Based on the gmu address and size of a gmu memory block, get the gmu iommu
 * domain to map the memory block to.
 *
 * Return: gmu iommu domain to which the given memory block is to be mapped
 */
struct iommu_domain *a6xx_get_gmu_domain(struct a6xx_gmu_device *gmu,
	u32 gmuaddr, u32 size);
#endif
+12 −20
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ struct a6xx_hfi *to_a6xx_hfi(struct adreno_device *adreno_dev)
}

/* Size in below functions are in unit of dwords */
static int a6xx_hfi_queue_read(struct a6xx_gmu_device *gmu, uint32_t queue_idx,
int a6xx_hfi_queue_read(struct a6xx_gmu_device *gmu, uint32_t queue_idx,
		unsigned int *output, unsigned int max_size)
{
	struct gmu_memdesc *mem_addr = gmu->hfi.hfi_mem;
@@ -91,8 +91,8 @@ static int a6xx_hfi_queue_read(struct a6xx_gmu_device *gmu, uint32_t queue_idx,
}

/* Size in below functions are in unit of dwords */
static int a6xx_hfi_queue_write(struct adreno_device *adreno_dev,
	uint32_t queue_idx, uint32_t *msg)
int a6xx_hfi_queue_write(struct adreno_device *adreno_dev, uint32_t queue_idx,
		uint32_t *msg)
{
	struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
	struct hfi_queue_table *tbl = gmu->hfi.hfi_mem->hostptr;
@@ -154,11 +154,6 @@ static int a6xx_hfi_queue_write(struct adreno_device *adreno_dev,
	return 0;
}

#define QUEUE_HDR_TYPE(id, prio, rtype, stype) \
	(((id) & 0xFF) | (((prio) & 0xFF) << 8) | \
	(((rtype) & 0xFF) << 16) | (((stype) & 0xFF) << 24))


/* Sizes of the queue and message are in unit of dwords */
static void init_queues(struct adreno_device *adreno_dev)
{
@@ -228,7 +223,7 @@ int a6xx_hfi_init(struct adreno_device *adreno_dev)
#define HDR_CMP_SEQNUM(out_hdr, in_hdr) \
	(MSG_HDR_GET_SEQNUM(out_hdr) == MSG_HDR_GET_SEQNUM(in_hdr))

static int receive_ack_cmd(struct a6xx_gmu_device *gmu, void *rcvd,
int a6xx_receive_ack_cmd(struct a6xx_gmu_device *gmu, void *rcvd,
	struct pending_cmd *ret_cmd)
{
	struct adreno_device *adreno_dev = a6xx_gmu_to_adreno(gmu);
@@ -259,9 +254,6 @@ static int receive_ack_cmd(struct a6xx_gmu_device *gmu, void *rcvd,
	return -ENODEV;
}

#define MSG_HDR_SET_SEQNUM(hdr, num) \
	(((hdr) & 0xFFFFF) | ((num) << 20))

static int poll_gmu_reg(struct adreno_device *adreno_dev,
	u32 offsetdwords, unsigned int expected_val,
	unsigned int mask, unsigned int timeout_ms)
@@ -336,7 +328,7 @@ static int a6xx_hfi_send_cmd(struct adreno_device *adreno_dev,

#define HFI_ACK_ERROR 0xffffffff

static int a6xx_hfi_send_generic_req(struct adreno_device *adreno_dev,
int a6xx_hfi_send_generic_req(struct adreno_device *adreno_dev,
		uint32_t queue, void *cmd)
{
	struct pending_cmd ret_cmd;
@@ -400,7 +392,7 @@ static int a6xx_hfi_get_fw_version(struct adreno_device *adreno_dev,
	return rc;
}

static int a6xx_hfi_send_core_fw_start(struct adreno_device *adreno_dev)
int a6xx_hfi_send_core_fw_start(struct adreno_device *adreno_dev)
{
	struct hfi_core_fw_start_cmd cmd = {
		.hdr = CMD_MSG_HDR(H2F_MSG_CORE_FW_START, sizeof(cmd)),
@@ -424,7 +416,7 @@ static const char *feature_to_string(uint32_t feature)
	return "unknown";
}

static int a6xx_hfi_send_feature_ctrl(struct adreno_device *adreno_dev,
int a6xx_hfi_send_feature_ctrl(struct adreno_device *adreno_dev,
	uint32_t feature, uint32_t enable, uint32_t data)
{
	struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
@@ -523,7 +515,7 @@ static void a6xx_hfi_v1_receiver(struct a6xx_gmu_device *gmu, uint32_t *rcvd,
{
	/* V1 ACK Handler */
	if (MSG_HDR_GET_TYPE(rcvd[0]) == HFI_V1_MSG_ACK) {
		receive_ack_cmd(gmu, rcvd, ret_cmd);
		a6xx_receive_ack_cmd(gmu, rcvd, ret_cmd);
		return;
	}

@@ -557,7 +549,7 @@ static int a6xx_hfi_process_queue(struct a6xx_gmu_device *gmu,

		/* V2 ACK Handler */
		if (MSG_HDR_GET_TYPE(rcvd[0]) == HFI_MSG_ACK) {
			int ret = receive_ack_cmd(gmu, rcvd, ret_cmd);
			int ret = a6xx_receive_ack_cmd(gmu, rcvd, ret_cmd);

			if (ret)
				return ret;
@@ -622,7 +614,7 @@ static int a6xx_hfi_verify_fw_version(struct adreno_device *adreno_dev)
	return 0;
}

static int a6xx_hfi_send_bcl_feature_ctrl(struct adreno_device *adreno_dev)
int a6xx_hfi_send_bcl_feature_ctrl(struct adreno_device *adreno_dev)
{
	int ret;

@@ -634,7 +626,7 @@ static int a6xx_hfi_send_bcl_feature_ctrl(struct adreno_device *adreno_dev)
	return ret;
}

static int a6xx_hfi_send_lm_feature_ctrl(struct adreno_device *adreno_dev)
int a6xx_hfi_send_lm_feature_ctrl(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct hfi_set_value_cmd req;
@@ -661,7 +653,7 @@ static int a6xx_hfi_send_lm_feature_ctrl(struct adreno_device *adreno_dev)
	return ret;
}

static int a6xx_hfi_send_acd_feature_ctrl(struct adreno_device *adreno_dev)
int a6xx_hfi_send_acd_feature_ctrl(struct adreno_device *adreno_dev)
{
	struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
	int ret = 0;
+100 −3
Original line number Diff line number Diff line
@@ -35,9 +35,6 @@
#define HFI_DBG_PRI 40
#define HFI_DSP_PRI_0 20

#define HFI_RSP_TIMEOUT 100 /* msec */

#define HFI_IRQ_MSGQ_MASK		BIT(0)
#define HFI_IRQ_SIDEMSGQ_MASK		BIT(1)
#define HFI_IRQ_DBGQ_MASK		BIT(2)
#define HFI_IRQ_CM3_FAULT_MASK		BIT(15)
@@ -159,6 +156,17 @@ struct hfi_queue_table {
#define MSG_HDR_GET_TYPE(hdr) (((hdr) >> 16) & 0xF)
#define MSG_HDR_GET_SEQNUM(hdr) (((hdr) >> 20) & 0xFFF)

#define MSG_HDR_SET_SEQNUM(hdr, num) \
	(((hdr) & 0xFFFFF) | ((num) << 20))

#define QUEUE_HDR_TYPE(id, prio, rtype, stype) \
	(((id) & 0xFF) | (((prio) & 0xFF) << 8) | \
	(((rtype) & 0xFF) << 16) | (((stype) & 0xFF) << 24))

#define HFI_RSP_TIMEOUT 100 /* msec */

#define HFI_IRQ_MSGQ_MASK  BIT(0)

#define H2F_MSG_INIT		0
#define H2F_MSG_FW_VER		1
#define H2F_MSG_LM_CFG		2
@@ -578,4 +586,93 @@ int a6xx_hfi_send_req(struct adreno_device *adreno_dev,

/* Helper function to get to a6xx hfi struct from adreno device */
struct a6xx_hfi *to_a6xx_hfi(struct adreno_device *adreno_dev);

/**
 * a6xx_hfi_queue_write - Write a command to hfi queue
 * @adreno_dev: Pointer to the adreno device
 * @queue_idx: destination queue id
 * @msg: Data to be written to the queue
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_hfi_queue_write(struct adreno_device *adreno_dev, u32 queue_idx,
	u32 *msg);

/**
 * a6xx_hfi_queue_read - Read data from hfi queue
 * @gmu: Pointer to the a6xx gmu device
 * @queue_idx: queue id to read from
 * @output: Pointer to read the data into
 * @max_size: Number of bytes to read from the queue
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_hfi_queue_read(struct a6xx_gmu_device *gmu, u32 queue_idx,
	u32 *output, u32 max_size);

/**
 * a6xx_receive_ack_cmd - Process ack type packets
 * @gmu: Pointer to the a6xx gmu device
 * @rcvd: Pointer to the data read from hfi queue
 * @ret_cmd: Container for the hfi packet for which this ack is received
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_receive_ack_cmd(struct a6xx_gmu_device *gmu, void *rcvd,
	struct pending_cmd *ret_cmd);

/**
 * a6xx_hfi_send_feature_ctrl - Enable gmu feature via hfi
 * @adreno_dev: Pointer to the adreno device
 * @feature: feature to be enabled or disabled
 * enable: Set 1 to enable or 0 to disable a feature
 * @data: payload for the send feature hfi packet
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_hfi_send_feature_ctrl(struct adreno_device *adreno_dev,
	u32 feature, u32 enable, u32 data);

/**
 * a6xx_hfi_send_core_fw_start - Send the core fw start hfi
 * @adreno_dev: Pointer to the adreno device
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_hfi_send_core_fw_start(struct adreno_device *adreno_dev);

/**
 * a6xx_hfi_send_acd_feature_ctrl - Send the acd table and acd feature
 * @adreno_dev: Pointer to the adreno device
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_hfi_send_acd_feature_ctrl(struct adreno_device *adreno_dev);

/**
 * a6xx_hfi_send_lm_feature_ctrl -  Send the lm feature hfi packet
 * @adreno_dev: Pointer to the adreno device
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_hfi_send_lm_feature_ctrl(struct adreno_device *adreno_dev);

/**
 * a6xx_hfi_send_generic_req -  Send a generic hfi packet
 * @adreno_dev: Pointer to the adreno device
 * @queue: The destination hfi queue
 * @cmd: Pointer to the hfi packet header and data
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_hfi_send_generic_req(struct adreno_device *adreno_dev,
	u32 queue, void *cmd);

/**
 * a6xx_hfi_send_bcl_feature_ctrl -  Send the bcl feature hfi packet
 * @adreno_dev: Pointer to the adreno device
 *
 * Return: 0 on success or negative error on failure
 */
int a6xx_hfi_send_bcl_feature_ctrl(struct adreno_device *adreno_dev);
#endif
+9 −18
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@
#include "adreno.h"
#include "adreno_a6xx.h"
#include "adreno_a6xx_hwsched.h"
#include "adreno_a6xx_hwsched_hfi.h"
#include "kgsl_device.h"
#include "kgsl_trace.h"
#include "kgsl_util.h"
@@ -67,11 +66,7 @@ static int a6xx_hwsched_gmu_first_boot(struct adreno_device *adreno_dev)
	if (ret)
		goto err;

	ret = a6xx_gmu_hfi_start(adreno_dev);
	if (ret)
		goto err;

	ret = a6xx_hfi_start(adreno_dev);
	ret = a6xx_hwsched_hfi_start(adreno_dev);
	if (ret)
		goto err;

@@ -132,11 +127,7 @@ static int a6xx_hwsched_gmu_boot(struct adreno_device *adreno_dev)
	if (ret)
		goto err;

	ret = a6xx_gmu_hfi_start(adreno_dev);
	if (ret)
		goto err;

	ret = a6xx_hfi_start(adreno_dev);
	ret = a6xx_hwsched_hfi_start(adreno_dev);
	if (ret)
		goto err;

@@ -215,7 +206,7 @@ static int a6xx_hwsched_gmu_power_off(struct adreno_device *adreno_dev)

	a6xx_gmu_irq_disable(adreno_dev);

	a6xx_hfi_stop(adreno_dev);
	a6xx_hwsched_hfi_stop(adreno_dev);

	clk_bulk_disable_unprepare(gmu->num_clks, gmu->clks);

@@ -226,7 +217,7 @@ static int a6xx_hwsched_gmu_power_off(struct adreno_device *adreno_dev)
	return ret;

error:
	a6xx_hfi_stop(adreno_dev);
	a6xx_hwsched_hfi_stop(adreno_dev);
	a6xx_gmu_suspend(adreno_dev);

	return ret;
@@ -565,15 +556,15 @@ int a6xx_hwsched_probe(struct platform_device *pdev,
{
	struct adreno_device *adreno_dev;
	struct kgsl_device *device;
	struct a6xx_device *a6xx_dev;
	struct a6xx_hwsched_device *a6xx_hwsched_dev;
	int ret;

	a6xx_dev = devm_kzalloc(&pdev->dev, sizeof(*a6xx_dev),
	a6xx_hwsched_dev = devm_kzalloc(&pdev->dev, sizeof(*a6xx_hwsched_dev),
				GFP_KERNEL);
	if (!a6xx_dev)
	if (!a6xx_hwsched_dev)
		return -ENOMEM;

	adreno_dev = &a6xx_dev->adreno_dev;
	adreno_dev = &a6xx_hwsched_dev->a6xx_dev.adreno_dev;

	ret = a6xx_probe_common(pdev, adreno_dev, chipid, gpucore);
	if (ret)
Loading