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

Commit bb1dccfc authored by Simon Que's avatar Simon Que Committed by Stephen Warren
Browse files

ARM: tegra: Fix PWM clock programming



PWM clock source registers in Tegra 2 have different clock source selection bit
fields than other registers.  PWM clock source bits in CLK_SOURCE_PWM_0 register
are located at bit field bit[30:28] while others are at bit field bit[31:30] in
their respective clock source register.

This patch updates the clock programming to correctly reflect that, by adding a
flag to indicate the alternate bit field format and checking for it when
selecting a clock source (parent clock).

Signed-off-by: default avatarBill Huang <bilhuang@nvidia.com>
Signed-off-by: default avatarSimon Que <sque@chromium.org>
Signed-off-by: default avatarThierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
parent 72d967ed
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@

#define PERIPH_CLK_SOURCE_MASK		(3<<30)
#define PERIPH_CLK_SOURCE_SHIFT		30
#define PERIPH_CLK_SOURCE_PWM_MASK	(7<<28)
#define PERIPH_CLK_SOURCE_PWM_SHIFT	28
#define PERIPH_CLK_SOURCE_ENABLE	(1<<28)
#define PERIPH_CLK_SOURCE_DIVU71_MASK	0xFF
#define PERIPH_CLK_SOURCE_DIVU16_MASK	0xFFFF
@@ -908,9 +910,20 @@ static void tegra2_periph_clk_init(struct clk *c)
	u32 val = clk_readl(c->reg);
	const struct clk_mux_sel *mux = NULL;
	const struct clk_mux_sel *sel;
	u32 shift;
	u32 mask;

	if (c->flags & MUX_PWM) {
		shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
		mask = PERIPH_CLK_SOURCE_PWM_MASK;
	} else {
		shift = PERIPH_CLK_SOURCE_SHIFT;
		mask = PERIPH_CLK_SOURCE_MASK;
	}

	if (c->flags & MUX) {
		for (sel = c->inputs; sel->input != NULL; sel++) {
			if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
			if ((val & mask) >> shift == sel->value)
				mux = sel;
		}
		BUG_ON(!mux);
@@ -1023,12 +1036,23 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
{
	u32 val;
	const struct clk_mux_sel *sel;
	u32 mask, shift;

	pr_debug("%s: %s %s\n", __func__, c->name, p->name);

	if (c->flags & MUX_PWM) {
		shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
		mask = PERIPH_CLK_SOURCE_PWM_MASK;
	} else {
		shift = PERIPH_CLK_SOURCE_SHIFT;
		mask = PERIPH_CLK_SOURCE_MASK;
	}

	for (sel = c->inputs; sel->input != NULL; sel++) {
		if (sel->input == p) {
			val = clk_readl(c->reg);
			val &= ~PERIPH_CLK_SOURCE_MASK;
			val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
			val &= ~mask;
			val |= (sel->value) << shift;

			if (c->refcnt)
				clk_enable(p);
@@ -2156,7 +2180,7 @@ static struct clk tegra_list_clks[] = {
	PERIPH_CLK("i2s2",	"tegra20-i2s.1",	NULL,	18,	0x104,	26000000,  mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71),
	PERIPH_CLK("spdif_out",	"spdif_out",		NULL,	10,	0x108,	100000000, mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71),
	PERIPH_CLK("spdif_in",	"spdif_in",		NULL,	10,	0x10c,	100000000, mux_pllp_pllc_pllm,		MUX | DIV_U71),
	PERIPH_CLK("pwm",	"pwm",			NULL,	17,	0x110,	432000000, mux_pllp_pllc_audio_clkm_clk32,	MUX | DIV_U71),
	PERIPH_CLK("pwm",	"pwm",			NULL,	17,	0x110,	432000000, mux_pllp_pllc_audio_clkm_clk32,	MUX | DIV_U71 | MUX_PWM),
	PERIPH_CLK("spi",	"spi",			NULL,	43,	0x114,	40000000,  mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
	PERIPH_CLK("xio",	"xio",			NULL,	45,	0x120,	150000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
	PERIPH_CLK("twc",	"twc",			NULL,	16,	0x12c,	150000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),