diff options
-rw-r--r-- | arch/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/ddr.c | 11 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/boot-common.c | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-stm32f4/stm32.h | 10 | ||||
-rw-r--r-- | arch/m68k/lib/Makefile | 4 | ||||
-rw-r--r-- | arch/m68k/lib/ashldi3.c | 50 | ||||
-rw-r--r-- | arch/m68k/lib/lshrdi3.c | 50 | ||||
-rw-r--r-- | arch/m68k/lib/muldi3.c | 71 | ||||
-rw-r--r-- | board/siemens/draco/board.c | 5 | ||||
-rw-r--r-- | board/st/stm32f429-discovery/stm32f429-discovery.c | 13 | ||||
-rw-r--r-- | common/bootm_os.c | 2 | ||||
-rw-r--r-- | common/cli_hush.c | 4 | ||||
-rw-r--r-- | common/cmd_part.c | 2 | ||||
-rw-r--r-- | common/spl/spl_mmc.c | 8 | ||||
-rw-r--r-- | doc/driver-model/serial-howto.txt | 1 | ||||
-rw-r--r-- | drivers/serial/serial_stm32.c | 203 | ||||
-rw-r--r-- | include/configs/stm32f429-discovery.h | 10 | ||||
-rw-r--r-- | include/dm/platform_data/serial_stm32.h | 16 | ||||
-rw-r--r-- | tools/env/fw_env.c | 1 |
20 files changed, 334 insertions, 131 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 6489cc9..1709d40 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -40,6 +40,7 @@ config BLACKFIN config M68K bool "M68000 architecture" + select HAVE_PRIVATE_LIBGCC select HAVE_GENERIC_BOARD select SYS_GENERIC_BOARD diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7383975..75d6bbc 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -697,6 +697,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/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c index b3fb0c4..888cf1f 100644 --- a/arch/arm/cpu/armv7/am33xx/ddr.c +++ b/arch/arm/cpu/armv7/am33xx/ddr.c @@ -164,6 +164,13 @@ void config_sdram(const struct emif_regs *regs, int nr) writel(regs->zq_config, &emif_reg[nr]->emif_zq_config); writel(regs->sdram_config, &cstat->secure_emif_sdram_config); writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); + + /* Trigger initialization */ + writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl); + /* Wait 1ms because of L3 timeout error */ + udelay(1000); + + /* Write proper sdram_ref_cref_ctrl value */ writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); } @@ -292,7 +299,9 @@ void config_ddr_phy(const struct emif_regs *regs, int nr) EMIF_REG_INITREF_DIS_MASK); #endif if (regs->zq_config) - writel(0x80003100, &emif_reg[nr]->emif_sdram_ref_ctrl); + /* Set time between rising edge of DDR_RESET to rising + * edge of DDR_CKE to > 500us per memory spec. */ + writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl); writel(regs->emif_ddr_phy_ctlr_1, &emif_reg[nr]->emif_ddr_phy_ctrl_1); diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index 8e5d5c9..0456263 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -208,6 +208,7 @@ int board_mmc_init(bd_t *bis) break; case BOOT_DEVICE_MMC2: case BOOT_DEVICE_MMC2_2: + omap_mmc_init(0, 0, 0, -1, -1); omap_mmc_init(1, 0, 0, -1, -1); break; } 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, <rev13@wp.pl> + * Kamil Lulko, <kamil.lulko@gmail.com> * * 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/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index 73d40bd..dbca42c 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -5,6 +5,10 @@ # SPDX-License-Identifier: GPL-2.0+ # +## Build a couple of necessary functions into a private libgcc +## if the user asked for it +lib-$(CONFIG_USE_PRIVATE_LIBGCC) += lshrdi3.o muldi3.o ashldi3.o + obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += cache.o obj-y += interrupts.o diff --git a/arch/m68k/lib/ashldi3.c b/arch/m68k/lib/ashldi3.c new file mode 100644 index 0000000..be197da --- /dev/null +++ b/arch/m68k/lib/ashldi3.c @@ -0,0 +1,50 @@ +/* + * ashldi3.c extracted from gcc-2.7.2.3/libgcc2.c and + * gcc-2.7.2.3/longlong.h + * + * Copyright (C) 1989-2015 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define BITS_PER_UNIT 8 + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype __ashldi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.low = 0; + w.s.high = (USItype)uu.s.low << -bm; + } + else + { + USItype carries = (USItype)uu.s.low >> bm; + w.s.low = (USItype)uu.s.low << b; + w.s.high = ((USItype)uu.s.high << b) | carries; + } + + return w.ll; +}
\ No newline at end of file diff --git a/arch/m68k/lib/lshrdi3.c b/arch/m68k/lib/lshrdi3.c new file mode 100644 index 0000000..9052383 --- /dev/null +++ b/arch/m68k/lib/lshrdi3.c @@ -0,0 +1,50 @@ +/* + * lshrdi3.c extracted from gcc-2.7.2.3/libgcc2.c and + * gcc-2.7.2.3/longlong.h + * + * Copyright (C) 1989-2015 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define BITS_PER_UNIT 8 + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype __lshrdi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (USItype)uu.s.high >> -bm; + } + else + { + USItype carries = (USItype)uu.s.high << bm; + w.s.high = (USItype)uu.s.high >> b; + w.s.low = ((USItype)uu.s.low >> b) | carries; + } + + return w.ll; +}
\ No newline at end of file diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c new file mode 100644 index 0000000..d709c32 --- /dev/null +++ b/arch/m68k/lib/muldi3.c @@ -0,0 +1,71 @@ +/* + * muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and + * gcc-2.7.2.3/longlong.h + * + * Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define SI_TYPE_SIZE 32 +#define __BITS4 (SI_TYPE_SIZE / 4) +#define __ll_B (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((USItype) (t) % __ll_B) +#define __ll_highpart(t) ((USItype) (t) / __ll_B) + +#define umul_ppmm(w1, w0, u, v) \ + do { \ + USItype __x0, __x1, __x2, __x3; \ + USItype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (USItype) __ul * __vl; \ + __x1 = (USItype) __ul * __vh; \ + __x2 = (USItype) __uh * __vl; \ + __x3 = (USItype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) + +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype __muldi3 (DItype u, DItype v) +{ + DIunion w; + DIunion uu, vv; + + uu.ll = u, + vv.ll = v; + + w.ll = __umulsidi3 (uu.s.low, vv.s.low); + w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high + + (USItype) uu.s.high * (USItype) vv.s.low); + + return w.ll; +} diff --git a/board/siemens/draco/board.c b/board/siemens/draco/board.c index 4882314..988c12a 100644 --- a/board/siemens/draco/board.c +++ b/board/siemens/draco/board.c @@ -196,11 +196,6 @@ struct ctrl_ioregs draco_ddr3_ioregs = { config_ddr(DDR_PLL_FREQ, &draco_ddr3_ioregs, &draco_ddr3_data, &draco_ddr3_cmd_ctrl_data, &draco_ddr3_emif_reg_data, 0); - - /* For Samsung 2Gbit RAM we need this delay otherwise config fails after - * soft reset. - */ - udelay(2000); } static void spl_siemens_board_init(void) 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, <rev13@wp.pl> + * Kamil Lulko, <kamil.lulko@gmail.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -17,6 +17,8 @@ #include <asm/arch/stm32.h> #include <asm/arch/gpio.h> #include <asm/arch/fmc.h> +#include <dm/platdata.h> +#include <dm/platform_data/serial_stm32.h> 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/common/bootm_os.c b/common/bootm_os.c index 72477f0..cb83f4a 100644 --- a/common/bootm_os.c +++ b/common/bootm_os.c @@ -288,6 +288,8 @@ void do_bootvx_fdt(bootm_headers_t *images) if (ret) return; + fdt_fixup_ethernet(*of_flat_tree); + ret = fdt_add_subnode(*of_flat_tree, 0, "chosen"); if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) { bootline = getenv("bootargs"); diff --git a/common/cli_hush.c b/common/cli_hush.c index 7f69c06..2fbfdbe 100644 --- a/common/cli_hush.c +++ b/common/cli_hush.c @@ -3508,9 +3508,9 @@ static char *insert_var_value_sub(char *inp, int tag_subst) char *p, *p1, *res_str = NULL; while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) { - /* check the beginning of the string for normal charachters */ + /* check the beginning of the string for normal characters */ if (p != inp) { - /* copy any charachters to the result string */ + /* copy any characters to the result string */ len = p - inp; res_str = xrealloc(res_str, (res_str_len + len)); strncpy((res_str + res_str_len), inp, len); diff --git a/common/cmd_part.c b/common/cmd_part.c index b860624..5599509 100644 --- a/common/cmd_part.c +++ b/common/cmd_part.c @@ -100,7 +100,7 @@ static int do_part_list(int argc, char * const argv[]) if (bootable && !info.bootable) continue; - sprintf(t, "%s%d", str[0] ? " " : "", p); + sprintf(t, "%s%x", str[0] ? " " : "", p); strcat(str, t); } setenv(var, str); diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index f2c1af5..c1c29c0 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -23,12 +23,13 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) unsigned long count; u32 image_size_sectors; struct image_header *header; + int dev_num = mmc->block_dev.dev; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); /* read image header to find the image size & load address */ - count = mmc->block_dev.block_read(0, sector, 1, header); + count = mmc->block_dev.block_read(dev_num, sector, 1, header); debug("read sector %lx, count=%lu\n", sector, count); if (count == 0) goto end; @@ -45,7 +46,7 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) mmc->read_bl_len; /* Read the header too to avoid extra memcpy */ - count = mmc->block_dev.block_read(0, sector, image_size_sectors, + count = mmc->block_dev.block_read(dev_num, sector, image_size_sectors, (void *)(ulong)spl_image.load_addr); debug("read %x sectors to %x\n", image_size_sectors, spl_image.load_addr); @@ -149,7 +150,8 @@ static int mmc_load_image_raw_os(struct mmc *mmc) { unsigned long count; - count = mmc->block_dev.block_read(0, + count = mmc->block_dev.block_read( + mmc->block_dev.dev, CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, (void *) CONFIG_SYS_SPL_ARGS_ADDR); 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..91a5dde 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -1,45 +1,18 @@ /* * (C) Copyright 2015 - * Kamil Lulko, <rev13@wp.pl> + * Kamil Lulko, <kamil.lulko@gmail.com> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> #include <asm/io.h> #include <serial.h> #include <asm/arch/stm32.h> +#include <dm/platform_data/serial_stm32.h> -/* - * 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) +static int stm32_serial_setbrg(struct udevice *dev, int baudrate) { - serial_init(); -} + struct stm32_serial_platdata *plat = dev->platdata; + struct stm32_usart *const usart = plat->base; + u32 clock, int_div, frac_div, tmp; -static int stm32_serial_init(void) -{ - struct stm32_serial *usart = - (struct stm32_serial *)usart_base[USART_PORT]; - 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 { - return -1; - } + else + return -EINVAL; - 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 ? 1 : 0; + else + return readl(&usart->sr) & USART_SR_FLAG_TXE ? 0 : 1; } -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; + int usart_port = -1; + 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 == -1) + return -EINVAL; + + 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 -EINVAL; + + 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, <rev13@wp.pl> + * Kamil Lulko, <kamil.lulko@gmail.com> * * 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, <kamil.lulko@gmail.com> + * + * 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 */ diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index ba11f77..39f7333 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -10,6 +10,7 @@ #define _GNU_SOURCE +#include <compiler.h> #include <errno.h> #include <env_flags.h> #include <fcntl.h> |