mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 04:42:04 -04:00
Merge "msm: kgsl: Add support for RDPM frequency register writes"
This commit is contained in:
commit
ee912b37f3
5 changed files with 108 additions and 0 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 @@ gdsc_off:
|
|||
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 @@ gdsc_off:
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -220,6 +220,8 @@ gdsc_off:
|
|||
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 @@ gdsc_off:
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue