From f7485a509b4217b768d9d48b2642032fa31c431a Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Sat, 6 Dec 2025 16:46:50 +0000 Subject: [PATCH] clk changes, test later --- drivers/clk/tegra/clk-tegra210.c | 1 - drivers/clk/tegra/clk-tegra210b01.c | 150 ++++++++++++++-------------- 2 files changed, 77 insertions(+), 74 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index b34ec865b9c6..b097a171c47f 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -1813,7 +1813,6 @@ static struct tegra_clk_pll_freq_table pll_c4_vco_freq_table[] = { { 12000000, 600000000, 50, 1, 1, 0 }, { 13000000, 600000000, 46, 1, 1, 0 }, /* actual: 598.0 MHz */ { 38400000, 998400000, 78, 3, 1, 0 }, - { 38400000, 793600000, 62, 3, 1, 0 }, { 0, 0, 0, 0, 0, 0 }, }; diff --git a/drivers/clk/tegra/clk-tegra210b01.c b/drivers/clk/tegra/clk-tegra210b01.c index 54743f2156f1..0dc1445742a7 100644 --- a/drivers/clk/tegra/clk-tegra210b01.c +++ b/drivers/clk/tegra/clk-tegra210b01.c @@ -1705,7 +1705,6 @@ static struct div_nmp pllss_nmp = { static struct tegra_clk_pll_freq_table pll_c4_vco_freq_table[] = { { 38400000, 998400000, 52, 2, 1, 0 }, - { 38400000, 787200000, 41, 2, 1, 0 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -2177,9 +2176,9 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_i2s0] = { .dt_id = TEGRA210_CLK_I2S0, .present = true }, [tegra_clk_apbdma] = { .dt_id = TEGRA210_CLK_APBDMA, .present = true }, [tegra_clk_kfuse] = { .dt_id = TEGRA210_CLK_KFUSE, .present = true }, - [tegra_clk_sbc1_9] = { .dt_id = TEGRA210_CLK_SBC1, .present = true }, - [tegra_clk_sbc2_9] = { .dt_id = TEGRA210_CLK_SBC2, .present = true }, - [tegra_clk_sbc3_9] = { .dt_id = TEGRA210_CLK_SBC3, .present = true }, + [tegra_clk_sbc1_9] = { .dt_id = TEGRA210_CLK_SBC1, .use_integer_div = true, .present = true }, + [tegra_clk_sbc2_9] = { .dt_id = TEGRA210_CLK_SBC2, .use_integer_div = true, .present = true }, + [tegra_clk_sbc3_9] = { .dt_id = TEGRA210_CLK_SBC3, .use_integer_div = true, .present = true }, [tegra_clk_i2c5] = { .dt_id = TEGRA210_CLK_I2C5, .present = true }, [tegra_clk_csi] = { .dt_id = TEGRA210_CLK_CSI, .present = true }, [tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true }, @@ -2189,20 +2188,20 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true }, [tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true }, [tegra_clk_i2c3] = { .dt_id = TEGRA210_CLK_I2C3, .present = true }, - [tegra_clk_sbc4_9] = { .dt_id = TEGRA210_CLK_SBC4, .present = true }, + [tegra_clk_sbc4_9] = { .dt_id = TEGRA210_CLK_SBC4, .use_integer_div = true, .present = true }, [tegra_clk_sdmmc3_9] = { .dt_id = TEGRA210_CLK_SDMMC3, .present = true }, [tegra_clk_pcie] = { .dt_id = TEGRA210_CLK_PCIE, .present = true }, [tegra_clk_owr_8] = { .dt_id = TEGRA210_CLK_OWR, .present = true }, [tegra_clk_afi] = { .dt_id = TEGRA210_CLK_AFI, .present = true }, [tegra_clk_csite_8] = { .dt_id = TEGRA210_CLK_CSITE, .present = true }, - [tegra_clk_soc_therm_8] = { .dt_id = TEGRA210_CLK_SOC_THERM, .present = true }, + [tegra_clk_soc_therm_8] = { .dt_id = TEGRA210_CLK_SOC_THERM, .use_integer_div = true, .present = true }, [tegra_clk_dtv] = { .dt_id = TEGRA210_CLK_DTV, .present = true }, - [tegra_clk_i2cslow] = { .dt_id = TEGRA210_CLK_I2CSLOW, .present = true }, + [tegra_clk_i2cslow] = { .dt_id = TEGRA210_CLK_I2CSLOW, .use_integer_div = true, .present = true }, [tegra_clk_tsec_8] = { .dt_id = TEGRA210_CLK_TSEC, .present = true }, [tegra_clk_xusb_host] = { .dt_id = TEGRA210_CLK_XUSB_HOST, .present = true }, [tegra_clk_csus] = { .dt_id = TEGRA210_CLK_CSUS, .present = true }, [tegra_clk_mselect] = { .dt_id = TEGRA210_CLK_MSELECT, .present = true }, - [tegra_clk_tsensor] = { .dt_id = TEGRA210_CLK_TSENSOR, .present = true }, + [tegra_clk_tsensor] = { .dt_id = TEGRA210_CLK_TSENSOR, .use_integer_div = true, .present = true }, [tegra_clk_i2s3] = { .dt_id = TEGRA210_CLK_I2S3, .present = true }, [tegra_clk_i2s4] = { .dt_id = TEGRA210_CLK_I2S4, .present = true }, [tegra_clk_i2c4] = { .dt_id = TEGRA210_CLK_I2C4, .present = true }, @@ -2217,8 +2216,8 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_sata_8] = { .dt_id = TEGRA210_CLK_SATA, .present = true }, [tegra_clk_hda_8] = { .dt_id = TEGRA210_CLK_HDA, .present = true }, [tegra_clk_hda2hdmi] = { .dt_id = TEGRA210_CLK_HDA2HDMI, .present = true }, - [tegra_clk_cilab] = { .dt_id = TEGRA210_CLK_CILAB, .present = true }, - [tegra_clk_cilcd] = { .dt_id = TEGRA210_CLK_CILCD, .present = true }, + [tegra_clk_cilab] = { .dt_id = TEGRA210_CLK_CILAB, .use_integer_div = true, .present = true }, + [tegra_clk_cilcd] = { .dt_id = TEGRA210_CLK_CILCD, .use_integer_div = true, .present = true }, [tegra_clk_cile] = { .dt_id = TEGRA210_CLK_CILE, .present = true }, [tegra_clk_dsialp] = { .dt_id = TEGRA210_CLK_DSIALP, .present = true }, [tegra_clk_dsiblp] = { .dt_id = TEGRA210_CLK_DSIBLP, .present = true }, @@ -2238,7 +2237,7 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true }, - [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true }, + [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .use_integer_div = true, .present = true }, [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true }, [tegra_clk_vi_sensor_8] = { .dt_id = TEGRA210_CLK_VI_SENSOR, .present = true }, [tegra_clk_fuse] = { .dt_id = TEGRA210_CLK_FUSE, .present = true }, @@ -2276,7 +2275,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_pll_u_60m] = { .dt_id = TEGRA210_CLK_PLL_U_60M, .present = true }, [tegra_clk_pll_u_48m] = { .dt_id = TEGRA210_CLK_PLL_U_48M, .present = true }, [tegra_clk_pll_x] = { .dt_id = TEGRA210_CLK_PLL_X, .present = true }, - [tegra_clk_pll_x_out0] = { .dt_id = TEGRA210_CLK_PLL_X_OUT0, .present = true }, [tegra_clk_pll_re_vco] = { .dt_id = TEGRA210_CLK_PLL_RE_VCO, .present = true }, [tegra_clk_pll_re_out] = { .dt_id = TEGRA210_CLK_PLL_RE_OUT, .present = true }, [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA210_CLK_SPDIF_IN_SYNC, .present = true }, @@ -2310,7 +2308,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_hclk] = { .dt_id = TEGRA210_CLK_HCLK, .present = true }, [tegra_clk_pclk] = { .dt_id = TEGRA210_CLK_PCLK, .present = true }, [tegra_clk_cclk_g] = { .dt_id = TEGRA210_CLK_CCLK_G, .present = true }, - [tegra_clk_cclk_lp] = { .dt_id = TEGRA210_CLK_CCLK_LP, .present = true }, [tegra_clk_dfll_ref] = { .dt_id = TEGRA210_CLK_DFLL_REF, .present = true }, [tegra_clk_dfll_soc] = { .dt_id = TEGRA210_CLK_DFLL_SOC, .present = true }, [tegra_clk_vi_sensor2_8] = { .dt_id = TEGRA210_CLK_VI_SENSOR2, .present = true }, @@ -2325,8 +2322,8 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_spdif_mux] = { .dt_id = TEGRA210_CLK_SPDIF_MUX, .present = true }, [tegra_clk_maud] = { .dt_id = TEGRA210_CLK_MAUD, .present = true }, [tegra_clk_mipibif] = { .dt_id = TEGRA210_CLK_MIPIBIF, .present = true }, - [tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .present = true }, - [tegra_clk_sdmmc_legacy] = { .dt_id = TEGRA210_CLK_SDMMC_LEGACY, .present = true }, + [tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .use_integer_div = true, .present = true }, + [tegra_clk_sdmmc_legacy] = { .dt_id = TEGRA210_CLK_SDMMC_LEGACY, .use_integer_div = true, .present = true }, [tegra_clk_tsecb] = { .dt_id = TEGRA210_CLK_TSECB, .present = true }, [tegra_clk_uartape] = { .dt_id = TEGRA210_CLK_UARTAPE, .present = true }, [tegra_clk_vi_i2c] = { .dt_id = TEGRA210_CLK_VI_I2C, .present = true }, @@ -2535,7 +2532,7 @@ static void tegra210_utmi_hw_sequencer_enable(void) udelay(1); } -static int tegra210_enable_utmipll(void) +static int tegra210b01_enable_utmipll(void) { u32 reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); bool hw_on = reg & UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE; @@ -2618,7 +2615,7 @@ static int tegra210_enable_pllu(void) return 0; } -static int tegra210_init_pllu(void) +static int tegra210b01_init_pllu(void) { u32 reg; int err; @@ -2676,7 +2673,7 @@ static int tegra210_init_pllu(void) } /* enable UTMIPLL hw control if not yet done by the bootloader */ - return tegra210_enable_utmipll(); + return tegra210b01_enable_utmipll(); } /* @@ -2876,7 +2873,7 @@ static __init void tegra210_periph_clk_init(struct device_node *np, tegra210_clk_register_mc("mc", "emc"); } -static void __init tegra210_pll_init(void __iomem *clk_base, +static void __init tegra210b01_pll_init(void __iomem *clk_base, void __iomem *pmc) { struct clk *clk; @@ -2921,7 +2918,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base, clks[TEGRA210_CLK_PLL_C3] = clk; /* PLLU_VCO */ - if (!tegra210_init_pllu()) { + if (!tegra210b01_init_pllu()) { clk = clk_register_fixed_rate(NULL, "pll_u_vco", "pll_ref", 0, 480*1000*1000); clk_register_clkdev(clk, "pll_u_vco", NULL); @@ -3030,8 +3027,8 @@ static void __init tegra210_pll_init(void __iomem *clk_base, clks[TEGRA210_CLK_PLL_E] = clk; /* PLLC4 */ - clk = tegra_clk_register_pllre_tegra210("pll_c4_vco", "pll_ref", - clk_base, pmc, 0, &pll_c4_vco_params, NULL, pll_ref_freq); + clk = tegra_clk_register_pllre("pll_c4_vco", "pll_ref", clk_base, pmc, + 0, &pll_c4_vco_params, NULL, pll_ref_freq); clk_register_clkdev(clk, "pll_c4_vco", NULL); clks[TEGRA210_CLK_PLL_C4] = clk; @@ -3098,6 +3095,55 @@ static void __init tegra210_pll_init(void __iomem *clk_base, clks[TEGRA210_CLK_PLL_P_UPHY_OUT] = clk; } +static char *tegra210b01_determine_pllc4_rate(void) +{ + struct device_node *node; + u32 val; + int out0_ratio, i; + unsigned long sdmmc_max_rate = 0; + struct clk *clk; + char *sclk_high_clk; + + for_each_compatible_node(node, NULL, "nvidia,tegra210-sdhci") { + if (!of_device_is_available(node)) + continue; + + if (!of_property_read_u32(node, "max-frequency", &val) + && val > sdmmc_max_rate) + sdmmc_max_rate = val; + } + + switch (sdmmc_max_rate) { + case 266000000: + sclk_high_clk = "pll_c4_out1"; + pll_c4_vco_params.fixed_rate = 798000000; + out0_ratio = 4; + break; + default: + sclk_high_clk = "pll_c4_out3"; + pll_c4_vco_params.fixed_rate = 1000000000; + out0_ratio = 1; + break; + } + + pll_c4_vco_params.fixed_rate /= pll_ref_freq/pll_c4_vco_params.mdiv_default; + pll_c4_vco_params.fixed_rate *= pll_ref_freq/pll_c4_vco_params.mdiv_default; + + val = readl(clk_base + PLLC4_BASE); + for (i = 0; pll_vco_post_div_table[i].div; i++) + if (pll_vco_post_div_table[i].div >= out0_ratio) + break; + val &= ~GENMASK(23, 19); + val |= pll_vco_post_div_table[i].val << pll_c4_vco_params.div_nmp->divp_shift; + writel(val, clk_base + PLLC4_BASE); + + clk = clk_register_fixed_factor(NULL, "pll_c4_out0", "pll_c4_vco", 0, + 1, pll_vco_post_div_table[i].div); + clks[TEGRA210_CLK_PLL_C4_OUT0] = clk; + + return sclk_high_clk; +} + /* Tegra210 CPU clock and reset control functions */ static void tegra210_wait_cpu_in_reset(u32 cpu) { @@ -3179,7 +3225,7 @@ static void tegra210_clk_resume(void) fence_udelay(2, clk_base); /* restore PLLs and all peripheral clock rates */ - tegra210_init_pllu(); + tegra210b01_init_pllu(); clk_restore_context(); /* restore saved context of peripheral clocks and reset state */ @@ -3223,12 +3269,9 @@ static const struct of_device_id pmc_match[] __initconst = { }; static struct tegra_clk_init_table t210b01_init_table[] __initdata = { - { TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1, - TEGRA_TABLE_RATE_CHANGE_OVERCLOCK }, - { TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 0, 1, - TEGRA_TABLE_RATE_CHANGE_OVERCLOCK }, - { TEGRA210_CLK_PLL_DP, TEGRA210_CLK_CLK_MAX, 270000000, 0, - TEGRA_TABLE_RATE_CHANGE_OVERCLOCK }, + { TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1, TEGRA_TABLE_RATE_CHANGE_OVERCLOCK }, + //{ TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 0, 1, TEGRA_TABLE_RATE_CHANGE_OVERCLOCK }, + { TEGRA210_CLK_PLL_DP, TEGRA210_CLK_CLK_MAX, 270000000, 0, TEGRA_TABLE_RATE_CHANGE_OVERCLOCK }, { TEGRA210_CLK_PLL_P_UPHY_OUT, TEGRA210_CLK_CLK_MAX, 102000000, 1 }, { TEGRA210_CLK_SDMMC_LEGACY, TEGRA210_CLK_PLL_P, 12000000, 0 }, { TEGRA210_CLK_I2CSLOW, TEGRA210_CLK_CLK_32K, 32000, 0 }, @@ -3399,48 +3442,6 @@ static int tegra210b01_reset_deassert(unsigned long id) return 0; } -static enum clk_id tegra210b01_integer_div_id[] = { - tegra_clk_cilab, - tegra_clk_cilcd, - - tegra_clk_spdif_out, - - tegra_clk_sbc1_9, - tegra_clk_sbc2_9, - tegra_clk_sbc3_9, - tegra_clk_sbc4_9, - - tegra_clk_sdmmc_legacy, - tegra_clk_i2cslow, - tegra_clk_qspi, - - tegra_clk_soc_therm_8, - tegra_clk_tsensor, -}; - -static void tegra210b01_adjust_clks(struct tegra_clk *tegra_clks) -{ - int i; - - /* Remove CPU_LP claster clocks */ - tegra_clks[tegra_clk_cclk_lp].present = false; - tegra_clks[tegra_clk_pll_x_out0].present = false; - - /* Prevent 1:1.5 fractional divider setting */ - div1_5_not_allowed = true; - - /* Prevent any fractional setting */ - for (i = 0; i < ARRAY_SIZE(tegra210b01_integer_div_id); i++) { - enum clk_id cid = tegra210b01_integer_div_id[i]; - - if (cid >= tegra_clk_max || !tegra_clks[cid].present) { - pr_warn("%s: clk %d is not present\n", __func__, cid); - continue; - } - tegra_clks[cid].use_integer_div = true; - } -} - /** * tegra210b01_clock_init - Tegra210-specific clock initialization * @np: struct device_node * of the DT node for the SoC CAR IP block @@ -3453,6 +3454,7 @@ static void tegra210b01_adjust_clks(struct tegra_clk *tegra_clks) static void __init tegra210b01_clock_init(struct device_node *np) { struct device_node *node; + char *sclk_high_clk; u32 value, clk_m_div; clk_base = of_iomap(np, 0); @@ -3481,7 +3483,8 @@ static void __init tegra210b01_clock_init(struct device_node *np) if (!clks) return; - tegra210b01_adjust_clks(tegra210_clks); + /* Prevent 1:1.5 fractional divider setting */ + div1_5_not_allowed = true; value = readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT; clk_m_div = (value & CLK_M_DIVISOR_MASK) + 1; @@ -3492,7 +3495,8 @@ static void __init tegra210b01_clock_init(struct device_node *np) return; tegra_fixed_clk_init(tegra210_clks); - tegra210_pll_init(clk_base, pmc_base); + sclk_high_clk = tegra210b01_determine_pllc4_rate(); + tegra210b01_pll_init(clk_base, pmc_base); tegra210_periph_clk_init(np, clk_base, pmc_base); tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks, tegra210_audio_plls,