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

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

Merge "msm: kgsl: Add support for RDPM frequency register writes"

parents 47bb7dd5 bf7caa02
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -698,6 +698,40 @@ void a6xx_start(struct adreno_device *adreno_dev)
	}
}

/* Offsets into the MX/CX mapped register regions */
#define RDPM_MX_OFFSET 0xf00
#define RDPM_CX_OFFSET 0xf18

void a6xx_rdpm_mx_freq_update(struct a6xx_gmu_device *gmu,
		u32 freq)
{
	if (gmu->rdpm_mx_virt) {
		writel_relaxed(freq/1000,
			(gmu->rdpm_mx_virt + RDPM_MX_OFFSET));

		/*
		 * ensure previous writes post before this one,
		 * i.e. act like normal writel()
		 */
		wmb();
	}
}

void a6xx_rdpm_cx_freq_update(struct a6xx_gmu_device *gmu,
		u32 freq)
{
	if (gmu->rdpm_cx_virt) {
		writel_relaxed(freq/1000,
			(gmu->rdpm_cx_virt + RDPM_CX_OFFSET));

		/*
		 * ensure previous writes post before this one,
		 * i.e. act like normal writel()
		 */
		wmb();
	}
}

void a6xx_unhalt_sqe(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+18 −0
Original line number Diff line number Diff line
@@ -433,4 +433,22 @@ int a6xx_perfcounter_update(struct adreno_device *adreno_dev,
extern const struct adreno_perfcounters adreno_a630_perfcounters;
extern const struct adreno_perfcounters adreno_a6xx_perfcounters;
extern const struct adreno_perfcounters adreno_a6xx_legacy_perfcounters;

/**
 * a6xx_rdpm_mx_freq_update - Update the mx frequency
 * @gmu: An Adreno GMU handle
 * @freq: Frequency in KHz
 *
 * This function communicates GPU mx frequency(in Mhz) changes to rdpm.
 */
void a6xx_rdpm_mx_freq_update(struct a6xx_gmu_device *gmu, u32 freq);

/**
 * a6xx_rdpm_cx_freq_update - Update the cx frequency
 * @gmu: An Adreno GMU handle
 * @freq: Frequency in KHz
 *
 * This function communicates GPU cx frequency(in Mhz) changes to rdpm.
 */
void a6xx_rdpm_cx_freq_update(struct a6xx_gmu_device *gmu, u32 freq);
#endif
+40 −0
Original line number Diff line number Diff line
@@ -1092,6 +1092,9 @@ static int a6xx_gmu_gfx_rail_on(struct adreno_device *adreno_dev)
	gmu_core_regwrite(device, A6XX_GMU_MX_VOTE_IDX,
			ARC_VOTE_GET_SEC(default_opp));

	a6xx_rdpm_mx_freq_update(gmu,
			gmu->hfi.dcvs_table.gx_votes[perf_idx].freq);

	return a6xx_gmu_oob_set(device, oob_boot_slumber);
}

@@ -1781,6 +1784,8 @@ void a6xx_gmu_suspend(struct adreno_device *adreno_dev)
	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CX_GDSC))
		regulator_set_mode(gmu->cx_gdsc, REGULATOR_MODE_NORMAL);

	a6xx_rdpm_cx_freq_update(gmu, 0);

	dev_err(&gmu->pdev->dev, "Suspended GMU\n");

	device->state = KGSL_STATE_NONE;
@@ -1843,6 +1848,10 @@ static int a6xx_gmu_dcvs_set(struct adreno_device *adreno_dev,
		}
	}

	if (req.freq != INVALID_DCVS_IDX)
		a6xx_rdpm_mx_freq_update(gmu,
			gmu->hfi.dcvs_table.gx_votes[req.freq].freq);

	return ret;
}

@@ -2156,6 +2165,8 @@ int a6xx_gmu_enable_clks(struct adreno_device *adreno_dev)
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	int ret;

	a6xx_rdpm_cx_freq_update(gmu, GMU_FREQUENCY / 1000);

	ret = a6xx_gmu_clk_set_rate(gmu, "gmu_clk", GMU_FREQUENCY);
	if (ret) {
		dev_err(&gmu->pdev->dev, "Unable to set the GMU clock\n");
@@ -2278,6 +2289,8 @@ static int a6xx_gmu_first_boot(struct adreno_device *adreno_dev)
	if (!a6xx_cx_regulator_disable_wait(gmu->cx_gdsc, device, 5000))
		dev_err(&gmu->pdev->dev, "GMU CX gdsc off timeout\n");

	a6xx_rdpm_cx_freq_update(gmu, 0);

	return ret;
}

@@ -2357,6 +2370,8 @@ static int a6xx_gmu_boot(struct adreno_device *adreno_dev)
	if (!a6xx_cx_regulator_disable_wait(gmu->cx_gdsc, device, 5000))
		dev_err(&gmu->pdev->dev, "GMU CX gdsc off timeout\n");

	a6xx_rdpm_cx_freq_update(gmu, 0);

	return ret;
}

@@ -2541,6 +2556,24 @@ static int a6xx_gmu_reg_probe(struct adreno_device *adreno_dev)
	return 0;
}

static void a6xx_gmu_rdpm_probe(struct a6xx_gmu_device *gmu,
		struct kgsl_device *device)
{
	struct resource *res;

	res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
			"rdpm_cx");
	if (res)
		gmu->rdpm_cx_virt = devm_ioremap(&device->pdev->dev,
				res->start, resource_size(res));

	res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
			"rdpm_mx");
	if (res)
		gmu->rdpm_mx_virt = devm_ioremap(&device->pdev->dev,
				res->start, resource_size(res));
}

static int a6xx_gmu_regulators_probe(struct a6xx_gmu_device *gmu,
		struct platform_device *pdev)
{
@@ -2660,6 +2693,9 @@ int a6xx_gmu_probe(struct kgsl_device *device,
		}
	}

	/* Setup any rdpm register ranges */
	a6xx_gmu_rdpm_probe(gmu, device);

	/* Set up GMU regulators */
	ret = a6xx_gmu_regulators_probe(gmu, pdev);
	if (ret)
@@ -2790,6 +2826,8 @@ static int a6xx_gmu_power_off(struct adreno_device *adreno_dev)

	ret = a6xx_rscc_sleep_sequence(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))
		ret = a6xx_halt_gbif(adreno_dev);
@@ -2804,6 +2842,8 @@ static int a6xx_gmu_power_off(struct adreno_device *adreno_dev)
	if (!a6xx_cx_regulator_disable_wait(gmu->cx_gdsc, device, 5000))
		dev_err(&gmu->pdev->dev, "GMU CX gdsc off timeout\n");

	a6xx_rdpm_cx_freq_update(gmu, 0);

	device->state = KGSL_STATE_NONE;

	return ret;
+4 −0
Original line number Diff line number Diff line
@@ -201,6 +201,10 @@ struct a6xx_gmu_device {
	void __iomem *rscc_virt;
	/** @domain: IOMMU domain for the kernel context */
	struct iommu_domain *domain;
	/** @rdpm_cx_virt: Pointer where the RDPM CX block is mapped */
	void __iomem *rdpm_cx_virt;
	/** @rdpm_mx_virt: Pointer where the RDPM MX block is mapped */
	void __iomem *rdpm_mx_virt;
};

/* Helper function to get to a6xx gmu device from adreno device */
+12 −0
Original line number Diff line number Diff line
@@ -220,6 +220,8 @@ static int a6xx_hwsched_gmu_first_boot(struct adreno_device *adreno_dev)
	if (!a6xx_cx_regulator_disable_wait(gmu->cx_gdsc, device, 5000))
		dev_err(&gmu->pdev->dev, "GMU CX gdsc off timeout\n");

	a6xx_rdpm_cx_freq_update(gmu, 0);

	return ret;
}

@@ -281,6 +283,8 @@ static int a6xx_hwsched_gmu_boot(struct adreno_device *adreno_dev)
	if (!a6xx_cx_regulator_disable_wait(gmu->cx_gdsc, device, 5000))
		dev_err(&gmu->pdev->dev, "GMU CX gdsc off timeout\n");

	a6xx_rdpm_cx_freq_update(gmu, 0);

	return ret;
}

@@ -365,6 +369,8 @@ static int a6xx_hwsched_gmu_power_off(struct adreno_device *adreno_dev)

	ret = a6xx_rscc_sleep_sequence(adreno_dev);

	a6xx_rdpm_mx_freq_update(gmu, 0);

	/* Now that we are done with GMU and GPU, Clear the GBIF */
	ret = a6xx_halt_gbif(adreno_dev);

@@ -378,6 +384,8 @@ static int a6xx_hwsched_gmu_power_off(struct adreno_device *adreno_dev)
	if (!a6xx_cx_regulator_disable_wait(gmu->cx_gdsc, device, 5000))
		dev_err(&gmu->pdev->dev, "GMU CX gdsc off timeout\n");

	a6xx_rdpm_cx_freq_update(gmu, 0);

	return ret;

error:
@@ -776,6 +784,10 @@ static int a6xx_hwsched_dcvs_set(struct adreno_device *adreno_dev,

	}

	if (req.freq != INVALID_DCVS_IDX)
		a6xx_rdpm_mx_freq_update(gmu,
			gmu->hfi.dcvs_table.gx_votes[req.freq].freq);

	return ret;
}