ARM: tegra: dvfs: Invalidate CL-DVFS request when disabled
Alex Frid [Tue, 14 May 2013 18:42:16 +0000 (11:42 -0700)]
Invlidated frequency request when CL-DVFS is disabled. Made sure that
the first request after enabling CL-DVFS always includes regulator
undershoot guard-band (i.e., do not use stale across disabled state
frequency request to evaluate direction of the change).

Bug 1285525

Change-Id: Ib3a885b7add43b14e21df8cce974f3d5ea068cb0
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/228515
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>

arch/arm/mach-tegra/tegra_cl_dvfs.c

index 4d135ea..7bf12d0 100644 (file)
@@ -246,6 +246,14 @@ static inline void cl_dvfs_wmb(struct tegra_cl_dvfs *cld)
        cl_dvfs_readl(cld, CL_DVFS_CTRL);
 }
 
+static inline void invalidate_request(struct tegra_cl_dvfs *cld)
+{
+       u32 val = cl_dvfs_readl(cld, CL_DVFS_FREQ_REQ);
+       val &= ~CL_DVFS_FREQ_REQ_FREQ_VALID;
+       cl_dvfs_writel(cld, val, CL_DVFS_FREQ_REQ);
+       cl_dvfs_wmb(cld);
+}
+
 static inline int output_enable(struct tegra_cl_dvfs *cld)
 {
        u32 val = cl_dvfs_readl(cld, CL_DVFS_OUTPUT_CFG);
@@ -655,7 +663,8 @@ static void set_request(struct tegra_cl_dvfs *cld, struct dfll_rate_req *req)
        /* If going down apply force output floor */
        val = cl_dvfs_readl(cld, CL_DVFS_FREQ_REQ);
        f = (val & CL_DVFS_FREQ_REQ_FREQ_MASK) >> CL_DVFS_FREQ_REQ_FREQ_SHIFT;
-       if ((f > req->freq) &&  (cld->force_out_min > req->output))
+       if ((!(val & CL_DVFS_FREQ_REQ_FREQ_VALID) || (f > req->freq)) &&
+           (cld->force_out_min > req->output))
                force_val = cld->force_out_min - cld->safe_output;
 
        force_val = force_val * coef / cld->p_data->cfg_param->cg;
@@ -1449,11 +1458,13 @@ void tegra_cl_dvfs_disable(struct tegra_cl_dvfs *cld)
                output_disable_ol_prepare(cld);
                set_mode(cld, TEGRA_CL_DVFS_DISABLED);
                output_disable_post_ol(cld);
+               invalidate_request(cld);
                cl_dvfs_disable_clocks(cld);
                return;
 
        case TEGRA_CL_DVFS_OPEN_LOOP:
                set_mode(cld, TEGRA_CL_DVFS_DISABLED);
+               invalidate_request(cld);
                cl_dvfs_disable_clocks(cld);
                return;