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

Commit d3964166 authored by Kyle Piefer's avatar Kyle Piefer
Browse files

msm: kgsl: Restructure GMU idle level initialization



Idle level setting is currently initialized after powering
on the device. This incorrectly assumes that the kernel will
always control the HM and SPTP head switches at first.
To enable these features, the respective registers are
written at the same time as the setting of idle level,
but that is currently happening before turning on the power.

Fix these issues by initializing idle level during probe,
moving power configuration to after power on, and
cleaning up code.

CRs-Fixed: 2017390
Change-Id: Ia6e6b465c3f39049af0dae179548d0a2e0561e22
Signed-off-by: default avatarKyle Piefer <kpiefer@codeaurora.org>
parent 417dbabb
Loading
Loading
Loading
Loading
+24 −26
Original line number Diff line number Diff line
@@ -646,38 +646,36 @@ static void a6xx_gmu_power_config(struct kgsl_device *device)
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct gmu_device *gmu = &device->gmu;

	if (ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC)) {
		kgsl_gmu_regwrite(device, A6XX_GMU_PWR_COL_SPTPRAC_HYST,
			0x000A0080);
		_gmu_regrmw(device, A6XX_GMU_PWR_COL_INTER_FRAME_CTRL,
			SPTP_ENABLE_MASK);
		gmu->idle_level = GPU_HW_SPTP_PC;
	}

	if (ADRENO_FEATURE(adreno_dev, ADRENO_IFPC)) {
	/* Configure registers for idle setting. The setting is cumulative */
	switch (gmu->idle_level) {
	case GPU_HW_MIN_VOLT:
		_gmu_regrmw(device, A6XX_GMU_RPMH_CTRL, MIN_BW_ENABLE_MASK);
		_gmu_regrmw(device, A6XX_GMU_RPMH_HYST_CTRL, MIN_BW_HYST);
		/* fall through */
	case GPU_HW_NAP:
		_gmu_regrmw(device, A6XX_GMU_GPU_NAP_CTRL, HW_NAP_ENABLE_MASK);
		/* fall through */
	case GPU_HW_IFPC:
		kgsl_gmu_regwrite(device, A6XX_GMU_PWR_COL_INTER_FRAME_HYST,
				0x000A0080);
		_gmu_regrmw(device, A6XX_GMU_PWR_COL_INTER_FRAME_CTRL,
				IFPC_ENABLE_MASK);
		gmu->idle_level = GPU_HW_IFPC;
	}

	if (ADRENO_FEATURE(adreno_dev, ADRENO_HW_NAP)) {
		_gmu_regrmw(device, A6XX_GMU_GPU_NAP_CTRL,
			HW_NAP_ENABLE_MASK);
		gmu->idle_level = GPU_HW_NAP;
	}

	if (ADRENO_FEATURE(adreno_dev, ADRENO_MIN_VOLT)) {
		_gmu_regrmw(device, A6XX_GMU_RPMH_CTRL, MIN_BW_ENABLE_MASK);
		_gmu_regrmw(device, A6XX_GMU_RPMH_HYST_CTRL, MIN_BW_HYST);
		gmu->idle_level = GPU_HW_MIN_VOLT;
		/* fall through */
	case GPU_HW_SPTP_PC:
		kgsl_gmu_regwrite(device, A6XX_GMU_PWR_COL_SPTPRAC_HYST,
				0x000A0080);
		_gmu_regrmw(device, A6XX_GMU_PWR_COL_INTER_FRAME_CTRL,
				SPTP_ENABLE_MASK);
		/* fall through */
	default:
		break;
	}

	/* Enable RPMh GPU client */
	if (ADRENO_FEATURE(adreno_dev, ADRENO_RPMH))
		_gmu_regrmw(device, A6XX_GMU_RPMH_CTRL, RPMH_ENABLE_MASK);

	/* Disable reference bandgap voltage */
	kgsl_gmu_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 1);
}

@@ -1127,8 +1125,6 @@ static int a6xx_gmu_fw_start(struct kgsl_device *device,
	struct gmu_memdesc *mem_addr = gmu->hfi_mem;
	int ret, i;

	a6xx_gmu_power_config(device);

	if (boot_state == GMU_COLD_BOOT || boot_state == GMU_RESET) {
		/* Turn on the HM and SPTP head switches */
		ret = a6xx_hm_sptprac_control(device, true);
@@ -1173,6 +1169,8 @@ static int a6xx_gmu_fw_start(struct kgsl_device *device,
	kgsl_gmu_regwrite(device, A6XX_GMU_AHB_FENCE_RANGE_0,
			FENCE_RANGE_MASK);

	/* Configure power control and bring the GMU out of reset */
	a6xx_gmu_power_config(device);
	ret = a6xx_gmu_start(device);
	if (ret)
		return ret;
+12 −1
Original line number Diff line number Diff line
@@ -986,6 +986,7 @@ int gmu_probe(struct kgsl_device *device)
	struct gmu_memdesc *mem_addr = NULL;
	struct kgsl_hfi *hfi = &gmu->hfi;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	int i = 0, ret = -ENXIO;

	node = of_find_compatible_node(device->pdev->dev.of_node,
@@ -1086,6 +1087,16 @@ int gmu_probe(struct kgsl_device *device)

	hfi_init(&gmu->hfi, mem_addr, HFI_QUEUE_SIZE);

	/* Set up GMU idle states */
	if (ADRENO_FEATURE(adreno_dev, ADRENO_MIN_VOLT))
		gmu->idle_level = GPU_HW_MIN_VOLT;
	else if (ADRENO_FEATURE(adreno_dev, ADRENO_HW_NAP))
		gmu->idle_level = GPU_HW_NAP;
	else if (ADRENO_FEATURE(adreno_dev, ADRENO_IFPC))
		gmu->idle_level = GPU_HW_IFPC;
	else if (ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC))
		gmu->idle_level = GPU_HW_SPTP_PC;
	else
		gmu->idle_level = GPU_HW_ACTIVE;

	return 0;