stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Richard Watts <rrw@kynesim.co.uk>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	Ladislav Michl <ladis@linux-mips.org>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Adam Ford <aford173@gmail.com>
Subject: [PATCH 4.4 20/60] clk: ti: omap36xx: Work around sprz319 advisory 2.1
Date: Wed,  4 Jan 2017 21:47:05 +0100	[thread overview]
Message-ID: <20170104200706.635137131@linuxfoundation.org> (raw)
In-Reply-To: <20170104200705.627445996@linuxfoundation.org>

4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Richard Watts <rrw@kynesim.co.uk>

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.

Signed-off-by: Richard Watts <rrw@kynesim.co.uk>
[Upported from v3.2 to v4.9]
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: Adam Ford <aford173@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 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(-)

--- a/drivers/clk/ti/clk-3xxx.c
+++ b/drivers/clk/ti/clk-3xxx.c
@@ -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);
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -257,11 +257,20 @@ long omap2_dpll_round_rate(struct clk_hw
 unsigned 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,
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -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);
--- a/drivers/clk/ti/dpll3xxx.c
+++ b/drivers/clk/ti/dpll3xxx.c
@@ -815,3 +815,70 @@ int omap3_dpll4_set_rate_and_parent(stru
 	return omap3_noncore_dpll_set_rate_and_parent(hw, rate, parent_rate,
 						      index);
 }
+
+/* Apply DM3730 errata sprz319 advisory 2.1. */
+static bool omap3_dpll5_apply_errata(struct clk_hw *hw,
+				     unsigned long parent_rate)
+{
+	struct omap3_dpll5_settings {
+		unsigned int rate, m, n;
+	};
+
+	static const struct omap3_dpll5_settings precomputed[] = {
+		/*
+		 * From DM3730 errata advisory 2.1, table 35 and 36.
+		 * The N value is increased by 1 compared to the tables as the
+		 * errata lists register values while last_rounded_field is the
+		 * real divider value.
+		 */
+		{ 12000000,  80,  0 + 1 },
+		{ 13000000, 443,  5 + 1 },
+		{ 19200000,  50,  0 + 1 },
+		{ 26000000, 443, 11 + 1 },
+		{ 38400000,  25,  0 + 1 }
+	};
+
+	const struct omap3_dpll5_settings *d;
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct dpll_data *dd;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(precomputed); ++i) {
+		if (parent_rate == precomputed[i].rate)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(precomputed))
+		return false;
+
+	d = &precomputed[i];
+
+	/* Update the M, N and rounded rate values and program the DPLL. */
+	dd = clk->dpll_data;
+	dd->last_rounded_m = d->m;
+	dd->last_rounded_n = d->n;
+	dd->last_rounded_rate = div_u64((u64)parent_rate * d->m, d->n);
+	omap3_noncore_dpll_program(clk, 0);
+
+	return true;
+}
+
+/**
+ * omap3_dpll5_set_rate - set rate for omap3 dpll5
+ * @hw: clock to change
+ * @rate: target rate for clock
+ * @parent_rate: rate of the parent clock
+ *
+ * Set rate for the DPLL5 clock. Apply the sprz319 advisory 2.1 on OMAP36xx if
+ * the DPLL is used for USB host (detected through the requested rate).
+ */
+int omap3_dpll5_set_rate(struct clk_hw *hw, unsigned long rate,
+			 unsigned long parent_rate)
+{
+	if (rate == OMAP3_DPLL5_FREQ_FOR_USBHOST * 8) {
+		if (omap3_dpll5_apply_errata(hw, parent_rate))
+			return 0;
+	}
+
+	return omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
+}



  parent reply	other threads:[~2017-01-04 20:49 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20170104205105epcas5p4dfb9f8f2e2771bc19858b096e326c051@epcas5p4.samsung.com>
2017-01-04 20:46 ` [PATCH 4.4 00/60] 4.4.40-stable review Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 01/60] btrfs: limit async_work allocation and worker func duration Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 02/60] Btrfs: fix tree search logic when replaying directory entry deletes Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 03/60] btrfs: store and load values of stripes_min/stripes_max in balance status item Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 04/60] Btrfs: fix qgroup rescan worker initialization Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 05/60] USB: serial: option: add support for Telit LE922A PIDs 0x1040, 0x1041 Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 06/60] USB: serial: option: add dlink dwm-158 Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 07/60] USB: serial: kl5kusb105: fix open error path Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 08/60] USB: cdc-acm: add device id for GW Instek AFG-125 Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 09/60] usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 10/60] usb: gadget: f_uac2: fix error handling at afunc_bind Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 11/60] usb: gadget: composite: correctly initialize ep->maxpacket Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 12/60] USB: UHCI: report non-PME wakeup signalling for Intel hardware Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 13/60] ALSA: usb-audio: Add QuickCam Communicate Deluxe/S7500 to volume_control_quirks Greg Kroah-Hartman
2017-01-04 20:46   ` [PATCH 4.4 14/60] ALSA: hiface: Fix M2Tech hiFace driver sampling rate change Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 15/60] ALSA: hda/ca0132 - Add quirk for Alienware 15 R2 2016 Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 16/60] ALSA: hda - ignore the assoc and seq when comparing pin configurations Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 17/60] ALSA: hda - fix headset-mic problem on a Dell laptop Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 18/60] ALSA: hda - Gate the mic jack on HP Z1 Gen3 AiO Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 19/60] ALSA: hda: when comparing pin configurations, ignore assoc in addition to seq Greg Kroah-Hartman
2017-01-04 20:47   ` Greg Kroah-Hartman [this message]
2017-01-04 20:47   ` [PATCH 4.4 21/60] Btrfs: fix memory leak in reading btree blocks Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 22/60] Btrfs: bail out if block group has different mixed flag Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 23/60] Btrfs: return gracefully from balance if fs tree is corrupted Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 24/60] Btrfs: dont leak reloc root nodes on error Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 25/60] Btrfs: fix memory leak in do_walk_down Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 26/60] Btrfs: dont BUG() during drop snapshot Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 27/60] btrfs: make file clone aware of fatal signals Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 28/60] block_dev: dont test bdev->bd_contains when it is not stable Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 29/60] mm: Add a user_ns owner to mm_struct and fix ptrace permission checks Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 30/60] ptrace: Capture the ptracers creds not PT_PTRACE_CAP Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 32/60] ext4: fix mballoc breakage with 64k block size Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 33/60] ext4: fix stack memory corruption " Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 34/60] ext4: use more strict checks for inodes_per_block on mount Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 35/60] ext4: fix in-superblock mount options processing Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 36/60] ext4: add sanity checking to count_overhead() Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 37/60] ext4: reject inodes with negative size Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 38/60] ext4: return -ENOMEM instead of success Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 39/60] ext4: do not perform data journaling when data is encrypted Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 40/60] f2fs: set ->owner for debugfs status files file_operations Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 41/60] loop: return proper error from loop_queue_rq() Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 42/60] mm/vmscan.c: set correct defer count for shrinker Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 43/60] fs: exec: apply CLOEXEC before changing dumpable task flags Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 44/60] exec: Ensure mm->user_ns contains the execed files Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 45/60] usb: gadget: composite: always set ep->mult to a sensible value Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 46/60] blk-mq: Do not invoke .queue_rq() for a stopped queue Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 47/60] dm flakey: return -EINVAL on interval bounds error in flakey_ctr() Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 48/60] dm crypt: mark key as invalid until properly loaded Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 49/60] dm space map metadata: fix struct sm_metadata leak on failed create Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 50/60] ASoC: intel: Fix crash at suspend/resume without card registration Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 51/60] CIFS: Fix a possible memory corruption during reconnect Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 52/60] CIFS: Fix missing nls unload in smb2_reconnect() Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 53/60] CIFS: Fix a possible memory corruption in push locks Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 54/60] kernel/watchdog: use nmi registers snapshot in hardlockup handler Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 55/60] kernel/debug/debug_core.c: more properly delay for secondary CPUs Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 56/60] tpm xen: Remove bogus tpm_chip_unregister Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 57/60] xen/gntdev: Use VM_MIXEDMAP instead of VM_IO to avoid NUMA balancing Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 58/60] arm/xen: Use alloc_percpu rather than __alloc_percpu Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 59/60] xfs: set AGI buffer type in xlog_recover_clear_agi_bucket Greg Kroah-Hartman
2017-01-04 20:47   ` [PATCH 4.4 60/60] driver core: fix race between creating/querying glue dir and its cleanup Greg Kroah-Hartman
2017-01-05  0:42   ` [PATCH 4.4 00/60] 4.4.40-stable review Shuah Khan
2017-01-05  5:25   ` Guenter Roeck
2017-01-05 15:33   ` Guillaume Nault
2017-01-05 20:35     ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170104200706.635137131@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=aford173@gmail.com \
    --cc=ladis@linux-mips.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rrw@kynesim.co.uk \
    --cc=sboyd@codeaurora.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).