Patch "clk: ti: omap36xx: Work around sprz319 advisory 2.1" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
clk: ti: omap36xx: Work around sprz319 advisory 2.1
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
clk-ti-omap36xx-work-around-sprz319-advisory-2.1.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
035cd485a47dda64f25ccf8a90b11a07d0b7aa7aMon Sep 17 00:00:00 2001
From: Richard Watts <[email protected]>
Date: Fri, 2 Dec 2016 23:14:38 +0200
Subject: clk: ti: omap36xx: Work around sprz319 advisory 2.1
From: Richard Watts <[email protected]>
commit 035cd485a47dda64f25ccf8a90b11a07d0b7aa7a upstream.
The OMAP36xx DPLL5, driving EHCI USB, can be subject to a long-term frequency drift. The frequency drift magnitude depends on the VCO update rate, which is inversely proportional to the PLL divider. The kernel DPLL configuration code results in a high value for the divider, leading to a long term drift high enough to cause USB transmission errors. In the worst case the USB PHY's ULPI interface can stop responding, breaking USB operation completely. This manifests itself on the Beagleboard xM by the LAN9514 reporting 'Cannot enable port 2. Maybe the cable is bad?' in the kernel log.
Errata sprz319 advisory 2.1 documents PLL values that minimize the drift. Use them automatically when DPLL5 is used for USB operation, which we detect based on the requested clock rate. The clock framework will still compute the PLL parameters and resulting rate as usual, but the PLL M and N values will then be overridden. This can result in the effective clock rate being slightly different than the rate cached by the clock framework, but won't cause any adverse effect to USB operation.
--- drivers/clk/ti/clk-3xxx.c | 20 ++++++------- drivers/clk/ti/clock.h | 9 ++++++ drivers/clk/ti/dpll.c | 19 ++++++++++++- drivers/clk/ti/dpll3xxx.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 11 deletions(-)
drivers/clk/ti/clk-3xxx.c +10 -10
@@ -22,13 +22,6 @@#include "clock.h" -/* -* DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks -* that are sourced by DPLL5, and both of these require this clock -* to be at 120 MHz for proper operation. -*/ -#define DPLL5_FREQ_FOR_USBHOST 120000000 -#define OMAP3430ES2_ST_DSS_IDLE_SHIFT 1#define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT 5#define OMAP3430ES2_ST_SSI_IDLE_SHIFT 8
@@ -546,14 +539,21 @@ void __init omap3_clk_lock_dpll5(void)struct clk *dpll5_clk;struct clk *dpll5_m2_clk; +/* +* Errata sprz319f advisory 2.1 documents a USB host clock drift issue +* that can be worked around using specially crafted dpll5 settings +* with a dpll5_m2 divider set to 8. Set the dpll5 rate to 8x the USB +* host clock rate, its .set_rate handler() will detect that frequency +* and use the errata settings. +*/ dpll5_clk =clk_get (NULL ,"dpll5_ck" ); -clk_set_rate (dpll5_clk,DPLL5_FREQ_FOR_USBHOST ); +clk_set_rate (dpll5_clk,OMAP3_DPLL5_FREQ_FOR_USBHOST *8 );clk_prepare_enable (dpll5_clk); -/* Program dpll5_m2_clk divider for no division */ +/* Program dpll5_m2_clk divider */ dpll5_m2_clk =clk_get (NULL ,"dpll5_m2_ck" );clk_prepare_enable (dpll5_m2_clk); -clk_set_rate (dpll5_m2_clk,DPLL5_FREQ_FOR_USBHOST ); +clk_set_rate (dpll5_m2_clk,OMAP3_DPLL5_FREQ_FOR_USBHOST );clk_disable_unprepare (dpll5_m2_clk);clk_disable_unprepare (dpll5_clk);
drivers/clk/ti/clock.h +9 -0
@@ -257,11 +257,20 @@ long omap2_dpll_round_rate(struct clk_hwunsigned long omap3_clkoutx2_recalc (struct clk_hw *hw,unsigned long parent_rate); +/* +* OMAP3_DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks +* that are sourced by DPLL5, and both of these require this clock +* to be at 120 MHz for proper operation. +*/ +#define OMAP3_DPLL5_FREQ_FOR_USBHOST 120000000 +unsigned long omap3_dpll_recalc (struct clk_hw *hw,unsigned long parent_rate);int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate);int omap3_dpll4_set_rate_and_parent (struct clk_hw *hw,unsigned long rate,unsigned long parent_rate,u8 index); +int omap3_dpll5_set_rate (struct clk_hw *hw,unsigned long rate, +unsigned long parent_rate);void omap3_clk_lock_dpll5 (void ); unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
drivers/clk/ti/dpll.c +18 -1
@@ -114,6 +114,18 @@ static const struct clk_ops omap3_dpll_c .round_rate = &omap2_dpll_round_rate, }; +static const struct clk_ops omap3_dpll5_ck_ops = { + .enable = &omap3_noncore_dpll_enable, + .disable = &omap3_noncore_dpll_disable, + .get_parent = &omap2_init_dpll_parent, + .recalc_rate = &omap3_dpll_recalc, + .set_rate = &omap3_dpll5_set_rate, + .set_parent = &omap3_noncore_dpll_set_parent, + .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, + .determine_rate = &omap3_noncore_dpll_determine_rate, + .round_rate = &omap2_dpll_round_rate, +}; +static const struct clk_ops omap3_dpll_per_ck_ops = { .enable = &omap3_noncore_dpll_enable, .disable = &omap3_noncore_dpll_disable,
@@ -461,7 +473,12 @@ static void __init of_ti_omap3_dpll_setu .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), }; -of_ti_dpll_setup (node, &omap3_dpll_ck_ops, &dd); +if ((of_machine_is_compatible ("ti,omap3630" ) || +of_machine_is_compatible ("ti,omap36xx" )) && + !strcmp (node->name,"dpll5_ck" )) +of_ti_dpll_setup (node, &omap3_dpll5_ck_ops, &dd); +else +of_ti_dpll_setup (node, &omap3_dpll_ck_ops, &dd); }CLK_OF_DECLARE (ti_omap3_dpll_clock,"ti,omap3-dpll-clock" , of_ti_omap3_dpll_setup);
drivers/clk/ti/dpll3xxx.c +67 -0
70 lines not on this page · raw message
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/clk-ti-omap36xx-work-around-sprz319-advisory-2.1.patch