static int nvhost_scale3d_target(struct device *d, unsigned long *freq, u32 flags) { long hz; long after; /* Inform that the clock is disabled */ if (!tegra_is_clk_enabled(power_profile.clk_3d)) { *freq = 0; return 0; } /* Limit the frequency */ if (*freq < power_profile.min_rate_3d) *freq = power_profile.min_rate_3d; else if (*freq > power_profile.max_rate_3d) *freq = power_profile.max_rate_3d; /* Check if we're already running at the desired speed */ if (*freq == clk_get_rate(power_profile.clk_3d)) return 0; /* Set GPU clockrate */ if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3) nvhost_module_set_devfreq_rate(power_profile.dev, clk_to_idx(power_profile.clk_3d2), 0); nvhost_module_set_devfreq_rate(power_profile.dev, clk_to_idx(power_profile.clk_3d), *freq); /* Set EMC clockrate */ after = (long) clk_get_rate(power_profile.clk_3d); after = INT_TO_FX(HZ_TO_MHZ(after)); hz = FXMUL(after, power_profile.emc_slope) + power_profile.emc_offset; hz -= FXMUL(power_profile.emc_dip_slope, FXMUL(after - power_profile.emc_xmid, after - power_profile.emc_xmid)) + power_profile.emc_dip_offset; hz = MHZ_TO_HZ(FX_TO_INT(hz + FX_HALF)); /* round to nearest */ hz = (hz < 0) ? 0 : hz; nvhost_module_set_devfreq_rate(power_profile.dev, clk_to_idx(power_profile.clk_3d_emc), hz); /* Get the new clockrate */ *freq = clk_get_rate(power_profile.clk_3d); return 0; }
long nvhost_scale_emc_get_emc_rate(struct nvhost_emc_params *emc_params, long freq) { long hz; freq = INT_TO_FX(HZ_TO_MHZ(freq)); hz = FXMUL(freq, emc_params->emc_slope) + emc_params->emc_offset; if (!emc_params->linear) hz -= FXMUL(emc_params->emc_dip_slope, FXMUL(freq - emc_params->emc_xmid, freq - emc_params->emc_xmid)) + emc_params->emc_dip_offset; hz = MHZ_TO_HZ(FX_TO_INT(hz + FX_HALF)); /* round to nearest */ hz = (hz < 0) ? 0 : hz; return hz; }