From ed235d556945f46dbac84227f6f1467d397e39a3 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 4 Jul 2018 10:49:23 -0300 Subject: [PATCH 1/7] clk: imx51-imx53: Annotate critical clocks as CLK_IS_CRITICAL Instead of explicitly enabling critical clocks via clk_prepare_enable(), let's use the standard CLK_IS_CRITICAL flag instead, which makes the code a bit shorter. Signed-off-by: Fabio Estevam Signed-off-by: Stephen Boyd --- drivers/clk/imx/clk-imx51-imx53.c | 43 ++++++++++--------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c index caa8bd40692c6..346a53b48f9c9 100644 --- a/drivers/clk/imx/clk-imx51-imx53.c +++ b/drivers/clk/imx/clk-imx51-imx53.c @@ -175,13 +175,13 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) clk[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, per_root_sel, ARRAY_SIZE(per_root_sel)); clk[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); - clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); - clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24); - clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26); - clk[IMX5_CLK_TMAX1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0); - clk[IMX5_CLK_TMAX2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2); - clk[IMX5_CLK_TMAX3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4); - clk[IMX5_CLK_SPBA] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0); + clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2_flags("ahb_max", "ahb", MXC_CCM_CCGR0, 28, CLK_IS_CRITICAL); + clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", MXC_CCM_CCGR0, 24, CLK_IS_CRITICAL); + clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", MXC_CCM_CCGR0, 26, CLK_IS_CRITICAL); + clk[IMX5_CLK_TMAX1] = imx_clk_gate2_flags("tmax1", "ahb", MXC_CCM_CCGR1, 0, CLK_IS_CRITICAL); + clk[IMX5_CLK_TMAX2] = imx_clk_gate2_flags("tmax2", "ahb", MXC_CCM_CCGR1, 2, CLK_IS_CRITICAL); + clk[IMX5_CLK_TMAX3] = imx_clk_gate2_flags("tmax3", "ahb", MXC_CCM_CCGR1, 4, CLK_IS_CRITICAL); + clk[IMX5_CLK_SPBA] = imx_clk_gate2_flags("spba", "ipg", MXC_CCM_CCGR5, 0, CLK_IS_CRITICAL); clk[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2); clk[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3); clk[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3); @@ -252,8 +252,8 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) clk[IMX5_CLK_ECSPI2_PER_GATE] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24); clk[IMX5_CLK_CSPI_IPG_GATE] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26); clk[IMX5_CLK_SDMA_GATE] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30); - clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14); - clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16); + clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2_flags("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14, CLK_IS_CRITICAL); + clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2_flags("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16, CLK_IS_CRITICAL); clk[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); clk[IMX5_CLK_IPU_GATE] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10); clk[IMX5_CLK_NFC_GATE] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); @@ -267,7 +267,7 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); - clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24); + clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2_flags("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24, CLK_IS_CRITICAL); clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels)); clk[IMX5_CLK_SSI1_ROOT_SEL] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); @@ -316,21 +316,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) /* move usb phy clk to 24MHz */ clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]); - - clk_prepare_enable(clk[IMX5_CLK_GPC_DVFS]); - clk_prepare_enable(clk[IMX5_CLK_AHB_MAX]); /* esdhc3 */ - clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ1]); - clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ2]); /* fec */ - clk_prepare_enable(clk[IMX5_CLK_SPBA]); - clk_prepare_enable(clk[IMX5_CLK_EMI_FAST_GATE]); /* fec */ - clk_prepare_enable(clk[IMX5_CLK_EMI_SLOW_GATE]); /* eim */ - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC1_GATE]); - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC2_GATE]); - clk_prepare_enable(clk[IMX5_CLK_MIPI_ESC_GATE]); - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSP_GATE]); - clk_prepare_enable(clk[IMX5_CLK_TMAX1]); - clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ - clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ } static void __init mx50_clocks_init(struct device_node *np) @@ -442,10 +427,10 @@ static void __init mx51_clocks_init(struct device_node *np) clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); - clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6); - clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8); - clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10); - clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12); + clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL); + clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL); + clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL); + clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2_flags("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12, CLK_IS_CRITICAL); clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel)); clk[IMX5_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2, From d0897bc85ca89d5ddc6c2fcf2f99e04d4a577b63 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 6 Jul 2018 14:08:04 -0700 Subject: [PATCH 2/7] clk: imx51-imx53: Include sizes.h to silence compile errors This driver uses sizes.h, but relies on it being implicitly included somewhere else breaking random direct compilation of the file. Include sizes.h so we can build it those configurations too for better compile coverage. Signed-off-by: Stephen Boyd --- drivers/clk/imx/clk-imx51-imx53.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c index 346a53b48f9c9..fc8e782d817bd 100644 --- a/drivers/clk/imx/clk-imx51-imx53.c +++ b/drivers/clk/imx/clk-imx51-imx53.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include From f7b3182232c82bb9769e2d5471d702bae2972d2b Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Fri, 29 Jun 2018 17:38:14 +0300 Subject: [PATCH 3/7] clk: tegra: bpmp: Don't crash when a clock fails to register When registering clocks, we just skip any that fail to register (leaving a NULL hole in the clock table). However, our of_xlate function still tries to dereference each entry while looking for the clock with the requested id, causing a crash if any clocks failed to register. Add a check to of_xlate to skip any NULL clocks. Signed-off-by: Mikko Perttunen Acked-by: Jon Hunter Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-bpmp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index a896692b74ec8..01dada561c10c 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -586,9 +586,15 @@ static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec, unsigned int id = clkspec->args[0], i; struct tegra_bpmp *bpmp = data; - for (i = 0; i < bpmp->num_clocks; i++) - if (bpmp->clocks[i]->id == id) - return &bpmp->clocks[i]->hw; + for (i = 0; i < bpmp->num_clocks; i++) { + struct tegra_bpmp_clk *clk = bpmp->clocks[i]; + + if (!clk) + continue; + + if (clk->id == id) + return &clk->hw; + } return NULL; } From 26f8590c4a1f7bd30ef9b9d713388bd96eb43d16 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 11 Jun 2018 10:18:53 +0200 Subject: [PATCH 4/7] clk: tegra: Make vic03 a child of pll_c3 By default, the vic03 clock is a child of pll_m but that runs at 924 MHz which is too fast for VIC. Make vic03 a child of pll_c3 by default so it will run at a supported frequency. Signed-off-by: Thierry Reding Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-tegra124.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 0c69c79709504..f5048f82c0b9c 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -1290,6 +1290,7 @@ static struct tegra_clk_init_table common_init_table[] __initdata = { { TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1 }, { TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1 }, { TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0 }, + { TEGRA124_CLK_VIC03, TEGRA124_CLK_PLL_C3, 0, 0 }, /* must be the last entry */ { TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 }, }; From 8097d4c75f00f3fce8f4916521ec61ec0c607324 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 11 Jun 2018 10:20:37 +0200 Subject: [PATCH 5/7] clk: tegra: Make vde a child of pll_c3 The current default is to leave the VDE clock's parent at the default, which is clk_m. However, that is not a configuration that will allow the VDE to function. Reparent it to pll_c3 instead to make sure the hardware can actually decode video content. Signed-off-by: Thierry Reding Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-tegra124.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index f5048f82c0b9c..b6cf28ca2ed29 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -1267,7 +1267,7 @@ static struct tegra_clk_init_table common_init_table[] __initdata = { { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, - { TEGRA124_CLK_VDE, TEGRA124_CLK_CLK_MAX, 600000000, 0 }, + { TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_C3, 600000000, 0 }, { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 }, { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 }, { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 }, From da0d2239a56ec8fe6a617aade5901ab3bffc1ef4 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Mon, 4 Jun 2018 01:48:05 +0300 Subject: [PATCH 6/7] clk: tegra: Mark Memory Controller clock as critical Memory Controller should be always-on. Currently the sibling EMC clock is marked as critical, let's mark MC clock too for consistency. Signed-off-by: Dmitry Osipenko Acked-By: Peter De Schrijver Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-divider.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index 16e0aee14773b..58874c1bbf5e6 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c @@ -194,6 +194,7 @@ static const struct clk_div_table mc_div_table[] = { struct clk *tegra_clk_register_mc(const char *name, const char *parent_name, void __iomem *reg, spinlock_t *lock) { - return clk_register_divider_table(NULL, name, parent_name, 0, reg, - 16, 1, 0, mc_div_table, lock); + return clk_register_divider_table(NULL, name, parent_name, + CLK_IS_CRITICAL, reg, 16, 1, 0, + mc_div_table, lock); } From 405fcacbd866cfe75733b94bacdef5bcb4aa6c6c Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Tue, 5 Jun 2018 15:12:32 +0300 Subject: [PATCH 7/7] clk: tegra: emc: Avoid out-of-bounds bug Apparently there was an attempt to avoid out-of-bounds accesses when there is only one memory timing available, but there is a typo in the code that neglects that attempt. Signed-off-by: Dmitry Osipenko Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-emc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c index 5234acd30e898..0621a3a82ea6c 100644 --- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c @@ -132,7 +132,7 @@ static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) timing = tegra->timings + i; if (timing->rate > req->max_rate) { - i = min(i, 1); + i = max(i, 1); req->rate = tegra->timings[i - 1].rate; return 0; }