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

Commit 8af3ce59 authored by Suman Tatiraju's avatar Suman Tatiraju
Browse files

msm: kgsl: Enable Peak Power Detection for A430v2



Peak Power Detection(PPD) is a feature to mitigate peak current
conditions on the GPU. The throttling happens only in turbo mode,
hence mask the throttle signal and reset the logic around clock switch
boundaries. Also add the registers to snapshot for A430v2.

Change-Id: I6235d10c0ed348e6a45c3f4ea44de984155f2b62
Signed-off-by: default avatarSuman Tatiraju <sumant@codeaurora.org>
parent 2f0184f7
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -434,12 +434,16 @@ enum a4xx_rb_perfctr_rb_sel {
#define A4XX_RBBM_CFG_DEBBUS_MISR0		0x1ae
#define A4XX_RBBM_CFG_DEBBUS_MISR1		0x1af
#define A4XX_RBBM_POWER_STATUS			0x1b0
#define A4XX_RBBM_PPD_V2_SP_PWR_WEIGHTS		0x1b2
#define A4XX_RBBM_PPD_V2_SP_RB_EPOCH_TH		0x1b3
#define A4XX_RBBM_PPD_V2_TP_CONFIG		0x1b4
#define A4XX_RBBM_PPD_RAMP_V2_CONTROL		0x1b5
#define A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL2		0x1b8
#define A4XX_RBBM_PPD_CTRL			0x1b9
#define A4XX_RBBM_PPD_EPOCH_INTRA_TH_1		0x1ba
#define A4XX_RBBM_PPD_EPOCH_INTRA_TH_2		0x1bb
#define A4XX_RBBM_PPD_EPOCH_INTER_TH_HI_CLR_TH  0x1bc
#define A4XX_RBBM_PPD_EPOCH_INTER_TH_LO         0x1bd
#define A4XX_RBBM_PPD_EPOCH_INTER_TH_HIGH_CLEAR_THR  0x1bc
#define A4XX_RBBM_PPD_EPOCH_INTER_TH_LOW	0x1bd
/* SECVID registers */
#define A4XX_RBBM_SECVID_TRUST_CONFIG		0xf000
#define A4XX_RBBM_SECVID_TRUST_CONTROL		0xf400
+15 −1
Original line number Diff line number Diff line
@@ -1821,6 +1821,10 @@ static ssize_t ppd_enable_store(struct kgsl_device *device,
	if ((adreno_dev == NULL) || (device == NULL))
		return -ENODEV;

	if (!adreno_is_a430v2(adreno_dev) ||
		!ADRENO_FEATURE(adreno_dev, ADRENO_PPD))
		return count;

	gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	ret = kgsl_sysfs_store(buf, &ppd_on);
	if (ret < 0)
@@ -2782,6 +2786,16 @@ static void adreno_regulator_disable(struct kgsl_device *device)
		gpudev->regulator_disable(adreno_dev);
}

static void adreno_pwrlevel_change_settings(struct kgsl_device *device,
						bool mask_throttle)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev  = ADRENO_GPU_DEVICE(adreno_dev);

	if (gpudev->pwrlevel_change_settings)
		gpudev->pwrlevel_change_settings(adreno_dev, mask_throttle);
}

static const struct kgsl_functable adreno_functable = {
	/* Mandatory functions */
	.regread = adreno_regread,
@@ -2815,7 +2829,7 @@ static const struct kgsl_functable adreno_functable = {
	.regulator_enable = adreno_regulator_enable,
	.is_hw_collapsible = adreno_is_hw_collapsible,
	.regulator_disable = adreno_regulator_disable,

	.pwrlevel_change_settings = adreno_pwrlevel_change_settings,
};

static struct platform_driver adreno_platform_driver = {
+5 −0
Original line number Diff line number Diff line
@@ -611,6 +611,8 @@ struct adreno_gpudev {
	void (*enable_ppd)(struct adreno_device *);
	void (*regulator_enable)(struct adreno_device *);
	void (*regulator_disable)(struct adreno_device *);
	void (*pwrlevel_change_settings)(struct adreno_device *,
					bool mask_throttle);
};

struct log_field {
@@ -689,6 +691,9 @@ extern const unsigned int a4xx_registers_count;
extern const unsigned int a4xx_sp_tp_registers[];
extern const unsigned int a4xx_sp_tp_registers_count;

extern const unsigned int a4xx_ppd_registers[];
extern const unsigned int a4xx_ppd_registers_count;

extern const unsigned int a4xx_xpu_registers[];
extern const unsigned int a4xx_xpu_reg_cnt;

+53 −9
Original line number Diff line number Diff line
@@ -89,6 +89,16 @@ const unsigned int a4xx_sp_tp_registers[] = {
const unsigned int a4xx_sp_tp_registers_count =
			ARRAY_SIZE(a4xx_sp_tp_registers) / 2;

const unsigned int a4xx_ppd_registers[] = {
	/* V2 Thresholds */
	0x01B2, 0x01B5,
	/* Control and Status */
	0x01B9, 0x01BE,
};

const unsigned int a4xx_ppd_registers_count =
			ARRAY_SIZE(a4xx_ppd_registers) / 2;

const unsigned int a4xx_xpu_registers[] = {
	/* XPU */
	0x2C00, 0x2C01, 0x2C10, 0x2C10, 0x2C12, 0x2C16, 0x2C1D, 0x2C20,
@@ -420,26 +430,59 @@ static void a4xx_enable_pc(struct adreno_device *adreno_dev)
 * a4xx_enable_ppd() - Enable the Peak power detect logic in the h/w
 * @adreno_dev: The adreno device pointer
 *
 * A430 can detect peak current conditions inside h/w and throttle the
 * gpu clock to mitigate it.
 * A430 can detect peak current conditions inside h/w and throttle
 * the workload to ALUs to mitigate it.
 */
static void a4xx_enable_ppd(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = &adreno_dev->dev;

	if (!ADRENO_FEATURE(adreno_dev, ADRENO_PPD) ||
		!test_bit(ADRENO_PPD_CTRL, &adreno_dev->pwrctrl_flag))
		!test_bit(ADRENO_PPD_CTRL, &adreno_dev->pwrctrl_flag) ||
		!adreno_is_a430v2(adreno_dev))
		return;

	/* Program thresholds */
	kgsl_regwrite(device, A4XX_RBBM_PPD_EPOCH_INTRA_TH_1, 0x000A800C);
	kgsl_regwrite(device, A4XX_RBBM_PPD_EPOCH_INTRA_TH_2, 0x00140002);
	kgsl_regwrite(device, A4XX_RBBM_PPD_EPOCH_INTER_TH_HI_CLR_TH,
								0x00000000);
	kgsl_regwrite(device, A4XX_RBBM_PPD_EPOCH_INTER_TH_LO, 0x00010101);
	kgsl_regwrite(device, A4XX_RBBM_PPD_EPOCH_INTER_TH_HIGH_CLEAR_THR,
								0x003F0101);
	kgsl_regwrite(device, A4XX_RBBM_PPD_EPOCH_INTER_TH_LOW, 0x00000101);
	kgsl_regwrite(device, A4XX_RBBM_PPD_V2_SP_PWR_WEIGHTS, 0x00085014);
	kgsl_regwrite(device, A4XX_RBBM_PPD_V2_SP_RB_EPOCH_TH, 0x00000B46);
	kgsl_regwrite(device, A4XX_RBBM_PPD_V2_TP_CONFIG, 0xE4525111);
	kgsl_regwrite(device, A4XX_RBBM_PPD_RAMP_V2_CONTROL, 0x0000000B);

	/* Enable PPD*/
	kgsl_regwrite(device, A4XX_RBBM_PPD_CTRL, 0x1908E401);
	kgsl_regwrite(device, A4XX_RBBM_PPD_CTRL, 0x1002E40C);
};

/*
 * a4xx_pwrlevel_change_settings() - Program the hardware during power level
 * transitions
 * @adreno_dev: The adreno device pointer
 * @mask_throttle: flag to check if PPD throttle should be masked
 */
static void a4xx_pwrlevel_change_settings(struct adreno_device *adreno_dev,
						bool mask_throttle)
{
	struct kgsl_device *device = &adreno_dev->dev;

	/* PPD programming only for A430v2 */
	if (!ADRENO_FEATURE(adreno_dev, ADRENO_PPD) ||
		!test_bit(ADRENO_PPD_CTRL, &adreno_dev->pwrctrl_flag) ||
		!adreno_is_a430v2(adreno_dev))
		return;

	if (mask_throttle) {
		/* Going to Non-Turbo mode - mask the throttle and reset */
		kgsl_regwrite(device, A4XX_RBBM_PPD_CTRL, 0x1002E40E);
		kgsl_regwrite(device, A4XX_RBBM_PPD_CTRL, 0x1002E40C);
	} else {
		/* Going to Turbo mode - unmask the throttle and reset */
		kgsl_regwrite(device, A4XX_RBBM_PPD_CTRL, 0x1002E40A);
		kgsl_regwrite(device, A4XX_RBBM_PPD_CTRL, 0x1002E408);
	}
}

/*
 * a4xx_enable_hwcg() - Program the clock control registers
 * @device: The adreno device pointer
@@ -1781,6 +1824,7 @@ struct adreno_gpudev adreno_a4xx_gpudev = {
	.is_sptp_idle = a4xx_is_sptp_idle,
	.enable_pc = a4xx_enable_pc,
	.enable_ppd = a4xx_enable_ppd,
	.pwrlevel_change_settings = a4xx_pwrlevel_change_settings,
	.regulator_enable = a4xx_regulator_enable,
	.regulator_disable = a4xx_regulator_disable,
};
+6 −0
Original line number Diff line number Diff line
@@ -406,6 +406,12 @@ void a4xx_snapshot(struct adreno_device *adreno_dev,
		_snapshot_a3xx_regs(regs, &list, a4xx_xpu_registers,
				a4xx_xpu_reg_cnt, 1);
	}

	if (adreno_is_a430v2(adreno_dev)) {
		_snapshot_a3xx_regs(regs, &list, a4xx_ppd_registers,
				a4xx_ppd_registers_count, 1);
	}

	a4xx_snapshot_vbif_registers(device, regs, &list);

	/* Turn on MMU clocks since we read MMU registers */
Loading