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

Commit d15b8b69 authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Greg Kroah-Hartman
Browse files

clk: tegra20: Turn EMC clock gate into divider



[ Upstream commit 514fddba845ed3a1b17e01e99cb3a2a52256a88a ]

Kernel should never gate the EMC clock as it causes immediate lockup, so
removing clk-gate functionality doesn't affect anything. Turning EMC clk
gate into divider allows to implement glitch-less EMC scaling, avoiding
reparenting to a backup clock.

Signed-off-by: default avatarDmitry Osipenko <digetx@gmail.com>
Acked-by: default avatarPeter De Schrijver <pdeschrijver@nvidia.com>
Acked-by: default avatarStephen Boyd <sboyd@kernel.org>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 91c5f99d
Loading
Loading
Loading
Loading
+26 −10
Original line number Diff line number Diff line
@@ -578,7 +578,6 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = {
	[tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true },
	[tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true },
	[tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true },
	[tegra_clk_emc] = { .dt_id = TEGRA20_CLK_EMC, .present = true },
};

static unsigned long tegra20_clk_measure_input_freq(void)
@@ -799,6 +798,31 @@ static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
	TEGRA_INIT_DATA_NODIV("disp2",	mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26,  0, TEGRA20_CLK_DISP2),
};

static void __init tegra20_emc_clk_init(void)
{
	struct clk *clk;

	clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
			       ARRAY_SIZE(mux_pllmcp_clkm),
			       CLK_SET_RATE_NO_REPARENT,
			       clk_base + CLK_SOURCE_EMC,
			       30, 2, 0, &emc_lock);

	clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
				    &emc_lock);
	clks[TEGRA20_CLK_MC] = clk;

	/*
	 * Note that 'emc_mux' source and 'emc' rate shouldn't be changed at
	 * the same time due to a HW bug, this won't happen because we're
	 * defining 'emc_mux' and 'emc' as distinct clocks.
	 */
	clk = tegra_clk_register_divider("emc", "emc_mux",
				clk_base + CLK_SOURCE_EMC, CLK_IS_CRITICAL,
				TEGRA_DIVIDER_INT, 0, 8, 1, &emc_lock);
	clks[TEGRA20_CLK_EMC] = clk;
}

static void __init tegra20_periph_clk_init(void)
{
	struct tegra_periph_init_data *data;
@@ -812,15 +836,7 @@ static void __init tegra20_periph_clk_init(void)
	clks[TEGRA20_CLK_AC97] = clk;

	/* emc */
	clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
			       ARRAY_SIZE(mux_pllmcp_clkm),
			       CLK_SET_RATE_NO_REPARENT,
			       clk_base + CLK_SOURCE_EMC,
			       30, 2, 0, &emc_lock);

	clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
				    &emc_lock);
	clks[TEGRA20_CLK_MC] = clk;
	tegra20_emc_clk_init();

	/* dsi */
	clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0,