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

Commit 19aab273 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge branch 'clk-determine-rate-struct' into clk-next

* clk-determine-rate-struct:
  clk: fix some determine_rate implementations
  clk: change clk_ops' ->determine_rate() prototype
parents 86665d28 57d866e6
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -71,12 +71,8 @@ the operations defined in clk.h:
		long		(*round_rate)(struct clk_hw *hw,
						unsigned long rate,
						unsigned long *parent_rate);
		long		(*determine_rate)(struct clk_hw *hw,
						unsigned long rate,
						unsigned long min_rate,
						unsigned long max_rate,
						unsigned long *best_parent_rate,
						struct clk_hw **best_parent_clk);
		int		(*determine_rate)(struct clk_hw *hw,
						  struct clk_rate_request *req);
		int		(*set_parent)(struct clk_hw *hw, u8 index);
		u8		(*get_parent)(struct clk_hw *hw);
		int		(*set_rate)(struct clk_hw *hw,
+12 −17
Original line number Diff line number Diff line
@@ -462,43 +462,38 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw)
/**
 * omap3_noncore_dpll_determine_rate - determine rate for a DPLL
 * @hw: pointer to the clock to determine rate for
 * @rate: target rate for the DPLL
 * @best_parent_rate: pointer for returning best parent rate
 * @best_parent_clk: pointer for returning best parent clock
 * @req: target rate request
 *
 * Determines which DPLL mode to use for reaching a desired target rate.
 * Checks whether the DPLL shall be in bypass or locked mode, and if
 * locked, calculates the M,N values for the DPLL via round-rate.
 * Returns a positive clock rate with success, negative error value
 * in failure.
 * Returns a 0 on success, negative error value in failure.
 */
long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate,
				       unsigned long min_rate,
				       unsigned long max_rate,
				       unsigned long *best_parent_rate,
				       struct clk_hw **best_parent_clk)
int omap3_noncore_dpll_determine_rate(struct clk_hw *hw,
				      struct clk_rate_request *req)
{
	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
	struct dpll_data *dd;

	if (!hw || !rate)
	if (!req->rate)
		return -EINVAL;

	dd = clk->dpll_data;
	if (!dd)
		return -EINVAL;

	if (__clk_get_rate(dd->clk_bypass) == rate &&
	if (__clk_get_rate(dd->clk_bypass) == req->rate &&
	    (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
		*best_parent_clk = __clk_get_hw(dd->clk_bypass);
		req->best_parent_hw = __clk_get_hw(dd->clk_bypass);
	} else {
		rate = omap2_dpll_round_rate(hw, rate, best_parent_rate);
		*best_parent_clk = __clk_get_hw(dd->clk_ref);
		req->rate = omap2_dpll_round_rate(hw, req->rate,
					  &req->best_parent_rate);
		req->best_parent_hw = __clk_get_hw(dd->clk_ref);
	}

	*best_parent_rate = rate;
	req->best_parent_rate = req->rate;

	return rate;
	return 0;
}

/**
+12 −18
Original line number Diff line number Diff line
@@ -191,42 +191,36 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
/**
 * omap4_dpll_regm4xen_determine_rate - determine rate for a DPLL
 * @hw: pointer to the clock to determine rate for
 * @rate: target rate for the DPLL
 * @best_parent_rate: pointer for returning best parent rate
 * @best_parent_clk: pointer for returning best parent clock
 * @req: target rate request
 *
 * Determines which DPLL mode to use for reaching a desired rate.
 * Checks whether the DPLL shall be in bypass or locked mode, and if
 * locked, calculates the M,N values for the DPLL via round-rate.
 * Returns a positive clock rate with success, negative error value
 * in failure.
 * Returns 0 on success and a negative error value otherwise.
 */
long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
					unsigned long min_rate,
					unsigned long max_rate,
					unsigned long *best_parent_rate,
					struct clk_hw **best_parent_clk)
int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
				       struct clk_rate_request *req)
{
	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
	struct dpll_data *dd;

	if (!hw || !rate)
	if (!req->rate)
		return -EINVAL;

	dd = clk->dpll_data;
	if (!dd)
		return -EINVAL;

	if (__clk_get_rate(dd->clk_bypass) == rate &&
	if (__clk_get_rate(dd->clk_bypass) == req->rate &&
	    (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
		*best_parent_clk = __clk_get_hw(dd->clk_bypass);
		req->best_parent_hw = __clk_get_hw(dd->clk_bypass);
	} else {
		rate = omap4_dpll_regm4xen_round_rate(hw, rate,
						      best_parent_rate);
		*best_parent_clk = __clk_get_hw(dd->clk_ref);
		req->rate = omap4_dpll_regm4xen_round_rate(hw, req->rate,
						&req->best_parent_rate);
		req->best_parent_hw = __clk_get_hw(dd->clk_ref);
	}

	*best_parent_rate = rate;
	req->best_parent_rate = req->rate;

	return rate;
	return 0;
}
+29 −36
Original line number Diff line number Diff line
@@ -389,9 +389,8 @@ static long alchemy_calc_div(unsigned long rate, unsigned long prate,
	return div1;
}

static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
					unsigned long *best_parent_rate,
					struct clk_hw **best_parent_clk,
static int alchemy_clk_fgcs_detr(struct clk_hw *hw,
				 struct clk_rate_request *req,
				 int scale, int maxdiv)
{
	struct clk *pc, *bpc, *free;
@@ -422,14 +421,14 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
		}

		pr = clk_get_rate(pc);
		if (pr < rate)
		if (pr < req->rate)
			continue;

		/* what can hardware actually provide */
		tdv = alchemy_calc_div(rate, pr, scale, maxdiv, NULL);
		tdv = alchemy_calc_div(req->rate, pr, scale, maxdiv, NULL);
		nr = pr / tdv;
		diff = rate - nr;
		if (nr > rate)
		diff = req->rate - nr;
		if (nr > req->rate)
			continue;

		if (diff < lastdiff) {
@@ -448,15 +447,16 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
	 */
	if (lastdiff && free) {
		for (j = (maxdiv == 4) ? 1 : scale; j <= maxdiv; j += scale) {
			tpr = rate * j;
			tpr = req->rate * j;
			if (tpr < 0)
				break;
			pr = clk_round_rate(free, tpr);

			tdv = alchemy_calc_div(rate, pr, scale, maxdiv, NULL);
			tdv = alchemy_calc_div(req->rate, pr, scale, maxdiv,
					       NULL);
			nr = pr / tdv;
			diff = rate - nr;
			if (nr > rate)
			diff = req->rate - nr;
			if (nr > req->rate)
				continue;
			if (diff < lastdiff) {
				lastdiff = diff;
@@ -469,9 +469,14 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
		}
	}

	*best_parent_rate = bpr;
	*best_parent_clk = __clk_get_hw(bpc);
	if (br < 0)
		return br;

	req->best_parent_rate = bpr;
	req->best_parent_hw = __clk_get_hw(bpc);
	req->rate = br;

	return 0;
}

static int alchemy_clk_fgv1_en(struct clk_hw *hw)
@@ -562,14 +567,10 @@ static unsigned long alchemy_clk_fgv1_recalc(struct clk_hw *hw,
	return parent_rate / v;
}

static long alchemy_clk_fgv1_detr(struct clk_hw *hw, unsigned long rate,
					unsigned long min_rate,
					unsigned long max_rate,
					unsigned long *best_parent_rate,
					struct clk_hw **best_parent_clk)
static int alchemy_clk_fgv1_detr(struct clk_hw *hw,
				 struct clk_rate_request *req)
{
	return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate,
				     best_parent_clk, 2, 512);
	return alchemy_clk_fgcs_detr(hw, req, 2, 512);
}

/* Au1000, Au1100, Au15x0, Au12x0 */
@@ -696,11 +697,8 @@ static unsigned long alchemy_clk_fgv2_recalc(struct clk_hw *hw,
	return t;
}

static long alchemy_clk_fgv2_detr(struct clk_hw *hw, unsigned long rate,
					unsigned long min_rate,
					unsigned long max_rate,
					unsigned long *best_parent_rate,
					struct clk_hw **best_parent_clk)
static int alchemy_clk_fgv2_detr(struct clk_hw *hw,
				 struct clk_rate_request *req)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	int scale, maxdiv;
@@ -713,8 +711,7 @@ static long alchemy_clk_fgv2_detr(struct clk_hw *hw, unsigned long rate,
		maxdiv = 512;
	}

	return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate,
				     best_parent_clk, scale, maxdiv);
	return alchemy_clk_fgcs_detr(hw, req, scale, maxdiv);
}

/* Au1300 larger input mux, no separate disable bit, flexible divider */
@@ -917,17 +914,13 @@ static int alchemy_clk_csrc_setr(struct clk_hw *hw, unsigned long rate,
	return 0;
}

static long alchemy_clk_csrc_detr(struct clk_hw *hw, unsigned long rate,
					unsigned long min_rate,
					unsigned long max_rate,
					unsigned long *best_parent_rate,
					struct clk_hw **best_parent_clk)
static int alchemy_clk_csrc_detr(struct clk_hw *hw,
				 struct clk_rate_request *req)
{
	struct alchemy_fgcs_clk *c = to_fgcs_clk(hw);
	int scale = c->dt[2] == 3 ? 1 : 2; /* au1300 check */

	return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate,
				     best_parent_clk, scale, 4);
	return alchemy_clk_fgcs_detr(hw, req, scale, 4);
}

static struct clk_ops alchemy_clkops_csrc = {
+13 −12
Original line number Diff line number Diff line
@@ -54,12 +54,8 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
	return parent_rate >> pres;
}

static long clk_programmable_determine_rate(struct clk_hw *hw,
					    unsigned long rate,
					    unsigned long min_rate,
					    unsigned long max_rate,
					    unsigned long *best_parent_rate,
					    struct clk_hw **best_parent_hw)
static int clk_programmable_determine_rate(struct clk_hw *hw,
					   struct clk_rate_request *req)
{
	struct clk *parent = NULL;
	long best_rate = -EINVAL;
@@ -76,24 +72,29 @@ static long clk_programmable_determine_rate(struct clk_hw *hw,
		parent_rate = __clk_get_rate(parent);
		for (shift = 0; shift < PROG_PRES_MASK; shift++) {
			tmp_rate = parent_rate >> shift;
			if (tmp_rate <= rate)
			if (tmp_rate <= req->rate)
				break;
		}

		if (tmp_rate > rate)
		if (tmp_rate > req->rate)
			continue;

		if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) {
		if (best_rate < 0 ||
		    (req->rate - tmp_rate) < (req->rate - best_rate)) {
			best_rate = tmp_rate;
			*best_parent_rate = parent_rate;
			*best_parent_hw = __clk_get_hw(parent);
			req->best_parent_rate = parent_rate;
			req->best_parent_hw = __clk_get_hw(parent);
		}

		if (!best_rate)
			break;
	}

	if (best_rate < 0)
		return best_rate;

	req->rate = best_rate;
	return 0;
}

static int clk_programmable_set_parent(struct clk_hw *hw, u8 index)
Loading