lkml.org 
[lkml]   [2019]   [Nov]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 236/306] clk: tegra20: Turn EMC clock gate into divider
    Date
    From: Dmitry Osipenko <digetx@gmail.com>

    [ 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: Dmitry Osipenko <digetx@gmail.com>
    Acked-by: Peter De Schrijver <pdeschrijver@nvidia.com>
    Acked-by: Stephen Boyd <sboyd@kernel.org>
    Signed-off-by: Thierry Reding <treding@nvidia.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/clk/tegra/clk-tegra20.c | 36 ++++++++++++++++++++++++---------
    1 file changed, 26 insertions(+), 10 deletions(-)

    diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
    index cc857d4d4a86e..68551effb5ca2 100644
    --- a/drivers/clk/tegra/clk-tegra20.c
    +++ b/drivers/clk/tegra/clk-tegra20.c
    @@ -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,
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-11-27 22:06    [W:2.696 / U:0.388 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site