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

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

Merge changes Iea7b02fd,I591c0e3f,Icffeed49,I4f414194,I6dd733db into msm-4.14

* changes:
  msm: kgsl: Remove guard band on HFI message queues
  msm: kgsl: Return correct error code if HFI write fails
  msm: kgsl: Free temporary GMU allocated memory
  msm: kgsl: Report GMU firmware failure up the stack
  msm: kgsl: Make DCVS nohfi not use hfi types directly
parents 730b46d6 b69722d9
Loading
Loading
Loading
Loading
+6 −16
Original line number Diff line number Diff line
@@ -2036,6 +2036,8 @@ static int a6xx_gmu_fw_start(struct kgsl_device *device,
	return ret;
}

#define PERF_VOTE(idx, ack) (((idx) & 0xFF) | (((ack) & 0xF) << 28))
#define BW_VOTE(idx) ((idx) & 0xFF)
/*
 * a6xx_gmu_dcvs_nohfi() - request GMU to do DCVS without using HFI
 * @device: Pointer to KGSL device
@@ -2047,28 +2049,16 @@ static int a6xx_gmu_fw_start(struct kgsl_device *device,
static int a6xx_gmu_dcvs_nohfi(struct kgsl_device *device,
		unsigned int perf_idx, unsigned int bw_idx)
{
	struct hfi_dcvs_cmd dcvs_cmd = {
		.ack_type = ACK_NONBLOCK,
		.freq = {
			.perf_idx = perf_idx,
			.clkset_opt = OPTION_AT_LEAST,
		},
		.bw = {
			.bw_idx = bw_idx,
		},
	};
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct gmu_device *gmu = &device->gmu;
	union gpu_perf_vote vote;
	int ret;

	kgsl_gmu_regwrite(device, A6XX_GMU_DCVS_ACK_OPTION, dcvs_cmd.ack_type);
	kgsl_gmu_regwrite(device, A6XX_GMU_DCVS_ACK_OPTION, ACK_NONBLOCK);

	vote.fvote = dcvs_cmd.freq;
	kgsl_gmu_regwrite(device, A6XX_GMU_DCVS_PERF_SETTING, vote.raw);
	kgsl_gmu_regwrite(device, A6XX_GMU_DCVS_PERF_SETTING,
			PERF_VOTE(perf_idx, OPTION_AT_LEAST));

	vote.bvote = dcvs_cmd.bw;
	kgsl_gmu_regwrite(device, A6XX_GMU_DCVS_BW_SETTING, vote.raw);
	kgsl_gmu_regwrite(device, A6XX_GMU_DCVS_BW_SETTING, BW_VOTE(bw_idx));

	ret = a6xx_oob_set(adreno_dev, OOB_DCVS_SET_MASK, OOB_DCVS_CHECK_MASK,
		OOB_DCVS_CLEAR_MASK);
+4 −3
Original line number Diff line number Diff line
@@ -736,7 +736,7 @@ static int gmu_bus_vote_init(struct gmu_device *gmu, struct kgsl_pwrctrl *pwr)
	 */
	ret = msm_bus_scale_query_tcs_cmd_all(&hdl, gmu->pcl);
	if (ret)
		return ret;
		goto out;

	build_rpmh_bw_votes(&votes->ddr_votes, gmu->num_bwlevels, hdl);

@@ -745,13 +745,14 @@ static int gmu_bus_vote_init(struct gmu_device *gmu, struct kgsl_pwrctrl *pwr)
	 */
	ret = msm_bus_scale_query_tcs_cmd_all(&hdl, gmu->ccl);
	if (ret)
		return ret;
		goto out;

	build_rpmh_bw_votes(&votes->cnoc_votes, gmu->num_cnocbwlevels, hdl);

out:
	kfree(usecases);

	return 0;
	return ret;
}

static int gmu_rpmh_init(struct gmu_device *gmu, struct kgsl_pwrctrl *pwr)
+0 −5
Original line number Diff line number Diff line
@@ -15,11 +15,6 @@

#include "kgsl_hfi.h"

#define FW_VER_MAJOR(ver)		(((ver)>>28) & 0xFF)
#define FW_VER_MINOR(ver)		(((ver)>>16) & 0xFFF)
#define FW_VERSION(major, minor)	\
		(((major) << 28) | (((minor) & 0xFFF) << 16))

#define GMU_INT_WDOG_BITE		BIT(0)
#define GMU_INT_RSCC_COMP		BIT(1)
#define GMU_INT_FENCE_ERR		BIT(3)
+50 −32
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
#include "kgsl_trace.h"

/* Size in below functions are in unit of dwords */
static int hfi_msgq_read(struct gmu_device *gmu,
static int hfi_queue_read(struct gmu_device *gmu,
		enum hfi_queue_type queue_idx, void *msg,
		unsigned int max_size)
{
@@ -64,7 +64,7 @@ static int hfi_msgq_read(struct gmu_device *gmu,
}

/* Size in below functions are in unit of dwords */
static int hfi_cmdq_write(struct gmu_device *gmu,
static int hfi_queue_write(struct gmu_device *gmu,
		enum hfi_queue_type queue_idx,
		struct hfi_msg_hdr *msg)
{
@@ -122,7 +122,7 @@ static int hfi_cmdq_write(struct gmu_device *gmu,
	adreno_write_gmureg(ADRENO_DEVICE(device),
		ADRENO_REG_GMU_HOST2GMU_INTR_SET, 0x1);

	return msg->size;
	return 0;
}

#define QUEUE_HDR_TYPE(id, prio, rtype, stype) \
@@ -220,11 +220,8 @@ static int hfi_send_msg(struct gmu_device *gmu, struct hfi_msg_hdr *msg,
	struct kgsl_hfi *hfi = &gmu->hfi;

	msg->seqnum = atomic_inc_return(&hfi->seqnum);
	if (msg->type != HFI_MSG_CMD) {
		if (hfi_cmdq_write(gmu, HFI_CMD_QUEUE, msg) != size)
			rc = -EINVAL;
		return rc;
	}
	if (msg->type != HFI_MSG_CMD)
		return hfi_queue_write(gmu, HFI_CMD_QUEUE, msg);

	/* For messages of type HFI_MSG_CMD we must handle the ack */
	init_completion(&ret_msg->msg_complete);
@@ -235,10 +232,9 @@ static int hfi_send_msg(struct gmu_device *gmu, struct hfi_msg_hdr *msg,
	list_add_tail(&ret_msg->node, &hfi->msglist);
	spin_unlock_bh(&hfi->msglock);

	if (hfi_cmdq_write(gmu, HFI_CMD_QUEUE, msg) != size) {
		rc = -EINVAL;
	rc = hfi_queue_write(gmu, HFI_CMD_QUEUE, msg);
	if (rc)
		goto done;
	}

	rc = wait_for_completion_timeout(
			&ret_msg->msg_complete,
@@ -542,7 +538,7 @@ void hfi_receiver(unsigned long data)

	gmu = (struct gmu_device *)data;

	while (hfi_msgq_read(gmu, HFI_MSG_QUEUE,
	while (hfi_queue_read(gmu, HFI_MSG_QUEUE,
			&response, sizeof(response)) > 0) {
		if (response.hdr.size > (sizeof(response) >> 2)) {
			dev_err(&gmu->pdev->dev,
@@ -567,15 +563,51 @@ void hfi_receiver(unsigned long data)
	};
}

int hfi_start(struct gmu_device *gmu, uint32_t boot_state)
#define FW_VER_MAJOR(ver) (((ver) >> 28) & 0xF)
#define FW_VER_MINOR(ver) (((ver) >> 16) & 0xFFF)
#define FW_VERSION(major, minor) \
	((((major) & 0xF) << 28) | (((minor) & 0xFFF) << 16))

static int hfi_verify_fw_version(struct gmu_device *gmu)
{
	struct kgsl_device *device =
			container_of(gmu, struct kgsl_device, gmu);
	struct kgsl_device *device = container_of(gmu, struct kgsl_device, gmu);
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct device *dev = &gmu->pdev->dev;
	int result;
	unsigned int ver = 0, major, minor;

	major = adreno_dev->gpucore->gpmu_major;
	minor = adreno_dev->gpucore->gpmu_minor;

	result = hfi_get_fw_version(gmu, FW_VERSION(major, minor), &ver);
	if (result) {
		dev_err_once(&gmu->pdev->dev,
				"Failed to get FW version via HFI\n");
		return result;
	}

	/* For now, warn once. Could return error later if needed */
	if (major != FW_VER_MAJOR(ver))
		dev_err_once(&gmu->pdev->dev,
				"FW Major Error: Wanted %d, got %d\n",
				major, FW_VER_MAJOR(ver));

	if (minor > FW_VER_MINOR(ver))
		dev_err_once(&gmu->pdev->dev,
				"FW Minor Error: Wanted < %d, got %d\n",
				FW_VER_MINOR(ver), minor);

	/* Save the gmu version information */
	gmu->ver = ver;

	return 0;
}

int hfi_start(struct gmu_device *gmu, uint32_t boot_state)
{
	struct kgsl_device *device = container_of(gmu, struct kgsl_device, gmu);
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	int result;

	if (test_bit(GMU_HFI_ON, &gmu->flags))
		return 0;

@@ -583,23 +615,9 @@ int hfi_start(struct gmu_device *gmu, uint32_t boot_state)
	if (result)
		return result;

	major = adreno_dev->gpucore->gpmu_major;
	minor = adreno_dev->gpucore->gpmu_minor;
	result = hfi_get_fw_version(gmu,
			FW_VERSION(major, minor), &ver);
	result = hfi_verify_fw_version(gmu);
	if (result)
		dev_err(dev, "Failed to get FW version via HFI\n");

	gmu->ver = ver;
	if (major != FW_VER_MAJOR(ver))
		WARN_ONCE(1, "FW version major %d error (expect %d)\n",
				FW_VER_MAJOR(ver),
				adreno_dev->gpucore->gpmu_major);

	if (minor > FW_VER_MINOR(ver))
		WARN_ONCE(1, "FW version minor %d error (expect %d)\n",
				FW_VER_MINOR(ver),
				adreno_dev->gpucore->gpmu_minor);
		return result;

	result = hfi_send_perftbl(gmu);
	if (result)
+1 −2
Original line number Diff line number Diff line
@@ -27,10 +27,9 @@ enum hfi_queue_type {
	HFI_QUEUE_MAX
};

/* Add 16B guard band between HFI queues */
#define HFI_QUEUE_OFFSET(i)		\
		((sizeof(struct hfi_queue_table)) + \
		((i) * (HFI_QUEUE_SIZE + 16)))
		((i) * HFI_QUEUE_SIZE))

#define HOST_QUEUE_START_ADDR(hfi_mem, i) \
	((hfi_mem)->hostptr + HFI_QUEUE_OFFSET(i))