From patchwork Wed Sep 26 15:21:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 11737 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 4CCBF24140 for ; Wed, 26 Sep 2012 15:22:03 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id C4A34A18049 for ; Wed, 26 Sep 2012 15:22:02 +0000 (UTC) Received: by ieje10 with SMTP id e10so1646349iej.11 for ; Wed, 26 Sep 2012 08:22:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :x-gm-message-state; bh=NKSwtYEypSnTWnd/MdvoxsARqixvlDcqxbASC0n3IpI=; b=Nax+T+TJXyj+hvRd7tuRc2aU77D5X1fV1RKMJlkcY/NUXGyhDFshJU4gm1DSNqENji Gre94MgVHTv5JGyvGWOVk+vrhbu4aKrfYjrdnx8WH++uColpuMhVcByP+zv3KExgDo/b r1LICtTZD/g+0EhTfc8nY5mIl9Y9gS3HFGjZc4EIJuzkwLX4BSijBwZ6tHfQ6OYvrAkI BW0b/rV034hl5gwatuOtyVvwyU8EmLn+EdZ6TdLLGtrGnbQ3cUsmyOv8HlEZO5WIhOUS OveaGib11esEAG+N9ZQeRGrk1G1SZzBYekOTexJRs/W4t0PycwOI85oNvEkcpIu59YVd 7Ymg== Received: by 10.50.184.129 with SMTP id eu1mr855536igc.0.1348672921537; Wed, 26 Sep 2012 08:22:01 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp361895igc; Wed, 26 Sep 2012 08:22:00 -0700 (PDT) Received: by 10.14.4.201 with SMTP id 49mr1964855eej.0.1348672918127; Wed, 26 Sep 2012 08:21:58 -0700 (PDT) Received: from eu1sys200aog103.obsmtp.com (eu1sys200aog103.obsmtp.com [207.126.144.115]) by mx.google.com with SMTP id y1si3038170eep.138.2012.09.26.08.21.49 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 26 Sep 2012 08:21:58 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.115 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.115; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.115 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob103.postini.com ([207.126.147.11]) with SMTP ID DSNKUGMdi5/SLpS+It/x3c45K1Nt7cW2e0sJ@postini.com; Wed, 26 Sep 2012 15:21:57 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 0DAABAC; Wed, 26 Sep 2012 15:13:28 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 40C95A66; Wed, 26 Sep 2012 15:21:43 +0000 (GMT) Received: from exdcvycastm004.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm004", Issuer "exdcvycastm004" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id 3E09EA8074; Wed, 26 Sep 2012 17:21:36 +0200 (CEST) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.2) with Microsoft SMTP Server (TLS) id 8.3.83.0; Wed, 26 Sep 2012 17:21:42 +0200 From: Linus Walleij To: , Greg Kroah-Hartman Cc: , Anmar Oueja , Linus Walleij , , Bibek Basu , Par-Gunnar Hjalmdahl , Guillaume Jaunet , Christophe Arnal , Matthias Locher , Rajanikanth HV Subject: [PATCH v3] serial: pl011: handle corruption at high clock speeds Date: Wed, 26 Sep 2012 17:21:36 +0200 Message-ID: <1348672896-6005-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.11.3 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQlV4cjUfTqx4Ox0zDRbaDw6oVMVeE248DUt92UPymSnHUJg0N8p9f1hw8Jlgk0r7CXdiEo1 From: Linus Walleij This works around a few glitches in the ST version of the PL011 serial driver when using very high baud rates, as we do in the Ux500: 3, 3.25, 4 and 4.05 Mbps. Problem Observed/rootcause: When using high baud-rates, and the baudrate*8 is getting close to the provided clock frequency (so a division factor close to 1), when using bursts of characters (so they are abutted), then it seems as if there is not enough time to detect the beginning of the start-bit which is a timing reference for the entire character, and thus the sampling moment of character bits is moving towards the end of each bit, instead of the middle. Fix: Increase slightly the RX baud rate of the UART above the theoretical baudrate by 5%. This will definitely give more margin time to the UART_RX to correctly sample the data at the middle of the bit period. Also fix the ages old copy-paste error in the very stressed comment, it's referencing the registers used in the PL010 driver rather than the PL011 ones. Cc: stable@kernel.org Cc: Bibek Basu Cc: Par-Gunnar Hjalmdahl Signed-off-by: Guillaume Jaunet Signed-off-by: Christophe Arnal Signed-off-by: Matthias Locher Signed-off-by: Rajanikanth HV Signed-off-by: Linus Walleij --- ChangeLog v2->v3: - Actually commit the v2 changes... ChangeLog v1->v2: - Use >= comparison for 3 Mbaud, add some parenthesis to make the logical expressions crystal clear. --- drivers/tty/serial/amba-pl011.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d626d84..25508c7 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1594,13 +1594,26 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, old_cr &= ~ST_UART011_CR_OVSFACT; } + /* + * Workaround for the ST Micro oversampling variants to + * increase the bitrate slightly, by lowering the divisor, + * to avoid delayed sampling of start bit at high speeds, + * else we see data corruption. + */ + if (uap->vendor->oversampling) { + if ((baud >= 3000000) && (baud < 3250000) && (quot > 1)) + quot -= 1; + else if ((baud > 3250000) && (quot > 2)) + quot -= 2; + } /* Set baud rate */ writew(quot & 0x3f, port->membase + UART011_FBRD); writew(quot >> 6, port->membase + UART011_IBRD); /* * ----------v----------v----------v----------v----- - * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L + * NOTE: lcrh_tx and lcrh_rx MUST BE WRITTEN AFTER + * UART011_FBRD & UART011_IBRD. * ----------^----------^----------^----------^----- */ writew(lcr_h, port->membase + uap->lcrh_rx);