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

Commit cc4d8f7b authored by Akhil P Oommen's avatar Akhil P Oommen
Browse files

msm: kgsl: Add support for speedbin specific acd table



Currently, there is a common acd hfi table which is sent
irrespective of the speedbin. This won't work since some
SKUs may have an odd frequency. Also, the gmu firmware
doesn't like it if the size of dcvs table is smaller than the
acd table.

To solve this, specify the acd dvm value as part of the frequency
table and dynamically generate the acd table that matches the SKU.

Change-Id: I8a98465b35099334bed2fdc11b517ec9ebbb9983
Signed-off-by: default avatarAkhil P Oommen <akhilpo@codeaurora.org>
parent 364e8d57
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -947,6 +947,9 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
			&level->gpu_freq))
			return -EINVAL;

		of_property_read_u32(child, "qcom,acd-level",
			&level->acd_level);

		ret = _of_property_read_ddrtype(child,
			"qcom,bus-freq", &level->bus_freq);
		if (ret) {
+36 −43
Original line number Diff line number Diff line
@@ -807,38 +807,6 @@ static void build_bwtable_cmd_cache(struct gmu_device *gmu)
				votes->cnoc_votes.cmd_data[i][j];
}

static int gmu_acd_probe(struct gmu_device *gmu, struct device_node *node)
{
	struct hfi_acd_table_cmd *cmd = &gmu->hfi.acd_tbl_cmd;
	struct device_node *acd_node;

	acd_node = of_find_node_by_name(node, "qcom,gpu-acd-table");
	if (!acd_node)
		return -ENODEV;

	cmd->hdr = 0xFFFFFFFF;
	cmd->version = HFI_ACD_INIT_VERSION;
	cmd->enable_by_level = 0;
	cmd->stride = 0;
	cmd->num_levels = 0;

	of_property_read_u32(acd_node, "qcom,acd-stride", &cmd->stride);
	if (!cmd->stride || cmd->stride > MAX_ACD_STRIDE)
		return -EINVAL;

	of_property_read_u32(acd_node, "qcom,acd-num-levels", &cmd->num_levels);
	if (!cmd->num_levels || cmd->num_levels > MAX_ACD_NUM_LEVELS)
		return -EINVAL;

	of_property_read_u32(acd_node, "qcom,acd-enable-by-level",
			&cmd->enable_by_level);
	if (hweight32(cmd->enable_by_level) != cmd->num_levels)
		return -EINVAL;

	return of_property_read_u32_array(acd_node, "qcom,acd-data",
			cmd->data, cmd->stride * cmd->num_levels);
}

/*
 * gmu_bus_vote_init - initialized RPMh votes needed for bw scaling by GMU.
 * @gmu: Pointer to GMU device
@@ -1281,6 +1249,41 @@ int gmu_cache_finalize(struct kgsl_device *device)
	return 0;
}

static void gmu_acd_probe(struct kgsl_device *device, struct gmu_device *gmu,
		struct device_node *node)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct hfi_acd_table_cmd *cmd = &gmu->hfi.acd_tbl_cmd;
	u32 acd_level, cmd_idx, numlvl = pwr->num_pwrlevels;
	int ret, i;

	if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_ACD))
		return;

	cmd->hdr = 0xFFFFFFFF;
	cmd->version = HFI_ACD_INIT_VERSION;
	cmd->stride = 1;
	cmd->enable_by_level = 0;

	for (i = 0, cmd_idx = 0; i < numlvl; i++) {
		acd_level = pwr->pwrlevels[numlvl - i - 1].acd_level;
		if (acd_level) {
			cmd->enable_by_level |= (1 << i);
			cmd->data[cmd_idx++] = acd_level;
		}
	}

	if (!cmd->enable_by_level)
		return;

	cmd->num_levels = cmd_idx;

	ret = gmu_aop_mailbox_init(device, gmu);
	if (ret)
		dev_err(&gmu->pdev->dev,
			"AOP mailbox init failed: %d\n", ret);
}

/* Do not access any GMU registers in GMU probe function */
static int gmu_probe(struct kgsl_device *device, struct device_node *node)
{
@@ -1393,17 +1396,7 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node)
	else
		gmu->idle_level = GPU_HW_ACTIVE;

	if (ADRENO_FEATURE(adreno_dev, ADRENO_ACD)) {
		if (!gmu_acd_probe(gmu, node)) {
			/* Init the AOP mailbox if we have a valid ACD table */
			ret = gmu_aop_mailbox_init(device, gmu);
			if (ret)
				dev_err(&gmu->pdev->dev,
					"AOP mailbox init failed: %d\n", ret);
		} else
			dev_err(&gmu->pdev->dev,
				"ACD probe failed: missing or invalid table\n");
	}
	gmu_acd_probe(device, gmu, node);

	set_bit(GMU_ENABLED, &device->gmu_core.flags);
	device->gmu_core.dev_ops = &adreno_a6xx_gmudev;
+1 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ struct kgsl_pwrlevel {
	unsigned int bus_freq;
	unsigned int bus_min;
	unsigned int bus_max;
	unsigned int acd_level;
};

struct kgsl_regulator {