From patchwork Sun Nov 29 10:49:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamil Lulko X-Patchwork-Id: 549747 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 304BB1401AD for ; Mon, 30 Nov 2015 00:43:26 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=K2Zz3O1E; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 76C7E4B779; Sun, 29 Nov 2015 14:43:23 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id tG_pnV9EmZ8V; Sun, 29 Nov 2015 14:43:23 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BAD964B76B; Sun, 29 Nov 2015 14:43:22 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 971684B70B for ; Sun, 29 Nov 2015 11:50:26 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vRKtwhwe4h0S for ; Sun, 29 Nov 2015 11:50:26 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-lf0-f49.google.com (mail-lf0-f49.google.com [209.85.215.49]) by theia.denx.de (Postfix) with ESMTPS id 4A9DE4B6E3 for ; Sun, 29 Nov 2015 11:50:23 +0100 (CET) Received: by lfs39 with SMTP id 39so164518427lfs.3 for ; Sun, 29 Nov 2015 02:50:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=BBrF/bumJMr8tYRMl1jgHoWmYECmi/yIn/4SsZJrmYo=; b=K2Zz3O1EO2uLlaO8ERBJK87aC/PN0qyH29LXIxTY6GvMEms8MsW+uvu2IuzGWpuaTw AaxBVvg3n5qoBQSOIAC4ZKE4ZsLkFmwmuaqCjzxfF2rqXtwXTU9mEIA1avXI7V9NSYP1 vQsprq36KeXKviz7AiDxTPtQoCdoRpxCAomVyUTsiAn0aePzhT8l41VEVTE9+dDvYw5F jZAG4ShASfXgiqJdonoF2WihzgEdKWgVgFQyYmUKX2AW1vNTBs2bL7bW+g9NJ0BfFNAG A1t8tVM+eE8mdLZplPIASeCqlgr+dTFnkeX5RaaLlytCcxAHzUNUqxCyar42/VsyhxLO YOOA== X-Received: by 10.25.90.195 with SMTP id o186mr23868106lfb.9.1448794222586; Sun, 29 Nov 2015 02:50:22 -0800 (PST) Received: from localhost.localdomain (31-178-203-157.dynamic.chello.pl. [31.178.203.157]) by smtp.gmail.com with ESMTPSA id m5sm6018439lfe.22.2015.11.29.02.50.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 29 Nov 2015 02:50:22 -0800 (PST) From: Kamil Lulko To: u-boot@lists.denx.de Date: Sun, 29 Nov 2015 11:49:59 +0100 Message-Id: <1448794199-22171-1-git-send-email-kamil.lulko@gmail.com> X-Mailer: git-send-email 2.5.0 X-Mailman-Approved-At: Sun, 29 Nov 2015 14:43:22 +0100 Cc: trini@konsulko.com, Kamil Lulko Subject: [U-Boot] [PATCH 1/1] stm32: Convert serial driver to DM X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Signed-off-by: Kamil Lulko --- arch/arm/Kconfig | 2 + arch/arm/include/asm/arch-stm32f4/stm32.h | 10 +- board/st/stm32f429-discovery/stm32f429-discovery.c | 13 +- doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_stm32.c | 201 ++++++++++----------- include/configs/stm32f429-discovery.h | 10 +- include/dm/platform_data/serial_stm32.h | 16 ++ 7 files changed, 135 insertions(+), 118 deletions(-) create mode 100644 include/dm/platform_data/serial_stm32.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6542c38..a611ad9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -674,6 +674,8 @@ config ARCH_UNIPHIER config TARGET_STM32F429_DISCOVERY bool "Support STM32F429 Discovery" select CPU_V7M + select DM + select DM_SERIAL config ARCH_ROCKCHIP bool "Support Rockchip SoCs" diff --git a/arch/arm/include/asm/arch-stm32f4/stm32.h b/arch/arm/include/asm/arch-stm32f4/stm32.h index 7ca6dc3..6b64d03 100644 --- a/arch/arm/include/asm/arch-stm32f4/stm32.h +++ b/arch/arm/include/asm/arch-stm32f4/stm32.h @@ -3,7 +3,7 @@ * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com * * (C) Copyright 2015 - * Kamil Lulko, + * Kamil Lulko, * * SPDX-License-Identifier: GPL-2.0+ */ @@ -106,6 +106,14 @@ struct stm32_flash_regs { #define STM32_FLASH_CR_SNB_OFFSET 3 #define STM32_FLASH_CR_SNB_MASK (15 << STM32_FLASH_CR_SNB_OFFSET) +/* + * Peripheral base addresses + */ +#define STM32_USART1_BASE (STM32_APB2PERIPH_BASE + 0x1000) +#define STM32_USART2_BASE (STM32_APB1PERIPH_BASE + 0x4400) +#define STM32_USART3_BASE (STM32_APB1PERIPH_BASE + 0x4800) +#define STM32_USART6_BASE (STM32_APB2PERIPH_BASE + 0x1400) + enum clock { CLOCK_CORE, CLOCK_AHB, diff --git a/board/st/stm32f429-discovery/stm32f429-discovery.c b/board/st/stm32f429-discovery/stm32f429-discovery.c index f418186..8bc2d9e 100644 --- a/board/st/stm32f429-discovery/stm32f429-discovery.c +++ b/board/st/stm32f429-discovery/stm32f429-discovery.c @@ -6,7 +6,7 @@ * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com * * (C) Copyright 2015 - * Kamil Lulko, + * Kamil Lulko, * * SPDX-License-Identifier: GPL-2.0+ */ @@ -17,6 +17,8 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -263,6 +265,15 @@ int dram_init(void) return rv; } +static const struct stm32_serial_platdata serial_platdata = { + .base = (struct stm32_usart *)STM32_USART1_BASE, +}; + +U_BOOT_DEVICE(stm32_serials) = { + .name = "serial_stm32", + .platdata = &serial_platdata, +}; + u32 get_board_rev(void) { return 0; diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 60483a4..76ad629 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c - serial_stm32.c serial_xuartlite.c usbtty.c diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c index 8b2830b..df2258e 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -1,45 +1,18 @@ /* * (C) Copyright 2015 - * Kamil Lulko, + * Kamil Lulko, * * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include #include +#include -/* - * Set up the usart port - */ -#if (CONFIG_STM32_USART >= 1) && (CONFIG_STM32_USART <= 6) -#define USART_PORT (CONFIG_STM32_USART - 1) -#else -#define USART_PORT 0 -#endif -/* - * Set up the usart base address - * - * --STM32_USARTD_BASE means default setting - */ -#define STM32_USART1_BASE (STM32_APB2PERIPH_BASE + 0x1000) -#define STM32_USART2_BASE (STM32_APB1PERIPH_BASE + 0x4400) -#define STM32_USART3_BASE (STM32_APB1PERIPH_BASE + 0x4800) -#define STM32_USART6_BASE (STM32_APB2PERIPH_BASE + 0x1400) -#define STM32_USARTD_BASE STM32_USART1_BASE -/* - * RCC USART specific definitions - * - * --RCC_ENR_USARTDEN means default setting - */ -#define RCC_ENR_USART1EN (1 << 4) -#define RCC_ENR_USART2EN (1 << 17) -#define RCC_ENR_USART3EN (1 << 18) -#define RCC_ENR_USART6EN (1 << 5) -#define RCC_ENR_USARTDEN RCC_ENR_USART1EN - -struct stm32_serial { +struct stm32_usart { u32 sr; u32 dr; u32 brr; @@ -49,120 +22,136 @@ struct stm32_serial { u32 gtpr; }; -#define USART_CR1_RE (1 << 2) -#define USART_CR1_TE (1 << 3) -#define USART_CR1_UE (1 << 13) +#define USART_CR1_RE (1 << 2) +#define USART_CR1_TE (1 << 3) +#define USART_CR1_UE (1 << 13) #define USART_SR_FLAG_RXNE (1 << 5) -#define USART_SR_FLAG_TXE (1 << 7) +#define USART_SR_FLAG_TXE (1 << 7) -#define USART_BRR_F_MASK 0xF +#define USART_BRR_F_MASK 0xF #define USART_BRR_M_SHIFT 4 #define USART_BRR_M_MASK 0xFFF0 DECLARE_GLOBAL_DATA_PTR; -static const unsigned long usart_base[] = { - STM32_USART1_BASE, - STM32_USART2_BASE, - STM32_USART3_BASE, - STM32_USARTD_BASE, - STM32_USARTD_BASE, - STM32_USART6_BASE -}; +#define MAX_SERIAL_PORTS 4 -static const unsigned long rcc_enr_en[] = { - RCC_ENR_USART1EN, - RCC_ENR_USART2EN, - RCC_ENR_USART3EN, - RCC_ENR_USARTDEN, - RCC_ENR_USARTDEN, - RCC_ENR_USART6EN +/* + * RCC USART specific definitions + */ +#define RCC_ENR_USART1EN (1 << 4) +#define RCC_ENR_USART2EN (1 << 17) +#define RCC_ENR_USART3EN (1 << 18) +#define RCC_ENR_USART6EN (1 << 5) + +/* Array used to figure out which RCC bit needs to be set */ +static const unsigned long usart_port_rcc_pairs[MAX_SERIAL_PORTS][2] = { + { STM32_USART1_BASE, RCC_ENR_USART1EN }, + { STM32_USART2_BASE, RCC_ENR_USART2EN }, + { STM32_USART3_BASE, RCC_ENR_USART3EN }, + { STM32_USART6_BASE, RCC_ENR_USART6EN } }; -static void stm32_serial_setbrg(void) -{ - serial_init(); -} - -static int stm32_serial_init(void) +static int stm32_serial_setbrg(struct udevice *dev, int baudrate) { - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; - u32 clock, int_div, frac_div, tmp; + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; + u32 clock, int_div, frac_div, tmp; - if ((usart_base[USART_PORT] & STM32_BUS_MASK) == - STM32_APB1PERIPH_BASE) { - setbits_le32(&STM32_RCC->apb1enr, rcc_enr_en[USART_PORT]); + if (((u32)usart & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE) clock = clock_get(CLOCK_APB1); - } else if ((usart_base[USART_PORT] & STM32_BUS_MASK) == - STM32_APB2PERIPH_BASE) { - setbits_le32(&STM32_RCC->apb2enr, rcc_enr_en[USART_PORT]); + else if (((u32)usart & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE) clock = clock_get(CLOCK_APB2); - } else { + else return -1; - } - int_div = (25 * clock) / (4 * gd->baudrate); + int_div = (25 * clock) / (4 * baudrate); tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK; frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT)); tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK; - writel(tmp, &usart->brr); - setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); return 0; } -static int stm32_serial_getc(void) +static int stm32_serial_getc(struct udevice *dev) { - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; - while ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0) - ; + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; + + if ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0) + return -EAGAIN; + return readl(&usart->dr); } -static void stm32_serial_putc(const char c) +static int stm32_serial_putc(struct udevice *dev, const char c) { - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; - if (c == '\n') - stm32_serial_putc('\r'); + if ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0) + return -EAGAIN; - while ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0) - ; writel(c, &usart->dr); + + return 0; } -static int stm32_serial_tstc(void) +static int stm32_serial_pending(struct udevice *dev, bool input) { - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; - u8 ret; + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; - ret = readl(&usart->sr) & USART_SR_FLAG_RXNE; - return ret; + if (input) + return readl(&usart->sr) & USART_SR_FLAG_RXNE; + else + return !(readl(&usart->sr) & USART_SR_FLAG_TXE); } -static struct serial_device stm32_serial_drv = { - .name = "stm32_serial", - .start = stm32_serial_init, - .stop = NULL, - .setbrg = stm32_serial_setbrg, - .putc = stm32_serial_putc, - .puts = default_serial_puts, - .getc = stm32_serial_getc, - .tstc = stm32_serial_tstc, -}; - -void stm32_serial_initialize(void) +static int stm32_serial_probe(struct udevice *dev) { - serial_register(&stm32_serial_drv); -} + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; + unsigned char usart_port = 0xFF; + unsigned int i; + + for (i = 0; i < MAX_SERIAL_PORTS; i++) { + if ((u32)usart == usart_port_rcc_pairs[i][0]) { + usart_port = i; + break; + } + } -__weak struct serial_device *default_serial_console(void) -{ - return &stm32_serial_drv; + if (usart_port == 0xFF) + return -1; + + if (((u32)usart & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE) + setbits_le32(&STM32_RCC->apb1enr, + usart_port_rcc_pairs[usart_port][1]); + else if (((u32)usart & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE) + setbits_le32(&STM32_RCC->apb2enr, + usart_port_rcc_pairs[usart_port][1]); + else + return -1; + + setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); + + return 0; } + +static const struct dm_serial_ops stm32_serial_ops = { + .putc = stm32_serial_putc, + .pending = stm32_serial_pending, + .getc = stm32_serial_getc, + .setbrg = stm32_serial_setbrg, +}; + +U_BOOT_DRIVER(serial_stm32) = { + .name = "serial_stm32", + .id = UCLASS_SERIAL, + .ops = &stm32_serial_ops, + .probe = stm32_serial_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/include/configs/stm32f429-discovery.h b/include/configs/stm32f429-discovery.h index 8191fb2..3e80861 100644 --- a/include/configs/stm32f429-discovery.h +++ b/include/configs/stm32f429-discovery.h @@ -1,6 +1,6 @@ /* * (C) Copyright 2015 - * Kamil Lulko, + * Kamil Lulko, * * SPDX-License-Identifier: GPL-2.0+ */ @@ -51,14 +51,6 @@ #define CONFIG_STM32_GPIO #define CONFIG_STM32_SERIAL -/* - * Configuration of the USART - * 1: TX:PA9 RX:PA10 - * 2: TX:PD5 RX:PD6 - * 3: TX:PC10 RX:PC11 - * 6: TX:PG14 RX:PG9 - */ -#define CONFIG_STM32_USART 1 #define CONFIG_STM32_HSE_HZ 8000000 diff --git a/include/dm/platform_data/serial_stm32.h b/include/dm/platform_data/serial_stm32.h new file mode 100644 index 0000000..d1cfcbe --- /dev/null +++ b/include/dm/platform_data/serial_stm32.h @@ -0,0 +1,16 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SERIAL_STM32_H +#define __SERIAL_STM32_H + +/* Information about a serial port */ +struct stm32_serial_platdata { + struct stm32_usart *base; /* address of registers in physical memory */ +}; + +#endif /* __SERIAL_STM32_H */