From patchwork Thu Apr 25 08:41:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Cheng X-Patchwork-Id: 10916301 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 614261515 for ; Thu, 25 Apr 2019 08:42:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4BAF228BD0 for ; Thu, 25 Apr 2019 08:42:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D04C28C2E; Thu, 25 Apr 2019 08:42:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B3ADA28BD0 for ; Thu, 25 Apr 2019 08:42:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=koQBefvQxvLGtSVtUDTAUNCvu/mWxXTRyzRYyalHNP8=; b=VN7H9nOVn9MDjI 6goJBWv33YJiV6m26zIkWnz5GvKodEqRthj6FBSXg28ADnHym2kQFQcpTm7P3+sfb8S9R8G+Mv+AU 5Je+tII7ko9GbFcljlwZT2xlQ6T3uGxgpgqnuDpfRAcV+Xp8K9DbEeisMWBfiwHDZOOd3mV9SyYMg AbAk0wWTl2LTgDNVFs3EP+V0hrnkMruSgBulsAvVmWUANKTQ4ZBWIjdqBP1ptxBXfFBi43NiJZbKd gB6P8iQFRTiNikKRKl0FAoKv+HQZyz+TsJSfZ1oUdMHi2faPi2keO4KrawFcoG7euVHRje5dklqsF 6Y6Df2GAOikvX3jNqlPQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hJZxI-00019G-5T; Thu, 25 Apr 2019 08:42:08 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hJZwz-0000l3-If; Thu, 25 Apr 2019 08:41:50 +0000 X-UUID: fcdb705127ab452cb90b8715292c7016-20190425 X-UUID: fcdb705127ab452cb90b8715292c7016-20190425 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 430294238; Thu, 25 Apr 2019 00:41:44 -0800 Received: from mtkmbs03n2.mediatek.inc (172.21.101.182) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Thu, 25 Apr 2019 01:41:43 -0700 Received: from mtkcas09.mediatek.inc (172.21.101.178) by mtkmbs03n2.mediatek.inc (172.21.101.182) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Thu, 25 Apr 2019 16:41:36 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas09.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Thu, 25 Apr 2019 16:41:35 +0800 From: Long Cheng To: Greg Kroah-Hartman Subject: [PATCH 2/2] serial: 8250-mtk: modify baudrate setting Date: Thu, 25 Apr 2019 16:41:31 +0800 Message-ID: <1556181691-10293-3-git-send-email-long.cheng@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1556181691-10293-1-git-send-email-long.cheng@mediatek.com> References: <1556181691-10293-1-git-send-email-long.cheng@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: 9BCFE159B135E749B2F86214D9E511DAB2E50153D76EBD17E8A61F441291CCAB2000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190425_014149_617580_6D9CA7C1 X-CRM114-Status: GOOD ( 11.04 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Zhenbao Liu , Peter Shih , srv_heupstream@mediatek.com, "Gustavo A. R. Silva" , Changqi Hu , linux-kernel@vger.kernel.org, Long Cheng , linux-mediatek@lists.infradead.org, linux-serial@vger.kernel.org, Jiri Slaby , Matthias Brugger , Yingjoe Chen , linux-arm-kernel@lists.infradead.org Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP In termios function, add Fractional divider to adjust baudrate. Signed-off-by: Long Cheng --- drivers/tty/serial/8250/8250_mtk.c | 102 ++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 959fd85..417c7c8 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -25,13 +25,28 @@ #define MTK_UART_SAMPLE_COUNT 0x0a /* Sample count register */ #define MTK_UART_SAMPLE_POINT 0x0b /* Sample point register */ #define MTK_UART_RATE_FIX 0x0d /* UART Rate Fix Register */ +#define MTK_UART_ESCAPE_DAT 0x10 /* Escape Character register */ +#define MTK_UART_ESCAPE_EN 0x11 /* Escape Enable register */ #define MTK_UART_DMA_EN 0x13 /* DMA Enable register */ #define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */ #define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */ #define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */ +#define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */ +#define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ +#define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ + +#define MTK_UART_EFR_EN 0x10 /* Enable enhancement feature */ +#define MTK_UART_EFR_RTS 0x40 /* Enable hardware rx flow control */ +#define MTK_UART_EFR_CTS 0x80 /* Enable hardware tx flow control */ +#define MTK_UART_EFR_NO_SW_FC 0x0 /* no sw flow control */ +#define MTK_UART_EFR_XON1_XOFF1 0xa /* XON1/XOFF1 as sw flow control */ +#define MTK_UART_EFR_XON2_XOFF2 0x5 /* XON2/XOFF2 as sw flow control */ +#define MTK_UART_EFR_SW_FC_MASK 0xf /* Enable CTS Modem status interrupt */ +#define MTK_UART_EFR_HW_FC (MTK_UART_EFR_RTS | MTK_UART_EFR_CTS) #define MTK_UART_DMA_EN_TX 0x2 #define MTK_UART_DMA_EN_RX 0x5 +#define MTK_UART_ESCAPE_CHAR 0x77 /* Escape char added under sw fc */ #define MTK_UART_TX_SIZE UART_XMIT_SIZE #define MTK_UART_RX_SIZE 0x8000 #define MTK_UART_TX_TRIGGER 1 @@ -57,6 +72,13 @@ struct mtk8250_data { #endif }; +/* flow control mode */ +enum { + MTK_UART_FC_NONE, + MTK_UART_FC_SW, + MTK_UART_FC_HW, +}; + #ifdef CONFIG_SERIAL_8250_DMA static void mtk8250_rx_dma(struct uart_8250_port *up); @@ -195,6 +217,75 @@ static void mtk8250_shutdown(struct uart_port *port) return serial8250_do_shutdown(port); } +static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask) +{ + serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask)); +} + +static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask) +{ + serial_out(up, UART_IER, serial_in(up, UART_IER) | mask); +} + +static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode) +{ + struct uart_port *port = &up->port; + int lcr = serial_in(up, UART_LCR); + + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_EFR, UART_EFR_ECB); + serial_out(up, UART_LCR, lcr); + lcr = serial_in(up, UART_LCR); + + switch (mode) { + case MTK_UART_FC_NONE: + serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR); + serial_out(up, MTK_UART_ESCAPE_EN, 0x00); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_EFR, serial_in(up, UART_EFR) & + (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))); + serial_out(up, UART_LCR, lcr); + mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI | + MTK_UART_IER_RTSI | MTK_UART_IER_CTSI); + break; + + case MTK_UART_FC_HW: + serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR); + serial_out(up, MTK_UART_ESCAPE_EN, 0x00); + serial_out(up, UART_MCR, UART_MCR_RTS); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + + /*enable hw flow control*/ + serial_out(up, UART_EFR, MTK_UART_EFR_HW_FC | + (serial_in(up, UART_EFR) & + (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)))); + + serial_out(up, UART_LCR, lcr); + mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI); + mtk8250_enable_intrs(up, MTK_UART_IER_CTSI | MTK_UART_IER_RTSI); + break; + + case MTK_UART_FC_SW: /*MTK software flow control */ + serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR); + serial_out(up, MTK_UART_ESCAPE_EN, 0x01); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + + /*enable sw flow control */ + serial_out(up, UART_EFR, MTK_UART_EFR_XON1_XOFF1 | + (serial_in(up, UART_EFR) & + (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)))); + + serial_out(up, UART_XON1, START_CHAR(port->state->port.tty)); + serial_out(up, UART_XOFF1, STOP_CHAR(port->state->port.tty)); + serial_out(up, UART_LCR, lcr); + mtk8250_disable_intrs(up, MTK_UART_IER_CTSI|MTK_UART_IER_RTSI); + mtk8250_enable_intrs(up, MTK_UART_IER_XOFFI); + break; + default: + break; + } +} + static void mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) @@ -208,6 +299,7 @@ static void mtk8250_shutdown(struct uart_port *port) struct uart_8250_port *up = up_to_u8250p(port); unsigned int baud, quot, fraction; unsigned long flags; + int mode; #ifdef CONFIG_SERIAL_8250_DMA if (up->dma) { @@ -281,6 +373,16 @@ static void mtk8250_shutdown(struct uart_port *port) serial_port_out(port, MTK_UART_FRACDIV_L, 0x00); serial_port_out(port, MTK_UART_FRACDIV_M, 0x00); } + + if ((termios->c_cflag & CRTSCTS) && (!(termios->c_iflag & CRTSCTS))) + mode = MTK_UART_FC_HW; + else if (termios->c_iflag & CRTSCTS) + mode = MTK_UART_FC_SW; + else + mode = MTK_UART_FC_NONE; + + mtk8250_set_flow_ctrl(up, mode); + if (uart_console(port)) up->port.cons->cflag = termios->c_cflag;