struct panfrost_device *pfdev = dev_get_drvdata(dev);
int ret;
+ if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) {
+ unsigned long freq = pfdev->pfdevfreq.fast_rate;
+ struct dev_pm_opp *opp;
+
+ opp = dev_pm_opp_find_freq_ceil(dev, &freq);
+ if (IS_ERR(opp))
+ return PTR_ERR(opp);
+ dev_pm_opp_set_opp(dev, opp);
+ dev_pm_opp_put(opp);
+ }
+
if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) {
ret = clk_enable(pfdev->clock);
if (ret)
- return ret;
+ goto err_clk;
if (pfdev->bus_clock) {
ret = clk_enable(pfdev->bus_clock);
err_bus_clk:
if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS))
clk_disable(pfdev->clock);
+err_clk:
+ if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF))
+ dev_pm_opp_set_opp(dev, NULL);
return ret;
}
clk_disable(pfdev->clock);
}
+ if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF))
+ dev_pm_opp_set_opp(dev, NULL);
+
return 0;
}
/**
* enum panfrost_gpu_pm - Supported kernel power management features
* @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend
+ * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend
*/
enum panfrost_gpu_pm {
GPU_PM_CLK_DIS,
+ GPU_PM_VREG_OFF,
};
struct panfrost_features {