void nvhost_scale_emc_calibrate_emc(struct nvhost_emc_params *emc_params,
				  struct clk *clk_3d, struct clk *clk_3d_emc,
				  bool linear_emc)
{
	long correction;
	unsigned long max_emc;
	unsigned long min_emc;
	unsigned long min_rate_3d;
	unsigned long max_rate_3d;

	max_emc = clk_round_rate(clk_3d_emc, UINT_MAX);
	max_emc = INT_TO_FX(HZ_TO_MHZ(max_emc));

	min_emc = clk_round_rate(clk_3d_emc, 0);
	min_emc = INT_TO_FX(HZ_TO_MHZ(min_emc));

	max_rate_3d = clk_round_rate(clk_3d, UINT_MAX);
	max_rate_3d = INT_TO_FX(HZ_TO_MHZ(max_rate_3d));

	min_rate_3d = clk_round_rate(clk_3d, 0);
	min_rate_3d = INT_TO_FX(HZ_TO_MHZ(min_rate_3d));

	emc_params->emc_slope =
		FXDIV((max_emc - min_emc), (max_rate_3d - min_rate_3d));
	emc_params->emc_offset = max_emc -
		FXMUL(emc_params->emc_slope, max_rate_3d);
	/* Guarantee max 3d rate maps to max emc rate */
	emc_params->emc_offset += max_emc -
		(FXMUL(emc_params->emc_slope, max_rate_3d) +
		emc_params->emc_offset);

	emc_params->linear = linear_emc;
	if (linear_emc)
		return;

	emc_params->emc_dip_offset = (max_emc - min_emc) / 4;
	emc_params->emc_dip_slope =
		-FXDIV(emc_params->emc_slope, max_rate_3d - min_rate_3d);
	emc_params->emc_xmid = (max_rate_3d + min_rate_3d) / 2;
	correction =
		emc_params->emc_dip_offset +
			FXMUL(emc_params->emc_dip_slope,
			FXMUL(max_rate_3d - emc_params->emc_xmid,
				max_rate_3d - emc_params->emc_xmid));
	emc_params->emc_dip_offset -= correction;
}
static void nvhost_scale3d_calibrate_emc(void)
{
	long correction;
	unsigned long max_emc;
	unsigned long min_emc;
	unsigned long min_rate_3d;
	unsigned long max_rate_3d;

	max_emc = clk_round_rate(power_profile.clk_3d_emc, UINT_MAX);
	max_emc = INT_TO_FX(HZ_TO_MHZ(max_emc));

	min_emc = clk_round_rate(power_profile.clk_3d_emc, 0);
	min_emc = INT_TO_FX(HZ_TO_MHZ(min_emc));

	max_rate_3d = INT_TO_FX(HZ_TO_MHZ(power_profile.max_rate_3d));
	min_rate_3d = INT_TO_FX(HZ_TO_MHZ(power_profile.min_rate_3d));

	power_profile.emc_slope =
		FXDIV((max_emc - min_emc), (max_rate_3d - min_rate_3d));
	power_profile.emc_offset = max_emc -
		FXMUL(power_profile.emc_slope, max_rate_3d);
	/* Guarantee max 3d rate maps to max emc rate */
	power_profile.emc_offset += max_emc -
		(FXMUL(power_profile.emc_slope, max_rate_3d) +
		power_profile.emc_offset);

	power_profile.emc_dip_offset = (max_emc - min_emc) / 4;
	power_profile.emc_dip_slope =
		-4 * FXDIV(power_profile.emc_dip_offset,
		(FXMUL(max_rate_3d - min_rate_3d,
			max_rate_3d - min_rate_3d)));
	power_profile.emc_xmid = (max_rate_3d + min_rate_3d) / 2;
	correction =
		power_profile.emc_dip_offset +
			FXMUL(power_profile.emc_dip_slope,
			FXMUL(max_rate_3d - power_profile.emc_xmid,
				max_rate_3d - power_profile.emc_xmid));
	power_profile.emc_dip_offset -= correction;
}