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

Commit ba66d7f0 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge branch 'omap/cleanup' into next/soc



This is a dependency for the omap/soc branch

Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 60c70c8c 3db53918
Loading
Loading
Loading
Loading
+45 −53
Original line number Diff line number Diff line
@@ -21,10 +21,7 @@

#include <asm/div64.h>

#include "soc.h"
#include "clock.h"
#include "cm-regbits-24xx.h"
#include "cm-regbits-34xx.h"

/* DPLL rate rounding: minimum DPLL multiplier, divider values */
#define DPLL_MIN_MULTIPLIER		2
@@ -44,20 +41,12 @@
#define DPLL_ROUNDING_VAL		((DPLL_SCALE_BASE / 2) * \
					 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))

/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
#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
@@ -87,33 +76,31 @@ static int _dpll_test_fint(struct clk_hw_omap *clk, unsigned int n)
	/* DPLL divider must result in a valid jitter correction val */
	fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n;

	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) {
	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;
		fint_min = ti_clk_features.fint_min;
		fint_max = ti_clk_features.fint_max;
	}

	if (fint < fint_min) {
	if (!fint_min || !fint_max) {
		WARN(1, "No fint limits available!\n");
		return DPLL_FINT_INVALID;
	}

	if (fint < ti_clk_features.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 > fint_max) {
	} else if (fint > ti_clk_features.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) {
	} else if (fint > ti_clk_features.fint_band1_max &&
		   fint < ti_clk_features.fint_band2_min) {
		pr_debug("rejecting n=%d due to Fint failure\n", n);
		ret = DPLL_FINT_INVALID;
	}
@@ -185,6 +172,34 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
	return r;
}

/**
 * _omap2_dpll_is_in_bypass - check if DPLL is in bypass mode or not
 * @v: bitfield value of the DPLL enable
 *
 * Checks given DPLL enable bitfield to see whether the DPLL is in bypass
 * mode or not. Returns 1 if the DPLL is in bypass, 0 otherwise.
 */
static int _omap2_dpll_is_in_bypass(u32 v)
{
	u8 mask, val;

	mask = ti_clk_features.dpll_bypass_vals;

	/*
	 * Each set bit in the mask corresponds to a bypass value equal
	 * to the bitshift. Go through each set-bit in the mask and
	 * compare against the given register value.
	 */
	while (mask) {
		val = __ffs(mask);
		mask ^= (1 << val);
		if (v == val)
			return 1;
	}

	return 0;
}

/* Public functions */
u8 omap2_init_dpll_parent(struct clk_hw *hw)
{
@@ -201,20 +216,9 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw)
	v >>= __ffs(dd->enable_mask);

	/* Reparent the struct clk in case the dpll is in bypass */
	if (cpu_is_omap24xx()) {
		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
			return 1;
	} else if (cpu_is_omap34xx()) {
		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
	if (_omap2_dpll_is_in_bypass(v))
		return 1;
	} else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) {
		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
			return 1;
	}

	return 0;
}

@@ -247,20 +251,8 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
	v &= dd->enable_mask;
	v >>= __ffs(dd->enable_mask);

	if (cpu_is_omap24xx()) {
		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
	if (_omap2_dpll_is_in_bypass(v))
		return __clk_get_rate(dd->clk_bypass);
	} else if (cpu_is_omap34xx()) {
		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
			return __clk_get_rate(dd->clk_bypass);
	} else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) {
		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
			return __clk_get_rate(dd->clk_bypass);
	}

	v = omap2_clk_readl(clk, dd->mult_div1_reg);
	dpll_mult = v & dd->mult_mask;
+4 −4
Original line number Diff line number Diff line
@@ -14,11 +14,11 @@
#include <linux/clk-provider.h>
#include <linux/io.h>


#include "clock.h"
#include "clock2xxx.h"
#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"

/* Register offsets */
#define CM_AUTOIDLE			0x30
#define CM_ICLKEN			0x10

/* Private functions */

+69 −7
Original line number Diff line number Diff line
@@ -46,6 +46,24 @@

u16 cpu_mask;

/*
 * Clock features setup. Used instead of CPU type checks.
 */
struct ti_clk_features ti_clk_features;

/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
#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_MIN		32000
#define OMAP3PLUS_DPLL_FINT_MAX		52000000

/*
 * clkdm_control: if true, then when a clock is enabled in the
 * hardware, its clockdomain will first be enabled; and when a clock
@@ -287,13 +305,7 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
	 * 34xx reverses this, just to keep us on our toes
	 * AM35xx uses both, depending on the module.
	 */
	if (cpu_is_omap24xx())
		*idlest_val = OMAP24XX_CM_IDLEST_VAL;
	else if (cpu_is_omap34xx())
		*idlest_val = OMAP34XX_CM_IDLEST_VAL;
	else
		BUG();

	*idlest_val = ti_clk_features.cm_idlest_val;
}

/**
@@ -731,3 +743,53 @@ void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name,
		(clk_get_rate(core_ck) / 1000000),
		(clk_get_rate(mpu_ck) / 1000000));
}

/**
 * ti_clk_init_features - init clock features struct for the SoC
 *
 * Initializes the clock features struct based on the SoC type.
 */
void __init ti_clk_init_features(void)
{
	/* Fint setup for DPLLs */
	if (cpu_is_omap3430()) {
		ti_clk_features.fint_min = OMAP3430_DPLL_FINT_BAND1_MIN;
		ti_clk_features.fint_max = OMAP3430_DPLL_FINT_BAND2_MAX;
		ti_clk_features.fint_band1_max = OMAP3430_DPLL_FINT_BAND1_MAX;
		ti_clk_features.fint_band2_min = OMAP3430_DPLL_FINT_BAND2_MIN;
	} else {
		ti_clk_features.fint_min = OMAP3PLUS_DPLL_FINT_MIN;
		ti_clk_features.fint_max = OMAP3PLUS_DPLL_FINT_MAX;
	}

	/* Bypass value setup for DPLLs */
	if (cpu_is_omap24xx()) {
		ti_clk_features.dpll_bypass_vals |=
			(1 << OMAP2XXX_EN_DPLL_LPBYPASS) |
			(1 << OMAP2XXX_EN_DPLL_FRBYPASS);
	} else if (cpu_is_omap34xx()) {
		ti_clk_features.dpll_bypass_vals |=
			(1 << OMAP3XXX_EN_DPLL_LPBYPASS) |
			(1 << OMAP3XXX_EN_DPLL_FRBYPASS);
	} else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx() ||
		   soc_is_omap54xx() || soc_is_dra7xx()) {
		ti_clk_features.dpll_bypass_vals |=
			(1 << OMAP4XXX_EN_DPLL_LPBYPASS) |
			(1 << OMAP4XXX_EN_DPLL_FRBYPASS) |
			(1 << OMAP4XXX_EN_DPLL_MNBYPASS);
	}

	/* Jitter correction only available on OMAP343X */
	if (cpu_is_omap343x())
		ti_clk_features.flags |= TI_CLK_DPLL_HAS_FREQSEL;

	/* Idlest value for interface clocks.
	 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
	 * 34xx reverses this, just to keep us on our toes
	 * AM35xx uses both, depending on the module.
	 */
	if (cpu_is_omap24xx())
		ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL;
	else if (cpu_is_omap34xx())
		ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL;
}
+19 −25
Original line number Diff line number Diff line
@@ -101,31 +101,6 @@ struct clockdomain;
	};							\
	DEFINE_STRUCT_CLK(_name, _parent_names, _ops);

#define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name,		\
				_parent_ptr, _flags,		\
				_clksel_reg, _clksel_mask)	\
	static const struct clksel _name##_div[] = {		\
		{						\
			.parent = _parent_ptr,			\
			.rates = div31_1to31_rates		\
		},						\
		{ .parent = NULL },				\
	};							\
	static struct clk _name;				\
	static const char *_name##_parent_names[] = {		\
		_parent_name,					\
	};							\
	static struct clk_hw_omap _name##_hw = {		\
		.hw = {						\
			.clk = &_name,				\
		},						\
		.clksel		= _name##_div,			\
		.clksel_reg	= _clksel_reg,			\
		.clksel_mask	= _clksel_mask,			\
		.ops		= &clkhwops_omap4_dpllmx,	\
	};							\
	DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops);

/* struct clksel_rate.flags possibilities */
#define RATE_IN_242X		(1 << 0)
#define RATE_IN_243X		(1 << 1)
@@ -248,6 +223,23 @@ void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg);

extern u16 cpu_mask;

/*
 * Clock features setup. Used instead of CPU type checks.
 */
struct ti_clk_features {
	u32 flags;
	long fint_min;
	long fint_max;
	long fint_band1_max;
	long fint_band2_min;
	u8 dpll_bypass_vals;
	u8 cm_idlest_val;
};

#define TI_CLK_DPLL_HAS_FREQSEL		(1 << 0)

extern struct ti_clk_features ti_clk_features;

extern const struct clkops clkops_omap2_dflt_wait;
extern const struct clkops clkops_dummy;
extern const struct clkops clkops_omap2_dflt;
@@ -286,4 +278,6 @@ extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);

extern void omap_clocks_register(struct omap_clk *oclks, int cnt);

void __init ti_clk_init_features(void);
#endif
+45 −15
Original line number Diff line number Diff line
@@ -44,8 +44,7 @@ struct omap3_scratchpad {
};

struct omap3_scratchpad_prcm_block {
	u32 prm_clksrc_ctrl;
	u32 prm_clksel;
	u32 prm_contents[2];
	u32 cm_contents[11];
	u32 prcm_block_size;
};
@@ -282,13 +281,9 @@ void omap3_clear_scratchpad_contents(void)
	void __iomem *v_addr;
	u32 offset = 0;
	v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM);
	if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
	    OMAP3430_GLOBAL_COLD_RST_MASK) {
	if (omap3xxx_prm_clear_global_cold_reset()) {
		for ( ; offset <= max_offset; offset += 0x4)
			writel_relaxed(0x0, (v_addr + offset));
		omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK,
					   OMAP3430_GR_MOD,
					   OMAP3_PRM_RSTST_OFFSET);
	}
}

@@ -331,13 +326,7 @@ void omap3_save_scratchpad_contents(void)
	scratchpad_contents.sdrc_block_offset = 0x64;

	/* Populate the PRCM block contents */
	prcm_block_contents.prm_clksrc_ctrl =
		omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
				       OMAP3_PRM_CLKSRC_CTRL_OFFSET);
	prcm_block_contents.prm_clksel =
		omap2_prm_read_mod_reg(OMAP3430_CCR_MOD,
				       OMAP3_PRM_CLKSEL_OFFSET);

	omap3_prm_save_scratchpad_contents(prcm_block_contents.prm_contents);
	omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents);

	prcm_block_contents.prcm_block_size = 0x0;
@@ -575,9 +564,50 @@ int omap3_ctrl_save_padconf(void)
 * Sets the bootmode for IVA2 to idle. This is needed by the PM code to
 * force disable IVA2 so that it does not prevent any low-power states.
 */
void omap3_ctrl_set_iva_bootmode_idle(void)
static void __init omap3_ctrl_set_iva_bootmode_idle(void)
{
	omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
			 OMAP343X_CONTROL_IVA2_BOOTMOD);
}

/**
 * omap3_ctrl_setup_d2d_padconf - setup stacked modem pads for idle
 *
 * Sets up the pads controlling the stacked modem in such way that the
 * device can enter idle.
 */
static void __init omap3_ctrl_setup_d2d_padconf(void)
{
	u16 mask, padconf;

	/*
	 * In a stand alone OMAP3430 where there is not a stacked
	 * modem for the D2D Idle Ack and D2D MStandby must be pulled
	 * high. S CONTROL_PADCONF_SAD2D_IDLEACK and
	 * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up.
	 */
	mask = (1 << 4) | (1 << 3); /* pull-up, enabled */
	padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY);
	padconf |= mask;
	omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY);

	padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK);
	padconf |= mask;
	omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK);
}

/**
 * omap3_ctrl_init - does static initializations for control module
 *
 * Initializes system control module. This sets up the sysconfig autoidle,
 * and sets up modem and iva2 so that they can be idled properly.
 */
void __init omap3_ctrl_init(void)
{
	omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG);

	omap3_ctrl_set_iva_bootmode_idle();

	omap3_ctrl_setup_d2d_padconf();
}
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
Loading