Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b1ff6c0 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "qcom-geni-se : Add neareset frequency match support"

parents b2e1e922 d7f3f897
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -991,6 +991,9 @@ int geni_se_clk_freq_match(struct se_geni_rsc *rsc, unsigned long req_freq,
	unsigned long *tbl;
	int num_clk_levels;
	int i;
	unsigned long best_delta = 0;
	unsigned long new_delta;
	unsigned int divider;

	num_clk_levels = geni_se_clk_tbl_get(rsc, &tbl);
	if (num_clk_levels < 0)
@@ -1000,17 +1003,21 @@ int geni_se_clk_freq_match(struct se_geni_rsc *rsc, unsigned long req_freq,
		return -EFAULT;

	*res_freq = 0;

	for (i = 0; i < num_clk_levels; i++) {
		if (!(tbl[i] % req_freq)) {
		divider = DIV_ROUND_UP(tbl[i], req_freq);
		new_delta = req_freq - (tbl[i] / divider);

		if (!best_delta || new_delta < best_delta) {
			/* We have a new best! */
			*index = i;
			*res_freq = tbl[i];

			/*If the new best is exact then we're done*/
			if (new_delta == 0)
				return 0;
		}

		if (!(*res_freq) || ((tbl[i] > *res_freq) &&
				     (tbl[i] < req_freq))) {
			*index = i;
			*res_freq = tbl[i];
			best_delta = new_delta;
		}
	}

+9 −4
Original line number Diff line number Diff line
@@ -170,27 +170,32 @@ static int get_spi_clk_cfg(u32 speed_hz, struct spi_geni_master *mas,
			int *clk_idx, int *clk_div)
{
	unsigned long sclk_freq;
	unsigned long res_freq;
	struct se_geni_rsc *rsc = &mas->spi_rsc;
	int ret = 0;

	ret = geni_se_clk_freq_match(&mas->spi_rsc,
				(speed_hz * mas->oversampling), clk_idx,
				&sclk_freq, true);
				&sclk_freq, false);
	if (ret) {
		dev_err(mas->dev, "%s: Failed(%d) to find src clk for 0x%x\n",
						__func__, ret, speed_hz);
		return ret;
	}

	*clk_div = ((sclk_freq / mas->oversampling) / speed_hz);
	*clk_div = DIV_ROUND_UP(sclk_freq,  (mas->oversampling*speed_hz));

	if (!(*clk_div)) {
		dev_err(mas->dev, "%s:Err:sclk:%lu oversampling:%d speed:%u\n",
			__func__, sclk_freq, mas->oversampling, speed_hz);
		return -EINVAL;
	}

	dev_dbg(mas->dev, "%s: req %u sclk %lu, idx %d, div %d\n", __func__,
				speed_hz, sclk_freq, *clk_idx, *clk_div);
	res_freq = (sclk_freq / (*clk_div));

	dev_dbg(mas->dev, "%s: req %u resultant %u sclk %lu, idx %d, div %d\n",
		__func__, speed_hz, res_freq, sclk_freq, *clk_idx, *clk_div);

	ret = clk_set_rate(rsc->se_clk, sclk_freq);
	if (ret)
		dev_err(mas->dev, "%s: clk_set_rate failed %d\n",