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

Commit 8f86f362 authored by Tony Lindgren's avatar Tony Lindgren
Browse files

Merge branch 'omap_clock_fixes_3.2' of git://git.pwsan.com/linux-2.6 into fixes

parents 994c0e99 1194d7b8
Loading
Loading
Loading
Loading
+35 −16
Original line number Diff line number Diff line
@@ -46,10 +46,19 @@
					 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))

/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
#define DPLL_FINT_BAND1_MIN		750000
#define DPLL_FINT_BAND1_MAX		2100000
#define DPLL_FINT_BAND2_MIN		7500000
#define DPLL_FINT_BAND2_MAX		21000000
#define OMAP3430_DPLL_FINT_BAND1_MIN	750000
#define OMAP3430_DPLL_FINT_BAND1_MAX	2100000
#define OMAP3430_DPLL_FINT_BAND2_MIN	7500000
#define OMAP3430_DPLL_FINT_BAND2_MAX	21000000

/*
 * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx.
 * From device data manual section 4.3 "DPLL and DLL Specifications".
 */
#define OMAP3PLUS_DPLL_FINT_JTYPE_MIN	500000
#define OMAP3PLUS_DPLL_FINT_JTYPE_MAX	2500000
#define OMAP3PLUS_DPLL_FINT_MIN		32000
#define OMAP3PLUS_DPLL_FINT_MAX		52000000

/* _dpll_test_fint() return codes */
#define DPLL_FINT_UNDERFLOW		-1
@@ -71,33 +80,43 @@
static int _dpll_test_fint(struct clk *clk, u8 n)
{
	struct dpll_data *dd;
	long fint;
	long fint, fint_min, fint_max;
	int ret = 0;

	dd = clk->dpll_data;

	/* DPLL divider must result in a valid jitter correction val */
	fint = clk->parent->rate / n;
	if (fint < DPLL_FINT_BAND1_MIN) {

	if (cpu_is_omap24xx()) {
		/* Should not be called for OMAP2, so warn if it is called */
		WARN(1, "No fint limits available for OMAP2!\n");
		return DPLL_FINT_INVALID;
	} else if (cpu_is_omap3430()) {
		fint_min = OMAP3430_DPLL_FINT_BAND1_MIN;
		fint_max = OMAP3430_DPLL_FINT_BAND2_MAX;
	} else if (dd->flags & DPLL_J_TYPE) {
		fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN;
		fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX;
	} else {
		fint_min = OMAP3PLUS_DPLL_FINT_MIN;
		fint_max = OMAP3PLUS_DPLL_FINT_MAX;
	}

	if (fint < fint_min) {
		pr_debug("rejecting n=%d due to Fint failure, "
			 "lowering max_divider\n", n);
		dd->max_divider = n;
		ret = DPLL_FINT_UNDERFLOW;

	} else if (fint > DPLL_FINT_BAND1_MAX &&
		   fint < DPLL_FINT_BAND2_MIN) {

		pr_debug("rejecting n=%d due to Fint failure\n", n);
		ret = DPLL_FINT_INVALID;

	} else if (fint > DPLL_FINT_BAND2_MAX) {

	} else if (fint > fint_max) {
		pr_debug("rejecting n=%d due to Fint failure, "
			 "boosting min_divider\n", n);
		dd->min_divider = n;
		ret = DPLL_FINT_INVALID;

	} else if (cpu_is_omap3430() && fint > OMAP3430_DPLL_FINT_BAND1_MAX &&
		   fint < OMAP3430_DPLL_FINT_BAND2_MIN) {
		pr_debug("rejecting n=%d due to Fint failure\n", n);
		ret = DPLL_FINT_INVALID;
	}

	return ret;
+2 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ void omap3_noncore_dpll_disable(struct clk *clk);
int omap4_dpllmx_gatectrl_read(struct clk *clk);
void omap4_dpllmx_allow_gatectrl(struct clk *clk);
void omap4_dpllmx_deny_gatectrl(struct clk *clk);
long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate);
unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk);

#ifdef CONFIG_OMAP_RESET_CLOCKS
void omap2_clk_disable_unused(struct clk *clk);
+7 −0
Original line number Diff line number Diff line
@@ -8,6 +8,13 @@
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
#define __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H

/*
 * OMAP4430_REGM4XEN_MULT: If the CM_CLKMODE_DPLL_ABE.DPLL_REGM4XEN bit is
 *    set, then the DPLL's lock frequency is multiplied by 4 (OMAP4430 TRM
 *    vV Section 3.6.3.3.1 "DPLLs Output Clocks Parameters")
 */
#define OMAP4430_REGM4XEN_MULT	4

int omap4xxx_clk_init(void);

#endif
+23 −9
Original line number Diff line number Diff line
@@ -270,8 +270,8 @@ static struct clk dpll_abe_ck = {
	.dpll_data	= &dpll_abe_dd,
	.init		= &omap2_init_dpll_parent,
	.ops		= &clkops_omap3_noncore_dpll_ops,
	.recalc		= &omap3_dpll_recalc,
	.round_rate	= &omap2_dpll_round_rate,
	.recalc		= &omap4_dpll_regm4xen_recalc,
	.round_rate	= &omap4_dpll_regm4xen_round_rate,
	.set_rate	= &omap3_noncore_dpll_set_rate,
};

@@ -1195,11 +1195,25 @@ static struct clk l4_wkup_clk_mux_ck = {
	.recalc		= &omap2_clksel_recalc,
};

static const struct clksel_rate div2_2to1_rates[] = {
	{ .div = 1, .val = 1, .flags = RATE_IN_4430 },
	{ .div = 2, .val = 0, .flags = RATE_IN_4430 },
	{ .div = 0 },
};

static const struct clksel ocp_abe_iclk_div[] = {
	{ .parent = &aess_fclk, .rates = div2_2to1_rates },
	{ .parent = NULL },
};

static struct clk ocp_abe_iclk = {
	.name		= "ocp_abe_iclk",
	.parent		= &aess_fclk,
	.clksel		= ocp_abe_iclk_div,
	.clksel_reg	= OMAP4430_CM1_ABE_AESS_CLKCTRL,
	.clksel_mask	= OMAP4430_CLKSEL_AESS_FCLK_MASK,
	.ops		= &clkops_null,
	.recalc		= &followparent_recalc,
	.recalc		= &omap2_clksel_recalc,
};

static struct clk per_abe_24m_fclk = {
@@ -1398,9 +1412,9 @@ static struct clk dss_dss_clk = {
};

static const struct clksel_rate div3_8to32_rates[] = {
	{ .div = 8, .val = 0, .flags = RATE_IN_44XX },
	{ .div = 16, .val = 1, .flags = RATE_IN_44XX },
	{ .div = 32, .val = 2, .flags = RATE_IN_44XX },
	{ .div = 8, .val = 0, .flags = RATE_IN_4460 },
	{ .div = 16, .val = 1, .flags = RATE_IN_4460 },
	{ .div = 32, .val = 2, .flags = RATE_IN_4460 },
	{ .div = 0 },
};

@@ -3403,12 +3417,12 @@ int __init omap4xxx_clk_init(void)
	struct omap_clk *c;
	u32 cpu_clkflg;

	if (cpu_is_omap44xx()) {
	if (cpu_is_omap443x()) {
		cpu_mask = RATE_IN_4430;
		cpu_clkflg = CK_443X;
	} else if (cpu_is_omap446x()) {
		cpu_mask = RATE_IN_4460;
		cpu_clkflg = CK_446X;
		cpu_mask = RATE_IN_4460 | RATE_IN_4430;
		cpu_clkflg = CK_446X | CK_443X;
	} else {
		return 0;
	}
+6 −3
Original line number Diff line number Diff line
@@ -390,7 +390,8 @@ int omap3_noncore_dpll_enable(struct clk *clk)
	 * propagating?
	 */
	if (!r)
		clk->rate = omap2_get_dpll_rate(clk);
		clk->rate = (clk->recalc) ? clk->recalc(clk) :
			omap2_get_dpll_rate(clk);

	return r;
}
@@ -424,6 +425,7 @@ void omap3_noncore_dpll_disable(struct clk *clk)
int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
{
	struct clk *new_parent = NULL;
	unsigned long hw_rate;
	u16 freqsel = 0;
	struct dpll_data *dd;
	int ret;
@@ -435,7 +437,8 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
	if (!dd)
		return -EINVAL;

	if (rate == omap2_get_dpll_rate(clk))
	hw_rate = (clk->recalc) ? clk->recalc(clk) : omap2_get_dpll_rate(clk);
	if (rate == hw_rate)
		return 0;

	/*
@@ -455,7 +458,7 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
			new_parent = dd->clk_bypass;
	} else {
		if (dd->last_rounded_rate != rate)
			omap2_dpll_round_rate(clk, rate);
			rate = clk->round_rate(clk, rate);

		if (dd->last_rounded_rate == 0)
			return -EINVAL;
Loading