static int ptp_qoriq_auto_config()

in ptp_qoriq.c [379:431]


static int ptp_qoriq_auto_config(struct ptp_qoriq *ptp_qoriq,
				 struct device_node *node)
{
	struct clk *clk;
	u64 freq_comp;
	u64 max_adj;
	u32 nominal_freq;
	u32 remainder = 0;
	u32 clk_src = 0;

	ptp_qoriq->cksel = DEFAULT_CKSEL;

	clk = of_clk_get(node, 0);
	if (!IS_ERR(clk)) {
		clk_src = clk_get_rate(clk);
		clk_put(clk);
	}

	if (clk_src <= 100000000UL) {
		pr_err("error reference clock value, or lower than 100MHz\n");
		return -EINVAL;
	}

	nominal_freq = ptp_qoriq_nominal_freq(clk_src);
	if (!nominal_freq)
		return -EINVAL;

	ptp_qoriq->tclk_period = 1000000000UL / nominal_freq;
	ptp_qoriq->tmr_prsc = DEFAULT_TMR_PRSC;

	/* Calculate initial frequency compensation value for TMR_ADD register.
	 * freq_comp = ceil(2^32 / freq_ratio)
	 * freq_ratio = reference_clock_freq / nominal_freq
	 */
	freq_comp = ((u64)1 << 32) * nominal_freq;
	freq_comp = div_u64_rem(freq_comp, clk_src, &remainder);
	if (remainder)
		freq_comp++;

	ptp_qoriq->tmr_add = freq_comp;
	ptp_qoriq->tmr_fiper1 = DEFAULT_FIPER1_PERIOD - ptp_qoriq->tclk_period;
	ptp_qoriq->tmr_fiper2 = DEFAULT_FIPER2_PERIOD - ptp_qoriq->tclk_period;
	ptp_qoriq->tmr_fiper3 = DEFAULT_FIPER3_PERIOD - ptp_qoriq->tclk_period;

	/* max_adj = 1000000000 * (freq_ratio - 1.0) - 1
	 * freq_ratio = reference_clock_freq / nominal_freq
	 */
	max_adj = 1000000000ULL * (clk_src - nominal_freq);
	max_adj = div_u64(max_adj, nominal_freq) - 1;
	ptp_qoriq->caps.max_adj = max_adj;

	return 0;
}