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

Commit 395f735d authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Add support for the new ACD protocol"

parents bf251c4d e56ca8b1
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -50,9 +50,11 @@
#define A6XX_CP_RB_RPTR                  0x806
#define A6XX_CP_RB_WPTR                  0x807
#define A6XX_CP_SQE_CNTL                 0x808
#define A6XX_CP_CP2GMU_STATUS            0x812
#define A6XX_CP_HW_FAULT                 0x821
#define A6XX_CP_INTERRUPT_STATUS         0x823
#define A6XX_CP_PROTECT_STATUS           0X824
#define A6XX_CP_PROTECT_STATUS           0x824
#define A6XX_CP_STATUS_1                 0x825
#define A6XX_CP_SQE_INSTR_BASE_LO        0x830
#define A6XX_CP_SQE_INSTR_BASE_HI        0x831
#define A6XX_CP_MISC_CNTL                0x840
+0 −4
Original line number Diff line number Diff line
@@ -940,10 +940,6 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
		if (of_property_read_u32(child, "qcom,bus-max",
			&level->bus_max))
			level->bus_max = level->bus_freq;

		if (of_property_read_u32(child, "qcom,dvm-val",
				&level->acd_dvm_val))
			level->acd_dvm_val = 0xFFFFFFFF;
	}

	return 0;
+32 −3
Original line number Diff line number Diff line
@@ -849,7 +849,7 @@ static bool idle_trandition_complete(unsigned int idle_level,
static int a6xx_gmu_wait_for_lowest_idle(struct kgsl_device *device)
{
	struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
	unsigned int reg, reg1;
	unsigned int reg, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8;
	unsigned long t;
	uint64_t ts1, ts2, ts3;

@@ -881,9 +881,38 @@ static int a6xx_gmu_wait_for_lowest_idle(struct kgsl_device *device)
		return 0;

	ts3 = read_AO_counter(device);
	WARN(1, "Timeout waiting for lowest idle: %08x %llx %llx %llx %x\n",
		reg, ts1, ts2, ts3, reg1);

	/* Collect abort data to help with debugging */
	gmu_core_regread(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, &reg2);
	gmu_core_regread(device, A6XX_CP_STATUS_1, &reg3);
	gmu_core_regread(device, A6XX_GMU_RBBM_INT_UNMASKED_STATUS, &reg4);
	gmu_core_regread(device, A6XX_GMU_GMU_PWR_COL_KEEPALIVE, &reg5);
	gmu_core_regread(device, A6XX_CP_CP2GMU_STATUS, &reg6);
	gmu_core_regread(device, A6XX_CP_CONTEXT_SWITCH_CNTL, &reg7);
	gmu_core_regread(device, A6XX_GMU_AO_SPARE_CNTL, &reg8);

	dev_err(&gmu->pdev->dev,
		"----------------------[ GMU error ]----------------------\n");
	dev_err(&gmu->pdev->dev,
		"Timeout waiting for lowest idle level %s\n",
		gpu_idle_level_names[gmu->idle_level]);
	dev_err(&gmu->pdev->dev, "Start: %llx (absolute ticks)\n", ts1);
	dev_err(&gmu->pdev->dev, "Poll: %llx (ticks relative to start)\n",
		ts2-ts1);
	dev_err(&gmu->pdev->dev, "Retry: %llx (ticks relative to poll)\n",
		ts3-ts2);
	dev_err(&gmu->pdev->dev,
		"RPMH_POWER_STATE=%x SPTPRAC_PWR_CLK_STATUS=%x\n", reg, reg1);
	dev_err(&gmu->pdev->dev,
		"CX_BUSY_STATUS=%x CP_STATUS_1=%x\n", reg2, reg3);
	dev_err(&gmu->pdev->dev,
		"RBBM_INT_UNMASKED_STATUS=%x PWR_COL_KEEPALIVE=%x\n",
		reg4, reg5);
	dev_err(&gmu->pdev->dev,
		"CP2GMU_STATUS=%x CONTEXT_SWITCH_CNTL=%x AO_SPARE_CNTL=%x\n",
		reg6, reg7, reg8);

	WARN_ON(1);
	return -ETIMEDOUT;
}

+40 −4
Original line number Diff line number Diff line
@@ -807,6 +807,38 @@ 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
@@ -1310,7 +1342,6 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node)
		int j = gmu->num_gpupwrlevels - 1 - i;

		gmu->gpu_freqs[i] = pwr->pwrlevels[j].gpu_freq;
		gmu->acd_dvm_vals[i] = pwr->pwrlevels[j].acd_dvm_val;
	}

	/* Initializes GPU b/w levels configuration */
@@ -1343,10 +1374,15 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node)
		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");
	}

	/* disable LM if the feature is not enabled */
+0 −2
Original line number Diff line number Diff line
@@ -149,7 +149,6 @@ struct kgsl_mailbox {
 * @ccl: CNOC BW scaling client
 * @idle_level: Minimal GPU idle power level
 * @fault_count: GMU fault count
 * @acd_dvm_vals: Table of DVM values that correspond to frequency levels
 * @mailbox: Messages to AOP for ACD enable/disable go through this
 */
struct gmu_device {
@@ -182,7 +181,6 @@ struct gmu_device {
	unsigned int ccl;
	unsigned int idle_level;
	unsigned int fault_count;
	unsigned int acd_dvm_vals[MAX_GX_LEVELS];
	struct kgsl_mailbox mailbox;
};

Loading