From patchwork Fri Jan 12 09:52:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 762442 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16F9F5DF3A; Fri, 12 Jan 2024 09:53:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="c9C3su9q" Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40C8bRbX014643; Fri, 12 Jan 2024 10:53:24 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=MZ2yC/2e1I4xidBJg4kSl8TM52bi1bQR+pbYIgCU74I=; b=c9 C3su9qwUns9Om7PEG5p0j01D37iXNkrQnfJi7cdsqh9JEpWt3Y+HXn9VbSU6hzKK NeFLnJTbuABMcStI72AUVgB/4zGEOXBBYuHg9wJTs8UrSMCFboPk42PC8vwf/zbe 5rKdXn2rdI7WSI2n9w2NRNBp2mP7KF8EWgaw8vlJvzkXq0INpipTWsUG/FabwCNW RK0d3M9Px74lb8Yjf9OmZEX699DvISBjDCkBva2TRp1WFt/egevapgqJFDXwmPAs DIQCcpEo9VPkEivZFn9cg9IwHoxffCEGaFzIX9TVsVCsTdevzWj/2MKBW5zeiBvG x0g33wQrK6mUOXuawSDg== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3vk22w8bhu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 12 Jan 2024 10:53:24 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 423DE10004D; Fri, 12 Jan 2024 10:53:24 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 3B0E8208D4E; Fri, 12 Jan 2024 10:53:24 +0100 (CET) Received: from localhost (10.201.21.102) by SHFDAG1NODE1.st.com (10.75.129.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 12 Jan 2024 10:53:23 +0100 From: Valentin Caron To: Greg Kroah-Hartman , Jiri Slaby CC: Alexandre Torgue , , , , , Valentin Caron Subject: [PATCH v2 1/4] serial: stm32: implement prescaler tuning to compute low baudrate Date: Fri, 12 Jan 2024 10:52:57 +0100 Message-ID: <20240112095300.2004878-2-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240112095300.2004878-1-valentin.caron@foss.st.com> References: <20240112095300.2004878-1-valentin.caron@foss.st.com> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: EQNCAS1NODE4.st.com (10.75.129.82) To SHFDAG1NODE1.st.com (10.75.129.69) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-01-05_08,2024-01-05_01,2023-05-22_02 In the case of high USART input clock and low baud rate, BRR value is not enough to get correct baud rate. So here we use USART prescaler to divide USART input clock to get the correct baud rate. PRESC register is only available since stm32h7. Signed-off-by: Valentin Caron --- drivers/tty/serial/stm32-usart.c | 71 ++++++++++++++++++++++---------- drivers/tty/serial/stm32-usart.h | 6 +++ 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 794b77512740..19a45e1b7102 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -9,6 +9,7 @@ * Inspired by st-asc.c from STMicroelectronics (c) */ +#include #include #include #include @@ -50,6 +51,7 @@ static struct stm32_usart_info __maybe_unused stm32f4_info = { .rtor = UNDEF_REG, .rqr = UNDEF_REG, .icr = UNDEF_REG, + .presc = UNDEF_REG, }, .cfg = { .uart_enable_bit = 13, @@ -71,6 +73,7 @@ static struct stm32_usart_info __maybe_unused stm32f7_info = { .icr = 0x20, .rdr = 0x24, .tdr = 0x28, + .presc = UNDEF_REG, }, .cfg = { .uart_enable_bit = 0, @@ -93,6 +96,7 @@ static struct stm32_usart_info __maybe_unused stm32h7_info = { .icr = 0x20, .rdr = 0x24, .tdr = 0x28, + .presc = 0x2c, }, .cfg = { .uart_enable_bit = 0, @@ -1145,6 +1149,8 @@ static void stm32_usart_shutdown(struct uart_port *port) free_irq(port->irq, port); } +static const unsigned int stm32_usart_presc_val[] = {1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256}; + static void stm32_usart_set_termios(struct uart_port *port, struct ktermios *termios, const struct ktermios *old) @@ -1153,17 +1159,19 @@ static void stm32_usart_set_termios(struct uart_port *port, const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; const struct stm32_usart_config *cfg = &stm32_port->info->cfg; struct serial_rs485 *rs485conf = &port->rs485; - unsigned int baud, bits; + unsigned int baud, bits, uart_clk, uart_clk_pres; u32 usartdiv, mantissa, fraction, oversampling; tcflag_t cflag = termios->c_cflag; - u32 cr1, cr2, cr3, isr; + u32 cr1, cr2, cr3, isr, brr, presc; unsigned long flags; int ret; if (!stm32_port->hw_flow_control) cflag &= ~CRTSCTS; - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 8); + uart_clk = clk_get_rate(stm32_port->clk); + + baud = uart_get_baud_rate(port, termios, old, 0, uart_clk / 8); uart_port_lock_irqsave(port, &flags); @@ -1265,27 +1273,48 @@ static void stm32_usart_set_termios(struct uart_port *port, cr3 |= USART_CR3_CTSE | USART_CR3_RTSE; } - usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud); + for (presc = 0; presc <= USART_PRESC_MAX; presc++) { + uart_clk_pres = DIV_ROUND_CLOSEST(uart_clk, stm32_usart_presc_val[presc]); + usartdiv = DIV_ROUND_CLOSEST(uart_clk_pres, baud); - /* - * The USART supports 16 or 8 times oversampling. - * By default we prefer 16 times oversampling, so that the receiver - * has a better tolerance to clock deviations. - * 8 times oversampling is only used to achieve higher speeds. - */ - if (usartdiv < 16) { - oversampling = 8; - cr1 |= USART_CR1_OVER8; - stm32_usart_set_bits(port, ofs->cr1, USART_CR1_OVER8); - } else { - oversampling = 16; - cr1 &= ~USART_CR1_OVER8; - stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_OVER8); + /* + * The USART supports 16 or 8 times oversampling. + * By default we prefer 16 times oversampling, so that the receiver + * has a better tolerance to clock deviations. + * 8 times oversampling is only used to achieve higher speeds. + */ + if (usartdiv < 16) { + oversampling = 8; + cr1 |= USART_CR1_OVER8; + stm32_usart_set_bits(port, ofs->cr1, USART_CR1_OVER8); + } else { + oversampling = 16; + cr1 &= ~USART_CR1_OVER8; + stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_OVER8); + } + + mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT; + fraction = usartdiv % oversampling; + brr = mantissa | fraction; + + if (FIELD_FIT(USART_BRR_MASK, brr)) { + if (ofs->presc != UNDEF_REG) { + port->uartclk = uart_clk_pres; + writel_relaxed(presc, port->membase + ofs->presc); + } else if (presc) { + /* We need a prescaler but we don't have it (STM32F4, STM32F7) */ + dev_err(port->dev, + "unable to set baudrate, input clock is too high"); + } + break; + } else if (presc == USART_PRESC_MAX) { + /* Even with prescaler and brr at max value we can't set baudrate */ + dev_err(port->dev, "unable to set baudrate, input clock is too high"); + break; + } } - mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT; - fraction = usartdiv % oversampling; - writel_relaxed(mantissa | fraction, port->membase + ofs->brr); + writel_relaxed(brr, port->membase + ofs->brr); uart_update_timeout(port, cflag, baud); diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index f59f831b2a10..8cecfdce9386 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -20,6 +20,7 @@ struct stm32_usart_offsets { u8 icr; u8 rdr; u8 tdr; + u8 presc; }; struct stm32_usart_config { @@ -71,6 +72,7 @@ struct stm32_usart_info { #define USART_BRR_DIV_M_MASK GENMASK(15, 4) #define USART_BRR_DIV_M_SHIFT 4 #define USART_BRR_04_R_SHIFT 1 +#define USART_BRR_MASK (USART_BRR_DIV_M_MASK | USART_BRR_DIV_F_MASK) /* USART_CR1 */ #define USART_CR1_SBK BIT(0) @@ -176,6 +178,10 @@ struct stm32_usart_info { #define USART_ICR_CMCF BIT(17) /* F7 */ #define USART_ICR_WUCF BIT(20) /* H7 */ +/* USART_PRESC */ +#define USART_PRESC GENMASK(3, 0) /* H7 */ +#define USART_PRESC_MAX 0b1011 + #define STM32_SERIAL_NAME "ttySTM" #define STM32_MAX_PORTS 8 From patchwork Fri Jan 12 09:52:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 762641 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16F565DF39; Fri, 12 Jan 2024 09:53:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="UDpBVYMj" Received: from pps.filterd (m0369458.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40C8bCIZ006983; Fri, 12 Jan 2024 10:53:25 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=BPsKvGwCvtumO70J1qmyLApJgoRqO+4A21EFeihpSLQ=; b=UD pBVYMjDjnJNjr1QLk+RLRTvjibKIvdCLuilnRkyyJgm3Gi/laODH+O4E1JUI5yaG gQHjiwnHxh/9hHiKmX8gbrH5K4ma785VRVyx9ZjQGrApkAti0jW5dtdsB4dwRUoc APAdygVQYZGIoLo3i6jmR2coDidTUzcMytJRFmZPEAfRqdVzpF1sZCuav4FNB6Mv poEnr8Fv8UfCPRJjFDEUyqbVZ2YBfGUj7f/QZw7XkdKZjmKkzYuuAkfTZJQQcbO6 vqwB0IjhM9pAdxPyCHEemd+dmbnmYo8/vR5P9Vm7lq6R4O1O8eKw5v6h40899S9z yp/uSxoA+CjRQZ7OXkdg== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3vk22u0bk5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 12 Jan 2024 10:53:25 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 21C7A10004F; Fri, 12 Jan 2024 10:53:25 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 1AF58208D4E; Fri, 12 Jan 2024 10:53:25 +0100 (CET) Received: from localhost (10.201.21.102) by SHFDAG1NODE1.st.com (10.75.129.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 12 Jan 2024 10:53:24 +0100 From: Valentin Caron To: Greg Kroah-Hartman , Jiri Slaby CC: Alexandre Torgue , , , , , Valentin Caron Subject: [PATCH v2 2/4] serial: stm32: extend max number of U(S)ART to 9 Date: Fri, 12 Jan 2024 10:52:58 +0100 Message-ID: <20240112095300.2004878-3-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240112095300.2004878-1-valentin.caron@foss.st.com> References: <20240112095300.2004878-1-valentin.caron@foss.st.com> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: EQNCAS1NODE4.st.com (10.75.129.82) To SHFDAG1NODE1.st.com (10.75.129.69) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-01-05_08,2024-01-05_01,2023-05-22_02 STM32MP25x got 9 instances of U(S)ART. So extend STM32_MAX_PORTS to 9, in order to handle all instances. Signed-off-by: Valentin Caron --- drivers/tty/serial/stm32-usart.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index 8cecfdce9386..5ce1d3aae07e 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -183,7 +183,7 @@ struct stm32_usart_info { #define USART_PRESC_MAX 0b1011 #define STM32_SERIAL_NAME "ttySTM" -#define STM32_MAX_PORTS 8 +#define STM32_MAX_PORTS 9 #define RX_BUF_L 4096 /* dma rx buffer length */ #define RX_BUF_P (RX_BUF_L / 2) /* dma rx buffer period */ From patchwork Fri Jan 12 09:52:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 762443 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0893E5DF11; Fri, 12 Jan 2024 09:53:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="2IghlVbA" Received: from pps.filterd (m0288072.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40C8bGNe014416; Fri, 12 Jan 2024 10:53:26 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=gqYDRY1M+y29PGSIorc/WBQGH1vOYxwvtXDzkuKQQrM=; b=2I ghlVbAGkQnYxvdLj3nwjl223nZpmpUyAmAVjWD8c2b3yReNr+tXxIoe94+zATJcq kpqfh7sCPaihTweYHUe4/wWRxgy6Io7xkEzSds5Z6pJC274SN0cZCDUmj9dA4XX+ V0h+6QTLhvF1Kicvujws4oZafG6I1ssIou+Q0DfjSX6zwD0Ag6AYopxVBeTQA6al TedgnTQxtz9dRdiE4cSx3ukO10icaU8wYFHFzRV0oQFIDbOogSIdfC3xJ5q0Lg1H Zi/ruAqiyZZkQ6Y4EYQF9+4X5VeZN/XFFn5idSTgYVoUOMLY49hVKovEI/ZtBdBa cnmBQFLPGR20J/go8YTQ== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3vk22u8bpm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 12 Jan 2024 10:53:26 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id E6AD010002A; Fri, 12 Jan 2024 10:53:25 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id DFBE8208D4E; Fri, 12 Jan 2024 10:53:25 +0100 (CET) Received: from localhost (10.201.21.102) by SHFDAG1NODE1.st.com (10.75.129.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 12 Jan 2024 10:53:25 +0100 From: Valentin Caron To: Greg Kroah-Hartman , Jiri Slaby CC: Alexandre Torgue , , , , , Valentin Caron Subject: [PATCH v2 3/4] serial: stm32: change register's offset type from u8 to u16 Date: Fri, 12 Jan 2024 10:52:59 +0100 Message-ID: <20240112095300.2004878-4-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240112095300.2004878-1-valentin.caron@foss.st.com> References: <20240112095300.2004878-1-valentin.caron@foss.st.com> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: EQNCAS1NODE4.st.com (10.75.129.82) To SHFDAG1NODE1.st.com (10.75.129.69) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-01-05_08,2024-01-05_01,2023-05-22_02 USART has registers above 0xff offset, so extend variable type to u16. And change UNDEF_REG to 0xffff. Signed-off-by: Valentin Caron --- drivers/tty/serial/stm32-usart.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index 5ce1d3aae07e..bf3720948704 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -9,18 +9,18 @@ #define DRIVER_NAME "stm32-usart" struct stm32_usart_offsets { - u8 cr1; - u8 cr2; - u8 cr3; - u8 brr; - u8 gtpr; - u8 rtor; - u8 rqr; - u8 isr; - u8 icr; - u8 rdr; - u8 tdr; - u8 presc; + u16 cr1; + u16 cr2; + u16 cr3; + u16 brr; + u16 gtpr; + u16 rtor; + u16 rqr; + u16 isr; + u16 icr; + u16 rdr; + u16 tdr; + u16 presc; }; struct stm32_usart_config { @@ -37,7 +37,7 @@ struct stm32_usart_info { struct stm32_usart_config cfg; }; -#define UNDEF_REG 0xff +#define UNDEF_REG 0xffff /* USART_SR (F4) / USART_ISR (F7) */ #define USART_SR_PE BIT(0) From patchwork Fri Jan 12 09:53:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 762640 Received: from mx07-00178001.pphosted.com (mx08-00178001.pphosted.com [91.207.212.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A98E5EE65; Fri, 12 Jan 2024 09:53:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="vJx5K3mq" Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40C8bMus023989; Fri, 12 Jan 2024 10:53:27 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=i98/hBFkGLGzRNaC6B6POzerMvXKbdE4VOEIPqiij1g=; b=vJ x5K3mqtqK4Wsm2qp9tAqWLylPpusz/27jSMrZLhF1UzjD151CJLxvYRMVZ+YSPr2 Z1rF9/Z8oGT7WaQ38h3VDUNilW5oj3PiG+sz26SpUE1P3tTmyAsIT/EjOL9Nbpiu AfbGhI/Xmum7gvSrfz5HipFZhl945hvhdIGqtYudst02xzvSX9adOjcr2rwkLSxD mqgFUfQg5Laxos0XT0mUoMbcErLx/17EB+Sbqx1Es7xFsGsDaK3ns3NQ1NXuG+jN GmPLYJOGpvHu0t17XkBlcOPBsjHvEcjCKBAZOqUzMgjYRHQwPZl18NIunL4ztnfw DvDEeymo+uzU+R+jrCuQ== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3vk22w8b9b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 12 Jan 2024 10:53:27 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id D042710002A; Fri, 12 Jan 2024 10:53:26 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id C7DCD208D4E; Fri, 12 Jan 2024 10:53:26 +0100 (CET) Received: from localhost (10.201.21.102) by SHFDAG1NODE1.st.com (10.75.129.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 12 Jan 2024 10:53:26 +0100 From: Valentin Caron To: Greg Kroah-Hartman , Jiri Slaby CC: Alexandre Torgue , , , , , Valentin Caron Subject: [PATCH v2 4/4] serial: stm32: get FIFO size from hwcfg register Date: Fri, 12 Jan 2024 10:53:00 +0100 Message-ID: <20240112095300.2004878-5-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240112095300.2004878-1-valentin.caron@foss.st.com> References: <20240112095300.2004878-1-valentin.caron@foss.st.com> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: EQNCAS1NODE4.st.com (10.75.129.82) To SHFDAG1NODE1.st.com (10.75.129.69) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-01-05_08,2024-01-05_01,2023-05-22_02 Since STM32MP25, FIFO size could vary regarding the STM32MPxx version. So we get this size from "hwcfgr1" register and compute threshold values corresponding to the ratio given by reference manual. As STM32MP1x, STM32MP25 and STM32H7 share the same compatible and STM32H7 doesn't have a register to get FIFO size, we force FIFO size to 16 in case of zero read from hwcfgr1 register. Signed-off-by: Valentin Caron --- drivers/tty/serial/stm32-usart.c | 158 +++++++++++++++++-------------- drivers/tty/serial/stm32-usart.h | 6 +- 2 files changed, 94 insertions(+), 70 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 19a45e1b7102..3cbb498c6ea6 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -40,63 +40,64 @@ /* Register offsets */ static struct stm32_usart_info __maybe_unused stm32f4_info = { .ofs = { - .isr = 0x00, - .rdr = 0x04, - .tdr = 0x04, - .brr = 0x08, - .cr1 = 0x0c, - .cr2 = 0x10, - .cr3 = 0x14, - .gtpr = 0x18, - .rtor = UNDEF_REG, - .rqr = UNDEF_REG, - .icr = UNDEF_REG, - .presc = UNDEF_REG, + .isr = 0x00, + .rdr = 0x04, + .tdr = 0x04, + .brr = 0x08, + .cr1 = 0x0c, + .cr2 = 0x10, + .cr3 = 0x14, + .gtpr = 0x18, + .rtor = UNDEF_REG, + .rqr = UNDEF_REG, + .icr = UNDEF_REG, + .presc = UNDEF_REG, + .hwcfgr1 = UNDEF_REG, }, .cfg = { .uart_enable_bit = 13, .has_7bits_data = false, - .fifosize = 1, } }; static struct stm32_usart_info __maybe_unused stm32f7_info = { .ofs = { - .cr1 = 0x00, - .cr2 = 0x04, - .cr3 = 0x08, - .brr = 0x0c, - .gtpr = 0x10, - .rtor = 0x14, - .rqr = 0x18, - .isr = 0x1c, - .icr = 0x20, - .rdr = 0x24, - .tdr = 0x28, - .presc = UNDEF_REG, + .cr1 = 0x00, + .cr2 = 0x04, + .cr3 = 0x08, + .brr = 0x0c, + .gtpr = 0x10, + .rtor = 0x14, + .rqr = 0x18, + .isr = 0x1c, + .icr = 0x20, + .rdr = 0x24, + .tdr = 0x28, + .presc = UNDEF_REG, + .hwcfgr1 = UNDEF_REG, }, .cfg = { .uart_enable_bit = 0, .has_7bits_data = true, .has_swap = true, - .fifosize = 1, } }; static struct stm32_usart_info __maybe_unused stm32h7_info = { .ofs = { - .cr1 = 0x00, - .cr2 = 0x04, - .cr3 = 0x08, - .brr = 0x0c, - .gtpr = 0x10, - .rtor = 0x14, - .rqr = 0x18, - .isr = 0x1c, - .icr = 0x20, - .rdr = 0x24, - .tdr = 0x28, - .presc = 0x2c, + .cr1 = 0x00, + .cr2 = 0x04, + .cr3 = 0x08, + .brr = 0x0c, + .gtpr = 0x10, + .rtor = 0x14, + .rqr = 0x18, + .isr = 0x1c, + .icr = 0x20, + .rdr = 0x24, + .tdr = 0x28, + .presc = 0x2c, + .hwcfgr1 = 0x3f0, }, .cfg = { .uart_enable_bit = 0, @@ -104,7 +105,6 @@ static struct stm32_usart_info __maybe_unused stm32h7_info = { .has_swap = true, .has_wakeup = true, .has_fifo = true, - .fifosize = 16, } }; @@ -1498,37 +1498,57 @@ static const struct uart_ops stm32_uart_ops = { #endif /* CONFIG_CONSOLE_POLL */ }; -/* - * STM32H7 RX & TX FIFO threshold configuration (CR3 RXFTCFG / TXFTCFG) - * Note: 1 isn't a valid value in RXFTCFG / TXFTCFG. In this case, - * RXNEIE / TXEIE can be used instead of threshold irqs: RXFTIE / TXFTIE. - * So, RXFTCFG / TXFTCFG bitfields values are encoded as array index + 1. - */ -static const u32 stm32h7_usart_fifo_thresh_cfg[] = { 1, 2, 4, 8, 12, 14, 16 }; +struct stm32_usart_thresh_ratio { + int mul; + int div; +}; + +static const struct stm32_usart_thresh_ratio stm32h7_usart_fifo_thresh_cfg[] = { + {1, 8}, {1, 4}, {1, 2}, {3, 4}, {7, 8}, {1, 1} }; -static void stm32_usart_get_ftcfg(struct platform_device *pdev, const char *p, - int *ftcfg) +static int stm32_usart_get_thresh_value(u32 fifo_size, int index) { - u32 bytes, i; + return fifo_size * stm32h7_usart_fifo_thresh_cfg[index].mul / + stm32h7_usart_fifo_thresh_cfg[index].div; +} - /* DT option to get RX & TX FIFO threshold (default to 8 bytes) */ +static int stm32_usart_get_ftcfg(struct platform_device *pdev, struct stm32_port *stm32port, + const char *p, int *ftcfg) +{ + const struct stm32_usart_offsets *ofs = &stm32port->info->ofs; + u32 bytes, i, cfg8; + int fifo_size; + + if (WARN_ON(ofs->hwcfgr1 == UNDEF_REG)) + return 1; + + cfg8 = FIELD_GET(USART_HWCFGR1_CFG8, + readl_relaxed(stm32port->port.membase + ofs->hwcfgr1)); + + /* On STM32H7, hwcfgr is not present, so returned value will be 0 */ + fifo_size = cfg8 ? 1 << cfg8 : STM32H7_USART_FIFO_SIZE; + + /* DT option to get RX & TX FIFO threshold (default to half fifo size) */ if (of_property_read_u32(pdev->dev.of_node, p, &bytes)) - bytes = 8; + bytes = fifo_size / 2; + + if (bytes < stm32_usart_get_thresh_value(fifo_size, 0)) { + *ftcfg = -EINVAL; + return fifo_size; + } - for (i = 0; i < ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg); i++) - if (stm32h7_usart_fifo_thresh_cfg[i] >= bytes) + for (i = 0; i < ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg); i++) { + if (stm32_usart_get_thresh_value(fifo_size, i) >= bytes) break; + } if (i >= ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg)) i = ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg) - 1; - dev_dbg(&pdev->dev, "%s set to %d bytes\n", p, - stm32h7_usart_fifo_thresh_cfg[i]); + dev_dbg(&pdev->dev, "%s set to %d/%d bytes\n", p, + stm32_usart_get_thresh_value(fifo_size, i), fifo_size); - /* Provide FIFO threshold ftcfg (1 is invalid: threshold irq unused) */ - if (i) - *ftcfg = i - 1; - else - *ftcfg = -EINVAL; + *ftcfg = i; + return fifo_size; } static void stm32_usart_deinit_port(struct stm32_port *stm32port) @@ -1558,7 +1578,6 @@ static int stm32_usart_init_port(struct stm32_port *stm32port, port->flags = UPF_BOOT_AUTOCONF; port->ops = &stm32_uart_ops; port->dev = &pdev->dev; - port->fifosize = stm32port->info->cfg.fifosize; port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_STM32_CONSOLE); port->irq = irq; port->rs485_config = stm32_usart_config_rs485; @@ -1574,14 +1593,6 @@ static int stm32_usart_init_port(struct stm32_port *stm32port, stm32port->swap = stm32port->info->cfg.has_swap && of_property_read_bool(pdev->dev.of_node, "rx-tx-swap"); - stm32port->fifoen = stm32port->info->cfg.has_fifo; - if (stm32port->fifoen) { - stm32_usart_get_ftcfg(pdev, "rx-threshold", - &stm32port->rxftcfg); - stm32_usart_get_ftcfg(pdev, "tx-threshold", - &stm32port->txftcfg); - } - port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(port->membase)) return PTR_ERR(port->membase); @@ -1604,6 +1615,15 @@ static int stm32_usart_init_port(struct stm32_port *stm32port, goto err_clk; } + stm32port->fifoen = stm32port->info->cfg.has_fifo; + if (stm32port->fifoen) { + stm32_usart_get_ftcfg(pdev, stm32port, "rx-threshold", &stm32port->rxftcfg); + port->fifosize = stm32_usart_get_ftcfg(pdev, stm32port, "tx-threshold", + &stm32port->txftcfg); + } else { + port->fifosize = 1; + } + stm32port->gpios = mctrl_gpio_init(&stm32port->port, 0); if (IS_ERR(stm32port->gpios)) { ret = PTR_ERR(stm32port->gpios); diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index bf3720948704..af20258ccc7a 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -21,6 +21,7 @@ struct stm32_usart_offsets { u16 rdr; u16 tdr; u16 presc; + u16 hwcfgr1; }; struct stm32_usart_config { @@ -29,7 +30,6 @@ struct stm32_usart_config { bool has_swap; bool has_wakeup; bool has_fifo; - int fifosize; }; struct stm32_usart_info { @@ -182,8 +182,12 @@ struct stm32_usart_info { #define USART_PRESC GENMASK(3, 0) /* H7 */ #define USART_PRESC_MAX 0b1011 +/* USART_HWCFCR1 */ +#define USART_HWCFGR1_CFG8 GENMASK(31, 28) /* MP1 */ + #define STM32_SERIAL_NAME "ttySTM" #define STM32_MAX_PORTS 9 +#define STM32H7_USART_FIFO_SIZE 16 #define RX_BUF_L 4096 /* dma rx buffer length */ #define RX_BUF_P (RX_BUF_L / 2) /* dma rx buffer period */