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

Commit 457deee7 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Poll GDCSR for holi target to ensure CX collapse"

parents 0d15c452 a18eecda
Loading
Loading
Loading
Loading
+26 −23
Original line number Diff line number Diff line
@@ -2036,18 +2036,6 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	if (regulator_left_on)
		_soft_reset(adreno_dev);

	/*
	 * During adreno_stop, GBIF halt is asserted to ensure
	 * no further transaction can go through GPU before GPU
	 * headswitch is turned off.
	 *
	 * This halt is deasserted once headswitch goes off but
	 * incase headswitch doesn't goes off clear GBIF halt
	 * here to ensure GPU wake-up doesn't fail because of
	 * halted GPU transactions.
	 */
	adreno_deassert_gbif_halt(adreno_dev);

	adreno_ringbuffer_set_global(adreno_dev, 0);

	status = kgsl_mmu_start(device);
@@ -3522,7 +3510,7 @@ static int adreno_regulator_enable(struct kgsl_device *device)
	return ret;
}

static bool adreno_is_hw_collapsible(struct kgsl_device *device)
static bool adreno_prepare_for_power_off(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	const struct adreno_gpudev *gpudev  = ADRENO_GPU_DEVICE(adreno_dev);
@@ -3536,8 +3524,16 @@ static bool adreno_is_hw_collapsible(struct kgsl_device *device)
			device->pwrctrl.ctrl_flags)
		return false;

	return adreno_isidle(adreno_dev) && (gpudev->is_sptp_idle ?
				gpudev->is_sptp_idle(adreno_dev) : true);
	if (!adreno_isidle(adreno_dev) || !(gpudev->is_sptp_idle ?
				gpudev->is_sptp_idle(adreno_dev) : true))
		return false;

	if (gpudev->clear_pending_transactions(adreno_dev))
		return false;

	adreno_dispatcher_stop_fault_timer(device);

	return true;
}

static void adreno_regulator_disable(struct kgsl_device *device)
@@ -3576,17 +3572,15 @@ static void adreno_clk_set_options(struct kgsl_device *device, const char *name,
static void adreno_regulator_disable_poll(struct kgsl_device *device)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	const struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(
						ADRENO_DEVICE(device));

	/* Set the parent in retention voltage to disable CPR interrupts */
	kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent,
			pwr->gx_gdsc_parent_min_corner);
	if (gpudev->regulator_disable_poll)
		return gpudev->regulator_disable_poll(device);

	if (!kgsl_regulator_disable_wait(pwr->gx_gdsc, 200))
		dev_err(device->dev, "Regulator vdd is stuck on\n");

	/* Remove the vote for the vdd parent supply */
	kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent, 0);

	if (!kgsl_regulator_disable_wait(pwr->cx_gdsc, 200))
		dev_err(device->dev, "Regulator vddcx is stuck on\n");
}
@@ -3744,6 +3738,15 @@ static int adreno_gpu_bus_set(struct kgsl_device *device, int level, u32 ab)
	return adreno_interconnect_bus_set(adreno_dev, level, ab);
}

static void adreno_deassert_gbif_halt(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	const struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);

	if (gpudev->deassert_gbif_halt)
		gpudev->deassert_gbif_halt(adreno_dev);
}

static const struct kgsl_functable adreno_functable = {
	/* Mandatory functions */
	.regread = adreno_regread,
@@ -3778,17 +3781,17 @@ static const struct kgsl_functable adreno_functable = {
	.drawctxt_sched = adreno_drawctxt_sched,
	.resume = adreno_dispatcher_start,
	.regulator_enable = adreno_regulator_enable,
	.is_hw_collapsible = adreno_is_hw_collapsible,
	.prepare_for_power_off = adreno_prepare_for_power_off,
	.regulator_disable = adreno_regulator_disable,
	.pwrlevel_change_settings = adreno_pwrlevel_change_settings,
	.regulator_disable_poll = adreno_regulator_disable_poll,
	.clk_set_options = adreno_clk_set_options,
	.gpu_model = adreno_gpu_model,
	.stop_fault_timer = adreno_dispatcher_stop_fault_timer,
	.query_property_list = adreno_query_property_list,
	.is_hwcg_on = adreno_is_hwcg_on,
	.gpu_clock_set = adreno_gpu_clock_set,
	.gpu_bus_set = adreno_gpu_bus_set,
	.deassert_gbif_halt = adreno_deassert_gbif_halt,
};

static const struct component_master_ops adreno_ops = {
+2 −20
Original line number Diff line number Diff line
@@ -696,9 +696,7 @@ enum adreno_regs {
	ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
	ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
	ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
	ADRENO_REG_GBIF_HALT,
	ADRENO_REG_VBIF_VERSION,
	ADRENO_REG_RBBM_GBIF_HALT,
	ADRENO_REG_GMU_AO_HOST_INTERRUPT_MASK,
	ADRENO_REG_GMU_AHB_FENCE_STATUS,
	ADRENO_REG_GMU_GMU2HOST_INTR_MASK,
@@ -813,6 +811,8 @@ struct adreno_gpudev {
	 */
	const struct adreno_power_ops *power_ops;
	int (*clear_pending_transactions)(struct adreno_device *adreno_dev);
	void (*deassert_gbif_halt)(struct adreno_device *adreno_dev);
	void (*regulator_disable_poll)(struct kgsl_device *device);
};

/**
@@ -1692,22 +1692,6 @@ static inline int adreno_wait_for_halt_ack(struct kgsl_device *device,
	return 0;
}

static inline void adreno_deassert_gbif_halt(struct adreno_device *adreno_dev)
{
	if (adreno_has_gbif(adreno_dev)) {
		adreno_writereg(adreno_dev, ADRENO_REG_GBIF_HALT, 0x0);

		/*
		 * Release GBIF GX halt. For A615 family, GPU GX halt
		 * will be cleared automatically on reset.
		 */
		if (!gmu_core_gpmu_isenabled(KGSL_DEVICE(adreno_dev)) &&
			!adreno_is_a615_family(adreno_dev))
			adreno_writereg(adreno_dev,
				ADRENO_REG_RBBM_GBIF_HALT, 0x0);
	}
}

/**
 * adreno_move_preempt_state - Update the preemption state
 * @adreno_dev: An Adreno GPU device handle
@@ -1753,8 +1737,6 @@ static inline u32 adreno_get_level(u32 priority)
int adreno_gmu_fenced_write(struct adreno_device *adreno_dev,
	enum adreno_regs offset, unsigned int val,
	unsigned int fence_mask);
int adreno_clear_pending_transactions(struct kgsl_device *device);


/**
 * adreno_get_firwmare - Load firmware into a adreno_firmware struct
+59 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "adreno_pm4types.h"
#include "adreno_trace.h"
#include "kgsl_trace.h"
#include "kgsl_util.h"

/* IFPC & Preemption static powerup restore list */
static u32 a6xx_pwrup_reglist[] = {
@@ -249,6 +250,7 @@ bool a6xx_cx_regulator_disable_wait(struct regulator *reg,
{
	ktime_t tout = ktime_add_us(ktime_get(), timeout * 1000);
	unsigned int val;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	if (IS_ERR_OR_NULL(reg))
		return true;
@@ -256,13 +258,22 @@ bool a6xx_cx_regulator_disable_wait(struct regulator *reg,
	regulator_disable(reg);

	for (;;) {
		if (adreno_is_a619_holi(adreno_dev))
			adreno_read_gmu_wrapper(adreno_dev,
					A6XX_GPU_CC_CX_GDSCR, &val);
		else
			gmu_core_regread(device, A6XX_GPU_CC_CX_GDSCR, &val);

		if (!(val & BIT(31)))
			return true;

		if (ktime_compare(ktime_get(), tout) > 0) {
			gmu_core_regread(device, A6XX_GPU_CC_CX_GDSCR, &val);
			if (adreno_is_a619_holi(adreno_dev))
				adreno_read_gmu_wrapper(adreno_dev,
						A6XX_GPU_CC_CX_GDSCR, &val);
			else
				gmu_core_regread(device, A6XX_GPU_CC_CX_GDSCR,
							&val);
			return (!(val & BIT(31)));
		}

@@ -426,6 +437,18 @@ static void a6xx_set_secvid(struct kgsl_device *device)
		set = true;
}

static void a6xx_deassert_gbif_halt(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);

	kgsl_regwrite(device, A6XX_GBIF_HALT, 0x0);

	if (adreno_is_a619_holi(adreno_dev))
		kgsl_regwrite(device, A6XX_RBBM_GPR0_CNTL, 0x0);
	else
		kgsl_regwrite(device, A6XX_RBBM_GBIF_HALT, 0x0);
}

/*
 * Some targets support marking certain transactions as always privileged which
 * allows us to mark more memory as privileged without having to explicitly set
@@ -696,6 +719,19 @@ void a6xx_start(struct adreno_device *adreno_dev)
		a6xx_patch_pwrup_reglist(adreno_dev);
		patch_reglist = true;
	}

	/*
	 * During adreno_stop, GBIF halt is asserted to ensure
	 * no further transaction can go through GPU before GPU
	 * headswitch is turned off.
	 *
	 * This halt is deasserted once headswitch goes off but
	 * incase headswitch doesn't goes off clear GBIF halt
	 * here to ensure GPU wake-up doesn't fail because of
	 * halted GPU transactions.
	 */
	a6xx_deassert_gbif_halt(adreno_dev);

}

/* Offsets into the MX/CX mapped register regions */
@@ -2300,9 +2336,6 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
				A6XX_RBBM_PERFCTR_LOAD_VALUE_HI),
	ADRENO_REG_DEFINE(ADRENO_REG_VBIF_VERSION, A6XX_VBIF_VERSION),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_GBIF_HALT,
				A6XX_RBBM_GBIF_HALT),
	ADRENO_REG_DEFINE(ADRENO_REG_GBIF_HALT, A6XX_GBIF_HALT),
	ADRENO_REG_DEFINE(ADRENO_REG_GMU_AO_HOST_INTERRUPT_MASK,
				A6XX_GMU_AO_HOST_INTERRUPT_MASK),
	ADRENO_REG_DEFINE(ADRENO_REG_GMU_AHB_FENCE_STATUS,
@@ -2454,6 +2487,24 @@ u64 a6xx_read_alwayson(struct adreno_device *adreno_dev)
	return (((u64) hi) << 32) | lo;
}

static void a619_holi_regulator_disable_poll(struct kgsl_device *device)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;

	/* Set the parent in retention voltage to disable CPR interrupts */
	kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent,
			pwr->gx_gdsc_parent_min_corner);

	if (!kgsl_regulator_disable_wait(pwr->gx_gdsc, 200))
		dev_err(device->dev, "Regulator vdd is stuck on\n");

	/* Remove the vote for the vdd parent supply */
	kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent, 0);

	if (!a6xx_cx_regulator_disable_wait(pwr->cx_gdsc, device, 200))
		dev_err(device->dev, "Regulator vddcx is stuck on\n");
}

const struct adreno_gpudev adreno_a6xx_gpudev = {
	.reg_offsets = a6xx_register_offsets,
	.probe = a6xx_probe,
@@ -2487,6 +2538,7 @@ const struct adreno_gpudev adreno_a6xx_gpudev = {
	.read_alwayson = a6xx_read_alwayson,
	.power_ops = &adreno_power_operations,
	.clear_pending_transactions = a6xx_clear_pending_transactions,
	.deassert_gbif_halt = a6xx_deassert_gbif_halt,
};

const struct adreno_gpudev adreno_a6xx_hwsched_gpudev = {
@@ -2600,6 +2652,8 @@ const struct adreno_gpudev adreno_a619_holi_gpudev = {
	.read_alwayson = a6xx_read_alwayson,
	.power_ops = &adreno_power_operations,
	.clear_pending_transactions = a6xx_clear_pending_transactions,
	.deassert_gbif_halt = a6xx_deassert_gbif_halt,
	.regulator_disable_poll = a619_holi_regulator_disable_poll,
};

const struct adreno_gpudev adreno_a630_gpudev = {
+6 −4
Original line number Diff line number Diff line
@@ -1626,6 +1626,8 @@ static void a6xx_gmu_pwrctrl_suspend(struct adreno_device *adreno_dev)
		}
		/* Halt CX traffic */
		a6xx_halt_gbif(adreno_dev);
		/* De-assert the halts */
		kgsl_regwrite(device, A6XX_GBIF_HALT, 0x0);
	}

	if (a6xx_gmu_gx_is_on(device))
@@ -2764,9 +2766,6 @@ int a6xx_halt_gbif(struct adreno_device *adreno_dev)
	ret = adreno_wait_for_halt_ack(device,
		A6XX_GBIF_HALT_ACK, A6XX_GBIF_ARB_HALT_MASK);

	/* De-assert the halts */
	kgsl_regwrite(device, A6XX_GBIF_HALT, 0x0);

	return ret;
}

@@ -2797,8 +2796,11 @@ static int a6xx_gmu_power_off(struct adreno_device *adreno_dev)
	a6xx_rdpm_mx_freq_update(gmu, 0);

	/* Now that we are done with GMU and GPU, Clear the GBIF */
	if (!adreno_is_a630(adreno_dev))
	if (!adreno_is_a630(adreno_dev)) {
		ret = a6xx_halt_gbif(adreno_dev);
		/* De-assert the halts */
		kgsl_regwrite(device, A6XX_GBIF_HALT, 0x0);
	}

	a6xx_gmu_irq_disable(adreno_dev);

+2 −0
Original line number Diff line number Diff line
@@ -373,6 +373,8 @@ static int a6xx_hwsched_gmu_power_off(struct adreno_device *adreno_dev)

	/* Now that we are done with GMU and GPU, Clear the GBIF */
	ret = a6xx_halt_gbif(adreno_dev);
	/* De-assert the halts */
	kgsl_regwrite(device, A6XX_GBIF_HALT, 0x0);

	a6xx_gmu_irq_disable(adreno_dev);

Loading