From patchwork Thu Jan 11 15:27:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 762141 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 7B8044F1EA; Thu, 11 Jan 2024 15:27: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="7EahDuFr" Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40B9tTvo026791; Thu, 11 Jan 2024 16:27:36 +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=YarNn8OP74+yN6py9j9Ts62si400Ka1Aub9xlZXNVqs=; b=7E ahDuFrCCPXbqpNTNUbKWeOo75UGXZ8hiJRZ92ayPWZwj7rulGamkEC0X72dk/8Nw tKm/swZ6PMX5Wq04Q5gj8RZVLlvuVI3nIq4blhVoO48oX80i7ONFZsoBpdap4HOK JWG3XguR7yF8iyRN/rniXCYTT9ofvPHTjDRJUiCAK273GsOq9q+LRBVk3WIQEIdM vP4a+6eEa9MKkXhn7iY2cjhLxrP/nr9m5ihDitt77pykIEFdsO3pJhke1HOItFgj +l8vhqcpVcX8MAL05gOSPEYIZAr4+SiDIi7gYANOrBrhWhvQY9a5aV1ardt3wECJ iwwKzNCbzPaaez6l2GYQ== 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 3vexrcdr80-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Jan 2024 16:27:36 +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 5FBBA100049; Thu, 11 Jan 2024 16:27:35 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 57DA3290CC6; Thu, 11 Jan 2024 16:27:35 +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; Thu, 11 Jan 2024 16:27:35 +0100 From: Valentin Caron To: Greg Kroah-Hartman , Jiri Slaby CC: Alexandre Torgue , , , , , Valentin Caron Subject: [PATCH 1/4] serial: stm32: implement prescaler tuning to compute low baudrate Date: Thu, 11 Jan 2024 16:27:09 +0100 Message-ID: <20240111152712.1842790-2-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240111152712.1842790-1-valentin.caron@foss.st.com> References: <20240111152712.1842790-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 | 70 ++++++++++++++++++++++---------- drivers/tty/serial/stm32-usart.h | 6 +++ 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 794b77512740..e8ab5efad945 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -50,6 +50,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 +72,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 +95,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 +1148,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 +1158,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 +1272,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 Thu Jan 11 15:27:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 762446 Received: from mx08-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 314184F1E6; Thu, 11 Jan 2024 15:27: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="XknZtJ+h" Received: from pps.filterd (m0369457.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40BAFBxP001702; Thu, 11 Jan 2024 16:27:36 +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=Xk nZtJ+hCyCb5HWGuYyRfOxV3x1ApcTJlfMknUPtfnkTrv5ACs32wPNE8yjwZEFT0P 9M64m4vUrAAFRG2ZC7AireZ99e4qZnG9728Dtlcj+lHda7rKFFRNlPwfaFa0kX7X Ik7Sm3j7b9tXrzJ6YaXFOjanjhKP7pix1rm1geYl5WjTsTnJELo4q8unza0xMsEd x9iUsyfs6fjTQ5N6Qx/iqNKRMoJgujE6G5HEtFYC0t2pPZ+GG0iVGAw1+su0a6ZB uB7MjEHpk/Tv4V3wtYY/W0j8sG/4BGGSkbygjnvc35C7rcLk7HlBWHen5KkObE3w mRcPhIuSm5tIDZVZhVIA== 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 3vfjpp3fex-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Jan 2024 16:27:36 +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 3024B10002A; Thu, 11 Jan 2024 16:27:36 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 29013290CC7; Thu, 11 Jan 2024 16:27:36 +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; Thu, 11 Jan 2024 16:27:35 +0100 From: Valentin Caron To: Greg Kroah-Hartman , Jiri Slaby CC: Alexandre Torgue , , , , , Valentin Caron Subject: [PATCH 2/4] serial: stm32: extend max number of U(S)ART to 9 Date: Thu, 11 Jan 2024 16:27:10 +0100 Message-ID: <20240111152712.1842790-3-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240111152712.1842790-1-valentin.caron@foss.st.com> References: <20240111152712.1842790-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 Thu Jan 11 15:27:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 762445 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 0E5334CB34; Thu, 11 Jan 2024 15:27:49 +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="wKgiygsZ" 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 40B9Nxh1024403; Thu, 11 Jan 2024 16:27:37 +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=wK giygsZhOiUfY5kpE1T2ZnrdSZBWMIEJaXtbVB4rHjbOPvuXX4lXNQV6Vv5uxFOtP bOgo+hjCbDZJDbi2HYIKUhIoZj/0O02kRzsVgk5XQsvS7xvM0BZLThzdxlCP3qpn i/Fa2bnZFxzcVrXQb/3L/i/o8+mEka7ERtOU/2m0p4ZClnsBhI9U3TL/rbwiToQv 9kaJFz+4o6OxOrLaU/KAk3IrfABnZZ7SatY4kLnSIWCfAKPIuPlTc1w7MCrmzojK nz/ZOyO5581eEJiUPOuqTC0xcYiy2TBlWC4R5DdURuhHzpWjU6M/X4E7FoOZzJ+Z reItamJN7b1xG7mcmJuw== 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 3vey30x63x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Jan 2024 16:27:37 +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 0201610002A; Thu, 11 Jan 2024 16:27:37 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id EFD75290CC6; Thu, 11 Jan 2024 16:27:36 +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; Thu, 11 Jan 2024 16:27:36 +0100 From: Valentin Caron To: Greg Kroah-Hartman , Jiri Slaby CC: Alexandre Torgue , , , , , Valentin Caron Subject: [PATCH 3/4] serial: stm32: change register's offset type from u8 to u16 Date: Thu, 11 Jan 2024 16:27:11 +0100 Message-ID: <20240111152712.1842790-4-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240111152712.1842790-1-valentin.caron@foss.st.com> References: <20240111152712.1842790-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 Thu Jan 11 15:27:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 762140 Received: from mx08-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 94A3C4F1F0; Thu, 11 Jan 2024 15:27:49 +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="sngouWZt" Received: from pps.filterd (m0369457.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40B9Re7M021699; Thu, 11 Jan 2024 16:27:38 +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=hs6rE/Qe9qEFkmYH23V4JIMvxN7TUaLJ3XR/KPAMoPo=; b=sn gouWZto11iWdYw9+4w1u1VLiAfBCtqPMlw6m8EhQafvKLdEb3IsnkJ+HZgFCK9go sIV/6BRPerdkwYLO5Fj0MO19uXcotWBYoSuS2mgA/Ql6iZsIKRrb7ZvlarO//Bj+ bU26eDjZH0Wk660WZ50lwhu6639zPup1B+rc574odg97/ySqwgj3KLT/R3aQb5qD mjMWrz36Aa8wyp4R9LroKA7kii0TCxyq8s7Bj7F3dkaGwWTCyzKEGelKZn/+nbSw F70FmtUCQwdpaeqyijq3IYM/lVCczqE3ZbT4PRog6C9LmqneHGYoOC23D77Xt3QK CKZ4X80Bm3StAJL7qesA== 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 3vfjpp3ff3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Jan 2024 16:27:38 +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 CF07A10004D; Thu, 11 Jan 2024 16:27:37 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id C74C4290CC6; Thu, 11 Jan 2024 16:27:37 +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; Thu, 11 Jan 2024 16:27:37 +0100 From: Valentin Caron To: Greg Kroah-Hartman , Jiri Slaby CC: Alexandre Torgue , , , , , Valentin Caron Subject: [PATCH 4/4] serial: stm32: get FIFO size from hwcfg register Date: Thu, 11 Jan 2024 16:27:12 +0100 Message-ID: <20240111152712.1842790-5-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240111152712.1842790-1-valentin.caron@foss.st.com> References: <20240111152712.1842790-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 e8ab5efad945..ffb2d4248107 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -39,63 +39,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, @@ -103,7 +104,6 @@ static struct stm32_usart_info __maybe_unused stm32h7_info = { .has_swap = true, .has_wakeup = true, .has_fifo = true, - .fifosize = 16, } }; @@ -1497,37 +1497,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) @@ -1557,7 +1577,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; @@ -1573,14 +1592,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); @@ -1603,6 +1614,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 */