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

Commit 93c50b8f authored by Sunil Khatri's avatar Sunil Khatri
Browse files

msm: kgsl: Add multiple fuses based speed bin



Add multiple fuses based speed bin. This enables
support for different GPU Fmax frequencies based
on speed bin value.

Change-Id: I9799111c2ccdafee405a4612c342e809720eb612
Signed-off-by: default avatarSunil Khatri <sunilkh@codeaurora.org>
parent c287f849
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -127,6 +127,19 @@ Optional Properties:
				mask   - mask for the relevant bits in the efuse register.
				shift  - number of bits to right shift to get the speed bin
				value.

- qcom,gpu-speed-bin-vectors:
				GPU speed bin vectors property is the series of all the vectors
				in format specified below. Values from individual fuses are read,
				masked and shifted to form a value. At the end all fuse values
				are ordered together to form final speed bin value.
				<offset mask shift>
				<offset mask shift>
				<  ..   ..    ..  >
				offset - offset of the efuse register from the base.
				mask   - mask for the relevant bits in the efuse register.
				shift  - number of bits to right shift.

- qcom,gpu-disable-fuse:	GPU disable fuse
				<offset mask shift>
				offset - offset of the efuse register from the base.
+53 −0
Original line number Diff line number Diff line
@@ -279,6 +279,59 @@ int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset,
	return 0;
}

void adreno_efuse_speed_bin_array(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	int ret, count, i = 0;
	unsigned int val, vector_size = 3;
	unsigned int *bin_vector;

	/*
	 * Here count is no of 32 bit elements in the
	 * speed-bin-vector array. If there are two fuses
	 * i.e If no of fuses are 2 then no of elements will be
	 * 2 * 3 = 6(elements of 32 bit each).
	 */
	count = of_property_count_u32_elems(device->pdev->dev.of_node,
				"qcom,gpu-speed-bin-vectors");
	if (count <= 0)
		return;

	bin_vector = kmalloc(sizeof(count * sizeof(unsigned int)),
			GFP_KERNEL);
	if (bin_vector == NULL) {
		KGSL_DRV_ERR(device,
				"Unable to allocate memory for speed-bin vector\n");
		return;
	}

	if (of_property_read_u32_array(device->pdev->
			dev.of_node, "qcom,gpu-speed-bin-vectors",
			bin_vector, count)) {
		KGSL_DRV_ERR(device,
				"Speed-bin-vectors is invalid\n");
		kfree(bin_vector);
		return;
	}

	/*
	 * Final value of adreno_dev->speed_bin is the value formed by
	 * OR'ing the values read from all the fuses.
	 */
	while (i < count) {
		ret = adreno_efuse_read_u32(adreno_dev, bin_vector[i], &val);

		if (ret < 0)
			break;

		adreno_dev->speed_bin |= (val & bin_vector[i+1])
				>> bin_vector[i+2];
		i += vector_size;
	}

	kfree(bin_vector);
}

static int _get_counter(struct adreno_device *adreno_dev,
		int group, int countable, unsigned int *lo,
		unsigned int *hi)
+1 −0
Original line number Diff line number Diff line
@@ -1130,6 +1130,7 @@ int adreno_efuse_map(struct adreno_device *adreno_dev);
int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset,
		unsigned int *val);
void adreno_efuse_unmap(struct adreno_device *adreno_dev);
void adreno_efuse_speed_bin_array(struct adreno_device *adreno_dev);

bool adreno_is_cx_dbgc_register(struct kgsl_device *device,
		unsigned int offset);
+22 −2
Original line number Diff line number Diff line
@@ -122,14 +122,34 @@ static void a530_efuse_speed_bin(struct adreno_device *adreno_dev)
	adreno_dev->speed_bin = (val & speed_bin[1]) >> speed_bin[2];
}

static void a5xx_efuse_speed_bin(struct adreno_device *adreno_dev)
{
	unsigned int val;
	unsigned int speed_bin[3];
	struct kgsl_device *device = &adreno_dev->dev;

	if (of_get_property(device->pdev->dev.of_node,
			"qcom,gpu-speed-bin-vectors", NULL)) {
		adreno_efuse_speed_bin_array(adreno_dev);
		return;
	}

	if (!of_property_read_u32_array(device->pdev->dev.of_node,
			"qcom,gpu-speed-bin", speed_bin, 3)) {
		adreno_efuse_read_u32(adreno_dev, speed_bin[0], &val);
		adreno_dev->speed_bin = (val & speed_bin[1]) >> speed_bin[2];
		return;
	}
}

static const struct {
	int (*check)(struct adreno_device *adreno_dev);
	void (*func)(struct adreno_device *adreno_dev);
} a5xx_efuse_funcs[] = {
	{ adreno_is_a530, a530_efuse_leakage },
	{ adreno_is_a530, a530_efuse_speed_bin },
	{ adreno_is_a504, a530_efuse_speed_bin },
	{ adreno_is_a505, a530_efuse_speed_bin },
	{ adreno_is_a504, a5xx_efuse_speed_bin },
	{ adreno_is_a505, a5xx_efuse_speed_bin },
	{ adreno_is_a512, a530_efuse_speed_bin },
	{ adreno_is_a508, a530_efuse_speed_bin },
};