From 0d34dfbf3023cf119b83f6470692c0b10c832495 Mon Sep 17 00:00:00 2001 From: JC Kuo Date: Wed, 12 Jun 2019 11:14:34 +0800 Subject: clk: tegra210: fix PLLU and PLLU_OUT1 Full-speed and low-speed USB devices do not work with Tegra210 platforms because of incorrect PLLU/PLLU_OUT1 clock settings. When full-speed device is connected: [ 14.059886] usb 1-3: new full-speed USB device number 2 using tegra-xusb [ 14.196295] usb 1-3: device descriptor read/64, error -71 [ 14.436311] usb 1-3: device descriptor read/64, error -71 [ 14.675749] usb 1-3: new full-speed USB device number 3 using tegra-xusb [ 14.812335] usb 1-3: device descriptor read/64, error -71 [ 15.052316] usb 1-3: device descriptor read/64, error -71 [ 15.164799] usb usb1-port3: attempt power cycle When low-speed device is connected: [ 37.610949] usb usb1-port3: Cannot enable. Maybe the USB cable is bad? [ 38.557376] usb usb1-port3: Cannot enable. Maybe the USB cable is bad? [ 38.564977] usb usb1-port3: attempt power cycle This commit fixes the issue by: 1. initializing PLLU_OUT1 before initializing XUSB_FS_SRC clock because PLLU_OUT1 is parent of XUSB_FS_SRC. 2. changing PLLU post-divider to /2 (DIVP=1) according to Technical Reference Manual. Fixes: e745f992cf4b ("clk: tegra: Rework pll_u") Signed-off-by: JC Kuo Acked-By: Peter De Schrijver Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-tegra210.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/clk/tegra/clk-tegra210.c') diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index ed3c7df75d1e..1be4d82d78cf 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -2215,9 +2215,9 @@ static struct div_nmp pllu_nmp = { }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 40, 1, 0, 0 }, - { 13000000, 480000000, 36, 1, 0, 0 }, /* actual: 468.0 MHz */ - { 38400000, 480000000, 25, 2, 0, 0 }, + { 12000000, 480000000, 40, 1, 1, 0 }, + { 13000000, 480000000, 36, 1, 1, 0 }, /* actual: 468.0 MHz */ + { 38400000, 480000000, 25, 2, 1, 0 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -3344,6 +3344,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, { TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 672000000, 1 }, + { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 }, { TEGRA210_CLK_XUSB_GATE, TEGRA210_CLK_CLK_MAX, 0, 1 }, { TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0 }, { TEGRA210_CLK_XUSB_FS_SRC, TEGRA210_CLK_PLL_U_48M, 48000000, 0 }, @@ -3368,7 +3369,6 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA210_CLK_PLL_DP, TEGRA210_CLK_CLK_MAX, 270000000, 0 }, { TEGRA210_CLK_SOC_THERM, TEGRA210_CLK_PLL_P, 51000000, 0 }, { TEGRA210_CLK_CCLK_G, TEGRA210_CLK_CLK_MAX, 0, 1 }, - { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 }, { TEGRA210_CLK_PLL_U_OUT2, TEGRA210_CLK_CLK_MAX, 60000000, 1 }, { TEGRA210_CLK_SPDIF_IN_SYNC, TEGRA210_CLK_CLK_MAX, 24576000, 0 }, { TEGRA210_CLK_I2S0_SYNC, TEGRA210_CLK_CLK_MAX, 24576000, 0 }, -- cgit v1.2.3 From 20675070127b51c6ca26a895c7e0b459f2c397e1 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Jun 2019 18:12:23 +0200 Subject: clk: tegra: Do not warn unnecessarily There is no need to warn if the reference PLL is enabled with the correct defaults. Only warn if the boot values don't match the defaults. Signed-off-by: Thierry Reding Acked-by: Jon Hunter Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-tegra210.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/clk/tegra/clk-tegra210.c') diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 1be4d82d78cf..51a21bf1715e 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -995,8 +995,6 @@ static void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre) pllre->params->defaults_set = true; if (val & PLL_ENABLE) { - pr_warn("PLL_RE already enabled. Postponing set full defaults\n"); - /* * PLL is ON: check if defaults already set, then set those * that can be updated in flight. @@ -1023,6 +1021,9 @@ static void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre) writel_relaxed(val, clk_base + pllre->params->ext_misc_reg[0]); udelay(1); + if (!pllre->params->defaults_set) + pr_warn("PLL_RE already enabled. Postponing set full defaults\n"); + return; } -- cgit v1.2.3 From c1139d20833f8882df608f456ce65b06cd1caa98 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Jun 2019 18:12:24 +0200 Subject: clk: tegra: Warn if an enabled PLL is in IDDQ A PLL in IDDQ doesn't work, whether it's enabled or not. This is not a configuration that makes sense, so warn about it. Signed-off-by: Thierry Reding Acked-by: Jon Hunter Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-tegra210.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/clk/tegra/clk-tegra210.c') diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 51a21bf1715e..18384666b380 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -1014,8 +1014,12 @@ static void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre) _pll_misc_chk_default(clk_base, pllre->params, 0, val, ~mask & PLLRE_MISC0_WRITE_MASK); - /* Enable lock detect */ + /* The PLL doesn't work if it's in IDDQ. */ val = readl_relaxed(clk_base + pllre->params->ext_misc_reg[0]); + if (val & PLLRE_MISC0_IDDQ) + pr_warn("unexpected IDDQ bit set for enabled clock\n"); + + /* Enable lock detect */ val &= ~mask; val |= PLLRE_MISC0_DEFAULT_VALUE & mask; writel_relaxed(val, clk_base + pllre->params->ext_misc_reg[0]); -- cgit v1.2.3 From e3527dca15c853daaacddc3f95461e8a02190114 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Jun 2019 18:12:25 +0200 Subject: clk: tegra: Do not enable PLL_RE_VCO on Tegra210 It turns out that this PLL is not used on Tegra210, so there's no need to enable it via the init table. Remove the init table entry for this PLL to avoid it getting enabled at boot time. If the bootloader enabled it and forgot to turn it off, the common clock framework will now know to disable it because it is unused. Signed-off-by: Thierry Reding Acked-by: Jon Hunter Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-tegra210.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/clk/tegra/clk-tegra210.c') diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 18384666b380..b474d3d7b1b6 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -3348,7 +3348,6 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, - { TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 672000000, 1 }, { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 }, { TEGRA210_CLK_XUSB_GATE, TEGRA210_CLK_CLK_MAX, 0, 1 }, { TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0 }, -- cgit v1.2.3